nRF9161 to lowest power mode

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;
}

Parents
  • I got to this code from the example but this doesn't include restarting and/or waking up;

    #include <modem/lte_lc.h>
    void main(void)
    {
     lte_lc_power_off();
     k_sleep(K_MSEC(1000));
     NRF_REGULATORS->SYSTEMOFF = 1;
    }


    I tried this code but didn't wake up / restart either;

    #define WAKEUP_MS 5000
    
    int main(void)
    {
            // Turn off LTE modem
        lte_lc_power_off();
    
        // Wait for LTE to properly power off
        k_sleep(K_MSEC(1000));
    
        // Configure the RTC0 to wakeup from SYSTEMOFF
        NRF_RTC0->TASKS_STOP = 1;          // Stop RTC0
        NRF_RTC0->PRESCALER = 327;         // 327 => 1 tick = 1ms (32.768kHz / (327+1) = 100Hz -> 10ms per tick, adjust if needed)
        NRF_RTC0->CC[0] = WAKEUP_MS;       // Set compare value in milliseconds
        NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;  // Enable compare interrupt
        NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;  // Enable event
        NRF_RTC0->TASKS_CLEAR = 1;          // Clear the counter
        NRF_RTC0->TASKS_START = 1;          // Start RTC0
    
        // Configure wakeup source: RTC0 COMPARE0
        NRF_REGULATORS->SYSTEMOFF = 1;
        return 0;
    }

Reply
  • I got to this code from the example but this doesn't include restarting and/or waking up;

    #include <modem/lte_lc.h>
    void main(void)
    {
     lte_lc_power_off();
     k_sleep(K_MSEC(1000));
     NRF_REGULATORS->SYSTEMOFF = 1;
    }


    I tried this code but didn't wake up / restart either;

    #define WAKEUP_MS 5000
    
    int main(void)
    {
            // Turn off LTE modem
        lte_lc_power_off();
    
        // Wait for LTE to properly power off
        k_sleep(K_MSEC(1000));
    
        // Configure the RTC0 to wakeup from SYSTEMOFF
        NRF_RTC0->TASKS_STOP = 1;          // Stop RTC0
        NRF_RTC0->PRESCALER = 327;         // 327 => 1 tick = 1ms (32.768kHz / (327+1) = 100Hz -> 10ms per tick, adjust if needed)
        NRF_RTC0->CC[0] = WAKEUP_MS;       // Set compare value in milliseconds
        NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;  // Enable compare interrupt
        NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;  // Enable event
        NRF_RTC0->TASKS_CLEAR = 1;          // Clear the counter
        NRF_RTC0->TASKS_START = 1;          // Start RTC0
    
        // Configure wakeup source: RTC0 COMPARE0
        NRF_REGULATORS->SYSTEMOFF = 1;
        return 0;
    }

Children
No Data
Related