5 years, 4 months ago.

I2C InterruptIn Failed

I'm using I2C to read data from MPU9250. I2C can write and data successfully without InterruptIn. I want to using InterrputIn to read data. When data of MPU9250 is ready, the pin of interruptin gets low. When the program runs, it can get in the callback function of interruptin. But in the callback function, i2c.read() and i2c.write() always return 1. How can I solve the problem?

include the mbed library with this snippet

//InterruptIn Callback Function
void MPU9250::Read_IMU_Data()
{
	int status;
	char int_status=0;
	char gyro_data_raw[6]={0};
	char accel_data_raw[6]={0};
	
	flag_read_data=0;

	status=iic_imu.Read_Reg(slave_addr, MPU_INT_STA_REG, &int_status, 1); //always return 1 when interrupt happens
	if((int_status&0x01)==0)
		return;

	
	status=iic_imu.Read_Reg(slave_addr, MPU_GYRO_XOUTH_REG, gyro_data_raw, 6);
	if(status)
	{
		flag_read_data=1;
		return;
	}
		
	
	status=iic_imu.Read_Reg(slave_addr, MPU_ACCEL_XOUTH_REG, accel_data_raw, 6);
	if(status)
	{
		flag_read_data=2;
		return;
	}
	return;
}

//Setting of callback function of interruptin
int_imu.fall(callback(this,&MPU9250::Read_IMU_Data));

1 Answer

5 years, 4 months ago.

Hello Cunqiu,

I2C's read method cannot be called in an Interrup Service Routine (ISR) because read in first step locks the mutex and unlocks it only before returning, which is not allowed in context of an interrupt service routine (ISR). Read here.
However, you can set a flag in InterruptIn ISR and use it the context of the main function for example as outlined here.