1use core::marker::PhantomData;
8use core::{fmt, ops::Deref};
9
10use nb::block;
11
12use crate::pac::{
13 uart0::RegisterBlock, UART0, UART0_SECURE, UART1, UART1_SECURE, UART2, UART2_SECURE, UART3,
14 UART3_SECURE, UART4, UART4_SECURE, UART5, UART5_SECURE,
15};
16
17pub trait ValidUart: Deref<Target = RegisterBlock> {
18 const PTR: *const RegisterBlock;
19}
20pub trait Pins<UART> {}
21pub trait PinTx<UART> {}
22pub trait PinRx<UART> {}
23
24macro_rules! impl_valid_uart {
25 ($($name: ty),+) => {
26 $(
27 impl ValidUart for $name {
28 const PTR: *const RegisterBlock = <$name>::PTR;
29 }
30 )+
31 }
32}
33
34impl_valid_uart!(UART0, UART1, UART2, UART3, UART4, UART5);
35
36impl<UART, TX, RX> Pins<UART> for (RX, TX)
37where
38 TX: PinTx<UART>,
39 RX: PinRx<UART>,
40{
41}
42
43pub struct AutoTx;
45pub struct AutoRx;
47
48impl PinRx<UART0> for AutoRx {}
49impl PinTx<UART0> for AutoTx {}
50impl PinRx<UART1> for AutoRx {}
51impl PinTx<UART1> for AutoTx {}
52impl PinRx<UART2> for AutoRx {}
53impl PinTx<UART2> for AutoTx {}
54impl PinRx<UART3> for crate::shield::Pin<0, 0, crate::shield::Uart> {}
55impl PinTx<UART3> for crate::shield::Pin<0, 1, crate::shield::Uart> {}
56impl PinRx<UART4> for crate::shield::Pin<1, 0, crate::shield::Uart> {}
57impl PinTx<UART4> for crate::shield::Pin<1, 1, crate::shield::Uart> {}
58impl PinRx<UART5> for AutoRx {}
59impl PinTx<UART5> for AutoTx {}
60impl PinRx<UART0_SECURE> for AutoRx {}
61impl PinTx<UART0_SECURE> for AutoTx {}
62impl PinRx<UART1_SECURE> for AutoRx {}
63impl PinTx<UART1_SECURE> for AutoTx {}
64impl PinRx<UART2_SECURE> for AutoRx {}
65impl PinTx<UART2_SECURE> for AutoTx {}
66impl PinRx<UART3_SECURE> for crate::shield::Pin<0, 0, crate::shield::Uart> {}
67impl PinTx<UART3_SECURE> for crate::shield::Pin<0, 1, crate::shield::Uart> {}
68impl PinRx<UART4_SECURE> for crate::shield::Pin<1, 0, crate::shield::Uart> {}
69impl PinTx<UART4_SECURE> for crate::shield::Pin<1, 1, crate::shield::Uart> {}
70impl PinRx<UART5_SECURE> for AutoRx {}
71impl PinTx<UART5_SECURE> for AutoTx {}
72
73pub struct Serial<UART, RxPin, TxPin> {
74 rx: Rx<UART, RxPin>,
75 tx: Tx<UART, TxPin>,
76}
77
78pub struct Rx<UART, RxPin> {
79 _serial: PhantomData<UART>,
80 _pin: RxPin,
81}
82
83pub struct Tx<UART, TxPin> {
84 _serial: PhantomData<UART>,
85 _pin: TxPin,
86}
87
88#[derive(Debug, Clone, Copy)]
89pub enum Error {
90 Overrun,
92}
93
94pub mod config {
95 #[derive(Debug, Clone, Copy)]
96 pub enum Error {
97 UnreachableBaudrate,
99 }
100}
101impl<U: ValidUart, RxPin, TxPin> Serial<U, RxPin, TxPin>
102where
103 (RxPin, TxPin): Pins<U>,
104{
105 pub fn new(
107 uart: U,
108 (rx, tx): (RxPin, TxPin),
109 baudrate: fugit::HertzU32,
110 ) -> Result<Self, (U, (RxPin, TxPin), config::Error)> {
111 if let Some(bauddiv) = (baudrate.to_Hz() != 0)
113 .then(|| crate::PERIPHERAL_CLOCK.to_Hz() / baudrate.to_Hz())
114 .filter(|&bauddiv| bauddiv >= 16)
115 {
116 uart.bauddiv.write(|w| unsafe { w.bits(bauddiv) });
117 } else {
118 return Err((uart, (rx, tx), config::Error::UnreachableBaudrate));
119 }
120
121 uart.ctrl.modify(|_, w| w.rxen().set_bit().txen().set_bit());
123
124 Ok(Serial {
125 rx: Rx {
126 _serial: PhantomData,
127 _pin: rx,
128 },
129
130 tx: Tx {
131 _serial: PhantomData,
132 _pin: tx,
133 },
134 })
135 }
136
137 pub fn split(self) -> (Rx<U, RxPin>, Tx<U, TxPin>) {
139 let Self { rx, tx } = self;
140 (rx, tx)
141 }
142 }
149
150impl<U: ValidUart, P: PinRx<U>> embedded_hal::serial::Read<u8> for Rx<U, P> {
151 type Error = Error;
152
153 fn read(&mut self) -> nb::Result<u8, Self::Error> {
154 let serial = unsafe { &*U::PTR };
155
156 if serial.state.read().rxbf().bit_is_clear() {
159 Err(nb::Error::WouldBlock)
160 } else {
161 Ok(serial.data.read().bits())
162 }
163 }
164}
165impl<U: ValidUart, P: PinTx<U>> embedded_hal::serial::Write<u8> for Tx<U, P> {
166 type Error = Error;
167
168 fn flush(&mut self) -> nb::Result<(), Self::Error> {
169 let serial = unsafe { &*U::PTR };
170
171 if serial.state.read().txbf().bit_is_set() {
172 Err(nb::Error::WouldBlock)
173 } else {
174 Ok(())
175 }
176 }
177
178 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
179 let serial = unsafe { &*U::PTR };
180
181 if serial.state.read().txbf().bit_is_set() {
182 Err(nb::Error::WouldBlock)
183 } else {
184 unsafe {
185 serial.data.write_with_zero(|w| w.bits(byte));
186 }
187 Ok(())
188 }
189 }
190}
191
192impl<U: ValidUart, RxPin, TxPin> embedded_hal::serial::Read<u8> for Serial<U, RxPin, TxPin>
194where
195 (RxPin, TxPin): Pins<U>,
196 RxPin: PinRx<U>,
197{
198 type Error = Error;
199
200 fn read(&mut self) -> nb::Result<u8, Self::Error> {
201 self.rx.read()
202 }
203}
204impl<U: ValidUart, RxPin, TxPin> embedded_hal::serial::Write<u8> for Serial<U, RxPin, TxPin>
205where
206 (RxPin, TxPin): Pins<U>,
207 TxPin: PinTx<U>,
208{
209 type Error = Error;
210
211 fn flush(&mut self) -> nb::Result<(), Self::Error> {
212 self.tx.flush()
213 }
214
215 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
216 self.tx.write(byte)
217 }
218}
219
220impl<U, RxPin, TxPin> fmt::Write for Serial<U, RxPin, TxPin>
221where
222 U: ValidUart,
223 (RxPin, TxPin): Pins<U>,
224 TxPin: PinTx<U>,
225{
226 fn write_str(&mut self, s: &str) -> fmt::Result {
227 use embedded_hal::serial::Write;
228 for &b in s.as_bytes() {
229 block!(self.write(b)).map_err(|_| core::fmt::Error)?;
230 }
231 Ok(())
232 }
233}
234impl<UART, P> fmt::Write for Tx<UART, P>
235where
236 Tx<UART, P>: embedded_hal::serial::Write<u8>,
237 P: PinTx<UART>,
238{
239 fn write_str(&mut self, s: &str) -> fmt::Result {
240 use embedded_hal::serial::Write;
241 for &b in s.as_bytes() {
242 block!(self.write(b)).map_err(|_| core::fmt::Error)?;
243 }
244 Ok(())
245 }
246}
247
248#[cfg(feature = "eh1-0-alpha")]
249mod eh1 {
250 use eh1_0_alpha::serial::ErrorKind;
251
252 use super::{Error, Rx, Serial, Tx};
253
254 impl eh1_0_alpha::serial::Error for Error {
255 fn kind(&self) -> ErrorKind {
256 match self {
257 Error::Overrun => ErrorKind::Overrun,
258 }
259 }
260 }
261
262 impl<UART, RxPin, TxPin> eh1_0_alpha::serial::ErrorType for Serial<UART, RxPin, TxPin> {
263 type Error = Error;
264 }
265 impl<UART, RxPin, TxPin> eh1_0_alpha::serial::nb::Read for Serial<UART, RxPin, TxPin>
267 where
268 Self: embedded_hal::serial::Read<u8, Error = Error>,
269 {
270 fn read(&mut self) -> nb::Result<u8, Self::Error> {
271 <Self as embedded_hal::serial::Read<_>>::read(self)
272 }
273 }
274 impl<UART, RxPin, TxPin> eh1_0_alpha::serial::nb::Write for Serial<UART, RxPin, TxPin>
275 where
276 Self: embedded_hal::serial::Write<u8, Error = Error>,
277 {
278 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
279 <Self as embedded_hal::serial::Write<u8>>::write(self, word)
280 }
281
282 fn flush(&mut self) -> nb::Result<(), Self::Error> {
283 <Self as embedded_hal::serial::Write<u8>>::flush(self)
284 }
285 }
286
287 impl<UART, RxPin, TxPin> eh1_0_alpha::serial::blocking::Write for Serial<UART, RxPin, TxPin>
289 where
290 Self: embedded_hal::serial::Write<u8, Error = Error>,
291 {
292 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
293 for &b in buffer {
294 nb::block!(<Self as eh1_0_alpha::serial::nb::Write>::write(self, b))?
295 }
296 Ok(())
297 }
298
299 fn flush(&mut self) -> Result<(), Self::Error> {
300 nb::block!(<Self as eh1_0_alpha::serial::nb::Write>::flush(self))
301 }
302 }
303
304 impl<UART, RxPin> eh1_0_alpha::serial::ErrorType for Rx<UART, RxPin> {
306 type Error = Error;
307 }
308 impl<UART, RxPin> eh1_0_alpha::serial::nb::Read for Rx<UART, RxPin>
309 where
310 Self: embedded_hal::serial::Read<u8, Error = Error>,
311 {
312 fn read(&mut self) -> nb::Result<u8, Self::Error> {
313 <Self as embedded_hal::serial::Read<_>>::read(self)
314 }
315 }
316 impl<UART, TxPin> eh1_0_alpha::serial::ErrorType for Tx<UART, TxPin> {
317 type Error = Error;
318 }
319 impl<UART, TxPin> eh1_0_alpha::serial::nb::Write for Tx<UART, TxPin>
320 where
321 Self: embedded_hal::serial::Write<u8, Error = Error>,
322 {
323 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
324 <Self as embedded_hal::serial::Write<u8>>::write(self, word)
325 }
326
327 fn flush(&mut self) -> nb::Result<(), Self::Error> {
328 <Self as embedded_hal::serial::Write<u8>>::flush(self)
329 }
330 }
331 impl<UART, TxPin> eh1_0_alpha::serial::blocking::Write for Tx<UART, TxPin>
332 where
333 Self: embedded_hal::serial::Write<u8, Error = Error>,
334 {
335 fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> {
336 for &b in buffer {
337 nb::block!(<Self as eh1_0_alpha::serial::nb::Write>::write(self, b))?
338 }
339 Ok(())
340 }
341
342 fn flush(&mut self) -> Result<(), Self::Error> {
343 nb::block!(<Self as eh1_0_alpha::serial::nb::Write>::flush(self))
344 }
345 }
346}