stm32f1_hal/uart/
mod.rs

1#[cfg(any(all(feature = "f103", feature = "high"), feature = "connectivity"))]
2mod uart4;
3#[cfg(any(all(feature = "f103", feature = "high"), feature = "connectivity"))]
4mod uart5;
5mod usart1;
6mod usart2;
7mod usart3;
8
9pub use crate::common::uart::*;
10
11use crate::{
12    Mcu, Steal,
13    afio::{RemapMode, uart_remap::*},
14    dma::{DmaBindRx, DmaBindTx, DmaRingbufTxLoader},
15    os_trait::{MicrosDurationU32, prelude::*},
16    rcc::{Enable, GetClock, Reset},
17};
18use core::marker::PhantomData;
19
20pub trait UartInit<U> {
21    fn init<OS: OsInterface>(self, mcu: &mut Mcu) -> Uart<OS, U>;
22}
23
24pub trait UartPeriphConfig: UartPeriph + GetClock + Enable + Reset + Steal {
25    fn config(&mut self, config: Config);
26    fn enable_comm(&mut self, tx: bool, rx: bool);
27    fn set_stop_bits(&mut self, bits: StopBits);
28    fn is_tx_empty(&self) -> bool;
29    fn is_rx_not_empty(&self) -> bool;
30}
31
32// wrapper
33pub struct Uart<OS: OsInterface, U> {
34    uart: U,
35    _os: PhantomData<OS>,
36}
37
38#[allow(clippy::type_complexity)]
39impl<OS, U> Uart<OS, U>
40where
41    OS: OsInterface,
42    U: UartPeriphConfig,
43{
44    pub fn into_tx_rx<REMAP: RemapMode<U>>(
45        mut self,
46        pins: (impl UartTxPin<REMAP>, impl UartRxPin<REMAP>),
47        config: Config,
48        mcu: &mut Mcu,
49    ) -> (Option<Tx<OS, U>>, Option<Rx<OS, U>>) {
50        REMAP::remap(&mut mcu.afio);
51        let baudrate = config.baudrate;
52        self.uart.config(config);
53        self.uart.enable_comm(pins.0.is_pin(), pins.1.is_pin());
54        unsafe {
55            (
56                if pins.0.is_pin() {
57                    Some(Tx::new(self.uart.steal(), baudrate))
58                } else {
59                    None
60                },
61                if pins.1.is_pin() {
62                    Some(Rx::new(self.uart.steal(), baudrate))
63                } else {
64                    None
65                },
66            )
67        }
68    }
69
70    pub fn get_idle_interrupt_handler(&self) -> UartIdleInterrupt<U> {
71        UartIdleInterrupt::new(unsafe { self.uart.steal() })
72    }
73}
74
75// ------------------------------------------------------------------------------------------------
76
77/// UART Transmitter
78pub struct Tx<OS: OsInterface, U> {
79    uart: U,
80    baudrate: u32,
81    _os: PhantomData<OS>,
82}
83
84impl<OS, U> Tx<OS, U>
85where
86    OS: OsInterface,
87    U: UartPeriphConfig,
88{
89    pub(crate) fn new(uart: U, baudrate: u32) -> Self {
90        Self {
91            uart,
92            baudrate,
93            _os: PhantomData,
94        }
95    }
96
97    pub fn into_poll(self, timeout: MicrosDurationU32) -> UartPollTx<U, OS> {
98        UartPollTx::new(self.uart, self.baudrate, timeout)
99    }
100
101    pub fn into_interrupt(
102        self,
103        buf_size: usize,
104        timeout: MicrosDurationU32,
105    ) -> (UartInterruptTx<U, OS>, UartInterruptTxHandler<U, OS>) {
106        let u2 = unsafe { self.uart.steal() };
107        UartInterruptTx::new([self.uart, u2], buf_size, self.baudrate, timeout)
108    }
109}
110
111impl<OS, U> Tx<OS, U>
112where
113    OS: OsInterface,
114    U: UartPeriphConfig + UartPeriphWithDma,
115{
116    pub fn into_dma_ringbuf<CH>(
117        self,
118        dma_ch: CH,
119        buf_size: usize,
120        timeout: MicrosDurationU32,
121    ) -> (UartDmaBufTx<U, CH, OS>, DmaRingbufTxLoader<u8, CH, OS>)
122    where
123        CH: DmaBindTx<U>,
124        OS: OsInterface,
125    {
126        UartDmaBufTx::new(self.uart, dma_ch, buf_size, self.baudrate, timeout)
127    }
128}
129
130// ------------------------------------------------------------------------------------------------
131
132/// UART Receiver
133pub struct Rx<OS: OsInterface, U> {
134    uart: U,
135    baudrate: u32,
136    _os: PhantomData<OS>,
137}
138
139impl<OS, U> Rx<OS, U>
140where
141    OS: OsInterface,
142    U: UartPeriphConfig,
143{
144    pub(crate) fn new(uart: U, baudrate: u32) -> Self {
145        Self {
146            uart,
147            baudrate,
148            _os: PhantomData,
149        }
150    }
151
152    pub fn into_poll(self, timeout: MicrosDurationU32) -> UartPollRx<U, OS> {
153        UartPollRx::new(self.uart, self.baudrate, timeout)
154    }
155
156    pub fn into_interrupt(
157        self,
158        buf_size: usize,
159        timeout: MicrosDurationU32,
160    ) -> (UartInterruptRx<U, OS>, UartInterruptRxHandler<U, OS>) {
161        let u2 = unsafe { self.uart.steal() };
162        UartInterruptRx::new([self.uart, u2], buf_size, timeout)
163    }
164}
165
166impl<OS, U> Rx<OS, U>
167where
168    OS: OsInterface,
169    U: UartPeriphConfig + UartPeriphWithDma,
170{
171    pub fn into_dma_circle<CH>(
172        self,
173        dma_ch: CH,
174        buf_size: usize,
175        timeout: MicrosDurationU32,
176    ) -> (UartDmaRx<U, CH, OS>, UartDmaRxNotify<CH, OS>)
177    where
178        CH: DmaBindRx<U> + Steal,
179        OS: OsInterface,
180    {
181        UartDmaRx::new(self.uart, dma_ch, buf_size, timeout)
182    }
183}