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.

LP-CC2652RB: Why does my configured timer not start?

Other Parts Discussed in Thread: SYSCONFIG

I wanted to write a wrapper over the timer functionality provided by TI to include as part of a class. Something isn't working even though i seemed to have followed the configuration provided in the timerled example. Below i have attached my code running on the empty TIRTOS provided example:

Timer.h

#ifndef USER_TIMER_H_
#define USER_TIMER_H_


#include <ti/drivers/Timer.h>
#include "User/defs.h"
#include "Debug/syscfg/ti_drivers_config.h"

class Timer
{
public:
    Timer(uint_least8_t timerIndex);
    virtual ~Timer();

    Timer_Handle* getHandle();
    void updateTimerParams(Timer_Params* newParams);
    void updateTimerMode(Timer_Mode newMode);
    void updateTimerPeriodUnit(Timer_PeriodUnits newPeriodUnit);
    void updateTimerPeriod(uint32_t newPeriod);
    void updateTimerCallback(Timer_CallBackFxn newCallback);

    EPDStatus timerStart();
    void timerStop();
    bool isCounting();

private:
    Timer_Handle handle;
    Timer_Params timerParams;
    Timer_PeriodUnits period;
    Timer_Mode timerMode;
    Timer_CallBackFxn callback;
    uint_least8_t timerIndex;
    bool isRunning;

    void initialTimerSetup();

protected:

};

#endif /* USER_TIMER_H_ */

Timer.cpp

#include <Timer.h>

Timer::Timer(uint_least8_t timerIndex) :
        timerIndex(timerIndex)
{
    // TODO Auto-generated constructor stub
    initialTimerSetup();
}

Timer::~Timer()
{
    // TODO Auto-generated destructor stub
    timerStop();
}

void Timer::initialTimerSetup()
{
    Timer_init();
    Timer_Params_init(&timerParams);
}

Timer_Handle* Timer::getHandle()
{
    return &this->handle;
}

void Timer::updateTimerParams(Timer_Params *newParams)
{
    if (nullptr == newParams)
    {
        return;
    }

    this->timerParams.periodUnits = newParams->periodUnits;
    this->timerParams.period = newParams->period;
    this->timerParams.timerMode = newParams->timerMode;
    this->timerParams.timerCallback = newParams->timerCallback;
}

void Timer::updateTimerCallback(Timer_CallBackFxn newCallback)
{
    this->timerParams.timerCallback = newCallback;
}

void Timer::updateTimerMode(Timer_Mode newMode)
{
    this->timerParams.timerMode = newMode;
}

void Timer::updateTimerPeriodUnit(Timer_PeriodUnits newPeriodUnit)
{
    this->timerParams.periodUnits = newPeriodUnit;
}

void Timer::updateTimerPeriod(uint32_t newPeriod)
{
    if (newPeriod <= 0)
    {
        return;
    }

    this->timerParams.period = newPeriod;
}

EPDStatus Timer::timerStart()
{
    this->handle = Timer_open(timerIndex, &timerParams);

    if (NULL == this->handle)
    {
        return EPDStatus::EPD_FAILURE;
    }

    auto res = Timer_start(handle);

    if (Timer_STATUS_SUCCESS == res)
    {
        isRunning = true;
    }

    return static_cast<EPDStatus>(res);
}

void Timer::timerStop()
{
    Timer_stop(handle);

    isRunning = false;
}

bool Timer::isCounting()
{
    return Timer_getCount(handle) > 0;
}

Timer initialization and setup. I call this within mainThread of empty.c that gets made as a task.

void timerTest(void);
void dummyFunc(Timer_Handle handle, int_fast16_t status);

void timerTest(void)
{
    GPIO_init();
    static Timer tim(CONFIG_TIMER_0);

    Timer_Params timerParams;
    timerParams.periodUnits = Timer_PERIOD_US;
    timerParams.period = 10 * EPD_S;
    timerParams.timerMode = Timer_CONTINUOUS_CALLBACK;
    timerParams.timerCallback = dummyFunc;

    tim.updateTimerParams(&timerParams);

    EPDStatus res = tim.timerStart();
}

void dummyFunc(Timer_Handle handle, int_fast16_t status)
{
    ++count;
}

defs.h only contains some simple defines:

#include <cstdint>

#define EPD_MAX_BUFFER 2888
#define EPD_SEND_NO_DATA 0
#define EPD_MS 1000
#define EPD_S 1000000
#define EPD_PIN_HIGH 1
#define EPD_PIN_LOW 0

typedef struct pinType_t
{
    uint_least8_t pin;
} pinType;

typedef enum
{
    EPD_SUCCESS = 0, EPD_FAILURE = -1
} EPDStatus;

Following this code with the debugger, i can see that updateTimerParams works and the timer parameters structure is correctly setup with my desired values. However, Timer_open(timerIndex, &timerParams); returns NULL and thus the timer cannot be started. The aforementioned timerled example works when tested, so it must be something wrong with my initialization steps. Moving initialTimerSetup to timerStart does not work either, so i'm guessing there's something wrong when opening the timer.

Any help would be greatly appreciated.

  • Hi A V,

    Where do you initialize CONFIG_TIMER_0?  Please again refer to the timerled example which configures a SysConfig Timer instance which, after building to generate the files, populates the Timer configuration inside the ti_drivers_config.c file.  Otherwise you can step debug and check variable/register contents to ensure that your parameter initialization and timer instance is as expected.

    Regards,
    Ryan

  • Hi Ryan,

    I have checked both configuration files and can confirm that mine is present and seemingly correct; with the exception of me having used a 16-bit timer. How can i debug this further? If i put a breakpoint on  Timer_init(); and step into the code, i get thrown to some random part of my code that doesn't have anything to do with function. 

  • You can add Timer.c/h from <SDK directory\source\ti\drivers and TimerCC26XX.c/h from <SDK directory\source\ti\drivers\timers directly into your project to debug Timer APIs through bypassing the pre-built libraries.

    Regards,
    Ryan

  • Hi Ryan and sorry for my belated response. 
    Have spent some more time debugging every possible cause of errors and have found a possible cause for this issue. The snippet below is an excerpt from Timer_open inside TimerCC26xx.c .

        if (params->timerMode != Timer_FREE_RUNNING) {
            /* Set Timer Period and Units */
            status = Timer_setPeriod(handle, params->periodUnits, object->period); // last reachable line using the debugger
            if (status != Timer_STATUS_SUCCESS) {
                Timer_close(handle);
                return (NULL);
            }
    
            /* Create the semaphore for blocking mode */
            if (params->timerMode == Timer_ONESHOT_BLOCKING) {
                object->semHandle = SemaphoreP_constructBinary(&(object->semStruct), 0);
    
                if (object->semHandle == NULL) {
                    Timer_close(handle); // however, debugger jumps here and returns NULL
                    return (NULL);
                }
            }

    I find it weird that the first inner if clause is not reachable and then the code jumps to the line marked with a comment. Cannot see the result of Timer_setPeriod either. object->semHandle is apparently NULL, but the  object->semHandle = SemaphoreP_constructBinary(&(object->semStruct), 0); doesn't seem to get executed anyways.

  • You can remove Arm Compiler Optimizations to improve debug behavior and compare the operation of the working timerled example against yours to determine the initialization parameter which is causing the issue.  You will also want to compare the .cfg files to determine whether your example has disabled semaphore operation or something similar.

    Regards,
    Ryan