1use core::marker::PhantomData;
3use core::ops::Deref;
4
5use crate::gcr::{
6 clocks::{Clock, InternalBaudRateOscillator, PeripheralClock},
7 ClockForPeripheral,
8};
9use crate::gpio::{Af1, Pin};
10use embedded_hal_nb::{nb, serial};
11use paste::paste;
12
13enum UartClockSource {
14 Pclk,
15 Ibro,
16}
17
18pub enum DataBits {
20 Five,
22 Six,
24 Seven,
26 Eight,
28}
29
30pub enum StopBits {
32 One,
34 More,
37}
38
39pub enum ParityBit {
41 None,
43 Even,
52 Odd,
61 SpaceZero,
63 MarkOne,
65}
66
67#[doc(hidden)]
68pub mod marker {
69 pub trait UartState: crate::Sealed {}
71 #[doc(hidden)]
72 pub struct NotBuilt;
73 #[doc(hidden)]
74 pub struct Built;
75
76 impl crate::Sealed for NotBuilt {}
77 impl crate::Sealed for Built {}
78 impl UartState for NotBuilt {}
79 impl UartState for Built {}
80
81 pub trait UartClockState: crate::Sealed {}
83 #[doc(hidden)]
84 pub struct NotClockSet;
85 #[doc(hidden)]
86 pub struct ClockSet;
87 impl crate::Sealed for NotClockSet {}
88 impl crate::Sealed for ClockSet {}
89 impl UartClockState for NotClockSet {}
90 impl UartClockState for ClockSet {}
91}
92
93pub struct UartPeripheral<STATE: marker::UartState, CLOCK, UART, RX, TX, CTS, RTS> {
122 _state: PhantomData<STATE>,
123 _clock: PhantomData<CLOCK>,
124 uart: UART,
125 _rx_pin: RX,
126 _tx_pin: TX,
127 _cts_pin: CTS,
128 _rts_pin: RTS,
129 clk_src: Option<UartClockSource>,
130 clk_src_freq: Option<u32>,
131 baud: u32,
132 data_bits: DataBits,
133 stop_bits: StopBits,
134 parity: ParityBit,
135}
136
137pub struct BuiltUartPeripheral<UART, RX, TX, CTS, RTS> {
138 uart: UART,
139 _rx_pin: RX,
140 _tx_pin: TX,
141 _cts_pin: CTS,
142 _rts_pin: RTS,
143}
144
145pub trait RxPin<UART>: crate::Sealed {}
161pub trait TxPin<UART>: crate::Sealed {}
163
164type UartRegisterBlock = crate::pac::uart0::RegisterBlock;
170
171macro_rules! uart {
172 (
173 $uart:ident,
174 rx: $rx_pin:ty,
175 tx: $tx_pin:ty,
176 cts: $cts_pin:ty,
177 rts: $rts_pin:ty,
178 ) => {
179 paste! {
180 use crate::pac::$uart;
181
182 impl crate::Sealed for $rx_pin {}
183 impl RxPin<$uart> for $rx_pin {}
184
185 impl crate::Sealed for $tx_pin {}
186 impl TxPin<$uart> for $tx_pin {}
187
188 impl UartPeripheral<
189 marker::NotBuilt,
190 marker::NotClockSet,
191 $uart,
192 $rx_pin,
193 $tx_pin,
194 (),
197 (),
198 >
199 {
200 #[doc = "Construct a new "]
201 #[doc = stringify!([<$uart:upper>])]
202 #[doc = " peripheral."]
203 pub fn [<$uart:lower>](
204 uart: $uart,
205 reg: &mut crate::gcr::GcrRegisters,
206 rx_pin: $rx_pin,
207 tx_pin: $tx_pin
208 ) -> UartPeripheral<marker::NotBuilt, marker::NotClockSet, $uart, $rx_pin, $tx_pin, (), ()> {
209 unsafe { uart.enable_clock(&mut reg.gcr); }
211 UartPeripheral {
212 _state: PhantomData,
213 _clock: PhantomData,
214 uart,
215 _rx_pin: rx_pin,
216 _tx_pin: tx_pin,
217 _cts_pin: (),
218 _rts_pin: (),
219 clk_src: None,
220 clk_src_freq: None,
221 baud: 115200,
222 data_bits: DataBits::Eight,
223 stop_bits: StopBits::One,
224 parity: ParityBit::None,
225 }
226 }
227 }
228 }
229 };
230}
231
232uart! {Uart0,
233 rx: Pin<0, 0, Af1>,
234 tx: Pin<0, 1, Af1>,
235 cts: (),
236 rts: (),
237}
238
239uart! {Uart1,
240 rx: Pin<0, 12, Af1>,
241 tx: Pin<0, 13, Af1>,
242 cts: (),
243 rts: (),
244}
245
246uart! {Uart2,
247 rx: Pin<1, 0, Af1>,
248 tx: Pin<1, 1, Af1>,
249 cts: (),
250 rts: (),
251}
252
253impl<UART, RX, TX, CTS, RTS>
257 UartPeripheral<marker::NotBuilt, marker::NotClockSet, UART, RX, TX, CTS, RTS>
258{
259 pub fn clock_pclk(
261 self,
262 clock: &Clock<PeripheralClock>,
263 ) -> UartPeripheral<marker::NotBuilt, marker::ClockSet, UART, RX, TX, CTS, RTS> {
264 UartPeripheral {
265 _state: PhantomData,
266 _clock: PhantomData,
267 uart: self.uart,
268 _rx_pin: self._rx_pin,
269 _tx_pin: self._tx_pin,
270 _cts_pin: self._cts_pin,
271 _rts_pin: self._rts_pin,
272 clk_src: Some(UartClockSource::Pclk),
273 clk_src_freq: Some(clock.frequency),
274 baud: self.baud,
275 data_bits: self.data_bits,
276 stop_bits: self.stop_bits,
277 parity: self.parity,
278 }
279 }
280
281 pub fn clock_ibro(
283 self,
284 clock: &Clock<InternalBaudRateOscillator>,
285 ) -> UartPeripheral<marker::NotBuilt, marker::ClockSet, UART, RX, TX, CTS, RTS> {
286 UartPeripheral {
287 _state: PhantomData,
288 _clock: PhantomData,
289 uart: self.uart,
290 _rx_pin: self._rx_pin,
291 _tx_pin: self._tx_pin,
292 _cts_pin: self._cts_pin,
293 _rts_pin: self._rts_pin,
294 clk_src: Some(UartClockSource::Ibro),
295 clk_src_freq: Some(clock.frequency),
296 baud: self.baud,
297 data_bits: self.data_bits,
298 stop_bits: self.stop_bits,
299 parity: self.parity,
300 }
301 }
302}
303
304impl<CLOCK, UART, RX, TX, CTS, RTS> UartPeripheral<marker::NotBuilt, CLOCK, UART, RX, TX, CTS, RTS>
309where
310 UART: Deref<Target = UartRegisterBlock>,
311{
312 pub fn baud(mut self, baud: u32) -> Self {
316 self.baud = baud;
317 self
318 }
319
320 pub fn data_bits(mut self, data_bits: DataBits) -> Self {
324 self.data_bits = data_bits;
325 self
326 }
327
328 pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
332 self.stop_bits = stop_bits;
333 self
334 }
335
336 pub fn parity(mut self, parity: ParityBit) -> Self {
340 self.parity = parity;
341 self
342 }
343
344 }
370
371impl<UART, RX, TX, CTS, RTS>
372 UartPeripheral<marker::NotBuilt, marker::ClockSet, UART, RX, TX, CTS, RTS>
373where
374 UART: Deref<Target = UartRegisterBlock>,
375{
376 pub fn build(self) -> BuiltUartPeripheral<UART, RX, TX, CTS, RTS> {
379 let clk_src_freq = self.clk_src_freq.unwrap();
381 self.uart.ctrl().write(|w| {
382 w.ucagm().set_bit();
383 match self.clk_src {
384 Some(UartClockSource::Pclk) => w.bclksrc().peripheral_clock(),
385 Some(UartClockSource::Ibro) => w.bclksrc().clk2(),
386 None => unreachable!("UART clock source not set"),
387 };
388 w.bclken().set_bit();
389 match self.data_bits {
390 DataBits::Five => w.char_size()._5bits(),
391 DataBits::Six => w.char_size()._6bits(),
392 DataBits::Seven => w.char_size()._7bits(),
393 DataBits::Eight => w.char_size()._8bits(),
394 };
395 match self.stop_bits {
396 StopBits::One => w.stopbits().clear_bit(),
397 StopBits::More => w.stopbits().set_bit(),
398 };
399 match self.parity {
400 ParityBit::None => w.par_en().clear_bit(),
401 ParityBit::Even => w.par_en().set_bit().par_eo().clear_bit(),
402 ParityBit::Odd => w.par_en().set_bit().par_eo().set_bit(),
403 ParityBit::SpaceZero => w.par_en().set_bit().par_md().clear_bit(),
404 ParityBit::MarkOne => w.par_en().set_bit().par_md().set_bit(),
405 };
406 return w;
407 });
408 let clkdiv = clk_src_freq / self.baud;
410 self.uart
411 .clkdiv()
412 .write(|w| unsafe { w.clkdiv().bits(clkdiv) });
413 while self.uart.ctrl().read().bclkrdy().bit_is_clear() {}
415 BuiltUartPeripheral {
416 uart: self.uart,
417 _rx_pin: self._rx_pin,
418 _tx_pin: self._tx_pin,
419 _cts_pin: self._cts_pin,
420 _rts_pin: self._rts_pin,
421 }
422 }
423}
424
425impl<UART, RX, TX, CTS, RTS> BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
429where
430 UART: Deref<Target = UartRegisterBlock>,
431{
432 #[doc(hidden)]
433 #[inline(always)]
434 fn _is_tx_full(&self) -> bool {
435 self.uart.status().read().tx_full().bit_is_set()
436 }
437
438 #[doc(hidden)]
439 #[inline(always)]
440 fn _is_tx_empty(&self) -> bool {
441 self.uart.status().read().tx_em().bit_is_set()
442 }
443
444 #[doc(hidden)]
445 #[inline(always)]
446 fn _is_rx_empty(&self) -> bool {
447 self.uart.status().read().rx_em().bit_is_set()
448 }
449
450 #[doc(hidden)]
451 #[inline(always)]
452 fn _read_byte(&self) -> nb::Result<u8, serial::ErrorKind> {
453 if self._is_rx_empty() {
454 return Err(nb::Error::WouldBlock);
455 }
456 Ok(self.uart.fifo().read().data().bits())
457 }
458
459 #[doc(hidden)]
460 #[inline(always)]
461 fn _write_byte(&self, byte: u8) -> nb::Result<(), serial::ErrorKind> {
462 if self._is_tx_full() {
463 return Err(nb::Error::WouldBlock);
464 }
465 self.uart.fifo().write(|w| unsafe { w.data().bits(byte) });
466 Ok(())
467 }
468
469 #[inline(always)]
472 fn flush_tx(&self) {
473 while !self._is_tx_empty() {}
474 }
475
476 pub fn read_byte(&self) -> u8 {
478 nb::block!(self._read_byte()).unwrap()
479 }
480
481 pub fn write_byte(&self, byte: u8) {
483 nb::block!(self._write_byte(byte)).unwrap()
484 }
485
486 pub fn read_bytes(&self, buffer: &mut [u8]) {
490 for byte in buffer {
491 *byte = self.read_byte();
492 }
493 }
494
495 pub fn write_bytes(&self, buffer: &[u8]) {
498 for byte in buffer {
499 self.write_byte(*byte);
500 }
501 }
502}
503
504impl<UART, RX, TX, CTS, RTS> serial::ErrorType for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
506where
507 UART: Deref<Target = UartRegisterBlock>,
508{
509 type Error = serial::ErrorKind;
510}
511
512impl<UART, RX, TX, CTS, RTS> serial::Read<u8> for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
513where
514 UART: Deref<Target = UartRegisterBlock>,
515{
516 fn read(&mut self) -> nb::Result<u8, Self::Error> {
517 self._read_byte()
518 }
519}
520
521impl<UART, RX, TX, CTS, RTS> serial::Write<u8> for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
522where
523 UART: Deref<Target = UartRegisterBlock>,
524{
525 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
526 self._write_byte(byte)
527 }
528
529 fn flush(&mut self) -> nb::Result<(), Self::Error> {
530 self.flush_tx();
531 Ok(())
532 }
533}
534
535impl<UART, RX, TX, CTS, RTS> embedded_io::ErrorType for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
537where
538 UART: Deref<Target = UartRegisterBlock>,
539{
540 type Error = core::convert::Infallible;
541}
542
543impl<UART, RX, TX, CTS, RTS> embedded_io::Read for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
544where
545 UART: Deref<Target = UartRegisterBlock>,
546{
547 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
548 let mut count = 0;
549 if buf.len() == 0 {
550 return Ok(0);
551 }
552 if self._is_rx_empty() {
555 let byte = self.read_byte();
556 buf[count] = byte;
557 count += 1;
558 } else {
560 while count < buf.len() && !self._is_rx_empty() {
561 let byte = self.read_byte();
562 buf[count] = byte;
563 count += 1;
564 }
565 }
566 Ok(count)
567 }
568}
569
570impl<UART, RX, TX, CTS, RTS> embedded_io::ReadReady for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
571where
572 UART: Deref<Target = UartRegisterBlock>,
573{
574 fn read_ready(&mut self) -> Result<bool, Self::Error> {
575 Ok(!self._is_rx_empty())
576 }
577}
578
579impl<UART, RX, TX, CTS, RTS> embedded_io::Write for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
580where
581 UART: Deref<Target = UartRegisterBlock>,
582{
583 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
584 for byte in buf {
585 self.write_byte(*byte);
586 }
587 Ok(buf.len())
588 }
589
590 fn flush(&mut self) -> Result<(), Self::Error> {
591 self.flush_tx();
592 Ok(())
593 }
594}
595
596impl<UART, RX, TX, CTS, RTS> embedded_io::WriteReady for BuiltUartPeripheral<UART, RX, TX, CTS, RTS>
597where
598 UART: Deref<Target = UartRegisterBlock>,
599{
600 fn write_ready(&mut self) -> Result<bool, Self::Error> {
601 Ok(!self._is_tx_full())
602 }
603}