DSPRelated.com
Code

Clarke and Park direct and inverse transforms

Carlo Concari November 18, 20101 comment Coded in Mixed C and ASM for the Freescale DSP56F8xx

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 ------------- */