embassy_stm32_plus/builder/uart/uart1/
mod.rs

1use embassy_stm32::{bind_interrupts, Peripheral, usart};
2use embassy_stm32::mode::Async;
3#[cfg(not(STM32C0))]
4use embassy_stm32::peripherals::{DMA1_CH4, DMA1_CH5};
5use embassy_stm32::peripherals::USART1;
6use embassy_stm32::usart::{Config, ConfigError, RtsPin, RxPin, TxPin, Uart};
7#[cfg(STM32C0)]
8use embassy_stm32::usart::{RxDma, TxDma};
9use crate::builder::uart::base::UartBase;
10use crate::builder::uart::uart1::rx::{Uart1Rts, Uart1Rx, Uart1RxBuilder};
11use crate::builder::uart::uart1::tx::{Uart1Cts, Uart1Tx};
12
13pub mod rx;
14pub mod tx;
15
16bind_interrupts!(struct Irqs {
17    USART1 => usart::InterruptHandler<USART1>;
18});
19
20/// uart1 builder
21pub struct Uart1Builder {
22    /// uart1 base data
23    pub base: UartBase<USART1>,
24    /// uart1 tx pin
25    pub tx: Uart1Tx,
26    /// uart1 rx pin
27    pub rx: Uart1Rx,
28    /// use rts cts
29    pub rts_cts: Option<(Uart1Rts, Uart1Cts)>,
30}
31
32/// uart1 build
33macro_rules! uart1_build {
34    ($tx_dma:ty,$rx_dma:ty) => {
35        /// build a serial port that supports read and write data
36        pub fn build(self, tx_dma: $tx_dma, rx_dma: $rx_dma) -> Result<Uart<'static, Async>, ConfigError> {
37            let rx = Uart1RxBuilder { base: self.base, rx: self.rx, rts: None };
38            match self.tx {
39                #[cfg(USART1_PA0)]
40                Uart1Tx::PA0(pa0) => { Self::build_rx(pa0, rx, tx_dma, rx_dma, self.rts_cts) }
41                #[cfg(PA9)]
42                Uart1Tx::PA9(pa9) => { Self::build_rx(pa9, rx, tx_dma, rx_dma, self.rts_cts) }
43                #[cfg(USART1_PB6)]
44                Uart1Tx::PB6(pb6) => { Self::build_rx(pb6, rx, tx_dma, rx_dma, self.rts_cts) }
45                #[cfg(USART1_PC14)]
46                Uart1Tx::PC14(pc14) => { Self::build_rx(pc14, rx, tx_dma, rx_dma, self.rts_cts) }
47            }
48        }
49
50        /// build by rx
51        fn build_rx(
52            tx: impl Peripheral<P=impl TxPin<USART1>> + 'static,
53            rx: Uart1RxBuilder,
54            tx_dma: $tx_dma,
55            rx_dma: $rx_dma,
56            rts_cts: Option<(Uart1Rts, Uart1Cts)>)
57            -> Result<Uart<'static, Async>, ConfigError> {
58            match rx.rx {
59                #[cfg(USART1_PA1)]
60                Uart1Rx::PA1(pa1) => { Self::build_rts(tx, pa1, rx.base, tx_dma, rx_dma, rts_cts) }
61                #[cfg(USART1_RX_PA8)]
62                Uart1Rx::PA8(pa8) => { Self::build_rts(tx, pa8, rx.base, tx_dma, rx_dma, rts_cts) }
63                #[cfg(PA10)]
64                Uart1Rx::PA10(pa10) => { Self::build_rts(tx, pa10, rx.base, tx_dma, rx_dma, rts_cts) }
65                #[cfg(USART1_PB2)]
66                Uart1Rx::PB2(pb2) => { Self::build_rts(tx, pb2, rx.base, tx_dma, rx_dma, rts_cts) }
67                Uart1Rx::PB7(pb7) => { Self::build_rts(tx, pb7, rx.base, tx_dma, rx_dma, rts_cts) }
68            }
69        }
70
71        /// build rts or default
72        fn build_rts(
73            tx: impl Peripheral<P=impl TxPin<USART1>> + 'static,
74            rx: impl Peripheral<P=impl RxPin<USART1>> + 'static,
75            base: UartBase<USART1>,
76            tx_dma: $tx_dma,
77            rx_dma: $rx_dma,
78            rts_cts: Option<(Uart1Rts, Uart1Cts)>)
79            -> Result<Uart<'static, Async>, ConfigError> {
80            let (rts, cts) = crate::match_some_return!(rts_cts,
81                Uart::new(base.uart, rx, tx, Irqs, tx_dma, rx_dma, base.config.unwrap_or_default()));
82            match rts {
83                #[cfg(USART1_PA12)]
84                Uart1Rts::PA12(pa12) => { Self::build_cts(tx, rx, base, tx_dma, rx_dma, pa12, cts) }
85                #[cfg(USART1_PA14)]
86                Uart1Rts::PA14(pa14) => { Self::build_cts(tx, rx, base, tx_dma, rx_dma, pa14, cts) }
87                #[cfg(USART1_PA15)]
88                Uart1Rts::PA15(pa15) => { Self::build_cts(tx, rx, base, tx_dma, rx_dma, pa15, cts) }
89                #[cfg(USART1_PB3)]
90                Uart1Rts::PB3(pb3) => { Self::build_cts(tx, rx, base, tx_dma, rx_dma, pb3, cts) }
91            }
92        }
93
94        fn build_cts(
95            tx: impl Peripheral<P=impl TxPin<USART1>> + 'static,
96            rx: impl Peripheral<P=impl RxPin<USART1>> + 'static,
97            base: UartBase<USART1>,
98            tx_dma: $tx_dma,
99            rx_dma: $rx_dma,
100            rts: impl Peripheral<P=impl RtsPin<USART1>> + 'static,
101            cts: Uart1Cts,
102        ) -> Result<Uart<'static, Async>, ConfigError> {
103            match cts {
104                #[cfg(USART1_PA11)]
105                Uart1Cts::PA11(pa11) => { Uart::new_with_rtscts(base.uart, rx, tx, Irqs, rts, pa11, tx_dma, rx_dma, base.config.unwrap_or_default()) }
106                #[cfg(USART1_PB4)]
107                Uart1Cts::PB4(pb4) => { Uart::new_with_rtscts(base.uart, rx, tx, Irqs, rts, pb4, tx_dma, rx_dma, base.config.unwrap_or_default()) }
108                #[cfg(USART1_CTS_PB6)]
109                Uart1Cts::PB6(pb6) => { Uart::new_with_rtscts(base.uart, rx, tx, Irqs, rts, pb6, tx_dma, rx_dma, base.config.unwrap_or_default()) }
110            }
111        }
112    };
113}
114
115/// custom method
116impl Uart1Builder {
117    /// create builder
118    #[inline]
119    pub fn new(uart: USART1, tx: Uart1Tx, rx: Uart1Rx) -> Self {
120        Self { base: UartBase::new(uart), tx, rx, rts_cts: None }
121    }
122
123    /// set uart config
124    #[inline]
125    pub fn config(mut self, config: Config) -> Self {
126        self.base.set_config(config);
127        self
128    }
129
130    /// set rts cts
131    #[inline]
132    pub fn rts_cts(mut self, rts: Uart1Rts, cts: Uart1Cts) -> Self {
133        self.rts_cts = Some((rts, cts));
134        self
135    }
136
137    #[cfg(STM32C0)]
138    uart1_build!(impl Peripheral<P = impl TxDma<USART1>> + 'static,impl Peripheral<P = impl RxDma<USART1>> + 'static);
139    #[cfg(not(STM32C0))]
140    uart1_build!(DMA1_CH4,DMA1_CH5);
141}