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.

TMS320F28069: Frequency change during runtime on 3 phase-shifted ePWMs

Part Number: TMS320F28069


Hello,

I have a solution which uses 3 ePWM modules to generate 3 PWM signals with same frequency and same duty cycle. The ePWM modules are configured to be phase-shifted to each other in the following way:

  • ePWM8 has no phase shift relative to main synchronization
  • ePWM6 has 8 sysclocks phase shift relative to ePWM8
  • ePWM4 has 16 sysclocks phase shift relative to ePWM6

ePWM8 is configured has high-resolution.

Rest of the configuration for all 3 ePWM modules is the same. The only difference is the phase as described above.

EPwmxRegs.TBPRD = 224U;
EPwmxRegs.CMPB = 112U;
EPwmxRegs.TBPHS.half.TBPHS = phase;

EPwmxRegs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwmxRegs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwmxRegs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwmxRegs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwmxRegs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwmxRegs.TBCTL.bit.CLKDIV = TB_DIV1;

EPwmxRegs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwmxRegs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwmxRegs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;
EPwmxRegs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;

EPwmxRegs.AQCTLB.bit.ZRO = AQ_SET;
EPwmxRegs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwmxRegs.AQCTLB.bit.PRD = AQ_NO_ACTION;

During normal operation, everything is working excellent. However, my intention is to change the frequency and duty-cycle during runtime. For this I am using an ISR triggered when ePWM4 TBCTR == 0. Within the ISR, I am changing values of TBPRD and CMPB of all ePWM modules. With the phase-shift disabled, the functionality is working well - I can see the frequency changing for all 3 signals. However, if I enable the phase-shift, then I see 100% duty cycle on ePWM8, for ePWM4 and ePWM6 the frequency remains constant at ~401kHz as defined with the initial configuration.

As far as I understood from the initial reply, changing the frequency should be as simple as changing TBPRD value within the period also when the phase shift is enabled.
I also tried different triggers for the ISR, such as TBCTR == 0, TBCTR == PRD with both ePWM6 and ePWM8.

Do you have any idea what might be wrong? Any kind of support would be appreciated.

Looking forward to your reply and thanks in advance!

