1use core::future::Future;
3use core::slice;
4use core::sync::atomic::{AtomicU8, Ordering};
5
6use embassy_hal_internal::atomic_ring_buffer::RingBuffer;
7
8use super::*;
9
10pub struct State {
11 tx_waker: AtomicWaker,
12 tx_buf: RingBuffer,
13 rx_waker: AtomicWaker,
14 rx_buf: RingBuffer,
15 rx_error: AtomicU8,
16}
17
18const RXE_OVERRUN: u8 = 8;
20const RXE_BREAK: u8 = 4;
21const RXE_PARITY: u8 = 2;
22const RXE_FRAMING: u8 = 1;
23
24impl State {
25 pub const fn new() -> Self {
26 Self {
27 rx_buf: RingBuffer::new(),
28 tx_buf: RingBuffer::new(),
29 rx_waker: AtomicWaker::new(),
30 tx_waker: AtomicWaker::new(),
31 rx_error: AtomicU8::new(0),
32 }
33 }
34}
35
36pub struct BufferedUart {
38 pub(super) rx: BufferedUartRx,
39 pub(super) tx: BufferedUartTx,
40}
41
42pub struct BufferedUartRx {
44 pub(super) info: &'static Info,
45 pub(super) state: &'static State,
46}
47
48pub struct BufferedUartTx {
50 pub(super) info: &'static Info,
51 pub(super) state: &'static State,
52}
53
54pub(super) fn init_buffers<'d>(
55 info: &Info,
56 state: &State,
57 tx_buffer: Option<&'d mut [u8]>,
58 rx_buffer: Option<&'d mut [u8]>,
59) {
60 if let Some(tx_buffer) = tx_buffer {
61 let len = tx_buffer.len();
62 unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
63 }
64
65 if let Some(rx_buffer) = rx_buffer {
66 let len = rx_buffer.len();
67 unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
68 }
69
70 info.regs.uartimsc().write(|w| {
81 w.set_rxim(true);
82 w.set_rtim(true);
83 w.set_txim(true);
84 });
85
86 info.interrupt.unpend();
87 unsafe { info.interrupt.enable() };
88}
89
90impl BufferedUart {
91 pub fn new<'d, T: Instance>(
93 _uart: Peri<'d, T>,
94 tx: Peri<'d, impl TxPin<T>>,
95 rx: Peri<'d, impl RxPin<T>>,
96 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
97 tx_buffer: &'d mut [u8],
98 rx_buffer: &'d mut [u8],
99 config: Config,
100 ) -> Self {
101 super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), Some(rx.into()), None, None, config);
102 init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer));
103
104 Self {
105 rx: BufferedUartRx {
106 info: T::info(),
107 state: T::buffered_state(),
108 },
109 tx: BufferedUartTx {
110 info: T::info(),
111 state: T::buffered_state(),
112 },
113 }
114 }
115
116 pub fn new_with_rtscts<'d, T: Instance>(
118 _uart: Peri<'d, T>,
119 tx: Peri<'d, impl TxPin<T>>,
120 rx: Peri<'d, impl RxPin<T>>,
121 rts: Peri<'d, impl RtsPin<T>>,
122 cts: Peri<'d, impl CtsPin<T>>,
123 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
124 tx_buffer: &'d mut [u8],
125 rx_buffer: &'d mut [u8],
126 config: Config,
127 ) -> Self {
128 super::Uart::<'d, Async>::init(
129 T::info(),
130 Some(tx.into()),
131 Some(rx.into()),
132 Some(rts.into()),
133 Some(cts.into()),
134 config,
135 );
136 init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), Some(rx_buffer));
137
138 Self {
139 rx: BufferedUartRx {
140 info: T::info(),
141 state: T::buffered_state(),
142 },
143 tx: BufferedUartTx {
144 info: T::info(),
145 state: T::buffered_state(),
146 },
147 }
148 }
149
150 pub fn blocking_write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
152 self.tx.blocking_write(buffer)
153 }
154
155 pub fn blocking_flush(&mut self) -> Result<(), Error> {
157 self.tx.blocking_flush()
158 }
159
160 pub fn blocking_read(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
162 self.rx.blocking_read(buffer)
163 }
164
165 pub fn busy(&self) -> bool {
167 self.tx.busy()
168 }
169
170 pub async fn send_break(&mut self, bits: u32) {
172 self.tx.send_break(bits).await
173 }
174
175 pub fn set_baudrate<'d>(&mut self, baudrate: u32) {
177 super::Uart::<'d, Async>::set_baudrate_inner(self.rx.info, baudrate);
178 }
179
180 pub fn split(self) -> (BufferedUartTx, BufferedUartRx) {
182 (self.tx, self.rx)
183 }
184
185 pub fn split_ref(&mut self) -> (&mut BufferedUartTx, &mut BufferedUartRx) {
189 (&mut self.tx, &mut self.rx)
190 }
191}
192
193impl BufferedUartRx {
194 pub fn new<'d, T: Instance>(
196 _uart: Peri<'d, T>,
197 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
198 rx: Peri<'d, impl RxPin<T>>,
199 rx_buffer: &'d mut [u8],
200 config: Config,
201 ) -> Self {
202 super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), None, None, config);
203 init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer));
204
205 Self {
206 info: T::info(),
207 state: T::buffered_state(),
208 }
209 }
210
211 pub fn new_with_rts<'d, T: Instance>(
213 _uart: Peri<'d, T>,
214 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
215 rx: Peri<'d, impl RxPin<T>>,
216 rts: Peri<'d, impl RtsPin<T>>,
217 rx_buffer: &'d mut [u8],
218 config: Config,
219 ) -> Self {
220 super::Uart::<'d, Async>::init(T::info(), None, Some(rx.into()), Some(rts.into()), None, config);
221 init_buffers(T::info(), T::buffered_state(), None, Some(rx_buffer));
222
223 Self {
224 info: T::info(),
225 state: T::buffered_state(),
226 }
227 }
228
229 fn read<'a>(
230 info: &'static Info,
231 state: &'static State,
232 buf: &'a mut [u8],
233 ) -> impl Future<Output = Result<usize, Error>> + 'a {
234 poll_fn(move |cx| {
235 if let Poll::Ready(r) = Self::try_read(info, state, buf) {
236 return Poll::Ready(r);
237 }
238 state.rx_waker.register(cx.waker());
239 Poll::Pending
240 })
241 }
242
243 fn get_rx_error(state: &State) -> Option<Error> {
244 let errs = critical_section::with(|_| {
245 let val = state.rx_error.load(Ordering::Relaxed);
246 state.rx_error.store(0, Ordering::Relaxed);
247 val
248 });
249 if errs & RXE_OVERRUN != 0 {
250 Some(Error::Overrun)
251 } else if errs & RXE_BREAK != 0 {
252 Some(Error::Break)
253 } else if errs & RXE_PARITY != 0 {
254 Some(Error::Parity)
255 } else if errs & RXE_FRAMING != 0 {
256 Some(Error::Framing)
257 } else {
258 None
259 }
260 }
261
262 fn try_read(info: &Info, state: &State, buf: &mut [u8]) -> Poll<Result<usize, Error>> {
263 if buf.is_empty() {
264 return Poll::Ready(Ok(0));
265 }
266
267 let mut rx_reader = unsafe { state.rx_buf.reader() };
268 let n = rx_reader.pop(|data| {
269 let n = data.len().min(buf.len());
270 buf[..n].copy_from_slice(&data[..n]);
271 n
272 });
273
274 let result = if n == 0 {
275 match Self::get_rx_error(state) {
276 None => return Poll::Pending,
277 Some(e) => Err(e),
278 }
279 } else {
280 Ok(n)
281 };
282
283 info.regs.uartimsc().write_set(|w| {
286 w.set_rxim(true);
287 w.set_rtim(true);
288 });
289
290 Poll::Ready(result)
291 }
292
293 pub fn blocking_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
295 loop {
296 match Self::try_read(self.info, self.state, buf) {
297 Poll::Ready(res) => return res,
298 Poll::Pending => continue,
299 }
300 }
301 }
302
303 fn fill_buf<'a>(state: &'static State) -> impl Future<Output = Result<&'a [u8], Error>> {
304 poll_fn(move |cx| {
305 let mut rx_reader = unsafe { state.rx_buf.reader() };
306 let (p, n) = rx_reader.pop_buf();
307 let result = if n == 0 {
308 match Self::get_rx_error(state) {
309 None => {
310 state.rx_waker.register(cx.waker());
311 return Poll::Pending;
312 }
313 Some(e) => Err(e),
314 }
315 } else {
316 let buf = unsafe { slice::from_raw_parts(p, n) };
317 Ok(buf)
318 };
319
320 Poll::Ready(result)
321 })
322 }
323
324 fn consume(info: &Info, state: &State, amt: usize) {
325 let mut rx_reader = unsafe { state.rx_buf.reader() };
326 rx_reader.pop_done(amt);
327
328 info.regs.uartimsc().write_set(|w| {
331 w.set_rxim(true);
332 w.set_rtim(true);
333 });
334 }
335
336 fn read_ready(state: &State) -> Result<bool, Error> {
338 Ok(!state.rx_buf.is_empty())
339 }
340}
341
342impl BufferedUartTx {
343 pub fn new<'d, T: Instance>(
345 _uart: Peri<'d, T>,
346 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
347 tx: Peri<'d, impl TxPin<T>>,
348 tx_buffer: &'d mut [u8],
349 config: Config,
350 ) -> Self {
351 super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, None, config);
352 init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None);
353
354 Self {
355 info: T::info(),
356 state: T::buffered_state(),
357 }
358 }
359
360 pub fn new_with_cts<'d, T: Instance>(
362 _uart: Peri<'d, T>,
363 _irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
364 tx: Peri<'d, impl TxPin<T>>,
365 cts: Peri<'d, impl CtsPin<T>>,
366 tx_buffer: &'d mut [u8],
367 config: Config,
368 ) -> Self {
369 super::Uart::<'d, Async>::init(T::info(), Some(tx.into()), None, None, Some(cts.into()), config);
370 init_buffers(T::info(), T::buffered_state(), Some(tx_buffer), None);
371
372 Self {
373 info: T::info(),
374 state: T::buffered_state(),
375 }
376 }
377
378 fn write<'d>(
379 info: &'static Info,
380 state: &'static State,
381 buf: &'d [u8],
382 ) -> impl Future<Output = Result<usize, Error>> + 'd {
383 poll_fn(move |cx| {
384 if buf.is_empty() {
385 return Poll::Ready(Ok(0));
386 }
387
388 let mut tx_writer = unsafe { state.tx_buf.writer() };
389 let n = tx_writer.push(|data| {
390 let n = data.len().min(buf.len());
391 data[..n].copy_from_slice(&buf[..n]);
392 n
393 });
394 if n == 0 {
395 state.tx_waker.register(cx.waker());
396 return Poll::Pending;
397 }
398
399 info.interrupt.pend();
404 Poll::Ready(Ok(n))
405 })
406 }
407
408 fn flush(state: &'static State) -> impl Future<Output = Result<(), Error>> {
409 poll_fn(move |cx| {
410 if !state.tx_buf.is_empty() {
411 state.tx_waker.register(cx.waker());
412 return Poll::Pending;
413 }
414
415 Poll::Ready(Ok(()))
416 })
417 }
418
419 pub fn blocking_write(&mut self, buf: &[u8]) -> Result<usize, Error> {
421 if buf.is_empty() {
422 return Ok(0);
423 }
424
425 loop {
426 let mut tx_writer = unsafe { self.state.tx_buf.writer() };
427 let n = tx_writer.push(|data| {
428 let n = data.len().min(buf.len());
429 data[..n].copy_from_slice(&buf[..n]);
430 n
431 });
432
433 if n != 0 {
434 self.info.interrupt.pend();
439 return Ok(n);
440 }
441 }
442 }
443
444 pub fn blocking_flush(&mut self) -> Result<(), Error> {
446 loop {
447 if self.state.tx_buf.is_empty() {
448 return Ok(());
449 }
450 }
451 }
452
453 pub fn busy(&self) -> bool {
455 self.info.regs.uartfr().read().busy()
456 }
457
458 pub async fn send_break(&mut self, bits: u32) {
466 let regs = self.info.regs;
467 let bits = bits.max({
468 let lcr = regs.uartlcr_h().read();
469 let width = lcr.wlen() as u32 + 5;
470 let parity = lcr.pen() as u32;
471 let stops = 1 + lcr.stp2() as u32;
472 2 * (1 + width + parity + stops)
473 });
474 let divx64 = (((regs.uartibrd().read().baud_divint() as u32) << 6)
475 + regs.uartfbrd().read().baud_divfrac() as u32) as u64;
476 let div_clk = clk_peri_freq() as u64 * 64;
477 let wait_usecs = (1_000_000 * bits as u64 * divx64 * 16 + div_clk - 1) / div_clk;
478
479 Self::flush(self.state).await.unwrap();
480 while self.busy() {}
481 regs.uartlcr_h().write_set(|w| w.set_brk(true));
482 Timer::after_micros(wait_usecs).await;
483 regs.uartlcr_h().write_clear(|w| w.set_brk(true));
484 }
485}
486
487impl Drop for BufferedUartRx {
488 fn drop(&mut self) {
489 unsafe { self.state.rx_buf.deinit() }
490
491 if !self.state.tx_buf.is_available() {
494 self.info.interrupt.disable();
495 }
496 }
497}
498
499impl Drop for BufferedUartTx {
500 fn drop(&mut self) {
501 unsafe { self.state.tx_buf.deinit() }
502
503 if !self.state.rx_buf.is_available() {
506 self.info.interrupt.disable();
507 }
508 }
509}
510
511pub struct BufferedInterruptHandler<T: Instance> {
513 _uart: PhantomData<T>,
514}
515
516impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> {
517 unsafe fn on_interrupt() {
518 let r = T::info().regs;
519 if r.uartdmacr().read().rxdmae() {
520 return;
521 }
522
523 let s = T::buffered_state();
524
525 let ris = r.uartris().read();
528 r.uarticr().write(|w| {
529 w.set_txic(ris.txris());
530 w.set_feic(ris.feris());
531 w.set_peic(ris.peris());
532 w.set_beic(ris.beris());
533 w.set_oeic(ris.oeris());
534 });
535
536 if ris.feris() {
538 warn!("Framing error");
539 }
540 if ris.peris() {
541 warn!("Parity error");
542 }
543 if ris.beris() {
544 warn!("Break error");
545 }
546 if ris.oeris() {
547 warn!("Overrun error");
548 }
549
550 if s.rx_buf.is_available() {
552 let mut rx_writer = unsafe { s.rx_buf.writer() };
553 let rx_buf = rx_writer.push_slice();
554 let mut n_read = 0;
555 let mut error = false;
556 for rx_byte in rx_buf {
557 if r.uartfr().read().rxfe() {
558 break;
559 }
560 let dr = r.uartdr().read();
561 if (dr.0 >> 8) != 0 {
562 critical_section::with(|_| {
563 let val = s.rx_error.load(Ordering::Relaxed);
564 s.rx_error.store(val | ((dr.0 >> 8) as u8), Ordering::Relaxed);
565 });
566 error = true;
567 break;
573 }
574 *rx_byte = dr.data();
575 n_read += 1;
576 }
577 if n_read > 0 {
578 rx_writer.push_done(n_read);
579 s.rx_waker.wake();
580 } else if error {
581 s.rx_waker.wake();
582 }
583 if s.rx_buf.is_full() || error {
589 r.uartimsc().write_clear(|w| {
590 w.set_rxim(true);
591 w.set_rtim(true);
592 });
593 }
594 }
595
596 if s.tx_buf.is_available() {
598 let mut tx_reader = unsafe { s.tx_buf.reader() };
599 let tx_buf = tx_reader.pop_slice();
600 let mut n_written = 0;
601 for tx_byte in tx_buf.iter_mut() {
602 if r.uartfr().read().txff() {
603 break;
604 }
605 r.uartdr().write(|w| w.set_data(*tx_byte));
606 n_written += 1;
607 }
608 if n_written > 0 {
609 tx_reader.pop_done(n_written);
610 s.tx_waker.wake();
611 }
612 }
616 }
617}
618
619impl embedded_io::Error for Error {
620 fn kind(&self) -> embedded_io::ErrorKind {
621 embedded_io::ErrorKind::Other
622 }
623}
624
625impl embedded_io_async::ErrorType for BufferedUart {
626 type Error = Error;
627}
628
629impl embedded_io_async::ErrorType for BufferedUartRx {
630 type Error = Error;
631}
632
633impl embedded_io_async::ErrorType for BufferedUartTx {
634 type Error = Error;
635}
636
637impl embedded_io_async::Read for BufferedUart {
638 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
639 BufferedUartRx::read(self.rx.info, self.rx.state, buf).await
640 }
641}
642
643impl embedded_io_async::Read for BufferedUartRx {
644 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
645 Self::read(self.info, self.state, buf).await
646 }
647}
648
649impl embedded_io_async::ReadReady for BufferedUart {
650 fn read_ready(&mut self) -> Result<bool, Self::Error> {
651 BufferedUartRx::read_ready(self.rx.state)
652 }
653}
654
655impl embedded_io_async::ReadReady for BufferedUartRx {
656 fn read_ready(&mut self) -> Result<bool, Self::Error> {
657 Self::read_ready(self.state)
658 }
659}
660
661impl embedded_io_async::BufRead for BufferedUart {
662 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
663 BufferedUartRx::fill_buf(self.rx.state).await
664 }
665
666 fn consume(&mut self, amt: usize) {
667 BufferedUartRx::consume(self.rx.info, self.rx.state, amt)
668 }
669}
670
671impl embedded_io_async::BufRead for BufferedUartRx {
672 async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
673 Self::fill_buf(self.state).await
674 }
675
676 fn consume(&mut self, amt: usize) {
677 Self::consume(self.info, self.state, amt)
678 }
679}
680
681impl embedded_io_async::Write for BufferedUart {
682 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
683 BufferedUartTx::write(self.tx.info, self.tx.state, buf).await
684 }
685
686 async fn flush(&mut self) -> Result<(), Self::Error> {
687 BufferedUartTx::flush(self.tx.state).await
688 }
689}
690
691impl embedded_io_async::Write for BufferedUartTx {
692 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
693 Self::write(self.info, self.state, buf).await
694 }
695
696 async fn flush(&mut self) -> Result<(), Self::Error> {
697 Self::flush(self.state).await
698 }
699}
700
701impl embedded_io::Read for BufferedUart {
702 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
703 self.rx.blocking_read(buf)
704 }
705}
706
707impl embedded_io::Read for BufferedUartRx {
708 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
709 self.blocking_read(buf)
710 }
711}
712
713impl embedded_io::Write for BufferedUart {
714 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
715 self.tx.blocking_write(buf)
716 }
717
718 fn flush(&mut self) -> Result<(), Self::Error> {
719 self.tx.blocking_flush()
720 }
721}
722
723impl embedded_io::Write for BufferedUartTx {
724 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
725 self.blocking_write(buf)
726 }
727
728 fn flush(&mut self) -> Result<(), Self::Error> {
729 self.blocking_flush()
730 }
731}
732
733impl embedded_hal_02::serial::Read<u8> for BufferedUartRx {
734 type Error = Error;
735
736 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
737 let r = self.info.regs;
738 if r.uartfr().read().rxfe() {
739 return Err(nb::Error::WouldBlock);
740 }
741
742 let dr = r.uartdr().read();
743
744 if dr.oe() {
745 Err(nb::Error::Other(Error::Overrun))
746 } else if dr.be() {
747 Err(nb::Error::Other(Error::Break))
748 } else if dr.pe() {
749 Err(nb::Error::Other(Error::Parity))
750 } else if dr.fe() {
751 Err(nb::Error::Other(Error::Framing))
752 } else {
753 Ok(dr.data())
754 }
755 }
756}
757
758impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUartTx {
759 type Error = Error;
760
761 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
762 while !buffer.is_empty() {
763 match self.blocking_write(buffer) {
764 Ok(0) => panic!("zero-length write."),
765 Ok(n) => buffer = &buffer[n..],
766 Err(e) => return Err(e),
767 }
768 }
769 Ok(())
770 }
771
772 fn bflush(&mut self) -> Result<(), Self::Error> {
773 self.blocking_flush()
774 }
775}
776
777impl embedded_hal_02::serial::Read<u8> for BufferedUart {
778 type Error = Error;
779
780 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
781 embedded_hal_02::serial::Read::read(&mut self.rx)
782 }
783}
784
785impl embedded_hal_02::blocking::serial::Write<u8> for BufferedUart {
786 type Error = Error;
787
788 fn bwrite_all(&mut self, mut buffer: &[u8]) -> Result<(), Self::Error> {
789 while !buffer.is_empty() {
790 match self.blocking_write(buffer) {
791 Ok(0) => panic!("zero-length write."),
792 Ok(n) => buffer = &buffer[n..],
793 Err(e) => return Err(e),
794 }
795 }
796 Ok(())
797 }
798
799 fn bflush(&mut self) -> Result<(), Self::Error> {
800 self.blocking_flush()
801 }
802}
803
804impl embedded_hal_nb::serial::ErrorType for BufferedUartRx {
805 type Error = Error;
806}
807
808impl embedded_hal_nb::serial::ErrorType for BufferedUartTx {
809 type Error = Error;
810}
811
812impl embedded_hal_nb::serial::ErrorType for BufferedUart {
813 type Error = Error;
814}
815
816impl embedded_hal_nb::serial::Read for BufferedUartRx {
817 fn read(&mut self) -> nb::Result<u8, Self::Error> {
818 embedded_hal_02::serial::Read::read(self)
819 }
820}
821
822impl embedded_hal_nb::serial::Write for BufferedUartTx {
823 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
824 self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
825 }
826
827 fn flush(&mut self) -> nb::Result<(), Self::Error> {
828 self.blocking_flush().map_err(nb::Error::Other)
829 }
830}
831
832impl embedded_hal_nb::serial::Read for BufferedUart {
833 fn read(&mut self) -> Result<u8, nb::Error<Self::Error>> {
834 embedded_hal_02::serial::Read::read(&mut self.rx)
835 }
836}
837
838impl embedded_hal_nb::serial::Write for BufferedUart {
839 fn write(&mut self, char: u8) -> nb::Result<(), Self::Error> {
840 self.blocking_write(&[char]).map(drop).map_err(nb::Error::Other)
841 }
842
843 fn flush(&mut self) -> nb::Result<(), Self::Error> {
844 self.blocking_flush().map_err(nb::Error::Other)
845 }
846}