finds.dev← search

// the find

MaJerle/stm32-usart-uart-dma-rx-tx

★ 1,828 · C · MIT · updated Sep 2026

STM32 examples for USART using DMA for efficient RX and TX transmission

A set of STM32 LL-driver examples and a companion application note on receiving data of unknown length over UART with DMA in circular mode, using the IDLE line or receiver-timeout event together with half-transfer and transfer-complete interrupts. It also covers transmitting through a ring buffer with DMA in normal mode. It is aimed at embedded developers moving from polling or per-byte interrupts to DMA on Nucleo and BluePill boards.

- The README walks through the HT, TC and IDLE event combinations as concrete cases (A through E) with buffer positions spelled out. Vendor examples usually skip this part. The `usart_rx_check` function handles the wrap-around by splitting the read into two linear blocks, which is the piece people most often get wrong.

- It states the constraint that makes this hard: the DMA and UART interrupts must share a preemption priority, or the last-read position gets corrupted. Most tutorials that do this never mention it.

- Coverage spans F1, F4, G0, G4, L4, H7, U5 and C5 with a per-board table of pins, DMA controllers, channels and streams. The build is CMake presets with Ninja and arm-none-eabi-gcc, and each example ships its own `.vscode` folder. That is more usable than a single-board HAL snippet.

- `usart_rx_check` keeps `old_pos` in a function-static variable, so it is neither reentrant nor safe to call from two contexts. The README says so, but nothing in the code enforces the rule, and the priority setup has to be right by hand.

- The TX half is described in a few paragraphs with no code in the README, and it defers to the demo project. The race between an application write and the TC-triggered restart is the part that matters, and the README does not address it directly.

- Every example targets one board and uses a 20-byte buffer for demonstration. The DMA mapping differs across families (channels, streams, requests, GPDMA, LPDMA), so porting to another part means re-deriving the mapping. The README's own table shows how much it varies.

- The visible tree shows only a release workflow and no test or simulation target. The overflow and race cases the README describes are not exercised by anything I can see, so they are verified by hand on hardware, if at all.

View on GitHub →

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →