diff options
| -rw-r--r-- | embassy-hal-internal/src/atomic_ring_buffer.rs | 33 | ||||
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 447 | ||||
| -rw-r--r-- | tests/nrf52840/src/bin/buffered_uart.rs | 2 | ||||
| -rw-r--r-- | tests/nrf52840/src/bin/buffered_uart_full.rs | 2 |
4 files changed, 261 insertions, 223 deletions
diff --git a/embassy-hal-internal/src/atomic_ring_buffer.rs b/embassy-hal-internal/src/atomic_ring_buffer.rs index b4f2cec28..34ceac852 100644 --- a/embassy-hal-internal/src/atomic_ring_buffer.rs +++ b/embassy-hal-internal/src/atomic_ring_buffer.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | //! Atomic reusable ringbuffer. | 1 | //! Atomic reusable ringbuffer. |
| 2 | use core::slice; | ||
| 3 | use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; | 2 | use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; |
| 3 | use core::{ptr, slice}; | ||
| 4 | 4 | ||
| 5 | /// Atomic reusable ringbuffer | 5 | /// Atomic reusable ringbuffer |
| 6 | /// | 6 | /// |
| @@ -73,6 +73,7 @@ impl RingBuffer { | |||
| 73 | pub unsafe fn deinit(&self) { | 73 | pub unsafe fn deinit(&self) { |
| 74 | // Ordering: it's OK to use `Relaxed` because this is not called | 74 | // Ordering: it's OK to use `Relaxed` because this is not called |
| 75 | // concurrently with other methods. | 75 | // concurrently with other methods. |
| 76 | self.buf.store(ptr::null_mut(), Ordering::Relaxed); | ||
| 76 | self.len.store(0, Ordering::Relaxed); | 77 | self.len.store(0, Ordering::Relaxed); |
| 77 | self.start.store(0, Ordering::Relaxed); | 78 | self.start.store(0, Ordering::Relaxed); |
| 78 | self.end.store(0, Ordering::Relaxed); | 79 | self.end.store(0, Ordering::Relaxed); |
| @@ -82,20 +83,46 @@ impl RingBuffer { | |||
| 82 | /// | 83 | /// |
| 83 | /// # Safety | 84 | /// # Safety |
| 84 | /// | 85 | /// |
| 85 | /// Only one reader can exist at a time. | 86 | /// - Only one reader can exist at a time. |
| 87 | /// - Ringbuffer must be initialized. | ||
| 86 | pub unsafe fn reader(&self) -> Reader<'_> { | 88 | pub unsafe fn reader(&self) -> Reader<'_> { |
| 87 | Reader(self) | 89 | Reader(self) |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 92 | /// Try creating a reader, fails if not initialized. | ||
| 93 | /// | ||
| 94 | /// # Safety | ||
| 95 | /// | ||
| 96 | /// Only one reader can exist at a time. | ||
| 97 | pub unsafe fn try_reader(&self) -> Option<Reader<'_>> { | ||
| 98 | if self.buf.load(Ordering::Relaxed).is_null() { | ||
| 99 | return None; | ||
| 100 | } | ||
| 101 | Some(Reader(self)) | ||
| 102 | } | ||
| 103 | |||
| 90 | /// Create a writer. | 104 | /// Create a writer. |
| 91 | /// | 105 | /// |
| 92 | /// # Safety | 106 | /// # Safety |
| 93 | /// | 107 | /// |
| 94 | /// Only one writer can exist at a time. | 108 | /// - Only one writer can exist at a time. |
| 109 | /// - Ringbuffer must be initialized. | ||
| 95 | pub unsafe fn writer(&self) -> Writer<'_> { | 110 | pub unsafe fn writer(&self) -> Writer<'_> { |
| 96 | Writer(self) | 111 | Writer(self) |
| 97 | } | 112 | } |
| 98 | 113 | ||
| 114 | /// Try creating a writer, fails if not initialized. | ||
| 115 | /// | ||
| 116 | /// # Safety | ||
| 117 | /// | ||
| 118 | /// Only one writer can exist at a time. | ||
| 119 | pub unsafe fn try_writer(&self) -> Option<Writer<'_>> { | ||
| 120 | if self.buf.load(Ordering::Relaxed).is_null() { | ||
| 121 | return None; | ||
| 122 | } | ||
| 123 | Some(Writer(self)) | ||
| 124 | } | ||
| 125 | |||
| 99 | /// Return length of buffer. | 126 | /// Return length of buffer. |
| 100 | pub fn len(&self) -> usize { | 127 | pub fn len(&self) -> usize { |
| 101 | self.len.load(Ordering::Relaxed) | 128 | self.len.load(Ordering::Relaxed) |
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index e0916f775..b1b639f10 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -22,13 +22,13 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 22 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; | 22 | pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; |
| 23 | 23 | ||
| 24 | use crate::gpio::sealed::Pin; | 24 | use crate::gpio::sealed::Pin; |
| 25 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; | 25 | use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; |
| 26 | use crate::interrupt::typelevel::Interrupt; | 26 | use crate::interrupt::typelevel::Interrupt; |
| 27 | use crate::ppi::{ | 27 | use crate::ppi::{ |
| 28 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, | 28 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, |
| 29 | }; | 29 | }; |
| 30 | use crate::timer::{Instance as TimerInstance, Timer}; | 30 | use crate::timer::{Instance as TimerInstance, Timer}; |
| 31 | use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance}; | 31 | use crate::uarte::{apply_workaround_for_enable_anomaly, drop_tx_rx, Config, Instance as UarteInstance}; |
| 32 | use crate::{interrupt, pac, Peripheral}; | 32 | use crate::{interrupt, pac, Peripheral}; |
| 33 | 33 | ||
| 34 | mod sealed { | 34 | mod sealed { |
| @@ -86,126 +86,128 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 86 | let r = U::regs(); | 86 | let r = U::regs(); |
| 87 | let s = U::buffered_state(); | 87 | let s = U::buffered_state(); |
| 88 | 88 | ||
| 89 | let buf_len = s.rx_buf.len(); | 89 | if let Some(mut rx) = unsafe { s.rx_buf.try_writer() } { |
| 90 | let half_len = buf_len / 2; | 90 | let buf_len = s.rx_buf.len(); |
| 91 | let mut tx = unsafe { s.tx_buf.reader() }; | 91 | let half_len = buf_len / 2; |
| 92 | let mut rx = unsafe { s.rx_buf.writer() }; | ||
| 93 | 92 | ||
| 94 | if r.events_error.read().bits() != 0 { | 93 | if r.events_error.read().bits() != 0 { |
| 95 | r.events_error.reset(); | 94 | r.events_error.reset(); |
| 96 | let errs = r.errorsrc.read(); | 95 | let errs = r.errorsrc.read(); |
| 97 | r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) }); | 96 | r.errorsrc.write(|w| unsafe { w.bits(errs.bits()) }); |
| 98 | 97 | ||
| 99 | if errs.overrun().bit() { | 98 | if errs.overrun().bit() { |
| 100 | panic!("BufferedUarte overrun"); | 99 | panic!("BufferedUarte overrun"); |
| 100 | } | ||
| 101 | } | 101 | } |
| 102 | } | ||
| 103 | 102 | ||
| 104 | // Received some bytes, wake task. | 103 | // Received some bytes, wake task. |
| 105 | if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 { | 104 | if r.inten.read().rxdrdy().bit_is_set() && r.events_rxdrdy.read().bits() != 0 { |
| 106 | r.intenclr.write(|w| w.rxdrdy().clear()); | 105 | r.intenclr.write(|w| w.rxdrdy().clear()); |
| 107 | r.events_rxdrdy.reset(); | 106 | r.events_rxdrdy.reset(); |
| 108 | s.rx_waker.wake(); | 107 | s.rx_waker.wake(); |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | if r.events_endrx.read().bits() != 0 { | 110 | if r.events_endrx.read().bits() != 0 { |
| 112 | //trace!(" irq_rx: endrx"); | 111 | //trace!(" irq_rx: endrx"); |
| 113 | r.events_endrx.reset(); | 112 | r.events_endrx.reset(); |
| 114 | 113 | ||
| 115 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 114 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 116 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 115 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { | 118 | if r.events_rxstarted.read().bits() != 0 || !s.rx_started.load(Ordering::Relaxed) { |
| 120 | //trace!(" irq_rx: rxstarted"); | 119 | //trace!(" irq_rx: rxstarted"); |
| 121 | let (ptr, len) = rx.push_buf(); | 120 | let (ptr, len) = rx.push_buf(); |
| 122 | if len >= half_len { | 121 | if len >= half_len { |
| 123 | r.events_rxstarted.reset(); | 122 | r.events_rxstarted.reset(); |
| 124 | 123 | ||
| 125 | //trace!(" irq_rx: starting second {:?}", half_len); | 124 | //trace!(" irq_rx: starting second {:?}", half_len); |
| 126 | 125 | ||
| 127 | // Set up the DMA read | 126 | // Set up the DMA read |
| 128 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 127 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 129 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); | 128 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(half_len as _) }); |
| 130 | 129 | ||
| 131 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); | 130 | let chn = s.rx_ppi_ch.load(Ordering::Relaxed); |
| 132 | 131 | ||
| 133 | // Enable endrx -> startrx PPI channel. | 132 | // Enable endrx -> startrx PPI channel. |
| 134 | // From this point on, if endrx happens, startrx is automatically fired. | 133 | // From this point on, if endrx happens, startrx is automatically fired. |
| 135 | ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); | 134 | ppi::regs().chenset.write(|w| unsafe { w.bits(1 << chn) }); |
| 136 | 135 | ||
| 137 | // It is possible that endrx happened BEFORE enabling the PPI. In this case | 136 | // It is possible that endrx happened BEFORE enabling the PPI. In this case |
| 138 | // the PPI channel doesn't trigger, and we'd hang. We have to detect this | 137 | // the PPI channel doesn't trigger, and we'd hang. We have to detect this |
| 139 | // and manually start. | 138 | // and manually start. |
| 140 | 139 | ||
| 141 | // check again in case endrx has happened between the last check and now. | 140 | // check again in case endrx has happened between the last check and now. |
| 142 | if r.events_endrx.read().bits() != 0 { | 141 | if r.events_endrx.read().bits() != 0 { |
| 143 | //trace!(" irq_rx: endrx"); | 142 | //trace!(" irq_rx: endrx"); |
| 144 | r.events_endrx.reset(); | 143 | r.events_endrx.reset(); |
| 145 | 144 | ||
| 146 | let val = s.rx_ended_count.load(Ordering::Relaxed); | 145 | let val = s.rx_ended_count.load(Ordering::Relaxed); |
| 147 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); | 146 | s.rx_ended_count.store(val.wrapping_add(1), Ordering::Relaxed); |
| 148 | } | 147 | } |
| 149 | 148 | ||
| 150 | let rx_ended = s.rx_ended_count.load(Ordering::Relaxed); | 149 | let rx_ended = s.rx_ended_count.load(Ordering::Relaxed); |
| 151 | let rx_started = s.rx_started_count.load(Ordering::Relaxed); | 150 | let rx_started = s.rx_started_count.load(Ordering::Relaxed); |
| 152 | 151 | ||
| 153 | // If we started the same amount of transfers as ended, the last rxend has | 152 | // If we started the same amount of transfers as ended, the last rxend has |
| 154 | // already occured. | 153 | // already occured. |
| 155 | let rxend_happened = rx_started == rx_ended; | 154 | let rxend_happened = rx_started == rx_ended; |
| 156 | 155 | ||
| 157 | // Check if the PPI channel is still enabled. The PPI channel disables itself | 156 | // Check if the PPI channel is still enabled. The PPI channel disables itself |
| 158 | // when it fires, so if it's still enabled it hasn't fired. | 157 | // when it fires, so if it's still enabled it hasn't fired. |
| 159 | let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; | 158 | let ppi_ch_enabled = ppi::regs().chen.read().bits() & (1 << chn) != 0; |
| 160 | 159 | ||
| 161 | // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. | 160 | // if rxend happened, and the ppi channel hasn't fired yet, the rxend got missed. |
| 162 | // this condition also naturally matches if `!started`, needed to kickstart the DMA. | 161 | // this condition also naturally matches if `!started`, needed to kickstart the DMA. |
| 163 | if rxend_happened && ppi_ch_enabled { | 162 | if rxend_happened && ppi_ch_enabled { |
| 164 | //trace!("manually starting."); | 163 | //trace!("manually starting."); |
| 165 | 164 | ||
| 166 | // disable the ppi ch, it's of no use anymore. | 165 | // disable the ppi ch, it's of no use anymore. |
| 167 | ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); | 166 | ppi::regs().chenclr.write(|w| unsafe { w.bits(1 << chn) }); |
| 168 | 167 | ||
| 169 | // manually start | 168 | // manually start |
| 170 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); | 169 | r.tasks_startrx.write(|w| unsafe { w.bits(1) }); |
| 171 | } | 170 | } |
| 172 | 171 | ||
| 173 | rx.push_done(half_len); | 172 | rx.push_done(half_len); |
| 174 | 173 | ||
| 175 | s.rx_started_count.store(rx_started.wrapping_add(1), Ordering::Relaxed); | 174 | s.rx_started_count.store(rx_started.wrapping_add(1), Ordering::Relaxed); |
| 176 | s.rx_started.store(true, Ordering::Relaxed); | 175 | s.rx_started.store(true, Ordering::Relaxed); |
| 177 | } else { | 176 | } else { |
| 178 | //trace!(" irq_rx: rxstarted no buf"); | 177 | //trace!(" irq_rx: rxstarted no buf"); |
| 179 | r.intenclr.write(|w| w.rxstarted().clear()); | 178 | r.intenclr.write(|w| w.rxstarted().clear()); |
| 179 | } | ||
| 180 | } | 180 | } |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | // ============================= | 183 | // ============================= |
| 184 | 184 | ||
| 185 | // TX end | 185 | if let Some(mut tx) = unsafe { s.tx_buf.try_reader() } { |
| 186 | if r.events_endtx.read().bits() != 0 { | 186 | // TX end |
| 187 | r.events_endtx.reset(); | 187 | if r.events_endtx.read().bits() != 0 { |
| 188 | r.events_endtx.reset(); | ||
| 188 | 189 | ||
| 189 | let n = s.tx_count.load(Ordering::Relaxed); | 190 | let n = s.tx_count.load(Ordering::Relaxed); |
| 190 | //trace!(" irq_tx: endtx {:?}", n); | 191 | //trace!(" irq_tx: endtx {:?}", n); |
| 191 | tx.pop_done(n); | 192 | tx.pop_done(n); |
| 192 | s.tx_waker.wake(); | 193 | s.tx_waker.wake(); |
| 193 | s.tx_count.store(0, Ordering::Relaxed); | 194 | s.tx_count.store(0, Ordering::Relaxed); |
| 194 | } | 195 | } |
| 195 | 196 | ||
| 196 | // If not TXing, start. | 197 | // If not TXing, start. |
| 197 | if s.tx_count.load(Ordering::Relaxed) == 0 { | 198 | if s.tx_count.load(Ordering::Relaxed) == 0 { |
| 198 | let (ptr, len) = tx.pop_buf(); | 199 | let (ptr, len) = tx.pop_buf(); |
| 199 | if len != 0 { | 200 | if len != 0 { |
| 200 | //trace!(" irq_tx: starting {:?}", len); | 201 | //trace!(" irq_tx: starting {:?}", len); |
| 201 | s.tx_count.store(len, Ordering::Relaxed); | 202 | s.tx_count.store(len, Ordering::Relaxed); |
| 202 | 203 | ||
| 203 | // Set up the DMA write | 204 | // Set up the DMA write |
| 204 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); | 205 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as u32) }); |
| 205 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 206 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 206 | 207 | ||
| 207 | // Start UARTE Transmit transaction | 208 | // Start UARTE Transmit transaction |
| 208 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); | 209 | r.tasks_starttx.write(|w| unsafe { w.bits(1) }); |
| 210 | } | ||
| 209 | } | 211 | } |
| 210 | } | 212 | } |
| 211 | 213 | ||
| @@ -215,11 +217,8 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 215 | 217 | ||
| 216 | /// Buffered UARTE driver. | 218 | /// Buffered UARTE driver. |
| 217 | pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { | 219 | pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { |
| 218 | _peri: PeripheralRef<'d, U>, | 220 | tx: BufferedUarteTx<'d, U>, |
| 219 | timer: Timer<'d, T>, | 221 | rx: BufferedUarteRx<'d, U, T>, |
| 220 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, | ||
| 221 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, | ||
| 222 | _ppi_group: PpiGroup<'d, AnyGroup>, | ||
| 223 | } | 222 | } |
| 224 | 223 | ||
| 225 | impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} | 224 | impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} |
| @@ -404,19 +403,23 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 404 | U::Interrupt::pend(); | 403 | U::Interrupt::pend(); |
| 405 | unsafe { U::Interrupt::enable() }; | 404 | unsafe { U::Interrupt::enable() }; |
| 406 | 405 | ||
| 406 | let s = U::state(); | ||
| 407 | s.tx_rx_refcount.store(2, Ordering::Relaxed); | ||
| 408 | |||
| 407 | Self { | 409 | Self { |
| 408 | _peri: peri, | 410 | tx: BufferedUarteTx { |
| 409 | timer, | 411 | _peri: unsafe { peri.clone_unchecked() }, |
| 410 | _ppi_ch1: ppi_ch1, | 412 | }, |
| 411 | _ppi_ch2: ppi_ch2, | 413 | rx: BufferedUarteRx { |
| 412 | _ppi_group: ppi_group, | 414 | _peri: peri, |
| 415 | timer, | ||
| 416 | _ppi_ch1: ppi_ch1, | ||
| 417 | _ppi_ch2: ppi_ch2, | ||
| 418 | _ppi_group: ppi_group, | ||
| 419 | }, | ||
| 413 | } | 420 | } |
| 414 | } | 421 | } |
| 415 | 422 | ||
| 416 | fn pend_irq() { | ||
| 417 | U::Interrupt::pend() | ||
| 418 | } | ||
| 419 | |||
| 420 | /// Adjust the baud rate to the provided value. | 423 | /// Adjust the baud rate to the provided value. |
| 421 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | 424 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { |
| 422 | let r = U::regs(); | 425 | let r = U::regs(); |
| @@ -426,19 +429,52 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 426 | /// Split the UART in reader and writer parts. | 429 | /// Split the UART in reader and writer parts. |
| 427 | /// | 430 | /// |
| 428 | /// This allows reading and writing concurrently from independent tasks. | 431 | /// This allows reading and writing concurrently from independent tasks. |
| 429 | pub fn split(&mut self) -> (BufferedUarteRx<'_, U, T>, BufferedUarteTx<'_, U, T>) { | 432 | pub fn split(self) -> (BufferedUarteRx<'d, U, T>, BufferedUarteTx<'d, U>) { |
| 430 | (BufferedUarteRx { inner: self }, BufferedUarteTx { inner: self }) | 433 | (self.rx, self.tx) |
| 431 | } | 434 | } |
| 432 | 435 | ||
| 433 | async fn inner_read(&self, buf: &mut [u8]) -> Result<usize, Error> { | 436 | /// Split the UART in reader and writer parts, by reference. |
| 434 | let data = self.inner_fill_buf().await?; | 437 | /// |
| 435 | let n = data.len().min(buf.len()); | 438 | /// The returned halves borrow from `self`, so you can drop them and go back to using |
| 436 | buf[..n].copy_from_slice(&data[..n]); | 439 | /// the "un-split" `self`. This allows temporarily splitting the UART. |
| 437 | self.inner_consume(n); | 440 | pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d, U, T>, &mut BufferedUarteTx<'d, U>) { |
| 438 | Ok(n) | 441 | (&mut self.rx, &mut self.tx) |
| 442 | } | ||
| 443 | |||
| 444 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 445 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 446 | self.rx.read(buf).await | ||
| 447 | } | ||
| 448 | |||
| 449 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 450 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | ||
| 451 | self.rx.fill_buf().await | ||
| 452 | } | ||
| 453 | |||
| 454 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 455 | pub fn consume(&mut self, amt: usize) { | ||
| 456 | self.rx.consume(amt) | ||
| 457 | } | ||
| 458 | |||
| 459 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 460 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 461 | self.tx.write(buf).await | ||
| 439 | } | 462 | } |
| 440 | 463 | ||
| 441 | async fn inner_write<'a>(&'a self, buf: &'a [u8]) -> Result<usize, Error> { | 464 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. |
| 465 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 466 | self.tx.flush().await | ||
| 467 | } | ||
| 468 | } | ||
| 469 | |||
| 470 | /// Reader part of the buffered UARTE driver. | ||
| 471 | pub struct BufferedUarteTx<'d, U: UarteInstance> { | ||
| 472 | _peri: PeripheralRef<'d, U>, | ||
| 473 | } | ||
| 474 | |||
| 475 | impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | ||
| 476 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 477 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 442 | poll_fn(move |cx| { | 478 | poll_fn(move |cx| { |
| 443 | //trace!("poll_write: {:?}", buf.len()); | 479 | //trace!("poll_write: {:?}", buf.len()); |
| 444 | let s = U::buffered_state(); | 480 | let s = U::buffered_state(); |
| @@ -458,14 +494,15 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 458 | //trace!("poll_write: queued {:?}", n); | 494 | //trace!("poll_write: queued {:?}", n); |
| 459 | 495 | ||
| 460 | compiler_fence(Ordering::SeqCst); | 496 | compiler_fence(Ordering::SeqCst); |
| 461 | Self::pend_irq(); | 497 | U::Interrupt::pend(); |
| 462 | 498 | ||
| 463 | Poll::Ready(Ok(n)) | 499 | Poll::Ready(Ok(n)) |
| 464 | }) | 500 | }) |
| 465 | .await | 501 | .await |
| 466 | } | 502 | } |
| 467 | 503 | ||
| 468 | async fn inner_flush<'a>(&'a self) -> Result<(), Error> { | 504 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. |
| 505 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 469 | poll_fn(move |cx| { | 506 | poll_fn(move |cx| { |
| 470 | //trace!("poll_flush"); | 507 | //trace!("poll_flush"); |
| 471 | let s = U::buffered_state(); | 508 | let s = U::buffered_state(); |
| @@ -479,8 +516,51 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 479 | }) | 516 | }) |
| 480 | .await | 517 | .await |
| 481 | } | 518 | } |
| 519 | } | ||
| 520 | |||
| 521 | impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | ||
| 522 | fn drop(&mut self) { | ||
| 523 | let r = U::regs(); | ||
| 482 | 524 | ||
| 483 | async fn inner_fill_buf<'a>(&'a self) -> Result<&'a [u8], Error> { | 525 | r.intenclr.write(|w| { |
| 526 | w.txdrdy().set_bit(); | ||
| 527 | w.txstarted().set_bit(); | ||
| 528 | w.txstopped().set_bit(); | ||
| 529 | w | ||
| 530 | }); | ||
| 531 | r.events_txstopped.reset(); | ||
| 532 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | ||
| 533 | while r.events_txstopped.read().bits() == 0 {} | ||
| 534 | |||
| 535 | let s = U::buffered_state(); | ||
| 536 | unsafe { s.tx_buf.deinit() } | ||
| 537 | |||
| 538 | let s = U::state(); | ||
| 539 | drop_tx_rx(r, s); | ||
| 540 | } | ||
| 541 | } | ||
| 542 | |||
| 543 | /// Reader part of the buffered UARTE driver. | ||
| 544 | pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { | ||
| 545 | _peri: PeripheralRef<'d, U>, | ||
| 546 | timer: Timer<'d, T>, | ||
| 547 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, | ||
| 548 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, | ||
| 549 | _ppi_group: PpiGroup<'d, AnyGroup>, | ||
| 550 | } | ||
| 551 | |||
| 552 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | ||
| 553 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 554 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 555 | let data = self.fill_buf().await?; | ||
| 556 | let n = data.len().min(buf.len()); | ||
| 557 | buf[..n].copy_from_slice(&data[..n]); | ||
| 558 | self.consume(n); | ||
| 559 | Ok(n) | ||
| 560 | } | ||
| 561 | |||
| 562 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 563 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | ||
| 484 | poll_fn(move |cx| { | 564 | poll_fn(move |cx| { |
| 485 | compiler_fence(Ordering::SeqCst); | 565 | compiler_fence(Ordering::SeqCst); |
| 486 | //trace!("poll_read"); | 566 | //trace!("poll_read"); |
| @@ -532,7 +612,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 532 | .await | 612 | .await |
| 533 | } | 613 | } |
| 534 | 614 | ||
| 535 | fn inner_consume(&self, amt: usize) { | 615 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. |
| 616 | pub fn consume(&mut self, amt: usize) { | ||
| 536 | if amt == 0 { | 617 | if amt == 0 { |
| 537 | return; | 618 | return; |
| 538 | } | 619 | } |
| @@ -542,69 +623,31 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 542 | rx.pop_done(amt); | 623 | rx.pop_done(amt); |
| 543 | U::regs().intenset.write(|w| w.rxstarted().set()); | 624 | U::regs().intenset.write(|w| w.rxstarted().set()); |
| 544 | } | 625 | } |
| 545 | |||
| 546 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | ||
| 547 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | ||
| 548 | self.inner_read(buf).await | ||
| 549 | } | ||
| 550 | |||
| 551 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | ||
| 552 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | ||
| 553 | self.inner_fill_buf().await | ||
| 554 | } | ||
| 555 | |||
| 556 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | ||
| 557 | pub fn consume(&mut self, amt: usize) { | ||
| 558 | self.inner_consume(amt) | ||
| 559 | } | ||
| 560 | |||
| 561 | /// Write a buffer into this writer, returning how many bytes were written. | ||
| 562 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | ||
| 563 | self.inner_write(buf).await | ||
| 564 | } | ||
| 565 | |||
| 566 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | ||
| 567 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 568 | self.inner_flush().await | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | /// Reader part of the buffered UARTE driver. | ||
| 573 | pub struct BufferedUarteTx<'d, U: UarteInstance, T: TimerInstance> { | ||
| 574 | inner: &'d BufferedUarte<'d, U, T>, | ||
| 575 | } | 626 | } |
| 576 | 627 | ||
| 577 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteTx<'d, U, T> { | 628 | impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T> { |
| 578 | /// Write a buffer into this writer, returning how many bytes were written. | 629 | fn drop(&mut self) { |
| 579 | pub async fn write(&mut self, buf: &[u8]) -> Result<usize, Error> { | 630 | self._ppi_group.disable_all(); |
| 580 | self.inner.inner_write(buf).await | ||
| 581 | } | ||
| 582 | 631 | ||
| 583 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | 632 | let r = U::regs(); |
| 584 | pub async fn flush(&mut self) -> Result<(), Error> { | ||
| 585 | self.inner.inner_flush().await | ||
| 586 | } | ||
| 587 | } | ||
| 588 | 633 | ||
| 589 | /// Writer part of the buffered UARTE driver. | 634 | self.timer.stop(); |
| 590 | pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { | ||
| 591 | inner: &'d BufferedUarte<'d, U, T>, | ||
| 592 | } | ||
| 593 | 635 | ||
| 594 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | 636 | r.intenclr.write(|w| { |
| 595 | /// Pull some bytes from this source into the specified buffer, returning how many bytes were read. | 637 | w.rxdrdy().set_bit(); |
| 596 | pub async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 638 | w.rxstarted().set_bit(); |
| 597 | self.inner.inner_read(buf).await | 639 | w.rxto().set_bit(); |
| 598 | } | 640 | w |
| 641 | }); | ||
| 642 | r.events_rxto.reset(); | ||
| 643 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | ||
| 644 | while r.events_rxto.read().bits() == 0 {} | ||
| 599 | 645 | ||
| 600 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | 646 | let s = U::buffered_state(); |
| 601 | pub async fn fill_buf(&mut self) -> Result<&[u8], Error> { | 647 | unsafe { s.rx_buf.deinit() } |
| 602 | self.inner.inner_fill_buf().await | ||
| 603 | } | ||
| 604 | 648 | ||
| 605 | /// Tell this buffer that `amt` bytes have been consumed from the buffer, so they should no longer be returned in calls to `fill_buf`. | 649 | let s = U::state(); |
| 606 | pub fn consume(&mut self, amt: usize) { | 650 | drop_tx_rx(r, s); |
| 607 | self.inner.inner_consume(amt) | ||
| 608 | } | 651 | } |
| 609 | } | 652 | } |
| 610 | 653 | ||
| @@ -625,91 +668,59 @@ mod _embedded_io { | |||
| 625 | type Error = Error; | 668 | type Error = Error; |
| 626 | } | 669 | } |
| 627 | 670 | ||
| 628 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U, T> { | 671 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U> { |
| 629 | type Error = Error; | 672 | type Error = Error; |
| 630 | } | 673 | } |
| 631 | 674 | ||
| 632 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarte<'d, U, T> { | 675 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarte<'d, U, T> { |
| 633 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 676 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 634 | self.inner_read(buf).await | 677 | self.read(buf).await |
| 635 | } | 678 | } |
| 636 | } | 679 | } |
| 637 | 680 | ||
| 638 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarteRx<'d, U, T> { | 681 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarteRx<'d, U, T> { |
| 639 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 682 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 640 | self.inner.inner_read(buf).await | 683 | self.read(buf).await |
| 641 | } | 684 | } |
| 642 | } | 685 | } |
| 643 | 686 | ||
| 644 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarte<'d, U, T> { | 687 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarte<'d, U, T> { |
| 645 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 688 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 646 | self.inner_fill_buf().await | 689 | self.fill_buf().await |
| 647 | } | 690 | } |
| 648 | 691 | ||
| 649 | fn consume(&mut self, amt: usize) { | 692 | fn consume(&mut self, amt: usize) { |
| 650 | self.inner_consume(amt) | 693 | self.consume(amt) |
| 651 | } | 694 | } |
| 652 | } | 695 | } |
| 653 | 696 | ||
| 654 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U, T> { | 697 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U, T> { |
| 655 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 698 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 656 | self.inner.inner_fill_buf().await | 699 | self.fill_buf().await |
| 657 | } | 700 | } |
| 658 | 701 | ||
| 659 | fn consume(&mut self, amt: usize) { | 702 | fn consume(&mut self, amt: usize) { |
| 660 | self.inner.inner_consume(amt) | 703 | self.consume(amt) |
| 661 | } | 704 | } |
| 662 | } | 705 | } |
| 663 | 706 | ||
| 664 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarte<'d, U, T> { | 707 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarte<'d, U, T> { |
| 665 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 708 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 666 | self.inner_write(buf).await | 709 | self.write(buf).await |
| 667 | } | 710 | } |
| 668 | 711 | ||
| 669 | async fn flush(&mut self) -> Result<(), Self::Error> { | 712 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 670 | self.inner_flush().await | 713 | self.flush().await |
| 671 | } | 714 | } |
| 672 | } | 715 | } |
| 673 | 716 | ||
| 674 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarteTx<'d, U, T> { | 717 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Write for BufferedUarteTx<'d, U> { |
| 675 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 718 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 676 | self.inner.inner_write(buf).await | 719 | self.write(buf).await |
| 677 | } | 720 | } |
| 678 | 721 | ||
| 679 | async fn flush(&mut self) -> Result<(), Self::Error> { | 722 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 680 | self.inner.inner_flush().await | 723 | self.flush().await |
| 681 | } | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 685 | impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarte<'a, U, T> { | ||
| 686 | fn drop(&mut self) { | ||
| 687 | self._ppi_group.disable_all(); | ||
| 688 | |||
| 689 | let r = U::regs(); | ||
| 690 | |||
| 691 | self.timer.stop(); | ||
| 692 | |||
| 693 | r.inten.reset(); | ||
| 694 | r.events_rxto.reset(); | ||
| 695 | r.tasks_stoprx.write(|w| unsafe { w.bits(1) }); | ||
| 696 | r.events_txstopped.reset(); | ||
| 697 | r.tasks_stoptx.write(|w| unsafe { w.bits(1) }); | ||
| 698 | |||
| 699 | while r.events_txstopped.read().bits() == 0 {} | ||
| 700 | while r.events_rxto.read().bits() == 0 {} | ||
| 701 | |||
| 702 | r.enable.write(|w| w.enable().disabled()); | ||
| 703 | |||
| 704 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | ||
| 705 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | ||
| 706 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | ||
| 707 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | ||
| 708 | |||
| 709 | let s = U::buffered_state(); | ||
| 710 | unsafe { | ||
| 711 | s.rx_buf.deinit(); | ||
| 712 | s.tx_buf.deinit(); | ||
| 713 | } | 724 | } |
| 714 | } | 725 | } |
| 715 | } | 726 | } |
diff --git a/tests/nrf52840/src/bin/buffered_uart.rs b/tests/nrf52840/src/bin/buffered_uart.rs index 354d787b4..721751136 100644 --- a/tests/nrf52840/src/bin/buffered_uart.rs +++ b/tests/nrf52840/src/bin/buffered_uart.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | 23 | let mut tx_buffer = [0u8; 1024]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 24 | let mut rx_buffer = [0u8; 1024]; |
| 25 | 25 | ||
| 26 | let mut u = BufferedUarte::new( | 26 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 27 | p.UARTE0, |
| 28 | p.TIMER0, | 28 | p.TIMER0, |
| 29 | p.PPI_CH0, | 29 | p.PPI_CH0, |
diff --git a/tests/nrf52840/src/bin/buffered_uart_full.rs b/tests/nrf52840/src/bin/buffered_uart_full.rs index e59c75ba9..62edaed25 100644 --- a/tests/nrf52840/src/bin/buffered_uart_full.rs +++ b/tests/nrf52840/src/bin/buffered_uart_full.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | 23 | let mut tx_buffer = [0u8; 1024]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 24 | let mut rx_buffer = [0u8; 1024]; |
| 25 | 25 | ||
| 26 | let mut u = BufferedUarte::new( | 26 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 27 | p.UARTE0, |
| 28 | p.TIMER0, | 28 | p.TIMER0, |
| 29 | p.PPI_CH0, | 29 | p.PPI_CH0, |
