My code was successfully using the polling method for I2C, interfacing with a MCP23017 bus expander. However, due to some timing problems, I am moving to interrupt driven I2C comms to free up some CPU time. I have based my code on the source files provided for SPMA073 found here on the TI site. I realize that it was written for the Tm4C129x, but I was hoping to adapt it to the TM4C123.
The first thing I noticed was that the sample code seems to be using a 16-bit register address, where I only need an 8-bit register address, so I corrected that. I can set breakpoints in the interrupt handler and see if sends the register address and the two bytes of data (register address 0x00, data is 0x00 and 0x00, to set the bus expander ports to outputs.)
I also see it send the last byte from
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
Then it hangs up in the while loop in the code below. It never transitions to the I2C_OP_STOP state. See snippet from interrupt handle at the bottom. Any ideas??
g_ui8MasterTxData[0] = 0x00;
g_ui8MasterTxData[1] = 0x00;
g_ui8MasterTxData[2] = 0x00;
g_ui8MasterBytesLength = 2;
//
// Set Transmit Flag and set the Page Address in
// external slave to 0x0000
//
g_bI2CDirection = false;
g_registerAddress = 0x00;
g_ui16SlaveWordAddress = 0x0;
g_ui8MasterBytes = 0;
IntTrigger(INT_I2C0);
while(g_ui8MasterCurrState != I2C_OP_STOP);
g_ui8MasterCurrState = I2C_OP_IDLE;
INTERRUPT HANDLER SNIPPET
case I2C_OP_TXDATA:
//
// Move the current state to the previous state
// Else continue with the transmission till last byte
//
g_ui8MasterPrevState = g_ui8MasterCurrState;
//
// If Address or Data has been NAK'ed then go to stop state
// If a Stop condition is seen due to number of bytes getting
// done then move to STOP state
//
if(ui32I2CMasterInterruptStatus & I2C_MASTER_INT_NACK)
{
g_ui8MasterCurrState = I2C_OP_STOP;
}
else if(ui32I2CMasterInterruptStatus & I2C_MASTER_INT_STOP)
{
g_ui8MasterCurrState = I2C_OP_STOP;
}
else
{
I2CMasterDataPut(I2C0_BASE, g_ui8MasterTxData[g_ui8MasterBytes++]);
if(g_ui8MasterBytes == g_ui8MasterBytesLength)
{
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
}
else
{
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
}
}
break;