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.

TIVA: Create accurate delay

Other Parts Discussed in Thread: TM4C1294NCPDT

Hello,

In order to create an accurate delay I wrote the following code:

TimerConfigure(TIMER0_BASE,  TIMER_CFG_A_ONE_SHOT);

TimerLoadSet(TIMER0_BASE, TIMER_A, 3000);

TimerEnable(TIMER0_BASE, TIMER_A);

while (TimerValueGet(TIMER0_BASE, TIMER_A) !=0);  

Cab you tell what is worng with my code ?

What is  Half-width one-shot timer compared to  Full-width one-shot timer ?


Best regards,

Z.V

 

  • Hello Zvi,

    Each timer can work in 32-bit or 16-bit mode. That is what is referred to as Half and Full Width timer.

    The configuration of the timer must use TIMER_CFG_ONE_SHOT for 32-bit mode.

    Regards
    Amit
  • Amit Ashara said:
    Each timer can work in 32-bit or 16-bit mode.

    While true - cannot certain (wide) timers work in 32/64 bit modes?   (believe they can)

    Was unaware that 16/32 bit timer must (only) use, "TIMER_CFG_ONE_SHOT for 32-bit mode."   Seems limiting - perhaps "escaped" by choosing the "wide" timer - as suggested herein...

  • Hello cb1

    On the TM4C123 only. TM4C129 does not have Wide Timers and the post was not clear on which device family it is.

    Regards
    Amit
  • Hi Amit,

    I did not know - thank you. Is this true - I thought our firm's LX4F (father to TM4C) contained wide timers. (in fact - I'm sure of that - wide timers "alive/well" on LX4F231...)
  • Hi Amit,

    Something "out of whack" here - this from our TM4C123AH MCU manual:

    The General-Purpose Timer Module (GPTM) contains six 16/32-bit GPTM blocks and six 32/64-bit Wide GPTM blocks with the following functional options:

    ■ 32/64-bit operating modes: – 32- or 64-bit programmable one-shot timer32- or 64-bit programmable periodic timer

    As you know - our small firm uses M4 MCUs from multiple vendors - and most all (ALL!) support such wide timer "32/64" bit operation...

    Unless you've "very special, "insider (i.e. hoarded) knowledge - appears that 32/64 bit timers do exist (TM4C123 (at least this one)) and that they operate beyond the limitation you prescribed, as well...

  • Hello cb1

    Both LX4F and TM4C123 have wide timer. They are the same family of device.

    Regards
    Amit
  • Thanks Amit - I must have "mis-read" your limiting the appearance of "wide timers" to TM4C129 family - only.

    That is surprising - "Cadillac family" normally is expected to contain best/brightest feature/function set...
  • Hello cb1,

    Yes that's true but were higher cost from chip die area.

    Regards
    Amit
  • Hi Amit,

    My TIVA is :  TM4C1294NCPDT

    The clock source of the timer is system clock (120MHz)

    So in order to get a delay of 480usec, the initial value of the timer is: 480E-6 * 120E6 = 57600 ticks

    Code is:

    TimerConfigure (TIMER1_BASE,  TIMER_CFG_A_ONE_SHOT);

    TimerLoadSet (TIMER1_BASE, TIMER_A, 57600);

    TimerEnable (TIMER1_BASE, TIMER_A);

    while (TimerValueGet(TIMER1_BASE, TIMER_A) !=0);  

    Should this code cause a delay of 480usec ?

    Best regards,

    Z.V

  • Hello Zvi,

    Yes that is correct. However are you operating it in 16 bit mode or 32 bit mode?

    Regards
    Amit
  • Hi Amit,

    How should I set 16 or 32 bit mode ?
    In the TivaWare sample code for timers, no mode is set.

    Best regards,
    Z.V
  • Hello Zvi,

    Configuration of a timer in 16 bit mode requires the use of the parameter TIMER_CFG_SPLIT_PAIR

    TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT);

    Also it would be advisable to use interrupt instead of a blocking while loop (your original code had a while loop with timer read value)

    Regards
    Amit
  • Hi Amit,

    My code is now:

    ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_TIMER0);

    ROM_TimerConfigure(TIMER0_BASE,  TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT);

    ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, 3000);

    ROM_TimerEnable(TIMER0_BASE, TIMER_A);

    while (ROM_TimerValueGet(TIMER0_BASE, TIMER_A) !=0);

    But the while loop hangs for ever. The value of the timer is 3000

    Best regards,

    Z.V  

  • Hi Zvi,

    After you enable a peripheral you need to wait some cycles before accessing the registers (or use any TivaWare function for it).
    Using SysCtlDelay(3); after enabling the peripheral clock should do the trick.

    I am not sure, will have to check but I believe that the timer in One shot reloads the value 3000 when it reaches 0 and only then it stops.


    Here is a example how I would create delays.
    sites.google.com/.../timer-delay
    This is for the TM4C123, everything can be used for your board except the CPU clock configuration:
    SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); // only for TM4C123 devices.

    Adding to that, I normally use the Systick timer for the example I provided above but currently I don't have a standalone example for it.
  • Yes I can confirm that in One shot mode the timer reloads to that 3000 value after reaching 0.

    As Amit said, it's best to use the interrupt, why? Because it's hard, especially by using Tivaware function, to catch the timer every tick, it's at 80Mhz after all, so it won't catch it when it reaches 0 practically always.
    So you really need a interrupt.
    Other option is checking the Raw interrupt flag inside the while instead of the timer value (remember to clear it before the while)
  • Might another (fuller) explanation compare the execution time of:

    "while (ROM_TimerValueGet(TIMER0_BASE, TIMER_A) !=0);"

    with your system clock's "machine gunning" of the timer's count value at a vastly higher rate?

    Thus - as poster Luis suggests - you're unlikely to catch that 0 count.

    If you fear or are otherwise resistant to Timer interrupts - and don't mind some (slight) imprecision - you may replace the test for "0" with a test for less than "n" - where "n" is some (experimentally determined) small number - which enables the while loop to "capture" the equality.

    In general - holding your program "hostage" via such "while loops" may not serve you well - long term...

  • Hello,

    You are right. I set a one shot up timer to a long delay (e.g 1000 usec) and then polled the timer value till is was greater that the specified delay (e.g 480 usec).

    This made an accurate delay.

    Thank you for your help,

    Z.V

  • Hi there

    1: If you want to make a delay use a following code

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerClockSourceSet(TIMER1_BASE,TIMER_CLOCK_PIOSC);
    TimerConfigure(TIMER1_BASE,TIMER_CFG_A_ONE_SHOT_UP );
    TimerIntRegister(TIMER1_BASE, TIMER_A,Timer1IntHandler); // Timer1IntHandler is the interrupt function for the timer to generate interrupt on
    completion of timer cycle
    IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    TimerEnable(TIMER0_BASE, TIMER_A);



    2: full width timer is 32 bits while half width is 16 bits
    means full width can hold 4294967295 value at most
    while half width can hold 65535 at most