Unable to get gpio interrupt from LSM6DS3TR_C to nRF52840 in the Seeed Studio Xiao Ble Sense

static void IMU_config(void)
{
  uint8_t error=0;
  //Set the Accelerometer control register to work at 6.6kHz Hz,Full Scale 16g
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_CTRL1_XL,0x90);
  //Set ODR/4
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_CTRL8_XL,0x1C);
  error +=i2c_reg_write_byte(lsm6ds3tr_c,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_CTRL9_XL,0x34);
  // A wake up threshold of 5042 mg
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_WAKE_UP_THS,0x0F);
  // Wake up duration is in ms therefore value has to be set to 0x00
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_WAKE_UP_DUR,0x60);
  // Enables Interrupts
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_TAP_CFG,0xB1);
  //Routing of Wake up event
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_MD1_CFG,0x20);
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_INT1_CTRL,0x43);
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_MD2_CFG,0x20);
  error+= i2c_reg_write_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_INT2_CTRL,0x03);
}
static void IMU_Sensor(){
   //Rd reg
   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTX_L_XL,&xAccelL);
   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTY_L_XL,&yAccelL);
   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTZ_L_XL,&zAccelL);

   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTX_H_XL,&xAccelH);
   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTY_H_XL,&yAccelH);
   i2c_reg_read_byte(lsm6ds3trc,LSM6DSL_VAL_WHO_AM_I,LSM6DSL_REG_OUTZ_H_XL,&zAccelH);

    x_accRaw = ((int16_t)(xAccelH<<8))|(xAccelL & 0xFF);
    y_accRaw = ((int16_t)(yAccelH<<8))|(yAccelL & 0xFF);
    z_accRaw = ((int16_t)(zAccelH<<8))|(zAccelL & 0xFF);

    x_accRaw = (x_accRaw*0.061)/15;
    y_accRaw = (y_accRaw*0.061)/15;
    z_accRaw = (z_accRaw*0.061)/15;
}
void sleep_handler(nrfx_power_sleep_evt_t current_state )
{
  switch (current_state)
  {
  case NRFX_POWER_SLEEP_EVT_ENTER:
       printf("System sleep\n");
       NRF_POWER->INTENSET=1;//Enables Interrupt
       NRF_POWER->EVENTS_SLEEPENTER=1;// CPU enters wait for WFI/WFE
    break;
  case NRFX_POWER_SLEEP_EVT_EXIT:
       NRF_POWER->EVENTS_SLEEPEXIT=1;//CPU Exits WFI/WFE
        IMU_config();
        IMU_Sensor();
        err = i2c_reg_read_byte(lsm6ds3trc, LSM6DSL_VAL_WHO_AM_I, LSM6DSL_REG_WAKE_UP_SRC, &wkp);
    if (err)
    {
    printf("Failed to read wake-up source.");
    }  
    if(wkp && 0x0F){
       printk("Exceeded Threshold----------------------->\n");
            // Read timestamp
            err = i2c_reg_read_byte(lsm6ds3trc, LSM6DSL_VAL_WHO_AM_I, LSM6DSL_REG_TIMESTAMP0, &timestamp0);
            err = i2c_reg_read_byte(lsm6ds3trc, LSM6DSL_VAL_WHO_AM_I, LSM6DSL_REG_TIMESTAMP1, &timestamp1);
            err = i2c_reg_read_byte(lsm6ds3trc, LSM6DSL_VAL_WHO_AM_I, LSM6DSL_REG_TIMESTAMP2, &timestamp2);
            timestamp = ((uint32_t)timestamp2 << 16) | ((uint16_t)timestamp1 << 8) | timestamp0;
           
                // Calculate acceleration
                pAc = sqrt(sqr(x_accRaw) + sqr(y_accRaw) + sqr(z_accRaw));
                snprintf(X1, sizeof(X1), "Peak %d\n", pAc);
                printk("Acceleration=%s\n", X1);
                // Check if pAc is greater than 4500
                if (pAc > 900)
                {
                ret=gpio_pin_configure_dt(&led_2,GPIO_OUTPUT_ACTIVE);
                bt_ready();
                k_sleep(K_SECONDS(10)); // Delay for 10 seconds
                bt_disable();
                ret=gpio_pin_configure_dt(&led_2,GPIO_OUTPUT_INACTIVE);
               }
                 else
                  {
                   printk("No fall detected\n");
                  }
    }
    else
    {
       printf("No wake up in LSM6DS3.\n");
    }
   
  default:
       //NRF_POWER->TASKS_LOWPWR=1;//Low power mode
    break;
  }
}
// Interrupt Call back function
void lsm6ds3trc_irq_callback(const struct device *port,struct gpio_callback *cb,gpio_port_pins_t pins)
{      
        current_state = NRFX_POWER_SLEEP_EVT_EXIT;
         sleep_handler(current_state);
         printf("Successful Interrupt\n");
         NRFX_DELAY_US(100000);
         current_state=NRFX_POWER_SLEEP_EVT_ENTER;
         sleep_handler(current_state);
}
static struct gpio_callback interrupt_callback={
  .handler=lsm6ds3trc_irq_callback,
};

