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 motor control bugs in BLDC_Sensored example?

Other Parts Discussed in Thread: DRV8312, CONTROLSUITE, DRV8301

 

I'm working with the BLDC_Sensored example for the DRV8312 kit.  Here's some code from "f2803xbldcpwm_BLDC.h".  It looks like it has multiple bugs (unless I'm missing something).

1. Why is "EPwm1Regs.CMPB = (int16)(Tmp2>>15)" always set for all commutation states?

2. Why is "EPwm1Regs.CMPA.half.CMPA = (int16)(Tmp>>15)" when the next statement forces output A high?

3. Why is "CMPB_SMPL_POINT" important?  The motor control code in the "C:\ti\controlSUITE\libs\app_libs\motor_control\drivers\f2803x_v2.0\f2803xbldcpwm.h" file doesn't use this technique.

4. Is the DRV8312 board configured to drive the PWM signal on output B (for all commutation states)?  The motor control code uses output A.

5. When PWM is "active high", do you need to invert forced outputs (change from "force low" to "force high", etc)?

6. Why does this example work at all?

 

 #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==0)\
    {\
        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 */\
    }\
    ...

  • Jerry,

    Moving this to C2000 forum and the team will comment.

  • Jerry,

    1. Why is "EPwm1Regs.CMPB = (int16)(Tmp2>>15)" always set for all commutation states?

    The CMPB event is always used to set the sample point for the motor current at the center of the PWM on-time. 

    2. Why is "EPwm1Regs.CMPA.half.CMPA = (int16)(Tmp>>15)" when the next statement forces output A high?

    The CMPA event triggers a change in the state of the EPWM1 ‘B’ output not the ‘A’ output.  So, the ‘B’ output is PWM’d while the ‘A’ output is forced high. 

    3. Why is "CMPB_SMPL_POINT" important?  The motor control code in the "C:\ti\controlSUITE\libs\app_libs\motor_control\drivers\f2803x_v2.0\f2803xbldcpwm.h" file doesn't use this technique.

    I believe there was a mistake in the motor current sampling strategy from previous BLDC sensored projects.  The DRV8312 project was based on sensored BLDC project from the Hvkit.  In the Hvkit project the ADC SOC was generated on a PRD match event.  At the PRD match event the PWM was also in the process of transitioning from high to low so the ADC motor current sample was being taken during a PWM transition.  I changed the sampling strategy for the DRV8301 to use the CMPB event to sample in the center of the PWM on-time. 

    4. Is the DRV8312 board configured to drive the PWM signal on output B (for all commutation states)?  The motor control code uses output A.

    As stated in 2 above the ‘B’ output is configured to use the CMPA event to generate a PWM.  The ‘A’ output is always forced high for the active phase.  This configuration was used in order to mimic the PWM strategy of the Hvkit BLDC sensored example.  On the Hvkit only the high-side device is PWM’d while the low-side of the same phase is held in the off state.  On a second phase the low-side device is held in a continuous on state to allow current to flow.  During the off time of the PWM’d phase the current recirculates through the diodes built into the IGBTs.  The DRV8301 only has one PWM signal per phase so we don’t have direct access to the high and low side devices.  In order to recreate the PWM strategy from the Hvkit we had to PWM the RESETn signal while holding the PWM input high.  This gave the same effect  as PWMing to high side only.

    5. When PWM is "active high", do you need to invert forced outputs (change from "force low" to "force high", etc)?

    Hmmm…maybe.  The PwmActive functionality probably should have been stripped out since this example was written specifically for the DRV8312

    6. Why does this example work at all?

    I think the main source of confusion was centered around CMPA event being used to drive the ‘B’ output.  With that cleared up it should be more clear.