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;
    }
    
  • I found the error. I was missing extern "C" around my interrupt function, I should have mentioned that I was programming in C++, sorry for that. Anyway, now it finally works :)

Reply Children
No Data
Related