Skip to content

arch/stm32h7: Add DAC/DMA driver#19539

Open
seniorandre wants to merge 3 commits into
apache:masterfrom
seniorandre:stm32h7-dac-dma
Open

arch/stm32h7: Add DAC/DMA driver#19539
seniorandre wants to merge 3 commits into
apache:masterfrom
seniorandre:stm32h7-dac-dma

Conversation

@seniorandre

Copy link
Copy Markdown

Summary

Add a lower-half DAC driver for the STM32H7 on-chip 12-bit DAC peripheral with three operating modes:

  • Basic write mode — single values via read() / write() file operations
  • DMA circular mode — continuous waveform playback from a pre-loaded buffer
  • DMA stream mode — ioctl-driven double-buffering for live data streaming

DMA stream mode exposes ioctl commands:

  • ANIOC_DAC_DMABUFF_INIT — load buffer into DMA memory
  • ANIOC_DAC_DMA_START — start DMA with optional half-transfer interrupts
  • ANIOC_DAC_DMA_STOP — stop DMA and timer
  • ANIOC_DAC_DMA_GET_EVENT — wait for half/complete transfer (semaphore)
  • ANIOC_DAC_DMA_WRITE_HBUF — write half-buffer while DMA fills the other half
  • ANIOC_DAC_INFO — query resolution, DMA support, buffer size

Basic write mode uses software trigger (SWTRIG); DMA modes use a timer (TIM1–8,15) as the DAC trigger source.
Kconfig (Low/Medium/High/VeryHigh).
Busy/poll-free event path via semaphore synchronization.

Also included:

  • include/nuttx/analog/dac.h — extended dac_info_s with DMA fields
  • include/nuttx/analog/ioctl.h — DAC DMA ioctl command codes
  • arch/arm/src/common/stm32/Kconfig.dac — DAC DMA Kconfig, priority choice
  • arch/arm/src/stm32h7/hardware/stm32_dac.h — register layout fixes
  • Documentation/components/drivers/character/analog/dac/stm32h7/index.rst — driver docs (395 lines): hardware features, write/DMA modes with code examples, ioctl reference, Kconfig configuration

Impact

  • New optional driver, gated by CONFIG_STM32_DAC; no effect when disabled
  • DMA features gated by CONFIG_STM32_DAC_DMA
  • Public ioctl codes in include/nuttx/analog/ioctl.h — additive, no breakage
  • dac_info_s extended with 2 new fields — additive
  • Only STM32H7 is wired up; other STM32 families are unaffected

Testing

  • Host: Linux x86_64, GNU/Linux 7.0.0-28-generic 24.04.1-Ubuntu SMP PREEMPT_DYNAMIC, GCC ARM toolchain (arm-none-eabi-gcc 13.2)
  • Board: devebox-stm32h743 (STM32H743VIT6, 480 MHz, VOS1)
  • Test setup: DAC1_OUT1 (PA4), DAC1_OUT2 (PA5) → oscilloscope.
  • Test application: examples/dac: add DMA mode test command for DAC driver (apache/nuttx-apps@4384fe6) — adds test-dma c|s [freq] [ampl] command with circular and stream mode support, DDS sine generator, Ctrl+C stop.

Config parameters:

CONFIG_DAC=y
CONFIG_STM32_DAC=y
CONFIG_STM32_DAC1=y
CONFIG_STM32_DAC1CH1=y
CONFIG_STM32_DAC1CH2=y
CONFIG_STM32_DAC_LL_OPS=y
CONFIG_STM32_DAC1CH1_DMA=y
CONFIG_STM32_DAC1CH1_DMA_BUFFER_SIZE=4096
CONFIG_STM32_DAC1CH1_DMA_PRIORITY_MEDIUM=y
CONFIG_STM32_DAC1CH1_TIMER=5
CONFIG_STM32_DAC1CH1_TIMER_FREQUENCY=100000
CONFIG_STM32_DAC1CH2_DMA=y
CONFIG_STM32_DAC1CH2_DMA_BUFFER_SIZE=4096
CONFIG_STM32_DAC1CH2_DMA_PRIORITY_MEDIUM=y
CONFIG_STM32_DAC1CH2_TIMER=6
CONFIG_STM32_DAC1CH2_TIMER_FREQUENCY=100000
CONFIG_STM32_DMA1=y
CONFIG_STM32_TIM=y
CONFIG_STM32_TIM5=y
CONFIG_STM32_TIM6=y
CONFIG_EXAMPLES_DAC=y

Results:

  • Basic write mode — dac put <0..4095> sets any 12-bit value, on both channels; confirmed on oscilloscope
  • DMA circular mode — dac test-dma c, triangle waveform; both channels verified
  • DMA stream mode — dac test-dma s 1000, on-the-fly 1Hz-100kHz sine via table-based DDS with double-buffering and half/complete events; both channels verified; tested at timer frequencies up to 2 MHz
  • Ctrl+C stop — DMA correctly stopped via ANIOC_DAC_DMA_STOP
  • Timer triggers — all 8 timers verified on both channels: TIM 1, 2, 4, 5, 6, 7, 8, 15
  • D-Cache — builds with and without CONFIG_ARMV7M_DCACHE both clean (DMA buffer in non-cacheable SRAM4)
  • tools/checkpatch.sh -f clean on all new/changed sources

+ added dac driver
* modified Kconfig for DAC, DAC_DMA, TMX_DAC
* checked DMA+DAC/DAC only
* checked DCASH/wo DCASH
* checked TIM 1,2,4,5,6,7,8,15

Signed-off-by: Andrey Sobol <andrey.sobol.nn@gmail.com>
@seniorandre seniorandre changed the title Stm32h7 dac dma Stm32h7 dac dma driver Jul 25, 2026
@acassis acassis changed the title Stm32h7 dac dma driver arch/stm32h7: Add DAC/DMA driver Jul 26, 2026
@github-actions github-actions Bot added Arch: arm Issues related to ARM (32-bit) architecture Area: Drivers Drivers issues Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. labels Jul 26, 2026
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@acassis

acassis commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

@seniorandre please fix:

../nuttx/tools/checkpatch.sh -c -u -m -g 216edd7..HEAD
❌ Missing Signed-off-by
Used config files:
1: .codespellrc
Some checks failed. For contributing guidelines, see:
https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md

Add DMA support for DAC output with configurable double-buffering
via ioctl interface:

- ANIOC_DAC_DMABUFF_INIT: Copy full buffer into DMA buffer (memcpy)
- ANIOC_DAC_DMA_START: Start DMA with optional half-transfer interrupts
- ANIOC_DAC_DMA_STOP: Stop DMA and timer
- ANIOC_DAC_DMA_GET_EVENT: Wait for half-transfer complete event
- ANIOC_DAC_DMA_WRITE_HBUF: Write half-buffer into DMA buffer
- ANIOC_DAC_INFO: Query DAC capabilities (resolution, DMA, buffer size)

Stream mode: when halfint=1, both HTIF and TCIF generate events
via a ring buffer and semaphore. User writes the completed half
while DMA fills the other half. TCIF indicates h=1, HTIF h=0.

DMA priority is configurable per-channel via Kconfig choice
(Low/Medium/High/VeryHigh), defaulting to Medium.

Signed-off-by: Andrey Sobol <andrey.sobol.nn@gmail.com>
Covers basic write mode, DMA circular and stream modes with code examples,
data structures, ioctl commands, and Kconfig configuration.

Signed-off-by: Andrey Sobol <andrey.sobol.nn@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Arch: arm Issues related to ARM (32-bit) architecture Area: Drivers Drivers issues Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants