cancel
Showing results for 
Search instead for 
Did you mean: 

I2C DMA with FIFO

zexx86
Associate II

Hello,

I am reading data from a motion sensor but I would like to save processor resources as much as possible. I want to implement I2C with DMA support.

Presently I have external interrupt (EXTI) from sensor which signalize that data in FIFO are ready.

In this interrupt I am reading approximately 32 bytes by I2C each time. This is happening at 1000 Hz rate.

Will DMA save some CPU time in this case?

Is there some way DMA could read FIFO without blocking the processor? Somehow automatically?

Or should I replace just few I2C commands from std peripheral library with DMA commands?

My point is to not use a blocking commands or timeouts, especially inside interrupts. I saw some examples from ST but for me it seems there is not a big benefit in I2C DMA.

My imagination would be to map RAM memory to the FIFO from I2C device and just read it directly. While STM32 MCU will handle all the transfers at the background.

Is it even possible?

6 REPLIES 6
KnarfB
Principal III

32 Bytes -> ~300 bits on the wire * 1000 = about 300kbit/s. This will consume 75% of the I2C bus bandwith (@400 kHz) and therefore, if you are using blocking (non DMA) functions, at least 75% CPU only for I2C interrupt handling, bad.

So you probably need DMA. You can trigger a DMA request from I2C peripheral to a memory buffer in the interrupt handler.

When the DMA transfer has finished, a DMA full interrupt can fire indicating that the memory buffer is valid.

I would suggest double buffering, i.e. the next DMA fills the other buffer so DMA transfer and buffer evaluation can overlap.

This can be achieved using some global variables acting as semaphores or, when using FreeRTOS or such, by a queue.

Edit: There is also an advanced solution triggering DMA by an event, not using the CPU at all. There were discussions about that in the forum.

hth

KnarfB

zexx86
Associate II

Thank you very much!

Sadly I am unable to find any example.

In (STM32F4) STD peripherals examples I can find only hints of this. But either without interrupts or without FIFO.

Indeed I can see it is consuming CPU time a lot without DMA at the moment.

zexx86
Associate II

Thank you very, very much! This helped me a lot! Although code is outdated and not compatible with the latest ST Peripheral Library I was able to port it.

Everything is running flawlessly. All perfect and problem is solved!

franz2
Associate III

I have same problem. I want read from I2C (Temperature sensor LM75DP) without any additional CPU load, without any IRQ. I want cyclic read temperature, and before I execute the new reading order I want read the data from previous action. I have no access to the link above. Can you check it or zexx86 can you present your result. Thank you for help. Franz

ADJAD.1
Associate

I have the same issue with my project : I have to read data from 12 differents sensors on my I²C bus (power meter, temp sensor, ...) and this consume a lot of MCU ressources.

I want to move to DMA . But I found no exemple yet, explaining why to specify pereperal adress on I²C bus; more exactely and think I must specify both I²C device adress and the I²C device memory adress corresponding to data to read.