This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

GPIOTE handler triggered for all registered GPIO's, when only one of them changes state

Hello, i have six buttons on my custom board, these buttons are inited with following code:

(there are pull up resistors present, hence NRF_GPIO_PIN_NOPULL is used)

SEGGER_RTT_printf(0, "buttons init.\n");

err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);

nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
in_config.pull = NRF_GPIO_PIN_NOPULL;

err_code = nrf_drv_gpiote_in_init(PIN_BTN1, &in_config, button_handler);
err_code = nrf_drv_gpiote_in_init(PIN_BTN2, &in_config, button_handler);
err_code = nrf_drv_gpiote_in_init(PIN_BTN3, &in_config, button_handler);
err_code = nrf_drv_gpiote_in_init(PIN_BTN4, &in_config, button_handler);
err_code = nrf_drv_gpiote_in_init(PIN_BTN5, &in_config, button_handler);
err_code = nrf_drv_gpiote_in_init(PIN_BTN6, &in_config, button_handler);

APP_ERROR_CHECK(err_code);

nrf_drv_gpiote_in_event_enable(PIN_BTN1, true);
nrf_drv_gpiote_in_event_enable(PIN_BTN2, true);
nrf_drv_gpiote_in_event_enable(PIN_BTN3, true);
nrf_drv_gpiote_in_event_enable(PIN_BTN4, true);
nrf_drv_gpiote_in_event_enable(PIN_BTN5, true);
nrf_drv_gpiote_in_event_enable(PIN_BTN6, true);

Problem is, that if i press any button when system is freshly booted and ready, after previous NVIC_SystemReset() , button_handler is triggered for all of the buttons at the same time.

My button_handler routine prints a debug message when it's triggered by button press, and if i press any of six buttons (when system is freshly booted), i get six subsequent messages for all of the buttons (all GPIO lines registered for GPIOTE IN events):

button_handler triggered: 10.
button_handler triggered: 15.
button_handler triggered: 17.
button_handler triggered: 36.
button_handler triggered: 9.
button_handler triggered: 38.

This looks like a hardware issue, but it happens only once, after system is booted. Then, after this first button press, all buttons work normally, without issues (one button press - one GPIOTE IN event triggered). Again, once, after reboot, when any of six buttons present on board is pressed - six GPIOTE events are triggered for all GPIO lines used for buttons. Then buttons work as expected.

All GPIO's have separate pull up resistors, nothing is common hardware wise.

 

Parents
  • Hi,

    I have not seen this issue before. Have you tested if you see the same with internal pullups configured?

    I see that you set the hi_accuracy flag of the config to false, which means that the PORT event is used for all GPIOs. The state must then be checked in the event handler, to see which pin caused the interrupt. Which SDK version are you using? If you are using SDK v17.x.x, checking of the pin states is done by reading the GPIO->LATCH register. If that is the case, what you are seeing could potentially be caused by this errata: [210] GPIO: Bits in GPIO LATCH register are incorrectly set to 1.

    Are you seeing this on multiple boards, or just one?

    Can you check using a debugger if the bits are set in the LATCH register before you push the button?

    Best regards,
    Jørgen

Reply
  • Hi,

    I have not seen this issue before. Have you tested if you see the same with internal pullups configured?

    I see that you set the hi_accuracy flag of the config to false, which means that the PORT event is used for all GPIOs. The state must then be checked in the event handler, to see which pin caused the interrupt. Which SDK version are you using? If you are using SDK v17.x.x, checking of the pin states is done by reading the GPIO->LATCH register. If that is the case, what you are seeing could potentially be caused by this errata: [210] GPIO: Bits in GPIO LATCH register are incorrectly set to 1.

    Are you seeing this on multiple boards, or just one?

    Can you check using a debugger if the bits are set in the LATCH register before you push the button?

    Best regards,
    Jørgen

Children
  • Hi Jørgen, adding internal pull up does not change anything. But indeed, when i read 0x50000520, 0x50000820, which should be LATCH for P0 and P1, i see that bits corresponding to GPIO's which are used and programmed for buttons, are set to 1. This only occurs when system is waken up from SYSTEMOFF by a button press, and does not happen when it is restarted with NVIC_SystemReset (then, all bits in LATCH for both ports are set to 0), contrary to what i wrote in initial description. 

    So how should i correct this in code?

    Workaround for this errata is: Always configure PIN_CNF[n].INPUT before PIN_CNF[n].SENSE

    My code already calls nrf_gpio_cfg_input(PIN_BTNx,NRF_GPIO_PIN_NOPULL); before calling GPIOTE init function described in initial post. I would assume that nrf_gpio_cfg_input() already does what errata suggests? 

  • To clarify:

    - i am using SDK v17.x.x.

    - I am not using high accuracy as this is battery powered device, and i would like to limit power consumption.

    - I am checking which pin is triggered in the event handler

  • Any ideas how to deal with this problem? Is there a way to reset LATCH register while initializing application?

  • You can reset latch register by writing 1 to the bits that are set (i.e. read the register and write back what you read).

    Have you checked if the LATCH bits are set before the GPIO/buttons are configured after wake from System OFF, i.e. at the very beginning of main()?

    nrf_gpio_cfg_input() writed all configs to the register in one operation, including both INPUT and SENSE, so it does not implement the workaround from the errata as far as I can see.

Related