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.

TM4C129ENCPDT: Delay using Timer

Part Number: TM4C129ENCPDT

I am a beginner to embedded programming. I am facing issues on creating delay using TM4C129  timer,  could someone help me to troubleshoot the issue? . The IDE used is keiluV5 and the code build process is successful. I am writing a toggling value to GPIO with the provided delay in the function (1ms, 10ms etc ) (The GPIO is monitored in oscilloscope with same code without 'while(DelaySet_Flag); '  and calling the function before the begin of wait while() of main code; there the timer is working fine) . The same code is not working inside the wait while at the end of main code.  

Please find the code below

Thanks

------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 

void Delay(uint32_t Delay_value) 

{
uint32_t Timer_Count;

Timer_Count = (120000 * Delay_value); // Count calcultion for value in milli sec

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER3)){}
ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);

ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, g_ui32SysClock);             // 120Mhz

ROM_IntEnable(INT_TIMER3A);
ROM_TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerLoadSet(TIMER3_BASE, INT_TIMER3A, Timer_Count);
ROM_TimerEnable(TIMER3_BASE, TIMER_A);

DelaySet_Flag=0x01;
while(DelaySet_Flag);                        // DelaySet_Flag=0x00 in intrrupt handler, DelaySet flag is a global variable
DelaySet_Flag=0x01;

}

  • Kurian,

    There could be something on your interrupt implementation, you did not send that part. Did you test that interrupts occur?

    Also on your code, you are loading the timer with the system clock. You want to load it with the pause cycles you are are looking for. And if it is a one shot count only, for a pause, then PERIODIC ain't the best option, since you are reconfiguring the timer on the next call of the function. Another detail, it might not be too good to disable and re-enable the timer peripheral "every time the function is called".

    However, the code you presented blocks the processor on the while(DelaySet) loop. You won't be able to do anything else until the flag is set - which is not that useful; you shall aim to set some sort of semaphores, and decide on the code executions according to those. During the wait time, you shall either be sleeping or using your processor for other important tasks...

    Rgds

  • Hello Kurian,

    As Bruno right pointed out IntEnable API call is missing. Also if the intent is a delay then I would suggest One Shot mode instead of periodic mode.
  • Thank you Amit and Bruno.

    The interrupt is occurring, I have analyzed it using break points. considering the discussed points the modifications on timer configuration and the interrupt handler are as follows.  But the issue is, these codes are running in execution on detail debug analysis. but the delay function is not returning back to where it has been call. While on testing, found that the continues execution of a 1 ms delayed toggled I/O write with 'ROM_SysCtlDelay()' is working but the delay function cal is not. 

    //------------------------------------------------------------------------------------------

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER3)){}

    ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_ONE_SHOT);

    ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, g_ui32SysClock);              // 120Mhz

    //--------------------------------------------------------------------------------------------------------------------------------------------

    void Delay(uint32_t Delay_value)
    {
    uint32_t Timer_Count;

    Timer_Count = (120000 * Delay_value); // Count calcultion for value in milli sec

    ROM_IntEnable(INT_TIMER3A);
    ROM_TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
    ROM_TimerLoadSet(TIMER3_BASE, INT_TIMER3A, Timer_Count);
    ROM_TimerEnable(TIMER3_BASE, TIMER_A);

    while(DelaySet_Flag <1) {}                    //delayset flag is initially 0 


    DelaySet_Flag=0;      
    ROM_TimerIntDisable(TIMER3_BASE, TIMER_A); // Disable Timer3 interrupt
    ROM_TimerDisable(TIMER3_BASE, TIMER_A); // Disable Timer3
    }

    --------------------------------------------------------------------------------------------------------------------------------------------------------------

    void Timer3IntHandler(void)
    {
    Interrupt_Flag = (Interrupt_Flag | Timer3_interrupt);
    ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
    DelaySet_Flag++;
    }

      

  • KurianThomas said:
    the delay function is not returning back to where it has been call

    Are you saying it is returning to a wrong memory execution location? Or is it stuck in one of your conditional loops?

    Maybe you are continuously going back into the timer ISR, because you are only clearing one specific interrupt flag (TIMER_TIMA_TIMEOUT) and there might be some other flag active? See the API examples, normally inside any IRS which requires flag clearing, the sequence is: read all the flags into a variable, clear ALL the interrupts, and take the appropriate measures according to each interrupt cause stored in the variable.

  • Thank you Bruno,

    The issue is resolved. The issue was the variable 'DelaySet_Flag' was not declared as volatile( "extern volatile uint8_t DelaySet_Flag;" ) in extern call from another file.