aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/usart/buffered.rs696
-rw-r--r--embassy-stm32/src/usart/mod.rs9
-rw-r--r--examples/stm32f4/src/bin/usart_buffered.rs14
-rw-r--r--examples/stm32l0/src/bin/usart_irq.rs16
4 files changed, 448 insertions, 287 deletions
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs
index cd7d72f91..3e23e7ca1 100644
--- a/embassy-stm32/src/usart/buffered.rs
+++ b/embassy-stm32/src/usart/buffered.rs
@@ -1,55 +1,51 @@
1use core::cell::RefCell;
2use core::future::poll_fn; 1use core::future::poll_fn;
3use core::sync::atomic::{compiler_fence, Ordering}; 2use core::slice;
4use core::task::Poll; 3use core::task::Poll;
5 4
6use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 5use embassy_cortex_m::interrupt::Interrupt;
7use embassy_hal_common::ring_buffer::RingBuffer; 6use embassy_hal_common::atomic_ring_buffer::RingBuffer;
8use embassy_sync::waitqueue::WakerRegistration; 7use embassy_sync::waitqueue::AtomicWaker;
9 8
10use super::*; 9use super::*;
11 10
12pub struct State<'d, T: BasicInstance>(StateStorage<StateInner<'d, T>>); 11pub struct State {
13impl<'d, T: BasicInstance> State<'d, T> { 12 rx_waker: AtomicWaker,
14 pub const fn new() -> Self { 13 rx_buf: RingBuffer,
15 Self(StateStorage::new())
16 }
17}
18
19struct StateInner<'d, T: BasicInstance> {
20 phantom: PhantomData<&'d mut T>,
21
22 rx_waker: WakerRegistration,
23 rx: RingBuffer<'d>,
24 14
25 tx_waker: WakerRegistration, 15 tx_waker: AtomicWaker,
26 tx: RingBuffer<'d>, 16 tx_buf: RingBuffer,
27} 17}
28 18
29unsafe impl<'d, T: BasicInstance> Send for StateInner<'d, T> {} 19impl State {
30unsafe impl<'d, T: BasicInstance> Sync for StateInner<'d, T> {} 20 pub const fn new() -> Self {
21 Self {
22 rx_buf: RingBuffer::new(),
23 tx_buf: RingBuffer::new(),
24 rx_waker: AtomicWaker::new(),
25 tx_waker: AtomicWaker::new(),
26 }
27 }
28}
31 29
32pub struct BufferedUart<'d, T: BasicInstance> { 30pub struct BufferedUart<'d, T: BasicInstance> {
33 inner: RefCell<PeripheralMutex<'d, StateInner<'d, T>>>, 31 rx: BufferedUartRx<'d, T>,
32 tx: BufferedUartTx<'d, T>,
34} 33}
35 34
36pub struct BufferedUartTx<'u, 'd, T: BasicInstance> { 35pub struct BufferedUartTx<'d, T: BasicInstance> {
37 inner: &'u BufferedUart<'d, T>, 36 phantom: PhantomData<&'d mut T>,
38} 37}
39 38
40pub struct BufferedUartRx<'u, 'd, T: BasicInstance> { 39pub struct BufferedUartRx<'d, T: BasicInstance> {
41 inner: &'u BufferedUart<'d, T>, 40 phantom: PhantomData<&'d mut T>,
42} 41}
43 42
44impl<'d, T: BasicInstance> Unpin for BufferedUart<'d, T> {}
45
46impl<'d, T: BasicInstance> BufferedUart<'d, T> { 43impl<'d, T: BasicInstance> BufferedUart<'d, T> {
47 pub fn new( 44 pub fn new(
48 state: &'d mut State<'d, T>,
49 peri: impl Peripheral<P = T> + 'd, 45 peri: impl Peripheral<P = T> + 'd,
46 irq: impl Peripheral<P = T::Interrupt> + 'd,
50 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 47 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
51 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 48 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
52 irq: impl Peripheral<P = T::Interrupt> + 'd,
53 tx_buffer: &'d mut [u8], 49 tx_buffer: &'d mut [u8],
54 rx_buffer: &'d mut [u8], 50 rx_buffer: &'d mut [u8],
55 config: Config, 51 config: Config,
@@ -57,15 +53,14 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
57 T::enable(); 53 T::enable();
58 T::reset(); 54 T::reset();
59 55
60 Self::new_inner(state, peri, rx, tx, irq, tx_buffer, rx_buffer, config) 56 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
61 } 57 }
62 58
63 pub fn new_with_rtscts( 59 pub fn new_with_rtscts(
64 state: &'d mut State<'d, T>,
65 peri: impl Peripheral<P = T> + 'd, 60 peri: impl Peripheral<P = T> + 'd,
61 irq: impl Peripheral<P = T::Interrupt> + 'd,
66 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 62 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
67 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 63 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
68 irq: impl Peripheral<P = T::Interrupt> + 'd,
69 rts: impl Peripheral<P = impl RtsPin<T>> + 'd, 64 rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
70 cts: impl Peripheral<P = impl CtsPin<T>> + 'd, 65 cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
71 tx_buffer: &'d mut [u8], 66 tx_buffer: &'d mut [u8],
@@ -86,16 +81,15 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
86 }); 81 });
87 } 82 }
88 83
89 Self::new_inner(state, peri, rx, tx, irq, tx_buffer, rx_buffer, config) 84 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
90 } 85 }
91 86
92 #[cfg(not(usart_v1))] 87 #[cfg(not(usart_v1))]
93 pub fn new_with_de( 88 pub fn new_with_de(
94 state: &'d mut State<'d, T>,
95 peri: impl Peripheral<P = T> + 'd, 89 peri: impl Peripheral<P = T> + 'd,
90 irq: impl Peripheral<P = T::Interrupt> + 'd,
96 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 91 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
97 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 92 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
98 irq: impl Peripheral<P = T::Interrupt> + 'd,
99 de: impl Peripheral<P = impl DePin<T>> + 'd, 93 de: impl Peripheral<P = impl DePin<T>> + 'd,
100 tx_buffer: &'d mut [u8], 94 tx_buffer: &'d mut [u8],
101 rx_buffer: &'d mut [u8], 95 rx_buffer: &'d mut [u8],
@@ -113,23 +107,27 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
113 }); 107 });
114 } 108 }
115 109
116 Self::new_inner(state, peri, rx, tx, irq, tx_buffer, rx_buffer, config) 110 Self::new_inner(peri, irq, rx, tx, tx_buffer, rx_buffer, config)
117 } 111 }
118 112
119 fn new_inner( 113 fn new_inner(
120 state: &'d mut State<'d, T>,
121 _peri: impl Peripheral<P = T> + 'd, 114 _peri: impl Peripheral<P = T> + 'd,
115 irq: impl Peripheral<P = T::Interrupt> + 'd,
122 rx: impl Peripheral<P = impl RxPin<T>> + 'd, 116 rx: impl Peripheral<P = impl RxPin<T>> + 'd,
123 tx: impl Peripheral<P = impl TxPin<T>> + 'd, 117 tx: impl Peripheral<P = impl TxPin<T>> + 'd,
124 irq: impl Peripheral<P = T::Interrupt> + 'd,
125 tx_buffer: &'d mut [u8], 118 tx_buffer: &'d mut [u8],
126 rx_buffer: &'d mut [u8], 119 rx_buffer: &'d mut [u8],
127 config: Config, 120 config: Config,
128 ) -> BufferedUart<'d, T> { 121 ) -> BufferedUart<'d, T> {
129 into_ref!(_peri, rx, tx, irq); 122 into_ref!(_peri, rx, tx, irq);
130 123
131 let r = T::regs(); 124 let state = T::buffered_state();
125 let len = tx_buffer.len();
126 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
127 let len = rx_buffer.len();
128 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
132 129
130 let r = T::regs();
133 unsafe { 131 unsafe {
134 rx.set_as_af(rx.af_num(), AFType::Input); 132 rx.set_as_af(rx.af_num(), AFType::Input);
135 tx.set_as_af(tx.af_num(), AFType::OutputPushPull); 133 tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
@@ -147,273 +145,259 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
147 }); 145 });
148 } 146 }
149 147
150 Self { 148 irq.set_handler(on_interrupt::<T>);
151 inner: RefCell::new(PeripheralMutex::new(irq, &mut state.0, move || StateInner { 149 irq.unpend();
152 phantom: PhantomData, 150 irq.enable();
153 tx: RingBuffer::new(tx_buffer),
154 tx_waker: WakerRegistration::new(),
155 151
156 rx: RingBuffer::new(rx_buffer), 152 Self {
157 rx_waker: WakerRegistration::new(), 153 rx: BufferedUartRx { phantom: PhantomData },
158 })), 154 tx: BufferedUartTx { phantom: PhantomData },
159 } 155 }
160 } 156 }
161 157
162 pub fn split<'u>(&'u mut self) -> (BufferedUartRx<'u, 'd, T>, BufferedUartTx<'u, 'd, T>) { 158 pub fn split(self) -> (BufferedUartTx<'d, T>, BufferedUartRx<'d, T>) {
163 (BufferedUartRx { inner: self }, BufferedUartTx { inner: self }) 159 (self.tx, self.rx)
164 } 160 }
161}
165 162
166 async fn inner_read<'a>(&'a self, buf: &'a mut [u8]) -> Result<usize, Error> { 163impl<'d, T: BasicInstance> BufferedUartRx<'d, T> {
164 async fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
167 poll_fn(move |cx| { 165 poll_fn(move |cx| {
168 let mut do_pend = false; 166 let state = T::buffered_state();
169 let mut inner = self.inner.borrow_mut(); 167 let mut rx_reader = unsafe { state.rx_buf.reader() };
170 let res = inner.with(|state| { 168 let data = rx_reader.pop_slice();
171 compiler_fence(Ordering::SeqCst);
172
173 // We have data ready in buffer? Return it.
174 let data = state.rx.pop_buf();
175 if !data.is_empty() {
176 let len = data.len().min(buf.len());
177 buf[..len].copy_from_slice(&data[..len]);
178
179 if state.rx.is_full() {
180 do_pend = true;
181 }
182 state.rx.pop(len);
183
184 return Poll::Ready(Ok(len));
185 }
186 169
187 state.rx_waker.register(cx.waker()); 170 if !data.is_empty() {
188 Poll::Pending 171 let len = data.len().min(buf.len());
189 }); 172 buf[..len].copy_from_slice(&data[..len]);
173
174 let do_pend = state.rx_buf.is_full();
175 rx_reader.pop_done(len);
190 176
191 if do_pend { 177 if do_pend {
192 inner.pend(); 178 unsafe { T::Interrupt::steal().pend() };
179 }
180
181 return Poll::Ready(Ok(len));
193 } 182 }
194 183
195 res 184 state.rx_waker.register(cx.waker());
185 Poll::Pending
196 }) 186 })
197 .await 187 .await
198 } 188 }
199 189
200 fn inner_blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> { 190 fn blocking_read(&self, buf: &mut [u8]) -> Result<usize, Error> {
201 loop { 191 loop {
202 let mut do_pend = false; 192 let state = T::buffered_state();
203 let mut inner = self.inner.borrow_mut(); 193 let mut rx_reader = unsafe { state.rx_buf.reader() };
204 let n = inner.with(|state| { 194 let data = rx_reader.pop_slice();
205 compiler_fence(Ordering::SeqCst);
206
207 // We have data ready in buffer? Return it.
208 let data = state.rx.pop_buf();
209 if !data.is_empty() {
210 let len = data.len().min(buf.len());
211 buf[..len].copy_from_slice(&data[..len]);
212
213 if state.rx.is_full() {
214 do_pend = true;
215 }
216 state.rx.pop(len);
217
218 return len;
219 }
220 195
221 0 196 if !data.is_empty() {
222 }); 197 let len = data.len().min(buf.len());
198 buf[..len].copy_from_slice(&data[..len]);
199
200 let do_pend = state.rx_buf.is_full();
201 rx_reader.pop_done(len);
202
203 if do_pend {
204 unsafe { T::Interrupt::steal().pend() };
205 }
223 206
224 if do_pend { 207 return Ok(len);
225 inner.pend();
226 } 208 }
209 }
210 }
227 211
228 if n > 0 { 212 async fn fill_buf(&self) -> Result<&[u8], Error> {
229 return Ok(n); 213 poll_fn(move |cx| {
214 let state = T::buffered_state();
215 let mut rx_reader = unsafe { state.rx_buf.reader() };
216 let (p, n) = rx_reader.pop_buf();
217 if n == 0 {
218 state.rx_waker.register(cx.waker());
219 return Poll::Pending;
230 } 220 }
221
222 let buf = unsafe { slice::from_raw_parts(p, n) };
223 Poll::Ready(Ok(buf))
224 })
225 .await
226 }
227
228 fn consume(&self, amt: usize) {
229 let state = T::buffered_state();
230 let mut rx_reader = unsafe { state.rx_buf.reader() };
231 let full = state.rx_buf.is_full();
232 rx_reader.pop_done(amt);
233 if full {
234 unsafe { T::Interrupt::steal().pend() };
231 } 235 }
232 } 236 }
237}
233 238
234 async fn inner_write<'a>(&'a self, buf: &'a [u8]) -> Result<usize, Error> { 239impl<'d, T: BasicInstance> BufferedUartTx<'d, T> {
240 async fn write(&self, buf: &[u8]) -> Result<usize, Error> {
235 poll_fn(move |cx| { 241 poll_fn(move |cx| {
236 let mut inner = self.inner.borrow_mut(); 242 let state = T::buffered_state();
237 let (poll, empty) = inner.with(|state| { 243 let empty = state.tx_buf.is_empty();
238 let empty = state.tx.is_empty(); 244
239 let tx_buf = state.tx.push_buf(); 245 let mut tx_writer = unsafe { state.tx_buf.writer() };
240 if tx_buf.is_empty() { 246 let data = tx_writer.push_slice();
241 state.tx_waker.register(cx.waker()); 247 if data.is_empty() {
242 return (Poll::Pending, empty); 248 state.tx_waker.register(cx.waker());
243 } 249 return Poll::Pending;
250 }
244 251
245 let n = core::cmp::min(tx_buf.len(), buf.len()); 252 let n = data.len().min(buf.len());
246 tx_buf[..n].copy_from_slice(&buf[..n]); 253 data[..n].copy_from_slice(&buf[..n]);
247 state.tx.push(n); 254 tx_writer.push_done(n);
248 255
249 (Poll::Ready(Ok(n)), empty)
250 });
251 if empty { 256 if empty {
252 inner.pend(); 257 unsafe { T::Interrupt::steal() }.pend();
253 } 258 }
254 poll 259
260 Poll::Ready(Ok(n))
255 }) 261 })
256 .await 262 .await
257 } 263 }
258 264
259 async fn inner_flush<'a>(&'a self) -> Result<(), Error> { 265 async fn flush(&self) -> Result<(), Error> {
260 poll_fn(move |cx| { 266 poll_fn(move |cx| {
261 self.inner.borrow_mut().with(|state| { 267 let state = T::buffered_state();
262 if !state.tx.is_empty() { 268 if !state.tx_buf.is_empty() {
263 state.tx_waker.register(cx.waker()); 269 state.tx_waker.register(cx.waker());
264 return Poll::Pending; 270 return Poll::Pending;
265 } 271 }
266 272
267 Poll::Ready(Ok(())) 273 Poll::Ready(Ok(()))
268 })
269 }) 274 })
270 .await 275 .await
271 } 276 }
272 277
273 fn inner_blocking_write(&self, buf: &[u8]) -> Result<usize, Error> { 278 fn blocking_write(&self, buf: &[u8]) -> Result<usize, Error> {
274 loop { 279 loop {
275 let mut inner = self.inner.borrow_mut(); 280 let state = T::buffered_state();
276 let (n, empty) = inner.with(|state| { 281 let empty = state.tx_buf.is_empty();
277 let empty = state.tx.is_empty(); 282
278 let tx_buf = state.tx.push_buf(); 283 let mut tx_writer = unsafe { state.tx_buf.writer() };
279 if tx_buf.is_empty() { 284 let data = tx_writer.push_slice();
280 return (0, empty); 285 if !data.is_empty() {
286 let n = data.len().min(buf.len());
287 data[..n].copy_from_slice(&buf[..n]);
288 tx_writer.push_done(n);
289
290 if empty {
291 unsafe { T::Interrupt::steal() }.pend();
281 } 292 }
282 293
283 let n = core::cmp::min(tx_buf.len(), buf.len());
284 tx_buf[..n].copy_from_slice(&buf[..n]);
285 state.tx.push(n);
286
287 (n, empty)
288 });
289 if empty {
290 inner.pend();
291 }
292 if n != 0 {
293 return Ok(n); 294 return Ok(n);
294 } 295 }
295 } 296 }
296 } 297 }
297 298
298 fn inner_blocking_flush(&self) -> Result<(), Error> { 299 fn blocking_flush(&self) -> Result<(), Error> {
299 loop { 300 loop {
300 if !self.inner.borrow_mut().with(|state| state.tx.is_empty()) { 301 let state = T::buffered_state();
302 if state.tx_buf.is_empty() {
301 return Ok(()); 303 return Ok(());
302 } 304 }
303 } 305 }
304 } 306 }
307}
305 308
306 async fn inner_fill_buf<'a>(&'a self) -> Result<&'a [u8], Error> { 309impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> {
307 poll_fn(move |cx| { 310 fn drop(&mut self) {
308 self.inner.borrow_mut().with(|state| { 311 let state = T::buffered_state();
309 compiler_fence(Ordering::SeqCst); 312 unsafe {
310 313 state.rx_buf.deinit();
311 // We have data ready in buffer? Return it.
312 let buf = state.rx.pop_buf();
313 if !buf.is_empty() {
314 let buf: &[u8] = buf;
315 // Safety: buffer lives as long as uart
316 let buf: &[u8] = unsafe { core::mem::transmute(buf) };
317 return Poll::Ready(Ok(buf));
318 }
319
320 state.rx_waker.register(cx.waker());
321 Poll::<Result<&[u8], Error>>::Pending
322 })
323 })
324 .await
325 }
326 314
327 fn inner_consume(&self, amt: usize) { 315 // TX is inactive if the the buffer is not available.
328 let mut inner = self.inner.borrow_mut(); 316 // We can now unregister the interrupt handler
329 let signal = inner.with(|state| { 317 if state.tx_buf.len() == 0 {
330 let full = state.rx.is_full(); 318 T::Interrupt::steal().disable();
331 state.rx.pop(amt); 319 }
332 full
333 });
334 if signal {
335 inner.pend();
336 } 320 }
337 } 321 }
338} 322}
339 323
340impl<'d, T: BasicInstance> StateInner<'d, T> 324impl<'d, T: BasicInstance> Drop for BufferedUartTx<'d, T> {
341where 325 fn drop(&mut self) {
342 Self: 'd, 326 let state = T::buffered_state();
343{
344 fn on_rx(&mut self) {
345 let r = T::regs();
346 unsafe { 327 unsafe {
347 let sr = sr(r).read(); 328 state.tx_buf.deinit();
348 clear_interrupt_flags(r, sr);
349 329
350 // This read also clears the error and idle interrupt flags on v1. 330 // RX is inactive if the the buffer is not available.
351 let b = rdr(r).read_volatile(); 331 // We can now unregister the interrupt handler
332 if state.rx_buf.len() == 0 {
333 T::Interrupt::steal().disable();
334 }
335 }
336 }
337}
352 338
353 if sr.rxne() { 339unsafe fn on_interrupt<T: BasicInstance>(_: *mut ()) {
354 if sr.pe() { 340 let r = T::regs();
355 warn!("Parity error"); 341 let state = T::buffered_state();
356 }
357 if sr.fe() {
358 warn!("Framing error");
359 }
360 if sr.ne() {
361 warn!("Noise error");
362 }
363 if sr.ore() {
364 warn!("Overrun error");
365 }
366 342
367 let buf = self.rx.push_buf(); 343 // RX
368 if !buf.is_empty() { 344 unsafe {
369 buf[0] = b; 345 let sr = sr(r).read();
370 self.rx.push(1); 346 clear_interrupt_flags(r, sr);
371 } else {
372 warn!("RX buffer full, discard received byte");
373 }
374 347
375 if self.rx.is_full() { 348 if sr.rxne() {
376 self.rx_waker.wake(); 349 if sr.pe() {
377 } 350 warn!("Parity error");
351 }
352 if sr.fe() {
353 warn!("Framing error");
354 }
355 if sr.ne() {
356 warn!("Noise error");
357 }
358 if sr.ore() {
359 warn!("Overrun error");
378 } 360 }
379 361
380 if sr.idle() { 362 let mut rx_writer = state.rx_buf.writer();
381 self.rx_waker.wake(); 363 let buf = rx_writer.push_slice();
382 }; 364 if !buf.is_empty() {
383 } 365 // This read also clears the error and idle interrupt flags on v1.
384 } 366 buf[0] = rdr(r).read_volatile();
367 rx_writer.push_done(1);
368 } else {
369 // FIXME: Should we disable any further RX interrupts when the buffer becomes full.
370 }
385 371
386 fn on_tx(&mut self) { 372 if state.rx_buf.is_full() {
387 let r = T::regs(); 373 state.rx_waker.wake();
388 unsafe {
389 if sr(r).read().txe() {
390 let buf = self.tx.pop_buf();
391 if !buf.is_empty() {
392 r.cr1().modify(|w| {
393 w.set_txeie(true);
394 });
395 tdr(r).write_volatile(buf[0].into());
396 self.tx.pop(1);
397 self.tx_waker.wake();
398 } else {
399 // Disable interrupt until we have something to transmit again
400 r.cr1().modify(|w| {
401 w.set_txeie(false);
402 });
403 }
404 } 374 }
405 } 375 }
406 }
407}
408 376
409impl<'d, T: BasicInstance> PeripheralState for StateInner<'d, T> 377 if sr.idle() {
410where 378 state.rx_waker.wake();
411 Self: 'd, 379 };
412{ 380 }
413 type Interrupt = T::Interrupt; 381
414 fn on_interrupt(&mut self) { 382 // TX
415 self.on_rx(); 383 unsafe {
416 self.on_tx(); 384 if sr(r).read().txe() {
385 let mut tx_reader = state.tx_buf.reader();
386 let buf = tx_reader.pop_slice();
387 if !buf.is_empty() {
388 r.cr1().modify(|w| {
389 w.set_txeie(true);
390 });
391 tdr(r).write_volatile(buf[0].into());
392 tx_reader.pop_done(1);
393 state.tx_waker.wake();
394 } else {
395 // Disable interrupt until we have something to transmit again
396 r.cr1().modify(|w| {
397 w.set_txeie(false);
398 });
399 }
400 }
417 } 401 }
418} 402}
419 403
@@ -427,94 +411,284 @@ impl<'d, T: BasicInstance> embedded_io::Io for BufferedUart<'d, T> {
427 type Error = Error; 411 type Error = Error;
428} 412}
429 413
430impl<'u, 'd, T: BasicInstance> embedded_io::Io for BufferedUartRx<'u, 'd, T> { 414impl<'d, T: BasicInstance> embedded_io::Io for BufferedUartRx<'d, T> {
431 type Error = Error; 415 type Error = Error;
432} 416}
433 417
434impl<'u, 'd, T: BasicInstance> embedded_io::Io for BufferedUartTx<'u, 'd, T> { 418impl<'d, T: BasicInstance> embedded_io::Io for BufferedUartTx<'d, T> {
435 type Error = Error; 419 type Error = Error;
436} 420}
437 421
438impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUart<'d, T> { 422impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUart<'d, T> {
439 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 423 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
440 self.inner_read(buf).await 424 self.rx.read(buf).await
441 } 425 }
442} 426}
443 427
444impl<'u, 'd, T: BasicInstance> embedded_io::asynch::Read for BufferedUartRx<'u, 'd, T> { 428impl<'d, T: BasicInstance> embedded_io::asynch::Read for BufferedUartRx<'d, T> {
445 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 429 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
446 self.inner.inner_read(buf).await 430 Self::read(self, buf).await
447 } 431 }
448} 432}
449 433
450impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T> { 434impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUart<'d, T> {
451 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 435 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
452 self.inner_fill_buf().await 436 self.rx.fill_buf().await
453 } 437 }
454 438
455 fn consume(&mut self, amt: usize) { 439 fn consume(&mut self, amt: usize) {
456 self.inner_consume(amt) 440 self.rx.consume(amt)
457 } 441 }
458} 442}
459 443
460impl<'u, 'd, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUartRx<'u, 'd, T> { 444impl<'d, T: BasicInstance> embedded_io::asynch::BufRead for BufferedUartRx<'d, T> {
461 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { 445 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
462 self.inner.inner_fill_buf().await 446 Self::fill_buf(self).await
463 } 447 }
464 448
465 fn consume(&mut self, amt: usize) { 449 fn consume(&mut self, amt: usize) {
466 self.inner.inner_consume(amt) 450 Self::consume(self, amt)
467 } 451 }
468} 452}
469 453
470impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUart<'d, T> { 454impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUart<'d, T> {
471 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 455 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
472 self.inner_write(buf).await 456 self.tx.write(buf).await
473 } 457 }
474 458
475 async fn flush(&mut self) -> Result<(), Self::Error> { 459 async fn flush(&mut self) -> Result<(), Self::Error> {
476 self.inner_flush().await 460 self.tx.flush().await
477 } 461 }
478} 462}
479 463
480impl<'u, 'd, T: BasicInstance> embedded_io::asynch::Write for BufferedUartTx<'u, 'd, T> { 464impl<'d, T: BasicInstance> embedded_io::asynch::Write for BufferedUartTx<'d, T> {
481 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 465 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
482 self.inner.inner_write(buf).await 466 Self::write(self, buf).await
483 } 467 }
484 468
485 async fn flush(&mut self) -> Result<(), Self::Error> { 469 async fn flush(&mut self) -> Result<(), Self::Error> {
486 self.inner.inner_flush().await 470 Self::flush(self).await
487 } 471 }
488} 472}
489 473
490impl<'d, T: BasicInstance> embedded_io::blocking::Read for BufferedUart<'d, T> { 474impl<'d, T: BasicInstance> embedded_io::blocking::Read for BufferedUart<'d, T> {
491 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 475 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
492 self.inner_blocking_read(buf) 476 self.rx.blocking_read(buf)
493 } 477 }
494} 478}
495 479
496impl<'u, 'd, T: BasicInstance> embedded_io::blocking::Read for BufferedUartRx<'u, 'd, T> { 480impl<'d, T: BasicInstance> embedded_io::blocking::Read for BufferedUartRx<'d, T> {
497 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { 481 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
498 self.inner.inner_blocking_read(buf) 482 self.blocking_read(buf)
499 } 483 }
500} 484}
501 485
502impl<'d, T: BasicInstance> embedded_io::blocking::Write for BufferedUart<'d, T> { 486impl<'d, T: BasicInstance> embedded_io::blocking::Write for BufferedUart<'d, T> {
503 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 487 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
504 self.inner_blocking_write(buf) 488 self.tx.blocking_write(buf)
505 } 489 }
506 490
507 fn flush(&mut self) -> Result<(), Self::Error> { 491 fn flush(&mut self) -> Result<(), Self::Error> {
508 self.inner_blocking_flush() 492 self.tx.blocking_flush()
509 } 493 }
510} 494}
511 495
512impl<'u, 'd, T: BasicInstance> embedded_io::blocking::Write for BufferedUartTx<'u, 'd, T> { 496impl<'d, T: BasicInstance> embedded_io::blocking::Write for BufferedUartTx<'d, T> {
513 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { 497 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
514 self.inner.inner_blocking_write(buf) 498 Self::blocking_write(self, buf)
515 } 499 }
516 500
517 fn flush(&mut self) -> Result<(), Self::Error> { 501 fn flush(&mut self) -> Result<(), Self::Error> {
518 self.inner.inner_blocking_flush() 502 Self::blocking_flush(self)
503 }
504}
505
506mod eh02 {
507 use super::*;
508
509 impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUartRx<'d, T> {
510 type Error = Error;
511
512 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
513 let r = T::regs();
514 unsafe {
515 let sr = sr(r).read();
516 if sr.pe() {
517 rdr(r).read_volatile();
518 Err(nb::Error::Other(Error::Parity))
519 } else if sr.fe() {
520 rdr(r).read_volatile();
521 Err(nb::Error::Other(Error::Framing))
522 } else if sr.ne() {
523 rdr(r).read_volatile();
524 Err(nb::Error::Other(Error::Noise))
525 } else if sr.ore() {
526 rdr(r).read_volatile();
527 Err(nb::Error::Other(Error::Overrun))
528 } else if sr.rxne() {
529 Ok(rdr(r).read_volatile())
530 } else {
531 Err(nb::Error::WouldBlock)
532 }
533 }
534 }
535 }
536
537 impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx<'d, T> {
538 type Error = Error;
539
540 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
541 while !buffer.is_empty() {
542 match self.blocking_write(buffer) {
543 Ok(0) => panic!("zero-length write."),
544 Ok(n) => buffer = &buffer[n..],
545 Err(e) => return Err(e),
546 }
547 }
548 Ok(())
549 }
550
551 fn bflush(&mut self) -> Result<(), Self::Error> {
552 self.blocking_flush()
553 }
554 }
555
556 impl<'d, T: BasicInstance> embedded_hal_02::serial::Read<u8> for BufferedUart<'d, T> {
557 type Error = Error;
558
559 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
560 embedded_hal_02::serial::Read::read(&mut self.rx)
561 }
562 }
563
564 impl<'d, T: BasicInstance> embedded_hal_02::blocking::serial::Write<u8> for BufferedUart<'d, T> {
565 type Error = Error;
566
567 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
568 while !buffer.is_empty() {
569 match self.tx.blocking_write(buffer) {
570 Ok(0) => panic!("zero-length write."),
571 Ok(n) => buffer = &buffer[n..],
572 Err(e) => return Err(e),
573 }
574 }
575 Ok(())
576 }
577
578 fn bflush(&mut self) -> Result<(), Self::Error> {
579 self.tx.blocking_flush()
580 }
581 }
582}
583
584#[cfg(feature = "unstable-traits")]
585mod eh1 {
586 use super::*;
587
588 impl<'d, T: BasicInstance> embedded_hal_1::serial::ErrorType for BufferedUart<'d, T> {
589 type Error = Error;
590 }
591
592 impl<'d, T: BasicInstance> embedded_hal_1::serial::ErrorType for BufferedUartTx<'d, T> {
593 type Error = Error;
594 }
595
596 impl<'d, T: BasicInstance> embedded_hal_1::serial::ErrorType for BufferedUartRx<'d, T> {
597 type Error = Error;
598 }
599
600 impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUartRx<'d, T> {
601 fn read(&mut self) -> nb::Result<u8, Self::Error> {
602 embedded_hal_02::serial::Read::read(self)
603 }
604 }
605
606 impl<'d, T: BasicInstance> embedded_hal_1::serial::Write for BufferedUartTx<'d, T> {
607 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
608 self.blocking_write(buffer).map(drop)
609 }
610
611 fn flush(&mut self) -> Result<(), Self::Error> {
612 self.blocking_flush()
613 }
614 }
615
616 impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUartTx<'d, T> {
617 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
618 self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
619 }
620
621 fn flush(&mut self) -> nb::Result<(), Self::Error> {
622 self.blocking_flush().map_err(nb::Error::Other)
623 }
624 }
625
626 impl<'d, T: BasicInstance> embedded_hal_nb::serial::Read for BufferedUart<'d, T> {
627 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
628 embedded_hal_02::serial::Read::read(&mut self.rx)
629 }
630 }
631
632 impl<'d, T: BasicInstance> embedded_hal_1::serial::Write for BufferedUart<'d, T> {
633 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
634 self.tx.blocking_write(buffer).map(drop)
635 }
636
637 fn flush(&mut self) -> Result<(), Self::Error> {
638 self.tx.blocking_flush()
639 }
640 }
641
642 impl<'d, T: BasicInstance> embedded_hal_nb::serial::Write for BufferedUart<'d, T> {
643 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
644 self.tx.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
645 }
646
647 fn flush(&mut self) -> nb::Result<(), Self::Error> {
648 self.tx.blocking_flush().map_err(nb::Error::Other)
649 }
650 }
651}
652
653#[cfg(all(
654 feature = "unstable-traits",
655 feature = "nightly",
656 feature = "_todo_embedded_hal_serial"
657))]
658mod eha {
659 use core::future::Future;
660
661 use super::*;
662
663 impl<'d, T: BasicInstance> embedded_hal_async::serial::Write for BufferedUartTx<'d, T> {
664 async fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
665 Self::write(buf)
666 }
667
668 async fn flush(&mut self) -> Result<(), Self::Error> {
669 Self::flush()
670 }
671 }
672
673 impl<'d, T: BasicInstance> embedded_hal_async::serial::Read for BufferedUartRx<'d, T> {
674 async fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
675 Self::read(buf)
676 }
677 }
678
679 impl<'d, T: BasicInstance> embedded_hal_async::serial::Write for BufferedUart<'d, T> {
680 async fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
681 self.tx.write(buf)
682 }
683
684 async fn flush(&mut self) -> Result<(), Self::Error> {
685 self.tx.flush()
686 }
687 }
688
689 impl<'d, T: BasicInstance> embedded_hal_async::serial::Read for BufferedUart<'d, T> {
690 async fn read(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
691 self.rx.read(buf)
692 }
519 } 693 }
520} 694}
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs
index f80323e37..a42eede18 100644
--- a/embassy-stm32/src/usart/mod.rs
+++ b/embassy-stm32/src/usart/mod.rs
@@ -1112,6 +1112,9 @@ pub(crate) mod sealed {
1112 1112
1113 fn regs() -> Regs; 1113 fn regs() -> Regs;
1114 fn state() -> &'static State; 1114 fn state() -> &'static State;
1115
1116 #[cfg(feature = "nightly")]
1117 fn buffered_state() -> &'static buffered::State;
1115 } 1118 }
1116 1119
1117 pub trait FullInstance: BasicInstance { 1120 pub trait FullInstance: BasicInstance {
@@ -1147,6 +1150,12 @@ macro_rules! impl_lpuart {
1147 static STATE: crate::usart::sealed::State = crate::usart::sealed::State::new(); 1150 static STATE: crate::usart::sealed::State = crate::usart::sealed::State::new();
1148 &STATE 1151 &STATE
1149 } 1152 }
1153
1154 #[cfg(feature = "nightly")]
1155 fn buffered_state() -> &'static buffered::State {
1156 static STATE: buffered::State = buffered::State::new();
1157 &STATE
1158 }
1150 } 1159 }
1151 1160
1152 impl BasicInstance for peripherals::$inst {} 1161 impl BasicInstance for peripherals::$inst {}
diff --git a/examples/stm32f4/src/bin/usart_buffered.rs b/examples/stm32f4/src/bin/usart_buffered.rs
index dd171fe13..a93f8baeb 100644
--- a/examples/stm32f4/src/bin/usart_buffered.rs
+++ b/examples/stm32f4/src/bin/usart_buffered.rs
@@ -5,7 +5,7 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::interrupt; 7use embassy_stm32::interrupt;
8use embassy_stm32::usart::{BufferedUart, Config, State}; 8use embassy_stm32::usart::{BufferedUart, Config};
9use embedded_io::asynch::BufRead; 9use embedded_io::asynch::BufRead;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
@@ -16,20 +16,10 @@ async fn main(_spawner: Spawner) {
16 16
17 let config = Config::default(); 17 let config = Config::default();
18 18
19 let mut state = State::new();
20 let irq = interrupt::take!(USART3); 19 let irq = interrupt::take!(USART3);
21 let mut tx_buf = [0u8; 32]; 20 let mut tx_buf = [0u8; 32];
22 let mut rx_buf = [0u8; 32]; 21 let mut rx_buf = [0u8; 32];
23 let mut buf_usart = BufferedUart::new( 22 let mut buf_usart = BufferedUart::new(p.USART3, irq, p.PD9, p.PD8, &mut tx_buf, &mut rx_buf, config);
24 &mut state,
25 p.USART3,
26 p.PD9,
27 p.PD8,
28 irq,
29 &mut tx_buf,
30 &mut rx_buf,
31 config,
32 );
33 23
34 loop { 24 loop {
35 let buf = buf_usart.fill_buf().await.unwrap(); 25 let buf = buf_usart.fill_buf().await.unwrap();
diff --git a/examples/stm32l0/src/bin/usart_irq.rs b/examples/stm32l0/src/bin/usart_irq.rs
index 8e84cd092..465347004 100644
--- a/examples/stm32l0/src/bin/usart_irq.rs
+++ b/examples/stm32l0/src/bin/usart_irq.rs
@@ -5,7 +5,7 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::interrupt; 7use embassy_stm32::interrupt;
8use embassy_stm32::usart::{BufferedUart, Config, State}; 8use embassy_stm32::usart::{BufferedUart, Config};
9use embedded_io::asynch::{Read, Write}; 9use embedded_io::asynch::{Read, Write};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
@@ -20,20 +20,8 @@ async fn main(_spawner: Spawner) {
20 let mut config = Config::default(); 20 let mut config = Config::default();
21 config.baudrate = 9600; 21 config.baudrate = 9600;
22 22
23 let mut state = State::new();
24 let irq = interrupt::take!(USART2); 23 let irq = interrupt::take!(USART2);
25 let mut usart = unsafe { 24 let mut usart = unsafe { BufferedUart::new(p.USART2, irq, p.PA3, p.PA2, &mut TX_BUFFER, &mut RX_BUFFER, config) };
26 BufferedUart::new(
27 &mut state,
28 p.USART2,
29 p.PA3,
30 p.PA2,
31 irq,
32 &mut TX_BUFFER,
33 &mut RX_BUFFER,
34 config,
35 )
36 };
37 25
38 usart.write_all(b"Hello Embassy World!\r\n").await.unwrap(); 26 usart.write_all(b"Hello Embassy World!\r\n").await.unwrap();
39 info!("wrote Hello, starting echo"); 27 info!("wrote Hello, starting echo");