CC1314R10: Setting RTC with custom value. - No driver code found in SDK only reset is provided.

Part Number: CC1314R10


Tool/software:

Hi Team,
            In CC1314 70bit RTC is there. I want to use that for my produce (I assume it can count upto years - 70bit running on 32K crystal). So I am trying to init , set , reset, and read the RTC.
First of all I could not find any example on the SimpleLink SDK. I read some of the e2e threads and found this file, aon_rtc.h 
< https://software-dl.ti.com/simplelink/esd/simplelink_cc13x0_sdk/4.10.00.10/exports/docs/driverlib_cc13xx_cc26xx/cc13x0/driverlib/group__aonrtc__api.html>

Which has some APIs and it is matching with the reference manual. 


However, I wonder that it doesn't have an RTC set API, It has only the reset API that will set the reset bit on the control register.

So my question is that,
 can we set the RTC with our custom value during run time in CC1314R10? 
Like as follows,

void rtc_set_time(uint32_t new_sec, uint32_t new_subsec)
{
// Stop RTC
AONRTCDisable();

// Write directly to RTC registers
HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = new_sec;
HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) = new_subsec;

// Start RTC again
AONRTCEnable();
}




Also From manual I understand there is no need for channel config if we are using RTC for timing alone. channels are needed to enable when we are using events, 

--Is my understanding is correct?. 


