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.

CCS/CC2650: CC2650 SysTick Interrupt

Part Number: CC2650

Tool/software: Code Composer Studio

Hello,

I'm struggling to get the SysTick interrupts working on the CC2650.  My goal is to setup a 1mS interrupt to use for system timing.  I've started my project using the rfPacketRx example project and modified accordingly.  Below are the functions I've created along with the modified Vector Map.  At the moment, I can't get the call back (Interrupt Service Routine) to compile using the SysTickIntRegister() call.  Can you help get me headed in the right direction?

Thanks,
Dan

//initialization function in the rfPacketrx.c file

void TickTimerInit(void){

SysTickDisable();
SysTickIntRegister(&TickTimerISR);
SysTickPeriodSet(48000); // 1mS interrupt timing
SysTickIntEnable();
SysTickEnable();
// HWREG(CPU_SCS_O_STCSR) = 0; //disable timer before configuring
// HWREG(CPU_SCS_O_STCSR) = 0x00000003; //enables timer and interrupt
// HWREG(CPU_SCS_O_STRVR) = 48000; //load counter register
// HWREG(CPU_SCS_NVIC_ISER0_SETENA14) = 1;//enable interrupt

} //end of void TickTimerInit(void){

//below vector map and ISR function are located in the startup_css.c file

extern void TickTimerISR(void);

#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
(void (*)(void))((unsigned long)&__STACK_END),
// The initial stack pointer
ResetISR, // The reset handler
NmiSR, // The NMI handler
FaultISR, // The hard fault handler
IntDefaultHandler, // The MPU fault handler
IntDefaultHandler, // The bus fault handler
IntDefaultHandler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // SVCall handler
IntDefaultHandler, // Debug monitor handler
0, // Reserved
IntDefaultHandler, // The PendSV handler
TickTimerISR, // The SysTick handler
IntDefaultHandler, // AON edge detect
IntDefaultHandler, // I2C
IntDefaultHandler, // RF Core Command & Packet Engine 1
IntDefaultHandler, // AON SpiSplave Rx, Tx and CS
IntDefaultHandler, // AON RTC
UART0_ISR, // UART0 Rx and Tx
IntDefaultHandler, // AUX software event 0
IntDefaultHandler, // SSI0 Rx and Tx
IntDefaultHandler, // SSI1 Rx and Tx
IntDefaultHandler, // RF Core Command & Packet Engine 0
IntDefaultHandler, // RF Core Hardware
IntDefaultHandler, // RF Core Command Acknowledge
IntDefaultHandler, // I2S
IntDefaultHandler, // AUX software event 1
IntDefaultHandler, // Watchdog timer
IntDefaultHandler, // Timer 0 subtimer A
IntDefaultHandler, // Timer 0 subtimer B
IntDefaultHandler, // Timer 1 subtimer A
IntDefaultHandler, // Timer 1 subtimer B
IntDefaultHandler, // Timer 2 subtimer A
IntDefaultHandler, // Timer 2 subtimer B
IntDefaultHandler, // Timer 3 subtimer A
IntDefaultHandler, // Timer 3 subtimer B
IntDefaultHandler, // Crypto Core Result available
IntDefaultHandler, // uDMA Software
IntDefaultHandler, // uDMA Error
IntDefaultHandler, // Flash controller
IntDefaultHandler, // Software Event 0
IntDefaultHandler, // AUX combined event
IntDefaultHandler, // AON programmable 0
IntDefaultHandler, // Dynamic Programmable interrupt
// source (Default: PRCM)
IntDefaultHandler, // AUX Comparator A
IntDefaultHandler, // AUX ADC new sample or ADC DMA
// done, ADC underflow, ADC overflow
IntDefaultHandler // TRNG event
};

