Cadence/Speed and motion sensor

I´m using nRF52dk and nRFConnect SDK for peripheral_csc application. I have added an accelerometer (kxtj3) and it works fine if polling. If interrupts are enabled and accelerometer is serviced in the interrupt handler, I can see the start of the I2C activity and suddenly it stops. Image below illustrates the start and the only no further activity after this event.
In blue the I2C SCK and in yellow the I2C SDA.

What do I need to configure to get I2C working in the interrupt handler?


static const struct gpio_dt_spec irq_acc_pin = GPIO_DT_SPEC_GET_OR(IRQ_ACC_NODE, gpios, {0});
static const struct gpio_dt_spec irqled = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec prgmled = GPIO_DT_SPEC_GET(LED1_NODE, gpios);
static struct gpio_callback irq_acc_callback;
volatile bool WUIrqFlg = false;
static const struct i2c_dt_spec dev_kxtj3_s[4] = {I2C_DT_SPEC_GET(I2C0_NODE0),
                                                    I2C_DT_SPEC_GET(I2C0_NODE1),
                                                    I2C_DT_SPEC_GET(I2C0_NODE2),
                                                    I2C_DT_SPEC_GET(I2C0_NODE3)};

void IRQ_ACC_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    uint8_t i2c_R, i2c_D;

    gpio_pin_toggle_dt(&irqled);

    if(WUIrqFlg) {
         i2c_R = STATUS_REG;
         i2c_write_read_dt(&dev_kxtj3, &i2c_R, 1, &i2c_D, 1);
         if(i2c_D & KIONIX_INT) {
            i2c_R = INT_SOURCE1;
            i2c_write_read_dt(&dev_kxtj3, &i2c_R, 1, &i2c_D, 1);
            if(i2c_D & KIONIX_WUFS)
    WUIrqFlg = true;
         }
    }
    else {

    }
}
    if (!device_is_ready(irq_acc_pin.port))
    {
        printk("Error: gpio device %s is not ready\n", irq_acc_pin.port->name);
        return;
    }
    err = gpio_pin_configure_dt(&irq_acc_pin, GPIO_PULL_UP | GPIO_INPUT);
    if (err != 0) {
        printk("Error: failed to configure %s pin %d\n", irq_acc_pin.port->name, irq_acc_pin.pin);
        return;
    }

    err = gpio_pin_interrupt_configure_dt(&irq_acc_pin, GPIO_INT_EDGE_RISING);
    if (err != 0) {
        printk("Error: failed to configure interrupt on %s pin %d\n", irq_acc_pin.port->name, irq_acc_pin.pin);
        return;
    }

Regards

Parents
  • Hello,

    Do you have any logs you could share from your program execution?

    When looking at the provided code there are some things I immediately notice:
    - You do not check the returned error code from you call to i2c_write_read_dt, which means that the call could have failed without you knowing it.
    - It seems to me that you have a possible infinite/very long while loop in your interrupt handler; this is far from good practice and should not be done.

    Please check the error codes, and share the logs output when you run the code again.
    Could you detail more about the intentions for your application? This would better my understanding of your situation and my ability to advise you on how to best approach it.

    Best regards,
    Karl

Reply
  • Hello,

    Do you have any logs you could share from your program execution?

    When looking at the provided code there are some things I immediately notice:
    - You do not check the returned error code from you call to i2c_write_read_dt, which means that the call could have failed without you knowing it.
    - It seems to me that you have a possible infinite/very long while loop in your interrupt handler; this is far from good practice and should not be done.

    Please check the error codes, and share the logs output when you run the code again.
    Could you detail more about the intentions for your application? This would better my understanding of your situation and my ability to advise you on how to best approach it.

    Best regards,
    Karl

Children
Related