2024-03-10 11:05 AM
My STM32 can only correctly retrieve data from LSM6DSL when debugging. The code remains unchanged. When debugging, I get the correct data; without debugging, I get incorrect data.My SPI frequency is limited to 8 MHz, and there is a delay of more than 200 microseconds inserted between each SPI send and receive call to ensure sufficient preparation time for the sensor.I have removed all irrelevant code.The problem seems absurd but has been troubling me for a long time.It's worth noting that even without debugging, I can correctly read the 'WHO AM I' register. This is what's causing me great confusion since the communication seems to be fine
In non-debug mode, the data register can only be read as 0 and 255 as log
If I start debugging mode, I don't need to perform any operations on the microcontroller. I just need to reset it and run at full speed. With the same code, I can obtain the correct data.
void LSM6D_Write_Reg(uint8_t reg, uint8_t data)
{
IMU_CS_CLR;
LSM6D_DELAY;
LL_SPI_TransmitData8(SPI1, reg);
while(LL_SPI_IsActiveFlag_RXNE(IMU_SPI)==0);
LSM6D_DELAY
LL_SPI_TransmitData8(SPI1, data);
while(LL_SPI_IsActiveFlag_RXNE(IMU_SPI)==0);
LSM6D_DELAY
IMU_CS_SET;
}
uint8_t LSM6D_Read_Reg(uint8_t reg)
{
uint8_t read_data;
IMU_CS_CLR;
LSM6D_DELAY;
LL_SPI_TransmitData8(SPI1, reg|0x80);
while(LL_SPI_IsActiveFlag_RXNE(IMU_SPI)==0);
LSM6D_DELAY;
LL_SPI_TransmitData8(SPI1, 0xFF);
while(LL_SPI_IsActiveFlag_RXNE(IMU_SPI)==0);
read_data = (SPI1->DR);
LSM6D_DELAY;
IMU_CS_SET;
return (SPI1->DR);
}
void LSM6D_Init(void)
{
uint8_t imu_id = 0;
volatile uint8_t temp = 0;
IMU_CS_SET;
LL_mDelay(10);
imu_id = LSM6D_Read_Reg(0x0f);
if(imu_id!=0x6A)
{
printf("ERROR : IMU ID 0x%2X not 0x6A.", imu_id);
while(1);
}
LSM6D_Write_Reg(LSM6D_CTRL2_G,0X40);
LSM6D_Write_Reg(LSM6D_CTRL10_C,0x38);
LSM6D_Write_Reg(LSM6D_CTRL1_XL,0x60);
LSM6D_Write_Reg(LSM6D_TAP_CFG,0x90);
LSM6D_Write_Reg(LSM6D_WAKE_UP_DUR,0x00);
LSM6D_Write_Reg(LSM6D_WAKE_UP_THS,0x02);
LSM6D_Write_Reg(LSM6D_MD1_CFG,0x20);
LSM6D_Write_Reg(LSM6D_TAP_THS_6D,0x40);
LSM6D_Write_Reg(LSM6D_CTRL8_XL,0x01);
printf("LSM6D OK\n\r");
}
//Ax Ay... are "volatile short" global variables
void LSM6D_Get_RawAcc(void)
{
static uint8_t buf[6];
if((LSM6D_Read_Reg(LSM6D_STATUS_REG)&0x01))
{
buf[0]= LSM6D_Read_Reg(LSM6D_OUTX_H_XL);
buf[1]= LSM6D_Read_Reg(LSM6D_OUTX_L_XL);
buf[2]= LSM6D_Read_Reg(LSM6D_OUTY_H_XL);
buf[3]= LSM6D_Read_Reg(LSM6D_OUTY_L_XL);
buf[4]= LSM6D_Read_Reg(LSM6D_OUTZ_H_XL);
buf[4]= LSM6D_Read_Reg(LSM6D_OUTZ_H_XL);
buf[4]= LSM6D_Read_Reg(LSM6D_OUTZ_H_XL);
buf[5]= LSM6D_Read_Reg(LSM6D_OUTZ_L_XL);
Ax=((buf[0]<<8)|buf[1]);
Ay=((buf[2]<<8)|buf[3]);
Az=((buf[4]<<8)|buf[5]);
}
}
void LSM6D_Get_RawGryo(void)
{
uint8_t buf[6];
if((LSM6D_Read_Reg(LSM6D_STATUS_REG)&0x02))
{
buf[0]= LSM6D_Read_Reg(LSM6D_OUTX_H_G);
buf[1]= LSM6D_Read_Reg(LSM6D_OUTX_L_G);
buf[2]= LSM6D_Read_Reg(LSM6D_OUTY_H_G);
buf[3]= LSM6D_Read_Reg(LSM6D_OUTY_L_G);
buf[4]= LSM6D_Read_Reg(LSM6D_OUTZ_H_G);
buf[5]= LSM6D_Read_Reg(LSM6D_OUTZ_L_G);
Gx=((short)((buf[0]<<8)|buf[1]));
Gy=((short)((buf[2]<<8)|buf[3]));
Gz=((short)((buf[4]<<8)|buf[5]));
}
}
2024-03-21 11:33 AM
Have you tried a scope or logic analyser to see what changes when debugging from when not debugging?
2024-03-21 11:44 AM
Using the wrong tools to diagnose the issue.
Look at the signals on the wire, likely to lie a lot less..
Almost certainly issues with initial expectations, or speed/timing.
2024-04-04 07:16 AM