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.

TMS320F280049C: I2C ARDY bit behaviour in Master Transmitter in Repeat Mode in case of NACK from slave

Part Number: TMS320F280049C

I am doing some experiments with the I2C peripheral to understand it better. When in repeat mode master transmitter, I enable STT bit and then put data in TX FIFO. The code is as follows:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Set as master transmitter in Repeat mode
I2C_setConfig(I2CA_BASE, (I2C_MASTER_SEND_MODE|I2C_REPEAT_MODE));
I2C_sendStartCondition(I2CA_BASE);
//Configure FIFO data for EEPROM address
I2C_putData(I2CA_BASE, (address>>8) & 0xFF);
I2C_putData(I2CA_BASE, address & 0xFF);
//wait for the data to be sent
//ARDY is low when data is not yet sent. ARDY gets set when all data in FIFO has been sent
attemptCount = 1;
extern volatile uint32_t externcount;
attemptCount = 0;
while(attemptCount < 160)
{
if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) != 0U)
{
//all data in FIFO has been sent along with START, Device Address
//so break out of the loop
break;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

If the microcontroller recieves NACK from slave receiver, I see that NACK goes high and ARDY goes high as seen from the snapshot below:

I could not find any mention of such behaviour in the TRM.
I only found the following information regarding behaviour of ARDY in the document:



Behaviour of ARDY under NACK reception is not clear from above. Is my understanding that ARDY bit is set when TX or RX is successful or NACK is received correct?
Could anyone please give a clarification regarding this behaviour?

  • Apran,

    ARDY bit behavior is mentioned below. It doesn't explicitly talk about NACK vs ACK because the behavior of ARDY bit is the same whether NACK (or) ACK is received. So, yes ARDY bit does get set irrespective ACK / NACK condition.

    Regards,

    Manoj

  • Hi Manoj,

    ARDY bit behavior is mentioned below.

    I think you missed to add something.

    ARDY bit does get set irrespective ACK / NACK condition.

    Let's say there are 3 bytes to be transmitted in TX FIFO in REPEAT MASTER mode. NACK is received on the first byte itself. What happens next? Will it set ARDY immediately? Or it will try to send all 3  bytes one by one and get NACKed 3 times and then set ARDY in the end?

    Regards,
    Arpan

  • Hi Manoj,

    Let's say in Repeat mode as master transmitter, if there is no data in TX FIFO and we set STT. Does ARDY get set after START condition is sent? Similarly, if we raise STP, is ARDY set after STOP condition gets sent?

    Regards,
    Arpan

  • Arpan,


    Let's say in Repeat mode as master transmitter, if there is no data in TX FIFO and we set STT. Does ARDY get set after START condition is sent?

    Yes, ARDY bit does get set

    Similarly, if we raise STP, is ARDY set after STOP condition gets sent?

    No, ARDY doesn't get set when STOP condition is set. You can wait for I2caRegs.I2CSTR.SCD bit to set to detect whether STOP condition got generated.

    Regards,

    Manoj

  • Hi Manoj,

    Okay. Understood. Could you please add these to the documentation. All these are not at all clear from the present documentation.

    Regards,
    Arpan

  • Hi Manoj,

    Could you please reply to the message quoted below?

    Hi Manoj,

    ARDY bit behavior is mentioned below.

    I think you missed to add something.

    ARDY bit does get set irrespective ACK / NACK condition.

    Let's say there are 3 bytes to be transmitted in TX FIFO in REPEAT MASTER mode. NACK is received on the first byte itself. What happens next? Will it set ARDY immediately? Or it will try to send all 3  bytes one by one and get NACKed 3 times and then set ARDY in the end?

    Regards,
    Arpan

    Regards,
    Arpan

  • As soon as I2C gets NACK condition ARDY bit does get set immediately.

  • Hi Manoj,

    The vrious aspects of ARDY are not clear from the available information in TRM. Could it be expanded so that it's clearer?

  • Hi Manoj,

    In the example provided by you in a different thread e2e.ti.com/.../3909865

    Arpan,

    In I2C master receiver configuration in repeat mode, you should be knowing when you are receiving the last byte. Before you receive last byte you need to enable NACKMOD = 1. There is a code snippet which demonstrates that.

    #define WAIT_TILL_REGISTERS_ARE_READY !(I2C_getStatus(I2CA_BASE) & I2C_STS_REG_ACCESS_RDY)

        I2C_disableFIFO(I2CA_BASE);

        I2C_setConfig(I2CA_BASE, (I2C_MASTER_SEND_MODE | I2C_REPEAT_MODE));

        I2C_sendStartCondition(I2CA_BASE);

        I2C_putData(I2CA_BASE, 0); while(WAIT_TILL_REGISTERS_ARE_READY);

        I2C_putData(I2CA_BASE, 0); while(WAIT_TILL_REGISTERS_ARE_READY);

        I2C_setConfig(I2CA_BASE, (I2C_MASTER_RECEIVE_MODE | I2C_REPEAT_MODE));

        I2C_sendStartCondition(I2CA_BASE);

        for(i=1;i<=5;i++)
        {
          status = I2C_getData(I2CA_BASE);while(WAIT_TILL_REGISTERS_ARE_READY);
        }

        I2C_sendNACK(I2CA_BASE);

        status = I2C_getData(I2CA_BASE);while(WAIT_TILL_REGISTERS_ARE_READY);

        I2C_sendStopCondition(I2CA_BASE);

    Regards,

    Manoj

    After configuring it in receive mode and sending Start condition, if we call I2C_getData() immediately, we are not giving time to microcontroller to receive the data from slave. Should we add ARDY and NACK check in between. If yes, then how many times ARDY check is needed? Twice? Once for STP bit and then for RX?

    Regards,
    Arpan

  • Hi Manoj,

    I have written the following code to Receive 1 byte as Master in Repeat mode:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    //Set as master receiver in Repeat mode
    I2C_setConfig(I2CA_BASE, (I2C_MASTER_RECEIVE_MODE|I2C_REPEAT_MODE));
    I2C_sendStartCondition(I2CA_BASE);
    //NACK would be sent on next byte received from slave
    //I2C mandates NACK be sent upon reading the last byte before STOP
    I2C_sendNACK(I2CA_BASE);
    //wait for the START condition to be sent. It will also send the slave address with R/W bit
    //ARDY is low when START, slave address+R/W bit is not yet sent. ARDY gets set when START, slave address+R/W bit has been sent or NACK is received
    attemptCount = 1U;
    while(attemptCount < 100U)
    {
    DEVICE_DELAY_US(10);
    if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) != 0U)
    {
    //START, Device Address has been sent or NACK has been received
    //so break out of the loop
    break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    I need your feedback regarding this code:

    1. After setting STP bit, I am waiting till MST bit is reset and then checking for MST and STP bites to ensure that STOP condition has been sent. In this code, I am doing this after sending STOP if NACK is received from slave (lines 38 to 81). Do you think it's a correct approach after NACK has been received and when I want to send STOP at the end of any I2C operation?
    2. What do you think of the following seuence to receive 1 byte ? The sequence used in the above code is summarised below: 

      I2C_setConfig(I2CA_BASE, (I2C_MASTER_RECEIVE_MODE|I2C_REPEAT_MODE));
      I2C_sendStartCondition(I2CA_BASE);
      I2C_sendNACK(I2CA_BASE);
      //wait for START and slave address+R/W to be sent
      while(WAIT_TILL_REGISTERS_ARE_READY);
      //wait for 1 byte data to be clocked in
      while(WAIT_TILL_REGISTERS_ARE_READY);
      //read the 1 byte data received
      *byte = I2C_getData(I2CA_BASE);
      I2C_sendStopCondition(I2CA_BASE);

    Regards,
    Arpan

  • Arpan,

    After configuring it in receive mode and sending Start condition, if we call I2C_getData() immediately, we are not giving time to microcontroller to receive the data from slave. Should we add ARDY and NACK check in between.

    ARDY and NACK condition needs on START condition, each time a byte is transmitted / received. For STOP condition, you can wait for I2CSTR.SCD bit to go high to ensure STOP condition is generated.

  • What do you think of the following seuence to receive 1 byte ? The sequence used in the above code is summarised below: 

    I2C_setConfig(I2CA_BASE, (I2C_MASTER_RECEIVE_MODE|I2C_REPEAT_MODE));
    I2C_sendStartCondition(I2CA_BASE);
    I2C_sendNACK(I2CA_BASE);
    //wait for START and slave address+R/W to be sent
    while(WAIT_TILL_REGISTERS_ARE_READY);
    //wait for 1 byte data to be clocked in
    while(WAIT_TILL_REGISTERS_ARE_READY);
    //read the 1 byte data received
    *byte = I2C_getData(I2CA_BASE);
    I2C_sendStopCondition(I2CA_BASE);

    You don't need two while(WAIT_TILL_REGISTERS_ARE_READY) loops. You just need one.

    After setting STP bit, I am waiting till MST bit is reset and then checking for MST and STP bites to ensure that STOP condition has been sent. In this code, I am doing this after sending STOP if NACK is received from slave (lines 38 to 81). Do you think it's a correct approach after NACK has been received and when I want to send STOP at the end of any I2C operation?

    To check whether STOP condition has been successfully generated, you need to use I2CSTR.SCD bit. You seem to be using I2CMDR.MST bit. I wouldn't do that when there is specifically a SCD bit to tell whether STOP condition got generated.

    Regards,

    Manoj


  • The vrious aspects of ARDY are not clear from the available information in TRM. Could it be expanded so that it's clearer?

    All the contents regarding ARDY bit is provided in current TRM. It is just that it is little bit scattered all over the place. I will review and try to consolidate it next TRM release.

  • You don't need two while(WAIT_TILL_REGISTERS_ARE_READY) loops. You just need one.

    When does ARDY go high? Because you had said earlier that ARDY goes high after START condition is sent out by master. 
    I think then again ARDY will go high after 1 byte is received. Is it not so?

    Regards,
    Arpan

  • To check whether STOP condition has been successfully generated, you need to use I2CSTR.SCD bit. You seem to be using I2CMDR.MST bit. I wouldn't do that when there is specifically a SCD bit to tell whether STOP condition got generated.

    This is according to I2C tips recommendation :

    Back-to-Back Transfers[edit]

    If you do multiple transfers in a row you may notice that you need some amount of delay between the transfers. That is, once the stop bit has been sent for one transfer you need to wait a specific amount of time before starting the next transfer. This is similar to the NACK handling where you issue a STOP condition and then retry. In both of these scenarios you need to poll for I2CMDR.MST==0 before you attempt to initiate the next START condition.
  • Arpan,

    In my previous post, I had said ARDY does get SET even if the slave NACK the transaction on a START condition. Below, code will work file for 1 byte receive transaction.

        I2C_setConfig(I2CA_BASE, (I2C_MASTER_RECEIVE_MODE | I2C_REPEAT_MODE));

        I2C_sendStartCondition(I2CA_BASE);

        I2C_sendNACK(I2CA_BASE);

        while(WAIT_TILL_REGISTERS_ARE_READY); //check ARDY bit is set (or) not.

        RX_MsgBuffer[0] = I2C_getData(I2CA_BASE);

        I2C_sendStopCondition(I2CA_BASE);

    Regards,

    Manoj