Regards,
Muniyappan R.M

  • Hello, 

    From another E2E they recommended something like this, although I would recommend not modifying the RTC if you are actively using the radio or using the BLE stack as they both depend on specific timings from the RTC and could cause issues if modified. 

    __STATIC_INLINE void hal_rtc_sec_set_2(unsigned int sec)
    {
        AONRTCDisable();
        uint32_t diff = HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP) - HWREG(AON_RTC_BASE + AON_RTC_O_TIME);
        HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = sec;
        HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP) = diff + (uint32_t)((sec&0xFFFF)<<16);
        AONRTCEnable();
    }

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for replying back.

    I will first clearly explain my product use case.

    We are kind of building wireless sensor and gateway model. In which multiple sensors will be connected to one gateway, and all the sensors will normally be in sleep, and when their reporting time comes, they will wake up from sleep and transmit data to the gateway. Gateway will be an active network manager, and it will be continuously listening. So Gateway will be having the network time, and all the sensors should use this same time.
    When a sensor is joining or rejoining a network, the gateway will transmit the network time (simply its RTC time), and the joining sensor should configure this value to its RTC.

    So I need to set sensor's RTC whenever its joining the network (in worst case scenario I may resync my network time ).


    Now From your response,

    I would recommend not modifying the RTC if you are actively using the radio or using the BLE stack as they both depend on specific timings from the RTC and could cause issues if modified. 

    In my use case I will be using the Radio as well. So can you kindly help me to achieve my requirement? (Can I turn off the radio and update the RTC and turn it on?)

    Also I am having some doubts on the code you are sharing,

    My Init , write and read APIs are as follows,
    
    void rtc_init(void)
    {
    // Make sure RTC is off before config
    AONRTCDisable();
    AONRTCReset();
    SysCtrlAonSync(); // wait for reset done
    
    // Enable RTC module
    AONRTCEnable();
    SysCtrlAonSync(); // ensure enable applied
    }
    
    void rtc_set_time(uint32_t new_sec, uint32_t new_subsec)
    {
    // Stop RTC
    AONRTCDisable();
    SysCtrlAonSync();
    
    // Write directly to RTC registers
    HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = new_sec;
    HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) = new_subsec;
     SysCtrlAonSync();
    
    // Start RTC again
    AONRTCEnable();
    SysCtrlAonSync(); //ensure RTC start takes effect
    }
    
    uint32_t rtc_read_ms(void)
    {
    uint32_t sec = AONRTCSecGet();
    uint32_t subsec = AONRTCFractionGet();
    
    // Convert 32-bit subsecond to milliseconds
    uint32_t msec = (uint32_t)(((uint64_t)subsec * 1000ULL) >> 32);
    
    return (sec * 1000 + msec);
    }




    But In your shared code you are taking diff between the current time and channel 0 compare value, why is it so?

    __STATIC_INLINE void hal_rtc_sec_set_2(unsigned int sec)
    {
    AONRTCDisable();
    uint32_t diff = HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP) - HWREG(AON_RTC_BASE + AON_RTC_O_TIME);
    HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = sec;
    HWREG(AON_RTC_BASE + AON_RTC_O_CH0CMP) = diff + (uint32_t)((sec&0xFFFF)<<16);
    AONRTCEnable();
    }


    ***As I already asked in my question

    Also From manual I understand there is no need for channel config if we are using RTC for timing alone. channels are needed to enable when we are using events, 

    So Do I need to enable channel 0 as well?


    Sorry for asking too many questions, Kindly help me to understand this RTC functionality.
    Thanks in Advance.

    Regards,
    Muniyappan R.M

  • Hello Muniyappan R.M

    In my use case I will be using the Radio as well. So can you kindly help me to achieve my requirement? (Can I turn off the radio and update the RTC and turn it on?)

    I would recommend turning off the radio (and making sure all the commands finished), then updating the RTC before starting the radio again. 

    The code I posed was taken from another E2E, there is one of my older responses about RTC:

    There are a few ways to manipulate the RTC, one I would recommend is use the functions defined by the driver library found here. The driver library resource provides many functions that can be helpful when manipulating the RTC. 

    There are also a few other threads on E2E which discuss the use of RTC:

    RTC TIME RESET ON WATCHDOG RESET - Bluetooth forum - Bluetooth®︎ - TI E2E support forums

    CC2642R-Q1: cc2642 RTC peripheral - Bluetooth forum - Bluetooth®︎ - TI E2E support forums

    Rather than manipulating the RTC of the device itself I would recommend using a global variable you set the calculates the "offset" or delta of the current time of your parent device's RTC vs the child device's RTC, then using AONRTCSecGet() to figure out that delta and store that locally to use in your application.

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for replying back.

    I will do this one. 

    I would recommend turning off the radio (and making sure all the commands finished), then updating the RTC before starting the radio again. 


    I referred to the below and it is the same as the link that I have shared (both don't have the RTC set APIs).

    There are a few ways to manipulate the RTC, one I would recommend is use the functions defined by the driver library found here. The driver library resource provides many functions that can be helpful when manipulating the RTC



    Also, thanks for your recommendation on using the offset. But we may prefer reconfiguring the RTC of sensor device to the gateway's current network time so that It will be useful when implementing frequency hopping based on the current network time.
    So I have implemented the rtc_set_time() API as I shared and It is working. 

    As an extension to my question,If you have some time,  Can you kindly help me on implementing the Sleep and Wakeup using RTC event?.

    Till now I have configured the events on RTC channels; now I want to implement standby mode and set the wake up source as RTC event and wakeup.

    I think there is no example on standby mode in the SDK, I found some E2E threads,
    CCS/CC1310: How to set up standby mode and wake up from RTC? 

     RTOS/CC1310: Standby and wake-up by RTC 

    But I think none of them are configuring the RTC events. So can you kindly help me to achieve standby mode and wake up using RTC events?


    Thanks and Regards,
    Muniyappan R M.

  • Hello Muniyappan R M.

    I do want to ask if you are using TI-RTOS here, reason being is that messing with the RTC will also affect TI-RTOS events. 

    Next on the RTC wakeup it should be possible but there are other ways to do it as well, see the following thread that discusses RTC:

    (+) RTOS/CC1310: CC1310 : How to wakeup from Standby by timer(RTC)every 8ms - Sub-1 GHz forum - Sub-1 GHz - TI E2E support forums

    Most of the time I recommend customers to use the clock driver to generate the period for sleep and schedule the wakeup. 

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for the response. 
     

    I do want to ask if you are using TI-RTOS here, reason being is that messing with the RTC will also affect TI-RTOS events. 

    We are using FreeRTOS, not the TI-RTOS. So is it safe to manipulate RTC? . (I hope FreeRTOS timer is not based on the RTC timer.)

    Most of the time I recommend customers to use the clock driver to generate the period for sleep and schedule the wakeup. 

    In my case, the sleep period can go high, like 1 hour, 4 hours or even 12 hours (depends on the user).

    So using the clock driver, can I achieve that? (using FreeRTOS as well)


    Regards,
    Muniyappan R M.

  • Hello Muniyappan R M.

    Per the TRM we should be able to use the GPT (general purpose timer) or SysTick. For the purpose of this long sleep question I will look into GPT here. 

    The GPT can be configured as up to 32-bit one-shot/periodic timer, which if my math is correct is around 18 hours of time we can store in it (assuming its counting at a rate of 32 kHz).

    CC13x4, CC26x4 SimpleLinkTm Wireless MCU Technical Reference Manual

    So you should be able to use the GPT to create a long sleep period of 1-4-12 hours.

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for your valuable insights.

    As a conclusion, I will configure the RTC for my network time and set time on RTC after turning off the Radio operations (though your recomendation is to maintain offset variable on application and add/subtract with the RTC time value)
    For standby mode wakeup we can use GPT timer.

    ** Although I have tested the Standby mode wakeup using RTC Channel0 compare value. So If anyone needs it, they can refer to that.

    #include "ti_drivers_config.h"
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/aon_rtc.h)
    #include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
    #include DeviceFamily_constructPath(driverlib/aon_event.h)
    #include DeviceFamily_constructPath(driverlib/event.h)
    #include DeviceFamily_constructPath(inc/hw_types.h)
    #include DeviceFamily_constructPath(inc/hw_aon_rtc.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    #include DeviceFamily_constructPath(driverlib/interrupt.h)
    #include DeviceFamily_constructPath(driverlib/gpio.h)

    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26X2.h>

    #define FACTOR_SEC_TO_COMP_VAL_FORMAT 0x00010000


    //==================== Global Variables ====================
    volatile uint32_t rtc_ch0_wakeup_int = 0;
    volatile uint32_t rtc_loop_count = 0;

    //==================== RTC ISR ====================
    void rtc_isr(void)
    {
    if (AONRTCEventGet(AON_RTC_CH0))
    {
    AONRTCEventClear(AON_RTC_CH0);
    rtc_ch0_wakeup_int++;
    GPIO_toggle(CONFIG_GPIO_GLED); // Debug LED toggle at wake
    }
    }

    //==================== RTC Initialization ====================
    void rtc_init_ch0_wakeup(void)
    {
    // Disable + reset before config
    AONRTCDisable();
    AONRTCReset();
    SysCtrlAonSync();

    // Enable RTC Channel 0 (compare mode)
    AONRTCChannelEnable(AON_RTC_CH0);

    // Route CH0 to wake-up event
    /* Muni - No effect when multiple RTC channels are configured.
    * i.e If we configure RTC CH2 then MCU will wakeup from standby mode for the CH2 event also
    * */
    AONEventMcuWakeUpSet(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0);

    // Map combined interrupt (used for CH0)
    IntRegister(INT_AON_RTC_COMB, rtc_isr);
    IntEnable(INT_AON_RTC_COMB);
    IntMasterEnable();

    // Only CH0 should trigger combined event (and wake-up)
    /*Muni - currently this is no need as we configured only one RTC channel.
    *If you have already configured some other RTC channels then we may explicitly set the combine event to ensure wakeup based on our desired channel event*/
    //AONRTCCombinedEventConfig(AON_RTC_CH0);

    // Enable RTC
    AONRTCEnable();
    SysCtrlAonSync();
    }

    //==================== Enter Standby for 'sleep_seconds' ====================
    void enter_standby_for(uint32_t sleep_seconds)
    {
    uint32_t current_time = AONRTCCurrentCompareValueGet();

    // Schedule CH0 compare 'sleep_seconds' ahead
    AONRTCCompareValueSet(AON_RTC_CH0, current_time + (sleep_seconds * FACTOR_SEC_TO_COMP_VAL_FORMAT));
    AONRTCEventClear(AON_RTC_CH0);

    // Optional: Turn off LED (to avoid current draw)
    GPIO_write(CONFIG_GPIO_RLED, 0);
    GPIO_write(CONFIG_GPIO_GLED, 0);

    // Enter standby (deep sleep)
    Power_sleep(PowerCC26XX_STANDBY);

    // Execution resumes here after wake-up
    }

    //==================== MAIN EVENT LOOP ====================
    void RTC_TEST_EVENT_LOOP(void)
    {
    rtc_init_ch0_wakeup();

    while (1)
    {
    rtc_loop_count++;

    // Normal sleep duration = 60 seconds (1 minutes)
    uint32_t sleep_duration_sec = 600/10;

    GPIO_write(CONFIG_GPIO_RLED, 1);
    sleep(2);
    GPIO_write(CONFIG_GPIO_RLED, 0);

    // Enter standby for next wake-up
    enter_standby_for(sleep_duration_sec);
    }
    }

    Thanks, Alex, for your continuous support.

    Best Regards,
    Muniyappan R.M