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.

EK-TM4C1294XL: Synchronize PWM

Part Number: EK-TM4C1294XL

I am trying to synchronize two PWM signals so that the rising edge matches up.  For some reason Gen2, Out5 seems to be about 150 ns late. I tried reading the processor manual about the PWM modules, but the information on synchronization is not making any sense to me about which and when to set the right SYNC bits. I tried many different settings combinations.  What am I doing wrong?

    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PG1_M0PWM5);
    GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);
    GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
	PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, (BOARD_CLOCK / TIM5_FREQ) - 1);
	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, TIM5B_10US);
	PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, (BOARD_CLOCK / TIM5_FREQ) - 1);
	PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, TIM5B_10US);

	PWMGenEnable(PWM0_BASE, PWM_GEN_3);
	PWMGenEnable(PWM0_BASE, PWM_GEN_2);

	PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT | PWM_OUT_5_BIT, true);

	PWMSyncTimeBase(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);
	PWMSyncUpdate(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);

  • Might your parameter, "PWM_GEN_MODE_NO_SYNC" for (both) PWM_GEN 3 & 2 (w/in PWMGenConfigure()) - effectively defeat/disable your (later) call to PWMSync() ? I've not used this vendor's PWM modules in quite some time - but believe that to be your issue...

    Found past code - the parameter w/in PWMGenConfigure() which worked for us: "PWM_GEN_MODE_SYNC."     You got (most) of the hard code parts right - curious how you "missed" that "sync turn-off..."

    Should this not (quickly) resolve I'll search/find our old code which clearly (did) sync 3 PWM Generators...   (further - years ago I posted that exact code on this forum...)

  • I had tried PWM_GEN_MODE_SYNC before, but that seemed to completely break the PWM signal.

  • "Completely break" inadequately describes your issue when employing "PWM_GEN_MODE_SYNC."

    Our firm has many K units in the field - which properly "Sync" multiple PWM Generators - and employ that parameter.

    Did you "humor me" by simply adding the suggested parameter change - and then re-running your code - and (properly) monitoring the outputs?   (that's completely unclear in your abbreviated writing)

    You may benefit from imposing a delay prior to your call of, "PWMSyncUpdate()."

  • The only lines I changed:

    PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);
    PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);

    This only sets the pins high, and leaves them there.
  • We've just crossed - delay the call to "Sync Update" and monitor - then report...
  • Eureka!

    Remove:
    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PG1_M0PWM5);

    You require (only) GPIOPinType()... Again - I've not visited this code for years - our "RUNNING/SYNCED" PWM avoids PinConfig calls.

    Further - you probably want, "SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);" to occur prior to your entire PWM Code Block.

    We "PWMSyncTimebase()" immediately following PWMGenEnable() - only then call "PWMOutputState()."

  • Odd, even with these changes I've still got the same problem with the pins staying high.

    I definitely need the GPIOPinConfigure, otherwise I don't get any output at all.

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PG1_M0PWM5);
    GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);
    GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);

    PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);
    PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);

    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, (BOARD_CLOCK / TIM5_FREQ) - 1);
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, TIM5B_10US);
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, (BOARD_CLOCK / TIM5_FREQ) - 1);
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, TIM5B_10US);

    PWMGenEnable(PWM0_BASE, PWM_GEN_3);
    PWMGenEnable(PWM0_BASE, PWM_GEN_2);

    PWMSyncTimeBase(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);
    PWMSyncUpdate(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);

    PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT | PWM_OUT_5_BIT, true);

  • I'm bothered - given you much work - we've nothing (yet) to show for that.

    Forgive me - but is there the chance that (other) code is "undoing" the new code block you present here? Or - might some external connection be impacting those PWM pins?

    In addition - might you (for clarity & duplication by my team) replace the "unique" labels w/in "PeriodSet & WidthSet()" w/hard coded, numeric values. I've just noted that your MCU is 1294 - we've only used LX4F & TM4C123. (use higher speed MCUs from others - normally).

    And - only those pins (officially designated as PWM) may be so used. Are you sure that "K-4 & G-1" are (legitimate) PWM (candidate) pins. You cannot "force" non PWM pins into PWM mode. (we chase our tails if I don't ask such...)

    [edit]...I (now) note that newer MCUs (such as yours) DO require "GPIOPinConfigure()" - mea culpa.    (that call does NOT appear anywhere in our past (successful) Synced PWM code!   {we ran find w/out success}

  • The PWM is working just fine with NO_SYNC, so the pins are definitely PWM capable. I'm doing all of this in an empty project with a single task so there's no other code. There's also no other connection to the board. Just the oscilloscope probes. Here is the code with the literals:

    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    GPIOPinConfigure(GPIO_PK4_M0PWM6);
    GPIOPinConfigure(GPIO_PG1_M0PWM5);
    GPIOPinTypePWM(GPIO_PORTK_BASE, GPIO_PIN_4);
    GPIOPinTypePWM(GPIO_PORTG_BASE, GPIO_PIN_1);

    PWMGenConfigure(PWM0_BASE, PWM_GEN_3, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);
    PWMGenConfigure(PWM0_BASE, PWM_GEN_2, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC);

    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_3, (120000000 / 2500) - 1);
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_6, (120000000 / 100000) - 1);
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_2, (120000000 / 2500) - 1);
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_5, (120000000 / 100000) - 1);

    PWMGenEnable(PWM0_BASE, PWM_GEN_3);
    PWMGenEnable(PWM0_BASE, PWM_GEN_2);

    PWMSyncTimeBase(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);
    PWMSyncUpdate(PWM0_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT);

    PWMOutputState(PWM0_BASE, PWM_OUT_6_BIT | PWM_OUT_5_BIT, true);
  • I appreciate your cooperation/efforts - thank you. I have a local TM4C123 LPad - but NO 129 based parts.

    Would you be so good as to (temporarily) "comment out" SyncTimeBase() & Sync Update - WHILE using parameter, "PWM_GEN_MODE_NO_SYNC" - and monitor & report. Does PWM Output then restore?  (yet it will remain UNSync'ed.)

  • I commented out those two sync lines, and set the config to "PWM_GEN_MODE_NO_SYNC" for both generators. The PWM output looks just fine, and of course is not synced.
  • Forgive me - clearly I'm NOT a multi-tasker.    The goal was to see if we could restore PWM Output upon both channels when employing, "PWM_GEN_MODE_SYNC."   (you've thus far reported the LOSS of PWM when that parameter is employed...)   I apologize.    (waiting for my flight @ an airport)

    Are you triggering upon a single, edge event?    (if so the "Sync" may not have yet established)    Also - iirc - PWMSyncUpdate() should be called w/some regularity - as the "sync" may erode w/time.   (recall this finding was observed several years past...)

    Perhaps worthwhile to try a different PWM pin set.    (from 2 different PWM Generators - to see if you've encountered a unique "pin limitation.")    

    Even though it has been years past - I distinctly recall the (2nd & 3rd) PWM Channels, "Jumping into alignment" when we called, "SyncTimeBase & SyncUpdate()."

  • And - at last - (most likely) a SOLUTION is at hand!

    // Synchronize the time base of the generators. *** Finally found my past code - just as boarding... ***
    //
    ROM_PWMSyncTimeBase(PWM0_BASE, PWM_GEN_0_BIT | PWM_GEN_2_BIT | PWM_GEN_3_BIT);  // Note: Parameters in highlight DIFFER from yours!

    Your parameters addressed individual BITS - these address individual GENERATORS!     (and "la raison d'etre" for this SYNC function is to SYNC multiple GENERATORS!)

    Clearly there are TOO MANY Parameters w/in this cobbled PWM function collection!    (effectively tormenting NEW Users until they (finally) get it right!)    Driver Peripheral Guide (stinks) in clearly/fully describing!

  • Great catch! This seems to have solved the problem! I can't believe I made such an oversight. Thank you for your help!
  • Thank you - I've now "twin" GREEN Rewards - one (kindly) from you - the second a "Shamrock Shake" upon landing.

    You are NOT alone in stumbling on such detail. As I noted - the User Manual fails to adequately & properly describe - and NO example delves into this level of PWM Control.

    You were extremely coachable - sorry for the "monkey motion" - I discovered that our 1st PWM efforts were made w/vendor's "LM3S" MCUs - which did NOT support GPIOPinConfigure()!    Later we moved to LX4F - and sure enough - PinConfigure() (as you thought) was right there!

    Devil (always) delights in such detail.    Marketing's "push" upon poor tech writer(s) led to manual's inadequacy in this area.   (I'd bet)