UART communication between two microcontrollers using DMA.

Post here first, or if you can't find a relevant section!
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

Hello, :D

I am using Stm32f103c8t6 with Offical core with HID bootloader. I am working on Visual Studio Code IDE using Microsoft Arduino Extension.

Is it possible to make use of UART communication in DMA without disturbing the Loop function which will be running in CPU or Flash Memory?

If so, How can I achieve it? Any examples would be really helpful. Are there any limitations in using DMA for UART communication? A detailed explanation would also appreaciateble.

I hope to get your suggestions, opinions, guidance, directions, and references to achieve my task.

Thanks all in advance.
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

Re: UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

Thanks for your reply. Is there any example done in stm32f103c8t6 with an official stm32 core in Arduino or something similar?
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

Re: UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

Okay, let me be more clear here. I have implemented a library for a custom made PCB board with stm32f103c8t6 with lots of functionalities (All the functionality were explained as follow (The board has 6 General Purpose Output (using built internal GPIO pins) with all necessary electronics to drive up to 24 volts. It also has 4 analogue industrial inputs (using external ADC pins via I2C1 communication (ADS1115 IC https://www.ti.com/lit/ds/symlink/ads1113.pdf)) with all necessary electronics to read the voltage up to 10 volts. Then, the board has 6 PWM using BTN8962TA https://www.infineon.com/dgdl/Infineon- ... 2d247a7bf5 to drive the motors using PWM frequency and Dutycycle using the outputs from PWM. To be noted for all the 6 PWMs, from the schematics of the board there are two external ADC pins(one for I sense, and V sense(using ADS1115 IC via I2C1)), one external GPIO pin(for Inhibit pin of PWM(using MCP23017 IC http://ww1.microchip.com/downloads/en/D ... 01952C.pdf via I2C1)), and an internal timer pin connected to PWM directly from the microcontroller. Then there are 5 thermocouple pins using MCP9600 IC http://ww1.microchip.com/downloads/en/D ... 02417A.pdf via I2C1. Then, the board has 3.3 to 5V I2C2 pins to use Sensirion SCD30 Sensor Module and Senseair K30 Sensor Module and Senseair K33 Sensor Module. Also, it has compatibility to support NeoPixel LED. Also, SPI2 is also available for using an SD card and touch screen to work it as HMI. Above all that it also has its I2C2, USART1, USART2, LIN.)). Now, The entire program functionality is able to fit in the MCU with all the functionalities having still 7-kilo bytes of free space :D.

The duration of the entire loop to run takes almost approximately 1200 milliseconds.

So, to reduce the time of the loop, I thought of using DMA for UART communication. [ From my understanding, using DMA will free up the main CPU. So, I think using DMA is like multitasking. (That is in the main CPU it will do the work that it needs to do without getting disturbed by UART communication because UART communication will be done in DMA with Channel 4 and Channel 5 for USART1, and Channel 6 and Channel 7 for USART2.) So, I think that UART communication in DMA and other functionalities can take place in the main CPU simultaneously. ] :?: :!: By this, I believe and hope that some amount of time will be reduced in my entire loop. :idea:

But, I also did some research on my own to get some relevant or working examples for my purpose in Arduino with stm32official core. But I could not able to find it.

So, let me know If I was wrong in understanding the DMA. I hope, I understood about DMA correctly. If so, please guide me on how can I achieve this.
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: UART communication between two microcontrollers using DMA.

Post by fpiSTM »

The HardwareSerial implementation does not manage the DMA. You will have to develop your own one if you want to use it.
You can convert a STM32Cube Example to try:
https://github.com/STMicroelectronics/S ... rds_ComDMA

I've made an example for ADC in the code snippet.
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

Re: UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

Thank you so much. Just for my clear understanding and clarification, I am asking this again! So, STM32 is capable of Multitasking with the help of DMA?
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: UART communication between two microcontrollers using DMA.

Post by ag123 »

normally u'd need to design a *protocol* that sends data wait for ack, if it timeout send it again.
that's how dma is avoided.
this concept is used *everywhere* including in 3d printers today !
if you are paranoid you can add crc checks
this is as old as comms/networking itself
https://en.wikipedia.org/wiki/High-Leve ... nk_Control
https://github.com/jarkko-hautakorpi/Arduhdlc
hdlc is *rigorous*, it has been used in cisco routers since the beginning of internet.

i think there are some more exoteric stm32 socs with a FIFO in the uart, it'd take some searching for those.
normally with a fifo, the chance of missing a chunk of data is less likely for busy mcu, but still the protocol is needed for fault-tolerant comms

the keyword in uart is *asynchronous*

oh an alternative - use USB
the techno wizards at Intel, Microsoft designed it into usb since Microsoft start shipping windows 95.
today USB is that *comm port*, it totally replaced rs232 - pretty much , and in fact much more.
today's microcontrollers like stm32 with usb puts back the *comm port* into the hands of fhe average tinkerer
usb is the new comm port
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

Re: UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

ag123 wrote: Tue Nov 30, 2021 3:16 pm that's how dma is avoided.
What do you mean by DMA is avoided?
ag123 wrote: Tue Nov 30, 2021 3:16 pm normally u'd need to design a *protocol* that sends data wait for ack, if it timeout send it again.
I agree, I have made a similar protocol as you described along with CRC (simple checksum stuff.) in UART asynchronous mode via RS485. But the entire duration of the loop takes around 1200 milliseconds. (including all the functionalities and UART communication done in the loop on the main CPU)
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: UART communication between two microcontrollers using DMA.

Post by ag123 »

oh normally, uart with stm32duino(s) don't lose data, as i'd think when data is received, an interrupt fires and stm32duino puts that data in the queue (ring buffer), so that the next time Serial.read() runs, it pulls that from the queue.
the exception is if the mcu is *too busy*
a mcu with a uart fifo, would basically reduce missing bytes to a miminal.
still if you need fault tolerant comms, a *protocol* is needed

that latency thing is *complicated* stuff, i'd think it'd be necessary to measure timings for where things run in each timeslice.
that's called *profiling*, and the subsequent tuning is called *optimization*, it can be done, but it'd take effort.

oh there are *hacks* sort of, accordingly it is possible to change the priority of the interripts (i'm not too sure how).
there are some tinkerers who did just that, and accordingly it works!
the catch is, usually if uart has the priority, something else needs to give way to it.
for a 3d printer, it may perhaps cause skipped stepper steps, pauses etc.
mustaq_ahm
Posts: 31
Joined: Tue Sep 14, 2021 11:08 am
Answers: 2

Re: UART communication between two microcontrollers using DMA.

Post by mustaq_ahm »

ag123 wrote: Tue Nov 30, 2021 3:43 pm oh normally, uart with stm32duino(s) don't lose data, as i'd think when data is received, an interrupt fires and stm32duino puts that data in the queue (ring buffer), so that the next time Serial.read() runs, it pulls that from the queue.
the exception is if the mcu is *too busy*
a mcu with a uart fifo, would basically reduce missing bytes to a miminal.
still if you need fault tolerant comms, a *protocol* is needed

that latency thing is *complicated* stuff, i'd think it'd be necessary to measure timings for where things run in each timeslice.
that's called *profiling*, and the subsequent tuning is called *optimization*, it can be done, but it'd take effort.

oh there are *hacks* sort of, accordingly it is possible to change the priority of the interripts (i'm not too sure how).
there are some tinkerers who did just that, and accordingly it works!
the catch is, usually if uart has the priority, something else needs to give way to it.
for a 3d printer, it may perhaps cause skipped stepper steps, pauses etc.
Sorry for the confusion. I think I might misunderstand something. And I might be not explaining correctly, what I would like to achieve. :?

Or, I might not understand what you are trying to explain me(if so please let me know) :(

I do not have the problem of losing data. I could able to get all the desired data as I want with the protocol. As you mentioned with the First_In_First_Out(FIFO) UART communication, I do not miss any data. I am able to succeed in UART communication. There is no problem for me in communication. ;)

Okay. In my loop, the STM32f103c8t6 does all the functions that I need it to do. (including UART communications) without any problem.

Inside the loop, I am also checking for any data available for reading? If yes, then it runs in a while loop until data available == 0, I read everything using Serial.read().

Let's assume the receiving data in UART has a maximum of 64 bytes. again let's assume that it might take up to 64milli seconds inside a while loop to read all the data available in UART. (Just for example).

So, what I thought and believe: With the help of DMA and its channels STM32F103C8T6 is capable of multitasking. :!:

So, My idea is to run the loop in the main CPU with all other functionalities which does not support DMA. And with help of DMA, I would like to access all the other peripherals like USART1, USART2, ADC, and Timers using DMA and its corresponding channels. :idea:

So, with my Idea, I believe: I might reduce the time of the entire loop from 1200 milliseconds to (I don't know but maybe less than 1000 milliseconds). Because I might be doing several tasks at the same time with the help of DMA and its channels and also the main CPU will be running all the other functionalities which don't support DMA. :idea: :!: :?:

Also please let me know if I am not clear in explaining what I need. :|

:arrow: My problem is with the total Time of the void loop() to complete one cycle.

Let me know, and guide me in the correct way if my entire understanding of DMA is wrong. :? :( :o
Post Reply

Return to “General discussion”