1use crate::prelude::*;
6use core::cmp::Ordering;
7use core::marker;
8
9use crate::port;
10
11#[derive(Debug, Clone, Copy)]
15pub struct Baudrate<CLOCK> {
16 pub ubrr: u16,
18 pub u2x: bool,
20 pub _clock: marker::PhantomData<CLOCK>,
23}
24
25impl<CLOCK: crate::clock::Clock> PartialEq for Baudrate<CLOCK> {
26 fn eq(&self, other: &Self) -> bool {
27 self.compare_value() == other.compare_value()
28 }
29}
30
31impl<CLOCK: crate::clock::Clock> Eq for Baudrate<CLOCK> {}
32
33impl<CLOCK: crate::clock::Clock> PartialOrd for Baudrate<CLOCK> {
34 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
35 Some(self.compare_value().cmp(&other.compare_value()))
36 }
37}
38
39impl<CLOCK: crate::clock::Clock> Ord for Baudrate<CLOCK> {
40 fn cmp(&self, other: &Self) -> Ordering {
41 other.compare_value().cmp(&self.compare_value())
42 }
43}
44
45impl<CLOCK: crate::clock::Clock> From<u32> for Baudrate<CLOCK> {
46 fn from(baud: u32) -> Self {
47 Baudrate::new(baud)
48 }
49}
50
51impl<CLOCK: crate::clock::Clock> Baudrate<CLOCK> {
52 pub fn new(baud: u32) -> Baudrate<CLOCK> {
54 let mut ubrr = (CLOCK::FREQ / 4 / baud - 1) / 2;
55 let mut u2x = true;
56 debug_assert!(ubrr <= u16::MAX as u32);
57 if ubrr > 4095 {
58 u2x = false;
59 ubrr = (CLOCK::FREQ / 8 / baud - 1) / 2;
60 }
61
62 Baudrate {
63 ubrr: ubrr as u16,
64 u2x,
65 _clock: marker::PhantomData,
66 }
67 }
68
69 pub fn with_exact(u2x: bool, ubrr: u16) -> Baudrate<CLOCK> {
73 Baudrate {
74 ubrr,
75 u2x,
76 _clock: marker::PhantomData,
77 }
78 }
79
80 fn compare_value(&self) -> u32 {
81 if self.u2x {
82 8 * (self.ubrr as u32 + 1)
83 } else {
84 16 * (self.ubrr as u32 + 1)
85 }
86 }
87}
88
89pub trait BaudrateExt {
104 fn into_baudrate<CLOCK: crate::clock::Clock>(self) -> Baudrate<CLOCK>;
106}
107
108impl BaudrateExt for u32 {
109 fn into_baudrate<CLOCK: crate::clock::Clock>(self) -> Baudrate<CLOCK> {
110 Baudrate::new(self)
111 }
112}
113
114pub trait BaudrateArduinoExt {
122 fn into_baudrate<CLOCK: crate::clock::Clock>(self) -> Baudrate<CLOCK>;
124}
125
126impl BaudrateArduinoExt for u32 {
127 fn into_baudrate<CLOCK: crate::clock::Clock>(self) -> Baudrate<CLOCK> {
128 let br = Baudrate::new(self);
129
130 if CLOCK::FREQ == 16_000_000 && br.ubrr == 34 && br.u2x {
136 Baudrate::with_exact(false, 16)
138 } else {
139 br
140 }
141 }
142}
143
144#[repr(u8)]
146pub enum Event {
147 RxComplete,
152
153 TxComplete,
158
159 DataRegisterEmpty,
164}
165
166pub trait UsartOps<H, RX, TX> {
172 fn raw_init<CLOCK>(&mut self, baudrate: Baudrate<CLOCK>);
176 fn raw_deinit(&mut self);
180
181 fn raw_flush(&mut self) -> nb::Result<(), core::convert::Infallible>;
188 fn raw_write(&mut self, byte: u8) -> nb::Result<(), core::convert::Infallible>;
195 fn raw_read(&mut self) -> nb::Result<u8, core::convert::Infallible>;
202
203 fn raw_interrupt(&mut self, event: Event, state: bool);
207}
208
209pub struct Usart<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> {
231 p: USART,
232 rx: RX,
233 tx: TX,
234 _clock: marker::PhantomData<CLOCK>,
235 _h: marker::PhantomData<H>,
236}
237
238impl<H, USART, RXPIN, TXPIN, CLOCK>
239 Usart<
240 H,
241 USART,
242 port::Pin<port::mode::Input, RXPIN>,
243 port::Pin<port::mode::Output, TXPIN>,
244 CLOCK,
245 >
246where
247 USART: UsartOps<H, port::Pin<port::mode::Input, RXPIN>, port::Pin<port::mode::Output, TXPIN>>,
248 RXPIN: port::PinOps,
249 TXPIN: port::PinOps,
250{
251 pub fn new<IMODE: port::mode::InputMode>(
256 p: USART,
257 rx: port::Pin<port::mode::Input<IMODE>, RXPIN>,
258 tx: port::Pin<port::mode::Output, TXPIN>,
259 baudrate: Baudrate<CLOCK>,
260 ) -> Self {
261 let mut usart = Self {
262 p,
263 rx: rx.forget_imode(),
264 tx,
265 _clock: marker::PhantomData,
266 _h: marker::PhantomData,
267 };
268 usart.p.raw_init(baudrate);
269 usart
270 }
271}
272
273impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> Usart<H, USART, RX, TX, CLOCK> {
274 pub fn release(mut self) -> (USART, RX, TX) {
276 self.p.raw_deinit();
277 (self.p, self.rx, self.tx)
278 }
279
280 pub fn flush(&mut self) {
282 nb::block!(self.p.raw_flush()).unwrap_infallible()
283 }
284
285 pub fn write_byte(&mut self, byte: u8) {
290 nb::block!(self.p.raw_write(byte)).unwrap_infallible()
291 }
292
293 pub fn read_byte(&mut self) -> u8 {
297 nb::block!(self.p.raw_read()).unwrap_infallible()
298 }
299
300 pub fn listen(&mut self, event: Event) {
302 self.p.raw_interrupt(event, true);
303 }
304
305 pub fn unlisten(&mut self, event: Event) {
307 self.p.raw_interrupt(event, false);
308 }
309
310 pub fn split(
314 self,
315 ) -> (
316 UsartReader<H, USART, RX, TX, CLOCK>,
317 UsartWriter<H, USART, RX, TX, CLOCK>,
318 ) {
319 (
320 UsartReader {
321 p: unsafe { core::ptr::read(&self.p) },
322 rx: self.rx,
323 _tx: marker::PhantomData,
324 _clock: marker::PhantomData,
325 _h: marker::PhantomData,
326 },
327 UsartWriter {
328 p: self.p,
329 tx: self.tx,
330 _rx: marker::PhantomData,
331 _clock: marker::PhantomData,
332 _h: marker::PhantomData,
333 },
334 )
335 }
336}
337
338impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite for Usart<H, USART, RX, TX, CLOCK> {
339 type Error = core::convert::Infallible;
340
341 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
342 for b in s.as_bytes().iter() {
343 self.write_byte(*b);
344 }
345 Ok(())
346 }
347}
348
349impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Write<u8>
350 for Usart<H, USART, RX, TX, CLOCK>
351{
352 type Error = core::convert::Infallible;
353
354 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
355 self.p.raw_write(byte)
356 }
357
358 fn flush(&mut self) -> nb::Result<(), Self::Error> {
359 self.p.raw_flush()
360 }
361}
362
363impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Read<u8>
364 for Usart<H, USART, RX, TX, CLOCK>
365{
366 type Error = core::convert::Infallible;
367
368 fn read(&mut self) -> nb::Result<u8, Self::Error> {
369 self.p.raw_read()
370 }
371}
372
373pub struct UsartWriter<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> {
381 p: USART,
382 tx: TX,
383 _rx: marker::PhantomData<RX>,
384 _clock: marker::PhantomData<CLOCK>,
385 _h: marker::PhantomData<H>,
386}
387
388pub struct UsartReader<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> {
395 p: USART,
396 rx: RX,
397 _tx: marker::PhantomData<TX>,
398 _clock: marker::PhantomData<CLOCK>,
399 _h: marker::PhantomData<H>,
400}
401
402impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartWriter<H, USART, RX, TX, CLOCK> {
403 pub fn reunite(
405 self,
406 other: UsartReader<H, USART, RX, TX, CLOCK>,
407 ) -> Usart<H, USART, RX, TX, CLOCK> {
408 Usart {
409 p: self.p,
410 rx: other.rx,
411 tx: self.tx,
412 _clock: marker::PhantomData,
413 _h: marker::PhantomData,
414 }
415 }
416}
417
418impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> UsartReader<H, USART, RX, TX, CLOCK> {
419 pub fn reunite(
421 self,
422 other: UsartWriter<H, USART, RX, TX, CLOCK>,
423 ) -> Usart<H, USART, RX, TX, CLOCK> {
424 Usart {
425 p: self.p,
426 rx: self.rx,
427 tx: other.tx,
428 _clock: marker::PhantomData,
429 _h: marker::PhantomData,
430 }
431 }
432}
433
434impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> ufmt::uWrite
435 for UsartWriter<H, USART, RX, TX, CLOCK>
436{
437 type Error = core::convert::Infallible;
438
439 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
440 for b in s.as_bytes().iter() {
441 nb::block!(self.p.raw_write(*b)).unwrap_infallible()
442 }
443 Ok(())
444 }
445}
446
447impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Write<u8>
448 for UsartWriter<H, USART, RX, TX, CLOCK>
449{
450 type Error = core::convert::Infallible;
451
452 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
453 self.p.raw_write(byte)
454 }
455
456 fn flush(&mut self) -> nb::Result<(), Self::Error> {
457 self.p.raw_flush()
458 }
459}
460
461impl<H, USART: UsartOps<H, RX, TX>, RX, TX, CLOCK> embedded_hal_v0::serial::Read<u8>
462 for UsartReader<H, USART, RX, TX, CLOCK>
463{
464 type Error = core::convert::Infallible;
465
466 fn read(&mut self) -> nb::Result<u8, Self::Error> {
467 self.p.raw_read()
468 }
469}
470
471#[macro_export]
472macro_rules! impl_usart_traditional {
473 (
474 hal: $HAL:ty,
475 peripheral: $USART:ty,
476 register_suffix: $n:expr,
477 rx: $rxpin:ty,
478 tx: $txpin:ty,
479 ) => {
480 $crate::paste::paste! {
481 impl $crate::usart::UsartOps<
482 $HAL,
483 $crate::port::Pin<$crate::port::mode::Input, $rxpin>,
484 $crate::port::Pin<$crate::port::mode::Output, $txpin>,
485 > for $USART {
486 fn raw_init<CLOCK>(&mut self, baudrate: $crate::usart::Baudrate<CLOCK>) {
487 self.[<ubrr $n>].write(|w| unsafe { w.bits(baudrate.ubrr) });
488 self.[<ucsr $n a>].write(|w| w.[<u2x $n>]().bit(baudrate.u2x));
489
490 self.[<ucsr $n b>].write(|w| w
492 .[<txen $n>]().set_bit()
493 .[<rxen $n>]().set_bit()
494 );
495
496 self.[<ucsr $n c>].write(|w| w
499 .[<umsel $n>]().usart_async()
500 .[<ucsz $n>]().chr8()
501 .[<usbs $n>]().stop1()
502 .[<upm $n>]().disabled()
503 );
504 }
505
506 fn raw_deinit(&mut self) {
507 $crate::nb::block!(self.raw_flush()).ok();
509 self.[<ucsr $n b>].reset();
510 }
511
512 fn raw_flush(&mut self) -> $crate::nb::Result<(), core::convert::Infallible> {
513 if self.[<ucsr $n a>].read().[<udre $n>]().bit_is_clear() {
514 Err($crate::nb::Error::WouldBlock)
515 } else {
516 Ok(())
517 }
518 }
519
520 fn raw_write(&mut self, byte: u8) -> $crate::nb::Result<(), core::convert::Infallible> {
521 self.raw_flush()?;
523
524 self.[<udr $n>].write(|w| unsafe { w.bits(byte) });
525 Ok(())
526 }
527
528 fn raw_read(&mut self) -> $crate::nb::Result<u8, core::convert::Infallible> {
529 if self.[<ucsr $n a>].read().[<rxc $n>]().bit_is_clear() {
530 return Err($crate::nb::Error::WouldBlock);
531 }
532
533 Ok(self.[<udr $n>].read().bits())
534 }
535
536 fn raw_interrupt(&mut self, event: $crate::usart::Event, state: bool) {
537 match event {
538 $crate::usart::Event::RxComplete =>
539 self.[<ucsr $n b>].modify(|_, w| w.[<rxcie $n>]().bit(state)),
540 $crate::usart::Event::TxComplete =>
541 self.[<ucsr $n b>].modify(|_, w| w.[<txcie $n>]().bit(state)),
542 $crate::usart::Event::DataRegisterEmpty =>
543 self.[<ucsr $n b>].modify(|_, w| w.[<udrie $n>]().bit(state)),
544 }
545 }
546 }
547 }
548 };
549}