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
32pub 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
75pub 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
130pub 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}