This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DRV8312-C2-KIT Sensorless Reverse Commutation

Other Parts Discussed in Thread: INSTASPIN-BLDC

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

  • I haven't run this code in many years...but did you first just try changing the speed reference to a (-) value?
    I know the InstaSPIN-BLDC project works from -1.0 to 1.0 per unit, crossing through 0 (assuming your power supply can source the current required for the deceleration)

    notice that this project uses
    mod6_cnt_dir.h

    which includes a direction bit. you may want to look at using this version of the MOD6.
  • Chris,

    I did try the (-) value for the speedRef without any luck. I remember building another code example where this worked and I had hoped it would do the same. Thanks for pointing out the mod6_cnt_dir.h. I will take a look at that and hopefully it will solve my problems. Thanks