GPIOTE on *Both* P0 & P1 GPIOs in NRF52840

Hello,

I would like to attach interrupts to the following pins on the P0 GPIO and the P1 GPIO:

P0:

  • 21
  • 23
  • 27

P1:

  • 11
  • 12
  • 13
  • 14
  • 15

However, it seems that there is only one GPIOTE instance on the NRF52840 (which corresponds to P0).

How would I go about attaching interrupts to the P1 pins?

To give you some background, I am developing on an Arduino Nano 33 BLE, and would like to have interrupts attached to pins on both GPIO instances through its NRF52840.

Right now, the calling the function: init_gpio_interrupts() causes the board to freeze a few 100 clock cycles later.

// Rising Edge Interrupt for GPIO (D2-9) Events
extern "C" void GPIOTE_IRQHandler_v() {
  if (NRF_GPIOTE->EVENTS_IN[0] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[0] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[1] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[1] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[2] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[2] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[3] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[3] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[4] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[4] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[5] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[5] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[6] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[6] = 0;
    
    // Code Here
  }
  else if (NRF_GPIOTE->EVENTS_IN[7] == 1)
  {
    NRF_GPIOTE->EVENTS_IN[7] = 0;
    
    // Code Here
  }
}


#define GPIO_P0 0UL
#define GPIO_P1 1UL

#define D2_PIN_NUM 11UL
#define D3_PIN_NUM 12UL
#define D4_PIN_NUM 15UL
#define D5_PIN_NUM 13UL
#define D6_PIN_NUM 14UL
#define D7_PIN_NUM 23UL
#define D8_PIN_NUM 21UL
#define D9_PIN_NUM 27UL

constexpr uint32_t GPIOTE_PIN_NUMS[] = {D2_PIN_NUM, 
                                        D3_PIN_NUM, 
                                        D4_PIN_NUM, 
                                        D5_PIN_NUM, 
                                        D6_PIN_NUM, 
                                        D7_PIN_NUM, 
                                        D8_PIN_NUM, 
                                        D9_PIN_NUM};

constexpr uint32_t GPIOTE_PINS[] = {D2, 
                                    D3, 
                                    D4, 
                                    D5, 
                                    D6, 
                                    D7, 
                                    D8, 
                                    D9};

constexpr uint32_t NUM_GPIOTE_PINS = sizeof(GPIOTE_PINS) / sizeof(uint32_t);

enum NRF_GPIOTE_CONFIG_POS
{
  GPIOTE_CONFIG_MODE_POS     = 0UL,
  GPIOTE_CONFIG_PSEL_POS     = 8UL,
  GPIOTE_CONFIG_PORT_POS     = 13UL,
  GPIOTE_CONFIG_POLARITY_POS = 16UL,
  GPIOTE_CONFIG_OUTINIT_POS  = 20UL
};

