diff options
Diffstat (limited to 'embassy-nrf/src/buffered_uarte.rs')
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 229 |
1 files changed, 135 insertions, 94 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 29e126903..40c679190 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -23,6 +23,7 @@ pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | |||
| 23 | 23 | ||
| 24 | use crate::gpio::{AnyPin, Pin as GpioPin}; | 24 | use crate::gpio::{AnyPin, Pin as GpioPin}; |
| 25 | use crate::interrupt::typelevel::Interrupt; | 25 | use crate::interrupt::typelevel::Interrupt; |
| 26 | use crate::interrupt::InterruptExt; | ||
| 26 | use crate::ppi::{ | 27 | use crate::ppi::{ |
| 27 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, | 28 | self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, |
| 28 | }; | 29 | }; |
| @@ -207,21 +208,21 @@ impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for Interrupt | |||
| 207 | } | 208 | } |
| 208 | 209 | ||
| 209 | /// Buffered UARTE driver. | 210 | /// Buffered UARTE driver. |
| 210 | pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> { | 211 | pub struct BufferedUarte<'d> { |
| 211 | tx: BufferedUarteTx<'d, U>, | 212 | tx: BufferedUarteTx<'d>, |
| 212 | rx: BufferedUarteRx<'d, U, T>, | 213 | rx: BufferedUarteRx<'d>, |
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {} | 216 | impl<'d> Unpin for BufferedUarte<'d> {} |
| 216 | 217 | ||
| 217 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | 218 | impl<'d> BufferedUarte<'d> { |
| 218 | /// Create a new BufferedUarte without hardware flow control. | 219 | /// Create a new BufferedUarte without hardware flow control. |
| 219 | /// | 220 | /// |
| 220 | /// # Panics | 221 | /// # Panics |
| 221 | /// | 222 | /// |
| 222 | /// Panics if `rx_buffer.len()` is odd. | 223 | /// Panics if `rx_buffer.len()` is odd. |
| 223 | #[allow(clippy::too_many_arguments)] | 224 | #[allow(clippy::too_many_arguments)] |
| 224 | pub fn new( | 225 | pub fn new<U: UarteInstance, T: TimerInstance>( |
| 225 | uarte: Peri<'d, U>, | 226 | uarte: Peri<'d, U>, |
| 226 | timer: Peri<'d, T>, | 227 | timer: Peri<'d, T>, |
| 227 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, | 228 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, |
| @@ -256,7 +257,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 256 | /// | 257 | /// |
| 257 | /// Panics if `rx_buffer.len()` is odd. | 258 | /// Panics if `rx_buffer.len()` is odd. |
| 258 | #[allow(clippy::too_many_arguments)] | 259 | #[allow(clippy::too_many_arguments)] |
| 259 | pub fn new_with_rtscts( | 260 | pub fn new_with_rtscts<U: UarteInstance, T: TimerInstance>( |
| 260 | uarte: Peri<'d, U>, | 261 | uarte: Peri<'d, U>, |
| 261 | timer: Peri<'d, T>, | 262 | timer: Peri<'d, T>, |
| 262 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, | 263 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, |
| @@ -288,7 +289,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 288 | } | 289 | } |
| 289 | 290 | ||
| 290 | #[allow(clippy::too_many_arguments)] | 291 | #[allow(clippy::too_many_arguments)] |
| 291 | fn new_inner( | 292 | fn new_inner<U: UarteInstance, T: TimerInstance>( |
| 292 | peri: Peri<'d, U>, | 293 | peri: Peri<'d, U>, |
| 293 | timer: Peri<'d, T>, | 294 | timer: Peri<'d, T>, |
| 294 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, | 295 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, |
| @@ -302,30 +303,33 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 302 | rx_buffer: &'d mut [u8], | 303 | rx_buffer: &'d mut [u8], |
| 303 | tx_buffer: &'d mut [u8], | 304 | tx_buffer: &'d mut [u8], |
| 304 | ) -> Self { | 305 | ) -> Self { |
| 305 | configure(U::regs(), config, cts.is_some()); | 306 | let r = U::regs(); |
| 307 | let irq = U::Interrupt::IRQ; | ||
| 308 | let state = U::state(); | ||
| 309 | |||
| 310 | configure(r, config, cts.is_some()); | ||
| 306 | 311 | ||
| 307 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); | 312 | let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer); |
| 308 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 313 | let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 309 | 314 | ||
| 310 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 315 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 311 | U::Interrupt::pend(); | 316 | irq.pend(); |
| 312 | unsafe { U::Interrupt::enable() }; | 317 | unsafe { irq.enable() }; |
| 313 | 318 | ||
| 314 | U::state().tx_rx_refcount.store(2, Ordering::Relaxed); | 319 | state.tx_rx_refcount.store(2, Ordering::Relaxed); |
| 315 | 320 | ||
| 316 | Self { tx, rx } | 321 | Self { tx, rx } |
| 317 | } | 322 | } |
| 318 | 323 | ||
| 319 | /// Adjust the baud rate to the provided value. | 324 | /// Adjust the baud rate to the provided value. |
| 320 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | 325 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { |
| 321 | let r = U::regs(); | 326 | self.tx.set_baudrate(baudrate); |
| 322 | r.baudrate().write(|w| w.set_baudrate(baudrate)); | ||
| 323 | } | 327 | } |
| 324 | 328 | ||
| 325 | /// Split the UART in reader and writer parts. | 329 | /// Split the UART in reader and writer parts. |
| 326 | /// | 330 | /// |
| 327 | /// This allows reading and writing concurrently from independent tasks. | 331 | /// This allows reading and writing concurrently from independent tasks. |
| 328 | pub fn split(self) -> (BufferedUarteRx<'d, U, T>, BufferedUarteTx<'d, U>) { | 332 | pub fn split(self) -> (BufferedUarteRx<'d>, BufferedUarteTx<'d>) { |
| 329 | (self.rx, self.tx) | 333 | (self.rx, self.tx) |
| 330 | } | 334 | } |
| 331 | 335 | ||
| @@ -333,7 +337,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 333 | /// | 337 | /// |
| 334 | /// The returned halves borrow from `self`, so you can drop them and go back to using | 338 | /// The returned halves borrow from `self`, so you can drop them and go back to using |
| 335 | /// the "un-split" `self`. This allows temporarily splitting the UART. | 339 | /// the "un-split" `self`. This allows temporarily splitting the UART. |
| 336 | pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d, U, T>, &mut BufferedUarteTx<'d, U>) { | 340 | pub fn split_by_ref(&mut self) -> (&mut BufferedUarteRx<'d>, &mut BufferedUarteTx<'d>) { |
| 337 | (&mut self.rx, &mut self.tx) | 341 | (&mut self.rx, &mut self.tx) |
| 338 | } | 342 | } |
| 339 | 343 | ||
| @@ -369,13 +373,17 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 369 | } | 373 | } |
| 370 | 374 | ||
| 371 | /// Reader part of the buffered UARTE driver. | 375 | /// Reader part of the buffered UARTE driver. |
| 372 | pub struct BufferedUarteTx<'d, U: UarteInstance> { | 376 | pub struct BufferedUarteTx<'d> { |
| 373 | _peri: Peri<'d, U>, | 377 | r: pac::uarte::Uarte, |
| 378 | _irq: interrupt::Interrupt, | ||
| 379 | state: &'static crate::uarte::State, | ||
| 380 | buffered_state: &'static State, | ||
| 381 | _p: PhantomData<&'d ()>, | ||
| 374 | } | 382 | } |
| 375 | 383 | ||
| 376 | impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | 384 | impl<'d> BufferedUarteTx<'d> { |
| 377 | /// Create a new BufferedUarteTx without hardware flow control. | 385 | /// Create a new BufferedUarteTx without hardware flow control. |
| 378 | pub fn new( | 386 | pub fn new<U: UarteInstance>( |
| 379 | uarte: Peri<'d, U>, | 387 | uarte: Peri<'d, U>, |
| 380 | txd: Peri<'d, impl GpioPin>, | 388 | txd: Peri<'d, impl GpioPin>, |
| 381 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, | 389 | _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd, |
| @@ -390,7 +398,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 390 | /// # Panics | 398 | /// # Panics |
| 391 | /// | 399 | /// |
| 392 | /// Panics if `rx_buffer.len()` is odd. | 400 | /// Panics if `rx_buffer.len()` is odd. |
| 393 | pub fn new_with_cts( | 401 | pub fn new_with_cts<U: UarteInstance>( |
| 394 | uarte: Peri<'d, U>, | 402 | uarte: Peri<'d, U>, |
| 395 | txd: Peri<'d, impl GpioPin>, | 403 | txd: Peri<'d, impl GpioPin>, |
| 396 | cts: Peri<'d, impl GpioPin>, | 404 | cts: Peri<'d, impl GpioPin>, |
| @@ -401,41 +409,48 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 401 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer) | 409 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config, tx_buffer) |
| 402 | } | 410 | } |
| 403 | 411 | ||
| 404 | fn new_inner( | 412 | fn new_inner<U: UarteInstance>( |
| 405 | peri: Peri<'d, U>, | 413 | peri: Peri<'d, U>, |
| 406 | txd: Peri<'d, AnyPin>, | 414 | txd: Peri<'d, AnyPin>, |
| 407 | cts: Option<Peri<'d, AnyPin>>, | 415 | cts: Option<Peri<'d, AnyPin>>, |
| 408 | config: Config, | 416 | config: Config, |
| 409 | tx_buffer: &'d mut [u8], | 417 | tx_buffer: &'d mut [u8], |
| 410 | ) -> Self { | 418 | ) -> Self { |
| 411 | configure(U::regs(), config, cts.is_some()); | 419 | let r = U::regs(); |
| 420 | let irq = U::Interrupt::IRQ; | ||
| 421 | let state = U::state(); | ||
| 422 | let _buffered_state = U::buffered_state(); | ||
| 423 | |||
| 424 | configure(r, config, cts.is_some()); | ||
| 412 | 425 | ||
| 413 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); | 426 | let this = Self::new_innerer(peri, txd, cts, tx_buffer); |
| 414 | 427 | ||
| 415 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 428 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 416 | U::Interrupt::pend(); | 429 | irq.pend(); |
| 417 | unsafe { U::Interrupt::enable() }; | 430 | unsafe { irq.enable() }; |
| 418 | 431 | ||
| 419 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | 432 | state.tx_rx_refcount.store(1, Ordering::Relaxed); |
| 420 | 433 | ||
| 421 | this | 434 | this |
| 422 | } | 435 | } |
| 423 | 436 | ||
| 424 | fn new_innerer( | 437 | fn new_innerer<U: UarteInstance>( |
| 425 | peri: Peri<'d, U>, | 438 | _peri: Peri<'d, U>, |
| 426 | txd: Peri<'d, AnyPin>, | 439 | txd: Peri<'d, AnyPin>, |
| 427 | cts: Option<Peri<'d, AnyPin>>, | 440 | cts: Option<Peri<'d, AnyPin>>, |
| 428 | tx_buffer: &'d mut [u8], | 441 | tx_buffer: &'d mut [u8], |
| 429 | ) -> Self { | 442 | ) -> Self { |
| 430 | let r = U::regs(); | 443 | let r = U::regs(); |
| 444 | let irq = U::Interrupt::IRQ; | ||
| 445 | let state = U::state(); | ||
| 446 | let buffered_state = U::buffered_state(); | ||
| 431 | 447 | ||
| 432 | configure_tx_pins(r, txd, cts); | 448 | configure_tx_pins(r, txd, cts); |
| 433 | 449 | ||
| 434 | // Initialize state | 450 | // Initialize state |
| 435 | let s = U::buffered_state(); | 451 | buffered_state.tx_count.store(0, Ordering::Relaxed); |
| 436 | s.tx_count.store(0, Ordering::Relaxed); | ||
| 437 | let len = tx_buffer.len(); | 452 | let len = tx_buffer.len(); |
| 438 | unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | 453 | unsafe { buffered_state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; |
| 439 | 454 | ||
| 440 | r.events_txstarted().write_value(0); | 455 | r.events_txstarted().write_value(0); |
| 441 | 456 | ||
| @@ -444,15 +459,21 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 444 | w.set_endtx(true); | 459 | w.set_endtx(true); |
| 445 | }); | 460 | }); |
| 446 | 461 | ||
| 447 | Self { _peri: peri } | 462 | Self { |
| 463 | r, | ||
| 464 | _irq: irq, | ||
| 465 | state, | ||
| 466 | buffered_state, | ||
| 467 | _p: PhantomData, | ||
| 468 | } | ||
| 448 | } | 469 | } |
| 449 | 470 | ||
| 450 | /// Write a buffer into this writer, returning how many bytes were written. | 471 | /// Write a buffer into this writer, returning how many bytes were written. |
| 451 | pub fn write<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = Result<usize, Error>> + 'a { | 472 | pub fn write<'a>(&'a mut self, buf: &'a [u8]) -> impl Future<Output = Result<usize, Error>> + 'a + use<'a, 'd> { |
| 452 | poll_fn(move |cx| { | 473 | poll_fn(move |cx| { |
| 453 | //trace!("poll_write: {:?}", buf.len()); | 474 | //trace!("poll_write: {:?}", buf.len()); |
| 454 | let ss = U::state(); | 475 | let ss = self.state; |
| 455 | let s = U::buffered_state(); | 476 | let s = self.buffered_state; |
| 456 | let mut tx = unsafe { s.tx_buf.writer() }; | 477 | let mut tx = unsafe { s.tx_buf.writer() }; |
| 457 | 478 | ||
| 458 | let tx_buf = tx.push_slice(); | 479 | let tx_buf = tx.push_slice(); |
| @@ -469,7 +490,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 469 | //trace!("poll_write: queued {:?}", n); | 490 | //trace!("poll_write: queued {:?}", n); |
| 470 | 491 | ||
| 471 | compiler_fence(Ordering::SeqCst); | 492 | compiler_fence(Ordering::SeqCst); |
| 472 | U::Interrupt::pend(); | 493 | self._irq.pend(); |
| 473 | 494 | ||
| 474 | Poll::Ready(Ok(n)) | 495 | Poll::Ready(Ok(n)) |
| 475 | }) | 496 | }) |
| @@ -478,7 +499,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 478 | /// Try writing a buffer without waiting, returning how many bytes were written. | 499 | /// Try writing a buffer without waiting, returning how many bytes were written. |
| 479 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { | 500 | pub fn try_write(&mut self, buf: &[u8]) -> Result<usize, Error> { |
| 480 | //trace!("poll_write: {:?}", buf.len()); | 501 | //trace!("poll_write: {:?}", buf.len()); |
| 481 | let s = U::buffered_state(); | 502 | let s = self.buffered_state; |
| 482 | let mut tx = unsafe { s.tx_buf.writer() }; | 503 | let mut tx = unsafe { s.tx_buf.writer() }; |
| 483 | 504 | ||
| 484 | let tx_buf = tx.push_slice(); | 505 | let tx_buf = tx.push_slice(); |
| @@ -493,17 +514,17 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 493 | //trace!("poll_write: queued {:?}", n); | 514 | //trace!("poll_write: queued {:?}", n); |
| 494 | 515 | ||
| 495 | compiler_fence(Ordering::SeqCst); | 516 | compiler_fence(Ordering::SeqCst); |
| 496 | U::Interrupt::pend(); | 517 | self._irq.pend(); |
| 497 | 518 | ||
| 498 | Ok(n) | 519 | Ok(n) |
| 499 | } | 520 | } |
| 500 | 521 | ||
| 501 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. | 522 | /// Flush this output stream, ensuring that all intermediately buffered contents reach their destination. |
| 502 | pub fn flush(&mut self) -> impl Future<Output = Result<(), Error>> + '_ { | 523 | pub fn flush(&mut self) -> impl Future<Output = Result<(), Error>> + '_ { |
| 524 | let ss = self.state; | ||
| 525 | let s = self.buffered_state; | ||
| 503 | poll_fn(move |cx| { | 526 | poll_fn(move |cx| { |
| 504 | //trace!("poll_flush"); | 527 | //trace!("poll_flush"); |
| 505 | let ss = U::state(); | ||
| 506 | let s = U::buffered_state(); | ||
| 507 | if !s.tx_buf.is_empty() { | 528 | if !s.tx_buf.is_empty() { |
| 508 | //trace!("poll_flush: pending"); | 529 | //trace!("poll_flush: pending"); |
| 509 | ss.tx_waker.register(cx.waker()); | 530 | ss.tx_waker.register(cx.waker()); |
| @@ -513,11 +534,16 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> { | |||
| 513 | Poll::Ready(Ok(())) | 534 | Poll::Ready(Ok(())) |
| 514 | }) | 535 | }) |
| 515 | } | 536 | } |
| 537 | |||
| 538 | /// Adjust the baud rate to the provided value. | ||
| 539 | pub fn set_baudrate(&mut self, baudrate: Baudrate) { | ||
| 540 | self.r.baudrate().write(|w| w.set_baudrate(baudrate)); | ||
| 541 | } | ||
| 516 | } | 542 | } |
| 517 | 543 | ||
| 518 | impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | 544 | impl<'a> Drop for BufferedUarteTx<'a> { |
| 519 | fn drop(&mut self) { | 545 | fn drop(&mut self) { |
| 520 | let r = U::regs(); | 546 | let r = self.r; |
| 521 | 547 | ||
| 522 | r.intenclr().write(|w| { | 548 | r.intenclr().write(|w| { |
| 523 | w.set_txdrdy(true); | 549 | w.set_txdrdy(true); |
| @@ -528,31 +554,34 @@ impl<'a, U: UarteInstance> Drop for BufferedUarteTx<'a, U> { | |||
| 528 | r.tasks_stoptx().write_value(1); | 554 | r.tasks_stoptx().write_value(1); |
| 529 | while r.events_txstopped().read() == 0 {} | 555 | while r.events_txstopped().read() == 0 {} |
| 530 | 556 | ||
| 531 | let s = U::buffered_state(); | 557 | let s = self.buffered_state; |
| 532 | unsafe { s.tx_buf.deinit() } | 558 | unsafe { s.tx_buf.deinit() } |
| 533 | 559 | ||
| 534 | let s = U::state(); | 560 | let s = self.state; |
| 535 | drop_tx_rx(r, s); | 561 | drop_tx_rx(r, s); |
| 536 | } | 562 | } |
| 537 | } | 563 | } |
| 538 | 564 | ||
| 539 | /// Reader part of the buffered UARTE driver. | 565 | /// Reader part of the buffered UARTE driver. |
| 540 | pub struct BufferedUarteRx<'d, U: UarteInstance, T: TimerInstance> { | 566 | pub struct BufferedUarteRx<'d> { |
| 541 | _peri: Peri<'d, U>, | 567 | r: pac::uarte::Uarte, |
| 542 | timer: Timer<'d, T>, | 568 | state: &'static crate::uarte::State, |
| 569 | buffered_state: &'static State, | ||
| 570 | timer: Timer<'d>, | ||
| 543 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, | 571 | _ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>, |
| 544 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, | 572 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>, |
| 545 | _ppi_group: PpiGroup<'d, AnyGroup>, | 573 | _ppi_group: PpiGroup<'d, AnyGroup>, |
| 574 | _p: PhantomData<&'d ()>, | ||
| 546 | } | 575 | } |
| 547 | 576 | ||
| 548 | impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | 577 | impl<'d> BufferedUarteRx<'d> { |
| 549 | /// Create a new BufferedUarte without hardware flow control. | 578 | /// Create a new BufferedUarte without hardware flow control. |
| 550 | /// | 579 | /// |
| 551 | /// # Panics | 580 | /// # Panics |
| 552 | /// | 581 | /// |
| 553 | /// Panics if `rx_buffer.len()` is odd. | 582 | /// Panics if `rx_buffer.len()` is odd. |
| 554 | #[allow(clippy::too_many_arguments)] | 583 | #[allow(clippy::too_many_arguments)] |
| 555 | pub fn new( | 584 | pub fn new<U: UarteInstance, T: TimerInstance>( |
| 556 | uarte: Peri<'d, U>, | 585 | uarte: Peri<'d, U>, |
| 557 | timer: Peri<'d, T>, | 586 | timer: Peri<'d, T>, |
| 558 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, | 587 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, |
| @@ -582,7 +611,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 582 | /// | 611 | /// |
| 583 | /// Panics if `rx_buffer.len()` is odd. | 612 | /// Panics if `rx_buffer.len()` is odd. |
| 584 | #[allow(clippy::too_many_arguments)] | 613 | #[allow(clippy::too_many_arguments)] |
| 585 | pub fn new_with_rts( | 614 | pub fn new_with_rts<U: UarteInstance, T: TimerInstance>( |
| 586 | uarte: Peri<'d, U>, | 615 | uarte: Peri<'d, U>, |
| 587 | timer: Peri<'d, T>, | 616 | timer: Peri<'d, T>, |
| 588 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, | 617 | ppi_ch1: Peri<'d, impl ConfigurableChannel>, |
| @@ -608,7 +637,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 608 | } | 637 | } |
| 609 | 638 | ||
| 610 | #[allow(clippy::too_many_arguments)] | 639 | #[allow(clippy::too_many_arguments)] |
| 611 | fn new_inner( | 640 | fn new_inner<U: UarteInstance, T: TimerInstance>( |
| 612 | peri: Peri<'d, U>, | 641 | peri: Peri<'d, U>, |
| 613 | timer: Peri<'d, T>, | 642 | timer: Peri<'d, T>, |
| 614 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, | 643 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, |
| @@ -619,22 +648,27 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 619 | config: Config, | 648 | config: Config, |
| 620 | rx_buffer: &'d mut [u8], | 649 | rx_buffer: &'d mut [u8], |
| 621 | ) -> Self { | 650 | ) -> Self { |
| 622 | configure(U::regs(), config, rts.is_some()); | 651 | let r = U::regs(); |
| 652 | let irq = U::Interrupt::IRQ; | ||
| 653 | let state = U::state(); | ||
| 654 | let _buffered_state = U::buffered_state(); | ||
| 655 | |||
| 656 | configure(r, config, rts.is_some()); | ||
| 623 | 657 | ||
| 624 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); | 658 | let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer); |
| 625 | 659 | ||
| 626 | U::regs().enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 660 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 627 | U::Interrupt::pend(); | 661 | irq.pend(); |
| 628 | unsafe { U::Interrupt::enable() }; | 662 | unsafe { irq.enable() }; |
| 629 | 663 | ||
| 630 | U::state().tx_rx_refcount.store(1, Ordering::Relaxed); | 664 | state.tx_rx_refcount.store(1, Ordering::Relaxed); |
| 631 | 665 | ||
| 632 | this | 666 | this |
| 633 | } | 667 | } |
| 634 | 668 | ||
| 635 | #[allow(clippy::too_many_arguments)] | 669 | #[allow(clippy::too_many_arguments)] |
| 636 | fn new_innerer( | 670 | fn new_innerer<U: UarteInstance, T: TimerInstance>( |
| 637 | peri: Peri<'d, U>, | 671 | _peri: Peri<'d, U>, |
| 638 | timer: Peri<'d, T>, | 672 | timer: Peri<'d, T>, |
| 639 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, | 673 | ppi_ch1: Peri<'d, AnyConfigurableChannel>, |
| 640 | ppi_ch2: Peri<'d, AnyConfigurableChannel>, | 674 | ppi_ch2: Peri<'d, AnyConfigurableChannel>, |
| @@ -646,16 +680,17 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 646 | assert!(rx_buffer.len() % 2 == 0); | 680 | assert!(rx_buffer.len() % 2 == 0); |
| 647 | 681 | ||
| 648 | let r = U::regs(); | 682 | let r = U::regs(); |
| 683 | let state = U::state(); | ||
| 684 | let buffered_state = U::buffered_state(); | ||
| 649 | 685 | ||
| 650 | configure_rx_pins(r, rxd, rts); | 686 | configure_rx_pins(r, rxd, rts); |
| 651 | 687 | ||
| 652 | // Initialize state | 688 | // Initialize state |
| 653 | let s = U::buffered_state(); | 689 | buffered_state.rx_started_count.store(0, Ordering::Relaxed); |
| 654 | s.rx_started_count.store(0, Ordering::Relaxed); | 690 | buffered_state.rx_ended_count.store(0, Ordering::Relaxed); |
| 655 | s.rx_ended_count.store(0, Ordering::Relaxed); | 691 | buffered_state.rx_started.store(false, Ordering::Relaxed); |
| 656 | s.rx_started.store(false, Ordering::Relaxed); | ||
| 657 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); | 692 | let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2); |
| 658 | unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; | 693 | unsafe { buffered_state.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) }; |
| 659 | 694 | ||
| 660 | // clear errors | 695 | // clear errors |
| 661 | let errors = r.errorsrc().read(); | 696 | let errors = r.errorsrc().read(); |
| @@ -683,7 +718,9 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 683 | let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(r.events_rxdrdy()), timer.task_count()); | 718 | let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(r.events_rxdrdy()), timer.task_count()); |
| 684 | ppi_ch1.enable(); | 719 | ppi_ch1.enable(); |
| 685 | 720 | ||
| 686 | s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed); | 721 | buffered_state |
| 722 | .rx_ppi_ch | ||
| 723 | .store(ppi_ch2.number() as u8, Ordering::Relaxed); | ||
| 687 | let mut ppi_group = PpiGroup::new(ppi_group); | 724 | let mut ppi_group = PpiGroup::new(ppi_group); |
| 688 | let mut ppi_ch2 = Ppi::new_one_to_two( | 725 | let mut ppi_ch2 = Ppi::new_one_to_two( |
| 689 | ppi_ch2, | 726 | ppi_ch2, |
| @@ -695,11 +732,14 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 695 | ppi_group.add_channel(&ppi_ch2); | 732 | ppi_group.add_channel(&ppi_ch2); |
| 696 | 733 | ||
| 697 | Self { | 734 | Self { |
| 698 | _peri: peri, | 735 | r, |
| 736 | state, | ||
| 737 | buffered_state, | ||
| 699 | timer, | 738 | timer, |
| 700 | _ppi_ch1: ppi_ch1, | 739 | _ppi_ch1: ppi_ch1, |
| 701 | _ppi_ch2: ppi_ch2, | 740 | _ppi_ch2: ppi_ch2, |
| 702 | _ppi_group: ppi_group, | 741 | _ppi_group: ppi_group, |
| 742 | _p: PhantomData, | ||
| 703 | } | 743 | } |
| 704 | } | 744 | } |
| 705 | 745 | ||
| @@ -714,17 +754,17 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 714 | 754 | ||
| 715 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. | 755 | /// Return the contents of the internal buffer, filling it with more data from the inner reader if it is empty. |
| 716 | pub fn fill_buf(&mut self) -> impl Future<Output = Result<&'_ [u8], Error>> { | 756 | pub fn fill_buf(&mut self) -> impl Future<Output = Result<&'_ [u8], Error>> { |
| 757 | let r = self.r; | ||
| 758 | let s = self.buffered_state; | ||
| 759 | let ss = self.state; | ||
| 760 | let timer = &self.timer; | ||
| 717 | poll_fn(move |cx| { | 761 | poll_fn(move |cx| { |
| 718 | compiler_fence(Ordering::SeqCst); | 762 | compiler_fence(Ordering::SeqCst); |
| 719 | //trace!("poll_read"); | 763 | //trace!("poll_read"); |
| 720 | 764 | ||
| 721 | let r = U::regs(); | ||
| 722 | let s = U::buffered_state(); | ||
| 723 | let ss = U::state(); | ||
| 724 | |||
| 725 | // Read the RXDRDY counter. | 765 | // Read the RXDRDY counter. |
| 726 | T::regs().tasks_capture(0).write_value(1); | 766 | timer.cc(0).capture(); |
| 727 | let mut end = T::regs().cc(0).read() as usize; | 767 | let mut end = timer.cc(0).read() as usize; |
| 728 | //trace!(" rxdrdy count = {:?}", end); | 768 | //trace!(" rxdrdy count = {:?}", end); |
| 729 | 769 | ||
| 730 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. | 770 | // We've set a compare channel that resets the counter to 0 when it reaches `len*2`. |
| @@ -771,24 +811,24 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> { | |||
| 771 | return; | 811 | return; |
| 772 | } | 812 | } |
| 773 | 813 | ||
| 774 | let s = U::buffered_state(); | 814 | let s = self.buffered_state; |
| 775 | let mut rx = unsafe { s.rx_buf.reader() }; | 815 | let mut rx = unsafe { s.rx_buf.reader() }; |
| 776 | rx.pop_done(amt); | 816 | rx.pop_done(amt); |
| 777 | U::regs().intenset().write(|w| w.set_rxstarted(true)); | 817 | self.r.intenset().write(|w| w.set_rxstarted(true)); |
| 778 | } | 818 | } |
| 779 | 819 | ||
| 780 | /// we are ready to read if there is data in the buffer | 820 | /// we are ready to read if there is data in the buffer |
| 781 | fn read_ready() -> Result<bool, Error> { | 821 | fn read_ready(&self) -> Result<bool, Error> { |
| 782 | let state = U::buffered_state(); | 822 | let state = self.buffered_state; |
| 783 | Ok(!state.rx_buf.is_empty()) | 823 | Ok(!state.rx_buf.is_empty()) |
| 784 | } | 824 | } |
| 785 | } | 825 | } |
| 786 | 826 | ||
| 787 | impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T> { | 827 | impl<'a> Drop for BufferedUarteRx<'a> { |
| 788 | fn drop(&mut self) { | 828 | fn drop(&mut self) { |
| 789 | self._ppi_group.disable_all(); | 829 | self._ppi_group.disable_all(); |
| 790 | 830 | ||
| 791 | let r = U::regs(); | 831 | let r = self.r; |
| 792 | 832 | ||
| 793 | self.timer.stop(); | 833 | self.timer.stop(); |
| 794 | 834 | ||
| @@ -801,10 +841,10 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for BufferedUarteRx<'a, U, T> | |||
| 801 | r.tasks_stoprx().write_value(1); | 841 | r.tasks_stoprx().write_value(1); |
| 802 | while r.events_rxto().read() == 0 {} | 842 | while r.events_rxto().read() == 0 {} |
| 803 | 843 | ||
| 804 | let s = U::buffered_state(); | 844 | let s = self.buffered_state; |
| 805 | unsafe { s.rx_buf.deinit() } | 845 | unsafe { s.rx_buf.deinit() } |
| 806 | 846 | ||
| 807 | let s = U::state(); | 847 | let s = self.state; |
| 808 | drop_tx_rx(r, s); | 848 | drop_tx_rx(r, s); |
| 809 | } | 849 | } |
| 810 | } | 850 | } |
| @@ -818,43 +858,44 @@ mod _embedded_io { | |||
| 818 | } | 858 | } |
| 819 | } | 859 | } |
| 820 | 860 | ||
| 821 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarte<'d, U, T> { | 861 | impl<'d> embedded_io_async::ErrorType for BufferedUarte<'d> { |
| 822 | type Error = Error; | 862 | type Error = Error; |
| 823 | } | 863 | } |
| 824 | 864 | ||
| 825 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::ErrorType for BufferedUarteRx<'d, U, T> { | 865 | impl<'d> embedded_io_async::ErrorType for BufferedUarteRx<'d> { |
| 826 | type Error = Error; | 866 | type Error = Error; |
| 827 | } | 867 | } |
| 828 | 868 | ||
| 829 | impl<'d, U: UarteInstance> embedded_io_async::ErrorType for BufferedUarteTx<'d, U> { | 869 | impl<'d> embedded_io_async::ErrorType for BufferedUarteTx<'d> { |
| 830 | type Error = Error; | 870 | type Error = Error; |
| 831 | } | 871 | } |
| 832 | 872 | ||
| 833 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarte<'d, U, T> { | 873 | impl<'d> embedded_io_async::Read for BufferedUarte<'d> { |
| 834 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 874 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 835 | self.read(buf).await | 875 | self.read(buf).await |
| 836 | } | 876 | } |
| 837 | } | 877 | } |
| 838 | 878 | ||
| 839 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::Read for BufferedUarteRx<'d, U, T> { | 879 | impl<'d> embedded_io_async::Read for BufferedUarteRx<'d> { |
| 840 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { | 880 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 841 | self.read(buf).await | 881 | self.read(buf).await |
| 842 | } | 882 | } |
| 843 | } | 883 | } |
| 844 | 884 | ||
| 845 | impl<'d, U: UarteInstance, T: TimerInstance + 'd> embedded_io_async::ReadReady for BufferedUarte<'d, U, T> { | 885 | impl<'d> embedded_io_async::ReadReady for BufferedUarte<'d> { |
| 846 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 886 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 847 | BufferedUarteRx::<'d, U, T>::read_ready() | 887 | self.rx.read_ready() |
| 848 | } | 888 | } |
| 849 | } | 889 | } |
| 850 | 890 | ||
| 851 | impl<'d, U: UarteInstance, T: TimerInstance + 'd> embedded_io_async::ReadReady for BufferedUarteRx<'d, U, T> { | 891 | impl<'d> embedded_io_async::ReadReady for BufferedUarteRx<'d> { |
| 852 | fn read_ready(&mut self) -> Result<bool, Self::Error> { | 892 | fn read_ready(&mut self) -> Result<bool, Self::Error> { |
| 853 | Self::read_ready() | 893 | let state = self.buffered_state; |
| 894 | Ok(!state.rx_buf.is_empty()) | ||
| 854 | } | 895 | } |
| 855 | } | 896 | } |
| 856 | 897 | ||
| 857 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarte<'d, U, T> { | 898 | impl<'d> embedded_io_async::BufRead for BufferedUarte<'d> { |
| 858 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 899 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 859 | self.fill_buf().await | 900 | self.fill_buf().await |
| 860 | } | 901 | } |
| @@ -864,7 +905,7 @@ mod _embedded_io { | |||
| 864 | } | 905 | } |
| 865 | } | 906 | } |
| 866 | 907 | ||
| 867 | impl<'d: 'd, U: UarteInstance, T: TimerInstance> embedded_io_async::BufRead for BufferedUarteRx<'d, U, T> { | 908 | impl<'d> embedded_io_async::BufRead for BufferedUarteRx<'d> { |
| 868 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { | 909 | async fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 869 | self.fill_buf().await | 910 | self.fill_buf().await |
| 870 | } | 911 | } |
| @@ -874,7 +915,7 @@ mod _embedded_io { | |||
| 874 | } | 915 | } |
| 875 | } | 916 | } |
| 876 | 917 | ||
| 877 | impl<'d, U: UarteInstance, T: TimerInstance> embedded_io_async::Write for BufferedUarte<'d, U, T> { | 918 | impl<'d> embedded_io_async::Write for BufferedUarte<'d> { |
| 878 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 919 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 879 | self.write(buf).await | 920 | self.write(buf).await |
| 880 | } | 921 | } |
| @@ -884,7 +925,7 @@ mod _embedded_io { | |||
| 884 | } | 925 | } |
| 885 | } | 926 | } |
| 886 | 927 | ||
| 887 | impl<'d: 'd, U: UarteInstance> embedded_io_async::Write for BufferedUarteTx<'d, U> { | 928 | impl<'d> embedded_io_async::Write for BufferedUarteTx<'d> { |
| 888 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 929 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 889 | self.write(buf).await | 930 | self.write(buf).await |
| 890 | } | 931 | } |
