aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/i2c/mod.rs89
-rw-r--r--embassy-stm32/src/i2c/v1.rs6
-rw-r--r--embassy-stm32/src/i2c/v2.rs6
-rw-r--r--embassy-stm32/src/spi/mod.rs39
-rw-r--r--embassy-stm32/src/usart/buffered.rs154
-rw-r--r--embassy-stm32/src/usart/mod.rs133
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs10
7 files changed, 257 insertions, 180 deletions
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 0bf57ef8a..6d12af2cc 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -9,16 +9,16 @@ use core::future::Future;
9use core::iter; 9use core::iter;
10use core::marker::PhantomData; 10use core::marker::PhantomData;
11 11
12use embassy_hal_internal::{into_ref, Peripheral}; 12use embassy_hal_internal::{Peripheral, PeripheralRef};
13use embassy_sync::waitqueue::AtomicWaker; 13use embassy_sync::waitqueue::AtomicWaker;
14#[cfg(feature = "time")] 14#[cfg(feature = "time")]
15use embassy_time::{Duration, Instant}; 15use embassy_time::{Duration, Instant};
16 16
17use crate::dma::ChannelAndRequest; 17use crate::dma::ChannelAndRequest;
18use crate::gpio::{AFType, Pull}; 18use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
19use crate::interrupt::typelevel::Interrupt; 19use crate::interrupt::typelevel::Interrupt;
20use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
21use crate::rcc::{self, RccInfo, SealedRccPeripheral}; 21use crate::rcc::{RccInfo, SealedRccPeripheral};
22use crate::time::Hertz; 22use crate::time::Hertz;
23use crate::{interrupt, peripherals}; 23use crate::{interrupt, peripherals};
24 24
@@ -72,11 +72,29 @@ impl Default for Config {
72 } 72 }
73} 73}
74 74
75impl Config {
76 fn scl_pull_mode(&self) -> Pull {
77 match self.scl_pullup {
78 true => Pull::Up,
79 false => Pull::Down,
80 }
81 }
82
83 fn sda_pull_mode(&self) -> Pull {
84 match self.sda_pullup {
85 true => Pull::Up,
86 false => Pull::Down,
87 }
88 }
89}
90
75/// I2C driver. 91/// I2C driver.
76pub struct I2c<'d, M: Mode> { 92pub struct I2c<'d, M: Mode> {
77 info: &'static Info, 93 info: &'static Info,
78 state: &'static State, 94 state: &'static State,
79 kernel_clock: Hertz, 95 kernel_clock: Hertz,
96 scl: Option<PeripheralRef<'d, AnyPin>>,
97 sda: Option<PeripheralRef<'d, AnyPin>>,
80 tx_dma: Option<ChannelAndRequest<'d>>, 98 tx_dma: Option<ChannelAndRequest<'d>>,
81 rx_dma: Option<ChannelAndRequest<'d>>, 99 rx_dma: Option<ChannelAndRequest<'d>>,
82 #[cfg(feature = "time")] 100 #[cfg(feature = "time")]
@@ -98,7 +116,15 @@ impl<'d> I2c<'d, Async> {
98 freq: Hertz, 116 freq: Hertz,
99 config: Config, 117 config: Config,
100 ) -> Self { 118 ) -> Self {
101 Self::new_inner(peri, scl, sda, new_dma!(tx_dma), new_dma!(rx_dma), freq, config) 119 Self::new_inner(
120 peri,
121 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
122 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
123 new_dma!(tx_dma),
124 new_dma!(rx_dma),
125 freq,
126 config,
127 )
102 } 128 }
103} 129}
104 130
@@ -111,7 +137,15 @@ impl<'d> I2c<'d, Blocking> {
111 freq: Hertz, 137 freq: Hertz,
112 config: Config, 138 config: Config,
113 ) -> Self { 139 ) -> Self {
114 Self::new_inner(peri, scl, sda, None, None, freq, config) 140 Self::new_inner(
141 peri,
142 new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
143 new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
144 None,
145 None,
146 freq,
147 config,
148 )
115 } 149 }
116} 150}
117 151
@@ -119,34 +153,13 @@ impl<'d, M: Mode> I2c<'d, M> {
119 /// Create a new I2C driver. 153 /// Create a new I2C driver.
120 fn new_inner<T: Instance>( 154 fn new_inner<T: Instance>(
121 _peri: impl Peripheral<P = T> + 'd, 155 _peri: impl Peripheral<P = T> + 'd,
122 scl: impl Peripheral<P = impl SclPin<T>> + 'd, 156 scl: Option<PeripheralRef<'d, AnyPin>>,
123 sda: impl Peripheral<P = impl SdaPin<T>> + 'd, 157 sda: Option<PeripheralRef<'d, AnyPin>>,
124 tx_dma: Option<ChannelAndRequest<'d>>, 158 tx_dma: Option<ChannelAndRequest<'d>>,
125 rx_dma: Option<ChannelAndRequest<'d>>, 159 rx_dma: Option<ChannelAndRequest<'d>>,
126 freq: Hertz, 160 freq: Hertz,
127 config: Config, 161 config: Config,
128 ) -> Self { 162 ) -> Self {
129 into_ref!(scl, sda);
130
131 rcc::enable_and_reset::<T>();
132
133 scl.set_as_af_pull(
134 scl.af_num(),
135 AFType::OutputOpenDrain,
136 match config.scl_pullup {
137 true => Pull::Up,
138 false => Pull::None,
139 },
140 );
141 sda.set_as_af_pull(
142 sda.af_num(),
143 AFType::OutputOpenDrain,
144 match config.sda_pullup {
145 true => Pull::Up,
146 false => Pull::None,
147 },
148 );
149
150 unsafe { T::EventInterrupt::enable() }; 163 unsafe { T::EventInterrupt::enable() };
151 unsafe { T::ErrorInterrupt::enable() }; 164 unsafe { T::ErrorInterrupt::enable() };
152 165
@@ -154,18 +167,23 @@ impl<'d, M: Mode> I2c<'d, M> {
154 info: T::info(), 167 info: T::info(),
155 state: T::state(), 168 state: T::state(),
156 kernel_clock: T::frequency(), 169 kernel_clock: T::frequency(),
170 scl,
171 sda,
157 tx_dma, 172 tx_dma,
158 rx_dma, 173 rx_dma,
159 #[cfg(feature = "time")] 174 #[cfg(feature = "time")]
160 timeout: config.timeout, 175 timeout: config.timeout,
161 _phantom: PhantomData, 176 _phantom: PhantomData,
162 }; 177 };
163 178 this.enable_and_init(freq, config);
164 this.init(freq, config);
165
166 this 179 this
167 } 180 }
168 181
182 fn enable_and_init(&mut self, freq: Hertz, config: Config) {
183 self.info.rcc.enable_and_reset();
184 self.init(freq, config);
185 }
186
169 fn timeout(&self) -> Timeout { 187 fn timeout(&self) -> Timeout {
170 Timeout { 188 Timeout {
171 #[cfg(feature = "time")] 189 #[cfg(feature = "time")]
@@ -174,6 +192,15 @@ impl<'d, M: Mode> I2c<'d, M> {
174 } 192 }
175} 193}
176 194
195impl<'d, M: Mode> Drop for I2c<'d, M> {
196 fn drop(&mut self) {
197 self.scl.as_ref().map(|x| x.set_as_disconnected());
198 self.sda.as_ref().map(|x| x.set_as_disconnected());
199
200 self.info.rcc.disable()
201 }
202}
203
177#[derive(Copy, Clone)] 204#[derive(Copy, Clone)]
178struct Timeout { 205struct Timeout {
179 #[cfg(feature = "time")] 206 #[cfg(feature = "time")]
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs
index 0e2bd2e40..28026f83c 100644
--- a/embassy-stm32/src/i2c/v1.rs
+++ b/embassy-stm32/src/i2c/v1.rs
@@ -700,12 +700,6 @@ impl<'d> I2c<'d, Async> {
700 } 700 }
701} 701}
702 702
703impl<'d, M: PeriMode> Drop for I2c<'d, M> {
704 fn drop(&mut self) {
705 self.info.rcc.disable()
706 }
707}
708
709enum Mode { 703enum Mode {
710 Fast, 704 Fast,
711 Standard, 705 Standard,
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs
index 193f29733..80163c287 100644
--- a/embassy-stm32/src/i2c/v2.rs
+++ b/embassy-stm32/src/i2c/v2.rs
@@ -671,12 +671,6 @@ impl<'d> I2c<'d, Async> {
671 } 671 }
672} 672}
673 673
674impl<'d, M: Mode> Drop for I2c<'d, M> {
675 fn drop(&mut self) {
676 self.info.rcc.disable();
677 }
678}
679
680/// I2C Stop Configuration 674/// I2C Stop Configuration
681/// 675///
682/// Peripheral options for generating the STOP condition 676/// Peripheral options for generating the STOP condition
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 720e80e0d..4eaf7777f 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -13,7 +13,7 @@ use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 15use crate::pac::spi::{regs, vals, Spi as Regs};
16use crate::rcc::{self, RccInfo, SealedRccPeripheral}; 16use crate::rcc::{RccInfo, SealedRccPeripheral};
17use crate::time::Hertz; 17use crate::time::Hertz;
18use crate::Peripheral; 18use crate::Peripheral;
19 19
@@ -120,17 +120,30 @@ impl<'d, M: PeriMode> Spi<'d, M> {
120 rx_dma: Option<ChannelAndRequest<'d>>, 120 rx_dma: Option<ChannelAndRequest<'d>>,
121 config: Config, 121 config: Config,
122 ) -> Self { 122 ) -> Self {
123 let regs = T::info().regs; 123 let mut this = Self {
124 let kernel_clock = T::frequency(); 124 info: T::info(),
125 let br = compute_baud_rate(kernel_clock, config.frequency); 125 kernel_clock: T::frequency(),
126 sck,
127 mosi,
128 miso,
129 tx_dma,
130 rx_dma,
131 current_word_size: <u8 as SealedWord>::CONFIG,
132 _phantom: PhantomData,
133 };
134 this.enable_and_init(config);
135 this
136 }
126 137
138 fn enable_and_init(&mut self, config: Config) {
139 let br = compute_baud_rate(self.kernel_clock, config.frequency);
127 let cpha = config.raw_phase(); 140 let cpha = config.raw_phase();
128 let cpol = config.raw_polarity(); 141 let cpol = config.raw_polarity();
129
130 let lsbfirst = config.raw_byte_order(); 142 let lsbfirst = config.raw_byte_order();
131 143
132 rcc::enable_and_reset::<T>(); 144 self.info.rcc.enable_and_reset();
133 145
146 let regs = self.info.regs;
134 #[cfg(any(spi_v1, spi_f1))] 147 #[cfg(any(spi_v1, spi_f1))]
135 { 148 {
136 regs.cr2().modify(|w| { 149 regs.cr2().modify(|w| {
@@ -209,18 +222,6 @@ impl<'d, M: PeriMode> Spi<'d, M> {
209 w.set_spe(true); 222 w.set_spe(true);
210 }); 223 });
211 } 224 }
212
213 Self {
214 info: T::info(),
215 kernel_clock,
216 sck,
217 mosi,
218 miso,
219 tx_dma,
220 rx_dma,
221 current_word_size: <u8 as SealedWord>::CONFIG,
222 _phantom: PhantomData,
223 }
224 } 225 }
225 226
226 /// Reconfigures it with the supplied config. 227 /// Reconfigures it with the supplied config.
@@ -611,7 +612,7 @@ impl<'d> Spi<'d, Async> {
611 // see RM0453 rev 1 section 7.2.13 page 291 612 // see RM0453 rev 1 section 7.2.13 page 291
612 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. 613 // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two.
613 // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. 614 // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz.
614 let pclk3_freq = <crate::peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; 615 let pclk3_freq = <crate::peripherals::SUBGHZSPI as SealedRccPeripheral>::frequency().0;
615 let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); 616 let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000));
616 let mut config = Config::default(); 617 let mut config = Config::default();
617 config.mode = MODE_0; 618 config.mode = MODE_0;
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index eacf95002..fd79e035e 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -6,7 +6,7 @@ use core::task::Poll;
6 6
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
8use embassy_hal_internal::atomic_ring_buffer::RingBuffer; 8use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
9use embassy_hal_internal::{into_ref, Peripheral}; 9use embassy_hal_internal::{Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12#[cfg(not(any(usart_v1, usart_v2)))] 12#[cfg(not(any(usart_v1, usart_v2)))]
@@ -15,10 +15,8 @@ use super::{
15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance, 15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance,
16 Regs, RtsPin, RxPin, TxPin, 16 Regs, RtsPin, RxPin, TxPin,
17}; 17};
18use crate::gpio::AFType; 18use crate::gpio::{AFType, AnyPin, SealedPin as _};
19use crate::interrupt::typelevel::Interrupt as _;
20use crate::interrupt::{self, InterruptExt}; 19use crate::interrupt::{self, InterruptExt};
21use crate::rcc;
22use crate::time::Hertz; 20use crate::time::Hertz;
23 21
24/// Interrupt handler. 22/// Interrupt handler.
@@ -156,7 +154,9 @@ pub struct BufferedUartTx<'d> {
156 info: &'static Info, 154 info: &'static Info,
157 state: &'static State, 155 state: &'static State,
158 kernel_clock: Hertz, 156 kernel_clock: Hertz,
159 _phantom: PhantomData<&'d mut ()>, 157 tx: Option<PeripheralRef<'d, AnyPin>>,
158 cts: Option<PeripheralRef<'d, AnyPin>>,
159 de: Option<PeripheralRef<'d, AnyPin>>,
160} 160}
161 161
162/// Rx-only buffered UART 162/// Rx-only buffered UART
@@ -166,7 +166,8 @@ pub struct BufferedUartRx<'d> {
166 info: &'static Info, 166 info: &'static Info,
167 state: &'static State, 167 state: &'static State,
168 kernel_clock: Hertz, 168 kernel_clock: Hertz,
169 _phantom: PhantomData<&'d mut ()>, 169 rx: Option<PeripheralRef<'d, AnyPin>>,
170 rts: Option<PeripheralRef<'d, AnyPin>>,
170} 171}
171 172
172impl<'d> SetConfig for BufferedUart<'d> { 173impl<'d> SetConfig for BufferedUart<'d> {
@@ -207,9 +208,17 @@ impl<'d> BufferedUart<'d> {
207 rx_buffer: &'d mut [u8], 208 rx_buffer: &'d mut [u8],
208 config: Config, 209 config: Config,
209 ) -> Result<Self, ConfigError> { 210 ) -> Result<Self, ConfigError> {
210 rcc::enable_and_reset::<T>(); 211 Self::new_inner(
211 212 peri,
212 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) 213 new_pin!(rx, AFType::Input),
214 new_pin!(tx, AFType::OutputPushPull),
215 None,
216 None,
217 None,
218 tx_buffer,
219 rx_buffer,
220 config,
221 )
213 } 222 }
214 223
215 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins 224 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
@@ -224,18 +233,17 @@ impl<'d> BufferedUart<'d> {
224 rx_buffer: &'d mut [u8], 233 rx_buffer: &'d mut [u8],
225 config: Config, 234 config: Config,
226 ) -> Result<Self, ConfigError> { 235 ) -> Result<Self, ConfigError> {
227 into_ref!(cts, rts); 236 Self::new_inner(
228 237 peri,
229 rcc::enable_and_reset::<T>(); 238 new_pin!(rx, AFType::Input),
230 239 new_pin!(tx, AFType::OutputPushPull),
231 rts.set_as_af(rts.af_num(), AFType::OutputPushPull); 240 new_pin!(rts, AFType::OutputPushPull),
232 cts.set_as_af(cts.af_num(), AFType::Input); 241 new_pin!(cts, AFType::Input),
233 T::info().regs.cr3().write(|w| { 242 None,
234 w.set_rtse(true); 243 tx_buffer,
235 w.set_ctse(true); 244 rx_buffer,
236 }); 245 config,
237 246 )
238 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
239 } 247 }
240 248
241 /// Create a new bidirectional buffered UART driver with a driver-enable pin 249 /// Create a new bidirectional buffered UART driver with a driver-enable pin
@@ -250,66 +258,89 @@ impl<'d> BufferedUart<'d> {
250 rx_buffer: &'d mut [u8], 258 rx_buffer: &'d mut [u8],
251 config: Config, 259 config: Config,
252 ) -> Result<Self, ConfigError> { 260 ) -> Result<Self, ConfigError> {
253 into_ref!(de); 261 Self::new_inner(
254 262 peri,
255 rcc::enable_and_reset::<T>(); 263 new_pin!(rx, AFType::Input),
256 264 new_pin!(tx, AFType::OutputPushPull),
257 de.set_as_af(de.af_num(), AFType::OutputPushPull); 265 None,
258 T::info().regs.cr3().write(|w| { 266 None,
259 w.set_dem(true); 267 new_pin!(de, AFType::OutputPushPull),
260 }); 268 tx_buffer,
261 269 rx_buffer,
262 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) 270 config,
271 )
263 } 272 }
264 273
265 fn new_inner<T: Instance>( 274 fn new_inner<T: Instance>(
266 _peri: impl Peripheral<P = T> + 'd, 275 _peri: impl Peripheral<P = T> + 'd,
267 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 276 rx: Option<PeripheralRef<'d, AnyPin>>,
268 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 277 tx: Option<PeripheralRef<'d, AnyPin>>,
278 rts: Option<PeripheralRef<'d, AnyPin>>,
279 cts: Option<PeripheralRef<'d, AnyPin>>,
280 de: Option<PeripheralRef<'d, AnyPin>>,
269 tx_buffer: &'d mut [u8], 281 tx_buffer: &'d mut [u8],
270 rx_buffer: &'d mut [u8], 282 rx_buffer: &'d mut [u8],
271 config: Config, 283 config: Config,
272 ) -> Result<Self, ConfigError> { 284 ) -> Result<Self, ConfigError> {
273 into_ref!(_peri, rx, tx);
274
275 let info = T::info(); 285 let info = T::info();
276 let state = T::buffered_state(); 286 let state = T::buffered_state();
277 let kernel_clock = T::frequency(); 287 let kernel_clock = T::frequency();
278 let len = tx_buffer.len();
279 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
280 let len = rx_buffer.len();
281 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
282
283 let r = info.regs;
284 rx.set_as_af(rx.af_num(), AFType::Input);
285 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
286
287 configure(info, kernel_clock, &config, true, true)?;
288
289 r.cr1().modify(|w| {
290 w.set_rxneie(true);
291 w.set_idleie(true);
292 });
293
294 T::Interrupt::unpend();
295 unsafe { T::Interrupt::enable() };
296 288
297 state.tx_rx_refcount.store(2, Ordering::Relaxed); 289 let mut this = Self {
298
299 Ok(Self {
300 rx: BufferedUartRx { 290 rx: BufferedUartRx {
301 info, 291 info,
302 state, 292 state,
303 kernel_clock, 293 kernel_clock,
304 _phantom: PhantomData, 294 rx,
295 rts,
305 }, 296 },
306 tx: BufferedUartTx { 297 tx: BufferedUartTx {
307 info, 298 info,
308 state, 299 state,
309 kernel_clock, 300 kernel_clock,
310 _phantom: PhantomData, 301 tx,
302 cts,
303 de,
311 }, 304 },
312 }) 305 };
306 this.enable_and_configure(tx_buffer, rx_buffer, &config)?;
307 Ok(this)
308 }
309
310 fn enable_and_configure(
311 &mut self,
312 tx_buffer: &'d mut [u8],
313 rx_buffer: &'d mut [u8],
314 config: &Config,
315 ) -> Result<(), ConfigError> {
316 let info = self.rx.info;
317 let state = self.rx.state;
318 state.tx_rx_refcount.store(2, Ordering::Relaxed);
319
320 info.rcc.enable_and_reset();
321
322 let len = tx_buffer.len();
323 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
324 let len = rx_buffer.len();
325 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
326
327 info.regs.cr3().write(|w| {
328 w.set_rtse(self.rx.rts.is_some());
329 w.set_ctse(self.tx.cts.is_some());
330 #[cfg(not(any(usart_v1, usart_v2)))]
331 w.set_dem(self.tx.de.is_some());
332 });
333 configure(info, self.rx.kernel_clock, &config, true, true)?;
334
335 info.regs.cr1().modify(|w| {
336 w.set_rxneie(true);
337 w.set_idleie(true);
338 });
339
340 info.interrupt.unpend();
341 unsafe { info.interrupt.enable() };
342
343 Ok(())
313 } 344 }
314 345
315 /// Split the driver into a Tx and Rx part (useful for sending to separate tasks) 346 /// Split the driver into a Tx and Rx part (useful for sending to separate tasks)
@@ -516,6 +547,8 @@ impl<'d> Drop for BufferedUartRx<'d> {
516 } 547 }
517 } 548 }
518 549
550 self.rx.as_ref().map(|x| x.set_as_disconnected());
551 self.rts.as_ref().map(|x| x.set_as_disconnected());
519 drop_tx_rx(self.info, state); 552 drop_tx_rx(self.info, state);
520 } 553 }
521} 554}
@@ -533,6 +566,9 @@ impl<'d> Drop for BufferedUartTx<'d> {
533 } 566 }
534 } 567 }
535 568
569 self.tx.as_ref().map(|x| x.set_as_disconnected());
570 self.cts.as_ref().map(|x| x.set_as_disconnected());
571 self.de.as_ref().map(|x| x.set_as_disconnected());
536 drop_tx_rx(self.info, state); 572 drop_tx_rx(self.info, state);
537 } 573 }
538} 574}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index 2a39c6301..53321391a 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -14,7 +14,7 @@ use embassy_sync::waitqueue::AtomicWaker;
14use futures_util::future::{select, Either}; 14use futures_util::future::{select, Either};
15 15
16use crate::dma::ChannelAndRequest; 16use crate::dma::ChannelAndRequest;
17use crate::gpio::{AFType, AnyPin, SealedPin}; 17use crate::gpio::{AFType, AnyPin, SealedPin as _};
18use crate::interrupt::typelevel::Interrupt as _; 18use crate::interrupt::typelevel::Interrupt as _;
19use crate::interrupt::{self, Interrupt, InterruptExt}; 19use crate::interrupt::{self, Interrupt, InterruptExt};
20use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
@@ -28,7 +28,7 @@ use crate::pac::usart::Lpuart as Regs;
28#[cfg(any(usart_v1, usart_v2))] 28#[cfg(any(usart_v1, usart_v2))]
29use crate::pac::usart::Usart as Regs; 29use crate::pac::usart::Usart as Regs;
30use crate::pac::usart::{regs, vals}; 30use crate::pac::usart::{regs, vals};
31use crate::rcc::{self, RccInfo, SealedRccPeripheral}; 31use crate::rcc::{RccInfo, SealedRccPeripheral};
32use crate::time::Hertz; 32use crate::time::Hertz;
33use crate::Peripheral; 33use crate::Peripheral;
34 34
@@ -429,29 +429,33 @@ impl<'d, M: Mode> UartTx<'d, M> {
429 tx_dma: Option<ChannelAndRequest<'d>>, 429 tx_dma: Option<ChannelAndRequest<'d>>,
430 config: Config, 430 config: Config,
431 ) -> Result<Self, ConfigError> { 431 ) -> Result<Self, ConfigError> {
432 rcc::enable_and_reset::<T>(); 432 let mut this = Self {
433 433 info: T::info(),
434 let info = T::info(); 434 state: T::state(),
435 let state = T::state(); 435 kernel_clock: T::frequency(),
436 let kernel_clock = T::frequency();
437 let r = info.regs;
438 r.cr3().modify(|w| {
439 w.set_ctse(cts.is_some());
440 });
441 configure(info, kernel_clock, &config, false, true)?;
442
443 state.tx_rx_refcount.store(1, Ordering::Relaxed);
444
445 Ok(Self {
446 info,
447 state,
448 kernel_clock,
449 tx, 436 tx,
450 cts, 437 cts,
451 de: None, 438 de: None,
452 tx_dma, 439 tx_dma,
453 _phantom: PhantomData, 440 _phantom: PhantomData,
454 }) 441 };
442 this.enable_and_configure(&config)?;
443 Ok(this)
444 }
445
446 fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
447 let info = self.info;
448 let state = self.state;
449 state.tx_rx_refcount.store(1, Ordering::Relaxed);
450
451 info.rcc.enable_and_reset();
452
453 info.regs.cr3().modify(|w| {
454 w.set_ctse(self.cts.is_some());
455 });
456 configure(info, self.kernel_clock, config, false, true)?;
457
458 Ok(())
455 } 459 }
456 460
457 /// Reconfigure the driver 461 /// Reconfigure the driver
@@ -775,34 +779,38 @@ impl<'d, M: Mode> UartRx<'d, M> {
775 rx_dma: Option<ChannelAndRequest<'d>>, 779 rx_dma: Option<ChannelAndRequest<'d>>,
776 config: Config, 780 config: Config,
777 ) -> Result<Self, ConfigError> { 781 ) -> Result<Self, ConfigError> {
778 rcc::enable_and_reset::<T>(); 782 let mut this = Self {
779
780 let info = T::info();
781 let state = T::state();
782 let kernel_clock = T::frequency();
783 let r = info.regs;
784 r.cr3().write(|w| {
785 w.set_rtse(rts.is_some());
786 });
787 configure(info, kernel_clock, &config, true, false)?;
788
789 T::Interrupt::unpend();
790 unsafe { T::Interrupt::enable() };
791
792 state.tx_rx_refcount.store(1, Ordering::Relaxed);
793
794 Ok(Self {
795 _phantom: PhantomData, 783 _phantom: PhantomData,
796 info, 784 info: T::info(),
797 state, 785 state: T::state(),
798 kernel_clock, 786 kernel_clock: T::frequency(),
799 rx, 787 rx,
800 rts, 788 rts,
801 rx_dma, 789 rx_dma,
802 detect_previous_overrun: config.detect_previous_overrun, 790 detect_previous_overrun: config.detect_previous_overrun,
803 #[cfg(any(usart_v1, usart_v2))] 791 #[cfg(any(usart_v1, usart_v2))]
804 buffered_sr: stm32_metapac::usart::regs::Sr(0), 792 buffered_sr: stm32_metapac::usart::regs::Sr(0),
805 }) 793 };
794 this.enable_and_configure(&config)?;
795 Ok(this)
796 }
797
798 fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
799 let info = self.info;
800 let state = self.state;
801 state.tx_rx_refcount.store(1, Ordering::Relaxed);
802
803 info.rcc.enable_and_reset();
804
805 info.regs.cr3().write(|w| {
806 w.set_rtse(self.rts.is_some());
807 });
808 configure(info, self.kernel_clock, &config, true, false)?;
809
810 info.interrupt.unpend();
811 unsafe { info.interrupt.enable() };
812
813 Ok(())
806 } 814 }
807 815
808 /// Reconfigure the driver 816 /// Reconfigure the driver
@@ -1228,27 +1236,11 @@ impl<'d, M: Mode> Uart<'d, M> {
1228 rx_dma: Option<ChannelAndRequest<'d>>, 1236 rx_dma: Option<ChannelAndRequest<'d>>,
1229 config: Config, 1237 config: Config,
1230 ) -> Result<Self, ConfigError> { 1238 ) -> Result<Self, ConfigError> {
1231 rcc::enable_and_reset::<T>();
1232
1233 let info = T::info(); 1239 let info = T::info();
1234 let state = T::state(); 1240 let state = T::state();
1235 let kernel_clock = T::frequency(); 1241 let kernel_clock = T::frequency();
1236 let r = info.regs;
1237
1238 r.cr3().write(|w| {
1239 w.set_rtse(rts.is_some());
1240 w.set_ctse(cts.is_some());
1241 #[cfg(not(any(usart_v1, usart_v2)))]
1242 w.set_dem(de.is_some());
1243 });
1244 configure(info, kernel_clock, &config, true, true)?;
1245
1246 T::Interrupt::unpend();
1247 unsafe { T::Interrupt::enable() };
1248 1242
1249 state.tx_rx_refcount.store(2, Ordering::Relaxed); 1243 let mut this = Self {
1250
1251 Ok(Self {
1252 tx: UartTx { 1244 tx: UartTx {
1253 _phantom: PhantomData, 1245 _phantom: PhantomData,
1254 info, 1246 info,
@@ -1271,7 +1263,30 @@ impl<'d, M: Mode> Uart<'d, M> {
1271 #[cfg(any(usart_v1, usart_v2))] 1263 #[cfg(any(usart_v1, usart_v2))]
1272 buffered_sr: stm32_metapac::usart::regs::Sr(0), 1264 buffered_sr: stm32_metapac::usart::regs::Sr(0),
1273 }, 1265 },
1274 }) 1266 };
1267 this.enable_and_configure(&config)?;
1268 Ok(this)
1269 }
1270
1271 fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> {
1272 let info = self.rx.info;
1273 let state = self.rx.state;
1274 state.tx_rx_refcount.store(2, Ordering::Relaxed);
1275
1276 info.rcc.enable_and_reset();
1277
1278 info.regs.cr3().write(|w| {
1279 w.set_rtse(self.rx.rts.is_some());
1280 w.set_ctse(self.tx.cts.is_some());
1281 #[cfg(not(any(usart_v1, usart_v2)))]
1282 w.set_dem(self.tx.de.is_some());
1283 });
1284 configure(info, self.rx.kernel_clock, config, true, true)?;
1285
1286 info.interrupt.unpend();
1287 unsafe { info.interrupt.enable() };
1288
1289 Ok(())
1275 } 1290 }
1276 1291
1277 /// Perform a blocking write 1292 /// Perform a blocking write
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index f3a88b93f..8cf75933a 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -4,10 +4,12 @@ use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
7use embassy_hal_internal::PeripheralRef;
7use futures_util::future::{select, Either}; 8use futures_util::future::{select, Either};
8 9
9use super::{clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx}; 10use super::{clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx};
10use crate::dma::ReadableRingBuffer; 11use crate::dma::ReadableRingBuffer;
12use crate::gpio::{AnyPin, SealedPin as _};
11use crate::mode::Async; 13use crate::mode::Async;
12use crate::time::Hertz; 14use crate::time::Hertz;
13use crate::usart::{Regs, Sr}; 15use crate::usart::{Regs, Sr};
@@ -19,6 +21,8 @@ pub struct RingBufferedUartRx<'d> {
19 info: &'static Info, 21 info: &'static Info,
20 state: &'static State, 22 state: &'static State,
21 kernel_clock: Hertz, 23 kernel_clock: Hertz,
24 rx: Option<PeripheralRef<'d, AnyPin>>,
25 rts: Option<PeripheralRef<'d, AnyPin>>,
22 ring_buf: ReadableRingBuffer<'d, u8>, 26 ring_buf: ReadableRingBuffer<'d, u8>,
23} 27}
24 28
@@ -49,6 +53,8 @@ impl<'d> UartRx<'d, Async> {
49 let state = self.state; 53 let state = self.state;
50 let kernel_clock = self.kernel_clock; 54 let kernel_clock = self.kernel_clock;
51 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) }; 55 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) };
56 let rx = unsafe { self.rx.as_ref().map(|x| x.clone_unchecked()) };
57 let rts = unsafe { self.rts.as_ref().map(|x| x.clone_unchecked()) };
52 58
53 // Don't disable the clock 59 // Don't disable the clock
54 mem::forget(self); 60 mem::forget(self);
@@ -57,6 +63,8 @@ impl<'d> UartRx<'d, Async> {
57 info, 63 info,
58 state, 64 state,
59 kernel_clock, 65 kernel_clock,
66 rx,
67 rts,
60 ring_buf, 68 ring_buf,
61 } 69 }
62 } 70 }
@@ -221,6 +229,8 @@ impl<'d> RingBufferedUartRx<'d> {
221impl Drop for RingBufferedUartRx<'_> { 229impl Drop for RingBufferedUartRx<'_> {
222 fn drop(&mut self) { 230 fn drop(&mut self) {
223 self.teardown_uart(); 231 self.teardown_uart();
232 self.rx.as_ref().map(|x| x.set_as_disconnected());
233 self.rts.as_ref().map(|x| x.set_as_disconnected());
224 super::drop_tx_rx(self.info, self.state); 234 super::drop_tx_rx(self.info, self.state);
225 } 235 }
226} 236}