GPIO interrupt custom callback data

Hi,

I just started looking around with the NRF52840 development kit and tried to implement simple GPIO interrupt based on the button sample.

I settled multiple GPIO pins configured in interrupt mode and wanted to use only one callback function to handle them but can't find a way to know which pin/device tree object has triggered the call.

I found that we might be able to do a relation between the last argument given to the callback handler (uint32_t pins, that seems to be pin mask value) but it really seems ugly to do so.

Am I missing something or do I have to declare/define dedicated callback function for each interrupt ?

Thanks !

Parents
  • For now, I've done something like this as a workaround to identify which pin triggered the common callback :/

    #include <zephyr/zephyr.h>
    #include <zephyr/drivers/gpio.h>
    #include <math.h>
    
    
    #define SW0_NODE DT_ALIAS(sw0)
    #define SW1_NODE DT_ALIAS(sw1)
    
    #if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
    #error "Unsupported board: sw0 devicetree alias is not defined"
    #endif
    #if !DT_NODE_HAS_STATUS(SW1_NODE, okay)
    #error "Unsupported board: sw1 devicetree alias is not defined"
    #endif
    
    static const struct gpio_dt_spec swUp = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
    static const struct gpio_dt_spec swDown = GPIO_DT_SPEC_GET_OR(SW1_NODE, gpios, {0});
    
    static struct gpio_callback swUp_cb_data;
    static struct gpio_callback swDown_cb_data;
    
    /* Interrupt routine: must be kept whithout blocking calls */
    void btn_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
    
      if(pins == (uint32_t)pow(2, (double)swUp.pin)) { // It is SW0_NODE
        // Doing stuff
      } else if(pins == (uint32_t)pow(2, (double)swDown.pin)) { // It is SW1_NODE
        // Doing other stuff
      }
      // ...
    }
    
    int set_pin_int_cb(const struct gpio_dt_spec itr_pin, gpio_callback_handler_t cb, struct gpio_callback *itr_pin_cb_data) {
      // ...
      
      gpio_init_callback(itr_pin_cb_data, cb, BIT(itr_pin.pin));
      gpio_add_callback(itr_pin.port, itr_pin_cb_data);
    }
    
    void main(void) {
      
      set_pin_int_cb(swUp, &btn_pressed, &swUp_cb_data); // Initialising GPIO interrupt here as in basic/button sample
      set_pin_int_cb(swDown, &btn_pressed, &swDown_cb_data);
      
      while(1) { ... }
    
      return;
    }

Reply
  • For now, I've done something like this as a workaround to identify which pin triggered the common callback :/

    #include <zephyr/zephyr.h>
    #include <zephyr/drivers/gpio.h>
    #include <math.h>
    
    
    #define SW0_NODE DT_ALIAS(sw0)
    #define SW1_NODE DT_ALIAS(sw1)
    
    #if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
    #error "Unsupported board: sw0 devicetree alias is not defined"
    #endif
    #if !DT_NODE_HAS_STATUS(SW1_NODE, okay)
    #error "Unsupported board: sw1 devicetree alias is not defined"
    #endif
    
    static const struct gpio_dt_spec swUp = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
    static const struct gpio_dt_spec swDown = GPIO_DT_SPEC_GET_OR(SW1_NODE, gpios, {0});
    
    static struct gpio_callback swUp_cb_data;
    static struct gpio_callback swDown_cb_data;
    
    /* Interrupt routine: must be kept whithout blocking calls */
    void btn_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
    
      if(pins == (uint32_t)pow(2, (double)swUp.pin)) { // It is SW0_NODE
        // Doing stuff
      } else if(pins == (uint32_t)pow(2, (double)swDown.pin)) { // It is SW1_NODE
        // Doing other stuff
      }
      // ...
    }
    
    int set_pin_int_cb(const struct gpio_dt_spec itr_pin, gpio_callback_handler_t cb, struct gpio_callback *itr_pin_cb_data) {
      // ...
      
      gpio_init_callback(itr_pin_cb_data, cb, BIT(itr_pin.pin));
      gpio_add_callback(itr_pin.port, itr_pin_cb_data);
    }
    
    void main(void) {
      
      set_pin_int_cb(swUp, &btn_pressed, &swUp_cb_data); // Initialising GPIO interrupt here as in basic/button sample
      set_pin_int_cb(swDown, &btn_pressed, &swDown_cb_data);
      
      while(1) { ... }
    
      return;
    }

Children
Related