stm32g0xx_hal/serial/
usart.rs

1use core::fmt;
2use core::marker::PhantomData;
3
4use crate::dma;
5use crate::dmamux::DmaMuxIndex;
6use crate::gpio::{AltFunction, *};
7use crate::prelude::*;
8use crate::rcc::*;
9use crate::serial::config::*;
10use crate::stm32::*;
11
12use cortex_m::interrupt;
13use nb::block;
14
15/// Serial error
16#[derive(Debug)]
17pub enum Error {
18    /// Framing error
19    Framing,
20    /// Noise error
21    Noise,
22    /// RX buffer overrun
23    Overrun,
24    /// Parity check error
25    Parity,
26}
27
28/// Interrupt event
29pub enum Event {
30    /// TXFIFO reaches the threshold
31    TXFT = 1 << 27,
32    /// This bit is set by hardware when the threshold programmed in RXFTCFG in USART_CR3 register is reached.
33    RXFT = 1 << 26,
34
35    /// RXFIFO full
36    RXFF = 1 << 24,
37    /// TXFIFO empty
38    TXFE = 1 << 23,
39
40    /// Active when a communication is ongoing on the RX line
41    BUSY = 1 << 16,
42
43    /// Receiver timeout.This bit is set by hardware when the timeout value,
44    /// programmed in the RTOR register has lapsed, without any communication.
45    RTOF = 1 << 11,
46    /// Transmit data register empty. New data can be sent
47    Txe = 1 << 7,
48
49    /// Transmission Complete. The last data written in the USART_TDR has been transmitted out of the shift register.
50    TC = 1 << 6,
51    /// New data has been received
52    Rxne = 1 << 5,
53    /// Idle line state detected
54    Idle = 1 << 4,
55
56    /// Overrun error
57    ORE = 1 << 3,
58
59    /// Noise detection flag
60    NE = 1 << 2,
61
62    /// Framing error
63    FE = 1 << 1,
64
65    /// Parity error
66    PE = 1 << 0,
67}
68
69impl Event {
70    fn val(self) -> u32 {
71        self as u32
72    }
73}
74
75/// Serial receiver
76pub struct Rx<USART, Config> {
77    _usart: PhantomData<USART>,
78    _config: PhantomData<Config>,
79}
80
81/// Serial transmitter
82pub struct Tx<USART, Config> {
83    _usart: PhantomData<USART>,
84    _config: PhantomData<Config>,
85}
86
87/// Serial abstraction
88pub struct Serial<USART, Config> {
89    tx: Tx<USART, Config>,
90    rx: Rx<USART, Config>,
91    usart: USART,
92    _config: PhantomData<Config>,
93}
94
95// Serial TX pin
96pub trait TxPin<USART> {
97    fn setup(&self);
98    fn release(self) -> Self;
99}
100
101// Serial RX pin
102pub trait RxPin<USART> {
103    fn setup(&self);
104    fn release(self) -> Self;
105}
106
107pub struct NoTx;
108
109impl<USART> TxPin<USART> for NoTx {
110    fn setup(&self) {}
111
112    fn release(self) -> Self {
113        self
114    }
115}
116pub struct NoRx;
117
118impl<USART> RxPin<USART> for NoRx {
119    fn setup(&self) {}
120
121    fn release(self) -> Self {
122        self
123    }
124}
125
126// Driver enable pin
127pub trait DriverEnablePin<USART> {
128    fn setup(&self);
129    fn release(self) -> Self;
130}
131
132// Serial pins
133pub trait Pins<USART> {
134    const DRIVER_ENABLE: bool;
135
136    fn setup(&self);
137    fn release(self) -> Self;
138}
139
140// Duplex mode
141impl<USART, TX, RX> Pins<USART> for (TX, RX)
142where
143    TX: TxPin<USART>,
144    RX: RxPin<USART>,
145{
146    const DRIVER_ENABLE: bool = false;
147
148    fn setup(&self) {
149        self.0.setup();
150        self.1.setup();
151    }
152
153    fn release(self) -> Self {
154        (self.0.release(), self.1.release())
155    }
156}
157
158// Duplex mode with driver enabled
159impl<USART, TX, RX, DE> Pins<USART> for (TX, RX, DE)
160where
161    TX: TxPin<USART>,
162    RX: RxPin<USART>,
163    DE: DriverEnablePin<USART>,
164{
165    const DRIVER_ENABLE: bool = true;
166
167    fn setup(&self) {
168        self.0.setup();
169        self.1.setup();
170        self.2.setup();
171    }
172
173    fn release(self) -> Self {
174        (self.0.release(), self.1.release(), self.2.release())
175    }
176}
177
178pub trait SerialExt<USART, Config> {
179    fn usart<PINS: Pins<USART>>(
180        self,
181        pins: PINS,
182        config: Config,
183        rcc: &mut Rcc,
184    ) -> Result<Serial<USART, Config>, InvalidConfig>;
185}
186
187impl<USART, Config> fmt::Write for Serial<USART, Config>
188where
189    Serial<USART, Config>: hal::serial::Write<u8>,
190{
191    fn write_str(&mut self, s: &str) -> fmt::Result {
192        let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
193        Ok(())
194    }
195}
196
197impl<USART, Config> fmt::Write for Tx<USART, Config>
198where
199    Tx<USART, Config>: hal::serial::Write<u8>,
200{
201    fn write_str(&mut self, s: &str) -> fmt::Result {
202        let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
203        Ok(())
204    }
205}
206
207macro_rules! uart_shared {
208    ($USARTX:ident, $dmamux_rx:ident, $dmamux_tx:ident,
209        tx: [ $(($PTX:ident, $TAF:expr),)+ ],
210        rx: [ $(($PRX:ident, $RAF:expr),)+ ],
211        de: [ $(($PDE:ident, $DAF:expr),)+ ]) => {
212
213        $(
214            impl<MODE> TxPin<$USARTX> for $PTX<MODE> {
215                fn setup(&self) {
216                    self.set_alt_mode($TAF)
217                }
218
219                fn release(self) -> Self {
220                    self
221                }
222            }
223        )+
224
225        $(
226            impl<MODE> RxPin<$USARTX> for $PRX<MODE> {
227                fn setup(&self) {
228                    self.set_alt_mode($RAF)
229                }
230
231                fn release(self) -> Self {
232                    self
233                }
234            }
235        )+
236
237        $(
238            impl<MODE> DriverEnablePin<$USARTX> for $PDE<MODE> {
239                fn setup(&self) {
240                    self.set_alt_mode($DAF)
241                }
242
243                fn release(self) -> Self {
244                    self
245                }
246            }
247        )+
248
249        impl<Config> Rx<$USARTX, Config> {
250            /// Listen for a data interrupt event
251            pub fn listen(&mut self) {
252                let usart = unsafe { &(*$USARTX::ptr()) };
253                usart.cr1.modify(|_, w| w.rxneie().set_bit());
254            }
255
256            /// Stop listening for a data interrupt event
257            pub fn unlisten(&mut self) {
258                let usart = unsafe { &(*$USARTX::ptr()) };
259                usart.cr1.modify(|_, w| w.rxneie().clear_bit());
260            }
261
262            /// Return true if the rx register is not empty (and can be read)
263            pub fn is_rxne(&self) -> bool {
264                let usart = unsafe { &(*$USARTX::ptr()) };
265                usart.isr.read().rxne().bit_is_set()
266            }
267
268            /// Listen for an idle interrupt event
269            pub fn listen_idle(&mut self) {
270                let usart = unsafe { &(*$USARTX::ptr()) };
271                usart.cr1.modify(|_, w| w.idleie().set_bit());
272            }
273
274            /// Stop listening for an idle interrupt event
275            pub fn unlisten_idle(&mut self) {
276                let usart = unsafe { &(*$USARTX::ptr()) };
277                usart.cr1.modify(|_, w| w.idleie().clear_bit());
278            }
279
280            /// Return true if the idle event occured
281            pub fn is_idle(&self) -> bool {
282                let usart = unsafe { &(*$USARTX::ptr()) };
283                usart.isr.read().idle().bit_is_set()
284            }
285
286            /// Clear the idle event flag
287            pub fn clear_idle(&mut self) {
288                let usart = unsafe { &(*$USARTX::ptr()) };
289                usart.icr.write(|w| w.idlecf().set_bit());
290            }
291        }
292
293        impl<Config> hal::serial::Read<u8> for Rx<$USARTX, Config> {
294            type Error = Error;
295
296            fn read(&mut self) -> nb::Result<u8, Error> {
297                let usart = unsafe { &(*$USARTX::ptr()) };
298                let isr = usart.isr.read();
299                Err(
300                    if isr.pe().bit_is_set() {
301                        usart.icr.write(|w| w.pecf().set_bit());
302                        nb::Error::Other(Error::Parity)
303                    } else if isr.fe().bit_is_set() {
304                        usart.icr.write(|w| w.fecf().set_bit());
305                        nb::Error::Other(Error::Framing)
306                    } else if isr.nf().bit_is_set() {
307                        usart.icr.write(|w| w.ncf().set_bit());
308                        nb::Error::Other(Error::Noise)
309                    } else if isr.ore().bit_is_set() {
310                        usart.icr.write(|w| w.orecf().set_bit());
311                        nb::Error::Other(Error::Overrun)
312                    } else if isr.rxne().bit_is_set() {
313                        return Ok(usart.rdr.read().bits() as u8)
314                    } else {
315                        nb::Error::WouldBlock
316                    }
317                )
318            }
319        }
320
321        impl<Config> hal::serial::Read<u8> for Serial<$USARTX, Config> {
322            type Error = Error;
323
324            fn read(&mut self) -> nb::Result<u8, Error> {
325                self.rx.read()
326            }
327        }
328
329        impl<Config> Tx<$USARTX, Config> {
330
331            /// Starts listening for an interrupt event
332            pub fn listen(&mut self) {
333                let usart = unsafe { &(*$USARTX::ptr()) };
334                usart.cr1.modify(|_, w| w.txeie().set_bit());
335            }
336
337            /// Stop listening for an interrupt event
338            pub fn unlisten(&mut self) {
339                let usart = unsafe { &(*$USARTX::ptr()) };
340                usart.cr1.modify(|_, w| w.txeie().clear_bit());
341            }
342
343            /// Return true if the tx register is empty (and can accept data)
344            pub fn is_txe(&self) -> bool {
345                let usart = unsafe { &(*$USARTX::ptr()) };
346                usart.isr.read().txe().bit_is_set()
347            }
348
349        }
350
351        impl<Config> hal::serial::Write<u8> for Tx<$USARTX, Config> {
352            type Error = Error;
353
354            fn flush(&mut self) -> nb::Result<(), Self::Error> {
355                let usart = unsafe { &(*$USARTX::ptr()) };
356                if usart.isr.read().tc().bit_is_set() {
357                    Ok(())
358                } else {
359                    Err(nb::Error::WouldBlock)
360                }
361            }
362
363            fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
364                let usart = unsafe { &(*$USARTX::ptr()) };
365                if usart.isr.read().txe().bit_is_set() {
366                    usart.tdr.write(|w| unsafe { w.bits(byte as u32) });
367                    Ok(())
368                } else {
369                    Err(nb::Error::WouldBlock)
370                }
371            }
372        }
373
374        impl<Config> hal::serial::Write<u8> for Serial<$USARTX, Config> {
375            type Error = Error;
376
377            fn flush(&mut self) -> nb::Result<(), Self::Error> {
378                self.tx.flush()
379            }
380
381            fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
382                self.tx.write(byte)
383            }
384        }
385
386
387        impl<Config> Serial<$USARTX, Config> {
388
389            /// Separates the serial struct into separate channel objects for sending (Tx) and
390            /// receiving (Rx)
391            pub fn split(self) -> (Tx<$USARTX, Config>, Rx<$USARTX, Config>) {
392                (self.tx, self.rx)
393            }
394
395        }
396
397        impl<Config> dma::Target for Rx<$USARTX, Config> {
398
399            fn dmamux(&self) -> DmaMuxIndex {
400                DmaMuxIndex::$dmamux_rx
401            }
402
403            fn enable_dma(&mut self) {
404                // NOTE(unsafe) critical section prevents races
405                interrupt::free(|_| unsafe {
406                    let cr3 = &(*$USARTX::ptr()).cr3;
407                    cr3.modify(|_, w| w.dmar().set_bit());
408                });
409            }
410
411            fn disable_dma(&mut self) {
412                // NOTE(unsafe) critical section prevents races
413                interrupt::free(|_| unsafe {
414                    let cr3 = &(*$USARTX::ptr()).cr3;
415                    cr3.modify(|_, w| w.dmar().clear_bit());
416                });
417            }
418        }
419
420        impl<Config> dma::Target for Tx<$USARTX, Config> {
421
422            fn dmamux(&self) -> DmaMuxIndex {
423                DmaMuxIndex::$dmamux_tx
424            }
425
426            fn enable_dma(&mut self) {
427                // NOTE(unsafe) critical section prevents races
428                interrupt::free(|_| unsafe {
429                    let cr3 = &(*$USARTX::ptr()).cr3;
430                    cr3.modify(|_, w| w.dmat().set_bit());
431                });
432            }
433
434            fn disable_dma(&mut self) {
435                // NOTE(unsafe) critical section prevents races
436                interrupt::free(|_| unsafe {
437                    let cr3 = &(*$USARTX::ptr()).cr3;
438                    cr3.modify(|_, w| w.dmat().clear_bit());
439                });
440            }
441        }
442    }
443}
444
445macro_rules! uart_basic {
446    ($USARTX:ident,
447        $usartX:ident, $clk_mul:expr
448    ) => {
449        impl SerialExt<$USARTX, BasicConfig> for $USARTX {
450            fn usart<PINS: Pins<$USARTX>>(
451                self,
452                pins: PINS,
453                config: BasicConfig,
454                rcc: &mut Rcc,
455            ) -> Result<Serial<$USARTX, BasicConfig>, InvalidConfig> {
456                Serial::$usartX(self, pins, config, rcc)
457            }
458        }
459
460        impl Serial<$USARTX, BasicConfig> {
461            pub fn $usartX<PINS: Pins<$USARTX>>(
462                usart: $USARTX,
463                pins: PINS,
464                config: BasicConfig,
465                rcc: &mut Rcc,
466            ) -> Result<Self, InvalidConfig> {
467                // Enable clock for USART
468                $USARTX::enable(rcc);
469
470                let clk = rcc.clocks.apb_clk.raw() as u64;
471                let bdr = config.baudrate.0 as u64;
472                let div = ($clk_mul * clk) / bdr;
473                usart.brr.write(|w| unsafe { w.bits(div as u32) });
474                // Reset other registers to disable advanced USART features
475                usart.cr2.reset();
476                usart.cr3.reset();
477
478                // Disable USART, there are many bits where UE=0 is required
479                usart.cr1.modify(|_, w| w.ue().clear_bit());
480
481                // Enable transmission and receiving
482                usart.cr1.write(|w| {
483                    w.te()
484                        .set_bit()
485                        .re()
486                        .set_bit()
487                        .m0()
488                        .bit(config.wordlength == WordLength::DataBits9)
489                        .m1()
490                        .bit(config.wordlength == WordLength::DataBits7)
491                        .pce()
492                        .bit(config.parity != Parity::ParityNone)
493                        .ps()
494                        .bit(config.parity == Parity::ParityOdd)
495                });
496                usart.cr2.write(|w| unsafe {
497                    w.stop()
498                        .bits(match config.stopbits {
499                            StopBits::STOP1 => 0b00,
500                            StopBits::STOP0P5 => 0b01,
501                            StopBits::STOP2 => 0b10,
502                            StopBits::STOP1P5 => 0b11,
503                        })
504                        .txinv()
505                        .bit(config.inverted_tx)
506                        .rxinv()
507                        .bit(config.inverted_rx)
508                        .swap()
509                        .bit(config.swap)
510                });
511
512                usart.cr3.write(|w| w.dem().bit(PINS::DRIVER_ENABLE));
513
514                // Enable pins
515                pins.setup();
516
517                // Enable USART
518                usart.cr1.modify(|_, w| w.ue().set_bit());
519
520                Ok(Serial {
521                    tx: Tx {
522                        _usart: PhantomData,
523                        _config: PhantomData,
524                    },
525                    rx: Rx {
526                        _usart: PhantomData,
527                        _config: PhantomData,
528                    },
529                    usart,
530                    _config: PhantomData,
531                })
532            }
533
534            /// Starts listening for an interrupt event
535            pub fn listen(&mut self, event: Event) {
536                match event {
537                    Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
538                    Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
539                    Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
540                    _ => {}
541                }
542            }
543
544            /// Stop listening for an interrupt event
545            pub fn unlisten(&mut self, event: Event) {
546                match event {
547                    Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
548                    Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
549                    Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
550                    _ => {}
551                }
552            }
553
554            /// Check if interrupt event is pending
555            pub fn is_pending(&mut self, event: Event) -> bool {
556                (self.usart.isr.read().bits() & event.val()) != 0
557            }
558
559            /// Clear pending interrupt
560            pub fn unpend(&mut self, event: Event) {
561                // mask the allowed bits
562                let mask: u32 = 0x123BFF;
563                self.usart
564                    .icr
565                    .write(|w| unsafe { w.bits(event.val() & mask) });
566            }
567        }
568    };
569}
570
571macro_rules! uart_full {
572    ($USARTX:ident,
573        $usartX:ident, $clk_mul:expr
574    ) => {
575        impl SerialExt<$USARTX, FullConfig> for $USARTX {
576            fn usart<PINS: Pins<$USARTX>>(
577                self,
578                pins: PINS,
579                config: FullConfig,
580                rcc: &mut Rcc,
581            ) -> Result<Serial<$USARTX, FullConfig>, InvalidConfig> {
582                Serial::$usartX(self, pins, config, rcc)
583            }
584        }
585
586        impl Serial<$USARTX, FullConfig> {
587            pub fn $usartX<PINS: Pins<$USARTX>>(
588                usart: $USARTX,
589                pins: PINS,
590                config: FullConfig,
591                rcc: &mut Rcc,
592            ) -> Result<Self, InvalidConfig> {
593                // Enable clock for USART
594                $USARTX::enable(rcc);
595
596                let clk = rcc.clocks.apb_clk.raw() as u64;
597                let bdr = config.baudrate.0 as u64;
598                let clk_mul = 1;
599                let div = (clk_mul * clk) / bdr;
600                usart.brr.write(|w| unsafe { w.bits(div as u32) });
601
602                usart.cr1.reset();
603                usart.cr2.reset();
604                usart.cr3.reset();
605
606                usart.cr2.write(|w| unsafe {
607                    w.stop()
608                        .bits(config.stopbits.bits())
609                        .txinv()
610                        .bit(config.inverted_tx)
611                        .rxinv()
612                        .bit(config.inverted_rx)
613                        .swap()
614                        .bit(config.swap)
615                });
616
617                if let Some(timeout) = config.receiver_timeout {
618                    usart.cr1.write(|w| w.rtoie().set_bit());
619                    usart.cr2.modify(|_, w| w.rtoen().set_bit());
620                    usart.rtor.write(|w| unsafe { w.rto().bits(timeout) });
621                }
622
623                usart.cr3.write(|w| unsafe {
624                    w.txftcfg()
625                        .bits(config.tx_fifo_threshold.bits())
626                        .rxftcfg()
627                        .bits(config.rx_fifo_threshold.bits())
628                        .txftie()
629                        .bit(config.tx_fifo_interrupt)
630                        .rxftie()
631                        .bit(config.rx_fifo_interrupt)
632                        .dem()
633                        .bit(PINS::DRIVER_ENABLE)
634                });
635
636                usart.cr1.modify(|_, w| {
637                    w.ue()
638                        .set_bit()
639                        .te()
640                        .set_bit()
641                        .re()
642                        .set_bit()
643                        .m0()
644                        .bit(config.wordlength == WordLength::DataBits7)
645                        .m1()
646                        .bit(config.wordlength == WordLength::DataBits9)
647                        .pce()
648                        .bit(config.parity != Parity::ParityNone)
649                        .ps()
650                        .bit(config.parity == Parity::ParityOdd)
651                        .fifoen()
652                        .bit(config.fifo_enable)
653                });
654
655                // Enable pins
656                pins.setup();
657
658                Ok(Serial {
659                    tx: Tx {
660                        _usart: PhantomData,
661                        _config: PhantomData,
662                    },
663                    rx: Rx {
664                        _usart: PhantomData,
665                        _config: PhantomData,
666                    },
667                    usart,
668                    _config: PhantomData,
669                })
670            }
671
672            /// Starts listening for an interrupt event
673            pub fn listen(&mut self, event: Event) {
674                match event {
675                    Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().set_bit()),
676                    Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().set_bit()),
677                    Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().set_bit()),
678                    _ => {}
679                }
680            }
681
682            /// Stop listening for an interrupt event
683            pub fn unlisten(&mut self, event: Event) {
684                match event {
685                    Event::Rxne => self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()),
686                    Event::Txe => self.usart.cr1.modify(|_, w| w.txeie().clear_bit()),
687                    Event::Idle => self.usart.cr1.modify(|_, w| w.idleie().clear_bit()),
688                    _ => {}
689                }
690            }
691
692            /// Check if interrupt event is pending
693            pub fn is_pending(&mut self, event: Event) -> bool {
694                (self.usart.isr.read().bits() & event.val()) != 0
695            }
696
697            /// Clear pending interrupt
698            pub fn unpend(&mut self, event: Event) {
699                // mask the allowed bits
700                let mask: u32 = 0x123BFF;
701                self.usart
702                    .icr
703                    .write(|w| unsafe { w.bits(event.val() & mask) });
704            }
705        }
706        impl Tx<$USARTX, FullConfig> {
707            /// Returns true if the tx fifo threshold has been reached.
708            pub fn fifo_threshold_reached(&self) -> bool {
709                let usart = unsafe { &(*$USARTX::ptr()) };
710                usart.isr.read().txft().bit_is_set()
711            }
712        }
713
714        impl Rx<$USARTX, FullConfig> {
715            /// Check if receiver timeout has lapsed
716            /// Returns the current state of the ISR RTOF bit
717            pub fn timeout_lapsed(&self) -> bool {
718                let usart = unsafe { &(*$USARTX::ptr()) };
719                usart.isr.read().rtof().bit_is_set()
720            }
721
722            /// Clear pending receiver timeout interrupt
723            pub fn clear_timeout(&mut self) {
724                let usart = unsafe { &(*$USARTX::ptr()) };
725                usart.icr.write(|w| w.rtocf().set_bit());
726            }
727
728            /// Returns true if the rx fifo threshold has been reached.
729            pub fn fifo_threshold_reached(&self) -> bool {
730                let usart = unsafe { &(*$USARTX::ptr()) };
731                usart.isr.read().rxft().bit_is_set()
732            }
733        }
734    };
735}
736
737uart_shared!(USART1, USART1_RX, USART1_TX,
738    tx: [
739        (PA9, AltFunction::AF1),
740        (PB6, AltFunction::AF0),
741        (PC4, AltFunction::AF1),
742    ],
743    rx: [
744        (PA10, AltFunction::AF1),
745        (PB7, AltFunction::AF0),
746        (PC5, AltFunction::AF1),
747    ],
748    de: [
749        (PA12, AltFunction::AF1),
750        (PB3, AltFunction::AF4),
751    ]
752);
753
754uart_shared!(USART2, USART2_RX, USART2_TX,
755    tx: [
756        (PA2, AltFunction::AF1),
757        (PA14, AltFunction::AF1),
758        (PD5, AltFunction::AF0),
759    ],
760    rx: [
761        (PA3, AltFunction::AF1),
762        (PA15, AltFunction::AF1),
763        (PD6, AltFunction::AF0),
764    ],
765    de: [
766        (PA1, AltFunction::AF1),
767        (PD4, AltFunction::AF0),
768    ]
769);
770
771#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
772uart_shared!(USART3, USART3_RX, USART3_TX,
773    tx: [
774        (PA5, AltFunction::AF4),
775        (PB2, AltFunction::AF4),
776        (PB8, AltFunction::AF4),
777        (PB10, AltFunction::AF4),
778        (PC4, AltFunction::AF1),
779        (PC10, AltFunction::AF1),
780        (PD8, AltFunction::AF1),
781    ],
782    rx: [
783        (PB0, AltFunction::AF4),
784        (PB9, AltFunction::AF4),
785        (PB11, AltFunction::AF4),
786        (PC5, AltFunction::AF1),
787        (PC11, AltFunction::AF1),
788        (PD9, AltFunction::AF1),
789    ],
790    de: [
791        (PA15, AltFunction::AF5),
792        (PB1, AltFunction::AF4),
793        (PB14, AltFunction::AF4),
794        (PD2, AltFunction::AF0),
795        (PD12, AltFunction::AF0),
796    ]
797);
798
799#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
800uart_shared!(USART4, USART4_RX, USART4_TX,
801    tx: [
802        (PA0, AltFunction::AF4),
803        (PC10, AltFunction::AF1),
804    ],
805    rx: [
806        (PC11, AltFunction::AF1),
807        (PA1, AltFunction::AF4),
808    ],
809    de: [
810        (PA15, AltFunction::AF4),
811    ]
812);
813
814#[cfg(feature = "stm32g0x1")]
815uart_shared!(LPUART, LPUART_RX, LPUART_TX,
816    tx: [
817        (PA2, AltFunction::AF6),
818        (PB11, AltFunction::AF1),
819        (PC1, AltFunction::AF1),
820    ],
821    rx: [
822        (PA3, AltFunction::AF6),
823        (PB10, AltFunction::AF1),
824        (PC0, AltFunction::AF1),
825    ],
826    de: [
827        (PB1, AltFunction::AF6),
828        (PB12, AltFunction::AF1),
829    ]
830);
831
832uart_full!(USART1, usart1, 1);
833
834#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
835uart_full!(USART2, usart2, 1);
836
837#[cfg(any(feature = "stm32g030", feature = "stm32g031", feature = "stm32g041"))]
838uart_basic!(USART2, usart2, 1);
839
840#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
841uart_basic!(USART3, usart3, 1);
842
843#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
844uart_basic!(USART4, usart4, 1);
845
846// LPUART Should be given its own implementation when it needs to be used with features not present on
847// the basic feature set such as: Dual clock domain, FIFO or prescaler.
848// Or when Synchronous mode is implemented for the basic feature set, since the LP feature set does not have support.
849#[cfg(feature = "stm32g0x1")]
850uart_basic!(LPUART, lpuart, 256);