I am having an I2C communications lockup issue when during communications the processor experiences a brownout or is put into a low power state because of loss of power.
I am using the KSDK_1.30 and MKL36Z64 microcontroller for this project. I am using the SDK functions (“I2C_DRV_MasterSendDataBlocking” / “I2C_DRV_MasterReceiveDataBlocking”) to send/receive a message and result status is “kStatus_I2C_Busy”.
i2c_result = I2C_DRV_MasterReceiveDataBlocking(I2C_PORT_0, &i2c_slave_eeprom, cmdBuff, 1, receiveValues, 3, I2C_TIMEOUT_MS);
I am using the low voltage warning interrupt flag to initiate sleep mode and uses a supcap to maintain power during the power outage. The I2C EEPROM that we are communicating with is not backed up by the supercap. When power is restored a rising edge on the LLWU wakeup pin restores the processor to normal operation. The only thing we need operational and maintained during the sleep is the RTC. Upon wakening the code starts running from the beginning and reconfigures the I/O and reinitializes memory values.
For debug purpose, I also have I2C0_C1, I2C0_S, I2C0_FLT, and “i2c_result” values displayed on LCD when the device is up and running.
When device wakes up from a sleep mode, all modules work correctly except I2C. Receiving a “kStatus_I2C_Busy” status each time when I2C is used.
Here are the register values when device wakes up from a sleep mode and starts running:
I2C0_C1 value is 0x90,
I2C0_S value is 0x80,
I2C0_FLT is 0x80, and
“i2c_result” is “kStatus_I2C_Busy”.
With sleep mode code commenting out:
There is no issue with I2C except under certain brownout conditions. When VCC is removed, the device shuts down and when VCC is applied back, it will go through a power on reset (or LVD reset).
Here are the register values when device goes through a power on reset/LVD reset:
I2C0_C1 value is 0x88,
I2C0_S value is 0x84,
I2C0_FLT is 0xd0, and
“i2c_result” is “kStatus_I2C_Success”.
/*********** I2C Initialization Code ******************/
The code to initialize i2c is below:
void init_i2c_master( void )
//Initialize the I2C master mode driver
init_i2c_master (); //Initialize I2C instance 0 master
//Debug: Stop Hold Enable. Stop holdoff is enabled.
I2C0_FLT |= I2C_FLT_SHEN_MASK;
/****** END of I2C Initialization Code *****************/
I have tried several things to resolve the problem. But none of them have worked.
- If "i2c_result" is "Arbitration lost" or "busy", disable and re-enable I2C. Did not work.
- Toggle the I2C clock line if “i2c_result” is NOT “kStatus_I2C_Success”. I did this by disabling I2C then set I2C clock line as GPIO output and toggle it. Then reconfigure the pin as an I2C clock line. Finally enable I2C. Did not work.
- In LVD_LVW_IRQHandler ( ), I tried I2C “Deinit” and changed I2C clock and data line mux settings to “0” (pins are disabled). This did not work.
I have reached the end of what I know, any comments or suggestions would be appreciated. Thank you.