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.

TMS320F28P650DK: Latency observed in two PWM

Part Number: TMS320F28P650DK
Other Parts Discussed in Thread: SYSCONFIG, C2000WARE

Hi,

MCU operating clock frequency is 120MHz with 20MHz occilator.

 I am using EPWM1 & EPWM2 but i am seing approx 84ns phase shift between this two PWM.

Output and PWM initialization i have shared for referance, 

How to make this phase shift ZERO ? Can you please guide us.

image.png

here is what my initialization.

Initialization( )

{

    EPWM1init( );
    EPWM2init( );

    HWREGH(myEPWM1_BASE + EPWM_O_TBCTL) =
            ((HWREGH(myEPWM1_BASE + EPWM_O_TBCTL) & ~(EPWM_TBCTL_CTRMODE_M)) |
             ((uint16_t)EPWM_COUNTER_MODE_UP));

    HWREGH(myEPWM2_BASE + EPWM_O_TBCTL) =
            ((HWREGH(myEPWM2_BASE + EPWM_O_TBCTL) & ~(EPWM_TBCTL_CTRMODE_M)) |
             ((uint16_t)EPWM_COUNTER_MODE_UP));

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

}

void EPWM1init( void )
{
    EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setTimeBasePeriod(myEPWM1_BASE, 0);
    EPWM_setTimeBaseCounter(myEPWM1_BASE, 0);
    EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
    EPWM_enablePhaseShiftLoad(myEPWM1_BASE);
    EPWM_setPhaseShift(myEPWM1_BASE, 0);

    EPWM_disableCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A);
    EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 83);

    EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_HIGH,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_LOW,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

    EPWM_setPeriodLoadMode(myEPWM1_BASE, EPWM_PERIOD_DIRECT_LOAD);
    PRD_CLK_GRID = PRD_CLK_GRID_CH;
    EPWM_setTimeBasePeriod(myEPWM1_BASE, PRD_CLK_GRID - 1);
    EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);

}

void EPWM2init( void )
{
    EPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setTimeBasePeriod(myEPWM2_BASE, 0);
    EPWM_setTimeBaseCounter(myEPWM2_BASE, 0);
    EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
    EPWM_setPhaseShift(myEPWM2_BASE, 0);

    EPWM_disableCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A);
    EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, 83);

    EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_LOW,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_HIGH,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

    EPWM_setPeriodLoadMode(myEPWM2_BASE, EPWM_PERIOD_DIRECT_LOAD);
    PRD_CLK_GRID = PRD_CLK_GRID_CH;
    EPWM_setTimeBasePeriod(myEPWM2_BASE, PRD_CLK_GRID - 1);
    EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);

}

 

Regards,

Bhavin P

 

  • Bhavin,

    There are three things need to be addressed here, I would recommend fix those

    1. Before initialization or configuration of ePWM, use the following sequence 

    first SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); //freeze TBCLK

    then do ePWM configuration;

    after that only do SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // Run TBCLK

    This way it will be synchronized properly.

    2. Another thing I noticed is that you don't have syncout and syncin configured.

    if syncout is ePWM1 then this can be configured as follows

    EPWM_enableSyncOutPulseSource(myEPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
     
    syncin can be configured on ePWM2 as follows
    EPWM_setSyncInPulseSource(myEPWM2_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
    3. Also, there is 1~2 TBCLK static delay you need to account for as shown in TRM section as follows:
    This can be done in this case in ePWM2 --> EPWM_setPhaseShift(myEPWM2_BASE, 2); // in your code this is '0'
    Let me know if this fixes the issue.
    Regards,
    Sumit
  • Thanks  Sumit,

    Meanwhile, could you clarify the following for me?

    1. If I use a single PWM module, for example EPWM1, which has two outputs (channels A & B),

      • Can we generate PWM signals with different duty cycles on these two channels?
      • Is it possible to achieve zero latency between these two PWM signals?
    2. If the answer is yes, could you share the configuration details for this setup?

    3. Additionally, I would like the default output state to be HIGH after PWM initialization, but the PWM should start only upon a specific event trigger. Is this achievable?

    Regards,

    Bhavin P

  • 1. Here is the response regarding independent duty control on A and B

    • If you want EPWM1's channel A and channel B to be operated with different duty cycle then you can use CMPA and CMPB two events for each to adjust duty for each and bypass dead band module.
    • There won't be any latency if you use up count mode since its edge aligned PWM mode and its part of same ePWM module

    2. I am attaching sysconfig based example project which is modified from C2000ware's "epwm_ex13_up_aq" example which has sysconfig gui which makes this. ePWM1 is setup on this. You can change compAVal in expression window to change duty of A and and compAVal for duty of B.

     3005.epwm_ex13_up_aq.zip

    3. I have setup this in file above: In action qualifier setting you can set zero count high and compare event low

    Let me know if any issue or question on this

    Regards,

    Sumit

  • HI Sumit,

    Great, things are working fine now. However, I have one more specific requirement, and I’m not sure if it can be achieved through the PWM driver. Please refer to the attached signal diagram.

    Requirement:

    1. At power‑up, the frequency should start at 75 kHz up to pulse number 8, where Channel‑A and Channel‑B are exact complements of each other
      (Pulse #1 is not shown in the figure, but it exists).

    2. Starting from pulse number 8, Channel‑A must switch from 75 kHz to 13 kHz.

    3. For Channel‑B, the transition is not identical to Channel‑A. There is a delay before Channel‑B starts its PWM at 13 kHz.
      The amount of delay corresponds exactly to the toggle point of pulse #8 on Channel‑A, as shown in the diagram (blue text).

    4. After the transition, Channel‑B follows a different duty cycle.

    What i am able to execute successfully is 

    1. Chan-A transition from 75KHz to 13KHz
    2. Not able to achieve delay required for channel - B

    Can you suggest can we achive this requirement through EPWM driver using Chan-A & B here ? If yes then exactly how to transit can you guide ?

    What I am currently able to achieve is:

    • Channel‑A transitions correctly from 75 kHz to 13 kHz.
    • I am not able to generate the required delay on Channel‑B but transition achieved on Chan- B 

    Could you please advise whether this requirement can be achieved using the EPWM driver with Channel‑A and Channel‑B?
    If yes, could you guide me on the exact method or sequence needed to perform this transition?

    Regards,

    Bhavin P

  • Bhavin,

    Looks like you need to use Global load feature to make sure that both values are loading from shadow to active only when both shadow value writing is completed and no partial values remain. Please do following two steps.

    1. You can edit the following in the syscofig to enable global load.

    2. Also, use following API in ISR just after update is complete to indicate that all shadow writing is finish and now values are ready to transfer from shadow to active in next shadow to active event (TBCTR = zero in this case)

    You can also refer the following example for global load use case: C:\ti\c2000\C2000Ware_6_00_00_00\driverlib\f28p65x\examples\c28x\epwm\CCS

    Let me know if this resolves your delay issue.

    Regards,

    Sumit