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

NCS: How to configure gpio input pins?

Dear NCS experts,
 
can you please lend a hand at configuring gpio input pins at nRF Connect SDK (1.7.1)? Here's a short code snippet that configures pin 3 as input:
 

static struct gpio_callback gpio_button_callback;
#define BUTTON_PIN 3
 
static void button_callback(const struct device *gpiodev, struct gpio_callback *cb, uint32_t pin) {
    int isPinActive = gpio_pin_get(gpiodev, pin);
    printk("Pin: %d - isActive: %d\n", pin, isPinActive);
}
 
// This is how the gpio pins are configured.
// Error handling has been removed to keep it short.
gpio_pin_configure(dev_gpio, BUTTON_PIN, GPIO_INPUT | GPIO_INT_DEBOUNCE);
gpio_init_callback(&gpio_button_callback, button_callback, 1 << BUTTON_PIN);
gpio_add_callback(dev_gpio, &gpio_button_callback);
gpio_pin_interrupt_configure(dev_gpio, BUTTON_PIN, GPIO_INT_EDGE_BOTH);
 

 
This is basically working. When pushing or releasing the button wired to pin 3 button_callback() is executed. Strange thing, however, is that gpio_pin_get() always returns 1, even if the button is released. In which case I'd expect the returned value to be zero. Do you have any ideas how to fix this?

And second:

Another thing that causes problems is setting BUTTON_PIN to 5 in the above example, which causes the call of gpio_pin_get(gpiodev, pin) at button_callback() to assert with:
ASSERTION FAIL [(cfg->port_pin_mask & (gpio_port_pins_t)(1UL << (pin))) != 0U] @ WEST_TOPDIR/zephyr/include/drivers/gpio.h:1107
        Unsupported pin
[00:00:45.254,425] <err> os: r0/a1:  0x00000004  r1/a2:  0x00000453  r2/a3:  0x00000003
[00:00:45.254,425] <err> os: r3/a4:  0x200023c0 r12/ip:  0x00000000 r14/lr:  0x0001ae11
[00:00:45.254,425] <err> os:  xpsr:  0x41000016
[00:00:45.254,455] <err> os: Faulting instruction address (r15/pc): 0x000424aa
[00:00:45.254,455] <err> os: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
[00:00:45.254,455] <err> os: Fault during interrupt handling
 
[00:00:45.254,486] <err> os: Current thread: 0x20002f50 (idle 00)
[00:00:45.535,369] <err> fatal_error: Resetting system
 
Question here is, why is pin 5 unsupported? And how can it be made "supported"?  

The hardware is based on a nRF52832 and is working well with a firmware application based on the Mesh SDK, so, obviously, I'm missing some important NCS details here.

Your help is very much appreciated,
Thank you,
Michael.

Parents
  • Hi,

    It would be useful to have a little more information about your application.

    Are you able to get 0 from gpio_pin_get() at other times, for example if you call it outside of the callback?

    Are you building for nrf52dk_nrf52832 with the default board files? By default pin 5 is set as the RTS pin for uart0.

  • Hi Øivind,

    Thanks for your help!

    Outside the isr, gpio_pin_get(3) returns 0 - thanks for pointing in that direction! Would be nice to have it return zero from inside the isr as well, but that's easy to workaround.

    Yes, I'm building for nrf52dk_nrf52832 with the default board files. I've first tried to remove rts-pin by adding the following to the overlay:

    &uart0 {
        /delete-property/rts-pin;
    };
    

    This successfully removes rts-pin from uart0, however the app still crashes when calling gpio_pin_get(5). So I've tried to remove the complete uart0:

    / {   
       chosen {
            /delete-property/zephyr,console;
            /delete-property/zephyr,shell-uart;
            /delete-property/zephyr,uart-mcumgr;
            /delete-property/zephyr,bt-mon-uart;
            /delete-property/zephyr,bt-c2h-uart;
        };
        /delete-node/arduino_serial; 
        /delete-node/uart0;
    };
    

    Unfortunately this didn't work: uart0 is still in the device tree, and calling gpio_pin_get(5) still crashes. Do you have any other ideas how to fix the crash?

  • gpio_pin_configure(), gpio_add_callback() and gpio_pin_interrupt_configure() all return 0 if they are successful, and a negative error code on failure. Could you check if any of them return error codes?

Reply Children
  • gpio_pin_configure(), gpio_add_callback() and gpio_pin_interrupt_configure() all return zero. The interrupt happens and the callback is executed, however, calling gpio_pin_get(5) from inside the callback crashes the application.

    Maybe I should just handle the interrupt in a thread outside the isr, would be no effort, however, I'm having a bad feeling workarounding a crash without knowing the reason for the crash....

  • Ah, I'm sorry, I was mixing up a bit with another api. You need the pin in the device tree. You can add it to the overlay, like how buttons are added in the board files.

  • So the device tree overlay now looks like this:

    / {
        buttons {
            compatible = "gpio-keys";
            buttonred: button_red {
                gpios = <&gpio0 0x5 0x11>;
                label = "Button red.";
            };
        };
    };

    &uart0 {
        /delete-property/rts-pin;
        /delete-property/status;
    };

    Please note:

    • gpio pin 5 has been unassigned as uart0 rts-pin.
    • a new button has been added for pin 5 instead.

    Still the same behavior: Calling gpio_pin_get(5) at the isr crashes the firmware...

    Any ideas why it crashes and how to fix it are welcome.

    Thank you,
    Michael.

  • In your code, could you try to replicate how it is done in zephyr/samples/basic/button?

    static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(DT_NODELABEL(buttonred), gpios,
    							      {0});
    							      
    gpio_pin_configure_dt(&button, GPIO_INPUT | GPIO_INT_DEBOUNCE);
    
    gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_BOTH);
    					      
    gpio_init_callback(&gpio_button_callback, button_callback, BIT(button.pin));
    
    gpio_add_callback(button.port, &gpio_button_callback);
    
    gpio_pin_get_dt(&button);

Related