void TickTimerISR(void){
//clear interrupt
clk_ticks++; //1mS Counter Variable
} //end of void TickTimerISR(void){

  • Hi Daniels,

    Are you basing your project on TI-RTOS? In that case, you would need to use the Hwi module to register the interrupts:

    dev.ti.com/.../index.html
  • I am using the rfPacketRx example so if that uses the RTOS, then yes. I still don't understand why I can't implement the SysTick Timer the way I've shown regardless of the RTOS. Do you have any examples of setting up the SysTick within the RTOS that I can review?
    Dan
  • You can implement it just as you do, (however, I would not pass the reference of the pointer to SysTickIntRegister()). You don't have to modify the actual vector table in any way. This means the code would look like:

    void TickTimerISR(void){
        // Handle interrupt
    }
    
    void startSysTick(void *arg0)
    {
        SysTickDisable();
        SysTickPeriodSet(48000); // 1mS interrupt timing
        SysTickIntRegister(TickTimerISR);
        SysTickIntEnable();
        SysTickEnable();
    }

    This will work fine, however, it is recommended to use the Hwi module if you are building on TI-RTOS so that the interrupt is handled inside the RTOS, making it safe to use different RTOS APIs inside the ISR. This would look like this:

    void TickTimerISR(void){
        // Handle interrupt
    }
    
    void startSysTick(void *arg0)
    {
        Hwi_Params hwiParams;
        Hwi_Struct hwi;
    
        SysTickDisable();
        SysTickPeriodSet(48000); // 1mS interrupt timing
    
        /* Create Hwi object for this peripheral */
        Hwi_Params_init(&hwiParams);
        hwiParams.priority = ~0; // Lowest
        Hwi_construct(&hwi, INT_SYSTICK, TickTimerISR, &hwiParams, NULL);
    
        SysTickEnable();
    }
  • Thanks M-W. I've tried both methods which compile just fine. The only issue was I thought I had to pass the interrupt function as an address based on some examples I had found.
    I still do not receive interrupts so I still missing something... After the startSysTick function called in main, I simply call IntMasterEnable(). Is there more to this than that?

    int main(void)
    {
    uint32_t txTimer;

    /* Call board init functions. */
    Board_initGeneral();
    TickTimerInit();
    IntMasterEnable();

    I'm not sure which register to check for the IntMasterEnable function as when I step through, the debugger gets lost looking for a source file so I can't see what registers this call is setting/clearing etc to verify that global interrupts are being enabled.

    Can't find a source file at "C:\Jenkins\jobs\FWGroup-DriverLib\workspace\modules\output\cc26xx_cha_2_2_ext\driverlib\bin\ccs/./../../../driverlib/cpu.c"
    Locate the file or edit the source lookup path to include its location.

    I'm guessing this is the issue but no clue what the tool is looking for as these are built in function calls.

    Regards,
    Dan
  • Hi Daniel,

    I ran this precise code and it worked for me:

    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/systick.h)
    #include DeviceFamily_constructPath(driverlib/interrupt.h)
    
    /*
     *  ======== main ========
     */
    void TickTimerISR(void){
        // Handle interrupt
    }
    
    int main(void)
    {
    
        SysTickDisable();
         SysTickPeriodSet(48000); // 1mS interrupt timing
         SysTickIntRegister(TickTimerISR);
         SysTickIntEnable();
         SysTickEnable();
         IntMasterEnable();
    
    
         while(1) {};
    }

    Could you maybe put together an example file showing the exact steps you do all in all from start -> timer?

    I would recommend using the DriverLib documentation to get to the source of the API calls (the functions and source is well documented):

    http://dev.ti.com/tirex/content/simplelink_cc13x0_sdk_2_20_00_38/docs/driverlib_cc13xx_cc26xx/cc26x0r2/driverlib/group__interrupt__api.html#gaa6aaa682af18f11fd33a42b28e11c308

    I still recommend you using the Hwi module when working together with TI-RTOS. Furthermore, I would recommend you to not enable interrupts before the BIOS_start() call as this could impact the RTOS (this call will actually enable the global interrupts). 

    You can find the source files in the SDK folder: "<SDK>/source/ti/device/cc----/driverlib". The reason you see such a strange path in CCS is due to using the driverlib library (containing links relative to the host machine actually building it). If you browse for the SDK version, it should pop open just fine.

    Another point to the puzzle, are you planing on utilizing any low-power modes in your application? The reason I ask is because the SysTick will be inactive when the TI-RTOS power driver puts the device into standby (as done in almost all of our examples) which means the timer will not tick unless the CPU is running. 

    Have you considered simply using the Clock module in the TI-RTOS to create your system tick? It runs off the RTC and are active during standby. 

  • This is really strange.  I simply add the #include <driverlib/interrupt.h> as I noticed it in your working example.  

    Not it's working just fine...

    Thanks for the link to the RTOS documentation and assistance with this issue.

    Regards,

    Dan