1use 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
32const DATA_7BIT_MASK: u8 = 0x7F;
34const DATA_9BIT_MASK: u32 = 0x1FF;
36const USARTDIV_MAX_X16: u32 = 0xFFFF;
38const USARTDIV_MAX_X8: u32 = 0x7FFF;
41
42pub trait TxPin<USART> {}
44pub 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
59usart_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#[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#[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
87pub trait BusClocks {
92 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#[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#[derive(Clone, Copy, PartialEq, Eq)]
139#[cfg_attr(feature = "defmt", derive(defmt::Format))]
140pub enum Oversampling {
141 X8,
143 X16,
145}
146
147#[derive(Clone, Copy, PartialEq, Eq)]
154#[cfg_attr(feature = "defmt", derive(defmt::Format))]
155pub enum FrameFormat {
156 N8,
158 E8,
160 O8,
162 E7,
164 O7,
166}
167
168#[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 pub const fn baud(mut self, baud: Bps) -> Self {
184 self.baud = baud;
185 self
186 }
187 pub const fn oversampling(mut self, oversampling: Oversampling) -> Self {
189 self.oversampling = oversampling;
190 self
191 }
192 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#[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 pub const fn baud(mut self, baud: Bps) -> Self {
224 self.baud = baud;
225 self
226 }
227 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 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 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 usart.ctl0().modify(|_, w| match oversampling {
280 Oversampling::X16 => w.ovsmod().oversampling16(),
281 Oversampling::X8 => w.ovsmod().oversampling8(),
282 });
283}
284
285fn 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
297pub struct Byte;
300pub struct Word;
303
304#[derive(Clone, Copy, Debug, PartialEq, Eq)]
309#[cfg_attr(feature = "defmt", derive(defmt::Format))]
310#[non_exhaustive]
311pub enum Error {
312 Overrun,
314 Noise,
316 Framing,
319 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#[derive(Clone, Copy, PartialEq, Eq)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359pub enum Event {
360 Rbne,
366 Tbe,
369 Error,
376 ParityError,
381}
382
383pub 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 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 pub fn read_ready(&self) -> bool {
448 self.rbne()
449 }
450 pub fn write_ready(&self) -> bool {
454 self.tbe()
455 }
456 pub fn flush_ready(&self) -> bool {
461 self.tc()
462 }
463 pub fn flush(&self) {
469 self.wait_tc();
470 }
471
472 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 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 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 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 pub fn write_byte(&mut self, byte: u8) {
546 while !self.tbe() {}
547 self.usart.tdata().write(|w| unsafe { w.bits(byte as u32) });
549 }
550 pub fn write_bytes(&mut self, buf: &[u8]) {
555 for &byte in buf {
556 self.write_byte(byte);
557 }
558 }
559 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 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 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 pub fn write_word(&mut self, word: u16) {
642 while !self.tbe() {}
643 self.usart
645 .tdata()
646 .write(|w| unsafe { w.bits(word as u32 & DATA_9BIT_MASK) });
647 }
648 pub fn write_words(&mut self, buf: &[u16]) {
653 for &word in buf {
654 self.write_word(word);
655 }
656 }
657 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 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 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 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 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}