Merge pull request #3500 from KennethKnudsen97/main

Add split_ref for stm32 uart
This commit is contained in:
Dario Nieuwenhuis 2024-11-06 17:08:16 +00:00 committed by GitHub
commit dbba791795
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 23 deletions

View File

@ -157,6 +157,7 @@ pub struct BufferedUartTx<'d> {
tx: Option<PeripheralRef<'d, AnyPin>>, tx: Option<PeripheralRef<'d, AnyPin>>,
cts: Option<PeripheralRef<'d, AnyPin>>, cts: Option<PeripheralRef<'d, AnyPin>>,
de: Option<PeripheralRef<'d, AnyPin>>, de: Option<PeripheralRef<'d, AnyPin>>,
is_borrowed: bool,
} }
/// Rx-only buffered UART /// Rx-only buffered UART
@ -168,6 +169,7 @@ pub struct BufferedUartRx<'d> {
kernel_clock: Hertz, kernel_clock: Hertz,
rx: Option<PeripheralRef<'d, AnyPin>>, rx: Option<PeripheralRef<'d, AnyPin>>,
rts: Option<PeripheralRef<'d, AnyPin>>, rts: Option<PeripheralRef<'d, AnyPin>>,
is_borrowed: bool,
} }
impl<'d> SetConfig for BufferedUart<'d> { impl<'d> SetConfig for BufferedUart<'d> {
@ -341,6 +343,7 @@ impl<'d> BufferedUart<'d> {
kernel_clock, kernel_clock,
rx, rx,
rts, rts,
is_borrowed: false,
}, },
tx: BufferedUartTx { tx: BufferedUartTx {
info, info,
@ -349,6 +352,7 @@ impl<'d> BufferedUart<'d> {
tx, tx,
cts, cts,
de, de,
is_borrowed: false,
}, },
}; };
this.enable_and_configure(tx_buffer, rx_buffer, &config)?; this.enable_and_configure(tx_buffer, rx_buffer, &config)?;
@ -396,6 +400,31 @@ impl<'d> BufferedUart<'d> {
(self.tx, self.rx) (self.tx, self.rx)
} }
/// Split the Uart into a transmitter and receiver,
/// which is particularly useful when having two tasks correlating to
/// transmitting and receiving.
pub fn split_ref(&mut self) -> (BufferedUartTx<'_>, BufferedUartRx<'_>) {
(
BufferedUartTx {
info: self.tx.info,
state: self.tx.state,
kernel_clock: self.tx.kernel_clock,
tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow),
cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow),
de: self.tx.de.as_mut().map(PeripheralRef::reborrow),
is_borrowed: true,
},
BufferedUartRx {
info: self.rx.info,
state: self.rx.state,
kernel_clock: self.rx.kernel_clock,
rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow),
rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow),
is_borrowed: true,
},
)
}
/// Reconfigure the driver /// Reconfigure the driver
pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> { pub fn set_config(&mut self, config: &Config) -> Result<(), ConfigError> {
reconfigure(self.rx.info, self.rx.kernel_clock, config)?; reconfigure(self.rx.info, self.rx.kernel_clock, config)?;
@ -600,40 +629,44 @@ impl<'d> BufferedUartTx<'d> {
impl<'d> Drop for BufferedUartRx<'d> { impl<'d> Drop for BufferedUartRx<'d> {
fn drop(&mut self) { fn drop(&mut self) {
let state = self.state; if !self.is_borrowed {
unsafe { let state = self.state;
state.rx_buf.deinit(); unsafe {
state.rx_buf.deinit();
// TX is inactive if the the buffer is not available. // TX is inactive if the the buffer is not available.
// We can now unregister the interrupt handler // We can now unregister the interrupt handler
if state.tx_buf.len() == 0 { if state.tx_buf.len() == 0 {
self.info.interrupt.disable(); self.info.interrupt.disable();
}
} }
}
self.rx.as_ref().map(|x| x.set_as_disconnected()); self.rx.as_ref().map(|x| x.set_as_disconnected());
self.rts.as_ref().map(|x| x.set_as_disconnected()); self.rts.as_ref().map(|x| x.set_as_disconnected());
drop_tx_rx(self.info, state); drop_tx_rx(self.info, state);
}
} }
} }
impl<'d> Drop for BufferedUartTx<'d> { impl<'d> Drop for BufferedUartTx<'d> {
fn drop(&mut self) { fn drop(&mut self) {
let state = self.state; if !self.is_borrowed {
unsafe { let state = self.state;
state.tx_buf.deinit(); unsafe {
state.tx_buf.deinit();
// RX is inactive if the the buffer is not available. // RX is inactive if the the buffer is not available.
// We can now unregister the interrupt handler // We can now unregister the interrupt handler
if state.rx_buf.len() == 0 { if state.rx_buf.len() == 0 {
self.info.interrupt.disable(); self.info.interrupt.disable();
}
} }
}
self.tx.as_ref().map(|x| x.set_as_disconnected()); self.tx.as_ref().map(|x| x.set_as_disconnected());
self.cts.as_ref().map(|x| x.set_as_disconnected()); self.cts.as_ref().map(|x| x.set_as_disconnected());
self.de.as_ref().map(|x| x.set_as_disconnected()); self.de.as_ref().map(|x| x.set_as_disconnected());
drop_tx_rx(self.info, state); drop_tx_rx(self.info, state);
}
} }
} }

View File

@ -1440,6 +1440,13 @@ impl<'d, M: Mode> Uart<'d, M> {
(self.tx, self.rx) (self.tx, self.rx)
} }
/// Split the Uart into a transmitter and receiver by mutable reference,
/// which is particularly useful when having two tasks correlating to
/// transmitting and receiving.
pub fn split_ref(&mut self) -> (&mut UartTx<'d, M>, &mut UartRx<'d, M>) {
(&mut self.tx, &mut self.rx)
}
/// Send break character /// Send break character
pub fn send_break(&self) { pub fn send_break(&self) {
self.tx.send_break(); self.tx.send_break();