NRF52833 SLEEP MODE & WAKEUP THROUGH GPIO INTERRUPT.

Hi All,

         I have implemented sleep mode in the firmware. I am using NRF52833 in my project. When the device is in idle state it goes in sleep mode. Now I wanted to wakeup the device through GPIO interrupt. How can I wake up the device? The sleep mode is implemented as below in the attached code.

#define AQ_USER_BUTTON          NRF_GPIO_PIN_MAP(0,4)


void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
//bool erase_bonds;
   switch(pin)
   {
      case AQ_USER_BUTTON:
              NRF_LOG_INFO("ADVERTISING START\r\n");
              advertising_start(false);
            break;
   }

}

 void gpio_init(void)
{
    ret_code_t err_code;

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
    in_config.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(AQ_USER_BUTTON, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(AQ_USER_BUTTON, true);

}


static void sleep_mode_enter(void)
	{
	  ret_code_t err_code;
	  sleep = 1;
	  NRF_LOG_INFO("SLEEP MODE ENTER\r\n");
	  err_code = bsp_indication_set(BSP_INDICATE_IDLE);
	  APP_ERROR_CHECK(err_code);

	  // Prepare wakeup buttons.
	  err_code = bsp_btn_ble_sleep_mode_prepare();
	  APP_ERROR_CHECK(err_code);

	  // Go to system-off mode (this function will not return; wakeup will cause a reset).
	  err_code = sd_power_system_off();
	  // APP_ERROR_CHECK(err_code);
}

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
		uint32_t err_code;

		switch (ble_adv_evt) {
		case BLE_ADV_EVT_FAST:
		NRF_LOG_INFO("Fast advertising.");
		err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
		APP_ERROR_CHECK(err_code);
		break;

		case BLE_ADV_EVT_IDLE:
		sleep_mode_enter();
		break;

		default:
		break;
}
}





Is my code correct? what code needs to be put to wakeup the device from sleep mode and then advertise it again??

Parents
  • Hi,

    I'm not sure if using GPIOTE_CONFIG_IN_SENSE_TOGGLE() will give you the intended behavior. If you are using a button to generate the interrupt, this will trigger the handler both on push and release of the button, which will try to call advertising_init() two times. This may generate error codes and restarts, as the advertising is already started from the button push. If your signal comes from a switch or another device that only generates 1 signal, it may work. You should either way make sure that you keep track of when the advertising is enabled, and only try to enable it when it is not already enabled.

    If you are using a push-button, I would recommend that you rather use GPIOTE_CONFIG_IN_SENSE_LOTOHI() or GPIOTE_CONFIG_IN_SENSE_HITOLO based on your button connections and desired behavior.

    Best regards,
    Jørgen

  • How do you declare and set the flag in your code? Do you unset the flag anywhere?

    Did you check with a debugger/log message that the event handler is not entered, or did you just not see advertising_init() being called? 

    The double-trigger may be caused by noise/bouncing signals from the button.

Reply Children
  • Hi Jorgen,

                   I am setting a flag when we first advertise. If error code is 0 then I set the flasg adv_success. I am setting it back to 0 when device enters sleep mode. So I am checking this flag inside the interuupt handler. If flag is set to 0 only then it will advertise after switch is pressed. This is working. 

    But what I observed is that the timers are not getting initialized again after waking up. I have one timer which runs few tasks at an interval of 20seconds. How to start that after waking up??

    Thanks & Regards,

    Snehal

  • Hi Jorgen,

              Can you please help?

    I observed is that the timers are not getting initialized again after waking up. I have one timer which runs few tasks at an interval of 20seconds. How to start that after waking up??

    Thanks & Regards,

    Snehal

  • How do you configure/setup the timer? Are you using RTC/app_timer or the TIMER peripheral? As long as you only enter System ON idle mode, not System OFF, the timer can run during the sleep period. The timer will then wakeup the chip every 20 second. If you shut down the timer when going to sleep, you need to restart it when you press the button to wakeup.

    Please post your code to show what you are doing and what is not working.

Related