aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs6
-rw-r--r--embassy-stm32/src/usart/buffered.rs372
-rw-r--r--embassy-stm32/src/usart/mod.rs450
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs57
-rw-r--r--examples/stm32h5/src/bin/usart_split.rs3
-rw-r--r--examples/stm32h7/src/bin/usart_split.rs3
-rw-r--r--examples/stm32h7rs/src/bin/usart_split.rs3
-rw-r--r--tests/stm32/src/bin/usart_rx_ringbuffered.rs4
8 files changed, 467 insertions, 431 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 4eed6fe7d..7bf6ffba2 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -387,7 +387,6 @@ fn main() {
387 struct ClockGen<'a> { 387 struct ClockGen<'a> {
388 rcc_registers: &'a PeripheralRegisters, 388 rcc_registers: &'a PeripheralRegisters,
389 chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>, 389 chained_muxes: HashMap<&'a str, &'a PeripheralRccRegister>,
390 force_refcount: HashSet<&'a str>,
391 390
392 refcount_statics: BTreeSet<Ident>, 391 refcount_statics: BTreeSet<Ident>,
393 clock_names: BTreeSet<String>, 392 clock_names: BTreeSet<String>,
@@ -397,7 +396,6 @@ fn main() {
397 let mut clock_gen = ClockGen { 396 let mut clock_gen = ClockGen {
398 rcc_registers, 397 rcc_registers,
399 chained_muxes: HashMap::new(), 398 chained_muxes: HashMap::new(),
400 force_refcount: HashSet::from(["usart"]),
401 399
402 refcount_statics: BTreeSet::new(), 400 refcount_statics: BTreeSet::new(),
403 clock_names: BTreeSet::new(), 401 clock_names: BTreeSet::new(),
@@ -542,7 +540,6 @@ fn main() {
542 None => (TokenStream::new(), TokenStream::new()), 540 None => (TokenStream::new(), TokenStream::new()),
543 }; 541 };
544 542
545 let ptype = if let Some(reg) = &p.registers { reg.kind } else { "" };
546 let pname = format_ident!("{}", p.name); 543 let pname = format_ident!("{}", p.name);
547 let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); 544 let en_reg = format_ident!("{}", en.register.to_ascii_lowercase());
548 let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase()); 545 let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
@@ -570,8 +567,7 @@ fn main() {
570 }; 567 };
571 let en_bit_offs: u8 = en_bit_offs.offset.try_into().unwrap(); 568 let en_bit_offs: u8 = en_bit_offs.offset.try_into().unwrap();
572 569
573 let refcount = 570 let refcount = *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1;
574 clock_gen.force_refcount.contains(ptype) || *rcc_field_count.get(&(en.register, en.field)).unwrap() > 1;
575 let (before_enable, before_disable) = if refcount { 571 let (before_enable, before_disable) = if refcount {
576 let refcount_static = 572 let refcount_static =
577 format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase()); 573 format_ident!("{}_{}", en.register.to_ascii_uppercase(), en.field.to_ascii_uppercase());
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index 52011cd1f..492ad334b 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -1,7 +1,7 @@
1use core::future::poll_fn; 1use core::future::poll_fn;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::slice; 3use core::slice;
4use core::sync::atomic::{AtomicBool, Ordering}; 4use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5use core::task::Poll; 5use core::task::Poll;
6 6
7use embassy_embedded_hal::SetConfig; 7use embassy_embedded_hal::SetConfig;
@@ -12,154 +12,163 @@ use embassy_sync::waitqueue::AtomicWaker;
12#[cfg(not(any(usart_v1, usart_v2)))] 12#[cfg(not(any(usart_v1, usart_v2)))]
13use super::DePin; 13use super::DePin;
14use super::{ 14use super::{
15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, BasicInstance, Config, ConfigError, CtsPin, Error, 15 clear_interrupt_flags, configure, rdr, reconfigure, sr, tdr, Config, ConfigError, CtsPin, Error, Info, Instance,
16 RtsPin, RxPin, TxPin, 16 Regs, RtsPin, RxPin, TxPin,
17}; 17};
18use crate::gpio::AFType; 18use crate::gpio::AFType;
19use crate::interrupt; 19use crate::interrupt::typelevel::Interrupt as _;
20use crate::interrupt::typelevel::Interrupt; 20use crate::interrupt::{self, InterruptExt};
21use crate::time::Hertz;
21 22
22/// Interrupt handler. 23/// Interrupt handler.
23pub struct InterruptHandler<T: BasicInstance> { 24pub struct InterruptHandler<T: Instance> {
24 _phantom: PhantomData<T>, 25 _phantom: PhantomData<T>,
25} 26}
26 27
27impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { 28impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
28 unsafe fn on_interrupt() { 29 unsafe fn on_interrupt() {
29 let r = T::regs(); 30 on_interrupt(T::info().regs, T::buffered_state())
30 let state = T::buffered_state(); 31 }
31 32}
32 // RX 33
33 let sr_val = sr(r).read(); 34unsafe fn on_interrupt(r: Regs, state: &'static State) {
34 // On v1 & v2, reading DR clears the rxne, error and idle interrupt 35 // RX
35 // flags. Keep this close to the SR read to reduce the chance of a 36 let sr_val = sr(r).read();
36 // flag being set in-between. 37 // On v1 & v2, reading DR clears the rxne, error and idle interrupt
37 let dr = if sr_val.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr_val.ore() || sr_val.idle()) { 38 // flags. Keep this close to the SR read to reduce the chance of a
38 Some(rdr(r).read_volatile()) 39 // flag being set in-between.
39 } else { 40 let dr = if sr_val.rxne() || cfg!(any(usart_v1, usart_v2)) && (sr_val.ore() || sr_val.idle()) {
40 None 41 Some(rdr(r).read_volatile())
41 }; 42 } else {
42 clear_interrupt_flags(r, sr_val); 43 None
43 44 };
44 if sr_val.pe() { 45 clear_interrupt_flags(r, sr_val);
45 warn!("Parity error"); 46
46 } 47 if sr_val.pe() {
47 if sr_val.fe() { 48 warn!("Parity error");
48 warn!("Framing error"); 49 }
49 } 50 if sr_val.fe() {
50 if sr_val.ne() { 51 warn!("Framing error");
51 warn!("Noise error"); 52 }
52 } 53 if sr_val.ne() {
53 if sr_val.ore() { 54 warn!("Noise error");
54 warn!("Overrun error"); 55 }
55 } 56 if sr_val.ore() {
56 if sr_val.rxne() { 57 warn!("Overrun error");
57 let mut rx_writer = state.rx_buf.writer(); 58 }
58 let buf = rx_writer.push_slice(); 59 if sr_val.rxne() {
59 if !buf.is_empty() { 60 let mut rx_writer = state.rx_buf.writer();
60 if let Some(byte) = dr { 61 let buf = rx_writer.push_slice();
61 buf[0] = byte; 62 if !buf.is_empty() {
62 rx_writer.push_done(1); 63 if let Some(byte) = dr {
63 } 64 buf[0] = byte;
64 } else { 65 rx_writer.push_done(1);
65 // FIXME: Should we disable any further RX interrupts when the buffer becomes full.
66 }
67
68 if !state.rx_buf.is_empty() {
69 state.rx_waker.wake();
70 } 66 }
67 } else {
68 // FIXME: Should we disable any further RX interrupts when the buffer becomes full.
71 } 69 }
72 70
73 if sr_val.idle() { 71 if !state.rx_buf.is_empty() {
74 state.rx_waker.wake(); 72 state.rx_waker.wake();
75 } 73 }
74 }
76 75
77 // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC) 76 if sr_val.idle() {
78 // indicates that all bytes are pushed out from the FIFO. 77 state.rx_waker.wake();
79 // For other usart variants it shows that last byte from the buffer was just sent. 78 }
80 if sr_val.tc() {
81 // For others it is cleared above with `clear_interrupt_flags`.
82 #[cfg(any(usart_v1, usart_v2))]
83 sr(r).modify(|w| w.set_tc(false));
84 79
85 r.cr1().modify(|w| { 80 // With `usart_v4` hardware FIFO is enabled and Transmission complete (TC)
86 w.set_tcie(false); 81 // indicates that all bytes are pushed out from the FIFO.
87 }); 82 // For other usart variants it shows that last byte from the buffer was just sent.
83 if sr_val.tc() {
84 // For others it is cleared above with `clear_interrupt_flags`.
85 #[cfg(any(usart_v1, usart_v2))]
86 sr(r).modify(|w| w.set_tc(false));
88 87
89 state.tx_done.store(true, Ordering::Release); 88 r.cr1().modify(|w| {
90 state.tx_waker.wake(); 89 w.set_tcie(false);
91 } 90 });
92 91
93 // TX 92 state.tx_done.store(true, Ordering::Release);
94 if sr(r).read().txe() { 93 state.tx_waker.wake();
95 let mut tx_reader = state.tx_buf.reader(); 94 }
96 let buf = tx_reader.pop_slice();
97 if !buf.is_empty() {
98 r.cr1().modify(|w| {
99 w.set_txeie(true);
100 });
101 95
102 // Enable transmission complete interrupt when last byte is going to be sent out. 96 // TX
103 if buf.len() == 1 { 97 if sr(r).read().txe() {
104 r.cr1().modify(|w| { 98 let mut tx_reader = state.tx_buf.reader();
105 w.set_tcie(true); 99 let buf = tx_reader.pop_slice();
106 }); 100 if !buf.is_empty() {
107 } 101 r.cr1().modify(|w| {
102 w.set_txeie(true);
103 });
108 104
109 tdr(r).write_volatile(buf[0].into()); 105 // Enable transmission complete interrupt when last byte is going to be sent out.
110 tx_reader.pop_done(1); 106 if buf.len() == 1 {
111 } else {
112 // Disable interrupt until we have something to transmit again.
113 r.cr1().modify(|w| { 107 r.cr1().modify(|w| {
114 w.set_txeie(false); 108 w.set_tcie(true);
115 }); 109 });
116 } 110 }
111
112 tdr(r).write_volatile(buf[0].into());
113 tx_reader.pop_done(1);
114 } else {
115 // Disable interrupt until we have something to transmit again.
116 r.cr1().modify(|w| {
117 w.set_txeie(false);
118 });
117 } 119 }
118 } 120 }
119} 121}
120 122
121pub(crate) struct State { 123pub(super) struct State {
122 pub(crate) rx_waker: AtomicWaker, 124 rx_waker: AtomicWaker,
123 pub(crate) rx_buf: RingBuffer, 125 rx_buf: RingBuffer,
124 pub(crate) tx_waker: AtomicWaker, 126 tx_waker: AtomicWaker,
125 pub(crate) tx_buf: RingBuffer, 127 tx_buf: RingBuffer,
126 pub(crate) tx_done: AtomicBool, 128 tx_done: AtomicBool,
129 tx_rx_refcount: AtomicU8,
127} 130}
128 131
129impl State { 132impl State {
130 /// Create new state 133 pub(super) const fn new() -> Self {
131 pub(crate) const fn new() -> Self {
132 Self { 134 Self {
133 rx_buf: RingBuffer::new(), 135 rx_buf: RingBuffer::new(),
134 tx_buf: RingBuffer::new(), 136 tx_buf: RingBuffer::new(),
135 rx_waker: AtomicWaker::new(), 137 rx_waker: AtomicWaker::new(),
136 tx_waker: AtomicWaker::new(), 138 tx_waker: AtomicWaker::new(),
137 tx_done: AtomicBool::new(true), 139 tx_done: AtomicBool::new(true),
140 tx_rx_refcount: AtomicU8::new(0),
138 } 141 }
139 } 142 }
140} 143}
141 144
142/// Bidirectional buffered UART 145/// Bidirectional buffered UART
143pub struct BufferedUart<'d, T: BasicInstance> { 146pub struct BufferedUart<'d> {
144 rx: BufferedUartRx<'d, T>, 147 rx: BufferedUartRx<'d>,
145 tx: BufferedUartTx<'d, T>, 148 tx: BufferedUartTx<'d>,
146} 149}
147 150
148/// Tx-only buffered UART 151/// Tx-only buffered UART
149/// 152///
150/// Created with [BufferedUart::split] 153/// Created with [BufferedUart::split]
151pub struct BufferedUartTx<'d, T: BasicInstance> { 154pub struct BufferedUartTx<'d> {
152 phantom: PhantomData<&'d mut T>, 155 info: &'static Info,
156 state: &'static State,
157 kernel_clock: Hertz,
158 _phantom: PhantomData<&'d mut ()>,
153} 159}
154 160
155/// Rx-only buffered UART 161/// Rx-only buffered UART
156/// 162///
157/// Created with [BufferedUart::split] 163/// Created with [BufferedUart::split]
158pub struct BufferedUartRx<'d, T: BasicInstance> { 164pub struct BufferedUartRx<'d> {
159 phantom: PhantomData<&'d mut T>, 165 info: &'static Info,
166 state: &'static State,
167 kernel_clock: Hertz,
168 _phantom: PhantomData<&'d mut ()>,
160} 169}
161 170
162impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> { 171impl<'d> SetConfig for BufferedUart<'d> {
163 type Config = Config; 172 type Config = Config;
164 type ConfigError = ConfigError; 173 type ConfigError = ConfigError;
165 174
@@ -168,7 +177,7 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUart<'d, T> {
168 } 177 }
169} 178}
170 179
171impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> { 180impl<'d> SetConfig for BufferedUartRx<'d> {
172 type Config = Config; 181 type Config = Config;
173 type ConfigError = ConfigError; 182 type ConfigError = ConfigError;
174 183
@@ -177,7 +186,7 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUartRx<'d, T> {
177 } 186 }
178} 187}
179 188
180impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> { 189impl<'d> SetConfig for BufferedUartTx<'d> {
181 type Config = Config; 190 type Config = Config;
182 type ConfigError = ConfigError; 191 type ConfigError = ConfigError;
183 192
@@ -186,9 +195,9 @@ impl<'d, T: BasicInstance> SetConfig for BufferedUartTx<'d, T> {
186 } 195 }
187} 196}
188 197
189impl<'d, T: BasicInstance> BufferedUart<'d, T> { 198impl<'d> BufferedUart<'d> {
190 /// Create a new bidirectional buffered UART driver 199 /// Create a new bidirectional buffered UART driver
191 pub fn new( 200 pub fn new<T: Instance>(
192 peri: impl Peripheral<P = T> + 'd, 201 peri: impl Peripheral<P = T> + 'd,
193 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 202 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
194 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 203 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -197,15 +206,13 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
197 rx_buffer: &'d mut [u8], 206 rx_buffer: &'d mut [u8],
198 config: Config, 207 config: Config,
199 ) -> Result<Self, ConfigError> { 208 ) -> Result<Self, ConfigError> {
200 // UartRx and UartTx have one refcount ea.
201 T::enable_and_reset();
202 T::enable_and_reset(); 209 T::enable_and_reset();
203 210
204 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) 211 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
205 } 212 }
206 213
207 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins 214 /// Create a new bidirectional buffered UART driver with request-to-send and clear-to-send pins
208 pub fn new_with_rtscts( 215 pub fn new_with_rtscts<T: Instance>(
209 peri: impl Peripheral<P = T> + 'd, 216 peri: impl Peripheral<P = T> + 'd,
210 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 217 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
211 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 218 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -218,13 +225,11 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
218 ) -> Result<Self, ConfigError> { 225 ) -> Result<Self, ConfigError> {
219 into_ref!(cts, rts); 226 into_ref!(cts, rts);
220 227
221 // UartRx and UartTx have one refcount ea.
222 T::enable_and_reset();
223 T::enable_and_reset(); 228 T::enable_and_reset();
224 229
225 rts.set_as_af(rts.af_num(), AFType::OutputPushPull); 230 rts.set_as_af(rts.af_num(), AFType::OutputPushPull);
226 cts.set_as_af(cts.af_num(), AFType::Input); 231 cts.set_as_af(cts.af_num(), AFType::Input);
227 T::regs().cr3().write(|w| { 232 T::info().regs.cr3().write(|w| {
228 w.set_rtse(true); 233 w.set_rtse(true);
229 w.set_ctse(true); 234 w.set_ctse(true);
230 }); 235 });
@@ -234,7 +239,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
234 239
235 /// Create a new bidirectional buffered UART driver with a driver-enable pin 240 /// Create a new bidirectional buffered UART driver with a driver-enable pin
236 #[cfg(not(any(usart_v1, usart_v2)))] 241 #[cfg(not(any(usart_v1, usart_v2)))]
237 pub fn new_with_de( 242 pub fn new_with_de<T: Instance>(
238 peri: impl Peripheral<P = T> + 'd, 243 peri: impl Peripheral<P = T> + 'd,
239 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 244 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
240 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 245 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -246,19 +251,17 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
246 ) -> Result<Self, ConfigError> { 251 ) -> Result<Self, ConfigError> {
247 into_ref!(de); 252 into_ref!(de);
248 253
249 // UartRx and UartTx have one refcount ea.
250 T::enable_and_reset();
251 T::enable_and_reset(); 254 T::enable_and_reset();
252 255
253 de.set_as_af(de.af_num(), AFType::OutputPushPull); 256 de.set_as_af(de.af_num(), AFType::OutputPushPull);
254 T::regs().cr3().write(|w| { 257 T::info().regs.cr3().write(|w| {
255 w.set_dem(true); 258 w.set_dem(true);
256 }); 259 });
257 260
258 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config) 261 Self::new_inner(peri, rx, tx, tx_buffer, rx_buffer, config)
259 } 262 }
260 263
261 fn new_inner( 264 fn new_inner<T: Instance>(
262 _peri: impl Peripheral<P = T> + 'd, 265 _peri: impl Peripheral<P = T> + 'd,
263 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 266 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
264 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 267 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -268,17 +271,19 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
268 ) -> Result<Self, ConfigError> { 271 ) -> Result<Self, ConfigError> {
269 into_ref!(_peri, rx, tx); 272 into_ref!(_peri, rx, tx);
270 273
274 let info = T::info();
271 let state = T::buffered_state(); 275 let state = T::buffered_state();
276 let kernel_clock = T::frequency();
272 let len = tx_buffer.len(); 277 let len = tx_buffer.len();
273 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; 278 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
274 let len = rx_buffer.len(); 279 let len = rx_buffer.len();
275 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; 280 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
276 281
277 let r = T::regs(); 282 let r = info.regs;
278 rx.set_as_af(rx.af_num(), AFType::Input); 283 rx.set_as_af(rx.af_num(), AFType::Input);
279 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 284 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
280 285
281 configure(r, &config, T::frequency(), T::KIND, true, true)?; 286 configure(info, kernel_clock, &config, true, true)?;
282 287
283 r.cr1().modify(|w| { 288 r.cr1().modify(|w| {
284 w.set_rxneie(true); 289 w.set_rxneie(true);
@@ -288,22 +293,34 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
288 T::Interrupt::unpend(); 293 T::Interrupt::unpend();
289 unsafe { T::Interrupt::enable() }; 294 unsafe { T::Interrupt::enable() };
290 295
296 state.tx_rx_refcount.store(2, Ordering::Relaxed);
297
291 Ok(Self { 298 Ok(Self {
292 rx: BufferedUartRx { phantom: PhantomData }, 299 rx: BufferedUartRx {
293 tx: BufferedUartTx { phantom: PhantomData }, 300 info,
301 state,
302 kernel_clock,
303 _phantom: PhantomData,
304 },
305 tx: BufferedUartTx {
306 info,
307 state,
308 kernel_clock,
309 _phantom: PhantomData,
310 },
294 }) 311 })
295 } 312 }
296 313
297 /// Split the driver into a Tx and Rx part (useful for sending to separate tasks) 314 /// Split the driver into a Tx and Rx part (useful for sending to separate tasks)
298 pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) { 315 pub fn split(self) -> (BufferedUartTx<'d>, BufferedUartRx<'d>) {
299 (self.tx, self.rx) 316 (self.tx, self.rx)
300 } 317 }
301 318
302 /// Reconfigure the driver 319 /// Reconfigure the driver
303 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 320 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
304 reconfigure::<T>(config)?; 321 reconfigure(self.rx.info, self.rx.kernel_clock, config)?;
305 322
306 T::regs().cr1().modify(|w| { 323 self.rx.info.regs.cr1().modify(|w| {
307 w.set_rxneie(true); 324 w.set_rxneie(true);
308 w.set_idleie(true); 325 w.set_idleie(true);
309 }); 326 });
@@ -312,10 +329,10 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
312 } 329 }
313} 330}
314 331
315impl<'d, T: BasicInstance> BufferedUartRx<'d, T> { 332impl<'d> BufferedUartRx<'d> {
316 async fn read(&self, buf: &mut [u8]) -> Result<usize, Error> { 333 async fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
317 poll_fn(move |cx| { 334 poll_fn(move |cx| {
318 let state = T::buffered_state(); 335 let state = self.state;
319 let mut rx_reader = unsafe { state.rx_buf.reader() }; 336 let mut rx_reader = unsafe { state.rx_buf.reader() };
320 let data = rx_reader.pop_slice(); 337 let data = rx_reader.pop_slice();
321 338
@@ -327,7 +344,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
327 rx_reader.pop_done(len); 344 rx_reader.pop_done(len);
328 345
329 if do_pend { 346 if do_pend {
330 T::Interrupt::pend(); 347 self.info.interrupt.pend();
331 } 348 }
332 349
333 return Poll::Ready(Ok(len)); 350 return Poll::Ready(Ok(len));
@@ -341,7 +358,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
341 358
342 fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> { 359 fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> {
343 loop { 360 loop {
344 let state = T::buffered_state(); 361 let state = self.state;
345 let mut rx_reader = unsafe { state.rx_buf.reader() }; 362 let mut rx_reader = unsafe { state.rx_buf.reader() };
346 let data = rx_reader.pop_slice(); 363 let data = rx_reader.pop_slice();
347 364
@@ -353,7 +370,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
353 rx_reader.pop_done(len); 370 rx_reader.pop_done(len);
354 371
355 if do_pend { 372 if do_pend {
356 T::Interrupt::pend(); 373 self.info.interrupt.pend();
357 } 374 }
358 375
359 return Ok(len); 376 return Ok(len);
@@ -363,7 +380,7 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
363 380
364 async fn fill_buf(&self) -> Result<&[u8], Error> { 381 async fn fill_buf(&self) -> Result<&[u8], Error> {
365 poll_fn(move |cx| { 382 poll_fn(move |cx| {
366 let state = T::buffered_state(); 383 let state = self.state;
367 let mut rx_reader = unsafe { state.rx_buf.reader() }; 384 let mut rx_reader = unsafe { state.rx_buf.reader() };
368 let (p, n) = rx_reader.pop_buf(); 385 let (p, n) = rx_reader.pop_buf();
369 if n == 0 { 386 if n == 0 {
@@ -378,20 +395,20 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
378 } 395 }
379 396
380 fn consume(&self, amt: usize) { 397 fn consume(&self, amt: usize) {
381 let state = T::buffered_state(); 398 let state = self.state;
382 let mut rx_reader = unsafe { state.rx_buf.reader() }; 399 let mut rx_reader = unsafe { state.rx_buf.reader() };
383 let full = state.rx_buf.is_full(); 400 let full = state.rx_buf.is_full();
384 rx_reader.pop_done(amt); 401 rx_reader.pop_done(amt);
385 if full { 402 if full {
386 T::Interrupt::pend(); 403 self.info.interrupt.pend();
387 } 404 }
388 } 405 }
389 406
390 /// Reconfigure the driver 407 /// Reconfigure the driver
391 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 408 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
392 reconfigure::<T>(config)?; 409 reconfigure(self.info, self.kernel_clock, config)?;
393 410
394 T::regs().cr1().modify(|w| { 411 self.info.regs.cr1().modify(|w| {
395 w.set_rxneie(true); 412 w.set_rxneie(true);
396 w.set_idleie(true); 413 w.set_idleie(true);
397 }); 414 });
@@ -400,10 +417,10 @@ impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
400 } 417 }
401} 418}
402 419
403impl<'d, T: BasicInstance> BufferedUartTx<'d, T> { 420impl<'d> BufferedUartTx<'d> {
404 async fn write(&self, buf: &[u8]) -> Result<usize, Error> { 421 async fn write(&self, buf: &[u8]) -> Result<usize, Error> {
405 poll_fn(move |cx| { 422 poll_fn(move |cx| {
406 let state = T::buffered_state(); 423 let state = self.state;
407 state.tx_done.store(false, Ordering::Release); 424 state.tx_done.store(false, Ordering::Release);
408 425
409 let empty = state.tx_buf.is_empty(); 426 let empty = state.tx_buf.is_empty();
@@ -420,7 +437,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
420 tx_writer.push_done(n); 437 tx_writer.push_done(n);
421 438
422 if empty { 439 if empty {
423 T::Interrupt::pend(); 440 self.info.interrupt.pend();
424 } 441 }
425 442
426 Poll::Ready(Ok(n)) 443 Poll::Ready(Ok(n))
@@ -430,7 +447,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
430 447
431 async fn flush(&self) -> Result<(), Error> { 448 async fn flush(&self) -> Result<(), Error> {
432 poll_fn(move |cx| { 449 poll_fn(move |cx| {
433 let state = T::buffered_state(); 450 let state = self.state;
434 451
435 if !state.tx_done.load(Ordering::Acquire) { 452 if !state.tx_done.load(Ordering::Acquire) {
436 state.tx_waker.register(cx.waker()); 453 state.tx_waker.register(cx.waker());
@@ -444,7 +461,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
444 461
445 fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> { 462 fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> {
446 loop { 463 loop {
447 let state = T::buffered_state(); 464 let state = self.state;
448 let empty = state.tx_buf.is_empty(); 465 let empty = state.tx_buf.is_empty();
449 466
450 let mut tx_writer = unsafe { state.tx_buf.writer() }; 467 let mut tx_writer = unsafe { state.tx_buf.writer() };
@@ -455,7 +472,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
455 tx_writer.push_done(n); 472 tx_writer.push_done(n);
456 473
457 if empty { 474 if empty {
458 T::Interrupt::pend(); 475 self.info.interrupt.pend();
459 } 476 }
460 477
461 return Ok(n); 478 return Ok(n);
@@ -465,7 +482,7 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
465 482
466 fn blocking_flush(&self) -> Result<(), Error> { 483 fn blocking_flush(&self) -> Result<(), Error> {
467 loop { 484 loop {
468 let state = T::buffered_state(); 485 let state = self.state;
469 if state.tx_buf.is_empty() { 486 if state.tx_buf.is_empty() {
470 return Ok(()); 487 return Ok(());
471 } 488 }
@@ -474,9 +491,9 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
474 491
475 /// Reconfigure the driver 492 /// Reconfigure the driver
476 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 493 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
477 reconfigure::<T>(config)?; 494 reconfigure(self.info, self.kernel_clock, config)?;
478 495
479 T::regs().cr1().modify(|w| { 496 self.info.regs.cr1().modify(|w| {
480 w.set_rxneie(true); 497 w.set_rxneie(true);
481 w.set_idleie(true); 498 w.set_idleie(true);
482 }); 499 });
@@ -485,65 +502,78 @@ impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
485 } 502 }
486} 503}
487 504
488impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { 505impl<'d> Drop for BufferedUartRx<'d> {
489 fn drop(&mut self) { 506 fn drop(&mut self) {
490 let state = T::buffered_state(); 507 let state = self.state;
491 unsafe { 508 unsafe {
492 state.rx_buf.deinit(); 509 state.rx_buf.deinit();
493 510
494 // TX is inactive if the the buffer is not available. 511 // TX is inactive if the the buffer is not available.
495 // We can now unregister the interrupt handler 512 // We can now unregister the interrupt handler
496 if state.tx_buf.len() == 0 { 513 if state.tx_buf.len() == 0 {
497 T::Interrupt::disable(); 514 self.info.interrupt.disable();
498 } 515 }
499 } 516 }
500 517
501 T::disable(); 518 drop_tx_rx(self.info, state);
502 } 519 }
503} 520}
504 521
505impl<'d, T: BasicInstance> Drop for BufferedUartTx<'d, T> { 522impl<'d> Drop for BufferedUartTx<'d> {
506 fn drop(&mut self) { 523 fn drop(&mut self) {
507 let state = T::buffered_state(); 524 let state = self.state;
508 unsafe { 525 unsafe {
509 state.tx_buf.deinit(); 526 state.tx_buf.deinit();
510 527
511 // RX is inactive if the the buffer is not available. 528 // RX is inactive if the the buffer is not available.
512 // We can now unregister the interrupt handler 529 // We can now unregister the interrupt handler
513 if state.rx_buf.len() == 0 { 530 if state.rx_buf.len() == 0 {
514 T::Interrupt::disable(); 531 self.info.interrupt.disable();
515 } 532 }
516 } 533 }
517 534
518 T::disable(); 535 drop_tx_rx(self.info, state);
536 }
537}
538
539fn drop_tx_rx(info: &Info, state: &State) {
540 // We cannot use atomic subtraction here, because it's not supported for all targets
541 let is_last_drop = critical_section::with(|_| {
542 let refcount = state.tx_rx_refcount.load(Ordering::Relaxed);
543 assert!(refcount >= 1);
544 state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed);
545 refcount == 1
546 });
547 if is_last_drop {
548 info.enable_bit.disable();
519 } 549 }
520} 550}
521 551
522impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUart<'d, T> { 552impl<'d> embedded_io_async::ErrorType for BufferedUart<'d> {
523 type Error = Error; 553 type Error = Error;
524} 554}
525 555
526impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUartRx<'d, T> { 556impl<'d> embedded_io_async::ErrorType for BufferedUartRx<'d> {
527 type Error = Error; 557 type Error = Error;
528} 558}
529 559
530impl<'d, T: BasicInstance> embedded_io_async::ErrorType for BufferedUartTx<'d, T> { 560impl<'d> embedded_io_async::ErrorType for BufferedUartTx<'d> {
531 type Error = Error; 561 type Error = Error;
532} 562}
533 563
534impl<'d, T: BasicInstance> embedded_io_async::Read for BufferedUart<'d, T> { 564impl<'d> embedded_io_async::Read for BufferedUart<'d> {
535 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 565 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
536 self.rx.read(buf).await 566 self.rx.read(buf).await
537 } 567 }
538} 568}
539 569
540impl<'d, T: BasicInstance> embedded_io_async::Read for BufferedUartRx<'d, T> { 570impl<'d> embedded_io_async::Read for BufferedUartRx<'d> {
541 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 571 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
542 Self::read(self, buf).await 572 Self::read(self, buf).await
543 } 573 }
544} 574}
545 575
546impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUart<'d, T> { 576impl<'d> embedded_io_async::BufRead for BufferedUart<'d> {
547 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 577 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
548 self.rx.fill_buf().await 578 self.rx.fill_buf().await
549 } 579 }
@@ -553,7 +583,7 @@ impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUart<'d, T> {
553 } 583 }
554} 584}
555 585
556impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUartRx<'d, T> { 586impl<'d> embedded_io_async::BufRead for BufferedUartRx<'d> {
557 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 587 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
558 Self::fill_buf(self).await 588 Self::fill_buf(self).await
559 } 589 }
@@ -563,7 +593,7 @@ impl<'d, T: BasicInstance> embedded_io_async::BufRead for BufferedUartRx<'d, T>
563 } 593 }
564} 594}
565 595
566impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUart<'d, T> { 596impl<'d> embedded_io_async::Write for BufferedUart<'d> {
567 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 597 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
568 self.tx.write(buf).await 598 self.tx.write(buf).await
569 } 599 }
@@ -573,7 +603,7 @@ impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUart<'d, T> {
573 } 603 }
574} 604}
575 605
576impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUartTx<'d, T> { 606impl<'d> embedded_io_async::Write for BufferedUartTx<'d> {
577 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 607 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
578 Self::write(self, buf).await 608 Self::write(self, buf).await
579 } 609 }
@@ -583,19 +613,19 @@ impl<'d, T: BasicInstance> embedded_io_async::Write for BufferedUartTx<'d, T> {
583 } 613 }
584} 614}
585 615
586impl<'d, T: BasicInstance> embedded_io::Read for BufferedUart<'d, T> { 616impl<'d> embedded_io::Read for BufferedUart<'d> {
587 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 617 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
588 self.rx.blocking_read(buf) 618 self.rx.blocking_read(buf)
589 } 619 }
590} 620}
591 621
592impl<'d, T: BasicInstance> embedded_io::Read for BufferedUartRx<'d, T> { 622impl<'d> embedded_io::Read for BufferedUartRx<'d> {
593 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 623 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
594 self.blocking_read(buf) 624 self.blocking_read(buf)
595 } 625 }
596} 626}
597 627
598impl<'d, T: BasicInstance> embedded_io::Write for BufferedUart<'d, T> { 628impl<'d> embedded_io::Write for BufferedUart<'d> {
599 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 629 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
600 self.tx.blocking_write(buf) 630 self.tx.blocking_write(buf)
601 } 631 }
@@ -605,7 +635,7 @@ impl<'d, T: BasicInstance> embedded_io::Write for BufferedUart<'d, T> {
605 } 635 }
606} 636}
607 637
608impl<'d, T: BasicInstance> embedded_io::Write for BufferedUartTx<'d, T> { 638impl<'d> embedded_io::Write for BufferedUartTx<'d> {
609 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 639 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
610 Self::blocking_write(self, buf) 640 Self::blocking_write(self, buf)
611 } 641 }
@@ -615,11 +645,11 @@ impl<'d, T: BasicInstance> embedded_io::Write for BufferedUartTx<'d, T> {
615 } 645 }
616} 646}
617 647
618impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> { 648impl<'d> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d> {
619 type Error = Error; 649 type Error = Error;
620 650
621 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 651 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
622 let r = T::regs(); 652 let r = self.info.regs;
623 unsafe { 653 unsafe {
624 let sr = sr(r).read(); 654 let sr = sr(r).read();
625 if sr.pe() { 655 if sr.pe() {
@@ -643,7 +673,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<
643 } 673 }
644} 674}
645 675
646impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> { 676impl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d> {
647 type Error = Error; 677 type Error = Error;
648 678
649 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { 679 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
@@ -662,7 +692,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for Buff
662 } 692 }
663} 693}
664 694
665impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> { 695impl<'d> embedded_hal_02::serial::Read<u8> for BufferedUart<'d> {
666 type Error = Error; 696 type Error = Error;
667 697
668 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 698 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
@@ -670,7 +700,7 @@ impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d
670 } 700 }
671} 701}
672 702
673impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> { 703impl<'d> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d> {
674 type Error = Error; 704 type Error = Error;
675 705
676 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> { 706 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
@@ -689,25 +719,25 @@ impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for Buff
689 } 719 }
690} 720}
691 721
692impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUart<'d, T> { 722impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUart<'d> {
693 type Error = Error; 723 type Error = Error;
694} 724}
695 725
696impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d, T> { 726impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUartTx<'d> {
697 type Error = Error; 727 type Error = Error;
698} 728}
699 729
700impl<'d, T: BasicInstance> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d, T> { 730impl<'d> embedded_hal_nb::serial::ErrorType for BufferedUartRx<'d> {
701 type Error = Error; 731 type Error = Error;
702} 732}
703 733
704impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> { 734impl<'d> embedded_hal_nb::serial::Read for BufferedUartRx<'d> {
705 fn read(&mut self) -> nb::Result<u8, Self::Error> { 735 fn read(&mut self) -> nb::Result<u8, Self::Error> {
706 embedded_hal_02::serial::Read::read(self) 736 embedded_hal_02::serial::Read::read(self)
707 } 737 }
708} 738}
709 739
710impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> { 740impl<'d> embedded_hal_nb::serial::Write for BufferedUartTx<'d> {
711 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 741 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
712 self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) 742 self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
713 } 743 }
@@ -717,13 +747,13 @@ impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUartTx<'d,
717 } 747 }
718} 748}
719 749
720impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> { 750impl<'d> embedded_hal_nb::serial::Read for BufferedUart<'d> {
721 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 751 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
722 embedded_hal_02::serial::Read::read(&mut self.rx) 752 embedded_hal_02::serial::Read::read(&mut self.rx)
723 } 753 }
724} 754}
725 755
726impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> { 756impl<'d> embedded_hal_nb::serial::Write for BufferedUart<'d> {
727 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 757 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
728 self.tx.blocking_write(&[char]).map(drop).map_err(nb::Error::Other) 758 self.tx.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
729 } 759 }
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index a6dfbd482..b24335f3a 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -4,7 +4,7 @@
4 4
5use core::future::poll_fn; 5use core::future::poll_fn;
6use core::marker::PhantomData; 6use core::marker::PhantomData;
7use core::sync::atomic::{compiler_fence, Ordering}; 7use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
8use core::task::Poll; 8use core::task::Poll;
9 9
10use embassy_embedded_hal::SetConfig; 10use embassy_embedded_hal::SetConfig;
@@ -15,7 +15,8 @@ use 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};
18use crate::interrupt::typelevel::Interrupt; 18use crate::interrupt::typelevel::Interrupt as _;
19use crate::interrupt::{self, Interrupt, InterruptExt};
19use crate::mode::{Async, Blocking, Mode}; 20use crate::mode::{Async, Blocking, Mode};
20#[allow(unused_imports)] 21#[allow(unused_imports)]
21#[cfg(not(any(usart_v1, usart_v2)))] 22#[cfg(not(any(usart_v1, usart_v2)))]
@@ -27,55 +28,57 @@ use crate::pac::usart::Lpuart as Regs;
27#[cfg(any(usart_v1, usart_v2))] 28#[cfg(any(usart_v1, usart_v2))]
28use crate::pac::usart::Usart as Regs; 29use crate::pac::usart::Usart as Regs;
29use crate::pac::usart::{regs, vals}; 30use crate::pac::usart::{regs, vals};
31use crate::rcc::{ClockEnableBit, SealedRccPeripheral};
30use crate::time::Hertz; 32use crate::time::Hertz;
31use crate::{interrupt, peripherals, Peripheral}; 33use crate::Peripheral;
32 34
33/// Interrupt handler. 35/// Interrupt handler.
34pub struct InterruptHandler<T: BasicInstance> { 36pub struct InterruptHandler<T: Instance> {
35 _phantom: PhantomData<T>, 37 _phantom: PhantomData<T>,
36} 38}
37 39
38impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { 40impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
39 unsafe fn on_interrupt() { 41 unsafe fn on_interrupt() {
40 let r = T::regs(); 42 on_interrupt(T::info().regs, T::state())
41 let s = T::state(); 43 }
42 44}
43 let (sr, cr1, cr3) = (sr(r).read(), r.cr1().read(), r.cr3().read());
44 45
45 let has_errors = (sr.pe() && cr1.peie()) || ((sr.fe() || sr.ne() || sr.ore()) && cr3.eie()); 46unsafe fn on_interrupt(r: Regs, s: &'static State) {
46 if has_errors { 47 let (sr, cr1, cr3) = (sr(r).read(), r.cr1().read(), r.cr3().read());
47 // clear all interrupts and DMA Rx Request
48 r.cr1().modify(|w| {
49 // disable RXNE interrupt
50 w.set_rxneie(false);
51 // disable parity interrupt
52 w.set_peie(false);
53 // disable idle line interrupt
54 w.set_idleie(false);
55 });
56 r.cr3().modify(|w| {
57 // disable Error Interrupt: (Frame error, Noise error, Overrun error)
58 w.set_eie(false);
59 // disable DMA Rx Request
60 w.set_dmar(false);
61 });
62 } else if cr1.idleie() && sr.idle() {
63 // IDLE detected: no more data will come
64 r.cr1().modify(|w| {
65 // disable idle line detection
66 w.set_idleie(false);
67 });
68 } else if cr1.rxneie() {
69 // We cannot check the RXNE flag as it is auto-cleared by the DMA controller
70 48
71 // It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection 49 let has_errors = (sr.pe() && cr1.peie()) || ((sr.fe() || sr.ne() || sr.ore()) && cr3.eie());
72 } else { 50 if has_errors {
73 return; 51 // clear all interrupts and DMA Rx Request
74 } 52 r.cr1().modify(|w| {
53 // disable RXNE interrupt
54 w.set_rxneie(false);
55 // disable parity interrupt
56 w.set_peie(false);
57 // disable idle line interrupt
58 w.set_idleie(false);
59 });
60 r.cr3().modify(|w| {
61 // disable Error Interrupt: (Frame error, Noise error, Overrun error)
62 w.set_eie(false);
63 // disable DMA Rx Request
64 w.set_dmar(false);
65 });
66 } else if cr1.idleie() && sr.idle() {
67 // IDLE detected: no more data will come
68 r.cr1().modify(|w| {
69 // disable idle line detection
70 w.set_idleie(false);
71 });
72 } else if cr1.rxneie() {
73 // We cannot check the RXNE flag as it is auto-cleared by the DMA controller
75 74
76 compiler_fence(Ordering::SeqCst); 75 // It is up to the listener to determine if this in fact was a RX event and disable the RXNE detection
77 s.rx_waker.wake(); 76 } else {
77 return;
78 } 78 }
79
80 compiler_fence(Ordering::SeqCst);
81 s.rx_waker.wake();
79} 82}
80 83
81#[derive(Clone, Copy, PartialEq, Eq, Debug)] 84#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -239,12 +242,12 @@ enum ReadCompletionEvent {
239/// 242///
240/// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`] 243/// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`]
241/// as alternatives that do provide the necessary guarantees for `embedded_io::Read`. 244/// as alternatives that do provide the necessary guarantees for `embedded_io::Read`.
242pub struct Uart<'d, T: BasicInstance, M: Mode> { 245pub struct Uart<'d, M: Mode> {
243 tx: UartTx<'d, T, M>, 246 tx: UartTx<'d, M>,
244 rx: UartRx<'d, T, M>, 247 rx: UartRx<'d, M>,
245} 248}
246 249
247impl<'d, T: BasicInstance, M: Mode> SetConfig for Uart<'d, T, M> { 250impl<'d, M: Mode> SetConfig for Uart<'d, M> {
248 type Config = Config; 251 type Config = Config;
249 type ConfigError = ConfigError; 252 type ConfigError = ConfigError;
250 253
@@ -258,15 +261,18 @@ impl<'d, T: BasicInstance, M: Mode> SetConfig for Uart<'d, T, M> {
258/// 261///
259/// Can be obtained from [`Uart::split`], or can be constructed independently, 262/// Can be obtained from [`Uart::split`], or can be constructed independently,
260/// if you do not need the receiving half of the driver. 263/// if you do not need the receiving half of the driver.
261pub struct UartTx<'d, T: BasicInstance, M: Mode> { 264pub struct UartTx<'d, M: Mode> {
262 _phantom: PhantomData<(T, M)>, 265 info: &'static Info,
266 state: &'static State,
267 kernel_clock: Hertz,
263 tx: Option<PeripheralRef<'d, AnyPin>>, 268 tx: Option<PeripheralRef<'d, AnyPin>>,
264 cts: Option<PeripheralRef<'d, AnyPin>>, 269 cts: Option<PeripheralRef<'d, AnyPin>>,
265 de: Option<PeripheralRef<'d, AnyPin>>, 270 de: Option<PeripheralRef<'d, AnyPin>>,
266 tx_dma: Option<ChannelAndRequest<'d>>, 271 tx_dma: Option<ChannelAndRequest<'d>>,
272 _phantom: PhantomData<M>,
267} 273}
268 274
269impl<'d, T: BasicInstance, M: Mode> SetConfig for UartTx<'d, T, M> { 275impl<'d, M: Mode> SetConfig for UartTx<'d, M> {
270 type Config = Config; 276 type Config = Config;
271 type ConfigError = ConfigError; 277 type ConfigError = ConfigError;
272 278
@@ -304,17 +310,20 @@ impl<'d, T: BasicInstance, M: Mode> SetConfig for UartTx<'d, T, M> {
304/// store data received between calls. 310/// store data received between calls.
305/// 311///
306/// Also see [this github comment](https://github.com/embassy-rs/embassy/pull/2185#issuecomment-1810047043). 312/// Also see [this github comment](https://github.com/embassy-rs/embassy/pull/2185#issuecomment-1810047043).
307pub struct UartRx<'d, T: BasicInstance, M: Mode> { 313pub struct UartRx<'d, M: Mode> {
308 _phantom: PhantomData<(T, M)>, 314 info: &'static Info,
315 state: &'static State,
316 kernel_clock: Hertz,
309 rx: Option<PeripheralRef<'d, AnyPin>>, 317 rx: Option<PeripheralRef<'d, AnyPin>>,
310 rts: Option<PeripheralRef<'d, AnyPin>>, 318 rts: Option<PeripheralRef<'d, AnyPin>>,
311 rx_dma: Option<ChannelAndRequest<'d>>, 319 rx_dma: Option<ChannelAndRequest<'d>>,
312 detect_previous_overrun: bool, 320 detect_previous_overrun: bool,
313 #[cfg(any(usart_v1, usart_v2))] 321 #[cfg(any(usart_v1, usart_v2))]
314 buffered_sr: stm32_metapac::usart::regs::Sr, 322 buffered_sr: stm32_metapac::usart::regs::Sr,
323 _phantom: PhantomData<M>,
315} 324}
316 325
317impl<'d, T: BasicInstance, M: Mode> SetConfig for UartRx<'d, T, M> { 326impl<'d, M: Mode> SetConfig for UartRx<'d, M> {
318 type Config = Config; 327 type Config = Config;
319 type ConfigError = ConfigError; 328 type ConfigError = ConfigError;
320 329
@@ -323,9 +332,9 @@ impl<'d, T: BasicInstance, M: Mode> SetConfig for UartRx<'d, T, M> {
323 } 332 }
324} 333}
325 334
326impl<'d, T: BasicInstance> UartTx<'d, T, Async> { 335impl<'d> UartTx<'d, Async> {
327 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. 336 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
328 pub fn new( 337 pub fn new<T: Instance>(
329 peri: impl Peripheral<P = T> + 'd, 338 peri: impl Peripheral<P = T> + 'd,
330 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 339 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
331 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, 340 tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd,
@@ -341,7 +350,7 @@ impl<'d, T: BasicInstance> UartTx<'d, T, Async> {
341 } 350 }
342 351
343 /// Create a new tx-only UART with a clear-to-send pin 352 /// Create a new tx-only UART with a clear-to-send pin
344 pub fn new_with_cts( 353 pub fn new_with_cts<T: Instance>(
345 peri: impl Peripheral<P = T> + 'd, 354 peri: impl Peripheral<P = T> + 'd,
346 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 355 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
347 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 356 cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
@@ -359,7 +368,7 @@ impl<'d, T: BasicInstance> UartTx<'d, T, Async> {
359 368
360 /// Initiate an asynchronous UART write 369 /// Initiate an asynchronous UART write
361 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> { 370 pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
362 let r = T::regs(); 371 let r = self.info.regs;
363 372
364 // Disable Receiver for Half-Duplex mode 373 // Disable Receiver for Half-Duplex mode
365 if r.cr3().read().hdsel() { 374 if r.cr3().read().hdsel() {
@@ -377,21 +386,17 @@ impl<'d, T: BasicInstance> UartTx<'d, T, Async> {
377 Ok(()) 386 Ok(())
378 } 387 }
379 388
380 async fn flush_inner() -> Result<(), Error> {
381 Self::blocking_flush_inner()
382 }
383
384 /// Wait until transmission complete 389 /// Wait until transmission complete
385 pub async fn flush(&mut self) -> Result<(), Error> { 390 pub async fn flush(&mut self) -> Result<(), Error> {
386 Self::flush_inner().await 391 self.blocking_flush()
387 } 392 }
388} 393}
389 394
390impl<'d, T: BasicInstance> UartTx<'d, T, Blocking> { 395impl<'d> UartTx<'d, Blocking> {
391 /// Create a new blocking tx-only UART with no hardware flow control. 396 /// Create a new blocking tx-only UART with no hardware flow control.
392 /// 397 ///
393 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power. 398 /// Useful if you only want Uart Tx. It saves 1 pin and consumes a little less power.
394 pub fn new_blocking( 399 pub fn new_blocking<T: Instance>(
395 peri: impl Peripheral<P = T> + 'd, 400 peri: impl Peripheral<P = T> + 'd,
396 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 401 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
397 config: Config, 402 config: Config,
@@ -400,7 +405,7 @@ impl<'d, T: BasicInstance> UartTx<'d, T, Blocking> {
400 } 405 }
401 406
402 /// Create a new blocking tx-only UART with a clear-to-send pin 407 /// Create a new blocking tx-only UART with a clear-to-send pin
403 pub fn new_blocking_with_cts( 408 pub fn new_blocking_with_cts<T: Instance>(
404 peri: impl Peripheral<P = T> + 'd, 409 peri: impl Peripheral<P = T> + 'd,
405 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 410 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
406 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 411 cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
@@ -416,8 +421,8 @@ impl<'d, T: BasicInstance> UartTx<'d, T, Blocking> {
416 } 421 }
417} 422}
418 423
419impl<'d, T: BasicInstance, M: Mode> UartTx<'d, T, M> { 424impl<'d, M: Mode> UartTx<'d, M> {
420 fn new_inner( 425 fn new_inner<T: Instance>(
421 _peri: impl Peripheral<P = T> + 'd, 426 _peri: impl Peripheral<P = T> + 'd,
422 tx: Option<PeripheralRef<'d, AnyPin>>, 427 tx: Option<PeripheralRef<'d, AnyPin>>,
423 cts: Option<PeripheralRef<'d, AnyPin>>, 428 cts: Option<PeripheralRef<'d, AnyPin>>,
@@ -426,16 +431,21 @@ impl<'d, T: BasicInstance, M: Mode> UartTx<'d, T, M> {
426 ) -> Result<Self, ConfigError> { 431 ) -> Result<Self, ConfigError> {
427 T::enable_and_reset(); 432 T::enable_and_reset();
428 433
429 let r = T::regs(); 434 let info = T::info();
435 let state = T::state();
436 let kernel_clock = T::frequency();
437 let r = info.regs;
430 r.cr3().modify(|w| { 438 r.cr3().modify(|w| {
431 w.set_ctse(cts.is_some()); 439 w.set_ctse(cts.is_some());
432 }); 440 });
433 configure(r, &config, T::frequency(), T::KIND, false, true)?; 441 configure(info, kernel_clock, &config, false, true)?;
434 442
435 // create state once! 443 state.tx_rx_refcount.store(1, Ordering::Relaxed);
436 let _s = T::state();
437 444
438 Ok(Self { 445 Ok(Self {
446 info,
447 state,
448 kernel_clock,
439 tx, 449 tx,
440 cts, 450 cts,
441 de: None, 451 de: None,
@@ -446,12 +456,12 @@ impl<'d, T: BasicInstance, M: Mode> UartTx<'d, T, M> {
446 456
447 /// Reconfigure the driver 457 /// Reconfigure the driver
448 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 458 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
449 reconfigure::<T>(config) 459 reconfigure(self.info, self.kernel_clock, config)
450 } 460 }
451 461
452 /// Perform a blocking UART write 462 /// Perform a blocking UART write
453 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { 463 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
454 let r = T::regs(); 464 let r = self.info.regs;
455 465
456 // Disable Receiver for Half-Duplex mode 466 // Disable Receiver for Half-Duplex mode
457 if r.cr3().read().hdsel() { 467 if r.cr3().read().hdsel() {
@@ -465,28 +475,29 @@ impl<'d, T: BasicInstance, M: Mode> UartTx<'d, T, M> {
465 Ok(()) 475 Ok(())
466 } 476 }
467 477
468 fn blocking_flush_inner() -> Result<(), Error> {
469 let r = T::regs();
470 while !sr(r).read().tc() {}
471
472 // Enable Receiver after transmission complete for Half-Duplex mode
473 if r.cr3().read().hdsel() {
474 r.cr1().modify(|reg| reg.set_re(true));
475 }
476 Ok(())
477 }
478
479 /// Block until transmission complete 478 /// Block until transmission complete
480 pub fn blocking_flush(&mut self) -> Result<(), Error> { 479 pub fn blocking_flush(&mut self) -> Result<(), Error> {
481 Self::blocking_flush_inner() 480 blocking_flush(self.info)
481 }
482}
483
484fn blocking_flush(info: &Info) -> Result<(), Error> {
485 let r = info.regs;
486 while !sr(r).read().tc() {}
487
488 // Enable Receiver after transmission complete for Half-Duplex mode
489 if r.cr3().read().hdsel() {
490 r.cr1().modify(|reg| reg.set_re(true));
482 } 491 }
492
493 Ok(())
483} 494}
484 495
485impl<'d, T: BasicInstance> UartRx<'d, T, Async> { 496impl<'d> UartRx<'d, Async> {
486 /// Create a new rx-only UART with no hardware flow control. 497 /// Create a new rx-only UART with no hardware flow control.
487 /// 498 ///
488 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. 499 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
489 pub fn new( 500 pub fn new<T: Instance>(
490 peri: impl Peripheral<P = T> + 'd, 501 peri: impl Peripheral<P = T> + 'd,
491 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 502 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
492 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 503 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -497,7 +508,7 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
497 } 508 }
498 509
499 /// Create a new rx-only UART with a request-to-send pin 510 /// Create a new rx-only UART with a request-to-send pin
500 pub fn new_with_rts( 511 pub fn new_with_rts<T: Instance>(
501 peri: impl Peripheral<P = T> + 'd, 512 peri: impl Peripheral<P = T> + 'd,
502 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 513 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
503 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 514 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
@@ -531,11 +542,11 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
531 buffer: &mut [u8], 542 buffer: &mut [u8],
532 enable_idle_line_detection: bool, 543 enable_idle_line_detection: bool,
533 ) -> Result<ReadCompletionEvent, Error> { 544 ) -> Result<ReadCompletionEvent, Error> {
534 let r = T::regs(); 545 let r = self.info.regs;
535 546
536 // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. 547 // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written.
537 if r.cr3().read().hdsel() { 548 if r.cr3().read().hdsel() {
538 UartTx::<'d, T, Async>::flush_inner().await?; 549 blocking_flush(self.info)?;
539 } 550 }
540 551
541 // make sure USART state is restored to neutral state when this future is dropped 552 // make sure USART state is restored to neutral state when this future is dropped
@@ -565,7 +576,7 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
565 // Start USART DMA 576 // Start USART DMA
566 // will not do anything yet because DMAR is not yet set 577 // will not do anything yet because DMAR is not yet set
567 // future which will complete when DMA Read request completes 578 // future which will complete when DMA Read request completes
568 let transfer = unsafe { ch.read(rdr(T::regs()), buffer, Default::default()) }; 579 let transfer = unsafe { ch.read(rdr(r), buffer, Default::default()) };
569 580
570 // clear ORE flag just before enabling DMA Rx Request: can be mandatory for the second transfer 581 // clear ORE flag just before enabling DMA Rx Request: can be mandatory for the second transfer
571 if !self.detect_previous_overrun { 582 if !self.detect_previous_overrun {
@@ -640,9 +651,8 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
640 compiler_fence(Ordering::SeqCst); 651 compiler_fence(Ordering::SeqCst);
641 652
642 // future which completes when idle line or error is detected 653 // future which completes when idle line or error is detected
654 let s = self.state;
643 let abort = poll_fn(move |cx| { 655 let abort = poll_fn(move |cx| {
644 let s = T::state();
645
646 s.rx_waker.register(cx.waker()); 656 s.rx_waker.register(cx.waker());
647 657
648 let sr = sr(r).read(); 658 let sr = sr(r).read();
@@ -728,11 +738,11 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
728 } 738 }
729} 739}
730 740
731impl<'d, T: BasicInstance> UartRx<'d, T, Blocking> { 741impl<'d> UartRx<'d, Blocking> {
732 /// Create a new rx-only UART with no hardware flow control. 742 /// Create a new rx-only UART with no hardware flow control.
733 /// 743 ///
734 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. 744 /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
735 pub fn new_blocking( 745 pub fn new_blocking<T: Instance>(
736 peri: impl Peripheral<P = T> + 'd, 746 peri: impl Peripheral<P = T> + 'd,
737 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 747 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
738 config: Config, 748 config: Config,
@@ -741,7 +751,7 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Blocking> {
741 } 751 }
742 752
743 /// Create a new rx-only UART with a request-to-send pin 753 /// Create a new rx-only UART with a request-to-send pin
744 pub fn new_blocking_with_rts( 754 pub fn new_blocking_with_rts<T: Instance>(
745 peri: impl Peripheral<P = T> + 'd, 755 peri: impl Peripheral<P = T> + 'd,
746 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 756 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
747 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 757 rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
@@ -757,8 +767,8 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Blocking> {
757 } 767 }
758} 768}
759 769
760impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> { 770impl<'d, M: Mode> UartRx<'d, M> {
761 fn new_inner( 771 fn new_inner<T: Instance>(
762 _peri: impl Peripheral<P = T> + 'd, 772 _peri: impl Peripheral<P = T> + 'd,
763 rx: Option<PeripheralRef<'d, AnyPin>>, 773 rx: Option<PeripheralRef<'d, AnyPin>>,
764 rts: Option<PeripheralRef<'d, AnyPin>>, 774 rts: Option<PeripheralRef<'d, AnyPin>>,
@@ -767,20 +777,25 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
767 ) -> Result<Self, ConfigError> { 777 ) -> Result<Self, ConfigError> {
768 T::enable_and_reset(); 778 T::enable_and_reset();
769 779
770 let r = T::regs(); 780 let info = T::info();
781 let state = T::state();
782 let kernel_clock = T::frequency();
783 let r = info.regs;
771 r.cr3().write(|w| { 784 r.cr3().write(|w| {
772 w.set_rtse(rts.is_some()); 785 w.set_rtse(rts.is_some());
773 }); 786 });
774 configure(r, &config, T::frequency(), T::KIND, true, false)?; 787 configure(info, kernel_clock, &config, true, false)?;
775 788
776 T::Interrupt::unpend(); 789 T::Interrupt::unpend();
777 unsafe { T::Interrupt::enable() }; 790 unsafe { T::Interrupt::enable() };
778 791
779 // create state once! 792 state.tx_rx_refcount.store(1, Ordering::Relaxed);
780 let _s = T::state();
781 793
782 Ok(Self { 794 Ok(Self {
783 _phantom: PhantomData, 795 _phantom: PhantomData,
796 info,
797 state,
798 kernel_clock,
784 rx, 799 rx,
785 rts, 800 rts,
786 rx_dma, 801 rx_dma,
@@ -792,12 +807,12 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
792 807
793 /// Reconfigure the driver 808 /// Reconfigure the driver
794 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 809 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
795 reconfigure::<T>(config) 810 reconfigure(self.info, self.kernel_clock, config)
796 } 811 }
797 812
798 #[cfg(any(usart_v1, usart_v2))] 813 #[cfg(any(usart_v1, usart_v2))]
799 fn check_rx_flags(&mut self) -> Result<bool, Error> { 814 fn check_rx_flags(&mut self) -> Result<bool, Error> {
800 let r = T::regs(); 815 let r = self.info.regs;
801 loop { 816 loop {
802 // Handle all buffered error flags. 817 // Handle all buffered error flags.
803 if self.buffered_sr.pe() { 818 if self.buffered_sr.pe() {
@@ -830,7 +845,7 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
830 845
831 #[cfg(any(usart_v3, usart_v4))] 846 #[cfg(any(usart_v3, usart_v4))]
832 fn check_rx_flags(&mut self) -> Result<bool, Error> { 847 fn check_rx_flags(&mut self) -> Result<bool, Error> {
833 let r = T::regs(); 848 let r = self.info.regs;
834 let sr = r.isr().read(); 849 let sr = r.isr().read();
835 if sr.pe() { 850 if sr.pe() {
836 r.icr().write(|w| w.set_pe(true)); 851 r.icr().write(|w| w.set_pe(true));
@@ -850,7 +865,7 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
850 865
851 /// Read a single u8 if there is one available, otherwise return WouldBlock 866 /// Read a single u8 if there is one available, otherwise return WouldBlock
852 pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> { 867 pub(crate) fn nb_read(&mut self) -> Result<u8, nb::Error<Error>> {
853 let r = T::regs(); 868 let r = self.info.regs;
854 if self.check_rx_flags()? { 869 if self.check_rx_flags()? {
855 Ok(unsafe { rdr(r).read_volatile() }) 870 Ok(unsafe { rdr(r).read_volatile() })
856 } else { 871 } else {
@@ -860,11 +875,11 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
860 875
861 /// Perform a blocking read into `buffer` 876 /// Perform a blocking read into `buffer`
862 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 877 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
863 let r = T::regs(); 878 let r = self.info.regs;
864 879
865 // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written. 880 // Call flush for Half-Duplex mode. It prevents reading of bytes which have just been written.
866 if r.cr3().read().hdsel() { 881 if r.cr3().read().hdsel() {
867 UartTx::<'d, T, M>::blocking_flush_inner()?; 882 blocking_flush(self.info)?;
868 } 883 }
869 884
870 for b in buffer { 885 for b in buffer {
@@ -875,26 +890,39 @@ impl<'d, T: BasicInstance, M: Mode> UartRx<'d, T, M> {
875 } 890 }
876} 891}
877 892
878impl<'d, T: BasicInstance, M: Mode> Drop for UartTx<'d, T, M> { 893impl<'d, M: Mode> Drop for UartTx<'d, M> {
879 fn drop(&mut self) { 894 fn drop(&mut self) {
880 self.tx.as_ref().map(|x| x.set_as_disconnected()); 895 self.tx.as_ref().map(|x| x.set_as_disconnected());
881 self.cts.as_ref().map(|x| x.set_as_disconnected()); 896 self.cts.as_ref().map(|x| x.set_as_disconnected());
882 self.de.as_ref().map(|x| x.set_as_disconnected()); 897 self.de.as_ref().map(|x| x.set_as_disconnected());
883 T::disable(); 898 drop_tx_rx(self.info, self.state);
884 } 899 }
885} 900}
886 901
887impl<'d, T: BasicInstance, M: Mode> Drop for UartRx<'d, T, M> { 902impl<'d, M: Mode> Drop for UartRx<'d, M> {
888 fn drop(&mut self) { 903 fn drop(&mut self) {
889 self.rx.as_ref().map(|x| x.set_as_disconnected()); 904 self.rx.as_ref().map(|x| x.set_as_disconnected());
890 self.rts.as_ref().map(|x| x.set_as_disconnected()); 905 self.rts.as_ref().map(|x| x.set_as_disconnected());
891 T::disable(); 906 drop_tx_rx(self.info, self.state);
892 } 907 }
893} 908}
894 909
895impl<'d, T: BasicInstance> Uart<'d, T, Async> { 910fn drop_tx_rx(info: &Info, state: &State) {
911 // We cannot use atomic subtraction here, because it's not supported for all targets
912 let is_last_drop = critical_section::with(|_| {
913 let refcount = state.tx_rx_refcount.load(Ordering::Relaxed);
914 assert!(refcount >= 1);
915 state.tx_rx_refcount.store(refcount - 1, Ordering::Relaxed);
916 refcount == 1
917 });
918 if is_last_drop {
919 info.enable_bit.disable();
920 }
921}
922
923impl<'d> Uart<'d, Async> {
896 /// Create a new bidirectional UART 924 /// Create a new bidirectional UART
897 pub fn new( 925 pub fn new<T: Instance>(
898 peri: impl Peripheral<P = T> + 'd, 926 peri: impl Peripheral<P = T> + 'd,
899 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 927 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
900 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 928 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -917,7 +945,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Async> {
917 } 945 }
918 946
919 /// Create a new bidirectional UART with request-to-send and clear-to-send pins 947 /// Create a new bidirectional UART with request-to-send and clear-to-send pins
920 pub fn new_with_rtscts( 948 pub fn new_with_rtscts<T: Instance>(
921 peri: impl Peripheral<P = T> + 'd, 949 peri: impl Peripheral<P = T> + 'd,
922 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 950 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
923 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 951 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -943,7 +971,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Async> {
943 971
944 #[cfg(not(any(usart_v1, usart_v2)))] 972 #[cfg(not(any(usart_v1, usart_v2)))]
945 /// Create a new bidirectional UART with a driver-enable pin 973 /// Create a new bidirectional UART with a driver-enable pin
946 pub fn new_with_de( 974 pub fn new_with_de<T: Instance>(
947 peri: impl Peripheral<P = T> + 'd, 975 peri: impl Peripheral<P = T> + 'd,
948 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 976 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
949 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 977 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -977,7 +1005,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Async> {
977 /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict 1005 /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
978 /// on the line must be managed by software (for instance by using a centralized arbiter). 1006 /// on the line must be managed by software (for instance by using a centralized arbiter).
979 #[doc(alias("HDSEL"))] 1007 #[doc(alias("HDSEL"))]
980 pub fn new_half_duplex( 1008 pub fn new_half_duplex<T: Instance>(
981 peri: impl Peripheral<P = T> + 'd, 1009 peri: impl Peripheral<P = T> + 'd,
982 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1010 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
983 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1011 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@@ -1015,7 +1043,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Async> {
1015 /// on the line must be managed by software (for instance by using a centralized arbiter). 1043 /// on the line must be managed by software (for instance by using a centralized arbiter).
1016 #[cfg(not(any(usart_v1, usart_v2)))] 1044 #[cfg(not(any(usart_v1, usart_v2)))]
1017 #[doc(alias("HDSEL"))] 1045 #[doc(alias("HDSEL"))]
1018 pub fn new_half_duplex_on_rx( 1046 pub fn new_half_duplex_on_rx<T: Instance>(
1019 peri: impl Peripheral<P = T> + 'd, 1047 peri: impl Peripheral<P = T> + 'd,
1020 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1048 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
1021 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, 1049 _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
@@ -1055,9 +1083,9 @@ impl<'d, T: BasicInstance> Uart<'d, T, Async> {
1055 } 1083 }
1056} 1084}
1057 1085
1058impl<'d, T: BasicInstance> Uart<'d, T, Blocking> { 1086impl<'d> Uart<'d, Blocking> {
1059 /// Create a new blocking bidirectional UART. 1087 /// Create a new blocking bidirectional UART.
1060 pub fn new_blocking( 1088 pub fn new_blocking<T: Instance>(
1061 peri: impl Peripheral<P = T> + 'd, 1089 peri: impl Peripheral<P = T> + 'd,
1062 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1090 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
1063 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1091 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -1077,7 +1105,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Blocking> {
1077 } 1105 }
1078 1106
1079 /// Create a new bidirectional UART with request-to-send and clear-to-send pins 1107 /// Create a new bidirectional UART with request-to-send and clear-to-send pins
1080 pub fn new_blocking_with_rtscts( 1108 pub fn new_blocking_with_rtscts<T: Instance>(
1081 peri: impl Peripheral<P = T> + 'd, 1109 peri: impl Peripheral<P = T> + 'd,
1082 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1110 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
1083 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1111 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -1100,7 +1128,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Blocking> {
1100 1128
1101 #[cfg(not(any(usart_v1, usart_v2)))] 1129 #[cfg(not(any(usart_v1, usart_v2)))]
1102 /// Create a new bidirectional UART with a driver-enable pin 1130 /// Create a new bidirectional UART with a driver-enable pin
1103 pub fn new_blocking_with_de( 1131 pub fn new_blocking_with_de<T: Instance>(
1104 peri: impl Peripheral<P = T> + 'd, 1132 peri: impl Peripheral<P = T> + 'd,
1105 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1133 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
1106 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1134 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
@@ -1131,7 +1159,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Blocking> {
1131 /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict 1159 /// Apart from this, the communication protocol is similar to normal USART mode. Any conflict
1132 /// on the line must be managed by software (for instance by using a centralized arbiter). 1160 /// on the line must be managed by software (for instance by using a centralized arbiter).
1133 #[doc(alias("HDSEL"))] 1161 #[doc(alias("HDSEL"))]
1134 pub fn new_blocking_half_duplex( 1162 pub fn new_blocking_half_duplex<T: Instance>(
1135 peri: impl Peripheral<P = T> + 'd, 1163 peri: impl Peripheral<P = T> + 'd,
1136 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 1164 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
1137 mut config: Config, 1165 mut config: Config,
@@ -1166,7 +1194,7 @@ impl<'d, T: BasicInstance> Uart<'d, T, Blocking> {
1166 /// on the line must be managed by software (for instance by using a centralized arbiter). 1194 /// on the line must be managed by software (for instance by using a centralized arbiter).
1167 #[cfg(not(any(usart_v1, usart_v2)))] 1195 #[cfg(not(any(usart_v1, usart_v2)))]
1168 #[doc(alias("HDSEL"))] 1196 #[doc(alias("HDSEL"))]
1169 pub fn new_blocking_half_duplex_on_rx( 1197 pub fn new_blocking_half_duplex_on_rx<T: Instance>(
1170 peri: impl Peripheral<P = T> + 'd, 1198 peri: impl Peripheral<P = T> + 'd,
1171 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 1199 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
1172 mut config: Config, 1200 mut config: Config,
@@ -1188,8 +1216,8 @@ impl<'d, T: BasicInstance> Uart<'d, T, Blocking> {
1188 } 1216 }
1189} 1217}
1190 1218
1191impl<'d, T: BasicInstance, M: Mode> Uart<'d, T, M> { 1219impl<'d, M: Mode> Uart<'d, M> {
1192 fn new_inner( 1220 fn new_inner<T: Instance>(
1193 _peri: impl Peripheral<P = T> + 'd, 1221 _peri: impl Peripheral<P = T> + 'd,
1194 rx: Option<PeripheralRef<'d, AnyPin>>, 1222 rx: Option<PeripheralRef<'d, AnyPin>>,
1195 tx: Option<PeripheralRef<'d, AnyPin>>, 1223 tx: Option<PeripheralRef<'d, AnyPin>>,
@@ -1200,11 +1228,12 @@ impl<'d, T: BasicInstance, M: Mode> Uart<'d, T, M> {
1200 rx_dma: Option<ChannelAndRequest<'d>>, 1228 rx_dma: Option<ChannelAndRequest<'d>>,
1201 config: Config, 1229 config: Config,
1202 ) -> Result<Self, ConfigError> { 1230 ) -> Result<Self, ConfigError> {
1203 // UartRx and UartTx have one refcount each.
1204 T::enable_and_reset();
1205 T::enable_and_reset(); 1231 T::enable_and_reset();
1206 1232
1207 let r = T::regs(); 1233 let info = T::info();
1234 let state = T::state();
1235 let kernel_clock = T::frequency();
1236 let r = info.regs;
1208 1237
1209 r.cr3().write(|w| { 1238 r.cr3().write(|w| {
1210 w.set_rtse(rts.is_some()); 1239 w.set_rtse(rts.is_some());
@@ -1212,17 +1241,19 @@ impl<'d, T: BasicInstance, M: Mode> Uart<'d, T, M> {
1212 #[cfg(not(any(usart_v1, usart_v2)))] 1241 #[cfg(not(any(usart_v1, usart_v2)))]
1213 w.set_dem(de.is_some()); 1242 w.set_dem(de.is_some());
1214 }); 1243 });
1215 configure(r, &config, T::frequency(), T::KIND, true, true)?; 1244 configure(info, kernel_clock, &config, true, true)?;
1216 1245
1217 T::Interrupt::unpend(); 1246 T::Interrupt::unpend();
1218 unsafe { T::Interrupt::enable() }; 1247 unsafe { T::Interrupt::enable() };
1219 1248
1220 // create state once! 1249 state.tx_rx_refcount.store(2, Ordering::Relaxed);
1221 let _s = T::state();
1222 1250
1223 Ok(Self { 1251 Ok(Self {
1224 tx: UartTx { 1252 tx: UartTx {
1225 _phantom: PhantomData, 1253 _phantom: PhantomData,
1254 info,
1255 state,
1256 kernel_clock,
1226 tx, 1257 tx,
1227 cts, 1258 cts,
1228 de, 1259 de,
@@ -1230,6 +1261,9 @@ impl<'d, T: BasicInstance, M: Mode> Uart<'d, T, M> {
1230 }, 1261 },
1231 rx: UartRx { 1262 rx: UartRx {
1232 _phantom: PhantomData, 1263 _phantom: PhantomData,
1264 info,
1265 state,
1266 kernel_clock,
1233 rx, 1267 rx,
1234 rts, 1268 rts,
1235 rx_dma, 1269 rx_dma,
@@ -1263,32 +1297,34 @@ impl<'d, T: BasicInstance, M: Mode> Uart<'d, T, M> {
1263 /// Split the Uart into a transmitter and receiver, which is 1297 /// Split the Uart into a transmitter and receiver, which is
1264 /// particularly useful when having two tasks correlating to 1298 /// particularly useful when having two tasks correlating to
1265 /// transmitting and receiving. 1299 /// transmitting and receiving.
1266 pub fn split(self) -> (UartTx<'d, T, M>, UartRx<'d, T, M>) { 1300 pub fn split(self) -> (UartTx<'d, M>, UartRx<'d, M>) {
1267 (self.tx, self.rx) 1301 (self.tx, self.rx)
1268 } 1302 }
1269} 1303}
1270 1304
1271fn reconfigure<T: BasicInstance>(config: &Config) -> Result<(), ConfigError> { 1305fn reconfigure(info: &Info, kernel_clock: Hertz, config: &Config) -> Result<(), ConfigError> {
1272 T::Interrupt::disable(); 1306 info.interrupt.disable();
1273 let r = T::regs(); 1307 let r = info.regs;
1274 1308
1275 let cr = r.cr1().read(); 1309 let cr = r.cr1().read();
1276 configure(r, config, T::frequency(), T::KIND, cr.re(), cr.te())?; 1310 configure(info, kernel_clock, config, cr.re(), cr.te())?;
1277 1311
1278 T::Interrupt::unpend(); 1312 info.interrupt.unpend();
1279 unsafe { T::Interrupt::enable() }; 1313 unsafe { info.interrupt.enable() };
1280 1314
1281 Ok(()) 1315 Ok(())
1282} 1316}
1283 1317
1284fn configure( 1318fn configure(
1285 r: Regs, 1319 info: &Info,
1320 kernel_clock: Hertz,
1286 config: &Config, 1321 config: &Config,
1287 pclk_freq: Hertz,
1288 kind: Kind,
1289 enable_rx: bool, 1322 enable_rx: bool,
1290 enable_tx: bool, 1323 enable_tx: bool,
1291) -> Result<(), ConfigError> { 1324) -> Result<(), ConfigError> {
1325 let r = info.regs;
1326 let kind = info.kind;
1327
1292 if !enable_rx && !enable_tx { 1328 if !enable_rx && !enable_tx {
1293 return Err(ConfigError::RxOrTxNotEnabled); 1329 return Err(ConfigError::RxOrTxNotEnabled);
1294 } 1330 }
@@ -1348,7 +1384,7 @@ fn configure(
1348 let mut over8 = false; 1384 let mut over8 = false;
1349 let mut found_brr = None; 1385 let mut found_brr = None;
1350 for &(presc, _presc_val) in &DIVS { 1386 for &(presc, _presc_val) in &DIVS {
1351 let brr = calculate_brr(config.baudrate, pclk_freq.0, presc as u32, mul); 1387 let brr = calculate_brr(config.baudrate, kernel_clock.0, presc as u32, mul);
1352 trace!( 1388 trace!(
1353 "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})", 1389 "USART: presc={}, div=0x{:08x} (mantissa = {}, fraction = {})",
1354 presc, 1390 presc,
@@ -1389,7 +1425,7 @@ fn configure(
1389 "Using {} oversampling, desired baudrate: {}, actual baudrate: {}", 1425 "Using {} oversampling, desired baudrate: {}, actual baudrate: {}",
1390 oversampling, 1426 oversampling,
1391 config.baudrate, 1427 config.baudrate,
1392 pclk_freq.0 / brr * mul 1428 kernel_clock.0 / brr * mul
1393 ); 1429 );
1394 1430
1395 r.cr2().write(|w| { 1431 r.cr2().write(|w| {
@@ -1458,14 +1494,14 @@ fn configure(
1458 Ok(()) 1494 Ok(())
1459} 1495}
1460 1496
1461impl<'d, T: BasicInstance, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, T, M> { 1497impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for UartRx<'d, M> {
1462 type Error = Error; 1498 type Error = Error;
1463 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 1499 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1464 self.nb_read() 1500 self.nb_read()
1465 } 1501 }
1466} 1502}
1467 1503
1468impl<'d, T: BasicInstance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, T, M> { 1504impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for UartTx<'d, M> {
1469 type Error = Error; 1505 type Error = Error;
1470 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 1506 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
1471 self.blocking_write(buffer) 1507 self.blocking_write(buffer)
@@ -1475,14 +1511,14 @@ impl<'d, T: BasicInstance, M: Mode> embedded_hal_02::blocking::serial::Write<u8>
1475 } 1511 }
1476} 1512}
1477 1513
1478impl<'d, T: BasicInstance, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, T, M> { 1514impl<'d, M: Mode> embedded_hal_02::serial::Read<u8> for Uart<'d, M> {
1479 type Error = Error; 1515 type Error = Error;
1480 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 1516 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1481 self.nb_read() 1517 self.nb_read()
1482 } 1518 }
1483} 1519}
1484 1520
1485impl<'d, T: BasicInstance, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, T, M> { 1521impl<'d, M: Mode> embedded_hal_02::blocking::serial::Write<u8> for Uart<'d, M> {
1486 type Error = Error; 1522 type Error = Error;
1487 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { 1523 fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
1488 self.blocking_write(buffer) 1524 self.blocking_write(buffer)
@@ -1504,25 +1540,25 @@ impl embedded_hal_nb::serial::Error for Error {
1504 } 1540 }
1505} 1541}
1506 1542
1507impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, T, M> { 1543impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for Uart<'d, M> {
1508 type Error = Error; 1544 type Error = Error;
1509} 1545}
1510 1546
1511impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, T, M> { 1547impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartTx<'d, M> {
1512 type Error = Error; 1548 type Error = Error;
1513} 1549}
1514 1550
1515impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, T, M> { 1551impl<'d, M: Mode> embedded_hal_nb::serial::ErrorType for UartRx<'d, M> {
1516 type Error = Error; 1552 type Error = Error;
1517} 1553}
1518 1554
1519impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, T, M> { 1555impl<'d, M: Mode> embedded_hal_nb::serial::Read for UartRx<'d, M> {
1520 fn read(&mut self) -> nb::Result<u8, Self::Error> { 1556 fn read(&mut self) -> nb::Result<u8, Self::Error> {
1521 self.nb_read() 1557 self.nb_read()
1522 } 1558 }
1523} 1559}
1524 1560
1525impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, T, M> { 1561impl<'d, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d, M> {
1526 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 1562 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
1527 self.blocking_write(&[char]).map_err(nb::Error::Other) 1563 self.blocking_write(&[char]).map_err(nb::Error::Other)
1528 } 1564 }
@@ -1532,13 +1568,13 @@ impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::Write for UartTx<'d
1532 } 1568 }
1533} 1569}
1534 1570
1535impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, T, M> { 1571impl<'d, M: Mode> embedded_hal_nb::serial::Read for Uart<'d, M> {
1536 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> { 1572 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
1537 self.nb_read() 1573 self.nb_read()
1538 } 1574 }
1539} 1575}
1540 1576
1541impl<'d, T: BasicInstance, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, T, M> { 1577impl<'d, M: Mode> embedded_hal_nb::serial::Write for Uart<'d, M> {
1542 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> { 1578 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
1543 self.blocking_write(&[char]).map_err(nb::Error::Other) 1579 self.blocking_write(&[char]).map_err(nb::Error::Other)
1544 } 1580 }
@@ -1554,24 +1590,15 @@ impl embedded_io::Error for Error {
1554 } 1590 }
1555} 1591}
1556 1592
1557impl<T, M: Mode> embedded_io::ErrorType for Uart<'_, T, M> 1593impl<M: Mode> embedded_io::ErrorType for Uart<'_, M> {
1558where
1559 T: BasicInstance,
1560{
1561 type Error = Error; 1594 type Error = Error;
1562} 1595}
1563 1596
1564impl<T, M: Mode> embedded_io::ErrorType for UartTx<'_, T, M> 1597impl<M: Mode> embedded_io::ErrorType for UartTx<'_, M> {
1565where
1566 T: BasicInstance,
1567{
1568 type Error = Error; 1598 type Error = Error;
1569} 1599}
1570 1600
1571impl<T, M: Mode> embedded_io::Write for Uart<'_, T, M> 1601impl<M: Mode> embedded_io::Write for Uart<'_, M> {
1572where
1573 T: BasicInstance,
1574{
1575 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 1602 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1576 self.blocking_write(buf)?; 1603 self.blocking_write(buf)?;
1577 Ok(buf.len()) 1604 Ok(buf.len())
@@ -1582,10 +1609,7 @@ where
1582 } 1609 }
1583} 1610}
1584 1611
1585impl<T, M: Mode> embedded_io::Write for UartTx<'_, T, M> 1612impl<M: Mode> embedded_io::Write for UartTx<'_, M> {
1586where
1587 T: BasicInstance,
1588{
1589 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 1613 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1590 self.blocking_write(buf)?; 1614 self.blocking_write(buf)?;
1591 Ok(buf.len()) 1615 Ok(buf.len())
@@ -1596,10 +1620,7 @@ where
1596 } 1620 }
1597} 1621}
1598 1622
1599impl<T> embedded_io_async::Write for Uart<'_, T, Async> 1623impl embedded_io_async::Write for Uart<'_, Async> {
1600where
1601 T: BasicInstance,
1602{
1603 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 1624 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1604 self.write(buf).await?; 1625 self.write(buf).await?;
1605 Ok(buf.len()) 1626 Ok(buf.len())
@@ -1610,10 +1631,7 @@ where
1610 } 1631 }
1611} 1632}
1612 1633
1613impl<T> embedded_io_async::Write for UartTx<'_, T, Async> 1634impl embedded_io_async::Write for UartTx<'_, Async> {
1614where
1615 T: BasicInstance,
1616{
1617 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 1635 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1618 self.write(buf).await?; 1636 self.write(buf).await?;
1619 Ok(buf.len()) 1637 Ok(buf.len())
@@ -1686,72 +1704,75 @@ enum Kind {
1686 1704
1687struct State { 1705struct State {
1688 rx_waker: AtomicWaker, 1706 rx_waker: AtomicWaker,
1707 tx_rx_refcount: AtomicU8,
1689} 1708}
1690 1709
1691impl State { 1710impl State {
1692 const fn new() -> Self { 1711 const fn new() -> Self {
1693 Self { 1712 Self {
1694 rx_waker: AtomicWaker::new(), 1713 rx_waker: AtomicWaker::new(),
1714 tx_rx_refcount: AtomicU8::new(0),
1695 } 1715 }
1696 } 1716 }
1697} 1717}
1698 1718
1699trait SealedBasicInstance: crate::rcc::RccPeripheral { 1719struct Info {
1700 const KIND: Kind; 1720 regs: Regs,
1721 enable_bit: ClockEnableBit,
1722 interrupt: Interrupt,
1723 kind: Kind,
1724}
1701 1725
1702 fn regs() -> Regs; 1726#[allow(private_interfaces)]
1727pub(crate) trait SealedInstance: crate::rcc::RccPeripheral {
1728 fn info() -> &'static Info;
1703 fn state() -> &'static State; 1729 fn state() -> &'static State;
1704
1705 fn buffered_state() -> &'static buffered::State; 1730 fn buffered_state() -> &'static buffered::State;
1706} 1731}
1707 1732
1708trait SealedFullInstance: SealedBasicInstance { 1733/// USART peripheral instance trait.
1709 #[allow(unused)]
1710 fn regs_uart() -> crate::pac::usart::Usart;
1711}
1712
1713/// Basic UART driver instance
1714#[allow(private_bounds)] 1734#[allow(private_bounds)]
1715pub trait BasicInstance: Peripheral<P = Self> + SealedBasicInstance + 'static + Send { 1735pub trait Instance: Peripheral<P = Self> + SealedInstance + 'static + Send {
1716 /// Interrupt for this instance. 1736 /// Interrupt for this peripheral.
1717 type Interrupt: interrupt::typelevel::Interrupt; 1737 type Interrupt: interrupt::typelevel::Interrupt;
1718} 1738}
1719 1739
1720/// Full UART driver instance 1740pin_trait!(RxPin, Instance);
1721#[allow(private_bounds)] 1741pin_trait!(TxPin, Instance);
1722pub trait FullInstance: SealedFullInstance {} 1742pin_trait!(CtsPin, Instance);
1743pin_trait!(RtsPin, Instance);
1744pin_trait!(CkPin, Instance);
1745pin_trait!(DePin, Instance);
1723 1746
1724pin_trait!(RxPin, BasicInstance); 1747dma_trait!(TxDma, Instance);
1725pin_trait!(TxPin, BasicInstance); 1748dma_trait!(RxDma, Instance);
1726pin_trait!(CtsPin, BasicInstance);
1727pin_trait!(RtsPin, BasicInstance);
1728pin_trait!(CkPin, BasicInstance);
1729pin_trait!(DePin, BasicInstance);
1730
1731dma_trait!(TxDma, BasicInstance);
1732dma_trait!(RxDma, BasicInstance);
1733 1749
1734macro_rules! impl_usart { 1750macro_rules! impl_usart {
1735 ($inst:ident, $irq:ident, $kind:expr) => { 1751 ($inst:ident, $irq:ident, $kind:expr) => {
1736 impl SealedBasicInstance for crate::peripherals::$inst { 1752 #[allow(private_interfaces)]
1737 const KIND: Kind = $kind; 1753 impl SealedInstance for crate::peripherals::$inst {
1738 1754 fn info() -> &'static Info {
1739 fn regs() -> Regs { 1755 static INFO: Info = Info {
1740 unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) } 1756 regs: unsafe { Regs::from_ptr(crate::pac::$inst.as_ptr()) },
1757 enable_bit: crate::peripherals::$inst::ENABLE_BIT,
1758 interrupt: crate::interrupt::typelevel::$irq::IRQ,
1759 kind: $kind,
1760 };
1761 &INFO
1741 } 1762 }
1742 1763
1743 fn state() -> &'static crate::usart::State { 1764 fn state() -> &'static State {
1744 static STATE: crate::usart::State = crate::usart::State::new(); 1765 static STATE: State = State::new();
1745 &STATE 1766 &STATE
1746 } 1767 }
1747 1768
1748 fn buffered_state() -> &'static buffered::State { 1769 fn buffered_state() -> &'static buffered::State {
1749 static STATE: buffered::State = buffered::State::new(); 1770 static BUFFERED_STATE: buffered::State = buffered::State::new();
1750 &STATE 1771 &BUFFERED_STATE
1751 } 1772 }
1752 } 1773 }
1753 1774
1754 impl BasicInstance for peripherals::$inst { 1775 impl Instance for crate::peripherals::$inst {
1755 type Interrupt = crate::interrupt::typelevel::$irq; 1776 type Interrupt = crate::interrupt::typelevel::$irq;
1756 } 1777 }
1757 }; 1778 };
@@ -1761,16 +1782,7 @@ foreach_interrupt!(
1761 ($inst:ident, usart, LPUART, $signal_name:ident, $irq:ident) => { 1782 ($inst:ident, usart, LPUART, $signal_name:ident, $irq:ident) => {
1762 impl_usart!($inst, $irq, Kind::Lpuart); 1783 impl_usart!($inst, $irq, Kind::Lpuart);
1763 }; 1784 };
1764
1765 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => { 1785 ($inst:ident, usart, $block:ident, $signal_name:ident, $irq:ident) => {
1766 impl_usart!($inst, $irq, Kind::Uart); 1786 impl_usart!($inst, $irq, Kind::Uart);
1767
1768 impl SealedFullInstance for peripherals::$inst {
1769 fn regs_uart() -> crate::pac::usart::Usart {
1770 crate::pac::$inst
1771 }
1772 }
1773
1774 impl FullInstance for peripherals::$inst {}
1775 }; 1787 };
1776); 1788);
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index 0a6491bd5..f3a88b93f 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -1,5 +1,4 @@
1use core::future::poll_fn; 1use core::future::poll_fn;
2use core::marker::PhantomData;
3use core::mem; 2use core::mem;
4use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 4use core::task::Poll;
@@ -7,20 +6,23 @@ use core::task::Poll;
7use embassy_embedded_hal::SetConfig; 6use embassy_embedded_hal::SetConfig;
8use futures_util::future::{select, Either}; 7use futures_util::future::{select, Either};
9 8
10use super::{clear_interrupt_flags, rdr, reconfigure, sr, BasicInstance, Config, ConfigError, Error, UartRx}; 9use super::{clear_interrupt_flags, rdr, reconfigure, sr, Config, ConfigError, Error, Info, State, UartRx};
11use crate::dma::ReadableRingBuffer; 10use crate::dma::ReadableRingBuffer;
12use crate::mode::Async; 11use crate::mode::Async;
12use crate::time::Hertz;
13use crate::usart::{Regs, Sr}; 13use crate::usart::{Regs, Sr};
14 14
15/// Rx-only Ring-buffered UART Driver 15/// Rx-only Ring-buffered UART Driver
16/// 16///
17/// Created with [UartRx::into_ring_buffered] 17/// Created with [UartRx::into_ring_buffered]
18pub struct RingBufferedUartRx<'d, T: BasicInstance> { 18pub struct RingBufferedUartRx<'d> {
19 _phantom: PhantomData<T>, 19 info: &'static Info,
20 state: &'static State,
21 kernel_clock: Hertz,
20 ring_buf: ReadableRingBuffer<'d, u8>, 22 ring_buf: ReadableRingBuffer<'d, u8>,
21} 23}
22 24
23impl<'d, T: BasicInstance> SetConfig for RingBufferedUartRx<'d, T> { 25impl<'d> SetConfig for RingBufferedUartRx<'d> {
24 type Config = Config; 26 type Config = Config;
25 type ConfigError = ConfigError; 27 type ConfigError = ConfigError;
26 28
@@ -29,11 +31,11 @@ impl<'d, T: BasicInstance> SetConfig for RingBufferedUartRx<'d, T> {
29 } 31 }
30} 32}
31 33
32impl<'d, T: BasicInstance> UartRx<'d, T, Async> { 34impl<'d> UartRx<'d, Async> {
33 /// Turn the `UartRx` into a buffered uart which can continously receive in the background 35 /// Turn the `UartRx` into a buffered uart which can continously receive in the background
34 /// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the 36 /// without the possibility of losing bytes. The `dma_buf` is a buffer registered to the
35 /// DMA controller, and must be large enough to prevent overflows. 37 /// DMA controller, and must be large enough to prevent overflows.
36 pub fn into_ring_buffered(mut self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d, T> { 38 pub fn into_ring_buffered(mut self, dma_buf: &'d mut [u8]) -> RingBufferedUartRx<'d> {
37 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 39 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
38 40
39 let opts = Default::default(); 41 let opts = Default::default();
@@ -43,19 +45,24 @@ impl<'d, T: BasicInstance> UartRx<'d, T, Async> {
43 let request = rx_dma.request; 45 let request = rx_dma.request;
44 let rx_dma = unsafe { rx_dma.channel.clone_unchecked() }; 46 let rx_dma = unsafe { rx_dma.channel.clone_unchecked() };
45 47
46 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(T::regs()), dma_buf, opts) }; 48 let info = self.info;
49 let state = self.state;
50 let kernel_clock = self.kernel_clock;
51 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) };
47 52
48 // Don't disable the clock 53 // Don't disable the clock
49 mem::forget(self); 54 mem::forget(self);
50 55
51 RingBufferedUartRx { 56 RingBufferedUartRx {
52 _phantom: PhantomData, 57 info,
58 state,
59 kernel_clock,
53 ring_buf, 60 ring_buf,
54 } 61 }
55 } 62 }
56} 63}
57 64
58impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> { 65impl<'d> RingBufferedUartRx<'d> {
59 /// Clear the ring buffer and start receiving in the background 66 /// Clear the ring buffer and start receiving in the background
60 pub fn start(&mut self) -> Result<(), Error> { 67 pub fn start(&mut self) -> Result<(), Error> {
61 // Clear the ring buffer so that it is ready to receive data 68 // Clear the ring buffer so that it is ready to receive data
@@ -74,7 +81,7 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
74 81
75 /// Reconfigure the driver 82 /// Reconfigure the driver
76 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { 83 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
77 reconfigure::<T>(config) 84 reconfigure(self.info, self.kernel_clock, config)
78 } 85 }
79 86
80 /// Start uart background receive 87 /// Start uart background receive
@@ -85,7 +92,7 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
85 // start the dma controller 92 // start the dma controller
86 self.ring_buf.start(); 93 self.ring_buf.start();
87 94
88 let r = T::regs(); 95 let r = self.info.regs;
89 // clear all interrupts and DMA Rx Request 96 // clear all interrupts and DMA Rx Request
90 r.cr1().modify(|w| { 97 r.cr1().modify(|w| {
91 // disable RXNE interrupt 98 // disable RXNE interrupt
@@ -107,7 +114,7 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
107 fn teardown_uart(&mut self) { 114 fn teardown_uart(&mut self) {
108 self.ring_buf.request_stop(); 115 self.ring_buf.request_stop();
109 116
110 let r = T::regs(); 117 let r = self.info.regs;
111 // clear all interrupts and DMA Rx Request 118 // clear all interrupts and DMA Rx Request
112 r.cr1().modify(|w| { 119 r.cr1().modify(|w| {
113 // disable RXNE interrupt 120 // disable RXNE interrupt
@@ -136,14 +143,14 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
136 /// Receive in the background is terminated if an error is returned. 143 /// Receive in the background is terminated if an error is returned.
137 /// It must then manually be started again by calling `start()` or by re-calling `read()`. 144 /// It must then manually be started again by calling `start()` or by re-calling `read()`.
138 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { 145 pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
139 let r = T::regs(); 146 let r = self.info.regs;
140 147
141 // Start background receive if it was not already started 148 // Start background receive if it was not already started
142 if !r.cr3().read().dmar() { 149 if !r.cr3().read().dmar() {
143 self.start()?; 150 self.start()?;
144 } 151 }
145 152
146 check_for_errors(clear_idle_flag(T::regs()))?; 153 check_for_errors(clear_idle_flag(r))?;
147 154
148 loop { 155 loop {
149 match self.ring_buf.read(buf) { 156 match self.ring_buf.read(buf) {
@@ -184,15 +191,15 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
184 }); 191 });
185 192
186 // Future which completes when idle line is detected 193 // Future which completes when idle line is detected
194 let s = self.state;
187 let uart = poll_fn(|cx| { 195 let uart = poll_fn(|cx| {
188 let s = T::state();
189 s.rx_waker.register(cx.waker()); 196 s.rx_waker.register(cx.waker());
190 197
191 compiler_fence(Ordering::SeqCst); 198 compiler_fence(Ordering::SeqCst);
192 199
193 // Critical section is needed so that IDLE isn't set after 200 // Critical section is needed so that IDLE isn't set after
194 // our read but before we clear it. 201 // our read but before we clear it.
195 let sr = critical_section::with(|_| clear_idle_flag(T::regs())); 202 let sr = critical_section::with(|_| clear_idle_flag(self.info.regs));
196 203
197 check_for_errors(sr)?; 204 check_for_errors(sr)?;
198 205
@@ -211,13 +218,13 @@ impl<'d, T: BasicInstance> RingBufferedUartRx<'d, T> {
211 } 218 }
212} 219}
213 220
214impl<T: BasicInstance> Drop for RingBufferedUartRx<'_, T> { 221impl Drop for RingBufferedUartRx<'_> {
215 fn drop(&mut self) { 222 fn drop(&mut self) {
216 self.teardown_uart(); 223 self.teardown_uart();
217 224 super::drop_tx_rx(self.info, self.state);
218 T::disable();
219 } 225 }
220} 226}
227
221/// Return an error result if the Sr register has errors 228/// Return an error result if the Sr register has errors
222fn check_for_errors(s: Sr) -> Result<(), Error> { 229fn check_for_errors(s: Sr) -> Result<(), Error> {
223 if s.pe() { 230 if s.pe() {
@@ -248,17 +255,11 @@ fn clear_idle_flag(r: Regs) -> Sr {
248 sr 255 sr
249} 256}
250 257
251impl<T> embedded_io_async::ErrorType for RingBufferedUartRx<'_, T> 258impl embedded_io_async::ErrorType for RingBufferedUartRx<'_> {
252where
253 T: BasicInstance,
254{
255 type Error = Error; 259 type Error = Error;
256} 260}
257 261
258impl<T> embedded_io_async::Read for RingBufferedUartRx<'_, T> 262impl embedded_io_async::Read for RingBufferedUartRx<'_> {
259where
260 T: BasicInstance,
261{
262 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 263 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
263 self.read(buf).await 264 self.read(buf).await
264 } 265 }
diff --git a/examples/stm32h5/src/bin/usart_split.rs b/examples/stm32h5/src/bin/usart_split.rs
index 77b4caa9e..d26c5003c 100644
--- a/examples/stm32h5/src/bin/usart_split.rs
+++ b/examples/stm32h5/src/bin/usart_split.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::mode::Async; 6use embassy_stm32::mode::Async;
7use embassy_stm32::peripherals::UART7;
8use embassy_stm32::usart::{Config, Uart, UartRx}; 7use embassy_stm32::usart::{Config, Uart, UartRx};
9use embassy_stm32::{bind_interrupts, peripherals, usart}; 8use embassy_stm32::{bind_interrupts, peripherals, usart};
10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 9use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
@@ -38,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
38} 37}
39 38
40#[embassy_executor::task] 39#[embassy_executor::task]
41async fn reader(mut rx: UartRx<'static, UART7, Async>) { 40async fn reader(mut rx: UartRx<'static, Async>) {
42 let mut buf = [0; 8]; 41 let mut buf = [0; 8];
43 loop { 42 loop {
44 info!("reading..."); 43 info!("reading...");
diff --git a/examples/stm32h7/src/bin/usart_split.rs b/examples/stm32h7/src/bin/usart_split.rs
index 4ad8e77ce..2bb58be5e 100644
--- a/examples/stm32h7/src/bin/usart_split.rs
+++ b/examples/stm32h7/src/bin/usart_split.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::mode::Async; 6use embassy_stm32::mode::Async;
7use embassy_stm32::peripherals::UART7;
8use embassy_stm32::usart::{Config, Uart, UartRx}; 7use embassy_stm32::usart::{Config, Uart, UartRx};
9use embassy_stm32::{bind_interrupts, peripherals, usart}; 8use embassy_stm32::{bind_interrupts, peripherals, usart};
10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 9use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
@@ -38,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
38} 37}
39 38
40#[embassy_executor::task] 39#[embassy_executor::task]
41async fn reader(mut rx: UartRx<'static, UART7, Async>) { 40async fn reader(mut rx: UartRx<'static, Async>) {
42 let mut buf = [0; 8]; 41 let mut buf = [0; 8];
43 loop { 42 loop {
44 info!("reading..."); 43 info!("reading...");
diff --git a/examples/stm32h7rs/src/bin/usart_split.rs b/examples/stm32h7rs/src/bin/usart_split.rs
index 77b4caa9e..d26c5003c 100644
--- a/examples/stm32h7rs/src/bin/usart_split.rs
+++ b/examples/stm32h7rs/src/bin/usart_split.rs
@@ -4,7 +4,6 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::mode::Async; 6use embassy_stm32::mode::Async;
7use embassy_stm32::peripherals::UART7;
8use embassy_stm32::usart::{Config, Uart, UartRx}; 7use embassy_stm32::usart::{Config, Uart, UartRx};
9use embassy_stm32::{bind_interrupts, peripherals, usart}; 8use embassy_stm32::{bind_interrupts, peripherals, usart};
10use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 9use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
@@ -38,7 +37,7 @@ async fn main(spawner: Spawner) -> ! {
38} 37}
39 38
40#[embassy_executor::task] 39#[embassy_executor::task]
41async fn reader(mut rx: UartRx<'static, UART7, Async>) { 40async fn reader(mut rx: UartRx<'static, Async>) {
42 let mut buf = [0; 8]; 41 let mut buf = [0; 8];
43 loop { 42 loop {
44 info!("reading..."); 43 info!("reading...");
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
index 908452eaf..ea1e52358 100644
--- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs
+++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
@@ -52,7 +52,7 @@ async fn main(spawner: Spawner) {
52} 52}
53 53
54#[embassy_executor::task] 54#[embassy_executor::task]
55async fn transmit_task(mut tx: UartTx<'static, peris::UART, Async>) { 55async fn transmit_task(mut tx: UartTx<'static, Async>) {
56 // workaround https://github.com/embassy-rs/embassy/issues/1426 56 // workaround https://github.com/embassy-rs/embassy/issues/1426
57 Timer::after_millis(100).await; 57 Timer::after_millis(100).await;
58 58
@@ -75,7 +75,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, Async>) {
75} 75}
76 76
77#[embassy_executor::task] 77#[embassy_executor::task]
78async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART>) { 78async fn receive_task(mut rx: RingBufferedUartRx<'static>) {
79 info!("Ready to receive..."); 79 info!("Ready to receive...");
80 80
81 let mut rng = ChaCha8Rng::seed_from_u64(1337); 81 let mut rng = ChaCha8Rng::seed_from_u64(1337);