Repository navigation
Fix TX underruns and implement the shared dmdrvi audio stream contract - #7
Merged
Merged
Conversation
stm32_sai_dma_write/read/flush polled with Dmod_ThreadSleep(1). With dmod-boot's 100 Hz FreeRTOS tick that sleep lasts ~10 ms, longer than the whole TX path (256-frame queue + 2x64-frame DMA halves = 8 ms at 48 kHz), so every full queue ended in ~4 ms of silence: choppy playback and thousands of tx_underruns. Post a binary semaphore from the DMA half/complete/error callback and from stop, and wait on it (bounded at 10 ms) instead. Reproduced in Renode with an 8 s melody: before 4887 underruns and 14 s of output, after only the 4 drain-tail halves and 7.94 s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Nr1HhezRY951yBxxTm1b65
This was referenced Oct 11, 2026
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.
1. Wake SAI writers from the DMA interrupt instead of sleeping a tick (372b0fd)
Problem
stm32_sai_dma_write/read/flushwaited for queue space withDmod_ThreadSleep(1). dmod-boot runs FreeRTOS at a 100 Hz tick, so that sleep lasts about 10 ms. That is longer than the whole TX path at 48 kHz: a 256-frame queue plus two 64-frame DMA halves is about 8 ms. Every full queue therefore ended in about 4 ms of silence: choppy, crackling playback and thousands oftx_underruns.Fix
stm32_sai_dma_stoppost a binarydmosisemaphore.wait_queuewaits on that semaphore for at most 10 ms, instead of sleeping.stoptakes any pending wake before posting.Verification (Renode, 8 s melody through
/dev/wm8994)2. Shared dmdrvi audio stream contract instead of DMSAI_IOCTL_* (9c7f004, e90310f)
The node implements the
DMDRVI_IOCTL_AUDIO_*stream commands from choco-technologies/dmdrvi#28. A codec node implements the same contract, so an application plays the same way on the codec and on the bare SAI.AUDIO_GET_STREAMreturnsdmdrvi_audio_stream_t: the buffer layout (rate, format, channels = active slots) and the link (framing, clock role, slots).AUDIO_CONFIGUREreturns 0 only when rate, channels and width match the ini format; otherwise-ENOTSUP.AUDIO_STARTsucceeds when the stream is already running (it used to return-EBUSY).AUDIO_STOP,AUDIO_GET_STATUS,AUDIO_SET/GET_TIMEOUTandAUDIO_DRAINbehave as before.AUDIO_GET_INFO,SET_VOLUMEandSET_MUTEreturn-ENOTSUP, since the SAI has no analog stage. This also keeps dmdevfs from reporting the SAI as anaudiodevice.dmsai_ioctl.handDMSAI_IOCTL_*are removed. The port API keepsdmsai_config_t/dmsai_status_t, and static asserts check that format and clock role values match dmdrvi.docs/api-reference.mdand the driver board test are updated. The board test now also checks CONFIGURE matching and mismatching, the -ENOTSUP volume control, and the idempotent START.Requires dmdrvi 2.7. CI cannot fetch it until choco-technologies/dmdrvi#28 is merged and released. Merge this together with choco-technologies/dmwm8994#3.
Verified locally: built for cortex-m7 against the new header and ran in Renode with a generic player that uses only the shared commands.
/dev/wm8994: all 32 notes are correct./dev/dmsai1directly: the stream runs without underruns (drain tail only). It is silent there because nothing configures the codec on that path.🤖 Generated with Claude Code
https://claude.ai/code/session_01Nr1HhezRY951yBxxTm1b65