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.

TMS320F28377S: ePWM software sync not working

Part Number: TMS320F28377S

Hi, we have an issue with software syncronization between 2 ePWM modules. We have initialized ePWM2 and ePWM3 with the following code:

// PWM2B, 1KHz
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBPRD = 50000;                // Set timer period, TBCLK / 50000 = 1ms --> 1kHz
EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;     // Phase is 0
EPwm2Regs.TBCTR = 0x0000;               // Clear counter
EPwm2Regs.CMPB.bit.CMPB = 25000;        // duty 50%
EPwm2Regs.AQCTLB.bit.PRD = AQ_SET;
EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;
EPwm2Regs.TBCTL2.bit.PRDLDSYNC = 2;
EPwm2Regs.CMPCTL.bit.LOADBSYNC = 2;

// PWM3A, 2KHz
EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_DOWN;
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm3Regs.TBPRD = 25000;                // Set timer period, TBCLK / 50000 = 1ms --> 1kHz
EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;     // Phase is 0
EPwm3Regs.TBCTR = 0x0000;               // Clear counter
EPwm3Regs.CMPA.bit.CMPA = 12500;        // duty 50%
EPwm3Regs.AQCTLA.bit.PRD = AQ_SET;
EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm3Regs.TBCTL2.bit.PRDLDSYNC = 2;
EPwm3Regs.CMPCTL.bit.LOADASYNC = 2;

At some point in our code, we need to update our frequency and duty cycle with software synconization mode. We issue the change of frequency and software syncronization like this:

EPwm2Regs.TBPRD = 25000;            // Set timer period ePWM2B
EPwm2Regs.CMPB.bit.CMPB = 12500;    // duty 50%
EPwm3Regs.TBPRD = 12000;            // Set timer period ePWM3A
EPwm3Regs.CMPA.bit.CMPA = 6000;     // duty 50%

EPwm2Regs.TBCTL.bit.SWFSYNC = 1;    // phase software syncronization

We expect that the PWM signal start from Period Value in each ePWM unit, but only the ePWM2 restart. ePWM3 continue with the same frequency.

Can anyone help us? What's wrong?

  • Hello,

    Have you tried setting the SWFSYNC bit for ePWM3 as you did for ePWM2?

    Elizabeth
  • Hi Massimo,

    I reviewed your settings and it appears you have set things up the proper way for the software SYNC to propagate from EPWM2 to EPWM3. It seems like the SYNCO is not being generated though based upon the EPWM3 behavior you described.

    EDIT: I'm suspecting the issue is with the SWFSYNC.  As a test, can you set the SYNCOSEL for EPWM2 to 0x1 instead of doing the SWFSYNC and see if EPWM3 syncs when EPWM2's TBCTR=0?  If another value of SYNCOSEL is more convenient you could use that as well.

    What is the frequency of EPWMCLK in your system (note this is not TBCLK, it is SYSCLK/EPWMCLKDIV)?


    Regards,
    Kris

  • Thak you for your reply.

    Yes, we tried to sync both unit and it works fine. We are using this method for our purpose, but we would like to know why the first method doesn't work.

  • We test this option and seems it works: ePWM3 waveform restart when ePWM2's TBCTR=0. Our EPWMCLK is 100 MHz.
  • Massimo,

    I'm using your exact code and I'm seeing the SWFSYNC is working.

    How are you checking this on your device?  I am seeing that if I single step the SWFSYNC instruction or write the SWFSYNC in the Expressions Window that it does not take effect.  I right clicked and did a "Move to line" on the SWFSYNC instruction then set a breakpoint at the end of some NOPs and saw that it executed successfully.

    I do not have an oscilloscope with me, so my verification method was to modify the TBCTR on EPWM3 to something far out of sync and verify that the counter was back in sync after executing the following.

    EPwm2Regs.TBCTL.bit.SWFSYNC = 1;    // Move to line
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");    // Set breakpoint

    Regards,

    Kris