1use core::fmt;
6use core::marker::PhantomData;
7use core::ops::DerefMut;
8use core::ptr;
9use core::sync::atomic::{self, Ordering};
10use embedded_dma::StaticWriteBuffer;
11use stable_deref_trait::StableDeref;
12
13use crate::hal::serial::{self, Write};
14
15use crate::dma::{
16 dma1, CircBuffer, DMAFrame, FrameReader, FrameSender, Receive, RxDma, TransferPayload,
17 Transmit, TxDma,
18};
19use crate::dmamux::{DmaInput, DmaMux};
20use crate::gpio::{self, Alternate, OpenDrain, PushPull};
21use crate::pac;
22use crate::rcc::{Clocks, Enable, RccBus, Reset};
23use crate::time::{Bps, U32Ext};
24
25#[cfg(any(
26 feature = "stm32l475",
31 feature = "stm32l476",
32 feature = "stm32l485",
33 feature = "stm32l486",
34 feature = "stm32l496",
35 feature = "stm32l4a6",
36 feature = "stm32l4r9",
43 feature = "stm32l4s9",
44))]
45use crate::dma::dma2;
46
47pub enum Event {
49 Rxne,
51 Txe,
53 Idle,
55 CharacterMatch,
57 ReceiverTimeout,
59}
60
61#[non_exhaustive]
63#[derive(Debug)]
64pub enum Error {
65 Framing,
67 Noise,
69 Overrun,
71 Parity,
73}
74
75pub enum Parity {
77 ParityNone,
79 ParityEven,
81 ParityOdd,
83}
84
85pub enum StopBits {
87 STOP1,
89 STOP0P5,
91 STOP2,
93 STOP1P5,
95}
96
97pub enum Oversampling {
99 Over8,
101 Over16,
103}
104
105pub struct Config {
107 baudrate: Bps,
108 parity: Parity,
109 stopbits: StopBits,
110 oversampling: Oversampling,
111 character_match: Option<u8>,
112 receiver_timeout: Option<u32>,
113 disable_overrun: bool,
114 onebit_sampling: bool,
115}
116
117impl Config {
118 pub fn baudrate(mut self, baudrate: Bps) -> Self {
120 self.baudrate = baudrate;
121 self
122 }
123
124 pub fn parity_none(mut self) -> Self {
126 self.parity = Parity::ParityNone;
127 self
128 }
129
130 pub fn parity_even(mut self) -> Self {
132 self.parity = Parity::ParityEven;
133 self
134 }
135
136 pub fn parity_odd(mut self) -> Self {
138 self.parity = Parity::ParityOdd;
139 self
140 }
141
142 pub fn stopbits(mut self, stopbits: StopBits) -> Self {
144 self.stopbits = stopbits;
145 self
146 }
147
148 pub fn oversampling(mut self, oversampling: Oversampling) -> Self {
150 self.oversampling = oversampling;
151 self
152 }
153
154 pub fn character_match(mut self, character_match: u8) -> Self {
156 self.character_match = Some(character_match);
157 self
158 }
159
160 pub fn receiver_timeout(mut self, receiver_timeout: u32) -> Self {
164 assert!(receiver_timeout < 1 << 24);
165 self.receiver_timeout = Some(receiver_timeout);
166 self
167 }
168
169 pub fn with_overrun_disabled(mut self) -> Self {
171 self.disable_overrun = true;
172 self
173 }
174
175 pub fn with_onebit_sampling(mut self) -> Self {
177 self.onebit_sampling = true;
178 self
179 }
180}
181
182impl Default for Config {
183 fn default() -> Config {
184 let baudrate = 115_200_u32.bps();
185 Config {
186 baudrate,
187 parity: Parity::ParityNone,
188 stopbits: StopBits::STOP1,
189 oversampling: Oversampling::Over16,
190 character_match: None,
191 receiver_timeout: None,
192 disable_overrun: false,
193 onebit_sampling: false,
194 }
195 }
196}
197
198impl From<Bps> for Config {
199 fn from(baudrate: Bps) -> Config {
200 Config {
201 baudrate,
202 ..Default::default()
203 }
204 }
205}
206
207pub struct Serial<USART, PINS> {
209 usart: USART,
210 pins: PINS,
211}
212
213pub struct Rx<USART> {
215 _usart: PhantomData<USART>,
216}
217
218pub struct Tx<USART> {
220 _usart: PhantomData<USART>,
221}
222
223macro_rules! hal {
224 ($(
225 $(#[$meta:meta])*
226 $USARTX:ident: (
227 $usartX:ident,
228 $pclkX:ident,
229 tx: ($txdma:ident, $dmatxch:path, $dmatxsel:path),
230 rx: ($rxdma:ident, $dmarxch:path, $dmarxsel:path)
231 ),
232 )+) => {
233 $(
234 impl<PINS> Serial<pac::$USARTX, PINS> {
235 pub fn $usartX(
251 usart: pac::$USARTX,
252 pins: PINS,
253 config: impl Into<Config>,
254 clocks: Clocks,
255 apb: &mut <pac::$USARTX as RccBus>::Bus,
256 ) -> Self
257 where
258 PINS: Pins<pac::$USARTX>,
259 {
260 let config = config.into();
261
262 <pac::$USARTX>::enable(apb);
264 <pac::$USARTX>::reset(apb);
265
266 usart.cr1.reset();
268 usart.cr2.reset();
269 usart.cr3.reset();
270
271 match config.oversampling {
273 Oversampling::Over8 => {
274 let uartdiv = 2 * clocks.$pclkX().raw() / config.baudrate.0;
275 assert!(uartdiv >= 16, "impossible baud rate");
276
277 let lower = (uartdiv & 0xf) >> 1;
278 let brr = (uartdiv & !0xf) | lower;
279
280 usart.cr1.modify(|_, w| w.over8().set_bit());
281 usart.brr.write(|w| unsafe { w.bits(brr) });
282 }
283 Oversampling::Over16 => {
284 let brr = clocks.$pclkX().raw() / config.baudrate.0;
285 assert!(brr >= 16, "impossible baud rate");
286
287 usart.brr.write(|w| unsafe { w.bits(brr) });
288 }
289 }
290
291 if let Some(val) = config.receiver_timeout {
292 usart.rtor.modify(|_, w| w.rto().bits(val));
293 }
294
295 usart.cr3.modify(|_, w| w.dmat().set_bit().dmar().set_bit());
297
298 if PINS::FLOWCTL {
300 usart.cr3.modify(|_, w| w.rtse().set_bit().ctse().set_bit());
301 } else if PINS::DEM {
302 usart.cr3.modify(|_, w| w.dem().set_bit());
303
304 usart.cr1.modify(|_, w| w.deat().bits(0b1111).dedt().bits(0b1111));
306 } else {
307 usart.cr3.modify(|_, w| w.rtse().clear_bit().ctse().clear_bit());
308 }
309
310 usart.cr3.modify(|_, w| {
312 if config.onebit_sampling {
313 w.onebit().set_bit();
314 }
315
316 if config.disable_overrun {
317 w.ovrdis().set_bit();
318 }
319
320 if PINS::HALF_DUPLEX {
322 w.hdsel().set_bit();
323 }
324
325 w
326 });
327
328 let (word_length, parity_control_enable, parity) = match config.parity {
334 Parity::ParityNone => (false, false, false),
335 Parity::ParityEven => (true, true, false),
336 Parity::ParityOdd => (true, true, true),
337 };
338 usart.cr1.modify(|_r, w| {
339 w
340 .m0().bit(word_length)
341 .ps().bit(parity)
342 .pce().bit(parity_control_enable)
343 });
344
345 let stop_bits = match config.stopbits {
347 StopBits::STOP1 => 0b00,
348 StopBits::STOP0P5 => 0b01,
349 StopBits::STOP2 => 0b10,
350 StopBits::STOP1P5 => 0b11,
351 };
352 usart.cr2.modify(|_r, w| {
353 w.stop().bits(stop_bits);
354
355 if let Some(c) = config.character_match {
357 w.add().bits(c);
358 }
359
360 if config.receiver_timeout.is_some() {
361 w.rtoen().set_bit();
362 }
363
364 w
365 });
366
367
368 usart
372 .cr1
373 .modify(|_, w| w.ue().set_bit().re().set_bit().te().set_bit());
374
375 Serial { usart, pins }
376 }
377
378 pub fn listen(&mut self, event: Event) {
380 match event {
381 Event::Rxne => {
382 self.usart.cr1.modify(|_, w| w.rxneie().set_bit())
383 },
384 Event::Txe => {
385 self.usart.cr1.modify(|_, w| w.txeie().set_bit())
386 },
387 Event::Idle => {
388 self.usart.cr1.modify(|_, w| w.idleie().set_bit())
389 },
390 Event::CharacterMatch => {
391 self.usart.cr1.modify(|_, w| w.cmie().set_bit())
392 },
393 Event::ReceiverTimeout => {
394 self.usart.cr1.modify(|_, w| w.rtoie().set_bit())
395 },
396 }
397 }
398
399 pub fn check_for_error() -> Result<(), Error> {
403 let mut rx: Rx<pac::$USARTX> = Rx {
404 _usart: PhantomData,
405 };
406 rx.check_for_error()
407 }
408
409 pub fn unlisten(&mut self, event: Event) {
411 match event {
412 Event::Rxne => {
413 self.usart.cr1.modify(|_, w| w.rxneie().clear_bit())
414 },
415 Event::Txe => {
416 self.usart.cr1.modify(|_, w| w.txeie().clear_bit())
417 },
418 Event::Idle => {
419 self.usart.cr1.modify(|_, w| w.idleie().clear_bit())
420 },
421 Event::CharacterMatch => {
422 self.usart.cr1.modify(|_, w| w.cmie().clear_bit())
423 },
424 Event::ReceiverTimeout => {
425 self.usart.cr1.modify(|_, w| w.rtoie().clear_bit())
426 },
427 }
428 }
429
430 pub fn split(self) -> (Tx<pac::$USARTX>, Rx<pac::$USARTX>) {
432 (
433 Tx {
434 _usart: PhantomData,
435 },
436 Rx {
437 _usart: PhantomData,
438 },
439 )
440 }
441
442 pub fn release(self) -> (pac::$USARTX, PINS) {
444 (self.usart, self.pins)
445 }
446 }
447
448 impl<PINS> serial::Read<u8> for Serial<pac::$USARTX, PINS> {
449 type Error = Error;
450
451 fn read(&mut self) -> nb::Result<u8, Error> {
452 let mut rx: Rx<pac::$USARTX> = Rx {
453 _usart: PhantomData,
454 };
455 rx.read()
456 }
457 }
458
459 impl serial::Read<u8> for Rx<pac::$USARTX> {
460 type Error = Error;
461
462 fn read(&mut self) -> nb::Result<u8, Error> {
463 self.check_for_error()?;
464
465 let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
467
468 if isr.rxne().bit_is_set() {
469 return Ok(unsafe {
471 ptr::read_volatile(&(*pac::$USARTX::ptr()).rdr as *const _ as *const _)
472 });
473 }
474
475 Err(nb::Error::WouldBlock)
476 }
477 }
478
479 impl<PINS> serial::Write<u8> for Serial<pac::$USARTX, PINS> {
480 type Error = Error;
481
482 fn flush(&mut self) -> nb::Result<(), Error> {
483 let mut tx: Tx<pac::$USARTX> = Tx {
484 _usart: PhantomData,
485 };
486 tx.flush()
487 }
488
489 fn write(&mut self, byte: u8) -> nb::Result<(), Error> {
490 let mut tx: Tx<pac::$USARTX> = Tx {
491 _usart: PhantomData,
492 };
493 tx.write(byte)
494 }
495 }
496
497 impl serial::Write<u8> for Tx<pac::$USARTX> {
498 type Error = Error;
503
504 fn flush(&mut self) -> nb::Result<(), Error> {
505 let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
507
508 if isr.tc().bit_is_set() {
509 Ok(())
510 } else {
511 Err(nb::Error::WouldBlock)
512 }
513 }
514
515 fn write(&mut self, byte: u8) -> nb::Result<(), Error> {
516 let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
518
519 if isr.txe().bit_is_set() {
520 unsafe {
523 ptr::write_volatile(&(*pac::$USARTX::ptr()).tdr as *const _ as *mut _, byte)
524 }
525 Ok(())
526 } else {
527 Err(nb::Error::WouldBlock)
528 }
529 }
530 }
531
532 impl embedded_hal::blocking::serial::write::Default<u8>
533 for Tx<pac::$USARTX> {}
534
535 pub type $rxdma = RxDma<Rx<pac::$USARTX>, $dmarxch>;
536 pub type $txdma = TxDma<Tx<pac::$USARTX>, $dmatxch>;
537
538 impl Receive for $rxdma {
539 type RxChannel = $dmarxch;
540 type TransmittedWord = u8;
541 }
542
543 impl Transmit for $txdma {
544 type TxChannel = $dmatxch;
545 type ReceivedWord = u8;
546 }
547
548 impl TransferPayload for $rxdma {
549 fn start(&mut self) {
550 self.channel.start();
551 }
552 fn stop(&mut self) {
553 self.channel.stop();
554 }
555 }
556
557 impl TransferPayload for $txdma {
558 fn start(&mut self) {
559 self.channel.start();
560 }
561 fn stop(&mut self) {
562 self.channel.stop();
563 }
564 }
565
566 impl Rx<pac::$USARTX> {
567 pub fn with_dma(self, channel: $dmarxch) -> $rxdma {
568 RxDma {
569 payload: self,
570 channel,
571 }
572 }
573
574 pub fn check_for_error(&mut self) -> Result<(), Error> {
582 let isr = unsafe { (*pac::$USARTX::ptr()).isr.read() };
584 let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
585
586 if isr.pe().bit_is_set() {
587 icr.write(|w| w.pecf().clear());
588 return Err(Error::Parity);
589 }
590 if isr.fe().bit_is_set() {
591 icr.write(|w| w.fecf().clear());
592 return Err(Error::Framing);
593 }
594 if isr.nf().bit_is_set() {
595 icr.write(|w| w.ncf().clear());
596 return Err(Error::Noise);
597 }
598 if isr.ore().bit_is_set() {
599 icr.write(|w| w.orecf().clear());
600 return Err(Error::Overrun);
601 }
602
603 Ok(())
604 }
605
606 pub fn is_idle(&mut self, clear: bool) -> bool {
609 let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
610 let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
611
612 if isr.idle().bit_is_set() {
613 if clear {
614 icr.write(|w| w.idlecf().set_bit() );
615 }
616 true
617 } else {
618 false
619 }
620 }
621
622
623 pub fn is_receiver_timeout(&mut self, clear: bool) -> bool {
626 let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
627 let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
628
629 if isr.rtof().bit_is_set() {
630 if clear {
631 icr.write(|w| w.rtocf().set_bit() );
632 }
633 true
634 } else {
635 false
636 }
637 }
638
639 pub fn check_character_match(&mut self, clear: bool) -> bool {
642 let isr = unsafe { &(*pac::$USARTX::ptr()).isr.read() };
643 let icr = unsafe { &(*pac::$USARTX::ptr()).icr };
644
645 if isr.cmf().bit_is_set() {
646 if clear {
647 icr.write(|w| w.cmcf().set_bit() );
648 }
649 true
650 } else {
651 false
652 }
653 }
654 }
655
656 impl crate::dma::CharacterMatch for Rx<pac::$USARTX> {
657 fn check_character_match(&mut self, clear: bool) -> bool {
660 self.check_character_match(clear)
661 }
662 }
663
664 impl crate::dma::ReceiverTimeout for Rx<pac::$USARTX> {
665 fn check_receiver_timeout(&mut self, clear: bool) -> bool {
666 self.is_receiver_timeout(clear)
667 }
668 }
669
670 impl crate::dma::OperationError<(), Error> for Rx<pac::$USARTX>{
671 fn check_operation_error(&mut self) -> Result<(), Error> {
672 self.check_for_error()
673 }
674 }
675
676 impl Tx<pac::$USARTX> {
677 pub fn with_dma(self, channel: $dmatxch) -> $txdma {
678 TxDma {
679 payload: self,
680 channel,
681 }
682 }
683 }
684
685 impl $rxdma {
686 pub fn split(mut self) -> (Rx<pac::$USARTX>, $dmarxch) {
687 self.stop();
688 let RxDma {payload, channel} = self;
689 (
690 payload,
691 channel
692 )
693 }
694 }
695
696 impl $txdma {
697 pub fn split(mut self) -> (Tx<pac::$USARTX>, $dmatxch) {
698 self.stop();
699 let TxDma {payload, channel} = self;
700 (
701 payload,
702 channel,
703 )
704 }
705 }
706
707 impl<B> crate::dma::CircReadDma<B, u8> for $rxdma
708 where
709 &'static mut B: StaticWriteBuffer<Word = u8>,
710 B: 'static,
711 Self: core::marker::Sized,
712 {
713 fn circ_read(mut self, mut buffer: &'static mut B,
714 ) -> CircBuffer<B, Self>
715 {
716 let (ptr, len) = unsafe { buffer.static_write_buffer() };
717 self.channel.set_peripheral_address(
718 unsafe { &(*pac::$USARTX::ptr()).rdr as *const _ as u32 },
719 false,
720 );
721 self.channel.set_memory_address(ptr as u32, true);
722 self.channel.set_transfer_length(len as u16);
723
724 self.channel.set_request_line($dmarxsel).unwrap();
726
727 self.channel.ccr().modify(|_, w| {
728 w
729 .mem2mem()
731 .clear_bit()
732 .pl()
734 .medium()
735 .msize()
737 .bits8()
738 .psize()
740 .bits8()
741 .circ()
743 .set_bit()
744 .dir()
746 .clear_bit()
747 });
748
749 atomic::compiler_fence(Ordering::Release);
752
753 self.start();
754
755 CircBuffer::new(buffer, self)
756 }
757 }
758
759 impl $rxdma {
760 pub fn frame_reader<BUFFER, const N: usize>(
763 mut self,
764 buffer: BUFFER,
765 ) -> FrameReader<BUFFER, Self, N>
766 where
767 BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
768 {
769 let usart = unsafe{ &(*pac::$USARTX::ptr()) };
770
771 let buf = &*buffer;
773 self.channel.set_peripheral_address(&usart.rdr as *const _ as u32, false);
774 self.channel.set_memory_address(unsafe { buf.buffer_address_for_dma() } as u32, true);
775 self.channel.set_transfer_length(buf.max_len() as u16);
776
777 self.channel.set_request_line($dmarxsel).unwrap();
779
780 self.channel.ccr().modify(|_, w| {
781 w
782 .mem2mem()
784 .clear_bit()
785 .pl()
787 .medium()
788 .msize()
790 .bits8()
791 .psize()
793 .bits8()
794 .dir()
796 .clear_bit()
797 });
798
799 atomic::compiler_fence(Ordering::Release);
802
803 self.channel.start();
804
805 FrameReader::new(buffer, self, usart.cr2.read().add().bits())
806 }
807 }
808
809 impl $txdma {
810 pub fn frame_sender<BUFFER, const N: usize>(
812 mut self,
813 ) -> FrameSender<BUFFER, Self, N>
814 where
815 BUFFER: Sized + StableDeref<Target = DMAFrame<N>> + DerefMut + 'static,
816 {
817 let usart = unsafe{ &(*pac::$USARTX::ptr()) };
818
819 self.channel.set_peripheral_address(&usart.tdr as *const _ as u32, false);
821
822 self.channel.set_request_line($dmatxsel).unwrap();
824
825 self.channel.ccr().modify(|_, w| unsafe {
826 w.mem2mem()
827 .clear_bit()
828 .pl()
830 .bits(0b01)
831 .msize()
833 .bits(0b00)
834 .psize()
836 .bits(0b00)
837 .dir()
839 .set_bit()
840 });
841
842 FrameSender::new(self)
843 }
844 }
845 )+
846 }
847}
848
849hal! {
850 USART1: (usart1, pclk2, tx: (TxDma1, dma1::C4, DmaInput::Usart1Tx), rx: (RxDma1, dma1::C5, DmaInput::Usart1Rx)),
851 USART2: (usart2, pclk1, tx: (TxDma2, dma1::C7, DmaInput::Usart2Tx), rx: (RxDma2, dma1::C6, DmaInput::Usart2Rx)),
852}
853
854#[cfg(not(any(feature = "stm32l432", feature = "stm32l442")))]
855hal! {
856 USART3: (usart3, pclk1, tx: (TxDma3, dma1::C2, DmaInput::Usart3Tx), rx: (RxDma3, dma1::C3, DmaInput::Usart3Rx)),
857}
858
859#[cfg(any(
860 feature = "stm32l475",
865 feature = "stm32l476",
866 feature = "stm32l485",
867 feature = "stm32l486",
868 feature = "stm32l496",
869 feature = "stm32l4a6",
870 feature = "stm32l4r9",
877 feature = "stm32l4s9",
878))]
879hal! {
880 UART4: (uart4, pclk1, tx: (TxDma4, dma2::C3, DmaInput::Uart4Tx), rx: (RxDma4, dma2::C5, DmaInput::Uart4Rx)),
881}
882
883#[cfg(any(
884 feature = "stm32l475",
886 feature = "stm32l476",
887 feature = "stm32l485",
888 feature = "stm32l486",
889 feature = "stm32l496",
890 feature = "stm32l4a6",
891 feature = "stm32l4r9",
898 feature = "stm32l4s9",
899))]
900hal! {
901 UART5: (uart5, pclk1, tx: (TxDma5, dma2::C1, DmaInput::Uart5Tx), rx: (RxDma5, dma2::C2, DmaInput::Uart5Rx)),
902}
903
904impl<USART, PINS> fmt::Write for Serial<USART, PINS>
905where
906 Serial<USART, PINS>: crate::hal::serial::Write<u8>,
907{
908 fn write_str(&mut self, s: &str) -> fmt::Result {
909 let _ = s
910 .as_bytes()
911 .iter()
912 .map(|c| nb::block!(self.write(*c)))
913 .last();
914 Ok(())
915 }
916}
917
918impl<USART> fmt::Write for Tx<USART>
919where
920 Tx<USART>: crate::hal::serial::Write<u8>,
921{
922 fn write_str(&mut self, s: &str) -> fmt::Result {
923 let _ = s
924 .as_bytes()
925 .iter()
926 .map(|c| nb::block!(self.write(*c)))
927 .last();
928 Ok(())
929 }
930}
931
932pub trait TxPin<Instance>: private::SealedTx {}
934
935pub trait TxHalfDuplexPin<Instance>: private::SealedTxHalfDuplex {}
937
938pub trait RxPin<Instance>: private::SealedRx {}
940
941pub trait RtsDePin<Instance>: private::SealedRtsDe {}
943
944pub trait CtsPin<Instance>: private::SealedCts {}
946
947macro_rules! impl_pin_traits {
948 (
949 $(
950 $instance:ident: {
951 $(
952 $af:literal: {
953 TX: $($tx:ident),*;
954 RX: $($rx:ident),*;
955 RTS_DE: $($rts_de:ident),*;
956 CTS: $($cts:ident),*;
957 }
958 )*
959 }
960 )*
961 ) => {
962 $(
963 $(
964 $(
965 impl private::SealedTx for
966 gpio::$tx<Alternate<PushPull, $af>> {}
967 impl TxPin<pac::$instance> for
968 gpio::$tx<Alternate<PushPull, $af>> {}
969 )*
970
971 $(
972 impl private::SealedTxHalfDuplex for
973 gpio::$tx<Alternate<OpenDrain, $af>> {}
974 impl TxHalfDuplexPin<pac::$instance> for
975 gpio::$tx<Alternate<OpenDrain, $af>> {}
976 )*
977
978 $(
979 impl private::SealedRx for
980 gpio::$rx<Alternate<PushPull, $af>> {}
981 impl RxPin<pac::$instance> for
982 gpio::$rx<Alternate<PushPull, $af>> {}
983 )*
984
985 $(
986 impl private::SealedRtsDe for
987 gpio::$rts_de<Alternate<PushPull, $af>> {}
988 impl RtsDePin<pac::$instance> for
989 gpio::$rts_de<Alternate<PushPull, $af>> {}
990 )*
991
992 $(
993 impl private::SealedCts for
994 gpio::$cts<Alternate<PushPull, $af>> {}
995 impl CtsPin<pac::$instance> for
996 gpio::$cts<Alternate<PushPull, $af>> {}
997 )*
998 )*
999 )*
1000 };
1001}
1002
1003impl_pin_traits! {
1004 USART1: {
1005 7: {
1006 TX: PA9, PB6;
1007 RX: PA10, PB7;
1008 RTS_DE: PA12, PB3;
1009 CTS: PA11, PB4;
1010 }
1011 }
1012 USART2: {
1013 7: {
1014 TX: PA2, PD5;
1015 RX: PA3, PD6;
1016 RTS_DE: PA1, PD4;
1017 CTS: PA0, PD3;
1018 }
1019 3: {
1020 TX: ;
1021 RX: PA15;
1022 RTS_DE: ;
1023 CTS: ;
1024 }
1025 }
1026 USART3: {
1027 7: {
1028 TX: PB10, PC4, PC10, PD8;
1029 RX: PB11, PC5, PC11, PD9;
1030 RTS_DE: PB1, PB14, PD2, PD12;
1031 CTS: PA6, PB13, PD11;
1032 }
1033 }
1034}
1035
1036#[cfg(any(
1037 feature = "stm32l475",
1042 feature = "stm32l476",
1043 feature = "stm32l485",
1044 feature = "stm32l486",
1045 feature = "stm32l496",
1046 feature = "stm32l4a6",
1047 feature = "stm32l4r9",
1054 feature = "stm32l4s9",
1055))]
1056impl_pin_traits! {
1057 UART4: {
1058 8: {
1059 TX: PA0, PC10;
1060 RX: PA1, PC11;
1061 RTS_DE: PA15;
1062 CTS: PB7;
1063 }
1064 }
1065}
1066
1067#[cfg(any(
1068 feature = "stm32l475",
1070 feature = "stm32l476",
1071 feature = "stm32l485",
1072 feature = "stm32l486",
1073 feature = "stm32l496",
1074 feature = "stm32l4a6",
1075 feature = "stm32l4r9",
1082 feature = "stm32l4s9",
1083))]
1084impl_pin_traits! {
1085 UART5: {
1086 8: {
1087 TX: PC12;
1088 RX: PD2;
1089 RTS_DE: PB4;
1090 CTS: PB5;
1091 }
1092 }
1093}
1094
1095pub trait Pins<USART> {
1097 const FLOWCTL: bool;
1098 const DEM: bool;
1099 const HALF_DUPLEX: bool;
1100}
1101
1102impl<Instance, Tx, Rx> Pins<Instance> for (Tx, Rx)
1104where
1105 Tx: TxPin<Instance>,
1106 Rx: RxPin<Instance>,
1107{
1108 const FLOWCTL: bool = false;
1109 const DEM: bool = false;
1110 const HALF_DUPLEX: bool = false;
1111}
1112
1113impl<Instance, Tx> Pins<Instance> for (Tx,)
1115where
1116 Tx: TxHalfDuplexPin<Instance>,
1117{
1118 const FLOWCTL: bool = false;
1119 const DEM: bool = false;
1120 const HALF_DUPLEX: bool = true;
1121}
1122
1123impl<Instance, Tx, Rx, Rts, Cts> Pins<Instance> for (Tx, Rx, Rts, Cts)
1125where
1126 Tx: TxPin<Instance>,
1127 Rx: RxPin<Instance>,
1128 Rts: RtsDePin<Instance>,
1129 Cts: CtsPin<Instance>,
1130{
1131 const FLOWCTL: bool = true;
1132 const DEM: bool = false;
1133 const HALF_DUPLEX: bool = false;
1134}
1135
1136impl<Instance, Tx, Rx, De> Pins<Instance> for (Tx, Rx, De)
1138where
1139 Tx: TxPin<Instance>,
1140 Rx: RxPin<Instance>,
1141 De: RtsDePin<Instance>,
1142{
1143 const FLOWCTL: bool = false;
1144 const DEM: bool = true;
1145 const HALF_DUPLEX: bool = false;
1146}
1147
1148mod private {
1150 pub trait SealedTx {}
1151 pub trait SealedTxHalfDuplex {}
1152 pub trait SealedRx {}
1153 pub trait SealedRtsDe {}
1154 pub trait SealedCts {}
1155}