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.
I am using a modified design on a MSP430F2619 based off the example code available here.
In the example code, the DMA will enable UCB0RXIE and UCB0TXIE depending on what operation has just completed. The TX operation makes sense to me. The DMA can't know when to send a STOP signal, so the I2C TX interrupt is enabled to send the STOP. However, the example code reads the last two bytes manually out of the UCB0RXBUF register before sending the STOP signal for an RX operation.
I am curious as to why this needs to happen. If the DMA is setup to read multiple bytes, shouldn't it take care of it automatically? It does that for transmitting multiple bytes . . . .
Out of curiosity, I removed the code that reads the last two bytes in the USCIAB0TX_VECTOR interrupt handler and only sent the stop signal on a receive operation. The code stops working. I noticed that it starts to work if I place breakpoints between write and read operations. If I manually read UCB0RXBUF for the last byte I expected to receive, everything works fine. Why? Why can't the DMA controller take care of the last byte on its own like it does for TX operations?
In master RX mode, if a byte was received, receiving the next one immediately starts. So if DMA is receiving the bytes you need, another one is already on its way before you can set the stop. You may of course simply discard this excess byte, but on most I2C slaves, reading a byte has side-effects. E.g. an internal address counter is incremented and the next read my start with a wrong address. So the DMA only reads two bytes less, so in the ISR, when reading the penultimate byte, you know that receiving the last has already begun but not completed (as you didn’t read RXBUF yet), and you can set the stop flag before the last is completed an one more is read in excess.
Thank you for your reply. What you say makes sense. Initially I was assuming that the MSP430 would stop clocking in data on the I2C bus once the DMA0SZ register decrements to 0, but all this does is halt the transfer of data from RXBUF to RAM, not I2C communications.
I saw you comment in another thread stating that DMA on the MSP430 isn't really useful for I2C due to the overhead involved in I2C transactions. I'm starting to see that now.
**Attention** This is a public forum