aboutsummaryrefslogtreecommitdiff
path: root/embassy-mspm0
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mspm0')
-rw-r--r--embassy-mspm0/Cargo.toml4
-rw-r--r--embassy-mspm0/src/uart/buffered.rs1060
-rw-r--r--embassy-mspm0/src/uart/mod.rs (renamed from embassy-mspm0/src/uart.rs)145
3 files changed, 1168 insertions, 41 deletions
diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml
index d2adc63d7..61afcd76d 100644
--- a/embassy-mspm0/Cargo.toml
+++ b/embassy-mspm0/Cargo.toml
@@ -36,7 +36,10 @@ embassy-embedded-hal = { version = "0.3.1", path = "../embassy-embedded-hal", de
36embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional = true } 36embassy-executor = { version = "0.7.0", path = "../embassy-executor", optional = true }
37 37
38embedded-hal = { version = "1.0" } 38embedded-hal = { version = "1.0" }
39embedded-hal-nb = { version = "1.0" }
39embedded-hal-async = { version = "1.0" } 40embedded-hal-async = { version = "1.0" }
41embedded-io = "0.6.1"
42embedded-io-async = "0.6.1"
40 43
41defmt = { version = "1.0.1", optional = true } 44defmt = { version = "1.0.1", optional = true }
42fixed = "1.29" 45fixed = "1.29"
@@ -51,6 +54,7 @@ mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag
51[build-dependencies] 54[build-dependencies]
52proc-macro2 = "1.0.94" 55proc-macro2 = "1.0.94"
53quote = "1.0.40" 56quote = "1.0.40"
57cfg_aliases = "0.2.1"
54 58
55# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } 59# mspm0-metapac = { version = "", default-features = false, features = ["metadata"] }
56mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-235158ac2865d8aac3a1eceb2d62026eb12bf38f", default-features = false, features = ["metadata"] } 60mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-235158ac2865d8aac3a1eceb2d62026eb12bf38f", default-features = false, features = ["metadata"] }
diff --git a/embassy-mspm0/src/uart/buffered.rs b/embassy-mspm0/src/uart/buffered.rs
new file mode 100644
index 000000000..cbc0b6c80
--- /dev/null
+++ b/embassy-mspm0/src/uart/buffered.rs
@@ -0,0 +1,1060 @@
1use core::future::{poll_fn, Future};
2use core::marker::PhantomData;
3use core::slice;
4use core::sync::atomic::{AtomicU8, Ordering};
5use core::task::Poll;
6
7use embassy_embedded_hal::SetConfig;
8use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
9use embassy_hal_internal::interrupt::InterruptExt;
10use embassy_sync::waitqueue::AtomicWaker;
11use embedded_hal_nb::nb;
12
13use crate::gpio::{AnyPin, SealedPin};
14use crate::interrupt::typelevel::Binding;
15use crate::pac::uart::Uart as Regs;
16use crate::uart::{Config, ConfigError, CtsPin, Error, Info, Instance, RtsPin, RxPin, State, TxPin};
17use crate::{interrupt, Peri};
18
19/// Interrupt handler.
20pub struct BufferedInterruptHandler<T: Instance> {
21 _uart: PhantomData<T>,
22}
23
24impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> {
25 unsafe fn on_interrupt() {
26 on_interrupt(T::info().regs, T::buffered_state())
27 }
28}
29
30/// Bidirectional buffered UART which acts as a combination of [`BufferedUartTx`] and [`BufferedUartRx`].
31pub struct BufferedUart<'d> {
32 rx: BufferedUartRx<'d>,
33 tx: BufferedUartTx<'d>,
34}
35
36impl SetConfig for BufferedUart<'_> {
37 type Config = Config;
38 type ConfigError = ConfigError;
39
40 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
41 self.set_config(config)
42 }
43}
44
45impl<'d> BufferedUart<'d> {
46 /// Create a new bidirectional buffered UART.
47 pub fn new<T: Instance>(
48 uart: Peri<'d, T>,
49 tx: Peri<'d, impl TxPin<T>>,
50 rx: Peri<'d, impl RxPin<T>>,
51 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
52 tx_buffer: &'d mut [u8],
53 rx_buffer: &'d mut [u8],
54 config: Config,
55 ) -> Result<Self, ConfigError> {
56 Self::new_inner(
57 uart,
58 new_pin!(rx, config.rx_pf()),
59 new_pin!(tx, config.tx_pf()),
60 None,
61 None,
62 tx_buffer,
63 rx_buffer,
64 config,
65 )
66 }
67
68 /// Create a new bidirectional buffered UART with request-to-send and clear-to-send pins
69 pub fn new_with_rtscts<T: Instance>(
70 uart: Peri<'d, T>,
71 tx: Peri<'d, impl TxPin<T>>,
72 rx: Peri<'d, impl RxPin<T>>,
73 rts: Peri<'d, impl RtsPin<T>>,
74 cts: Peri<'d, impl CtsPin<T>>,
75 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
76 tx_buffer: &'d mut [u8],
77 rx_buffer: &'d mut [u8],
78 config: Config,
79 ) -> Result<Self, ConfigError> {
80 Self::new_inner(
81 uart,
82 new_pin!(rx, config.rx_pf()),
83 new_pin!(tx, config.tx_pf()),
84 new_pin!(rts, config.rts_pf()),
85 new_pin!(cts, config.cts_pf()),
86 tx_buffer,
87 rx_buffer,
88 config,
89 )
90 }
91
92 /// Reconfigure the driver
93 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
94 self.tx.set_config(config)?;
95 self.rx.set_config(config)
96 }
97
98 /// Set baudrate
99 pub fn set_baudrate(&mut self, baudrate: u32) -> Result<(), ConfigError> {
100 self.rx.set_baudrate(baudrate)
101 }
102
103 /// Write to UART TX buffer, blocking execution until done.
104 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
105 self.tx.blocking_write(buffer)
106 }
107
108 /// Flush UART TX buffer, blocking execution until done.
109 pub fn blocking_flush(&mut self) -> Result<(), Error> {
110 self.tx.blocking_flush()
111 }
112
113 /// Check if UART is busy.
114 pub fn busy(&self) -> bool {
115 self.tx.busy()
116 }
117
118 /// Read from UART RX buffer, blocking execution until done.
119 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
120 self.rx.blocking_read(buffer)
121 }
122
123 /// Send break character.
124 pub fn send_break(&mut self) {
125 self.tx.send_break()
126 }
127
128 /// Split into separate RX and TX handles.
129 pub fn split(self) -> (BufferedUartTx<'d>, BufferedUartRx<'d>) {
130 (self.tx, self.rx)
131 }
132
133 /// Split into separate RX and TX handles.
134 pub fn split_ref(&mut self) -> (BufferedUartTx<'_>, BufferedUartRx<'_>) {
135 (
136 BufferedUartTx {
137 info: self.tx.info,
138 state: self.tx.state,
139 tx: self.tx.tx.as_mut().map(Peri::reborrow),
140 cts: self.tx.cts.as_mut().map(Peri::reborrow),
141 reborrowed: true,
142 },
143 BufferedUartRx {
144 info: self.rx.info,
145 state: self.rx.state,
146 rx: self.rx.rx.as_mut().map(Peri::reborrow),
147 rts: self.rx.rts.as_mut().map(Peri::reborrow),
148 reborrowed: true,
149 },
150 )
151 }
152}
153
154/// Rx-only buffered UART.
155///
156/// Can be obtained from [`BufferedUart::split`], or can be constructed independently,
157/// if you do not need the transmitting half of the driver.
158pub struct BufferedUartRx<'d> {
159 info: &'static Info,
160 state: &'static BufferedState,
161 rx: Option<Peri<'d, AnyPin>>,
162 rts: Option<Peri<'d, AnyPin>>,
163 reborrowed: bool,
164}
165
166impl SetConfig for BufferedUartRx<'_> {
167 type Config = Config;
168 type ConfigError = ConfigError;
169
170 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
171 self.set_config(config)
172 }
173}
174
175impl<'d> BufferedUartRx<'d> {
176 /// Create a new rx-only buffered UART with no hardware flow control.
177 ///
178 /// Useful if you only want Uart Rx. It saves 1 pin.
179 pub fn new<T: Instance>(
180 uart: Peri<'d, T>,
181 rx: Peri<'d, impl RxPin<T>>,
182 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
183 rx_buffer: &'d mut [u8],
184 config: Config,
185 ) -> Result<Self, ConfigError> {
186 Self::new_inner(uart, new_pin!(rx, config.rx_pf()), None, rx_buffer, config)
187 }
188
189 /// Create a new rx-only buffered UART with a request-to-send pin
190 pub fn new_with_rts<T: Instance>(
191 uart: Peri<'d, T>,
192 rx: Peri<'d, impl RxPin<T>>,
193 rts: Peri<'d, impl RtsPin<T>>,
194 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
195 rx_buffer: &'d mut [u8],
196 config: Config,
197 ) -> Result<Self, ConfigError> {
198 Self::new_inner(
199 uart,
200 new_pin!(rx, config.rx_pf()),
201 new_pin!(rts, config.rts_pf()),
202 rx_buffer,
203 config,
204 )
205 }
206
207 /// Reconfigure the driver
208 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
209 if let Some(ref rx) = self.rx {
210 rx.update_pf(config.rx_pf());
211 }
212
213 if let Some(ref rts) = self.rts {
214 rts.update_pf(config.rts_pf());
215 }
216
217 super::reconfigure(&self.info, &self.state.state, config)
218 }
219
220 /// Set baudrate
221 pub fn set_baudrate(&mut self, baudrate: u32) -> Result<(), ConfigError> {
222 super::set_baudrate(&self.info, self.state.state.clock.load(Ordering::Relaxed), baudrate)
223 }
224
225 /// Read from UART RX buffer, blocking execution until done.
226 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
227 self.blocking_read_inner(buffer)
228 }
229}
230
231impl Drop for BufferedUartRx<'_> {
232 fn drop(&mut self) {
233 if !self.reborrowed {
234 let state = self.state;
235
236 // SAFETY: RX is being dropped (and is not reborrowed), so the ring buffer must be deinitialized
237 // in order to meet the requirements of init.
238 unsafe {
239 state.rx_buf.deinit();
240 }
241
242 // TX is inactive if the buffer is not available. If this is true, then disable the
243 // interrupt handler since we are running in RX only mode.
244 if state.tx_buf.len() == 0 {
245 self.info.interrupt.disable();
246 }
247
248 self.rx.as_ref().map(|x| x.set_as_disconnected());
249 self.rts.as_ref().map(|x| x.set_as_disconnected());
250 }
251 }
252}
253
254/// Tx-only buffered UART.
255///
256/// Can be obtained from [`BufferedUart::split`], or can be constructed independently,
257/// if you do not need the receiving half of the driver.
258pub struct BufferedUartTx<'d> {
259 info: &'static Info,
260 state: &'static BufferedState,
261 tx: Option<Peri<'d, AnyPin>>,
262 cts: Option<Peri<'d, AnyPin>>,
263 reborrowed: bool,
264}
265
266impl SetConfig for BufferedUartTx<'_> {
267 type Config = Config;
268 type ConfigError = ConfigError;
269
270 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
271 self.set_config(config)
272 }
273}
274
275impl<'d> BufferedUartTx<'d> {
276 /// Create a new tx-only buffered UART with no hardware flow control.
277 ///
278 /// Useful if you only want Uart Tx. It saves 1 pin.
279 pub fn new<T: Instance>(
280 uart: Peri<'d, T>,
281 tx: Peri<'d, impl TxPin<T>>,
282 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
283 tx_buffer: &'d mut [u8],
284 config: Config,
285 ) -> Result<Self, ConfigError> {
286 Self::new_inner(uart, new_pin!(tx, config.tx_pf()), None, tx_buffer, config)
287 }
288
289 /// Create a new tx-only buffered UART with a clear-to-send pin
290 pub fn new_with_rts<T: Instance>(
291 uart: Peri<'d, T>,
292 tx: Peri<'d, impl TxPin<T>>,
293 cts: Peri<'d, impl CtsPin<T>>,
294 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
295 tx_buffer: &'d mut [u8],
296 config: Config,
297 ) -> Result<Self, ConfigError> {
298 Self::new_inner(
299 uart,
300 new_pin!(tx, config.tx_pf()),
301 new_pin!(cts, config.cts_pf()),
302 tx_buffer,
303 config,
304 )
305 }
306
307 /// Reconfigure the driver
308 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
309 if let Some(ref tx) = self.tx {
310 tx.update_pf(config.tx_pf());
311 }
312
313 if let Some(ref cts) = self.cts {
314 cts.update_pf(config.cts_pf());
315 }
316
317 super::reconfigure(self.info, &self.state.state, config)
318 }
319
320 /// Set baudrate
321 pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
322 super::set_baudrate(&self.info, self.state.state.clock.load(Ordering::Relaxed), baudrate)
323 }
324
325 /// Write to UART TX buffer, blocking execution until done.
326 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
327 self.blocking_write_inner(buffer)
328 }
329
330 /// Flush UART TX buffer, blocking execution until done.
331 pub fn blocking_flush(&mut self) -> Result<(), Error> {
332 let state = self.state;
333
334 loop {
335 if state.tx_buf.is_empty() {
336 return Ok(());
337 }
338 }
339 }
340
341 /// Check if UART is busy.
342 pub fn busy(&self) -> bool {
343 super::busy(self.info.regs)
344 }
345
346 /// Send break character
347 pub fn send_break(&mut self) {
348 let r = self.info.regs;
349
350 r.lcrh().modify(|w| {
351 w.set_brk(true);
352 });
353 }
354}
355
356impl Drop for BufferedUartTx<'_> {
357 fn drop(&mut self) {
358 if !self.reborrowed {
359 let state = self.state;
360
361 // SAFETY: TX is being dropped (and is not reborrowed), so the ring buffer must be deinitialized
362 // in order to meet the requirements of init.
363 unsafe {
364 state.tx_buf.deinit();
365 }
366
367 // RX is inactive if the buffer is not available. If this is true, then disable the
368 // interrupt handler since we are running in TX only mode.
369 if state.rx_buf.len() == 0 {
370 self.info.interrupt.disable();
371 }
372
373 self.tx.as_ref().map(|x| x.set_as_disconnected());
374 self.cts.as_ref().map(|x| x.set_as_disconnected());
375 }
376 }
377}
378
379impl embedded_io_async::ErrorType for BufferedUart<'_> {
380 type Error = Error;
381}
382
383impl embedded_io_async::ErrorType for BufferedUartRx<'_> {
384 type Error = Error;
385}
386
387impl embedded_io_async::ErrorType for BufferedUartTx<'_> {
388 type Error = Error;
389}
390
391impl embedded_io_async::Read for BufferedUart<'_> {
392 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
393 self.rx.read(buf).await
394 }
395}
396
397impl embedded_io_async::Read for BufferedUartRx<'_> {
398 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
399 self.read_inner(buf).await
400 }
401}
402
403impl embedded_io_async::ReadReady for BufferedUart<'_> {
404 fn read_ready(&mut self) -> Result<bool, Self::Error> {
405 self.rx.read_ready()
406 }
407}
408
409impl embedded_io_async::ReadReady for BufferedUartRx<'_> {
410 fn read_ready(&mut self) -> Result<bool, Self::Error> {
411 self.read_ready_inner()
412 }
413}
414
415impl embedded_io_async::BufRead for BufferedUart<'_> {
416 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
417 self.rx.fill_buf().await
418 }
419
420 fn consume(&mut self, amt: usize) {
421 self.rx.consume(amt);
422 }
423}
424
425impl embedded_io_async::BufRead for BufferedUartRx<'_> {
426 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
427 self.fill_buf_inner().await
428 }
429
430 fn consume(&mut self, amt: usize) {
431 self.consume_inner(amt);
432 }
433}
434
435impl embedded_io_async::Write for BufferedUart<'_> {
436 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
437 self.tx.write_inner(buf).await
438 }
439}
440
441impl embedded_io_async::Write for BufferedUartTx<'_> {
442 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
443 self.write_inner(buf).await
444 }
445
446 async fn flush(&mut self) -> Result<(), Self::Error> {
447 self.flush_inner().await
448 }
449}
450
451impl embedded_io::Read for BufferedUart<'_> {
452 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
453 self.rx.read(buf)
454 }
455}
456
457impl embedded_io::Read for BufferedUartRx<'_> {
458 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
459 self.blocking_read_inner(buf)
460 }
461}
462
463impl embedded_io::Write for BufferedUart<'_> {
464 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
465 self.tx.write(buf)
466 }
467
468 fn flush(&mut self) -> Result<(), Self::Error> {
469 self.tx.flush()
470 }
471}
472
473impl embedded_io::Write for BufferedUartTx<'_> {
474 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
475 self.blocking_write_inner(buf)
476 }
477
478 fn flush(&mut self) -> Result<(), Self::Error> {
479 self.blocking_flush()
480 }
481}
482
483impl embedded_hal_nb::serial::Error for Error {
484 fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
485 match self {
486 Error::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
487 Error::Noise => embedded_hal_nb::serial::ErrorKind::Noise,
488 Error::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
489 Error::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
490 Error::Break => embedded_hal_nb::serial::ErrorKind::Other,
491 }
492 }
493}
494
495impl embedded_hal_nb::serial::ErrorType for BufferedUart<'_> {
496 type Error = Error;
497}
498
499impl embedded_hal_nb::serial::ErrorType for BufferedUartRx<'_> {
500 type Error = Error;
501}
502
503impl embedded_hal_nb::serial::ErrorType for BufferedUartTx<'_> {
504 type Error = Error;
505}
506
507impl embedded_hal_nb::serial::Read for BufferedUart<'_> {
508 fn read(&mut self) -> nb::Result<u8, Self::Error> {
509 self.rx.read()
510 }
511}
512
513impl embedded_hal_nb::serial::Read for BufferedUartRx<'_> {
514 fn read(&mut self) -> nb::Result<u8, Self::Error> {
515 if self.info.regs.stat().read().rxfe() {
516 return Err(nb::Error::WouldBlock);
517 }
518
519 super::read_with_error(self.info.regs).map_err(nb::Error::Other)
520 }
521}
522
523impl embedded_hal_nb::serial::Write for BufferedUart<'_> {
524 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
525 self.tx.write(word)
526 }
527
528 fn flush(&mut self) -> nb::Result<(), Self::Error> {
529 self.tx.flush()
530 }
531}
532
533impl embedded_hal_nb::serial::Write for BufferedUartTx<'_> {
534 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
535 self.blocking_write(&[word]).map(drop).map_err(nb::Error::Other)
536 }
537
538 fn flush(&mut self) -> nb::Result<(), Self::Error> {
539 self.blocking_flush().map_err(nb::Error::Other)
540 }
541}
542
543// Impl details
544
545/// Buffered UART state.
546pub(crate) struct BufferedState {
547 /// non-buffered UART state. This is inline in order to avoid [`BufferedUartRx`]/Tx
548 /// needing to carry around a 2nd static reference and waste another 4 bytes.
549 state: State,
550 rx_waker: AtomicWaker,
551 rx_buf: RingBuffer,
552 tx_waker: AtomicWaker,
553 tx_buf: RingBuffer,
554 rx_error: AtomicU8,
555}
556
557// these must match bits 8..12 in RXDATA, but shifted by 8 to the right
558const RXE_NOISE: u8 = 16;
559const RXE_OVERRUN: u8 = 8;
560const RXE_BREAK: u8 = 4;
561const RXE_PARITY: u8 = 2;
562const RXE_FRAMING: u8 = 1;
563
564impl BufferedState {
565 pub const fn new() -> Self {
566 Self {
567 state: State::new(),
568 rx_waker: AtomicWaker::new(),
569 rx_buf: RingBuffer::new(),
570 tx_waker: AtomicWaker::new(),
571 tx_buf: RingBuffer::new(),
572 rx_error: AtomicU8::new(0),
573 }
574 }
575}
576
577impl<'d> BufferedUart<'d> {
578 fn new_inner<T: Instance>(
579 _peri: Peri<'d, T>,
580 rx: Option<Peri<'d, AnyPin>>,
581 tx: Option<Peri<'d, AnyPin>>,
582 rts: Option<Peri<'d, AnyPin>>,
583 cts: Option<Peri<'d, AnyPin>>,
584 tx_buffer: &'d mut [u8],
585 rx_buffer: &'d mut [u8],
586 config: Config,
587 ) -> Result<Self, ConfigError> {
588 let info = T::info();
589 let state = T::buffered_state();
590
591 let mut this = Self {
592 tx: BufferedUartTx {
593 info,
594 state,
595 tx,
596 cts,
597 reborrowed: false,
598 },
599 rx: BufferedUartRx {
600 info,
601 state,
602 rx,
603 rts,
604 reborrowed: false,
605 },
606 };
607 this.enable_and_configure(tx_buffer, rx_buffer, &config)?;
608
609 Ok(this)
610 }
611
612 fn enable_and_configure(
613 &mut self,
614 tx_buffer: &'d mut [u8],
615 rx_buffer: &'d mut [u8],
616 config: &Config,
617 ) -> Result<(), ConfigError> {
618 let info = self.rx.info;
619 let state = self.rx.state;
620
621 assert!(!tx_buffer.is_empty());
622 assert!(!rx_buffer.is_empty());
623
624 init_buffers(info, state, Some(tx_buffer), Some(rx_buffer));
625 super::enable(info.regs);
626 super::configure(
627 info,
628 &state.state,
629 config,
630 true,
631 self.rx.rts.is_some(),
632 true,
633 self.tx.cts.is_some(),
634 )?;
635
636 info.interrupt.unpend();
637 unsafe { info.interrupt.enable() };
638
639 Ok(())
640 }
641}
642
643impl<'d> BufferedUartRx<'d> {
644 fn new_inner<T: Instance>(
645 _peri: Peri<'d, T>,
646 rx: Option<Peri<'d, AnyPin>>,
647 rts: Option<Peri<'d, AnyPin>>,
648 rx_buffer: &'d mut [u8],
649 config: Config,
650 ) -> Result<Self, ConfigError> {
651 let mut this = Self {
652 info: T::info(),
653 state: T::buffered_state(),
654 rx,
655 rts,
656 reborrowed: false,
657 };
658 this.enable_and_configure(rx_buffer, &config)?;
659
660 Ok(this)
661 }
662
663 fn enable_and_configure(&mut self, rx_buffer: &'d mut [u8], config: &Config) -> Result<(), ConfigError> {
664 let info = self.info;
665 let state = self.state;
666
667 init_buffers(info, state, None, Some(rx_buffer));
668 super::enable(info.regs);
669 super::configure(info, &self.state.state, config, true, self.rts.is_some(), false, false)?;
670
671 info.interrupt.unpend();
672 unsafe { info.interrupt.enable() };
673
674 Ok(())
675 }
676
677 async fn read_inner(&self, buf: &mut [u8]) -> Result<usize, Error> {
678 poll_fn(move |cx| {
679 let state = self.state;
680
681 if let Poll::Ready(r) = self.try_read(buf) {
682 return Poll::Ready(r);
683 }
684
685 state.rx_waker.register(cx.waker());
686 Poll::Pending
687 })
688 .await
689 }
690
691 fn blocking_read_inner(&self, buffer: &mut [u8]) -> Result<usize, Error> {
692 loop {
693 match self.try_read(buffer) {
694 Poll::Ready(res) => return res,
695 Poll::Pending => continue,
696 }
697 }
698 }
699
700 fn fill_buf_inner(&self) -> impl Future<Output = Result<&'_ [u8], Error>> {
701 poll_fn(move |cx| {
702 let mut rx_reader = unsafe { self.state.rx_buf.reader() };
703 let (p, n) = rx_reader.pop_buf();
704 let result = if n == 0 {
705 match Self::get_rx_error(self.state) {
706 None => {
707 self.state.rx_waker.register(cx.waker());
708 return Poll::Pending;
709 }
710 Some(e) => Err(e),
711 }
712 } else {
713 let buf = unsafe { slice::from_raw_parts(p, n) };
714 Ok(buf)
715 };
716
717 Poll::Ready(result)
718 })
719 }
720
721 fn consume_inner(&self, amt: usize) {
722 let mut rx_reader = unsafe { self.state.rx_buf.reader() };
723 rx_reader.pop_done(amt);
724
725 // (Re-)Enable the interrupt to receive more data in case it was
726 // disabled because the buffer was full or errors were detected.
727 self.info.regs.cpu_int(0).imask().modify(|w| {
728 w.set_rxint(true);
729 w.set_rtout(true);
730 });
731 }
732
733 /// we are ready to read if there is data in the buffer
734 fn read_ready_inner(&self) -> Result<bool, Error> {
735 Ok(!self.state.rx_buf.is_empty())
736 }
737
738 fn try_read(&self, buf: &mut [u8]) -> Poll<Result<usize, Error>> {
739 let state = self.state;
740
741 if buf.is_empty() {
742 return Poll::Ready(Ok(0));
743 }
744
745 let mut rx_reader = unsafe { state.rx_buf.reader() };
746 let n = rx_reader.pop(|data| {
747 let n = data.len().min(buf.len());
748 buf[..n].copy_from_slice(&data[..n]);
749 n
750 });
751
752 let result = if n == 0 {
753 match Self::get_rx_error(state) {
754 None => return Poll::Pending,
755 Some(e) => Err(e),
756 }
757 } else {
758 Ok(n)
759 };
760
761 // (Re-)Enable the interrupt to receive more data in case it was
762 // disabled because the buffer was full or errors were detected.
763 self.info.regs.cpu_int(0).imask().modify(|w| {
764 w.set_rxint(true);
765 w.set_rtout(true);
766 });
767
768 Poll::Ready(result)
769 }
770
771 fn get_rx_error(state: &BufferedState) -> Option<Error> {
772 // Cortex-M0 has does not support atomic swap, so we must do two operations.
773 let errs = critical_section::with(|_cs| {
774 let errs = state.rx_error.load(Ordering::Relaxed);
775 state.rx_error.store(0, Ordering::Relaxed);
776
777 errs
778 });
779
780 if errs & RXE_NOISE != 0 {
781 Some(Error::Noise)
782 } else if errs & RXE_OVERRUN != 0 {
783 Some(Error::Overrun)
784 } else if errs & RXE_BREAK != 0 {
785 Some(Error::Break)
786 } else if errs & RXE_PARITY != 0 {
787 Some(Error::Parity)
788 } else if errs & RXE_FRAMING != 0 {
789 Some(Error::Framing)
790 } else {
791 None
792 }
793 }
794}
795
796impl<'d> BufferedUartTx<'d> {
797 fn new_inner<T: Instance>(
798 _peri: Peri<'d, T>,
799 tx: Option<Peri<'d, AnyPin>>,
800 cts: Option<Peri<'d, AnyPin>>,
801 tx_buffer: &'d mut [u8],
802 config: Config,
803 ) -> Result<Self, ConfigError> {
804 let mut this = Self {
805 info: T::info(),
806 state: T::buffered_state(),
807 tx,
808 cts,
809 reborrowed: false,
810 };
811
812 this.enable_and_configure(tx_buffer, &config)?;
813
814 Ok(this)
815 }
816
817 async fn write_inner(&self, buf: &[u8]) -> Result<usize, Error> {
818 poll_fn(move |cx| {
819 let state = self.state;
820
821 if buf.is_empty() {
822 return Poll::Ready(Ok(0));
823 }
824
825 let mut tx_writer = unsafe { state.tx_buf.writer() };
826 let n = tx_writer.push(|data| {
827 let n = data.len().min(buf.len());
828 data[..n].copy_from_slice(&buf[..n]);
829 n
830 });
831
832 if n == 0 {
833 state.tx_waker.register(cx.waker());
834 return Poll::Pending;
835 }
836
837 // The TX interrupt only triggers when the there was data in the
838 // FIFO and the number of bytes drops below a threshold. When the
839 // FIFO was empty we have to manually pend the interrupt to shovel
840 // TX data from the buffer into the FIFO.
841 self.info.interrupt.pend();
842 Poll::Ready(Ok(n))
843 })
844 .await
845 }
846
847 fn blocking_write_inner(&self, buffer: &[u8]) -> Result<usize, Error> {
848 let state = self.state;
849
850 loop {
851 let empty = state.tx_buf.is_empty();
852
853 // SAFETY: tx buf must be initialized if BufferedUartTx exists.
854 let mut tx_writer = unsafe { state.tx_buf.writer() };
855 let data = tx_writer.push_slice();
856
857 if !data.is_empty() {
858 let n = data.len().min(buffer.len());
859 data[..n].copy_from_slice(&buffer[..n]);
860 tx_writer.push_done(n);
861
862 if empty {
863 self.info.interrupt.pend();
864 }
865
866 return Ok(n);
867 }
868 }
869 }
870
871 async fn flush_inner(&self) -> Result<(), Error> {
872 poll_fn(move |cx| {
873 let state = self.state;
874
875 if !state.tx_buf.is_empty() {
876 state.tx_waker.register(cx.waker());
877 return Poll::Pending;
878 }
879
880 Poll::Ready(Ok(()))
881 })
882 .await
883 }
884
885 fn enable_and_configure(&mut self, tx_buffer: &'d mut [u8], config: &Config) -> Result<(), ConfigError> {
886 let info = self.info;
887 let state = self.state;
888
889 init_buffers(info, state, Some(tx_buffer), None);
890 super::enable(info.regs);
891 super::configure(info, &state.state, config, false, false, true, self.cts.is_some())?;
892
893 info.interrupt.unpend();
894 unsafe { info.interrupt.enable() };
895
896 Ok(())
897 }
898}
899
900fn init_buffers<'d>(
901 info: &Info,
902 state: &BufferedState,
903 tx_buffer: Option<&'d mut [u8]>,
904 rx_buffer: Option<&'d mut [u8]>,
905) {
906 if let Some(tx_buffer) = tx_buffer {
907 let len = tx_buffer.len();
908 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
909 }
910
911 if let Some(rx_buffer) = rx_buffer {
912 let len = rx_buffer.len();
913 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
914 }
915
916 info.regs.cpu_int(0).imask().modify(|w| {
917 w.set_nerr(true);
918 w.set_frmerr(true);
919 w.set_parerr(true);
920 w.set_brkerr(true);
921 w.set_ovrerr(true);
922 });
923}
924
925fn on_interrupt(r: Regs, state: &'static BufferedState) {
926 let int = r.cpu_int(0).mis().read();
927
928 // Per https://github.com/embassy-rs/embassy/pull/1458, both buffered and unbuffered handlers may be bound.
929 if super::dma_enabled(r) {
930 return;
931 }
932
933 // RX
934 if state.rx_buf.is_available() {
935 // SAFETY: RX must have been initialized if RXE is set.
936 let mut rx_writer = unsafe { state.rx_buf.writer() };
937 let rx_buf = rx_writer.push_slice();
938 let mut n_read = 0;
939 let mut error = false;
940
941 for rx_byte in rx_buf {
942 let stat = r.stat().read();
943
944 if stat.rxfe() {
945 break;
946 }
947
948 let data = r.rxdata().read();
949
950 if (data.0 >> 8) != 0 {
951 // Cortex-M0 does not support atomic fetch_or, must do 2 operations.
952 critical_section::with(|_cs| {
953 let mut value = state.rx_error.load(Ordering::Relaxed);
954 value |= (data.0 >> 8) as u8;
955 state.rx_error.store(value, Ordering::Relaxed);
956 });
957 error = true;
958
959 // only fill the buffer with valid characters. the current character is fine
960 // if the error is an overrun, but if we add it to the buffer we'll report
961 // the overrun one character too late. drop it instead and pretend we were
962 // a bit slower at draining the rx fifo than we actually were.
963 // this is consistent with blocking uart error reporting.
964 break;
965 }
966
967 *rx_byte = data.data();
968 n_read += 1;
969 }
970
971 if n_read > 0 {
972 rx_writer.push_done(n_read);
973 state.rx_waker.wake();
974 } else if error {
975 state.rx_waker.wake();
976 }
977
978 // Disable any further RX interrupts when the buffer becomes full or
979 // errors have occurred. This lets us buffer additional errors in the
980 // fifo without needing more error storage locations, and most applications
981 // will want to do a full reset of their uart state anyway once an error
982 // has happened.
983 if state.rx_buf.is_full() || error {
984 r.cpu_int(0).imask().modify(|w| {
985 w.set_rxint(false);
986 w.set_rtout(false);
987 });
988 }
989 }
990
991 if int.eot() {
992 r.cpu_int(0).imask().modify(|w| {
993 w.set_eot(false);
994 });
995
996 r.cpu_int(0).iclr().write(|w| {
997 w.set_eot(true);
998 });
999
1000 state.tx_waker.wake();
1001 }
1002
1003 // TX
1004 if state.tx_buf.is_available() {
1005 // SAFETY: TX must have been initialized if TXE is set.
1006 let mut tx_reader = unsafe { state.tx_buf.reader() };
1007 let buf = tx_reader.pop_slice();
1008 let mut n_written = 0;
1009
1010 for tx_byte in buf.iter_mut() {
1011 let stat = r.stat().read();
1012
1013 if stat.txff() {
1014 break;
1015 }
1016
1017 r.txdata().write(|w| {
1018 w.set_data(*tx_byte);
1019 });
1020 n_written += 1;
1021 }
1022
1023 if n_written > 0 {
1024 // EOT will wake.
1025 r.cpu_int(0).imask().modify(|w| {
1026 w.set_eot(true);
1027 });
1028
1029 tx_reader.pop_done(n_written);
1030 }
1031 }
1032
1033 // Clear TX and error interrupt flags
1034 // RX interrupt flags are cleared by writing to ICLR.
1035 let mis = r.cpu_int(0).mis().read();
1036 r.cpu_int(0).iclr().write(|w| {
1037 w.set_nerr(mis.nerr());
1038 w.set_frmerr(mis.frmerr());
1039 w.set_parerr(mis.parerr());
1040 w.set_brkerr(mis.brkerr());
1041 w.set_ovrerr(mis.ovrerr());
1042 });
1043
1044 // Errors
1045 if mis.nerr() {
1046 warn!("Noise error");
1047 }
1048 if mis.frmerr() {
1049 warn!("Framing error");
1050 }
1051 if mis.parerr() {
1052 warn!("Parity error");
1053 }
1054 if mis.brkerr() {
1055 warn!("Break error");
1056 }
1057 if mis.ovrerr() {
1058 warn!("Overrun error");
1059 }
1060}
diff --git a/embassy-mspm0/src/uart.rs b/embassy-mspm0/src/uart/mod.rs
index bc1d2e343..6599cea06 100644
--- a/embassy-mspm0/src/uart.rs
+++ b/embassy-mspm0/src/uart/mod.rs
@@ -1,8 +1,11 @@
1#![macro_use] 1#![macro_use]
2 2
3mod buffered;
4
3use core::marker::PhantomData; 5use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; 6use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
5 7
8pub use buffered::*;
6use embassy_embedded_hal::SetConfig; 9use embassy_embedded_hal::SetConfig;
7use embassy_hal_internal::PeripheralType; 10use embassy_hal_internal::PeripheralType;
8 11
@@ -128,8 +131,8 @@ pub struct Config {
128 // pub manchester: bool, 131 // pub manchester: bool,
129 132
130 // TODO: majority voting 133 // TODO: majority voting
131 134 /// If true: the built-in FIFO is enabled.
132 // TODO: fifo level select - need power domain info in metapac 135 pub fifo_enable: bool,
133 136
134 // TODO: glitch suppression 137 // TODO: glitch suppression
135 /// If true: invert TX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle). 138 /// If true: invert TX pin signal values (V<sub>DD</sub> = 0/mark, Gnd = 1/idle).
@@ -169,6 +172,7 @@ impl Default for Config {
169 msb_order: BitOrder::LsbFirst, 172 msb_order: BitOrder::LsbFirst,
170 loop_back_enable: false, 173 loop_back_enable: false,
171 // manchester: false, 174 // manchester: false,
175 fifo_enable: false,
172 invert_tx: false, 176 invert_tx: false,
173 invert_rx: false, 177 invert_rx: false,
174 invert_rts: false, 178 invert_rts: false,
@@ -185,7 +189,7 @@ impl Default for Config {
185/// 189///
186/// ### Notes on [`embedded_io::Read`] 190/// ### Notes on [`embedded_io::Read`]
187/// 191///
188/// `embedded_io::Read` requires guarantees that the base [`UartRx`] cannot provide. 192/// [`embedded_io::Read`] requires guarantees that the base [`UartRx`] cannot provide.
189/// 193///
190/// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`] 194/// See [`UartRx`] for more details, and see [`BufferedUart`] and [`RingBufferedUartRx`]
191/// as alternatives that do provide the necessary guarantees for `embedded_io::Read`. 195/// as alternatives that do provide the necessary guarantees for `embedded_io::Read`.
@@ -199,8 +203,7 @@ impl<'d, M: Mode> SetConfig for Uart<'d, M> {
199 type ConfigError = ConfigError; 203 type ConfigError = ConfigError;
200 204
201 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { 205 fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
202 self.tx.set_config(config)?; 206 self.set_config(config)
203 self.rx.set_config(config)
204 } 207 }
205} 208}
206 209
@@ -236,6 +239,12 @@ impl core::fmt::Display for Error {
236 239
237impl core::error::Error for Error {} 240impl core::error::Error for Error {}
238 241
242impl embedded_io::Error for Error {
243 fn kind(&self) -> embedded_io::ErrorKind {
244 embedded_io::ErrorKind::Other
245 }
246}
247
239/// Rx-only UART Driver. 248/// Rx-only UART Driver.
240/// 249///
241/// Can be obtained from [`Uart::split`], or can be constructed independently, 250/// Can be obtained from [`Uart::split`], or can be constructed independently,
@@ -260,7 +269,7 @@ impl<'d, M: Mode> SetConfig for UartRx<'d, M> {
260impl<'d> UartRx<'d, Blocking> { 269impl<'d> UartRx<'d, Blocking> {
261 /// Create a new rx-only UART with no hardware flow control. 270 /// Create a new rx-only UART with no hardware flow control.
262 /// 271 ///
263 /// Useful if you only want Uart Rx. It saves 1 pin . 272 /// Useful if you only want Uart Rx. It saves 1 pin.
264 pub fn new_blocking<T: Instance>( 273 pub fn new_blocking<T: Instance>(
265 peri: Peri<'d, T>, 274 peri: Peri<'d, T>,
266 rx: Peri<'d, impl RxPin<T>>, 275 rx: Peri<'d, impl RxPin<T>>,
@@ -286,19 +295,6 @@ impl<'d> UartRx<'d, Blocking> {
286} 295}
287 296
288impl<'d, M: Mode> UartRx<'d, M> { 297impl<'d, M: Mode> UartRx<'d, M> {
289 /// Reconfigure the driver
290 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
291 if let Some(ref rx) = self.rx {
292 rx.update_pf(config.rx_pf());
293 }
294
295 if let Some(ref rts) = self.rts {
296 rts.update_pf(config.rts_pf());
297 }
298
299 reconfigure(self.info, self.state, config)
300 }
301
302 /// Perform a blocking read into `buffer` 298 /// Perform a blocking read into `buffer`
303 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 299 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
304 let r = self.info.regs; 300 let r = self.info.regs;
@@ -315,6 +311,19 @@ impl<'d, M: Mode> UartRx<'d, M> {
315 Ok(()) 311 Ok(())
316 } 312 }
317 313
314 /// Reconfigure the driver
315 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
316 if let Some(ref rx) = self.rx {
317 rx.update_pf(config.rx_pf());
318 }
319
320 if let Some(ref rts) = self.rts {
321 rts.update_pf(config.rts_pf());
322 }
323
324 reconfigure(self.info, self.state, config)
325 }
326
318 /// Set baudrate 327 /// Set baudrate
319 pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> { 328 pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
320 set_baudrate(&self.info, self.state.clock.load(Ordering::Relaxed), baudrate) 329 set_baudrate(&self.info, self.state.clock.load(Ordering::Relaxed), baudrate)
@@ -378,19 +387,6 @@ impl<'d> UartTx<'d, Blocking> {
378} 387}
379 388
380impl<'d, M: Mode> UartTx<'d, M> { 389impl<'d, M: Mode> UartTx<'d, M> {
381 /// Reconfigure the driver
382 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
383 if let Some(ref tx) = self.tx {
384 tx.update_pf(config.tx_pf());
385 }
386
387 if let Some(ref cts) = self.cts {
388 cts.update_pf(config.cts_pf());
389 }
390
391 reconfigure(self.info, self.state, config)
392 }
393
394 /// Perform a blocking UART write 390 /// Perform a blocking UART write
395 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> { 391 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<(), Error> {
396 let r = self.info.regs; 392 let r = self.info.regs;
@@ -427,6 +423,24 @@ impl<'d, M: Mode> UartTx<'d, M> {
427 }); 423 });
428 } 424 }
429 425
426 /// Check if UART is busy.
427 pub fn busy(&self) -> bool {
428 busy(self.info.regs)
429 }
430
431 /// Reconfigure the driver
432 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
433 if let Some(ref tx) = self.tx {
434 tx.update_pf(config.tx_pf());
435 }
436
437 if let Some(ref cts) = self.cts {
438 cts.update_pf(config.cts_pf());
439 }
440
441 reconfigure(self.info, self.state, config)
442 }
443
430 /// Set baudrate 444 /// Set baudrate
431 pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> { 445 pub fn set_baudrate(&self, baudrate: u32) -> Result<(), ConfigError> {
432 set_baudrate(&self.info, self.state.clock.load(Ordering::Relaxed), baudrate) 446 set_baudrate(&self.info, self.state.clock.load(Ordering::Relaxed), baudrate)
@@ -489,6 +503,11 @@ impl<'d, M: Mode> Uart<'d, M> {
489 self.tx.blocking_flush() 503 self.tx.blocking_flush()
490 } 504 }
491 505
506 /// Check if UART is busy.
507 pub fn busy(&self) -> bool {
508 self.tx.busy()
509 }
510
492 /// Perform a blocking read into `buffer` 511 /// Perform a blocking read into `buffer`
493 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { 512 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
494 self.rx.blocking_read(buffer) 513 self.rx.blocking_read(buffer)
@@ -508,6 +527,12 @@ impl<'d, M: Mode> Uart<'d, M> {
508 (&mut self.tx, &mut self.rx) 527 (&mut self.tx, &mut self.rx)
509 } 528 }
510 529
530 /// Reconfigure the driver
531 pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
532 self.tx.set_config(config)?;
533 self.rx.set_config(config)
534 }
535
511 /// Send break character 536 /// Send break character
512 pub fn send_break(&self) { 537 pub fn send_break(&self) {
513 self.tx.send_break(); 538 self.tx.send_break();
@@ -557,8 +582,16 @@ pub(crate) struct Info {
557} 582}
558 583
559pub(crate) struct State { 584pub(crate) struct State {
560 /// The clock rate of the UART. This might be configured. 585 /// The clock rate of the UART in Hz.
561 pub(crate) clock: AtomicU32, 586 clock: AtomicU32,
587}
588
589impl State {
590 pub const fn new() -> Self {
591 Self {
592 clock: AtomicU32::new(0),
593 }
594 }
562} 595}
563 596
564impl<'d, M: Mode> UartRx<'d, M> { 597impl<'d, M: Mode> UartRx<'d, M> {
@@ -746,7 +779,8 @@ fn configure(
746 779
747 info.regs.ctl0().modify(|w| { 780 info.regs.ctl0().modify(|w| {
748 w.set_lbe(config.loop_back_enable); 781 w.set_lbe(config.loop_back_enable);
749 w.set_rxe(enable_rx); 782 // Errata UART_ERR_02, must set RXE to allow use of EOT.
783 w.set_rxe(enable_rx | enable_tx);
750 w.set_txe(enable_tx); 784 w.set_txe(enable_tx);
751 // RXD_OUT_EN and TXD_OUT_EN? 785 // RXD_OUT_EN and TXD_OUT_EN?
752 w.set_menc(false); 786 w.set_menc(false);
@@ -754,13 +788,18 @@ fn configure(
754 w.set_rtsen(enable_rts); 788 w.set_rtsen(enable_rts);
755 w.set_ctsen(enable_cts); 789 w.set_ctsen(enable_cts);
756 // oversampling is set later 790 // oversampling is set later
757 // TODO: config 791 w.set_fen(config.fifo_enable);
758 w.set_fen(false);
759 // TODO: config 792 // TODO: config
760 w.set_majvote(false); 793 w.set_majvote(false);
761 w.set_msbfirst(matches!(config.msb_order, BitOrder::MsbFirst)); 794 w.set_msbfirst(matches!(config.msb_order, BitOrder::MsbFirst));
762 }); 795 });
763 796
797 info.regs.ifls().modify(|w| {
798 // TODO: Need power domain info for other options.
799 w.set_txiflsel(vals::Iflssel::AT_LEAST_ONE);
800 w.set_rxiflsel(vals::Iflssel::AT_LEAST_ONE);
801 });
802
764 info.regs.lcrh().modify(|w| { 803 info.regs.lcrh().modify(|w| {
765 let eps = if matches!(config.parity, Parity::ParityEven) { 804 let eps = if matches!(config.parity, Parity::ParityEven) {
766 vals::Eps::EVEN 805 vals::Eps::EVEN
@@ -1021,9 +1060,29 @@ fn read_with_error(r: Regs) -> Result<u8, Error> {
1021 Ok(rx.data()) 1060 Ok(rx.data())
1022} 1061}
1023 1062
1063/// This function assumes CTL0.ENABLE is set (for errata cases).
1064fn busy(r: Regs) -> bool {
1065 // Errata UART_ERR_08
1066 if cfg!(any(
1067 mspm0g151x, mspm0g351x, mspm0l110x, mspm0l130x, mspm0l134x, mspm0c110x,
1068 )) {
1069 let stat = r.stat().read();
1070 // "Poll TXFIFO status and the CTL0.ENABLE register bit to identify BUSY status."
1071 !stat.txfe()
1072 } else {
1073 r.stat().read().busy()
1074 }
1075}
1076
1077// TODO: Implement when dma uart is implemented.
1078fn dma_enabled(_r: Regs) -> bool {
1079 false
1080}
1081
1024pub(crate) trait SealedInstance { 1082pub(crate) trait SealedInstance {
1025 fn info() -> &'static Info; 1083 fn info() -> &'static Info;
1026 fn state() -> &'static State; 1084 fn state() -> &'static State;
1085 fn buffered_state() -> &'static BufferedState;
1027} 1086}
1028 1087
1029macro_rules! impl_uart_instance { 1088macro_rules! impl_uart_instance {
@@ -1041,12 +1100,16 @@ macro_rules! impl_uart_instance {
1041 } 1100 }
1042 1101
1043 fn state() -> &'static crate::uart::State { 1102 fn state() -> &'static crate::uart::State {
1044 use crate::interrupt::typelevel::Interrupt;
1045 use crate::uart::State; 1103 use crate::uart::State;
1046 1104
1047 static STATE: State = State { 1105 static STATE: State = State::new();
1048 clock: core::sync::atomic::AtomicU32::new(0), 1106 &STATE
1049 }; 1107 }
1108
1109 fn buffered_state() -> &'static crate::uart::BufferedState {
1110 use crate::uart::BufferedState;
1111
1112 static STATE: BufferedState = BufferedState::new();
1050 &STATE 1113 &STATE
1051 } 1114 }
1052 } 1115 }