diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-28 20:58:10 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-09-28 20:58:10 +0000 |
| commit | 5fc197529e4260196f99e8d6341a37d7e623c9f6 (patch) | |
| tree | 332718f0fd84026562d3ebd0b1acec60696a9479 | |
| parent | b29c7295e406045ec137b78ca5f220bf7909006b (diff) | |
| parent | 864eaef3a3f7678bcc4ff20b5180b1ce50332fce (diff) | |
Merge pull request #4715 from embassy-rs/nrf-erase
nrf: remove instance generics
28 files changed, 960 insertions, 823 deletions
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md index b8d03a1f8..21b299f36 100644 --- a/embassy-nrf/CHANGELOG.md +++ b/embassy-nrf/CHANGELOG.md | |||
| @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 8 | <!-- next-header --> | 8 | <!-- next-header --> |
| 9 | ## Unreleased - ReleaseDate | 9 | ## Unreleased - ReleaseDate |
| 10 | 10 | ||
| 11 | - changed: erase Instance type from Spim | 11 | - changed: Remove `T: Instance` generic params in all drivers. |
| 12 | - changed: nrf54l: Disable glitch detection and enable DC/DC in init. | 12 | - changed: nrf54l: Disable glitch detection and enable DC/DC in init. |
| 13 | - changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4 | 13 | - changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4 |
| 14 | - changed: add persist() method for gpio and ppi | 14 | - changed: add persist() method for gpio and ppi |
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 | } |
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs index 028396c7c..f7372fca1 100644 --- a/embassy-nrf/src/egu.rs +++ b/embassy-nrf/src/egu.rs | |||
| @@ -13,21 +13,26 @@ use crate::ppi::{Event, Task}; | |||
| 13 | use crate::{interrupt, pac, Peri}; | 13 | use crate::{interrupt, pac, Peri}; |
| 14 | 14 | ||
| 15 | /// An instance of the EGU. | 15 | /// An instance of the EGU. |
| 16 | pub struct Egu<'d, T: Instance> { | 16 | pub struct Egu<'d> { |
| 17 | _p: Peri<'d, T>, | 17 | r: pac::egu::Egu, |
| 18 | _phantom: PhantomData<&'d ()>, | ||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | impl<'d, T: Instance> Egu<'d, T> { | 21 | impl<'d> Egu<'d> { |
| 21 | /// Create a new EGU instance. | 22 | /// Create a new EGU instance. |
| 22 | pub fn new(_p: Peri<'d, T>) -> Self { | 23 | pub fn new<T: Instance>(_p: Peri<'d, T>) -> Self { |
| 23 | Self { _p } | 24 | Self { |
| 25 | r: T::regs(), | ||
| 26 | _phantom: PhantomData, | ||
| 27 | } | ||
| 24 | } | 28 | } |
| 25 | 29 | ||
| 26 | /// Get a handle to a trigger for the EGU. | 30 | /// Get a handle to a trigger for the EGU. |
| 27 | pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d, T> { | 31 | pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d> { |
| 28 | Trigger { | 32 | Trigger { |
| 29 | number, | 33 | number, |
| 30 | _p: PhantomData, | 34 | r: self.r, |
| 35 | _phantom: PhantomData, | ||
| 31 | } | 36 | } |
| 32 | } | 37 | } |
| 33 | } | 38 | } |
| @@ -57,36 +62,37 @@ macro_rules! impl_egu { | |||
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | /// Represents a trigger within the EGU. | 64 | /// Represents a trigger within the EGU. |
| 60 | pub struct Trigger<'d, T: Instance> { | 65 | pub struct Trigger<'d> { |
| 61 | number: TriggerNumber, | 66 | number: TriggerNumber, |
| 62 | _p: PhantomData<&'d T>, | 67 | r: pac::egu::Egu, |
| 68 | _phantom: PhantomData<&'d ()>, | ||
| 63 | } | 69 | } |
| 64 | 70 | ||
| 65 | impl<'d, T: Instance> Trigger<'d, T> { | 71 | impl<'d> Trigger<'d> { |
| 66 | /// Get task for this trigger to use with PPI. | 72 | /// Get task for this trigger to use with PPI. |
| 67 | pub fn task(&self) -> Task<'d> { | 73 | pub fn task(&self) -> Task<'d> { |
| 68 | let nr = self.number as usize; | 74 | let nr = self.number as usize; |
| 69 | let regs = T::regs(); | 75 | Task::from_reg(self.r.tasks_trigger(nr)) |
| 70 | Task::from_reg(regs.tasks_trigger(nr)) | ||
| 71 | } | 76 | } |
| 72 | 77 | ||
| 73 | /// Get event for this trigger to use with PPI. | 78 | /// Get event for this trigger to use with PPI. |
| 74 | pub fn event(&self) -> Event<'d> { | 79 | pub fn event(&self) -> Event<'d> { |
| 75 | let nr = self.number as usize; | 80 | let nr = self.number as usize; |
| 76 | let regs = T::regs(); | 81 | Event::from_reg(self.r.events_triggered(nr)) |
| 77 | Event::from_reg(regs.events_triggered(nr)) | ||
| 78 | } | 82 | } |
| 79 | 83 | ||
| 80 | /// Enable interrupts for this trigger | 84 | /// Enable interrupts for this trigger |
| 81 | pub fn enable_interrupt(&mut self) { | 85 | pub fn enable_interrupt(&mut self) { |
| 82 | let regs = T::regs(); | 86 | self.r |
| 83 | regs.intenset().modify(|w| w.set_triggered(self.number as usize, true)); | 87 | .intenset() |
| 88 | .modify(|w| w.set_triggered(self.number as usize, true)); | ||
| 84 | } | 89 | } |
| 85 | 90 | ||
| 86 | /// Enable interrupts for this trigger | 91 | /// Enable interrupts for this trigger |
| 87 | pub fn disable_interrupt(&mut self) { | 92 | pub fn disable_interrupt(&mut self) { |
| 88 | let regs = T::regs(); | 93 | self.r |
| 89 | regs.intenset().modify(|w| w.set_triggered(self.number as usize, false)); | 94 | .intenset() |
| 95 | .modify(|w| w.set_triggered(self.number as usize, false)); | ||
| 90 | } | 96 | } |
| 91 | } | 97 | } |
| 92 | 98 | ||
diff --git a/embassy-nrf/src/embassy_net_802154_driver.rs b/embassy-nrf/src/embassy_net_802154_driver.rs index 8662be787..b3fc5df2c 100644 --- a/embassy-nrf/src/embassy_net_802154_driver.rs +++ b/embassy-nrf/src/embassy_net_802154_driver.rs | |||
| @@ -32,12 +32,12 @@ impl<const N_RX: usize, const N_TX: usize> State<N_RX, N_TX> { | |||
| 32 | /// Background runner for the driver. | 32 | /// Background runner for the driver. |
| 33 | /// | 33 | /// |
| 34 | /// You must call `.run()` in a background task for the driver to operate. | 34 | /// You must call `.run()` in a background task for the driver to operate. |
| 35 | pub struct Runner<'d, T: nrf::radio::Instance> { | 35 | pub struct Runner<'d> { |
| 36 | radio: nrf::radio::ieee802154::Radio<'d, T>, | 36 | radio: nrf::radio::ieee802154::Radio<'d>, |
| 37 | ch: ch::Runner<'d, MTU>, | 37 | ch: ch::Runner<'d, MTU>, |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | impl<'d, T: nrf::radio::Instance> Runner<'d, T> { | 40 | impl<'d> Runner<'d> { |
| 41 | /// Drives the radio. Needs to run to use the driver. | 41 | /// Drives the radio. Needs to run to use the driver. |
| 42 | pub async fn run(mut self) -> ! { | 42 | pub async fn run(mut self) -> ! { |
| 43 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); | 43 | let (state_chan, mut rx_chan, mut tx_chan) = self.ch.split(); |
| @@ -84,7 +84,7 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, T: nrf::radio::Instan | |||
| 84 | radio: nrf::Peri<'a, T>, | 84 | radio: nrf::Peri<'a, T>, |
| 85 | irq: Irq, | 85 | irq: Irq, |
| 86 | state: &'a mut State<N_RX, N_TX>, | 86 | state: &'a mut State<N_RX, N_TX>, |
| 87 | ) -> Result<(Device<'a>, Runner<'a, T>), ()> | 87 | ) -> Result<(Device<'a>, Runner<'a>), ()> |
| 88 | where | 88 | where |
| 89 | Irq: interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a, | 89 | Irq: interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'a, |
| 90 | { | 90 | { |
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index 53de8deee..1bfa18491 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -381,7 +381,7 @@ pub struct InterruptHandler<T: Instance> { | |||
| 381 | 381 | ||
| 382 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { | 382 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { |
| 383 | unsafe fn on_interrupt() { | 383 | unsafe fn on_interrupt() { |
| 384 | let device = Device::<T>::new(); | 384 | let device = Device::new(T::regs()); |
| 385 | let s = T::state(); | 385 | let s = T::state(); |
| 386 | 386 | ||
| 387 | if device.is_tx_ptr_updated() { | 387 | if device.is_tx_ptr_updated() { |
| @@ -405,8 +405,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | /// I2S driver. | 407 | /// I2S driver. |
| 408 | pub struct I2S<'d, T: Instance> { | 408 | pub struct I2S<'d> { |
| 409 | i2s: Peri<'d, T>, | 409 | r: pac::i2s::I2s, |
| 410 | state: &'static State, | ||
| 410 | mck: Option<Peri<'d, AnyPin>>, | 411 | mck: Option<Peri<'d, AnyPin>>, |
| 411 | sck: Peri<'d, AnyPin>, | 412 | sck: Peri<'d, AnyPin>, |
| 412 | lrck: Peri<'d, AnyPin>, | 413 | lrck: Peri<'d, AnyPin>, |
| @@ -416,10 +417,10 @@ pub struct I2S<'d, T: Instance> { | |||
| 416 | config: Config, | 417 | config: Config, |
| 417 | } | 418 | } |
| 418 | 419 | ||
| 419 | impl<'d, T: Instance> I2S<'d, T> { | 420 | impl<'d> I2S<'d> { |
| 420 | /// Create a new I2S in master mode | 421 | /// Create a new I2S in master mode |
| 421 | pub fn new_master( | 422 | pub fn new_master<T: Instance>( |
| 422 | i2s: Peri<'d, T>, | 423 | _i2s: Peri<'d, T>, |
| 423 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 424 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 424 | mck: Peri<'d, impl GpioPin>, | 425 | mck: Peri<'d, impl GpioPin>, |
| 425 | sck: Peri<'d, impl GpioPin>, | 426 | sck: Peri<'d, impl GpioPin>, |
| @@ -427,8 +428,12 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 427 | master_clock: MasterClock, | 428 | master_clock: MasterClock, |
| 428 | config: Config, | 429 | config: Config, |
| 429 | ) -> Self { | 430 | ) -> Self { |
| 431 | T::Interrupt::unpend(); | ||
| 432 | unsafe { T::Interrupt::enable() }; | ||
| 433 | |||
| 430 | Self { | 434 | Self { |
| 431 | i2s, | 435 | r: T::regs(), |
| 436 | state: T::state(), | ||
| 432 | mck: Some(mck.into()), | 437 | mck: Some(mck.into()), |
| 433 | sck: sck.into(), | 438 | sck: sck.into(), |
| 434 | lrck: lrck.into(), | 439 | lrck: lrck.into(), |
| @@ -440,15 +445,19 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 440 | } | 445 | } |
| 441 | 446 | ||
| 442 | /// Create a new I2S in slave mode | 447 | /// Create a new I2S in slave mode |
| 443 | pub fn new_slave( | 448 | pub fn new_slave<T: Instance>( |
| 444 | i2s: Peri<'d, T>, | 449 | _i2s: Peri<'d, T>, |
| 445 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 450 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 446 | sck: Peri<'d, impl GpioPin>, | 451 | sck: Peri<'d, impl GpioPin>, |
| 447 | lrck: Peri<'d, impl GpioPin>, | 452 | lrck: Peri<'d, impl GpioPin>, |
| 448 | config: Config, | 453 | config: Config, |
| 449 | ) -> Self { | 454 | ) -> Self { |
| 455 | T::Interrupt::unpend(); | ||
| 456 | unsafe { T::Interrupt::enable() }; | ||
| 457 | |||
| 450 | Self { | 458 | Self { |
| 451 | i2s, | 459 | r: T::regs(), |
| 460 | state: T::state(), | ||
| 452 | mck: None, | 461 | mck: None, |
| 453 | sck: sck.into(), | 462 | sck: sck.into(), |
| 454 | lrck: lrck.into(), | 463 | lrck: lrck.into(), |
| @@ -464,10 +473,13 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 464 | mut self, | 473 | mut self, |
| 465 | sdout: Peri<'d, impl GpioPin>, | 474 | sdout: Peri<'d, impl GpioPin>, |
| 466 | buffers: MultiBuffering<S, NB, NS>, | 475 | buffers: MultiBuffering<S, NB, NS>, |
| 467 | ) -> OutputStream<'d, T, S, NB, NS> { | 476 | ) -> OutputStream<'d, S, NB, NS> { |
| 468 | self.sdout = Some(sdout.into()); | 477 | self.sdout = Some(sdout.into()); |
| 478 | let p = self.build(); | ||
| 469 | OutputStream { | 479 | OutputStream { |
| 470 | _p: self.build(), | 480 | r: p.0, |
| 481 | state: p.1, | ||
| 482 | _phantom: PhantomData, | ||
| 471 | buffers, | 483 | buffers, |
| 472 | } | 484 | } |
| 473 | } | 485 | } |
| @@ -477,11 +489,14 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 477 | mut self, | 489 | mut self, |
| 478 | sdin: Peri<'d, impl GpioPin>, | 490 | sdin: Peri<'d, impl GpioPin>, |
| 479 | buffers: MultiBuffering<S, NB, NS>, | 491 | buffers: MultiBuffering<S, NB, NS>, |
| 480 | ) -> InputStream<'d, T, S, NB, NS> { | 492 | ) -> InputStream<'d, S, NB, NS> { |
| 481 | self.sdin = Some(sdin.into()); | 493 | self.sdin = Some(sdin.into()); |
| 494 | let p = self.build(); | ||
| 482 | InputStream { | 495 | InputStream { |
| 483 | _p: self.build(), | 496 | r: p.0, |
| 497 | state: p.1, | ||
| 484 | buffers, | 498 | buffers, |
| 499 | _phantom: PhantomData, | ||
| 485 | } | 500 | } |
| 486 | } | 501 | } |
| 487 | 502 | ||
| @@ -492,30 +507,33 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 492 | sdout: Peri<'d, impl GpioPin>, | 507 | sdout: Peri<'d, impl GpioPin>, |
| 493 | buffers_out: MultiBuffering<S, NB, NS>, | 508 | buffers_out: MultiBuffering<S, NB, NS>, |
| 494 | buffers_in: MultiBuffering<S, NB, NS>, | 509 | buffers_in: MultiBuffering<S, NB, NS>, |
| 495 | ) -> FullDuplexStream<'d, T, S, NB, NS> { | 510 | ) -> FullDuplexStream<'d, S, NB, NS> { |
| 496 | self.sdout = Some(sdout.into()); | 511 | self.sdout = Some(sdout.into()); |
| 497 | self.sdin = Some(sdin.into()); | 512 | self.sdin = Some(sdin.into()); |
| 513 | let p = self.build(); | ||
| 498 | 514 | ||
| 499 | FullDuplexStream { | 515 | FullDuplexStream { |
| 500 | _p: self.build(), | 516 | r: p.0, |
| 517 | state: p.1, | ||
| 518 | _phantom: PhantomData, | ||
| 501 | buffers_out, | 519 | buffers_out, |
| 502 | buffers_in, | 520 | buffers_in, |
| 503 | } | 521 | } |
| 504 | } | 522 | } |
| 505 | 523 | ||
| 506 | fn build(self) -> Peri<'d, T> { | 524 | fn build(self) -> (pac::i2s::I2s, &'static State) { |
| 507 | self.apply_config(); | 525 | self.apply_config(); |
| 508 | self.select_pins(); | 526 | self.select_pins(); |
| 509 | self.setup_interrupt(); | 527 | self.setup_interrupt(); |
| 510 | 528 | ||
| 511 | let device = Device::<T>::new(); | 529 | let device = Device::new(self.r); |
| 512 | device.enable(); | 530 | device.enable(); |
| 513 | 531 | ||
| 514 | self.i2s | 532 | (self.r, self.state) |
| 515 | } | 533 | } |
| 516 | 534 | ||
| 517 | fn apply_config(&self) { | 535 | fn apply_config(&self) { |
| 518 | let c = T::regs().config(); | 536 | let c = self.r.config(); |
| 519 | match &self.master_clock { | 537 | match &self.master_clock { |
| 520 | Some(MasterClock { freq, ratio }) => { | 538 | Some(MasterClock { freq, ratio }) => { |
| 521 | c.mode().write(|w| w.set_mode(vals::Mode::MASTER)); | 539 | c.mode().write(|w| w.set_mode(vals::Mode::MASTER)); |
| @@ -535,7 +553,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 535 | } | 553 | } |
| 536 | 554 | ||
| 537 | fn select_pins(&self) { | 555 | fn select_pins(&self) { |
| 538 | let psel = T::regs().psel(); | 556 | let psel = self.r.psel(); |
| 539 | psel.mck().write_value(self.mck.psel_bits()); | 557 | psel.mck().write_value(self.mck.psel_bits()); |
| 540 | psel.sck().write_value(self.sck.psel_bits()); | 558 | psel.sck().write_value(self.sck.psel_bits()); |
| 541 | psel.lrck().write_value(self.lrck.psel_bits()); | 559 | psel.lrck().write_value(self.lrck.psel_bits()); |
| @@ -544,10 +562,9 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 544 | } | 562 | } |
| 545 | 563 | ||
| 546 | fn setup_interrupt(&self) { | 564 | fn setup_interrupt(&self) { |
| 547 | T::Interrupt::unpend(); | 565 | // Interrupt is already set up in constructor |
| 548 | unsafe { T::Interrupt::enable() }; | ||
| 549 | 566 | ||
| 550 | let device = Device::<T>::new(); | 567 | let device = Device::new(self.r); |
| 551 | device.disable_tx_ptr_interrupt(); | 568 | device.disable_tx_ptr_interrupt(); |
| 552 | device.disable_rx_ptr_interrupt(); | 569 | device.disable_rx_ptr_interrupt(); |
| 553 | device.disable_stopped_interrupt(); | 570 | device.disable_stopped_interrupt(); |
| @@ -561,16 +578,16 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 561 | device.enable_stopped_interrupt(); | 578 | device.enable_stopped_interrupt(); |
| 562 | } | 579 | } |
| 563 | 580 | ||
| 564 | async fn stop() { | 581 | async fn stop(r: pac::i2s::I2s, state: &State) { |
| 565 | compiler_fence(Ordering::SeqCst); | 582 | compiler_fence(Ordering::SeqCst); |
| 566 | 583 | ||
| 567 | let device = Device::<T>::new(); | 584 | let device = Device::new(r); |
| 568 | device.stop(); | 585 | device.stop(); |
| 569 | 586 | ||
| 570 | T::state().started.store(false, Ordering::Relaxed); | 587 | state.started.store(false, Ordering::Relaxed); |
| 571 | 588 | ||
| 572 | poll_fn(|cx| { | 589 | poll_fn(|cx| { |
| 573 | T::state().stop_waker.register(cx.waker()); | 590 | state.stop_waker.register(cx.waker()); |
| 574 | 591 | ||
| 575 | if device.is_stopped() { | 592 | if device.is_stopped() { |
| 576 | trace!("STOP: Ready"); | 593 | trace!("STOP: Ready"); |
| @@ -586,7 +603,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 586 | device.disable(); | 603 | device.disable(); |
| 587 | } | 604 | } |
| 588 | 605 | ||
| 589 | async fn send_from_ram<S>(buffer_ptr: *const [S]) -> Result<(), Error> | 606 | async fn send_from_ram<S>(r: pac::i2s::I2s, state: &State, buffer_ptr: *const [S]) -> Result<(), Error> |
| 590 | where | 607 | where |
| 591 | S: Sample, | 608 | S: Sample, |
| 592 | { | 609 | { |
| @@ -596,22 +613,22 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 596 | 613 | ||
| 597 | compiler_fence(Ordering::SeqCst); | 614 | compiler_fence(Ordering::SeqCst); |
| 598 | 615 | ||
| 599 | let device = Device::<T>::new(); | 616 | let device = Device::new(r); |
| 600 | 617 | ||
| 601 | device.update_tx(buffer_ptr)?; | 618 | device.update_tx(buffer_ptr)?; |
| 602 | 619 | ||
| 603 | Self::wait_tx_ptr_update().await; | 620 | Self::wait_tx_ptr_update(r, state).await; |
| 604 | 621 | ||
| 605 | compiler_fence(Ordering::SeqCst); | 622 | compiler_fence(Ordering::SeqCst); |
| 606 | 623 | ||
| 607 | Ok(()) | 624 | Ok(()) |
| 608 | } | 625 | } |
| 609 | 626 | ||
| 610 | async fn wait_tx_ptr_update() { | 627 | async fn wait_tx_ptr_update(r: pac::i2s::I2s, state: &State) { |
| 611 | let drop = OnDrop::new(move || { | 628 | let drop = OnDrop::new(move || { |
| 612 | trace!("TX DROP: Stopping"); | 629 | trace!("TX DROP: Stopping"); |
| 613 | 630 | ||
| 614 | let device = Device::<T>::new(); | 631 | let device = Device::new(r); |
| 615 | device.disable_tx_ptr_interrupt(); | 632 | device.disable_tx_ptr_interrupt(); |
| 616 | device.reset_tx_ptr_event(); | 633 | device.reset_tx_ptr_event(); |
| 617 | device.disable_tx(); | 634 | device.disable_tx(); |
| @@ -623,9 +640,9 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 623 | }); | 640 | }); |
| 624 | 641 | ||
| 625 | poll_fn(|cx| { | 642 | poll_fn(|cx| { |
| 626 | T::state().tx_waker.register(cx.waker()); | 643 | state.tx_waker.register(cx.waker()); |
| 627 | 644 | ||
| 628 | let device = Device::<T>::new(); | 645 | let device = Device::new(r); |
| 629 | if device.is_tx_ptr_updated() { | 646 | if device.is_tx_ptr_updated() { |
| 630 | trace!("TX POLL: Ready"); | 647 | trace!("TX POLL: Ready"); |
| 631 | device.reset_tx_ptr_event(); | 648 | device.reset_tx_ptr_event(); |
| @@ -641,7 +658,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 641 | drop.defuse(); | 658 | drop.defuse(); |
| 642 | } | 659 | } |
| 643 | 660 | ||
| 644 | async fn receive_from_ram<S>(buffer_ptr: *mut [S]) -> Result<(), Error> | 661 | async fn receive_from_ram<S>(r: pac::i2s::I2s, state: &State, buffer_ptr: *mut [S]) -> Result<(), Error> |
| 645 | where | 662 | where |
| 646 | S: Sample, | 663 | S: Sample, |
| 647 | { | 664 | { |
| @@ -652,22 +669,22 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 652 | 669 | ||
| 653 | compiler_fence(Ordering::SeqCst); | 670 | compiler_fence(Ordering::SeqCst); |
| 654 | 671 | ||
| 655 | let device = Device::<T>::new(); | 672 | let device = Device::new(r); |
| 656 | 673 | ||
| 657 | device.update_rx(buffer_ptr)?; | 674 | device.update_rx(buffer_ptr)?; |
| 658 | 675 | ||
| 659 | Self::wait_rx_ptr_update().await; | 676 | Self::wait_rx_ptr_update(r, state).await; |
| 660 | 677 | ||
| 661 | compiler_fence(Ordering::SeqCst); | 678 | compiler_fence(Ordering::SeqCst); |
| 662 | 679 | ||
| 663 | Ok(()) | 680 | Ok(()) |
| 664 | } | 681 | } |
| 665 | 682 | ||
| 666 | async fn wait_rx_ptr_update() { | 683 | async fn wait_rx_ptr_update(r: pac::i2s::I2s, state: &State) { |
| 667 | let drop = OnDrop::new(move || { | 684 | let drop = OnDrop::new(move || { |
| 668 | trace!("RX DROP: Stopping"); | 685 | trace!("RX DROP: Stopping"); |
| 669 | 686 | ||
| 670 | let device = Device::<T>::new(); | 687 | let device = Device::new(r); |
| 671 | device.disable_rx_ptr_interrupt(); | 688 | device.disable_rx_ptr_interrupt(); |
| 672 | device.reset_rx_ptr_event(); | 689 | device.reset_rx_ptr_event(); |
| 673 | device.disable_rx(); | 690 | device.disable_rx(); |
| @@ -679,9 +696,9 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 679 | }); | 696 | }); |
| 680 | 697 | ||
| 681 | poll_fn(|cx| { | 698 | poll_fn(|cx| { |
| 682 | T::state().rx_waker.register(cx.waker()); | 699 | state.rx_waker.register(cx.waker()); |
| 683 | 700 | ||
| 684 | let device = Device::<T>::new(); | 701 | let device = Device::new(r); |
| 685 | if device.is_rx_ptr_updated() { | 702 | if device.is_rx_ptr_updated() { |
| 686 | trace!("RX POLL: Ready"); | 703 | trace!("RX POLL: Ready"); |
| 687 | device.reset_rx_ptr_event(); | 704 | device.reset_rx_ptr_event(); |
| @@ -699,12 +716,14 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 699 | } | 716 | } |
| 700 | 717 | ||
| 701 | /// I2S output | 718 | /// I2S output |
| 702 | pub struct OutputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { | 719 | pub struct OutputStream<'d, S: Sample, const NB: usize, const NS: usize> { |
| 703 | _p: Peri<'d, T>, | 720 | r: pac::i2s::I2s, |
| 721 | state: &'static State, | ||
| 704 | buffers: MultiBuffering<S, NB, NS>, | 722 | buffers: MultiBuffering<S, NB, NS>, |
| 723 | _phantom: PhantomData<&'d ()>, | ||
| 705 | } | 724 | } |
| 706 | 725 | ||
| 707 | impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream<'d, T, S, NB, NS> { | 726 | impl<'d, S: Sample, const NB: usize, const NS: usize> OutputStream<'d, S, NB, NS> { |
| 708 | /// Get a mutable reference to the current buffer. | 727 | /// Get a mutable reference to the current buffer. |
| 709 | pub fn buffer(&mut self) -> &mut [S] { | 728 | pub fn buffer(&mut self) -> &mut [S] { |
| 710 | self.buffers.get_mut() | 729 | self.buffers.get_mut() |
| @@ -715,10 +734,9 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream< | |||
| 715 | where | 734 | where |
| 716 | S: Sample, | 735 | S: Sample, |
| 717 | { | 736 | { |
| 718 | let device = Device::<T>::new(); | 737 | let device = Device::new(self.r); |
| 719 | 738 | ||
| 720 | let s = T::state(); | 739 | if self.state.started.load(Ordering::Relaxed) { |
| 721 | if s.started.load(Ordering::Relaxed) { | ||
| 722 | self.stop().await; | 740 | self.stop().await; |
| 723 | } | 741 | } |
| 724 | 742 | ||
| @@ -727,11 +745,11 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream< | |||
| 727 | 745 | ||
| 728 | device.update_tx(self.buffers.switch())?; | 746 | device.update_tx(self.buffers.switch())?; |
| 729 | 747 | ||
| 730 | s.started.store(true, Ordering::Relaxed); | 748 | self.state.started.store(true, Ordering::Relaxed); |
| 731 | 749 | ||
| 732 | device.start(); | 750 | device.start(); |
| 733 | 751 | ||
| 734 | I2S::<T>::wait_tx_ptr_update().await; | 752 | I2S::wait_tx_ptr_update(self.r, self.state).await; |
| 735 | 753 | ||
| 736 | Ok(()) | 754 | Ok(()) |
| 737 | } | 755 | } |
| @@ -739,7 +757,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream< | |||
| 739 | /// Stops the I2S transfer and waits until it has stopped. | 757 | /// Stops the I2S transfer and waits until it has stopped. |
| 740 | #[inline(always)] | 758 | #[inline(always)] |
| 741 | pub async fn stop(&self) { | 759 | pub async fn stop(&self) { |
| 742 | I2S::<T>::stop().await | 760 | I2S::stop(self.r, self.state).await |
| 743 | } | 761 | } |
| 744 | 762 | ||
| 745 | /// Sends the current buffer for transmission in the DMA. | 763 | /// Sends the current buffer for transmission in the DMA. |
| @@ -748,17 +766,19 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> OutputStream< | |||
| 748 | where | 766 | where |
| 749 | S: Sample, | 767 | S: Sample, |
| 750 | { | 768 | { |
| 751 | I2S::<T>::send_from_ram(self.buffers.switch()).await | 769 | I2S::send_from_ram(self.r, self.state, self.buffers.switch()).await |
| 752 | } | 770 | } |
| 753 | } | 771 | } |
| 754 | 772 | ||
| 755 | /// I2S input | 773 | /// I2S input |
| 756 | pub struct InputStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { | 774 | pub struct InputStream<'d, S: Sample, const NB: usize, const NS: usize> { |
| 757 | _p: Peri<'d, T>, | 775 | r: pac::i2s::I2s, |
| 776 | state: &'static State, | ||
| 758 | buffers: MultiBuffering<S, NB, NS>, | 777 | buffers: MultiBuffering<S, NB, NS>, |
| 778 | _phantom: PhantomData<&'d ()>, | ||
| 759 | } | 779 | } |
| 760 | 780 | ||
| 761 | impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<'d, T, S, NB, NS> { | 781 | impl<'d, S: Sample, const NB: usize, const NS: usize> InputStream<'d, S, NB, NS> { |
| 762 | /// Get a mutable reference to the current buffer. | 782 | /// Get a mutable reference to the current buffer. |
| 763 | pub fn buffer(&mut self) -> &mut [S] { | 783 | pub fn buffer(&mut self) -> &mut [S] { |
| 764 | self.buffers.get_mut() | 784 | self.buffers.get_mut() |
| @@ -769,10 +789,9 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<' | |||
| 769 | where | 789 | where |
| 770 | S: Sample, | 790 | S: Sample, |
| 771 | { | 791 | { |
| 772 | let device = Device::<T>::new(); | 792 | let device = Device::new(self.r); |
| 773 | 793 | ||
| 774 | let s = T::state(); | 794 | if self.state.started.load(Ordering::Relaxed) { |
| 775 | if s.started.load(Ordering::Relaxed) { | ||
| 776 | self.stop().await; | 795 | self.stop().await; |
| 777 | } | 796 | } |
| 778 | 797 | ||
| @@ -781,11 +800,11 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<' | |||
| 781 | 800 | ||
| 782 | device.update_rx(self.buffers.switch())?; | 801 | device.update_rx(self.buffers.switch())?; |
| 783 | 802 | ||
| 784 | s.started.store(true, Ordering::Relaxed); | 803 | self.state.started.store(true, Ordering::Relaxed); |
| 785 | 804 | ||
| 786 | device.start(); | 805 | device.start(); |
| 787 | 806 | ||
| 788 | I2S::<T>::wait_rx_ptr_update().await; | 807 | I2S::wait_rx_ptr_update(self.r, self.state).await; |
| 789 | 808 | ||
| 790 | Ok(()) | 809 | Ok(()) |
| 791 | } | 810 | } |
| @@ -793,7 +812,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<' | |||
| 793 | /// Stops the I2S transfer and waits until it has stopped. | 812 | /// Stops the I2S transfer and waits until it has stopped. |
| 794 | #[inline(always)] | 813 | #[inline(always)] |
| 795 | pub async fn stop(&self) { | 814 | pub async fn stop(&self) { |
| 796 | I2S::<T>::stop().await | 815 | I2S::stop(self.r, self.state).await |
| 797 | } | 816 | } |
| 798 | 817 | ||
| 799 | /// Sets the current buffer for reception from the DMA. | 818 | /// Sets the current buffer for reception from the DMA. |
| @@ -803,18 +822,20 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> InputStream<' | |||
| 803 | where | 822 | where |
| 804 | S: Sample, | 823 | S: Sample, |
| 805 | { | 824 | { |
| 806 | I2S::<T>::receive_from_ram(self.buffers.switch_mut()).await | 825 | I2S::receive_from_ram(self.r, self.state, self.buffers.switch_mut()).await |
| 807 | } | 826 | } |
| 808 | } | 827 | } |
| 809 | 828 | ||
| 810 | /// I2S full duplex stream (input & output) | 829 | /// I2S full duplex stream (input & output) |
| 811 | pub struct FullDuplexStream<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> { | 830 | pub struct FullDuplexStream<'d, S: Sample, const NB: usize, const NS: usize> { |
| 812 | _p: Peri<'d, T>, | 831 | r: pac::i2s::I2s, |
| 832 | state: &'static State, | ||
| 813 | buffers_out: MultiBuffering<S, NB, NS>, | 833 | buffers_out: MultiBuffering<S, NB, NS>, |
| 814 | buffers_in: MultiBuffering<S, NB, NS>, | 834 | buffers_in: MultiBuffering<S, NB, NS>, |
| 835 | _phantom: PhantomData<&'d ()>, | ||
| 815 | } | 836 | } |
| 816 | 837 | ||
| 817 | impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStream<'d, T, S, NB, NS> { | 838 | impl<'d, S: Sample, const NB: usize, const NS: usize> FullDuplexStream<'d, S, NB, NS> { |
| 818 | /// Get the current output and input buffers. | 839 | /// Get the current output and input buffers. |
| 819 | pub fn buffers(&mut self) -> (&mut [S], &[S]) { | 840 | pub fn buffers(&mut self) -> (&mut [S], &[S]) { |
| 820 | (self.buffers_out.get_mut(), self.buffers_in.get()) | 841 | (self.buffers_out.get_mut(), self.buffers_in.get()) |
| @@ -825,10 +846,9 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStr | |||
| 825 | where | 846 | where |
| 826 | S: Sample, | 847 | S: Sample, |
| 827 | { | 848 | { |
| 828 | let device = Device::<T>::new(); | 849 | let device = Device::new(self.r); |
| 829 | 850 | ||
| 830 | let s = T::state(); | 851 | if self.state.started.load(Ordering::Relaxed) { |
| 831 | if s.started.load(Ordering::Relaxed) { | ||
| 832 | self.stop().await; | 852 | self.stop().await; |
| 833 | } | 853 | } |
| 834 | 854 | ||
| @@ -839,12 +859,12 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStr | |||
| 839 | device.update_tx(self.buffers_out.switch())?; | 859 | device.update_tx(self.buffers_out.switch())?; |
| 840 | device.update_rx(self.buffers_in.switch_mut())?; | 860 | device.update_rx(self.buffers_in.switch_mut())?; |
| 841 | 861 | ||
| 842 | s.started.store(true, Ordering::Relaxed); | 862 | self.state.started.store(true, Ordering::Relaxed); |
| 843 | 863 | ||
| 844 | device.start(); | 864 | device.start(); |
| 845 | 865 | ||
| 846 | I2S::<T>::wait_tx_ptr_update().await; | 866 | I2S::wait_tx_ptr_update(self.r, self.state).await; |
| 847 | I2S::<T>::wait_rx_ptr_update().await; | 867 | I2S::wait_rx_ptr_update(self.r, self.state).await; |
| 848 | 868 | ||
| 849 | Ok(()) | 869 | Ok(()) |
| 850 | } | 870 | } |
| @@ -852,7 +872,7 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStr | |||
| 852 | /// Stops the I2S transfer and waits until it has stopped. | 872 | /// Stops the I2S transfer and waits until it has stopped. |
| 853 | #[inline(always)] | 873 | #[inline(always)] |
| 854 | pub async fn stop(&self) { | 874 | pub async fn stop(&self) { |
| 855 | I2S::<T>::stop().await | 875 | I2S::stop(self.r, self.state).await |
| 856 | } | 876 | } |
| 857 | 877 | ||
| 858 | /// Sets the current buffers for output and input for transmission/reception from the DMA. | 878 | /// Sets the current buffers for output and input for transmission/reception from the DMA. |
| @@ -861,18 +881,18 @@ impl<'d, T: Instance, S: Sample, const NB: usize, const NS: usize> FullDuplexStr | |||
| 861 | where | 881 | where |
| 862 | S: Sample, | 882 | S: Sample, |
| 863 | { | 883 | { |
| 864 | I2S::<T>::send_from_ram(self.buffers_out.switch()).await?; | 884 | I2S::send_from_ram(self.r, self.state, self.buffers_out.switch()).await?; |
| 865 | I2S::<T>::receive_from_ram(self.buffers_in.switch_mut()).await?; | 885 | I2S::receive_from_ram(self.r, self.state, self.buffers_in.switch_mut()).await?; |
| 866 | Ok(()) | 886 | Ok(()) |
| 867 | } | 887 | } |
| 868 | } | 888 | } |
| 869 | 889 | ||
| 870 | /// Helper encapsulating common I2S device operations. | 890 | /// Helper encapsulating common I2S device operations. |
| 871 | struct Device<T>(pac::i2s::I2s, PhantomData<T>); | 891 | struct Device(pac::i2s::I2s); |
| 872 | 892 | ||
| 873 | impl<T: Instance> Device<T> { | 893 | impl Device { |
| 874 | fn new() -> Self { | 894 | fn new(r: pac::i2s::I2s) -> Self { |
| 875 | Self(T::regs(), PhantomData) | 895 | Self(r) |
| 876 | } | 896 | } |
| 877 | 897 | ||
| 878 | #[inline(always)] | 898 | #[inline(always)] |
diff --git a/embassy-nrf/src/ipc.rs b/embassy-nrf/src/ipc.rs index a8a08c911..a40c36c99 100644 --- a/embassy-nrf/src/ipc.rs +++ b/embassy-nrf/src/ipc.rs | |||
| @@ -134,97 +134,99 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 134 | 134 | ||
| 135 | /// IPC driver | 135 | /// IPC driver |
| 136 | #[non_exhaustive] | 136 | #[non_exhaustive] |
| 137 | pub struct Ipc<'d, T: Instance> { | 137 | pub struct Ipc<'d> { |
| 138 | /// Event 0 | 138 | /// Event 0 |
| 139 | pub event0: Event<'d, T>, | 139 | pub event0: Event<'d>, |
| 140 | /// Event 1 | 140 | /// Event 1 |
| 141 | pub event1: Event<'d, T>, | 141 | pub event1: Event<'d>, |
| 142 | /// Event 2 | 142 | /// Event 2 |
| 143 | pub event2: Event<'d, T>, | 143 | pub event2: Event<'d>, |
| 144 | /// Event 3 | 144 | /// Event 3 |
| 145 | pub event3: Event<'d, T>, | 145 | pub event3: Event<'d>, |
| 146 | /// Event 4 | 146 | /// Event 4 |
| 147 | pub event4: Event<'d, T>, | 147 | pub event4: Event<'d>, |
| 148 | /// Event 5 | 148 | /// Event 5 |
| 149 | pub event5: Event<'d, T>, | 149 | pub event5: Event<'d>, |
| 150 | /// Event 6 | 150 | /// Event 6 |
| 151 | pub event6: Event<'d, T>, | 151 | pub event6: Event<'d>, |
| 152 | /// Event 7 | 152 | /// Event 7 |
| 153 | pub event7: Event<'d, T>, | 153 | pub event7: Event<'d>, |
| 154 | /// Event 8 | 154 | /// Event 8 |
| 155 | pub event8: Event<'d, T>, | 155 | pub event8: Event<'d>, |
| 156 | /// Event 9 | 156 | /// Event 9 |
| 157 | pub event9: Event<'d, T>, | 157 | pub event9: Event<'d>, |
| 158 | /// Event 10 | 158 | /// Event 10 |
| 159 | pub event10: Event<'d, T>, | 159 | pub event10: Event<'d>, |
| 160 | /// Event 11 | 160 | /// Event 11 |
| 161 | pub event11: Event<'d, T>, | 161 | pub event11: Event<'d>, |
| 162 | /// Event 12 | 162 | /// Event 12 |
| 163 | pub event12: Event<'d, T>, | 163 | pub event12: Event<'d>, |
| 164 | /// Event 13 | 164 | /// Event 13 |
| 165 | pub event13: Event<'d, T>, | 165 | pub event13: Event<'d>, |
| 166 | /// Event 14 | 166 | /// Event 14 |
| 167 | pub event14: Event<'d, T>, | 167 | pub event14: Event<'d>, |
| 168 | /// Event 15 | 168 | /// Event 15 |
| 169 | pub event15: Event<'d, T>, | 169 | pub event15: Event<'d>, |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | impl<'d, T: Instance> Ipc<'d, T> { | 172 | impl<'d> Ipc<'d> { |
| 173 | /// Create a new IPC driver. | 173 | /// Create a new IPC driver. |
| 174 | pub fn new( | 174 | pub fn new<T: Instance>( |
| 175 | _p: Peri<'d, T>, | 175 | _p: Peri<'d, T>, |
| 176 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 176 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 177 | ) -> Self { | 177 | ) -> Self { |
| 178 | T::Interrupt::unpend(); | 178 | T::Interrupt::unpend(); |
| 179 | unsafe { T::Interrupt::enable() }; | 179 | unsafe { T::Interrupt::enable() }; |
| 180 | 180 | ||
| 181 | let _phantom = PhantomData; | 181 | let r = T::regs(); |
| 182 | let state = T::state(); | ||
| 182 | #[rustfmt::skip] | 183 | #[rustfmt::skip] |
| 183 | let r = Self { // attributes on expressions are experimental | 184 | let result = Self { // attributes on expressions are experimental |
| 184 | event0: Event { number: EventNumber::Event0, _phantom }, | 185 | event0: Event { number: EventNumber::Event0, r, state, _phantom: PhantomData }, |
| 185 | event1: Event { number: EventNumber::Event1, _phantom }, | 186 | event1: Event { number: EventNumber::Event1, r, state, _phantom: PhantomData }, |
| 186 | event2: Event { number: EventNumber::Event2, _phantom }, | 187 | event2: Event { number: EventNumber::Event2, r, state, _phantom: PhantomData }, |
| 187 | event3: Event { number: EventNumber::Event3, _phantom }, | 188 | event3: Event { number: EventNumber::Event3, r, state, _phantom: PhantomData }, |
| 188 | event4: Event { number: EventNumber::Event4, _phantom }, | 189 | event4: Event { number: EventNumber::Event4, r, state, _phantom: PhantomData }, |
| 189 | event5: Event { number: EventNumber::Event5, _phantom }, | 190 | event5: Event { number: EventNumber::Event5, r, state, _phantom: PhantomData }, |
| 190 | event6: Event { number: EventNumber::Event6, _phantom }, | 191 | event6: Event { number: EventNumber::Event6, r, state, _phantom: PhantomData }, |
| 191 | event7: Event { number: EventNumber::Event7, _phantom }, | 192 | event7: Event { number: EventNumber::Event7, r, state, _phantom: PhantomData }, |
| 192 | event8: Event { number: EventNumber::Event8, _phantom }, | 193 | event8: Event { number: EventNumber::Event8, r, state, _phantom: PhantomData }, |
| 193 | event9: Event { number: EventNumber::Event9, _phantom }, | 194 | event9: Event { number: EventNumber::Event9, r, state, _phantom: PhantomData }, |
| 194 | event10: Event { number: EventNumber::Event10, _phantom }, | 195 | event10: Event { number: EventNumber::Event10, r, state, _phantom: PhantomData }, |
| 195 | event11: Event { number: EventNumber::Event11, _phantom }, | 196 | event11: Event { number: EventNumber::Event11, r, state, _phantom: PhantomData }, |
| 196 | event12: Event { number: EventNumber::Event12, _phantom }, | 197 | event12: Event { number: EventNumber::Event12, r, state, _phantom: PhantomData }, |
| 197 | event13: Event { number: EventNumber::Event13, _phantom }, | 198 | event13: Event { number: EventNumber::Event13, r, state, _phantom: PhantomData }, |
| 198 | event14: Event { number: EventNumber::Event14, _phantom }, | 199 | event14: Event { number: EventNumber::Event14, r, state, _phantom: PhantomData }, |
| 199 | event15: Event { number: EventNumber::Event15, _phantom }, | 200 | event15: Event { number: EventNumber::Event15, r, state, _phantom: PhantomData }, |
| 200 | }; | 201 | }; |
| 201 | r | 202 | result |
| 202 | } | 203 | } |
| 203 | } | 204 | } |
| 204 | 205 | ||
| 205 | /// IPC event | 206 | /// IPC event |
| 206 | pub struct Event<'d, T: Instance> { | 207 | pub struct Event<'d> { |
| 207 | number: EventNumber, | 208 | number: EventNumber, |
| 208 | _phantom: PhantomData<&'d T>, | 209 | r: pac::ipc::Ipc, |
| 210 | state: &'static State, | ||
| 211 | _phantom: PhantomData<&'d ()>, | ||
| 209 | } | 212 | } |
| 210 | 213 | ||
| 211 | impl<'d, T: Instance> Event<'d, T> { | 214 | impl<'d> Event<'d> { |
| 212 | /// Trigger the event. | 215 | /// Trigger the event. |
| 213 | pub fn trigger(&self) { | 216 | pub fn trigger(&self) { |
| 214 | let nr = self.number; | 217 | let nr = self.number; |
| 215 | T::regs().tasks_send(nr as usize).write_value(1); | 218 | self.r.tasks_send(nr as usize).write_value(1); |
| 216 | } | 219 | } |
| 217 | 220 | ||
| 218 | /// Wait for the event to be triggered. | 221 | /// Wait for the event to be triggered. |
| 219 | pub async fn wait(&mut self) { | 222 | pub async fn wait(&mut self) { |
| 220 | let regs = T::regs(); | ||
| 221 | let nr = self.number as usize; | 223 | let nr = self.number as usize; |
| 222 | regs.intenset().write(|w| w.0 = 1 << nr); | 224 | self.r.intenset().write(|w| w.0 = 1 << nr); |
| 223 | poll_fn(|cx| { | 225 | poll_fn(|cx| { |
| 224 | T::state().wakers[nr].register(cx.waker()); | 226 | self.state.wakers[nr].register(cx.waker()); |
| 225 | 227 | ||
| 226 | if regs.events_receive(nr).read() == 1 { | 228 | if self.r.events_receive(nr).read() == 1 { |
| 227 | regs.events_receive(nr).write_value(0x00); | 229 | self.r.events_receive(nr).write_value(0x00); |
| 228 | Poll::Ready(()) | 230 | Poll::Ready(()) |
| 229 | } else { | 231 | } else { |
| 230 | Poll::Pending | 232 | Poll::Pending |
| @@ -239,16 +241,17 @@ impl<'d, T: Instance> Event<'d, T> { | |||
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | /// Create a handle that can trigger the event. | 243 | /// Create a handle that can trigger the event. |
| 242 | pub fn trigger_handle(&self) -> EventTrigger<'d, T> { | 244 | pub fn trigger_handle(&self) -> EventTrigger<'d> { |
| 243 | EventTrigger { | 245 | EventTrigger { |
| 244 | number: self.number, | 246 | number: self.number, |
| 247 | r: self.r, | ||
| 245 | _phantom: PhantomData, | 248 | _phantom: PhantomData, |
| 246 | } | 249 | } |
| 247 | } | 250 | } |
| 248 | 251 | ||
| 249 | /// Configure the channels the event will broadcast to | 252 | /// Configure the channels the event will broadcast to |
| 250 | pub fn configure_trigger<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) { | 253 | pub fn configure_trigger<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) { |
| 251 | T::regs().send_cnf(self.number as usize).write(|w| { | 254 | self.r.send_cnf(self.number as usize).write(|w| { |
| 252 | for channel in channels { | 255 | for channel in channels { |
| 253 | w.0 |= channel.mask(); | 256 | w.0 |= channel.mask(); |
| 254 | } | 257 | } |
| @@ -257,7 +260,7 @@ impl<'d, T: Instance> Event<'d, T> { | |||
| 257 | 260 | ||
| 258 | /// Configure the channels the event will listen on | 261 | /// Configure the channels the event will listen on |
| 259 | pub fn configure_wait<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) { | 262 | pub fn configure_wait<I: IntoIterator<Item = IpcChannel>>(&mut self, channels: I) { |
| 260 | T::regs().receive_cnf(self.number as usize).write(|w| { | 263 | self.r.receive_cnf(self.number as usize).write(|w| { |
| 261 | for channel in channels { | 264 | for channel in channels { |
| 262 | w.0 |= channel.mask(); | 265 | w.0 |= channel.mask(); |
| 263 | } | 266 | } |
| @@ -267,22 +270,25 @@ impl<'d, T: Instance> Event<'d, T> { | |||
| 267 | /// Get the task for the IPC event to use with PPI. | 270 | /// Get the task for the IPC event to use with PPI. |
| 268 | pub fn task(&self) -> ppi::Task<'d> { | 271 | pub fn task(&self) -> ppi::Task<'d> { |
| 269 | let nr = self.number as usize; | 272 | let nr = self.number as usize; |
| 270 | let regs = T::regs(); | 273 | ppi::Task::from_reg(self.r.tasks_send(nr)) |
| 271 | ppi::Task::from_reg(regs.tasks_send(nr)) | ||
| 272 | } | 274 | } |
| 273 | 275 | ||
| 274 | /// Get the event for the IPC event to use with PPI. | 276 | /// Get the event for the IPC event to use with PPI. |
| 275 | pub fn event(&self) -> ppi::Event<'d> { | 277 | pub fn event(&self) -> ppi::Event<'d> { |
| 276 | let nr = self.number as usize; | 278 | let nr = self.number as usize; |
| 277 | let regs = T::regs(); | 279 | ppi::Event::from_reg(self.r.events_receive(nr)) |
| 278 | ppi::Event::from_reg(regs.events_receive(nr)) | ||
| 279 | } | 280 | } |
| 280 | 281 | ||
| 281 | /// Reborrow into a "child" Event. | 282 | /// Reborrow into a "child" Event. |
| 282 | /// | 283 | /// |
| 283 | /// `self` will stay borrowed until the child Event is dropped. | 284 | /// `self` will stay borrowed until the child Event is dropped. |
| 284 | pub fn reborrow(&mut self) -> Event<'_, T> { | 285 | pub fn reborrow(&mut self) -> Event<'_> { |
| 285 | Self { ..*self } | 286 | Event { |
| 287 | number: self.number, | ||
| 288 | r: self.r, | ||
| 289 | state: self.state, | ||
| 290 | _phantom: PhantomData, | ||
| 291 | } | ||
| 286 | } | 292 | } |
| 287 | 293 | ||
| 288 | /// Steal an IPC event by number. | 294 | /// Steal an IPC event by number. |
| @@ -290,9 +296,11 @@ impl<'d, T: Instance> Event<'d, T> { | |||
| 290 | /// # Safety | 296 | /// # Safety |
| 291 | /// | 297 | /// |
| 292 | /// The event number must not be in use by another [`Event`]. | 298 | /// The event number must not be in use by another [`Event`]. |
| 293 | pub unsafe fn steal(number: EventNumber) -> Self { | 299 | pub unsafe fn steal<T: Instance>(number: EventNumber) -> Self { |
| 294 | Self { | 300 | Self { |
| 295 | number, | 301 | number, |
| 302 | r: T::regs(), | ||
| 303 | state: T::state(), | ||
| 296 | _phantom: PhantomData, | 304 | _phantom: PhantomData, |
| 297 | } | 305 | } |
| 298 | } | 306 | } |
| @@ -301,17 +309,17 @@ impl<'d, T: Instance> Event<'d, T> { | |||
| 301 | /// A handle that can trigger an IPC event. | 309 | /// A handle that can trigger an IPC event. |
| 302 | /// | 310 | /// |
| 303 | /// This `struct` is returned by [`Event::trigger_handle`]. | 311 | /// This `struct` is returned by [`Event::trigger_handle`]. |
| 304 | #[derive(Debug, Copy, Clone)] | 312 | pub struct EventTrigger<'d> { |
| 305 | pub struct EventTrigger<'d, T: Instance> { | ||
| 306 | number: EventNumber, | 313 | number: EventNumber, |
| 307 | _phantom: PhantomData<&'d T>, | 314 | r: pac::ipc::Ipc, |
| 315 | _phantom: PhantomData<&'d ()>, | ||
| 308 | } | 316 | } |
| 309 | 317 | ||
| 310 | impl<T: Instance> EventTrigger<'_, T> { | 318 | impl EventTrigger<'_> { |
| 311 | /// Trigger the event. | 319 | /// Trigger the event. |
| 312 | pub fn trigger(&self) { | 320 | pub fn trigger(&self) { |
| 313 | let nr = self.number; | 321 | let nr = self.number; |
| 314 | T::regs().tasks_send(nr as usize).write_value(1); | 322 | self.r.tasks_send(nr as usize).write_value(1); |
| 315 | } | 323 | } |
| 316 | 324 | ||
| 317 | /// Returns the [`EventNumber`] of the event. | 325 | /// Returns the [`EventNumber`] of the event. |
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index c2a4ba65f..b6ee52850 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs | |||
| @@ -53,8 +53,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | /// PDM microphone interface | 55 | /// PDM microphone interface |
| 56 | pub struct Pdm<'d, T: Instance> { | 56 | pub struct Pdm<'d> { |
| 57 | _peri: Peri<'d, T>, | 57 | r: pac::pdm::Pdm, |
| 58 | state: &'static State, | ||
| 59 | _phantom: PhantomData<&'d ()>, | ||
| 58 | } | 60 | } |
| 59 | 61 | ||
| 60 | /// PDM error | 62 | /// PDM error |
| @@ -86,9 +88,9 @@ pub enum SamplerState { | |||
| 86 | Stopped, | 88 | Stopped, |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | impl<'d, T: Instance> Pdm<'d, T> { | 91 | impl<'d> Pdm<'d> { |
| 90 | /// Create PDM driver | 92 | /// Create PDM driver |
| 91 | pub fn new( | 93 | pub fn new<T: Instance>( |
| 92 | pdm: Peri<'d, T>, | 94 | pdm: Peri<'d, T>, |
| 93 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 95 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 94 | clk: Peri<'d, impl GpioPin>, | 96 | clk: Peri<'d, impl GpioPin>, |
| @@ -98,7 +100,7 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 98 | Self::new_inner(pdm, clk.into(), din.into(), config) | 100 | Self::new_inner(pdm, clk.into(), din.into(), config) |
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | fn new_inner(pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self { | 103 | fn new_inner<T: Instance>(_pdm: Peri<'d, T>, clk: Peri<'d, AnyPin>, din: Peri<'d, AnyPin>, config: Config) -> Self { |
| 102 | let r = T::regs(); | 104 | let r = T::regs(); |
| 103 | 105 | ||
| 104 | // setup gpio pins | 106 | // setup gpio pins |
| @@ -133,7 +135,11 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 133 | 135 | ||
| 134 | r.enable().write(|w| w.set_enable(true)); | 136 | r.enable().write(|w| w.set_enable(true)); |
| 135 | 137 | ||
| 136 | Self { _peri: pdm } | 138 | Self { |
| 139 | r: T::regs(), | ||
| 140 | state: T::state(), | ||
| 141 | _phantom: PhantomData, | ||
| 142 | } | ||
| 137 | } | 143 | } |
| 138 | 144 | ||
| 139 | fn _set_gain(r: pac::pdm::Pdm, gain_left: I7F1, gain_right: I7F1) { | 145 | fn _set_gain(r: pac::pdm::Pdm, gain_left: I7F1, gain_right: I7F1) { |
| @@ -147,26 +153,26 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 147 | 153 | ||
| 148 | /// Adjust the gain of the PDM microphone on the fly | 154 | /// Adjust the gain of the PDM microphone on the fly |
| 149 | pub fn set_gain(&mut self, gain_left: I7F1, gain_right: I7F1) { | 155 | pub fn set_gain(&mut self, gain_left: I7F1, gain_right: I7F1) { |
| 150 | Self::_set_gain(T::regs(), gain_left, gain_right) | 156 | Self::_set_gain(self.r, gain_left, gain_right) |
| 151 | } | 157 | } |
| 152 | 158 | ||
| 153 | /// Start sampling microphone data into a dummy buffer. | 159 | /// Start sampling microphone data into a dummy buffer. |
| 154 | /// Useful to start the microphone and keep it active between recording samples. | 160 | /// Useful to start the microphone and keep it active between recording samples. |
| 155 | pub async fn start(&mut self) { | 161 | pub async fn start(&mut self) { |
| 156 | let r = T::regs(); | ||
| 157 | |||
| 158 | // start dummy sampling because microphone needs some setup time | 162 | // start dummy sampling because microphone needs some setup time |
| 159 | r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); | 163 | self.r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); |
| 160 | r.sample().maxcnt().write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); | 164 | self.r |
| 165 | .sample() | ||
| 166 | .maxcnt() | ||
| 167 | .write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); | ||
| 161 | 168 | ||
| 162 | r.tasks_start().write_value(1); | 169 | self.r.tasks_start().write_value(1); |
| 163 | } | 170 | } |
| 164 | 171 | ||
| 165 | /// Stop sampling microphone data inta a dummy buffer | 172 | /// Stop sampling microphone data inta a dummy buffer |
| 166 | pub async fn stop(&mut self) { | 173 | pub async fn stop(&mut self) { |
| 167 | let r = T::regs(); | 174 | self.r.tasks_stop().write_value(1); |
| 168 | r.tasks_stop().write_value(1); | 175 | self.r.events_started().write_value(0); |
| 169 | r.events_started().write_value(0); | ||
| 170 | } | 176 | } |
| 171 | 177 | ||
| 172 | /// Sample data into the given buffer | 178 | /// Sample data into the given buffer |
| @@ -178,12 +184,11 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 178 | return Err(Error::BufferTooLong); | 184 | return Err(Error::BufferTooLong); |
| 179 | } | 185 | } |
| 180 | 186 | ||
| 181 | let r = T::regs(); | 187 | if self.r.events_started().read() == 0 { |
| 182 | |||
| 183 | if r.events_started().read() == 0 { | ||
| 184 | return Err(Error::NotRunning); | 188 | return Err(Error::NotRunning); |
| 185 | } | 189 | } |
| 186 | 190 | ||
| 191 | let r = self.r; | ||
| 187 | let drop = OnDrop::new(move || { | 192 | let drop = OnDrop::new(move || { |
| 188 | r.intenclr().write(|w| w.set_end(true)); | 193 | r.intenclr().write(|w| w.set_end(true)); |
| 189 | r.events_stopped().write_value(0); | 194 | r.events_stopped().write_value(0); |
| @@ -198,34 +203,37 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 198 | // setup user buffer | 203 | // setup user buffer |
| 199 | let ptr = buffer.as_ptr(); | 204 | let ptr = buffer.as_ptr(); |
| 200 | let len = buffer.len(); | 205 | let len = buffer.len(); |
| 201 | r.sample().ptr().write_value(ptr as u32); | 206 | self.r.sample().ptr().write_value(ptr as u32); |
| 202 | r.sample().maxcnt().write(|w| w.set_buffsize(len as _)); | 207 | self.r.sample().maxcnt().write(|w| w.set_buffsize(len as _)); |
| 203 | 208 | ||
| 204 | // wait till the current sample is finished and the user buffer sample is started | 209 | // wait till the current sample is finished and the user buffer sample is started |
| 205 | Self::wait_for_sample().await; | 210 | self.wait_for_sample().await; |
| 206 | 211 | ||
| 207 | // reset the buffer back to the dummy buffer | 212 | // reset the buffer back to the dummy buffer |
| 208 | r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); | 213 | self.r.sample().ptr().write_value(DUMMY_BUFFER.as_ptr() as u32); |
| 209 | r.sample().maxcnt().write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); | 214 | self.r |
| 215 | .sample() | ||
| 216 | .maxcnt() | ||
| 217 | .write(|w| w.set_buffsize(DUMMY_BUFFER.len() as _)); | ||
| 210 | 218 | ||
| 211 | // wait till the user buffer is sampled | 219 | // wait till the user buffer is sampled |
| 212 | Self::wait_for_sample().await; | 220 | self.wait_for_sample().await; |
| 213 | 221 | ||
| 214 | drop.defuse(); | 222 | drop.defuse(); |
| 215 | 223 | ||
| 216 | Ok(()) | 224 | Ok(()) |
| 217 | } | 225 | } |
| 218 | 226 | ||
| 219 | async fn wait_for_sample() { | 227 | async fn wait_for_sample(&mut self) { |
| 220 | let r = T::regs(); | 228 | self.r.events_end().write_value(0); |
| 221 | 229 | self.r.intenset().write(|w| w.set_end(true)); | |
| 222 | r.events_end().write_value(0); | ||
| 223 | r.intenset().write(|w| w.set_end(true)); | ||
| 224 | 230 | ||
| 225 | compiler_fence(Ordering::SeqCst); | 231 | compiler_fence(Ordering::SeqCst); |
| 226 | 232 | ||
| 233 | let state = self.state; | ||
| 234 | let r = self.r; | ||
| 227 | poll_fn(|cx| { | 235 | poll_fn(|cx| { |
| 228 | T::state().waker.register(cx.waker()); | 236 | state.waker.register(cx.waker()); |
| 229 | if r.events_end().read() != 0 { | 237 | if r.events_end().read() != 0 { |
| 230 | return Poll::Ready(()); | 238 | return Poll::Ready(()); |
| 231 | } | 239 | } |
| @@ -255,20 +263,18 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 255 | where | 263 | where |
| 256 | S: FnMut(&[i16; N]) -> SamplerState, | 264 | S: FnMut(&[i16; N]) -> SamplerState, |
| 257 | { | 265 | { |
| 258 | let r = T::regs(); | 266 | if self.r.events_started().read() != 0 { |
| 259 | |||
| 260 | if r.events_started().read() != 0 { | ||
| 261 | return Err(Error::AlreadyRunning); | 267 | return Err(Error::AlreadyRunning); |
| 262 | } | 268 | } |
| 263 | 269 | ||
| 264 | r.sample().ptr().write_value(bufs[0].as_mut_ptr() as u32); | 270 | self.r.sample().ptr().write_value(bufs[0].as_mut_ptr() as u32); |
| 265 | r.sample().maxcnt().write(|w| w.set_buffsize(N as _)); | 271 | self.r.sample().maxcnt().write(|w| w.set_buffsize(N as _)); |
| 266 | 272 | ||
| 267 | // Reset and enable the events | 273 | // Reset and enable the events |
| 268 | r.events_end().write_value(0); | 274 | self.r.events_end().write_value(0); |
| 269 | r.events_started().write_value(0); | 275 | self.r.events_started().write_value(0); |
| 270 | r.events_stopped().write_value(0); | 276 | self.r.events_stopped().write_value(0); |
| 271 | r.intenset().write(|w| { | 277 | self.r.intenset().write(|w| { |
| 272 | w.set_end(true); | 278 | w.set_end(true); |
| 273 | w.set_started(true); | 279 | w.set_started(true); |
| 274 | w.set_stopped(true); | 280 | w.set_stopped(true); |
| @@ -278,23 +284,24 @@ impl<'d, T: Instance> Pdm<'d, T> { | |||
| 278 | // wouldn't happen anyway | 284 | // wouldn't happen anyway |
| 279 | compiler_fence(Ordering::SeqCst); | 285 | compiler_fence(Ordering::SeqCst); |
| 280 | 286 | ||
| 281 | r.tasks_start().write_value(1); | 287 | self.r.tasks_start().write_value(1); |
| 282 | 288 | ||
| 283 | let mut current_buffer = 0; | 289 | let mut current_buffer = 0; |
| 284 | 290 | ||
| 285 | let mut done = false; | 291 | let mut done = false; |
| 286 | 292 | ||
| 287 | let drop = OnDrop::new(|| { | 293 | let r = self.r; |
| 294 | let drop = OnDrop::new(move || { | ||
| 288 | r.tasks_stop().write_value(1); | 295 | r.tasks_stop().write_value(1); |
| 289 | // N.B. It would be better if this were async, but Drop only support sync code | 296 | // N.B. It would be better if this were async, but Drop only support sync code |
| 290 | while r.events_stopped().read() != 0 {} | 297 | while r.events_stopped().read() != 0 {} |
| 291 | }); | 298 | }); |
| 292 | 299 | ||
| 300 | let state = self.state; | ||
| 301 | let r = self.r; | ||
| 293 | // Wait for events and complete when the sampler indicates it has had enough | 302 | // Wait for events and complete when the sampler indicates it has had enough |
| 294 | poll_fn(|cx| { | 303 | poll_fn(|cx| { |
| 295 | let r = T::regs(); | 304 | state.waker.register(cx.waker()); |
| 296 | |||
| 297 | T::state().waker.register(cx.waker()); | ||
| 298 | 305 | ||
| 299 | if r.events_end().read() != 0 { | 306 | if r.events_end().read() != 0 { |
| 300 | compiler_fence(Ordering::SeqCst); | 307 | compiler_fence(Ordering::SeqCst); |
| @@ -411,16 +418,14 @@ impl From<Edge> for vals::Edge { | |||
| 411 | } | 418 | } |
| 412 | } | 419 | } |
| 413 | 420 | ||
| 414 | impl<'d, T: Instance> Drop for Pdm<'d, T> { | 421 | impl<'d> Drop for Pdm<'d> { |
| 415 | fn drop(&mut self) { | 422 | fn drop(&mut self) { |
| 416 | let r = T::regs(); | 423 | self.r.tasks_stop().write_value(1); |
| 417 | |||
| 418 | r.tasks_stop().write_value(1); | ||
| 419 | 424 | ||
| 420 | r.enable().write(|w| w.set_enable(false)); | 425 | self.r.enable().write(|w| w.set_enable(false)); |
| 421 | 426 | ||
| 422 | r.psel().din().write_value(DISCONNECTED); | 427 | self.r.psel().din().write_value(DISCONNECTED); |
| 423 | r.psel().clk().write_value(DISCONNECTED); | 428 | self.r.psel().clk().write_value(DISCONNECTED); |
| 424 | } | 429 | } |
| 425 | } | 430 | } |
| 426 | 431 | ||
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index d6b40b5c0..d67cb546b 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -15,8 +15,8 @@ use crate::{interrupt, pac}; | |||
| 15 | 15 | ||
| 16 | /// SimplePwm is the traditional pwm interface you're probably used to, allowing | 16 | /// SimplePwm is the traditional pwm interface you're probably used to, allowing |
| 17 | /// to simply set a duty cycle across up to four channels. | 17 | /// to simply set a duty cycle across up to four channels. |
| 18 | pub struct SimplePwm<'d, T: Instance> { | 18 | pub struct SimplePwm<'d> { |
| 19 | _peri: Peri<'d, T>, | 19 | r: pac::pwm::Pwm, |
| 20 | duty: [u16; 4], | 20 | duty: [u16; 4], |
| 21 | ch0: Option<Peri<'d, AnyPin>>, | 21 | ch0: Option<Peri<'d, AnyPin>>, |
| 22 | ch1: Option<Peri<'d, AnyPin>>, | 22 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -26,8 +26,8 @@ pub struct SimplePwm<'d, T: Instance> { | |||
| 26 | 26 | ||
| 27 | /// SequencePwm allows you to offload the updating of a sequence of duty cycles | 27 | /// SequencePwm allows you to offload the updating of a sequence of duty cycles |
| 28 | /// to up to four channels, as well as repeat that sequence n times. | 28 | /// to up to four channels, as well as repeat that sequence n times. |
| 29 | pub struct SequencePwm<'d, T: Instance> { | 29 | pub struct SequencePwm<'d> { |
| 30 | _peri: Peri<'d, T>, | 30 | r: pac::pwm::Pwm, |
| 31 | ch0: Option<Peri<'d, AnyPin>>, | 31 | ch0: Option<Peri<'d, AnyPin>>, |
| 32 | ch1: Option<Peri<'d, AnyPin>>, | 32 | ch1: Option<Peri<'d, AnyPin>>, |
| 33 | ch2: Option<Peri<'d, AnyPin>>, | 33 | ch2: Option<Peri<'d, AnyPin>>, |
| @@ -51,16 +51,16 @@ const MAX_SEQUENCE_LEN: usize = 32767; | |||
| 51 | /// The used pwm clock frequency | 51 | /// The used pwm clock frequency |
| 52 | pub const PWM_CLK_HZ: u32 = 16_000_000; | 52 | pub const PWM_CLK_HZ: u32 = 16_000_000; |
| 53 | 53 | ||
| 54 | impl<'d, T: Instance> SequencePwm<'d, T> { | 54 | impl<'d> SequencePwm<'d> { |
| 55 | /// Create a new 1-channel PWM | 55 | /// Create a new 1-channel PWM |
| 56 | #[allow(unused_unsafe)] | 56 | #[allow(unused_unsafe)] |
| 57 | pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { | 57 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { |
| 58 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) | 58 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | /// Create a new 2-channel PWM | 61 | /// Create a new 2-channel PWM |
| 62 | #[allow(unused_unsafe)] | 62 | #[allow(unused_unsafe)] |
| 63 | pub fn new_2ch( | 63 | pub fn new_2ch<T: Instance>( |
| 64 | pwm: Peri<'d, T>, | 64 | pwm: Peri<'d, T>, |
| 65 | ch0: Peri<'d, impl GpioPin>, | 65 | ch0: Peri<'d, impl GpioPin>, |
| 66 | ch1: Peri<'d, impl GpioPin>, | 66 | ch1: Peri<'d, impl GpioPin>, |
| @@ -71,7 +71,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 71 | 71 | ||
| 72 | /// Create a new 3-channel PWM | 72 | /// Create a new 3-channel PWM |
| 73 | #[allow(unused_unsafe)] | 73 | #[allow(unused_unsafe)] |
| 74 | pub fn new_3ch( | 74 | pub fn new_3ch<T: Instance>( |
| 75 | pwm: Peri<'d, T>, | 75 | pwm: Peri<'d, T>, |
| 76 | ch0: Peri<'d, impl GpioPin>, | 76 | ch0: Peri<'d, impl GpioPin>, |
| 77 | ch1: Peri<'d, impl GpioPin>, | 77 | ch1: Peri<'d, impl GpioPin>, |
| @@ -83,7 +83,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 83 | 83 | ||
| 84 | /// Create a new 4-channel PWM | 84 | /// Create a new 4-channel PWM |
| 85 | #[allow(unused_unsafe)] | 85 | #[allow(unused_unsafe)] |
| 86 | pub fn new_4ch( | 86 | pub fn new_4ch<T: Instance>( |
| 87 | pwm: Peri<'d, T>, | 87 | pwm: Peri<'d, T>, |
| 88 | ch0: Peri<'d, impl GpioPin>, | 88 | ch0: Peri<'d, impl GpioPin>, |
| 89 | ch1: Peri<'d, impl GpioPin>, | 89 | ch1: Peri<'d, impl GpioPin>, |
| @@ -101,7 +101,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 101 | ) | 101 | ) |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | fn new_inner( | 104 | fn new_inner<T: Instance>( |
| 105 | _pwm: Peri<'d, T>, | 105 | _pwm: Peri<'d, T>, |
| 106 | ch0: Option<Peri<'d, AnyPin>>, | 106 | ch0: Option<Peri<'d, AnyPin>>, |
| 107 | ch1: Option<Peri<'d, AnyPin>>, | 107 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -174,7 +174,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 174 | r.countertop().write(|w| w.set_countertop(config.max_duty)); | 174 | r.countertop().write(|w| w.set_countertop(config.max_duty)); |
| 175 | 175 | ||
| 176 | Ok(Self { | 176 | Ok(Self { |
| 177 | _peri: _pwm, | 177 | r: T::regs(), |
| 178 | ch0, | 178 | ch0, |
| 179 | ch1, | 179 | ch1, |
| 180 | ch2, | 180 | ch2, |
| @@ -185,57 +185,43 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 185 | /// Returns reference to `Stopped` event endpoint for PPI. | 185 | /// Returns reference to `Stopped` event endpoint for PPI. |
| 186 | #[inline(always)] | 186 | #[inline(always)] |
| 187 | pub fn event_stopped(&self) -> Event<'d> { | 187 | pub fn event_stopped(&self) -> Event<'d> { |
| 188 | let r = T::regs(); | 188 | Event::from_reg(self.r.events_stopped()) |
| 189 | |||
| 190 | Event::from_reg(r.events_stopped()) | ||
| 191 | } | 189 | } |
| 192 | 190 | ||
| 193 | /// Returns reference to `LoopsDone` event endpoint for PPI. | 191 | /// Returns reference to `LoopsDone` event endpoint for PPI. |
| 194 | #[inline(always)] | 192 | #[inline(always)] |
| 195 | pub fn event_loops_done(&self) -> Event<'d> { | 193 | pub fn event_loops_done(&self) -> Event<'d> { |
| 196 | let r = T::regs(); | 194 | Event::from_reg(self.r.events_loopsdone()) |
| 197 | |||
| 198 | Event::from_reg(r.events_loopsdone()) | ||
| 199 | } | 195 | } |
| 200 | 196 | ||
| 201 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. | 197 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. |
| 202 | #[inline(always)] | 198 | #[inline(always)] |
| 203 | pub fn event_pwm_period_end(&self) -> Event<'d> { | 199 | pub fn event_pwm_period_end(&self) -> Event<'d> { |
| 204 | let r = T::regs(); | 200 | Event::from_reg(self.r.events_pwmperiodend()) |
| 205 | |||
| 206 | Event::from_reg(r.events_pwmperiodend()) | ||
| 207 | } | 201 | } |
| 208 | 202 | ||
| 209 | /// Returns reference to `Seq0 End` event endpoint for PPI. | 203 | /// Returns reference to `Seq0 End` event endpoint for PPI. |
| 210 | #[inline(always)] | 204 | #[inline(always)] |
| 211 | pub fn event_seq_end(&self) -> Event<'d> { | 205 | pub fn event_seq_end(&self) -> Event<'d> { |
| 212 | let r = T::regs(); | 206 | Event::from_reg(self.r.events_seqend(0)) |
| 213 | |||
| 214 | Event::from_reg(r.events_seqend(0)) | ||
| 215 | } | 207 | } |
| 216 | 208 | ||
| 217 | /// Returns reference to `Seq1 End` event endpoint for PPI. | 209 | /// Returns reference to `Seq1 End` event endpoint for PPI. |
| 218 | #[inline(always)] | 210 | #[inline(always)] |
| 219 | pub fn event_seq1_end(&self) -> Event<'d> { | 211 | pub fn event_seq1_end(&self) -> Event<'d> { |
| 220 | let r = T::regs(); | 212 | Event::from_reg(self.r.events_seqend(1)) |
| 221 | |||
| 222 | Event::from_reg(r.events_seqend(1)) | ||
| 223 | } | 213 | } |
| 224 | 214 | ||
| 225 | /// Returns reference to `Seq0 Started` event endpoint for PPI. | 215 | /// Returns reference to `Seq0 Started` event endpoint for PPI. |
| 226 | #[inline(always)] | 216 | #[inline(always)] |
| 227 | pub fn event_seq0_started(&self) -> Event<'d> { | 217 | pub fn event_seq0_started(&self) -> Event<'d> { |
| 228 | let r = T::regs(); | 218 | Event::from_reg(self.r.events_seqstarted(0)) |
| 229 | |||
| 230 | Event::from_reg(r.events_seqstarted(0)) | ||
| 231 | } | 219 | } |
| 232 | 220 | ||
| 233 | /// Returns reference to `Seq1 Started` event endpoint for PPI. | 221 | /// Returns reference to `Seq1 Started` event endpoint for PPI. |
| 234 | #[inline(always)] | 222 | #[inline(always)] |
| 235 | pub fn event_seq1_started(&self) -> Event<'d> { | 223 | pub fn event_seq1_started(&self) -> Event<'d> { |
| 236 | let r = T::regs(); | 224 | Event::from_reg(self.r.events_seqstarted(1)) |
| 237 | |||
| 238 | Event::from_reg(r.events_seqstarted(1)) | ||
| 239 | } | 225 | } |
| 240 | 226 | ||
| 241 | /// Returns reference to `Seq0 Start` task endpoint for PPI. | 227 | /// Returns reference to `Seq0 Start` task endpoint for PPI. |
| @@ -244,9 +230,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 244 | /// Interacting with the sequence while it runs puts it in an unknown state | 230 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 245 | #[inline(always)] | 231 | #[inline(always)] |
| 246 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { | 232 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { |
| 247 | let r = T::regs(); | 233 | Task::from_reg(self.r.tasks_seqstart(0)) |
| 248 | |||
| 249 | Task::from_reg(r.tasks_seqstart(0)) | ||
| 250 | } | 234 | } |
| 251 | 235 | ||
| 252 | /// Returns reference to `Seq1 Started` task endpoint for PPI. | 236 | /// Returns reference to `Seq1 Started` task endpoint for PPI. |
| @@ -255,9 +239,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 255 | /// Interacting with the sequence while it runs puts it in an unknown state | 239 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 256 | #[inline(always)] | 240 | #[inline(always)] |
| 257 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { | 241 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { |
| 258 | let r = T::regs(); | 242 | Task::from_reg(self.r.tasks_seqstart(1)) |
| 259 | |||
| 260 | Task::from_reg(r.tasks_seqstart(1)) | ||
| 261 | } | 243 | } |
| 262 | 244 | ||
| 263 | /// Returns reference to `NextStep` task endpoint for PPI. | 245 | /// Returns reference to `NextStep` task endpoint for PPI. |
| @@ -266,9 +248,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 266 | /// Interacting with the sequence while it runs puts it in an unknown state | 248 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 267 | #[inline(always)] | 249 | #[inline(always)] |
| 268 | pub unsafe fn task_next_step(&self) -> Task<'d> { | 250 | pub unsafe fn task_next_step(&self) -> Task<'d> { |
| 269 | let r = T::regs(); | 251 | Task::from_reg(self.r.tasks_nextstep()) |
| 270 | |||
| 271 | Task::from_reg(r.tasks_nextstep()) | ||
| 272 | } | 252 | } |
| 273 | 253 | ||
| 274 | /// Returns reference to `Stop` task endpoint for PPI. | 254 | /// Returns reference to `Stop` task endpoint for PPI. |
| @@ -277,36 +257,34 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 277 | /// Interacting with the sequence while it runs puts it in an unknown state | 257 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 278 | #[inline(always)] | 258 | #[inline(always)] |
| 279 | pub unsafe fn task_stop(&self) -> Task<'d> { | 259 | pub unsafe fn task_stop(&self) -> Task<'d> { |
| 280 | let r = T::regs(); | 260 | Task::from_reg(self.r.tasks_stop()) |
| 281 | |||
| 282 | Task::from_reg(r.tasks_stop()) | ||
| 283 | } | 261 | } |
| 284 | } | 262 | } |
| 285 | 263 | ||
| 286 | impl<'a, T: Instance> Drop for SequencePwm<'a, T> { | 264 | impl<'a> Drop for SequencePwm<'a> { |
| 287 | fn drop(&mut self) { | 265 | fn drop(&mut self) { |
| 288 | let r = T::regs(); | ||
| 289 | |||
| 290 | if let Some(pin) = &self.ch0 { | 266 | if let Some(pin) = &self.ch0 { |
| 291 | pin.set_low(); | 267 | pin.set_low(); |
| 292 | pin.conf().write(|_| ()); | 268 | pin.conf().write(|_| ()); |
| 293 | r.psel().out(0).write_value(DISCONNECTED); | 269 | self.r.psel().out(0).write_value(DISCONNECTED); |
| 294 | } | 270 | } |
| 295 | if let Some(pin) = &self.ch1 { | 271 | if let Some(pin) = &self.ch1 { |
| 296 | pin.set_low(); | 272 | pin.set_low(); |
| 297 | pin.conf().write(|_| ()); | 273 | pin.conf().write(|_| ()); |
| 298 | r.psel().out(1).write_value(DISCONNECTED); | 274 | self.r.psel().out(1).write_value(DISCONNECTED); |
| 299 | } | 275 | } |
| 300 | if let Some(pin) = &self.ch2 { | 276 | if let Some(pin) = &self.ch2 { |
| 301 | pin.set_low(); | 277 | pin.set_low(); |
| 302 | pin.conf().write(|_| ()); | 278 | pin.conf().write(|_| ()); |
| 303 | r.psel().out(2).write_value(DISCONNECTED); | 279 | self.r.psel().out(2).write_value(DISCONNECTED); |
| 304 | } | 280 | } |
| 305 | if let Some(pin) = &self.ch3 { | 281 | if let Some(pin) = &self.ch3 { |
| 306 | pin.set_low(); | 282 | pin.set_low(); |
| 307 | pin.conf().write(|_| ()); | 283 | pin.conf().write(|_| ()); |
| 308 | r.psel().out(3).write_value(DISCONNECTED); | 284 | self.r.psel().out(3).write_value(DISCONNECTED); |
| 309 | } | 285 | } |
| 286 | |||
| 287 | self.r.enable().write(|w| w.set_enable(false)); | ||
| 310 | } | 288 | } |
| 311 | } | 289 | } |
| 312 | 290 | ||
| @@ -384,13 +362,13 @@ impl<'s> Sequence<'s> { | |||
| 384 | /// A single sequence that can be started and stopped. | 362 | /// A single sequence that can be started and stopped. |
| 385 | /// Takes one sequence along with its configuration. | 363 | /// Takes one sequence along with its configuration. |
| 386 | #[non_exhaustive] | 364 | #[non_exhaustive] |
| 387 | pub struct SingleSequencer<'d, 's, T: Instance> { | 365 | pub struct SingleSequencer<'d, 's> { |
| 388 | sequencer: Sequencer<'d, 's, T>, | 366 | sequencer: Sequencer<'d, 's>, |
| 389 | } | 367 | } |
| 390 | 368 | ||
| 391 | impl<'d, 's, T: Instance> SingleSequencer<'d, 's, T> { | 369 | impl<'d, 's> SingleSequencer<'d, 's> { |
| 392 | /// Create a new sequencer | 370 | /// Create a new sequencer |
| 393 | pub fn new(pwm: &'s mut SequencePwm<'d, T>, words: &'s [u16], config: SequenceConfig) -> Self { | 371 | pub fn new(pwm: &'s mut SequencePwm<'d>, words: &'s [u16], config: SequenceConfig) -> Self { |
| 394 | Self { | 372 | Self { |
| 395 | sequencer: Sequencer::new(pwm, Sequence::new(words, config), None), | 373 | sequencer: Sequencer::new(pwm, Sequence::new(words, config), None), |
| 396 | } | 374 | } |
| @@ -423,16 +401,16 @@ impl<'d, 's, T: Instance> SingleSequencer<'d, 's, T> { | |||
| 423 | /// In the case where no second sequence is provided then the first sequence | 401 | /// In the case where no second sequence is provided then the first sequence |
| 424 | /// is used. | 402 | /// is used. |
| 425 | #[non_exhaustive] | 403 | #[non_exhaustive] |
| 426 | pub struct Sequencer<'d, 's, T: Instance> { | 404 | pub struct Sequencer<'d, 's> { |
| 427 | _pwm: &'s mut SequencePwm<'d, T>, | 405 | _pwm: &'s mut SequencePwm<'d>, |
| 428 | sequence0: Sequence<'s>, | 406 | sequence0: Sequence<'s>, |
| 429 | sequence1: Option<Sequence<'s>>, | 407 | sequence1: Option<Sequence<'s>>, |
| 430 | } | 408 | } |
| 431 | 409 | ||
| 432 | impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | 410 | impl<'d, 's> Sequencer<'d, 's> { |
| 433 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 | 411 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 |
| 434 | /// will be used twice in the one loop. | 412 | /// will be used twice in the one loop. |
| 435 | pub fn new(pwm: &'s mut SequencePwm<'d, T>, sequence0: Sequence<'s>, sequence1: Option<Sequence<'s>>) -> Self { | 413 | pub fn new(pwm: &'s mut SequencePwm<'d>, sequence0: Sequence<'s>, sequence1: Option<Sequence<'s>>) -> Self { |
| 436 | Sequencer { | 414 | Sequencer { |
| 437 | _pwm: pwm, | 415 | _pwm: pwm, |
| 438 | sequence0, | 416 | sequence0, |
| @@ -459,7 +437,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 459 | 437 | ||
| 460 | self.stop(); | 438 | self.stop(); |
| 461 | 439 | ||
| 462 | let r = T::regs(); | 440 | let r = self._pwm.r; |
| 463 | 441 | ||
| 464 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); | 442 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); |
| 465 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); | 443 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); |
| @@ -499,7 +477,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 499 | /// `start` so that they may be further mutated. | 477 | /// `start` so that they may be further mutated. |
| 500 | #[inline(always)] | 478 | #[inline(always)] |
| 501 | pub fn stop(&self) { | 479 | pub fn stop(&self) { |
| 502 | let r = T::regs(); | 480 | let r = self._pwm.r; |
| 503 | 481 | ||
| 504 | r.shorts().write(|_| ()); | 482 | r.shorts().write(|_| ()); |
| 505 | 483 | ||
| @@ -510,7 +488,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 510 | } | 488 | } |
| 511 | } | 489 | } |
| 512 | 490 | ||
| 513 | impl<'d, 's, T: Instance> Drop for Sequencer<'d, 's, T> { | 491 | impl<'d, 's> Drop for Sequencer<'d, 's> { |
| 514 | fn drop(&mut self) { | 492 | fn drop(&mut self) { |
| 515 | self.stop(); | 493 | self.stop(); |
| 516 | } | 494 | } |
| @@ -589,22 +567,22 @@ pub enum CounterMode { | |||
| 589 | UpAndDown, | 567 | UpAndDown, |
| 590 | } | 568 | } |
| 591 | 569 | ||
| 592 | impl<'d, T: Instance> SimplePwm<'d, T> { | 570 | impl<'d> SimplePwm<'d> { |
| 593 | /// Create a new 1-channel PWM | 571 | /// Create a new 1-channel PWM |
| 594 | #[allow(unused_unsafe)] | 572 | #[allow(unused_unsafe)] |
| 595 | pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { | 573 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { |
| 596 | unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } | 574 | unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } |
| 597 | } | 575 | } |
| 598 | 576 | ||
| 599 | /// Create a new 2-channel PWM | 577 | /// Create a new 2-channel PWM |
| 600 | #[allow(unused_unsafe)] | 578 | #[allow(unused_unsafe)] |
| 601 | pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { | 579 | pub fn new_2ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { |
| 602 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) | 580 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) |
| 603 | } | 581 | } |
| 604 | 582 | ||
| 605 | /// Create a new 3-channel PWM | 583 | /// Create a new 3-channel PWM |
| 606 | #[allow(unused_unsafe)] | 584 | #[allow(unused_unsafe)] |
| 607 | pub fn new_3ch( | 585 | pub fn new_3ch<T: Instance>( |
| 608 | pwm: Peri<'d, T>, | 586 | pwm: Peri<'d, T>, |
| 609 | ch0: Peri<'d, impl GpioPin>, | 587 | ch0: Peri<'d, impl GpioPin>, |
| 610 | ch1: Peri<'d, impl GpioPin>, | 588 | ch1: Peri<'d, impl GpioPin>, |
| @@ -615,7 +593,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 615 | 593 | ||
| 616 | /// Create a new 4-channel PWM | 594 | /// Create a new 4-channel PWM |
| 617 | #[allow(unused_unsafe)] | 595 | #[allow(unused_unsafe)] |
| 618 | pub fn new_4ch( | 596 | pub fn new_4ch<T: Instance>( |
| 619 | pwm: Peri<'d, T>, | 597 | pwm: Peri<'d, T>, |
| 620 | ch0: Peri<'d, impl GpioPin>, | 598 | ch0: Peri<'d, impl GpioPin>, |
| 621 | ch1: Peri<'d, impl GpioPin>, | 599 | ch1: Peri<'d, impl GpioPin>, |
| @@ -633,7 +611,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 633 | } | 611 | } |
| 634 | } | 612 | } |
| 635 | 613 | ||
| 636 | fn new_inner( | 614 | fn new_inner<T: Instance>( |
| 637 | _pwm: Peri<'d, T>, | 615 | _pwm: Peri<'d, T>, |
| 638 | ch0: Option<Peri<'d, AnyPin>>, | 616 | ch0: Option<Peri<'d, AnyPin>>, |
| 639 | ch1: Option<Peri<'d, AnyPin>>, | 617 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -656,7 +634,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 656 | } | 634 | } |
| 657 | 635 | ||
| 658 | let pwm = Self { | 636 | let pwm = Self { |
| 659 | _peri: _pwm, | 637 | r: T::regs(), |
| 660 | ch0, | 638 | ch0, |
| 661 | ch1, | 639 | ch1, |
| 662 | ch2, | 640 | ch2, |
| @@ -691,22 +669,19 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 691 | /// Returns the enable state of the pwm counter | 669 | /// Returns the enable state of the pwm counter |
| 692 | #[inline(always)] | 670 | #[inline(always)] |
| 693 | pub fn is_enabled(&self) -> bool { | 671 | pub fn is_enabled(&self) -> bool { |
| 694 | let r = T::regs(); | 672 | self.r.enable().read().enable() |
| 695 | r.enable().read().enable() | ||
| 696 | } | 673 | } |
| 697 | 674 | ||
| 698 | /// Enables the PWM generator. | 675 | /// Enables the PWM generator. |
| 699 | #[inline(always)] | 676 | #[inline(always)] |
| 700 | pub fn enable(&self) { | 677 | pub fn enable(&self) { |
| 701 | let r = T::regs(); | 678 | self.r.enable().write(|w| w.set_enable(true)); |
| 702 | r.enable().write(|w| w.set_enable(true)); | ||
| 703 | } | 679 | } |
| 704 | 680 | ||
| 705 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. | 681 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. |
| 706 | #[inline(always)] | 682 | #[inline(always)] |
| 707 | pub fn disable(&self) { | 683 | pub fn disable(&self) { |
| 708 | let r = T::regs(); | 684 | self.r.enable().write(|w| w.set_enable(false)); |
| 709 | r.enable().write(|w| w.set_enable(false)); | ||
| 710 | } | 685 | } |
| 711 | 686 | ||
| 712 | /// Returns the current duty of the channel | 687 | /// Returns the current duty of the channel |
| @@ -716,32 +691,30 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 716 | 691 | ||
| 717 | /// Sets duty cycle (15 bit) for a PWM channel. | 692 | /// Sets duty cycle (15 bit) for a PWM channel. |
| 718 | pub fn set_duty(&mut self, channel: usize, duty: u16) { | 693 | pub fn set_duty(&mut self, channel: usize, duty: u16) { |
| 719 | let r = T::regs(); | ||
| 720 | |||
| 721 | self.duty[channel] = duty & 0x7FFF; | 694 | self.duty[channel] = duty & 0x7FFF; |
| 722 | 695 | ||
| 723 | // reload ptr in case self was moved | 696 | // reload ptr in case self was moved |
| 724 | r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); | 697 | self.r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); |
| 725 | 698 | ||
| 726 | // defensive before seqstart | 699 | // defensive before seqstart |
| 727 | compiler_fence(Ordering::SeqCst); | 700 | compiler_fence(Ordering::SeqCst); |
| 728 | 701 | ||
| 729 | r.events_seqend(0).write_value(0); | 702 | self.r.events_seqend(0).write_value(0); |
| 730 | 703 | ||
| 731 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 704 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 732 | r.tasks_seqstart(0).write_value(1); | 705 | self.r.tasks_seqstart(0).write_value(1); |
| 733 | 706 | ||
| 734 | // defensive wait until waveform is loaded after seqstart so set_duty | 707 | // defensive wait until waveform is loaded after seqstart so set_duty |
| 735 | // can't be called again while dma is still reading | 708 | // can't be called again while dma is still reading |
| 736 | if self.is_enabled() { | 709 | if self.is_enabled() { |
| 737 | while r.events_seqend(0).read() == 0 {} | 710 | while self.r.events_seqend(0).read() == 0 {} |
| 738 | } | 711 | } |
| 739 | } | 712 | } |
| 740 | 713 | ||
| 741 | /// Sets the PWM clock prescaler. | 714 | /// Sets the PWM clock prescaler. |
| 742 | #[inline(always)] | 715 | #[inline(always)] |
| 743 | pub fn set_prescaler(&self, div: Prescaler) { | 716 | pub fn set_prescaler(&self, div: Prescaler) { |
| 744 | T::regs() | 717 | self.r |
| 745 | .prescaler() | 718 | .prescaler() |
| 746 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(div as u8))); | 719 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(div as u8))); |
| 747 | } | 720 | } |
| @@ -749,7 +722,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 749 | /// Gets the PWM clock prescaler. | 722 | /// Gets the PWM clock prescaler. |
| 750 | #[inline(always)] | 723 | #[inline(always)] |
| 751 | pub fn prescaler(&self) -> Prescaler { | 724 | pub fn prescaler(&self) -> Prescaler { |
| 752 | match T::regs().prescaler().read().prescaler().to_bits() { | 725 | match self.r.prescaler().read().prescaler().to_bits() { |
| 753 | 0 => Prescaler::Div1, | 726 | 0 => Prescaler::Div1, |
| 754 | 1 => Prescaler::Div2, | 727 | 1 => Prescaler::Div2, |
| 755 | 2 => Prescaler::Div4, | 728 | 2 => Prescaler::Div4, |
| @@ -765,13 +738,13 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 765 | /// Sets the maximum duty cycle value. | 738 | /// Sets the maximum duty cycle value. |
| 766 | #[inline(always)] | 739 | #[inline(always)] |
| 767 | pub fn set_max_duty(&self, duty: u16) { | 740 | pub fn set_max_duty(&self, duty: u16) { |
| 768 | T::regs().countertop().write(|w| w.set_countertop(duty.min(32767u16))); | 741 | self.r.countertop().write(|w| w.set_countertop(duty.min(32767u16))); |
| 769 | } | 742 | } |
| 770 | 743 | ||
| 771 | /// Returns the maximum duty cycle value. | 744 | /// Returns the maximum duty cycle value. |
| 772 | #[inline(always)] | 745 | #[inline(always)] |
| 773 | pub fn max_duty(&self) -> u16 { | 746 | pub fn max_duty(&self) -> u16 { |
| 774 | T::regs().countertop().read().countertop() | 747 | self.r.countertop().read().countertop() |
| 775 | } | 748 | } |
| 776 | 749 | ||
| 777 | /// Sets the PWM output frequency. | 750 | /// Sets the PWM output frequency. |
| @@ -823,9 +796,9 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 823 | } | 796 | } |
| 824 | } | 797 | } |
| 825 | 798 | ||
| 826 | impl<'a, T: Instance> Drop for SimplePwm<'a, T> { | 799 | impl<'a> Drop for SimplePwm<'a> { |
| 827 | fn drop(&mut self) { | 800 | fn drop(&mut self) { |
| 828 | let r = T::regs(); | 801 | let r = &self.r; |
| 829 | 802 | ||
| 830 | self.disable(); | 803 | self.disable(); |
| 831 | 804 | ||
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs index 69bfab0bb..0ebd7afb8 100644 --- a/embassy-nrf/src/qdec.rs +++ b/embassy-nrf/src/qdec.rs | |||
| @@ -16,8 +16,10 @@ use crate::pac::qdec::vals; | |||
| 16 | use crate::{interrupt, pac}; | 16 | use crate::{interrupt, pac}; |
| 17 | 17 | ||
| 18 | /// Quadrature decoder driver. | 18 | /// Quadrature decoder driver. |
| 19 | pub struct Qdec<'d, T: Instance> { | 19 | pub struct Qdec<'d> { |
| 20 | _p: Peri<'d, T>, | 20 | r: pac::qdec::Qdec, |
| 21 | state: &'static State, | ||
| 22 | _phantom: PhantomData<&'d ()>, | ||
| 21 | } | 23 | } |
| 22 | 24 | ||
| 23 | /// QDEC config | 25 | /// QDEC config |
| @@ -59,9 +61,9 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 59 | } | 61 | } |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | impl<'d, T: Instance> Qdec<'d, T> { | 64 | impl<'d> Qdec<'d> { |
| 63 | /// Create a new QDEC. | 65 | /// Create a new QDEC. |
| 64 | pub fn new( | 66 | pub fn new<T: Instance>( |
| 65 | qdec: Peri<'d, T>, | 67 | qdec: Peri<'d, T>, |
| 66 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 68 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 67 | a: Peri<'d, impl GpioPin>, | 69 | a: Peri<'d, impl GpioPin>, |
| @@ -72,7 +74,7 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | /// Create a new QDEC, with a pin for LED output. | 76 | /// Create a new QDEC, with a pin for LED output. |
| 75 | pub fn new_with_led( | 77 | pub fn new_with_led<T: Instance>( |
| 76 | qdec: Peri<'d, T>, | 78 | qdec: Peri<'d, T>, |
| 77 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 79 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 78 | a: Peri<'d, impl GpioPin>, | 80 | a: Peri<'d, impl GpioPin>, |
| @@ -83,8 +85,8 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 83 | Self::new_inner(qdec, a.into(), b.into(), Some(led.into()), config) | 85 | Self::new_inner(qdec, a.into(), b.into(), Some(led.into()), config) |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | fn new_inner( | 88 | fn new_inner<T: Instance>( |
| 87 | p: Peri<'d, T>, | 89 | _p: Peri<'d, T>, |
| 88 | a: Peri<'d, AnyPin>, | 90 | a: Peri<'d, AnyPin>, |
| 89 | b: Peri<'d, AnyPin>, | 91 | b: Peri<'d, AnyPin>, |
| 90 | led: Option<Peri<'d, AnyPin>>, | 92 | led: Option<Peri<'d, AnyPin>>, |
| @@ -147,7 +149,11 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 147 | // Start sampling | 149 | // Start sampling |
| 148 | r.tasks_start().write_value(1); | 150 | r.tasks_start().write_value(1); |
| 149 | 151 | ||
| 150 | Self { _p: p } | 152 | Self { |
| 153 | r: T::regs(), | ||
| 154 | state: T::state(), | ||
| 155 | _phantom: PhantomData, | ||
| 156 | } | ||
| 151 | } | 157 | } |
| 152 | 158 | ||
| 153 | /// Perform an asynchronous read of the decoder. | 159 | /// Perform an asynchronous read of the decoder. |
| @@ -173,17 +179,18 @@ impl<'d, T: Instance> Qdec<'d, T> { | |||
| 173 | /// # }; | 179 | /// # }; |
| 174 | /// ``` | 180 | /// ``` |
| 175 | pub async fn read(&mut self) -> i16 { | 181 | pub async fn read(&mut self) -> i16 { |
| 176 | let t = T::regs(); | 182 | self.r.intenset().write(|w| w.set_reportrdy(true)); |
| 177 | t.intenset().write(|w| w.set_reportrdy(true)); | 183 | self.r.tasks_readclracc().write_value(1); |
| 178 | t.tasks_readclracc().write_value(1); | ||
| 179 | 184 | ||
| 180 | poll_fn(|cx| { | 185 | let state = self.state; |
| 181 | T::state().waker.register(cx.waker()); | 186 | let r = self.r; |
| 182 | if t.events_reportrdy().read() == 0 { | 187 | poll_fn(move |cx| { |
| 188 | state.waker.register(cx.waker()); | ||
| 189 | if r.events_reportrdy().read() == 0 { | ||
| 183 | Poll::Pending | 190 | Poll::Pending |
| 184 | } else { | 191 | } else { |
| 185 | t.events_reportrdy().write_value(0); | 192 | r.events_reportrdy().write_value(0); |
| 186 | let acc = t.accread().read(); | 193 | let acc = r.accread().read(); |
| 187 | Poll::Ready(acc as i16) | 194 | Poll::Ready(acc as i16) |
| 188 | } | 195 | } |
| 189 | }) | 196 | }) |
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index e6e829f6e..94ad3f0d6 100755 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs | |||
| @@ -138,16 +138,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /// QSPI flash driver. | 140 | /// QSPI flash driver. |
| 141 | pub struct Qspi<'d, T: Instance> { | 141 | pub struct Qspi<'d> { |
| 142 | _peri: Peri<'d, T>, | 142 | r: pac::qspi::Qspi, |
| 143 | state: &'static State, | ||
| 143 | dpm_enabled: bool, | 144 | dpm_enabled: bool, |
| 144 | capacity: u32, | 145 | capacity: u32, |
| 146 | _phantom: PhantomData<&'d ()>, | ||
| 145 | } | 147 | } |
| 146 | 148 | ||
| 147 | impl<'d, T: Instance> Qspi<'d, T> { | 149 | impl<'d> Qspi<'d> { |
| 148 | /// Create a new QSPI driver. | 150 | /// Create a new QSPI driver. |
| 149 | pub fn new( | 151 | pub fn new<T: Instance>( |
| 150 | qspi: Peri<'d, T>, | 152 | _qspi: Peri<'d, T>, |
| 151 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 153 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 152 | sck: Peri<'d, impl GpioPin>, | 154 | sck: Peri<'d, impl GpioPin>, |
| 153 | csn: Peri<'d, impl GpioPin>, | 155 | csn: Peri<'d, impl GpioPin>, |
| @@ -214,9 +216,11 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 214 | r.enable().write(|w| w.set_enable(true)); | 216 | r.enable().write(|w| w.set_enable(true)); |
| 215 | 217 | ||
| 216 | let res = Self { | 218 | let res = Self { |
| 217 | _peri: qspi, | 219 | r: T::regs(), |
| 220 | state: T::state(), | ||
| 218 | dpm_enabled: config.deep_power_down.is_some(), | 221 | dpm_enabled: config.deep_power_down.is_some(), |
| 219 | capacity: config.capacity, | 222 | capacity: config.capacity, |
| 223 | _phantom: PhantomData, | ||
| 220 | }; | 224 | }; |
| 221 | 225 | ||
| 222 | r.events_ready().write_value(0); | 226 | r.events_ready().write_value(0); |
| @@ -274,14 +278,13 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 274 | } | 278 | } |
| 275 | } | 279 | } |
| 276 | 280 | ||
| 277 | let r = T::regs(); | 281 | self.r.cinstrdat0().write(|w| w.0 = dat0); |
| 278 | r.cinstrdat0().write(|w| w.0 = dat0); | 282 | self.r.cinstrdat1().write(|w| w.0 = dat1); |
| 279 | r.cinstrdat1().write(|w| w.0 = dat1); | ||
| 280 | 283 | ||
| 281 | r.events_ready().write_value(0); | 284 | self.r.events_ready().write_value(0); |
| 282 | r.intenset().write(|w| w.set_ready(true)); | 285 | self.r.intenset().write(|w| w.set_ready(true)); |
| 283 | 286 | ||
| 284 | r.cinstrconf().write(|w| { | 287 | self.r.cinstrconf().write(|w| { |
| 285 | w.set_opcode(opcode); | 288 | w.set_opcode(opcode); |
| 286 | w.set_length(vals::Length::from_bits(len + 1)); | 289 | w.set_length(vals::Length::from_bits(len + 1)); |
| 287 | w.set_lio2(true); | 290 | w.set_lio2(true); |
| @@ -295,10 +298,8 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 295 | } | 298 | } |
| 296 | 299 | ||
| 297 | fn custom_instruction_finish(&mut self, resp: &mut [u8]) -> Result<(), Error> { | 300 | fn custom_instruction_finish(&mut self, resp: &mut [u8]) -> Result<(), Error> { |
| 298 | let r = T::regs(); | 301 | let dat0 = self.r.cinstrdat0().read().0; |
| 299 | 302 | let dat1 = self.r.cinstrdat1().read().0; | |
| 300 | let dat0 = r.cinstrdat0().read().0; | ||
| 301 | let dat1 = r.cinstrdat1().read().0; | ||
| 302 | for i in 0..4 { | 303 | for i in 0..4 { |
| 303 | if i < resp.len() { | 304 | if i < resp.len() { |
| 304 | resp[i] = (dat0 >> (i * 8)) as u8; | 305 | resp[i] = (dat0 >> (i * 8)) as u8; |
| @@ -313,9 +314,9 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 313 | } | 314 | } |
| 314 | 315 | ||
| 315 | fn wait_ready(&mut self) -> impl Future<Output = ()> { | 316 | fn wait_ready(&mut self) -> impl Future<Output = ()> { |
| 317 | let r = self.r; | ||
| 318 | let s = self.state; | ||
| 316 | poll_fn(move |cx| { | 319 | poll_fn(move |cx| { |
| 317 | let r = T::regs(); | ||
| 318 | let s = T::state(); | ||
| 319 | s.waker.register(cx.waker()); | 320 | s.waker.register(cx.waker()); |
| 320 | if r.events_ready().read() != 0 { | 321 | if r.events_ready().read() != 0 { |
| 321 | return Poll::Ready(()); | 322 | return Poll::Ready(()); |
| @@ -326,7 +327,7 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 326 | 327 | ||
| 327 | fn blocking_wait_ready() { | 328 | fn blocking_wait_ready() { |
| 328 | loop { | 329 | loop { |
| 329 | let r = T::regs(); | 330 | let r = pac::QSPI; |
| 330 | if r.events_ready().read() != 0 { | 331 | if r.events_ready().read() != 0 { |
| 331 | break; | 332 | break; |
| 332 | } | 333 | } |
| @@ -339,15 +340,13 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 339 | assert_eq!(data.len() as u32 % 4, 0); | 340 | assert_eq!(data.len() as u32 % 4, 0); |
| 340 | assert_eq!(address % 4, 0); | 341 | assert_eq!(address % 4, 0); |
| 341 | 342 | ||
| 342 | let r = T::regs(); | 343 | self.r.read().src().write_value(address); |
| 343 | 344 | self.r.read().dst().write_value(data.as_ptr() as u32); | |
| 344 | r.read().src().write_value(address); | 345 | self.r.read().cnt().write(|w| w.set_cnt(data.len() as u32)); |
| 345 | r.read().dst().write_value(data.as_ptr() as u32); | ||
| 346 | r.read().cnt().write(|w| w.set_cnt(data.len() as u32)); | ||
| 347 | 346 | ||
| 348 | r.events_ready().write_value(0); | 347 | self.r.events_ready().write_value(0); |
| 349 | r.intenset().write(|w| w.set_ready(true)); | 348 | self.r.intenset().write(|w| w.set_ready(true)); |
| 350 | r.tasks_readstart().write_value(1); | 349 | self.r.tasks_readstart().write_value(1); |
| 351 | 350 | ||
| 352 | Ok(()) | 351 | Ok(()) |
| 353 | } | 352 | } |
| @@ -358,14 +357,13 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 358 | assert_eq!(data.len() as u32 % 4, 0); | 357 | assert_eq!(data.len() as u32 % 4, 0); |
| 359 | assert_eq!(address % 4, 0); | 358 | assert_eq!(address % 4, 0); |
| 360 | 359 | ||
| 361 | let r = T::regs(); | 360 | self.r.write().src().write_value(data.as_ptr() as u32); |
| 362 | r.write().src().write_value(data.as_ptr() as u32); | 361 | self.r.write().dst().write_value(address); |
| 363 | r.write().dst().write_value(address); | 362 | self.r.write().cnt().write(|w| w.set_cnt(data.len() as u32)); |
| 364 | r.write().cnt().write(|w| w.set_cnt(data.len() as u32)); | ||
| 365 | 363 | ||
| 366 | r.events_ready().write_value(0); | 364 | self.r.events_ready().write_value(0); |
| 367 | r.intenset().write(|w| w.set_ready(true)); | 365 | self.r.intenset().write(|w| w.set_ready(true)); |
| 368 | r.tasks_writestart().write_value(1); | 366 | self.r.tasks_writestart().write_value(1); |
| 369 | 367 | ||
| 370 | Ok(()) | 368 | Ok(()) |
| 371 | } | 369 | } |
| @@ -374,13 +372,12 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 374 | // TODO: Return these as errors instead. | 372 | // TODO: Return these as errors instead. |
| 375 | assert_eq!(address % 4096, 0); | 373 | assert_eq!(address % 4096, 0); |
| 376 | 374 | ||
| 377 | let r = T::regs(); | 375 | self.r.erase().ptr().write_value(address); |
| 378 | r.erase().ptr().write_value(address); | 376 | self.r.erase().len().write(|w| w.set_len(vals::Len::_4KB)); |
| 379 | r.erase().len().write(|w| w.set_len(vals::Len::_4KB)); | ||
| 380 | 377 | ||
| 381 | r.events_ready().write_value(0); | 378 | self.r.events_ready().write_value(0); |
| 382 | r.intenset().write(|w| w.set_ready(true)); | 379 | self.r.intenset().write(|w| w.set_ready(true)); |
| 383 | r.tasks_erasestart().write_value(1); | 380 | self.r.tasks_erasestart().write_value(1); |
| 384 | 381 | ||
| 385 | Ok(()) | 382 | Ok(()) |
| 386 | } | 383 | } |
| @@ -520,19 +517,17 @@ impl<'d, T: Instance> Qspi<'d, T> { | |||
| 520 | } | 517 | } |
| 521 | } | 518 | } |
| 522 | 519 | ||
| 523 | impl<'d, T: Instance> Drop for Qspi<'d, T> { | 520 | impl<'d> Drop for Qspi<'d> { |
| 524 | fn drop(&mut self) { | 521 | fn drop(&mut self) { |
| 525 | let r = T::regs(); | ||
| 526 | |||
| 527 | if self.dpm_enabled { | 522 | if self.dpm_enabled { |
| 528 | trace!("qspi: doing deep powerdown..."); | 523 | trace!("qspi: doing deep powerdown..."); |
| 529 | 524 | ||
| 530 | r.ifconfig1().modify(|w| w.set_dpmen(true)); | 525 | self.r.ifconfig1().modify(|w| w.set_dpmen(true)); |
| 531 | 526 | ||
| 532 | // Wait for DPM enter. | 527 | // Wait for DPM enter. |
| 533 | // Unfortunately we must spin. There's no way to do this interrupt-driven. | 528 | // Unfortunately we must spin. There's no way to do this interrupt-driven. |
| 534 | // The READY event does NOT fire on DPM enter (but it does fire on DPM exit :shrug:) | 529 | // The READY event does NOT fire on DPM enter (but it does fire on DPM exit :shrug:) |
| 535 | while !r.status().read().dpm() {} | 530 | while !self.r.status().read().dpm() {} |
| 536 | 531 | ||
| 537 | // Wait MORE for DPM enter. | 532 | // Wait MORE for DPM enter. |
| 538 | // I have absolutely no idea why, but the wait above is not enough :'( | 533 | // I have absolutely no idea why, but the wait above is not enough :'( |
| @@ -541,29 +536,29 @@ impl<'d, T: Instance> Drop for Qspi<'d, T> { | |||
| 541 | } | 536 | } |
| 542 | 537 | ||
| 543 | // it seems events_ready is not generated in response to deactivate. nrfx doesn't wait for it. | 538 | // it seems events_ready is not generated in response to deactivate. nrfx doesn't wait for it. |
| 544 | r.tasks_deactivate().write_value(1); | 539 | self.r.tasks_deactivate().write_value(1); |
| 545 | 540 | ||
| 546 | // Workaround https://docs.nordicsemi.com/bundle/errata_nRF52840_Rev3/page/ERR/nRF52840/Rev3/latest/anomaly_840_122.html | 541 | // Workaround https://docs.nordicsemi.com/bundle/errata_nRF52840_Rev3/page/ERR/nRF52840/Rev3/latest/anomaly_840_122.html |
| 547 | // Note that the doc has 2 register writes, but the first one is really the write to tasks_deactivate, | 542 | // Note that the doc has 2 register writes, but the first one is really the write to tasks_deactivate, |
| 548 | // so we only do the second one here. | 543 | // so we only do the second one here. |
| 549 | unsafe { ptr::write_volatile(0x40029054 as *mut u32, 1) } | 544 | unsafe { ptr::write_volatile(0x40029054 as *mut u32, 1) } |
| 550 | 545 | ||
| 551 | r.enable().write(|w| w.set_enable(false)); | 546 | self.r.enable().write(|w| w.set_enable(false)); |
| 552 | 547 | ||
| 553 | // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN, | 548 | // Note: we do NOT deconfigure CSN here. If DPM is in use and we disconnect CSN, |
| 554 | // leaving it floating, the flash chip might read it as zero which would cause it to | 549 | // leaving it floating, the flash chip might read it as zero which would cause it to |
| 555 | // spuriously exit DPM. | 550 | // spuriously exit DPM. |
| 556 | gpio::deconfigure_pin(r.psel().sck().read()); | 551 | gpio::deconfigure_pin(self.r.psel().sck().read()); |
| 557 | gpio::deconfigure_pin(r.psel().io0().read()); | 552 | gpio::deconfigure_pin(self.r.psel().io0().read()); |
| 558 | gpio::deconfigure_pin(r.psel().io1().read()); | 553 | gpio::deconfigure_pin(self.r.psel().io1().read()); |
| 559 | gpio::deconfigure_pin(r.psel().io2().read()); | 554 | gpio::deconfigure_pin(self.r.psel().io2().read()); |
| 560 | gpio::deconfigure_pin(r.psel().io3().read()); | 555 | gpio::deconfigure_pin(self.r.psel().io3().read()); |
| 561 | 556 | ||
| 562 | trace!("qspi: dropped"); | 557 | trace!("qspi: dropped"); |
| 563 | } | 558 | } |
| 564 | } | 559 | } |
| 565 | 560 | ||
| 566 | impl<'d, T: Instance> ErrorType for Qspi<'d, T> { | 561 | impl<'d> ErrorType for Qspi<'d> { |
| 567 | type Error = Error; | 562 | type Error = Error; |
| 568 | } | 563 | } |
| 569 | 564 | ||
| @@ -573,7 +568,7 @@ impl NorFlashError for Error { | |||
| 573 | } | 568 | } |
| 574 | } | 569 | } |
| 575 | 570 | ||
| 576 | impl<'d, T: Instance> ReadNorFlash for Qspi<'d, T> { | 571 | impl<'d> ReadNorFlash for Qspi<'d> { |
| 577 | const READ_SIZE: usize = 4; | 572 | const READ_SIZE: usize = 4; |
| 578 | 573 | ||
| 579 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | 574 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -586,7 +581,7 @@ impl<'d, T: Instance> ReadNorFlash for Qspi<'d, T> { | |||
| 586 | } | 581 | } |
| 587 | } | 582 | } |
| 588 | 583 | ||
| 589 | impl<'d, T: Instance> NorFlash for Qspi<'d, T> { | 584 | impl<'d> NorFlash for Qspi<'d> { |
| 590 | const WRITE_SIZE: usize = 4; | 585 | const WRITE_SIZE: usize = 4; |
| 591 | const ERASE_SIZE: usize = 4096; | 586 | const ERASE_SIZE: usize = 4096; |
| 592 | 587 | ||
| @@ -611,7 +606,7 @@ mod _eh1 { | |||
| 611 | 606 | ||
| 612 | use super::*; | 607 | use super::*; |
| 613 | 608 | ||
| 614 | impl<'d, T: Instance> AsyncNorFlash for Qspi<'d, T> { | 609 | impl<'d> AsyncNorFlash for Qspi<'d> { |
| 615 | const WRITE_SIZE: usize = <Self as NorFlash>::WRITE_SIZE; | 610 | const WRITE_SIZE: usize = <Self as NorFlash>::WRITE_SIZE; |
| 616 | const ERASE_SIZE: usize = <Self as NorFlash>::ERASE_SIZE; | 611 | const ERASE_SIZE: usize = <Self as NorFlash>::ERASE_SIZE; |
| 617 | 612 | ||
| @@ -627,7 +622,7 @@ mod _eh1 { | |||
| 627 | } | 622 | } |
| 628 | } | 623 | } |
| 629 | 624 | ||
| 630 | impl<'d, T: Instance> AsyncReadNorFlash for Qspi<'d, T> { | 625 | impl<'d> AsyncReadNorFlash for Qspi<'d> { |
| 631 | const READ_SIZE: usize = 4; | 626 | const READ_SIZE: usize = 4; |
| 632 | async fn read(&mut self, address: u32, data: &mut [u8]) -> Result<(), Self::Error> { | 627 | async fn read(&mut self, address: u32, data: &mut [u8]) -> Result<(), Self::Error> { |
| 633 | self.read(address, data).await | 628 | self.read(address, data).await |
diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs index 7f4f8f462..62af03a5a 100644 --- a/embassy-nrf/src/radio/ieee802154.rs +++ b/embassy-nrf/src/radio/ieee802154.rs | |||
| @@ -1,15 +1,17 @@ | |||
| 1 | //! IEEE 802.15.4 radio driver | 1 | //! IEEE 802.15.4 radio driver |
| 2 | 2 | ||
| 3 | use core::marker::PhantomData; | ||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 5 | use core::task::Poll; |
| 5 | 6 | ||
| 6 | use embassy_hal_internal::drop::OnDrop; | 7 | use embassy_hal_internal::drop::OnDrop; |
| 7 | 8 | ||
| 8 | use super::{Error, Instance, InterruptHandler, TxPower}; | 9 | use super::{Error, InterruptHandler, TxPower}; |
| 9 | use crate::interrupt::typelevel::Interrupt; | 10 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::interrupt::{self}; | 11 | use crate::interrupt::{self}; |
| 11 | use crate::pac::radio::vals; | 12 | use crate::pac::radio::vals; |
| 12 | pub use crate::pac::radio::vals::State as RadioState; | 13 | pub use crate::pac::radio::vals::State as RadioState; |
| 14 | use crate::radio::Instance; | ||
| 13 | use crate::Peri; | 15 | use crate::Peri; |
| 14 | 16 | ||
| 15 | /// Default (IEEE compliant) Start of Frame Delimiter | 17 | /// Default (IEEE compliant) Start of Frame Delimiter |
| @@ -32,18 +34,20 @@ pub enum Cca { | |||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | /// IEEE 802.15.4 radio driver. | 36 | /// IEEE 802.15.4 radio driver. |
| 35 | pub struct Radio<'d, T: Instance> { | 37 | pub struct Radio<'d> { |
| 36 | _p: Peri<'d, T>, | 38 | r: crate::pac::radio::Radio, |
| 39 | state: &'static crate::radio::State, | ||
| 37 | needs_enable: bool, | 40 | needs_enable: bool, |
| 41 | phantom: PhantomData<&'d ()>, | ||
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | impl<'d, T: Instance> Radio<'d, T> { | 44 | impl<'d> Radio<'d> { |
| 41 | /// Create a new IEEE 802.15.4 radio driver. | 45 | /// Create a new IEEE 802.15.4 radio driver. |
| 42 | pub fn new( | 46 | pub fn new<T: Instance>( |
| 43 | radio: Peri<'d, T>, | 47 | _radio: Peri<'d, T>, |
| 44 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 48 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 45 | ) -> Self { | 49 | ) -> Self { |
| 46 | let r = T::regs(); | 50 | let r = crate::pac::RADIO; |
| 47 | 51 | ||
| 48 | // Disable and enable to reset peripheral | 52 | // Disable and enable to reset peripheral |
| 49 | r.power().write(|w| w.set_power(false)); | 53 | r.power().write(|w| w.set_power(false)); |
| @@ -89,12 +93,14 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 89 | }); | 93 | }); |
| 90 | 94 | ||
| 91 | // Enable NVIC interrupt | 95 | // Enable NVIC interrupt |
| 92 | T::Interrupt::unpend(); | 96 | crate::interrupt::typelevel::RADIO::unpend(); |
| 93 | unsafe { T::Interrupt::enable() }; | 97 | unsafe { crate::interrupt::typelevel::RADIO::enable() }; |
| 94 | 98 | ||
| 95 | let mut radio = Self { | 99 | let mut radio = Self { |
| 96 | _p: radio, | 100 | r: crate::pac::RADIO, |
| 101 | state: T::state(), | ||
| 97 | needs_enable: false, | 102 | needs_enable: false, |
| 103 | phantom: PhantomData, | ||
| 98 | }; | 104 | }; |
| 99 | 105 | ||
| 100 | radio.set_sfd(DEFAULT_SFD); | 106 | radio.set_sfd(DEFAULT_SFD); |
| @@ -107,7 +113,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 107 | 113 | ||
| 108 | /// Changes the radio channel | 114 | /// Changes the radio channel |
| 109 | pub fn set_channel(&mut self, channel: u8) { | 115 | pub fn set_channel(&mut self, channel: u8) { |
| 110 | let r = T::regs(); | 116 | let r = self.r; |
| 111 | if channel < 11 || channel > 26 { | 117 | if channel < 11 || channel > 26 { |
| 112 | panic!("Bad 802.15.4 channel"); | 118 | panic!("Bad 802.15.4 channel"); |
| 113 | } | 119 | } |
| @@ -121,7 +127,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 121 | 127 | ||
| 122 | /// Changes the Clear Channel Assessment method | 128 | /// Changes the Clear Channel Assessment method |
| 123 | pub fn set_cca(&mut self, cca: Cca) { | 129 | pub fn set_cca(&mut self, cca: Cca) { |
| 124 | let r = T::regs(); | 130 | let r = self.r; |
| 125 | self.needs_enable = true; | 131 | self.needs_enable = true; |
| 126 | match cca { | 132 | match cca { |
| 127 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), | 133 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), |
| @@ -138,19 +144,19 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 138 | 144 | ||
| 139 | /// Changes the Start of Frame Delimiter (SFD) | 145 | /// Changes the Start of Frame Delimiter (SFD) |
| 140 | pub fn set_sfd(&mut self, sfd: u8) { | 146 | pub fn set_sfd(&mut self, sfd: u8) { |
| 141 | let r = T::regs(); | 147 | let r = self.r; |
| 142 | r.sfd().write(|w| w.set_sfd(sfd)); | 148 | r.sfd().write(|w| w.set_sfd(sfd)); |
| 143 | } | 149 | } |
| 144 | 150 | ||
| 145 | /// Clear interrupts | 151 | /// Clear interrupts |
| 146 | pub fn clear_all_interrupts(&mut self) { | 152 | pub fn clear_all_interrupts(&mut self) { |
| 147 | let r = T::regs(); | 153 | let r = self.r; |
| 148 | r.intenclr().write(|w| w.0 = 0xffff_ffff); | 154 | r.intenclr().write(|w| w.0 = 0xffff_ffff); |
| 149 | } | 155 | } |
| 150 | 156 | ||
| 151 | /// Changes the radio transmission power | 157 | /// Changes the radio transmission power |
| 152 | pub fn set_transmission_power(&mut self, power: i8) { | 158 | pub fn set_transmission_power(&mut self, power: i8) { |
| 153 | let r = T::regs(); | 159 | let r = self.r; |
| 154 | self.needs_enable = true; | 160 | self.needs_enable = true; |
| 155 | 161 | ||
| 156 | let tx_power: TxPower = match power { | 162 | let tx_power: TxPower = match power { |
| @@ -201,12 +207,12 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 201 | 207 | ||
| 202 | /// Get the current radio state | 208 | /// Get the current radio state |
| 203 | fn state(&self) -> RadioState { | 209 | fn state(&self) -> RadioState { |
| 204 | T::regs().state().read().state() | 210 | self.r.state().read().state() |
| 205 | } | 211 | } |
| 206 | 212 | ||
| 207 | /// Moves the radio from any state to the DISABLED state | 213 | /// Moves the radio from any state to the DISABLED state |
| 208 | fn disable(&mut self) { | 214 | fn disable(&mut self) { |
| 209 | let r = T::regs(); | 215 | let r = self.r; |
| 210 | // See figure 110 in nRF52840-PS | 216 | // See figure 110 in nRF52840-PS |
| 211 | loop { | 217 | loop { |
| 212 | match self.state() { | 218 | match self.state() { |
| @@ -238,15 +244,15 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 238 | } | 244 | } |
| 239 | 245 | ||
| 240 | fn set_buffer(&mut self, buffer: &[u8]) { | 246 | fn set_buffer(&mut self, buffer: &[u8]) { |
| 241 | let r = T::regs(); | 247 | let r = self.r; |
| 242 | r.packetptr().write_value(buffer.as_ptr() as u32); | 248 | r.packetptr().write_value(buffer.as_ptr() as u32); |
| 243 | } | 249 | } |
| 244 | 250 | ||
| 245 | /// Moves the radio to the RXIDLE state | 251 | /// Moves the radio to the RXIDLE state |
| 246 | fn receive_prepare(&mut self) { | 252 | fn receive_prepare(&mut self) { |
| 247 | // clear related events | 253 | // clear related events |
| 248 | T::regs().events_ccabusy().write_value(0); | 254 | self.r.events_ccabusy().write_value(0); |
| 249 | T::regs().events_phyend().write_value(0); | 255 | self.r.events_phyend().write_value(0); |
| 250 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE | 256 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE |
| 251 | let disable = match self.state() { | 257 | let disable = match self.state() { |
| 252 | RadioState::DISABLED => false, | 258 | RadioState::DISABLED => false, |
| @@ -263,7 +269,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 263 | fn receive_start(&mut self, packet: &mut Packet) { | 269 | fn receive_start(&mut self, packet: &mut Packet) { |
| 264 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's | 270 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 265 | // allocated in RAM | 271 | // allocated in RAM |
| 266 | let r = T::regs(); | 272 | let r = self.r; |
| 267 | 273 | ||
| 268 | self.receive_prepare(); | 274 | self.receive_prepare(); |
| 269 | 275 | ||
| @@ -290,7 +296,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 290 | 296 | ||
| 291 | /// Cancel receiving packet | 297 | /// Cancel receiving packet |
| 292 | fn receive_cancel() { | 298 | fn receive_cancel() { |
| 293 | let r = T::regs(); | 299 | let r = crate::pac::RADIO; |
| 294 | r.shorts().write(|_| {}); | 300 | r.shorts().write(|_| {}); |
| 295 | r.tasks_stop().write_value(1); | 301 | r.tasks_stop().write_value(1); |
| 296 | loop { | 302 | loop { |
| @@ -309,8 +315,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 309 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` | 315 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` |
| 310 | /// will be updated with the received packet's data | 316 | /// will be updated with the received packet's data |
| 311 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { | 317 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 312 | let s = T::state(); | 318 | let s = self.state; |
| 313 | let r = T::regs(); | 319 | let r = self.r; |
| 314 | 320 | ||
| 315 | // Start the read | 321 | // Start the read |
| 316 | self.receive_start(packet); | 322 | self.receive_start(packet); |
| @@ -356,8 +362,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 356 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's | 362 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 357 | // allocated in RAM | 363 | // allocated in RAM |
| 358 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { | 364 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 359 | let s = T::state(); | 365 | let s = self.state; |
| 360 | let r = T::regs(); | 366 | let r = self.r; |
| 361 | 367 | ||
| 362 | // enable radio to perform cca | 368 | // enable radio to perform cca |
| 363 | self.receive_prepare(); | 369 | self.receive_prepare(); |
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs index 9d3130e6e..8070c1afe 100644 --- a/embassy-nrf/src/rng.rs +++ b/embassy-nrf/src/rng.rs | |||
| @@ -56,21 +56,23 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 56 | /// A wrapper around an nRF RNG peripheral. | 56 | /// A wrapper around an nRF RNG peripheral. |
| 57 | /// | 57 | /// |
| 58 | /// It has a non-blocking API, and a blocking api through `rand`. | 58 | /// It has a non-blocking API, and a blocking api through `rand`. |
| 59 | pub struct Rng<'d, T: Instance, M: Mode> { | 59 | pub struct Rng<'d, M: Mode> { |
| 60 | _peri: Peri<'d, T>, | 60 | r: pac::rng::Rng, |
| 61 | _phantom: PhantomData<M>, | 61 | state: &'static State, |
| 62 | _phantom: PhantomData<(&'d (), M)>, | ||
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | impl<'d, T: Instance> Rng<'d, T, Blocking> { | 65 | impl<'d> Rng<'d, Blocking> { |
| 65 | /// Creates a new RNG driver from the `RNG` peripheral and interrupt. | 66 | /// Creates a new RNG driver from the `RNG` peripheral and interrupt. |
| 66 | /// | 67 | /// |
| 67 | /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor, | 68 | /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor, |
| 68 | /// e.g. using `mem::forget`. | 69 | /// e.g. using `mem::forget`. |
| 69 | /// | 70 | /// |
| 70 | /// The synchronous API is safe. | 71 | /// The synchronous API is safe. |
| 71 | pub fn new_blocking(rng: Peri<'d, T>) -> Self { | 72 | pub fn new_blocking<T: Instance>(_rng: Peri<'d, T>) -> Self { |
| 72 | let this = Self { | 73 | let this = Self { |
| 73 | _peri: rng, | 74 | r: T::regs(), |
| 75 | state: T::state(), | ||
| 74 | _phantom: PhantomData, | 76 | _phantom: PhantomData, |
| 75 | }; | 77 | }; |
| 76 | 78 | ||
| @@ -80,19 +82,20 @@ impl<'d, T: Instance> Rng<'d, T, Blocking> { | |||
| 80 | } | 82 | } |
| 81 | } | 83 | } |
| 82 | 84 | ||
| 83 | impl<'d, T: Instance> Rng<'d, T, Async> { | 85 | impl<'d> Rng<'d, Async> { |
| 84 | /// Creates a new RNG driver from the `RNG` peripheral and interrupt. | 86 | /// Creates a new RNG driver from the `RNG` peripheral and interrupt. |
| 85 | /// | 87 | /// |
| 86 | /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor, | 88 | /// SAFETY: The future returned from `fill_bytes` must not have its lifetime end without running its destructor, |
| 87 | /// e.g. using `mem::forget`. | 89 | /// e.g. using `mem::forget`. |
| 88 | /// | 90 | /// |
| 89 | /// The synchronous API is safe. | 91 | /// The synchronous API is safe. |
| 90 | pub fn new( | 92 | pub fn new<T: Instance>( |
| 91 | rng: Peri<'d, T>, | 93 | _rng: Peri<'d, T>, |
| 92 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 94 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 93 | ) -> Self { | 95 | ) -> Self { |
| 94 | let this = Self { | 96 | let this = Self { |
| 95 | _peri: rng, | 97 | r: T::regs(), |
| 98 | state: T::state(), | ||
| 96 | _phantom: PhantomData, | 99 | _phantom: PhantomData, |
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| @@ -106,11 +109,11 @@ impl<'d, T: Instance> Rng<'d, T, Async> { | |||
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | fn enable_irq(&self) { | 111 | fn enable_irq(&self) { |
| 109 | T::regs().intenset().write(|w| w.set_valrdy(true)); | 112 | self.r.intenset().write(|w| w.set_valrdy(true)); |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | fn disable_irq(&self) { | 115 | fn disable_irq(&self) { |
| 113 | T::regs().intenclr().write(|w| w.set_valrdy(true)); | 116 | self.r.intenclr().write(|w| w.set_valrdy(true)); |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | /// Fill the buffer with random bytes. | 119 | /// Fill the buffer with random bytes. |
| @@ -120,10 +123,11 @@ impl<'d, T: Instance> Rng<'d, T, Async> { | |||
| 120 | } | 123 | } |
| 121 | 124 | ||
| 122 | let range = dest.as_mut_ptr_range(); | 125 | let range = dest.as_mut_ptr_range(); |
| 126 | let state = self.state; | ||
| 123 | // Even if we've preempted the interrupt, it can't preempt us again, | 127 | // Even if we've preempted the interrupt, it can't preempt us again, |
| 124 | // so we don't need to worry about the order we write these in. | 128 | // so we don't need to worry about the order we write these in. |
| 125 | critical_section::with(|cs| { | 129 | critical_section::with(|cs| { |
| 126 | let mut state = T::state().borrow_mut(cs); | 130 | let mut state = state.borrow_mut(cs); |
| 127 | state.ptr = range.start; | 131 | state.ptr = range.start; |
| 128 | state.end = range.end; | 132 | state.end = range.end; |
| 129 | }); | 133 | }); |
| @@ -136,7 +140,7 @@ impl<'d, T: Instance> Rng<'d, T, Async> { | |||
| 136 | self.disable_irq(); | 140 | self.disable_irq(); |
| 137 | 141 | ||
| 138 | critical_section::with(|cs| { | 142 | critical_section::with(|cs| { |
| 139 | let mut state = T::state().borrow_mut(cs); | 143 | let mut state = state.borrow_mut(cs); |
| 140 | state.ptr = ptr::null_mut(); | 144 | state.ptr = ptr::null_mut(); |
| 141 | state.end = ptr::null_mut(); | 145 | state.end = ptr::null_mut(); |
| 142 | }); | 146 | }); |
| @@ -144,7 +148,7 @@ impl<'d, T: Instance> Rng<'d, T, Async> { | |||
| 144 | 148 | ||
| 145 | poll_fn(|cx| { | 149 | poll_fn(|cx| { |
| 146 | critical_section::with(|cs| { | 150 | critical_section::with(|cs| { |
| 147 | let mut s = T::state().borrow_mut(cs); | 151 | let mut s = state.borrow_mut(cs); |
| 148 | s.waker.register(cx.waker()); | 152 | s.waker.register(cx.waker()); |
| 149 | if s.ptr == s.end { | 153 | if s.ptr == s.end { |
| 150 | // We're done. | 154 | // We're done. |
| @@ -161,13 +165,13 @@ impl<'d, T: Instance> Rng<'d, T, Async> { | |||
| 161 | } | 165 | } |
| 162 | } | 166 | } |
| 163 | 167 | ||
| 164 | impl<'d, T: Instance, M: Mode> Rng<'d, T, M> { | 168 | impl<'d, M: Mode> Rng<'d, M> { |
| 165 | fn stop(&self) { | 169 | fn stop(&self) { |
| 166 | T::regs().tasks_stop().write_value(1) | 170 | self.r.tasks_stop().write_value(1) |
| 167 | } | 171 | } |
| 168 | 172 | ||
| 169 | fn start(&self) { | 173 | fn start(&self) { |
| 170 | T::regs().tasks_start().write_value(1) | 174 | self.r.tasks_start().write_value(1) |
| 171 | } | 175 | } |
| 172 | 176 | ||
| 173 | /// Enable or disable the RNG's bias correction. | 177 | /// Enable or disable the RNG's bias correction. |
| @@ -177,7 +181,7 @@ impl<'d, T: Instance, M: Mode> Rng<'d, T, M> { | |||
| 177 | /// | 181 | /// |
| 178 | /// Defaults to disabled. | 182 | /// Defaults to disabled. |
| 179 | pub fn set_bias_correction(&self, enable: bool) { | 183 | pub fn set_bias_correction(&self, enable: bool) { |
| 180 | T::regs().config().write(|w| w.set_dercen(enable)) | 184 | self.r.config().write(|w| w.set_dercen(enable)) |
| 181 | } | 185 | } |
| 182 | 186 | ||
| 183 | /// Fill the buffer with random bytes, blocking version. | 187 | /// Fill the buffer with random bytes, blocking version. |
| @@ -185,7 +189,7 @@ impl<'d, T: Instance, M: Mode> Rng<'d, T, M> { | |||
| 185 | self.start(); | 189 | self.start(); |
| 186 | 190 | ||
| 187 | for byte in dest.iter_mut() { | 191 | for byte in dest.iter_mut() { |
| 188 | let regs = T::regs(); | 192 | let regs = self.r; |
| 189 | while regs.events_valrdy().read() == 0 {} | 193 | while regs.events_valrdy().read() == 0 {} |
| 190 | regs.events_valrdy().write_value(0); | 194 | regs.events_valrdy().write_value(0); |
| 191 | *byte = regs.value().read().value(); | 195 | *byte = regs.value().read().value(); |
| @@ -210,18 +214,18 @@ impl<'d, T: Instance, M: Mode> Rng<'d, T, M> { | |||
| 210 | } | 214 | } |
| 211 | } | 215 | } |
| 212 | 216 | ||
| 213 | impl<'d, T: Instance, M: Mode> Drop for Rng<'d, T, M> { | 217 | impl<'d, M: Mode> Drop for Rng<'d, M> { |
| 214 | fn drop(&mut self) { | 218 | fn drop(&mut self) { |
| 215 | self.stop(); | 219 | self.stop(); |
| 216 | critical_section::with(|cs| { | 220 | critical_section::with(|cs| { |
| 217 | let mut state = T::state().borrow_mut(cs); | 221 | let mut state = self.state.borrow_mut(cs); |
| 218 | state.ptr = ptr::null_mut(); | 222 | state.ptr = ptr::null_mut(); |
| 219 | state.end = ptr::null_mut(); | 223 | state.end = ptr::null_mut(); |
| 220 | }); | 224 | }); |
| 221 | } | 225 | } |
| 222 | } | 226 | } |
| 223 | 227 | ||
| 224 | impl<'d, T: Instance, M: Mode> rand_core_06::RngCore for Rng<'d, T, M> { | 228 | impl<'d, M: Mode> rand_core_06::RngCore for Rng<'d, M> { |
| 225 | fn fill_bytes(&mut self, dest: &mut [u8]) { | 229 | fn fill_bytes(&mut self, dest: &mut [u8]) { |
| 226 | self.blocking_fill_bytes(dest); | 230 | self.blocking_fill_bytes(dest); |
| 227 | } | 231 | } |
| @@ -237,9 +241,9 @@ impl<'d, T: Instance, M: Mode> rand_core_06::RngCore for Rng<'d, T, M> { | |||
| 237 | } | 241 | } |
| 238 | } | 242 | } |
| 239 | 243 | ||
| 240 | impl<'d, T: Instance, M: Mode> rand_core_06::CryptoRng for Rng<'d, T, M> {} | 244 | impl<'d, M: Mode> rand_core_06::CryptoRng for Rng<'d, M> {} |
| 241 | 245 | ||
| 242 | impl<'d, T: Instance, M: Mode> rand_core_09::RngCore for Rng<'d, T, M> { | 246 | impl<'d, M: Mode> rand_core_09::RngCore for Rng<'d, M> { |
| 243 | fn fill_bytes(&mut self, dest: &mut [u8]) { | 247 | fn fill_bytes(&mut self, dest: &mut [u8]) { |
| 244 | self.blocking_fill_bytes(dest); | 248 | self.blocking_fill_bytes(dest); |
| 245 | } | 249 | } |
| @@ -251,7 +255,7 @@ impl<'d, T: Instance, M: Mode> rand_core_09::RngCore for Rng<'d, T, M> { | |||
| 251 | } | 255 | } |
| 252 | } | 256 | } |
| 253 | 257 | ||
| 254 | impl<'d, T: Instance, M: Mode> rand_core_09::CryptoRng for Rng<'d, T, M> {} | 258 | impl<'d, M: Mode> rand_core_09::CryptoRng for Rng<'d, M> {} |
| 255 | 259 | ||
| 256 | /// Peripheral static state | 260 | /// Peripheral static state |
| 257 | pub(crate) struct State { | 261 | pub(crate) struct State { |
diff --git a/embassy-nrf/src/rtc.rs b/embassy-nrf/src/rtc.rs index 1a90d1e24..652de511b 100644 --- a/embassy-nrf/src/rtc.rs +++ b/embassy-nrf/src/rtc.rs | |||
| @@ -2,10 +2,13 @@ | |||
| 2 | 2 | ||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::marker::PhantomData; | ||
| 6 | |||
| 7 | use embassy_hal_internal::interrupt::InterruptExt; | ||
| 5 | use embassy_hal_internal::{Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 6 | 9 | ||
| 7 | use crate::chip::interrupt::typelevel::Interrupt as _; | 10 | use crate::interrupt::typelevel::Interrupt as _; |
| 8 | use crate::pac; | 11 | use crate::{interrupt, pac}; |
| 9 | 12 | ||
| 10 | /// Prescaler has an invalid value which exceeds 12 bits. | 13 | /// Prescaler has an invalid value which exceeds 12 bits. |
| 11 | #[derive(Debug, PartialEq, Eq)] | 14 | #[derive(Debug, PartialEq, Eq)] |
| @@ -88,23 +91,31 @@ macro_rules! impl_rtc { | |||
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | /// nRF RTC driver. | 93 | /// nRF RTC driver. |
| 91 | pub struct Rtc<'d, T: Instance>(Peri<'d, T>); | 94 | pub struct Rtc<'d> { |
| 95 | r: pac::rtc::Rtc, | ||
| 96 | irq: interrupt::Interrupt, | ||
| 97 | _phantom: PhantomData<&'d ()>, | ||
| 98 | } | ||
| 92 | 99 | ||
| 93 | impl<'d, T: Instance> Rtc<'d, T> { | 100 | impl<'d> Rtc<'d> { |
| 94 | /// Create a new `Rtc` driver. | 101 | /// Create a new `Rtc` driver. |
| 95 | /// | 102 | /// |
| 96 | /// fRTC \[Hz\] = 32_768 / (`prescaler` + 1 ) | 103 | /// fRTC \[Hz\] = 32_768 / (`prescaler` + 1 ) |
| 97 | pub fn new(rtc: Peri<'d, T>, prescaler: u32) -> Result<Self, PrescalerOutOfRangeError> { | 104 | pub fn new<T: Instance>(_rtc: Peri<'d, T>, prescaler: u32) -> Result<Self, PrescalerOutOfRangeError> { |
| 98 | if prescaler >= (1 << 12) { | 105 | if prescaler >= (1 << 12) { |
| 99 | return Err(PrescalerOutOfRangeError(prescaler)); | 106 | return Err(PrescalerOutOfRangeError(prescaler)); |
| 100 | } | 107 | } |
| 101 | 108 | ||
| 102 | T::regs().prescaler().write(|w| w.set_prescaler(prescaler as u16)); | 109 | T::regs().prescaler().write(|w| w.set_prescaler(prescaler as u16)); |
| 103 | Ok(Self(rtc)) | 110 | Ok(Self { |
| 111 | r: T::regs(), | ||
| 112 | irq: T::Interrupt::IRQ, | ||
| 113 | _phantom: PhantomData, | ||
| 114 | }) | ||
| 104 | } | 115 | } |
| 105 | 116 | ||
| 106 | /// Create a new `Rtc` driver, configuring it to run at the given frequency. | 117 | /// Create a new `Rtc` driver, configuring it to run at the given frequency. |
| 107 | pub fn new_for_freq(rtc: Peri<'d, T>, freq_hz: u32) -> Result<Self, PrescalerOutOfRangeError> { | 118 | pub fn new_for_freq<T: Instance>(rtc: Peri<'d, T>, freq_hz: u32) -> Result<Self, PrescalerOutOfRangeError> { |
| 108 | let prescaler = (32_768 / freq_hz).saturating_sub(1); | 119 | let prescaler = (32_768 / freq_hz).saturating_sub(1); |
| 109 | Self::new(rtc, prescaler) | 120 | Self::new(rtc, prescaler) |
| 110 | } | 121 | } |
| @@ -115,34 +126,38 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 115 | /// | 126 | /// |
| 116 | /// Potentially allows to create multiple instances of the driver for the same peripheral | 127 | /// Potentially allows to create multiple instances of the driver for the same peripheral |
| 117 | /// which can lead to undefined behavior. | 128 | /// which can lead to undefined behavior. |
| 118 | pub unsafe fn steal() -> Self { | 129 | pub unsafe fn steal<T: Instance>() -> Self { |
| 119 | Self(unsafe { T::steal() }) | 130 | Self { |
| 131 | r: T::regs(), | ||
| 132 | irq: T::Interrupt::IRQ, | ||
| 133 | _phantom: PhantomData, | ||
| 134 | } | ||
| 120 | } | 135 | } |
| 121 | 136 | ||
| 122 | /// Direct access to the RTC registers. | 137 | /// Direct access to the RTC registers. |
| 123 | #[cfg(feature = "unstable-pac")] | 138 | #[cfg(feature = "unstable-pac")] |
| 124 | #[inline] | 139 | #[inline] |
| 125 | pub fn regs(&mut self) -> pac::rtc::Rtc { | 140 | pub fn regs(&mut self) -> pac::rtc::Rtc { |
| 126 | T::regs() | 141 | self.r |
| 127 | } | 142 | } |
| 128 | 143 | ||
| 129 | /// Enable the RTC. | 144 | /// Enable the RTC. |
| 130 | #[inline] | 145 | #[inline] |
| 131 | pub fn enable(&mut self) { | 146 | pub fn enable(&mut self) { |
| 132 | T::regs().tasks_start().write_value(1); | 147 | self.r.tasks_start().write_value(1); |
| 133 | } | 148 | } |
| 134 | 149 | ||
| 135 | /// Disable the RTC. | 150 | /// Disable the RTC. |
| 136 | #[inline] | 151 | #[inline] |
| 137 | pub fn disable(&mut self) { | 152 | pub fn disable(&mut self) { |
| 138 | T::regs().tasks_stop().write_value(1); | 153 | self.r.tasks_stop().write_value(1); |
| 139 | } | 154 | } |
| 140 | 155 | ||
| 141 | /// Enables interrupts for the given [Interrupt] source. | 156 | /// Enables interrupts for the given [Interrupt] source. |
| 142 | /// | 157 | /// |
| 143 | /// Optionally also enables the interrupt in the NVIC. | 158 | /// Optionally also enables the interrupt in the NVIC. |
| 144 | pub fn enable_interrupt(&mut self, int: Interrupt, enable_in_nvic: bool) { | 159 | pub fn enable_interrupt(&mut self, int: Interrupt, enable_in_nvic: bool) { |
| 145 | let regs = T::regs(); | 160 | let regs = self.r; |
| 146 | match int { | 161 | match int { |
| 147 | Interrupt::Tick => regs.intenset().write(|w| w.set_tick(true)), | 162 | Interrupt::Tick => regs.intenset().write(|w| w.set_tick(true)), |
| 148 | Interrupt::Overflow => regs.intenset().write(|w| w.set_ovrflw(true)), | 163 | Interrupt::Overflow => regs.intenset().write(|w| w.set_ovrflw(true)), |
| @@ -152,7 +167,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 152 | Interrupt::Compare3 => regs.intenset().write(|w| w.set_compare(3, true)), | 167 | Interrupt::Compare3 => regs.intenset().write(|w| w.set_compare(3, true)), |
| 153 | } | 168 | } |
| 154 | if enable_in_nvic { | 169 | if enable_in_nvic { |
| 155 | unsafe { T::Interrupt::enable() }; | 170 | unsafe { self.irq.enable() }; |
| 156 | } | 171 | } |
| 157 | } | 172 | } |
| 158 | 173 | ||
| @@ -160,7 +175,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 160 | /// | 175 | /// |
| 161 | /// Optionally also disables the interrupt in the NVIC. | 176 | /// Optionally also disables the interrupt in the NVIC. |
| 162 | pub fn disable_interrupt(&mut self, int: Interrupt, disable_in_nvic: bool) { | 177 | pub fn disable_interrupt(&mut self, int: Interrupt, disable_in_nvic: bool) { |
| 163 | let regs = T::regs(); | 178 | let regs = self.r; |
| 164 | match int { | 179 | match int { |
| 165 | Interrupt::Tick => regs.intenclr().write(|w| w.set_tick(true)), | 180 | Interrupt::Tick => regs.intenclr().write(|w| w.set_tick(true)), |
| 166 | Interrupt::Overflow => regs.intenclr().write(|w| w.set_ovrflw(true)), | 181 | Interrupt::Overflow => regs.intenclr().write(|w| w.set_ovrflw(true)), |
| @@ -170,13 +185,13 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 170 | Interrupt::Compare3 => regs.intenclr().write(|w| w.set_compare(3, true)), | 185 | Interrupt::Compare3 => regs.intenclr().write(|w| w.set_compare(3, true)), |
| 171 | } | 186 | } |
| 172 | if disable_in_nvic { | 187 | if disable_in_nvic { |
| 173 | T::Interrupt::disable(); | 188 | self.irq.disable(); |
| 174 | } | 189 | } |
| 175 | } | 190 | } |
| 176 | 191 | ||
| 177 | /// Enable the generation of a hardware event from a given stimulus. | 192 | /// Enable the generation of a hardware event from a given stimulus. |
| 178 | pub fn enable_event(&mut self, evt: Interrupt) { | 193 | pub fn enable_event(&mut self, evt: Interrupt) { |
| 179 | let regs = T::regs(); | 194 | let regs = self.r; |
| 180 | match evt { | 195 | match evt { |
| 181 | Interrupt::Tick => regs.evtenset().write(|w| w.set_tick(true)), | 196 | Interrupt::Tick => regs.evtenset().write(|w| w.set_tick(true)), |
| 182 | Interrupt::Overflow => regs.evtenset().write(|w| w.set_ovrflw(true)), | 197 | Interrupt::Overflow => regs.evtenset().write(|w| w.set_ovrflw(true)), |
| @@ -189,7 +204,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 189 | 204 | ||
| 190 | /// Disable the generation of a hardware event from a given stimulus. | 205 | /// Disable the generation of a hardware event from a given stimulus. |
| 191 | pub fn disable_event(&mut self, evt: Interrupt) { | 206 | pub fn disable_event(&mut self, evt: Interrupt) { |
| 192 | let regs = T::regs(); | 207 | let regs = self.r; |
| 193 | match evt { | 208 | match evt { |
| 194 | Interrupt::Tick => regs.evtenclr().write(|w| w.set_tick(true)), | 209 | Interrupt::Tick => regs.evtenclr().write(|w| w.set_tick(true)), |
| 195 | Interrupt::Overflow => regs.evtenclr().write(|w| w.set_ovrflw(true)), | 210 | Interrupt::Overflow => regs.evtenclr().write(|w| w.set_ovrflw(true)), |
| @@ -202,7 +217,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 202 | 217 | ||
| 203 | /// Resets the given event. | 218 | /// Resets the given event. |
| 204 | pub fn reset_event(&mut self, evt: Interrupt) { | 219 | pub fn reset_event(&mut self, evt: Interrupt) { |
| 205 | let regs = T::regs(); | 220 | let regs = self.r; |
| 206 | match evt { | 221 | match evt { |
| 207 | Interrupt::Tick => regs.events_tick().write_value(0), | 222 | Interrupt::Tick => regs.events_tick().write_value(0), |
| 208 | Interrupt::Overflow => regs.events_ovrflw().write_value(0), | 223 | Interrupt::Overflow => regs.events_ovrflw().write_value(0), |
| @@ -215,7 +230,7 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 215 | 230 | ||
| 216 | /// Checks if the given event has been triggered. | 231 | /// Checks if the given event has been triggered. |
| 217 | pub fn is_event_triggered(&self, evt: Interrupt) -> bool { | 232 | pub fn is_event_triggered(&self, evt: Interrupt) -> bool { |
| 218 | let regs = T::regs(); | 233 | let regs = self.r; |
| 219 | let val = match evt { | 234 | let val = match evt { |
| 220 | Interrupt::Tick => regs.events_tick().read(), | 235 | Interrupt::Tick => regs.events_tick().read(), |
| 221 | Interrupt::Overflow => regs.events_ovrflw().read(), | 236 | Interrupt::Overflow => regs.events_ovrflw().read(), |
| @@ -241,25 +256,19 @@ impl<'d, T: Instance> Rtc<'d, T> { | |||
| 241 | CompareChannel::_3 => 3, | 256 | CompareChannel::_3 => 3, |
| 242 | }; | 257 | }; |
| 243 | 258 | ||
| 244 | T::regs().cc(reg).write(|w| w.set_compare(val)); | 259 | self.r.cc(reg).write(|w| w.set_compare(val)); |
| 245 | Ok(()) | 260 | Ok(()) |
| 246 | } | 261 | } |
| 247 | 262 | ||
| 248 | /// Clear the Real Time Counter. | 263 | /// Clear the Real Time Counter. |
| 249 | #[inline] | 264 | #[inline] |
| 250 | pub fn clear(&self) { | 265 | pub fn clear(&self) { |
| 251 | T::regs().tasks_clear().write_value(1); | 266 | self.r.tasks_clear().write_value(1); |
| 252 | } | 267 | } |
| 253 | 268 | ||
| 254 | /// Obtain the current value of the Real Time Counter, 24 bits of range. | 269 | /// Obtain the current value of the Real Time Counter, 24 bits of range. |
| 255 | #[inline] | 270 | #[inline] |
| 256 | pub fn read(&self) -> u32 { | 271 | pub fn read(&self) -> u32 { |
| 257 | T::regs().counter().read().counter() | 272 | self.r.counter().read().counter() |
| 258 | } | ||
| 259 | |||
| 260 | /// Relase the RTC, returning the underlying peripheral instance. | ||
| 261 | #[inline] | ||
| 262 | pub fn release(self) -> Peri<'d, T> { | ||
| 263 | self.0 | ||
| 264 | } | 273 | } |
| 265 | } | 274 | } |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 2a3928d25..713163a55 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -96,14 +96,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | /// SPIS driver. | 99 | /// Serial Peripheral Interface in slave mode. |
| 100 | pub struct Spis<'d, T: Instance> { | 100 | pub struct Spis<'d> { |
| 101 | _p: Peri<'d, T>, | 101 | r: pac::spis::Spis, |
| 102 | state: &'static State, | ||
| 103 | _p: PhantomData<&'d ()>, | ||
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | impl<'d, T: Instance> Spis<'d, T> { | 106 | impl<'d> Spis<'d> { |
| 105 | /// Create a new SPIS driver. | 107 | /// Create a new SPIS driver. |
| 106 | pub fn new( | 108 | pub fn new<T: Instance>( |
| 107 | spis: Peri<'d, T>, | 109 | spis: Peri<'d, T>, |
| 108 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 110 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 109 | cs: Peri<'d, impl GpioPin>, | 111 | cs: Peri<'d, impl GpioPin>, |
| @@ -123,7 +125,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | /// Create a new SPIS driver, capable of TX only (MISO only). | 127 | /// Create a new SPIS driver, capable of TX only (MISO only). |
| 126 | pub fn new_txonly( | 128 | pub fn new_txonly<T: Instance>( |
| 127 | spis: Peri<'d, T>, | 129 | spis: Peri<'d, T>, |
| 128 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 130 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 129 | cs: Peri<'d, impl GpioPin>, | 131 | cs: Peri<'d, impl GpioPin>, |
| @@ -135,7 +137,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 135 | } | 137 | } |
| 136 | 138 | ||
| 137 | /// Create a new SPIS driver, capable of RX only (MOSI only). | 139 | /// Create a new SPIS driver, capable of RX only (MOSI only). |
| 138 | pub fn new_rxonly( | 140 | pub fn new_rxonly<T: Instance>( |
| 139 | spis: Peri<'d, T>, | 141 | spis: Peri<'d, T>, |
| 140 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 142 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 141 | cs: Peri<'d, impl GpioPin>, | 143 | cs: Peri<'d, impl GpioPin>, |
| @@ -147,7 +149,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 147 | } | 149 | } |
| 148 | 150 | ||
| 149 | /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. | 151 | /// Create a new SPIS driver, capable of TX only (MISO only) without SCK pin. |
| 150 | pub fn new_txonly_nosck( | 152 | pub fn new_txonly_nosck<T: Instance>( |
| 151 | spis: Peri<'d, T>, | 153 | spis: Peri<'d, T>, |
| 152 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 154 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 153 | cs: Peri<'d, impl GpioPin>, | 155 | cs: Peri<'d, impl GpioPin>, |
| @@ -157,8 +159,8 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 157 | Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config) | 159 | Self::new_inner(spis, cs.into(), None, Some(miso.into()), None, config) |
| 158 | } | 160 | } |
| 159 | 161 | ||
| 160 | fn new_inner( | 162 | fn new_inner<T: Instance>( |
| 161 | spis: Peri<'d, T>, | 163 | _spis: Peri<'d, T>, |
| 162 | cs: Peri<'d, AnyPin>, | 164 | cs: Peri<'d, AnyPin>, |
| 163 | sck: Option<Peri<'d, AnyPin>>, | 165 | sck: Option<Peri<'d, AnyPin>>, |
| 164 | miso: Option<Peri<'d, AnyPin>>, | 166 | miso: Option<Peri<'d, AnyPin>>, |
| @@ -191,10 +193,14 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 191 | // Enable SPIS instance. | 193 | // Enable SPIS instance. |
| 192 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 194 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 193 | 195 | ||
| 194 | let mut spis = Self { _p: spis }; | 196 | let mut spis = Self { |
| 197 | r: T::regs(), | ||
| 198 | state: T::state(), | ||
| 199 | _p: PhantomData, | ||
| 200 | }; | ||
| 195 | 201 | ||
| 196 | // Apply runtime peripheral configuration | 202 | // Apply runtime peripheral configuration |
| 197 | Self::set_config(&mut spis, &config).unwrap(); | 203 | spis.set_config(&config).unwrap(); |
| 198 | 204 | ||
| 199 | // Disable all events interrupts. | 205 | // Disable all events interrupts. |
| 200 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); | 206 | r.intenclr().write(|w| w.0 = 0xFFFF_FFFF); |
| @@ -212,7 +218,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 212 | 218 | ||
| 213 | compiler_fence(Ordering::SeqCst); | 219 | compiler_fence(Ordering::SeqCst); |
| 214 | 220 | ||
| 215 | let r = T::regs(); | 221 | let r = self.r; |
| 216 | 222 | ||
| 217 | // Set up the DMA write. | 223 | // Set up the DMA write. |
| 218 | if tx.len() > EASY_DMA_SIZE { | 224 | if tx.len() > EASY_DMA_SIZE { |
| @@ -239,7 +245,7 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 239 | 245 | ||
| 240 | fn blocking_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { | 246 | fn blocking_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { |
| 241 | compiler_fence(Ordering::SeqCst); | 247 | compiler_fence(Ordering::SeqCst); |
| 242 | let r = T::regs(); | 248 | let r = self.r; |
| 243 | 249 | ||
| 244 | // Acquire semaphore. | 250 | // Acquire semaphore. |
| 245 | if r.semstat().read().0 != 1 { | 251 | if r.semstat().read().0 != 1 { |
| @@ -276,8 +282,8 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | async fn async_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { | 284 | async fn async_inner_from_ram(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(usize, usize), Error> { |
| 279 | let r = T::regs(); | 285 | let r = self.r; |
| 280 | let s = T::state(); | 286 | let s = self.state; |
| 281 | 287 | ||
| 282 | // Clear status register. | 288 | // Clear status register. |
| 283 | r.status().write(|w| { | 289 | r.status().write(|w| { |
| @@ -420,21 +426,21 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 420 | 426 | ||
| 421 | /// Checks if last transaction overread. | 427 | /// Checks if last transaction overread. |
| 422 | pub fn is_overread(&mut self) -> bool { | 428 | pub fn is_overread(&mut self) -> bool { |
| 423 | T::regs().status().read().overread() | 429 | self.r.status().read().overread() |
| 424 | } | 430 | } |
| 425 | 431 | ||
| 426 | /// Checks if last transaction overflowed. | 432 | /// Checks if last transaction overflowed. |
| 427 | pub fn is_overflow(&mut self) -> bool { | 433 | pub fn is_overflow(&mut self) -> bool { |
| 428 | T::regs().status().read().overflow() | 434 | self.r.status().read().overflow() |
| 429 | } | 435 | } |
| 430 | } | 436 | } |
| 431 | 437 | ||
| 432 | impl<'d, T: Instance> Drop for Spis<'d, T> { | 438 | impl<'d> Drop for Spis<'d> { |
| 433 | fn drop(&mut self) { | 439 | fn drop(&mut self) { |
| 434 | trace!("spis drop"); | 440 | trace!("spis drop"); |
| 435 | 441 | ||
| 436 | // Disable | 442 | // Disable |
| 437 | let r = T::regs(); | 443 | let r = self.r; |
| 438 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); | 444 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 439 | 445 | ||
| 440 | gpio::deconfigure_pin(r.psel().sck().read()); | 446 | gpio::deconfigure_pin(r.psel().sck().read()); |
| @@ -489,11 +495,11 @@ macro_rules! impl_spis { | |||
| 489 | 495 | ||
| 490 | // ==================== | 496 | // ==================== |
| 491 | 497 | ||
| 492 | impl<'d, T: Instance> SetConfig for Spis<'d, T> { | 498 | impl<'d> SetConfig for Spis<'d> { |
| 493 | type Config = Config; | 499 | type Config = Config; |
| 494 | type ConfigError = (); | 500 | type ConfigError = (); |
| 495 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | 501 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { |
| 496 | let r = T::regs(); | 502 | let r = self.r; |
| 497 | // Configure mode. | 503 | // Configure mode. |
| 498 | let mode = config.mode; | 504 | let mode = config.mode; |
| 499 | r.config().write(|w| { | 505 | r.config().write(|w| { |
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs index 1d1f77ea8..0b0bb9780 100644 --- a/embassy-nrf/src/timer.rs +++ b/embassy-nrf/src/timer.rs | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #![macro_use] | 7 | #![macro_use] |
| 8 | 8 | ||
| 9 | use core::marker::PhantomData; | ||
| 10 | |||
| 9 | use embassy_hal_internal::{Peri, PeripheralType}; | 11 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 10 | 12 | ||
| 11 | use crate::pac; | 13 | use crate::pac; |
| @@ -81,16 +83,18 @@ pub enum Frequency { | |||
| 81 | /// | 83 | /// |
| 82 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter | 84 | /// It has either 4 or 6 Capture/Compare registers, which can be used to capture the current state of the counter |
| 83 | /// or trigger an event when the counter reaches a certain value. | 85 | /// or trigger an event when the counter reaches a certain value. |
| 84 | pub struct Timer<'d, T: Instance> { | 86 | pub struct Timer<'d> { |
| 85 | _p: Peri<'d, T>, | 87 | r: pac::timer::Timer, |
| 88 | ccs: usize, | ||
| 89 | _p: PhantomData<&'d ()>, | ||
| 86 | } | 90 | } |
| 87 | 91 | ||
| 88 | impl<'d, T: Instance> Timer<'d, T> { | 92 | impl<'d> Timer<'d> { |
| 89 | /// Create a new `Timer` driver. | 93 | /// Create a new `Timer` driver. |
| 90 | /// | 94 | /// |
| 91 | /// This can be useful for triggering tasks via PPI. | 95 | /// This can be useful for triggering tasks via PPI. |
| 92 | /// `Uarte` uses this internally. | 96 | /// `Uarte` uses this internally. |
| 93 | pub fn new(timer: Peri<'d, T>) -> Self { | 97 | pub fn new<T: Instance>(timer: Peri<'d, T>) -> Self { |
| 94 | Self::new_inner(timer, false) | 98 | Self::new_inner(timer, false) |
| 95 | } | 99 | } |
| 96 | 100 | ||
| @@ -98,14 +102,18 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 98 | /// | 102 | /// |
| 99 | /// This can be useful for triggering tasks via PPI. | 103 | /// This can be useful for triggering tasks via PPI. |
| 100 | /// `Uarte` uses this internally. | 104 | /// `Uarte` uses this internally. |
| 101 | pub fn new_counter(timer: Peri<'d, T>) -> Self { | 105 | pub fn new_counter<T: Instance>(timer: Peri<'d, T>) -> Self { |
| 102 | Self::new_inner(timer, true) | 106 | Self::new_inner(timer, true) |
| 103 | } | 107 | } |
| 104 | 108 | ||
| 105 | fn new_inner(timer: Peri<'d, T>, is_counter: bool) -> Self { | 109 | fn new_inner<T: Instance>(_timer: Peri<'d, T>, is_counter: bool) -> Self { |
| 106 | let regs = T::regs(); | 110 | let regs = T::regs(); |
| 107 | 111 | ||
| 108 | let this = Self { _p: timer }; | 112 | let this = Self { |
| 113 | r: regs, | ||
| 114 | ccs: T::CCS, | ||
| 115 | _p: PhantomData, | ||
| 116 | }; | ||
| 109 | 117 | ||
| 110 | // Stop the timer before doing anything else, | 118 | // Stop the timer before doing anything else, |
| 111 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. | 119 | // since changing BITMODE while running can cause 'unpredictable behaviour' according to the specification. |
| @@ -131,7 +139,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 131 | // Default to the max frequency of the lower power clock | 139 | // Default to the max frequency of the lower power clock |
| 132 | this.set_frequency(Frequency::F1MHz); | 140 | this.set_frequency(Frequency::F1MHz); |
| 133 | 141 | ||
| 134 | for n in 0..T::CCS { | 142 | for n in 0..this.ccs { |
| 135 | let cc = this.cc(n); | 143 | let cc = this.cc(n); |
| 136 | // Initialize all the shorts as disabled. | 144 | // Initialize all the shorts as disabled. |
| 137 | cc.unshort_compare_clear(); | 145 | cc.unshort_compare_clear(); |
| @@ -147,43 +155,43 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 147 | #[cfg(feature = "unstable-pac")] | 155 | #[cfg(feature = "unstable-pac")] |
| 148 | #[inline] | 156 | #[inline] |
| 149 | pub fn regs(&mut self) -> pac::timer::Timer { | 157 | pub fn regs(&mut self) -> pac::timer::Timer { |
| 150 | T::regs() | 158 | self.r |
| 151 | } | 159 | } |
| 152 | 160 | ||
| 153 | /// Starts the timer. | 161 | /// Starts the timer. |
| 154 | pub fn start(&self) { | 162 | pub fn start(&self) { |
| 155 | T::regs().tasks_start().write_value(1) | 163 | self.r.tasks_start().write_value(1) |
| 156 | } | 164 | } |
| 157 | 165 | ||
| 158 | /// Stops the timer. | 166 | /// Stops the timer. |
| 159 | pub fn stop(&self) { | 167 | pub fn stop(&self) { |
| 160 | T::regs().tasks_stop().write_value(1) | 168 | self.r.tasks_stop().write_value(1) |
| 161 | } | 169 | } |
| 162 | 170 | ||
| 163 | /// Reset the timer's counter to 0. | 171 | /// Reset the timer's counter to 0. |
| 164 | pub fn clear(&self) { | 172 | pub fn clear(&self) { |
| 165 | T::regs().tasks_clear().write_value(1) | 173 | self.r.tasks_clear().write_value(1) |
| 166 | } | 174 | } |
| 167 | 175 | ||
| 168 | /// Returns the START task, for use with PPI. | 176 | /// Returns the START task, for use with PPI. |
| 169 | /// | 177 | /// |
| 170 | /// When triggered, this task starts the timer. | 178 | /// When triggered, this task starts the timer. |
| 171 | pub fn task_start(&self) -> Task<'d> { | 179 | pub fn task_start(&self) -> Task<'d> { |
| 172 | Task::from_reg(T::regs().tasks_start()) | 180 | Task::from_reg(self.r.tasks_start()) |
| 173 | } | 181 | } |
| 174 | 182 | ||
| 175 | /// Returns the STOP task, for use with PPI. | 183 | /// Returns the STOP task, for use with PPI. |
| 176 | /// | 184 | /// |
| 177 | /// When triggered, this task stops the timer. | 185 | /// When triggered, this task stops the timer. |
| 178 | pub fn task_stop(&self) -> Task<'d> { | 186 | pub fn task_stop(&self) -> Task<'d> { |
| 179 | Task::from_reg(T::regs().tasks_stop()) | 187 | Task::from_reg(self.r.tasks_stop()) |
| 180 | } | 188 | } |
| 181 | 189 | ||
| 182 | /// Returns the CLEAR task, for use with PPI. | 190 | /// Returns the CLEAR task, for use with PPI. |
| 183 | /// | 191 | /// |
| 184 | /// When triggered, this task resets the timer's counter to 0. | 192 | /// When triggered, this task resets the timer's counter to 0. |
| 185 | pub fn task_clear(&self) -> Task<'d> { | 193 | pub fn task_clear(&self) -> Task<'d> { |
| 186 | Task::from_reg(T::regs().tasks_clear()) | 194 | Task::from_reg(self.r.tasks_clear()) |
| 187 | } | 195 | } |
| 188 | 196 | ||
| 189 | /// Returns the COUNT task, for use with PPI. | 197 | /// Returns the COUNT task, for use with PPI. |
| @@ -191,7 +199,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 191 | /// When triggered, this task increments the timer's counter by 1. | 199 | /// When triggered, this task increments the timer's counter by 1. |
| 192 | /// Only works in counter mode. | 200 | /// Only works in counter mode. |
| 193 | pub fn task_count(&self) -> Task<'d> { | 201 | pub fn task_count(&self) -> Task<'d> { |
| 194 | Task::from_reg(T::regs().tasks_count()) | 202 | Task::from_reg(self.r.tasks_count()) |
| 195 | } | 203 | } |
| 196 | 204 | ||
| 197 | /// Change the timer's frequency. | 205 | /// Change the timer's frequency. |
| @@ -201,7 +209,7 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 201 | pub fn set_frequency(&self, frequency: Frequency) { | 209 | pub fn set_frequency(&self, frequency: Frequency) { |
| 202 | self.stop(); | 210 | self.stop(); |
| 203 | 211 | ||
| 204 | T::regs() | 212 | self.r |
| 205 | .prescaler() | 213 | .prescaler() |
| 206 | // SAFETY: `frequency` is a variant of `Frequency`, | 214 | // SAFETY: `frequency` is a variant of `Frequency`, |
| 207 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). | 215 | // whose values are all in the range of 0-9 (the valid range of `prescaler`). |
| @@ -212,18 +220,19 @@ impl<'d, T: Instance> Timer<'d, T> { | |||
| 212 | /// | 220 | /// |
| 213 | /// # Panics | 221 | /// # Panics |
| 214 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). | 222 | /// Panics if `n` >= the number of CC registers this timer has (4 for a normal timer, 6 for an extended timer). |
| 215 | pub fn cc(&self, n: usize) -> Cc<'d, T> { | 223 | pub fn cc(&self, n: usize) -> Cc<'d> { |
| 216 | if n >= T::CCS { | 224 | if n >= self.ccs { |
| 217 | panic!("Cannot get CC register {} of timer with {} CC registers.", n, T::CCS); | 225 | panic!("Cannot get CC register {} of timer with {} CC registers.", n, self.ccs); |
| 218 | } | 226 | } |
| 219 | Cc { | 227 | Cc { |
| 220 | n, | 228 | n, |
| 221 | _p: unsafe { self._p.clone_unchecked() }, | 229 | r: self.r, |
| 230 | _p: PhantomData, | ||
| 222 | } | 231 | } |
| 223 | } | 232 | } |
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | impl<T: Instance> Timer<'static, T> { | 235 | impl Timer<'static> { |
| 227 | /// Persist the timer's configuration for the rest of the program's lifetime. This method | 236 | /// Persist the timer's configuration for the rest of the program's lifetime. This method |
| 228 | /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents | 237 | /// should be preferred over [`core::mem::forget()`] because the `'static` bound prevents |
| 229 | /// accidental reuse of the underlying peripheral. | 238 | /// accidental reuse of the underlying peripheral. |
| @@ -232,7 +241,7 @@ impl<T: Instance> Timer<'static, T> { | |||
| 232 | } | 241 | } |
| 233 | } | 242 | } |
| 234 | 243 | ||
| 235 | impl<'d, T: Instance> Drop for Timer<'d, T> { | 244 | impl<'d> Drop for Timer<'d> { |
| 236 | fn drop(&mut self) { | 245 | fn drop(&mut self) { |
| 237 | self.stop(); | 246 | self.stop(); |
| 238 | } | 247 | } |
| @@ -245,27 +254,28 @@ impl<'d, T: Instance> Drop for Timer<'d, T> { | |||
| 245 | /// | 254 | /// |
| 246 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. | 255 | /// The timer will fire the register's COMPARE event when its counter reaches the value stored in the register. |
| 247 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register | 256 | /// When the register's CAPTURE task is triggered, the timer will store the current value of its counter in the register |
| 248 | pub struct Cc<'d, T: Instance> { | 257 | pub struct Cc<'d> { |
| 249 | n: usize, | 258 | n: usize, |
| 250 | _p: Peri<'d, T>, | 259 | r: pac::timer::Timer, |
| 260 | _p: PhantomData<&'d ()>, | ||
| 251 | } | 261 | } |
| 252 | 262 | ||
| 253 | impl<'d, T: Instance> Cc<'d, T> { | 263 | impl<'d> Cc<'d> { |
| 254 | /// Get the current value stored in the register. | 264 | /// Get the current value stored in the register. |
| 255 | pub fn read(&self) -> u32 { | 265 | pub fn read(&self) -> u32 { |
| 256 | T::regs().cc(self.n).read() | 266 | self.r.cc(self.n).read() |
| 257 | } | 267 | } |
| 258 | 268 | ||
| 259 | /// Set the value stored in the register. | 269 | /// Set the value stored in the register. |
| 260 | /// | 270 | /// |
| 261 | /// `event_compare` will fire when the timer's counter reaches this value. | 271 | /// `event_compare` will fire when the timer's counter reaches this value. |
| 262 | pub fn write(&self, value: u32) { | 272 | pub fn write(&self, value: u32) { |
| 263 | T::regs().cc(self.n).write_value(value); | 273 | self.r.cc(self.n).write_value(value); |
| 264 | } | 274 | } |
| 265 | 275 | ||
| 266 | /// Capture the current value of the timer's counter in this register, and return it. | 276 | /// Capture the current value of the timer's counter in this register, and return it. |
| 267 | pub fn capture(&self) -> u32 { | 277 | pub fn capture(&self) -> u32 { |
| 268 | T::regs().tasks_capture(self.n).write_value(1); | 278 | self.r.tasks_capture(self.n).write_value(1); |
| 269 | self.read() | 279 | self.read() |
| 270 | } | 280 | } |
| 271 | 281 | ||
| @@ -273,20 +283,20 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 273 | /// | 283 | /// |
| 274 | /// When triggered, this task will capture the current value of the timer's counter in this register. | 284 | /// When triggered, this task will capture the current value of the timer's counter in this register. |
| 275 | pub fn task_capture(&self) -> Task<'d> { | 285 | pub fn task_capture(&self) -> Task<'d> { |
| 276 | Task::from_reg(T::regs().tasks_capture(self.n)) | 286 | Task::from_reg(self.r.tasks_capture(self.n)) |
| 277 | } | 287 | } |
| 278 | 288 | ||
| 279 | /// Returns this CC register's COMPARE event, for use with PPI. | 289 | /// Returns this CC register's COMPARE event, for use with PPI. |
| 280 | /// | 290 | /// |
| 281 | /// This event will fire when the timer's counter reaches the value in this CC register. | 291 | /// This event will fire when the timer's counter reaches the value in this CC register. |
| 282 | pub fn event_compare(&self) -> Event<'d> { | 292 | pub fn event_compare(&self) -> Event<'d> { |
| 283 | Event::from_reg(T::regs().events_compare(self.n)) | 293 | Event::from_reg(self.r.events_compare(self.n)) |
| 284 | } | 294 | } |
| 285 | 295 | ||
| 286 | /// Clear the COMPARE event for this CC register. | 296 | /// Clear the COMPARE event for this CC register. |
| 287 | #[inline] | 297 | #[inline] |
| 288 | pub fn clear_events(&self) { | 298 | pub fn clear_events(&self) { |
| 289 | T::regs().events_compare(self.n).write_value(0); | 299 | self.r.events_compare(self.n).write_value(0); |
| 290 | } | 300 | } |
| 291 | 301 | ||
| 292 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 302 | /// Enable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| @@ -295,12 +305,12 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 295 | /// | 305 | /// |
| 296 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. | 306 | /// So, when the timer's counter reaches the value stored in this register, the timer's counter will be reset to 0. |
| 297 | pub fn short_compare_clear(&self) { | 307 | pub fn short_compare_clear(&self) { |
| 298 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, true)) | 308 | self.r.shorts().modify(|w| w.set_compare_clear(self.n, true)) |
| 299 | } | 309 | } |
| 300 | 310 | ||
| 301 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. | 311 | /// Disable the shortcut between this CC register's COMPARE event and the timer's CLEAR task. |
| 302 | pub fn unshort_compare_clear(&self) { | 312 | pub fn unshort_compare_clear(&self) { |
| 303 | T::regs().shorts().modify(|w| w.set_compare_clear(self.n, false)) | 313 | self.r.shorts().modify(|w| w.set_compare_clear(self.n, false)) |
| 304 | } | 314 | } |
| 305 | 315 | ||
| 306 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 316 | /// Enable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| @@ -309,11 +319,11 @@ impl<'d, T: Instance> Cc<'d, T> { | |||
| 309 | /// | 319 | /// |
| 310 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. | 320 | /// So, when the timer's counter reaches the value stored in this register, the timer will stop counting up. |
| 311 | pub fn short_compare_stop(&self) { | 321 | pub fn short_compare_stop(&self) { |
| 312 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, true)) | 322 | self.r.shorts().modify(|w| w.set_compare_stop(self.n, true)) |
| 313 | } | 323 | } |
| 314 | 324 | ||
| 315 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. | 325 | /// Disable the shortcut between this CC register's COMPARE event and the timer's STOP task. |
| 316 | pub fn unshort_compare_stop(&self) { | 326 | pub fn unshort_compare_stop(&self) { |
| 317 | T::regs().shorts().modify(|w| w.set_compare_stop(self.n, false)) | 327 | self.r.shorts().modify(|w| w.set_compare_stop(self.n, false)) |
| 318 | } | 328 | } |
| 319 | } | 329 | } |
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs index 3fc59a39a..943ea9d31 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::future::{poll_fn, Future}; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::compiler_fence; | 7 | use core::sync::atomic::compiler_fence; |
| 8 | use core::sync::atomic::Ordering::SeqCst; | 8 | use core::sync::atomic::Ordering::SeqCst; |
| @@ -112,12 +112,14 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /// TWI driver. | 114 | /// TWI driver. |
| 115 | pub struct Twim<'d, T: Instance> { | 115 | pub struct Twim<'d> { |
| 116 | _p: Peri<'d, T>, | 116 | r: pac::twim::Twim, |
| 117 | state: &'static State, | ||
| 117 | tx_ram_buffer: &'d mut [u8], | 118 | tx_ram_buffer: &'d mut [u8], |
| 119 | _p: PhantomData<&'d ()>, | ||
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | impl<'d, T: Instance> Twim<'d, T> { | 122 | impl<'d> Twim<'d> { |
| 121 | /// Create a new TWI driver. | 123 | /// Create a new TWI driver. |
| 122 | /// | 124 | /// |
| 123 | /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM. | 125 | /// `tx_ram_buffer` is required if any write operations will be performed with data that is not in RAM. |
| @@ -125,8 +127,8 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 125 | /// needs to be at least as large as the largest write operation that will be executed with a buffer | 127 | /// needs to be at least as large as the largest write operation that will be executed with a buffer |
| 126 | /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may | 128 | /// that is not in RAM. If all write operations will be performed from RAM, an empty buffer (`&[]`) may |
| 127 | /// be used. | 129 | /// be used. |
| 128 | pub fn new( | 130 | pub fn new<T: Instance>( |
| 129 | twim: Peri<'d, T>, | 131 | _twim: Peri<'d, T>, |
| 130 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 132 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 131 | sda: Peri<'d, impl GpioPin>, | 133 | sda: Peri<'d, impl GpioPin>, |
| 132 | scl: Peri<'d, impl GpioPin>, | 134 | scl: Peri<'d, impl GpioPin>, |
| @@ -167,8 +169,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 167 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); | 169 | r.enable().write(|w| w.set_enable(vals::Enable::ENABLED)); |
| 168 | 170 | ||
| 169 | let mut twim = Self { | 171 | let mut twim = Self { |
| 170 | _p: twim, | 172 | r: T::regs(), |
| 173 | state: T::state(), | ||
| 171 | tx_ram_buffer, | 174 | tx_ram_buffer, |
| 175 | _p: PhantomData {}, | ||
| 172 | }; | 176 | }; |
| 173 | 177 | ||
| 174 | // Apply runtime peripheral configuration | 178 | // Apply runtime peripheral configuration |
| @@ -201,7 +205,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 201 | return Err(Error::TxBufferTooLong); | 205 | return Err(Error::TxBufferTooLong); |
| 202 | } | 206 | } |
| 203 | 207 | ||
| 204 | let r = T::regs(); | 208 | let r = self.r; |
| 205 | 209 | ||
| 206 | // We're giving the register a pointer to the stack. Since we're | 210 | // We're giving the register a pointer to the stack. Since we're |
| 207 | // waiting for the I2C transaction to end before this stack pointer | 211 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -228,7 +232,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 228 | return Err(Error::RxBufferTooLong); | 232 | return Err(Error::RxBufferTooLong); |
| 229 | } | 233 | } |
| 230 | 234 | ||
| 231 | let r = T::regs(); | 235 | let r = self.r; |
| 232 | 236 | ||
| 233 | // We're giving the register a pointer to the stack. Since we're | 237 | // We're giving the register a pointer to the stack. Since we're |
| 234 | // waiting for the I2C transaction to end before this stack pointer | 238 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -250,7 +254,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 250 | } | 254 | } |
| 251 | 255 | ||
| 252 | fn clear_errorsrc(&mut self) { | 256 | fn clear_errorsrc(&mut self) { |
| 253 | let r = T::regs(); | 257 | let r = self.r; |
| 254 | r.errorsrc().write(|w| { | 258 | r.errorsrc().write(|w| { |
| 255 | w.set_anack(true); | 259 | w.set_anack(true); |
| 256 | w.set_dnack(true); | 260 | w.set_dnack(true); |
| @@ -259,8 +263,8 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 259 | } | 263 | } |
| 260 | 264 | ||
| 261 | /// Get Error instance, if any occurred. | 265 | /// Get Error instance, if any occurred. |
| 262 | fn check_errorsrc() -> Result<(), Error> { | 266 | fn check_errorsrc(&mut self) -> Result<(), Error> { |
| 263 | let r = T::regs(); | 267 | let r = self.r; |
| 264 | 268 | ||
| 265 | let err = r.errorsrc().read(); | 269 | let err = r.errorsrc().read(); |
| 266 | if err.anack() { | 270 | if err.anack() { |
| @@ -276,7 +280,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 276 | } | 280 | } |
| 277 | 281 | ||
| 278 | fn check_rx(&self, len: usize) -> Result<(), Error> { | 282 | fn check_rx(&self, len: usize) -> Result<(), Error> { |
| 279 | let r = T::regs(); | 283 | let r = self.r; |
| 280 | if r.rxd().amount().read().0 != len as u32 { | 284 | if r.rxd().amount().read().0 != len as u32 { |
| 281 | Err(Error::Receive) | 285 | Err(Error::Receive) |
| 282 | } else { | 286 | } else { |
| @@ -285,7 +289,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 285 | } | 289 | } |
| 286 | 290 | ||
| 287 | fn check_tx(&self, len: usize) -> Result<(), Error> { | 291 | fn check_tx(&self, len: usize) -> Result<(), Error> { |
| 288 | let r = T::regs(); | 292 | let r = self.r; |
| 289 | if r.txd().amount().read().0 != len as u32 { | 293 | if r.txd().amount().read().0 != len as u32 { |
| 290 | Err(Error::Transmit) | 294 | Err(Error::Transmit) |
| 291 | } else { | 295 | } else { |
| @@ -295,7 +299,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 295 | 299 | ||
| 296 | /// Wait for stop or error | 300 | /// Wait for stop or error |
| 297 | fn blocking_wait(&mut self) { | 301 | fn blocking_wait(&mut self) { |
| 298 | let r = T::regs(); | 302 | let r = self.r; |
| 299 | loop { | 303 | loop { |
| 300 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 304 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| 301 | r.events_suspended().write_value(0); | 305 | r.events_suspended().write_value(0); |
| @@ -312,7 +316,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 312 | /// Wait for stop or error | 316 | /// Wait for stop or error |
| 313 | #[cfg(feature = "time")] | 317 | #[cfg(feature = "time")] |
| 314 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> { | 318 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<(), Error> { |
| 315 | let r = T::regs(); | 319 | let r = self.r; |
| 316 | let deadline = Instant::now() + timeout; | 320 | let deadline = Instant::now() + timeout; |
| 317 | loop { | 321 | loop { |
| 318 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 322 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| @@ -333,10 +337,10 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 333 | } | 337 | } |
| 334 | 338 | ||
| 335 | /// Wait for stop or error | 339 | /// Wait for stop or error |
| 336 | fn async_wait(&mut self) -> impl Future<Output = Result<(), Error>> { | 340 | async fn async_wait(&mut self) -> Result<(), Error> { |
| 337 | poll_fn(move |cx| { | 341 | poll_fn(|cx| { |
| 338 | let r = T::regs(); | 342 | let r = self.r; |
| 339 | let s = T::state(); | 343 | let s = self.state; |
| 340 | 344 | ||
| 341 | s.end_waker.register(cx.waker()); | 345 | s.end_waker.register(cx.waker()); |
| 342 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { | 346 | if r.events_suspended().read() != 0 || r.events_stopped().read() != 0 { |
| @@ -349,15 +353,16 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 349 | if r.events_error().read() != 0 { | 353 | if r.events_error().read() != 0 { |
| 350 | r.events_error().write_value(0); | 354 | r.events_error().write_value(0); |
| 351 | r.tasks_stop().write_value(1); | 355 | r.tasks_stop().write_value(1); |
| 352 | if let Err(e) = Self::check_errorsrc() { | 356 | if let Err(e) = self.check_errorsrc() { |
| 353 | return Poll::Ready(Err(e)); | 357 | return Poll::Ready(Err(e)); |
| 354 | } else { | 358 | } else { |
| 355 | panic!("Found events_error bit without an error in errorsrc reg"); | 359 | return Poll::Ready(Err(Error::Timeout)); |
| 356 | } | 360 | } |
| 357 | } | 361 | } |
| 358 | 362 | ||
| 359 | Poll::Pending | 363 | Poll::Pending |
| 360 | }) | 364 | }) |
| 365 | .await | ||
| 361 | } | 366 | } |
| 362 | 367 | ||
| 363 | fn setup_operations( | 368 | fn setup_operations( |
| @@ -367,7 +372,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 367 | last_op: Option<&Operation<'_>>, | 372 | last_op: Option<&Operation<'_>>, |
| 368 | inten: bool, | 373 | inten: bool, |
| 369 | ) -> Result<usize, Error> { | 374 | ) -> Result<usize, Error> { |
| 370 | let r = T::regs(); | 375 | let r = self.r; |
| 371 | 376 | ||
| 372 | compiler_fence(SeqCst); | 377 | compiler_fence(SeqCst); |
| 373 | 378 | ||
| @@ -511,7 +516,7 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 511 | 516 | ||
| 512 | fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> { | 517 | fn check_operations(&mut self, operations: &[Operation<'_>]) -> Result<(), Error> { |
| 513 | compiler_fence(SeqCst); | 518 | compiler_fence(SeqCst); |
| 514 | Self::check_errorsrc()?; | 519 | self.check_errorsrc()?; |
| 515 | 520 | ||
| 516 | assert!(operations.len() == 1 || operations.len() == 2); | 521 | assert!(operations.len() == 1 || operations.len() == 2); |
| 517 | match operations { | 522 | match operations { |
| @@ -696,14 +701,14 @@ impl<'d, T: Instance> Twim<'d, T> { | |||
| 696 | } | 701 | } |
| 697 | } | 702 | } |
| 698 | 703 | ||
| 699 | impl<'a, T: Instance> Drop for Twim<'a, T> { | 704 | impl<'a> Drop for Twim<'a> { |
| 700 | fn drop(&mut self) { | 705 | fn drop(&mut self) { |
| 701 | trace!("twim drop"); | 706 | trace!("twim drop"); |
| 702 | 707 | ||
| 703 | // TODO: check for abort | 708 | // TODO: check for abort |
| 704 | 709 | ||
| 705 | // disable! | 710 | // disable! |
| 706 | let r = T::regs(); | 711 | let r = self.r; |
| 707 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); | 712 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 708 | 713 | ||
| 709 | gpio::deconfigure_pin(r.psel().sda().read()); | 714 | gpio::deconfigure_pin(r.psel().sda().read()); |
| @@ -759,7 +764,7 @@ macro_rules! impl_twim { | |||
| 759 | mod eh02 { | 764 | mod eh02 { |
| 760 | use super::*; | 765 | use super::*; |
| 761 | 766 | ||
| 762 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Write for Twim<'a, T> { | 767 | impl<'a> embedded_hal_02::blocking::i2c::Write for Twim<'a> { |
| 763 | type Error = Error; | 768 | type Error = Error; |
| 764 | 769 | ||
| 765 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { | 770 | fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> { |
| @@ -767,7 +772,7 @@ mod eh02 { | |||
| 767 | } | 772 | } |
| 768 | } | 773 | } |
| 769 | 774 | ||
| 770 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::Read for Twim<'a, T> { | 775 | impl<'a> embedded_hal_02::blocking::i2c::Read for Twim<'a> { |
| 771 | type Error = Error; | 776 | type Error = Error; |
| 772 | 777 | ||
| 773 | fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> { | 778 | fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Error> { |
| @@ -775,7 +780,7 @@ mod eh02 { | |||
| 775 | } | 780 | } |
| 776 | } | 781 | } |
| 777 | 782 | ||
| 778 | impl<'a, T: Instance> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a, T> { | 783 | impl<'a> embedded_hal_02::blocking::i2c::WriteRead for Twim<'a> { |
| 779 | type Error = Error; | 784 | type Error = Error; |
| 780 | 785 | ||
| 781 | fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> { | 786 | fn write_read<'w>(&mut self, addr: u8, bytes: &'w [u8], buffer: &'w mut [u8]) -> Result<(), Error> { |
| @@ -804,27 +809,27 @@ impl embedded_hal_1::i2c::Error for Error { | |||
| 804 | } | 809 | } |
| 805 | } | 810 | } |
| 806 | 811 | ||
| 807 | impl<'d, T: Instance> embedded_hal_1::i2c::ErrorType for Twim<'d, T> { | 812 | impl<'d> embedded_hal_1::i2c::ErrorType for Twim<'d> { |
| 808 | type Error = Error; | 813 | type Error = Error; |
| 809 | } | 814 | } |
| 810 | 815 | ||
| 811 | impl<'d, T: Instance> embedded_hal_1::i2c::I2c for Twim<'d, T> { | 816 | impl<'d> embedded_hal_1::i2c::I2c for Twim<'d> { |
| 812 | fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { | 817 | fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { |
| 813 | self.blocking_transaction(address, operations) | 818 | self.blocking_transaction(address, operations) |
| 814 | } | 819 | } |
| 815 | } | 820 | } |
| 816 | 821 | ||
| 817 | impl<'d, T: Instance> embedded_hal_async::i2c::I2c for Twim<'d, T> { | 822 | impl<'d> embedded_hal_async::i2c::I2c for Twim<'d> { |
| 818 | async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { | 823 | async fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { |
| 819 | self.transaction(address, operations).await | 824 | self.transaction(address, operations).await |
| 820 | } | 825 | } |
| 821 | } | 826 | } |
| 822 | 827 | ||
| 823 | impl<'d, T: Instance> SetConfig for Twim<'d, T> { | 828 | impl<'d> SetConfig for Twim<'d> { |
| 824 | type Config = Config; | 829 | type Config = Config; |
| 825 | type ConfigError = (); | 830 | type ConfigError = (); |
| 826 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { | 831 | fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> { |
| 827 | let r = T::regs(); | 832 | let r = self.r; |
| 828 | r.frequency().write(|w| w.set_frequency(config.frequency)); | 833 | r.frequency().write(|w| w.set_frequency(config.frequency)); |
| 829 | 834 | ||
| 830 | Ok(()) | 835 | Ok(()) |
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs index c77d0f048..dd4978b3e 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs | |||
| @@ -140,14 +140,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | /// TWIS driver. | 142 | /// TWIS driver. |
| 143 | pub struct Twis<'d, T: Instance> { | 143 | pub struct Twis<'d> { |
| 144 | _p: Peri<'d, T>, | 144 | r: pac::twis::Twis, |
| 145 | state: &'static State, | ||
| 146 | _p: PhantomData<&'d ()>, | ||
| 145 | } | 147 | } |
| 146 | 148 | ||
| 147 | impl<'d, T: Instance> Twis<'d, T> { | 149 | impl<'d> Twis<'d> { |
| 148 | /// Create a new TWIS driver. | 150 | /// Create a new TWIS driver. |
| 149 | pub fn new( | 151 | pub fn new<T: Instance>( |
| 150 | twis: Peri<'d, T>, | 152 | _twis: Peri<'d, T>, |
| 151 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 153 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 152 | sda: Peri<'d, impl GpioPin>, | 154 | sda: Peri<'d, impl GpioPin>, |
| 153 | scl: Peri<'d, impl GpioPin>, | 155 | scl: Peri<'d, impl GpioPin>, |
| @@ -206,7 +208,11 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 206 | T::Interrupt::unpend(); | 208 | T::Interrupt::unpend(); |
| 207 | unsafe { T::Interrupt::enable() }; | 209 | unsafe { T::Interrupt::enable() }; |
| 208 | 210 | ||
| 209 | Self { _p: twis } | 211 | Self { |
| 212 | r: T::regs(), | ||
| 213 | state: T::state(), | ||
| 214 | _p: PhantomData, | ||
| 215 | } | ||
| 210 | } | 216 | } |
| 211 | 217 | ||
| 212 | /// Set TX buffer, checking that it is in RAM and has suitable length. | 218 | /// Set TX buffer, checking that it is in RAM and has suitable length. |
| @@ -217,7 +223,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 217 | return Err(Error::TxBufferTooLong); | 223 | return Err(Error::TxBufferTooLong); |
| 218 | } | 224 | } |
| 219 | 225 | ||
| 220 | let r = T::regs(); | 226 | let r = self.r; |
| 221 | 227 | ||
| 222 | // We're giving the register a pointer to the stack. Since we're | 228 | // We're giving the register a pointer to the stack. Since we're |
| 223 | // waiting for the I2C transaction to end before this stack pointer | 229 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -244,7 +250,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 244 | return Err(Error::RxBufferTooLong); | 250 | return Err(Error::RxBufferTooLong); |
| 245 | } | 251 | } |
| 246 | 252 | ||
| 247 | let r = T::regs(); | 253 | let r = self.r; |
| 248 | 254 | ||
| 249 | // We're giving the register a pointer to the stack. Since we're | 255 | // We're giving the register a pointer to the stack. Since we're |
| 250 | // waiting for the I2C transaction to end before this stack pointer | 256 | // waiting for the I2C transaction to end before this stack pointer |
| @@ -266,7 +272,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 266 | } | 272 | } |
| 267 | 273 | ||
| 268 | fn clear_errorsrc(&mut self) { | 274 | fn clear_errorsrc(&mut self) { |
| 269 | let r = T::regs(); | 275 | let r = self.r; |
| 270 | r.errorsrc().write(|w| { | 276 | r.errorsrc().write(|w| { |
| 271 | w.set_overflow(true); | 277 | w.set_overflow(true); |
| 272 | w.set_overread(true); | 278 | w.set_overread(true); |
| @@ -276,18 +282,18 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 276 | 282 | ||
| 277 | /// Returns matched address for latest command. | 283 | /// Returns matched address for latest command. |
| 278 | pub fn address_match(&self) -> u8 { | 284 | pub fn address_match(&self) -> u8 { |
| 279 | let r = T::regs(); | 285 | let r = self.r; |
| 280 | r.address(r.match_().read().0 as usize).read().address() | 286 | r.address(r.match_().read().0 as usize).read().address() |
| 281 | } | 287 | } |
| 282 | 288 | ||
| 283 | /// Returns the index of the address matched in the latest command. | 289 | /// Returns the index of the address matched in the latest command. |
| 284 | pub fn address_match_index(&self) -> usize { | 290 | pub fn address_match_index(&self) -> usize { |
| 285 | T::regs().match_().read().0 as _ | 291 | self.r.match_().read().0 as _ |
| 286 | } | 292 | } |
| 287 | 293 | ||
| 288 | /// Wait for read, write, stop or error | 294 | /// Wait for read, write, stop or error |
| 289 | fn blocking_listen_wait(&mut self) -> Result<Status, Error> { | 295 | fn blocking_listen_wait(&mut self) -> Result<Status, Error> { |
| 290 | let r = T::regs(); | 296 | let r = self.r; |
| 291 | loop { | 297 | loop { |
| 292 | if r.events_error().read() != 0 { | 298 | if r.events_error().read() != 0 { |
| 293 | r.events_error().write_value(0); | 299 | r.events_error().write_value(0); |
| @@ -312,7 +318,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 312 | 318 | ||
| 313 | /// Wait for stop, repeated start or error | 319 | /// Wait for stop, repeated start or error |
| 314 | fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> { | 320 | fn blocking_listen_wait_end(&mut self, status: Status) -> Result<Command, Error> { |
| 315 | let r = T::regs(); | 321 | let r = self.r; |
| 316 | loop { | 322 | loop { |
| 317 | // stop if an error occurred | 323 | // stop if an error occurred |
| 318 | if r.events_error().read() != 0 { | 324 | if r.events_error().read() != 0 { |
| @@ -338,7 +344,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 338 | 344 | ||
| 339 | /// Wait for stop or error | 345 | /// Wait for stop or error |
| 340 | fn blocking_wait(&mut self) -> Result<usize, Error> { | 346 | fn blocking_wait(&mut self) -> Result<usize, Error> { |
| 341 | let r = T::regs(); | 347 | let r = self.r; |
| 342 | loop { | 348 | loop { |
| 343 | // stop if an error occurred | 349 | // stop if an error occurred |
| 344 | if r.events_error().read() != 0 { | 350 | if r.events_error().read() != 0 { |
| @@ -363,7 +369,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 363 | /// Wait for stop or error with timeout | 369 | /// Wait for stop or error with timeout |
| 364 | #[cfg(feature = "time")] | 370 | #[cfg(feature = "time")] |
| 365 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> { | 371 | fn blocking_wait_timeout(&mut self, timeout: Duration) -> Result<usize, Error> { |
| 366 | let r = T::regs(); | 372 | let r = self.r; |
| 367 | let deadline = Instant::now() + timeout; | 373 | let deadline = Instant::now() + timeout; |
| 368 | loop { | 374 | loop { |
| 369 | // stop if an error occurred | 375 | // stop if an error occurred |
| @@ -392,7 +398,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 392 | /// Wait for read, write, stop or error with timeout | 398 | /// Wait for read, write, stop or error with timeout |
| 393 | #[cfg(feature = "time")] | 399 | #[cfg(feature = "time")] |
| 394 | fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> { | 400 | fn blocking_listen_wait_timeout(&mut self, timeout: Duration) -> Result<Status, Error> { |
| 395 | let r = T::regs(); | 401 | let r = self.r; |
| 396 | let deadline = Instant::now() + timeout; | 402 | let deadline = Instant::now() + timeout; |
| 397 | loop { | 403 | loop { |
| 398 | if r.events_error().read() != 0 { | 404 | if r.events_error().read() != 0 { |
| @@ -423,7 +429,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 423 | /// Wait for stop, repeated start or error with timeout | 429 | /// Wait for stop, repeated start or error with timeout |
| 424 | #[cfg(feature = "time")] | 430 | #[cfg(feature = "time")] |
| 425 | fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> { | 431 | fn blocking_listen_wait_end_timeout(&mut self, status: Status, timeout: Duration) -> Result<Command, Error> { |
| 426 | let r = T::regs(); | 432 | let r = self.r; |
| 427 | let deadline = Instant::now() + timeout; | 433 | let deadline = Instant::now() + timeout; |
| 428 | loop { | 434 | loop { |
| 429 | // stop if an error occurred | 435 | // stop if an error occurred |
| @@ -453,10 +459,9 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 453 | 459 | ||
| 454 | /// Wait for stop or error | 460 | /// Wait for stop or error |
| 455 | fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> { | 461 | fn async_wait(&mut self) -> impl Future<Output = Result<usize, Error>> { |
| 462 | let r = self.r; | ||
| 463 | let s = self.state; | ||
| 456 | poll_fn(move |cx| { | 464 | poll_fn(move |cx| { |
| 457 | let r = T::regs(); | ||
| 458 | let s = T::state(); | ||
| 459 | |||
| 460 | s.waker.register(cx.waker()); | 465 | s.waker.register(cx.waker()); |
| 461 | 466 | ||
| 462 | // stop if an error occurred | 467 | // stop if an error occurred |
| @@ -483,10 +488,9 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 483 | 488 | ||
| 484 | /// Wait for read or write | 489 | /// Wait for read or write |
| 485 | fn async_listen_wait(&mut self) -> impl Future<Output = Result<Status, Error>> { | 490 | fn async_listen_wait(&mut self) -> impl Future<Output = Result<Status, Error>> { |
| 491 | let r = self.r; | ||
| 492 | let s = self.state; | ||
| 486 | poll_fn(move |cx| { | 493 | poll_fn(move |cx| { |
| 487 | let r = T::regs(); | ||
| 488 | let s = T::state(); | ||
| 489 | |||
| 490 | s.waker.register(cx.waker()); | 494 | s.waker.register(cx.waker()); |
| 491 | 495 | ||
| 492 | // stop if an error occurred | 496 | // stop if an error occurred |
| @@ -510,10 +514,9 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 510 | 514 | ||
| 511 | /// Wait for stop, repeated start or error | 515 | /// Wait for stop, repeated start or error |
| 512 | fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> { | 516 | fn async_listen_wait_end(&mut self, status: Status) -> impl Future<Output = Result<Command, Error>> { |
| 517 | let r = self.r; | ||
| 518 | let s = self.state; | ||
| 513 | poll_fn(move |cx| { | 519 | poll_fn(move |cx| { |
| 514 | let r = T::regs(); | ||
| 515 | let s = T::state(); | ||
| 516 | |||
| 517 | s.waker.register(cx.waker()); | 520 | s.waker.register(cx.waker()); |
| 518 | 521 | ||
| 519 | // stop if an error occurred | 522 | // stop if an error occurred |
| @@ -540,7 +543,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 540 | } | 543 | } |
| 541 | 544 | ||
| 542 | fn setup_respond_from_ram(&mut self, buffer: &[u8], inten: bool) -> Result<(), Error> { | 545 | fn setup_respond_from_ram(&mut self, buffer: &[u8], inten: bool) -> Result<(), Error> { |
| 543 | let r = T::regs(); | 546 | let r = self.r; |
| 544 | 547 | ||
| 545 | compiler_fence(SeqCst); | 548 | compiler_fence(SeqCst); |
| 546 | 549 | ||
| @@ -584,7 +587,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 584 | } | 587 | } |
| 585 | 588 | ||
| 586 | fn setup_listen(&mut self, buffer: &mut [u8], inten: bool) -> Result<(), Error> { | 589 | fn setup_listen(&mut self, buffer: &mut [u8], inten: bool) -> Result<(), Error> { |
| 587 | let r = T::regs(); | 590 | let r = self.r; |
| 588 | compiler_fence(SeqCst); | 591 | compiler_fence(SeqCst); |
| 589 | 592 | ||
| 590 | // Set up the DMA read. | 593 | // Set up the DMA read. |
| @@ -620,7 +623,7 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 620 | } | 623 | } |
| 621 | 624 | ||
| 622 | fn setup_listen_end(&mut self, inten: bool) -> Result<(), Error> { | 625 | fn setup_listen_end(&mut self, inten: bool) -> Result<(), Error> { |
| 623 | let r = T::regs(); | 626 | let r = self.r; |
| 624 | compiler_fence(SeqCst); | 627 | compiler_fence(SeqCst); |
| 625 | 628 | ||
| 626 | // Clear events | 629 | // Clear events |
| @@ -753,14 +756,14 @@ impl<'d, T: Instance> Twis<'d, T> { | |||
| 753 | } | 756 | } |
| 754 | } | 757 | } |
| 755 | 758 | ||
| 756 | impl<'a, T: Instance> Drop for Twis<'a, T> { | 759 | impl<'a> Drop for Twis<'a> { |
| 757 | fn drop(&mut self) { | 760 | fn drop(&mut self) { |
| 758 | trace!("twis drop"); | 761 | trace!("twis drop"); |
| 759 | 762 | ||
| 760 | // TODO: check for abort | 763 | // TODO: check for abort |
| 761 | 764 | ||
| 762 | // disable! | 765 | // disable! |
| 763 | let r = T::regs(); | 766 | let r = self.r; |
| 764 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); | 767 | r.enable().write(|w| w.set_enable(vals::Enable::DISABLED)); |
| 765 | 768 | ||
| 766 | gpio::deconfigure_pin(r.psel().sda().read()); | 769 | gpio::deconfigure_pin(r.psel().sda().read()); |
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index 927a0ac08..66fb3b3f2 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -132,28 +132,32 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | /// UARTE driver. | 134 | /// UARTE driver. |
| 135 | pub struct Uarte<'d, T: Instance> { | 135 | pub struct Uarte<'d> { |
| 136 | tx: UarteTx<'d, T>, | 136 | tx: UarteTx<'d>, |
| 137 | rx: UarteRx<'d, T>, | 137 | rx: UarteRx<'d>, |
| 138 | } | 138 | } |
| 139 | 139 | ||
| 140 | /// Transmitter part of the UARTE driver. | 140 | /// Transmitter part of the UARTE driver. |
| 141 | /// | 141 | /// |
| 142 | /// This can be obtained via [`Uarte::split`], or created directly. | 142 | /// This can be obtained via [`Uarte::split`], or created directly. |
| 143 | pub struct UarteTx<'d, T: Instance> { | 143 | pub struct UarteTx<'d> { |
| 144 | _p: Peri<'d, T>, | 144 | r: pac::uarte::Uarte, |
| 145 | state: &'static State, | ||
| 146 | _p: PhantomData<&'d ()>, | ||
| 145 | } | 147 | } |
| 146 | 148 | ||
| 147 | /// Receiver part of the UARTE driver. | 149 | /// Receiver part of the UARTE driver. |
| 148 | /// | 150 | /// |
| 149 | /// This can be obtained via [`Uarte::split`], or created directly. | 151 | /// This can be obtained via [`Uarte::split`], or created directly. |
| 150 | pub struct UarteRx<'d, T: Instance> { | 152 | pub struct UarteRx<'d> { |
| 151 | _p: Peri<'d, T>, | 153 | r: pac::uarte::Uarte, |
| 154 | state: &'static State, | ||
| 155 | _p: PhantomData<&'d ()>, | ||
| 152 | } | 156 | } |
| 153 | 157 | ||
| 154 | impl<'d, T: Instance> Uarte<'d, T> { | 158 | impl<'d> Uarte<'d> { |
| 155 | /// Create a new UARTE without hardware flow control | 159 | /// Create a new UARTE without hardware flow control |
| 156 | pub fn new( | 160 | pub fn new<T: Instance>( |
| 157 | uarte: Peri<'d, T>, | 161 | uarte: Peri<'d, T>, |
| 158 | rxd: Peri<'d, impl GpioPin>, | 162 | rxd: Peri<'d, impl GpioPin>, |
| 159 | txd: Peri<'d, impl GpioPin>, | 163 | txd: Peri<'d, impl GpioPin>, |
| @@ -164,7 +168,7 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 164 | } | 168 | } |
| 165 | 169 | ||
| 166 | /// Create a new UARTE with hardware flow control (RTS/CTS) | 170 | /// Create a new UARTE with hardware flow control (RTS/CTS) |
| 167 | pub fn new_with_rtscts( | 171 | pub fn new_with_rtscts<T: Instance>( |
| 168 | uarte: Peri<'d, T>, | 172 | uarte: Peri<'d, T>, |
| 169 | rxd: Peri<'d, impl GpioPin>, | 173 | rxd: Peri<'d, impl GpioPin>, |
| 170 | txd: Peri<'d, impl GpioPin>, | 174 | txd: Peri<'d, impl GpioPin>, |
| @@ -183,8 +187,8 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 183 | ) | 187 | ) |
| 184 | } | 188 | } |
| 185 | 189 | ||
| 186 | fn new_inner( | 190 | fn new_inner<T: Instance>( |
| 187 | uarte: Peri<'d, T>, | 191 | _uarte: Peri<'d, T>, |
| 188 | rxd: Peri<'d, AnyPin>, | 192 | rxd: Peri<'d, AnyPin>, |
| 189 | txd: Peri<'d, AnyPin>, | 193 | txd: Peri<'d, AnyPin>, |
| 190 | cts: Option<Peri<'d, AnyPin>>, | 194 | cts: Option<Peri<'d, AnyPin>>, |
| @@ -211,16 +215,22 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 211 | 215 | ||
| 212 | Self { | 216 | Self { |
| 213 | tx: UarteTx { | 217 | tx: UarteTx { |
| 214 | _p: unsafe { uarte.clone_unchecked() }, | 218 | r: T::regs(), |
| 219 | state: T::state(), | ||
| 220 | _p: PhantomData {}, | ||
| 221 | }, | ||
| 222 | rx: UarteRx { | ||
| 223 | r: T::regs(), | ||
| 224 | state: T::state(), | ||
| 225 | _p: PhantomData {}, | ||
| 215 | }, | 226 | }, |
| 216 | rx: UarteRx { _p: uarte }, | ||
| 217 | } | 227 | } |
| 218 | } | 228 | } |
| 219 | 229 | ||
| 220 | /// Split the Uarte into the transmitter and receiver parts. | 230 | /// Split the Uarte into the transmitter and receiver parts. |
| 221 | /// | 231 | /// |
| 222 | /// This is useful to concurrently transmit and receive from independent tasks. | 232 | /// This is useful to concurrently transmit and receive from independent tasks. |
| 223 | pub fn split(self) -> (UarteTx<'d, T>, UarteRx<'d, T>) { | 233 | pub fn split(self) -> (UarteTx<'d>, UarteRx<'d>) { |
| 224 | (self.tx, self.rx) | 234 | (self.tx, self.rx) |
| 225 | } | 235 | } |
| 226 | 236 | ||
| @@ -228,7 +238,7 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 228 | /// | 238 | /// |
| 229 | /// The returned halves borrow from `self`, so you can drop them and go back to using | 239 | /// The returned halves borrow from `self`, so you can drop them and go back to using |
| 230 | /// the "un-split" `self`. This allows temporarily splitting the UART. | 240 | /// the "un-split" `self`. This allows temporarily splitting the UART. |
| 231 | pub fn split_by_ref(&mut self) -> (&mut UarteTx<'d, T>, &mut UarteRx<'d, T>) { | 241 | pub fn split_by_ref(&mut self) -> (&mut UarteTx<'d>, &mut UarteRx<'d>) { |
| 232 | (&mut self.tx, &mut self.rx) | 242 | (&mut self.tx, &mut self.rx) |
| 233 | } | 243 | } |
| 234 | 244 | ||
| @@ -240,13 +250,13 @@ impl<'d, T: Instance> Uarte<'d, T> { | |||
| 240 | timer: Peri<'d, U>, | 250 | timer: Peri<'d, U>, |
| 241 | ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, | 251 | ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, |
| 242 | ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, | 252 | ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, |
| 243 | ) -> (UarteTx<'d, T>, UarteRxWithIdle<'d, T, U>) { | 253 | ) -> (UarteTx<'d>, UarteRxWithIdle<'d>) { |
| 244 | (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2)) | 254 | (self.tx, self.rx.with_idle(timer, ppi_ch1, ppi_ch2)) |
| 245 | } | 255 | } |
| 246 | 256 | ||
| 247 | /// Return the endtx event for use with PPI | 257 | /// Return the endtx event for use with PPI |
| 248 | pub fn event_endtx(&self) -> Event<'_> { | 258 | pub fn event_endtx(&self) -> Event<'_> { |
| 249 | let r = T::regs(); | 259 | let r = self.tx.r; |
| 250 | Event::from_reg(r.events_endtx()) | 260 | Event::from_reg(r.events_endtx()) |
| 251 | } | 261 | } |
| 252 | 262 | ||
| @@ -343,9 +353,9 @@ pub(crate) fn configure(r: pac::uarte::Uarte, config: Config, hardware_flow_cont | |||
| 343 | apply_workaround_for_enable_anomaly(r); | 353 | apply_workaround_for_enable_anomaly(r); |
| 344 | } | 354 | } |
| 345 | 355 | ||
| 346 | impl<'d, T: Instance> UarteTx<'d, T> { | 356 | impl<'d> UarteTx<'d> { |
| 347 | /// Create a new tx-only UARTE without hardware flow control | 357 | /// Create a new tx-only UARTE without hardware flow control |
| 348 | pub fn new( | 358 | pub fn new<T: Instance>( |
| 349 | uarte: Peri<'d, T>, | 359 | uarte: Peri<'d, T>, |
| 350 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 360 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 351 | txd: Peri<'d, impl GpioPin>, | 361 | txd: Peri<'d, impl GpioPin>, |
| @@ -355,7 +365,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 355 | } | 365 | } |
| 356 | 366 | ||
| 357 | /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) | 367 | /// Create a new tx-only UARTE with hardware flow control (RTS/CTS) |
| 358 | pub fn new_with_rtscts( | 368 | pub fn new_with_rtscts<T: Instance>( |
| 359 | uarte: Peri<'d, T>, | 369 | uarte: Peri<'d, T>, |
| 360 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 370 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 361 | txd: Peri<'d, impl GpioPin>, | 371 | txd: Peri<'d, impl GpioPin>, |
| @@ -365,7 +375,12 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 365 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config) | 375 | Self::new_inner(uarte, txd.into(), Some(cts.into()), config) |
| 366 | } | 376 | } |
| 367 | 377 | ||
| 368 | fn new_inner(uarte: Peri<'d, T>, txd: Peri<'d, AnyPin>, cts: Option<Peri<'d, AnyPin>>, config: Config) -> Self { | 378 | fn new_inner<T: Instance>( |
| 379 | _uarte: Peri<'d, T>, | ||
| 380 | txd: Peri<'d, AnyPin>, | ||
| 381 | cts: Option<Peri<'d, AnyPin>>, | ||
| 382 | config: Config, | ||
| 383 | ) -> Self { | ||
| 369 | let r = T::regs(); | 384 | let r = T::regs(); |
| 370 | 385 | ||
| 371 | configure(r, config, cts.is_some()); | 386 | configure(r, config, cts.is_some()); |
| @@ -378,7 +393,11 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 378 | let s = T::state(); | 393 | let s = T::state(); |
| 379 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 394 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
| 380 | 395 | ||
| 381 | Self { _p: uarte } | 396 | Self { |
| 397 | r: T::regs(), | ||
| 398 | state: T::state(), | ||
| 399 | _p: PhantomData {}, | ||
| 400 | } | ||
| 382 | } | 401 | } |
| 383 | 402 | ||
| 384 | /// Write all bytes in the buffer. | 403 | /// Write all bytes in the buffer. |
| @@ -409,8 +428,8 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 409 | let ptr = buffer.as_ptr(); | 428 | let ptr = buffer.as_ptr(); |
| 410 | let len = buffer.len(); | 429 | let len = buffer.len(); |
| 411 | 430 | ||
| 412 | let r = T::regs(); | 431 | let r = self.r; |
| 413 | let s = T::state(); | 432 | let s = self.state; |
| 414 | 433 | ||
| 415 | let drop = OnDrop::new(move || { | 434 | let drop = OnDrop::new(move || { |
| 416 | trace!("write drop: stopping"); | 435 | trace!("write drop: stopping"); |
| @@ -479,7 +498,7 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 479 | let ptr = buffer.as_ptr(); | 498 | let ptr = buffer.as_ptr(); |
| 480 | let len = buffer.len(); | 499 | let len = buffer.len(); |
| 481 | 500 | ||
| 482 | let r = T::regs(); | 501 | let r = self.r; |
| 483 | 502 | ||
| 484 | r.txd().ptr().write_value(ptr as u32); | 503 | r.txd().ptr().write_value(ptr as u32); |
| 485 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 504 | r.txd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| @@ -501,11 +520,11 @@ impl<'d, T: Instance> UarteTx<'d, T> { | |||
| 501 | } | 520 | } |
| 502 | } | 521 | } |
| 503 | 522 | ||
| 504 | impl<'a, T: Instance> Drop for UarteTx<'a, T> { | 523 | impl<'a> Drop for UarteTx<'a> { |
| 505 | fn drop(&mut self) { | 524 | fn drop(&mut self) { |
| 506 | trace!("uarte tx drop"); | 525 | trace!("uarte tx drop"); |
| 507 | 526 | ||
| 508 | let r = T::regs(); | 527 | let r = self.r; |
| 509 | 528 | ||
| 510 | let did_stoptx = r.events_txstarted().read() != 0; | 529 | let did_stoptx = r.events_txstarted().read() != 0; |
| 511 | trace!("did_stoptx {}", did_stoptx); | 530 | trace!("did_stoptx {}", did_stoptx); |
| @@ -513,15 +532,15 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> { | |||
| 513 | // Wait for txstopped, if needed. | 532 | // Wait for txstopped, if needed. |
| 514 | while did_stoptx && r.events_txstopped().read() == 0 {} | 533 | while did_stoptx && r.events_txstopped().read() == 0 {} |
| 515 | 534 | ||
| 516 | let s = T::state(); | 535 | let s = self.state; |
| 517 | 536 | ||
| 518 | drop_tx_rx(r, s); | 537 | drop_tx_rx(r, s); |
| 519 | } | 538 | } |
| 520 | } | 539 | } |
| 521 | 540 | ||
| 522 | impl<'d, T: Instance> UarteRx<'d, T> { | 541 | impl<'d> UarteRx<'d> { |
| 523 | /// Create a new rx-only UARTE without hardware flow control | 542 | /// Create a new rx-only UARTE without hardware flow control |
| 524 | pub fn new( | 543 | pub fn new<T: Instance>( |
| 525 | uarte: Peri<'d, T>, | 544 | uarte: Peri<'d, T>, |
| 526 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 545 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 527 | rxd: Peri<'d, impl GpioPin>, | 546 | rxd: Peri<'d, impl GpioPin>, |
| @@ -531,7 +550,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 531 | } | 550 | } |
| 532 | 551 | ||
| 533 | /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) | 552 | /// Create a new rx-only UARTE with hardware flow control (RTS/CTS) |
| 534 | pub fn new_with_rtscts( | 553 | pub fn new_with_rtscts<T: Instance>( |
| 535 | uarte: Peri<'d, T>, | 554 | uarte: Peri<'d, T>, |
| 536 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 555 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 537 | rxd: Peri<'d, impl GpioPin>, | 556 | rxd: Peri<'d, impl GpioPin>, |
| @@ -543,13 +562,18 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 543 | 562 | ||
| 544 | /// Check for errors and clear the error register if an error occured. | 563 | /// Check for errors and clear the error register if an error occured. |
| 545 | fn check_and_clear_errors(&mut self) -> Result<(), Error> { | 564 | fn check_and_clear_errors(&mut self) -> Result<(), Error> { |
| 546 | let r = T::regs(); | 565 | let r = self.r; |
| 547 | let err_bits = r.errorsrc().read(); | 566 | let err_bits = r.errorsrc().read(); |
| 548 | r.errorsrc().write_value(err_bits); | 567 | r.errorsrc().write_value(err_bits); |
| 549 | ErrorSource::from_bits_truncate(err_bits.0).check() | 568 | ErrorSource::from_bits_truncate(err_bits.0).check() |
| 550 | } | 569 | } |
| 551 | 570 | ||
| 552 | fn new_inner(uarte: Peri<'d, T>, rxd: Peri<'d, AnyPin>, rts: Option<Peri<'d, AnyPin>>, config: Config) -> Self { | 571 | fn new_inner<T: Instance>( |
| 572 | _uarte: Peri<'d, T>, | ||
| 573 | rxd: Peri<'d, AnyPin>, | ||
| 574 | rts: Option<Peri<'d, AnyPin>>, | ||
| 575 | config: Config, | ||
| 576 | ) -> Self { | ||
| 553 | let r = T::regs(); | 577 | let r = T::regs(); |
| 554 | 578 | ||
| 555 | configure(r, config, rts.is_some()); | 579 | configure(r, config, rts.is_some()); |
| @@ -562,7 +586,11 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 562 | let s = T::state(); | 586 | let s = T::state(); |
| 563 | s.tx_rx_refcount.store(1, Ordering::Relaxed); | 587 | s.tx_rx_refcount.store(1, Ordering::Relaxed); |
| 564 | 588 | ||
| 565 | Self { _p: uarte } | 589 | Self { |
| 590 | r: T::regs(), | ||
| 591 | state: T::state(), | ||
| 592 | _p: PhantomData {}, | ||
| 593 | } | ||
| 566 | } | 594 | } |
| 567 | 595 | ||
| 568 | /// Upgrade to an instance that supports idle line detection. | 596 | /// Upgrade to an instance that supports idle line detection. |
| @@ -571,10 +599,10 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 571 | timer: Peri<'d, U>, | 599 | timer: Peri<'d, U>, |
| 572 | ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, | 600 | ppi_ch1: Peri<'d, impl ConfigurableChannel + 'd>, |
| 573 | ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, | 601 | ppi_ch2: Peri<'d, impl ConfigurableChannel + 'd>, |
| 574 | ) -> UarteRxWithIdle<'d, T, U> { | 602 | ) -> UarteRxWithIdle<'d> { |
| 575 | let timer = Timer::new(timer); | 603 | let timer = Timer::new(timer); |
| 576 | 604 | ||
| 577 | let r = T::regs(); | 605 | let r = self.r; |
| 578 | 606 | ||
| 579 | // BAUDRATE register values are `baudrate * 2^32 / 16000000` | 607 | // BAUDRATE register values are `baudrate * 2^32 / 16000000` |
| 580 | // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values | 608 | // source: https://devzone.nordicsemi.com/f/nordic-q-a/391/uart-baudrate-register-values |
| @@ -605,11 +633,15 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 605 | ); | 633 | ); |
| 606 | ppi_ch2.enable(); | 634 | ppi_ch2.enable(); |
| 607 | 635 | ||
| 636 | let state = self.state; | ||
| 637 | |||
| 608 | UarteRxWithIdle { | 638 | UarteRxWithIdle { |
| 609 | rx: self, | 639 | rx: self, |
| 610 | timer, | 640 | timer, |
| 611 | ppi_ch1, | 641 | ppi_ch1: ppi_ch1, |
| 612 | _ppi_ch2: ppi_ch2, | 642 | _ppi_ch2: ppi_ch2, |
| 643 | r: r, | ||
| 644 | state: state, | ||
| 613 | } | 645 | } |
| 614 | } | 646 | } |
| 615 | 647 | ||
| @@ -625,8 +657,8 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 625 | let ptr = buffer.as_ptr(); | 657 | let ptr = buffer.as_ptr(); |
| 626 | let len = buffer.len(); | 658 | let len = buffer.len(); |
| 627 | 659 | ||
| 628 | let r = T::regs(); | 660 | let r = self.r; |
| 629 | let s = T::state(); | 661 | let s = self.state; |
| 630 | 662 | ||
| 631 | let drop = OnDrop::new(move || { | 663 | let drop = OnDrop::new(move || { |
| 632 | trace!("read drop: stopping"); | 664 | trace!("read drop: stopping"); |
| @@ -692,7 +724,7 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 692 | let ptr = buffer.as_ptr(); | 724 | let ptr = buffer.as_ptr(); |
| 693 | let len = buffer.len(); | 725 | let len = buffer.len(); |
| 694 | 726 | ||
| 695 | let r = T::regs(); | 727 | let r = self.r; |
| 696 | 728 | ||
| 697 | r.rxd().ptr().write_value(ptr as u32); | 729 | r.rxd().ptr().write_value(ptr as u32); |
| 698 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); | 730 | r.rxd().maxcnt().write(|w| w.set_maxcnt(len as _)); |
| @@ -718,11 +750,11 @@ impl<'d, T: Instance> UarteRx<'d, T> { | |||
| 718 | } | 750 | } |
| 719 | } | 751 | } |
| 720 | 752 | ||
| 721 | impl<'a, T: Instance> Drop for UarteRx<'a, T> { | 753 | impl<'a> Drop for UarteRx<'a> { |
| 722 | fn drop(&mut self) { | 754 | fn drop(&mut self) { |
| 723 | trace!("uarte rx drop"); | 755 | trace!("uarte rx drop"); |
| 724 | 756 | ||
| 725 | let r = T::regs(); | 757 | let r = self.r; |
| 726 | 758 | ||
| 727 | let did_stoprx = r.events_rxstarted().read() != 0; | 759 | let did_stoprx = r.events_rxstarted().read() != 0; |
| 728 | trace!("did_stoprx {}", did_stoprx); | 760 | trace!("did_stoprx {}", did_stoprx); |
| @@ -730,7 +762,7 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> { | |||
| 730 | // Wait for rxto, if needed. | 762 | // Wait for rxto, if needed. |
| 731 | while did_stoprx && r.events_rxto().read() == 0 {} | 763 | while did_stoprx && r.events_rxto().read() == 0 {} |
| 732 | 764 | ||
| 733 | let s = T::state(); | 765 | let s = self.state; |
| 734 | 766 | ||
| 735 | drop_tx_rx(r, s); | 767 | drop_tx_rx(r, s); |
| 736 | } | 768 | } |
| @@ -739,14 +771,16 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> { | |||
| 739 | /// Receiver part of the UARTE driver, with `read_until_idle` support. | 771 | /// Receiver part of the UARTE driver, with `read_until_idle` support. |
| 740 | /// | 772 | /// |
| 741 | /// This can be obtained via [`Uarte::split_with_idle`]. | 773 | /// This can be obtained via [`Uarte::split_with_idle`]. |
| 742 | pub struct UarteRxWithIdle<'d, T: Instance, U: TimerInstance> { | 774 | pub struct UarteRxWithIdle<'d> { |
| 743 | rx: UarteRx<'d, T>, | 775 | rx: UarteRx<'d>, |
| 744 | timer: Timer<'d, U>, | 776 | timer: Timer<'d>, |
| 745 | ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, | 777 | ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 2>, |
| 746 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, | 778 | _ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 1>, |
| 779 | r: pac::uarte::Uarte, | ||
| 780 | state: &'static State, | ||
| 747 | } | 781 | } |
| 748 | 782 | ||
| 749 | impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | 783 | impl<'d> UarteRxWithIdle<'d> { |
| 750 | /// Read bytes until the buffer is filled. | 784 | /// Read bytes until the buffer is filled. |
| 751 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { | 785 | pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> { |
| 752 | self.ppi_ch1.disable(); | 786 | self.ppi_ch1.disable(); |
| @@ -773,8 +807,8 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | |||
| 773 | let ptr = buffer.as_ptr(); | 807 | let ptr = buffer.as_ptr(); |
| 774 | let len = buffer.len(); | 808 | let len = buffer.len(); |
| 775 | 809 | ||
| 776 | let r = T::regs(); | 810 | let r = self.r; |
| 777 | let s = T::state(); | 811 | let s = self.state; |
| 778 | 812 | ||
| 779 | self.ppi_ch1.enable(); | 813 | self.ppi_ch1.enable(); |
| 780 | 814 | ||
| @@ -846,7 +880,7 @@ impl<'d, T: Instance, U: TimerInstance> UarteRxWithIdle<'d, T, U> { | |||
| 846 | let ptr = buffer.as_ptr(); | 880 | let ptr = buffer.as_ptr(); |
| 847 | let len = buffer.len(); | 881 | let len = buffer.len(); |
| 848 | 882 | ||
| 849 | let r = T::regs(); | 883 | let r = self.r; |
| 850 | 884 | ||
| 851 | self.ppi_ch1.enable(); | 885 | self.ppi_ch1.enable(); |
| 852 | 886 | ||
| @@ -997,7 +1031,7 @@ macro_rules! impl_uarte { | |||
| 997 | mod eh02 { | 1031 | mod eh02 { |
| 998 | use super::*; | 1032 | use super::*; |
| 999 | 1033 | ||
| 1000 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for Uarte<'d, T> { | 1034 | impl<'d> embedded_hal_02::blocking::serial::Write<u8> for Uarte<'d> { |
| 1001 | type Error = Error; | 1035 | type Error = Error; |
| 1002 | 1036 | ||
| 1003 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | 1037 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -1009,7 +1043,7 @@ mod eh02 { | |||
| 1009 | } | 1043 | } |
| 1010 | } | 1044 | } |
| 1011 | 1045 | ||
| 1012 | impl<'d, T: Instance> embedded_hal_02::blocking::serial::Write<u8> for UarteTx<'d, T> { | 1046 | impl<'d> embedded_hal_02::blocking::serial::Write<u8> for UarteTx<'d> { |
| 1013 | type Error = Error; | 1047 | type Error = Error; |
| 1014 | 1048 | ||
| 1015 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { | 1049 | fn bwrite_all(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { |
| @@ -1038,22 +1072,22 @@ mod _embedded_io { | |||
| 1038 | } | 1072 | } |
| 1039 | } | 1073 | } |
| 1040 | 1074 | ||
| 1041 | impl<'d, U: Instance> embedded_io_async::ErrorType for Uarte<'d, U> { | 1075 | impl<'d> embedded_io_async::ErrorType for Uarte<'d> { |
| 1042 | type Error = Error; | 1076 | type Error = Error; |
| 1043 | } | 1077 | } |
| 1044 | 1078 | ||
| 1045 | impl<'d, U: Instance> embedded_io_async::ErrorType for UarteTx<'d, U> { | 1079 | impl<'d> embedded_io_async::ErrorType for UarteTx<'d> { |
| 1046 | type Error = Error; | 1080 | type Error = Error; |
| 1047 | } | 1081 | } |
| 1048 | 1082 | ||
| 1049 | impl<'d, U: Instance> embedded_io_async::Write for Uarte<'d, U> { | 1083 | impl<'d> embedded_io_async::Write for Uarte<'d> { |
| 1050 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 1084 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 1051 | self.write(buf).await?; | 1085 | self.write(buf).await?; |
| 1052 | Ok(buf.len()) | 1086 | Ok(buf.len()) |
| 1053 | } | 1087 | } |
| 1054 | } | 1088 | } |
| 1055 | 1089 | ||
| 1056 | impl<'d: 'd, U: Instance> embedded_io_async::Write for UarteTx<'d, U> { | 1090 | impl<'d> embedded_io_async::Write for UarteTx<'d> { |
| 1057 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { | 1091 | async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 1058 | self.write(buf).await?; | 1092 | self.write(buf).await?; |
| 1059 | Ok(buf.len()) | 1093 | Ok(buf.len()) |
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs index c6970fc0f..2a32fe922 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs | |||
| @@ -86,17 +86,18 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /// USB driver. | 88 | /// USB driver. |
| 89 | pub struct Driver<'d, T: Instance, V: VbusDetect> { | 89 | pub struct Driver<'d, V: VbusDetect> { |
| 90 | _p: Peri<'d, T>, | 90 | regs: pac::usbd::Usbd, |
| 91 | alloc_in: Allocator, | 91 | alloc_in: Allocator, |
| 92 | alloc_out: Allocator, | 92 | alloc_out: Allocator, |
| 93 | vbus_detect: V, | 93 | vbus_detect: V, |
| 94 | _phantom: PhantomData<&'d ()>, | ||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { | 97 | impl<'d, V: VbusDetect> Driver<'d, V> { |
| 97 | /// Create a new USB driver. | 98 | /// Create a new USB driver. |
| 98 | pub fn new( | 99 | pub fn new<T: Instance>( |
| 99 | usb: Peri<'d, T>, | 100 | _usb: Peri<'d, T>, |
| 100 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | 101 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, |
| 101 | vbus_detect: V, | 102 | vbus_detect: V, |
| 102 | ) -> Self { | 103 | ) -> Self { |
| @@ -104,19 +105,20 @@ impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> { | |||
| 104 | unsafe { T::Interrupt::enable() }; | 105 | unsafe { T::Interrupt::enable() }; |
| 105 | 106 | ||
| 106 | Self { | 107 | Self { |
| 107 | _p: usb, | 108 | regs: crate::pac::USBD, |
| 108 | alloc_in: Allocator::new(), | 109 | alloc_in: Allocator::new(), |
| 109 | alloc_out: Allocator::new(), | 110 | alloc_out: Allocator::new(), |
| 110 | vbus_detect, | 111 | vbus_detect, |
| 112 | _phantom: PhantomData, | ||
| 111 | } | 113 | } |
| 112 | } | 114 | } |
| 113 | } | 115 | } |
| 114 | 116 | ||
| 115 | impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V> { | 117 | impl<'d, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, V> { |
| 116 | type EndpointOut = Endpoint<'d, T, Out>; | 118 | type EndpointOut = Endpoint<'d, Out>; |
| 117 | type EndpointIn = Endpoint<'d, T, In>; | 119 | type EndpointIn = Endpoint<'d, In>; |
| 118 | type ControlPipe = ControlPipe<'d, T>; | 120 | type ControlPipe = ControlPipe<'d>; |
| 119 | type Bus = Bus<'d, T, V>; | 121 | type Bus = Bus<'d, V>; |
| 120 | 122 | ||
| 121 | fn alloc_endpoint_in( | 123 | fn alloc_endpoint_in( |
| 122 | &mut self, | 124 | &mut self, |
| @@ -127,12 +129,15 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V | |||
| 127 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { | 129 | ) -> Result<Self::EndpointIn, driver::EndpointAllocError> { |
| 128 | let index = self.alloc_in.allocate(ep_type, ep_addr)?; | 130 | let index = self.alloc_in.allocate(ep_type, ep_addr)?; |
| 129 | let ep_addr = EndpointAddress::from_parts(index, Direction::In); | 131 | let ep_addr = EndpointAddress::from_parts(index, Direction::In); |
| 130 | Ok(Endpoint::new(EndpointInfo { | 132 | Ok(Endpoint::new( |
| 131 | addr: ep_addr, | 133 | self.regs, |
| 132 | ep_type, | 134 | EndpointInfo { |
| 133 | max_packet_size: packet_size, | 135 | addr: ep_addr, |
| 134 | interval_ms, | 136 | ep_type, |
| 135 | })) | 137 | max_packet_size: packet_size, |
| 138 | interval_ms, | ||
| 139 | }, | ||
| 140 | )) | ||
| 136 | } | 141 | } |
| 137 | 142 | ||
| 138 | fn alloc_endpoint_out( | 143 | fn alloc_endpoint_out( |
| @@ -144,39 +149,45 @@ impl<'d, T: Instance, V: VbusDetect + 'd> driver::Driver<'d> for Driver<'d, T, V | |||
| 144 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { | 149 | ) -> Result<Self::EndpointOut, driver::EndpointAllocError> { |
| 145 | let index = self.alloc_out.allocate(ep_type, ep_addr)?; | 150 | let index = self.alloc_out.allocate(ep_type, ep_addr)?; |
| 146 | let ep_addr = EndpointAddress::from_parts(index, Direction::Out); | 151 | let ep_addr = EndpointAddress::from_parts(index, Direction::Out); |
| 147 | Ok(Endpoint::new(EndpointInfo { | 152 | Ok(Endpoint::new( |
| 148 | addr: ep_addr, | 153 | self.regs, |
| 149 | ep_type, | 154 | EndpointInfo { |
| 150 | max_packet_size: packet_size, | 155 | addr: ep_addr, |
| 151 | interval_ms, | 156 | ep_type, |
| 152 | })) | 157 | max_packet_size: packet_size, |
| 158 | interval_ms, | ||
| 159 | }, | ||
| 160 | )) | ||
| 153 | } | 161 | } |
| 154 | 162 | ||
| 155 | fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { | 163 | fn start(self, control_max_packet_size: u16) -> (Self::Bus, Self::ControlPipe) { |
| 156 | ( | 164 | ( |
| 157 | Bus { | 165 | Bus { |
| 158 | _p: unsafe { self._p.clone_unchecked() }, | 166 | regs: self.regs, |
| 159 | power_available: false, | 167 | power_available: false, |
| 160 | vbus_detect: self.vbus_detect, | 168 | vbus_detect: self.vbus_detect, |
| 169 | _phantom: PhantomData, | ||
| 161 | }, | 170 | }, |
| 162 | ControlPipe { | 171 | ControlPipe { |
| 163 | _p: self._p, | 172 | regs: self.regs, |
| 164 | max_packet_size: control_max_packet_size, | 173 | max_packet_size: control_max_packet_size, |
| 174 | _phantom: PhantomData, | ||
| 165 | }, | 175 | }, |
| 166 | ) | 176 | ) |
| 167 | } | 177 | } |
| 168 | } | 178 | } |
| 169 | 179 | ||
| 170 | /// USB bus. | 180 | /// USB bus. |
| 171 | pub struct Bus<'d, T: Instance, V: VbusDetect> { | 181 | pub struct Bus<'d, V: VbusDetect> { |
| 172 | _p: Peri<'d, T>, | 182 | regs: pac::usbd::Usbd, |
| 173 | power_available: bool, | 183 | power_available: bool, |
| 174 | vbus_detect: V, | 184 | vbus_detect: V, |
| 185 | _phantom: PhantomData<&'d ()>, | ||
| 175 | } | 186 | } |
| 176 | 187 | ||
| 177 | impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | 188 | impl<'d, V: VbusDetect> driver::Bus for Bus<'d, V> { |
| 178 | async fn enable(&mut self) { | 189 | async fn enable(&mut self) { |
| 179 | let regs = T::regs(); | 190 | let regs = self.regs; |
| 180 | 191 | ||
| 181 | errata::pre_enable(); | 192 | errata::pre_enable(); |
| 182 | 193 | ||
| @@ -215,14 +226,14 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 215 | } | 226 | } |
| 216 | 227 | ||
| 217 | async fn disable(&mut self) { | 228 | async fn disable(&mut self) { |
| 218 | let regs = T::regs(); | 229 | let regs = self.regs; |
| 219 | regs.enable().write(|x| x.set_enable(false)); | 230 | regs.enable().write(|x| x.set_enable(false)); |
| 220 | } | 231 | } |
| 221 | 232 | ||
| 222 | fn poll(&mut self) -> impl Future<Output = Event> { | 233 | fn poll(&mut self) -> impl Future<Output = Event> { |
| 223 | poll_fn(|cx| { | 234 | poll_fn(|cx| { |
| 224 | BUS_WAKER.register(cx.waker()); | 235 | BUS_WAKER.register(cx.waker()); |
| 225 | let regs = T::regs(); | 236 | let regs = self.regs; |
| 226 | 237 | ||
| 227 | if regs.events_usbreset().read() != 0 { | 238 | if regs.events_usbreset().read() != 0 { |
| 228 | regs.events_usbreset().write_value(0); | 239 | regs.events_usbreset().write_value(0); |
| @@ -280,7 +291,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 280 | } | 291 | } |
| 281 | 292 | ||
| 282 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { | 293 | fn endpoint_set_stalled(&mut self, ep_addr: EndpointAddress, stalled: bool) { |
| 283 | let regs = T::regs(); | 294 | let regs = self.regs; |
| 284 | if ep_addr.index() == 0 { | 295 | if ep_addr.index() == 0 { |
| 285 | if stalled { | 296 | if stalled { |
| 286 | regs.tasks_ep0stall().write_value(1); | 297 | regs.tasks_ep0stall().write_value(1); |
| @@ -298,7 +309,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 298 | } | 309 | } |
| 299 | 310 | ||
| 300 | fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { | 311 | fn endpoint_is_stalled(&mut self, ep_addr: EndpointAddress) -> bool { |
| 301 | let regs = T::regs(); | 312 | let regs = self.regs; |
| 302 | let i = ep_addr.index(); | 313 | let i = ep_addr.index(); |
| 303 | match ep_addr.direction() { | 314 | match ep_addr.direction() { |
| 304 | Direction::Out => regs.halted().epout(i).read().getstatus() == vals::Getstatus::HALTED, | 315 | Direction::Out => regs.halted().epout(i).read().getstatus() == vals::Getstatus::HALTED, |
| @@ -307,7 +318,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 307 | } | 318 | } |
| 308 | 319 | ||
| 309 | fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { | 320 | fn endpoint_set_enabled(&mut self, ep_addr: EndpointAddress, enabled: bool) { |
| 310 | let regs = T::regs(); | 321 | let regs = self.regs; |
| 311 | 322 | ||
| 312 | let i = ep_addr.index(); | 323 | let i = ep_addr.index(); |
| 313 | let mask = 1 << i; | 324 | let mask = 1 << i; |
| @@ -359,7 +370,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 359 | 370 | ||
| 360 | #[inline] | 371 | #[inline] |
| 361 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { | 372 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { |
| 362 | let regs = T::regs(); | 373 | let regs = self.regs; |
| 363 | 374 | ||
| 364 | if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER { | 375 | if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER { |
| 365 | errata::pre_wakeup(); | 376 | errata::pre_wakeup(); |
| @@ -368,7 +379,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 368 | 379 | ||
| 369 | poll_fn(|cx| { | 380 | poll_fn(|cx| { |
| 370 | BUS_WAKER.register(cx.waker()); | 381 | BUS_WAKER.register(cx.waker()); |
| 371 | let regs = T::regs(); | 382 | let regs = self.regs; |
| 372 | let r = regs.eventcause().read(); | 383 | let r = regs.eventcause().read(); |
| 373 | 384 | ||
| 374 | if regs.events_usbreset().read() != 0 { | 385 | if regs.events_usbreset().read() != 0 { |
| @@ -441,21 +452,23 @@ impl EndpointDir for Out { | |||
| 441 | } | 452 | } |
| 442 | 453 | ||
| 443 | /// USB endpoint. | 454 | /// USB endpoint. |
| 444 | pub struct Endpoint<'d, T: Instance, Dir> { | 455 | pub struct Endpoint<'d, Dir> { |
| 445 | _phantom: PhantomData<(&'d mut T, Dir)>, | 456 | regs: pac::usbd::Usbd, |
| 446 | info: EndpointInfo, | 457 | info: EndpointInfo, |
| 458 | _phantom: PhantomData<(&'d (), Dir)>, | ||
| 447 | } | 459 | } |
| 448 | 460 | ||
| 449 | impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | 461 | impl<'d, Dir> Endpoint<'d, Dir> { |
| 450 | fn new(info: EndpointInfo) -> Self { | 462 | fn new(regs: pac::usbd::Usbd, info: EndpointInfo) -> Self { |
| 451 | Self { | 463 | Self { |
| 464 | regs, | ||
| 452 | info, | 465 | info, |
| 453 | _phantom: PhantomData, | 466 | _phantom: PhantomData, |
| 454 | } | 467 | } |
| 455 | } | 468 | } |
| 456 | } | 469 | } |
| 457 | 470 | ||
| 458 | impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir> { | 471 | impl<'d, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, Dir> { |
| 459 | fn info(&self) -> &EndpointInfo { | 472 | fn info(&self) -> &EndpointInfo { |
| 460 | &self.info | 473 | &self.info |
| 461 | } | 474 | } |
| @@ -466,14 +479,14 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir | |||
| 466 | } | 479 | } |
| 467 | 480 | ||
| 468 | #[allow(private_bounds)] | 481 | #[allow(private_bounds)] |
| 469 | impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> { | 482 | impl<'d, Dir: EndpointDir> Endpoint<'d, Dir> { |
| 470 | fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> { | 483 | fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> + use<'_, 'd, Dir> { |
| 471 | let i = self.info.addr.index(); | 484 | let i = self.info.addr.index(); |
| 472 | assert!(i != 0); | 485 | assert!(i != 0); |
| 473 | 486 | ||
| 474 | poll_fn(move |cx| { | 487 | poll_fn(move |cx| { |
| 475 | Dir::waker(i).register(cx.waker()); | 488 | Dir::waker(i).register(cx.waker()); |
| 476 | if Dir::is_enabled(T::regs(), i) == state { | 489 | if Dir::is_enabled(self.regs, i) == state { |
| 477 | Poll::Ready(()) | 490 | Poll::Ready(()) |
| 478 | } else { | 491 | } else { |
| 479 | Poll::Pending | 492 | Poll::Pending |
| @@ -482,12 +495,12 @@ impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> { | |||
| 482 | } | 495 | } |
| 483 | 496 | ||
| 484 | /// Wait for the endpoint to be disabled | 497 | /// Wait for the endpoint to be disabled |
| 485 | pub fn wait_disabled(&mut self) -> impl Future<Output = ()> { | 498 | pub fn wait_disabled(&mut self) -> impl Future<Output = ()> + use<'_, 'd, Dir> { |
| 486 | self.wait_enabled_state(false) | 499 | self.wait_enabled_state(false) |
| 487 | } | 500 | } |
| 488 | } | 501 | } |
| 489 | 502 | ||
| 490 | impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | 503 | impl<'d, Dir> Endpoint<'d, Dir> { |
| 491 | async fn wait_data_ready(&mut self) -> Result<(), ()> | 504 | async fn wait_data_ready(&mut self) -> Result<(), ()> |
| 492 | where | 505 | where |
| 493 | Dir: EndpointDir, | 506 | Dir: EndpointDir, |
| @@ -497,7 +510,7 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | |||
| 497 | poll_fn(|cx| { | 510 | poll_fn(|cx| { |
| 498 | Dir::waker(i).register(cx.waker()); | 511 | Dir::waker(i).register(cx.waker()); |
| 499 | let r = READY_ENDPOINTS.load(Ordering::Acquire); | 512 | let r = READY_ENDPOINTS.load(Ordering::Acquire); |
| 500 | if !Dir::is_enabled(T::regs(), i) { | 513 | if !Dir::is_enabled(self.regs, i) { |
| 501 | Poll::Ready(Err(())) | 514 | Poll::Ready(Err(())) |
| 502 | } else if r & Dir::mask(i) != 0 { | 515 | } else if r & Dir::mask(i) != 0 { |
| 503 | Poll::Ready(Ok(())) | 516 | Poll::Ready(Ok(())) |
| @@ -514,9 +527,7 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | |||
| 514 | } | 527 | } |
| 515 | } | 528 | } |
| 516 | 529 | ||
| 517 | unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> { | 530 | unsafe fn read_dma(regs: pac::usbd::Usbd, i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 518 | let regs = T::regs(); | ||
| 519 | |||
| 520 | // Check that the packet fits into the buffer | 531 | // Check that the packet fits into the buffer |
| 521 | let size = regs.size().epout(i).read().0 as usize; | 532 | let size = regs.size().epout(i).read().0 as usize; |
| 522 | if size > buf.len() { | 533 | if size > buf.len() { |
| @@ -539,8 +550,7 @@ unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, Endpo | |||
| 539 | Ok(size) | 550 | Ok(size) |
| 540 | } | 551 | } |
| 541 | 552 | ||
| 542 | unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) { | 553 | unsafe fn write_dma(regs: pac::usbd::Usbd, i: usize, buf: &[u8]) { |
| 543 | let regs = T::regs(); | ||
| 544 | assert!(buf.len() <= 64); | 554 | assert!(buf.len() <= 64); |
| 545 | 555 | ||
| 546 | let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit(); | 556 | let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit(); |
| @@ -566,43 +576,44 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) { | |||
| 566 | dma_end(); | 576 | dma_end(); |
| 567 | } | 577 | } |
| 568 | 578 | ||
| 569 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { | 579 | impl<'d> driver::EndpointOut for Endpoint<'d, Out> { |
| 570 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { | 580 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 571 | let i = self.info.addr.index(); | 581 | let i = self.info.addr.index(); |
| 572 | assert!(i != 0); | 582 | assert!(i != 0); |
| 573 | 583 | ||
| 574 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; | 584 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; |
| 575 | 585 | ||
| 576 | unsafe { read_dma::<T>(i, buf) } | 586 | unsafe { read_dma(self.regs, i, buf) } |
| 577 | } | 587 | } |
| 578 | } | 588 | } |
| 579 | 589 | ||
| 580 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { | 590 | impl<'d> driver::EndpointIn for Endpoint<'d, In> { |
| 581 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { | 591 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { |
| 582 | let i = self.info.addr.index(); | 592 | let i = self.info.addr.index(); |
| 583 | assert!(i != 0); | 593 | assert!(i != 0); |
| 584 | 594 | ||
| 585 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; | 595 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; |
| 586 | 596 | ||
| 587 | unsafe { write_dma::<T>(i, buf) } | 597 | unsafe { write_dma(self.regs, i, buf) } |
| 588 | 598 | ||
| 589 | Ok(()) | 599 | Ok(()) |
| 590 | } | 600 | } |
| 591 | } | 601 | } |
| 592 | 602 | ||
| 593 | /// USB control pipe. | 603 | /// USB control pipe. |
| 594 | pub struct ControlPipe<'d, T: Instance> { | 604 | pub struct ControlPipe<'d> { |
| 595 | _p: Peri<'d, T>, | 605 | regs: pac::usbd::Usbd, |
| 596 | max_packet_size: u16, | 606 | max_packet_size: u16, |
| 607 | _phantom: PhantomData<&'d ()>, | ||
| 597 | } | 608 | } |
| 598 | 609 | ||
| 599 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 610 | impl<'d> driver::ControlPipe for ControlPipe<'d> { |
| 600 | fn max_packet_size(&self) -> usize { | 611 | fn max_packet_size(&self) -> usize { |
| 601 | usize::from(self.max_packet_size) | 612 | usize::from(self.max_packet_size) |
| 602 | } | 613 | } |
| 603 | 614 | ||
| 604 | async fn setup(&mut self) -> [u8; 8] { | 615 | async fn setup(&mut self) -> [u8; 8] { |
| 605 | let regs = T::regs(); | 616 | let regs = self.regs; |
| 606 | 617 | ||
| 607 | // Reset shorts | 618 | // Reset shorts |
| 608 | regs.shorts().write(|_| ()); | 619 | regs.shorts().write(|_| ()); |
| @@ -611,7 +622,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 611 | regs.intenset().write(|w| w.set_ep0setup(true)); | 622 | regs.intenset().write(|w| w.set_ep0setup(true)); |
| 612 | poll_fn(|cx| { | 623 | poll_fn(|cx| { |
| 613 | EP0_WAKER.register(cx.waker()); | 624 | EP0_WAKER.register(cx.waker()); |
| 614 | let regs = T::regs(); | 625 | let regs = self.regs; |
| 615 | if regs.events_ep0setup().read() != 0 { | 626 | if regs.events_ep0setup().read() != 0 { |
| 616 | Poll::Ready(()) | 627 | Poll::Ready(()) |
| 617 | } else { | 628 | } else { |
| @@ -636,7 +647,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 636 | } | 647 | } |
| 637 | 648 | ||
| 638 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { | 649 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { |
| 639 | let regs = T::regs(); | 650 | let regs = self.regs; |
| 640 | 651 | ||
| 641 | regs.events_ep0datadone().write_value(0); | 652 | regs.events_ep0datadone().write_value(0); |
| 642 | 653 | ||
| @@ -651,7 +662,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 651 | }); | 662 | }); |
| 652 | poll_fn(|cx| { | 663 | poll_fn(|cx| { |
| 653 | EP0_WAKER.register(cx.waker()); | 664 | EP0_WAKER.register(cx.waker()); |
| 654 | let regs = T::regs(); | 665 | let regs = self.regs; |
| 655 | if regs.events_ep0datadone().read() != 0 { | 666 | if regs.events_ep0datadone().read() != 0 { |
| 656 | Poll::Ready(Ok(())) | 667 | Poll::Ready(Ok(())) |
| 657 | } else if regs.events_usbreset().read() != 0 { | 668 | } else if regs.events_usbreset().read() != 0 { |
| @@ -666,17 +677,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 666 | }) | 677 | }) |
| 667 | .await?; | 678 | .await?; |
| 668 | 679 | ||
| 669 | unsafe { read_dma::<T>(0, buf) } | 680 | unsafe { read_dma(self.regs, 0, buf) } |
| 670 | } | 681 | } |
| 671 | 682 | ||
| 672 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { | 683 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { |
| 673 | let regs = T::regs(); | 684 | let regs = self.regs; |
| 674 | regs.events_ep0datadone().write_value(0); | 685 | regs.events_ep0datadone().write_value(0); |
| 675 | 686 | ||
| 676 | regs.shorts().write(|w| w.set_ep0datadone_ep0status(last)); | 687 | regs.shorts().write(|w| w.set_ep0datadone_ep0status(last)); |
| 677 | 688 | ||
| 678 | // This starts a TX on EP0. events_ep0datadone notifies when done. | 689 | // This starts a TX on EP0. events_ep0datadone notifies when done. |
| 679 | unsafe { write_dma::<T>(0, buf) } | 690 | unsafe { write_dma(self.regs, 0, buf) } |
| 680 | 691 | ||
| 681 | regs.intenset().write(|w| { | 692 | regs.intenset().write(|w| { |
| 682 | w.set_usbreset(true); | 693 | w.set_usbreset(true); |
| @@ -687,7 +698,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 687 | poll_fn(|cx| { | 698 | poll_fn(|cx| { |
| 688 | cx.waker().wake_by_ref(); | 699 | cx.waker().wake_by_ref(); |
| 689 | EP0_WAKER.register(cx.waker()); | 700 | EP0_WAKER.register(cx.waker()); |
| 690 | let regs = T::regs(); | 701 | let regs = self.regs; |
| 691 | if regs.events_ep0datadone().read() != 0 { | 702 | if regs.events_ep0datadone().read() != 0 { |
| 692 | Poll::Ready(Ok(())) | 703 | Poll::Ready(Ok(())) |
| 693 | } else if regs.events_usbreset().read() != 0 { | 704 | } else if regs.events_usbreset().read() != 0 { |
| @@ -704,12 +715,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 704 | } | 715 | } |
| 705 | 716 | ||
| 706 | async fn accept(&mut self) { | 717 | async fn accept(&mut self) { |
| 707 | let regs = T::regs(); | 718 | let regs = self.regs; |
| 708 | regs.tasks_ep0status().write_value(1); | 719 | regs.tasks_ep0status().write_value(1); |
| 709 | } | 720 | } |
| 710 | 721 | ||
| 711 | async fn reject(&mut self) { | 722 | async fn reject(&mut self) { |
| 712 | let regs = T::regs(); | 723 | let regs = self.regs; |
| 713 | regs.tasks_ep0stall().write_value(1); | 724 | regs.tasks_ep0stall().write_value(1); |
| 714 | } | 725 | } |
| 715 | 726 | ||
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index 7ab9adc29..dc99a16f5 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs | |||
| @@ -66,11 +66,11 @@ impl Default for Config { | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /// Watchdog driver. | 68 | /// Watchdog driver. |
| 69 | pub struct Watchdog<T: Instance> { | 69 | pub struct Watchdog { |
| 70 | _wdt: Peri<'static, T>, | 70 | r: pac::wdt::Wdt, |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | impl<T: Instance> Watchdog<T> { | 73 | impl Watchdog { |
| 74 | /// Try to create a new watchdog driver. | 74 | /// Try to create a new watchdog driver. |
| 75 | /// | 75 | /// |
| 76 | /// This function will return an error if the watchdog is already active | 76 | /// This function will return an error if the watchdog is already active |
| @@ -79,7 +79,7 @@ impl<T: Instance> Watchdog<T> { | |||
| 79 | /// | 79 | /// |
| 80 | /// `N` must be between 1 and 8, inclusive. | 80 | /// `N` must be between 1 and 8, inclusive. |
| 81 | #[inline] | 81 | #[inline] |
| 82 | pub fn try_new<const N: usize>( | 82 | pub fn try_new<T: Instance, const N: usize>( |
| 83 | wdt: Peri<'static, T>, | 83 | wdt: Peri<'static, T>, |
| 84 | config: Config, | 84 | config: Config, |
| 85 | ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, T>> { | 85 | ) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, T>> { |
| @@ -116,7 +116,7 @@ impl<T: Instance> Watchdog<T> { | |||
| 116 | r.tasks_start().write_value(1); | 116 | r.tasks_start().write_value(1); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | let this = Self { _wdt: wdt }; | 119 | let this = Self { r: T::REGS }; |
| 120 | 120 | ||
| 121 | let mut handles = [const { WatchdogHandle { index: 0 } }; N]; | 121 | let mut handles = [const { WatchdogHandle { index: 0 } }; N]; |
| 122 | for i in 0..N { | 122 | for i in 0..N { |
| @@ -135,7 +135,7 @@ impl<T: Instance> Watchdog<T> { | |||
| 135 | /// interrupt has been enabled. | 135 | /// interrupt has been enabled. |
| 136 | #[inline(always)] | 136 | #[inline(always)] |
| 137 | pub fn enable_interrupt(&mut self) { | 137 | pub fn enable_interrupt(&mut self) { |
| 138 | T::REGS.intenset().write(|w| w.set_timeout(true)); | 138 | self.r.intenset().write(|w| w.set_timeout(true)); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | /// Disable the watchdog interrupt. | 141 | /// Disable the watchdog interrupt. |
| @@ -143,7 +143,7 @@ impl<T: Instance> Watchdog<T> { | |||
| 143 | /// NOTE: This has no effect on the reset caused by the Watchdog. | 143 | /// NOTE: This has no effect on the reset caused by the Watchdog. |
| 144 | #[inline(always)] | 144 | #[inline(always)] |
| 145 | pub fn disable_interrupt(&mut self) { | 145 | pub fn disable_interrupt(&mut self) { |
| 146 | T::REGS.intenclr().write(|w| w.set_timeout(true)); | 146 | self.r.intenclr().write(|w| w.set_timeout(true)); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | /// Is the watchdog still awaiting pets from any handle? | 149 | /// Is the watchdog still awaiting pets from any handle? |
| @@ -152,9 +152,8 @@ impl<T: Instance> Watchdog<T> { | |||
| 152 | /// handles to prevent a reset this time period. | 152 | /// handles to prevent a reset this time period. |
| 153 | #[inline(always)] | 153 | #[inline(always)] |
| 154 | pub fn awaiting_pets(&self) -> bool { | 154 | pub fn awaiting_pets(&self) -> bool { |
| 155 | let r = T::REGS; | 155 | let enabled = self.r.rren().read().0; |
| 156 | let enabled = r.rren().read().0; | 156 | let status = self.r.reqstatus().read().0; |
| 157 | let status = r.reqstatus().read().0; | ||
| 158 | (status & enabled) == 0 | 157 | (status & enabled) == 0 |
| 159 | } | 158 | } |
| 160 | } | 159 | } |
diff --git a/examples/nrf52840/src/bin/rtc.rs b/examples/nrf52840/src/bin/rtc.rs index a3df7da14..9d475df7f 100644 --- a/examples/nrf52840/src/bin/rtc.rs +++ b/examples/nrf52840/src/bin/rtc.rs | |||
| @@ -14,8 +14,7 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 14 | 14 | ||
| 15 | // 64 bit counter which will never overflow. | 15 | // 64 bit counter which will never overflow. |
| 16 | static TICK_COUNTER: AtomicU64 = AtomicU64::new(0); | 16 | static TICK_COUNTER: AtomicU64 = AtomicU64::new(0); |
| 17 | static RTC: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc<'static, embassy_nrf::peripherals::RTC0>>>> = | 17 | static RTC: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc<'static>>>> = Mutex::new(RefCell::new(None)); |
| 18 | Mutex::new(RefCell::new(None)); | ||
| 19 | 18 | ||
| 20 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 21 | async fn main(_spawner: Spawner) { | 20 | async fn main(_spawner: Spawner) { |
diff --git a/examples/nrf52840/src/bin/sixlowpan.rs b/examples/nrf52840/src/bin/sixlowpan.rs index 00a597366..12e385e01 100644 --- a/examples/nrf52840/src/bin/sixlowpan.rs +++ b/examples/nrf52840/src/bin/sixlowpan.rs | |||
| @@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 21 | }); | 21 | }); |
| 22 | 22 | ||
| 23 | #[embassy_executor::task] | 23 | #[embassy_executor::task] |
| 24 | async fn ieee802154_task(runner: net::Runner<'static, peripherals::RADIO>) -> ! { | 24 | async fn ieee802154_task(runner: net::Runner<'static>) -> ! { |
| 25 | runner.run().await | 25 | runner.run().await |
| 26 | } | 26 | } |
| 27 | 27 | ||
diff --git a/examples/nrf52840/src/bin/uart_split.rs b/examples/nrf52840/src/bin/uart_split.rs index 51af90727..d75143126 100644 --- a/examples/nrf52840/src/bin/uart_split.rs +++ b/examples/nrf52840/src/bin/uart_split.rs | |||
| @@ -52,7 +52,7 @@ async fn main(spawner: Spawner) { | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | #[embassy_executor::task] | 54 | #[embassy_executor::task] |
| 55 | async fn reader(mut rx: UarteRx<'static, UARTE0>) { | 55 | async fn reader(mut rx: UarteRx<'static>) { |
| 56 | let mut buf = [0; 8]; | 56 | let mut buf = [0; 8]; |
| 57 | loop { | 57 | loop { |
| 58 | info!("reading..."); | 58 | info!("reading..."); |
diff --git a/examples/nrf52840/src/bin/usb_ethernet.rs b/examples/nrf52840/src/bin/usb_ethernet.rs index 87aa4c6c5..a75b967b4 100644 --- a/examples/nrf52840/src/bin/usb_ethernet.rs +++ b/examples/nrf52840/src/bin/usb_ethernet.rs | |||
| @@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs { | |||
| 22 | RNG => rng::InterruptHandler<peripherals::RNG>; | 22 | RNG => rng::InterruptHandler<peripherals::RNG>; |
| 23 | }); | 23 | }); |
| 24 | 24 | ||
| 25 | type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; | 25 | type MyDriver = Driver<'static, HardwareVbusDetect>; |
| 26 | 26 | ||
| 27 | const MTU: usize = 1514; | 27 | const MTU: usize = 1514; |
| 28 | 28 | ||
diff --git a/examples/nrf52840/src/bin/usb_serial.rs b/examples/nrf52840/src/bin/usb_serial.rs index 8d05df791..e7c2d0854 100644 --- a/examples/nrf52840/src/bin/usb_serial.rs +++ b/examples/nrf52840/src/bin/usb_serial.rs | |||
| @@ -5,7 +5,7 @@ use defmt::{info, panic}; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; | 7 | use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; |
| 8 | use embassy_nrf::usb::{Driver, Instance}; | 8 | use embassy_nrf::usb::Driver; |
| 9 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; | 9 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 11 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| @@ -89,9 +89,7 @@ impl From<EndpointError> for Disconnected { | |||
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | async fn echo<'d, T: Instance + 'd, P: VbusDetect + 'd>( | 92 | async fn echo<'d, V: VbusDetect + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, V>>) -> Result<(), Disconnected> { |
| 93 | class: &mut CdcAcmClass<'d, Driver<'d, T, P>>, | ||
| 94 | ) -> Result<(), Disconnected> { | ||
| 95 | let mut buf = [0; 64]; | 93 | let mut buf = [0; 64]; |
| 96 | loop { | 94 | loop { |
| 97 | let n = class.read_packet(&mut buf).await?; | 95 | let n = class.read_packet(&mut buf).await?; |
diff --git a/examples/nrf52840/src/bin/usb_serial_multitask.rs b/examples/nrf52840/src/bin/usb_serial_multitask.rs index 00a91a233..b6a983854 100644 --- a/examples/nrf52840/src/bin/usb_serial_multitask.rs +++ b/examples/nrf52840/src/bin/usb_serial_multitask.rs | |||
| @@ -17,7 +17,7 @@ bind_interrupts!(struct Irqs { | |||
| 17 | CLOCK_POWER => usb::vbus_detect::InterruptHandler; | 17 | CLOCK_POWER => usb::vbus_detect::InterruptHandler; |
| 18 | }); | 18 | }); |
| 19 | 19 | ||
| 20 | type MyDriver = Driver<'static, peripherals::USBD, HardwareVbusDetect>; | 20 | type MyDriver = Driver<'static, HardwareVbusDetect>; |
| 21 | 21 | ||
| 22 | #[embassy_executor::task] | 22 | #[embassy_executor::task] |
| 23 | async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { | 23 | async fn usb_task(mut device: UsbDevice<'static, MyDriver>) { |
diff --git a/examples/nrf52840/src/bin/usb_serial_winusb.rs b/examples/nrf52840/src/bin/usb_serial_winusb.rs index 8a20ce673..e30e08a01 100644 --- a/examples/nrf52840/src/bin/usb_serial_winusb.rs +++ b/examples/nrf52840/src/bin/usb_serial_winusb.rs | |||
| @@ -5,7 +5,7 @@ use defmt::{info, panic}; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; | 7 | use embassy_nrf::usb::vbus_detect::{HardwareVbusDetect, VbusDetect}; |
| 8 | use embassy_nrf::usb::{Driver, Instance}; | 8 | use embassy_nrf::usb::Driver; |
| 9 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; | 9 | use embassy_nrf::{bind_interrupts, pac, peripherals, usb}; |
| 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; | 10 | use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; |
| 11 | use embassy_usb::driver::EndpointError; | 11 | use embassy_usb::driver::EndpointError; |
| @@ -108,9 +108,7 @@ impl From<EndpointError> for Disconnected { | |||
| 108 | } | 108 | } |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | async fn echo<'d, T: Instance + 'd, P: VbusDetect + 'd>( | 111 | async fn echo<'d, V: VbusDetect + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, V>>) -> Result<(), Disconnected> { |
| 112 | class: &mut CdcAcmClass<'d, Driver<'d, T, P>>, | ||
| 113 | ) -> Result<(), Disconnected> { | ||
| 114 | let mut buf = [0; 64]; | 112 | let mut buf = [0; 64]; |
| 115 | loop { | 113 | loop { |
| 116 | let n = class.read_packet(&mut buf).await?; | 114 | let n = class.read_packet(&mut buf).await?; |
diff --git a/examples/nrf9160/src/bin/modem_tcp_client.rs b/examples/nrf9160/src/bin/modem_tcp_client.rs index 7d4815699..460a4cfae 100644 --- a/examples/nrf9160/src/bin/modem_tcp_client.rs +++ b/examples/nrf9160/src/bin/modem_tcp_client.rs | |||
| @@ -32,7 +32,7 @@ bind_interrupts!(struct Irqs { | |||
| 32 | }); | 32 | }); |
| 33 | 33 | ||
| 34 | #[embassy_executor::task] | 34 | #[embassy_executor::task] |
| 35 | async fn trace_task(mut uart: BufferedUarteTx<'static, peripherals::SERIAL0>, reader: TraceReader<'static>) -> ! { | 35 | async fn trace_task(mut uart: BufferedUarteTx<'static>, reader: TraceReader<'static>) -> ! { |
| 36 | let mut rx = [0u8; 1024]; | 36 | let mut rx = [0u8; 1024]; |
| 37 | loop { | 37 | loop { |
| 38 | let n = reader.read(&mut rx[..]).await; | 38 | let n = reader.read(&mut rx[..]).await; |
