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.

Wait on Trigger is not immediately triggering next timer

Other Parts Discussed in Thread: TM4C1294NCPDT

I'm using the TM4C1294NCPDT microcontroller and am having problems getting deterministic results using the Wait On Trigger feature.
I have 3 timers: Two PWM half width timers and one one-shot timer to trigger a delay on one of the PWM timers. Both PWM timers have the same frequency and Duty Cycles. The one-shot timer counts up to and above the period of the PWM signals to impart a delay on one of the PWM timers relative to the other. My timers are configured as follows:

void initTimers()
{
	// Delay between Timer 4A and Timer 5A
	uint32_t Delay = 0;

	// Enable Timer3B for one-shot count up, half width, period is 19999 + Delay
	// This timer will trigger the start of 4A
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
	TimerConfigure(TIMER3_BASE,  TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT_UP);
	TimerPrescaleSet(TIMER3_BASE, TIMER_B, 1);
	TimerLoadSet(TIMER3_BASE, TIMER_B, 119999 + Delay);
	TimerControlStall(TIMER3_BASE, TIMER_B, true);

	// Enable Timer5A for PWM, 1kHz 50% duty cycle
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER5);
	TimerConfigure(TIMER5_BASE,  TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
	TimerPrescaleSet(TIMER5_BASE, TIMER_A, 1);
	TimerLoadSet(TIMER5_BASE, TIMER_A, 119999);
    TimerMatchSet(TIMER5_BASE, TIMER_A, 59999);
	TimerControlStall(TIMER5_BASE, TIMER_A, true);

	// Enable Timer4A for PWM, 1kHz 50% duty cycle, counter will start on Timer3B timeout event
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER4);
	TimerConfigure(TIMER4_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
	TimerControlWaitOnTrigger(TIMER4_BASE, TIMER_A, true);
	TimerPrescaleSet(TIMER4_BASE, TIMER_A, 1);
    TimerLoadSet(TIMER4_BASE, TIMER_A, 119999);
	TimerMatchSet(TIMER4_BASE, TIMER_A, 59999);
	TimerControlStall(TIMER4_BASE, TIMER_A, true);

	// Enable Timer0.  Seems to be required to sync all timers.
	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

	// Enable Timers
	TimerEnable(TIMER3_BASE, TIMER_BOTH);
	TimerEnable(TIMER5_BASE, TIMER_A);
	TimerEnable(TIMER4_BASE, TIMER_BOTH);

	// Sync Timers
	TimerSynchronize(TIMER0_BASE, TIMER_3B_SYNC |
								  TIMER_4A_SYNC |
								  TIMER_5A_SYNC);

}

What I observe is that when Delay is set to 0, I observe an 8 count difference in the count value of timers 4A and 5A (instead of 1 count I expect).  When I set Delay to a non zero value, such as 1000, I observe a 1008 count different instead of 1001.  Even worse, when I step through an infinite while loop placed right after the TimerSynchronize command, and step right before and right after the TriggerOnWait event (when Timer 3B approaches it's load value), I can observe varying differences (4 or 1 instead of the 8 when Delay = 0).  It seems to be non deterministic when debugging, but a static 7 count difference from what I expect when not debugging.

Can anyone provide some assistance in addressing this problem?

  • Hello Justin

    Wait on trigger and Synchronization mechanism are two different mechanism. In Wait-On-Trigger when the previous timer reaches the Timeout event, does the next timer start. Using the Timer Synchronization forces the Timeout event to happen. Now this synchronization has to be sent out to the different timers across clock boundary, requiring a resync and may result in different time values.

    Also you are using a debugger that may cause the values to be read out differently. If you check the two PWM output on a scope, do you still see the 8 clock cycle difference?
  • I am seeing the same effect even if I remove the TIMER_4A_SYNC control from the TimerSynchronize command.

    Yes, I do see the 8 count difference on a scope. I don't have the pinconfig included above for simplicity and code conciseness, but I do have both PWM signals scoped. I see the differences I observe in the debugger also as differences on the scope traces. (~68ns for the 0 Delay, 8 120MHz clock ticks).
  • Hello Justin,

    Thanks for the confirmation. Let me use your code and check on my setup.
  • Hello Justin

    I checked the same and I could reproduce the issue. However I add a loop to wait for 1 timeout count, before synchronization and it now matches up fine.

    for(Delay=0;Delay<40000;Delay++);

    // Sync Timers
    TimerSynchronize(TIMER0_BASE, TIMER_3B_SYNC |
    TIMER_4A_SYNC |
    TIMER_5A_SYNC);
  • Thank you Amit! I gather this is not how the feature was intended to function. Possibly an errata or note in the data sheet.

    Thanks!
  • Hello Justin,

    I would need to understand why this is happening. If confirmed, then yest it would be an errata with a WA,

    Can you please confirm if the issue has been resolved on your setup?
  • Amit,

    Yes, I ended up configuring in a slightly different timer configuration that did not use the Wait on Trigger feature that avoided the problem all together without the need for a delay loop.
  • Hello Justin

    And I would be very interested in the "slightly different" method if you do not mind sharing the same.
  • Of course! Instead of having Timer 4A start on timer 3B, I started Timer 4A immediately with a load set of 19999 + Delay. Immediately after the TimerSynchronize command, I load a new load set into timer 4A with just 19999 with:

    HWREG(TIMER4_BASE + TIMER_O_TAMR) |= TIMER_TAMR_TAILD;
    HWREG(TIMER4_BASE + TIMER_O_TAILR) = myLoadset;
    HWREG(TIMER4_BASE + TIMER_O_TAPR) = myPrescaler;

    The first line is to ensure NOT to restart the timer when a new load is inserted with a count down timer.
  • Hello Justin

    Neat and elegant but the issue will be with different system clock, code placement and prefetch buffer, this timing may need adjustment.
  • Amit,

    Can you elaborate?  Are you saying this approach may not work under certain circumstances?  It seems to work for my application just fine.

  • Hello Justin,

    The delay is based on the code placement and execution. With different system clock the execution time may change. As an example drop the system clock to 60MHz or add some code which is not going to affect any operation but changes the code placement and you may start seeing the effect of the same on the PWM output