nrf54l15: RTC causing increase in sleep current

Hello Team,

I am using nrf54l15 dk for the development. In this, I am using k_sleep to put the device in system-on sleep mode. Using this, I have achieved the sleep current of 4 micro Amps with all RAM enabled. But I have a use case where I want to periodically wake the device from sleep mode. To wake up the device periodically, I configured the RTC by referring to the "Counter RTC Driver Sample" sample code from NCS v2.9.0, which provides an example of an alarm application. It sets an alarm with the desired time and sets a wake-up flag at alarm expiry. This is working as expected, but after configuring RTC sleep current is drastically increased from 4 micro Amps to 149 micro Amps, to reduce the sleep current, I tried to disable the RTC before putting the device in sleep mode, by disabling the RTC current is reduced to 4 micro Amps but here device will not wake up in a sleep mode. Below is the code snippet for the same.

int init_rtc(void)
{
	//const struct device *const counter_dev = DEVICE_DT_GET(TIMER);
	int err;

	printf("Counter alarm sample\n\n");

	if (!device_is_ready(RTC)) {
		printf("device not ready.\n");
		return 0;
	}

	counter_start(RTC);

	alarm_cfg.flags = 0;
	alarm_cfg.ticks = counter_us_to_ticks(RTC, DELAY);
	alarm_cfg.callback = test_counter_interrupt_fn;
	alarm_cfg.user_data = &alarm_cfg;

	err = counter_set_channel_alarm(RTC, ALARM_CHANNEL_ID, &alarm_cfg);
	printf("Set alarm in %u sec (%u ticks)\n",
	       (uint32_t)(counter_ticks_to_us(RTC, alarm_cfg.ticks) / USEC_PER_SEC), alarm_cfg.ticks);

	if (-EINVAL == err) {
		printf("Alarm settings invalid\n");
	} else if (-ENOTSUP == err) {
		printf("Alarm setting request not supported\n");
	} else if (err != 0) {
		printf("Error\n");
	}
}

static void test_counter_interrupt_fn(const struct device *counter_dev,
    uint8_t chan_id, uint32_t ticks,
    void *user_data)
{
    timer_wakeup = 1;

    err = counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID,
    user_data);
    if (err != 0) 
    {
        printf("Alarm could not be set\n");
    }
}

I am continuously checking the value of timer_wakeup, if it is 1, the device will wake up.

void execute_sleep_app(void)
{
    if(sleep_flag)
    {
		pm_device_action_run(UART0, PM_DEVICE_ACTION_SUSPEND);
		pm_device_action_run(UART1, PM_DEVICE_ACTION_SUSPEND);
		pm_device_action_run(RTC, PM_DEVICE_ACTION_SUSPEND);
        while(1)
        {
            k_sleep(K_SECONDS(30));
            if(get_timer_wakeup_flag())
            {
                break;
            }
        }

        if(get_timer_wakeup_flag())
        {
			pm_device_action_run(UART0, PM_DEVICE_ACTION_RESUME);
			pm_device_action_run(UART1, PM_DEVICE_ACTION_RESUME);
			pm_device_action_run(RTC, PM_DEVICE_ACTION_RESUME);
            set_timer_wakeup_flag(0);
            set_sleep_flag(0);
            //notify_wakeup(APP_BC65);
            notify_wakeup(APP_METER);
        }
    }
}
   

Can you please help to configure the RTC with a reduced sleep current? 

Along with this I came to know about GRTC but couldn't find the sample code for it.

The end goal is to wake up the device from sleep periodically. Could you help us with this query?

Thank you,

Payal

Parents Reply Children
  • Hello,

    You can use the Timer API to configure periodical wakeup

    I tried the Timer API to configure periodic wakeups. The wake-up functionality works as expected, but the sleep current has increased to 8 - 10 micro Amps. Following is the code snipped I have used to configure the periodic wake-up timer.

    #define WAKEUP_INTERVAL_MS          120000
    
    uint8_t timer_wakeup;
    
    void init_wakeup_timer(void)
    {
        k_timer_start(&wakeup_timer, K_NO_WAIT, K_MSEC(WAKEUP_INTERVAL_MS));
        k_timer_status_sync(&wakeup_timer);
    }
    
    void wakeup_handler(struct k_timer * timer)
    {
        timer_wakeup = 1;
    }
    
    uint8_t get_timer_wakeup_flag(void)
    {
        return timer_wakeup;
    }
    
    void set_timer_wakeup_flag(uint8_t val)
    {
        timer_wakeup = val;
    }

    I continuously check the value of timer_wakeup; if it is 1, action is taken to wake-up the device from sleep mode.

    void execute_sleep_app(void)
    {
        if(sleep_flag)
        {
    		pm_device_action_run(UART0, PM_DEVICE_ACTION_SUSPEND);
    		pm_device_action_run(UART1, PM_DEVICE_ACTION_SUSPEND);
    
            while(1)
            {
                k_sleep(K_SECONDS(5));
                if(get_timer_wakeup_flag() == 1)
                {
                    break;
                }
            }
    
            if(get_timer_wakeup_flag())
            {
    			pm_device_action_run(UART0, PM_DEVICE_ACTION_RESUME);
    			pm_device_action_run(UART1, PM_DEVICE_ACTION_RESUME);
                set_timer_wakeup_flag(0);
                set_sleep_flag(0);
                notify_wakeup(APP_METER);
            }
        }
    }
    

    What changes should I make to reduce the sleep current?

    I tried to stop the timer using k_timer_stop(&wakeup_timer); before putting the device in sleep mode, it reduced the sleep current to 4 micro Amps, but the device did not wake up once put in sleep mode.

    Thanks,

    Payal

  • Hi,

    Attaching a minimal sample where I used a k_timer to wakeup every 1000ms to toggle a LED: k_timer_sample_ncs290.zip

    Measured average current consumption over 60 seconds on nRF54L15 DK is about 5.4uA (VDD=3.0V) or 5.7uA (VDD=1.8V):

    Best regards,
    Jørgen

Related