From beb1e56003a0bc71ae461a32bfd17c30cfaff8a1 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Sun, 15 May 2022 06:11:45 +0200 Subject: [PATCH] Allow re-combining TX/RX pair to serial port. --- src/serial.rs | 106 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/src/serial.rs b/src/serial.rs index 493d9ec5..836ca582 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -206,20 +206,20 @@ impl From for Config { /// Serial abstraction pub struct Serial { - usart: USART, - pins: PINS, - tx: Tx, - rx: Rx, + tx: Tx, + rx: Rx, } /// Serial receiver -pub struct Rx { +pub struct Rx { _usart: PhantomData, + pins: PINS, } /// Serial transmitter -pub struct Tx { - _usart: PhantomData, +pub struct Tx { + usart: USART, + pins: PhantomData, } macro_rules! hal { @@ -375,29 +375,33 @@ macro_rules! hal { .modify(|_, w| w.ue().set_bit().re().set_bit().te().set_bit()); Serial { - usart, pins, - tx: Tx { _usart: PhantomData }, - rx: Rx { _usart: PhantomData }, + tx: Tx { usart, pins: PhantomData }, + rx: Rx { _usart: PhantomData, pins }, } } + #[inline] + fn usart(&self) -> &pac::$USARTX { + &self.tx.usart + } + /// Starts listening for an interrupt event pub fn listen(&mut self, event: Event) { match event { Event::Rxne => { - self.usart.cr1.modify(|_, w| w.rxneie().set_bit()) + self.usart().cr1.modify(|_, w| w.rxneie().set_bit()) }, Event::Txe => { - self.usart.cr1.modify(|_, w| w.txeie().set_bit()) + self.usart().cr1.modify(|_, w| w.txeie().set_bit()) }, Event::Idle => { - self.usart.cr1.modify(|_, w| w.idleie().set_bit()) + self.usart().cr1.modify(|_, w| w.idleie().set_bit()) }, Event::CharacterMatch => { - self.usart.cr1.modify(|_, w| w.cmie().set_bit()) + self.usart().cr1.modify(|_, w| w.cmie().set_bit()) }, Event::ReceiverTimeout => { - self.usart.cr1.modify(|_, w| w.rtoie().set_bit()) + self.usart().cr1.modify(|_, w| w.rtoie().set_bit()) }, } } @@ -434,25 +438,25 @@ macro_rules! hal { pub fn unlisten(&mut self, event: Event) { match event { Event::Rxne => { - self.usart.cr1.modify(|_, w| w.rxneie().clear_bit()) + self.usart().cr1.modify(|_, w| w.rxneie().clear_bit()) }, Event::Txe => { - self.usart.cr1.modify(|_, w| w.txeie().clear_bit()) + self.usart().cr1.modify(|_, w| w.txeie().clear_bit()) }, Event::Idle => { - self.usart.cr1.modify(|_, w| w.idleie().clear_bit()) + self.usart().cr1.modify(|_, w| w.idleie().clear_bit()) }, Event::CharacterMatch => { - self.usart.cr1.modify(|_, w| w.cmie().clear_bit()) + self.usart().cr1.modify(|_, w| w.cmie().clear_bit()) }, Event::ReceiverTimeout => { - self.usart.cr1.modify(|_, w| w.rtoie().clear_bit()) + self.usart().cr1.modify(|_, w| w.rtoie().clear_bit()) }, } } /// Splits the `Serial` abstraction into a transmitter and a receiver half - pub fn split(self) -> (Tx, Rx) { + pub fn split(self) -> (Tx, Rx) { ( self.tx, self.rx, @@ -461,7 +465,7 @@ macro_rules! hal { /// Frees the USART peripheral pub fn release(self) -> (pac::$USARTX, PINS) { - (self.usart, self.pins) + (self.tx.usart, self.rx.pins) } } @@ -473,7 +477,7 @@ macro_rules! hal { } } - impl serial::Read for Rx { + impl serial::Read for Rx { type Error = Error; fn read(&mut self) -> nb::Result { @@ -505,7 +509,7 @@ macro_rules! hal { } } - impl serial::Write for Tx { + impl serial::Write for Tx { // NOTE(Void) See section "29.7 USART interrupts"; the only possible errors during // transmission are: clear to send (which is disabled in this case) errors and // framing errors (which only occur in SmartCard mode); neither of these apply to @@ -540,23 +544,22 @@ macro_rules! hal { } } - impl embedded_hal::blocking::serial::write::Default - for Tx {} + impl embedded_hal::blocking::serial::write::Default for Tx {} - pub type $rxdma = RxDma, $dmarxch>; - pub type $txdma = TxDma, $dmatxch>; + pub type $rxdma = RxDma, $dmarxch>; + pub type $txdma = TxDma, $dmatxch>; - impl Receive for $rxdma { + impl Receive for $rxdma { type RxChannel = $dmarxch; type TransmittedWord = u8; } - impl Transmit for $txdma { + impl Transmit for $txdma { type TxChannel = $dmatxch; type ReceivedWord = u8; } - impl TransferPayload for $rxdma { + impl TransferPayload for $rxdma { fn start(&mut self) { self.channel.start(); } @@ -565,7 +568,7 @@ macro_rules! hal { } } - impl TransferPayload for $txdma { + impl TransferPayload for $txdma { fn start(&mut self) { self.channel.start(); } @@ -574,8 +577,8 @@ macro_rules! hal { } } - impl Rx { - pub fn with_dma(self, channel: $dmarxch) -> $rxdma { + impl Rx { + pub fn with_dma(self, channel: $dmarxch) -> $rxdma { RxDma { payload: self, channel, @@ -643,7 +646,7 @@ macro_rules! hal { } } - impl crate::dma::CharacterMatch for Rx { + impl crate::dma::CharacterMatch for Rx { /// Checks to see if the USART peripheral has detected an character match and /// clears the flag fn check_character_match(&mut self, clear: bool) -> bool { @@ -651,20 +654,20 @@ macro_rules! hal { } } - impl crate::dma::ReceiverTimeout for Rx { + impl crate::dma::ReceiverTimeout for Rx { fn check_receiver_timeout(&mut self, clear: bool) -> bool { self.is_receiver_timeout(clear) } } - impl crate::dma::OperationError<(), Error> for Rx{ + impl crate::dma::OperationError<(), Error> for Rx { fn check_operation_error(&mut self) -> Result<(), Error> { self.check_for_error() } } - impl Tx { - pub fn with_dma(self, channel: $dmatxch) -> $txdma { + impl Tx { + pub fn with_dma(self, channel: $dmatxch) -> $txdma { TxDma { payload: self, channel, @@ -672,8 +675,8 @@ macro_rules! hal { } } - impl $rxdma { - pub fn split(mut self) -> (Rx, $dmarxch) { + impl $rxdma { + pub fn split(mut self) -> (Rx, $dmarxch) { self.stop(); let RxDma {payload, channel} = self; ( @@ -683,8 +686,8 @@ macro_rules! hal { } } - impl $txdma { - pub fn split(mut self) -> (Tx, $dmatxch) { + impl $txdma { + pub fn split(mut self) -> (Tx, $dmatxch) { self.stop(); let TxDma {payload, channel} = self; ( @@ -694,7 +697,7 @@ macro_rules! hal { } } - impl crate::dma::CircReadDma for $rxdma + impl crate::dma::CircReadDma for $rxdma where &'static mut B: StaticWriteBuffer, B: 'static, @@ -746,7 +749,7 @@ macro_rules! hal { } } - impl $rxdma { + impl $rxdma { /// Create a frame reader that can either react on the Character match interrupt or /// Transfer Complete from the DMA. pub fn frame_reader( @@ -796,7 +799,7 @@ macro_rules! hal { } } - impl $txdma { + impl $txdma { /// Creates a new DMA frame sender pub fn frame_sender( mut self, @@ -836,6 +839,13 @@ macro_rules! hal { } } +impl From<(Tx, Rx)> for Serial { + /// Convert a transmitter/receiver back to a combined serial port. + fn from((tx, rx): (Tx, Rx)) -> Self { + Self { tx, rx } + } +} + hal! { USART1: (usart1, pclk2, tx: (TxDma1, dma1::C4, DmaInput::Usart1Tx), rx: (RxDma1, dma1::C5, DmaInput::Usart1Rx)), USART2: (usart2, pclk1, tx: (TxDma2, dma1::C7, DmaInput::Usart2Tx), rx: (RxDma2, dma1::C6, DmaInput::Usart2Rx)), @@ -905,9 +915,9 @@ where } } -impl fmt::Write for Tx +impl fmt::Write for Tx where - Tx: crate::hal::serial::Write, + Tx: crate::hal::serial::Write, { fn write_str(&mut self, s: &str) -> fmt::Result { let _ = s