Skip to main content

gd32e2_hal/
usart.rs

1//! Asynchronous serial (USART), blocking and non-blocking.
2//!
3//! Word width is a typestate: a [`Usart<.., Byte>`](Usart) moves `u8` values and
4//! is what [`new`](Usart::new) builds, while [`new_word`](Usart::new_word) gives a
5//! `Usart<.., Word>` for raw 9-bit frames carrying `u16`.
6//!
7//! ```ignore
8//! let tx = parts.pa9.into_alternate::<1>();
9//! let rx = parts.pa10.into_alternate::<1>();
10//! let mut serial = Usart::new(&mut rcu, dp.usart0, tx, rx, UsartConfig::default());
11//! serial.write_byte(b'x');
12//! ```
13//!
14//! Which pins are valid depends on the chip variant: on x6/x8 `PA2`/`PA3` reach
15//! USART1, not USART0.
16//!
17//! A receiver just built takes the first frame apart wrongly unless the line has
18//! been idle for a frame beforehand, and with frames arriving back to back the
19//! damage carries through the whole burst. Against a peer that comes up at the
20//! same time this never shows: raising `TEN` sends an idle frame. It bites when
21//! the peer is already transmitting — then the line has to be given that idle,
22//! by waiting a frame time before the traffic starts.
23
24use core::marker::PhantomData;
25use core::ops::Deref;
26
27use crate::gpio::{Alternate, Pin};
28use crate::pac;
29use crate::rcu::{Clocks, Enable, Rcu, Reset};
30use crate::time::{Bps, Hertz};
31
32/// 7 data bits: parity occupies bit 7 inside the u8 (`E7`/`O7`).
33const DATA_7BIT_MASK: u8 = 0x7F;
34/// 9 data bits: the full 9-bit word in `WL=1, PCEN=0` mode.
35const DATA_9BIT_MASK: u32 = 0x1FF;
36/// Largest `USARTDIV` that fits `BAUD` at ×16 oversampling.
37const USARTDIV_MAX_X16: u32 = 0xFFFF;
38/// Largest `USARTDIV` that fits `BAUD` at ×8: the integer part, `usartdiv / 8`,
39/// has 12 bits.
40const USARTDIV_MAX_X8: u32 = 0x7FFF;
41
42/// Marks a pin usable as `TX` for `USART`, in the right alternate function.
43pub trait TxPin<USART> {}
44/// Marks a pin usable as `RX` for `USART`, in the right alternate function.
45pub trait RxPin<USART> {}
46
47macro_rules! usart_pins {
48    ( $( $USART:ty:
49        TX: [ $($(#[$tx_cfg:meta])? $tx_p:literal $tx_n:literal : $tx_af:literal),* $(,)? ]
50        RX: [ $($(#[$rx_cfg:meta])? $rx_p:literal $rx_n:literal : $rx_af:literal),* $(,)? ]
51    ),* $(,)? ) => {
52        $(
53            $( $(#[$tx_cfg])? impl TxPin<$USART> for Pin<$tx_p, $tx_n, Alternate<$tx_af>> {} )*
54            $( $(#[$rx_cfg])? impl RxPin<$USART> for Pin<$rx_p, $rx_n, Alternate<$rx_af>> {} )*
55        )*
56    };
57}
58
59// PA2/PA3/PA14/PA15 at AF1 belong to a *different* USART depending on the chip
60// variant (datasheet Table 2-13 footnotes): USART0 on GD32E230x4, USART1 on
61// GD32E230x8/6. They are therefore listed in the gated blocks, not here.
62//
63// The `pads_ge_*` gates say the package bonds the pin at all, and match the ones in
64// `gpio::Parts`.
65usart_pins! {
66    pac::Usart0:
67        TX: [ 'A' 9:1, #[cfg(pads_ge_24)] 'B' 6:0 ]
68        RX: [ 'A' 10:1, #[cfg(pads_ge_24)] 'B' 7:0 ],
69}
70
71// ---- (1) GD32E230x4 only: PA2/PA3/PA14/PA15 AF1 are USART0 ----
72#[cfg(chip_x4)]
73usart_pins! {
74    pac::Usart0:
75        TX: [ 'A' 2:1, 'A' 14:1 ]
76        RX: [ 'A' 3:1, #[cfg(pads_ge_28)] 'A' 15:1 ],
77}
78
79// ---- (2) GD32E230x8/6: PA2/PA3/PA14/PA15 AF1 are USART1; USART1 exists ----
80#[cfg(any(chip_x6, chip_x8))]
81usart_pins! {
82    pac::Usart1:
83        TX: [ 'A' 2:1, #[cfg(pads_ge_24)] 'A' 8:4, 'A' 14:1 ]
84        RX: [ 'A' 3:1, #[cfg(pads_ge_28)] 'A' 15:1, #[cfg(pads_ge_24)] 'B' 0:4 ],
85}
86
87/// Supplies the clock frequency feeding a given USART.
88///
89/// USART0 can be reclocked away from its bus (see
90/// [`Usart0Sel`](crate::rcu::Usart0Sel)), USART1 always runs off APB1.
91pub trait BusClocks {
92    /// Returns the frequency actually clocking this USART.
93    fn clock(clocks: &Clocks) -> Hertz;
94}
95
96impl BusClocks for pac::Usart0 {
97    fn clock(clocks: &Clocks) -> Hertz {
98        clocks.usart0()
99    }
100}
101
102impl BusClocks for pac::Usart1 {
103    fn clock(clocks: &Clocks) -> Hertz {
104        clocks.pclk1()
105    }
106}
107
108/// Named constants for the standard bit rates.
109///
110/// Purely a readability aid — [`UsartConfig::baud`] takes any [`Bps`], the
111/// hardware divisor not being restricted to these values. `115_200.bps()` says
112/// the same thing.
113#[allow(missing_docs)]
114pub mod baud {
115    use crate::time::Bps;
116
117    pub const B110: Bps = Bps::from_raw(110);
118    pub const B300: Bps = Bps::from_raw(300);
119    pub const B600: Bps = Bps::from_raw(600);
120    pub const B1200: Bps = Bps::from_raw(1_200);
121    pub const B2400: Bps = Bps::from_raw(2_400);
122    pub const B4800: Bps = Bps::from_raw(4_800);
123    pub const B9600: Bps = Bps::from_raw(9_600);
124    pub const B14400: Bps = Bps::from_raw(14_400);
125    pub const B19200: Bps = Bps::from_raw(19_200);
126    pub const B38400: Bps = Bps::from_raw(38_400);
127    pub const B57600: Bps = Bps::from_raw(57_600);
128    pub const B115200: Bps = Bps::from_raw(115_200);
129    pub const B230400: Bps = Bps::from_raw(230_400);
130    pub const B460800: Bps = Bps::from_raw(460_800);
131    pub const B921600: Bps = Bps::from_raw(921_600);
132}
133
134/// How many times each bit is sampled.
135///
136/// ×16 is the default and more tolerant of clock error; ×8 halves the sampling
137/// rate, which allows higher bit rates from the same peripheral clock.
138#[derive(Clone, Copy, PartialEq, Eq)]
139#[cfg_attr(feature = "defmt", derive(defmt::Format))]
140pub enum Oversampling {
141    /// 8 samples per bit — allows twice the bit rate from the same clock.
142    X8,
143    /// 16 samples per bit — the default, more tolerant of clock error.
144    X16,
145}
146
147/// Word length and parity, as a single setting.
148///
149/// `E7`/`O7` leave 7 data bits because parity replaces the top one, `E8`/`O8`
150/// keep all 8 by widening the frame to 9 bits. No `N7` exists — without parity a
151/// frame carries the full 8 bits, which is `N8`. For raw 9-bit words see
152/// [`Usart::new_word`].
153#[derive(Clone, Copy, PartialEq, Eq)]
154#[cfg_attr(feature = "defmt", derive(defmt::Format))]
155pub enum FrameFormat {
156    /// 8 data bits, no parity.
157    N8,
158    /// 8 data bits, even parity.
159    E8,
160    /// 8 data bits, odd parity.
161    O8,
162    /// 7 data bits, even parity.
163    E7,
164    /// 7 data bits, odd parity.
165    O7,
166}
167
168/// Configuration for [`Usart::new`].
169///
170/// [`Default`] is 115200 baud, ×16 oversampling, [`FrameFormat::N8`] — i.e. the
171/// usual "115200 8N1".
172#[derive(Clone, Copy, PartialEq, Eq)]
173#[cfg_attr(feature = "defmt", derive(defmt::Format))]
174#[must_use]
175pub struct UsartConfig {
176    baud: Bps,
177    oversampling: Oversampling,
178    frame_format: FrameFormat,
179}
180
181impl UsartConfig {
182    /// Sets the bit rate. See the [`baud`] module for named constants.
183    pub const fn baud(mut self, baud: Bps) -> Self {
184        self.baud = baud;
185        self
186    }
187    /// Sets the oversampling ratio.
188    pub const fn oversampling(mut self, oversampling: Oversampling) -> Self {
189        self.oversampling = oversampling;
190        self
191    }
192    /// Sets the word length and parity.
193    pub const fn frame_format(mut self, frame_format: FrameFormat) -> Self {
194        self.frame_format = frame_format;
195        self
196    }
197}
198
199impl Default for UsartConfig {
200    fn default() -> Self {
201        Self {
202            baud: baud::B115200,
203            oversampling: Oversampling::X16,
204            frame_format: FrameFormat::N8,
205        }
206    }
207}
208
209/// Configuration for [`Usart::new_word`].
210///
211/// The 9-bit path is always 9 data bits, no parity, so there is no frame format
212/// to choose.
213#[derive(Clone, Copy, PartialEq, Eq)]
214#[cfg_attr(feature = "defmt", derive(defmt::Format))]
215#[must_use]
216pub struct UsartConfig9 {
217    baud: Bps,
218    oversampling: Oversampling,
219}
220
221impl UsartConfig9 {
222    /// Sets the bit rate. See the [`baud`] module for named constants.
223    pub const fn baud(mut self, baud: Bps) -> Self {
224        self.baud = baud;
225        self
226    }
227    /// Sets the oversampling ratio.
228    pub const fn oversampling(mut self, oversampling: Oversampling) -> Self {
229        self.oversampling = oversampling;
230        self
231    }
232}
233
234impl Default for UsartConfig9 {
235    fn default() -> Self {
236        Self {
237            baud: baud::B115200,
238            oversampling: Oversampling::X16,
239        }
240    }
241}
242
243fn configure<USARTX>(rcu: &mut Rcu, usart: &USARTX, baud: Bps, oversampling: Oversampling)
244where
245    USARTX: Deref<Target = pac::usart0::RegisterBlock> + Enable + Reset + BusClocks,
246{
247    let clocks = rcu.clocks();
248    let pclk = USARTX::clock(&clocks).to_Hz();
249    let baud = baud.to_raw();
250    assert!(baud != 0, "USART baud rate must not be zero");
251    // round(pclk / baud) in integers: adding half the divisor before truncating rounds.
252    let usartdiv = (pclk + baud / 2) / baud;
253    let usartdiv_max = match oversampling {
254        Oversampling::X16 => USARTDIV_MAX_X16,
255        Oversampling::X8 => USARTDIV_MAX_X8,
256    };
257    assert!(
258        usartdiv <= usartdiv_max,
259        "USART baud rate too low for this clock"
260    );
261
262    USARTX::enable(rcu);
263    USARTX::reset(rcu);
264    // SAFETY: asserted above to fit `BAUD`.
265    usart.baud().write(|w| unsafe {
266        match oversampling {
267            Oversampling::X16 => w.bits(usartdiv),
268            Oversampling::X8 => {
269                let intdiv = usartdiv / 8;
270                let fradiv_8 = usartdiv % 8;
271                w.bits((intdiv << 4) | (fradiv_8 & 0x7))
272            }
273        }
274    });
275
276    // UEN, TEN and REN are all left off here: WL and parity must be written
277    // while the USART is disabled, and the manual brings the three up in their
278    // own order afterwards (UEN, then the transmitter and receiver).
279    usart.ctl0().modify(|_, w| match oversampling {
280        Oversampling::X16 => w.ovsmod().oversampling16(),
281        Oversampling::X8 => w.ovsmod().oversampling8(),
282    });
283}
284
285/// Brings the peripheral up, in the order the manual prescribes: `UEN` first,
286/// the transmitter and receiver after it.
287fn enable<USARTX>(usart: &USARTX)
288where
289    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
290{
291    usart.ctl0().modify(|_, w| w.uen().enabled());
292    usart
293        .ctl0()
294        .modify(|_, w| w.ten().enabled().ren().enabled());
295}
296
297/// Word-width marker: 8-bit words ([`Usart::write_byte`], [`Usart::read_byte`]),
298/// optionally with parity.
299pub struct Byte;
300/// Word-width marker: raw 9-bit words ([`Usart::write_word`],
301/// [`Usart::read_word`]), no parity possible.
302pub struct Word;
303
304/// A line error the receiver reported for one frame.
305///
306/// The portable classifications are one `kind` call away:
307/// [`embedded_hal_nb::serial::Error::kind`] and [`embedded_io::Error::kind`].
308#[derive(Clone, Copy, Debug, PartialEq, Eq)]
309#[cfg_attr(feature = "defmt", derive(defmt::Format))]
310#[non_exhaustive]
311pub enum Error {
312    /// A frame arrived before the previous one had been read, and was lost.
313    Overrun,
314    /// The sampling logic disagreed with itself about a bit's level.
315    Noise,
316    /// The stop bit was not where the configured frame said it would be —
317    /// usually a baud rate or frame format mismatch between the two ends.
318    Framing,
319    /// The parity bit contradicts the data bits.
320    Parity,
321}
322
323impl core::fmt::Display for Error {
324    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
325        match self {
326            Self::Overrun => write!(f, "receive overrun, a frame was lost"),
327            Self::Noise => write!(f, "noise detected on the line"),
328            Self::Framing => write!(f, "framing error, no stop bit where expected"),
329            Self::Parity => write!(f, "parity check failed"),
330        }
331    }
332}
333
334impl core::error::Error for Error {}
335
336impl embedded_io::Error for Error {
337    fn kind(&self) -> embedded_io::ErrorKind {
338        match self {
339            Self::Framing | Self::Noise | Self::Parity => embedded_io::ErrorKind::InvalidData,
340            Self::Overrun => embedded_io::ErrorKind::Other,
341        }
342    }
343}
344
345impl embedded_hal_nb::serial::Error for Error {
346    fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
347        match self {
348            Self::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
349            Self::Noise => embedded_hal_nb::serial::ErrorKind::Noise,
350            Self::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
351            Self::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
352        }
353    }
354}
355
356/// A USART event that can raise an interrupt.
357#[derive(Clone, Copy, PartialEq, Eq)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359pub enum Event {
360    /// A byte arrived in `RDATA`, cleared by reading it.
361    ///
362    /// Also carries overrun: `ORERR` reaches the NVIC through this enable as
363    /// well as through [`Error`](Self::Error), and
364    /// [`read_byte`](Usart::read_byte) acknowledges it either way.
365    Rbne,
366    /// The transmit buffer is free — true at idle, so listening for this needs
367    /// `unlisten` from inside the handler once nothing is left to send.
368    Tbe,
369    /// A framing, noise or overrun error.
370    ///
371    /// Reaches the NVIC **only while receiving through DMA**: in hardware the
372    /// enable is `ANDed` with the DMA request line, so without it the interrupt
373    /// never fires. Cleared by [`take_error`](Usart::take_error), which a
374    /// handler must call — nothing else drains these flags on the DMA path.
375    Error,
376    /// The parity check failed.
377    ///
378    /// Its own enable, separate from [`Error`](Self::Error) and not gated by
379    /// DMA. Cleared by [`take_error`](Usart::take_error).
380    ParityError,
381}
382
383/// A configured USART, owning the peripheral and both pins.
384///
385/// `WORD` is the word width: `write_byte`/`read_byte` live on `Usart<..,
386/// Byte>`, `write_word`/`read_word` on `Usart<.., Word>`. Defaults to [`Byte`].
387pub struct Usart<USARTX, TX, RX, WORD = Byte> {
388    usart: USARTX,
389    tx_pin: TX,
390    rx_pin: RX,
391    frame_format: FrameFormat,
392    _word: PhantomData<WORD>,
393}
394
395impl<USARTX, TX, RX, WORD> Usart<USARTX, TX, RX, WORD>
396where
397    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
398{
399    /// Returns the pending receive error, if any, and clears it.
400    ///
401    /// The acknowledge for [`Event::Error`] and [`Event::ParityError`]: those
402    /// flags are what hold the interrupt request up, and on the DMA receive path
403    /// nothing else drains them, so a handler that skips this re-enters forever.
404    /// One error per call — with two pending, the second survives for the next.
405    /// Also drains `RDATA`, the frame having been lost or corrupted either way.
406    pub fn take_error(&mut self) -> Option<Error> {
407        let stat = self.usart.stat().read();
408        let error = if stat.orerr().bit_is_set() {
409            self.usart.intc().write(|w| w.orec().clear());
410            Some(Error::Overrun)
411        } else if stat.nerr().bit_is_set() {
412            self.usart.intc().write(|w| w.nec().clear());
413            Some(Error::Noise)
414        } else if stat.ferr().bit_is_set() {
415            self.usart.intc().write(|w| w.fec().clear());
416            Some(Error::Framing)
417        } else if stat.perr().bit_is_set() {
418            self.usart.intc().write(|w| w.pec().clear());
419            Some(Error::Parity)
420        } else {
421            None
422        };
423
424        if error.is_some() {
425            self.usart.rdata().read();
426        }
427
428        error
429    }
430    fn rbne(&self) -> bool {
431        self.usart.stat().read().rbne().bit_is_set()
432    }
433    fn tbe(&self) -> bool {
434        self.usart.stat().read().tbe().bit_is_set()
435    }
436    fn tc(&self) -> bool {
437        self.usart.stat().read().tc().bit_is_set()
438    }
439    fn wait_tc(&self) {
440        while !self.tc() {}
441    }
442
443    /// Returns whether a received word is waiting to be read.
444    ///
445    /// Only guarantees that the *next* single read will not block; a buffered
446    /// read may still block once it has taken what was already there.
447    pub fn read_ready(&self) -> bool {
448        self.rbne()
449    }
450    /// Returns whether the transmit buffer can accept a word right now.
451    ///
452    /// Only guarantees that the *next* single write will not block.
453    pub fn write_ready(&self) -> bool {
454        self.tbe()
455    }
456    /// Returns whether everything handed to the peripheral has left the wire.
457    ///
458    /// `TC`, the flag [`flush`](Usart::flush) waits for, so this is the same
459    /// question asked without blocking.
460    pub fn flush_ready(&self) -> bool {
461        self.tc()
462    }
463    /// Blocks until everything handed to the peripheral has left the wire.
464    ///
465    /// Waits for `TC`, not `TBE` — the latter only says `TDATA` reached the shift
466    /// register while the byte is still being clocked out. Call this before
467    /// cutting power to a transceiver or sleeping. Cannot fail.
468    pub fn flush(&self) {
469        self.wait_tc();
470    }
471
472    /// Lets `event` raise an interrupt. Unmasking the line in the NVIC is the
473    /// caller's.
474    ///
475    /// No event needs a separate clear — each is acknowledged by the same call a
476    /// handler makes to do its work: `Rbne` by [`read_byte`](Usart::read_byte),
477    /// `Tbe` by [`write_byte`](Usart::write_byte), both error events by
478    /// [`take_error`](Usart::take_error). `Tbe` is set whenever nothing is
479    /// queued, so a handler that listens for it must call `unlisten` once it has
480    /// nothing left to send, or it re-enters at once.
481    pub fn listen(&mut self, event: Event) {
482        match event {
483            Event::Rbne => self.usart.ctl0().modify(|_, w| w.rbneie().enabled()),
484            Event::Tbe => self.usart.ctl0().modify(|_, w| w.tbeie().enabled()),
485            Event::Error => self.usart.ctl2().modify(|_, w| w.errie().enabled()),
486            Event::ParityError => self.usart.ctl0().modify(|_, w| w.perrie().enabled()),
487        }
488    }
489    /// Stops `event` from raising an interrupt. Leaves the NVIC alone.
490    pub fn unlisten(&mut self, event: Event) {
491        match event {
492            Event::Rbne => self.usart.ctl0().modify(|_, w| w.rbneie().disabled()),
493            Event::Tbe => self.usart.ctl0().modify(|_, w| w.tbeie().disabled()),
494            Event::Error => self.usart.ctl2().modify(|_, w| w.errie().disabled()),
495            Event::ParityError => self.usart.ctl0().modify(|_, w| w.perrie().disabled()),
496        }
497    }
498    /// Whether `event` currently raises an interrupt.
499    ///
500    /// Every event here shares one NVIC line, so a handler needs this to tell
501    /// which of them woke it: the flag alone is not enough, since `Tbe` is set
502    /// at idle regardless of whether it is being listened for.
503    pub fn is_listening(&self, event: Event) -> bool {
504        match event {
505            Event::Rbne => self.usart.ctl0().read().rbneie().is_enabled(),
506            Event::Tbe => self.usart.ctl0().read().tbeie().is_enabled(),
507            Event::Error => self.usart.ctl2().read().errie().is_enabled(),
508            Event::ParityError => self.usart.ctl0().read().perrie().is_enabled(),
509        }
510    }
511
512    /// Waits for the last frame to leave the wire, then returns the peripheral
513    /// and both pins, disabled, with its interrupts off and its clock stopped.
514    pub fn release(mut self, rcu: &mut Rcu) -> (USARTX, TX, RX)
515    where
516        USARTX: Enable,
517    {
518        self.wait_tc();
519        self.unlisten(Event::Rbne);
520        self.unlisten(Event::Tbe);
521        self.unlisten(Event::Error);
522        self.unlisten(Event::ParityError);
523        self.usart.ctl0().modify(|_, w| w.uen().disabled());
524        USARTX::disable(rcu);
525        (self.usart, self.tx_pin, self.rx_pin)
526    }
527}
528
529impl<USARTX, TX, RX> Usart<USARTX, TX, RX, Byte>
530where
531    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
532{
533    fn received_byte(&mut self) -> u8 {
534        let raw = self.usart.rdata().read().bits() as u8;
535        match self.frame_format {
536            FrameFormat::E7 | FrameFormat::O7 => raw & DATA_7BIT_MASK,
537            FrameFormat::N8 | FrameFormat::E8 | FrameFormat::O8 => raw,
538        }
539    }
540
541    /// Sends one byte, blocking until the transmit buffer can accept it.
542    ///
543    /// Returning does not mean the byte has left the wire — for that, see
544    /// [`flush`](Usart::flush).
545    pub fn write_byte(&mut self, byte: u8) {
546        while !self.tbe() {}
547        // SAFETY: a byte always fits `TDATA`.
548        self.usart.tdata().write(|w| unsafe { w.bits(byte as u32) });
549    }
550    /// Sends every byte of `buf`, blocking until the last one is handed over.
551    ///
552    /// Returning does not mean the buffer has left the wire — for that see
553    /// [`flush`](Usart::flush). Cannot fail.
554    pub fn write_bytes(&mut self, buf: &[u8]) {
555        for &byte in buf {
556            self.write_byte(byte);
557        }
558    }
559    /// Receives one byte, blocking until one arrives.
560    ///
561    /// # Errors
562    ///
563    /// The line error flagged on the frame, which is consumed and reported
564    /// instead of the data, so a damaged byte is never mistaken for a good one.
565    pub fn read_byte(&mut self) -> Result<u8, Error> {
566        while !self.rbne() {}
567        if let Some(e) = self.take_error() {
568            Err(e)
569        } else {
570            Ok(self.received_byte())
571        }
572    }
573    /// Receives into `buf` and returns how many bytes were placed there.
574    ///
575    /// Blocks until at least one byte arrives, then takes whatever else is
576    /// waiting and returns — it does *not* wait for `buf` to fill, which would
577    /// deadlock against a peer waiting for its answer. Returns `0` only for an
578    /// empty `buf`.
579    ///
580    /// # Errors
581    ///
582    /// A line error ends the call at once, losing the bytes copied before it:
583    /// the count is not reported alongside an error.
584    pub fn read_bytes(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
585        if buf.is_empty() {
586            return Ok(0);
587        }
588        let mut index = 0;
589        while !self.rbne() {}
590        while index < buf.len() && self.rbne() {
591            buf[index] = self.read_byte()?;
592            index += 1;
593        }
594        Ok(index)
595    }
596}
597
598impl<USARTX, TX, RX> Usart<USARTX, TX, RX, Byte>
599where
600    USARTX: Deref<Target = pac::usart0::RegisterBlock> + Enable + Reset + BusClocks,
601    TX: TxPin<USARTX>,
602    RX: RxPin<USARTX>,
603{
604    /// Enables the peripheral's clock, resets it and configures 8-bit words.
605    ///
606    /// The pins must already be in this USART's alternate function;
607    /// [`release`](Usart::release) hands them back.
608    ///
609    /// # Panics
610    ///
611    /// If the baud rate is zero, or too low to reach from the USART's clock.
612    /// Checked before the peripheral is touched.
613    pub fn new(rcu: &mut Rcu, usart: USARTX, tx_pin: TX, rx_pin: RX, config: UsartConfig) -> Self {
614        configure(rcu, &usart, config.baud, config.oversampling);
615
616        usart.ctl0().modify(|_, w| match config.frame_format {
617            FrameFormat::N8 => w.pcen().disabled().wl().bit8(),
618            FrameFormat::E8 => w.pcen().enabled().pm().even().wl().bit9(),
619            FrameFormat::O8 => w.pcen().enabled().pm().odd().wl().bit9(),
620            FrameFormat::E7 => w.pcen().enabled().pm().even().wl().bit8(),
621            FrameFormat::O7 => w.pcen().enabled().pm().odd().wl().bit8(),
622        });
623        enable(&usart);
624        Self {
625            usart,
626            tx_pin,
627            rx_pin,
628            frame_format: config.frame_format,
629            _word: PhantomData,
630        }
631    }
632}
633
634impl<USARTX, TX, RX> Usart<USARTX, TX, RX, Word>
635where
636    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
637{
638    /// Sends one 9-bit word, blocking until the transmit buffer can accept it.
639    ///
640    /// Bits above the ninth are discarded.
641    pub fn write_word(&mut self, word: u16) {
642        while !self.tbe() {}
643        // SAFETY: masked to the nine bits `TDATA` holds.
644        self.usart
645            .tdata()
646            .write(|w| unsafe { w.bits(word as u32 & DATA_9BIT_MASK) });
647    }
648    /// Sends every word of `buf`, blocking until the last one is handed over.
649    ///
650    /// Returning does not mean the buffer has left the wire — for that see
651    /// [`flush`](Usart::flush). Cannot fail.
652    pub fn write_words(&mut self, buf: &[u16]) {
653        for &word in buf {
654            self.write_word(word);
655        }
656    }
657    /// Receives one 9-bit word, blocking until one arrives.
658    ///
659    /// # Errors
660    ///
661    /// As for [`read_byte`](Usart::read_byte).
662    pub fn read_word(&mut self) -> Result<u16, Error> {
663        while !self.rbne() {}
664        if let Some(e) = self.take_error() {
665            Err(e)
666        } else {
667            Ok((self.usart.rdata().read().bits() & DATA_9BIT_MASK) as u16)
668        }
669    }
670    /// Receives into `buf` and returns how many words were placed there.
671    ///
672    /// Same blocking rule as [`read_bytes`](Usart::read_bytes): waits for the
673    /// first word, then takes only what is already waiting.
674    ///
675    /// # Errors
676    ///
677    /// As for [`read_bytes`](Usart::read_bytes).
678    pub fn read_words(&mut self, buf: &mut [u16]) -> Result<usize, Error> {
679        if buf.is_empty() {
680            return Ok(0);
681        }
682        let mut index = 0;
683        while !self.rbne() {}
684        while index < buf.len() && self.rbne() {
685            buf[index] = self.read_word()?;
686            index += 1;
687        }
688        Ok(index)
689    }
690}
691
692impl<USARTX, TX, RX> Usart<USARTX, TX, RX, Word>
693where
694    USARTX: Deref<Target = pac::usart0::RegisterBlock> + Enable + Reset + BusClocks,
695    TX: TxPin<USARTX>,
696    RX: RxPin<USARTX>,
697{
698    /// Same as [`new`](Usart::new), but configures raw 9-bit words with no parity.
699    ///
700    /// All nine bits carry data, so there is no frame format to choose and the
701    /// peripheral moves `u16` rather than `u8`.
702    ///
703    /// # Panics
704    ///
705    /// As for [`new`](Usart::new).
706    pub fn new_word(
707        rcu: &mut Rcu,
708        usart: USARTX,
709        tx_pin: TX,
710        rx_pin: RX,
711        config: UsartConfig9,
712    ) -> Self {
713        configure(rcu, &usart, config.baud, config.oversampling);
714        usart.ctl0().modify(|_, w| w.pcen().disabled().wl().bit9());
715        enable(&usart);
716        Self {
717            usart,
718            tx_pin,
719            rx_pin,
720            // Never read: only `Byte`'s `received_byte` looks at `frame_format`.
721            frame_format: FrameFormat::N8,
722            _word: PhantomData,
723        }
724    }
725}
726
727impl<USARTX, TX, RX, WORD> embedded_hal_nb::serial::ErrorType for Usart<USARTX, TX, RX, WORD> {
728    type Error = Error;
729}
730
731impl<USARTX, TX, RX, WORD> embedded_io::ErrorType for Usart<USARTX, TX, RX, WORD> {
732    type Error = Error;
733}
734
735impl<USARTX, TX, RX> embedded_hal_nb::serial::Read<u8> for Usart<USARTX, TX, RX, Byte>
736where
737    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
738{
739    fn read(&mut self) -> nb::Result<u8, Self::Error> {
740        if !self.rbne() {
741            return Err(nb::Error::WouldBlock);
742        }
743        if let Some(e) = self.take_error() {
744            Err(nb::Error::Other(e))
745        } else {
746            Ok(self.received_byte())
747        }
748    }
749}
750
751impl<USARTX, TX, RX> embedded_io::Read for Usart<USARTX, TX, RX, Byte>
752where
753    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
754{
755    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
756        self.read_bytes(buf)
757    }
758}
759
760impl<USARTX, TX, RX> embedded_hal_nb::serial::Write<u8> for Usart<USARTX, TX, RX, Byte>
761where
762    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
763{
764    fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
765        if self.tbe() {
766            // SAFETY: a byte always fits `TDATA`.
767            self.usart.tdata().write(|w| unsafe { w.bits(byte as u32) });
768            Ok(())
769        } else {
770            Err(nb::Error::WouldBlock)
771        }
772    }
773    fn flush(&mut self) -> nb::Result<(), Self::Error> {
774        if self.tc() {
775            Ok(())
776        } else {
777            Err(nb::Error::WouldBlock)
778        }
779    }
780}
781
782impl<USARTX, TX, RX> embedded_io::Write for Usart<USARTX, TX, RX, Byte>
783where
784    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
785{
786    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
787        match buf.first() {
788            Some(&b) => {
789                self.write_byte(b);
790                Ok(1usize)
791            }
792            None => Ok(0usize),
793        }
794    }
795    fn flush(&mut self) -> Result<(), Self::Error> {
796        self.wait_tc();
797        Ok(())
798    }
799}
800
801impl<USARTX, TX, RX> embedded_io::ReadReady for Usart<USARTX, TX, RX, Byte>
802where
803    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
804{
805    fn read_ready(&mut self) -> Result<bool, Self::Error> {
806        Ok(self.rbne())
807    }
808}
809
810impl<USARTX, TX, RX> embedded_io::WriteReady for Usart<USARTX, TX, RX, Byte>
811where
812    USARTX: Deref<Target = pac::usart0::RegisterBlock>,
813{
814    fn write_ready(&mut self) -> Result<bool, Self::Error> {
815        Ok(self.tbe())
816    }
817}