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)
|
Writer(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.len.load(Ordering::Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_full(&self) -> bool {
|
pub fn is_full(&self) -> bool {
|
||||||
let len = self.len.load(Ordering::Relaxed);
|
let len = self.len.load(Ordering::Relaxed);
|
||||||
let start = self.start.load(Ordering::Relaxed);
|
let start = self.start.load(Ordering::Relaxed);
|
||||||
|
|
|
@ -27,7 +27,8 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BufferedUart<'d, T: Instance> {
|
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> {
|
pub struct BufferedUartRx<'d, T: Instance> {
|
||||||
|
@ -91,7 +92,10 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||||
rx_buffer,
|
rx_buffer,
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
Self { phantom: PhantomData }
|
Self {
|
||||||
|
rx: BufferedUartRx { phantom: PhantomData },
|
||||||
|
tx: BufferedUartTx { phantom: PhantomData },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_rtscts(
|
pub fn new_with_rtscts(
|
||||||
|
@ -116,14 +120,14 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||||
rx_buffer,
|
rx_buffer,
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
Self { phantom: PhantomData }
|
Self {
|
||||||
|
rx: BufferedUartRx { phantom: PhantomData },
|
||||||
|
tx: BufferedUartTx { phantom: PhantomData },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn split(&mut self) -> (BufferedUartRx<'d, T>, BufferedUartTx<'d, T>) {
|
pub fn split(self) -> (BufferedUartRx<'d, T>, BufferedUartTx<'d, T>) {
|
||||||
(
|
(self.rx, self.tx)
|
||||||
BufferedUartRx { phantom: PhantomData },
|
|
||||||
BufferedUartTx { phantom: PhantomData },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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> {
|
impl<'d, T: Instance> Drop for BufferedUartRx<'d, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
|
||||||
T::Interrupt::steal().disable();
|
|
||||||
let state = T::state();
|
let state = T::state();
|
||||||
state.tx_buf.deinit();
|
unsafe {
|
||||||
state.rx_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> {
|
impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
|
||||||
T::Interrupt::steal().disable();
|
|
||||||
let state = T::state();
|
let state = T::state();
|
||||||
|
unsafe {
|
||||||
state.tx_buf.deinit();
|
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 irq = interrupt::take!(UART0_IRQ);
|
||||||
let tx_buf = &mut singleton!([0u8; 16])[..];
|
let tx_buf = &mut singleton!([0u8; 16])[..];
|
||||||
let rx_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();
|
let (rx, mut tx) = uart.split();
|
||||||
|
|
||||||
unwrap!(spawner.spawn(reader(rx)));
|
unwrap!(spawner.spawn(reader(rx)));
|
||||||
|
|
Loading…
Reference in a new issue