diff options
| author | Mathias <[email protected]> | 2022-09-21 06:00:35 +0200 |
|---|---|---|
| committer | Mathias <[email protected]> | 2022-09-21 06:00:35 +0200 |
| commit | 1d3e41f970c1b04fc98533a0a6d09cb5be85ff09 (patch) | |
| tree | 9ad63d8e67ee8ef1889a58b3af6c771f45aabfe7 | |
| parent | c495c765df42ca273da55b320c869b0aaabc6ef8 (diff) | |
Remove code-duplication in async bufferedUart implementations
| -rw-r--r-- | embassy-rp/src/uart/buffered.rs | 215 |
1 files changed, 89 insertions, 126 deletions
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs index 3eb96e3d5..6d395b6f4 100644 --- a/embassy-rp/src/uart/buffered.rs +++ b/embassy-rp/src/uart/buffered.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use core::future::Future; | 1 | use core::future::Future; |
| 2 | use core::task::Poll; | 2 | use core::task::{Poll, Waker}; |
| 3 | 3 | ||
| 4 | use atomic_polyfill::{compiler_fence, Ordering}; | 4 | use atomic_polyfill::{compiler_fence, Ordering}; |
| 5 | use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; | 5 | use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage}; |
| @@ -87,9 +87,9 @@ impl<'d, T: Instance> BufferedUart<'d, T> { | |||
| 87 | let r = T::regs(); | 87 | let r = T::regs(); |
| 88 | unsafe { | 88 | unsafe { |
| 89 | r.uartimsc().modify(|w| { | 89 | r.uartimsc().modify(|w| { |
| 90 | // TODO: Should and more or fewer interrupts be enabled? | ||
| 91 | w.set_rxim(true); | 90 | w.set_rxim(true); |
| 92 | w.set_rtim(true); | 91 | w.set_rtim(true); |
| 92 | w.set_txim(true); | ||
| 93 | }); | 93 | }); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| @@ -122,7 +122,6 @@ impl<'d, T: Instance> RxBufferedUart<'d, T> { | |||
| 122 | let r = T::regs(); | 122 | let r = T::regs(); |
| 123 | unsafe { | 123 | unsafe { |
| 124 | r.uartimsc().modify(|w| { | 124 | r.uartimsc().modify(|w| { |
| 125 | // TODO: Should and more or fewer interrupts be enabled? | ||
| 126 | w.set_rxim(true); | 125 | w.set_rxim(true); |
| 127 | w.set_rtim(true); | 126 | w.set_rtim(true); |
| 128 | }); | 127 | }); |
| @@ -151,9 +150,7 @@ impl<'d, T: Instance> TxBufferedUart<'d, T> { | |||
| 151 | let r = T::regs(); | 150 | let r = T::regs(); |
| 152 | unsafe { | 151 | unsafe { |
| 153 | r.uartimsc().modify(|w| { | 152 | r.uartimsc().modify(|w| { |
| 154 | // TODO: Should and more or fewer interrupts be enabled? | 153 | w.set_txim(true); |
| 155 | w.set_rxim(true); | ||
| 156 | w.set_rtim(true); | ||
| 157 | }); | 154 | }); |
| 158 | } | 155 | } |
| 159 | 156 | ||
| @@ -179,6 +176,51 @@ where | |||
| 179 | } | 176 | } |
| 180 | } | 177 | } |
| 181 | 178 | ||
| 179 | impl<'d, T: Instance> RxStateInner<'d, T> | ||
| 180 | where | ||
| 181 | Self: 'd, | ||
| 182 | { | ||
| 183 | fn read(&mut self, buf: &mut [u8], waker: &Waker) -> (Poll<Result<usize, Error>>, bool) { | ||
| 184 | // We have data ready in buffer? Return it. | ||
| 185 | let mut do_pend = false; | ||
| 186 | let data = self.buf.pop_buf(); | ||
| 187 | if !data.is_empty() { | ||
| 188 | let len = data.len().min(buf.len()); | ||
| 189 | buf[..len].copy_from_slice(&data[..len]); | ||
| 190 | |||
| 191 | if self.buf.is_full() { | ||
| 192 | do_pend = true; | ||
| 193 | } | ||
| 194 | self.buf.pop(len); | ||
| 195 | |||
| 196 | return (Poll::Ready(Ok(len)), do_pend); | ||
| 197 | } | ||
| 198 | |||
| 199 | self.waker.register(waker); | ||
| 200 | (Poll::Pending, do_pend) | ||
| 201 | } | ||
| 202 | |||
| 203 | fn fill_buf<'a>(&mut self, waker: &Waker) -> Poll<Result<&'a [u8], Error>> { | ||
| 204 | // We have data ready in buffer? Return it. | ||
| 205 | let buf = self.buf.pop_buf(); | ||
| 206 | if !buf.is_empty() { | ||
| 207 | let buf: &[u8] = buf; | ||
| 208 | // Safety: buffer lives as long as uart | ||
| 209 | let buf: &[u8] = unsafe { core::mem::transmute(buf) }; | ||
| 210 | return Poll::Ready(Ok(buf)); | ||
| 211 | } | ||
| 212 | |||
| 213 | self.waker.register(waker); | ||
| 214 | Poll::Pending | ||
| 215 | } | ||
| 216 | |||
| 217 | fn consume(&mut self, amt: usize) -> bool { | ||
| 218 | let full = self.buf.is_full(); | ||
| 219 | self.buf.pop(amt); | ||
| 220 | full | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 182 | impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T> | 224 | impl<'d, T: Instance> PeripheralState for RxStateInner<'d, T> |
| 183 | where | 225 | where |
| 184 | Self: 'd, | 226 | Self: 'd, |
| @@ -240,6 +282,35 @@ where | |||
| 240 | } | 282 | } |
| 241 | } | 283 | } |
| 242 | 284 | ||
| 285 | impl<'d, T: Instance> TxStateInner<'d, T> | ||
| 286 | where | ||
| 287 | Self: 'd, | ||
| 288 | { | ||
| 289 | fn write(&mut self, buf: &[u8], waker: &Waker) -> (Poll<Result<usize, Error>>, bool) { | ||
| 290 | let empty = self.buf.is_empty(); | ||
| 291 | let tx_buf = self.buf.push_buf(); | ||
| 292 | if tx_buf.is_empty() { | ||
| 293 | self.waker.register(waker); | ||
| 294 | return (Poll::Pending, empty); | ||
| 295 | } | ||
| 296 | |||
| 297 | let n = core::cmp::min(tx_buf.len(), buf.len()); | ||
| 298 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 299 | self.buf.push(n); | ||
| 300 | |||
| 301 | (Poll::Ready(Ok(n)), empty) | ||
| 302 | } | ||
| 303 | |||
| 304 | fn flush(&mut self, waker: &Waker) -> Poll<Result<(), Error>> { | ||
| 305 | if !self.buf.is_empty() { | ||
| 306 | self.waker.register(waker); | ||
| 307 | return Poll::Pending; | ||
| 308 | } | ||
| 309 | |||
| 310 | Poll::Ready(Ok(())) | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 243 | impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T> | 314 | impl<'d, T: Instance> PeripheralState for TxStateInner<'d, T> |
| 244 | where | 315 | where |
| 245 | Self: 'd, | 316 | Self: 'd, |
| @@ -299,26 +370,9 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for BufferedUart<'d, T> { | |||
| 299 | 370 | ||
| 300 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | 371 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 301 | poll_fn(move |cx| { | 372 | poll_fn(move |cx| { |
| 302 | let mut do_pend = false; | 373 | let (res, do_pend) = self.inner.with(|state| { |
| 303 | let res = self.inner.with(|state| { | ||
| 304 | compiler_fence(Ordering::SeqCst); | 374 | compiler_fence(Ordering::SeqCst); |
| 305 | 375 | state.rx.read(buf, cx.waker()) | |
| 306 | // We have data ready in buffer? Return it. | ||
| 307 | let data = state.rx.buf.pop_buf(); | ||
| 308 | if !data.is_empty() { | ||
| 309 | let len = data.len().min(buf.len()); | ||
| 310 | buf[..len].copy_from_slice(&data[..len]); | ||
| 311 | |||
| 312 | if state.rx.buf.is_full() { | ||
| 313 | do_pend = true; | ||
| 314 | } | ||
| 315 | state.rx.buf.pop(len); | ||
| 316 | |||
| 317 | return Poll::Ready(Ok(len)); | ||
| 318 | } | ||
| 319 | |||
| 320 | state.rx.waker.register(cx.waker()); | ||
| 321 | Poll::Pending | ||
| 322 | }); | 376 | }); |
| 323 | 377 | ||
| 324 | if do_pend { | 378 | if do_pend { |
| @@ -337,26 +391,9 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Read for RxBufferedUart<'d, T> { | |||
| 337 | 391 | ||
| 338 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { | 392 | fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { |
| 339 | poll_fn(move |cx| { | 393 | poll_fn(move |cx| { |
| 340 | let mut do_pend = false; | 394 | let (res, do_pend) = self.inner.with(|state| { |
| 341 | let res = self.inner.with(|state| { | ||
| 342 | compiler_fence(Ordering::SeqCst); | 395 | compiler_fence(Ordering::SeqCst); |
| 343 | 396 | state.read(buf, cx.waker()) | |
| 344 | // We have data ready in buffer? Return it. | ||
| 345 | let data = state.buf.pop_buf(); | ||
| 346 | if !data.is_empty() { | ||
| 347 | let len = data.len().min(buf.len()); | ||
| 348 | buf[..len].copy_from_slice(&data[..len]); | ||
| 349 | |||
| 350 | if state.buf.is_full() { | ||
| 351 | do_pend = true; | ||
| 352 | } | ||
| 353 | state.buf.pop(len); | ||
| 354 | |||
| 355 | return Poll::Ready(Ok(len)); | ||
| 356 | } | ||
| 357 | |||
| 358 | state.waker.register(cx.waker()); | ||
| 359 | Poll::Pending | ||
| 360 | }); | 397 | }); |
| 361 | 398 | ||
| 362 | if do_pend { | 399 | if do_pend { |
| @@ -377,28 +414,13 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for BufferedUart<'d, T> | |||
| 377 | poll_fn(move |cx| { | 414 | poll_fn(move |cx| { |
| 378 | self.inner.with(|state| { | 415 | self.inner.with(|state| { |
| 379 | compiler_fence(Ordering::SeqCst); | 416 | compiler_fence(Ordering::SeqCst); |
| 380 | 417 | state.rx.fill_buf(cx.waker()) | |
| 381 | // We have data ready in buffer? Return it. | ||
| 382 | let buf = state.rx.buf.pop_buf(); | ||
| 383 | if !buf.is_empty() { | ||
| 384 | let buf: &[u8] = buf; | ||
| 385 | // Safety: buffer lives as long as uart | ||
| 386 | let buf: &[u8] = unsafe { core::mem::transmute(buf) }; | ||
| 387 | return Poll::Ready(Ok(buf)); | ||
| 388 | } | ||
| 389 | |||
| 390 | state.rx.waker.register(cx.waker()); | ||
| 391 | Poll::<Result<&[u8], Self::Error>>::Pending | ||
| 392 | }) | 418 | }) |
| 393 | }) | 419 | }) |
| 394 | } | 420 | } |
| 395 | 421 | ||
| 396 | fn consume(&mut self, amt: usize) { | 422 | fn consume(&mut self, amt: usize) { |
| 397 | let signal = self.inner.with(|state| { | 423 | let signal = self.inner.with(|state| state.rx.consume(amt)); |
| 398 | let full = state.rx.buf.is_full(); | ||
| 399 | state.rx.buf.pop(amt); | ||
| 400 | full | ||
| 401 | }); | ||
| 402 | if signal { | 424 | if signal { |
| 403 | self.inner.pend(); | 425 | self.inner.pend(); |
| 404 | } | 426 | } |
| @@ -414,28 +436,13 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::BufRead for RxBufferedUart<'d, T | |||
| 414 | poll_fn(move |cx| { | 436 | poll_fn(move |cx| { |
| 415 | self.inner.with(|state| { | 437 | self.inner.with(|state| { |
| 416 | compiler_fence(Ordering::SeqCst); | 438 | compiler_fence(Ordering::SeqCst); |
| 417 | 439 | state.fill_buf(cx.waker()) | |
| 418 | // We have data ready in buffer? Return it. | ||
| 419 | let buf = state.buf.pop_buf(); | ||
| 420 | if !buf.is_empty() { | ||
| 421 | let buf: &[u8] = buf; | ||
| 422 | // Safety: buffer lives as long as uart | ||
| 423 | let buf: &[u8] = unsafe { core::mem::transmute(buf) }; | ||
| 424 | return Poll::Ready(Ok(buf)); | ||
| 425 | } | ||
| 426 | |||
| 427 | state.waker.register(cx.waker()); | ||
| 428 | Poll::<Result<&[u8], Self::Error>>::Pending | ||
| 429 | }) | 440 | }) |
| 430 | }) | 441 | }) |
| 431 | } | 442 | } |
| 432 | 443 | ||
| 433 | fn consume(&mut self, amt: usize) { | 444 | fn consume(&mut self, amt: usize) { |
| 434 | let signal = self.inner.with(|state| { | 445 | let signal = self.inner.with(|state| state.consume(amt)); |
| 435 | let full = state.buf.is_full(); | ||
| 436 | state.buf.pop(amt); | ||
| 437 | full | ||
| 438 | }); | ||
| 439 | if signal { | 446 | if signal { |
| 440 | self.inner.pend(); | 447 | self.inner.pend(); |
| 441 | } | 448 | } |
| @@ -449,20 +456,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> { | |||
| 449 | 456 | ||
| 450 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 457 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { |
| 451 | poll_fn(move |cx| { | 458 | poll_fn(move |cx| { |
| 452 | let (poll, empty) = self.inner.with(|state| { | 459 | let (poll, empty) = self.inner.with(|state| state.tx.write(buf, cx.waker())); |
| 453 | let empty = state.tx.buf.is_empty(); | ||
| 454 | let tx_buf = state.tx.buf.push_buf(); | ||
| 455 | if tx_buf.is_empty() { | ||
| 456 | state.tx.waker.register(cx.waker()); | ||
| 457 | return (Poll::Pending, empty); | ||
| 458 | } | ||
| 459 | |||
| 460 | let n = core::cmp::min(tx_buf.len(), buf.len()); | ||
| 461 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 462 | state.tx.buf.push(n); | ||
| 463 | |||
| 464 | (Poll::Ready(Ok(n)), empty) | ||
| 465 | }); | ||
| 466 | if empty { | 460 | if empty { |
| 467 | self.inner.pend(); | 461 | self.inner.pend(); |
| 468 | } | 462 | } |
| @@ -475,16 +469,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for BufferedUart<'d, T> { | |||
| 475 | Self: 'a; | 469 | Self: 'a; |
| 476 | 470 | ||
| 477 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | 471 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { |
| 478 | poll_fn(move |cx| { | 472 | poll_fn(move |cx| self.inner.with(|state| state.tx.flush(cx.waker()))) |
| 479 | self.inner.with(|state| { | ||
| 480 | if !state.tx.buf.is_empty() { | ||
| 481 | state.tx.waker.register(cx.waker()); | ||
| 482 | return Poll::Pending; | ||
| 483 | } | ||
| 484 | |||
| 485 | Poll::Ready(Ok(())) | ||
| 486 | }) | ||
| 487 | }) | ||
| 488 | } | 473 | } |
| 489 | } | 474 | } |
| 490 | 475 | ||
| @@ -495,20 +480,7 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T> | |||
| 495 | 480 | ||
| 496 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { | 481 | fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> { |
| 497 | poll_fn(move |cx| { | 482 | poll_fn(move |cx| { |
| 498 | let (poll, empty) = self.inner.with(|state| { | 483 | let (poll, empty) = self.inner.with(|state| state.write(buf, cx.waker())); |
| 499 | let empty = state.buf.is_empty(); | ||
| 500 | let tx_buf = state.buf.push_buf(); | ||
| 501 | if tx_buf.is_empty() { | ||
| 502 | state.waker.register(cx.waker()); | ||
| 503 | return (Poll::Pending, empty); | ||
| 504 | } | ||
| 505 | |||
| 506 | let n = core::cmp::min(tx_buf.len(), buf.len()); | ||
| 507 | tx_buf[..n].copy_from_slice(&buf[..n]); | ||
| 508 | state.buf.push(n); | ||
| 509 | |||
| 510 | (Poll::Ready(Ok(n)), empty) | ||
| 511 | }); | ||
| 512 | if empty { | 484 | if empty { |
| 513 | self.inner.pend(); | 485 | self.inner.pend(); |
| 514 | } | 486 | } |
| @@ -521,15 +493,6 @@ impl<'d, T: Instance + 'd> embedded_io::asynch::Write for TxBufferedUart<'d, T> | |||
| 521 | Self: 'a; | 493 | Self: 'a; |
| 522 | 494 | ||
| 523 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | 495 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { |
| 524 | poll_fn(move |cx| { | 496 | poll_fn(move |cx| self.inner.with(|state| state.flush(cx.waker()))) |
| 525 | self.inner.with(|state| { | ||
| 526 | if !state.buf.is_empty() { | ||
| 527 | state.waker.register(cx.waker()); | ||
| 528 | return Poll::Pending; | ||
| 529 | } | ||
| 530 | |||
| 531 | Poll::Ready(Ok(())) | ||
| 532 | }) | ||
| 533 | }) | ||
| 534 | } | 497 | } |
| 535 | } | 498 | } |
