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
  • Question, Is it OK for the accelerometer int1 pin to be under "gpio-keys"  binding? The documentation says this is for buttons

    If no - what binding should be under ?

    Thanks

  • 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 

  • AndyM said:
    I put in a request but it's out of my hands,l hopefully later this week.

    Got it,

    AndyM said:
    GPIO_INPUT|GPIO_ACTIVE_HIGH so I expected to see a 1
    Is my expectation correct?

    If by this you mean that you configure the pin as GPIO_ACTIVE_HIGH in the dts and as an INPUT in the application with for example gpio_pin_configure_dt() then that is OK. But you still need to configure what interrupt that should trigger the callback handler which you have already done in gpio_pin_interrupt_configure_dt().

    I therefore wonder, does the accelerometer pull the signal to a logical 1 or a logical 0 when it enables the interrupt? Have you tried switching it to a GPIO_ACTIVE_LOW and see if that fixes the issue?

    regards

    Jared 

  • Jared, just to clarify, I made the following changes  but it did not make a difference

    acc_int1: acc_int1 {
                gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
            };
    gpio_pin_configure_dt(&_int1_dt_spec, GPIO_INPUT|GPIO_ACTIVE_LOW);
    gpio_pin_interrupt_configure_dt(&_int1_dt_spec,GPIO_INT_LEVEL_INACTIVE);

    I also tried  GPIO_INT_EDGE_TO_ACTIVE when configuring the interrupt - no luck

    Did I miss anything?

    Thank you

     
  • Hi,

    AndyM said:
    Did I miss anything?

    That looks correct, were you able to verify if the interrupt line is toggled by the slave and if so in what direction?

    Another suggestion, can you try to move the gpio_pin_interrupt_configure_dt() call before gpio_init_callback() and see if that changes anything? Also try using 

    GPIO_INT_EDGE_TO_ACTIVE instead of GPIO_INT_LEVEL_ACTIVE as well. 
    regards
    Jared
  • Yes, in the code gpio_pin_interrupt_configure_dt is called before gpio_init_callback

    Unfortunately did not work

    Waiting on the results of the hardware analysis, will keep you posted

    Anything else worth trying in the meantime?

    Thank you

  • Jared

    I checked the spec - by default the INT1 pin polarity is active-high

    Also my gpio nodes are configured with sense-edge-mask i.e

    &gpio0 {
        status = "okay";
        sense-edge-mask = <0xffffffff>;
    };
    I believe this is done to avoid the limitation of 8 gpiote channels in the NRF52
    Not sure it matters, it does not work without that property either. Thought I'd bring it up just in case 
    Thank you
Reply
  • Jared

    I checked the spec - by default the INT1 pin polarity is active-high

    Also my gpio nodes are configured with sense-edge-mask i.e

    &gpio0 {
        status = "okay";
        sense-edge-mask = <0xffffffff>;
    };
    I believe this is done to avoid the limitation of 8 gpiote channels in the NRF52
    Not sure it matters, it does not work without that property either. Thought I'd bring it up just in case 
    Thank you
Children
Related