int main(void)
{
    int err;
   
    if(!device_is_ready(lsm6ds3trc))
    {
      printk("LSM6DS3 device not ready\n");
    }
    IMU_config();
    IMU_Sensor();
    printf("IMU Configured and Sensed\n");
    err=gpio_pin_configure_dt(&irq_pin,GPIO_INPUT);
    if(err!=0){
       printf("Pin not configured\n");
    }
    err=gpio_pin_interrupt_configure_dt(&irq_pin,GPIO_INT_EDGE_RISING);
    if(err!=0){
      printf("Interrupt not configured\n");
    }
    nrf_gpio_cfg_input(irq_pin.pin,NRFX_GPIOTE_DEFAULT_PULL_CONFIG);
    nrf_gpio_cfg_sense_set(irq_pin.pin,NRFX_GPIOTE_ENABLED);
    err = i2c_reg_read_byte(lsm6ds3trc, LSM6DSL_VAL_WHO_AM_I, LSM6DSL_REG_WAKE_UP_SRC, &wkp);
    if (err)
    {
    printf("Failed to read wake-up source.");
    }  
   
    if(wkp && 0x0F){
    gpio_init_callback(&interrupt_callback,lsm6ds3trc_irq_callback,BIT(irq_pin.pin));
    gpio_add_callback(irq_pin.port,&interrupt_callback);
    }
    else
    {
      printf("Wake up threshold not exceeded\n");
    }
    current_state=NRFX_POWER_SLEEP_EVT_ENTER;
    sleep_handler(current_state);
    k_sleep(K_MSEC(100));    
   return 0;
}This the program that I use to make the nRF52840 to go sleep and wake up when an interrupt arrives from lsm6ds3tr_c due to FREE_FALL bit . But it seems like it is not waking up. The same program when used by replacing an external gpio button instead of lsm6ds3tr_c works fine. Could anyone please tell me to find a solution for this.
#define LED2_NODE DT_ALIAS(led2) //BLUE colour LED
#define I2C_NODE DT_NODELABEL(i2c0)
#define INT_NODE DT_NODELABEL(lsm6ds3tr_c)

// Declaration I2C connection of LSM6DS3TRC
static const struct device *lsm6ds3trc = DEVICE_DT_GET(I2C_NODE);
// Declaration of GPIO for pin interrupt
static const struct gpio_dt_spec irq_pin = GPIO_DT_SPEC_GET(INT_NODE,irq_gpios);
// LED declaration
static const struct gpio_dt_spec led_2 = GPIO_DT_SPEC_GET(LED2_NODE, gpios); these are the user defined macros
Parents Reply Children
No Data
Related