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

Cannot clear 'wake on GPIO' input sense pin

The wake on GPIO is working all the time now.

Unfortunately, I want to disable it except when needed.

Here is the scenario:

  1. Power up, pushbutton pin senses clicks to allow pairing or to clear pairing, depending on number of clicks.
  2. On timeout, I want to start SYSTEMOFF for a low power mode, with a wakeup on GPIO, it works fine:

    nrf_gpio_cfg_sense_input(PIN_GPIO_WAKEUP, BUTTON_PULL, NRF_GPIO_PIN_SENSE_LOW);

    // Workaround for PAN_028 rev1.1 anomaly 22 - System: Issues with disable System OFF mechanism

    nrf_delay_ms(1);

    NRF_POWER->SYSTEMOFF = 0x1;

 

  1. When it wakes on the GPIO Pushbutton click, I then want the pushbutton to return to working as in step 1 above. I have used several attempts, all do not disable the wake on GPIO from happening while running, eg. When I click the pushbutton it resets the CPU, and starts up again. Here are the things I have tried:

nrf_gpio_cfg_sense_set(PIN_GPIO_WAKEUP,NRF_GPIO_PIN_NOSENSE);

or

nrf_gpio_cfg_sense_input(PIN_GPIO_WAKEUP, BUTTON_PULL, NRF_GPIO_PIN_NOSENSE);

or

nrf_gpio_input_disconnect(PIN_GPIO_WAKEUP);

or

setting the wake on GPIO to another unused pin

or

    nrf_gpio_cfg_input(PIO_PUSHBUTTON, NRF_GPIO_PIN_NOPULL);

 

Do you know of any way to disable wake on GPIO after its been setup,

so that I can use the pushbutton when the unit is running, since I don’t need to wake it up when its running ?!!

