InBuilt RTC Implementation for nrf54l15 nordic MCU

My task is to implement inbuilt RTC for nordic MCU nrf54l15 series.

When i use the below API nrfx_grtc_init, it is throwing a error and returning a error code which is saying Zephyr already initialized GRTC internally.

is it true ? if not, how i can use the API for initialising the RTC , any other API we need to use?
provide inputs in going forward.



//Initialize GRTC
// nrfx_err_t err = nrfx_grtc_init(GRTC_IRQ_PRIORITY);
// if (err != NRFX_SUCCESS)
// {
// printk("nrfx_grtc_init() failed with code: %d\n", err);
// // prints NRFX_ERROR_ALREADY =195887116 error code
// // Zephyr already initialized GRTC internally
// return;
// }

  • Also, i am using the below IRQ handler for nrf54l15, is it the correct one to use ? suggest if any ?

    void GRTC_2_IRQHandler(void)
    {
    //nrfx_grtc_irq_handler(); // Handles internal NRFX logic
    printk(">>> GRTC IRQ Handler called <<<\n");

    // Check and clear Compare0 event
    if (nrf_grtc_event_check(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_0))
    {
    nrf_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_0);
    printk("Compare0 event occurred!\n");
    gpio_pin_toggle_dt(&led);
    printk("LED toggled!\n");

    // Schedule next compare event (every 5 seconds)
    uint64_t next_ticks = nrf_grtc_sys_counter_get(NRF_GRTC) + (TOGGLE_INTERVAL_SEC * ticks_per_sec);
    //set_grtc_compare(0, next_ticks);

    printk("Rescheduling next compare at ticks: %llu\n", next_ticks);

    nrf_grtc_sys_counter_cc_set(NRF_GRTC, 0, next_ticks);
    //nrf_grtc_event_clear(NRF_GRTC, NRF_GRTC_EVENT_COMPARE_0);
    nrf_grtc_int_enable(NRF_GRTC, NRF_GRTC_INT_COMPARE0_MASK);
    }
    }

  • I am using the below lines of code for RTC_init() and making toggle a LED every 5 seconds as per the RTC frequency ?
    are the below API's being correctly used for nrf54l15 ?
    Can i get the correct HIGH clock frequency being used for nrf54l15 MCU ? 
    provide inputs on the above 2 questions as well.

    void GRTC_Init(void)
    {
    printk("Starting GRTC LED toggle example on nRF54L15...\n");

    if (!device_is_ready(led.port))
    {
    printk("LED GPIO not ready!\n");
    return;
    }

    gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);

    //Initialize GRTC
    // nrfx_err_t err = nrfx_grtc_init(GRTC_IRQ_PRIORITY);
    // if (err != NRFX_SUCCESS)
    // {
    // printk("nrfx_grtc_init() failed with code: %d\n", err);
    // // prints NRFX_ERROR_ALREADY =195887116 error code
    // // Zephyr already initialized GRTC internally
    // return;
    // }

    // Measure actual GRTC frequency dynamically
    measure_grtc_frequency();

    /* Configure NVIC manually (no Zephyr IRQ macros) */
    NVIC_SetPriority(GRTC_2_IRQn, GRTC_IRQ_PRIORITY);
    NVIC_EnableIRQ(GRTC_2_IRQn);
    printk("NVIC IRQ enabled for GRTC_2_IRQn: %d\n", NVIC_GetEnableIRQ(GRTC_2_IRQn));

    // Schedule first compare event after 5 seconds
    // Converts seconds to ticks accurately based on actual GRTC frequency (~15.8 MHz on nRF54L15).
    uint64_t ticks = nrf_grtc_sys_counter_get(NRF_GRTC) + (TOGGLE_INTERVAL_SEC * ticks_per_sec);
    nrf_grtc_sys_counter_cc_set(NRF_GRTC, 0, ticks); //set_grtc_compare(0, ticks);

    // No nrfx_grtc_init() because Zephyr already initialized GRTC
    // Just enable interrupt for channel 0
    nrf_grtc_int_enable(NRF_GRTC, NRF_GRTC_INT_COMPARE0_MASK);

    printk("LED will toggle every 5 seconds.\n");
    }

  • Hi,

    May I ask what you will use the GRTC for? As you write, it is used by the Zephyr RTOS, and the typical way of using it is via Zephyr kernel timer APIs. Unless there is a need to use the GRTC directly, I advice against it.

    You cannot stop/start or change "global" configurations of the GRTC, as it is used by the system. In principle you can use available CC channels and interrupts as long as you don't touch anything used by the Zephyr kernel or MPSL, though. For MPSL it is documented that it used GRTC_3_IRQn for interrupt and GRTC channels 7 to 11 (so you cannot use the IRQ you have selected).

    From your code snippets I see you use interrupts and then I do not see major with using it that way instead of using Zephyr timer APIs (if you had a need to use it with PPI, that could have been different).

  • GRTC is used for synchronization b/w subsystems, wakeup events, timestamping events, low power operations, comparing channels. It provides global time base.

    I am trying to implement inbuilt RTC for nrf54l15 MCU, can you please provide inputs in implementing this?

    a.) can i use COUNTER api's to implement inbuilt RTC ?
    b.) Can i use nrfx APIs ?

    Suggest which way is better to proceed further on implementing inbuilt RTC ?

  • Hi,

    Using the GRTC directly is tricky, as it is "own" by the Zephyr kernel and the MPSL. With the use case you describe I do not see any benefits of using it directly instead of using normal Zephyr timerAPIs? Note that when you use this, the GRTC is used under the hood, and that is the recommended and supported way to use it.

Related