|
1 | 1 | //! # Serial Communication (USART)
|
| 2 | +//! |
2 | 3 | //! This module contains the functions to utilize the USART (Universal
|
3 | 4 | //! synchronous asynchronous receiver transmitter)
|
4 | 5 | //!
|
5 |
| -//! |
6 | 6 | //! ## Example usage:
|
| 7 | +//! |
7 | 8 | //! ```rust
|
8 | 9 | //! // prelude: create handles to the peripherals and registers
|
9 | 10 | //! let p = crate::pac::Peripherals::take().unwrap();
|
@@ -113,6 +114,16 @@ impl Pins<USART3> for (PD8<Alternate<PushPull>>, PD9<Input<Floating>>) {
|
113 | 114 | const REMAP: u8 = 0b11;
|
114 | 115 | }
|
115 | 116 |
|
| 117 | +/// Internal trait for the serial read / write logic. |
| 118 | +/// |
| 119 | +/// Note that reading / writing is done on the USART peripheral, not on the |
| 120 | +/// rx / tx pins! |
| 121 | +trait UsartReadWrite<Word> { |
| 122 | + fn read() -> nb::Result<Word, Error>; |
| 123 | + fn write(byte: Word) -> nb::Result<(), Infallible>; |
| 124 | + fn flush() -> nb::Result<(), Infallible>; |
| 125 | +} |
| 126 | + |
116 | 127 | pub enum Parity {
|
117 | 128 | ParityNone,
|
118 | 129 | ParityEven,
|
@@ -346,10 +357,8 @@ macro_rules! hal {
|
346 | 357 | }
|
347 | 358 | }
|
348 | 359 |
|
349 |
| - impl crate::hal::serial::Read<u8> for Rx<$USARTX> { |
350 |
| - type Error = Error; |
351 |
| - |
352 |
| - fn read(&mut self) -> nb::Result<u8, Error> { |
| 360 | + impl UsartReadWrite<u8> for $USARTX { |
| 361 | + fn read() -> nb::Result<u8, Error> { |
353 | 362 | // NOTE(unsafe) atomic read with no side effects
|
354 | 363 | let sr = unsafe { (*$USARTX::ptr()).sr.read() };
|
355 | 364 |
|
@@ -389,38 +398,74 @@ macro_rules! hal {
|
389 | 398 | }
|
390 | 399 | }
|
391 | 400 | }
|
392 |
| - } |
393 |
| - |
394 |
| - impl crate::hal::serial::Write<u8> for Tx<$USARTX> { |
395 |
| - type Error = Infallible; |
396 | 401 |
|
397 |
| - fn flush(&mut self) -> nb::Result<(), Self::Error> { |
| 402 | + fn write(byte: u8) -> nb::Result<(), Infallible> { |
398 | 403 | // NOTE(unsafe) atomic read with no side effects
|
399 | 404 | let sr = unsafe { (*$USARTX::ptr()).sr.read() };
|
400 | 405 |
|
401 |
| - if sr.tc().bit_is_set() { |
| 406 | + if sr.txe().bit_is_set() { |
| 407 | + // NOTE(unsafe) atomic write to stateless register |
| 408 | + // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API |
| 409 | + unsafe { |
| 410 | + ptr::write_volatile(&(*$USARTX::ptr()).dr as *const _ as *mut _, byte) |
| 411 | + } |
402 | 412 | Ok(())
|
403 | 413 | } else {
|
404 | 414 | Err(nb::Error::WouldBlock)
|
405 | 415 | }
|
406 | 416 | }
|
407 | 417 |
|
408 |
| - fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { |
| 418 | + fn flush() -> nb::Result<(), Infallible> { |
409 | 419 | // NOTE(unsafe) atomic read with no side effects
|
410 | 420 | let sr = unsafe { (*$USARTX::ptr()).sr.read() };
|
411 | 421 |
|
412 |
| - if sr.txe().bit_is_set() { |
413 |
| - // NOTE(unsafe) atomic write to stateless register |
414 |
| - // NOTE(write_volatile) 8-bit write that's not possible through the svd2rust API |
415 |
| - unsafe { |
416 |
| - ptr::write_volatile(&(*$USARTX::ptr()).dr as *const _ as *mut _, byte) |
417 |
| - } |
| 422 | + if sr.tc().bit_is_set() { |
418 | 423 | Ok(())
|
419 | 424 | } else {
|
420 | 425 | Err(nb::Error::WouldBlock)
|
421 | 426 | }
|
422 | 427 | }
|
423 | 428 | }
|
| 429 | + |
| 430 | + impl crate::hal::serial::Read<u8> for Rx<$USARTX> { |
| 431 | + type Error = Error; |
| 432 | + |
| 433 | + fn read(&mut self) -> nb::Result<u8, Error> { |
| 434 | + $USARTX::read() |
| 435 | + } |
| 436 | + } |
| 437 | + |
| 438 | + impl crate::hal::serial::Write<u8> for Tx<$USARTX> { |
| 439 | + type Error = Infallible; |
| 440 | + |
| 441 | + fn flush(&mut self) -> nb::Result<(), Self::Error> { |
| 442 | + $USARTX::flush() |
| 443 | + } |
| 444 | + fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { |
| 445 | + $USARTX::write(byte) |
| 446 | + } |
| 447 | + } |
| 448 | + |
| 449 | + impl<PINS> crate::hal::serial::Read<u8> for Serial<$USARTX, PINS> { |
| 450 | + type Error = Error; |
| 451 | + |
| 452 | + fn read(&mut self) -> nb::Result<u8, Error> { |
| 453 | + $USARTX::read() |
| 454 | + } |
| 455 | + } |
| 456 | + |
| 457 | + impl<PINS> crate::hal::serial::Write<u8> for Serial<$USARTX, PINS> { |
| 458 | + type Error = Infallible; |
| 459 | + |
| 460 | + fn flush(&mut self) -> nb::Result<(), Self::Error> { |
| 461 | + $USARTX::flush() |
| 462 | + } |
| 463 | + |
| 464 | + fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> { |
| 465 | + $USARTX::write(byte) |
| 466 | + } |
| 467 | + } |
| 468 | + |
424 | 469 | )+
|
425 | 470 | }
|
426 | 471 | }
|
|
0 commit comments