I am attempting to modify the DRV8312-C2-KIT BLDC_Sensorless example code to drive the BLDC motor included in the kit in the reverse direction.
I went through the PDF included in the docs section and was successfully able to go through build levels 1-7 with the motor spinning in the clockwise direction. Now I want to use the software to drive the motor in the counter clockwise direction. I did a search on this forum/google and found multiple examples of the same question. In each the suggestion was to change the commutation order. So I made a table of the commutation order based on the code in f2803xbldcpwm_BLDC.h. The order is as follows: A->B, A->C, B->C, B->A, C->a, C->B. As I understand it to change the direction I swap two of the phases and my new commutation becomes: A->C, A->B, C->B, C->A, B->A, B->C. (I swapped B and C phases).
Now to test the motor I build it using LEVEL2 which runs the motor in open loop. The motor runs CCW just as it did with the default code. Ok so now I want to use the closed speed loop and speed PI controller in build LEVEL7. Looking at the system block diagram I see that CmtnPointer feeds into the BLDC PWM DRV and COMTN_TRIG Macro. I have already modified the BLDC PWM DRV block by changing the code in f2803xbldcpwm_BLDC.h. To use the bemf feedback correctly I believe I need to modify the COMTN_TRIG macro. I found the instances of the variable CmtnPointer in the file com_trig.h and modified the order to follow the commutation order. I rebuild the project and go into debug mode but the motor will not spin. It starts moving and then errors out. Am I missing something? Am I modifying the right code?
Below is the code as I have modified it
(Lines 201, 217, 233, 249, 265, 281 in f2803xbldcpwm.h and lines 87, 97, 107, 117, 127, 139 in com_tring.h)
/* ================================================================================== File name: F2803XBLDCPWM.H Originator: Digital Control Systems Group Texas Instruments Description: Header file containing data type and object definitions and initializers. Also contains prototypes for the functions in F280XBLDCPWM.C. Target: TMS320F2803x family ===================================================================================== History: ------------------------------------------------------------------------------------- 03-09-2011 Version 1.0: ------------------------------------------------------------------------------------*/ #ifndef __F2803X_BLDCPWM_H__ #define __F2803X_BLDCPWM_H__ #include "f2803xbmsk.h" #include "PeripheralHeaderIncludes.h" /*---------------------------------------------------------------------------- Initialization constant for the F280X Time-Base Control Registers for PWM Generation. Sets up the timer to run free upon emulation suspend, count up mode prescaler 1. ----------------------------------------------------------------------------*/ #define BLDCPWM_INIT_STATE ( FREE_RUN_FLAG + \ PRDLD_IMMEDIATE + \ TIMER_CNT_UP + \ HSPCLKDIV_PRESCALE_X_1 + \ CLKDIV_PRESCALE_X_1 + \ PHSDIR_CNT_UP + \ CNTLD_DISABLE ) /*---------------------------------------------------------------------------- Initialization constant for the F280X Compare Control Register. ----------------------------------------------------------------------------*/ #define BLDCPWM_CMPCTL_INIT_STATE ( LOADAMODE_ZRO + \ LOADBMODE_ZRO + \ SHDWAMODE_SHADOW + \ SHDWBMODE_SHADOW ) /*---------------------------------------------------------------------------- Initialization constant for the F280X Action Qualifier Output A Register. ----------------------------------------------------------------------------*/ #define BLDCPWM_AQCTLA_INIT_STATE CAU_SET /*---------------------------------------------------------------------------- Initialization constant for the F280X Dead-Band Control Generator register. ----------------------------------------------------------------------------*/ #define BLDCPWM_DBCTL_INIT_STATE BP_DISABLE /*---------------------------------------------------------------------------- Initialization constant for the F280X PWM Chopper Control register for PWM Generation. ----------------------------------------------------------------------------*/ #define BLDCPWM_PCCTL_INIT_STATE CHPEN_DISABLE /*---------------------------------------------------------------------------- Initialization constant for the F280X Trip Zone Select Register ----------------------------------------------------------------------------*/ #define BLDCPWM_TZSEL_INIT_STATE DISABLE_TZSEL /*----------------------------------------------------------------------------- Define the structure of the PWM Driver Object -----------------------------------------------------------------------------*/ typedef struct { Uint16 CmtnPointer; // Input: Commutation (or switching) state pointer input (Q0) int16 MfuncPeriod; // Input: Duty ratio of the PWM outputs (Q15) Uint16 PeriodMax; // Parameter: Maximum period (Q0) int16 DutyFunc; // Input: PWM period modulation input (Q15) Uint16 PwmActive; // Parameter: 0 = PWM active low, 1 = PWM active high (0 or 1) } PWMGEN; /* The "PwmActive" setting depends on Power devices. when PwmActive = 1 (active high) implies the power device turns ON with a HIGH gate signal. PwmActive = 0 (active low) implies the power device turns ON with a LOW gate signal. */ /*----------------------------------------------------------------------------- Define a PWMGEN_handle -----------------------------------------------------------------------------*/ typedef PWMGEN *PWMGEN_handle; /*------------------------------------------------------------------------------ Default Initializers for the F281X PWMGEN Object ------------------------------------------------------------------------------*/ #define F2803X_BLDC_PWM_GEN {0x0000, \ 0x7FFF, \ 0x1D4C, \ 0x0000, \ 0x0001, \ } #define PWMGEN_DEFAULTS F2803X_BLDC_PWM_GEN /*------------------------------------------------------------------------------ F280XBLDCPWM Macro Definitions ------------------------------------------------------------------------------*/ #define BLDCPWM_INIT_MACRO(v) \ /* Setup Sync*/ \ EPwm1Regs.TBCTL.bit.SYNCOSEL = 0; \ EPwm2Regs.TBCTL.bit.SYNCOSEL = 0; \ EPwm3Regs.TBCTL.bit.SYNCOSEL = 0; \ EPwm4Regs.TBCTL.bit.SYNCOSEL = 0; \ EPwm5Regs.TBCTL.bit.SYNCOSEL = 0; \ EPwm6Regs.TBCTL.bit.SYNCOSEL = 0; \ \ /* Allow each timer to be sync'ed*/ \ EPwm1Regs.TBCTL.bit.PHSEN = 1; \ EPwm2Regs.TBCTL.bit.PHSEN = 1; \ EPwm3Regs.TBCTL.bit.PHSEN = 1; \ EPwm4Regs.TBCTL.bit.PHSEN = 1; \ EPwm5Regs.TBCTL.bit.PHSEN = 1; \ EPwm6Regs.TBCTL.bit.PHSEN = 1; \ \ /* Init Timer-Base Period Register for EPWM1-EPWM3*/ \ EPwm1Regs.TBPRD = v.PeriodMax; \ EPwm2Regs.TBPRD = v.PeriodMax; \ EPwm3Regs.TBPRD = v.PeriodMax; \ \ /* Init Timer-Base Phase Register for EPWM1-EPWM3*/ \ EPwm1Regs.TBPHS.half.TBPHS = 0; \ EPwm2Regs.TBPHS.half.TBPHS = 0; \ EPwm3Regs.TBPHS.half.TBPHS = 0; \ \ /* Init Timer-Base Control Register for EPWM1-EPWM3*/ \ EPwm1Regs.TBCTL.all = BLDCPWM_INIT_STATE; \ EPwm2Regs.TBCTL.all = BLDCPWM_INIT_STATE; \ EPwm3Regs.TBCTL.all = BLDCPWM_INIT_STATE; \ \ /* Init Compare Control Register for EPWM1-EPWM3 */ \ EPwm1Regs.CMPCTL.all = BLDCPWM_CMPCTL_INIT_STATE; \ EPwm2Regs.CMPCTL.all = BLDCPWM_CMPCTL_INIT_STATE; \ EPwm3Regs.CMPCTL.all = BLDCPWM_CMPCTL_INIT_STATE; \ \ /* Init Action Qualifier Output A Register for EPWM1-EPWM3*/ \ EPwm1Regs.AQCTLA.all = BLDCPWM_AQCTLA_INIT_STATE; \ EPwm2Regs.AQCTLA.all = BLDCPWM_AQCTLA_INIT_STATE; \ EPwm3Regs.AQCTLA.all = BLDCPWM_AQCTLA_INIT_STATE; \ \ /* Init Dead-Band Generator Control Register for EPWM1-EPWM3*/ \ EPwm1Regs.DBCTL.all = BLDCPWM_DBCTL_INIT_STATE; \ EPwm2Regs.DBCTL.all = BLDCPWM_DBCTL_INIT_STATE; \ EPwm3Regs.DBCTL.all = BLDCPWM_DBCTL_INIT_STATE; \ \ /* Init PWM Chopper Control Register for EPWM1-EPWM3*/ \ EPwm1Regs.PCCTL.all = BLDCPWM_PCCTL_INIT_STATE; \ EPwm2Regs.PCCTL.all = BLDCPWM_PCCTL_INIT_STATE; \ EPwm3Regs.PCCTL.all = BLDCPWM_PCCTL_INIT_STATE; \ \ EALLOW; /* Enable EALLOW */ \ \ \ /* Setting six EPWM as primary output pins*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; /* EPWM1A pin*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; /* EPWM1B pin*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; /* EPWM2A pin*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; /* EPWM2B pin*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; /* EPWM3A pin*/ \ GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; /* EPWM3B pin*/ \ \ EDIS; /* Disable EALLOW*/ int32 Tmp,Tmp2; int16 Period, GPR0_BLDC_PWM; int16 CMPB_SMPL_POINT; #define BLDCPWM_MACRO(v) /* */\ /* Convert "Period" (Q15) modulation function to Q0 */\ Tmp = (int32)v.PeriodMax*(int32)v.MfuncPeriod; /* Q15 = Q0xQ15 */\ Period = (int16)(Tmp>>15); /* Q15 -> Q0 (Period) */\ /* */\ /* Check PwmActive setting */\ if (v.PwmActive==1) /* PWM active high */\ { /* */\ GPR0_BLDC_PWM = 0x7FFF - v.DutyFunc; /* */\ CMPB_SMPL_POINT = 0x7FFF - (v.DutyFunc >> 1); /* Sample in center of PWM pulse using CMPB */\ } /* */\ /* */\ else if (v.PwmActive==0) /* PWM active low */\ { /* */\ GPR0_BLDC_PWM = v.DutyFunc; /* */\ CMPB_SMPL_POINT = v.DutyFunc >> 1; /* Sample in center of PWM pulse using CMPB */\ } /* */\ /* */\ /* Convert "DutyFunc" or "GPR0_BLDC_PWM" (Q15) duty modulation function to Q0 */\ Tmp = (int32)Period*(int32)GPR0_BLDC_PWM; /* Q15 = Q0xQ15 */\ Tmp2 = (int32)Period*(int32)CMPB_SMPL_POINT; /* Q15 = Q0xQ15 */\ EPwm1Regs.CMPB = (int16)(Tmp2>>15); /* Sample in center of PWM pulse using CMPB */\ /* */\ /* State s1: current flows to motor windings from phase A->B, de-energized phase = C */\ if (v.CmtnPointer==1) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabled on output B of EPWM1 */\ EPwm1Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm1Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm1Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM1 (Q15 -> Q0) */\ EPwm1Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM2 */\ EPwm2Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */\ EPwm3Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */\ } /* */\ /* */\ /* State s2: current flows to motor windings from phase A->C, de-energized phase = B */\ else if (v.CmtnPointer==0) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabledd on output B of EPWM1 */\ EPwm1Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm1Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm1Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM1 (Q15 -> Q0) */\ EPwm1Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM2 */\ EPwm2Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */\ EPwm3Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM3 */\ } /* */\ /* */\ /* State s3: current flows to motor windings from phase B->C, de-energized phase = A */\ else if (v.CmtnPointer==5) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM1 */\ EPwm1Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabled on output B of EPWM2 */\ EPwm2Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm2Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm2Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM2 (Q15 -> Q0) */\ EPwm2Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */\ EPwm3Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM3 */\ } /* */\ /* */\ /* State s4: current flows to motor windings from phase B->A, de-energized phase = C */\ else if (v.CmtnPointer==4) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM1 */\ EPwm1Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabled on output B of EPWM2 */\ EPwm2Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm2Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm2Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM2 (Q15 -> Q0) */\ EPwm2Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */\ EPwm3Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */\ } /* */\ /* */\ /* State s5: current flows to motor windings from phase C->A, de-energized phase = B */\ else if (v.CmtnPointer==3) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM1 */\ EPwm1Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM2 */\ EPwm2Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabled on output B of EPWM3 */\ EPwm3Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm3Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm3Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM3 (Q15 -> Q0) */\ EPwm3Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM3 */\ } /* */\ /* */\ /* State s6: current flows to motor windings from phase C->B, de-energized phase = A */\ else if (v.CmtnPointer==2) /* */\ { /* */\ EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM1 */\ EPwm1Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM1 */\ /* */\ EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM2 */\ EPwm2Regs.AQCSFRC.bit.CSFB = 2; /* Forcing a continuous High on output B of EPWM2 */\ /* */\ EPwm3Regs.AQCSFRC.bit.CSFB = 0; /* Forcing disabled on output B of EPWM3 */\ EPwm3Regs.AQCTLB.bit.CAU = 2; /* Set high when CTR = CMPA on UP-count */\ EPwm3Regs.AQCTLB.bit.ZRO = 1; /* Set low when CTR = Zero */\ EPwm3Regs.CMPA.half.CMPA = (int16)(Tmp>>15); /* PWM signal on output B of EPWM3 (Q15 -> Q0) */\ EPwm3Regs.AQCSFRC.bit.CSFA = 2; /* Forcing a continuous High on output A of EPWM3 */\ } #endif // __F2803X_BLDCPWM_H__
/* ================================================================================= File name: COM_TRIG.H (IQ version) Originator: Digital Control Systems Group Texas Instruments Description: Header file containing constants, data type definitions, and function prototypes for the CMTN. ===================================================================================== History: ------------------------------------------------------------------------------------- 03-01-2010 Version 1.0 ------------------------------------------------------------------------------*/ #include "PeripheralHeaderIncludes.h" typedef struct { Uint32 CmtnTrig; // Output: Commutation trigger output (0 or 0x00007FFF) _iq Va; // Input: Motor phase a voltage referenced to GND (pu) _iq Vb; // Input: Motor phase b voltage referenced to GND (pu) _iq Vc; // Input: Motor phase c voltage referenced to GND (pu) _iq Neutral; // Variable: 3*Motor netural voltage (pu) Uint32 RevPeriod; // Variable: revolution time counter (Q0) Uint32 ZcTrig; // Variable: Zero-Crossing trig flag (0 or 0x00007FFF) Uint32 CmtnPointer; // Input: Commutation state pointer input (0,1,2,3,4,5) _iq DebugBemf; // Variable: 3*Back EMF = 3*(vx=vn), x=a,b,c (pu) Uint32 NoiseWindowCounter;// Variable: Noise windows counter (Q0) Uint32 Delay30DoneFlag; // Variable: 30 Deg delay flag (0 or 0x0000000F) Uint32 NewTimeStamp; // Variable: Time stamp (Q0) Uint32 OldTimeStamp; // History: Previous time stamp (Q0) Uint32 VirtualTimer; // Input: Virtual timer (Q0) Uint32 CmtnDelay; // Variable: Time delay in terms of number of sampling time periods (Q0) Uint32 DelayTaskPointer; // Variable: Delay task pointer, see note below (0 or 1) Uint32 NoiseWindowMax; // Variable: Maximum noise windows counter (Q0) Uint32 CmtnDelayCounter; // Variable: Time delay counter (Q0) Uint32 NWDelta; // Variable: Noise windows delta (Q0) Uint32 NWDelayThres; // Variable: Noise windows dynamic threshold (Q0) } CMTN; /* Note: DelayTaskPointer = 0, branch for #COUNT_DWN DelayTaskPointer = 1, branch for #CHK_TRIGGER */ typedef CMTN *CMTN_handle; /*----------------------------------------------------------------------------- Default initalizer for the CMTN object. -----------------------------------------------------------------------------*/ #define CMTN_DEFAULTS { 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 0, \ 1, \ 0, \ 0, \ 0, \ 0, \ } /*---------------------------------------------------------------------------------------------- CMTN_TRIG Macro Definition ----------------------------------------------------------------------------------------------*/ #define CMTN_TRIG_MACRO(v) \ \ /* Always clear flags on entry*/ \ v.CmtnTrig = 0; \ v.ZcTrig = 0; \ \ /* Neutral voltage calculation (3*motor Neutral voltage)*/ \ v.Neutral = v.Va + v.Vb + v.Vc; \ \ /* Commutation State table Tasks*/ \ /* State s1: current flows to motor windings from phase A->B, de-energized phase = C*/ \ if (v.CmtnPointer == 1) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral; \ if (v.DebugBemf > 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing*/ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s1*/ \ \ /* State s2: current flows to motor windings from phase A->C, de-energized phase = B*/ \ else if (v.CmtnPointer == 0) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral; \ if (v.DebugBemf < 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing*/ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s2*/ \ \ /* State s3: current flows to motor windings from phase B->C, de-energized phase = A*/ \ else if (v.CmtnPointer == 5) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral; \ if (v.DebugBemf > 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing*/ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s3*/ \ \ /* State s4: current flows to motor windings from phase B->A, de-energized phase = C*/ \ else if (v.CmtnPointer == 4) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Vc) - v.Neutral; \ if (v.DebugBemf < 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing*/ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s4*/ \ \ /* State s5: current flows to motor windings from phase C->A, de-energized phase = B*/ \ else if (v.CmtnPointer == 3) \ { \ v.Delay30DoneFlag = 0; /* clear flag for delay calc in State 5*/ \ \ v.DebugBemf = _IQmpy(_IQ(3),v.Vb) - v.Neutral; \ if (v.DebugBemf > 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing */ \ NOISE_WINDOW_CNT_MACRO(v); \ } /* else if-end: State s5 */ \ \ /* State s6: current flows to motor windings from phase C->B, de-energized phase = A*/ \ else if (v.CmtnPointer == 2) \ { \ v.DebugBemf = _IQmpy(_IQ(3),v.Va) - v.Neutral; \ if (v.DebugBemf < 0) \ v.NoiseWindowCounter = 0; \ else /* Zero crossing Noise window processing*/ \ NOISE_WINDOW_CNT_MACRO(v); \ DELAY_30DEG_MACRO(v); \ } /* else if-end: State s6*/ \ \ /* Zero crossing to Commutation trigger delay*/ \ v.CmtnTrig = 0; /* Always clear flag on entry */ \ \ if (v.DelayTaskPointer > 0) /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/ \ { \ if (v.ZcTrig != 0) \ { \ /* Substract NoiseWindowMax to compensate the advanced zero-crossing validation point */ \ v.CmtnDelayCounter = v.CmtnDelay - v.NoiseWindowMax; \ v.DelayTaskPointer = 0; /* v.DelayTaskPointer = 0 for #COUNT_DWN*/ \ } \ } \ else /* v.DelayTaskPointer = 0 for #COUNT_DWN */ \ { \ v.CmtnDelayCounter -= 1; \ if (v.CmtnDelayCounter == 0) \ { \ v.CmtnTrig = 0x00007FFF; /* Yes!- Set trigger. This is used */ \ /* as an input to "MOD6_CNTR" module that changes the commutation sequence.*/ \ \ v.DelayTaskPointer = 1; /* v.DelayTaskPointer = 1 for #CHK_TRIGGER*/ \ } \ } /*---------------------------------------------------------------------------------------------- NOISE_WINDOW_CNT Macro Definition ----------------------------------------------------------------------------------------------*/ #define NOISE_WINDOW_CNT_MACRO(v) \ if (v.CmtnDelay >= v.NWDelayThres) /* noise window is fixed Value*/ \ v.NoiseWindowMax = v.NWDelayThres - v.NWDelta; \ else /* noise window adjusted dynamically*/ \ v.NoiseWindowMax = v.CmtnDelay - v.NWDelta; \ \ v.NoiseWindowCounter += 1; \ \ if (v.NoiseWindowCounter == v.NoiseWindowMax) /* zc must occur max_noise_window times*/ \ { \ v.ZcTrig = 0x00007FFF; /* Yes! Set trigger */ \ v.NoiseWindowCounter = 0; \ } /*---------------------------------------------------------------------------------------------- DELAY_30DEG Macro Definition ----------------------------------------------------------------------------------------------*/ int32 Tmp, GPR1_COM_TRIG; #define DELAY_30DEG_MACRO(v) \ /* Delay 30 deg calculator*/ \ if (v.Delay30DoneFlag == 0) \ { \ v.OldTimeStamp = v.NewTimeStamp; \ v.NewTimeStamp = v.VirtualTimer; \ Tmp = v.NewTimeStamp - v.OldTimeStamp; \ \ if (Tmp > 0) /* Period = NewTimeStamp - OldTimeStamp*/ \ v.RevPeriod = Tmp; \ else /* If Period is negative, allow "wrapping" */ \ v.RevPeriod = 0x00007FFF + Tmp; \ \ v.RevPeriod &= 0x0000FFFF; \ \ v.CmtnDelay = v.RevPeriod/12; /* Division quotient*/ \ GPR1_COM_TRIG = v.RevPeriod - v.CmtnDelay*12; /* Division reminder*/ \ if (GPR1_COM_TRIG >= 6) \ v.CmtnDelay += 1; /* if Division reminder >= 6, rounding division quotient*/ \ v.Delay30DoneFlag = 0x0000000F; /* flag indicates "gone through" once*/ \ } /* if-end: v.Delay30DoneFlag == 0*/