Multiple GPIO interrupts

Hello

I have 2 peripherals on my custom nRF52840 board: accelerometer and a touch button

I configured the gpio callbacks for both parts but see strange behavior: On a button press both  button and accelerometer GPIO callbacks trigger. But on the accelerometer event the accelerometer GPIO callback DOES NOT  trigger. I am 100% certain that the accelerometer is configured correctly and generates interrupt events.

Details below

Any ideas what is wrong??
Thank you

DTS

custom_pins {
        compatible = "gpio-keys";
button1: button_1 {
            gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
            label = "Touch button";
        };
// accelerometer int1
        acc_int1: acc_int1 {
            gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
        };
};
proj.conf
CONFIG_GPIO=y
---------------------------------
// buttton init code
static const struct gpio_dt_spec _btn_map[] = {
    GPIO_DT_SPEC_GET_OR(DT_ALIAS(sw1), gpios, {0}),
};

      
int btn_init(btn_cb_t cb)
{
    int ret;
    uint32_t btn_mask = 0;

    // Setup common callback. Note the callback struct must not be a local var.
    static struct gpio_callback gpio_cb;
   
    for (unsigned i=0; i<NUM_BTNS; ++i) {
        ret = gpio_pin_configure_dt(&_btn_map[i], GPIO_INPUT);
        if (ret != 0) {
            LOG_ERR("Error %d: failed to configure %s pin %d", ret, _btn_map[i].port->name, _btn_map[i].pin);
            return -1;
        }
        btn_mask |= BIT(_btn_map[i].pin);
        gpio_init_callback(&gpio_cb, btn_gpio_evt_cb, btn_mask);
        gpio_add_callback(_btn_map[i].port, &gpio_cb);
        ret = gpio_pin_interrupt_configure_dt(&_btn_map[i], GPIO_INT_EDGE_BOTH);
        if (ret != 0) {
            LOG_ERR("Error %d: failed to configure interrupt on %s pin %d", ret, _btn_map[i].port->name, _btn_map[i].pin);
            return -2;
        }
    }

    LOG_DBG("button config done.");

    return 0;
}
//------------------------
Accelerometer INT1 init  code
static const struct gpio_dt_spec _int1_dt_spec = GPIO_DT_SPEC_GET_OR(DT_ALIAS(accint1), gpios, {0});
gpio_pin_configure_dt(&_int1_dt_spec, GPIO_INPUT);
gpio_init_callback(&_gpio_int1_cb,gpio_int1_callback, BIT(_int1_dt_spec.pin));
gpio_add_callback(_int1_dt_spec.port, &_gpio_int1_cb);
gpio_pin_interrupt_configure_dt(&_int1_dt_spec,GPIO_INT_LEVEL_ACTIVE);

Parents Reply
  • Hi Jared

    There were 2 bugs

    1. The GPIO pin mask was wrong. It included the pin that the button is connected to. That caused the accelerometer interrupt callback to fire on button touch. That code is shared above an you suggested to check the value of the mask passed to gpio_init_callback() . When I did I realized that the mask was wrong and fixed it.

    2. The second bug is in the code that configures the accelerometer by writing various values to its registers. It enabled the interrupt correctly but the next line of code disabled it by mistake.

    Thank you so much for help! 

Children
Related