Clarke and Park direct and inverse transforms
This library implements C-callable ASM Clarke and Park direct and inverse transforms for the Freescale DSP56F800E family of digital signal controllers.
Source includes the header file for inclusion in C applications as well as the code itself and an usage example in C.
/* -------------- CPTrans.h begins -------------- */
#ifndef __CPTRANS_H__
#define __CPTRANS_H__
#include "types.h"
#define Minus1Over2 0xC000
#define Root3Over2 0x6EDA
#define TwoOver3 0x5555
#define Minus1Over3 0xD555
#define OneOnRoot3 0x49E7
/*---------------------------------------------------------------------------;
; Clarke transform (Vuvw -> Vab) with constant amplitudes. ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: (R2) = Vu ;
; (R2+1) = Vv ;
; (R2+2) = Vw ;
; (R3) = Destination memory location for Va ;
; (R3+1) = Destination memory location for Vb ;
; ;
; Output: None ;
; ;
; Registers modified: A, X0, Y ;
;---------------------------------------------------------------------------*/
asm void Clarke(Frac16 *Vuvw, Frac16 *Vab);
/*---------------------------------------------------------------------------;
; Inverse Clarke transform (Vab -> Vuvw) with constant amplitudes. ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: (R2) = Va ;
; (R2+1) = Vb ;
; (R3) = Destination memory location for Vu ;
; (R3+1) = Destination memory location for Vv ;
; (R3+2) = Destination memory location for Vw ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0, Y ;
;---------------------------------------------------------------------------*/
asm void InvClarke(Frac16 *Vab, Frac16 *Vuvw);
/*---------------------------------------------------------------------------;
; Park transform (Vab -> Vdq). ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: Y0 = cos(phi) ;
; Y1 = sin(phi) ;
; (R2) = Va ;
; (R2+1) = Vb ;
; (R3) = Destination memory location for Vd ;
; (R3+1) = Destination memory location for Vq ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0 ;
;---------------------------------------------------------------------------*/
asm void Park(Frac16 cosphi, Frac16 sinphi, Frac16 *Vab, Frac16 *Vdq);
/*---------------------------------------------------------------------------;
; Inverse Park transform (Vdq -> Vab). ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: Y0 = cos(phi) ;
; Y1 = sin(phi) ;
; (R2) = Vd ;
; (R2+1) = Vq ;
; (R3) = Destination memory location for Va ;
; (R3+1) = Destination memory location for Vb ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0 ;
;---------------------------------------------------------------------------*/
asm void InvPark(Frac16 cosphi, Frac16 sinphi, Frac16 *Vdq, Frac16 *Vab);
#endif //ifndef __CPTRANS_H__
/* -------------- CPTrans.h ends -------------- */
/* -------------- CPTrans.c begins -------------- */
/*---------------------------------------------------------------------------;
; Clarke transform (Vuvw -> Vab) with constant amplitudes. ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: (R2) = Vu ;
; (R2+1) = Vv ;
; (R2+2) = Vw ;
; (R3) = Destination memory location for Va ;
; (R3+1) = Destination memory location for Vb ;
; ;
; Output: None ;
; ;
; Registers modified: A, X0, Y ;
;---------------------------------------------------------------------------*/
asm void Clarke(Frac16 *Vuvw, Frac16 *Vab){
MOVE.W X:(R2),X0 //X0 = Vu
MOVE.W #TwoOver3,Y0 //Y0 = 2/3
MPY X0,Y0,A //A = 2/3*Vu
MOVE.W #Minus1Over3,X0 //X0 = -1/3
MOVE.W X:(R2+1),Y0 //Y0 = Vv
MOVE.W X:(R2+2),Y1 //Y1 = Vw
MAC X0,Y0,A //A = 2/3*Vu-1/3*Vv
MAC X0,Y1,A //A = 2/3*Vu-1/3*Vv-1/3*Vw
MOVE.W A,X:(R3) //Va = 2/3*Vu-1/3*Vv-1/3*Vw
MOVE.W #OneOnRoot3,X0 //X0 = 1/sqrt(3)
MPY X0,Y0,A //A = 1/sqrt(3)*Vv
MACR -X0,Y1,A //A = 1/sqrt(3)*Vv-1/sqrt(3)*Vw
MOVE.W A,X:(R3+1) //Vb = 1/sqrt(3)*Vv-1/sqrt(3)*Vw
RTS //Return from subroutine
}
/*---------------------------------------------------------------------------;
; Inverse Clarke transform (Vab -> Vuvw) with constant amplitudes. ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: (R2) = Va ;
; (R2+1) = Vb ;
; (R3) = Destination memory location for Vu ;
; (R3+1) = Destination memory location for Vv ;
; (R3+2) = Destination memory location for Vw ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0, Y ;
;---------------------------------------------------------------------------*/
asm void InvClarke(Frac16 *Vab, Frac16 *Vuvw){
MOVE.W X:(R2),Y0 //Y0 = Va
MOVE.W X:(R2+1),Y1 //Y1 = Vb
MOVE.W Y0,X:(R3) //Vu = Va
MOVE.W #Minus1Over2,X0 //X0 = -1/2
MPY X0,Y0,A //A = -1/2*Va
TFR A,B //B = -1/2*Va
MOVE.W #Root3Over2,X0 //X0 = sqrt(3)/2
MAC X0,Y1,A //A = -1/2*Va+sqrt(3)/2*Vb
MAC -X0,Y1,B //B = -1/2*Va-sqrt(3)/2*Vb
MOVE.W A,X:(R3+1) //Vv = -1/2*Va+sqrt(3)/2*Vb
MOVE.W B,X:(R3+2) //Vw = -1/2*Va-sqrt(3)/2*Vb
RTS //Return from subroutine
}
/*---------------------------------------------------------------------------;
; Park transform (Vab -> Vdq). ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: Y0 = cos(phi) ;
; Y1 = sin(phi) ;
; (R2) = Va ;
; (R2+1) = Vb ;
; (R3) = Destination memory location for Vd ;
; (R3+1) = Destination memory location for Vq ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0 ;
;---------------------------------------------------------------------------*/
asm void Park(Frac16 cosphi, Frac16 sinphi, Frac16 *Vab, Frac16 *Vdq){
MOVE.W X:(R2),X0 //X0 = Va
MPY X0,Y0,A //A = Va*cos(phi)
MPY -X0,Y1,B //B = -Va*sin(phi)
MOVE.W X:(R2+1),X0 //X0 = Vb
MAC X0,Y1,A //A = Va*cos(phi)+Vb*sin(phi)
MAC X0,Y0,B //B = -Va*sin(phi)+Vb*cos(phi)
MOVE.W A,X:(R3) //Vd = Va*cos(phi)+Vb*sin(phi)
MOVE.W B,X:(R3+1) //Vq = -Va*sin(phi)+Vb*cos(phi)
RTS //Return from subroutine
}
/*---------------------------------------------------------------------------;
; Inverse Park transform (Vdq -> Vab). ;
; For optimal results it is advised to call this function with saturation ;
; disabled. ;
; ;
; Input: Y0 = cos(phi) ;
; Y1 = sin(phi) ;
; (R2) = Vd ;
; (R2+1) = Vq ;
; (R3) = Destination memory location for Va ;
; (R3+1) = Destination memory location for Vb ;
; ;
; Output: None ;
; ;
; Registers modified: A, B, X0 ;
;---------------------------------------------------------------------------*/
asm void InvPark(Frac16 cosphi, Frac16 sinphi, Frac16 *Vdq, Frac16 *Vab){
MOVE.W X:(R2),X0 //X0 = Vd
MPY X0,Y0,A //A = Vd*cos(phi)
MPY X0,Y1,B //B = Vd*sin(phi)
MOVE.W X:(R2+1),X0 //X0 = Vq
MAC -X0,Y1,A //A = Vd*cos(phi)-Vq*sin(phi)
MAC X0,Y0,B //B = Vd*sin(phi)+Vq*cos(phi)
MOVE.W A,X:(R3) //Vd = Vd*cos(phi)-Vq*sin(phi)
MOVE.W B,X:(R3+1) //Vq = Vd*sin(phi)+Vq*cos(phi)
RTS //Return from subroutine
}
/* -------------- CPTrans.c ends -------------- */
/* -------------- Usage example begins ------------- */
/* application specific includes */
#include "CPTrans.h"
/* global variables */
Frac16 cosphi,sinphi;
Frac16 Vuvw[3];
Frac16 Vab[2];
Frac16 Vdq[2];
Frac16 Vab1[2];
Frac16 Vuvw1[3];
/* Transform function calls */
//This example performs the full processing chain from three-phase fixed to
//two-phase rotating reference and back. In the end Vuvw and Vuvw1 should be
//equal save for rounding errors.
Clarke((Frac16*)&Vuvw,(Frac16*)&Vab);
Park(cosphi,sinphi,(Frac16*)&Vab,(Frac16*)&Vdq);
InvPark(cosphi,sinphi,(Frac16*)&Vdq,(Frac16*)&Vab1);
InvClarke((Frac16*)&Vab1,(Frac16*)&Vuvw1);
/* -------------- Usage example ends ------------- */