aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchemicstry <[email protected]>2022-03-18 01:11:57 +0200
committerchemicstry <[email protected]>2022-03-18 01:16:07 +0200
commitb30a42aff886f9c6fff42ce539eb09aeeefd2a41 (patch)
tree8b6fede93a6e0e0455b1d95e1180c2f8f83540a2
parentca88ace98d4bb751ac942b122c1a2006171fa1bd (diff)
Fix RCC safety and add reset to DAC
-rw-r--r--embassy-stm32/src/adc/v2.rs16
-rw-r--r--embassy-stm32/src/adc/v3.rs18
-rw-r--r--embassy-stm32/src/dac/v2.rs32
3 files changed, 43 insertions, 23 deletions
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index e79680493..d2429b111 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -7,16 +7,18 @@ use embedded_hal_02::blocking::delay::DelayUs;
7pub const VDDA_CALIB_MV: u32 = 3000; 7pub const VDDA_CALIB_MV: u32 = 3000;
8 8
9#[cfg(not(rcc_f4))] 9#[cfg(not(rcc_f4))]
10unsafe fn enable() { 10fn enable() {
11 todo!() 11 todo!()
12} 12}
13 13
14#[cfg(rcc_f4)] 14#[cfg(rcc_f4)]
15unsafe fn enable() { 15fn enable() {
16 // TODO do not enable all adc clocks if not needed 16 critical_section::with(|_| unsafe {
17 crate::pac::RCC.apb2enr().modify(|w| w.set_adc1en(true)); 17 // TODO do not enable all adc clocks if not needed
18 crate::pac::RCC.apb2enr().modify(|w| w.set_adc2en(true)); 18 crate::pac::RCC.apb2enr().modify(|w| w.set_adc1en(true));
19 crate::pac::RCC.apb2enr().modify(|w| w.set_adc3en(true)); 19 crate::pac::RCC.apb2enr().modify(|w| w.set_adc2en(true));
20 crate::pac::RCC.apb2enr().modify(|w| w.set_adc3en(true));
21 });
20} 22}
21 23
22pub enum Resolution { 24pub enum Resolution {
@@ -125,8 +127,8 @@ where
125{ 127{
126 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 128 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
127 unborrow!(_peri); 129 unborrow!(_peri);
130 enable();
128 unsafe { 131 unsafe {
129 enable();
130 // disable before config is set 132 // disable before config is set
131 T::regs().cr2().modify(|reg| { 133 T::regs().cr2().modify(|reg| {
132 reg.set_adon(crate::pac::adc::vals::Adon::DISABLED); 134 reg.set_adon(crate::pac::adc::vals::Adon::DISABLED);
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index 387b62470..d51b687f1 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -8,13 +8,15 @@ pub const VDDA_CALIB_MV: u32 = 3000;
8 8
9/// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock 9/// Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent ADC clock
10/// configuration. 10/// configuration.
11unsafe fn enable() { 11fn enable() {
12 #[cfg(stm32h7)] 12 critical_section::with(|_| unsafe {
13 crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true)); 13 #[cfg(stm32h7)]
14 #[cfg(stm32g0)] 14 crate::pac::RCC.apb2enr().modify(|w| w.set_adcen(true));
15 crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true)); 15 #[cfg(stm32g0)]
16 #[cfg(stm32l4)] 16 crate::pac::RCC.apbenr2().modify(|w| w.set_adcen(true));
17 crate::pac::RCC.ahb2enr().modify(|w| w.set_adcen(true)); 17 #[cfg(stm32l4)]
18 crate::pac::RCC.ahb2enr().modify(|w| w.set_adcen(true));
19 });
18} 20}
19 21
20pub enum Resolution { 22pub enum Resolution {
@@ -206,8 +208,8 @@ pub struct Adc<'d, T: Instance> {
206impl<'d, T: Instance> Adc<'d, T> { 208impl<'d, T: Instance> Adc<'d, T> {
207 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self { 209 pub fn new(_peri: impl Unborrow<Target = T> + 'd, delay: &mut impl DelayUs<u32>) -> Self {
208 unborrow!(_peri); 210 unborrow!(_peri);
211 enable();
209 unsafe { 212 unsafe {
210 enable();
211 T::regs().cr().modify(|reg| { 213 T::regs().cr().modify(|reg| {
212 #[cfg(not(adc_g0))] 214 #[cfg(not(adc_g0))]
213 reg.set_deeppwd(false); 215 reg.set_deeppwd(false);
diff --git a/embassy-stm32/src/dac/v2.rs b/embassy-stm32/src/dac/v2.rs
index 9fb01fa94..7825dd8b3 100644
--- a/embassy-stm32/src/dac/v2.rs
+++ b/embassy-stm32/src/dac/v2.rs
@@ -91,6 +91,20 @@ pub struct Dac<'d, T: Instance> {
91 phantom: PhantomData<&'d mut T>, 91 phantom: PhantomData<&'d mut T>,
92} 92}
93 93
94macro_rules! enable {
95 ($enable_reg:ident, $enable_field: ident, $reset_reg:ident, $reset_field:ident) => {
96 crate::pac::RCC
97 .$enable_reg()
98 .modify(|w| w.$enable_field(true));
99 crate::pac::RCC
100 .$reset_reg()
101 .modify(|w| w.$reset_field(true));
102 crate::pac::RCC
103 .$reset_reg()
104 .modify(|w| w.$reset_field(false));
105 };
106}
107
94impl<'d, T: Instance> Dac<'d, T> { 108impl<'d, T: Instance> Dac<'d, T> {
95 pub fn new_1ch( 109 pub fn new_1ch(
96 peri: impl Unborrow<Target = T> + 'd, 110 peri: impl Unborrow<Target = T> + 'd,
@@ -113,14 +127,16 @@ impl<'d, T: Instance> Dac<'d, T> {
113 unsafe { 127 unsafe {
114 // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock 128 // Sadly we cannot use `RccPeripheral::enable` since devices are quite inconsistent DAC clock
115 // configuration. 129 // configuration.
116 #[cfg(rcc_h7)] 130 critical_section::with(|_| {
117 crate::pac::RCC.apb1lenr().modify(|w| w.set_dac12en(true)); 131 #[cfg(rcc_h7)]
118 #[cfg(rcc_h7ab)] 132 enable!(apb1lenr, set_dac12en, apb1lrstr, set_dac12rst);
119 crate::pac::RCC.apb1lenr().modify(|w| w.set_dac1en(true)); 133 #[cfg(rcc_h7ab)]
120 #[cfg(stm32g0)] 134 enable!(apb1lenr, set_dac1en, apb1lrstr, set_dac1rst);
121 crate::pac::RCC.apbenr1().modify(|w| w.set_dac1en(true)); 135 #[cfg(stm32g0)]
122 #[cfg(stm32l4)] 136 enable!(apbenr1, set_dac1en, apbrstr1, set_dac1rst);
123 crate::pac::RCC.apb1enr1().modify(|w| w.set_dac1en(true)); 137 #[cfg(stm32l4)]
138 enable!(apb1enr1, set_dac1en, apb1rstr1, set_dac1rst);
139 });
124 140
125 if channels >= 1 { 141 if channels >= 1 {
126 T::regs().cr().modify(|reg| { 142 T::regs().cr().modify(|reg| {