1#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
2pub mod uart4;
3#[cfg(any(all(feature = "stm32f103", feature = "high"), feature = "connectivity"))]
4pub mod uart5;
5pub mod usart1;
6pub mod usart2;
7pub mod usart3;
8pub use crate::common::uart::*;
9
10use crate::{
11 Steal,
12 afio::{RemapMode, uart_remap::*},
13 common::os::*,
14 dma::{DmaBindRx, DmaBindTx, DmaRingbufTxLoader},
15 rcc::{BusClock, Enable, Reset},
16};
17
18use crate::Mcu;
19
20pub trait UartInit<U> {
21 fn constrain(self, mcu: &mut Mcu) -> Uart<U>;
22}
23
24pub trait UartPeriphExt: UartPeriph + BusClock + Enable + Reset + Steal {
25 fn config(&mut self, config: Config, mcu: &mut Mcu);
26 fn enable_comm(&mut self, tx: bool, rx: bool);
27 fn set_stop_bits(&mut self, bits: StopBits);
28}
29
30pub struct Uart<U> {
32 uart: U,
33}
34
35impl<U: UartPeriphExt> Uart<U> {
36 pub fn into_tx_rx<REMAP: RemapMode<U>>(
37 mut self,
38 pins: (Option<impl UartTxPin<REMAP>>, Option<impl UartRxPin<REMAP>>),
39 config: Config,
40 mcu: &mut Mcu,
41 ) -> (Option<Tx<U>>, Option<Rx<U>>) {
42 REMAP::remap(&mut mcu.afio);
43 self.uart.config(config, mcu);
44 self.uart.enable_comm(pins.0.is_some(), pins.1.is_some());
45 unsafe {
46 (
47 pins.0.map(|_| Tx::new(self.uart.steal())),
48 pins.1.map(|_| Rx::new(self.uart.steal())),
49 )
50 }
51 }
52
53 pub fn get_idle_interrupt_handler(&self) -> UartIdleInterrupt<U> {
54 UartIdleInterrupt::new(unsafe { self.uart.steal() })
55 }
56}
57
58pub struct Tx<U> {
62 uart: U,
63}
64
65impl<U: UartPeriphExt> Tx<U> {
66 pub(crate) fn new(uart: U) -> Self {
67 Self { uart }
68 }
69
70 pub fn into_poll<W: Waiter>(self, timeout: W, flush_timeout: W) -> UartPollTx<U, W> {
71 UartPollTx::new(self.uart, timeout, flush_timeout)
72 }
73
74 pub fn into_interrupt<W: Waiter>(
75 self,
76 buf_size: usize,
77 timeout: W,
78 flush_timeout: W,
79 ) -> (UartInterruptTx<U, W>, UartInterruptTxHandler<U>) {
80 let u2 = unsafe { self.uart.steal() };
81 UartInterruptTx::new([self.uart, u2], buf_size, timeout, flush_timeout)
82 }
83
84 pub fn into_dma_ringbuf<CH, W>(
92 self,
93 dma_ch: CH,
94 buf_size: usize,
95 timeout: W,
96 flush_timeout: W,
97 ) -> (UartDmaBufTx<U, CH, W>, DmaRingbufTxLoader<u8, CH>)
98 where
99 CH: DmaBindTx<U>,
100 W: Waiter,
101 {
102 UartDmaBufTx::new(self.uart, dma_ch, buf_size, timeout, flush_timeout)
103 }
104}
105
106pub struct Rx<U> {
110 uart: U,
111}
112
113impl<U: UartPeriphExt> Rx<U> {
114 pub(crate) fn new(uart: U) -> Self {
115 Self { uart }
116 }
117
118 pub fn into_poll<W: Waiter>(self, timeout: W, continue_timeout: W) -> UartPollRx<U, W> {
119 UartPollRx::new(self.uart, timeout, continue_timeout)
120 }
121
122 pub fn into_interrupt<W: Waiter>(
123 self,
124 buf_size: usize,
125 timeout: W,
126 ) -> (UartInterruptRx<U, W>, UartInterruptRxHandler<U>) {
127 let u2 = unsafe { self.uart.steal() };
128 UartInterruptRx::new([self.uart, u2], buf_size, timeout)
129 }
130
131 pub fn into_dma_circle<CH, W>(
132 self,
133 dma_ch: CH,
134 buf_size: usize,
135 timeout: W,
136 ) -> UartDmaRx<U, CH, W>
137 where
138 CH: DmaBindRx<U>,
139 W: Waiter,
140 {
141 UartDmaRx::new(self.uart, dma_ch, buf_size, timeout)
142 }
143}