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.

TMS320F28379D: C2000 LaunchPad: ePWM pulse width and period don't match register settings

Part Number: TMS320F28379D

Hello!

I want to use the F2837xD block from said package to create four synchronized 100kHz, 50% duty cycle PWMs, each phased shifted with respect to the others.

The scheme I'm using is the following: ePWM12 generates a 100MHz "master clock" (the frequency is identical with the ePWM clock), that generates a SYNCOUT signal every time the counter reaches zero. I use this SYNCOUT signal to synchronize other "slave" PWMs (ePWM1 up to ePWM4). The latter have their Sync. Output set to "Pass through".  The slaves share the counter period value of the master (ePWMLink TBPRD set to ePWM12).
Because high resolution is needed, I enabled the option "Enable high resolution PWM (HRPWM)" in the slave ePWM modules (not in the master). I enter the phase shift value as a decimal (in this case, i tried the register value 10.25 which should be "broken down" into TBPHS and TBPHSHR values). TBPHSHR doesn't work right now, but that's another story.

With that, I encountered a bug:

For exactly 100kHz, 50% duty cycle, I have to change ePWM12 counter period value to 991 instead of 1000 and the counter compare value for the duty cycle to 492 instead of 500. I apply no phase shift to the reference counter (ePWM12). What causes this error between mathematically correct and really needed values?




Sincerely

Matthias
Student (University of Applied Sciences Ingolstadt)