void configure_digital_pins_for_gpiote()
{
  NRF_GPIOTE->CONFIG[0] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D7_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);

  NRF_GPIOTE->CONFIG[1] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D8_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
  
  NRF_GPIOTE->CONFIG[2] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D9_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
                          
  NRF_GPIOTE->CONFIG[3] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D2_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);

  NRF_GPIOTE->CONFIG[4] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D3_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);

  NRF_GPIOTE->CONFIG[5] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D4_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);

  NRF_GPIOTE->CONFIG[6] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D5_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);

  NRF_GPIOTE->CONFIG[7] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                          (D6_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                          (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                          (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
}

void configure_gpiote_for_events()
{

  configure_digital_pins_for_gpiote();

  // Enable GPIOTE Interrupts
  nrf_gpiote_int_enable(NRF_GPIOTE_INT_IN0_MASK |
                        NRF_GPIOTE_INT_IN1_MASK |
                        NRF_GPIOTE_INT_IN2_MASK |
                        NRF_GPIOTE_INT_IN3_MASK |
                        NRF_GPIOTE_INT_IN4_MASK |
                        NRF_GPIOTE_INT_IN5_MASK |
                        NRF_GPIOTE_INT_IN6_MASK |
                        NRF_GPIOTE_INT_IN7_MASK);

  NVIC_SetVector(GPIOTE_IRQn, (uint32_t)&GPIOTE_IRQHandler_v);
  NVIC_SetPriority( GPIOTE_IRQn, 1UL );
  NVIC_EnableIRQ( GPIOTE_IRQn );
  
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///   
///   INITIALIZATION
///   
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void init_gpio_interrupts()
{
  init_event_buffer_ptrs();
  
  configure_gpiote_for_events();
}

Thanks!

Parents Reply Children
  • Hi Priyanka,

    Thanks for showing me that ticket. This is my current (nonworking) implementation. I will continue to investigate why the SWI0_EGU0_IRQHandler_v is not triggering when I start the "configure_gpiote_for_events()" function.

    I'll keep your team updated.

    // Rising Edge Interrupt for GPIO (D2-9) Events
    extern "C" void SWI3_IRQHandler_v() {
      pinMode(LEDG, OUTPUT);
      if (NRF_EGU3->EVENTS_TRIGGERED[0] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[0] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[1] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[1] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[2] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[2] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[3] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[3] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[4] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[4] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[5] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[5] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[6] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[6] = 0;
        
        // Code Here
      }
      else if (NRF_EGU3->EVENTS_TRIGGERED[7] == 1)
      {
        NRF_EGU3->EVENTS_TRIGGERED[7] = 0;
        
        // Code Here
      }
    }
    
    #define GPIO_P0 0UL
    #define GPIO_P1 1UL
    
    // P0
    #define D7_PIN_NUM 23UL
    #define D8_PIN_NUM 21UL
    #define D9_PIN_NUM 27UL
    
    // P1
    #define D2_PIN_NUM 11UL
    #define D3_PIN_NUM 12UL
    #define D4_PIN_NUM 15UL
    #define D5_PIN_NUM 13UL
    #define D6_PIN_NUM 14UL
    
    
    constexpr uint32_t GPIOTE_PINS[] = {D2, 
                                        D3, 
                                        D4, 
                                        D5, 
                                        D6, 
                                        D7, 
                                        D8, 
                                        D9};
    
    constexpr uint32_t NUM_GPIOTE_PINS = sizeof(GPIOTE_PINS) / sizeof(uint32_t);
    
    enum NRF_GPIOTE_CONFIG_POS
    {
      GPIOTE_CONFIG_MODE_POS     = 0UL,
      GPIOTE_CONFIG_PSEL_POS     = 8UL,
      GPIOTE_CONFIG_PORT_POS     = 13UL,
      GPIOTE_CONFIG_POLARITY_POS = 16UL,
      GPIOTE_CONFIG_OUTINIT_POS  = 20UL
    };
    
    /**
     * Configure the Digital Pins for input
     */
    void configure_digital_pins()
    {
      NRF_P0->PIN_CNF[23] = 0x0UL;
      NRF_P0->PIN_CNF[21] = 0x0UL;
      NRF_P0->PIN_CNF[27] = 0x0UL;
      
      NRF_P1->PIN_CNF[11] = 0x0UL;
      NRF_P1->PIN_CNF[12] = 0x0UL;
      NRF_P1->PIN_CNF[15] = 0x0UL;
      NRF_P1->PIN_CNF[13] = 0x0UL;
      NRF_P1->PIN_CNF[14] = 0x0UL;
    }
    
    /**
     * Configure the Digital Pins on the Nano 33 for GPIOTE Signalling
     */
    void configure_digital_pins_for_gpiote()
    {
      configure_digital_pins();
      
      NRF_GPIOTE->CONFIG[0] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D7_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    
      NRF_GPIOTE->CONFIG[1] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D8_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
      
      NRF_GPIOTE->CONFIG[2] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D9_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P0                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
                              
      NRF_GPIOTE->CONFIG[3] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D2_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    
      NRF_GPIOTE->CONFIG[4] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D3_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    
      NRF_GPIOTE->CONFIG[5] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D4_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    
      NRF_GPIOTE->CONFIG[6] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D5_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    
      NRF_GPIOTE->CONFIG[7] = (1UL                        << GPIOTE_CONFIG_MODE_POS)     |
                              (D6_PIN_NUM                 << GPIOTE_CONFIG_PSEL_POS)     |
                              (GPIO_P1                    << GPIOTE_CONFIG_PORT_POS)     |
                              (NRF_GPIOTE_POLARITY_LOTOHI << GPIOTE_CONFIG_POLARITY_POS);
    }
    
    /**
     * Configure the PPI for GPIOTE Events
     */
    void configure_ppi_for_gpiote()
    {
      NRF_PPI->CH[0].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];
      NRF_PPI->CH[0].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[0];
    
      NRF_PPI->CH[1].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[1];
      NRF_PPI->CH[1].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[1];
    
      NRF_PPI->CH[2].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[2];
      NRF_PPI->CH[2].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[2];
    
      NRF_PPI->CH[3].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[3];
      NRF_PPI->CH[3].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[3];
    
      NRF_PPI->CH[4].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[4];
      NRF_PPI->CH[4].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[4];
    
      NRF_PPI->CH[5].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[5];
      NRF_PPI->CH[5].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[5];
    
      NRF_PPI->CH[6].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[6];
      NRF_PPI->CH[6].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[6];
    
      NRF_PPI->CH[7].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[7];
      NRF_PPI->CH[7].TEP = (uint32_t)&NRF_EGU3->TASKS_TRIGGER[7];
    
      NRF_PPI->CHENSET = 0x000000FFUL;
    }
    
    void configure_gpiote_for_events()
    {
    
      configure_digital_pins_for_gpiote();
    
      NVIC_DisableIRQ( SWI3_IRQn ); 
      NVIC_ClearPendingIRQ( SWI3_IRQn );
    
      configure_ppi_for_gpiote();
    
      NRF_EGU3->INTENSET = 0x000000FFUL;
      
      NVIC_SetPriority( SWI3_IRQn, 7UL );
      NVIC_EnableIRQ( SWI3_IRQn );
    
      while(1);
    }

Related