diff options
| author | chasingRs <[email protected]> | 2025-10-10 10:26:46 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-10 10:26:46 +0800 |
| commit | 944fda48a94c2d6cb6bea56c8c8471858d75da7d (patch) | |
| tree | 1e3e2f463c2440afe81ca37b2e161f85d0bfc374 /embassy-nrf/src | |
| parent | 04171d903d3676d87aa0fd85719878d3087028f3 (diff) | |
| parent | 35b0ba4ce0fed7588febe504e16bbf1788384f5a (diff) | |
Merge branch 'embassy-rs:main' into fix/simple-pwm-32bit-timer-support
Diffstat (limited to 'embassy-nrf/src')
35 files changed, 1088 insertions, 884 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 29e126903..4c946497d 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -9,26 +9,27 @@ | |||
| 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. | 9 | //! Please also see [crate::uarte] to understand when [BufferedUarte] should be used. |
| 10 | 10 | ||
| 11 | use core::cmp::min; | 11 | use core::cmp::min; |
| 12 | use core::future::{poll_fn, Future}; | 12 | use core::future::{Future, poll_fn}; |
| 13 | use core::marker::PhantomData; | 13 | use core::marker::PhantomData; |
| 14 | use core::slice; | 14 | use core::slice; |
| 15 | use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU8, AtomicUsize, Ordering}; | 15 | use core::sync::atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering, compiler_fence}; |
| 16 | use core::task::Poll; | 16 | use core::task::Poll; |
| 17 | 17 | ||
| 18 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 19 | use embassy_hal_internal::Peri; | 18 | use embassy_hal_internal::Peri; |
| 19 | use embassy_hal_internal::atomic_ring_buffer::RingBuffer; | ||
| 20 | use pac::uarte::vals; | 20 | use pac::uarte::vals; |
| 21 | // Re-export SVD variants to allow user to directly set values | 21 | // Re-export SVD variants to allow user to directly set values |
| 22 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | 22 | 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::InterruptExt; | ||
| 25 | use crate::interrupt::typelevel::Interrupt; | 26 | use crate::interrupt::typelevel::Interrupt; |
| 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 | }; |
| 29 | use crate::timer::{Instance as TimerInstance, Timer}; | 30 | use crate::timer::{Instance as TimerInstance, Timer}; |
| 30 | use crate::uarte::{configure, configure_rx_pins, configure_tx_pins, drop_tx_rx, Config, Instance as UarteInstance}; | 31 | use crate::uarte::{Config, Instance as UarteInstance, configure, configure_rx_pins, configure_tx_pins, drop_tx_rx}; |
| 31 | use crate::{interrupt, pac, EASY_DMA_SIZE}; | 32 | use crate::{EASY_DMA_SIZE, interrupt, pac}; |
| 32 | 33 | ||
| 33 | pub(crate) struct State { | 34 | pub(crate) struct State { |
| 34 | tx_buf: RingBuffer, | 35 | tx_buf: RingBuffer, |
| @@ -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/chips/nrf54l15_app.rs b/embassy-nrf/src/chips/nrf54l15_app.rs index ff05bbec0..82d30104f 100644 --- a/embassy-nrf/src/chips/nrf54l15_app.rs +++ b/embassy-nrf/src/chips/nrf54l15_app.rs | |||
| @@ -94,6 +94,7 @@ pub mod pac { | |||
| 94 | #[cfg(feature = "_s")] | 94 | #[cfg(feature = "_s")] |
| 95 | #[doc(no_inline)] | 95 | #[doc(no_inline)] |
| 96 | pub use nrf_pac::{ | 96 | pub use nrf_pac::{ |
| 97 | FICR_NS as FICR, | ||
| 97 | SICR_S as SICR, | 98 | SICR_S as SICR, |
| 98 | ICACHEDATA_S as ICACHEDATA, | 99 | ICACHEDATA_S as ICACHEDATA, |
| 99 | ICACHEINFO_S as ICACHEINFO, | 100 | ICACHEINFO_S as ICACHEINFO, |
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs index 028396c7c..666986115 100644 --- a/embassy-nrf/src/egu.rs +++ b/embassy-nrf/src/egu.rs | |||
| @@ -10,24 +10,29 @@ use core::marker::PhantomData; | |||
| 10 | use embassy_hal_internal::PeripheralType; | 10 | use embassy_hal_internal::PeripheralType; |
| 11 | 11 | ||
| 12 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| 13 | use crate::{interrupt, pac, Peri}; | 13 | use crate::{Peri, interrupt, pac}; |
| 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..4c47b7cbd 100644 --- a/embassy-nrf/src/embassy_net_802154_driver.rs +++ b/embassy-nrf/src/embassy_net_802154_driver.rs | |||
| @@ -1,12 +1,12 @@ | |||
| 1 | //! embassy-net IEEE 802.15.4 driver | 1 | //! embassy-net IEEE 802.15.4 driver |
| 2 | 2 | ||
| 3 | use embassy_futures::select::{select3, Either3}; | 3 | use embassy_futures::select::{Either3, select3}; |
| 4 | use embassy_net_driver_channel::driver::LinkState; | 4 | use embassy_net_driver_channel::driver::LinkState; |
| 5 | use embassy_net_driver_channel::{self as ch}; | 5 | use embassy_net_driver_channel::{self as ch}; |
| 6 | use embassy_time::{Duration, Ticker}; | 6 | use embassy_time::{Duration, Ticker}; |
| 7 | 7 | ||
| 8 | use crate::radio::ieee802154::{Packet, Radio}; | ||
| 9 | use crate::radio::InterruptHandler; | 8 | use crate::radio::InterruptHandler; |
| 9 | use crate::radio::ieee802154::{Packet, Radio}; | ||
| 10 | use crate::{self as nrf, interrupt}; | 10 | use crate::{self as nrf, interrupt}; |
| 11 | 11 | ||
| 12 | /// MTU for the nrf radio. | 12 | /// MTU for the nrf radio. |
| @@ -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/gpio.rs b/embassy-nrf/src/gpio.rs index ab5e7ed4b..7ed3a7927 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -5,10 +5,10 @@ use core::convert::Infallible; | |||
| 5 | use core::hint::unreachable_unchecked; | 5 | use core::hint::unreachable_unchecked; |
| 6 | 6 | ||
| 7 | use cfg_if::cfg_if; | 7 | use cfg_if::cfg_if; |
| 8 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 8 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 9 | 9 | ||
| 10 | use crate::pac; | 10 | use crate::pac; |
| 11 | use crate::pac::common::{Reg, RW}; | 11 | use crate::pac::common::{RW, Reg}; |
| 12 | use crate::pac::gpio; | 12 | use crate::pac::gpio; |
| 13 | use crate::pac::gpio::vals; | 13 | use crate::pac::gpio::vals; |
| 14 | #[cfg(not(feature = "_nrf51"))] | 14 | #[cfg(not(feature = "_nrf51"))] |
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 43e43f0bf..a490d5b60 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | //! GPIO task/event (GPIOTE) driver. | 1 | //! GPIO task/event (GPIOTE) driver. |
| 2 | 2 | ||
| 3 | use core::convert::Infallible; | 3 | use core::convert::Infallible; |
| 4 | use core::future::{poll_fn, Future}; | 4 | use core::future::{Future, poll_fn}; |
| 5 | use core::task::{Context, Poll}; | 5 | use core::task::{Context, Poll}; |
| 6 | 6 | ||
| 7 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 7 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | 9 | ||
| 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; | 10 | use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _}; |
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs index 53de8deee..9cce9f1e8 100644 --- a/embassy-nrf/src/i2s.rs +++ b/embassy-nrf/src/i2s.rs | |||
| @@ -6,7 +6,7 @@ use core::future::poll_fn; | |||
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::mem::size_of; | 7 | use core::mem::size_of; |
| 8 | use core::ops::{Deref, DerefMut}; | 8 | use core::ops::{Deref, DerefMut}; |
| 9 | use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; | 9 | use core::sync::atomic::{AtomicBool, Ordering, compiler_fence}; |
| 10 | use core::task::Poll; | 10 | use core::task::Poll; |
| 11 | 11 | ||
| 12 | use embassy_hal_internal::drop::OnDrop; | 12 | use embassy_hal_internal::drop::OnDrop; |
| @@ -17,7 +17,7 @@ use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; | |||
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::i2s::vals; | 18 | use crate::pac::i2s::vals; |
| 19 | use crate::util::slice_in_ram_or; | 19 | use crate::util::slice_in_ram_or; |
| 20 | use crate::{interrupt, pac, EASY_DMA_SIZE}; | 20 | use crate::{EASY_DMA_SIZE, interrupt, pac}; |
| 21 | 21 | ||
| 22 | /// Type alias for `MultiBuffering` with 2 buffers. | 22 | /// Type alias for `MultiBuffering` with 2 buffers. |
| 23 | pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; | 23 | pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; |
| @@ -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/lib.rs b/embassy-nrf/src/lib.rs index 7c26a6184..1b7fb7e7f 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![allow(async_fn_in_trait)] | 2 | #![allow(async_fn_in_trait)] |
| 3 | #![allow(unsafe_op_in_unsafe_fn)] | ||
| 3 | #![cfg_attr( | 4 | #![cfg_attr( |
| 4 | docsrs, | 5 | docsrs, |
| 5 | doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-nrf'>browse the `embassy-nrf` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (nRF52840 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" | 6 | doc = "<div style='padding:30px;background:#810;color:#fff;text-align:center;'><p>You might want to <a href='https://docs.embassy.dev/embassy-nrf'>browse the `embassy-nrf` documentation on the Embassy website</a> instead.</p><p>The documentation here on `docs.rs` is built for a single chip only (nRF52840 in particular), while on the Embassy website you can pick your exact chip from the top menu. Available peripherals and their APIs change depending on the chip.</p></div>\n\n" |
| @@ -252,7 +253,7 @@ macro_rules! bind_interrupts { | |||
| 252 | 253 | ||
| 253 | $( | 254 | $( |
| 254 | #[allow(non_snake_case)] | 255 | #[allow(non_snake_case)] |
| 255 | #[no_mangle] | 256 | #[unsafe(no_mangle)] |
| 256 | $(#[cfg($cond_irq)])? | 257 | $(#[cfg($cond_irq)])? |
| 257 | unsafe extern "C" fn $irq() { | 258 | unsafe extern "C" fn $irq() { |
| 258 | unsafe { | 259 | unsafe { |
| @@ -284,7 +285,7 @@ macro_rules! bind_interrupts { | |||
| 284 | pub use chip::pac; | 285 | pub use chip::pac; |
| 285 | #[cfg(not(feature = "unstable-pac"))] | 286 | #[cfg(not(feature = "unstable-pac"))] |
| 286 | pub(crate) use chip::pac; | 287 | pub(crate) use chip::pac; |
| 287 | pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; | 288 | pub use chip::{EASY_DMA_SIZE, Peripherals, peripherals}; |
| 288 | pub use embassy_hal_internal::{Peri, PeripheralType}; | 289 | pub use embassy_hal_internal::{Peri, PeripheralType}; |
| 289 | 290 | ||
| 290 | pub use crate::chip::interrupt; | 291 | pub use crate::chip::interrupt; |
| @@ -406,9 +407,10 @@ pub mod config { | |||
| 406 | /// Settings for the internal capacitors. | 407 | /// Settings for the internal capacitors. |
| 407 | #[cfg(feature = "nrf5340-app-s")] | 408 | #[cfg(feature = "nrf5340-app-s")] |
| 408 | pub struct InternalCapacitors { | 409 | pub struct InternalCapacitors { |
| 409 | /// Config for the internal capacitors on pins XC1 and XC2. | 410 | /// Config for the internal capacitors on pins XC1 and XC2. Pass `None` to not touch it. |
| 410 | pub hfxo: Option<HfxoCapacitance>, | 411 | pub hfxo: Option<HfxoCapacitance>, |
| 411 | /// Config for the internal capacitors between pins XL1 and XL2. | 412 | /// Config for the internal capacitors between pins XL1 and XL2. Pass `None` to not touch |
| 413 | /// it. | ||
| 412 | pub lfxo: Option<LfxoCapacitance>, | 414 | pub lfxo: Option<LfxoCapacitance>, |
| 413 | } | 415 | } |
| 414 | 416 | ||
| @@ -416,6 +418,8 @@ pub mod config { | |||
| 416 | #[cfg(feature = "nrf5340-app-s")] | 418 | #[cfg(feature = "nrf5340-app-s")] |
| 417 | #[derive(Copy, Clone)] | 419 | #[derive(Copy, Clone)] |
| 418 | pub enum HfxoCapacitance { | 420 | pub enum HfxoCapacitance { |
| 421 | /// Use external capacitors | ||
| 422 | External, | ||
| 419 | /// 7.0 pF | 423 | /// 7.0 pF |
| 420 | _7_0pF, | 424 | _7_0pF, |
| 421 | /// 7.5 pF | 425 | /// 7.5 pF |
| @@ -475,8 +479,9 @@ pub mod config { | |||
| 475 | #[cfg(feature = "nrf5340-app-s")] | 479 | #[cfg(feature = "nrf5340-app-s")] |
| 476 | impl HfxoCapacitance { | 480 | impl HfxoCapacitance { |
| 477 | /// The capacitance value times two. | 481 | /// The capacitance value times two. |
| 478 | pub(crate) const fn value2(self) -> i32 { | 482 | pub(crate) fn value2(self) -> i32 { |
| 479 | match self { | 483 | match self { |
| 484 | HfxoCapacitance::External => unreachable!(), | ||
| 480 | HfxoCapacitance::_7_0pF => 14, | 485 | HfxoCapacitance::_7_0pF => 14, |
| 481 | HfxoCapacitance::_7_5pF => 15, | 486 | HfxoCapacitance::_7_5pF => 15, |
| 482 | HfxoCapacitance::_8_0pF => 16, | 487 | HfxoCapacitance::_8_0pF => 16, |
| @@ -506,11 +511,17 @@ pub mod config { | |||
| 506 | HfxoCapacitance::_20_0pF => 40, | 511 | HfxoCapacitance::_20_0pF => 40, |
| 507 | } | 512 | } |
| 508 | } | 513 | } |
| 514 | |||
| 515 | pub(crate) fn external(self) -> bool { | ||
| 516 | matches!(self, Self::External) | ||
| 517 | } | ||
| 509 | } | 518 | } |
| 510 | 519 | ||
| 511 | /// Internal capacitance value for the LFXO. | 520 | /// Internal capacitance value for the LFXO. |
| 512 | #[cfg(feature = "nrf5340-app-s")] | 521 | #[cfg(feature = "nrf5340-app-s")] |
| 513 | pub enum LfxoCapacitance { | 522 | pub enum LfxoCapacitance { |
| 523 | /// Use external capacitors | ||
| 524 | External = 0, | ||
| 514 | /// 6 pF | 525 | /// 6 pF |
| 515 | _6pF = 1, | 526 | _6pF = 1, |
| 516 | /// 7 pF | 527 | /// 7 pF |
| @@ -523,6 +534,7 @@ pub mod config { | |||
| 523 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { | 534 | impl From<LfxoCapacitance> for super::pac::oscillators::vals::Intcap { |
| 524 | fn from(t: LfxoCapacitance) -> Self { | 535 | fn from(t: LfxoCapacitance) -> Self { |
| 525 | match t { | 536 | match t { |
| 537 | LfxoCapacitance::External => Self::EXTERNAL, | ||
| 526 | LfxoCapacitance::_6pF => Self::C6PF, | 538 | LfxoCapacitance::_6pF => Self::C6PF, |
| 527 | LfxoCapacitance::_7pF => Self::C7PF, | 539 | LfxoCapacitance::_7pF => Self::C7PF, |
| 528 | LfxoCapacitance::_9pF => Self::C9PF, | 540 | LfxoCapacitance::_9pF => Self::C9PF, |
| @@ -720,6 +732,29 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 720 | } | 732 | } |
| 721 | } | 733 | } |
| 722 | 734 | ||
| 735 | // Apply trimming values from the FICR. | ||
| 736 | #[cfg(any( | ||
| 737 | all(feature = "_nrf5340-app", feature = "_s"), | ||
| 738 | all(feature = "_nrf54l", feature = "_s"), | ||
| 739 | feature = "_nrf5340-net", | ||
| 740 | ))] | ||
| 741 | { | ||
| 742 | #[cfg(feature = "_nrf5340")] | ||
| 743 | let n = 32; | ||
| 744 | #[cfg(feature = "_nrf54l")] | ||
| 745 | let n = 64; | ||
| 746 | for i in 0..n { | ||
| 747 | let info = pac::FICR.trimcnf(i); | ||
| 748 | let addr = info.addr().read(); | ||
| 749 | if addr == 0 || addr == 0xFFFF_FFFF { | ||
| 750 | break; | ||
| 751 | } | ||
| 752 | unsafe { | ||
| 753 | (addr as *mut u32).write_volatile(info.data().read()); | ||
| 754 | } | ||
| 755 | } | ||
| 756 | } | ||
| 757 | |||
| 723 | // GLITCHDET is only accessible for secure code | 758 | // GLITCHDET is only accessible for secure code |
| 724 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] | 759 | #[cfg(all(feature = "_nrf54l", feature = "_s"))] |
| 725 | { | 760 | { |
| @@ -953,17 +988,21 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 953 | #[cfg(feature = "nrf5340-app-s")] | 988 | #[cfg(feature = "nrf5340-app-s")] |
| 954 | { | 989 | { |
| 955 | if let Some(cap) = config.internal_capacitors.hfxo { | 990 | if let Some(cap) = config.internal_capacitors.hfxo { |
| 956 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; | 991 | if cap.external() { |
| 957 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; | 992 | pac::OSCILLATORS.xosc32mcaps().write(|w| w.set_enable(false)); |
| 958 | // slope is a signed 5-bit integer | 993 | } else { |
| 959 | if slope >= 16 { | 994 | let mut slope = pac::FICR.xosc32mtrim().read().slope() as i32; |
| 960 | slope -= 32; | 995 | let offset = pac::FICR.xosc32mtrim().read().offset() as i32; |
| 996 | // slope is a signed 5-bit integer | ||
| 997 | if slope >= 16 { | ||
| 998 | slope -= 32; | ||
| 999 | } | ||
| 1000 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 1001 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 1002 | w.set_capvalue(capvalue as u8); | ||
| 1003 | w.set_enable(true); | ||
| 1004 | }); | ||
| 961 | } | 1005 | } |
| 962 | let capvalue = (((slope + 56) * (cap.value2() - 14)) + ((offset - 8) << 4) + 32) >> 6; | ||
| 963 | pac::OSCILLATORS.xosc32mcaps().write(|w| { | ||
| 964 | w.set_capvalue(capvalue as u8); | ||
| 965 | w.set_enable(true); | ||
| 966 | }); | ||
| 967 | } | 1006 | } |
| 968 | if let Some(cap) = config.internal_capacitors.lfxo { | 1007 | if let Some(cap) = config.internal_capacitors.lfxo { |
| 969 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); | 1008 | pac::OSCILLATORS.xosc32ki().intcap().write(|w| w.set_intcap(cap.into())); |
diff --git a/embassy-nrf/src/nfct.rs b/embassy-nrf/src/nfct.rs index 8d70ec954..bfbdc2906 100644 --- a/embassy-nrf/src/nfct.rs +++ b/embassy-nrf/src/nfct.rs | |||
| @@ -10,18 +10,18 @@ | |||
| 10 | #![macro_use] | 10 | #![macro_use] |
| 11 | 11 | ||
| 12 | use core::future::poll_fn; | 12 | use core::future::poll_fn; |
| 13 | use core::sync::atomic::{compiler_fence, Ordering}; | 13 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 14 | use core::task::Poll; | 14 | use core::task::Poll; |
| 15 | 15 | ||
| 16 | use embassy_sync::waitqueue::AtomicWaker; | 16 | use embassy_sync::waitqueue::AtomicWaker; |
| 17 | pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode}; | 17 | pub use vals::{Bitframesdd as SddPat, Discardmode as DiscardMode}; |
| 18 | 18 | ||
| 19 | use crate::interrupt::InterruptExt; | 19 | use crate::interrupt::InterruptExt; |
| 20 | use crate::pac::nfct::vals; | ||
| 21 | use crate::pac::NFCT; | 20 | use crate::pac::NFCT; |
| 21 | use crate::pac::nfct::vals; | ||
| 22 | use crate::peripherals::NFCT; | 22 | use crate::peripherals::NFCT; |
| 23 | use crate::util::slice_in_ram; | 23 | use crate::util::slice_in_ram; |
| 24 | use crate::{interrupt, pac, Peri}; | 24 | use crate::{Peri, interrupt, pac}; |
| 25 | 25 | ||
| 26 | /// NFCID1 (aka UID) of different sizes. | 26 | /// NFCID1 (aka UID) of different sizes. |
| 27 | #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] | 27 | #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] |
diff --git a/embassy-nrf/src/nvmc.rs b/embassy-nrf/src/nvmc.rs index c46af0b34..3f38cd0f5 100644 --- a/embassy-nrf/src/nvmc.rs +++ b/embassy-nrf/src/nvmc.rs | |||
| @@ -8,7 +8,7 @@ use embedded_storage::nor_flash::{ | |||
| 8 | 8 | ||
| 9 | use crate::pac::nvmc::vals; | 9 | use crate::pac::nvmc::vals; |
| 10 | use crate::peripherals::NVMC; | 10 | use crate::peripherals::NVMC; |
| 11 | use crate::{pac, Peri}; | 11 | use crate::{Peri, pac}; |
| 12 | 12 | ||
| 13 | #[cfg(not(feature = "_nrf5340-net"))] | 13 | #[cfg(not(feature = "_nrf5340-net"))] |
| 14 | /// Erase size of NVMC flash in bytes. | 14 | /// Erase size of NVMC flash in bytes. |
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs index c2a4ba65f..bc28f5c8a 100644 --- a/embassy-nrf/src/pdm.rs +++ b/embassy-nrf/src/pdm.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::{compiler_fence, Ordering}; | 7 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use embassy_hal_internal::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| @@ -13,7 +13,7 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 13 | use fixed::types::I7F1; | 13 | use fixed::types::I7F1; |
| 14 | 14 | ||
| 15 | use crate::chip::EASY_DMA_SIZE; | 15 | use crate::chip::EASY_DMA_SIZE; |
| 16 | use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin, DISCONNECTED}; | 16 | use crate::gpio::{AnyPin, DISCONNECTED, Pin as GpioPin, SealedPin}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::gpio::vals as gpiovals; | 18 | use crate::pac::gpio::vals as gpiovals; |
| 19 | use crate::pac::pdm::vals; | 19 | use crate::pac::pdm::vals; |
| @@ -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/ppi/dppi.rs b/embassy-nrf/src/ppi/dppi.rs index 078d2fd1c..168647be3 100644 --- a/embassy-nrf/src/ppi/dppi.rs +++ b/embassy-nrf/src/ppi/dppi.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{pac, Peri}; | 2 | use crate::{Peri, pac}; |
| 3 | 3 | ||
| 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; | 4 | const DPPI_ENABLE_BIT: u32 = 0x8000_0000; |
| 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; | 5 | const DPPI_CHANNEL_MASK: u32 = 0x0000_00FF; |
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs index 2bcf72e9c..f30c2218d 100644 --- a/embassy-nrf/src/ppi/mod.rs +++ b/embassy-nrf/src/ppi/mod.rs | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | use core::marker::PhantomData; | 18 | use core::marker::PhantomData; |
| 19 | use core::ptr::NonNull; | 19 | use core::ptr::NonNull; |
| 20 | 20 | ||
| 21 | use embassy_hal_internal::{impl_peripheral, Peri, PeripheralType}; | 21 | use embassy_hal_internal::{Peri, PeripheralType, impl_peripheral}; |
| 22 | 22 | ||
| 23 | use crate::pac::common::{Reg, RW, W}; | 23 | use crate::pac::common::{RW, Reg, W}; |
| 24 | use crate::peripherals; | 24 | use crate::peripherals; |
| 25 | 25 | ||
| 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] | 26 | #[cfg_attr(feature = "_dppi", path = "dppi.rs")] |
diff --git a/embassy-nrf/src/ppi/ppi.rs b/embassy-nrf/src/ppi/ppi.rs index 531c25444..18bc8b8db 100644 --- a/embassy-nrf/src/ppi/ppi.rs +++ b/embassy-nrf/src/ppi/ppi.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; | 1 | use super::{Channel, ConfigurableChannel, Event, Ppi, Task}; |
| 2 | use crate::{pac, Peri}; | 2 | use crate::{Peri, pac}; |
| 3 | 3 | ||
| 4 | impl<'d> Task<'d> { | 4 | impl<'d> Task<'d> { |
| 5 | fn reg_val(&self) -> u32 { | 5 | fn reg_val(&self) -> u32 { |
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index d6b40b5c0..e038f44b8 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -2,11 +2,11 @@ | |||
| 2 | 2 | ||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 6 | 6 | ||
| 7 | use embassy_hal_internal::{Peri, PeripheralType}; | 7 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 8 | 8 | ||
| 9 | use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; | 9 | use crate::gpio::{AnyPin, DISCONNECTED, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; |
| 10 | use crate::pac::gpio::vals as gpiovals; | 10 | use crate::pac::gpio::vals as gpiovals; |
| 11 | use crate::pac::pwm::vals; | 11 | use crate::pac::pwm::vals; |
| 12 | use crate::ppi::{Event, Task}; | 12 | use crate::ppi::{Event, Task}; |
| @@ -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..6bb7c033e 100755 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.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::{Future, poll_fn}; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::ptr; | 7 | use core::ptr; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| @@ -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 | ||
| @@ -604,14 +599,14 @@ impl<'d, T: Instance> NorFlash for Qspi<'d, T> { | |||
| 604 | } | 599 | } |
| 605 | 600 | ||
| 606 | #[cfg(feature = "qspi-multiwrite-flash")] | 601 | #[cfg(feature = "qspi-multiwrite-flash")] |
| 607 | impl<'d, T: Instance> embedded_storage::nor_flash::MultiwriteNorFlash for Qspi<'d, T> {} | 602 | impl<'d> embedded_storage::nor_flash::MultiwriteNorFlash for Qspi<'d> {} |
| 608 | 603 | ||
| 609 | mod _eh1 { | 604 | mod _eh1 { |
| 610 | use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash}; | 605 | use embedded_storage_async::nor_flash::{NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash}; |
| 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 |
| @@ -639,7 +634,7 @@ mod _eh1 { | |||
| 639 | } | 634 | } |
| 640 | 635 | ||
| 641 | #[cfg(feature = "qspi-multiwrite-flash")] | 636 | #[cfg(feature = "qspi-multiwrite-flash")] |
| 642 | impl<'d, T: Instance> embedded_storage_async::nor_flash::MultiwriteNorFlash for Qspi<'d, T> {} | 637 | impl<'d> embedded_storage_async::nor_flash::MultiwriteNorFlash for Qspi<'d> {} |
| 643 | } | 638 | } |
| 644 | 639 | ||
| 645 | /// Peripheral static state | 640 | /// Peripheral static state |
diff --git a/embassy-nrf/src/radio/ieee802154.rs b/embassy-nrf/src/radio/ieee802154.rs index 7f4f8f462..54b463343 100644 --- a/embassy-nrf/src/radio/ieee802154.rs +++ b/embassy-nrf/src/radio/ieee802154.rs | |||
| @@ -1,16 +1,18 @@ | |||
| 1 | //! IEEE 802.15.4 radio driver | 1 | //! IEEE 802.15.4 radio driver |
| 2 | 2 | ||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::marker::PhantomData; |
| 4 | use core::sync::atomic::{Ordering, compiler_fence}; | ||
| 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}; |
| 10 | use crate::Peri; | ||
| 9 | use crate::interrupt::typelevel::Interrupt; | 11 | use crate::interrupt::typelevel::Interrupt; |
| 10 | use crate::interrupt::{self}; | 12 | use crate::interrupt::{self}; |
| 11 | use crate::pac::radio::vals; | 13 | use crate::pac::radio::vals; |
| 12 | pub use crate::pac::radio::vals::State as RadioState; | 14 | pub use crate::pac::radio::vals::State as RadioState; |
| 13 | use crate::Peri; | 15 | use crate::radio::Instance; |
| 14 | 16 | ||
| 15 | /// Default (IEEE compliant) Start of Frame Delimiter | 17 | /// Default (IEEE compliant) Start of Frame Delimiter |
| 16 | pub const DEFAULT_SFD: u8 = 0xA7; | 18 | pub const DEFAULT_SFD: u8 = 0xA7; |
| @@ -32,22 +34,25 @@ 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)); |
| 50 | r.power().write(|w| w.set_power(true)); | 54 | r.power().write(|w| w.set_power(true)); |
| 55 | errata::post_power(); | ||
| 51 | 56 | ||
| 52 | // Enable 802.15.4 mode | 57 | // Enable 802.15.4 mode |
| 53 | r.mode().write(|w| w.set_mode(vals::Mode::IEEE802154_250KBIT)); | 58 | r.mode().write(|w| w.set_mode(vals::Mode::IEEE802154_250KBIT)); |
| @@ -89,12 +94,14 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 89 | }); | 94 | }); |
| 90 | 95 | ||
| 91 | // Enable NVIC interrupt | 96 | // Enable NVIC interrupt |
| 92 | T::Interrupt::unpend(); | 97 | crate::interrupt::typelevel::RADIO::unpend(); |
| 93 | unsafe { T::Interrupt::enable() }; | 98 | unsafe { crate::interrupt::typelevel::RADIO::enable() }; |
| 94 | 99 | ||
| 95 | let mut radio = Self { | 100 | let mut radio = Self { |
| 96 | _p: radio, | 101 | r: crate::pac::RADIO, |
| 102 | state: T::state(), | ||
| 97 | needs_enable: false, | 103 | needs_enable: false, |
| 104 | phantom: PhantomData, | ||
| 98 | }; | 105 | }; |
| 99 | 106 | ||
| 100 | radio.set_sfd(DEFAULT_SFD); | 107 | radio.set_sfd(DEFAULT_SFD); |
| @@ -107,7 +114,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 107 | 114 | ||
| 108 | /// Changes the radio channel | 115 | /// Changes the radio channel |
| 109 | pub fn set_channel(&mut self, channel: u8) { | 116 | pub fn set_channel(&mut self, channel: u8) { |
| 110 | let r = T::regs(); | 117 | let r = self.r; |
| 111 | if channel < 11 || channel > 26 { | 118 | if channel < 11 || channel > 26 { |
| 112 | panic!("Bad 802.15.4 channel"); | 119 | panic!("Bad 802.15.4 channel"); |
| 113 | } | 120 | } |
| @@ -121,7 +128,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 121 | 128 | ||
| 122 | /// Changes the Clear Channel Assessment method | 129 | /// Changes the Clear Channel Assessment method |
| 123 | pub fn set_cca(&mut self, cca: Cca) { | 130 | pub fn set_cca(&mut self, cca: Cca) { |
| 124 | let r = T::regs(); | 131 | let r = self.r; |
| 125 | self.needs_enable = true; | 132 | self.needs_enable = true; |
| 126 | match cca { | 133 | match cca { |
| 127 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), | 134 | Cca::CarrierSense => r.ccactrl().write(|w| w.set_ccamode(vals::Ccamode::CARRIER_MODE)), |
| @@ -138,19 +145,19 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 138 | 145 | ||
| 139 | /// Changes the Start of Frame Delimiter (SFD) | 146 | /// Changes the Start of Frame Delimiter (SFD) |
| 140 | pub fn set_sfd(&mut self, sfd: u8) { | 147 | pub fn set_sfd(&mut self, sfd: u8) { |
| 141 | let r = T::regs(); | 148 | let r = self.r; |
| 142 | r.sfd().write(|w| w.set_sfd(sfd)); | 149 | r.sfd().write(|w| w.set_sfd(sfd)); |
| 143 | } | 150 | } |
| 144 | 151 | ||
| 145 | /// Clear interrupts | 152 | /// Clear interrupts |
| 146 | pub fn clear_all_interrupts(&mut self) { | 153 | pub fn clear_all_interrupts(&mut self) { |
| 147 | let r = T::regs(); | 154 | let r = self.r; |
| 148 | r.intenclr().write(|w| w.0 = 0xffff_ffff); | 155 | r.intenclr().write(|w| w.0 = 0xffff_ffff); |
| 149 | } | 156 | } |
| 150 | 157 | ||
| 151 | /// Changes the radio transmission power | 158 | /// Changes the radio transmission power |
| 152 | pub fn set_transmission_power(&mut self, power: i8) { | 159 | pub fn set_transmission_power(&mut self, power: i8) { |
| 153 | let r = T::regs(); | 160 | let r = self.r; |
| 154 | self.needs_enable = true; | 161 | self.needs_enable = true; |
| 155 | 162 | ||
| 156 | let tx_power: TxPower = match power { | 163 | let tx_power: TxPower = match power { |
| @@ -201,12 +208,12 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 201 | 208 | ||
| 202 | /// Get the current radio state | 209 | /// Get the current radio state |
| 203 | fn state(&self) -> RadioState { | 210 | fn state(&self) -> RadioState { |
| 204 | T::regs().state().read().state() | 211 | self.r.state().read().state() |
| 205 | } | 212 | } |
| 206 | 213 | ||
| 207 | /// Moves the radio from any state to the DISABLED state | 214 | /// Moves the radio from any state to the DISABLED state |
| 208 | fn disable(&mut self) { | 215 | fn disable(&mut self) { |
| 209 | let r = T::regs(); | 216 | let r = self.r; |
| 210 | // See figure 110 in nRF52840-PS | 217 | // See figure 110 in nRF52840-PS |
| 211 | loop { | 218 | loop { |
| 212 | match self.state() { | 219 | match self.state() { |
| @@ -238,15 +245,15 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 238 | } | 245 | } |
| 239 | 246 | ||
| 240 | fn set_buffer(&mut self, buffer: &[u8]) { | 247 | fn set_buffer(&mut self, buffer: &[u8]) { |
| 241 | let r = T::regs(); | 248 | let r = self.r; |
| 242 | r.packetptr().write_value(buffer.as_ptr() as u32); | 249 | r.packetptr().write_value(buffer.as_ptr() as u32); |
| 243 | } | 250 | } |
| 244 | 251 | ||
| 245 | /// Moves the radio to the RXIDLE state | 252 | /// Moves the radio to the RXIDLE state |
| 246 | fn receive_prepare(&mut self) { | 253 | fn receive_prepare(&mut self) { |
| 247 | // clear related events | 254 | // clear related events |
| 248 | T::regs().events_ccabusy().write_value(0); | 255 | self.r.events_ccabusy().write_value(0); |
| 249 | T::regs().events_phyend().write_value(0); | 256 | self.r.events_phyend().write_value(0); |
| 250 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE | 257 | // NOTE to avoid errata 204 (see rev1 v1.4) we do TX_IDLE -> DISABLED -> RXIDLE |
| 251 | let disable = match self.state() { | 258 | let disable = match self.state() { |
| 252 | RadioState::DISABLED => false, | 259 | RadioState::DISABLED => false, |
| @@ -263,7 +270,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 263 | fn receive_start(&mut self, packet: &mut Packet) { | 270 | 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 | 271 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 265 | // allocated in RAM | 272 | // allocated in RAM |
| 266 | let r = T::regs(); | 273 | let r = self.r; |
| 267 | 274 | ||
| 268 | self.receive_prepare(); | 275 | self.receive_prepare(); |
| 269 | 276 | ||
| @@ -290,7 +297,7 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 290 | 297 | ||
| 291 | /// Cancel receiving packet | 298 | /// Cancel receiving packet |
| 292 | fn receive_cancel() { | 299 | fn receive_cancel() { |
| 293 | let r = T::regs(); | 300 | let r = crate::pac::RADIO; |
| 294 | r.shorts().write(|_| {}); | 301 | r.shorts().write(|_| {}); |
| 295 | r.tasks_stop().write_value(1); | 302 | r.tasks_stop().write_value(1); |
| 296 | loop { | 303 | loop { |
| @@ -309,8 +316,8 @@ impl<'d, T: Instance> Radio<'d, T> { | |||
| 309 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` | 316 | /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` |
| 310 | /// will be updated with the received packet's data | 317 | /// will be updated with the received packet's data |
| 311 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { | 318 | pub async fn receive(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 312 | let s = T::state(); | 319 | let s = self.state; |
| 313 | let r = T::regs(); | 320 | let r = self.r; |
| 314 | 321 | ||
| 315 | // Start the read | 322 | // Start the read |
| 316 | self.receive_start(packet); | 323 | self.receive_start(packet); |
| @@ -356,8 +363,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 | 363 | // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's |
| 357 | // allocated in RAM | 364 | // allocated in RAM |
| 358 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { | 365 | pub async fn try_send(&mut self, packet: &mut Packet) -> Result<(), Error> { |
| 359 | let s = T::state(); | 366 | let s = self.state; |
| 360 | let r = T::regs(); | 367 | let r = self.r; |
| 361 | 368 | ||
| 362 | // enable radio to perform cca | 369 | // enable radio to perform cca |
| 363 | self.receive_prepare(); | 370 | self.receive_prepare(); |
| @@ -535,3 +542,19 @@ fn dma_start_fence() { | |||
| 535 | fn dma_end_fence() { | 542 | fn dma_end_fence() { |
| 536 | compiler_fence(Ordering::Acquire); | 543 | compiler_fence(Ordering::Acquire); |
| 537 | } | 544 | } |
| 545 | |||
| 546 | mod errata { | ||
| 547 | pub fn post_power() { | ||
| 548 | // Workaround for anomaly 158 | ||
| 549 | #[cfg(feature = "_nrf5340-net")] | ||
| 550 | for i in 0..32 { | ||
| 551 | let info = crate::pac::FICR.trimcnf(i); | ||
| 552 | let addr = info.addr().read(); | ||
| 553 | if addr & 0xFFFF_F000 == crate::pac::RADIO.as_ptr() as u32 { | ||
| 554 | unsafe { | ||
| 555 | (addr as *mut u32).write_volatile(info.data().read()); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | } | ||
| 559 | } | ||
| 560 | } | ||
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/rramc.rs b/embassy-nrf/src/rramc.rs index 7cb5660cb..521ac4ee7 100644 --- a/embassy-nrf/src/rramc.rs +++ b/embassy-nrf/src/rramc.rs | |||
| @@ -7,7 +7,7 @@ use embedded_storage::nor_flash::{ | |||
| 7 | }; | 7 | }; |
| 8 | 8 | ||
| 9 | use crate::peripherals::RRAMC; | 9 | use crate::peripherals::RRAMC; |
| 10 | use crate::{pac, Peri}; | 10 | use crate::{Peri, pac}; |
| 11 | 11 | ||
| 12 | // | 12 | // |
| 13 | // Export Nvmc alias and page size for downstream compatibility | 13 | // Export Nvmc alias and page size for downstream compatibility |
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/saadc.rs b/embassy-nrf/src/saadc.rs index 92b6fb01f..a199c1c4d 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -4,11 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::{compiler_fence, Ordering}; | 7 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 8 | use core::task::Poll; | 8 | use core::task::Poll; |
| 9 | 9 | ||
| 10 | use embassy_hal_internal::drop::OnDrop; | 10 | use embassy_hal_internal::drop::OnDrop; |
| 11 | use embassy_hal_internal::{impl_peripheral, Peri}; | 11 | use embassy_hal_internal::{Peri, impl_peripheral}; |
| 12 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| 13 | pub(crate) use vals::Psel as InputChannel; | 13 | pub(crate) use vals::Psel as InputChannel; |
| 14 | 14 | ||
| @@ -457,6 +457,19 @@ impl<'d> Saadc<'d, 1> { | |||
| 457 | 457 | ||
| 458 | impl<'d, const N: usize> Drop for Saadc<'d, N> { | 458 | impl<'d, const N: usize> Drop for Saadc<'d, N> { |
| 459 | fn drop(&mut self) { | 459 | fn drop(&mut self) { |
| 460 | // Reset of SAADC. | ||
| 461 | // | ||
| 462 | // This is needed when more than one pin is sampled to avoid needless power consumption. | ||
| 463 | // More information can be found in [nrf52 Anomaly 241](https://docs.nordicsemi.com/bundle/errata_nRF52810_Rev1/page/ERR/nRF52810/Rev1/latest/anomaly_810_241.html). | ||
| 464 | // The workaround seems like it copies the configuration before reset and reapplies it after. | ||
| 465 | // The instance is dropped, forcing a reconfiguration at compile time, hence we only | ||
| 466 | // call what is the reset portion of the workaround. | ||
| 467 | #[cfg(feature = "_nrf52")] | ||
| 468 | { | ||
| 469 | unsafe { core::ptr::write_volatile(0x40007FFC as *mut u32, 0) } | ||
| 470 | unsafe { core::ptr::read_volatile(0x40007FFC as *const ()) } | ||
| 471 | unsafe { core::ptr::write_volatile(0x40007FFC as *mut u32, 1) } | ||
| 472 | } | ||
| 460 | let r = Self::regs(); | 473 | let r = Self::regs(); |
| 461 | r.enable().write(|w| w.set_enable(false)); | 474 | r.enable().write(|w| w.set_enable(false)); |
| 462 | for i in 0..N { | 475 | for i in 0..N { |
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index c410e49fd..ce994dbc9 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -6,17 +6,17 @@ use core::future::poll_fn; | |||
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | #[cfg(feature = "_nrf52832_anomaly_109")] | 7 | #[cfg(feature = "_nrf52832_anomaly_109")] |
| 8 | use core::sync::atomic::AtomicU8; | 8 | use core::sync::atomic::AtomicU8; |
| 9 | use core::sync::atomic::{compiler_fence, Ordering}; | 9 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 10 | use core::task::Poll; | 10 | use core::task::Poll; |
| 11 | 11 | ||
| 12 | use embassy_embedded_hal::SetConfig; | 12 | use embassy_embedded_hal::SetConfig; |
| 13 | use embassy_hal_internal::{Peri, PeripheralType}; | 13 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 14 | use embassy_sync::waitqueue::AtomicWaker; | 14 | use embassy_sync::waitqueue::AtomicWaker; |
| 15 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 15 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; |
| 16 | pub use pac::spim::vals::{Frequency, Order as BitOrder}; | 16 | pub use pac::spim::vals::{Frequency, Order as BitOrder}; |
| 17 | 17 | ||
| 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 18 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 19 | use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _}; | 19 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _, convert_drive}; |
| 20 | use crate::interrupt::typelevel::Interrupt; | 20 | use crate::interrupt::typelevel::Interrupt; |
| 21 | use crate::pac::gpio::vals as gpiovals; | 21 | use crate::pac::gpio::vals as gpiovals; |
| 22 | use crate::pac::spim::vals; | 22 | use crate::pac::spim::vals; |
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 2a3928d25..885821146 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -3,17 +3,17 @@ | |||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | use core::future::poll_fn; | 4 | use core::future::poll_fn; |
| 5 | use core::marker::PhantomData; | 5 | use core::marker::PhantomData; |
| 6 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{Ordering, compiler_fence}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_embedded_hal::SetConfig; | 9 | use embassy_embedded_hal::SetConfig; |
| 10 | use embassy_hal_internal::{Peri, PeripheralType}; | 10 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 11 | use embassy_sync::waitqueue::AtomicWaker; |
| 12 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 12 | pub use embedded_hal_02::spi::{MODE_0, MODE_1, MODE_2, MODE_3, Mode, Phase, Polarity}; |
| 13 | pub use pac::spis::vals::Order as BitOrder; | 13 | pub use pac::spis::vals::Order as BitOrder; |
| 14 | 14 | ||
| 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 15 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 16 | use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, SealedPin as _}; | 16 | use crate::gpio::{self, AnyPin, OutputDrive, Pin as GpioPin, SealedPin as _, convert_drive}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| 18 | use crate::pac::gpio::vals as gpiovals; | 18 | use crate::pac::gpio::vals as gpiovals; |
| 19 | use crate::pac::spis::vals; | 19 | use crate::pac::spis::vals; |
| @@ -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/temp.rs b/embassy-nrf/src/temp.rs index 44be0f6d1..a20e300b7 100644 --- a/embassy-nrf/src/temp.rs +++ b/embassy-nrf/src/temp.rs | |||
| @@ -9,7 +9,7 @@ use fixed::types::I30F2; | |||
| 9 | 9 | ||
| 10 | use crate::interrupt::InterruptExt; | 10 | use crate::interrupt::InterruptExt; |
| 11 | use crate::peripherals::TEMP; | 11 | use crate::peripherals::TEMP; |
| 12 | use crate::{interrupt, pac, Peri}; | 12 | use crate::{Peri, interrupt, pac}; |
| 13 | 13 | ||
| 14 | /// Interrupt handler. | 14 | /// Interrupt handler. |
| 15 | pub struct InterruptHandler { | 15 | pub struct InterruptHandler { |
diff --git a/embassy-nrf/src/time_driver.rs b/embassy-nrf/src/time_driver.rs index 03f4c2e2b..b723e2334 100644 --- a/embassy-nrf/src/time_driver.rs +++ b/embassy-nrf/src/time_driver.rs | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | use core::cell::{Cell, RefCell}; | 1 | use core::cell::{Cell, RefCell}; |
| 2 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | 2 | use core::sync::atomic::{AtomicU32, Ordering, compiler_fence}; |
| 3 | 3 | ||
| 4 | use critical_section::CriticalSection; | 4 | use critical_section::CriticalSection; |
| 5 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 6 | use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; | 5 | use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; |
| 6 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||
| 7 | use embassy_time_driver::Driver; | 7 | use embassy_time_driver::Driver; |
| 8 | use embassy_time_queue_utils::Queue; | 8 | use embassy_time_queue_utils::Queue; |
| 9 | 9 | ||
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..93255c832 100644 --- a/embassy-nrf/src/twim.rs +++ b/embassy-nrf/src/twim.rs | |||
| @@ -2,10 +2,10 @@ | |||
| 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; | ||
| 8 | use core::sync::atomic::Ordering::SeqCst; | 7 | use core::sync::atomic::Ordering::SeqCst; |
| 8 | use core::sync::atomic::compiler_fence; | ||
| 9 | use core::task::Poll; | 9 | use core::task::Poll; |
| 10 | 10 | ||
| 11 | use embassy_embedded_hal::SetConfig; | 11 | use embassy_embedded_hal::SetConfig; |
| @@ -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..2bc0a5c13 100644 --- a/embassy-nrf/src/twis.rs +++ b/embassy-nrf/src/twis.rs | |||
| @@ -2,10 +2,10 @@ | |||
| 2 | 2 | ||
| 3 | #![macro_use] | 3 | #![macro_use] |
| 4 | 4 | ||
| 5 | use core::future::{poll_fn, Future}; | 5 | use core::future::{Future, poll_fn}; |
| 6 | use core::marker::PhantomData; | 6 | use core::marker::PhantomData; |
| 7 | use core::sync::atomic::compiler_fence; | ||
| 8 | use core::sync::atomic::Ordering::SeqCst; | 7 | use core::sync::atomic::Ordering::SeqCst; |
| 8 | use core::sync::atomic::compiler_fence; | ||
| 9 | use core::task::Poll; | 9 | use core::task::Poll; |
| 10 | 10 | ||
| 11 | use embassy_hal_internal::{Peri, PeripheralType}; | 11 | use embassy_hal_internal::{Peri, PeripheralType}; |
| @@ -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..1ee452173 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | use core::future::poll_fn; | 16 | use core::future::poll_fn; |
| 17 | use core::marker::PhantomData; | 17 | use core::marker::PhantomData; |
| 18 | use core::sync::atomic::{compiler_fence, AtomicU8, Ordering}; | 18 | use core::sync::atomic::{AtomicU8, Ordering, compiler_fence}; |
| 19 | use core::task::Poll; | 19 | use core::task::Poll; |
| 20 | 20 | ||
| 21 | use embassy_hal_internal::drop::OnDrop; | 21 | use embassy_hal_internal::drop::OnDrop; |
| @@ -25,7 +25,7 @@ use embassy_sync::waitqueue::AtomicWaker; | |||
| 25 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; | 25 | pub use pac::uarte::vals::{Baudrate, ConfigParity as Parity}; |
| 26 | 26 | ||
| 27 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; | 27 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 28 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits, SealedPin as _, DISCONNECTED}; | 28 | use crate::gpio::{self, AnyPin, DISCONNECTED, Pin as GpioPin, PselBits, SealedPin as _}; |
| 29 | use crate::interrupt::typelevel::Interrupt; | 29 | use crate::interrupt::typelevel::Interrupt; |
| 30 | use crate::pac::gpio::vals as gpiovals; | 30 | use crate::pac::gpio::vals as gpiovals; |
| 31 | use crate::pac::uarte::vals; | 31 | use crate::pac::uarte::vals; |
| @@ -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..07cf2578a 100644 --- a/embassy-nrf/src/usb/mod.rs +++ b/embassy-nrf/src/usb/mod.rs | |||
| @@ -4,10 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | pub mod vbus_detect; | 5 | pub mod vbus_detect; |
| 6 | 6 | ||
| 7 | use core::future::{poll_fn, Future}; | 7 | use core::future::{Future, poll_fn}; |
| 8 | use core::marker::PhantomData; | 8 | use core::marker::PhantomData; |
| 9 | use core::mem::MaybeUninit; | 9 | use core::mem::MaybeUninit; |
| 10 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | 10 | use core::sync::atomic::{AtomicU32, Ordering, compiler_fence}; |
| 11 | use core::task::Poll; | 11 | use core::task::Poll; |
| 12 | 12 | ||
| 13 | use cortex_m::peripheral::NVIC; | 13 | use cortex_m::peripheral::NVIC; |
| @@ -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; |
| @@ -319,11 +330,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 319 | let mut was_enabled = false; | 330 | let mut was_enabled = false; |
| 320 | regs.epinen().modify(|w| { | 331 | regs.epinen().modify(|w| { |
| 321 | was_enabled = (w.0 & mask) != 0; | 332 | was_enabled = (w.0 & mask) != 0; |
| 322 | if enabled { | 333 | if enabled { w.0 |= mask } else { w.0 &= !mask } |
| 323 | w.0 |= mask | ||
| 324 | } else { | ||
| 325 | w.0 &= !mask | ||
| 326 | } | ||
| 327 | }); | 334 | }); |
| 328 | 335 | ||
| 329 | let ready_mask = In::mask(i); | 336 | let ready_mask = In::mask(i); |
| @@ -359,7 +366,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 359 | 366 | ||
| 360 | #[inline] | 367 | #[inline] |
| 361 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { | 368 | async fn remote_wakeup(&mut self) -> Result<(), Unsupported> { |
| 362 | let regs = T::regs(); | 369 | let regs = self.regs; |
| 363 | 370 | ||
| 364 | if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER { | 371 | if regs.lowpower().read().lowpower() == vals::Lowpower::LOW_POWER { |
| 365 | errata::pre_wakeup(); | 372 | errata::pre_wakeup(); |
| @@ -368,7 +375,7 @@ impl<'d, T: Instance, V: VbusDetect> driver::Bus for Bus<'d, T, V> { | |||
| 368 | 375 | ||
| 369 | poll_fn(|cx| { | 376 | poll_fn(|cx| { |
| 370 | BUS_WAKER.register(cx.waker()); | 377 | BUS_WAKER.register(cx.waker()); |
| 371 | let regs = T::regs(); | 378 | let regs = self.regs; |
| 372 | let r = regs.eventcause().read(); | 379 | let r = regs.eventcause().read(); |
| 373 | 380 | ||
| 374 | if regs.events_usbreset().read() != 0 { | 381 | if regs.events_usbreset().read() != 0 { |
| @@ -441,21 +448,23 @@ impl EndpointDir for Out { | |||
| 441 | } | 448 | } |
| 442 | 449 | ||
| 443 | /// USB endpoint. | 450 | /// USB endpoint. |
| 444 | pub struct Endpoint<'d, T: Instance, Dir> { | 451 | pub struct Endpoint<'d, Dir> { |
| 445 | _phantom: PhantomData<(&'d mut T, Dir)>, | 452 | regs: pac::usbd::Usbd, |
| 446 | info: EndpointInfo, | 453 | info: EndpointInfo, |
| 454 | _phantom: PhantomData<(&'d (), Dir)>, | ||
| 447 | } | 455 | } |
| 448 | 456 | ||
| 449 | impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | 457 | impl<'d, Dir> Endpoint<'d, Dir> { |
| 450 | fn new(info: EndpointInfo) -> Self { | 458 | fn new(regs: pac::usbd::Usbd, info: EndpointInfo) -> Self { |
| 451 | Self { | 459 | Self { |
| 460 | regs, | ||
| 452 | info, | 461 | info, |
| 453 | _phantom: PhantomData, | 462 | _phantom: PhantomData, |
| 454 | } | 463 | } |
| 455 | } | 464 | } |
| 456 | } | 465 | } |
| 457 | 466 | ||
| 458 | impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir> { | 467 | impl<'d, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, Dir> { |
| 459 | fn info(&self) -> &EndpointInfo { | 468 | fn info(&self) -> &EndpointInfo { |
| 460 | &self.info | 469 | &self.info |
| 461 | } | 470 | } |
| @@ -466,14 +475,14 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir | |||
| 466 | } | 475 | } |
| 467 | 476 | ||
| 468 | #[allow(private_bounds)] | 477 | #[allow(private_bounds)] |
| 469 | impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> { | 478 | impl<'d, Dir: EndpointDir> Endpoint<'d, Dir> { |
| 470 | fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> { | 479 | fn wait_enabled_state(&mut self, state: bool) -> impl Future<Output = ()> + use<'_, 'd, Dir> { |
| 471 | let i = self.info.addr.index(); | 480 | let i = self.info.addr.index(); |
| 472 | assert!(i != 0); | 481 | assert!(i != 0); |
| 473 | 482 | ||
| 474 | poll_fn(move |cx| { | 483 | poll_fn(move |cx| { |
| 475 | Dir::waker(i).register(cx.waker()); | 484 | Dir::waker(i).register(cx.waker()); |
| 476 | if Dir::is_enabled(T::regs(), i) == state { | 485 | if Dir::is_enabled(self.regs, i) == state { |
| 477 | Poll::Ready(()) | 486 | Poll::Ready(()) |
| 478 | } else { | 487 | } else { |
| 479 | Poll::Pending | 488 | Poll::Pending |
| @@ -482,12 +491,12 @@ impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> { | |||
| 482 | } | 491 | } |
| 483 | 492 | ||
| 484 | /// Wait for the endpoint to be disabled | 493 | /// Wait for the endpoint to be disabled |
| 485 | pub fn wait_disabled(&mut self) -> impl Future<Output = ()> { | 494 | pub fn wait_disabled(&mut self) -> impl Future<Output = ()> + use<'_, 'd, Dir> { |
| 486 | self.wait_enabled_state(false) | 495 | self.wait_enabled_state(false) |
| 487 | } | 496 | } |
| 488 | } | 497 | } |
| 489 | 498 | ||
| 490 | impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | 499 | impl<'d, Dir> Endpoint<'d, Dir> { |
| 491 | async fn wait_data_ready(&mut self) -> Result<(), ()> | 500 | async fn wait_data_ready(&mut self) -> Result<(), ()> |
| 492 | where | 501 | where |
| 493 | Dir: EndpointDir, | 502 | Dir: EndpointDir, |
| @@ -497,7 +506,7 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | |||
| 497 | poll_fn(|cx| { | 506 | poll_fn(|cx| { |
| 498 | Dir::waker(i).register(cx.waker()); | 507 | Dir::waker(i).register(cx.waker()); |
| 499 | let r = READY_ENDPOINTS.load(Ordering::Acquire); | 508 | let r = READY_ENDPOINTS.load(Ordering::Acquire); |
| 500 | if !Dir::is_enabled(T::regs(), i) { | 509 | if !Dir::is_enabled(self.regs, i) { |
| 501 | Poll::Ready(Err(())) | 510 | Poll::Ready(Err(())) |
| 502 | } else if r & Dir::mask(i) != 0 { | 511 | } else if r & Dir::mask(i) != 0 { |
| 503 | Poll::Ready(Ok(())) | 512 | Poll::Ready(Ok(())) |
| @@ -514,9 +523,7 @@ impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> { | |||
| 514 | } | 523 | } |
| 515 | } | 524 | } |
| 516 | 525 | ||
| 517 | unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, EndpointError> { | 526 | 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 | 527 | // Check that the packet fits into the buffer |
| 521 | let size = regs.size().epout(i).read().0 as usize; | 528 | let size = regs.size().epout(i).read().0 as usize; |
| 522 | if size > buf.len() { | 529 | if size > buf.len() { |
| @@ -539,8 +546,7 @@ unsafe fn read_dma<T: Instance>(i: usize, buf: &mut [u8]) -> Result<usize, Endpo | |||
| 539 | Ok(size) | 546 | Ok(size) |
| 540 | } | 547 | } |
| 541 | 548 | ||
| 542 | unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) { | 549 | unsafe fn write_dma(regs: pac::usbd::Usbd, i: usize, buf: &[u8]) { |
| 543 | let regs = T::regs(); | ||
| 544 | assert!(buf.len() <= 64); | 550 | assert!(buf.len() <= 64); |
| 545 | 551 | ||
| 546 | let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit(); | 552 | let mut ram_buf: MaybeUninit<[u8; 64]> = MaybeUninit::uninit(); |
| @@ -566,43 +572,44 @@ unsafe fn write_dma<T: Instance>(i: usize, buf: &[u8]) { | |||
| 566 | dma_end(); | 572 | dma_end(); |
| 567 | } | 573 | } |
| 568 | 574 | ||
| 569 | impl<'d, T: Instance> driver::EndpointOut for Endpoint<'d, T, Out> { | 575 | impl<'d> driver::EndpointOut for Endpoint<'d, Out> { |
| 570 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { | 576 | async fn read(&mut self, buf: &mut [u8]) -> Result<usize, EndpointError> { |
| 571 | let i = self.info.addr.index(); | 577 | let i = self.info.addr.index(); |
| 572 | assert!(i != 0); | 578 | assert!(i != 0); |
| 573 | 579 | ||
| 574 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; | 580 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; |
| 575 | 581 | ||
| 576 | unsafe { read_dma::<T>(i, buf) } | 582 | unsafe { read_dma(self.regs, i, buf) } |
| 577 | } | 583 | } |
| 578 | } | 584 | } |
| 579 | 585 | ||
| 580 | impl<'d, T: Instance> driver::EndpointIn for Endpoint<'d, T, In> { | 586 | impl<'d> driver::EndpointIn for Endpoint<'d, In> { |
| 581 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { | 587 | async fn write(&mut self, buf: &[u8]) -> Result<(), EndpointError> { |
| 582 | let i = self.info.addr.index(); | 588 | let i = self.info.addr.index(); |
| 583 | assert!(i != 0); | 589 | assert!(i != 0); |
| 584 | 590 | ||
| 585 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; | 591 | self.wait_data_ready().await.map_err(|_| EndpointError::Disabled)?; |
| 586 | 592 | ||
| 587 | unsafe { write_dma::<T>(i, buf) } | 593 | unsafe { write_dma(self.regs, i, buf) } |
| 588 | 594 | ||
| 589 | Ok(()) | 595 | Ok(()) |
| 590 | } | 596 | } |
| 591 | } | 597 | } |
| 592 | 598 | ||
| 593 | /// USB control pipe. | 599 | /// USB control pipe. |
| 594 | pub struct ControlPipe<'d, T: Instance> { | 600 | pub struct ControlPipe<'d> { |
| 595 | _p: Peri<'d, T>, | 601 | regs: pac::usbd::Usbd, |
| 596 | max_packet_size: u16, | 602 | max_packet_size: u16, |
| 603 | _phantom: PhantomData<&'d ()>, | ||
| 597 | } | 604 | } |
| 598 | 605 | ||
| 599 | impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | 606 | impl<'d> driver::ControlPipe for ControlPipe<'d> { |
| 600 | fn max_packet_size(&self) -> usize { | 607 | fn max_packet_size(&self) -> usize { |
| 601 | usize::from(self.max_packet_size) | 608 | usize::from(self.max_packet_size) |
| 602 | } | 609 | } |
| 603 | 610 | ||
| 604 | async fn setup(&mut self) -> [u8; 8] { | 611 | async fn setup(&mut self) -> [u8; 8] { |
| 605 | let regs = T::regs(); | 612 | let regs = self.regs; |
| 606 | 613 | ||
| 607 | // Reset shorts | 614 | // Reset shorts |
| 608 | regs.shorts().write(|_| ()); | 615 | regs.shorts().write(|_| ()); |
| @@ -611,7 +618,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 611 | regs.intenset().write(|w| w.set_ep0setup(true)); | 618 | regs.intenset().write(|w| w.set_ep0setup(true)); |
| 612 | poll_fn(|cx| { | 619 | poll_fn(|cx| { |
| 613 | EP0_WAKER.register(cx.waker()); | 620 | EP0_WAKER.register(cx.waker()); |
| 614 | let regs = T::regs(); | 621 | let regs = self.regs; |
| 615 | if regs.events_ep0setup().read() != 0 { | 622 | if regs.events_ep0setup().read() != 0 { |
| 616 | Poll::Ready(()) | 623 | Poll::Ready(()) |
| 617 | } else { | 624 | } else { |
| @@ -636,7 +643,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 636 | } | 643 | } |
| 637 | 644 | ||
| 638 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { | 645 | async fn data_out(&mut self, buf: &mut [u8], _first: bool, _last: bool) -> Result<usize, EndpointError> { |
| 639 | let regs = T::regs(); | 646 | let regs = self.regs; |
| 640 | 647 | ||
| 641 | regs.events_ep0datadone().write_value(0); | 648 | regs.events_ep0datadone().write_value(0); |
| 642 | 649 | ||
| @@ -651,7 +658,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 651 | }); | 658 | }); |
| 652 | poll_fn(|cx| { | 659 | poll_fn(|cx| { |
| 653 | EP0_WAKER.register(cx.waker()); | 660 | EP0_WAKER.register(cx.waker()); |
| 654 | let regs = T::regs(); | 661 | let regs = self.regs; |
| 655 | if regs.events_ep0datadone().read() != 0 { | 662 | if regs.events_ep0datadone().read() != 0 { |
| 656 | Poll::Ready(Ok(())) | 663 | Poll::Ready(Ok(())) |
| 657 | } else if regs.events_usbreset().read() != 0 { | 664 | } else if regs.events_usbreset().read() != 0 { |
| @@ -666,17 +673,17 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 666 | }) | 673 | }) |
| 667 | .await?; | 674 | .await?; |
| 668 | 675 | ||
| 669 | unsafe { read_dma::<T>(0, buf) } | 676 | unsafe { read_dma(self.regs, 0, buf) } |
| 670 | } | 677 | } |
| 671 | 678 | ||
| 672 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { | 679 | async fn data_in(&mut self, buf: &[u8], _first: bool, last: bool) -> Result<(), EndpointError> { |
| 673 | let regs = T::regs(); | 680 | let regs = self.regs; |
| 674 | regs.events_ep0datadone().write_value(0); | 681 | regs.events_ep0datadone().write_value(0); |
| 675 | 682 | ||
| 676 | regs.shorts().write(|w| w.set_ep0datadone_ep0status(last)); | 683 | regs.shorts().write(|w| w.set_ep0datadone_ep0status(last)); |
| 677 | 684 | ||
| 678 | // This starts a TX on EP0. events_ep0datadone notifies when done. | 685 | // This starts a TX on EP0. events_ep0datadone notifies when done. |
| 679 | unsafe { write_dma::<T>(0, buf) } | 686 | unsafe { write_dma(self.regs, 0, buf) } |
| 680 | 687 | ||
| 681 | regs.intenset().write(|w| { | 688 | regs.intenset().write(|w| { |
| 682 | w.set_usbreset(true); | 689 | w.set_usbreset(true); |
| @@ -687,7 +694,7 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 687 | poll_fn(|cx| { | 694 | poll_fn(|cx| { |
| 688 | cx.waker().wake_by_ref(); | 695 | cx.waker().wake_by_ref(); |
| 689 | EP0_WAKER.register(cx.waker()); | 696 | EP0_WAKER.register(cx.waker()); |
| 690 | let regs = T::regs(); | 697 | let regs = self.regs; |
| 691 | if regs.events_ep0datadone().read() != 0 { | 698 | if regs.events_ep0datadone().read() != 0 { |
| 692 | Poll::Ready(Ok(())) | 699 | Poll::Ready(Ok(())) |
| 693 | } else if regs.events_usbreset().read() != 0 { | 700 | } else if regs.events_usbreset().read() != 0 { |
| @@ -704,12 +711,12 @@ impl<'d, T: Instance> driver::ControlPipe for ControlPipe<'d, T> { | |||
| 704 | } | 711 | } |
| 705 | 712 | ||
| 706 | async fn accept(&mut self) { | 713 | async fn accept(&mut self) { |
| 707 | let regs = T::regs(); | 714 | let regs = self.regs; |
| 708 | regs.tasks_ep0status().write_value(1); | 715 | regs.tasks_ep0status().write_value(1); |
| 709 | } | 716 | } |
| 710 | 717 | ||
| 711 | async fn reject(&mut self) { | 718 | async fn reject(&mut self) { |
| 712 | let regs = T::regs(); | 719 | let regs = self.regs; |
| 713 | regs.tasks_ep0stall().write_value(1); | 720 | regs.tasks_ep0stall().write_value(1); |
| 714 | } | 721 | } |
| 715 | 722 | ||
diff --git a/embassy-nrf/src/usb/vbus_detect.rs b/embassy-nrf/src/usb/vbus_detect.rs index 33cf91ee2..f24a7bff5 100644 --- a/embassy-nrf/src/usb/vbus_detect.rs +++ b/embassy-nrf/src/usb/vbus_detect.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | //! Trait and implementations for performing VBUS detection. | 1 | //! Trait and implementations for performing VBUS detection. |
| 2 | 2 | ||
| 3 | use core::future::{poll_fn, Future}; | 3 | use core::future::{Future, poll_fn}; |
| 4 | use core::sync::atomic::{AtomicBool, Ordering}; | 4 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 5 | use core::task::Poll; | 5 | use core::task::Poll; |
| 6 | 6 | ||
diff --git a/embassy-nrf/src/util.rs b/embassy-nrf/src/util.rs index 78f71719f..87118d347 100644 --- a/embassy-nrf/src/util.rs +++ b/embassy-nrf/src/util.rs | |||
| @@ -15,9 +15,5 @@ pub(crate) fn slice_in_ram<T>(slice: *const [T]) -> bool { | |||
| 15 | 15 | ||
| 16 | /// Return an error if slice is not in RAM. Skips check if slice is zero-length. | 16 | /// Return an error if slice is not in RAM. Skips check if slice is zero-length. |
| 17 | pub(crate) fn slice_in_ram_or<T, E>(slice: *const [T], err: E) -> Result<(), E> { | 17 | pub(crate) fn slice_in_ram_or<T, E>(slice: *const [T], err: E) -> Result<(), E> { |
| 18 | if slice_in_ram(slice) { | 18 | if slice_in_ram(slice) { Ok(()) } else { Err(err) } |
| 19 | Ok(()) | ||
| 20 | } else { | ||
| 21 | Err(err) | ||
| 22 | } | ||
| 23 | } | 19 | } |
diff --git a/embassy-nrf/src/wdt.rs b/embassy-nrf/src/wdt.rs index 7ab9adc29..6afd73431 100644 --- a/embassy-nrf/src/wdt.rs +++ b/embassy-nrf/src/wdt.rs | |||
| @@ -11,7 +11,7 @@ use embassy_hal_internal::PeripheralType; | |||
| 11 | 11 | ||
| 12 | use crate::pac::wdt::vals; | 12 | use crate::pac::wdt::vals; |
| 13 | pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; | 13 | pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig}; |
| 14 | use crate::{interrupt, pac, peripherals, Peri}; | 14 | use crate::{Peri, interrupt, pac, peripherals}; |
| 15 | 15 | ||
| 16 | const MIN_TICKS: u32 = 15; | 16 | const MIN_TICKS: u32 = 15; |
| 17 | 17 | ||
| @@ -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 | } |
