1use core::mem;
10use core::convert::Infallible;
11
12use embedded_hal::serial;
13
14use crate::pac::{UARTHS,uart1,UART1,UART2,UART3};
15use crate::clock::Clocks;
16use crate::time::Bps;
17use core::marker::PhantomData;
18use crate::external_pins::ExternalPin;
19use crate::fpioa;
20
21
22pub trait SerialExt<PINS>: Sized {
24 fn configure(self, pins: PINS, baud_rate: Bps, clocks: &Clocks) -> Serial<Self, PINS>;
26}
27
28pub struct Serial<UART, PINS> {
30 uart: UART,
31 pins: PINS,
32}
33
34impl<UART, PINS> Serial<UART, PINS> {
35 pub fn split(self) -> (Tx<UART, PINS>, Rx<UART, PINS>) {
38 (
39 Tx {
40 uart: self.uart,
41 pins: self.pins
42 },
43 Rx {
44 uart: unsafe { mem::zeroed() },
45 _pins: PhantomData,
46 }
47 )
48 }
49
50 pub fn join(tx: Tx<UART, PINS>, _rx: Rx<UART, PINS>) -> Self {
53 Serial { uart: tx.uart, pins: tx.pins }
54 }
55
56 pub fn free(self) -> (UART, PINS) {
58 (self.uart, self.pins)
59 }
60}
61
62pub struct Tx<UART, PINS> {
64 uart: UART,
65 pins: PINS,
66}
67
68pub struct Rx<UART, PINS> {
70 uart: UART,
71 _pins: PhantomData<PINS>,
72}
73
74
75impl<TX: ExternalPin, RX: ExternalPin> SerialExt<(TX, RX)> for UARTHS {
76 fn configure(self, pins: (TX, RX), baud_rate: Bps, clocks: &Clocks) -> Serial<UARTHS, (TX, RX)>
77 {
78 let uart = self;
79 fpioa::set_function(TX::INDEX, fpioa::Function::UARTHS_TX);
80 fpioa::set_function(RX::INDEX, fpioa::Function::UARTHS_RX);
81
82 let div = clocks.cpu().0 / baud_rate.0 - 1;
83 unsafe {
84 uart.div.write(|w| w.bits(div));
85 }
86
87 uart.txctrl.write(|w| w.txen().bit(true));
88 uart.rxctrl.write(|w| w.rxen().bit(true));
89
90 Serial { uart, pins }
91 }
92}
93
94impl<PINS> Serial<UARTHS, PINS> {
95 pub fn listen(self) -> Self {
97 self.uart.ie.write(|w| w.txwm().bit(false).rxwm().bit(true));
98 self
99 }
100
101 pub fn unlisten(self) -> Self {
103 self.uart
104 .ie
105 .write(|w| w.txwm().bit(false).rxwm().bit(false));
106 self
107 }
108}
109
110impl<PINS> serial::Read<u8> for Rx<UARTHS, PINS> {
111 type Error = Infallible;
112
113 fn read(&mut self) -> nb::Result<u8, Infallible> {
114 let rxdata = self.uart.rxdata.read();
115
116 if rxdata.empty().bit_is_set() {
117 Err(nb::Error::WouldBlock)
118 } else {
119 Ok(rxdata.data().bits() as u8)
120 }
121 }
122}
123
124impl<PINS> serial::Write<u8> for Tx<UARTHS, PINS> {
125 type Error = Infallible;
126
127 fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
128 let txdata = self.uart.txdata.read();
129
130 if txdata.full().bit_is_set() {
131 Err(nb::Error::WouldBlock)
132 } else {
133 unsafe {
134 (*UARTHS::ptr()).txdata.write(|w| w.data().bits(byte));
135 }
136 Ok(())
137 }
138 }
139
140 fn flush(&mut self) -> nb::Result<(), Infallible> {
141 let txdata = self.uart.txdata.read();
142
143 if txdata.full().bit_is_set() {
144 Err(nb::Error::WouldBlock)
145 } else {
146 Ok(())
147 }
148 }
149}
150
151mod closed_trait {
152 use core::ops::Deref;
153 pub trait UartX: Deref<Target = super::uart1::RegisterBlock> {
155 const INDEX: u8;
156 }
157}
158use closed_trait::UartX;
159
160impl UartX for UART1 { const INDEX: u8 = 1; }
161impl UartX for UART2 { const INDEX: u8 = 2; }
162impl UartX for UART3 { const INDEX: u8 = 3; }
163
164const UART_RECEIVE_FIFO_1: u32 = 0;
165const UART_SEND_FIFO_8: u32 = 3;
166
167impl<UART: UartX, TX: ExternalPin, RX: ExternalPin> SerialExt<(TX, RX)> for UART {
168 fn configure(self, pins: (TX, RX), baud_rate: Bps, clocks: &Clocks) -> Serial<UART, (TX, RX)> {
169 let uart = self;
170 fpioa::set_function(TX::INDEX, fpioa::Function::uart(UART::INDEX, fpioa::UartFunction::TX));
171 fpioa::set_function(RX::INDEX, fpioa::Function::uart(UART::INDEX, fpioa::UartFunction::RX));
172
173 let data_width = 8; let stopbit_val = 0; let parity_val = 0; let divisor = clocks.apb0().0 / baud_rate.0;
179 let dlh = ((divisor >> 12) & 0xff) as u8;
180 let dll = ((divisor >> 4) & 0xff) as u8;
181 let dlf = (divisor & 0xf) as u8;
182 unsafe {
183 uart.lcr.write(|w| w.bits(1 << 7));
185 uart.dlh_ier.write(|w| w.bits(dlh.into()));
186 uart.rbr_dll_thr.write(|w| w.bits(dll.into()));
187 uart.dlf.write(|w| w.bits(dlf.into()));
188 uart.lcr.write(|w| w.bits((data_width - 5) | (stopbit_val << 2) | (parity_val << 3)));
190 uart.dlh_ier.write(|w| w.bits(0x80)); uart.fcr_iir.write(|w| w.bits(UART_RECEIVE_FIFO_1 << 6 | UART_SEND_FIFO_8 << 4 | 0x1 << 3 | 0x1));
194 }
195
196 Serial { uart, pins }
197 }
198}
199
200impl<UART: UartX, PINS> Serial<UART, PINS> {
201 pub fn listen(self) -> Self {
203 self
204 }
205
206 pub fn unlisten(self) -> Self {
208 self
209 }
210}
211
212impl<UART: UartX, PINS> serial::Read<u8> for Rx<UART, PINS> {
213 type Error = Infallible;
214
215 fn read(&mut self) -> nb::Result<u8, Infallible> {
216 let lsr = self.uart.lsr.read();
217
218 if (lsr.bits() & (1<<0)) == 0 { Err(nb::Error::WouldBlock)
220 } else {
221 let rbr = self.uart.rbr_dll_thr.read();
222 Ok((rbr.bits() & 0xff) as u8)
223 }
224 }
225}
226
227impl<UART: UartX, PINS> serial::Write<u8> for Tx<UART, PINS> {
228 type Error = Infallible;
229
230 fn write(&mut self, byte: u8) -> nb::Result<(), Infallible> {
231 let lsr = self.uart.lsr.read();
232
233 if (lsr.bits() & (1<<5)) != 0 { Err(nb::Error::WouldBlock)
235 } else {
236 unsafe {
237 self.uart.rbr_dll_thr.write(|w| w.bits(byte.into()));
238 }
239 Ok(())
240 }
241 }
242
243 fn flush(&mut self) -> nb::Result<(), Infallible> {
244 Ok(())
246 }
247}