From 5f01e56728c3a06f1d2298dea6dde000a43acc83 Mon Sep 17 00:00:00 2001 From: chemicstry Date: Thu, 4 Aug 2022 03:02:57 +0300 Subject: [PATCH] Merge v1, v2 DAC and update register definitions --- embassy-stm32/src/{dac/v2.rs => dac.rs} | 145 +++++++++++++----------- embassy-stm32/src/dac/mod.rs | 36 ------ embassy-stm32/src/dac/v1.rs | 1 - examples/stm32f1/Cargo.toml | 3 +- examples/stm32f1/src/bin/dac.rs | 37 ++++++ stm32-data | 2 +- 6 files changed, 119 insertions(+), 105 deletions(-) rename embassy-stm32/src/{dac/v2.rs => dac.rs} (66%) delete mode 100644 embassy-stm32/src/dac/mod.rs delete mode 100644 embassy-stm32/src/dac/v1.rs create mode 100644 examples/stm32f1/src/bin/dac.rs diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac.rs similarity index 66% rename from embassy-stm32/src/dac/v2.rs rename to embassy-stm32/src/dac.rs index 6b7f41c6..c0369d97 100644 --- a/embassy-stm32/src/dac/v2.rs +++ b/embassy-stm32/src/dac.rs @@ -1,8 +1,10 @@ +#![macro_use] + +use cfg_if::cfg_if; use embassy_hal_common::{into_ref, PeripheralRef}; -use crate::dac::{DacPin, Instance}; use crate::pac::dac; -use crate::Peripheral; +use crate::{peripherals, Peripheral}; #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -18,6 +20,15 @@ pub enum Channel { Ch2, } +impl Channel { + fn index(&self) -> usize { + match self { + Channel::Ch1 => 0, + Channel::Ch2 => 1, + } + } +} + #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Ch1Trigger { @@ -119,27 +130,28 @@ impl<'d, T: Instance> Dac<'d, T> { // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock // configuration. critical_section::with(|_| { - #[cfg(rcc_h7)] - enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst); - #[cfg(rcc_h7ab)] - enable!(apb1lenr, set_dac1en, apb1lrstr, set_dac1rst); - #[cfg(stm32g0)] - enable!(apbenr1, set_dac1en, apbrstr1, set_dac1rst); - #[cfg(any(stm32l4, stm32l5))] - enable!(apb1enr1, set_dac1en, apb1rstr1, set_dac1rst); + cfg_if! { + if #[cfg(rcc_f1)] { + enable!(apb1enr, set_dacen, apb1rstr, set_dacrst); + } else if #[cfg(rcc_h7)] { + enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst); + } else if #[cfg(rcc_h7ab)] { + enable!(apb1lenr, set_dac1en, apb1lrstr, set_dac1rst); + } else if #[cfg(stm32g0)] { + enable!(apbenr1, set_dac1en, apbrstr1, set_dac1rst); + } else if #[cfg(any(stm32l4, stm32l5))] { + enable!(apb1enr1, set_dac1en, apb1rstr1, set_dac1rst); + } else { + unimplemented!("DAC enable/reset is not yet implemented for this chip"); + } + } }); - if channels >= 1 { - T::regs().cr().modify(|reg| { - reg.set_en1(true); - }); - } - - if channels >= 2 { - T::regs().cr().modify(|reg| { - reg.set_en2(true); - }); - } + T::regs().cr().modify(|reg| { + for ch in 0..channels { + reg.set_en(ch as usize, true); + } + }); } Self { channels, _peri: peri } @@ -156,17 +168,10 @@ impl<'d, T: Instance> Dac<'d, T> { fn set_channel_enable(&mut self, ch: Channel, on: bool) -> Result<(), Error> { self.check_channel_exists(ch)?; - match ch { - Channel::Ch1 => unsafe { - T::regs().cr().modify(|reg| { - reg.set_en1(on); - }) - }, - Channel::Ch2 => unsafe { - T::regs().cr().modify(|reg| { - reg.set_en2(on); - }); - }, + unsafe { + T::regs().cr().modify(|reg| { + reg.set_en(ch.index(), on); + }) } Ok(()) } @@ -203,17 +208,10 @@ impl<'d, T: Instance> Dac<'d, T> { pub fn trigger(&mut self, ch: Channel) -> Result<(), Error> { self.check_channel_exists(ch)?; - match ch { - Channel::Ch1 => unsafe { - T::regs().swtrigr().write(|reg| { - reg.set_swtrig1(true); - }); - }, - Channel::Ch2 => unsafe { - T::regs().swtrigr().write(|reg| { - reg.set_swtrig2(true); - }) - }, + unsafe { + T::regs().swtrigr().write(|reg| { + reg.set_swtrig(ch.index(), true); + }); } Ok(()) } @@ -221,38 +219,53 @@ impl<'d, T: Instance> Dac<'d, T> { pub fn trigger_all(&mut self) { unsafe { T::regs().swtrigr().write(|reg| { - reg.set_swtrig1(true); - reg.set_swtrig2(true); + reg.set_swtrig(Channel::Ch1.index(), true); + reg.set_swtrig(Channel::Ch2.index(), true); }) } } pub fn set(&mut self, ch: Channel, value: Value) -> Result<(), Error> { self.check_channel_exists(ch)?; - match ch { - Channel::Ch1 => match value { - Value::Bit8(v) => unsafe { - T::regs().dhr8r1().write(|reg| reg.set_dacc1dhr(v)); - }, - Value::Bit12(v, Alignment::Left) => unsafe { - T::regs().dhr12l1().write(|reg| reg.set_dacc1dhr(v)); - }, - Value::Bit12(v, Alignment::Right) => unsafe { - T::regs().dhr12r1().write(|reg| reg.set_dacc1dhr(v)); - }, + match value { + Value::Bit8(v) => unsafe { + T::regs().dhr8r(ch.index()).write(|reg| reg.set_dhr(v)); }, - Channel::Ch2 => match value { - Value::Bit8(v) => unsafe { - T::regs().dhr8r2().write(|reg| reg.set_dacc2dhr(v)); - }, - Value::Bit12(v, Alignment::Left) => unsafe { - T::regs().dhr12l2().write(|reg| reg.set_dacc2dhr(v)); - }, - Value::Bit12(v, Alignment::Right) => unsafe { - T::regs().dhr12r2().write(|reg| reg.set_dacc2dhr(v)); - }, + Value::Bit12(v, Alignment::Left) => unsafe { + T::regs().dhr12l(ch.index()).write(|reg| reg.set_dhr(v)); + }, + Value::Bit12(v, Alignment::Right) => unsafe { + T::regs().dhr12r(ch.index()).write(|reg| reg.set_dhr(v)); }, } Ok(()) } } + +pub(crate) mod sealed { + pub trait Instance { + fn regs() -> &'static crate::pac::dac::Dac; + } +} + +pub trait Instance: sealed::Instance + 'static {} + +pub trait DacPin: crate::gpio::Pin + 'static {} + +foreach_peripheral!( + (dac, $inst:ident) => { + impl crate::dac::sealed::Instance for peripherals::$inst { + fn regs() -> &'static crate::pac::dac::Dac { + &crate::pac::$inst + } + } + + impl crate::dac::Instance for peripherals::$inst {} + }; +); + +macro_rules! impl_dac_pin { + ($inst:ident, $pin:ident, $ch:expr) => { + impl crate::dac::DacPin for crate::peripherals::$pin {} + }; +} diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs deleted file mode 100644 index f1cb452c..00000000 --- a/embassy-stm32/src/dac/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![macro_use] - -#[cfg_attr(dac_v1, path = "v1.rs")] -#[cfg_attr(dac_v2, path = "v2.rs")] -mod _version; -pub use _version::*; - -use crate::peripherals; - -pub(crate) mod sealed { - pub trait Instance { - fn regs() -> &'static crate::pac::dac::Dac; - } -} - -pub trait Instance: sealed::Instance + 'static {} - -pub trait DacPin: crate::gpio::Pin + 'static {} - -foreach_peripheral!( - (dac, $inst:ident) => { - impl crate::dac::sealed::Instance for peripherals::$inst { - fn regs() -> &'static crate::pac::dac::Dac { - &crate::pac::$inst - } - } - - impl crate::dac::Instance for peripherals::$inst {} - }; -); - -macro_rules! impl_dac_pin { - ($inst:ident, $pin:ident, $ch:expr) => { - impl crate::dac::DacPin for crate::peripherals::$pin {} - }; -} diff --git a/embassy-stm32/src/dac/v1.rs b/embassy-stm32/src/dac/v1.rs deleted file mode 100644 index 8b137891..00000000 --- a/embassy-stm32/src/dac/v1.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 9ce553b6..638f1eff 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml @@ -6,7 +6,7 @@ version = "0.1.0" [dependencies] embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] } -embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } +embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103rc", "unstable-pac", "memory-x", "time-driver-any"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } @@ -20,6 +20,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" +micromath = "2.0.0" [profile.dev] opt-level = "s" diff --git a/examples/stm32f1/src/bin/dac.rs b/examples/stm32f1/src/bin/dac.rs new file mode 100644 index 00000000..392f5bf4 --- /dev/null +++ b/examples/stm32f1/src/bin/dac.rs @@ -0,0 +1,37 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::executor::Spawner; +use embassy_stm32::dac::{Channel, Dac, Value}; +use embassy_stm32::Peripherals; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner, p: Peripherals) -> ! { + info!("Hello World, dude!"); + + let mut dac = Dac::new_1ch(p.DAC, p.PA4); + + loop { + for v in 0..=255 { + unwrap!(dac.set(Channel::Ch1, Value::Bit8(to_sine_wave(v)))); + unwrap!(dac.trigger(Channel::Ch1)); + } + } +} + +use micromath::F32Ext; + +fn to_sine_wave(v: u8) -> u8 { + if v >= 128 { + // top half + let r = 3.14 * ((v - 128) as f32 / 128.0); + (r.sin() * 128.0 + 127.0) as u8 + } else { + // bottom half + let r = 3.14 + 3.14 * (v as f32 / 128.0); + (r.sin() * 128.0 + 127.0) as u8 + } +} diff --git a/stm32-data b/stm32-data index b13ba26f..ac5e65f0 160000 --- a/stm32-data +++ b/stm32-data @@ -1 +1 @@ -Subproject commit b13ba26f6f9b7049097e39ccc7e5e246ac023d15 +Subproject commit ac5e65f02a48a443b160e08e8db4bbd7c7787ab4