Skip to main content

ra_hal/uart/
sci.rs

1//! Universal Asynchronous Receiver-Transmitter (`SCI`).
2//!
3//! # TODO
4//! * Get non-FIFO instances working
5//! # Notes
6//! * The driver will stop the `SCI` instance (`MSTPBnn=1`) when it is dropped.
7
8use 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/// UART configuration
37#[non_exhaustive]
38#[cfg_attr(feature = "defmt", derive(defmt::Format))]
39#[derive(Clone, Copy, PartialEq, Eq, Debug)]
40pub struct Config {
41    /// Baud rate
42    pub baud_rate: u32,
43
44    /// Number of data bits.
45    /// Note: 9 bit data is not yet supported.
46    #[allow(missing_docs)]
47    pub data_bits: DataBits,
48
49    /// Parity type
50    #[allow(missing_docs)]
51    pub parity: Parity,
52
53    /// Number of stop bits.
54    #[allow(missing_docs)]
55    pub stop_bits: StopBits,
56}
57
58/// UART driver, backed by a [`RingBuffer`] and 16-byte on-device FIFO buffer.
59#[allow(private_bounds)]
60pub struct Uart<'d, I: Instance, M: TransferMode> {
61    _phantom: PhantomData<&'d I>,
62    io_mode: M,
63}
64
65/// Interrupt handler that handles incoming data for an `SCI` instance.
66pub struct RxInterruptHandler<I: Instance> {
67    _phantom: PhantomData<I>,
68}
69
70/// Interrupt handler that handles outgoing data (transmission end) for an `SCI` instance.
71pub struct TeInterruptHandler<I: Instance> {
72    _phantom: PhantomData<I>,
73}
74
75/// Interrupt handler that handles outgoing data (tx buffer empty) for an `SCI` instance.
76pub struct TxInterruptHandler<I: Instance> {
77    _phantom: PhantomData<I>,
78}
79
80/// UART error
81#[derive(Debug, Eq, PartialEq, Copy, Clone)]
82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
83#[non_exhaustive]
84pub enum UartError {
85    /// Framing error
86    Framing,
87    /// RX buffer overrun
88    Overrun,
89    /// Parity check error
90    Parity,
91}
92
93/// Buffered UART instance.
94///
95/// Note: On the `RA4M1` only `SCI0` and `SCI1` have FIFOs.
96#[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    /// # Returns
114    ///
115    /// Static reference to the statically allocated [`RingBuffer`] for receive operations.
116    fn rx_buffer() -> &'static RingBuffer;
117
118    /// # Returns
119    ///
120    /// Static reference to the statically allocated [`RingBuffer`] for transmit operations.
121    fn tx_buffer() -> &'static RingBuffer;
122
123    /// Waker for receive events.
124    fn rx_waker() -> &'static AtomicWaker;
125
126    /// Waker for "transmit end" events.
127    fn te_waker() -> &'static AtomicWaker;
128
129    /// Waker for transmit buffer empty events.
130    fn tx_waker() -> &'static AtomicWaker;
131}
132
133/// A pin that can be used for reception.
134#[allow(private_bounds)]
135pub trait RxPin<I: Instance>: SealedRxPin<I> {}
136
137/// A pin that can be used for transmission.
138#[allow(private_bounds)]
139pub trait TxPin<I: Instance>: SealedTxPin<I> {}
140// impl<I: Instance, T: SealedTxPin<I>> UartTxPin<I> for T {}
141
142pub(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    /// Configures a new UART and returns the driver.
173    #[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        // We can leave the receiver on, but not the transmitter as enabling the transmitter in
206        // combination with the TX interrupt is what kicks off the whole transmit procedure.
207        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            // Enable FIFO
243            r.set_fm(true);
244            // TODO: Is this the value we want?
245            r.set_ttrg(I::FIFO_DEPTH);
246        });
247
248        // TODO: Give enum variants meaningful names.
249        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        // not-smart card mode
259        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        // Move pins over to SCI
280        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        // Safety: Interrupt handlers are defined by the irqs argument and thus the interrupts are safe to enable.
293        unsafe {
294            // Enable interrupts in NVIC. We can largely ignore the NVIC after this as all of the
295            // peripheral interrupts are going to be managed by the ICU and/or ELC.
296            RxInt::IRQ.enable();
297            TeInt::IRQ.enable();
298            TxInt::IRQ.enable();
299
300            // Enable in ICU
301            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    /// Reads data from the UART.
316    ///
317    /// # Returns
318    ///
319    /// Returns when there is data in the RX [`RingBuffer`].
320    /// `buf` is not guaranteed to be full and the length of its contents is returned.
321    #[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                // If there's nothing else wait on the Transmit End interrupt
388                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 we're still waiting for the FIFO to write everything to the wire
397                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    /// Configures a new UART and returns the driver.
410    #[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        // We can leave the receiver on, but not the transmitter as enabling the transmitter in
437        // combination with the TX interrupt is what kicks off the whole transmit procedure.
438        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            // Enable FIFO
462            r.set_fm(true);
463            // TODO: Is this the value we want?
464            r.set_ttrg(I::FIFO_DEPTH);
465        });
466
467        // TODO: Give enum variants meaningful names.
468        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        // not-smart card mode
478        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        // Move pins over to SCI
499        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    /// Reads data from the UART, blocks until `data` is full.
511    #[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    /// Writes `data` to the UART, blocking until the last byte has been sent out on the wire.
531    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    /// Sets the number of bits in a byte.
560    ///
561    /// Note:
562    /// * 9 bit data is supported by the underlying hardware but not yet by this driver.
563    /// * This will disable the transmitter and temporarily disable the receiver (RA4M1 §28.2.9 note 4).
564    #[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                // Restrictions apply, page 704 note 3
584                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                // // 9 Data bits
593                // sci.scmr().write(|r| r.set_chr1(false));
594                // sci.smr().write(|r| r.set_chr(false));
595                todo!()
596            }
597        }
598    }
599
600    /// Sets baud rate for the `SCI` instance.
601    ///
602    /// Note: This will disable the transmitter and temporarily disable the receiver (§28.2.9 note 4).
603    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    /// Set stop bit length.
632    ///
633    /// Note: This will disable the transmitter and temporarily disable the receiver (§28.2.9 note 4).
634    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        // Set it up for No Parity, 1 stop bit
651        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    /// Sets baud rate for the `SCI` instance.
660    ///
661    /// Note:
662    /// * This will disable the transmitter and temporarily disable the receiver (§28.2.9 note 4).
663    /// * Currently depends on micromath. Pending <https://github.com/rust-lang/rust/issues/137578>.
664    ///
665    /// # Arguments
666    /// * `baud_rate` - Desired baud rate.
667    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                    // If there isn't enough space in the static buffer are we dropping it on the floor when we reset dr?
739                    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                // Should we clear TDFE per Fig 28.14? (RA4M1)
831            }
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    // TODO: Change… "optimize" this so we only wait for data to leave the ring buffer.
895    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;