This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Wake up from GPIO pin

Hi,

I am struggling with a low power consumption solution for waking the NRF52832 with our product which is using a third part module.

Currently our product total power consumption is 20uA during nrf_pwr_mgmt_run() (which is fine for now, it has allot of other devices on board which take up a big portion of this 20uA).

We have several inputs connected to GPIO pins (but only one at the moment for testing). We need to be able to wake the device from nrf_pwr_mgmt_run() but we also need to know which pin caused this wake up.

The inputs we want to use are pulled to ground when activated and pulled up with the pullup inside the NRF52832 during idle.

Currently I tried the following 2 solutions, which both have issues:

void in_pin_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	switch(pin)
	{	case 31:
			//BuzzerOK();
		break;
	}
}

void GPIO_init(void)
{   ret_code_t err_code;
    err_code = nrfx_gpiote_init();
    APP_ERROR_CHECK(err_code);		
    
    nrfx_gpiote_in_config_t in_config31 = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true); // Set hi_accu to true to use IN_EVENT. 
    in_config31.pull = NRF_GPIO_PIN_PULLUP;
    err_code = nrfx_gpiote_in_init(31, &in_config31, in_pin_handler); // in_pin_handler = IN_EVENT
    nrfx_gpiote_in_event_enable(31, true);
}

Above works fine for waking up and knowing what pin did it, however the power consumption during nrf_pwr_mgmt_run(); is way too high when I enable the event with nrfx_gpiote_in_event_enable(). I am using a uA meter which is 100uA max and it goes off this scale.

I also tried this:

void GPIO_init(void)
{   ret_code_t err_code;
    err_code = nrfx_gpiote_init();
    APP_ERROR_CHECK(err_code);		
    
    nrf_gpio_cfg_sense_input(31, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
}

Which seem to work fine for waking it up and with no power issue during nrf_pwr_mgmt_run()  (20uA again), but I have no way of knowing what IO caused the wakeup (or at least I cannot find it in the documentation).

I am having trouble finding a good solution for this.

  • The minimum pulse width needed trigger DETECT Signal(which in turn will trigger the SENSE signal) is around 10uS. However, if you're using the GPIOTE driver then a longer pusle width is required for GPIOTE PORT events compared with PIN events. This is because when using port events, GPIOTE_IRQHandler in nrf_drv_gpiote.h checks the status of each gpio to figure out which gpio that was trigged when the PORT event occurred.

    Therefore, since the GPIOTE handler checks the state of each enabled  pin for PORT events, the triggered pin has to stay high (or low) until that operation is finished.

    It might be possible to modify the GPIOTE_IRQHandler so that it fits your application e.g. checks the pins with the shortest pulse first or similar. 

     Note: Since the radio has higher priority than GPIOTE when using the softdevice, software processing of the GPIOTE interrupt is delayed until the radio has finished its operations.

  • thats..... pretty insanly long... Our old product has a LPC11E68 Cortex M0+ MCU which this 10uS works fine with and is able to set wakeup events that know what pin caused the wakeup. Is there no way we can have something similar on NRF52832? Or is reading NRF_GPIO -> LATCH maybe an option when we resume from nrf_pwr_mgmt_run() to know this?

  • 10uS is the number I got from R&D, but they also stated that its conservative.  It was chosen as the recommended pulse length in order to avoid marginal designs where external factors reduce the actual pulse width seen by the device.

    Were you able to detect the 10uS pulse with the IN event enabled or do you see the same behaviour as with the Port event?

  • with the IN event it detected just fine. With the port event, it misses it all the time, even with the BLE stack disabled. So I guess we dont have a choice to make it a delayed flank with some RC components.

  • OK, you do not enter the GPIOTE_IRQHandler at all when using the port event? IF that is the case then yes, you will have to add some external circuitry.

Related