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.

TMS320F28379D: stale byte sent when polling XRDY during slave transmit routine

Part Number: TMS320F28379D

I have some I2C slave code that polls the XRDY bit in I2CSTR when a slave transmit is requested.

Have noticed that on the first call the slave transmit works as expected. On subsequent calls XRDY isn't set and the first data byte that the slave sends is a stale byte from the end of the Tx buffer from the last call.

Seems like during the last call the slave wrote to I2CDXR but the master NACKd indicating the transfer was done and so the slave never sent out the data to I2CXSR, data is still in I2CDXR, and the XRDY bit didn't get set. So on the next call this old byte gets sent first. Writing a 1 to XRDY before starting the slave transmit loop seems to fix the stale byte issue but I noticed in the TRM that XRDY is indicated as read only (R) but then in the description it infers R/W. From what I can tell I can write a 1 to XRDY but not a 0.

Wondering if there's any issue with forcing XRDY to 1 before starting the transfer or if there's a cleaner way that would maybe avoid this last byte getting written to I2CDXR? Thanks!

    if (I2caRegs.I2CSTR.bit.AAS == 1 && I2caRegs.I2CSTR.bit.SDIR == 1)
    {
        I2caRegs.I2CMDR.bit.TRX = 1; 
        //I2caRegs.I2CSTR.bit.XRDY = 1;  // when this line is uncommented the stale byte problem goes away
        while (I2caRegs.I2CSTR.bit.SCD == 0)  
        {
            if (I2caRegs.I2CSTR.bit.XRDY == 1)  
            {
                I2caRegs.I2CDXR.all = *data++;
            }
        }
        I2caRegs.I2CSTR.bit.SCD = 1;
        I2caRegs.I2CMDR.bit.TRX = 0;
    }

  • Hello Ricker,

    If I'm understanding you correctly, you're using the F2837xD as a target device and an external I2C controller is receiving data from the F2837xD. However the F2837xD receives a NACK from the I2C controller and the last data loaded to the I2CDXR doesn't get sent so the XRDY doesn't show that the I2C is ready to transmit another byte, is that correct?

    Writing a 1 to XRDY before starting the slave transmit loop seems to fix the stale byte issue but I noticed in the TRM that XRDY is indicated as read only (R) but then in the description it infers R/W. From what I can tell I can write a 1 to XRDY but not a 0.

    I see this conflicting information in the reference manual, I will discuss this with the design experts to determine which is the case (I believe the register description is accurate, but I will confirm).

  • Yes correct. The NACK from the master I2C controller is the normal NACK that occurs when the master-receiver is done reading data and is indicating such to the slave with a NACK. The last loaded data on the F2837xD doesn't get sent, which is the correct action because all the data bytes that the master wanted were received, however on the next transfer XRDY is not set so that last loaded byte gets sent (unless I force XRDY to 1).

  • Hello Ricker,

    The last loaded data on the F2837xD doesn't get sent, which is the correct action because all the data bytes that the master wanted were received, however on the next transfer XRDY is not set so that last loaded byte gets sent.

    I think the way you're clearing the status bit by clearing the XRDY bit is not what we describe should be done, I checked in driverlib and there is an existing function for doing something exactly like this but it explicitly excludes the macros used for XRDY (I2C_STS_TX_DATA_RDY) and some others:

    There is a way to reset all status bits by resetting the I2C module. The ISR bit in the I2CMDR register will reset only the I2CSTR bits and set them to their default values:

    This can be done in driverlib using the I2C_disableModule/I2C_enableModule functions.

  • Ok, yeah using the IRS bit at the end of the function seems to work. Guess I could also just write to I2CDXR once before the while (I2caRegs.I2CSTR.bit.SCD == 0) to bypass the first if (I2caRegs.I2CSTR.bit.XRDY == 1) .

    I was definitely able to write a 1 to XRDY so interesting to hear about the documentation on that one.

    Thanks for the ideas!

  • Hello Ricker,

    I was definitely able to write a 1 to XRDY so interesting to hear about the documentation on that one.

    I was able to confirm that while we only document read-only for the XRDY, the XRDY is R/W. I will update the documentation to reflect this.

    The design expert also said for devices after F2837xD (i.e. F28004x, F2838x, F28002x, F28003x, F280015x/13x, F28P65x, etc.) the issue of stale data can be resolved using FSM=1, but yes for F2837xD writing to the XRDY bit seems to be one possible solution.

  • Ok good to know. Thanks!