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 Children
  • Hi,

    Just to be clear, are you saying that _gpio_int1_cb() is called when you press the GPIO button, but it's not called when accint1 is toggled by the accelerometer? 

    AndyM said:
    Question, Is it OK for the accelerometer int1 pin to be under "gpio-keys"  binding? The documentation says this is for buttons

    Yes, this should be fine,

    regards

    Jared 

  • Just to be clear, are you saying that _gpio_int1_cb() is called when you press the GPIO button, but it's not called when accint1 is toggled by the accelerometer? 

    Yes, that's the behavior I see

  • Hi Andy,

    Can you set a breakpoint at line : gpio_init_callback(&_gpio_int1_cb,gpio_int1_callback, BIT(_int1_dt_spec.pin));

    And see what the third parameter BIT(_int1_dt_spec.pin) is when you run the program with the debugger?

    Can you share a screenshot of the variable from debug view?

    regards

    Jared 

  • Jared

    Your hunch was correct. I was including a header which redefined the BIT macro so the pin used for the button was added to the pin mask for the accelerometer interrupt and that' caused the accelerometer gpio callback to be called  on a button press. I fixed that and now the button press works fine and does not trigger the accelerometer gpio callback. .Thank you!

    However the accelerometer interrup callback still is not called on a movement event, as expected. I'm certain that the part generates the interrupt - if I poll the control register of the accelerometer in a loop I see the interrupt bit set when the event occurs. I tried using  GPIO_INT_EDGE_TO_ACTIVE  and GPIO_INT_LEVEL_ACTIVE flags in gpio_pin_interrupt_configure_dt() function - makes no difference

    Any ideas ?
  • AndyM said:
    Your hunch was correct. I was including a header which redefined the BIT macro so the pin used for the button was added to the pin mask for the accelerometer interrupt and that' caused the accelerometer gpio callback to be called  on a button press. I fixed that and now the button press works fine and does not trigger the accelerometer gpio callback. .Thank you!

    Good,

    AndyM said:
    However the accelerometer interrup callback still is not called on a movement event, as expected. I'm certain that the part generates the interrupt - if I poll the control register of the accelerometer in a loop I see the interrupt bit set when the event occurs. I tried using  GPIO_INT_EDGE_TO_ACTIVE  and GPIO_INT_LEVEL_ACTIVE flags in gpio_pin_interrupt_configure_dt() function - makes no difference

    Can you double check it by probing the interrupt line either with an oscilloscope or logic analyzer and confirm that the pin is asserted by the accelerometer? 

    regards

    Jared 

Related