I'm trying to develop a simple I2C F2809 Driver. Reading the datasheets, my expectation is that I should simply be able to set STT, STP and I2CCNT, then feed data in or extract it out as I need by checking XRDY/ARDY/RRDY/SCD. F2809 is always in master mode.
Here is the code I'm using... can any one see my mistake?
Thanks,
Roger
I2CTransactionResult_t I2CWrite(I2CPacket_t * I2CPacket)
{
if (I2caRegs.I2CSTR.bit.BB)
return I2CBB;
BSRL_LOCK_I2C(I2C_EEPROM);
I2CPacket->PacketTransmitFailed = FALSE;
I2CPacket->PayloadBytesTransacted = 0;
I2caRegs.I2CMDR.bit.TRX = 1; // Set to transmit data.
I2caRegs.I2CCNT = I2CPacket->AccessAddressBytes + I2CPacket->PayloadByteLength;
I2caRegs.I2CSAR = I2CPacket->SlaveIDAddress;
I2caRegs.I2CDXR = NextI2CByte(I2CPacket);
//////////////////////////////////////////
//
// For debugging, I2C is located at 0x7900.
//
// Start a write attempt. Set Start and stop bit.
I2CTransactionResult_t Result = I2CSTILLRUNNING;
I2caRegs.I2CMDR.bit.STT = 1; // Start code
// Wait for the write cycle to finish.
while (Result == I2CSTILLRUNNING)
{
// Code hangs in this loop.
if ((I2caRegs.I2CSTR.bit.XRDY) || (I2caRegs.I2CSTR.bit.ARDY)) // There is more data to send.
{
if (I2caRegs.I2CSTR.bit.XRDY) I2caRegs.I2CSTR.bit.XRDY = 1;
if (I2caRegs.I2CSTR.bit.ARDY) I2caRegs.I2CSTR.bit.ARDY = 1;
I2caRegs.I2CDXR = NextI2CByte(I2CPacket);
}
if (I2caRegs.I2CSTR.bit.SCD)
{
I2caRegs.I2CMDR.bit.STP = I2CPacket->EndWithStopBit; // Stop code
Result = I2COK;
}
else if (I2caRegs.I2CSTR.bit.NACK) // We received a NAK- probably because the device is busy.
{
I2caRegs.I2CMDR.bit.STP = I2CPacket->EndWithStopBit; // Stop code
Result = I2CNAK;
}
else if (I2caRegs.I2CSTR.bit.AL) // We received a NAK- probably because the device is busy.
Result = I2CAL;
}
BSRL_UNLOCK_I2C(I2C_EEPROM);
return I2COK;
}
I2CTransactionResult_t I2CRead(I2CPacket_t * I2CPacket)
{
BSRL_LOCK_I2C(I2C_EEPROM);
// Point SendPacket to I2C Packet.
I2CPacket->PacketTransmitFailed = FALSE;
I2CPacket->PayloadBytesTransacted = 0;
I2caRegs.I2CMDR.bit.TRX = 0; // Set to receive data.
I2caRegs.I2CCNT = I2CPacket->AccessAddressBytes + I2CPacket->PayloadByteLength;
I2caRegs.I2CSAR = I2CPacket->SlaveIDAddress;
I2caRegs.I2CDXR = NextI2CByte(I2CPacket);
I2CTransactionResult_t Result = I2CSTILLRUNNING;
I2caRegs.I2CMDR.bit.STT = 1; // Start code
I2caRegs.I2CMDR.bit.STP = I2CPacket->EndWithStopBit; // Stop code
while (Result == I2CSTILLRUNNING)
{
if (I2caRegs.I2CSTR.bit.RRDY)
{
I2CPacket->PayloadPtr[I2CPacket->PayloadBytesTransacted++] = I2caRegs.I2CDRR;
I2caRegs.I2CSTR.bit.RRDY = 1; // Acknowledge receive.
}
if (I2caRegs.I2CSTR.bit.SCD) // Stop condition detected.
{
I2caRegs.I2CMDR.bit.STP = I2CPacket->EndWithStopBit; // Stop code
Result = I2COK;
}
if (I2caRegs.I2CSTR.bit.NACK)
{
I2caRegs.I2CMDR.bit.STP = I2CPacket->EndWithStopBit; // Stop code
Result = I2CNAK;
}
else if (I2caRegs.I2CSTR.bit.AL)
Result = I2CAL;
}
BSRL_UNLOCK_I2C(I2C_EEPROM);
return I2COK;
}