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.

MSP430I2041: I2C Implementation without with flag polling only

Part Number: MSP430I2041

Hi!

I'm developing a portable I2C library which should rely on common flags that can be found on devices from G2553 to I2041: I chose only TX, RX and NACK flags by now.

However, this question aims to gain a better understanding of the I2C operations regardless the chosen MCU. I read three or four user guides looking at the I2C registers and the master operations flow chart, but it's still not clear how and when should i poll-reset the flag.

This is the reference scheme (eUSCI I2C Mode, from SLAU335):

 

According to this scheme, I drew the following conclusions and wrote a test code. Please tell me if i'm wrong.
  1. When I set UCTR, the start sequence (along with the slave address) is transmitted. UCTXIFG becomes 1, meaning I can write data in UCBxTXBUF (tx flag polling)
  2. The slave can ACK/NACK the address byte if and only if something is written in UCBxTXBUF, so after writing my data I have to clear UCTXIFG, check UCNACKIFG, and eventually give a STOP or a START condition. Thus, an ACK/NACK requires something to be written in TXBUF immediately after the start condition.
  3. After the TXBUF writing, the UCTXIFG will be set ONLY when I'm supposed to decide if sending another byte or if issuing a START/STOP condition.
  4. The ACK/NACK after a data byte comes only if i do another TXBUF write or a START/STOP condition.
So, for sending multiple bytes i wrote this code, but works only with one data byte:


char I2C_Send(unsigned char Slave_Address, unsigned char ByteNum, unsigned char * TxArrayAddr )
{

    unsigned int txBuf_index=0;

    UCB0I2CSA = Slave_Address;          // Address Assignment
    UCB0IFG &=~ (UCTXIFG + UCNACKIFG);  // Flag Clear

    UCB0CTL1 |= UCTR + UCTXSTT;         // I2C TX, start condition
    //UCB0IFG &=~ UCTXIFG;                // Azzero UCTXIFG (si alza solo dopo l'ack)

    while(!(UCB0IFG & UCTXIFG));    // While TXIFG = 0

    while(txBuf_index < (ByteNum - 1))
    {
        UCB0IFG &=~ UCTXIFG; // BO
        UCB0TXBUF = TxArrayAddr[txBuf_index++]; // Fill TxBuffer (slave can ACK/NACK)

        while(!(UCB0IFG & UCTXIFG))         // Mentre UCTXIFG è zero,
        {
            if(UCB0IFG & UCNACKIFG)         // Se ricevo un NACK, esco.
            {
                UCB0CTL1 |= UCTXSTP;        // Issue stop
                return 1;
            }
        }
        if(UCB0IFG & UCNACKIFG)         // Se ricevo un NACK, esco.
        {
            UCB0CTL1 |= UCTXSTP;        // Issue stop
            return 1;
        }
        // Se è uno (posso trasmettere anche il secondo byte)
        //UCB0IFG &=~ UCTXIFG;            // Flag Clear
    }

    UCB0IFG &=~ UCTXIFG; //  BO
    UCB0TXBUF = TxArrayAddr[txBuf_index++];
    while(!(UCB0IFG & UCTXIFG))         // Mentre UCTXIFG è zero,
    {
        if(UCB0IFG & UCNACKIFG)         // Se ricevo un NACK, esco.
        {
            UCB0CTL1 |= UCTXSTP;        // Issue stop
            return 1;
        }
    }


    UCB0CTL1 |= UCTXSTP;

    return 0;
}

What i'm missing? is something obviously wrong and i don't catch it? After two bytes i receive a nack  but it ignores it.

Thank you in advance!





  • Not only UCTR sorry, UCTR and UCTXSTT
  • Hello Mirco,

    In general, for the USCI module, you shouldn't have to poll the Reset flag. The USCI module takes care of most of the I2C operations. For a polling solution, you should only really need the TX , RX, and Start flags for most operations given the assumption that you know what the transactions look like (aka length) and are only on talking to one other device. You may need the addition of the Stop flag if length can be variable on some commands, but typically if its followed by another command, a repeated Start is done. You would only need to poll the NACK flag during the address phase of a transaction to make sure you are talking to the right end device and its ready to receive commands.
  • Jace H said:
    Hello Mirco,

    In general, for the USCI module, you shouldn't have to poll the Reset flag. The USCI module takes care of most of the I2C operations. For a polling solution, you should only really need the TX , RX, and Start flags for most operations given the assumption that you know what the transactions look like (aka length) and are only on talking to one other device. You may need the addition of the Stop flag if length can be variable on some commands, but typically if its followed by another command, a repeated Start is done. You would only need to poll the NACK flag during the address phase of a transaction to make sure you are talking to the right end device and its ready to receive commands.

    Thank you!

    Sorry, what do you mean with "poll the reset flag"? and, do i have to manually clear the flags?

    The idea is to create a dynamic library that can receive "n" bytes and that can manage NACKs without getting stuck.

    Another question: the slave can ACK/NACK if and only if i do one of these three operations: Write a byte in txbuf, set STP or STT. Is this correct? If so, when do I have to write my next data byte if TXIFG will raise only after an ACK/NACK?

  • Mirco,

    I think I misunderstood your question earlier in regards to reset. All interrupt flags are cleared automatically in the eUSCI module, but in associated with specific user actions. For example, the TXIFG flag is cleared when the TXBUFF is filled, and the RXIFG is cleared once the RXBUFF is read out.

    As far as possible times a slave can ack/nack, you would have to read the I2C specification document for all possible times.

    I do know:
    When Master Transmitting:
    the slave can ACK/NACK after receiving an address. The slave should ACK/NACK after receiving each databyte as well

    When Master Receiving:
    the slave can ACK/NACK after receiving an address. After that the Master ACKS/NACKs depending if they want to continue or stop the transmission with stop or repeated start.
  • Thank you! Almost finished my doubts...

    Please take a look at the first part of the scheme above where it says "the clock is stretched until data available" BEFORE the "A" square. The clock will be stretched after every byte of data?
  • Hello Mirco,

    Per I2C spec, a slave device can stretch the clock on any bit from an incoming data byte until said slave device is ready to receive the data. In practice though, its typically the seventh bit of a data stream. But to get back to your question, yes the slave can possible stretch the clock at any data byte that its incoming from the master.

**Attention** This is a public forum