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.

TMS320F28335: identify first and last byte in received I2C message

Part Number: TMS320F28335

I use my F28335 in I2C slave mode.

The I2C master is sending 4-byte messages, and the F28335 reads the messages in the I2C FIFO ISR:

interrupt void i2c_fifo_isr(void)
{
if (I2caRegs.I2CFFRX.bit.RXFFINT == 1)
{
Uint16 i=0;
for (i=0; i<4; i++)
receivedMessage[i] = I2caRegs.I2CDRR;
}
I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}

The problem: After some period of time I seem to be loosing sync.

For example, the master is sending messages with the content "ABCD" every 33[ms].

After a while, in my 4-byte buffer (receivedMessage), I see "BCDA" or "CDAB" (instead of "ABCD").

Is there a way to know that byte "A" was received after a start signal and that a stop signal was received after byte "D"?

Best regards,

Yiftah

  • Hi Yiftah,

    Have you confidently identified if this is an issue at the master or slave?

    Yiftah Kowal said:
    For example, the master is sending messages with the content "ABCD" every 33[ms].

    You've confirmed that the master is always sending the intended "ABCD" message correctly?

    Yiftah Kowal said:
    After a while, in my 4-byte buffer (receivedMessage), I see "BCDA" or "CDAB" (instead of "ABCD").

    If the issue is at the slave, maybe the FIFO buffer is not being emptied quick enough. Where new information from the transmitter is coming in before the slave's ready.

    Yiftah Kowal said:
    s there a way to know that byte "A" was received after a start signal and that a stop signal was received after byte "D"?

    This will take some additional processing to check the first and last bytes to see if they match "A" and "D". This feature isn't built into the I2C peripheral.

    Best,

    Kevin

  • Hi Kevin,

    You understand the problem correctly.

    After checking with an external I2C sniffer, my guess is both:

    • Sometimes it is caused by the master resetting itself, causing a message to be stopped in the middle sending only half of the message e.g. "AB", then after the master wakes from reset the master sends "ABCD...ABCD...ABDC", so the slave loses sync since it waits for 4-bytes messages and stores: "DCAB".
    • Sometimes the FIFO buffer is full and drops bytes.

    My question is not about keeping sync on the master side, but how to identify which byte is the first/last byte.

    I do not have control over the master. I would like to handle this problem on the slave side.

    Kevin Allen18 said:
    This will take some additional processing to check the first and last bytes to see if they match "A" and "D". This feature isn't built into the I2C peripheral.

    "ABCD" was just an example. The content of the message from the master may vary. So it will be difficult to add this additional processing without changing the message format on the master side.

    Is it possible to use the (AASINT) addressed as slave interrupt and (SCDINT) stop condition interrupt to detect the start and end of the I2C message? Will it work with the FIFO interrupt?

    Best regards,

    Yiftah

  • Hi Yiftah,

    Without being able to control/change the protocol from the master side this is definitely more difficult. Implementing a CRC would help with detecting these kinds of data errors.

    Yiftah Kowal said:
    Sometimes it is caused by the master resetting itself, causing a message to be stopped in the middle sending only half of the message e.g. "AB", then after the master wakes from reset the master sends "ABCD...ABCD...ABDC", so the slave loses sync since it waits for 4-bytes messages and stores: "DCAB".

    Can you probe the I2C bus and capture this issue? Maybe implementing a timeout on the c2000 slave receiver could help get around this. That is if "AB" is received and the bus hangs high for a while without any transmissions, the slave could assume the master had reset and timeout, then prepare for a new packet of data.

    Yiftah Kowal said:
    Sometimes the FIFO buffer is full and drops bytes.

    For this issue you could make the c2000 slave device NACK the slave address until it is ready to receive more data, i.e. emptied the FIFO buffer. The master should then keep trying to transmit the same data until it sees an ACK on the slave address.

    Yiftah Kowal said:
    Is it possible to use the (AASINT) addressed as slave interrupt and (SCDINT) stop condition interrupt to detect the start and end of the I2C message? Will it work with the FIFO interrupt?

    These registers can be used, but I don't understand how this helps you identify the first/last byte in a transmission.

    Best,

    Kevin

  • Kevin Allen18 said:
    implementing a timeout on the c2000 slave receiver

    I will add this.

    Kevin Allen18 said:
    you could make the c2000 slave device NACK the slave address

    How do I do that? 

    Kevin Allen18 said:
    These registers can be used, but I don't understand how this helps you identify the first/last byte in a transmission.

    In the FIFO ISR the last line of code disables and resets the FIFO RX:

    I2caRegs.I2CFFRX.bit.RXFFRST = 0; // disable receive FIFO

    And in the AAS ISR it is enabled:

    I2caRegs.I2CFFRX.bit.RXFFRST = 1; // enable receive FIFO

    Best regards,

    Yiftah

  • Hi Yiftah,

    Sorry for the delay in my response.

    To produce a NACK on the slave side, you would set the NACKMOD bit to 1 in the I2CMDR register. This will cause a NACK to be sent on the next Acknowledge cycle on the bus. You would cset this when the FIFO buffer is full or at a certain level. The FIFO interrupts can be utilized for this purpose, see the I2CFFRX register in the I2C guide:

    http://www.ti.com/lit/sprug03

    Yiftah Kowal said:

    In the FIFO ISR the last line of code disables and resets the FIFO RX:

    I2caRegs.I2CFFRX.bit.RXFFRST = 0; // disable receive FIFO

    And in the AAS ISR it is enabled:

    I2caRegs.I2CFFRX.bit.RXFFRST = 1; // enable receive FIFO

    Not really sure what the ISRs are used for in your application to comment much on this.

    Best,

    Kevin