From f5d084552d9f44d24f020269cc605de0fb4d1041 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sat, 17 Jun 2023 11:48:21 +0200 Subject: [PATCH] implement mwe of a DMA write() method for DAC --- embassy-stm32/build.rs | 2 + embassy-stm32/src/{dac.rs => dac/mod.rs} | 76 +++++++++++++++++++++--- 2 files changed, 71 insertions(+), 7 deletions(-) rename embassy-stm32/src/{dac.rs => dac/mod.rs} (76%) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 9e597f18..e2bd01d7 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -699,6 +699,8 @@ fn main() { // SDMMCv1 uses the same channel for both directions, so just implement for RX (("sdmmc", "RX"), quote!(crate::sdmmc::SdmmcDma)), (("quadspi", "QUADSPI"), quote!(crate::qspi::QuadDma)), + (("dac", "CH1"), quote!(crate::dac::Dma)), + (("dac", "CH2"), quote!(crate::dac::Dma)), ] .into(); diff --git a/embassy-stm32/src/dac.rs b/embassy-stm32/src/dac/mod.rs similarity index 76% rename from embassy-stm32/src/dac.rs rename to embassy-stm32/src/dac/mod.rs index 60e856c7..348d8bcc 100644 --- a/embassy-stm32/src/dac.rs +++ b/embassy-stm32/src/dac/mod.rs @@ -2,6 +2,7 @@ use embassy_hal_common::{into_ref, PeripheralRef}; +use crate::dma::{slice_ptr_parts, word, Transfer}; use crate::pac::dac; use crate::rcc::RccPeripheral; use crate::{peripherals, Peripheral}; @@ -97,39 +98,58 @@ pub enum Value { Bit12(u16, Alignment), } -pub struct Dac<'d, T: Instance> { +pub struct Dac<'d, T: Instance, Tx> { channels: u8, + txdma: PeripheralRef<'d, Tx>, _peri: PeripheralRef<'d, T>, } -impl<'d, T: Instance> Dac<'d, T> { - pub fn new_1ch(peri: impl Peripheral

+ 'd, _ch1: impl Peripheral

> + 'd) -> Self { +impl<'d, T: Instance, Tx> Dac<'d, T, Tx> { + pub fn new_1ch( + peri: impl Peripheral

+ 'd, + txdma: impl Peripheral

+ 'd, + _ch1: impl Peripheral

> + 'd, + ) -> Self { into_ref!(peri); - Self::new_inner(peri, 1) + Self::new_inner(peri, 1, txdma) } pub fn new_2ch( peri: impl Peripheral

+ 'd, + txdma: impl Peripheral

+ 'd, _ch1: impl Peripheral

> + 'd, _ch2: impl Peripheral

> + 'd, ) -> Self { into_ref!(peri); - Self::new_inner(peri, 2) + Self::new_inner(peri, 2, txdma) } - fn new_inner(peri: PeripheralRef<'d, T>, channels: u8) -> Self { + fn new_inner(peri: PeripheralRef<'d, T>, channels: u8, txdma: impl Peripheral

+ 'd) -> Self { + into_ref!(txdma); T::enable(); T::reset(); unsafe { + T::regs().mcr().modify(|reg| { + for ch in 0..channels { + reg.set_mode(ch as usize, 0); + reg.set_mode(ch as usize, 0); + } + }); + T::regs().cr().modify(|reg| { for ch in 0..channels { reg.set_en(ch as usize, true); + reg.set_ten(ch as usize, true); } }); } - Self { channels, _peri: peri } + Self { + channels, + txdma, + _peri: peri, + } } /// Check the channel is configured @@ -215,6 +235,47 @@ impl<'d, T: Instance> Dac<'d, T> { } Ok(()) } + + /// TODO: Allow an array of Value instead of only u16, right-aligned + pub async fn write(&mut self, data: &[u16]) -> Result<(), Error> + where + Tx: Dma, + { + // TODO: Make this a parameter or get it from the struct or so... + const CHANNEL: usize = 0; + + //debug!("Starting DAC"); + unsafe { + T::regs().cr().modify(|w| { + w.set_en(CHANNEL, true); + w.set_dmaen(CHANNEL, true); + }); + } + + let tx_request = self.txdma.request(); + + // Use the 12 bit right-aligned register for now. TODO: distinguish values + let tx_dst = T::regs().dhr12r(CHANNEL).ptr() as *mut u16; + + let tx_f = unsafe { Transfer::new_write(&mut self.txdma, tx_request, data, tx_dst, Default::default()) }; + + //debug!("Awaiting tx_f"); + + tx_f.await; + + // finish dma + unsafe { + // TODO: Do we need to check any status registers here? + + T::regs().cr().modify(|w| { + // Disable the dac peripheral + //w.set_en(CHANNEL, false); + // Disable the DMA. TODO: Is this necessary? + //w.set_dmaen(CHANNEL, false); + }); + } + Ok(()) + } } pub(crate) mod sealed { @@ -224,6 +285,7 @@ pub(crate) mod sealed { } pub trait Instance: sealed::Instance + RccPeripheral + 'static {} +dma_trait!(Dma, Instance); pub trait DacPin: crate::gpio::Pin + 'static {}