Repository navigation
Receive by DMA on STM32F7 - #8
Merged
Merged
Conversation
The USART has no RX FIFO: at 921600 baud a byte comes every ~11 us, and an RX interrupt that runs late (at dmosi's minimum priority) loses bytes to overrun. A UART with an RX ring now receives by DMA instead - a circular 1 KiB buffer (from the "dma" heap - uncached DTCM - when there is one, else with the D-cache invalidated) that the USART's idle line and the DMA's half / end events drain into the ring. No free stream (dmdma leases): by interrupt, as before. The ring then holds what comes while the reader is not scheduled: the F7 boards' consoles get 4096 bytes (~44 ms at 921600) instead of 256 (2.8 ms), which a reader behind a busy display thread overran. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The STM32F7 USART has no RX FIFO, so at 921600 baud a byte arrives every ~11 µs. The RX interrupt runs at dmosi's minimum priority, because it signals the ring's semaphore. When it ran late the byte was lost to an overrun: on the STM32F746G-DISCO console about 2 in 60 bytes sent back to back were lost.
Change
RX by DMA (
src/port/stm32f7/port.c). A UART with an RX ring now receives into a circular 1 KiB DMA buffer:dmaheap (dmod-boot's DTCM, uncached) when there is one. Otherwise it isDmod_AlignedMallocwith the D-cache invalidated before reading.dmdma_lease_*), from the two the UART can use (tablerx_dma_map, RM0385). If neither is free, the UART receives by interrupt as before, with a warning._set_interrupt_triggerkeeps RXNE masked and IDLE on while DMA receives._set_rx_ring(NULL)and_deinitstop the stream and free the buffer.dmdma@>=0.4,dmheap.Ring size (
configs/board/*for F7). The ring now holds what arrives while the reader is not scheduled. 256 bytes are 2.8 ms at 921600, and a reader behind a busy display thread overran it: the oldest bytes were dropped. The F7 boards' consoles get 4096 (~44 ms). Seedocs/configuration.md, section "Receiving by DMA".Tested on STM32F746G-DISCO
ymodem), 1024-byte blocks, no pacing: 8 × 300 KB with no block sent again, ~31 KiB/s.Related
some_datareads waited for all the requested data. Readers of this ring need it to get bytes as they come.dmuart_port@>=1.1<2.0, so the port's release has to be at least 1.1.🤖 Generated with Claude Code