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.

GPTM in PWM mode suffers period update glitch

Other Parts Discussed in Thread: TM4C123GH6PM, EK-TM4C123GXL

Hello,

I am using a GPTM in PWM mode to control a stepper motor driver. The width of each pulse should be the same, but frequency of the pulse train should ramp up and then down, to create a trapezoidal velocity profile for the motor. The new timer period is calculated and applied to the timer in an "acceleration" interrupt that is triggered by the rising edge of the timer's CCP signal. I have tested this code a fair amount and found that it works perfectly, unless the starting frequency of the pulse train is too low.

This picture shows the expected operation. Channel 1 (Yellow) is the pulse train generated by the GPTM. Channel 2 (blue) is a GPIO pin that is set high upon entry to the acceleration ISR and cleared upon exit from the ISR. The acceleration interrupt is (intentionally) disabled for the 3 pulses in the middle, because the middle portion of the move is expected to be at a constant velocity.

Here is a close-up of a pulse with acceleration enabled:

When the starting frequency of the pulsetrain is below a certain threshold, the following glitch happens:

Here is a close-up of the glitch:

Here is the initial configuration of the GPTM:

	MAP_TimerConfigure(MOTOR_A_PWM_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM);
	MAP_TimerControlLevel(MOTOR_A_PWM_TIMER_BASE, TIMER_A, false);
	MAP_TimerControlEvent(MOTOR_A_PWM_TIMER_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
	TimerUpdateMode(MOTOR_A_PWM_TIMER_BASE, TIMER_A,
			TIMER_UP_LOAD_TIMEOUT | TIMER_UP_MATCH_TIMEOUT);
	TimerIntRegister(MOTOR_A_PWM_TIMER_BASE, TIMER_A, motor_A_accel_ISR);
	MAP_TimerIntEnable(MOTOR_A_PWM_TIMER_BASE, TIMER_CAPA_EVENT);

Here is the function that sets a new frequency for the GPTM:

static void pwm_period_set(uint32_t timer_base, tcount_t period)
{
	tcount_t match_val = period - STEP_PULSE_COUNTS;

	// Set 'Load' value
	HWREG(timer_base + TIMER_O_TAILR) = (uint16_t)(period & 0xFFFF);
	HWREG(timer_base + TIMER_O_TAPR) = (uint8_t)((period >> 16) & 0xFF);

	// Set 'Match' value
	HWREG(timer_base + TIMER_O_TAMATCHR) = (uint16_t)(match_val & 0xFFFF);
	HWREG(timer_base + TIMER_O_TAPMR) = (uint8_t)((match_val >> 16) & 0xFF);
}

I wrote some code to capture the 'period', 'match_val', and TAR register at the end of each invocation of the function 'pwm_period_set'. Examining the data, I found that the glitch only occurs if TAR is greater than 'period' (by more than a few counts) at the end of the 'pwm_period_set' function. Here are the two data points that show this threshold frequency:

Issue appears here:
period = 29897
match = 29097
TAR   = 29992

Issue doesn't appear here:
period = 28848
match = 28048
TAR    = 28852

Note that this issue never occurs when the GPTM frequency is decreasing (deceleration), only when the frequency is increasing. From this I conclude that (in PWM mode) it is not safe to set a new GPTM period that is less than the old GPTM period IF the current TAR value is greater than the old GPTM period. What exactly is going on?

NOTE: I am using a TM4C123GH6PM, silicon rev. 7, with TivaWare 2.1.2.111.

  • Hello Oliver,

    I am a bit surprised here. The Period is the Load value and the match is the where the PWM edge is generated. The TAR is current value of the timer. PWM works only in down count mode, So the TAR cannot be more than TAILR.

    Regards
    Amit
  • Hello Amit,

    The TAR is more than the next TAILR, not the current TAILR. I am increasing the PWM frequency, shortly after the start of each PWM period, using the 'update on timeout event' mode. The Period and Match values that I reported are the values for the next PWM period, which I configure during 'pwm_period_set'. The TAR value that I reported is the only value related to the current PWM period.

    The issue is that the new Period and Match values should not take effect until the 'timeout' event, since I am using the 'update on timeout event' mode. But this expected behavior happens only if TAR is less than the new TAILR value when I write this new value to TAILR. Otherwise, I see this glitch.


    Thanks,

    Oliver

  • Hello Oliver

    The Timeout occurs when the counter counts up to the TAILR value. Since PWM works in down count, the timeout condition will not be met.

    Regards
    Amit
  • Amit,

    Section 11.3.2 [Functional Description - Timer Modes] in the TM4C123GH6PM data sheet says "Throughout this section, the timeout event in down-count mode is 0x0..." (page 707). Since the PWM mode counts down, I assume that it generates a timeout event at 0x0. If it doesn't, it would be helpful to mention that fact in the data sheet.

    In any case, what is the safe, glitch-free way to update to update TAILR in PWM mode?

    Thanks,
    Oliver
  • Hello Oliver

    PWM mode would be different than Timer Mode of Periodic and One Shot count. I would suggest updating the values on a Match TimeOut. It needs to be ensured that the TAILR is more than TAMATCH

    Regards
    Amit
  • Hello Amit,

    According to the data sheet, "The timer is capable of generating interrupts based on three types of events: rising edge, falling edge, or both." (pg 716)

    I assume in this case that 'Match TimeOut' means a falling edge, since my PWM signal is configured to go high when the timer reloads, and low when the match event occurs. Choosing rising or falling edge interrupts makes no difference in whether or not the bug appears. Moreover, I have ensured that TAILR is always more than TAMATCH. If you are in doubt of this, please look at my 'set_pwm_period' function.

    The glitch shows up if TAR is greater than the new TAILR value when I write the new TAILR value. It seems to me that this is either a hardware bug or a very unfortunate omission from the design of the timer hardware. I do not see why the current value of TAR should have an impact on updating TAILR, if the TAILD bit in TAMR is set. I should be able to schedule an update on TAILR to occur the next time TAR hits zero. Doing this should not affect anything in the current PWM period, regardless of when the write to TAILR occurs (except perhaps if the write occurs in the few clock cycles just before TAR hits zero).

    Your response suggests that the Timeout event, and therefore the TAILD bit in TAMR page, are totally irrelevant to the PWM mode. I find this quite surprising. If this is true, then

    1. The quote "Throughout this section, the timeout event in down-count mode is 0x0..." (pg 707) is quite misleading, because the PWM mode is discussed later in this section.
    2. There is no way to guarantee glitch-free updates of the timer period in PWM mode.

    Can you please clarify for me if this is correct?

    Thanks,

    Oliver

  • Hello Oliver

    Can you please provide with a simplified code so that I can evaluate the issue on my launchpad?

    Regards
    Amit
  • Hello Amit,

    I have attached a simple CCS project that demonstrates the bug. Please connect pin PB.6 of an EK-TM4C123GXL launchpad to an oscilloscope to see the PWM glitch that I described. The test program runs two trials, each of which generates a pulse train for about 3 milliseconds. There is a gap of roughly 4 milliseconds in between the two trials. The first trial should demonstrate the intended operation (no glitch), while the second trial should show a glitch similar to what I described previously.

    Thank you very much for looking into this issue.

    Oliver Douglas

    pwm-bug.zip

  • Hello Oliver

    I am able to reproduce the issue on my side. I checked the errata and it seems that what you are seeing is perhaps GPTM#10 (though it does not mention PWM mode)

    Regards
    Amit
  • Amit,

    Thanks for trying the code. I don't understand how GPTM #10 would cause this bug. I am looking at the errata for silicon revisions 6 and 7. GPTM #10 is "Writes to Some General-Purpose Timer Registers Cause the Counter to Increment and Decrement in Some Cases". If I understand this correctly, it should cause a single extra timer tick per register write. I don't see how this would cause the glitch if TAR is more than a few counts away from the Match or Prescale registers. I am curious to know what your line of reasoning is here, since it might help in finding a workaround.

    Thanks,
    Oliver
  • Hi Oliver,

    It seems to me you could simply change the duty cycle during the match count update interrupt at a static PWM frequency. Would not the stepper motor react to the duty cycle change at that static frequency?
  • BP101,

    Thanks for the suggestion. The waveform that I am generating acts as a 'step' command to a separate motor driver board. Each falling edge of the waveform causes the driver board to step the motor, so changing the duty cycle won't have any effect. The frequency of falling edges is all that matters.
  • Hello Oliver,

    I believe the loading is causing the value to change such that the match is always higher than the current value. And that is what I am trying to check with another experiment and the design team.

    In the meantime, I would suggest using the PWM module instead of the Timer so that you can move ahead with your project.

    Regards
    Amit
  • Amit,

    Thanks for the update. I will look into using the PWM module instead.
  • > Each falling edge of the waveform causes the driver board to step the motor, so changing the duty cycle won't have any effect.

    Is that not what changing the duty cycle (pulse width) does ? move the falling/rising edge % relative to other timers perhaps having 10% less duty edge time? Speaking of a 4 pole stepper motor in that case. Long as the edge of all 4 poles move together in the synchronous updates the PWM frequency remains fixed.

    Remain skeptical changing the frequency (period) is any better to that end. Seemingly the speed of the updates in the pulse width (duty %) and PI controller moves the edge event faster or slower relatively in the stepper shaft speed.
  • BP101,

    The microcontroller does not have direct control over the stepper drive circuit - it simply provides a 'Step' pulse to a separate driver board. If you want to know more about the driver board, it's an Automation Direct STP-DRV-4035.
  • Hi Oliver,

    Off the cuff it would seem fairly easy to provide a step pulse.
    We too used a PWM timer but for controlling the speed of a fan motor via match count interrupts driven by a separate CCP edge counter monitoring a feed back signal (taco speed) and updating the duty in the frequency to match the desired taco fan speed (closed loop).

    Can you post STP data timing diagram or simply post illustration of the expected drive/feed back signal requirement?

    *************************************************************

    BTW: Perhaps unrelated we started taco speed control project with timer up counting and had trouble with CCP edge match counts being correct during the interrupt. Amit suggested switching to CCP edge down counting and the edge count matches were then exact during interrupts, no more mismatches ever.

    Used CCP timer only for counting the number of pre set edges and matching count interrupts returned from the fans taco speed feed back signal. 

  • Hello Amit, is there any news with problem identified in this post. In my project I also have this error on two wide timer PWM outputs which generate PWM signals which need to have variable frequency. I cannot use PWM module on them since this outputs don't have that function, and signals go from 1Hz to 300 Hz so I assumed best way is to use wide timer for PWM signal generation. Now I am stuck. I have that glich, cannot use PWM module, and I need to generate that signal on those outputs to finish this project. What do you recomend? Is this wide timer option at all? Maybe to generate PWM signal with GPIO?
  • Hello Amit,

    Is there any news on how to avoid this problem? I am resuming my project from last summer and I would like to continue using TM4C devices for the project.

    I can't use the PWM module for this - the timer isn't wide enough for the range and precision I need. My goal is to do pulse frequency modulation (PFM) at rates from(approximately) 10 pulses / second up to 100,000 pulses / second, with a worst-case resolution of around 0.1%. For this purpose, the GPTM in PWM mode would be ideal - except for this period update glitch!
  • Hello,

    Absence of Amit response perhaps on vacation ? the PWM module can run at full SYSCLK speed, 120Mhz. The PWM generators and PWMENABLE register can be set to immediate update at next zero count. In any case the GPTM has the same basic counter behavior as the PWM module all of which can be made to interrupt upon the next zero count or even count load.

    We have found slower frequency PWM using GPTM modules appear to be more stable using the PIOS 16Mhz clock source when match count interrupts and updates to the counters during down counts. There is known errata when up count match interrupts (updates) are loaded at any GPTM clock source speed.