PS: I am generating my Code with the C2000 Simulink block set, but I don't think that causes the problem. I confirmed that the code only copies the values received from simulink into the corresponding registers.

  • Hi Matthias,

    If the ePWM frequency is off by about 1%, my guess would be that you are using the internal oscillator to clock the device. If you need the absolute frequency to be very accurate, you should instead use an external XTAL or single-ended oscillator. The launchpad provides a 10MHz XTAL which should be accurate to about 30ppm.
  • Hello Devin,

    I already made sure that the external oscillator is used (by unchecking the option "Use internal oscillator" in the "Hardware Implementation" Settings in Simulink).
    This is confirmed by the generated code, which doesn't access the corresponding CLKSRCCTL1 register. It is therefore still at the reset value ("Crystal (External) Oscillator On").

    In the ePWM Reference Manual (SPRUHM8F, Revised December 2016) on page 1561 it says there is a Master-to-Slave delay of 2 EPWMCLK cycles. Are there any more possible sources of delay? I'm guessing that a sum of multiple delays could result in me having to use too small counter compare values. Though this wouldn't explain the counter period value.

  • Hi Matthias,

    Do you always want the frequency to be exactly 100kHz?  In this case I don't think you should have to update the slave timer periods, only the phase and compare value?

    It also seems like you could accomplish this by using only 4 ePWM modules.  Can you explain a little more why you are using ePWM12 as the master and how this synchronization scheme works?  Also, how does ePWM12 act as the master.  Based on the sync. chain I don't see how this is possible...are you looping back the ePWM12 output to a pin to use as a sync. input?

  • Hi Devin,

    in my application (DC/DC converter), the frequency and duty cycle are parameters, i.e., I choose one value for each and keep them.
    The phase shift on the other hand is a variable, i.e. it must be changeable during execution time of the program. It is therefore the most important property of my PWM signal (it controls the amount of power my DC/DC converter transfers).

    I don't loop back any pin to another, i.e. I don't use EXTSYNCIN signals.

    As to why I use ePWM12 as a reference for all PWM signals: I originally only consulted the Simulink blockset wiki (de.mathworks.com/.../c280xc2802xc2803xc2805xc2806xc2833xc2834xf28m3xf2807xf2837xdf2837xsepwm.html )
    So I made the mistake of not looking up the synchronization scheme above. I originally wanted to use only 4 PWMs, like you say, but couldn't get ePWMs 1 to 4 to be in sync phase-wise. A colleague of mine also experimented with the same block set and got it to work by generating a PWM signal with ePWM12 and setting "ePWMLink TBPRD" of the slave modules to ePWM12. The SYNC output of the slaves is set to "pass through".

    As for the above pic, does that mean that I should be able to use ePWM1 and 4, 5, 6 to sync 4 PWMs and that the maximum number of ePWMs that you can sync is six, i.e. ePWM1, 4, 7, 10, 11, 12?

    I'll try to use ePWM1, 4, 5 and 6 and report back.
  • Hi Matthias,

    If you want to use 1 master and X slaves, you can actually use ePWM1 as the master for everything in the diagram. This is because the sync signals have fan-out...you don't have to achieve synchronization via daisy chaining only.

    For example, if ePWM1 is the master, you can set ePWM2 as pass-through to get ePWM2 and ePWM3 sync'ed to ePWM 1. You can then set the ePWM4 syncin MUX to also use ePWM1 SYNC signal and then set ePWM4 and ePWM5 as pass-through to get ePWM4, 5, and 6 sync'ed with ePWM1.

    If/where you do daisy chain, we specify the maximum number of modules in the chain as 4.
  • Hi Devin,

    Your advice was very helpful. It works like shown above if, for example, I use ePWM1 as master and 4, 5, 6 as slaves.
    Looking at the Reference Manual again, I also see that it is recommended not to sync more than 4 ePWM modules in series.
    This only applies to the longest "chain", right?
    For example, could one use ePWM1 as "glomaster and sync the slaves ePWM4,5,6,7,8,9,10 for 8 synced PWMs?

    Now I just need to additionally get the HRPWM to work and I'm at my goal.


    Just for your information (or anyone else reading this thread in the future): The scheme I'm using is now
    - all ePWM counters count UP and are clocked at 100MHz
    - all counters use ePWMA and SET the PWM on counter=CMPA and CLEAR on counter=PRD. This is so I can phase-shift the rising PWM edge and therefore am able to compensate for the master-to-slave delay (see below).
    - master ePWM:
    -> For a period of T cycles use counter period value PRD = T- 1
    -> For duty cycle D use counter compare value CMPA = (1-D)*T - 1
    - slave ePWMs:
    -> Because of master-to-slave delay of 2 clock cycles (see TRM p.1561), set PRD and CMPA values of the slaves 2 counts smaller than for the master.

  • Thanks! I think the original question of this thread is now answered.
    Your pointer to the above picture was key to the solution. I'll suggest your respective post as the answer.

    Regarding the use of HRPWM, I'll try to find an answer together with Mathworks' support.
    It seems the problem lies somewhere in the blockset and a missing piece of generated code.

    I'll wait with suggesting the "answer post" till I get the HRPWM to work. Just in case there are other problems with the interaction between HRPWM and the normal ePWM.

  • Hi Matthias,

    Glad things are mostly working now!

    The 4 modules does indeed only refer to the longest chain, so I don't think this will be an issue for you.

    I'll ping Mathworks and ask them to reply on this thread with whatever solution they come up with.
  • Hi Devin,

    as the ePWM module itself has been working for over a week now, I'll close this topic.Thanks for the help!


    In the meantime, I got the HRPWM to work with the Simulink blockset (I was provided a hot fix by Mathworks). Its phase shift still doesn't behave as intended, but that's the topic of another thread: 

  • hello Matthias
    i am working for three port DC-DC converter - i want write the program for generating 6 PWM signals for three bridge circuit. could you help me. this is my specifications : frequency 20khz,duty ratio =50%.
  • hi Matthias

    can you give me your simulink files...i want to see what's the problem....psher@rediffmail.com

  • Hi

    I tried attaching the Simulink-file I used to this post.

    Starting from there, you can build any number of PWM signals simply by copying the ePWM blocks, "re-wiring" them and changing their values (most of all, the PWM module number). PWM_LaunchPad.zip

    The meaning of each block value is described by the text above each block. You can change these values directly or change them "live" (in Simulink "external mode") by using the sliders. If the model is too slow, remove the sliders.

    As a side note, the "system initialize" and "idle task" blocks in the model allegedly help in avoiding problems by periodically calling the function "update_MepScaleFactor()", but it seems they don't really matter. You can try adding/removing them if you like.

    PS: I won't be online the next 2 weeks. Sorry.