diff options
author | Henrik Alsér <henrik.alser@me.com> | 2022-05-07 09:47:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-07 09:47:29 +0200 |
commit | 1ca5475010a1cae6ebc55a27948ca4320decd5cd (patch) | |
tree | 2484384d601823b4dfe96c2bc4bf2d260b34c5f1 /embassy-nrf | |
parent | 108a98136096f8b530266aa6687bdbbed4a6a382 (diff) | |
parent | a4bf190f2f0ce28a298626de6de1c8059269cedc (diff) | |
download | embassy-1ca5475010a1cae6ebc55a27948ca4320decd5cd.zip |
Merge branch 'embassy-rs:master' into qdec
Diffstat (limited to 'embassy-nrf')
-rw-r--r-- | embassy-nrf/Cargo.toml | 5 | ||||
-rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 144 | ||||
-rw-r--r-- | embassy-nrf/src/lib.rs | 1 |
3 files changed, 84 insertions, 66 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index b7c09286..cf61abcc 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -19,10 +19,10 @@ flavors = [ time = ["embassy/time"] -defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt"] +defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt", "embedded-io?/defmt"] # Enable nightly-only features -nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async"] +nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io"] # Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`. # This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version. @@ -73,6 +73,7 @@ embassy-usb = {version = "0.1.0", path = "../embassy-usb", optional=true } embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true} embedded-hal-async = { version = "0.1.0-alpha.0", optional = true} +embedded-io = { version = "0.2.0", features = ["async"], optional = true } defmt = { version = "0.3", optional = true } log = { version = "0.4.14", optional = true } diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index b49c1278..fc4e9c8d 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -14,18 +14,17 @@ //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. use core::cmp::min; +use core::future::Future; use core::marker::PhantomData; -use core::mem; -use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; -use core::task::{Context, Poll}; +use core::task::Poll; use embassy::interrupt::InterruptExt; -use embassy::io::{AsyncBufRead, AsyncWrite}; use embassy::util::Unborrow; use embassy::waitqueue::WakerRegistration; use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; use embassy_hal_common::ring_buffer::RingBuffer; use embassy_hal_common::{low_power_wait_until, unborrow}; +use futures::future::poll_fn; use crate::gpio::Pin as GpioPin; use crate::pac; @@ -197,82 +196,99 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { } } -impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { - fn poll_fill_buf( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll<embassy::io::Result<&[u8]>> { - self.inner.with(|state| { - compiler_fence(Ordering::SeqCst); - trace!("poll_read"); - - // We have data ready in buffer? Return it. - let buf = state.rx.pop_buf(); - if !buf.is_empty() { - trace!(" got {:?} {:?}", buf.as_ptr() as u32, buf.len()); - let buf: &[u8] = buf; - let buf: &[u8] = unsafe { mem::transmute(buf) }; - return Poll::Ready(Ok(buf)); +impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarte<'d, U, T> { + type Error = core::convert::Infallible; +} + +impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarte<'d, U, T> { + type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + where + Self: 'a; + + fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { + poll_fn(move |cx| { + let mut do_pend = false; + let res = self.inner.with(|state| { + compiler_fence(Ordering::SeqCst); + trace!("poll_read"); + + // We have data ready in buffer? Return it. + let data = state.rx.pop_buf(); + if !data.is_empty() { + trace!(" got {:?} {:?}", data.as_ptr() as u32, data.len()); + let len = data.len().min(data.len()); + buf[..len].copy_from_slice(&data[..len]); + state.rx.pop(len); + do_pend = true; + return Poll::Ready(Ok(len)); + } + + trace!(" empty"); + state.rx_waker.register(cx.waker()); + Poll::Pending + }); + if do_pend { + self.inner.pend(); } - trace!(" empty"); - state.rx_waker.register(cx.waker()); - Poll::<embassy::io::Result<&[u8]>>::Pending + res }) } - - fn consume(mut self: Pin<&mut Self>, amt: usize) { - self.inner.with(|state| { - trace!("consume {:?}", amt); - state.rx.pop(amt); - }); - self.inner.pend(); - } } -impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> { - fn poll_write( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll<embassy::io::Result<usize>> { - let poll = self.inner.with(|state| { - trace!("poll_write: {:?}", buf.len()); - - let tx_buf = state.tx.push_buf(); - if tx_buf.is_empty() { - trace!("poll_write: pending"); - state.tx_waker.register(cx.waker()); - return Poll::Pending; - } +impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write + for BufferedUarte<'d, U, T> +{ + type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> + where + Self: 'a; + + fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { + poll_fn(move |cx| { + let res = self.inner.with(|state| { + trace!("poll_write: {:?}", buf.len()); + + let tx_buf = state.tx.push_buf(); + if tx_buf.is_empty() { + trace!("poll_write: pending"); + state.tx_waker.register(cx.waker()); + return Poll::Pending; + } - let n = min(tx_buf.len(), buf.len()); - tx_buf[..n].copy_from_slice(&buf[..n]); - state.tx.push(n); + let n = min(tx_buf.len(), buf.len()); + tx_buf[..n].copy_from_slice(&buf[..n]); + state.tx.push(n); - trace!("poll_write: queued {:?}", n); + trace!("poll_write: queued {:?}", n); - compiler_fence(Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); - Poll::Ready(Ok(n)) - }); + Poll::Ready(Ok(n)) + }); - self.inner.pend(); + self.inner.pend(); - poll + res + }) } - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<embassy::io::Result<()>> { - self.inner.with(|state| { - trace!("poll_flush"); + type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> + where + Self: 'a; - if !state.tx.is_empty() { - trace!("poll_flush: pending"); - state.tx_waker.register(cx.waker()); - return Poll::Pending; - } + fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { + poll_fn(move |cx| { + self.inner.with(|state| { + trace!("poll_flush"); + + if !state.tx.is_empty() { + trace!("poll_flush: pending"); + state.tx_waker.register(cx.waker()); + return Poll::Pending; + } - Poll::Ready(Ok(())) + Poll::Ready(Ok(())) + }) }) } } diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 46234b4b..9c298a8b 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -64,6 +64,7 @@ pub(crate) mod util; #[cfg(feature = "_time-driver")] mod time_driver; +#[cfg(feature = "nightly")] pub mod buffered_uarte; pub mod gpio; #[cfg(feature = "gpiote")] |