rp: Fix BufferedUart drop code
Only unregister the interrupt handler when both parts are inactive
This commit is contained in:
parent
68c186309f
commit
a24037edf9
3 changed files with 31 additions and 26 deletions
|
@ -81,6 +81,10 @@ impl RingBuffer {
|
|||
Writer(self)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.len.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn is_full(&self) -> bool {
|
||||
let len = self.len.load(Ordering::Relaxed);
|
||||
let start = self.start.load(Ordering::Relaxed);
|
||||
|
|
|
@ -27,7 +27,8 @@ impl State {
|
|||
}
|
||||
|
||||
pub struct BufferedUart<'d, T: Instance> {
|
||||
phantom: PhantomData<&'d mut T>,
|
||||
rx: BufferedUartRx<'d, T>,
|
||||
tx: BufferedUartTx<'d, T>,
|
||||
}
|
||||
|
||||
pub struct BufferedUartRx<'d, T: Instance> {
|
||||
|
@ -91,7 +92,10 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
|||
rx_buffer,
|
||||
config,
|
||||
);
|
||||
Self { phantom: PhantomData }
|
||||
Self {
|
||||
rx: BufferedUartRx { phantom: PhantomData },
|
||||
tx: BufferedUartTx { phantom: PhantomData },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_rtscts(
|
||||
|
@ -116,14 +120,14 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
|||
rx_buffer,
|
||||
config,
|
||||
);
|
||||
Self { phantom: PhantomData }
|
||||
Self {
|
||||
rx: BufferedUartRx { phantom: PhantomData },
|
||||
tx: BufferedUartTx { phantom: PhantomData },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split(&mut self) -> (BufferedUartRx<'d, T>, BufferedUartTx<'d, T>) {
|
||||
(
|
||||
BufferedUartRx { phantom: PhantomData },
|
||||
BufferedUartTx { phantom: PhantomData },
|
||||
)
|
||||
pub fn split(self) -> (BufferedUartRx<'d, T>, BufferedUartTx<'d, T>) {
|
||||
(self.rx, self.tx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,35 +273,32 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Drop for BufferedUart<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
T::Interrupt::steal().disable();
|
||||
let state = T::state();
|
||||
state.tx_buf.deinit();
|
||||
state.rx_buf.deinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
let state = T::state();
|
||||
unsafe {
|
||||
T::Interrupt::steal().disable();
|
||||
let state = T::state();
|
||||
state.tx_buf.deinit();
|
||||
state.rx_buf.deinit();
|
||||
|
||||
// TX is inactive if the the buffer is not available.
|
||||
// We can now unregister the interrupt handler
|
||||
if state.tx_buf.len() == 0 {
|
||||
T::Interrupt::steal().disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
let state = T::state();
|
||||
unsafe {
|
||||
T::Interrupt::steal().disable();
|
||||
let state = T::state();
|
||||
state.tx_buf.deinit();
|
||||
state.rx_buf.deinit();
|
||||
|
||||
// RX is inactive if the the buffer is not available.
|
||||
// We can now unregister the interrupt handler
|
||||
if state.rx_buf.len() == 0 {
|
||||
T::Interrupt::steal().disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ async fn main(spawner: Spawner) {
|
|||
let irq = interrupt::take!(UART0_IRQ);
|
||||
let tx_buf = &mut singleton!([0u8; 16])[..];
|
||||
let rx_buf = &mut singleton!([0u8; 16])[..];
|
||||
let mut uart = BufferedUart::new(uart, irq, tx_pin, rx_pin, tx_buf, rx_buf, Config::default());
|
||||
let uart = BufferedUart::new(uart, irq, tx_pin, rx_pin, tx_buf, rx_buf, Config::default());
|
||||
let (rx, mut tx) = uart.split();
|
||||
|
||||
unwrap!(spawner.spawn(reader(rx)));
|
||||
|
|
Loading…
Reference in a new issue