aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
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/src
parent108a98136096f8b530266aa6687bdbbed4a6a382 (diff)
parenta4bf190f2f0ce28a298626de6de1c8059269cedc (diff)
Merge branch 'embassy-rs:master' into qdec
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs144
-rw-r--r--embassy-nrf/src/lib.rs1
2 files changed, 81 insertions, 64 deletions
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")]