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.

TM4C123AH6PM: Wide Timer PWM glitch when frequency changing

Part Number: TM4C123AH6PM

Hello everyone, 

I have a question regarding the problem with PWM output from pins configured for wide timer used. I have used timers to PWM outputs and configuration seems OK, when no frequency is changing it works fine (frequency changes according to some analog input received on ADC from 2-200Hz). But I noticed when changing frequency at very low values (2-15 Hz) sometimes I have output go completely low for some period before updating to give PWM with new freq out. This is the code snippet used when the system detects frequency request change: 

ulPeriod = SysCtlClockGet()/INPUT_AnalogVals.dPotFreqPWM;// calculate new period
dutyCyclePWM2 = (unsigned long)(ulPeriod-1)*dPWMDutyDivider;
TimerUpdateMode(WTIMER5_BASE, TIMER_A, TIMER_UP_LOAD_TIMEOUT | TIMER_UP_MATCH_TIMEOUT);
TimerLoadSet(WTIMER5_BASE, TIMER_A, ulPeriod-1);
uint32_t ui32_dutyCyclePWM2=(uint32_t)dutyCyclePWM2;
TimerMatchSet(WTIMER5_BASE, TIMER_A, ui32_dutyCyclePWM2);

Here is the code in which I configure this output: 

SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER5);
GPIOPinConfigure(GPIO_PD6_WT5CCP0);
GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_6);
ulPeriod = SysCtlClockGet()/2;	//200Hz default 
dutyCyclePWM2 = (unsigned long)(ulPeriod-1)*(1-(5.0/100.0));
TimerConfigure(WTIMER5_BASE, (TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM));
TimerUpdateMode(WTIMER5_BASE, TIMER_A, TIMER_UP_LOAD_TIMEOUT | TIMER_UP_MATCH_TIMEOUT);
TimerLoadSet(WTIMER5_BASE, TIMER_A, ulPeriod-1);
TimerMatchSet(WTIMER5_BASE, TIMER_A, dutyCyclePWM2);
TimerEnable(WTIMER5_BASE, TIMER_A);

I assumed that this line "TimerUpdateMode" controls timer not to update load value before previous match is counted but it seems that sometimes that is not true.

What do you think, what am I doing wrong?

Thank you in advance.

  • Hello Djedjica

    Note that the Load value at TimeOut means that the values loaded should not transcend a timeout boundary. Make sure that the rollover of the timer occurs and then load the new values.
  • Hello Mr.Ashara,
    OK, I think that I know what You mean, so when I am increasing frequency load value is getting lower than the previous one so at that point I should somehow wait for timer to count to 0 and than load new val. But how can I identify in realtime when timer is rollover?
    Note: Now I am refreshing values for timer in main loop at 1kHz.
  • Hello Djedjica

    I think you should be using the Timeout interrupt status to find the rollover point rather than reading the current timer counter.
  • Here is my config for WTIMER5 with interrupt

    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER5);
    GPIOPinConfigure(GPIO_PD6_WT5CCP0);
    GPIOPinTypeTimer(GPIO_PORTD_BASE, GPIO_PIN_6);
    ulPeriod = SysCtlClockGet()/2;
    dutyCyclePWM2 = (unsigned long)(ulPeriod-1)*(1-(5.0/100.0));
    TimerConfigure(WTIMER5_BASE, (TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PWM));
    TimerLoadSet(WTIMER5_BASE, TIMER_A, ulPeriod-1);
    TimerMatchSet(WTIMER5_BASE, TIMER_A, dutyCyclePWM2);
    TimerIntRegister(WTIMER5_BASE, TIMER_A, updatefreq);
    TimerIntEnable(WTIMER5_BASE, TIMER_TIMA_TIMEOUT);
    IntEnable(INT_WTIMER5A);
    TimerEnable(WTIMER5_BASE, TIMER_A);

    Also added interrupt in startup file but interrupt has never occured. I assumed to make update for match and load in interrupt if freq is changed. Is that OK or I am getting something wrong?

  • Hello Djedjica

    In case of the PWM mode it is the TIMER_DMA_CAPEVENT_A status bit in the interrupt registers that corresponds to the matched event. Once the matched event occurs you have a certain amount of time to update the Load and Match value before the timeout occurs.