multiple buttons

Dear all,

I wanted to create 10 buttons using 10 gpio pins :

int gpio_pins_0[10] = {29, 31, 10, 9, 24, 22, 20, 17, 15, 13};

When creating gpio interrupt with below enclosed code, I realized that only 4 buttons were active but no other:

const struct device *pin0 = device_get_binding("GPIO_0");
    if (!device_is_ready(pin0)) {
        printk("GPIO device %s is not ready!\n", pin0->name);
        return ret;
    }

for (int i = 0; i <= 9; i++) {
    printk("configuring pin:%d\n",i);
        gpio_pin_configure(pin0, gpio_pins_0[i], GPIO_INPUT);
    printk("init callback of pin:%d\n",i);
        gpio_init_callback(&gpio_callbacks[i], gpio_callback_handlers[i], BIT(gpio_pins_0[i]));
    printk("adding callback of pin:%d\n",i);
        gpio_add_callback(pin0, &gpio_callbacks[i]);
    printk("configuring interrupt of of pin:%d\n",i);
        ret = gpio_pin_interrupt_configure(pin0, gpio_pins_0[i], GPIO_INT_EDGE_TO_ACTIVE);
        if (ret != 0) {
            printk("cannot configure button %d on pin %d\n", i, gpio_pins_0[i]);
            return ret;
        }
    }

Therefore I had to skip so called GPIOTE method which is reduced to 4 interrupts only and use method of gpio masking in dts file this way:

&gpio0 {
status = "okay";
/* sense-edge-mask = < 0xffffffff >;*/
sense-edge-mask = <((1 << 29) | (1 << 31) | (1 << 10) | (1 << 9) | (1 << 24) | (1 << 22) | (1 << 20) | (1 << 17) | (1 << 15) | (1 << 13))>;
};

But I am seeing a rather strange behaviour when connecting voltage VDD out with every configured GPIO pin in a sense that bits 29 and 31 are working perfectly when tapping on them with the voltage, but when connecting VDD out with pin 9, callback of pin 9 as well as callback of pin 10 is triggered simultaneously, pin 24,22,17,15,13 are not working at all and pin 20 is working randomly. I flashed the same firmware on another board to make sure the board is not faulty and I experience the same behaviour.

Pins 22 and 24 are also configured in dts in uart0 section, but I disabled uart0 this way;

&uart0 {
compatible = "nordic,nrf-uarte";
current-speed = <115200>;
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
status = "disabled";
};

Does anyone know what the problem might be?

When using GPIOTE all 4 pins are behaving correctly, but I need more than 4 buttons.

  • Just to add, when using GPIOTE (without pin mask), the behaviour is pretty much the same with the only difference that more than 8 pins I cannot configure. Therefore it seems like 8 interrupts are allowed. But why it behaves so strange? Why gpio 9 and 10 are triggered simultaneously?

  • Hi

    First off, pins P0.09 and P0.10 are configured as NFCT pins by default, and needs to be configured as GPIOs to work as buttons like this. This is done by setting CONFIG_NFCT_PINS_AS_GPIOS in your prj.conf file, and this explains why the pins 9 and 10 are triggered at the same time, as there is a protection circuit active on these pins when configured as NFC pins. You can see more details on this in the NFCT chapter of the PS.

    Why this should make the other pins misbehave doesn't make much sense to me though, but please start out by configuring these pins as GPIOs, and see if that makes a difference.

    Best regards,

    Simon

  • Dear sir,

    thank you for your prompt response. I think I resolved it. It seems like I was missing pull_up resistor as well as definition of activity. Just to make things easiear, I made a cmultiple opy of a button of nrf52840 in dts file this way:

    button0: button_0 {
    gpios = <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "Push button switch 0";
    };

    Now it works the way I want, but I am not telling that it is the ideal way of making a button.

Related