cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSO32 device id 0x00 after few hours

mpopko
Associate II

Hi all,

We got odd issue with LSM6DSO32 IMU on our device. After like 6-10 hours of working it begins to not response correctly and it stays until completely power replug. Our code tries do reinitiate IMU when it happens, but within that "frezze" state it reads chip id as 0x00 using lsm6dso32_device_id_get (which we're using to determine which chip is on board) instead of 0x6C.

We're using latest libraries from https://github.com/STMicroelectronics/lsm6dso32-pid 

Whole init sequence:

imuSoftReset();

imuErr = imuReadID(&imuID);
if(imuErr != imuOk){
return GRAVITY_VECTOR_INIT_ERROR;
}


imuErr = imuInit(imuID);
if(imuErr != imuOk){
return GRAVITY_VECTOR_INIT_ERROR;
}


------------------------------

void imuSoftReset(void)
{
uint8_t resetValue = 1;

// Set the IMU's software reset bit and wait for it to clear after a reset
// Note: didn't use LSM6DSV32X's reset set function because that function also sets a new global reset bit not present in LSM6DSO32. Reset later if identified
lsm6dso32_reset_set(&lsm6Context, resetValue);
do
{
lsm6dso32_reset_get(&lsm6Context, &resetValue);
} while (resetValue);
}

ImuError imuReadID(uint8_t* imuID)
{
uint8_t id;

if (lsm6dso32_device_id_get(&lsm6Context, &id) != HAL_OK)
{
return imuError;
}

switch(id)
{
case LSM6DSO32_ID:
{
*imuID = LSM6DSO32_ID;
break;
}
case LSM6DSV32X_ID:
{
*imuID = LSM6DSV32X_ID;
break;
}
default:
{
*imuID = 0x00;
return imuUnknownID;
}
}

return imuOk;
}

 

imuInit code:

ImuError imuInit(uint8_t imuID)
{
HAL_StatusTypeDef err = HAL_OK;
uint8_t resetValue = 1;

switch(imuID)
{
case LSM6DSO32_ID:
{
sImuID = imuID; // set IMU ID

// Set the IMU's reset bit and wait for it to clear after a reset
resetValue = 1;
lsm6dso32_reset_set(&lsm6Context, resetValue);
do
{
lsm6dso32_reset_get(&lsm6Context, &resetValue);
} while (resetValue);

err = lsm6dso32_i3c_disable_set(&lsm6Context, LSM6DSO32_I3C_DISABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dso32_auto_increment_set(&lsm6Context, PROPERTY_ENABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dso32_block_data_update_set(&lsm6Context, PROPERTY_ENABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dso32_fifo_mode_set(&lsm6Context, LSM6DSO32_BYPASS_MODE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dso32_xl_full_scale_set(&lsm6Context, LSM6DSO32_8g);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dso32_gy_full_scale_set(&lsm6Context, LSM6DSO32_1000dps);
if (err != HAL_OK)
{
return imuInitError;
}

sGyroRange = gyro1000dps;
sGyroEnabledODR = LSM6DSO32_GYRO_ENABLED_ODR_HZ; // other parts of the application need to know the sampling rate

volatile uint32_t ret = 0;
lsm6dso32_pin_int1_route_t int1_route = { 0 };
int1_route.fsm_int1_a.int1_fsm1 = 1;
ret |= lsm6dso32_pin_int1_route_set(&lsm6Context, &int1_route);

ret |= lsm6dso32_long_cnt_int_value_set(&lsm6Context, 0x0000U);

ret |= lsm6dso32_fsm_start_address_set(&lsm6Context, 0x0400U);

uint8_t numPrograms = 1;
ret |= lsm6dso32_fsm_number_of_programs_set(&lsm6Context, &numPrograms);

lsm6dso32_emb_fsm_enable_t fsm_enable = { 0 };
fsm_enable.fsm_enable_a.fsm1_en = 1;
ret |= lsm6dso32_fsm_enable_set(&lsm6Context, &fsm_enable);

ret |= lsm6dso32_fsm_data_rate_set(&lsm6Context, LSM6DSO32_ODR_FSM_12Hz5);

ret |= lsm6dso32_ln_pg_write(&lsm6Context, 0x0400, (uint8_t *)lsm6dso32_prg_wakeup, sizeof(lsm6dso32_prg_wakeup));


ret |= lsm6dso32_emb_fsm_en_set(&lsm6Context, 1);

ret |= lsm6dso32_fsm_init_set(&lsm6Context, 1);


if(ret != 0)
{
return imuInitError;
}

// Set INT2 interrupt to gyro data ready
lsm6dso32_pin_int2_route_t int2_route = { 0 };
int2_route.int2_ctrl.int2_drdy_g = 1;
lsm6dso32_pin_int2_route_set(&lsm6Context, &int2_route);
break;
}
case LSM6DSV32X_ID:
{
sImuID = imuID; // set IMU ID

// Set the IMU's global reset bit and wait 30ms per AN6016
ImuError imuErr = imuGlobalReset();
if (imuErr != imuOk)
{
return imuInitError;
}
HAL_Delay(30);

err = lsm6dsv32x_ui_i2c_i3c_mode_set(&lsm6Context, LSM6DSV32X_I2C_I3C_DISABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dsv32x_auto_increment_set(&lsm6Context, PROPERTY_ENABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dsv32x_block_data_update_set(&lsm6Context, PROPERTY_ENABLE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dsv32x_fifo_mode_set(&lsm6Context, LSM6DSV32X_BYPASS_MODE);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dsv32x_xl_full_scale_set(&lsm6Context, LSM6DSV32X_8g);
if (err != HAL_OK)
{
return imuInitError;
}


err = lsm6dsv32x_gy_full_scale_set(&lsm6Context, LSM6DSV32X_1000dps);
if (err != HAL_OK)
{
return imuInitError;
}


sGyroRange = gyro1000dps;
sGyroEnabledODR = LSM6DSV32X_GYRO_ENABLED_ODR_HZ; // other parts of the application need to know the sampling rate

// Enables / masks execution trigger of the embedded functions when accelerometer/gyroscope data are settling (Spurious FSM interrupt fix)
lsm6dsv32x_filt_settling_mask_t settling_mask = { 0 };
//settling_mask.irq_g = 1; //keep in mind to enable it in the future when fsm will be using gyro
settling_mask.irq_xl = 1;
err = lsm6dsv32x_filt_settling_mask_set(&lsm6Context, settling_mask);

// Set INT1 interrupt to movement detection using finite state machine
err = HAL_OK;
for (uint32_t i = 0; i < (sizeof(lsm6dsv32x_fsm_configuration) /
sizeof(ucf_line_ext_t) ); i++ ) {
err |= lsm6dsv32x_write_reg(&lsm6Context, lsm6dsv32x_fsm_configuration[i].address,
(uint8_t *)&lsm6dsv32x_fsm_configuration[i].data, 1);


}
if (err != HAL_OK)
{
return imuInitError;
}

// Set INT2 interrupt to gyro data ready
lsm6dsv32x_pin_int_route_t int2_route = { 0 };
int2_route.drdy_g = 1;
err = lsm6dsv32x_pin_int2_route_set(&lsm6Context, &int2_route);
if (err != HAL_OK)
{
return imuInitError;
}
break;
}
default:
{
// do not set IMU ID

sGyroEnabledODR = 0; // other parts of the application need to know the sampling rate
return imuUnknownID;
}
}

return imuOk;
}

Ask for more code if needed.

Any ideas what went wrong here? Or even how to bring it back to live without power replugging?

 

1 REPLY 1

Please see How to write your question to maximize your chances to find a solution for how to properly post source code (and other tips)

I've edited you're post to use the </> tags, but all the indentation is lost.


Are you using SPI, I2C, or I3C?

 


@mpopko wrote:

After like 6-10 hours of working it begins to not response correctly 


First thing to do is to use an oscilloscope or logic analyser to see if it's actually the sensor misbehaving, or just your software.

Have you used the debugger to see what's happening in your code when this happens?

 


@mpopko wrote:

Ask for more code if needed.


You've shown the initialisation, but not the operational code.

As it works initially (and for many hours thereafter), the initialisation is probably OK - so the problem is probably somewhere in the operational code.

Are you taking care to always check return values from interface functions?