diff options
| author | chemicstry <[email protected]> | 2022-08-04 03:31:47 +0300 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2022-08-04 03:31:47 +0300 |
| commit | 206b7fd8edd6503ddf728d9c232ad395896990e4 (patch) | |
| tree | 106b36fd48b6ef37b20745dc10aa4b8792f75d88 | |
| parent | d990740dd5f04980006196c5a416416679d7b457 (diff) | |
Use RccPeripheral for DAC and add a hackfix for H7
| -rw-r--r-- | embassy-stm32/src/dac.rs | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/embassy-stm32/src/dac.rs b/embassy-stm32/src/dac.rs index c0369d978..60e856c78 100644 --- a/embassy-stm32/src/dac.rs +++ b/embassy-stm32/src/dac.rs | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use cfg_if::cfg_if; | ||
| 4 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 5 | 4 | ||
| 6 | use crate::pac::dac; | 5 | use crate::pac::dac; |
| 6 | use crate::rcc::RccPeripheral; | ||
| 7 | use crate::{peripherals, Peripheral}; | 7 | use crate::{peripherals, Peripheral}; |
| 8 | 8 | ||
| 9 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | 9 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
| @@ -102,14 +102,6 @@ pub struct Dac<'d, T: Instance> { | |||
| 102 | _peri: PeripheralRef<'d, T>, | 102 | _peri: PeripheralRef<'d, T>, |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | macro_rules! enable { | ||
| 106 | ($enable_reg:ident, $enable_field:ident, $reset_reg:ident, $reset_field:ident) => { | ||
| 107 | crate::pac::RCC.$enable_reg().modify(|w| w.$enable_field(true)); | ||
| 108 | crate::pac::RCC.$reset_reg().modify(|w| w.$reset_field(true)); | ||
| 109 | crate::pac::RCC.$reset_reg().modify(|w| w.$reset_field(false)); | ||
| 110 | }; | ||
| 111 | } | ||
| 112 | |||
| 113 | impl<'d, T: Instance> Dac<'d, T> { | 105 | impl<'d, T: Instance> Dac<'d, T> { |
| 114 | pub fn new_1ch(peri: impl Peripheral<P = T> + 'd, _ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd) -> Self { | 106 | pub fn new_1ch(peri: impl Peripheral<P = T> + 'd, _ch1: impl Peripheral<P = impl DacPin<T, 1>> + 'd) -> Self { |
| 115 | into_ref!(peri); | 107 | into_ref!(peri); |
| @@ -126,27 +118,10 @@ impl<'d, T: Instance> Dac<'d, T> { | |||
| 126 | } | 118 | } |
| 127 | 119 | ||
| 128 | fn new_inner(peri: PeripheralRef<'d, T>, channels: u8) -> Self { | 120 | fn new_inner(peri: PeripheralRef<'d, T>, channels: u8) -> Self { |
| 129 | unsafe { | 121 | T::enable(); |
| 130 | // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock | 122 | T::reset(); |
| 131 | // configuration. | ||
| 132 | critical_section::with(|_| { | ||
| 133 | cfg_if! { | ||
| 134 | if #[cfg(rcc_f1)] { | ||
| 135 | enable!(apb1enr, set_dacen, apb1rstr, set_dacrst); | ||
| 136 | } else if #[cfg(rcc_h7)] { | ||
| 137 | enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst); | ||
| 138 | } else if #[cfg(rcc_h7ab)] { | ||
| 139 | enable!(apb1lenr, set_dac1en, apb1lrstr, 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 | } | ||
| 148 | }); | ||
| 149 | 123 | ||
| 124 | unsafe { | ||
| 150 | T::regs().cr().modify(|reg| { | 125 | T::regs().cr().modify(|reg| { |
| 151 | for ch in 0..channels { | 126 | for ch in 0..channels { |
| 152 | reg.set_en(ch as usize, true); | 127 | reg.set_en(ch as usize, true); |
| @@ -248,12 +223,44 @@ pub(crate) mod sealed { | |||
| 248 | } | 223 | } |
| 249 | } | 224 | } |
| 250 | 225 | ||
| 251 | pub trait Instance: sealed::Instance + 'static {} | 226 | pub trait Instance: sealed::Instance + RccPeripheral + 'static {} |
| 252 | 227 | ||
| 253 | pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} | 228 | pub trait DacPin<T: Instance, const C: u8>: crate::gpio::Pin + 'static {} |
| 254 | 229 | ||
| 255 | foreach_peripheral!( | 230 | foreach_peripheral!( |
| 256 | (dac, $inst:ident) => { | 231 | (dac, $inst:ident) => { |
| 232 | // H7 uses single bit for both DAC1 and DAC2, this is a hack until a proper fix is implemented | ||
| 233 | #[cfg(rcc_h7)] | ||
| 234 | impl crate::rcc::sealed::RccPeripheral for peripherals::$inst { | ||
| 235 | fn frequency() -> crate::time::Hertz { | ||
| 236 | critical_section::with(|_| unsafe { | ||
| 237 | crate::rcc::get_freqs().apb1 | ||
| 238 | }) | ||
| 239 | } | ||
| 240 | |||
| 241 | fn reset() { | ||
| 242 | critical_section::with(|_| unsafe { | ||
| 243 | crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(true)); | ||
| 244 | crate::pac::RCC.apb1lrstr().modify(|w| w.set_dac12rst(false)); | ||
| 245 | }) | ||
| 246 | } | ||
| 247 | |||
| 248 | fn enable() { | ||
| 249 | critical_section::with(|_| unsafe { | ||
| 250 | crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); | ||
| 251 | }) | ||
| 252 | } | ||
| 253 | |||
| 254 | fn disable() { | ||
| 255 | critical_section::with(|_| unsafe { | ||
| 256 | crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(false)); | ||
| 257 | }) | ||
| 258 | } | ||
| 259 | } | ||
| 260 | |||
| 261 | #[cfg(rcc_h7)] | ||
| 262 | impl crate::rcc::RccPeripheral for peripherals::$inst {} | ||
| 263 | |||
| 257 | impl crate::dac::sealed::Instance for peripherals::$inst { | 264 | impl crate::dac::sealed::Instance for peripherals::$inst { |
| 258 | fn regs() -> &'static crate::pac::dac::Dac { | 265 | fn regs() -> &'static crate::pac::dac::Dac { |
| 259 | &crate::pac::$inst | 266 | &crate::pac::$inst |
