1use core::convert::Infallible;
4use core::fmt;
5use core::marker::PhantomData;
6
7use crate::clock::Osc;
8use crate::pac::{UART1, UART2};
9use crate::pps::{input, output, IsConnected, MappedPin};
10
11use embedded_hal_0_2::prelude::*;
12use embedded_io::{ReadReady, WriteReady};
13use nb::block;
14
15pub struct Uart<UART, RX, TX> {
17    uart: UART,
18    rx: RX,
19    tx: TX,
20}
21
22pub struct Rx<UART> {
24    _uart: PhantomData<UART>,
25}
26
27pub struct Tx<UART> {
29    _uart: PhantomData<UART>,
30}
31
32#[derive(Debug, PartialEq, Eq, Clone, Copy)]
34pub enum ReadError {
35    Overrun,
37
38    Parity,
40
41    Framing,
43
44    Break,
46}
47
48#[derive(Debug, PartialEq, Eq, Clone)]
50pub struct Config {
51    pub baudrate: u32,
53
54    pub parity: Parity,
56
57    pub stopbits: StopBits,
59}
60
61impl Config {
62    pub const fn new(baudrate: u32, parity: Parity, stopbits: StopBits) -> Self {
64        Config {
65            baudrate,
66            parity,
67            stopbits,
68        }
69    }
70}
71
72pub const CONFIG_115200_8N1: Config = Config {
73    baudrate: 115200,
74    parity: Parity::None,
75    stopbits: StopBits::One,
76};
77
78#[derive(Debug, PartialEq, Eq, Clone, Copy)]
80pub enum Parity {
81    None = 0,
83
84    Even = 1,
86
87    Odd = 2,
89}
90
91#[derive(Debug, PartialEq, Eq, Clone, Copy)]
93pub enum StopBits {
94    One = 0,
96
97    Two = 1,
99}
100
101impl embedded_io::Error for ReadError {
102    fn kind(&self) -> embedded_io::ErrorKind {
103        embedded_io::ErrorKind::Other
104    }
105}
106
107macro_rules! uart_impl {
108    ($Id:ident, $Uart:ident, $Rx:ty, $Tx:ty) => {
109        impl<RX, TX> Uart<$Uart, MappedPin<RX, $Rx>, MappedPin<TX, $Tx>> {
110            pub fn $Id(
111                uart: $Uart,
112                osc: &Osc,
113                config: Config,
114                rx: MappedPin<RX, $Rx>,
115                tx: MappedPin<TX, $Tx>,
116            ) -> Uart<$Uart, MappedPin<RX, $Rx>, MappedPin<TX, $Tx>>
117            where
118                MappedPin<RX, $Rx>: IsConnected,
119                MappedPin<TX, $Tx>: IsConnected,
120            {
121                let brg = osc.pb_clock().0 / (4 * config.baudrate) - 1;
122                let has_rx = rx.is_connected();
123                let has_tx = tx.is_connected();
124                unsafe {
125                    uart.mode.write(|w| w.bits(0));
126                    uart.mode.write(|w| {
127                        w.brgh()
128                            .bit(true)
129                            .pdsel()
130                            .bits(config.parity as u8)
131                            .stsel()
132                            .bit(config.stopbits as u8 != 0)
133                    });
134                    uart.sta.write(|w| {
135                        w.urxen()
136                            .bit(has_rx)
137                            .utxen()
138                            .bit(has_tx)
139                            .urxisel()
140                            .bits(0b10)
141                    });
142                    uart.brg.write(|w| w.bits(brg));
143                    uart.modeset.write(|w| w.on().bit(true));
144                }
145                Uart { uart, rx, tx }
146            }
147
148            pub fn transmit_break(&mut self) {
150                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
151                tx.transmit_break();
152            }
153
154            pub fn free(self) -> ($Uart, MappedPin<RX, $Rx>, MappedPin<TX, $Tx>) {
155                unsafe { (*$Uart::ptr()).modeclr.write(|w| w.on().bit(true)) };
156                (self.uart, self.rx, self.tx)
157            }
158
159            pub fn split(self) -> (Tx<$Uart>, Rx<$Uart>) {
160                (Tx { _uart: PhantomData }, Rx { _uart: PhantomData })
161            }
162        }
163
164        impl Tx<$Uart> {
165            pub fn transmit_break(&mut self) {
167                let _ = embedded_io::Write::flush(self);
168                unsafe { (*$Uart::ptr()).staset.write(|w| w.utxbrk().bit(true)) };
169                let _ = embedded_io::Write::write_all(self, &[0]);
170            }
171        }
172
173        impl embedded_hal_0_2::serial::Write<u8> for Uart<$Uart, $Rx, $Tx> {
174            type Error = ();
175
176            fn flush(&mut self) -> nb::Result<(), Self::Error> {
177                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
178                tx.flush()
179            }
180
181            fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
182                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
183                tx.write(byte)
184            }
185        }
186
187        impl embedded_hal_0_2::serial::Write<u8> for Tx<$Uart> {
188            type Error = ();
189
190            fn flush(&mut self) -> nb::Result<(), Self::Error> {
191                let trmt = unsafe { (*$Uart::ptr()).sta.read().trmt().bit() };
192                if trmt {
193                    Err(nb::Error::WouldBlock)
194                } else {
195                    Ok(())
196                }
197            }
198
199            fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
200                let utxbf = unsafe { (*$Uart::ptr()).sta.read().utxbf().bit() };
201                if utxbf {
202                    Err(nb::Error::WouldBlock)
203                } else {
204                    unsafe {
205                        (*$Uart::ptr()).txreg.write(|w| w.txreg().bits(byte as u16));
206                    }
207                    Ok(())
208                }
209            }
210        }
211
212        impl embedded_hal_0_2::serial::Read<u8> for Uart<$Uart, $Rx, $Tx> {
213            type Error = ();
214
215            fn read(&mut self) -> nb::Result<u8, Self::Error> {
216                let mut rx: Rx<$Uart> = Rx { _uart: PhantomData };
217                rx.read()
218            }
219        }
220
221        impl embedded_hal_0_2::serial::Read<u8> for Rx<$Uart> {
222            type Error = ();
223
224            fn read(&mut self) -> nb::Result<u8, Self::Error> {
225                let data_avail = unsafe { (*$Uart::ptr()).sta.read().urxda().bit() };
226                let result = if !data_avail {
227                    Err(nb::Error::WouldBlock)
228                } else {
229                    unsafe { Ok((*$Uart::ptr()).rxreg.read().rxreg().bits() as u8) }
230                };
231                let overrun = unsafe { (*$Uart::ptr()).sta.read().oerr().bit() };
232                if overrun {
233                    unsafe { (*$Uart::ptr()).staclr.write(|w| w.oerr().bit(true)) }
234                }
235                result
236            }
237        }
238
239        impl embedded_io::ErrorType for Tx<$Uart> {
240            type Error = Infallible;
241        }
242
243        impl embedded_io::WriteReady for Tx<$Uart> {
244            fn write_ready(&mut self) -> Result<bool, Self::Error> {
245                let utxbf = unsafe { (*$Uart::ptr()).sta.read().utxbf().bit() };
246                Ok(!utxbf)
247            }
248        }
249
250        impl embedded_io::Write for Tx<$Uart> {
251            fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
252                while !self.write_ready()? {}
253                let mut len = 0;
254                for byte in buf {
255                    if !self.write_ready()? {
256                        break;
257                    }
258                    unsafe {
259                        (*$Uart::ptr())
260                            .txreg
261                            .write(|w| w.txreg().bits(*byte as u16));
262                    }
263                    len += 1;
264                }
265                Ok(len)
266            }
267
268            fn flush(&mut self) -> Result<(), Self::Error> {
269                loop {
270                    let trmt = unsafe { (*$Uart::ptr()).sta.read().trmt().bit() };
271                    if trmt {
272                        break;
273                    }
274                }
275                Ok(())
276            }
277        }
278
279        impl embedded_io::ErrorType for Rx<$Uart> {
280            type Error = ReadError;
281        }
282
283        impl embedded_io::ReadReady for Rx<$Uart> {
284            fn read_ready(&mut self) -> Result<bool, Self::Error> {
285                let data_avail = unsafe { (*$Uart::ptr()).sta.read().urxda().bit() };
286                Ok(data_avail)
287            }
288        }
289
290        impl embedded_io::Read for Rx<$Uart> {
291            fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
292                if buf.is_empty() {
293                    return Ok(0);
294                }
295
296                if unsafe { (*$Uart::ptr()).sta.read().oerr().bit() } {
298                    unsafe {
300                        (*$Uart::ptr()).staclr.write(|w| w.oerr().bit(true));
301                    }
302                    return Err(ReadError::Overrun);
303                }
304
305                while !self.read_ready()? {}
307
308                let mut len = 0;
310                for bufbyte in buf {
311                    if !self.read_ready()? {
312                        break;
313                    }
314                    if unsafe { (*$Uart::ptr()).sta.read().ferr().bit() } {
316                        let word = unsafe { (*$Uart::ptr()).rxreg.read().bits() };
317                        if word == 0 {
318                            return Err(ReadError::Break);
319                        } else {
320                            return Err(ReadError::Framing);
321                        }
322                    }
323                    if unsafe { (*$Uart::ptr()).sta.read().perr().bit() } {
325                        let _skip = unsafe { (*$Uart::ptr()).rxreg.read().bits() };
326                        return Err(ReadError::Parity);
327                    }
328                    *bufbyte = unsafe { (*$Uart::ptr()).rxreg.read().bits() } as u8;
329                    len += 1;
330                }
331                Ok(len)
332            }
333        }
334
335        impl<RX, TX> embedded_io::ErrorType for Uart<$Uart, RX, TX> {
336            type Error = ReadError;
337        }
338
339        impl<RX, TX> embedded_io::WriteReady for Uart<$Uart, RX, TX> {
340            fn write_ready(&mut self) -> Result<bool, Self::Error> {
341                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
342                Ok(tx.write_ready().unwrap_or(false))
343            }
344        }
345
346        impl<RX, TX> embedded_io::Write for Uart<$Uart, RX, TX> {
347            fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
348                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
349                Ok(embedded_io::Write::write(&mut tx, buf).unwrap_or(0))
350            }
351
352            fn flush(&mut self) -> Result<(), Self::Error> {
353                let mut tx: Tx<$Uart> = Tx { _uart: PhantomData };
354                let _ = embedded_io::Write::flush(&mut tx);
355                Ok(())
356            }
357        }
358
359        impl<RX, TX> embedded_io::ReadReady for Uart<$Uart, RX, TX> {
360            fn read_ready(&mut self) -> Result<bool, Self::Error> {
361                let mut rx: Rx<$Uart> = Rx { _uart: PhantomData };
362                rx.read_ready()
363            }
364        }
365
366        impl<RX, TX> embedded_io::Read for Uart<$Uart, RX, TX> {
367            fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
368                let mut rx: Rx<$Uart> = Rx { _uart: PhantomData };
369                embedded_io::Read::read(&mut rx, buf)
370            }
371        }
372    };
373}
374
375uart_impl!(uart1, UART1, input::U1rx, output::U1tx);
376uart_impl!(uart2, UART2, input::U2rx, output::U2tx);
377
378impl<UART> fmt::Write for Tx<UART>
379where
380    Tx<UART>: embedded_hal_0_2::serial::Write<u8>,
381{
382    fn write_str(&mut self, s: &str) -> fmt::Result {
383        let _ = s.as_bytes().iter().map(|c| block!(self.write(*c))).last();
384        Ok(())
385    }
386}