through RTC i am trying it but it is not happening can you give any propre example one for the sleep mode enabling and wakening up from the sleep mode.
through RTC i am trying it but it is not happening can you give any propre example one for the sleep mode enabling and wakening up from the sleep mode.
Hello,
Unfortunately, it is not possible to wake the nRF5340 from systemoff using the RTC. This is only possible on the nRF54L-series, which has a GRTC. Other nRF devices will not be able to have the RTC running in SystemOff, and hence, it is not possible to wake up from it. If you need to wake on a timer, you need to use systemOn-Idle.
You can read about systemoff on the nRF5340 here:
https://docs.nordicsemi.com/bundle/ps_nrf5340/page/chapters/reset/doc/reset.html#ariaid-title5
So from systemOff, the only things that can wake up the nRF5340 are GPIO interrupts, reset pin, power on reset or NFC. If you need to wake it up from a timer, you need to have an external timer module that can give a pulse after a given amount of time.
Best regards,
Edvin
lalith88 said:Is it automatically entered when the CPU executesWFI/WFE,
Yes, but it will also be entered whenever it doesn't have any more tasks, so e.g. by calling k_sleep(), which is typcally what you will see in the samples. Also, when you are in a Bluetooth Low Energy connection, the system on idle is the state that it will be using between the connection events (the events occuring every connection interval). So whenever the radio is done maintaining the connection, it will go back to sleep (system on). So basically all samples use this system on state.
lalith88 said:tatic void system_on_idle(void){
gpio_pin_configure_dt(&leds, GPIO_OUTPUT_ACTIVE);/* Enter low-power idle mode until any interrupt/event occurs */__WFE();__SEV();__WFE();// NRF_VMC->RAM[0].POWER = 0x0001;// NRF_VMC->RAM[1].POWER = 0;// NRF_VMC->RAM[2].POWER = 0x8000;// NRF_VMC->RAM[3].POWER = 0xFFFF;// NRF_VMC->RAM[4].POWER = 0;// NRF_VMC->RAM[5].POWER = 0;// NRF_VMC->RAM[6].POWER = 0x8000;// NRF_VMC->RAM[7].POWER = 0;/* Optional: blink LED each time CPU wakes up *///gpio_pin_toggle_dt(&leds);
/* Let other threads run / handle events */// k_msleep(1000);}
I would remove the __WFE(), __SEV(), and __WFE(), and just use k_msleep(K_MSEC(1000)); to enter system on idle for 1 second.
Here are some numbers for system on vs system off:
Best regards,
Edvin
Hello Edvin,
Thank you for sharing the details and current consumption link. I have a follow-up question:
What is the practical difference between using:
__WFE();
__SEV();
__WFE();
versus simply using k_msleep(K_MSEC(1000)); in Zephyr?
I understand k_msleep() lets the thread sleep and the scheduler manages the idle entry, while the WFE sequence forces the CPU to sleep immediately. Could you please confirm if there are advantages in power saving or interrupt handling when using one approach vs the other?
Also, as I understand, for the system to actually enter SystemOn-Idle, all other threads/events should be idle as well. What is the recommended way to manage multiple threads so the device consistently goes into SystemOn-Idle whenever possible?
This will help me decide whether to rely fully on Zephyr APIs or mix in direct WFE/SEV calls for tighter control.
Best regards,
Lalith
1: It is the same, apart that k_sleep will also set the timer for you. You can also use k_sleep(K_FOREVER) if you want to just wait for an event. In addition you have k_cpu_idle(), which will also do the same.
Note that the device will also enter sleep in k_sem_take(), while it waits for the semaphore to be free.
2: It is the same. The OS (Zephyr) will handle the threads for you, and WFE will cause your current thread to go to sleep. If all the threads are in WFE/k_sleep, then the CPU will actually go to idle.
3: You need to have all threads go to sleep when there is no more work. All of the BLE samples in NCS\nrf\samples\bluetooth does this. Study one of them, e.g. the peripheral_uart, which has two threads (main() and ble_write_thread())
Best regards,
Edvin
Hello Edvin,
Thank you for the detailed explanation — it’s clear now.
So to confirm my understanding:
__WFE(), k_sleep(), and k_cpu_idle() will all enter SystemOn-Idle.
The main advantage of using k_sleep() is that it integrates with the scheduler and handles wakeup timers.
As long as all threads are waiting (sleep/semaphore/etc.), the CPU will automatically go into SystemOn-Idle.
I’ll go through the Bluetooth samples (like peripheral_uart) as you suggested to see this in practice.
Best regards,
Lalith
Hello Edvin,
Thank you for the detailed explanation — it’s clear now.
So to confirm my understanding:
__WFE(), k_sleep(), and k_cpu_idle() will all enter SystemOn-Idle.
The main advantage of using k_sleep() is that it integrates with the scheduler and handles wakeup timers.
As long as all threads are waiting (sleep/semaphore/etc.), the CPU will automatically go into SystemOn-Idle.
I’ll go through the Bluetooth samples (like peripheral_uart) as you suggested to see this in practice.
Best regards,
Lalith