Skip to content

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

Open
benpicco wants to merge 6 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 6 commits into
RIOT-OS:masterfrom
benpicco:periph/dac_dma

Conversation

@benpicco

@benpicco benpicco commented May 8, 2026

Copy link
Copy Markdown
Contributor

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

@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

riot-ci commented May 8, 2026

Copy link
Copy Markdown

Murdock results

✔️ PASSED

32af49c tests/periph: add test app for periph_dac_play

Success Failures Total Runtime
11281 0 11284 14m:35s

Artifacts

Comment thread tests/periph/dac_play/main.c Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
@crasbe crasbe added Type: new feature The issue requests / The PR implemements a new feature for RIOT AI: Not Used AI was stated to not be used in this PR/Issue labels Jul 20, 2026
Comment thread boards/same54-xpro/include/periph_conf.h Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
Comment thread cpu/sam0_common/include/periph_cpu_common.h Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread tests/periph/dac_play/main.c Outdated
Comment thread cpu/sam0_common/periph/dma.c Outdated
Comment thread drivers/include/periph/dac.h
Comment thread cpu/sam0_common/periph/dma.c
Comment thread boards/same54-xpro/include/periph_conf.h Outdated
Comment thread cpu/sam0_common/periph/dma.c
@github-actions github-actions Bot removed the Area: boards Area: Board ports label Aug 21, 2026
Comment thread drivers/include/periph/dac.h
@fabian18

fabian18 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

To me it looks good and I am using it successfully. There are just a few more minor comments from @crasbe in #22624

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.
@benpicco

benpicco commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

I think they are already fixed in this branch 🤔

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

Labels

AI: Not Used AI was stated to not be used in this PR/Issue 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 Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants