Reliable Time Delay on Custom TI Boards Using Timer Driver

Custom TI Boards Using Timer Driver

If you’ve worked with the TI-RTOS (SYS/BIOS), you probably used Task_sleep() function for delays. It works fine on LaunchPads… until you move to a custom board. Suddenly, Task_sleep() does not behave correctly your delays are off (Time delays not working), the system doesn’t respond at all and the board will reset loop with watchdog reset.

Here’s why:
Task_sleep() depends on the RTOS clock source (like the 32 kHz crystal). On LaunchPads have this ready to go. But on custom boards, if the LF clock isn’t there or isn’t configured, Task_sleep() won’t behave.

✅ Solution: Use the TI Timer Driver for delays.
It gives you hardware-backed, reliable timing that works on any board.

How It Works

  1. Timer Initialization
    The initDelayTimer() function are creates and configures a hardware timer (CONFIG_TIMER_0) in one-shot mode with a callback.
  2. Starting the Delay
    The delay_ms() function configures the timer period in microseconds and starts the timer.
  3. Callback Execution
    When the timer is expires, delayTimerCallback() is invoked. It sets a flag (delayDone = 1) and stops the timer.
  4. Busy Wait
    The calling code waits until the flag is set, effectively creating a blocking delay.
  5. Wrapper for Seconds
    The delay() function is just a convenience wrapper for the delay_ms().

Why this is better than Task_sleep():

  • Works even without LF clock setup.
  • Exact hardware timing
  • Portable for LaunchPads and custom boards
  • Flexible for both short and long delays

⚠️ Note: Uses a busy-wait loop. For the short delays, it is fine but long delays (especially in low-power devices), replace the loop with a semaphore or event so the CPU can sleep while waiting.

Here is the implementation (Creating a delay.c for portable access):

(delay.c)
#include "delay.h"
#include <ti/drivers/Timer.h>
#include "ti_drivers_config.h"  // CONFIG_TIMER_0
static volatile uint8_t delayDone = 0;
static Timer_Handle timerHandle = NULL;
// Callback when timer expires
static void delayTimerCallback(Timer_Handle handle, int_fast16_t status)
{
    delayDone = 1;
    Timer_stop(handle);
}
// Initialize the timer (runs once)
static void initDelayTimer(void)
{
    if(timerHandle) return; // already initialized
    Timer_Params tParams;
    Timer_Params_init(&tParams);
    tParams.timerMode = Timer_ONESHOT_CALLBACK;
    tParams.timerCallback = delayTimerCallback;
    timerHandle = Timer_open(CONFIG_TIMER_0, &tParams);
    if(!timerHandle) while(1); // trap if timer creation fails
}
// Millisecond delay
void delay_ms(int milliseconds)
{
    initDelayTimer();
    delayDone = 0;
    Timer_setPeriod(timerHandle, Timer_PERIOD_US, (uint32_t)milliseconds * 1000);
    Timer_start(timerHandle);

    while(!delayDone); // Busy-wait until callback
}
// Second delay
void delay(int seconds)
{
    delay_ms(seconds * 1000);
}

(Delay.h)
#ifndef DELAY_H
#define DELAY_H

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Delay for a number of seconds
 *
 * @param seconds Number of seconds to delay
 */
void delay(int seconds);

/**
 * @brief Delay for a number of milliseconds
 *
 * @param milliseconds Number of milliseconds to delay
 */
void delay_ms(int milliseconds);
#ifdef __cplusplus
}
#endif
#endif // DELAY_H

✅ Now you created a self-contained delay library:

  • Include delay.h wherever you need to create delay.
  • Add delay.c to your project sources.
  • Ensure the Timer (CONFIG_TIMER_0) is configured in SysConfig.

Now you are got a rock-solid delays – no more surprises when moving from eval boards to the production board!.

Conclusion

While Task_sleep() works on the TI evaluation kits like LaunchPads (MSP, CC1310, CC1354, CC1653…), it often fails on custom boards due to the clock source dependencies, In my case we are using the CC1354P10-1 LaunchPad to Custom Board to facing the issue on clock source while using Task_sleep functions. The solution is to implement your own delay functions using the Timer Driver, which ensures accurate and reliable delays across all the hardware platforms.

This approach gives you full control over timing and eliminates reliance on RTOS (SYS/BIOS) tick configurations, The preferred method is for robust embedded applications :).

Leave a Reply

Your email address will not be published. Required fields are marked *