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.
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.
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!
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?
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