diff options
| author | chemicstry <[email protected]> | 2022-08-04 03:02:57 +0300 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2022-08-04 03:02:57 +0300 |
| commit | 5f01e56728c3a06f1d2298dea6dde000a43acc83 (patch) | |
| tree | 9932cf2bb9ffb07a167d036eb92596e6d94b0281 | |
| parent | 1924f2d67d32a4466e71ef0aabc84305a9e8e165 (diff) | |
Merge v1, v2 DAC and update register definitions
| -rw-r--r-- | embassy-stm32/src/dac.rs (renamed from embassy-stm32/src/dac/v2.rs) | 145 | ||||
| -rw-r--r-- | embassy-stm32/src/dac/mod.rs | 36 | ||||
| -rw-r--r-- | embassy-stm32/src/dac/v1.rs | 1 | ||||
| -rw-r--r-- | examples/stm32f1/Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/stm32f1/src/bin/dac.rs | 37 | ||||
| m--------- | stm32-data | 0 |
6 files changed, 118 insertions, 104 deletions
diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac.rs index 6b7f41c63..c0369d978 100644 --- a/embassy-stm32/src/dac/v2.rs +++ b/embassy-stm32/src/dac.rs | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | use cfg_if::cfg_if; | ||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 4 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 2 | 5 | ||
| 3 | use crate::dac::{DacPin, Instance}; | ||
| 4 | use crate::pac::dac; | 6 | use crate::pac::dac; |
| 5 | use crate::Peripheral; | 7 | use crate::{peripherals, Peripheral}; |
| 6 | 8 | ||
| 7 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | 9 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| 8 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 10 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -18,6 +20,15 @@ pub enum Channel { | |||
| 18 | Ch2, | 20 | Ch2, |
| 19 | } | 21 | } |
| 20 | 22 | ||
| 23 | impl Channel { | ||
| 24 | fn index(&self) -> usize { | ||
| 25 | match self { | ||
| 26 | Channel::Ch1 => 0, | ||
| 27 | Channel::Ch2 => 1, | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 21 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | 32 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| 22 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 33 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 23 | pub enum Ch1Trigger { | 34 | pub enum Ch1Trigger { |
| @@ -119,27 +130,28 @@ impl<'d, T: Instance> Dac<'d, T> { | |||
| 119 | // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock | 130 | // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock |
| 120 | // configuration. | 131 | // configuration. |
| 121 | critical_section::with(|_| { | 132 | critical_section::with(|_| { |
| 122 | #[cfg(rcc_h7)] | 133 | cfg_if! { |
| 123 | enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst); | 134 | if #[cfg(rcc_f1)] { |
| 124 | #[cfg(rcc_h7ab)] | 135 | enable!(apb1enr, set_dacen, apb1rstr, set_dacrst); |
| 125 | enable!(apb1lenr, set_dac1en, apb1lrstr, set_dac1rst); | 136 | } else if #[cfg(rcc_h7)] { |
| 126 | #[cfg(stm32g0)] | 137 | enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst); |
| 127 | enable!(apbenr1, set_dac1en, apbrstr1, set_dac1rst); | 138 | } else if #[cfg(rcc_h7ab)] { |
| 128 | #[cfg(any(stm32l4, stm32l5))] | 139 | enable!(apb1lenr, set_dac1en, apb1lrstr, set_dac1rst); |
| 129 | enable!(apb1enr1, set_dac1en, apb1rstr1, set_dac1rst); | 140 | } else if #[cfg(stm32g0)] { |
| 141 | enable!(apbenr1, set_dac1en, apbrstr1, set_dac1rst); | ||
| 142 | } else if #[cfg(any(stm32l4, stm32l5))] { | ||
| 143 | enable!(apb1enr1, set_dac1en, apb1rstr1, set_dac1rst); | ||
| 144 | } else { | ||
| 145 | unimplemented!("DAC enable/reset is not yet implemented for this chip"); | ||
| 146 | } | ||
| 147 | } | ||
| 130 | }); | 148 | }); |
| 131 | 149 | ||
| 132 | if channels >= 1 { | 150 | T::regs().cr().modify(|reg| { |
| 133 | T::regs().cr().modify(|reg| { | 151 | for ch in 0..channels { |
| 134 | reg.set_en1(true); | 152 | reg.set_en(ch as usize, true); |
| 135 | }); | 153 | } |
| 136 | } | 154 | }); |
| 137 | |||
| 138 | if channels >= 2 { | ||
| 139 | T::regs().cr().modify(|reg| { | ||
| 140 | reg.set_en2(true); | ||
| 141 | }); | ||
| 142 | } | ||
| 143 | } | 155 | } |
| 144 | 156 | ||
| 145 | Self { channels, _peri: peri } | 157 | Self { channels, _peri: peri } |
| @@ -156,17 +168,10 @@ impl<'d, T: Instance> Dac<'d, T> { | |||
| 156 | 168 | ||
| 157 | fn set_channel_enable(&mut self, ch: Channel, on: bool) -> Result<(), Error> { | 169 | fn set_channel_enable(&mut self, ch: Channel, on: bool) -> Result<(), Error> { |
| 158 | self.check_channel_exists(ch)?; | 170 | self.check_channel_exists(ch)?; |
| 159 | match ch { | 171 | unsafe { |
| 160 | Channel::Ch1 => unsafe { | 172 | T::regs().cr().modify(|reg| { |
| 161 | T::regs().cr().modify(|reg| { | 173 | reg.set_en(ch.index(), on); |
| 162 | reg.set_en1(on); | 174 | }) |
| 163 | }) | ||
| 164 | }, | ||
| 165 | Channel::Ch2 => unsafe { | ||
| 166 | T::regs().cr().modify(|reg| { | ||
| 167 | reg.set_en2(on); | ||
| 168 | }); | ||
| 169 | }, | ||
| 170 | } | 175 | } |
| 171 | Ok(()) | 176 | Ok(()) |
| 172 | } | 177 | } |
| @@ -203,17 +208,10 @@ impl<'d, T: Instance> Dac<'d, T> { | |||
| 203 | 208 | ||
| 204 | pub fn trigger(&mut self, ch: Channel) -> Result<(), Error> { | 209 | pub fn trigger(&mut self, ch: Channel) -> Result<(), Error> { |
| 205 | self.check_channel_exists(ch)?; | 210 | self.check_channel_exists(ch)?; |
| 206 | match ch { | 211 | unsafe { |
| 207 | Channel::Ch1 => unsafe { | 212 | T::regs().swtrigr().write(|reg| { |
| 208 | T::regs().swtrigr().write(|reg| { | 213 | reg.set_swtrig(ch.index(), true); |
| 209 | reg.set_swtrig1(true); | 214 | }); |
| 210 | }); | ||
| 211 | }, | ||
| 212 | Channel::Ch2 => unsafe { | ||
| 213 | T::regs().swtrigr().write(|reg| { | ||
| 214 | reg.set_swtrig2(true); | ||
| 215 | }) | ||
| 216 | }, | ||
| 217 | } | 215 | } |
| 218 | Ok(()) | 216 | Ok(()) |
| 219 | } | 217 | } |
| @@ -221,38 +219,53 @@ impl<'d, T: Instance> Dac<'d, T> { | |||
| 221 | pub fn trigger_all(&mut self) { | 219 | pub fn trigger_all(&mut self) { |
| 222 | unsafe { | 220 | unsafe { |
| 223 | T::regs().swtrigr().write(|reg| { | 221 | T::regs().swtrigr().write(|reg| { |
| 224 | reg.set_swtrig1(true); | 222 | reg.set_swtrig(Channel::Ch1.index(), true); |
| 225 | reg.set_swtrig2(true); | 223 | reg.set_swtrig(Channel::Ch2.index(), true); |
| 226 | }) | 224 | }) |
| 227 | } | 225 | } |
| 228 | } | 226 | } |
| 229 | 227 | ||
| 230 | pub fn set(&mut self, ch: Channel, value: Value) -> Result<(), Error> { | 228 | pub fn set(&mut self, ch: Channel, value: Value) -> Result<(), Error> { |
| 231 | self.check_channel_exists(ch)?; | 229 | self.check_channel_exists(ch)?; |
| 232 | match ch { | 230 | match value { |
| 233 | Channel::Ch1 => match value { | 231 | Value::Bit8(v) => unsafe { |
| 234 | Value::Bit8(v) => unsafe { | 232 | T::regs().dhr8r(ch.index()).write(|reg| reg.set_dhr(v)); |
| 235 | T::regs().dhr8r1().write(|reg| reg.set_dacc1dhr(v)); | ||
| 236 | }, | ||
| 237 | Value::Bit12(v, Alignment::Left) => unsafe { | ||
| 238 | T::regs().dhr12l1().write(|reg| reg.set_dacc1dhr(v)); | ||
| 239 | }, | ||
| 240 | Value::Bit12(v, Alignment::Right) => unsafe { | ||
| 241 | T::regs().dhr12r1().write(|reg| reg.set_dacc1dhr(v)); | ||
| 242 | }, | ||
| 243 | }, | 233 | }, |
| 244 | Channel::Ch2 => match value { | 234 | Value::Bit12(v, Alignment::Left) => unsafe { |
| 245 | Value::Bit8(v) => unsafe { | 235 | T::regs().dhr12l(ch.index()).write(|reg| reg.set_dhr(v)); |
| 246 | T::regs().dhr8r2().write(|reg| reg.set_dacc2dhr(v)); | 236 | }, |
| 247 | }, | 237 | Value::Bit12(v, Alignment::Right) => unsafe { |
| 248 | Value::Bit12(v, Alignment::Left) => unsafe { | 238 | T::regs().dhr12r(ch.index()).write(|reg| reg.set_dhr(v)); |
| 249 | T::regs().dhr12l2().write(|reg| reg.set_dacc2dhr(v)); | ||
| 250 | }, | ||
| 251 | Value::Bit12(v, Alignment::Right) => unsafe { | ||
| 252 | T::regs().dhr12r2().write(|reg| reg.set_dacc2dhr(v)); | ||
| 253 | }, | ||
| 254 | }, | 239 | }, |
| 255 | } | 240 | } |
| 256 | Ok(()) | 241 | Ok(()) |
| 257 | } | 242 | } |
| 258 | } | 243 | } |
| 244 | |||
| 245 | pub(crate) mod sealed { | ||
| 246 | pub trait Instance { | ||
| 247 | fn regs() -> &'static crate::pac::dac::Dac; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | pub trait Instance: sealed::Instance + 'static {} | ||
| 252 | |||
| 253 | pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} | ||
| 254 | |||
| 255 | foreach_peripheral!( | ||
| 256 | (dac, $inst:ident) => { | ||
| 257 | impl crate::dac::sealed::Instance for peripherals::$inst { | ||
| 258 | fn regs() -> &'static crate::pac::dac::Dac { | ||
| 259 | &crate::pac::$inst | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | impl crate::dac::Instance for peripherals::$inst {} | ||
| 264 | }; | ||
| 265 | ); | ||
| 266 | |||
| 267 | macro_rules! impl_dac_pin { | ||
| 268 | ($inst:ident, $pin:ident, $ch:expr) => { | ||
| 269 | impl crate::dac::DacPin<peripherals::$inst, $ch> for crate::peripherals::$pin {} | ||
| 270 | }; | ||
| 271 | } | ||
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs deleted file mode 100644 index f1cb452c7..000000000 --- a/embassy-stm32/src/dac/mod.rs +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | #![macro_use] | ||
| 2 | |||
| 3 | #[cfg_attr(dac_v1, path = "v1.rs")] | ||
| 4 | #[cfg_attr(dac_v2, path = "v2.rs")] | ||
| 5 | mod _version; | ||
| 6 | pub use _version::*; | ||
| 7 | |||
| 8 | use crate::peripherals; | ||
| 9 | |||
| 10 | pub(crate) mod sealed { | ||
| 11 | pub trait Instance { | ||
| 12 | fn regs() -> &'static crate::pac::dac::Dac; | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | pub trait Instance: sealed::Instance + 'static {} | ||
| 17 | |||
| 18 | pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} | ||
| 19 | |||
| 20 | foreach_peripheral!( | ||
| 21 | (dac, $inst:ident) => { | ||
| 22 | impl crate::dac::sealed::Instance for peripherals::$inst { | ||
| 23 | fn regs() -> &'static crate::pac::dac::Dac { | ||
| 24 | &crate::pac::$inst | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | impl crate::dac::Instance for peripherals::$inst {} | ||
| 29 | }; | ||
| 30 | ); | ||
| 31 | |||
| 32 | macro_rules! impl_dac_pin { | ||
| 33 | ($inst:ident, $pin:ident, $ch:expr) => { | ||
| 34 | impl crate::dac::DacPin<peripherals::$inst, $ch> for crate::peripherals::$pin {} | ||
| 35 | }; | ||
| 36 | } | ||
diff --git a/embassy-stm32/src/dac/v1.rs b/embassy-stm32/src/dac/v1.rs deleted file mode 100644 index 8b1378917..000000000 --- a/embassy-stm32/src/dac/v1.rs +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | |||
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 9ce553b6d..638f1eff6 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml | |||
| @@ -6,7 +6,7 @@ version = "0.1.0" | |||
| 6 | [dependencies] | 6 | [dependencies] |
| 7 | embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } | 7 | embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } |
| 8 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] } | 8 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] } |
| 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } | 9 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103rc", "unstable-pac", "memory-x", "time-driver-any"] } |
| 10 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 10 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
| 11 | embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } | 11 | embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } |
| 12 | 12 | ||
| @@ -20,6 +20,7 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } | |||
| 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 20 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 21 | heapless = { version = "0.7.5", default-features = false } | 21 | heapless = { version = "0.7.5", default-features = false } |
| 22 | nb = "1.0.0" | 22 | nb = "1.0.0" |
| 23 | micromath = "2.0.0" | ||
| 23 | 24 | ||
| 24 | [profile.dev] | 25 | [profile.dev] |
| 25 | opt-level = "s" | 26 | opt-level = "s" |
diff --git a/examples/stm32f1/src/bin/dac.rs b/examples/stm32f1/src/bin/dac.rs new file mode 100644 index 000000000..392f5bf4d --- /dev/null +++ b/examples/stm32f1/src/bin/dac.rs | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | |||
| 5 | use defmt::*; | ||
| 6 | use embassy_executor::executor::Spawner; | ||
| 7 | use embassy_stm32::dac::{Channel, Dac, Value}; | ||
| 8 | use embassy_stm32::Peripherals; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { | ||
| 13 | info!("Hello World, dude!"); | ||
| 14 | |||
| 15 | let mut dac = Dac::new_1ch(p.DAC, p.PA4); | ||
| 16 | |||
| 17 | loop { | ||
| 18 | for v in 0..=255 { | ||
| 19 | unwrap!(dac.set(Channel::Ch1, Value::Bit8(to_sine_wave(v)))); | ||
| 20 | unwrap!(dac.trigger(Channel::Ch1)); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | use micromath::F32Ext; | ||
| 26 | |||
| 27 | fn to_sine_wave(v: u8) -> u8 { | ||
| 28 | if v >= 128 { | ||
| 29 | // top half | ||
| 30 | let r = 3.14 * ((v - 128) as f32 / 128.0); | ||
| 31 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 32 | } else { | ||
| 33 | // bottom half | ||
| 34 | let r = 3.14 + 3.14 * (v as f32 / 128.0); | ||
| 35 | (r.sin() * 128.0 + 127.0) as u8 | ||
| 36 | } | ||
| 37 | } | ||
diff --git a/stm32-data b/stm32-data | |||
| Subproject b13ba26f6f9b7049097e39ccc7e5e246ac023d1 | Subproject ac5e65f02a48a443b160e08e8db4bbd7c7787ab | ||
