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

Using more than 4 buttons with GPIOTE interrupts

Hi,

I am using GPIOTE interrupts to detect button presses. It works fine but there are only four channels in GPIOTE->EVENTS_IN[] and each channel can only be assigned to one pin. How should I do if I want to implement more than 4 buttons?

Basically I set up GPIOTE like this:

  pinInput(pin); // make sure the pin is set as input
  NRF_GPIOTE->CONFIG[channel] = (static_cast<uint32_t>(transitionMode) << GPIOTE_CONFIG_POLARITY_Pos) |
      (pin << GPIOTE_CONFIG_PSEL_Pos) |
      (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);
  NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Set << channel; // @warning: we should use bitfields instead
  NRF_GPIOTE->EVENTS_IN[channel] = 0;

and in the GPIOTE_IRQHandler I check which channel has been interrupted and send an appropriate callback.

I do not use any sd by the way.

Thanks!

Parents
  • Hi Aryan,

    Thanks for your reply. I tried using port but I am having som problems with it. In my test program I want to use one button to toggle a green LED. In a while loop a red LED is blinking. When I press the button the green LED is not toggled and the red LED stops blinking, I interpret that as that the program is stuck somewhere. I can't figure out why this does not work. Can you see the problem in my code?

    void GPIOTE_IRQHandler(void) {
      // If PORT event has been called, clear event and toggle LED
      if (NRF_GPIOTE->EVENTS_PORT) {
        NRF_GPIOTE->EVENTS_PORT = 0;
    
        pinToggle(LED_GREEN);
      }
    }
    
    int main() {
      setupLEDPins();
    
      // Set Menu button as input
      nrf_gpio_cfg_input(BUTTON_MENU_PIN, NRF_GPIO_PIN_NOPULL);
    
      // Enable sense on the Menu button
      nrf_gpio_cfg_sense_input(BUTTON_MENU_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);
    
      // Set the GPIOTE PORT event as interrupt source
      NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
    
      // Enable interrupts for GPIOTE
      NVIC_EnableIRQ(GPIOTE_IRQn);
    
      // Toggle red LED to show life sign
      while (1) {
        pinToggle(LED_RED);
        delayMs(100);
      }
      return 0;
    }
    
  • did you try running this in debugger, click the run button for few seconds and then click stop. Debugger will tell you where the code is stuck, that should give you clear hints.

Reply Children
No Data
Related