The wake on GPIO code is here:

    // power down CPU in specified power mode: wakeup on GPIO (pushbutton)
    nrf_gpio_cfg_sense_input(PIN_GPIO_WAKEUP, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
    // Workaround for PAN_028 rev1.1 anomaly 22 - System: Issues with disable System OFF mechanism
    nrf_delay_ms(1);
    NRF_POWER->SYSTEMOFF = 0x1;

//on wake up code to config pins:

void setup_pw_pins()
{
    nrf_gpio_cfg_input(PIN_GPIO_WAKEUP, NRF_GPIO_PIN_NOPULL);
    //1st reset GPIO by setting cfg to: Input with the input buffer disconnected, no pull, standard drives, and pin sensing disabled
    nrf_gpio_cfg_input(PIO_SEL_PIN_0, NRF_GPIO_PIN_NOPULL);        //BIT0
    nrf_gpio_cfg_input(PIO_SEL_PIN_1, NRF_GPIO_PIN_NOPULL);        //BIT1
    nrf_gpio_cfg_input(PIO_SEL_PIN_2, NRF_GPIO_PIN_NOPULL);        //BIT2
    nrf_gpio_cfg_input(PIO_SEL_PIN_3, NRF_GPIO_PIN_NOPULL);        //BIT3
    nrf_gpio_cfg_input(PIO_PUSHBUTTON, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_INTERRUPT, NRF_GPIO_PIN_NOPULL);

    nrf_gpio_cfg(PIO_LED_RED, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0D1, NRF_GPIO_PIN_NOSENSE);
    nrf_gpio_cfg(PIO_LED_BLUE, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0D1, NRF_GPIO_PIN_NOSENSE);

    nrf_gpio_cfg_input(PIO_3V_nTX_EN, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_MUX_DISABLE, NRF_GPIO_PIN_NOPULL);

    nrf_gpio_cfg_input(PIO_MUX_B, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_MUX_A, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_5V_nTX_EN, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_5V_nRX_EN, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_SUSTAIN, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_USB_EN, NRF_GPIO_PIN_NOPULL);

    nrf_delay_ms(50); //settle

    //2nd config as desired:
    nrf_gpio_cfg_input(PIO_SEL_PIN_0, NRF_GPIO_PIN_PULLUP);        //BIT0
    nrf_gpio_cfg_input(PIO_SEL_PIN_1, NRF_GPIO_PIN_PULLUP);        //BIT1
    nrf_gpio_cfg_input(PIO_SEL_PIN_2, NRF_GPIO_PIN_PULLUP);        //BIT2
    nrf_gpio_cfg_input(PIO_SEL_PIN_3, NRF_GPIO_PIN_PULLUP);        //BIT3
    nrf_gpio_cfg_input(PIO_PUSHBUTTON, NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(PIO_INTERRUPT, NRF_GPIO_PIN_NOPULL);
    //bit 5 is battery detect

    nrf_gpio_cfg(PIO_LED_RED, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0D1, NRF_GPIO_PIN_NOSENSE);
    nrf_gpio_cfg(PIO_LED_BLUE, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0D1, NRF_GPIO_PIN_NOSENSE);

    nrf_gpio_cfg_output(PIO_3V_nTX_EN);
    nrf_gpio_cfg_output(PIO_MUX_DISABLE);

    // Unlock the NFC pins as GPIO
    uint32_t nfcpins = (*(uint32_t *)0x1000120C);
    if (nfcpins & 1) {
        nrf_nvmc_write_word(0x1000120C, 0xFFFFFFFE);
        NVIC_SystemReset();
    }

    nrf_gpio_cfg_output(PIO_MUX_B);
    nrf_gpio_cfg_output(PIO_MUX_A);
    nrf_gpio_cfg_output(PIO_5V_nTX_EN);
    nrf_gpio_cfg_output(PIO_5V_nRX_EN);

    nrf_gpio_cfg_output(PIO_SUSTAIN);
    nrf_gpio_cfg_output(PIO_USB_EN);

Definition:

#define PIN_GPIO_WAKEUP PIO_INTERRUPT        /**< Wake up pin number. */

or

#define PIN_GPIO_WAKEUP PIO_PUSHBUTTON        /**< Wake up pin number. */

Parents
  • Hello,

    A wakeup pin should only cause a reset when the device is in system OFF mode (Wakeup from System OFF mode reset). Is it possible that you are seeing a code assert once the button is presses in the app?  Please add "DEBUG" to the list of pre-processor definitions and see if the program ends up in the app_error_handler() (actual handler name may be differ depending on SDK version) 

    Note that the pin must be configured with sense enabled if you are using PORT events to detect button presses.  nrf_gpio_cfg_default() can be used to configure a pin back to its reset state. 

Reply
  • Hello,

    A wakeup pin should only cause a reset when the device is in system OFF mode (Wakeup from System OFF mode reset). Is it possible that you are seeing a code assert once the button is presses in the app?  Please add "DEBUG" to the list of pre-processor definitions and see if the program ends up in the app_error_handler() (actual handler name may be differ depending on SDK version) 

    Note that the pin must be configured with sense enabled if you are using PORT events to detect button presses.  nrf_gpio_cfg_default() can be used to configure a pin back to its reset state. 

Children
  • I tried the above suggestions (DEBUG and nrf_gpio_cfg_default()), they did not work. Meanwhile I got another suggestion from Patyush Dave:

    the bit corresponding to the GPIO in the LATCH register needs to be reset by writing a ‘1’ to the bit.

    BUT I do  not know how to do the above suggestion.

    Please provide sample code, and location of where to put the change, per the above suggestion.

  • You can use nrf_gpio_pin_latch_clear() to clear bits in the latch register, but I don't think it explains why you are getting a reset when the device is not in system OFF mode. Suggest to check the NRF_POWER->RESETREAS on startup to check what the reset source is. Note that the RESETREAS register is only reset through brown out and power on reset.

  • RESETREAS reveals that there is an error causing the reset, the error is INVALID_STATE in app_timer.c timer create, line 991, for code which runs fine all the time before the error. We are not preserving RAM, but this looks like a resource problem.

    I am using this code to mask errors, so the error is happening just after wake on GPIO.

        NRF_POWER->SYSTEMOFF = 0x1;
        // Use data synchronization barrier and a delay to ensure that no failure
        // indication occurs before System OFF is actually entered.
        __DSB();
        __NOP();

  • I stopped all timers using this call:

        app_timer_stop(pwr_off_id);
        app_timer_stop(g_blink_timer_id);
        app_timer_stop(m_sec_req_timer_id);
        app_timer_stop(m_battery_timer_id);
        app_timer_stop(norecs_off_id);

    Which solves the above app_timer.c error. BUT now the error moved to this call in main.c :

        SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);

    I am trying to find the cause in this subroutine SOFTDEVICE_HANDLER_INIT, which executes all its code OK, but then causes the error at completion of the call.

  • Is there a trick to starting the softdevice after a NRF_POWER->SYSTEMOFF = 0x1; ?

    I would be OK with starting like a cold boot up, I am not preserving RAM.

Related