SYSTEM ON SLEEP : Wake up on gpio interrupt and Timer

I am using nrf52832, and I want to use SYSTEM ON Sleep.
Also , my wake up sourses are timer based, and also GPIO interrupt based. 
But I observed that the device cannot go to sleep for more than approximately 4 minutes.
Code: 

#define WAKEUP_PIN 17 // Pin number for wakeup button
K_TIMER_DEFINE(my_timer, NULL, NULL);
#define  SLEEP_TIME           K_SECONDS(600) // Define sleep time as 10 seconds
#define  SLEEP_TIMER_START    k_timer_start(&my_timer, SLEEP_TIME, SLEEP_TIME)
#define  SLEEP_TIMER_STOP     k_timer_stop(&my_timer)

void  handle_sleep(void)
{
    char woke_from_gpio = 0;
    printk("Going into the sleep...!!\n\n");
   
    nrf_gpio_cfg_sense_input(WAKEUP_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    SLEEP_TIMER_START;
    pm_state_force(0u,&(struct pm_state_info){PM_STATE_SUSPEND_TO_IDLE, 0, 0}); 
    __WFI();
    if (nrf_gpio_pin_read(WAKEUP_PIN) == 0)
    {
        woke_from_gpio = 1;
    }
    SLEEP_TIMER_STOP;
    if(woke_from_gpio == 1)
    {
        f.g_Panic_sense_F = 1;
        woke_from_gpio=0;
    }  
}

  • Hello,

     
    Yes, As you suggested, I tried to use k_timer related functions alone, and the _WFI related issues are not seen anymore.

    But, earlier, my device was running on 3uA during sleep(in _WFI).
    But after making these changes, the device is taking 6.2uA in sleep. Which is not acceptable, as this is a low power device. 

    #define WAKEUP_PIN 17 /
    K_TIMER_DEFINE(my_timer, NULL, NULL);
    #define  SLEEP_TIME           K_SECONDS(600) 
    #define  SLEEP_TIMER_START    k_timer_start(&my_timer, SLEEP_TIME, K_NO_WAIT)
    #define  SLEEP_TIMER_STOP     k_timer_stop(&my_timer)
     
    void handle_sleep(void)
    {
        char woke_from_gpio = 0;
        nrf_gpio_cfg_sense_input(WAKEUP_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
        SLEEP_TIMER_START; // Start the sleep timer
        pm_state_force(0u,&(struct pm_state_info){PM_STATE_SUSPEND_TO_IDLE, 0, 0}); 
        while(1)
        {
            if (k_timer_remaining_get(&my_timer) == 0) {
                    break;
            }
            if (nrf_gpio_pin_read(WAKEUP_PIN) == 0)
            {
                woke_from_gpio = 1;
                break;
            }
            k_msleep(100);
        }
        SLEEP_TIMER_STOP;
        if(woke_from_gpio == 1)
        {
            f.g_Panic_sense_F = 1;
            woke_from_gpio=0;
        }  
    }
  • Please look at the samples that I shared with you for an event/ISR based approach.

    The reason why you are seeing a higher consumption is because you are polling every 100 ms:

    k_msleep(100);

     

    Kind regards,

    Håkon

  • You might find this code useful on ascertaining pending interrupts: how-do-i-read-the-event-register

Related