Skip to content

drivers/periph/dac: add dac_play API for async multi sample output#22261

Open
benpicco wants to merge 7 commits into
RIOT-OS:masterfrom
benpicco:periph/dac_dma
Open

drivers/periph/dac: add dac_play API for async multi sample output#22261
benpicco wants to merge 7 commits into
RIOT-OS:masterfrom
benpicco:periph/dac_dma

Conversation

@benpicco
Copy link
Copy Markdown
Contributor

@benpicco benpicco commented May 8, 2026

Contribution description

The periph_dac API only plays single samples. The dac_dds drives does exist, but it's interrupt based so it's prone to distortions when interrupts are disabled even for a brief time.

The proper solution is to use DMA to feed the DAC and since the DAC API is CPU specific, the only way to do this is by extending the DAC API with a new dac_play() function that allows to supply a buffer of samples that will then be played asynchronously.

Support for this is indicated by the periph_dac_play feature.

We can supply a completion callback to supply the next buffer or set it to loop mode where the same sample is played over and over again independent of the CPU (e.g. if we want to produce a constant sine wave).

⚠️ This contains a change to the way dac_set() behaves on sam0 ⚠️

Previously the 12 bit DAC was not left-adjusted, that means dac_set(0xfff) would produce the highest amplitude while dac_set(0x1000) would be clipped to 0.

However our API doc says

The value is always given as 16-bit value and is internally scaled to the
actual resolution that the DAC unit provides (e.g. 12-bit).

Fix this by setting the LEFTADJ bit.
This however means that existing users will experience a lower amplitude when they supply 12 bit values.

Testing procedure

Try out the different waveforms in tests/periph/dac_play:

sine 330 10
image
triang 330 10
image
square 330 10
image
saw 330 10
image

(The overshooting for square and sawtooth waves are actually an artifact of the oscilloscope, the signal looks clean on the (more expensive) Tektronix scope)

Issues/PRs references

Declaration of AI-Tools / LLMs usage:

AI-Tools / LLMs that were used are:

  • none

benpicco added 6 commits May 8, 2026 18:15
The `dac_set()` API says

> The value is always given as 16-bit value and is internally scaled to the
> actual resolution that the DAC unit provides (e.g. 12-bit).

We didn't do that scaling before - enable it even though it breaks existing
users.
@github-actions github-actions Bot added Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: tests Area: tests and testing framework Area: build system Area: Build system Area: drivers Area: Device drivers Area: boards Area: Board ports Area: cpu Area: CPU/MCU ports labels May 8, 2026
@benpicco benpicco marked this pull request as ready for review May 8, 2026 17:23
@benpicco benpicco requested a review from maribu May 8, 2026 17:23
@crasbe crasbe added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label May 8, 2026
@riot-ci
Copy link
Copy Markdown

riot-ci commented May 8, 2026

Murdock results

FAILED

313c924 tests/periph: add test app for periph_dac_play

Success Failures Total Runtime
91 0 10095 01m:46s

Artifacts

#include "shell.h"

#ifndef CONFIG_DAC_LINE
#define CONFIG_DAC_LINE 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define CONFIG_DAC_LINE 0
# define CONFIG_DAC_LINE 0

#endif

#ifndef CONIFG_DAC_BUF_SAMPLES
#define CONIFG_DAC_BUF_SAMPLES 2048
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define CONIFG_DAC_BUF_SAMPLES 2048
# define CONIFG_DAC_BUF_SAMPLES 2048

Comment on lines +1189 to +1190
* @param cb
* @param ctx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have documentation for that too.

* @brief Release a previously acquired DMA channel
*
* @param dma DMA channel to release
* @param ctx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: boards Area: Board ports Area: build system Area: Build system Area: cpu Area: CPU/MCU ports Area: drivers Area: Device drivers Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants