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.

TMS320F28069M: PWM outputs a wrong waveform when using TBPHS register

Part Number: TMS320F28069M


Hi

Our customer uses our automatic generated project and finds that PWM will make wrong output
when setting PWM.TBPHS. To locate wrong PWM period, we wrote a project to save data near
the wrong PWM period. The project is designed as follows:

1. CPU: F28069M (we test the project on LaunchPad F28069M)
2. PWM1 works at switching frequency 240KHz.
3. PWM2 has same setting with PWM1, plus phase shift 20 degrre to 160 degree.
4. System contrl frequency is 20KHz, so we use PWM8 as a timer to cause 20KHz interrupt.
5. GPIO3(PWM2.B) links to GPIO12, and system uses GPIO12 as external interrupt source
and it triggers interrupt at rising edge.
6. The duty cycle of PWM1 and PWM2 is 0.5.
7. System uses external interrupt routine to calculate the width of the rising edge. The regular
width is about 4.17us, system will keep 15 data in the wrong PWM period( array aryErr).
8. nGblTimes is the number of the wrong PWM periods (my test result is 3).
9. All wrong periods are caused when change PWM2.TBPHS from 93 to 95.

The PWM2.B's waveform near the wrong PWM period is as below:

The project can be reached at the following:

Please let me know how to avoid this problem.

Same error occurs on F28335, too. Perhaps F2803x and F2802x have the same problem.

thanks,

Jiakai

  • Jiakai,

    Does this phenomenon only occur for 1 period after the update to TBPHS?

    What happens if you increase the TBPHS above 95? Does is continue to cause the issue?

    What can trigger sync signals in your code?...Do you ever initiate a SWSYNC?


    Regards,
    Cody

  • Hi Cody,

    Yes, it only occurs for 1 period. it will occur again about 1000 PWM periods late.

    This program doesn't set ePWM2.TBCTL.SWFSYNC, it just uses EPWMxSYNCI signal.
    TBCTL's initialization code for phase shift is as follows:

    ePwm2.TBCTL.bit.PHSEN = TB_ENABLE;
    ePwm2.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;

    In interrupt routine Task(), PWM registers are updated as follows:
    ePwm1.CMPA.all = ePwm1.TBPRD.all >> 1;
    ePwm2.CMPA.all = ePwm2.TBPRD.all >> 1;
    ePwm2.TBPHS.all = ePwm2.TBPRD.all * phaseShift; // the range of phaseShift is 20/180 - 160/180
    ePwm2.TBCTL.bit.PHSDIR = 1;

    phaseShift increases from 20/180 to 160/180, then decreases from 160/180 to 20/180. then increase again.

    To check the wrong period with scope, please comment out the following 2 lines in function TaskS1(),
    // CopyTo();
    // __asm (" ESTOP0");

    To save data for analysis, please remove the comment marks in above 2 lines
    CopyTo();
    __asm (" ESTOP0");

    thanks
    Jiakai
  • Jiakai,

    What is the frequency of the SYNCI signal?

     

    I suspect that while increasing your TBPHS you caused the TBCTR to jump past the compare value which caused the PWM to not go low for an extended amount of time.

    What happens: The TB counter counts up almost to the compare value, then the PWM receives a sync signal increasing the value of the TB counter to a value greater than the compare value causing the PWM to miss the compare value and not go low for an entire cycle.

    Do you think this is your case?

    Regards,
    Cody 

  • Dear Cody,

    I think that causes the issue. Do you have any ways to avoid this?

    thanks,

    Jiakai

    PS: I am so sorry that I took a vacation so I didn't reply in time. 

  • Hi Jiakai,

    Can you please confirm the long pulse "always" happen while TBPHS change?
    You can try to set the CBU of AQCTLA to clear, my application is PSFB.
    EPWMx-> AQCTLA.bit.CBU = 1;

    Regards,
    Bard
  • Hi Bard,

    In my project, I use CMPA to set duty cycle, so ARCTLA and ARCTLB are set as follows:

    EPWM2.AQCTLA.bit.CAU = AQ_SET;
    EPWM2.AQCTLA.bit.CAD = AQ_CLEAR;
    EPWM2.AQCTLB.bit.CAU = AQ_CLEAR;
    EPWM2.AQCTLB.bit.CAD = AQ_SET;

    For CMPB, I usually use it to specify the interrupt position or trigger ADC position.

    So you think I could avoid the mistake if I use CMPB for PWM output action(see below):

    EPWM2.AQCTLA.bit.CBU = AQ_SET;
    EPWM2.AQCTLA.bit.CBD = AQ_CLEAR;
    EPWM2.AQCTLB.bit.CBU = AQ_CLEAR;
    EPWM2.AQCTLB.bit.CBD = AQ_SET;

    thanks

    Jiakai

  • Jiakai,

    one workaround I know of is to update CMPA to TBPHS+1 to force it to immediately trip, then set it to the correct value. The workarounds are discussed in this post.

    Regards,
    Cody 

  • Hi Cody,

    It works.

    We have also considered two other ways: one is similar to your method, set TBPHS to CMPA - 1, it works too.
    Another way is changing interrupt position, for example, now PWM interrupt position is set to the start position of PWM period,
    if we change it to the middle position of PWM period, TBPHS will be changed after the first CMPA matched. But to my surprise,
    this does work.

    thanks,
    Jiakai
  • Jiakai,

    Great! I am glad to here everything is working. It sounds like your second solution should work, I'll keep it in mind if I ever get the chance to test it.

    Regards,
    Cody

  • thank you very much!