This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

I2C on F2809



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;
}