1use core::{future::poll_fn, marker::PhantomData, task::Poll};
9
10use cortex_m::asm;
11use embassy_hal_internal::{
12 Peri, PeripheralType, atomic_ring_buffer::RingBuffer, interrupt::InterruptExt as _,
13};
14use embassy_sync::waitqueue::AtomicWaker;
15
16use crate::{
17 event_link::{IcuInterrupt as _, InterruptEvent},
18 gpio::{Pin, PortFunction},
19 interrupt::{
20 self,
21 typelevel::{Handler as InterruptHandler, Interrupt as InterruptType},
22 },
23 module_stop::ModuleStop,
24 pac::{
25 self,
26 sci_fifo::{
27 regs::Scr,
28 vals::{ScrCke, SmrCks, SmrPm, Stop},
29 },
30 },
31 uart::{
32 Async, BaudGenConfig, Blocking, DataBits, Parity, StopBits, TransferMode, calc_baud_gen,
33 },
34};
35
36#[non_exhaustive]
38#[cfg_attr(feature = "defmt", derive(defmt::Format))]
39#[derive(Clone, Copy, PartialEq, Eq, Debug)]
40pub struct Config {
41 pub baud_rate: u32,
43
44 #[allow(missing_docs)]
47 pub data_bits: DataBits,
48
49 #[allow(missing_docs)]
51 pub parity: Parity,
52
53 #[allow(missing_docs)]
55 pub stop_bits: StopBits,
56}
57
58#[allow(private_bounds)]
60pub struct Uart<'d, I: Instance, M: TransferMode> {
61 _phantom: PhantomData<&'d I>,
62 io_mode: M,
63}
64
65pub struct RxInterruptHandler<I: Instance> {
67 _phantom: PhantomData<I>,
68}
69
70pub struct TeInterruptHandler<I: Instance> {
72 _phantom: PhantomData<I>,
73}
74
75pub struct TxInterruptHandler<I: Instance> {
77 _phantom: PhantomData<I>,
78}
79
80#[derive(Debug, Eq, PartialEq, Copy, Clone)]
82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
83#[non_exhaustive]
84pub enum UartError {
85 Framing,
87 Overrun,
89 Parity,
91}
92
93#[allow(private_bounds)]
97pub trait Instance: SealedInstance + ModuleStop + PeripheralType + 'static + Send {}
98
99pub(crate) trait SealedInstance {
100 #[cfg(feature = "defmt")]
101 const PERIPHERAL: &'static str;
102 #[cfg(not(feature = "defmt"))]
103 const PERIPHERAL: () = ();
104
105 const RX_INTERRUPT_EVENT: InterruptEvent;
106 const TE_INTERRUPT_EVENT: InterruptEvent;
107 const TX_INTERRUPT_EVENT: InterruptEvent;
108
109 const FIFO_DEPTH: u8 = 16;
110
111 fn regs() -> pac::sci_fifo::SciFifo;
112
113 fn rx_buffer() -> &'static RingBuffer;
117
118 fn tx_buffer() -> &'static RingBuffer;
122
123 fn rx_waker() -> &'static AtomicWaker;
125
126 fn te_waker() -> &'static AtomicWaker;
128
129 fn tx_waker() -> &'static AtomicWaker;
131}
132
133#[allow(private_bounds)]
135pub trait RxPin<I: Instance>: SealedRxPin<I> {}
136
137#[allow(private_bounds)]
139pub trait TxPin<I: Instance>: SealedTxPin<I> {}
140pub(crate) trait SealedRxPin<I: SealedInstance>: Pin + PeripheralType {
143 const PERIPHERAL_FUNC: PortFunction;
144
145 #[inline(always)]
146 fn set_pfunc(&self) {
147 self.set_as_pf(Self::PERIPHERAL_FUNC);
148 }
149}
150
151pub(crate) trait SealedTxPin<I: SealedInstance>: Pin + PeripheralType {
152 const PERIPHERAL_FUNC: PortFunction;
153
154 #[inline(always)]
155 fn set_pfunc(&self) {
156 self.set_as_pf(Self::PERIPHERAL_FUNC);
157 }
158}
159
160impl Default for Config {
161 fn default() -> Self {
162 Self {
163 baud_rate: 9600,
164 data_bits: DataBits::DataBits8,
165 parity: Parity::None,
166 stop_bits: StopBits::Stop1,
167 }
168 }
169}
170
171impl<'d, I: Instance> Uart<'d, I, Async> {
172 #[allow(private_bounds)]
174 pub fn new_async<RxInt: InterruptType, TeInt: InterruptType, TxInt: InterruptType>(
175 _peri: Peri<'d, I>,
176 tx_pin: Peri<'d, impl TxPin<I>>,
177 tx_buffer: &'d mut [u8],
178 rx_pin: Peri<'d, impl RxPin<I>>,
179 rx_buffer: &'d mut [u8],
180 irqs: impl interrupt::typelevel::Binding<RxInt, RxInterruptHandler<I>>
181 + interrupt::typelevel::Binding<TeInt, TeInterruptHandler<I>>
182 + interrupt::typelevel::Binding<TxInt, TxInterruptHandler<I>>
183 + 'd,
184 config: Config,
185 ) -> Self {
186 info!("{}{}", I::PERIPHERAL, config);
187
188 let clock_config = crate::clock::clock_status();
189 let mut this = Self::new_inner(tx_pin, tx_buffer, rx_pin, rx_buffer, irqs);
190
191 this.set_data_bits_inner(config.data_bits);
192 this.set_parity_inner(config.parity);
193 this.set_stop_bits_inner(config.stop_bits);
194
195 #[cfg(ra2)]
196 let brr_config = calc_baud_gen(config.baud_rate, clock_config.peripheral_b).unwrap();
197 #[cfg(not(ra2))]
198 let brr_config = calc_baud_gen(config.baud_rate, clock_config.peripheral_a).unwrap();
199
200 info!("{}{}", I::PERIPHERAL, brr_config);
201 Self::set_baud_from_config(&brr_config);
202
203 let sci = I::regs();
204
205 sci.scr().modify(|r| {
208 r.set_re(true);
209 r.set_rie(true);
210 });
211
212 this
213 }
214
215 fn new_inner<RxInt: InterruptType, TxInt: InterruptType, TeInt: InterruptType>(
216 tx_pin: Peri<'d, impl TxPin<I>>,
217 tx_buffer: &'d mut [u8],
218 rx_pin: Peri<'d, impl RxPin<I>>,
219 rx_buffer: &'d mut [u8],
220 irqs: impl interrupt::typelevel::Binding<RxInt, RxInterruptHandler<I>>
221 + interrupt::typelevel::Binding<TxInt, TxInterruptHandler<I>>
222 + interrupt::typelevel::Binding<TeInt, TeInterruptHandler<I>>
223 + 'd,
224 ) -> Self {
225 let _ = irqs;
226
227 I::start_module();
228
229 let sci = I::regs();
230
231 sci.scr().write_value(Scr(0));
232
233 sci.scr().modify(|r| {
234 r.set_re(false);
235 r.set_rie(false);
236 r.set_te(false);
237 r.set_teie(false);
238 r.set_tie(false);
239 });
240
241 sci.fcr().modify(|r| {
242 r.set_fm(true);
244 r.set_ttrg(I::FIFO_DEPTH);
246 });
247
248 sci.scr().modify(|r| r.set_cke(ScrCke::_00));
250
251 sci.simr1().modify(|r| r.set_iicm(false));
252
253 sci.spmr().modify(|r| {
254 r.set_ckph(false);
255 r.set_ckpol(false);
256 });
257
258 sci.scmr().modify(|r| r.set_smif(false));
260
261 sci.smr().modify(|r| {
262 r.set_cm(false);
263 r.set_mp(false);
264 });
265
266 sci.semr().modify(|r| {
267 r.set_abcs(false);
268 r.set_abcse(false);
269 r.set_bgdm(false);
270 r.set_brme(false);
271 r.set_rxdesel(false);
272 });
273
274 sci.sptr().write(|r| {
275 r.set_spb2dt(false);
276 r.set_spb2io(false);
277 });
278
279 trace!("P{}RX=p{}/{}", I::PERIPHERAL, rx_pin._port(), rx_pin._pin());
281 rx_pin.set_pfunc();
282
283 trace!("{}TX=p{}/{}", I::PERIPHERAL, tx_pin._port(), tx_pin._pin());
284 tx_pin.set_pfunc();
285
286 let rx_len = rx_buffer.len();
287 unsafe { I::rx_buffer().init(rx_buffer.as_mut_ptr(), rx_len) };
288
289 let tx_len = tx_buffer.len();
290 unsafe { I::tx_buffer().init(tx_buffer.as_mut_ptr(), tx_len) };
291
292 unsafe {
294 RxInt::IRQ.enable();
297 TeInt::IRQ.enable();
298 TxInt::IRQ.enable();
299
300 RxInt::IRQ.icu_enable(I::RX_INTERRUPT_EVENT);
302 TeInt::IRQ.icu_enable(I::TE_INTERRUPT_EVENT);
303 TxInt::IRQ.icu_enable(I::TX_INTERRUPT_EVENT);
304 }
305
306 Self {
307 _phantom: PhantomData,
308 io_mode: Async {
309 rx_int: RxInt::IRQ,
310 tx_int: TxInt::IRQ,
311 },
312 }
313 }
314
315 #[inline(always)]
322 pub async fn read(&self, buf: &mut [u8]) -> Result<usize, UartError> {
323 poll_fn(|cx| {
324 let mut buf_pos = 0;
325 let mut reader = unsafe { I::rx_buffer().reader() };
326 let mut data = reader.pop_slice();
327
328 while !data.is_empty() && buf_pos < buf.len() {
329 let data_len = data.len().min(buf.len() - buf_pos);
330 buf[buf_pos..buf_pos + data_len].copy_from_slice(&data[..data_len]);
331 buf_pos += data_len;
332
333 let pending = I::rx_buffer().is_full();
334 reader.pop_done(data_len);
335
336 if pending {
337 self.io_mode.rx_int.icu_pend();
338 }
339
340 data = reader.pop_slice();
341 }
342
343 if buf_pos != 0 {
344 Poll::Ready(Ok(buf_pos))
345 } else {
346 I::rx_waker().register(cx.waker());
347 Poll::Pending
348 }
349 })
350 .await
351 }
352
353 async fn write(&mut self, buf: &[u8]) -> Result<usize, UartError> {
354 warn!("Write: {}", str::from_utf8(&buf).unwrap());
355 let sci = I::regs();
356
357 let mut written: usize = 0;
358 let mut writer = unsafe { I::tx_buffer().writer() };
359
360 poll_fn(|cx| {
361 if written < buf.len() {
362 I::tx_waker().register(cx.waker());
363
364 if I::tx_buffer().is_full() {
365 trace!("{}TX buffer full in async write", I::PERIPHERAL);
366 return Poll::Pending;
367 }
368
369 let out = writer.push_slice();
370 let chunk_len = out.len().min(buf.len().saturating_sub(written));
371 out[..chunk_len].copy_from_slice(&buf[written..(written + chunk_len)]);
372 written += chunk_len;
373
374 writer.push_done(chunk_len);
375
376 if !sci.scr().read().te() {
377 sci.scr().modify(|r| {
378 r.set_te(true);
379 r.set_tie(true);
380 });
381 }
382
383 if written < buf.len() {
384 return Poll::Pending;
385 }
386
387 I::te_waker().register(cx.waker());
389
390 if !sci.ssr_fifo().read().tend() {
391 return Poll::Pending;
392 }
393 } else {
394 I::te_waker().register(cx.waker());
395
396 if !sci.ssr_fifo().read().tend() {
398 return Poll::Pending;
399 }
400 }
401
402 Poll::Ready(Ok(written))
403 })
404 .await
405 }
406}
407
408impl<'d, I: Instance> Uart<'d, I, Blocking> {
409 #[allow(private_bounds)]
411 pub fn new_blocking(
412 _peri: Peri<'d, I>,
413 tx_pin: Peri<'d, impl TxPin<I>>,
414 rx_pin: Peri<'d, impl RxPin<I>>,
415 config: Config,
416 ) -> Self {
417 info!("{}{}", I::PERIPHERAL, config);
418
419 let clock_config = crate::clock::clock_status();
420 let mut this = Self::new_inner(tx_pin, rx_pin);
421
422 this.set_data_bits_inner(config.data_bits);
423 this.set_parity_inner(config.parity);
424 this.set_stop_bits_inner(config.stop_bits);
425
426 #[cfg(ra2)]
427 let brr_config = calc_baud_gen(config.baud_rate, clock_config.peripheral_b).unwrap();
428 #[cfg(not(ra2))]
429 let brr_config = calc_baud_gen(config.baud_rate, clock_config.peripheral_a).unwrap();
430
431 info!("{}{}", I::PERIPHERAL, brr_config);
432 Self::set_baud_from_config(&brr_config);
433
434 let sci = I::regs();
435
436 sci.scr().modify(|r| {
439 r.set_re(true);
440 });
441
442 this
443 }
444
445 fn new_inner(tx_pin: Peri<'d, impl TxPin<I>>, rx_pin: Peri<'d, impl RxPin<I>>) -> Self {
446 I::start_module();
447
448 let sci = I::regs();
449
450 sci.scr().write_value(Scr(0));
451
452 sci.scr().modify(|r| {
453 r.set_re(false);
454 r.set_rie(false);
455 r.set_te(false);
456 r.set_teie(false);
457 r.set_tie(false);
458 });
459
460 sci.fcr().modify(|r| {
461 r.set_fm(true);
463 r.set_ttrg(I::FIFO_DEPTH);
465 });
466
467 sci.scr().modify(|r| r.set_cke(ScrCke::_00));
469
470 sci.simr1().modify(|r| r.set_iicm(false));
471
472 sci.spmr().modify(|r| {
473 r.set_ckph(false);
474 r.set_ckpol(false);
475 });
476
477 sci.scmr().modify(|r| r.set_smif(false));
479
480 sci.smr().modify(|r| {
481 r.set_cm(false);
482 r.set_mp(false);
483 });
484
485 sci.semr().modify(|r| {
486 r.set_abcs(false);
487 r.set_abcse(false);
488 r.set_bgdm(false);
489 r.set_brme(false);
490 r.set_rxdesel(false);
491 });
492
493 sci.sptr().write(|r| {
494 r.set_spb2dt(false);
495 r.set_spb2io(false);
496 });
497
498 trace!("P{}RX=p{}/{}", I::PERIPHERAL, rx_pin._port(), rx_pin._pin());
500 rx_pin.set_pfunc();
501
502 trace!("{}TX=p{}/{}", I::PERIPHERAL, tx_pin._port(), tx_pin._pin());
503 tx_pin.set_pfunc();
504
505 Self {
506 _phantom: PhantomData,
507 io_mode: Blocking {},
508 }
509 }
510 #[inline(always)]
512 pub fn blocking_read(&self, data: &mut [u8]) {
513 let mut reader = unsafe { I::rx_buffer().reader() };
514
515 for byte in data.iter_mut() {
516 loop {
517 match reader.pop_one() {
518 Some(rx) => {
519 *byte = rx;
520 break;
521 }
522 None => {
523 asm::nop();
524 }
525 }
526 }
527 }
528 }
529
530 pub fn blocking_write(&mut self, data: &[u8]) {
532 let sci = I::regs();
533
534 let mut written: usize = 0;
535
536 sci.scr().modify(|r| r.set_te(true));
537
538 while written != data.len() {
539 let fifo_contents = sci.fdr().read().t();
540 let fifo_available = usize::from(I::FIFO_DEPTH - fifo_contents);
541 let write_len = (data.len() - written).min(fifo_available);
542
543 for byte in data.iter().skip(written).take(write_len) {
544 sci.ftdrl().write_value(*byte);
545 }
546 sci.ssr().modify(|r| r.set_tdre(false));
547 written += write_len;
548 }
549
550 while !sci.ssr_fifo().read().tend() {
551 asm::nop();
552 }
553
554 sci.scr().modify(|r| r.set_te(false));
555 }
556}
557
558impl<'d, I: Instance, M: TransferMode> Uart<'d, I, M> {
559 #[inline]
565 pub fn set_data_bits(&mut self, n: DataBits) {
566 let sci = I::regs();
567
568 sci.scr().modify(|r| {
569 r.set_re(false);
570 r.set_te(false);
571 });
572
573 self.set_data_bits_inner(n);
574
575 sci.scr().modify(|r| r.set_re(true));
576 }
577
578 fn set_data_bits_inner(&mut self, n: DataBits) {
579 let sci = I::regs();
580
581 match n {
582 DataBits::DataBits7 => {
583 sci.scmr().modify(|r| r.set_chr1(true));
585 sci.smr().modify(|r| r.set_chr(true));
586 }
587 DataBits::DataBits8 => {
588 sci.scmr().modify(|r| r.set_chr1(true));
589 sci.smr().modify(|r| r.set_chr(false));
590 }
591 DataBits::DataBits9 => {
592 todo!()
596 }
597 }
598 }
599
600 pub fn set_parity(&mut self, parity: Parity) {
604 let sci = I::regs();
605
606 sci.scr().modify(|r| {
607 r.set_re(false);
608 r.set_te(false);
609 });
610
611 self.set_parity_inner(parity);
612
613 sci.scr().modify(|r| r.set_re(true));
614 }
615
616 fn set_parity_inner(&mut self, parity: Parity) {
617 let sci = I::regs();
618
619 let (pe, pm) = match parity {
620 Parity::Even => (true, SmrPm::Even),
621 Parity::Odd => (true, SmrPm::Odd),
622 Parity::None => (false, SmrPm::Even),
623 };
624
625 sci.smr().modify(|r| {
626 r.set_pe(pe);
627 r.set_pm(pm);
628 });
629 }
630
631 pub fn set_stop_bits(&mut self, stop_bits: StopBits) {
635 let sci = I::regs();
636
637 sci.scr().modify(|r| {
638 r.set_re(false);
639 r.set_te(false);
640 });
641
642 self.set_stop_bits_inner(stop_bits);
643
644 sci.scr().modify(|r| r.set_re(true));
645 }
646
647 fn set_stop_bits_inner(&mut self, stop_bits: StopBits) {
648 let sci = I::regs();
649
650 sci.smr().modify(|r| {
652 match stop_bits {
653 StopBits::Stop1 => r.set_stop(Stop::Stop1),
654 StopBits::Stop2 => r.set_stop(Stop::Stop2),
655 };
656 });
657 }
658
659 pub fn set_baud_rate(&mut self, baud_rate: u32) {
668 let clock_config = crate::clock::clock_status();
669
670 #[cfg(ra2)]
671 let brr_config = calc_baud_gen(baud_rate, clock_config.peripheral_b).unwrap();
672 #[cfg(not(ra2))]
673 let brr_config = calc_baud_gen(baud_rate, clock_config.peripheral_a).unwrap();
674
675 let sci = I::regs();
676
677 sci.scr().modify(|r| {
678 r.set_re(false);
679 r.set_te(false);
680 });
681
682 debug!(
683 "{}Baud rate: {}, Config: {}",
684 I::PERIPHERAL,
685 baud_rate,
686 brr_config
687 );
688
689 Self::set_baud_from_config(&brr_config);
690
691 sci.scr().modify(|r| r.set_re(true));
692 }
693
694 fn set_baud_from_config(brr_config: &BaudGenConfig) {
695 let sci = I::regs();
696
697 sci.brr()
698 .write_value(u8::try_from(brr_config.big_n).expect("SCI big_n > 255"));
699
700 sci.mddr().write_value(0);
701 sci.semr().modify(|r| r.set_brme(false));
702
703 sci.smr().modify(|r| {
704 r.set_cks(SmrCks::from_bits(
705 u8::try_from(brr_config.small_n).expect("SCI small_n > 255"),
706 ))
707 });
708
709 sci.scr().modify(|r| r.set_re(true));
710 }
711}
712
713impl<'d, I: Instance, M: TransferMode> Drop for Uart<'d, I, M> {
714 fn drop(&mut self) {
715 I::stop_module();
716 }
717}
718
719impl<I: Instance, RxInt: InterruptType> InterruptHandler<RxInt> for RxInterruptHandler<I> {
720 unsafe fn on_interrupt() {
721 trace!("RxI");
722
723 let sci = I::regs();
724 let mut writer = unsafe { I::rx_buffer().writer() };
725 let buf = writer.push_slice();
726
727 match buf.is_empty() {
728 false => {
729 let fifo_len = sci.fdr().read().r() as _;
730 let read_len = buf.len().min(fifo_len);
731
732 for out_byte in buf.iter_mut().take(read_len) {
733 *out_byte = sci.frdrl().read();
734 }
735 writer.push_done(read_len);
736
737 sci.ssr_fifo().modify(|r| {
738 r.set_dr(false);
740 r.set_rdf(false);
741 });
742
743 I::rx_waker().wake();
744
745 if read_len != fifo_len {
746 trace!("{}RX Buffer full, FIFO drain={}", I::PERIPHERAL, read_len);
747 } else {
748 RxInt::IRQ.icu_unpend();
749 }
750 }
751 true => {
752 let fifo_free = I::FIFO_DEPTH - sci.fdr().read().r();
753
754 warn!("{}RX Buffer full, FIFO cap={}", I::PERIPHERAL, fifo_free);
755
756 RxInt::IRQ.icu_unpend();
757
758 I::rx_waker().wake();
759
760 if sci.ssr_fifo().read().orer() {
761 error!("{}Overrun, dropping 1", I::PERIPHERAL);
762 sci.ssr_fifo().modify(|r| r.set_orer(false));
763 RxInt::IRQ.icu_unpend();
764 }
765 }
766 }
767 }
768}
769
770impl<I: Instance, TeInt: InterruptType> InterruptHandler<TeInt> for TeInterruptHandler<I> {
771 unsafe fn on_interrupt() {
772 trace!("TeI");
773 TeInt::IRQ.icu_unpend();
774
775 let sci = I::regs();
776
777 if I::tx_buffer().is_empty() {
778 while !sci.ssr_fifo().read().tend() {
779 asm::nop();
780 }
781
782 sci.scr().modify(|r| {
783 r.set_te(false);
784 r.set_teie(false);
785 r.set_tie(false);
786 });
787
788 I::te_waker().wake();
789 } else {
790 sci.scr().modify(|r| {
791 r.set_te(true);
792 r.set_teie(false);
793 r.set_tie(true);
794 });
795 }
796 }
797}
798
799impl<I: Instance, TxInt: InterruptType> InterruptHandler<TxInt> for TxInterruptHandler<I> {
800 unsafe fn on_interrupt() {
801 trace!("TxI");
802 TxInt::IRQ.icu_unpend();
803
804 let sci = I::regs();
805 let mut tx_reader = unsafe { I::tx_buffer().reader() };
806
807 let out_buf = tx_reader.pop_slice();
808
809 if out_buf.is_empty() {
810 sci.scr().modify(|r| {
811 r.set_teie(true);
812 r.set_tie(false);
813 });
814
815 return;
816 }
817
818 let out_len = out_buf.len();
819 let fifo_available = usize::from(I::FIFO_DEPTH - sci.fdr().read().t());
820
821 if out_len > fifo_available {
822 for byte in out_buf[0..fifo_available].iter() {
823 sci.ftdrl().write_value(*byte);
824 }
825
826 tx_reader.pop_done(fifo_available);
827 } else {
828 for byte in out_buf[0..out_len].iter() {
829 sci.ftdrl().write_value(*byte);
830 }
832
833 sci.scr().modify(|r| {
834 r.set_teie(true);
835 r.set_tie(false);
836 });
837
838 tx_reader.pop_done(out_len);
839 }
840
841 I::tx_waker().wake();
842 }
843}
844
845impl<'d, I: Instance> embedded_io_async::ErrorType for Uart<'d, I, Async> {
846 type Error = UartError;
847}
848
849impl<'d, I: Instance> embedded_io_async::Read for Uart<'d, I, Async> {
850 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
851 Uart::read(self, buf).await
852 }
853}
854
855impl<'d, I: Instance> embedded_io_async::Write for Uart<'d, I, Async> {
856 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
857 Uart::write(self, buf).await
858 }
859
860 async fn flush(&mut self) -> Result<(), Self::Error> {
861 todo!()
862 }
863}
864
865impl embedded_io::Error for UartError {
866 fn kind(&self) -> embedded_io::ErrorKind {
867 embedded_io::ErrorKind::Other
868 }
869}
870
871impl core::fmt::Display for UartError {
872 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
873 let message = match self {
874 Self::Framing => "Framing Error",
875 Self::Overrun => "RX Buffer Overrun",
876 Self::Parity => "Parity Check Error",
877 };
878
879 write!(f, "{}", message)
880 }
881}
882
883impl core::error::Error for UartError {}
884
885impl<'d, I: Instance> embedded_io_async::ReadReady for Uart<'d, I, Async> {
886 fn read_ready(&mut self) -> Result<bool, Self::Error> {
887 Self::read_ready(self)
888 }
889}
890
891impl<'d, I: Instance> embedded_serial::MutBlockingTx for Uart<'d, I, Blocking> {
892 type Error = ();
893
894 fn putc(&mut self, ch: u8) -> Result<(), Self::Error> {
896 Self::blocking_write(self, &[ch]);
897 Ok(())
898 }
899}
900
901impl<'d, I: Instance> embedded_serial::MutBlockingRx for Uart<'d, I, Blocking> {
902 type Error = ();
903
904 fn getc(&mut self) -> Result<u8, Self::Error> {
905 let mut ch = [0_u8];
906
907 Self::blocking_read(self, &mut ch);
908
909 Ok(ch[0])
910 }
911}
912
913macro_rules! tx_pin {
914 ($sci:ident, $pin:ident, $pfunc:ident) => {
915 impl crate::uart::sci::TxPin<crate::peripherals::$sci> for crate::peripherals::$pin {}
916 impl crate::uart::sci::SealedTxPin<crate::peripherals::$sci> for crate::peripherals::$pin {
917 const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
918 }
919 };
920}
921pub(crate) use tx_pin;
922
923macro_rules! rx_pin {
924 ($sci:ident, $pin:ident, $pfunc:ident) => {
925 impl crate::uart::sci::RxPin<crate::peripherals::$sci> for crate::peripherals::$pin {}
926 impl crate::uart::sci::SealedRxPin<crate::peripherals::$sci> for crate::peripherals::$pin {
927 const PERIPHERAL_FUNC: crate::gpio::PortFunction = crate::gpio::PortFunction::$pfunc;
928 }
929 };
930}
931pub(crate) use rx_pin;
932
933macro_rules! instance_impl {
934 ($instance:ident, $rx_int:ident, $te_int:ident, $tx_int:ident) => {
935 impl crate::uart::sci::Instance for peripherals::$instance {}
936
937 impl crate::uart::sci::SealedInstance for crate::peripherals::$instance {
938 #[cfg(feature = "defmt")]
939 const PERIPHERAL: &'static str = concat!(stringify!($instance), ": ");
940
941 const RX_INTERRUPT_EVENT: crate::event_link::InterruptEvent =
942 crate::event_link::InterruptEvent::$rx_int;
943 const TE_INTERRUPT_EVENT: crate::event_link::InterruptEvent =
944 crate::event_link::InterruptEvent::$te_int;
945 const TX_INTERRUPT_EVENT: crate::event_link::InterruptEvent =
946 crate::event_link::InterruptEvent::$tx_int;
947
948 #[inline]
949 fn regs() -> crate::pac::sci_fifo::SciFifo {
950 crate::pac::$instance
951 }
952
953 fn rx_buffer() -> &'static embassy_hal_internal::atomic_ring_buffer::RingBuffer {
954 static RX_BUF: embassy_hal_internal::atomic_ring_buffer::RingBuffer =
955 embassy_hal_internal::atomic_ring_buffer::RingBuffer::new();
956 &RX_BUF
957 }
958
959 fn tx_buffer() -> &'static embassy_hal_internal::atomic_ring_buffer::RingBuffer {
960 static TX_BUF: embassy_hal_internal::atomic_ring_buffer::RingBuffer =
961 embassy_hal_internal::atomic_ring_buffer::RingBuffer::new();
962 &TX_BUF
963 }
964
965 fn rx_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
966 static RX_WAKER: embassy_sync::waitqueue::AtomicWaker =
967 embassy_sync::waitqueue::AtomicWaker::new();
968 &RX_WAKER
969 }
970
971 fn te_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
972 static TE_WAKER: embassy_sync::waitqueue::AtomicWaker =
973 embassy_sync::waitqueue::AtomicWaker::new();
974 &TE_WAKER
975 }
976
977 fn tx_waker() -> &'static embassy_sync::waitqueue::AtomicWaker {
978 static TX_WAKER: embassy_sync::waitqueue::AtomicWaker =
979 embassy_sync::waitqueue::AtomicWaker::new();
980 &TX_WAKER
981 }
982 }
983 };
984}
985pub(crate) use instance_impl;