aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf
diff options
context:
space:
mode:
authorHenrik Alsér <[email protected]>2022-05-07 09:47:29 +0200
committerGitHub <[email protected]>2022-05-07 09:47:29 +0200
commit1ca5475010a1cae6ebc55a27948ca4320decd5cd (patch)
tree2484384d601823b4dfe96c2bc4bf2d260b34c5f1 /embassy-nrf
parent108a98136096f8b530266aa6687bdbbed4a6a382 (diff)
parenta4bf190f2f0ce28a298626de6de1c8059269cedc (diff)
Merge branch 'embassy-rs:master' into qdec
Diffstat (limited to 'embassy-nrf')
-rw-r--r--embassy-nrf/Cargo.toml5
-rw-r--r--embassy-nrf/src/buffered_uarte.rs144
-rw-r--r--embassy-nrf/src/lib.rs1
3 files changed, 84 insertions, 66 deletions
diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml
index b7c09286f..cf61abcc8 100644
--- a/embassy-nrf/Cargo.toml
+++ b/embassy-nrf/Cargo.toml
@@ -19,10 +19,10 @@ flavors = [
19 19
20time = ["embassy/time"] 20time = ["embassy/time"]
21 21
22defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt"] 22defmt = ["dep:defmt", "embassy/defmt", "embassy-usb?/defmt", "embedded-io?/defmt"]
23 23
24# Enable nightly-only features 24# Enable nightly-only features
25nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async"] 25nightly = ["embassy/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io"]
26 26
27# Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`. 27# Reexport the PAC for the currently enabled chip at `embassy_nrf::pac`.
28# This is unstable because semver-minor (non-breaking) releases of embassy-nrf may major-bump (breaking) the PAC version. 28# 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 }
73embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 73embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
74embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true} 74embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8", optional = true}
75embedded-hal-async = { version = "0.1.0-alpha.0", optional = true} 75embedded-hal-async = { version = "0.1.0-alpha.0", optional = true}
76embedded-io = { version = "0.2.0", features = ["async"], optional = true }
76 77
77defmt = { version = "0.3", optional = true } 78defmt = { version = "0.3", optional = true }
78log = { version = "0.4.14", optional = true } 79log = { version = "0.4.14", optional = true }
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index b49c12788..fc4e9c8d0 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -14,18 +14,17 @@
14//! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. 14//! Please also see [crate::uarte] to understand when [BufferedUarte] should be used.
15 15
16use core::cmp::min; 16use core::cmp::min;
17use core::future::Future;
17use core::marker::PhantomData; 18use core::marker::PhantomData;
18use core::mem;
19use core::pin::Pin;
20use core::sync::atomic::{compiler_fence, Ordering}; 19use core::sync::atomic::{compiler_fence, Ordering};
21use core::task::{Context, Poll}; 20use core::task::Poll;
22use embassy::interrupt::InterruptExt; 21use embassy::interrupt::InterruptExt;
23use embassy::io::{AsyncBufRead, AsyncWrite};
24use embassy::util::Unborrow; 22use embassy::util::Unborrow;
25use embassy::waitqueue::WakerRegistration; 23use embassy::waitqueue::WakerRegistration;
26use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; 24use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
27use embassy_hal_common::ring_buffer::RingBuffer; 25use embassy_hal_common::ring_buffer::RingBuffer;
28use embassy_hal_common::{low_power_wait_until, unborrow}; 26use embassy_hal_common::{low_power_wait_until, unborrow};
27use futures::future::poll_fn;
29 28
30use crate::gpio::Pin as GpioPin; 29use crate::gpio::Pin as GpioPin;
31use crate::pac; 30use crate::pac;
@@ -197,82 +196,99 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
197 } 196 }
198} 197}
199 198
200impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { 199impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarte<'d, U, T> {
201 fn poll_fill_buf( 200 type Error = core::convert::Infallible;
202 mut self: Pin<&mut Self>, 201}
203 cx: &mut Context<'_>, 202
204 ) -> Poll<embassy::io::Result<&[u8]>> { 203impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarte<'d, U, T> {
205 self.inner.with(|state| { 204 type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
206 compiler_fence(Ordering::SeqCst); 205 where
207 trace!("poll_read"); 206 Self: 'a;
208 207
209 // We have data ready in buffer? Return it. 208 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
210 let buf = state.rx.pop_buf(); 209 poll_fn(move |cx| {
211 if !buf.is_empty() { 210 let mut do_pend = false;
212 trace!(" got {:?} {:?}", buf.as_ptr() as u32, buf.len()); 211 let res = self.inner.with(|state| {
213 let buf: &[u8] = buf; 212 compiler_fence(Ordering::SeqCst);
214 let buf: &[u8] = unsafe { mem::transmute(buf) }; 213 trace!("poll_read");
215 return Poll::Ready(Ok(buf)); 214
215 // We have data ready in buffer? Return it.
216 let data = state.rx.pop_buf();
217 if !data.is_empty() {
218 trace!(" got {:?} {:?}", data.as_ptr() as u32, data.len());
219 let len = data.len().min(data.len());
220 buf[..len].copy_from_slice(&data[..len]);
221 state.rx.pop(len);
222 do_pend = true;
223 return Poll::Ready(Ok(len));
224 }
225
226 trace!(" empty");
227 state.rx_waker.register(cx.waker());
228 Poll::Pending
229 });
230 if do_pend {
231 self.inner.pend();
216 } 232 }
217 233
218 trace!(" empty"); 234 res
219 state.rx_waker.register(cx.waker());
220 Poll::<embassy::io::Result<&[u8]>>::Pending
221 }) 235 })
222 } 236 }
223
224 fn consume(mut self: Pin<&mut Self>, amt: usize) {
225 self.inner.with(|state| {
226 trace!("consume {:?}", amt);
227 state.rx.pop(amt);
228 });
229 self.inner.pend();
230 }
231} 237}
232 238
233impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> { 239impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write
234 fn poll_write( 240 for BufferedUarte<'d, U, T>
235 mut self: Pin<&mut Self>, 241{
236 cx: &mut Context<'_>, 242 type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>>
237 buf: &[u8], 243 where
238 ) -> Poll<embassy::io::Result<usize>> { 244 Self: 'a;
239 let poll = self.inner.with(|state| { 245
240 trace!("poll_write: {:?}", buf.len()); 246 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
241 247 poll_fn(move |cx| {
242 let tx_buf = state.tx.push_buf(); 248 let res = self.inner.with(|state| {
243 if tx_buf.is_empty() { 249 trace!("poll_write: {:?}", buf.len());
244 trace!("poll_write: pending"); 250
245 state.tx_waker.register(cx.waker()); 251 let tx_buf = state.tx.push_buf();
246 return Poll::Pending; 252 if tx_buf.is_empty() {
247 } 253 trace!("poll_write: pending");
254 state.tx_waker.register(cx.waker());
255 return Poll::Pending;
256 }
248 257
249 let n = min(tx_buf.len(), buf.len()); 258 let n = min(tx_buf.len(), buf.len());
250 tx_buf[..n].copy_from_slice(&buf[..n]); 259 tx_buf[..n].copy_from_slice(&buf[..n]);
251 state.tx.push(n); 260 state.tx.push(n);
252 261
253 trace!("poll_write: queued {:?}", n); 262 trace!("poll_write: queued {:?}", n);
254 263
255 compiler_fence(Ordering::SeqCst); 264 compiler_fence(Ordering::SeqCst);
256 265
257 Poll::Ready(Ok(n)) 266 Poll::Ready(Ok(n))
258 }); 267 });
259 268
260 self.inner.pend(); 269 self.inner.pend();
261 270
262 poll 271 res
272 })
263 } 273 }
264 274
265 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<embassy::io::Result<()>> { 275 type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>>
266 self.inner.with(|state| { 276 where
267 trace!("poll_flush"); 277 Self: 'a;
268 278
269 if !state.tx.is_empty() { 279 fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> {
270 trace!("poll_flush: pending"); 280 poll_fn(move |cx| {
271 state.tx_waker.register(cx.waker()); 281 self.inner.with(|state| {
272 return Poll::Pending; 282 trace!("poll_flush");
273 } 283
284 if !state.tx.is_empty() {
285 trace!("poll_flush: pending");
286 state.tx_waker.register(cx.waker());
287 return Poll::Pending;
288 }
274 289
275 Poll::Ready(Ok(())) 290 Poll::Ready(Ok(()))
291 })
276 }) 292 })
277 } 293 }
278} 294}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 46234b4b5..9c298a8b0 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -64,6 +64,7 @@ pub(crate) mod util;
64#[cfg(feature = "_time-driver")] 64#[cfg(feature = "_time-driver")]
65mod time_driver; 65mod time_driver;
66 66
67#[cfg(feature = "nightly")]
67pub mod buffered_uarte; 68pub mod buffered_uarte;
68pub mod gpio; 69pub mod gpio;
69#[cfg(feature = "gpiote")] 70#[cfg(feature = "gpiote")]