diff options
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 210 |
1 files changed, 150 insertions, 60 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 62af544ae..c3cba2470 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | //! | 13 | //! |
| 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 | ||
| 16 | use core::cell::RefCell; | ||
| 16 | use core::cmp::min; | 17 | use core::cmp::min; |
| 17 | use core::future::Future; | 18 | use core::future::Future; |
| 18 | use core::sync::atomic::{compiler_fence, Ordering}; | 19 | use core::sync::atomic::{compiler_fence, Ordering}; |
| @@ -71,7 +72,7 @@ struct StateInner<'d, U: UarteInstance, T: TimerInstance> { | |||
| 71 | 72 | ||
| 72 | /// Interface to a UARTE instance | 73 | /// Interface to a UARTE instance |
| 73 | pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { | 74 | pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { |
| 74 | inner: PeripheralMutex<'d, StateInner<'d, U, T>>, | 75 | inner: RefCell<PeripheralMutex<'d, StateInner<'d, U, T>>>, |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} | 78 | impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} |
| @@ -169,7 +170,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 169 | ppi_ch2.enable(); | 170 | ppi_ch2.enable(); |
| 170 | 171 | ||
| 171 | Self { | 172 | Self { |
| 172 | inner: PeripheralMutex::new(irq, &mut state.0, move || StateInner { | 173 | inner: RefCell::new(PeripheralMutex::new(irq, &mut state.0, move || StateInner { |
| 173 | _peri: peri, | 174 | _peri: peri, |
| 174 | timer, | 175 | timer, |
| 175 | _ppi_ch1: ppi_ch1, | 176 | _ppi_ch1: ppi_ch1, |
| @@ -182,13 +183,13 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 182 | tx: RingBuffer::new(tx_buffer), | 183 | tx: RingBuffer::new(tx_buffer), |
| 183 | tx_state: TxState::Idle, | 184 | tx_state: TxState::Idle, |
| 184 | tx_waker: WakerRegistration::new(), | 185 | tx_waker: WakerRegistration::new(), |
| 185 | }), | 186 | })), |
| 186 | } | 187 | } |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | /// Adjust the baud rate to the provided value. | 190 | /// Adjust the baud rate to the provided value. |
| 190 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | 191 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { |
| 191 | self.inner.with(|state| { | 192 | self.inner.borrow_mut().with(|state| { |
| 192 | let r = U::regs(); | 193 | let r = U::regs(); |
| 193 | 194 | ||
| 194 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); | 195 | let timeout = 0x8000_0000 / (baudrate as u32 / 40); |
| @@ -198,21 +199,16 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 198 | r.baudrate.write(|w| w.baudrate().variant(baudrate)); | 199 | r.baudrate.write(|w| w.baudrate().variant(baudrate)); |
| 199 | }); | 200 | }); |
| 200 | } | 201 | } |
| 201 | } | ||
| 202 | |||
| 203 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarte<'d, U, T> { | ||
| 204 | type Error = core::convert::Infallible; | ||
| 205 | } | ||
| 206 | 202 | ||
| 207 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarte<'d, U, T> { | 203 | pub fn split<'u>(&'u mut self) -> (BufferedUarteRx<'u, 'd, U, T>, BufferedUarteTx<'u, 'd, U, T>) { |
| 208 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | 204 | (BufferedUarteRx { inner: self }, BufferedUarteTx { inner: self }) |
| 209 | where | 205 | } |
| 210 | Self: 'a; | ||
| 211 | 206 | ||
| 212 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | 207 | async fn inner_read<'a>(&'a self, buf: &'a mut [u8]) -> Result<usize, core::convert::Infallible> { |
| 213 | poll_fn(move |cx| { | 208 | poll_fn(move |cx| { |
| 214 | let mut do_pend = false; | 209 | let mut do_pend = false; |
| 215 | let res = self.inner.with(|state| { | 210 | let mut inner = self.inner.borrow_mut(); |
| 211 | let res = inner.with(|state| { | ||
| 216 | compiler_fence(Ordering::SeqCst); | 212 | compiler_fence(Ordering::SeqCst); |
| 217 | trace!("poll_read"); | 213 | trace!("poll_read"); |
| 218 | 214 | ||
| @@ -232,22 +228,65 @@ impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for Buffe | |||
| 232 | Poll::Pending | 228 | Poll::Pending |
| 233 | }); | 229 | }); |
| 234 | if do_pend { | 230 | if do_pend { |
| 235 | self.inner.pend(); | 231 | inner.pend(); |
| 236 | } | 232 | } |
| 237 | 233 | ||
| 238 | res | 234 | res |
| 239 | }) | 235 | }) |
| 236 | .await | ||
| 240 | } | 237 | } |
| 241 | } | ||
| 242 | 238 | ||
| 243 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for BufferedUarte<'d, U, T> { | 239 | async fn inner_write<'a>(&'a self, buf: &'a [u8]) -> Result<usize, core::convert::Infallible> { |
| 244 | type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> | 240 | poll_fn(move |cx| { |
| 245 | where | 241 | let mut inner = self.inner.borrow_mut(); |
| 246 | Self: 'a; | 242 | let res = inner.with(|state| { |
| 243 | trace!("poll_write: {:?}", buf.len()); | ||
| 247 | 244 | ||
| 248 | fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> { | 245 | let tx_buf = state.tx.push_buf(); |
| 246 | if tx_buf.is_empty() { | ||
| 247 | trace!("poll_write: pending"); | ||
| 248 | state.tx_waker.register(cx.waker()); | ||
| 249 | return Poll::Pending; | ||
| 250 | } | ||
| 251 | |||
| 252 | let n = min(tx_buf.len(), buf.len()); | ||
| 253 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 254 | state.tx.push(n); | ||
| 255 | |||
| 256 | trace!("poll_write: queued {:?}", n); | ||
| 257 | |||
| 258 | compiler_fence(Ordering::SeqCst); | ||
| 259 | |||
| 260 | Poll::Ready(Ok(n)) | ||
| 261 | }); | ||
| 262 | |||
| 263 | inner.pend(); | ||
| 264 | |||
| 265 | res | ||
| 266 | }) | ||
| 267 | .await | ||
| 268 | } | ||
| 269 | |||
| 270 | async fn inner_flush<'a>(&'a self) -> Result<(), core::convert::Infallible> { | ||
| 249 | poll_fn(move |cx| { | 271 | poll_fn(move |cx| { |
| 250 | self.inner.with(|state| { | 272 | self.inner.borrow_mut().with(|state| { |
| 273 | trace!("poll_flush"); | ||
| 274 | |||
| 275 | if !state.tx.is_empty() { | ||
| 276 | trace!("poll_flush: pending"); | ||
| 277 | state.tx_waker.register(cx.waker()); | ||
| 278 | return Poll::Pending; | ||
| 279 | } | ||
| 280 | |||
| 281 | Poll::Ready(Ok(())) | ||
| 282 | }) | ||
| 283 | }) | ||
| 284 | .await | ||
| 285 | } | ||
| 286 | |||
| 287 | async fn inner_fill_buf<'a>(&'a self) -> Result<&'a [u8], core::convert::Infallible> { | ||
| 288 | poll_fn(move |cx| { | ||
| 289 | self.inner.borrow_mut().with(|state| { | ||
| 251 | compiler_fence(Ordering::SeqCst); | 290 | compiler_fence(Ordering::SeqCst); |
| 252 | trace!("fill_buf"); | 291 | trace!("fill_buf"); |
| 253 | 292 | ||
| @@ -263,55 +302,100 @@ impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for Bu | |||
| 263 | 302 | ||
| 264 | trace!(" empty"); | 303 | trace!(" empty"); |
| 265 | state.rx_waker.register(cx.waker()); | 304 | state.rx_waker.register(cx.waker()); |
| 266 | Poll::<Result<&[u8], Self::Error>>::Pending | 305 | Poll::<Result<&[u8], core::convert::Infallible>>::Pending |
| 267 | }) | 306 | }) |
| 268 | }) | 307 | }) |
| 308 | .await | ||
| 269 | } | 309 | } |
| 270 | 310 | ||
| 271 | fn consume(&mut self, amt: usize) { | 311 | fn inner_consume(&self, amt: usize) { |
| 272 | let signal = self.inner.with(|state| { | 312 | let mut inner = self.inner.borrow_mut(); |
| 313 | let signal = inner.with(|state| { | ||
| 273 | let full = state.rx.is_full(); | 314 | let full = state.rx.is_full(); |
| 274 | state.rx.pop(amt); | 315 | state.rx.pop(amt); |
| 275 | full | 316 | full |
| 276 | }); | 317 | }); |
| 277 | if signal { | 318 | if signal { |
| 278 | self.inner.pend(); | 319 | inner.pend(); |
| 279 | } | 320 | } |
| 280 | } | 321 | } |
| 281 | } | 322 | } |
| 282 | 323 | ||
| 283 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for BufferedUarte<'d, U, T> { | 324 | pub struct BufferedUarteTx<'u, 'd, U: UarteInstance, T: TimerInstance> { |
| 284 | type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | 325 | inner: &'u BufferedUarte<'d, U, T>, |
| 326 | } | ||
| 327 | |||
| 328 | pub struct BufferedUarteRx<'u, 'd, U: UarteInstance, T: TimerInstance> { | ||
| 329 | inner: &'u BufferedUarte<'d, U, T>, | ||
| 330 | } | ||
| 331 | |||
| 332 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarte<'d, U, T> { | ||
| 333 | type Error = core::convert::Infallible; | ||
| 334 | } | ||
| 335 | |||
| 336 | impl<'u, 'd, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarteRx<'u, 'd, U, T> { | ||
| 337 | type Error = core::convert::Infallible; | ||
| 338 | } | ||
| 339 | |||
| 340 | impl<'u, 'd, U: UarteInstance, T: TimerInstance> embedded_io::Io for BufferedUarteTx<'u, 'd, U, T> { | ||
| 341 | type Error = core::convert::Infallible; | ||
| 342 | } | ||
| 343 | |||
| 344 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarte<'d, U, T> { | ||
| 345 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | ||
| 285 | where | 346 | where |
| 286 | Self: 'a; | 347 | Self: 'a; |
| 287 | 348 | ||
| 288 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 349 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 289 | poll_fn(move |cx| { | 350 | self.inner_read(buf) |
| 290 | let res = self.inner.with(|state| { | 351 | } |
| 291 | trace!("poll_write: {:?}", buf.len()); | 352 | } |
| 292 | 353 | ||
| 293 | let tx_buf = state.tx.push_buf(); | 354 | impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Read for BufferedUarteRx<'u, 'd, U, T> { |
| 294 | if tx_buf.is_empty() { | 355 | type ReadFuture<'a> = impl Future<Output = Result<usize, Self::Error>> |
| 295 | trace!("poll_write: pending"); | 356 | where |
| 296 | state.tx_waker.register(cx.waker()); | 357 | Self: 'a; |
| 297 | return Poll::Pending; | ||
| 298 | } | ||
| 299 | 358 | ||
| 300 | let n = min(tx_buf.len(), buf.len()); | 359 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 301 | tx_buf[..n].copy_from_slice(&buf[..n]); | 360 | self.inner.inner_read(buf) |
| 302 | state.tx.push(n); | 361 | } |
| 362 | } | ||
| 303 | 363 | ||
| 304 | trace!("poll_write: queued {:?}", n); | 364 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for BufferedUarte<'d, U, T> { |
| 365 | type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> | ||
| 366 | where | ||
| 367 | Self: 'a; | ||
| 305 | 368 | ||
| 306 | compiler_fence(Ordering::SeqCst); | 369 | fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> { |
| 370 | self.inner_fill_buf() | ||
| 371 | } | ||
| 307 | 372 | ||
| 308 | Poll::Ready(Ok(n)) | 373 | fn consume(&mut self, amt: usize) { |
| 309 | }); | 374 | self.inner_consume(amt) |
| 375 | } | ||
| 376 | } | ||
| 310 | 377 | ||
| 311 | self.inner.pend(); | 378 | impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::BufRead for BufferedUarteRx<'u, 'd, U, T> { |
| 379 | type FillBufFuture<'a> = impl Future<Output = Result<&'a [u8], Self::Error>> | ||
| 380 | where | ||
| 381 | Self: 'a; | ||
| 312 | 382 | ||
| 313 | res | 383 | fn fill_buf<'a>(&'a mut self) -> Self::FillBufFuture<'a> { |
| 314 | }) | 384 | self.inner.inner_fill_buf() |
| 385 | } | ||
| 386 | |||
| 387 | fn consume(&mut self, amt: usize) { | ||
| 388 | self.inner.inner_consume(amt) | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for BufferedUarte<'d, U, T> { | ||
| 393 | type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> | ||
| 394 | where | ||
| 395 | Self: 'a; | ||
| 396 | |||
| 397 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 398 | self.inner_write(buf) | ||
| 315 | } | 399 | } |
| 316 | 400 | ||
| 317 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> | 401 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> |
| @@ -319,19 +403,25 @@ impl<'d, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for Buff | |||
| 319 | Self: 'a; | 403 | Self: 'a; |
| 320 | 404 | ||
| 321 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | 405 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { |
| 322 | poll_fn(move |cx| { | 406 | self.inner_flush() |
| 323 | self.inner.with(|state| { | 407 | } |
| 324 | trace!("poll_flush"); | 408 | } |
| 325 | 409 | ||
| 326 | if !state.tx.is_empty() { | 410 | impl<'u, 'd: 'u, U: UarteInstance, T: TimerInstance> embedded_io::asynch::Write for BufferedUarteTx<'u, 'd, U, T> { |
| 327 | trace!("poll_flush: pending"); | 411 | type WriteFuture<'a> = impl Future<Output = Result<usize, Self::Error>> |
| 328 | state.tx_waker.register(cx.waker()); | 412 | where |
| 329 | return Poll::Pending; | 413 | Self: 'a; |
| 330 | } | ||
| 331 | 414 | ||
| 332 | Poll::Ready(Ok(())) | 415 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { |
| 333 | }) | 416 | self.inner.inner_write(buf) |
| 334 | }) | 417 | } |
| 418 | |||
| 419 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||
| 420 | where | ||
| 421 | Self: 'a; | ||
| 422 | |||
| 423 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 424 | self.inner.inner_flush() | ||
| 335 | } | 425 | } |
| 336 | } | 426 | } |
| 337 | 427 | ||