Regards,
Lev

  • Lev,

    what I typically see users do is updating the TBPHS register with a value larger than one of the CMPx events. Please note that the CMPx events only happen on an exact TBCTR match. If you apply a phase shift of 100 and your CMPx event is supposed to occur at 90 then when your TBCTR jumps from 0 to 100 it will skip over the CMPx event of 90. That means that the event will not occur because, as stated before, this is an exact match(TBCTR=CMPx), it is not a greater than(TBCTR=>CMPx) comparison. This usually only happens the first cycle after you change your phase, if you change the phase again it could happen again.

    Please note that the PWM sync chain is not high-resolution, so you may see some small jitter each time you send a sync pulse between a non-HR PWM and your HR channel. (the HR channel is simply put higher precision than the sync path)

    Let me know if this is your issue.


    Regards,
    Cody 

  • Cody,

    Thanks for your reply.

    Value of TBPHS is set only once during the initialization for each ePWM and is not changed afterwards during runtime. Following values are used for TBPHS during initialization:

    EPwm4Regs.TBPHS.half.TBPHS = 16U;
    EPwm6Regs.TBPHS.half.TBPHS = 8U;
    EPwm8Regs.TBPHS.half.TBPHS = 0U;

    CMPB and TBPRD values are intended to be changed during runtime within an ISR. Value range for CMPB is 109...116 and for TBPRD 218...232. As you might see our intention is to keep 50% duty cycle all the time during runtime.

    Based on this information I am afraid the problem is in something else as TBPHS value can never become larger than CMPB value.

    Note: CMPA is not used in the solution.

    Regards,
    Lev

  • I have made some further experiments and can give a bit further information.

    If I configure TBPHS.half.TBPHS = 0U for all ePWMs and keep TBCTL.bit.PHSEN = TB_ENABLE, then as a result I see all 3 signals available, but with constant frequency (that was set during initialization).

    Note: the signal on ePWM8 was missing if using TBPHS values as described in my post above.

    If I set TBPHS.half.TBPHS = 0U for all ePWMs but disable the phase shift TBCTL.bit.PHSEN = TB_DISABLE, then I see all 3 signals with changing frequency as expected.

    Based on this it seems that having phase-shift enabled has some kind of impact on frequency change functionality. Hopefully this helps.

    Regards,
    Lev

  • Can you disable the HR enhancements for the moment and check if that fixes your issue? (We can work on adding them back in after if that is the case)

    Regards,
    Cody 

  • Cody,

    With disabled HR enhancements the functionality still does not work.

    HR is configured this way:

    EALLOW;

    EPwm8Regs.HRCNFG.EDGMODE = HR_FEP;
    EPwm8Regs.HRCNFG.CTLMODE = HR_CMP;
    EPwm8Regs.HRCNFG.HRLOAD = HR_CTR_ZERO_PRD;
    EPwm8Regs.HRCNFG.SELOUTB = 0U;
    EPwm8Regs.HRCNFG.AUTOCONV = 1U;
    EPwm8Regs.HRCNFG.SWAPAB = 1U;

    EPwm8Regs.HRPCTL.bit.HRPE = 0U;
    EPwm8Regs.HRPCTL.bit.TBPHSHRLOADE = 0U;

    EDIS;

    I have now tried following combinations:

    • Phase-shift disabled, HR enhancements enabled - everything is working as expected. All 3 PWM signals operational with changing frequency.
    • Phase-shift enabled, HR enhancements disabled - no output on ePWM8A and ePWM6B. Output available on ePWM4B. Frequency not changing.
    • Phase-shift enabled, HR enhancements enabled - output on ePWM8A and ePWM6B available, but on ePWM4B it is missing. Frequency not changing.

    Note: normally we use output on channel B. However, for the ePWM8 we swap the output to A to have the HR enhancements.

    Interrupt is triggered on ePWM8 CTR == 0 on every 3rd occurrence. I have also experimented with other combinations without success unfortunately.

    Regards,
    Lev

  • Lev,

    do you have anything else enabled in your PWM configuration? Maybe the trip-zone or the digital compare sub-models? 

    What else is going on in your code? Can we strip that out and get a simple test case?

    How have you configured the sync chain?

    Can you provide an image of the PWM outputs?

    You said you were keeping a constant phase shift, but are you syncing the PWMs once or are you doing a cycle-by-cycle resynchronization? 

    Regards,
    Cody 

  • Cody,

    First of all, I would like to thank you for the support!

    Apart from the configuration presented in the previous posts, I have also enabled interrupts on ePWM8 to trigger once the INTCTR = ZERO every 3rd event. This is the trigger point for changing the PWM frequency and the duty-cycle. However, those parameters are not changed in every interrupt. There are no trip-zone nor digital compare sub-models enabled.

    This is a component that is part of a big system. This component is intended to provide 3 phase shifted PWM signals with changing frequency and duty cycle as an input for hardware components. There is no other logic included.

    Those ePWMs are configured to listen to the EPWMxSYNCI input signal.

    I don't have the equipment right now to do the a oscilloscope picture containing all 3 signals as I need to modify the hardware for better access. If it becomes really necessary, I could do it next week.

    Yes, I my expectation is to have a constant phase shift. Having this in mind, I made a change that disables the phase shift before the frequency starts changing as the required phase shift is already achieved. I would like to note that such solution works very well. If I keep the phase shift enabled, then it does not work as described previously.

    Do you know to tell whether there are any restrictions on changing the TBPRD value while the phase shift is enabled?

    Thanks and regards,
    Lev

  • Lev,

    there is no hardware requirement that I know of, as long as you aren't changing the value in such a way that an event or action is missed or never occurs there are no restrictions with variable frequency and implementing a cycle-by-cycle phase shift.

    Are you updating the frequency EVERY cycle? Perhaps you are keeping the synchronized signals from ever reaching their TBPRD value which keeps an event from occurring.

    Oh, that actually gives me another idea, are all your PWMs running at the same frequency? If not that is OK, but the slowest signal MUST be the master, if not the slower signal will always be resynced by the faster signal before it reaches it TBPRD event. This issue could also be fixed by removing the cycle-by-cycle sync and replacing it with a one-time sync at the beginning of your code, so your last post supports this theory.

    Regards,
    Cody 

  • Cody,

    Thanks for clarification.

    The frequencies are not updated every cycle. There is a simple functionality, which ensures the frequency gets changed every 1 second.

    All my PWMs are intended to run at the same frequency and duty cycle, but with a phase-shift. This means that I change the frequencies of all 3 PWMs at the same time to ensure that same frequency requirement is fulfilled.

    Regards,
    Lev

  • Cody,

    I made some further experiments and found out that new TBPRD value written in the ISR for changing the PWM frequency is not taken into effect (presumably written from shadow to active register) when PHSEN = TB_ENABLE at the same time.

    If I set PHSEN = TB_DISABLE, modify TBPRD with new value and then set back PHSEN = TB_ENABLE within the same ISR, I can see the frequency changing as expected.

    However, over a time the signals go out of sync and then recover. This happens periodically.

    Hopefully this helps us further.

    Thanks and regards,
    Lev

  • Lev,

    it sounds like your PWM periods are not equal. The separate PWM modules use the exact same clock, if they are synchronized at one point in time they will remain synchronized. There will be no drift at all, this must be due to something else, resetting a TBCTR, resynchronizing or not having equal TBPRDs are all possibilities. If the change is very abrupt, perhaps you have changed one PWM's frequency before the Shadow-to-active load event occurs, then after the event finish changing the other PWMs. If this is the case you will need to define a safe window in which to update your PWM's period, typically towards the middle of the PWM period is a good time.

    Have you enabled shadow loading? What events have you configured for your shadow to active loads?

    Regards,
    Cody 

  • Cody,

    The PWMs are synchronized at the start of the PWMs. Once the ePWM6 TBCTR reaches the period (= CMPB), the phase-shift is disabled. Otherwise, the frequency change is not working at all.

    TBCTR is not touched by the software at all, synchronization is turned off as stated above. So, I also suspect that TBPRDs are possibly becoming not equal at some point during runtime as you already mentioned. However, the PWM's period change is implemented exactly as you mentioned - in the middle of the PWM period (ePWM8 to be more precise). At this point the system triggers an interrupt (EPWM8_INT) and within the ISR I change the values of TBPRD and CMPB for the new frequency and duty-cycle respectively. Nevertheless, I still see the drift.

    Shadow loading has been enabled for both, TBPRD and also CMPB. I didn't find any possibility to configure shadow to active load event for the TBPRD in the technical reference manual, so it is using the fault one when TBCTR = 0. CMPB load from shadow to active happens when TBCTR = PRD (also tried with 0).

    Any ideas that might help are appreciated.

    Regards,
    Lev

  • Lev,

    Lev Avdejev said:
    The PWMs are synchronized at the start of the PWMs. Once the ePWM6 TBCTR reaches the period (= CMPB), the phase-shift is disabled. Otherwise, the frequency change is not working at all.

    This should not be happening, this means that the PWM is never reaching the TBPRD shadow load point, or TBCTR=0. To confirm my theory, can you disable the shadow loading for TBPRD? Does this allow the TBPRD to update while phase shifting is enabled?

    This seems to suggest that the counter of the later PWMs are skipping over TBCTR = 0, I am not sure why but I would expect one of my previously mentioned theories. That being said maybe I have over looked another counter discontinuity.

    Regards,
    Cody 

  • Cody,

    Thanks for your response. I did not have time to check your suggestion today, but I will certainly do it tomorrow and inform you about the results.

    Regards,
    Lev

  • Not a problem Lev, let me know once you get the results.

    Regards,
    Cody 

  • Cody,

    I disabled the shadow loading for TBPRD by setting TBCTL.bit.PRDLD = TB_IMMEDIATE and as a result the signal is now running with 100% duty cycle for all 3 ePWMs. However, the duty cycle is configured to 50% by the software.

    Here I tried 2 options:

    1. Set CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE to load the CMPB value immediately.
    2. Set CMPCTL.bit.SHDWBMODE = CC_SHADOW to load the CMPB value from shadow.

    For both options the result was the same: all 3 PWMs are running with 100% duty cycle.

    Note that within the ISR in additional to frequency I also change the duty cycle by modifying CMPB value to ensure it is always 50%.

    Setting TBCTL.bit.PRDLD = TB_SHADOW and keeping the phase-shift also activated resulted in having the signal back with 50% PWM and 2.5us period, but the frequency is not changing although the TBPRD registers are modified within the ISR.

    Regards,
    Lev

  • Lev,

    my understanding is that you have PWM4 as your master, with PWMs 6 and 8 as your slaves, is this correct?

    What is your TBCTL[PHSEN] for each PWM?

    What is your TBCTL[SYNCOSEL] value for each PWM?

    Have you read back your TBPRD value using the register viewer? Sometimes there can be a code bug which keeps the values from updating.

    Regards,
    Cody 

  • Cody,

    EPWM modules are configured in a way, where ePWM8 has no phase-shift relative to main synchronization, ePWM6 has phase-shift of 8 system clocks relative to ePWM8 and ePWM4 has phase-shift of 16 system clocks relative to ePWM8.

    Do you mean under master which ePWMs are phase-shifted and related to what ePWM? The synchronization is coming from the first ePWM, which in turn gets it from an external component.

    TBCTL[PHSEN] is set to TB_ENABLE (0x1) for all 3 ePWM modules.

    TBCTL[SYNCOSEL] is set to TB_SYNC_IN (0x0) for all 3 ePWM modules.

    No, I haven't read back the TBPRD vales using the register viewer. Does it behave the same way as normal memory reader? Does it require the system to be stopped?

    Best regards,
    Lev

  • Ok, lets evaluate your sync chain configuration.

    1. Your first PWM is configured to receive a sync signal from an external source.
      1. What frequency does this external sync signal occur?
    2. Are all PWMs configured to pass ePWMxSYNCI to ePWMxSYNCO (TBCTL[SYNCOSEL] = TB_SYNC_IN), correct?
      1. if yes, this means that the external source is the sync signal for all PWMs, correct?
    3. PWM's 4, 6, and 8 are all running at 401kHz, correct?

    Try reading back the TBPRD values just to make sure they are being correctly read. You can do this with the code running, but the refresh rate on the window is much slower than your control loop, so you might be looking at slightly old values, but it will be close. If you pause the code the window will catch up to the latest register value and you'll know that's the latest.

    Regards,
    Cody 

  • Cody,

    Here is my feedback to your questions.

    Cody Watkins said:
    Your first PWM is configured to receive a sync signal from an external source.
    1. What frequency does this external sync signal occur?

    Answer: The external sync signal occurs with 400kHz frequency.

    Cody Watkins said:
    Are all PWMs configured to pass ePWMxSYNCI to ePWMxSYNCO (TBCTL[SYNCOSEL] = TB_SYNC_IN), correct?
    1. if yes, this means that the external source is the sync signal for all PWMs, correct?

    Answer: No, for ePWM3 the sync signal is generated once CTR of ePWM2 equals zero. Thus, for ePWM2 TBCTL[SYNCOSEL] = TB_CTR_ZERO. However, the following ePWM3 is TBCTL[SYNCOSEL] = TB_SYNC_IN again. For all the rest ePWM modules TBCTL[SYNCOSEL] = TB_SYNC_IN. 

    Cody Watkins said:
    PWM's 4, 6, and 8 are all running at 401kHz, correct?

    Answer: Yes, but only after the initial configuration.

    In general I am thinking, doesn't the ePWM2 configuration break the chain and all following ePWM modules (ePWM3-ePWM8) are actually synced to the ePWM2 synchronization output?

    I would prefer to leave the register reading using debugger to the really last state. The problem is that stopping the code might result in a HW damage due to vital usage of PWM signals. I will check for alternative possibilities for that.

    Regards,
    Lev

  • Lev,

    Lev Avdejev said:
    In general I am thinking, doesn't the ePWM2 configuration break the chain and all following ePWM modules (ePWM3-ePWM8) are actually synced to the ePWM2 synchronization output?

    That is exactly right. What frequency is ePWM2? Is there any chance that it is ever faster than ePWMs 4 6 or 8?

    Lev Avdejev said:
    would prefer to leave the register reading using debugger to the really last state. The problem is that stopping the code might result in a HW damage due to vital usage of PWM signals. I will check for alternative possibilities for that.

    I understand, no need to stop the code. As long as the registers aren't rapidly changing values it will be a helpful debug step. Go read the TBPRD value for PWMs 2, 4, 6 and 8's while the code is executing. If PWM 2's value is ever smaller it would explain why your are missing events.

    Regards,
    Cody 

  • Cody,

    Cody Watkins said:
    That is exactly right. What frequency is ePWM2? Is there any chance that it is ever faster than ePWMs 4 6 or 8?

    You are absolutely right. ePWM2 is running with constant frequency 401.786kHz, ePWMs 4, 6 and 8 have changing frequency from range ~390kHz to ~410kHz. Based on this it is clear, that at some point during runtime the ePWM2 is faster than the ePWMs 4, 8 and 8.

    How can it impact losing the phase-shift if I turn the phase-shift off TBCTL(PHSEN) = TB_DISABLE after 2 periods are passed?
    Note that the frequency change does not work at all if this is not done.

    I made an experiment, where I changed the frequency change range to ~401kHz...~410kHz to avoid ePWM2 running with higher frequency. However, the result was the same and the drift present.

    There is one new fact I noticed today. It seems that drift size is somehow depending on how often the frequency is changed. I tried using changing the frequency every ~500ms and then the drift was hardly noticeable. I could see one PWM drifting just a bit compared to other back and forth. After I decreased the delay to ~500us, the drift became quite large.

    Regards,
    Lev

  • Lev,

    Lev Avdejev said:
    How can it impact losing the phase-shift if I turn the phase-shift off TBCTL(PHSEN) = TB_DISABLE after 2 periods are passed?
    Note that the frequency change does not work at all if this is not done.

    If your phase sync is disabled and your PWM frequencies are not identical they will slowly drift. The frequency will not change when the master is faster than the slave because you have configured it to only happen at TBCTR = TBPRD which is never reached since the faster master PWM has already sent a sync signal.

    Lev Avdejev said:
    I made an experiment, where I changed the frequency change range to ~401kHz...~410kHz to avoid ePWM2 running with higher frequency. However, the result was the same and the drift present.

    You should not need to have the code that disables TBPHS anymore now what your slave periods are always longer than your master period. If TBPHS is loaded and enabled then there should be no drift, the master PWM should re synchronize with the slaves every period.

    When you ran the experiment did you still have the code that disabled TBPHS?

    Finally were the slaves drifting because they were faster than the master or because they were slower than the master?

    Regards,
    Cody 

  • Cody,

    Thanks for the explanations!

    Cody Watkins said:
    When you ran the experiment did you still have the code that disabled TBPHS?

    Yes, the disabling the TBPHS was still part of the code.

    Cody Watkins said:
    Finally were the slaves drifting because they were faster than the master or because they were slower than the master?

    When the frequency change interval was relatively large, then I saw it was drifting in one direction and when it was slower, then in other direction.

    Do I understand correctly that slave PWMs are synced to the master every period?

    I will make an experiment tomorrow, where I keep the TBCTL(TBPHS) = TB_ENABLE, but ensure that the slave periods are longer than master period. Once I have the results, I will post them here.

    Regards,
    Lev

  • Lev,

    Lev Avdejev said:
    Do I understand correctly that slave PWMs are synced to the master every period?

    It depends on how you have the PWM configured, they can be synchronized once, slowly but periodically or every master PWM cycle. In your system I would recommend you to synchronize every master PWM period.

    Please let me know how your experiment goes!

    Regards,
    Cody

  • Cody,

    I carried out following experiments:

    1. Keep phase-shift enabled; slave frequencies are slower than master frequency; slaves synchronized to EPWMxSYNC.
      Result: The frequencies were not changing at at all.
    2. Keep phase-shift enabled, slave frequencies are slower than master frequency; slaves synchronized to every master PWM period.
      Result: The frequencies were not changing at all.

    As long as I set TBCTL(PHSEN) = TB_DISABLE, the frequencies start to change, but drift is seen.

    Do you have any further ideas what could be tried? Thanks!

    Regards,
    Lev

  • Please read the TBPRD values while the system is running and see if they are correctly being updated. I know there is risk if you stop your system, so lets not stop it. Simply use the register viewer to observe the relevant PWM values.

    Is PHSEN always active?

    Is TBPRD correct?

    Do you ever see the TBCTR = Period ISR or Flag ever occurring during these experiments?

    Regards,
    Cody 

  • Cody,

    Thanks for suggestion.

    Will proceed with viewing the registers and reply as soon as I have the results.

    Regards,
    Lev

  • Lev,

    I look forward to the results.

    Regards,
    Cody 

  • Cody,

    Normally it should not be possible to see register values without stopping the program. Do I need some kind of special equipment and software for that?

    Until now I have only a connection via evaluation board as a debugger to access the memory or flash the MCU. It is a bit hard to explain what it looks like, but perhaps you might be aware of it.

    Regards,
    Lev

  • Lev,

    The "Registers" pane is what you want to use. Below I have linked to a quick tutorial on it. By default it is included in your debug environment, but if you have closed it you can reopen it by going to "view"->registers. 

     

    If you want to look at a variable in real time you can use the "expressions" pane or the "memory browser". If you use the memory browser please ensure it is set to refresh.

    Regards,
    Cody

  • Cody,

    Thanks for the instructions.

    Unfortunately, I will not have time to try it out this week due to other priorities and projects. I will definitely get back to it next week and provide you with the results.

    Regards,
    Lev

  • Lev, 

    I understand. please reply back when you know more!

    Regards,
    Cody