Teensy 4 - Master i2c, DMA possible?

Status
Not open for further replies.

AndyCap

Well-known member
Hi Guys,

I have searched around a bit on google and the forum and can't seem to find an answer to this.

Is it possible to use DMA for sends and receives over i2c on the teensy 4, I have found an enhanced i2c for T3 which I am guessing will just not work and teensy4_i2c from Richard Gemmell which doesn't support DMA.

Has anyone got any pointers?

Many thanks

Andy
 
The simple answer is that I believe the hardware does support DMA operations.

BUT:

I am not sure if there are any libraries that currently do this.

It looks like the owner of the library i2c_t3 has not done any updates in about a year and a half, so not sure how likely it will be for him to do so any time soon.

At one point I started to look at how much work it would be to add T4.x support to the i2c_t3 library. And I started to do so, but then did not take it very far. I was conflicted on how to proceed. I personally did like that idea that if you used the library, you then had to edit every library and your sketch to make sure that the Wire library was not also included. Plus that the interface was not compatible.... But then again it was not my library...

So was not sure of best approach to take here. Should we simply make the minimal changes needed to get the i2c_t3 library to work? Add some of the support to the Wire library? Create a new library? ... So far I have taken the 4th option: Punt ;)
 
Thanks for the reply Kurt.

I'm going to have a look at teensy4_i2c async calls in a while, maybe that will give me what I need.

I did take a quick look at the NXP side and there is a LPI2C_MasterTransferNonBlocking() which will call a callback at end of RX/TX. The callback is set with LPI2C_MasterTransferCreateHandle().

I will let you know how it goes with teensy4_i2c...
 
Is it possible to use DMA for sends and receives over i2c on the teensy 4

The hardware support is there, but so far no software.

I'm curious why so much focus on using DMA?


So far I have taken the 4th option: Punt ;)

That's what I've done too. And realistically, I'm going to keep doing this a while longer, since right now I'm working on making bootloader chips available, and then my main plans for Teensyduino 1.54 involve supporting more file storage media, file and filesytem abstractions, and MTP. I consider both of those a much higher priority than advanced I2C APIs.

But long term, we do need better I2C support. Slave mode is the most important missing piece. But good non-blocking master mode also matters. I've spent some time thinking about how I want to do this, but so far no coding. The main thing I want to see is an alternative non-blocking API that uses a queue of transfers to be performed. I really want to get away from the existing API where many function calls are used to set up a transfer, because that's a nightmare to make thread safe. I want to see a single function call that queues a transfer to be performed, with optional callback upon completion. Each transfer should be a single atomic bus use, beginning with start condition and ending with stop condition. The difficult part is handling repeated starts and whether to support data-dependent action (like deciding to read more data based on the first byte received). But those are fringe cases. The 3 most common transfers are write, read, and write-then-read.

Even with a good non-blocking queued transfer API on the Wire library, I'm still not convinced DMA makes sense. Maybe it does for very large transfers? But for small transfers it seems like a lot of extra overhead just to avoid a few interrupts, which aren't even that sensitive to latency since we have a small FIFO in the I2C hardware on Teensy 4.x.

Maybe DMA will turn out to be easier than I've imagined? But so far every lesson I've learned about I2C is it's relatively easy to make a library that works for the normal case where things go as they should, but even for the simple case of blocking APIs handling all the corner cases for a highly robust library when people deploy it with noisy environments and unusual I2C chips is extremely difficult. Adding the complexity & overhead of DMA feeling like it may turn out to be a long & painful journey of those ugly corner cases.
 
I'm really not interested in it being DMA based, just asynchronous with a callback so the processing is not blocked.

I worded the question incorrectly I guess.

Edit: I looked for a way to change the thread title but don't seem to be able to, maybe you can change it Paul?
 
I'm also interested in I2C DMA for T4. I've got an I2C OLED that I'm using as a simple display for an audio effect. Driving an I2C display requires pushing a moderate amount of data, but as a result I'm getting audio hiccups when doing display updates, presumably because the blocking I2C calls are not leaving enough time for the audio stream to keep up, even when the audio processing is effectively passthrough.

Without DMA, I may try another approach like putting the I2C transfers on a separate thread with the TeensyThreads library and limit it's time slicing.
 
Status
Not open for further replies.
Back
Top