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

nRF51822 and Zephyr: GPIO interrupt on multiple GPIOs

Hello, guys!

I am using nRF51822 SoC with Zephyr. There is a need to configure multiple GPIOs as inputs, with the possibility to fire an interrupt on rising/falling/both edges.
The following piece of code is used to configure one single GPIO:

#define GPIO_PORT DT_LABEL(DT_NODELABEL(gpio0))
const struct device *gpio0;
struct gpio_callback callback;
void Touch1IrqCallback(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins);
    
gpio0 = device_get_binding(GPIO_PORT);

gpio_pin_configure(gpio0, Pin1, GPIO_INPUT | GPIO_PULL_UP);
gpio_pin_interrupt_configure(gpio0, Pin1, GPIO_INT_EDGE_BOTH);
gpio_init_callback(&callback, Touch1IrqCallback, BIT(Pin1));    
gpio_add_callback(gpio0, &callback);



Everything works well until the point when I want to configure 3rd GPIO the same way. At that moment, gpio_pin_interrupt_configure() function returns -19 which is the code for ENODEV.

Is there anything I am missing or I am not aware of? Can we configure multiple nRF51822 GPIOs to fire an interrupt?

Parents
  • Hi,

     

    I highly suspect that it's this call that returns ENODEV:

    https://github.com/nrfconnect/sdk-zephyr/blob/v2.7.0-ncs1/drivers/gpio/gpio_nrfx.c#L60

     

    The nRF51 devices has 4 GPIOTE channels available, are you using any of them in other parts of your application?

     

    Kind regards,

    Håkon

  • Hello, Hakon.

    Thanks for the clarifications. I don't use GPIOTE channels in other parts of the code.

    Perhaps the error occurs because I have 2xGPIOs sensitive to BOTH edges?

    Regards,

    Bojan

  • Hello, Hakon.

    Here is how I tried to initialize GPIOs used to catch external interrupts:

    /* Touch Pads */
    #if DT_NODE_HAS_STATUS(DT_NODELABEL(touchpadsgpio), okay)
    	tp1GpioDevice = device_get_binding(DT_LABEL(DT_PHANDLE(DT_NODELABEL(touchpadsgpio), tp1_gpio)));
    	tp1Pin = DT_PROP(DT_NODELABEL(touchpadsgpio), tp1_pin);            
    	gpio_pin_configure(tp1GpioDevice, tp1Pin, GPIO_INPUT | GPIO_PULL_UP);
    	gpio_pin_interrupt_configure(tp1GpioDevice, tp1Pin, GPIO_INT_EDGE_BOTH);
    	gpio_init_callback(&callback, Touch1IrqCallback, BIT(tp1Pin));    
    	gpio_add_callback(tp1GpioDevice, &callback);
    
    	tp2GpioDevice = device_get_binding(DT_LABEL(DT_PHANDLE(DT_NODELABEL(touchpadsgpio), tp2_gpio)));
    	tp2Pin = DT_PROP(DT_NODELABEL(touchpadsgpio), tp2_pin);
    	gpio_pin_configure(tp2GpioDevice, tp2Pin, GPIO_INPUT | GPIO_PULL_UP);
    	gpio_pin_interrupt_configure(tp2GpioDevice, tp2Pin, GPIO_INT_EDGE_BOTH);
    	gpio_init_callback(&callback, Touch2IrqCallback, BIT(tp2Pin));    
    	gpio_add_callback(tp2GpioDevice, &callback);
    #else 
    #error "Can't find TouchPads GPIO node!"
    #endif 
    
    /* Accelerometer */
    #if DT_NODE_HAS_STATUS(DT_NODELABEL(da217gpio), okay)	
    	int1GpioDevice = device_get_binding(DT_LABEL(DT_PHANDLE(DT_NODELABEL(da217gpio), int1_gpio)));            
    	int1Pin = DT_PROP(DT_NODELABEL(da217gpio), int1_pin);
    	gpio_pin_configure(int1GpioDevice, int1Pin, GPIO_INPUT | GPIO_PULL_DOWN);
    	gpio_pin_interrupt_configure(int1GpioDevice, int1Pin, GPIO_INT_EDGE_RISING);	                        
    	gpio_init_callback(&accCallback, AccInt1IrqCallback, BIT(int1Pin));    
    	ret = gpio_add_callback(int1GpioDevice, &accCallback);
    
    	int2GpioDevice = device_get_binding(DT_LABEL(DT_PHANDLE(DT_NODELABEL(da217gpio), int2_gpio)));
    	int2Pin = DT_PROP(DT_NODELABEL(da217gpio), int2_pin);                      
    	gpio_pin_configure(int2GpioDevice, int2Pin, GPIO_INPUT | GPIO_PULL_DOWN);
    	gpio_pin_interrupt_configure(int2GpioDevice, int2Pin, GPIO_INT_EDGE_RISING);
    	gpio_init_callback(&accCallback, AccInt2IrqCallback, BIT(int2Pin));    
    	gpio_add_callback(int2GpioDevice, &accCallback);
    #else 
    #error "Can't find DA217 GPIO node!"
    #endif 

    touchpadgpio and da217gpio are defined in .overlay file:

        da217gpio: da217gpio {
            status = "okay";
            compatible = "da217-gpio";
            int1-gpio = <&gpio0>;
            int1-pin = <15>;
            int2-gpio = <&gpio0>;
            int2-pin = <16>;
        };        
    
        touchpadsgpio: touchpadsgpio {
            status = "okay";
            compatible = "touchpads-gpio";
            tp1-gpio = <&gpio0>;
            tp1-pin = <5>;
            tp2-gpio = <&gpio0>;
            tp2-pin = <2>;
        };

    Do you have any idea why with that approach I can properly initialize only 2 GPIOs and the 3rd one is returning -19 at gpio_pin_interrupt_configure() point?

    Regards,

    Bojan

  • Hi Bojan,

     

    Try to give each pin-interrupt each own "callback" variable. It looks like you are overwriting "callback" with Touch2IrqCallback now.

    Same goes both interrupt pins on the da271gpio device, where accCallback is used on both pins.

     

    Kind regards,

    Håkon

  • It did not help, Hakon.

    I now have 4 different callback variables but am still unable to properly configure more than two GPIOs.

  • Did you try the example that I tested to see if this also gives a similar error?

     

    Kind regards,

    Håkon

  • It is working. We can now move forward.

    Thanks for your assistance, Hakon!

    Regards,

    Bojan.

Reply Children
No Data
Related