cancel
Showing results for 
Search instead for 
Did you mean: 

[LSM6DSR] Why the span between 1st XL interrupt and 2nd XL interrupt is weird

E-John
Associate III

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

0693W00000aJ5m2QAC.pngFig.1 weird 1st XL interrupt, span between 1st XL interrrupt and 2nd one is about 4.3ms

0693W00000aJ5mCQAS.pngFig.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

1 REPLY 1
E-John
Associate III

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) },
},

0693W00000aJAUnQAO.png