1use core::{
11 convert::{Infallible, TryFrom},
12 fmt,
13 ops::Deref,
14};
15
16use crate::{
17 gpio::{gpioa, gpiob, gpioc, AF7},
18 hal::{blocking, serial, serial::Write},
19 pac::{
20 rcc::cfgr3::USART1SW_A,
21 usart1::{cr1::M_A, cr1::PCE_A, cr1::PS_A, RegisterBlock},
22 Interrupt, USART1, USART2, USART3,
23 },
24 rcc::{self, Clocks},
25 time::fixed_point::FixedPoint,
26 time::rate::{Baud, Hertz},
27 Switch,
28};
29
30#[allow(unused_imports)]
31use crate::pac::RCC;
32
33use cfg_if::cfg_if;
34#[cfg(feature = "enumset")]
35use enumset::{EnumSet, EnumSetType};
36
37use crate::dma;
38
39#[derive(Debug)]
44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
45#[cfg_attr(feature = "enumset", derive(EnumSetType))]
46#[cfg_attr(not(feature = "enumset"), derive(Copy, Clone, PartialEq, Eq))]
47#[non_exhaustive]
48pub enum Event {
50 #[doc(alias = "TXE")]
56 TransmitDataRegisterEmtpy,
57 #[doc(alias = "CTSIF")]
61 CtsInterrupt,
62 #[doc(alias = "TC")]
68 TransmissionComplete,
69 #[doc(alias = "RXNE")]
75 ReceiveDataRegisterNotEmpty,
76 #[doc(alias = "ORE")]
84 OverrunError,
85 Idle,
89 #[doc(alias = "PE")]
95 ParityError,
96 #[doc(alias = "NF")]
100 NoiseError,
101 #[doc(alias = "FE")]
106 FramingError,
107 #[doc(alias = "LBDF")]
111 LinBreak,
112 #[doc(alias = "CMF")]
116 CharacterMatch,
117 #[doc(alias = "RTOF")]
125 ReceiverTimeout,
126 }
141
142#[derive(Copy, Clone, PartialEq, Eq, Debug)]
146#[cfg_attr(feature = "defmt", derive(defmt::Format))]
147#[non_exhaustive]
148pub enum Error {
149 Framing,
154 Noise,
158 Overrun,
175 Parity,
179}
180
181impl From<Error> for Event {
182 fn from(error: Error) -> Self {
183 match error {
184 Error::Framing => Event::FramingError,
185 Error::Overrun => Event::OverrunError,
186 Error::Noise => Event::NoiseError,
187 Error::Parity => Event::ParityError,
188 }
189 }
190}
191
192#[derive(Debug, Copy, Clone, PartialEq, Eq)]
194#[cfg_attr(feature = "defmt", derive(defmt::Format))]
195pub struct TryFromEventError(pub(crate) ());
196
197impl TryFrom<Event> for Error {
198 type Error = TryFromEventError;
199 fn try_from(event: Event) -> Result<Self, Self::Error> {
200 Ok(match event {
201 Event::FramingError => Error::Framing,
202 Event::OverrunError => Error::Overrun,
203 Event::NoiseError => Error::Noise,
204 Event::ParityError => Error::Parity,
205 _ => return Err(TryFromEventError(())),
206 })
207 }
208}
209
210#[derive(Copy, Clone, PartialEq, Eq)]
212#[cfg_attr(feature = "defmt", derive(defmt::Format))]
213#[non_exhaustive]
214#[allow(missing_docs)]
215pub enum BaudTable {
216 Bd1200,
217 Bd9600,
218 Bd19200,
219 Bd38400,
220 Bd57600,
221 Bd115200,
222 Bd230400,
223 Bd460800,
224}
225
226impl From<BaudTable> for Baud {
227 fn from(baud: BaudTable) -> Self {
228 match baud {
229 BaudTable::Bd1200 => Baud(1_200),
230 BaudTable::Bd9600 => Baud(9_600),
231 BaudTable::Bd19200 => Baud(19_200),
232 BaudTable::Bd38400 => Baud(38_400),
233 BaudTable::Bd57600 => Baud(57_600),
234 BaudTable::Bd115200 => Baud(115_200),
235 BaudTable::Bd230400 => Baud(230_400),
236 BaudTable::Bd460800 => Baud(460_800),
237 }
238 }
239}
240
241#[derive(Debug, Copy, Clone, PartialEq, Eq)]
243#[cfg_attr(feature = "defmt", derive(defmt::Format))]
244pub struct TryFromBaudError(pub(crate) ());
245
246impl TryFrom<Baud> for BaudTable {
247 type Error = TryFromBaudError;
248 fn try_from(baud: Baud) -> Result<Self, Self::Error> {
249 Ok(match baud {
250 Baud(1_200) => BaudTable::Bd1200,
251 Baud(9_600) => BaudTable::Bd9600,
252 Baud(19_200) => BaudTable::Bd19200,
253 Baud(38_400) => BaudTable::Bd38400,
254 Baud(57_600) => BaudTable::Bd57600,
255 Baud(115_200) => BaudTable::Bd115200,
256 Baud(230_400) => BaudTable::Bd230400,
257 Baud(460_800) => BaudTable::Bd460800,
258 _ => return Err(TryFromBaudError(())),
259 })
260 }
261}
262
263pub trait TxPin<Usart>: crate::private::Sealed {}
265
266pub trait RxPin<Usart>: crate::private::Sealed {}
268
269impl<Otype> TxPin<USART1> for gpioa::PA9<AF7<Otype>> {}
270impl<Otype> TxPin<USART1> for gpiob::PB6<AF7<Otype>> {}
271impl<Otype> TxPin<USART1> for gpioc::PC4<AF7<Otype>> {}
272impl<Otype> RxPin<USART1> for gpioa::PA10<AF7<Otype>> {}
273impl<Otype> RxPin<USART1> for gpiob::PB7<AF7<Otype>> {}
274impl<Otype> RxPin<USART1> for gpioc::PC5<AF7<Otype>> {}
275
276impl<Otype> TxPin<USART2> for gpioa::PA2<AF7<Otype>> {}
277impl<Otype> TxPin<USART2> for gpiob::PB3<AF7<Otype>> {}
278impl<Otype> RxPin<USART2> for gpioa::PA3<AF7<Otype>> {}
279impl<Otype> RxPin<USART2> for gpiob::PB4<AF7<Otype>> {}
280
281impl<Otype> TxPin<USART3> for gpiob::PB10<AF7<Otype>> {}
282impl<Otype> TxPin<USART3> for gpioc::PC10<AF7<Otype>> {}
283impl<Otype> RxPin<USART3> for gpioc::PC11<AF7<Otype>> {}
284
285cfg_if! {
286 if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e", feature = "gpio-f373"))] {
287 use crate::gpio::{gpiod, gpioe};
288
289 impl<Otype> TxPin<USART1> for gpioe::PE0<AF7<Otype>> {}
290 impl<Otype> RxPin<USART1> for gpioe::PE1<AF7<Otype>> {}
291
292 impl<Otype> TxPin<USART2> for gpiod::PD5<AF7<Otype>> {}
293 impl<Otype> RxPin<USART2> for gpiod::PD6<AF7<Otype>> {}
294
295 impl<Otype> TxPin<USART3> for gpiod::PD8<AF7<Otype>> {}
296 impl<Otype> RxPin<USART3> for gpiod::PD9<AF7<Otype>> {}
297 impl<Otype> RxPin<USART3> for gpioe::PE15<AF7<Otype>> {}
298 }
299}
300
301cfg_if! {
302 if #[cfg(not(feature = "gpio-f373"))] {
303 impl<Otype> TxPin<USART2> for gpioa::PA14<AF7<Otype>> {}
304 impl<Otype> RxPin<USART2> for gpioa::PA15<AF7<Otype>> {}
305
306 impl<Otype> RxPin<USART3> for gpiob::PB11<AF7<Otype>> {}
307 }
308}
309
310cfg_if! {
311 if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e",))] {
312 use crate::pac::{UART4, UART5};
313 use crate::gpio::AF5;
314
315 impl<Otype> TxPin<UART4> for gpioc::PC10<AF5<Otype>> {}
316 impl<Otype> RxPin<UART4> for gpioc::PC11<AF5<Otype>> {}
317 impl<Otype> TxPin<UART5> for gpioc::PC12<AF5<Otype>> {}
318 impl<Otype> RxPin<UART5> for gpiod::PD2<AF5<Otype>> {}
319 }
320}
321
322pub mod config;
323
324pub struct Serial<Usart, Pins> {
329 usart: Usart,
330 pins: Pins,
331}
332
333impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
334where
335 Usart: Instance,
336{
337 pub fn new<Config>(
343 usart: Usart,
344 pins: (Tx, Rx),
345 config: Config,
346 clocks: Clocks,
347 apb: &mut <Usart as rcc::RccBus>::Bus,
348 ) -> Self
349 where
350 Usart: Instance,
351 Tx: TxPin<Usart>,
352 Rx: RxPin<Usart>,
353 Config: Into<config::Config>,
354 {
355 use config::Parity;
356
357 let config = config.into();
358
359 Usart::enable(apb);
361 Usart::reset(apb);
362 usart.cr1.modify(|_, w| w.ue().disabled());
365
366 let brr = Usart::clock(&clocks).integer() / config.baudrate.integer();
367 crate::assert!(brr >= 16, "impossible baud rate");
368 usart.brr.write(|w| {
369 w.brr().bits(
370 unsafe { u16::try_from(brr).unwrap_unchecked() },
372 )
373 });
374
375 let (m0, ps, pce) = match config.parity {
380 Parity::None => (M_A::Bit8, PS_A::Even, PCE_A::Disabled),
381 Parity::Even => (M_A::Bit9, PS_A::Even, PCE_A::Enabled),
382 Parity::Odd => (M_A::Bit9, PS_A::Odd, PCE_A::Enabled),
383 };
384
385 usart
386 .cr2
387 .modify(|_, w| w.stop().variant(config.stopbits.into()));
388 usart.cr1.modify(|_, w| {
389 w.ps().variant(ps); w.pce().variant(pce); w.m().variant(m0); w.re().enabled(); w.te().enabled() });
395
396 usart.cr1.modify(|_, w| w.ue().enabled());
398
399 Self { usart, pins }
400 }
401
402 pub unsafe fn peripheral(&mut self) -> &mut Usart {
412 &mut self.usart
413 }
414
415 pub fn free(self) -> (Usart, (Tx, Rx)) {
417 self.usart
418 .cr1
419 .modify(|_, w| w.ue().disabled().re().disabled().te().disabled());
420 (self.usart, self.pins)
421 }
422}
423
424impl<Usart, Pins> Serial<Usart, Pins>
425where
426 Usart: Instance,
427{
428 #[doc(alias = "RDR")]
442 pub fn read_data_register(&self) -> Option<u8> {
443 if self.usart.isr.read().busy().bit_is_set() {
444 return None;
445 }
446 #[allow(clippy::cast_possible_truncation)]
447 Some(self.usart.rdr.read().rdr().bits() as u8)
448 }
449
450 pub fn is_busy(&mut self) -> bool {
455 self.usart.isr.read().busy().bit_is_set()
456 }
457
458 #[doc(alias = "unmask")]
477 pub fn interrupt(&self) -> <Usart as crate::interrupts::InterruptNumber>::Interrupt {
478 <Usart as crate::interrupts::InterruptNumber>::INTERRUPT
479 }
480
481 #[inline]
483 pub fn enable_interrupt(&mut self, event: Event) {
484 self.configure_interrupt(event, Switch::On);
485 }
486
487 #[inline]
489 pub fn disable_interrupt(&mut self, event: Event) {
490 self.configure_interrupt(event, Switch::Off);
491 }
492
493 #[inline]
495 pub fn configure_interrupt(&mut self, event: Event, enable: impl Into<Switch>) {
496 let enable: Switch = enable.into();
498 let enable: bool = enable.into();
499 match event {
500 Event::TransmitDataRegisterEmtpy => self.usart.cr1.modify(|_, w| w.txeie().bit(enable)),
501 Event::CtsInterrupt => self.usart.cr3.modify(|_, w| w.ctsie().bit(enable)),
502 Event::TransmissionComplete => self.usart.cr1.modify(|_, w| w.tcie().bit(enable)),
503 Event::ReceiveDataRegisterNotEmpty => {
504 self.usart.cr1.modify(|_, w| w.rxneie().bit(enable));
505 }
506 Event::ParityError => self.usart.cr1.modify(|_, w| w.peie().bit(enable)),
507 Event::LinBreak => self.usart.cr2.modify(|_, w| w.lbdie().bit(enable)),
508 Event::NoiseError | Event::OverrunError | Event::FramingError => {
509 self.usart.cr3.modify(|_, w| w.eie().bit(enable));
510 }
511 Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().bit(enable)),
512 Event::CharacterMatch => self.usart.cr1.modify(|_, w| w.cmie().bit(enable)),
513 Event::ReceiverTimeout => self.usart.cr1.modify(|_, w| w.rtoie().bit(enable)),
514 };
517 }
518
519 #[cfg(feature = "enumset")]
525 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
526 pub fn configure_interrupts(&mut self, events: EnumSet<Event>) {
527 for event in events.complement().iter() {
528 self.configure_interrupt(event, false);
529 }
530 for event in events.iter() {
531 self.configure_interrupt(event, true);
532 }
533 }
534
535 #[inline]
537 pub fn is_interrupt_configured(&self, event: Event) -> bool {
538 match event {
539 Event::TransmitDataRegisterEmtpy => self.usart.cr1.read().txeie().is_enabled(),
540 Event::CtsInterrupt => self.usart.cr3.read().ctsie().is_enabled(),
541 Event::TransmissionComplete => self.usart.cr1.read().tcie().is_enabled(),
542 Event::ReceiveDataRegisterNotEmpty => self.usart.cr1.read().rxneie().is_enabled(),
543 Event::ParityError => self.usart.cr1.read().peie().is_enabled(),
544 Event::LinBreak => self.usart.cr2.read().lbdie().is_enabled(),
545 Event::NoiseError | Event::OverrunError | Event::FramingError => {
546 self.usart.cr3.read().eie().is_enabled()
547 }
548 Event::Idle => self.usart.cr1.read().idleie().is_enabled(),
549 Event::CharacterMatch => self.usart.cr1.read().cmie().is_enabled(),
550 Event::ReceiverTimeout => self.usart.cr1.read().rtoie().is_enabled(),
551 }
554 }
555
556 #[cfg(feature = "enumset")]
558 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
559 #[inline]
560 pub fn configured_interrupts(&mut self) -> EnumSet<Event> {
561 let mut events = EnumSet::new();
562
563 for event in EnumSet::<Event>::all().iter() {
564 if self.is_interrupt_configured(event) {
565 events |= event;
566 }
567 }
568
569 events
570 }
571
572 #[inline]
574 pub fn is_event_triggered(&self, event: Event) -> bool {
575 let isr = self.usart.isr.read();
576 match event {
577 Event::TransmitDataRegisterEmtpy => isr.txe().bit(),
578 Event::CtsInterrupt => isr.ctsif().bit(),
579 Event::TransmissionComplete => isr.tc().bit(),
580 Event::ReceiveDataRegisterNotEmpty => isr.rxne().bit(),
581 Event::OverrunError => isr.ore().bit(),
582 Event::Idle => isr.idle().bit(),
583 Event::ParityError => isr.pe().bit(),
584 Event::LinBreak => isr.lbdf().bit(),
585 Event::NoiseError => isr.nf().bit(),
586 Event::FramingError => isr.fe().bit(),
587 Event::CharacterMatch => isr.cmf().bit(),
588 Event::ReceiverTimeout => isr.rtof().bit(),
589 }
592 }
593
594 #[cfg(feature = "enumset")]
606 #[cfg_attr(docsrs, doc(cfg(feature = "enumset")))]
607 pub fn triggered_events(&self) -> EnumSet<Event> {
608 let mut events = EnumSet::new();
609
610 for event in EnumSet::<Event>::all().iter() {
611 if self.is_event_triggered(event) {
612 events |= event;
613 }
614 }
615
616 events
617 }
618
619 #[inline]
621 pub fn clear_event(&mut self, event: Event) {
622 self.usart.icr.write(|w| match event {
623 Event::CtsInterrupt => w.ctscf().clear(),
624 Event::TransmissionComplete => w.tccf().clear(),
625 Event::OverrunError => w.orecf().clear(),
626 Event::Idle => w.idlecf().clear(),
627 Event::ParityError => w.pecf().clear(),
628 Event::LinBreak => w.lbdcf().clear(),
629 Event::NoiseError => w.ncf().clear(),
630 Event::FramingError => w.fecf().clear(),
631 Event::CharacterMatch => w.cmcf().clear(),
632 Event::ReceiverTimeout => w.rtocf().clear(),
633 Event::ReceiveDataRegisterNotEmpty => {
636 self.usart.rqr.write(|w| w.rxfrq().set_bit());
638 w
639 }
640 Event::TransmitDataRegisterEmtpy => w,
643 });
644 }
645
646 #[inline]
648 pub fn clear_events(&mut self) {
649 self.usart.icr.write(|w| unsafe { w.bits(u32::MAX) });
651 }
652
653 #[doc(alias = "OVRDIS")]
660 #[inline]
661 pub fn detect_overrun(&mut self, enable: bool) {
662 let uart_enabled = self.usart.cr1.read().ue().bit();
663 self.usart.cr1.modify(|_, w| w.ue().disabled());
664 self.usart.cr3.modify(|_, w| w.ovrdis().bit(!enable));
665 self.usart.cr1.modify(|_, w| w.ue().bit(uart_enabled));
666 }
667
668 pub fn set_match_character(&mut self, char: u8) {
674 let enabled = self.usart.cr1.read().ue().bit_is_set();
677 self.usart.cr1.modify(|_, w| w.ue().disabled());
678 self.usart.cr2.modify(|_, w| w.add().bits(char));
679 self.usart.cr1.modify(|_, w| w.ue().bit(enabled));
680 }
681
682 pub fn match_character(&self) -> u8 {
684 self.usart.cr2.read().add().bits()
685 }
686}
687
688impl<Usart, Tx, Rx> Serial<Usart, (Tx, Rx)>
689where
690 Usart: Instance + ReceiverTimeoutExt,
691{
692 pub fn set_receiver_timeout(&mut self, value: Option<u32>) {
709 if let Some(value) = value {
710 self.usart.cr2.modify(|_, w| w.rtoen().enabled());
711 self.usart.rtor.modify(|_, w| w.rto().bits(value));
712 } else {
713 self.usart.cr2.modify(|_, w| w.rtoen().disabled());
714 }
715 }
716
717 pub fn receiver_timeout(&self) -> Option<u32> {
724 if self.usart.cr2.read().rtoen().is_enabled() {
725 Some(self.usart.rtor.read().rto().bits())
726 } else {
727 None
728 }
729 }
730}
731
732fn eh_read<Usart>(usart: &mut Usart) -> nb::Result<u8, Error>
735where
736 Usart: Instance,
737{
738 let isr = usart.isr.read();
739
740 Err(if isr.pe().bit_is_set() {
741 usart.icr.write(|w| w.pecf().clear());
742 nb::Error::Other(Error::Parity)
743 } else if isr.fe().bit_is_set() {
744 usart.icr.write(|w| w.fecf().clear());
745 nb::Error::Other(Error::Framing)
746 } else if isr.nf().bit_is_set() {
747 usart.icr.write(|w| w.ncf().clear());
748 nb::Error::Other(Error::Noise)
749 } else if isr.ore().bit_is_set() {
750 usart.icr.write(|w| w.orecf().clear());
751 usart.rqr.write(|w| w.rxfrq().set_bit());
778 nb::Error::Other(Error::Overrun)
779 } else if isr.rxne().bit_is_set() {
780 #[allow(clippy::cast_possible_truncation)]
781 return Ok(usart.rdr.read().bits() as u8);
782 } else {
783 nb::Error::WouldBlock
784 })
785}
786
787impl<Usart, Tx, Rx> serial::Read<u8> for Serial<Usart, (Tx, Rx)>
789where
790 Usart: Instance,
791{
792 type Error = Error;
793
794 fn read(&mut self) -> nb::Result<u8, Error> {
811 eh_read(&mut self.usart)
812 }
813}
814
815impl<Usart, Pins> serial::Write<u8> for Serial<Usart, Pins>
816where
817 Usart: Instance,
818{
819 type Error = Infallible;
824
825 fn flush(&mut self) -> nb::Result<(), Infallible> {
826 if self.usart.isr.read().tc().bit_is_set() {
827 Ok(())
828 } else {
829 Err(nb::Error::WouldBlock)
830 }
831 }
832
833 fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
834 if self.usart.isr.read().txe().bit_is_set() {
835 self.usart.tdr.write(|w| w.tdr().bits(u16::from(byte)));
836 Ok(())
837 } else {
838 Err(nb::Error::WouldBlock)
839 }
840 }
841}
842
843impl<Usart, Pins> fmt::Write for Serial<Usart, Pins>
844where
845 Serial<Usart, Pins>: serial::Write<u8>,
846{
847 fn write_str(&mut self, s: &str) -> fmt::Result {
848 s.bytes()
849 .try_for_each(|c| nb::block!(self.write(c)))
850 .map_err(|_| fmt::Error)
851 }
852}
853
854impl<USART, TX, RX> blocking::serial::write::Default<u8> for Serial<USART, (TX, RX)> where
855 USART: Instance
856{
857}
858
859impl<Usart, Pins> Serial<Usart, Pins>
860where
861 Usart: Instance + Dma,
862{
863 pub fn read_exact<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
865 where
866 Self: dma::OnChannel<C>,
867 B: dma::WriteBuffer<Word = u8> + 'static,
868 C: dma::Channel,
869 {
870 unsafe {
872 channel.set_peripheral_address(
873 core::ptr::addr_of!(self.usart.rdr) as u32,
874 dma::Increment::Disable,
875 );
876 };
877
878 dma::Transfer::start_write(buffer, channel, self)
879 }
880
881 pub fn write_all<B, C>(self, buffer: B, mut channel: C) -> dma::Transfer<B, C, Self>
883 where
884 Self: dma::OnChannel<C>,
885 B: dma::ReadBuffer<Word = u8> + 'static,
886 C: dma::Channel,
887 {
888 unsafe {
890 channel.set_peripheral_address(
891 core::ptr::addr_of!(self.usart.tdr) as u32,
892 dma::Increment::Disable,
893 );
894 };
895
896 dma::Transfer::start_read(buffer, channel, self)
897 }
898}
899
900impl<Usart, Pins> dma::Target for Serial<Usart, Pins>
901where
902 Usart: Instance + Dma,
903{
904 fn enable_dma(&mut self) {
905 self.usart
906 .cr3
907 .modify(|_, w| w.dmar().enabled().dmat().enabled());
908 }
909
910 fn disable_dma(&mut self) {
911 self.usart
912 .cr3
913 .modify(|_, w| w.dmar().disabled().dmat().disabled());
914 }
915}
916
917pub trait Dma: crate::private::Sealed {}
919
920impl Dma for USART1 {}
921impl Dma for USART2 {}
922impl Dma for USART3 {}
923
924pub trait ReceiverTimeoutExt: crate::private::Sealed {}
926
927impl ReceiverTimeoutExt for USART1 {}
928#[cfg(not(any(feature = "gpio-f333")))]
929impl ReceiverTimeoutExt for USART2 {}
930#[cfg(not(any(feature = "gpio-f333")))]
931impl ReceiverTimeoutExt for USART3 {}
932
933pub trait Instance:
935 Deref<Target = RegisterBlock>
936 + crate::interrupts::InterruptNumber
937 + crate::private::Sealed
938 + rcc::Enable
939 + rcc::Reset
940{
941 #[doc(hidden)]
942 fn clock(clocks: &Clocks) -> Hertz;
943}
944
945macro_rules! usart {
946 (
947 $(
948 $USARTX:ident: ($INTERRUPT:path),
949 )+
950 ) => {
951 $(
952 impl crate::interrupts::InterruptNumber for $USARTX {
953 type Interrupt = Interrupt;
954 const INTERRUPT: Interrupt = $INTERRUPT;
955 }
956
957 #[cfg(feature = "defmt")]
958 impl<Pins> defmt::Format for Serial<$USARTX, Pins> {
959 fn format(&self, f: defmt::Formatter) {
960 defmt::write!(
966 f,
967 "Serial {{ usart: {}, pins: ? }}",
968 stringify!($USARTX),
969 );
970 }
971 }
972
973 impl<Pins> fmt::Debug for Serial<$USARTX, Pins> {
974 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
975 f.debug_struct(stringify!(Serial))
976 .field("usart", &stringify!($USARTX))
977 .field("pins", &"?")
978 .finish()
979 }
980 }
981 )+
982 };
983
984 ([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
985 paste::paste! {
986 usart!(
987 $(
988 [<USART $X>]: ($INTERRUPT),
989 )+
990 );
991 }
992 };
993}
994
995#[allow(unused_macros)]
998macro_rules! usart_static_clock {
999 ($($USARTX:ident),+) => {
1000 $(
1001 impl Instance for $USARTX {
1002 fn clock(clocks: &Clocks) -> Hertz {
1003 <$USARTX as rcc::BusClock>::clock(clocks)
1004 }
1005 }
1006 )+
1007 };
1008 ($($X:literal),+) => {
1009 paste::paste! {
1010 usart_static_clock!(
1011 $([<USART $X>]),+
1012 );
1013 }
1014 };
1015}
1016
1017macro_rules! usart_var_clock {
1020 ($($USARTX:ident, $usartXsw:ident),+) => {
1021 $(
1022 impl Instance for $USARTX {
1023 fn clock(clocks: &Clocks) -> Hertz {
1024 match unsafe {(*RCC::ptr()).cfgr3.read().$usartXsw().variant()} {
1026 USART1SW_A::Pclk => <$USARTX as rcc::BusClock>::clock(clocks),
1027 USART1SW_A::Hsi => crate::rcc::HSI,
1028 USART1SW_A::Sysclk => clocks.sysclk(),
1029 USART1SW_A::Lse => crate::rcc::LSE,
1030 }
1031 }
1032 }
1033 )+
1034 };
1035 ($($X:literal),+) => {
1036 paste::paste! {
1037 usart_var_clock!(
1038 $([<USART $X>], [<usart $X sw>]),+
1039 );
1040 }
1041 };
1042}
1043
1044cfg_if::cfg_if! {
1045 if #[cfg(any(
1046 feature = "stm32f301x6",
1047 feature = "stm32f301x8",
1048 feature = "stm32f318x8",
1049 feature = "stm32f302x6",
1050 feature = "stm32f302x8",
1051 feature = "stm32f303x6",
1052 feature = "stm32f303x8",
1053 feature = "stm32f328x8",
1054 feature = "stm32f334x4",
1055 feature = "stm32f334x6",
1056 feature = "stm32f334x8",
1057 ))] {
1058 usart_var_clock!(1);
1061 usart_static_clock!(2, 3);
1064 } else {
1065 usart_var_clock!(1, 2, 3);
1066 }
1067}
1068
1069#[cfg(not(feature = "svd-f373"))]
1070usart!([
1071 (1, Interrupt::USART1_EXTI25),
1072 (2, Interrupt::USART2_EXTI26),
1073 (3, Interrupt::USART3_EXTI28)
1074]);
1075#[cfg(feature = "svd-f373")]
1076usart!([
1077 (1, Interrupt::USART1),
1078 (2, Interrupt::USART2),
1079 (3, Interrupt::USART3)
1080]);
1081
1082cfg_if::cfg_if! {
1083 if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e"))] {
1085
1086 macro_rules! uart {
1087 ([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
1088 paste::paste! {
1089 usart!(
1090 $(
1091 [<UART $X>]: ($INTERRUPT),
1092 )+
1093 );
1094 }
1095 };
1096 }
1097
1098 macro_rules! uart_var_clock {
1099 ($($X:literal),+) => {
1100 paste::paste! {
1101 usart_var_clock!(
1102 $([<UART $X>], [<uart $X sw>]),+
1103 );
1104 }
1105 };
1106 }
1107
1108 uart_var_clock!(4, 5);
1109 uart!([(4, Interrupt::UART4_EXTI34), (5, Interrupt::UART5_EXTI35)]);
1110
1111 impl Dma for UART4 {}
1112
1113 impl ReceiverTimeoutExt for UART4 {}
1114 impl ReceiverTimeoutExt for UART5 {}
1115 }
1116}