Help understanding UART DMA requirements?

When deciding which UARTs to use for which peripherals (eg RC link, telemetry modem, GPS, etc), how does DMA enter the equation? And which peripherals require or perform better with DMA?

Some of the boards I’m working with (MatekF405, Omnibus F4, Flywoo F745) only have DMA on a single UART, or only have DMA on TX. What are the implications of this?

Do I need to put the RC Link (usually SBUS) on a DMA UART? Will MavLink telemetry work better (eg faster parameter download) when connected to a DMA UART? Is DMA TX sufficient, or do I need a full TX/RX DMA UART?

And finally, can DMA assignments be modified in hwdef? What considerations have to be made if so? And how does it affect motor outputs (assuming I’m using DSHOT)?

Generally the gating factor here is RX baudrate - anything over about 200kbaud will be too noisy to be read accurately by polling. DMA offloads the reading directly to the MCU and allows the data to be read very, very evenly regardless of what other things the CPU is processing. So rule of thumb - anything that requires a baudrate > 200kbaud requires DMA. The exception to this is that on H7 there is a UART FIFO buffer that allows reads to be processed evenly enough without using DMA (although on H7 the DMA options are more flexible anyway so its not such a benefit). DMA also allows UARTs to be read reliably in the presence of high load - for instance on F4 CPUs which are already pretty loaded. So there are no hard and fast rules but:

  • CRSF definitely requires DMA - 416kbaud
  • GPS likely to require DMA - 234kbaud (especially when using high bandwidth things like RTK)
  • Companion computer - likely to require DMA
  • High rate sensor data of any kind

Everything else not so much, but anything that is flight critical is likely to benefit - so for instance you don’t have to use DMA for SBUS but you might benefit from it

Things that really don’t need DMA are slow things, so for example:

  • SmartAudio
  • RunCam

mavlink is unlikely to benefit. RX is the main one, TX can also benefit but we share DMA channels for TX so there can be contention between devices

You can change DMA assignments in hwdef but its a dark art - the script will simply not assign DMA channels if it cannot and you need to look in hwdef.h to see what got allocated and what not. You can change this behavior a bit through the use of DMA_PRIORITY and DMA_NOSHARE


Thank you! Is it possible to tell from the datasheet which UARTs can be assigned DMA? I checked the STM32F405 datasheet and don’t see any reference to DMA for the UARTs.

Where do I find hwdef.h? I’m familiar with hwdef.dat, but it’s not clear how DMA is assigned.

All UARTS can be assigned DMA, the constraint is that there are only so many DMA channels and not all of them can be shared. When you build - builds//hwdef.h is a generated file

Thanks Andy! I found some interesting discussion in the CRSF passthrough telemetry thread as well.

If I’m not using RTK, is there any benefit to running a GPS at 234kbaud vs 115k?

F405 boards are going to be severely limited on DMA, right? I think they only have one full DMA UART.
How about F745 and F765 boards?

Its not that F4 and F7 have fewer DMA channels, its that there is limited flexibility in what channels can be assigned to which functions. How this works out in practice is really down to the pin assignments that the vendor has decided on. H7 is much better because there are no restrictions on assignment.

1 Like

I’m still not understanding some key part of DMA assignments then, and haven’t been able to fill in the missing piece yet from the datasheets.

Is the limitation on which DMA channels can be assigned to which functions a timer limitation? That is, only certain timers are able to generate DMA requests, so you are limited by which timers and channels you can assign to a resource?

Not just timers, look at DMA_Map in libraries/AP_HAL_ChibiOS/hwdef/scripts/ to see the allowable channel assignments for F405 - this table is generated from the datasheet

1 Like