Hi,
I recently experienced a "well known" I2C bus hang issue which happens when you reset an I2C Master in the middle of a transaction, specifically when the slave device is ACKnowledging. In my case I was resetting a running TM4C1294NCPDT.
What happens is, on reset, the clock from the master stops leaving the slave device holding SDA low (ACK state), so when the I2C module starts up again the bus is stuck BUSY with SDA lo and no way of recovering.
All you have to do is toggle the SCL line a few times until the slave releases the SDA line. (I'm not sure if this is guaranteed to work with all slave devices, but it worked for me!).
Here is my I2C initialisation code incase it helps someone with the same problem...
uint32_t i, count;
//initialise I2C3..................................................................................
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); //ensure bus is idle
ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_1);
count = 0;
while(ROM_GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_1) == 0) {
ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x00);
for(i=0;i<1000;i++) ;
ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0);
for(i=0;i<1000;i++) ;
count++;
if(count > 100) //max 100 toggles before giving up to ensure we don't get stuck here
break;
}
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3); //now can initialise the I2C peripheral as normal
while(!(ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C3))); //wait for peripheral ready
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_I2C3);
ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL);
ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA);
ROM_GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);
//ROM_I2CMasterInitExpClk(I2C3_BASE, ROM_SysCtlClockGet(), true); //400K
ROM_I2CMasterInitExpClk(I2C3_BASE, ROM_SysCtlClockGet(), false); //100K
HWREG(I2C3_BASE + I2C_O_FIFOCTL) = 80008000; //clear I2C FIFOs