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.

CC2340R5: Wake up from standby mode using the RTC as an internal interrupt

Part Number: CC2340R5

Tool/software:

Hi,

I’m working with the CC2340R5 and have successfully implemented the rfPacketTx example code—everything is working fine so far.

I've written the RTC interrupt setup and ISR for the internal interrupt, but it's not working. Below is my code for your reference—please check and let me know what the issue might be.

#define RTC_CTL_EN       (1 << 0) // Enable bit
volatile bool rtcWakeFlag = false;

void RTC_IRQHandler(void)
{
    // Check if Compare Channel 1 (EV1) interrupt is pending
    if (HWREG(RTC_BASE + RTC_O_MIS) & RTC_MIS_EV1)
    {
        // Clear the EV1 interrupt flag
        HWREG(RTC_BASE + RTC_O_ICLR) = RTC_ICLR_EV1_CLR;

        // Set your application flag
        rtcWakeFlag = true;
    }
}

void setupRTCWakeup(uint32_t seconds)
{
    // Reset the RTC counter (if required)
    HWREG(RTC_BASE + RTC_O_CTL) = RTC_CTL_RST_CLR;

    // Enable RTC counter
    HWREG(RTC_BASE + RTC_O_CTL) |= RTC_CTL_EN;

    // Get current RTC time
    uint32_t now = HWREG(RTC_BASE + RTC_O_TIME8U); // bits [34:3] of counter
    uint32_t future = now + (seconds << 13); // RTC tick = 1/8192 s → seconds * 8192 ticks

    // Set Compare Channel 1 (CH1) to trigger at `future` time
    HWREG(RTC_BASE + RTC_O_CH1CC8U) = future;

    // Clear previous interrupt flag for EV1 (CH1)
    HWREG(RTC_BASE + RTC_O_ICLR) = RTC_ICLR_EV1_CLR;

    // Enable interrupt for EV1
    HWREG(RTC_BASE + RTC_O_IMSET) = RTC_IMSET_EV1;  // << Corrected

    // Register and enable RTC interrupt in NVIC
    IntRegister(INT_CPUIRQ0, RTC_IRQHandler);

    IntEnable(INT_CPUIRQ0);
    // Enable global interrupts
    IntEnableMaster();

}

Thanks in advance!

  • Hello Kumar,

    I hope you are doing well. While we should be able to setup the RTC to do as you have described above its usually a bit easier to use our timer functions/driver to achieve the same purpose. Is there a specific reason here you would want to use the RTC in this way instead of the ClockP/timer? 

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for your quick reply. I’ve already achieved the same functionality using ClockP. However, before starting the coding, I had designed the code architecture with the intention of waking up from standby mode using the RTC.

    If I can achieve my original architectural goal using the RTC, that would be ideal, as it aligns with my design plan and eliminates the need for further explanation.

    If there is any known issue or limitation with using the RTC for this purpose, please let me know. That way, I can clearly document in my design notes (e.g., 'goal not achieved due to a limitation with the TI chip') why the original plan couldn’t be implemented.


  • Hello Kumar,

    I will look further into the RTC interrupt/callback in this case. I believe there shouldn't be an issue making the RTC work here, but it can be a bit difficult to get started/setup with this. I may need to reach out to other internal members to see if we have any other documentation or examples on this.

    Thanks,
    Alex F

  • Hello Kumar,

    The following thread may be of good use for our case here: https://e2e.ti.com/f/1/t/1234806/.

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for your quick reply and your effort to help resolve the issue. I’ve already seen this thread, but I wasn’t able to relate it directly to my specific problem. If you understand what needs to be done, could you please make the necessary changes to my code so that it works correctly?

  • Hello Kumar,

    I worked on some code earlier (*also from the following E2E, https://e2e.ti.com/f/1/t/1500766/) and this allows us to setup/use RTC to wakeup and toggle a LED every 1 second or so; you should be able to take the code an apply it to your usecase:

    typedef struct rtc_struct_t
    {
        uint32_t                    delay_ticks;
        uint32_t                    rtc_timeout_ticks;
        HwiP_Struct                 hw_interrupt;
    } rtc_struct_t;
    rtc_struct_t rtc_struct;
    
    void rtc_isr_callback(uintptr_t arg)
    {
            rtc_struct.rtc_timeout_ticks += rtc_struct.delay_ticks;
            HWREG(RTC_BASE + RTC_O_CH0CC8U) = rtc_struct.rtc_timeout_ticks;
            GPIO_toggle((uint8_t)CONFIG_GPIO_GLED);
    }
    
    /*
     *  ======== mainThread ========
     */
    int mainThread(void)
    {
        uint32_t delay_usec;
        Board_init();
        GPIO_init();
        GPIO_setConfig(CONFIG_GPIO_GLED, GPIO_CFG_OUTPUT);
        GPIO_write(CONFIG_GPIO_GLED, 0);
    
        // Install the interrupt handler for the RTC.
        HwiP_Params rtc_params;
        HwiP_Params_init(&rtc_params);
        //rtc_params.arg = 0;
        //rtc_params.priority = INT_PRI_LEVEL2;
        HwiP_construct(&rtc_struct.hw_interrupt, INT_CPUIRQ0, rtc_isr_callback, &rtc_params);
        HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ0SEL) = EVTSVT_CPUIRQ0SEL_PUBID_AON_RTC_COMB;
        delay_usec = 1E6;
        // Update the run-time status for this timer
        rtc_struct.delay_ticks = delay_usec/8UL;
    
        // Adjust timeout value to be relative to the current time.
        rtc_struct.rtc_timeout_ticks = HWREG(RTC_BASE + RTC_O_TIME8U) + rtc_struct.delay_ticks;
        HWREG(RTC_BASE + RTC_O_CH0CC8U) = rtc_struct.rtc_timeout_ticks;
        HwiP_enableInterrupt(INT_CPUIRQ0);
    
        while (1)
        {
            sleep(10);
        }
        return 0;
    }
    

    Thanks,
    Alex F