2023-03-16 12:42 AM
Dear Sir,
Here set XL ODR = 104 Hz and Gyro ODR = 104Hz, routing XL data-ready to INT1, Gyro data-ready to INT2, respectively.
Interrupt mode is set to pulse mode here.
Do reading XL register and gyro register on INT1 and INT2 for clearing data-ready interrupt event, respectively.
After registers are programmed, use scope to view the waveform.
Except the 1st XL interrupt, the span between remainding adjacent interrupt is about 9ms, is approximately to XL ODR 104Hz, as expected.(see Fig.2)
Why the span between 1st XL interrupt and 2nd XL interrupt is weird? it is about 4.3ms (see Fig.1)
Yellow channel(channel 1) is XL interrupt
Blue channel(channel 2) is Gyro interrupt
Fig.1 weird 1st XL interrupt, span between 1st XL interrrupt and 2nd one is about 4.3ms
Fig.2 span between 3rd XL interrupt and 4th one, is about 9ms
read back reg = 0x12, val = 0x 4
read back reg = 0x14, val = 0x60
read back reg = 0x16, val = 0x 0
read back reg = 0x a, val = 0x 0
read back reg = 0x 9, val = 0x 0
read back reg = 0x5e, val = 0x 0
read back reg = 0x56, val = 0x 0
read back reg = 0x b, val = 0x80
read back reg = 0x17, val = 0x 0
read back reg = 0x18, val = 0x 2
read back reg = 0x d, val = 0x 1
read back reg = 0x e, val = 0x 2
read back reg = 0x11, val = 0x4c
read back reg = 0x10, val = 0x40
registers setting
const unsigned char gsensorInterrupTestTable[14][2] =
{
//Keep to update g and gyro data. H_LACTIVE:0,PP_OD:0,
{ (LSM6DSR_CTRL3_C_REG), (LSM6DSR_BLOCK_DATA_UPDATE_DISABLE + LSM6DSR_REGISTER_ADDRESS_AUTO_INCREMENTED) },
//Rounding read
{ (LSM6DSR_CTRL5_C_REG), (LSM6DSR_GYROSCOPE_AND_ACCELEROMETER) },
//Set high perform
{ (LSM6DSR_CTRL7_G_REG), (LSM6DSR_G_HM_MODE_ENABLE) },
//Disable FIFO fucntion
{ (LSM6DSR_FIFO_CTRL4_REG), (LSM6DSR_FIFO_MODE_BYPASS) },
{ (LSM6DSR_FIFO_CTRL3_REG), (LSM6DSR_FIFO_BDR_GY_NOT_IN_FIFO + LSM6DSR_FIFO_BDR_XL_DISABLE) },
//Disable interrupt for specific event.
{ (LSM6DSR_MD1_CFG), (LSM6DSR_INT1_6D_DISABLE) },
//Set interrupt property
//{ (LSM6DSR_TAP_CFG0), (LSM6DSR_TAP_CFG_LATCHED + LSM6DSR_TAP_CFG_INT_CLR_ON_READ) },
{ (LSM6DSR_TAP_CFG0), (0x00) },
{ (0x0b), (0x80) },
//Filter configuration
{ (LSM6DSR_CTRL8_XL_REG), (0) },
//Disable I3C
{ (LSM6DSR_CTRL9_XL_REG), (LSM6DSR_CTRL_DEVICE_CONF) },
//Set INT1 source
{ (LSM6DSR_INT1_CTRL_REG), (0x01) },
//Set INT2 source
{ (LSM6DSR_INT2_CTRL_REG), (0x02) },
//Set gyro scale and ODR
{ (LSM6DSR_CTRL2_G_REG), (LSM6DSR_G_ODR_104HZ + LSM6DSR_G_FS_2000DPS) },
//Set g sensor scale and ODR
{ (LSM6DSR_CTRL1_XL_REG), (LSM6DSR_XL_RANGE_2G + LSM6DSR_XL_ODR_104HZ) },
};
char LSM6DSR_InterruptTest(void)
{
unsigned char pucData[3];
unsigned char ucI2CCh = I2C_CH_LSM6DSR;
unsigned char ucCount = 0;
unsigned char ucRet = 0;
unsigned char i = 0;
#if (DEBUG_GS_GYRO_INT_COUNT == 1)
g_gs_int_count = 0;
g_gyro_int_count = 0;
#endif
// software reset
pucData[0] = LSM6DSR_CTRL3_C_REG;
pucData[1] = LSM6DSR_SOFT_RESET;
I2CWrite(I2C_ADDR_LSM6DSR, pucData, 2, ucI2CCh);
// timeout to check software rest bit status
// software reset bit is automatically cleared
i = 0;
do
{
I2CRead(I2C_ADDR_LSM6DSR, LSM6DSR_CTRL3_C_REG, &pucData[0], 1, ucI2CCh);
vTaskDelay(10 / portTICK_RATE_MS);
i++;
} while(((pucData[0] & LSM6DSR_SOFT_RESET) == 0) && i <= 10);
LSM6DSR_WriteRegisters(&gsensorInterrupTestTable[0][0],
REG_TABLE_ROW_NUM(gsensorInterrupTestTable));
while (ucCount < 50)
{
vTaskDelay(10/portTICK_RATE_MS);
ucCount++;
}
#if (DEBUG_GS_GYRO_INT_COUNT == 1)
DBGMSG("g-sensor int count = %d\r\n", g_gs_int_count);
DBGMSG("gyro int count = %d\r\n", g_gyro_int_count);
#endif
return ucRet;
}
void LSM6DSR_INT1(void)
{
// INT1
unsigned char pucData[3];
unsigned char ucI2CCh = I2C_CH_LSM6DSR;
I2CRead(I2C_ADDR_LSM6DSR, LSM6DSR_STATUS_REG, &pucData[0], 1, ucI2CCh);
if(pucData[0] & LSM6DSR_STATUS_XLDA)
{
#if (DEBUG_GS_GYRO_INT_COUNT == 1)
g_gs_int_count++;
#endif
GSensorRead(READ_CURRENT_XL);
}
}
void LSM6DSR_INT2(void)
{
// INT2
unsigned char pucData[3];
unsigned char ucI2CCh = I2C_CH_LSM6DSR;
I2CRead(I2C_ADDR_LSM6DSR, LSM6DSR_STATUS_REG, &pucData[0], 1, ucI2CCh);
if (pucData[0] & LSM6DSR_STATUS_GDA)
{
#if (DEBUG_GS_GYRO_INT_COUNT == 1)
g_gyro_int_count++;
#endif
GyroRead(READ_CURRENT_GYRO);
}
}
Interrupt test code
2023-03-16 07:54 PM
Dear All,
I found that swap the order of setup to enable XL ODR and Gyro ODR, the weird 1st XL interrupt disappears.
ie, swap the latest two setup order
But still don't know why?
//Set INT1 source
{ (LSM6DSR_INT1_CTRL_REG), (0x01) },
//Set INT2 source
{ (LSM6DSR_INT2_CTRL_REG), (0x02) },
//Set g sensor scale and ODR
{ (LSM6DSR_CTRL1_XL_REG), (LSM6DSR_XL_RANGE_2G + LSM6DSR_XL_ODR_104HZ)
//Set gyro scale and ODR
{ (LSM6DSR_CTRL2_G_REG), (LSM6DSR_G_ODR_104HZ + LSM6DSR_G_FS_2000DPS) },
},