Post Go back to editing

I2C Repeated start with DMA best practices

Thread Summary

The user asked about best practices for using repeated start conditions and DMA in an I2C driver for the ADuCM363, specifically when writing register addresses followed by data bytes. The final answer clarifies that a RESTART is not needed when writing to a register, as the data can follow the address information directly. The RESTART is only required when changing direction from a write to a read.
AI Generated Content
Category: Hardware
Product Number: ADuCM363

This is another case where EngineerZone is incorrectly routing my ADuCM363 question from the Ultra Low Power forum to the 8052 forum. I tried to put it in the right place.

I'm writing an I2C driver and am curious as to the best practices when using a repeated start condition and DMA. I'm thinking specifically of the situation where I need to write one or more register address bytes, send a RESTART and then write one or more (perhaps many) data bytes. This when I2C is acting as a master.

I can get a TX DMA queued up and ready to go with the register address bytes. Then write the device address to I2CADR0 to initiate the I2C transfer.

This brings up my first question. In order to have the RESTART sent, I need to queue up the restart address right away. Before the initial transmit completes. The manual says, "write to the I2CADR0 register either after the state machine starts to transmit the device address or after the first TXREQ interrupt is received." This is from page 104.

I can check the I2CMSTA.BUSY bit to determine when the state machine has started, but it doesn't generate an interrupt. That means I need to spin, which isn't the worst thing in the world, but grates on me a bit. The other option is to check for I2CMSTA.TXREQ. That flag does generate and interrupt, which means no spinning, but if I'm using DMA to transfer the register address bytes, I don't want to have to catch an interrupt for every byte. The DMA is getting signaled via I2CMCON.TXDMA and doesn't need the interrupt and I only need the very first interrupt to determine when to write to I2CADR0 again. What do people do? Do they spin, waiting for the BUSY status or do they catch the first TXREQ interrupt and then disable the following TXREQ interrupts in the interrupt handler? Or, can I just write to I2CADR0 twice, back-to-back, without having to poll the BUSY bit?

Okay, moving on. If I am going to do a RESTART read, I can queue up both the TX DMA and the RX DMA before I begin. The TX would start as soon as the first address byte (with LSB 0) is sent and presumably, the RX would start as soon as the restart address is sent (with LSB 1). How do people handle the case where the restart is a write, not a read? In that case, you can't queue up the second TX DMA before you start, since it is being used for the initial write of the register bytes. That means it needs to be set up after the first DMA completes and, importantly, after the TX FIFO empties. It is the emptying of the TX FIFO that triggers sending the RESTART. If the second TX DMA starts too soon, it will keep the TX FIFOs from emptying and the data will get sent before the RESTART. As near as I can tell, there is nothing to indicate when the RESTART is sent (either at the beginning of sending it or after it has been sent). What do people do? What is the best time to enable the second DMA TX?

mike

  • I think we can disregard my question. It was based on the faulty premise that a RESTART is required when writing to a register. That is not the case, and something that I should have remembered given how many times I've written I2C drivers. When writing to a register the data can immediately follow the address information. The RESTART is not needed. The RESTART is only required when changing direction from a write (of the register address) to a read (of the register data).