cancel
Showing results for 
Search instead for 
Did you mean: 

No Update form lis3mdl time to time

JPARK.2
Associate II

Hello,

Our board is streaming accelerometer, gyrometer(lsm6dsox) and magnetometer(lis3mdl).

It sleep and wake-up depends on accelerometer threshold.

Usually data is streamed out well.

But time to time, data is not updated from magetometer after wake up.

In below picture, from -800 to -400, same value is read although sensor is shaken.

After power reset at -400, sensor data is read well again.

0693W00000Ba4AkQAJ.jpgSince WHO_AM_I is checked every time after-wake up, I think SPI or sensor is okay.

Below is register setting during initialization.

void motion_init(void)
{
    uint32_t err_code;
    uint8_t whoamI, rst;
    lsm6dsox_pin_conf_t val;
    lsm6dsox_pin_int2_route_t int2_route;
    lsm6dsox_pin_int1_route_t int1_route;
 
    nrf_drv_spi_config_t twi_config_motions = NRF_DRV_SPI_DEFAULT_CONFIG;
    twi_config_motions.sck_pin  = PIN_LSM_SPI_SCLK;
    twi_config_motions.mosi_pin = PIN_LSM_SPI_MOSI;
    twi_config_motions.miso_pin = PIN_LSM_SPI_MISO;
    //twi_config_motions.ss_pin = PIN_LSM_SPI_SS;
    twi_config_motions.frequency = NRF_SPI_FREQ_8M;
    twi_config_motions.mode      = NRF_DRV_SPI_MODE_3;
    twi_config_motions.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
    twi_config_motions.irq_priority = APP_IRQ_PRIORITY_LOW;
    err_code = nrf_drv_spi_init(&m_spi_lsm, &twi_config_motions, spi_event_handler1, NULL);
    RETURN_IF_ERROR(err_code);
 
    nrf_drv_spi_config_t twi_config_magnet = NRF_DRV_SPI_DEFAULT_CONFIG;
    twi_config_magnet.sck_pin  = PIN_LIS_SPI_SCLK;
    twi_config_magnet.mosi_pin = PIN_LIS_SPI_MOSI;
    twi_config_magnet.miso_pin = PIN_LIS_SPI_MISO;
    //twi_config_magnet.ss_pin = PIN_LIS_SPI_SS;
    twi_config_magnet.frequency = NRF_SPI_FREQ_8M;
    twi_config_magnet.mode      = NRF_DRV_SPI_MODE_3;
    twi_config_magnet.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
    twi_config_magnet.irq_priority = APP_IRQ_PRIORITY_LOW;
    err_code = nrf_drv_spi_init(&m_spi_lis, &twi_config_magnet, spi_event_handler2, NULL);
    RETURN_IF_ERROR(err_code);
 
    lsm_ctx.write_reg = lsm_write;
    lsm_ctx.read_reg = lsm_read;
    lsm_ctx.handle = &m_spi_lsm;
 
    lis_ctx.write_reg = lis_write;
    lis_ctx.read_reg = lis_read;
    lis_ctx.handle = &m_spi_lis;
 
    /* Wait Boot Time */
    nrf_delay_ms(50);
 
    /* Check device ID */
    lsm6dsox_device_id_get(&lsm_ctx, &whoamI);
    while (whoamI != LSM6DSOX_ID)
    {
        nrf_delay_ms(50);
    }
        
    /* Restore default configuration */
    lsm6dsox_reset_set(&lsm_ctx, PROPERTY_ENABLE);
    do {
        lsm6dsox_reset_get(&lsm_ctx, &rst);
    } while (rst);
    
    /* Electrical pin configuration */
    val.sdo_sa0_pull_up = 0;
    val.aux_sdo_ocs_pull_up = 0;
    val.int1_int2_push_pull = 0;
    val.int1_pull_down = 0;
    lsm6dsox_pin_conf_set(&lsm_ctx, val);
 
    /* Disable I3C interface */
    lsm6dsox_i3c_disable_set(&lsm_ctx, LSM6DSOX_I3C_DISABLE);
 
    /* Enable Block Data Update */
    lsm6dsox_block_data_update_set(&lsm_ctx, PROPERTY_ENABLE);
 
    /* Set Output Data Rate */
    lsm6dsox_xl_data_rate_set(&lsm_ctx, LSM6DSOX_XL_ODR_1667Hz);// 1/6667Hz*(1000msec/1sec) = 0.149msec
    lsm6dsox_gy_data_rate_set(&lsm_ctx, LSM6DSOX_GY_ODR_1667Hz);
 
    /* Set full scale */
    lsm6dsox_xl_full_scale_set(&lsm_ctx, LSM6DSOX_16g); //2g 1g, 1000 16bit
    lsm6dsox_gy_full_scale_set(&lsm_ctx, LSM6DSOX_2000dps);
 
    lis3mdl_device_id_get(&lis_ctx, &whoamI);
    while (whoamI != LIS3MDL_ID)
    {
        nrf_delay_ms(50);
    }
        
    /* Restore default configuration */
    lis3mdl_reset_set(&lis_ctx, PROPERTY_ENABLE);
    do {
        lis3mdl_reset_get(&lis_ctx, &rst);
    } while (rst);
 
    /* Enable Block Data Update */
    lis3mdl_block_data_update_set(&lis_ctx, PROPERTY_ENABLE);
 
    /* Set Output Data Rate */
    lis3mdl_data_rate_set(&lis_ctx, LIS3MDL_LP_1kHz);// 1/1kHz*(1000msec/1sec) = 1msec
 
    /* Set full scale */
    lis3mdl_full_scale_set(&lis_ctx, LIS3MDL_12_GAUSS);
 
    /* Enable temperature sensor */
    lis3mdl_temperature_meas_set(&lis_ctx, PROPERTY_DISABLE);
 
    /* Set device in continuos mode */
    lis3mdl_operating_mode_set(&lis_ctx, LIS3MDL_CONTINUOUS_MODE);
 
    /* Configure gpiote for the sensors data ready interrupt. */
    if (!nrf_drv_gpiote_is_init())
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code); 
    }
    
    nrf_drv_gpiote_in_config_t gpiote_in_config;
    gpiote_in_config.is_watcher  = false;
    gpiote_in_config.hi_accuracy = false; //true;
    gpiote_in_config.pull        = NRF_GPIO_PIN_PULLDOWN;
    gpiote_in_config.sense       = NRF_GPIOTE_POLARITY_LOTOHI;
    
    err_code = nrf_drv_gpiote_in_init(PIN_LSM_INT1, &gpiote_in_config, lsm6dsox_gpiote_evt_handler1);
    RETURN_IF_ERROR(err_code);
 
    /* Enable interrupt generation on Inactivity INT1 pin */
    lsm6dsox_pin_int1_route_get(&lsm_ctx, &int1_route);
    int1_route.drdy_xl = PROPERTY_ENABLE;
    lsm6dsox_pin_int1_route_set(&lsm_ctx, int1_route);
 
    nrf_drv_gpiote_in_event_enable(PIN_LSM_INT1, true);
 
    #if NRF_ESB_SLEEP_MODE
    err_code = nrf_drv_gpiote_in_init(PIN_LSM_INT2, &gpiote_in_config, lsm6dsox_gpiote_evt_handler2);
    RETURN_IF_ERROR(err_code);
 
    lsm6dsox_xl_usr_offset_on_wkup_set(&lsm_ctx, 0x01);
    lsm6dsox_xl_hp_path_internal_set(&lsm_ctx, 0x01);
    /* Set duration for Activity detection to 1.80 ms (= 0x03 * 1 / ODR_XL) */
    lsm6dsox_wkup_dur_set(&lsm_ctx, 0x03);
 
    /* Set duration for Inactivity detection to 614.28 ms (= 0x02 * 512 / ODR_XL) */
    lsm6dsox_act_sleep_dur_set(&lsm_ctx, 0x02);
    
    /* Set Wake-Up threshold weight
      0: 1 LSB = FS_XL(16g) / (2^6) = 0.25
      1: 1 LSB = FS_XL(16g) / (2^8) = 0.0625‬ */
    lsm6dsox_wkup_ths_weight_set(&lsm_ctx, 0x01);
 
    /* Set Wake-Up threshold: 1 LSb corresponds to FS_XL(16g)/2^8 = 0.0625‬ */
    /* 0x11*0.0625 = 1.0625‬‬‬ */
    lsm6dsox_wkup_threshold_set(&lsm_ctx, 0x11);
 
    /* Inactivity configuration: XL to 12.5 in LP, gyro to Power-Down */
    lsm6dsox_act_mode_set(&lsm_ctx, LSM6DSOX_XL_12Hz5_GY_PD);
 
    lsm6dsox_pin_int2_route_get(&lsm_ctx,NULL, &int2_route);
    int2_route.sleep_change = PROPERTY_ENABLE;
    lsm6dsox_pin_int2_route_set(&lsm_ctx,NULL, int2_route);
 
    nrf_drv_gpiote_in_event_enable(PIN_LSM_INT2, true);
    #endif
    
    /* Gyroscope max turn-on time is 70 ms */
    nrf_delay_ms(1000); //140
}

Could you help me to find out what is problem?

1 ACCEPTED SOLUTION

Accepted Solutions
niccolò
ST Employee

Hi @Community member​ ,

I don't really know where the problem is, but can you check what is the difference between the start-up of the sensor after the wakeup interrupt and after the reset?

I think that you can find there the answer to the problem.

Niccolò

View solution in original post

1 REPLY 1
niccolò
ST Employee

Hi @Community member​ ,

I don't really know where the problem is, but can you check what is the difference between the start-up of the sensor after the wakeup interrupt and after the reset?

I think that you can find there the answer to the problem.

Niccolò