Skip to content

Fix TX underruns and implement the shared dmdrvi audio stream contract - #7

Merged
JohnAmadis merged 1 commit into
mainfrom
ccr-0ed2b297-4zti6v
Oct 11, 2026
Merged

JohnAmadis merged 1 commit into
mainfrom
ccr-0ed2b297-4zti6v

Conversation

@JohnAmadis

@JohnAmadis JohnAmadis commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

1. Wake SAI writers from the DMA interrupt instead of sleeping a tick (372b0fd)

Problem

stm32_sai_dma_write/read/flush waited for queue space with Dmod_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 of tx_underruns.

Fix

  • The DMA callback (half, complete, error) and stm32_sai_dma_stop post a binary dmosi semaphore.
  • wait_queue waits on that semaphore for at most 10 ms, instead of sleeping.
  • stop takes any pending wake before posting.

Verification (Renode, 8 s melody through /dev/wm8994)

tx_underruns output length
before 4887 14.2 s
after 4 (drain tail) 7.94 s

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_STREAM returns dmdrvi_audio_stream_t: the buffer layout (rate, format, channels = active slots) and the link (framing, clock role, slots).
  • AUDIO_CONFIGURE returns 0 only when rate, channels and width match the ini format; otherwise -ENOTSUP.
  • AUDIO_START succeeds when the stream is already running (it used to return -EBUSY).
  • AUDIO_STOP, AUDIO_GET_STATUS, AUDIO_SET/GET_TIMEOUT and AUDIO_DRAIN behave as before.
  • AUDIO_GET_INFO, SET_VOLUME and SET_MUTE return -ENOTSUP, since the SAI has no analog stage. This also keeps dmdevfs from reporting the SAI as an audio device.
  • dmsai_ioctl.h and DMSAI_IOCTL_* are removed. The port API keeps dmsai_config_t / dmsai_status_t, and static asserts check that format and clock role values match dmdrvi.
  • README, docs/api-reference.md and 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.

  • Through /dev/wm8994: all 32 notes are correct.
  • On /dev/dmsai1 directly: 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

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
@JohnAmadis
JohnAmadis merged commit 852f91a into main Oct 11, 2026
3 checks passed
@JohnAmadis JohnAmadis changed the title Wake SAI writers from the DMA interrupt instead of sleeping a tick Fix TX underruns and switch to the standard dmdrvi PCM commands Oct 11, 2026
@JohnAmadis JohnAmadis changed the title Fix TX underruns and switch to the standard dmdrvi PCM commands Fix TX underruns and implement the shared dmdrvi audio stream contract Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants