1use crate::clock::Clocks;
5use crate::pac;
6use core::fmt;
7use embedded_hal::serial::nb::Read as ReadOne;
8use embedded_hal::serial::nb::Write as WriteOne;
9use embedded_time::rate::{Baud, Extensions};
10use nb::block;
11
12#[derive(Debug)]
14#[non_exhaustive]
15pub enum Error {
16 Framing,
18 Noise,
20 Overrun,
22 Parity,
24}
25
26#[derive(Copy, Clone, Debug, PartialEq)]
28pub struct Config {
29 pub baudrate: Baud,
30 pub order: Order,
31 pub parity: Parity,
32 pub stopbits: StopBits,
33 pub wordlength: WordLength,
34}
35
36impl Config {
37 pub fn baudrate(mut self, baudrate: impl Into<Baud>) -> Self {
39 self.baudrate = baudrate.into();
40
41 self
42 }
43
44 pub fn parity_none(mut self) -> Self {
46 self.parity = Parity::ParityNone;
47
48 self
49 }
50
51 pub fn parity_even(mut self) -> Self {
53 self.parity = Parity::ParityEven;
54
55 self
56 }
57
58 pub fn parity_odd(mut self) -> Self {
60 self.parity = Parity::ParityOdd;
61
62 self
63 }
64
65 pub fn stopbits(mut self, stopbits: StopBits) -> Self {
67 self.stopbits = stopbits;
68
69 self
70 }
71}
72
73impl Default for Config {
74 fn default() -> Config {
75 Config {
76 baudrate: 115_200_u32.Bd(),
77 order: Order::LsbFirst,
78 parity: Parity::ParityNone,
79 stopbits: StopBits::STOP1,
80 wordlength: WordLength::Eight,
81 }
82 }
83}
84
85#[derive(Debug, Copy, Clone, Eq, PartialEq)]
87pub enum Order {
88 LsbFirst,
90 MsbFirst,
92}
93
94#[derive(Copy, Clone, Debug, PartialEq, Eq)]
96pub enum Parity {
97 ParityNone,
99 ParityEven,
101 ParityOdd,
103}
104
105#[derive(Copy, Clone, Debug, PartialEq, Eq)]
107pub enum StopBits {
108 STOP1,
110 STOP0P5,
112 STOP2,
114 STOP1P5,
116}
117
118#[derive(Copy, Clone, Debug, PartialEq, Eq)]
120pub enum WordLength {
121 Five,
122 Six,
123 Seven,
124 Eight,
125}
126
127pub enum Event {
129 RxFifoError,
131 TxFifoError,
133 RxParityError,
135 RxTimeout,
137 RxFifoReady,
139 TxFifoReady,
141 RxTransferEnd,
143 TxTransferEnd,
145}
146
147pub struct Serial<UART, PINS> {
149 uart: UART,
150 pins: PINS,
151}
152
153impl<PINS> Serial<pac::UART, PINS>
154where
155 PINS: Pins<pac::UART>,
156{
157 pub fn uart0(uart: pac::UART, config: Config, pins: PINS, _clocks: Clocks) -> Self {
160 let divisor = 48; uart.utx_config.modify(|_, w| w.cr_utx_en().clear_bit());
167 uart.urx_config.modify(|_, w| w.cr_urx_en().clear_bit());
168
169 uart.uart_bit_prd.write(|w| unsafe {
170 w.cr_urx_bit_prd()
171 .bits(divisor - 1)
172 .cr_utx_bit_prd()
173 .bits(divisor - 1)
174 });
175
176 let order_cfg = match config.order {
178 Order::LsbFirst => false,
179 Order::MsbFirst => true,
180 };
181
182 uart.data_config
183 .write(|w| w.cr_uart_bit_inv().bit(order_cfg));
184
185 let data_bits_cfg = match config.wordlength {
187 WordLength::Five => 4,
188 WordLength::Six => 5,
189 WordLength::Seven => 6,
190 WordLength::Eight => 7,
191 };
192 let stop_bits_cfg = match config.stopbits {
193 StopBits::STOP0P5 => 0,
194 StopBits::STOP1 => 1,
195 StopBits::STOP1P5 => 2,
196 StopBits::STOP2 => 3,
197 };
198 let (parity_enable, parity_type) = match config.parity {
199 Parity::ParityNone => (false, false),
200 Parity::ParityEven => (true, false), Parity::ParityOdd => (true, true), };
203
204 uart.utx_config.write(|w| unsafe {
205 w.cr_utx_prt_en().bit(parity_enable);
206 w.cr_utx_prt_sel().bit(parity_type);
207 w.cr_utx_bit_cnt_d().bits(data_bits_cfg);
208 w.cr_utx_bit_cnt_p().bits(stop_bits_cfg);
209 w.cr_utx_frm_en().set_bit(); w.cr_utx_cts_en().bit(false); w
212 });
213 uart.utx_config
214 .modify(|_, w| w.cr_utx_en().bit(PINS::HAS_TX));
215
216 uart.urx_config.write(|w| unsafe {
218 w.cr_urx_prt_en().bit(parity_enable);
219 w.cr_urx_prt_sel().bit(parity_type);
220 w.cr_urx_bit_cnt_d().bits(data_bits_cfg);
221 w.cr_urx_deg_en().clear_bit();
222 w.cr_urx_en().bit(PINS::HAS_RX);
226 w
227 });
228
229 uart.urx_config
230 .modify(|_, w| unsafe { w.cr_urx_deg_cnt().bits(15) });
231
232 Serial { uart, pins }
233 }
234
235 pub fn free(self) -> (pac::UART, PINS) {
236 (self.uart, self.pins)
238 }
239}
240
241impl<PINS> embedded_hal::serial::nb::Write<u8> for Serial<pac::UART, PINS> {
242 type Error = Error;
243
244 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
245 if self.uart.uart_fifo_config_1.read().tx_fifo_cnt().bits() == 0 {
247 Err(nb::Error::WouldBlock)
248 } else {
249 self.uart
250 .uart_fifo_wdata
251 .write(|w| unsafe { w.bits(word as u32) });
252 Ok(())
253 }
254 }
255
256 fn flush(&mut self) -> nb::Result<(), Self::Error> {
257 if self.uart.uart_fifo_config_1.read().tx_fifo_cnt().bits() != 32
259 || self.uart.uart_status.read().sts_utx_bus_busy().bit_is_set()
260 {
261 Err(nb::Error::WouldBlock)
262 } else {
263 Ok(())
264 }
265 }
266}
267
268impl<PINS> embedded_hal::serial::nb::Read<u8> for Serial<pac::UART, PINS> {
269 type Error = Error;
270
271 fn read(&mut self) -> nb::Result<u8, Self::Error> {
272 if self.uart.uart_fifo_config_1.read().rx_fifo_cnt().bits() == 0 {
273 Err(nb::Error::WouldBlock)
274 } else {
275 let ans = self.uart.uart_fifo_rdata.read().bits();
276 Ok((ans & 0xff) as u8)
277 }
278 }
279}
280
281impl<PINS> embedded_hal_zero::serial::Write<u8> for Serial<pac::UART, PINS> {
282 type Error = Error;
283
284 fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
285 WriteOne::write(self, word)
286 }
287
288 fn flush(&mut self) -> nb::Result<(), Self::Error> {
289 WriteOne::flush(self)
290 }
291}
292
293impl<PINS> embedded_hal_zero::serial::Read<u8> for Serial<pac::UART, PINS> {
294 type Error = Error;
295
296 fn read(&mut self) -> nb::Result<u8, Self::Error> {
297 ReadOne::read(self)
298 }
299}
300
301impl<UART, PINS> fmt::Write for Serial<UART, PINS>
302where
303 Serial<UART, PINS>: embedded_hal::serial::nb::Write<u8>,
304{
305 fn write_str(&mut self, s: &str) -> fmt::Result {
306 s.as_bytes()
307 .iter()
308 .try_for_each(|c| block!(self.write(*c)))
309 .map_err(|_| fmt::Error)
310 }
311}
312
313pub unsafe trait TxPin<UART> {}
316pub unsafe trait RxPin<UART> {}
318pub unsafe trait RtsPin<UART> {}
320pub unsafe trait CtsPin<UART> {}
322
323macro_rules! impl_uart_pin {
324 ($(($UartSigi: ident, $UartMuxi: ident),)+) => {
325 use crate::gpio::*;
326 $(
327 unsafe impl<PIN: UartPin<$UartSigi>> TxPin<pac::UART> for (PIN, $UartMuxi<Uart0Tx>) {}
328 unsafe impl<PIN: UartPin<$UartSigi>> RxPin<pac::UART> for (PIN, $UartMuxi<Uart0Rx>) {}
329 unsafe impl<PIN: UartPin<$UartSigi>> RtsPin<pac::UART> for (PIN, $UartMuxi<Uart0Rts>) {}
330 unsafe impl<PIN: UartPin<$UartSigi>> CtsPin<pac::UART> for (PIN, $UartMuxi<Uart0Cts>) {}
331 )+
332 };
333}
334
335impl_uart_pin!(
336 (UartSig0, UartMux0),
337 (UartSig1, UartMux1),
338 (UartSig2, UartMux2),
339 (UartSig3, UartMux3),
340 (UartSig4, UartMux4),
341 (UartSig5, UartMux5),
342 (UartSig6, UartMux6),
343 (UartSig7, UartMux7),
344);
345
346pub unsafe trait Pins<UART> {
349 const HAS_TX: bool;
350 const HAS_RX: bool;
351 const HAS_RTS: bool;
352 const HAS_CTS: bool;
353}
354
355unsafe impl<UART, TX, RX> Pins<UART> for (TX, RX)
356where
357 TX: TxPin<UART>,
358 RX: RxPin<UART>,
359{
360 const HAS_TX: bool = true;
361 const HAS_RX: bool = true;
362 const HAS_RTS: bool = false;
363 const HAS_CTS: bool = false;
364}
365
366unsafe impl<UART, TX, RX, RTS, CTS> Pins<UART> for (TX, RX, RTS, CTS)
367where
368 TX: TxPin<UART>,
369 RX: RxPin<UART>,
370 RTS: RxPin<UART>,
371 CTS: RxPin<UART>,
372{
373 const HAS_TX: bool = true;
374 const HAS_RX: bool = true;
375 const HAS_RTS: bool = true;
376 const HAS_CTS: bool = true;
377}