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.
Hello,
I have an MSP430F5438A using UCSI_Bx in Slave mode.
I want to do following: NACK current frame if received data are not allowed.
Frame A)
Command not allowed => NACK
START, ADR+W, CMD+ NACK, STOP
Frame B)
Invalid received DATA => NACK
START, ADR+W, CMD, DATA+ NACK, STOP
START, ADR+W, CMD, DATA1, DATA2+ NACK, STOP
Frame C)
Reading of this command is not allowed => NACK
START, ADR+W, CMD, RESTART, ADR+R+NACK, DATA1, DATA2, STOP
If I’m right, the user guide (SLAU208G page 602) tells me that after reading incoming buffer UCBxRXBUF the bus is released.
Thus how can I read incoming data, have time to evaluate it and ACK or NACK after?
It looks that I can only NACK the next byte.
If I add a CRC byte in the frame, then I’m able to NACK after evaluating incoming data, but in this case if CRC doesn’t match, how can I tell the master that the received frame was wrong?
Regards
Stephane
Indeed, you can only NACK a byte you haven't read from RXBUF. If you read it, you'll ACK the byte automatically.stephane freund said:It looks that I can only NACK the next byte.
Either you define that there is only one frame per transmission and a (repeated) start is required for the next frame, or teh protocol needs to define that a NCK will not only end the transfer but alos mark the previous frame (or all frames of this transfer) invalid.
The reason is the double buffering mechanism. After a byte has been received, the hardware ACKs it and continues receiving the next byte. If you didn't read the previous byte (or set NACK) when teh 7th bit of the next byte is received, it will stretch the clock until you do one of the two.
If you're fast enough and your interrupt latency is short neough, you may reset the USCI manually after receiving the last byte and detectign that it is a NACK. In this case, the SDA pin should go high again before the rising edge of the masters clock impulse, resulting in a NACK detected by the master. But only if you're fast enough. It would be a dirty hack.
If you do, however, busy waiting for the incoming data, and there are no ISRs which might cause any latency, it is a reliable option.
Hi Jens-Michael,
Thank you for your quick answer and sorry for my too late thanks.
I'm a bit surprise about TI's I2C handling, but no other way.
I don't understand your last sentence, "busy waiting" ?
I'm using the trick to disable the USCI to NACK on a not allowed reading frame (example Frame C), it works.
For Frame b), I don't know if it will works, but on the last received byte when the ISR occurs,
- set SCL as Output=0, (continu holding SCL low)
- set SDA as output=1,
- disable USCI,
- read UCBxRXBUF (hope that it's still valid)
- check incoming data (have time to check)
- NACK:
enable USCI
- ACK:
set SDA as output=0
set SCL as input (bus pull-up)
wait until master has take ACK in care, how long ??
enable USCI
Stephane
"busy waiting" means constantly checking the status ina while loop that ends when the desired condition is met.stephane freund said:I don't understand your last sentence, "busy waiting"
About your workaround, yes, that's a possible way, if you know that it is the last byte of the transmission and just want to check for ACK or NACK.
Should be stated in the masters datasheet. Minimum slave data hold time after rising clock edge.stephane freund said:wait until master has take ACK in care, how long ??
Normal I2C communication would not require this tweak. Here the slave know before the last byte whether it is the last byte or not. The last byte is NACKed, all others are ACKed. If the master wants to get a confirmation of teh last operation result, it has to do a restart and read the status.
Your setup is a bit mroe efficient, but collides with the double-buffering mechanism which is implemented for higher throughput. and relaxed read/write timing. (I2C on the USI, where this is no problem, is terribly timing-critical, and the I2C on the old 1X USART module is overly complex and doesn't even allow this kind of tweak.
**Attention** This is a public forum