aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-03-17 23:47:45 +0000
committerGitHub <[email protected]>2022-03-17 23:47:45 +0000
commitf683b5d4544b5b2095dd9e0530fb0569ab97967e (patch)
tree0f5aa78611f8dd738d0ac65835233e242e2ae749
parent842a1ae30bf9fa27a9f0dc0b5663a763a2943455 (diff)
parentbdeb537ffa1d57e6a4e59613705c0b2ff0abb819 (diff)
Merge #672
672: Reset peripherals on enable r=chemicstry a=chemicstry Add reset on initialization to peripherals that did not have it before. This fixes problems when same peripheral is reinitialized at runtime multiple times. Some exceptions: - ADC: all ADCs share a single reset - DCMI: does reset before enable - couldn't find anything about the order in the reference manual. Just keep it if it works? I also fixed safety issues where global RCC registers where accessed without critical section. Co-authored-by: chemicstry <[email protected]>
-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
-rw-r--r--embassy-stm32/src/i2c/v1.rs1
-rw-r--r--embassy-stm32/src/i2c/v2.rs1
-rw-r--r--embassy-stm32/src/usart/mod.rs1
6 files changed, 46 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..3221cf5ef 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(any(stm32l4, stm32wb))]
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..35facdd25 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| {
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index f280187e5..e0b151142 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -32,6 +32,7 @@ impl<'d, T: Instance> I2c<'d, T> {
32 unborrow!(scl, sda); 32 unborrow!(scl, sda);
33 33
34 T::enable(); 34 T::enable();
35 T::reset();
35 36
36 unsafe { 37 unsafe {
37 scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain); 38 scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 5e9de8fd3..f3714cbcb 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -53,6 +53,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
53 unborrow!(irq, scl, sda, tx_dma, rx_dma); 53 unborrow!(irq, scl, sda, tx_dma, rx_dma);
54 54
55 T::enable(); 55 T::enable();
56 T::reset();
56 57
57 unsafe { 58 unsafe {
58 scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain); 59 scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 0466065f1..caea8d71b 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -200,6 +200,7 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
200 unborrow!(_inner, rx, tx, tx_dma, rx_dma); 200 unborrow!(_inner, rx, tx, tx_dma, rx_dma);
201 201
202 T::enable(); 202 T::enable();
203 T::reset();
203 let pclk_freq = T::frequency(); 204 let pclk_freq = T::frequency();
204 205
205 // TODO: better calculation, including error checking and OVER8 if possible. 206 // TODO: better calculation, including error checking and OVER8 if possible.