2023-03-08 01:45 AM
I tried to get XL and gyro data by data-ready interrupt mode,
1. Configuartion registers sequence and values are as follows
Use Bypass mode, XL data-ready rounted to INT1; gyro data-ready rounted to INT2
2. In ISR1 reads the STATUS_REG, if XLDA bit is set, read XL data
3. In ISR2 reads the STATUS_REG, if GDA bit is set, read gyro data
is that correct to get XL and gyro by data-ready interrupt mode?
My questions are
setup sequence
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 = 0x41
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
const unsigned char gsensorInterrupTestTable[13][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) },
//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) },
};
========================================
INT1 and INT2 works fine if read XL, read gyro inside ISR
char LSM6DSR_InterruptTest(void)
{
unsigned char pucData[3];
unsigned char ucI2CCh = I2C_CH_LSM6DSR;
unsigned char ucCount = 0;
unsigned char ucRet = 0;
int rval = 0;
unsigned char i = 0;
uint32_t t0, t1 = 0;
// software reset
pucData[0] = LSM6DSR_CTRL3_C_REG;
pucData[1] = LSM6DSR_SOFT_RESET;
rval = 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++;
}
DEBUGMSG("g-sensor int count = %d\r\n", g_gs_int_count);
DEBUGMSG("gyro int count = %d\r\n", g_gyro_int_count);
return ucRet;
}
void LSM6DSR_ISR1(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) {
g_gs_int_count++;
GSensorRead(READ_CURRENT_XL);
}
}
void LSM6DSR_ISR2(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) {
g_gyro_int_count++;
GyroRead(READ_CURRENT_GYRO);
}
}
===========================================================
INT1 and INT2 goes high after read XL(system hangs), read gyro inside background while(1) during timeout 500ms
char LSM6DSR_InterruptTest(void)
{
unsigned char pucData[3];
unsigned char ucI2CCh = I2C_CH_LSM6DSR;
unsigned char ucCount = 0;
unsigned char ucRet = 0;
int rval = 0;
unsigned char i = 0;
uint32_t t0, t1 = 0;
// software reset
pucData[0] = LSM6DSR_CTRL3_C_REG;
pucData[1] = LSM6DSR_SOFT_RESET;
rval = 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) {
I2CRead(I2C_ADDR_LSM6DSR, LSM6DSR_STATUS_REG, &pucData[0], 1, ucI2CCh);
if(pucData[0] & LSM6DSR_STATUS_XLDA) {
GSensorRead(READ_CURRENT_XL, true);
}
if (pucData[0] & LSM6DSR_STATUS_GDA) {
GyroRead(READ_CURRENT_GYRO, true);
}
vTaskDelay(10/portTICK_RATE_MS);
ucCount++;
}
DEBUGMSG("g-sensor int count = %d\r\n", g_gs_int_count);
DEBUGMSG("gyro int count = %d\r\n", g_gyro_int_count);
return ucRet;
}
void LSM6DSR_ISR1(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) {
g_gs_int_count++;
}
}
void LSM6DSR_ISR2(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) {
g_gyro_int_count++;
}
}
2023-04-13 06:22 AM
Hi @E-John ,
For any other questions I suggest you look at our PID on github.
If my reply answered your question, please click on Select as Best at the bottom of this post. This will help other users with the same issue to find the answer faster!
2023-04-13 07:27 AM
Hi @Federica Bossi
I have referred to the code on github, it does not enable the ISR1 and ISR2 on LSM6DSR IC.
My question is when I enable XL and Gyro Interrupt on LSM6DSR
If read the XL and gyro data on while(1) loop, system is hanged, it is OK when read XL and gyro on ISR1 and ISR2
If XL and gyro interrupt is enable on LSM6DSR, to read data on while(1) or read data on ISR is correct?
Thanks.
2023-04-13 08:01 AM
Hi @E-John ,
Look at the function lsm6dsrx_main_interrupt on Github to enable the ISR1 and ISR2 on LSM6DSR IC.
In particular this part:
void lsm6dsrx_main_interrupt(void) {
stmdev_ctx_t dev_ctx;
/* Uncomment to configure INT 1 */
//lsm6dsrx_pin_int1_route_t int1_route;
/* Uncomment to configure INT 2 */
//lsm6dsrx_pin_int2_route_t int2_route;
/* Initialize mems driver interface. */
Let me know if this solves your problem
2023-04-25 01:01 AM
Hi Federica,
I have enable the interrupt on my system. it read the g-sensor and gyro data on while(1) loop, the system hanges on my side, is there any missing for this flow?
Thanks.
2023-04-26 01:41 AM
Ciao @E-John ,
Let's try to enable the dataready_pulsed bit (reg 0Bh) and see if the system still hangs.
Also please check interrupt priority in your system.
If my reply answered your question, please click on Select as Best at the bottom of this post. This will help other users with the same issue to find the answer faster!