aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2022-08-04 03:02:57 +0300
committerchemicstry <[email protected]>2022-08-04 03:02:57 +0300
commit5f01e56728c3a06f1d2298dea6dde000a43acc83 (patch)
tree9932cf2bb9ffb07a167d036eb92596e6d94b0281
parent1924f2d67d32a4466e71ef0aabc84305a9e8e165 (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.rs36
-rw-r--r--embassy-stm32/src/dac/v1.rs1
-rw-r--r--examples/stm32f1/Cargo.toml3
-rw-r--r--examples/stm32f1/src/bin/dac.rs37
m---------stm32-data0
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
3use cfg_if::cfg_if;
1use embassy_hal_common::{into_ref, PeripheralRef}; 4use embassy_hal_common::{into_ref, PeripheralRef};
2 5
3use crate::dac::{DacPin, Instance};
4use crate::pac::dac; 6use crate::pac::dac;
5use crate::Peripheral; 7use 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
23impl 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))]
23pub enum Ch1Trigger { 34pub 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
245pub(crate) mod sealed {
246 pub trait Instance {
247 fn regs() -> &'static crate::pac::dac::Dac;
248 }
249}
250
251pub trait Instance: sealed::Instance + 'static {}
252
253pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
254
255foreach_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
267macro_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")]
5mod _version;
6pub use _version::*;
7
8use crate::peripherals;
9
10pub(crate) mod sealed {
11 pub trait Instance {
12 fn regs() -> &'static crate::pac::dac::Dac;
13 }
14}
15
16pub trait Instance: sealed::Instance + 'static {}
17
18pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {}
19
20foreach_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
32macro_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]
7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] } 7embassy-util = { version = "0.1.0", path = "../../embassy-util", features = ["defmt"] }
8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] } 8embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "defmt-timestamp-uptime", "time-tick-32768hz"] }
9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } 9embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103rc", "unstable-pac", "memory-x", "time-driver-any"] }
10embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } 10embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] }
11embassy-usb-serial = { version = "0.1.0", path = "../../embassy-usb-serial", features = ["defmt"] } 11embassy-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"] }
20futures = { version = "0.3.17", default-features = false, features = ["async-await"] } 20futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
21heapless = { version = "0.7.5", default-features = false } 21heapless = { version = "0.7.5", default-features = false }
22nb = "1.0.0" 22nb = "1.0.0"
23micromath = "2.0.0"
23 24
24[profile.dev] 25[profile.dev]
25opt-level = "s" 26opt-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
5use defmt::*;
6use embassy_executor::executor::Spawner;
7use embassy_stm32::dac::{Channel, Dac, Value};
8use embassy_stm32::Peripherals;
9use {defmt_rtt as _, panic_probe as _};
10
11#[embassy_executor::main]
12async 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
25use micromath::F32Ext;
26
27fn 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