I am trying to make the nrf9161 go to very low power mode for 10 seconds and then come back online.
Actually I would not mind if it were to start all over again when coming back around but currently on my nrf9161dk I cannot achieve < 3.2mA.
I could not find any right source with an example but if someone has a good example source, please let me know. Otherwise, why doesn't the code that I provide here bring me anywhere below 3.2mA?
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <hal/nrf_power.h>
#include <hal/nrf_clock.h>
#include <hal/nrf_rtc.h>
#include <modem/lte_lc.h>
#define WAKEUP_SECONDS 10U // Sleep duration in seconds
// Start LFCLK (needed for RTC)
static void start_lfclk(void)
{
if (!NRF_CLOCK->LFCLKRUN) {
NRF_CLOCK->LFCLKSRC = 2U; // LFXO (external crystal)
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (!NRF_CLOCK->EVENTS_LFCLKSTARTED) {}
}
}
// Configure RTC0 as wake timer
static void setup_rtc_wakeup(uint32_t seconds)
{
// RTC0 runs at 32.768 kHz / (prescaler + 1)
nrf_rtc_prescaler_set(NRF_RTC0, 0);
nrf_rtc_cc_set(NRF_RTC0, 0, seconds * 32768UL);
nrf_rtc_int_enable(NRF_RTC0, NRF_RTC_INT_COMPARE0_MASK);
nrf_rtc_task_trigger(NRF_RTC0, NRF_RTC_TASK_START);
}
// Enter System OFF (deep sleep)
static void enter_system_off(void)
{
// Must power down LTE modem first
lte_lc_power_off();
// Ensure all memory operations completed
__DSB();
__WFI(); // Wait for interrupt; chip powers down
}
// Check if we woke from System OFF
static bool woke_from_system_off(void)
{
return (NRF_POWER->RESETREAS & (1U << 2)) != 0; // Bit 2 = OFF
}
// Clear wake reason
static void clear_wake_reason(void)
{
NRF_POWER->RESETREAS = NRF_POWER->RESETREAS;
}
int main(void)
{
while (1) {
if (woke_from_system_off()) {
printk("Woke from System OFF!\n");
clear_wake_reason();
} else {
printk("Power-on or other reset\n");
}
// Start LFCLK for RTC
start_lfclk();
// Set RTC wakeup
setup_rtc_wakeup(WAKEUP_SECONDS);
printk("Entering System OFF for %d seconds...\n", WAKEUP_SECONDS);
// Enter deep sleep
enter_system_off();
// Execution never reaches here in System OFF
while (1) {
k_sleep(K_MSEC(1000));
}
}
return 0;
}