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