for Interrupt
// If not TXing, start.
if s.tx_count.load(Ordering::Relaxed) == 0 {
let (ptr, len) = tx.pop_buf();
+ let len = len.min(EASY_DMA_SIZE);
if len != 0 {
//trace!(" irq_tx: starting {:?}", len);
s.tx_count.store(len, Ordering::Relaxed);
@@ -311,6 +305,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
let tx = BufferedUarteTx::new_innerer(unsafe { peri.clone_unchecked() }, txd, cts, tx_buffer);
let rx = BufferedUarteRx::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
+ U::regs().enable.write(|w| w.enable().enabled());
U::Interrupt::pend();
unsafe { U::Interrupt::enable() };
@@ -412,6 +407,7 @@ impl<'d, U: UarteInstance> BufferedUarteTx<'d, U> {
let this = Self::new_innerer(peri, txd, cts, tx_buffer);
+ U::regs().enable.write(|w| w.enable().enabled());
U::Interrupt::pend();
unsafe { U::Interrupt::enable() };
@@ -609,6 +605,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
let this = Self::new_innerer(peri, timer, ppi_ch1, ppi_ch2, ppi_group, rxd, rts, rx_buffer);
+ U::regs().enable.write(|w| w.enable().enabled());
U::Interrupt::pend();
unsafe { U::Interrupt::enable() };
@@ -645,8 +642,8 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
s.rx_started_count.store(0, Ordering::Relaxed);
s.rx_ended_count.store(0, Ordering::Relaxed);
s.rx_started.store(false, Ordering::Relaxed);
- let len = rx_buffer.len();
- unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
+ let rx_len = rx_buffer.len().min(EASY_DMA_SIZE * 2);
+ unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), rx_len) };
// clear errors
let errors = r.errorsrc.read().bits();
@@ -667,7 +664,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarteRx<'d, U, T> {
// Configure byte counter.
let timer = Timer::new_counter(timer);
- timer.cc(1).write(rx_buffer.len() as u32 * 2);
+ timer.cc(1).write(rx_len as u32 * 2);
timer.cc(1).short_compare_clear();
timer.clear();
timer.start();
diff --git a/embassy-nrf/src/chips/nrf52805.rs b/embassy-nrf/src/chips/nrf52805.rs
index 14c3f9b1a..b51b0c93e 100644
--- a/embassy-nrf/src/chips/nrf52805.rs
+++ b/embassy-nrf/src/chips/nrf52805.rs
@@ -132,6 +132,10 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -214,6 +218,9 @@ impl_saadc_input!(P0_05, ANALOG_INPUT3);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52810.rs b/embassy-nrf/src/chips/nrf52810.rs
index c607586db..273098d9b 100644
--- a/embassy-nrf/src/chips/nrf52810.rs
+++ b/embassy-nrf/src/chips/nrf52810.rs
@@ -138,6 +138,10 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -240,6 +244,9 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52811.rs b/embassy-nrf/src/chips/nrf52811.rs
index 5f70365b4..9bce38636 100644
--- a/embassy-nrf/src/chips/nrf52811.rs
+++ b/embassy-nrf/src/chips/nrf52811.rs
@@ -138,6 +138,10 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -242,6 +246,9 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52820.rs b/embassy-nrf/src/chips/nrf52820.rs
index 82d097407..2acae2c8f 100644
--- a/embassy-nrf/src/chips/nrf52820.rs
+++ b/embassy-nrf/src/chips/nrf52820.rs
@@ -133,6 +133,14 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_usb!(USBD, USBD, USBD);
@@ -229,6 +237,13 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+impl_egu!(EGU2, EGU2, SWI2_EGU2);
+impl_egu!(EGU3, EGU3, SWI3_EGU3);
+impl_egu!(EGU4, EGU4, SWI4_EGU4);
+impl_egu!(EGU5, EGU5, SWI5_EGU5);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52832.rs b/embassy-nrf/src/chips/nrf52832.rs
index 67b32fe5f..94b373ab3 100644
--- a/embassy-nrf/src/chips/nrf52832.rs
+++ b/embassy-nrf/src/chips/nrf52832.rs
@@ -153,6 +153,14 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_uarte!(UARTE0, UARTE0, UARTE0_UART0);
@@ -269,6 +277,13 @@ impl_i2s!(I2S, I2S, I2S);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+impl_egu!(EGU2, EGU2, SWI2_EGU2);
+impl_egu!(EGU3, EGU3, SWI3_EGU3);
+impl_egu!(EGU4, EGU4, SWI4_EGU4);
+impl_egu!(EGU5, EGU5, SWI5_EGU5);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52833.rs b/embassy-nrf/src/chips/nrf52833.rs
index 20f14e2d6..09cde1ac1 100644
--- a/embassy-nrf/src/chips/nrf52833.rs
+++ b/embassy-nrf/src/chips/nrf52833.rs
@@ -173,6 +173,14 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_usb!(USBD, USBD, USBD);
@@ -311,6 +319,13 @@ impl_i2s!(I2S, I2S, I2S);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+impl_egu!(EGU2, EGU2, SWI2_EGU2);
+impl_egu!(EGU3, EGU3, SWI3_EGU3);
+impl_egu!(EGU4, EGU4, SWI4_EGU4);
+impl_egu!(EGU5, EGU5, SWI5_EGU5);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf52840.rs b/embassy-nrf/src/chips/nrf52840.rs
index d3272b2e8..0f3d1b250 100644
--- a/embassy-nrf/src/chips/nrf52840.rs
+++ b/embassy-nrf/src/chips/nrf52840.rs
@@ -176,6 +176,14 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_usb!(USBD, USBD, USBD);
@@ -316,6 +324,13 @@ impl_i2s!(I2S, I2S, I2S);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, SWI0_EGU0);
+impl_egu!(EGU1, EGU1, SWI1_EGU1);
+impl_egu!(EGU2, EGU2, SWI2_EGU2);
+impl_egu!(EGU3, EGU3, SWI3_EGU3);
+impl_egu!(EGU4, EGU4, SWI4_EGU4);
+impl_egu!(EGU5, EGU5, SWI5_EGU5);
+
embassy_hal_internal::interrupt_mod!(
POWER_CLOCK,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf5340_app.rs b/embassy-nrf/src/chips/nrf5340_app.rs
index 62c74bb6f..584f6e43c 100644
--- a/embassy-nrf/src/chips/nrf5340_app.rs
+++ b/embassy-nrf/src/chips/nrf5340_app.rs
@@ -380,6 +380,14 @@ embassy_hal_internal::peripherals! {
P1_13,
P1_14,
P1_15,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_usb!(USBD, USBD, USBD);
@@ -519,6 +527,13 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
impl_saadc_input!(P0_19, ANALOG_INPUT6);
impl_saadc_input!(P0_20, ANALOG_INPUT7);
+impl_egu!(EGU0, EGU0, EGU0);
+impl_egu!(EGU1, EGU1, EGU1);
+impl_egu!(EGU2, EGU2, EGU2);
+impl_egu!(EGU3, EGU3, EGU3);
+impl_egu!(EGU4, EGU4, EGU4);
+impl_egu!(EGU5, EGU5, EGU5);
+
embassy_hal_internal::interrupt_mod!(
FPU,
CACHE,
diff --git a/embassy-nrf/src/chips/nrf5340_net.rs b/embassy-nrf/src/chips/nrf5340_net.rs
index 65e8f9653..d772c9a49 100644
--- a/embassy-nrf/src/chips/nrf5340_net.rs
+++ b/embassy-nrf/src/chips/nrf5340_net.rs
@@ -251,6 +251,9 @@ embassy_hal_internal::peripherals! {
// Radio
RADIO,
+
+ // EGU
+ EGU0,
}
impl_uarte!(SERIAL0, UARTE0, SERIAL0);
@@ -350,6 +353,8 @@ impl_ppi_channel!(PPI_CH31, 31 => configurable);
impl_radio!(RADIO, RADIO, RADIO);
+impl_egu!(EGU0, EGU0, EGU0);
+
embassy_hal_internal::interrupt_mod!(
CLOCK_POWER,
RADIO,
diff --git a/embassy-nrf/src/chips/nrf9160.rs b/embassy-nrf/src/chips/nrf9160.rs
index 8b1356ef8..8107ca175 100644
--- a/embassy-nrf/src/chips/nrf9160.rs
+++ b/embassy-nrf/src/chips/nrf9160.rs
@@ -283,6 +283,14 @@ embassy_hal_internal::peripherals! {
// PDM
PDM,
+
+ // EGU
+ EGU0,
+ EGU1,
+ EGU2,
+ EGU3,
+ EGU4,
+ EGU5,
}
impl_uarte!(SERIAL0, UARTE0, UARTE0_SPIM0_SPIS0_TWIM0_TWIS0);
@@ -380,6 +388,13 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
impl_saadc_input!(P0_19, ANALOG_INPUT6);
impl_saadc_input!(P0_20, ANALOG_INPUT7);
+impl_egu!(EGU0, EGU0, EGU0);
+impl_egu!(EGU1, EGU1, EGU1);
+impl_egu!(EGU2, EGU2, EGU2);
+impl_egu!(EGU3, EGU3, EGU3);
+impl_egu!(EGU4, EGU4, EGU4);
+impl_egu!(EGU5, EGU5, EGU5);
+
embassy_hal_internal::interrupt_mod!(
SPU,
CLOCK_POWER,
diff --git a/embassy-nrf/src/egu.rs b/embassy-nrf/src/egu.rs
new file mode 100644
index 000000000..204446d29
--- /dev/null
+++ b/embassy-nrf/src/egu.rs
@@ -0,0 +1,121 @@
+//! EGU driver.
+//!
+//! The event generator driver provides a higher level API for task triggering
+//! and events to use with PPI.
+
+#![macro_use]
+
+use core::marker::PhantomData;
+
+use embassy_hal_internal::into_ref;
+
+use crate::ppi::{Event, Task};
+use crate::{interrupt, pac, Peripheral, PeripheralRef};
+
+/// An instance of the EGU.
+pub struct Egu<'d, T: Instance> {
+ _p: PeripheralRef<'d, T>,
+}
+
+impl<'d, T: Instance> Egu<'d, T> {
+ /// Create a new EGU instance.
+ pub fn new(_p: impl Peripheral + 'd) -> Self {
+ into_ref!(_p);
+ Self { _p }
+ }
+
+ /// Get a handle to a trigger for the EGU.
+ pub fn trigger(&mut self, number: TriggerNumber) -> Trigger<'d, T> {
+ Trigger {
+ number,
+ _p: PhantomData,
+ }
+ }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::egu0::RegisterBlock;
+}
+
+/// Basic Egu instance.
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
+ /// Interrupt for this peripheral.
+ type Interrupt: interrupt::typelevel::Interrupt;
+}
+
+macro_rules! impl_egu {
+ ($type:ident, $pac_type:ident, $irq:ident) => {
+ impl crate::egu::SealedInstance for peripherals::$type {
+ fn regs() -> &'static pac::egu0::RegisterBlock {
+ unsafe { &*pac::$pac_type::ptr() }
+ }
+ }
+ impl crate::egu::Instance for peripherals::$type {
+ type Interrupt = crate::interrupt::typelevel::$irq;
+ }
+ };
+}
+
+/// Represents a trigger within the EGU.
+pub struct Trigger<'d, T: Instance> {
+ number: TriggerNumber,
+ _p: PhantomData<&'d T>,
+}
+
+impl<'d, T: Instance> Trigger<'d, T> {
+ /// Get task for this trigger to use with PPI.
+ pub fn task(&self) -> Task<'d> {
+ let nr = self.number as usize;
+ let regs = T::regs();
+ Task::from_reg(®s.tasks_trigger[nr])
+ }
+
+ /// Get event for this trigger to use with PPI.
+ pub fn event(&self) -> Event<'d> {
+ let nr = self.number as usize;
+ let regs = T::regs();
+ Event::from_reg(®s.events_triggered[nr])
+ }
+
+ /// Enable interrupts for this trigger
+ pub fn enable_interrupt(&mut self) {
+ let regs = T::regs();
+ unsafe {
+ regs.intenset
+ .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize)))
+ };
+ }
+
+ /// Enable interrupts for this trigger
+ pub fn disable_interrupt(&mut self) {
+ let regs = T::regs();
+ unsafe {
+ regs.intenclr
+ .modify(|r, w| w.bits(r.bits() | (1 << self.number as usize)))
+ };
+ }
+}
+
+/// Represents a trigger within an EGU.
+#[allow(missing_docs)]
+#[derive(Clone, Copy, PartialEq)]
+#[repr(u8)]
+pub enum TriggerNumber {
+ Trigger0 = 0,
+ Trigger1 = 1,
+ Trigger2 = 2,
+ Trigger3 = 3,
+ Trigger4 = 4,
+ Trigger5 = 5,
+ Trigger6 = 6,
+ Trigger7 = 7,
+ Trigger8 = 8,
+ Trigger9 = 9,
+ Trigger10 = 10,
+ Trigger11 = 11,
+ Trigger12 = 12,
+ Trigger13 = 13,
+ Trigger14 = 14,
+ Trigger15 = 15,
+}
diff --git a/embassy-nrf/src/fmt.rs b/embassy-nrf/src/fmt.rs
index 2ac42c557..35b929fde 100644
--- a/embassy-nrf/src/fmt.rs
+++ b/embassy-nrf/src/fmt.rs
@@ -6,6 +6,7 @@ use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
+#[collapse_debuginfo(yes)]
macro_rules! assert {
($($x:tt)*) => {
{
@@ -17,6 +18,7 @@ macro_rules! assert {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! assert_eq {
($($x:tt)*) => {
{
@@ -28,6 +30,7 @@ macro_rules! assert_eq {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! assert_ne {
($($x:tt)*) => {
{
@@ -39,6 +42,7 @@ macro_rules! assert_ne {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert {
($($x:tt)*) => {
{
@@ -50,6 +54,7 @@ macro_rules! debug_assert {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert_eq {
($($x:tt)*) => {
{
@@ -61,6 +66,7 @@ macro_rules! debug_assert_eq {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert_ne {
($($x:tt)*) => {
{
@@ -72,6 +78,7 @@ macro_rules! debug_assert_ne {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! todo {
($($x:tt)*) => {
{
@@ -84,6 +91,7 @@ macro_rules! todo {
}
#[cfg(not(feature = "defmt"))]
+#[collapse_debuginfo(yes)]
macro_rules! unreachable {
($($x:tt)*) => {
::core::unreachable!($($x)*)
@@ -91,12 +99,14 @@ macro_rules! unreachable {
}
#[cfg(feature = "defmt")]
+#[collapse_debuginfo(yes)]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
+#[collapse_debuginfo(yes)]
macro_rules! panic {
($($x:tt)*) => {
{
@@ -108,6 +118,7 @@ macro_rules! panic {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -121,6 +132,7 @@ macro_rules! trace {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -134,6 +146,7 @@ macro_rules! debug {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -147,6 +160,7 @@ macro_rules! info {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -160,6 +174,7 @@ macro_rules! warn {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -174,6 +189,7 @@ macro_rules! error {
}
#[cfg(feature = "defmt")]
+#[collapse_debuginfo(yes)]
macro_rules! unwrap {
($($x:tt)*) => {
::defmt::unwrap!($($x)*)
@@ -181,6 +197,7 @@ macro_rules! unwrap {
}
#[cfg(not(feature = "defmt"))]
+#[collapse_debuginfo(yes)]
macro_rules! unwrap {
($arg:expr) => {
match $crate::fmt::Try::into_result($arg) {
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs
index f2353f21d..7b272dca0 100644
--- a/embassy-nrf/src/gpio.rs
+++ b/embassy-nrf/src/gpio.rs
@@ -7,7 +7,6 @@ use core::hint::unreachable_unchecked;
use cfg_if::cfg_if;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
-use self::sealed::Pin as _;
#[cfg(feature = "nrf51")]
use crate::pac::gpio;
#[cfg(feature = "nrf51")]
@@ -361,59 +360,56 @@ impl<'d> Drop for Flex<'d> {
}
}
-pub(crate) mod sealed {
- use super::*;
+pub(crate) trait SealedPin {
+ fn pin_port(&self) -> u8;
- pub trait Pin {
- fn pin_port(&self) -> u8;
-
- #[inline]
- fn _pin(&self) -> u8 {
- cfg_if! {
- if #[cfg(feature = "_gpio-p1")] {
- self.pin_port() % 32
- } else {
- self.pin_port()
- }
+ #[inline]
+ fn _pin(&self) -> u8 {
+ cfg_if! {
+ if #[cfg(feature = "_gpio-p1")] {
+ self.pin_port() % 32
+ } else {
+ self.pin_port()
}
}
+ }
- #[inline]
- fn block(&self) -> &gpio::RegisterBlock {
- unsafe {
- match self.pin_port() / 32 {
- #[cfg(feature = "nrf51")]
- 0 => &*pac::GPIO::ptr(),
- #[cfg(not(feature = "nrf51"))]
- 0 => &*pac::P0::ptr(),
- #[cfg(feature = "_gpio-p1")]
- 1 => &*pac::P1::ptr(),
- _ => unreachable_unchecked(),
- }
+ #[inline]
+ fn block(&self) -> &gpio::RegisterBlock {
+ unsafe {
+ match self.pin_port() / 32 {
+ #[cfg(feature = "nrf51")]
+ 0 => &*pac::GPIO::ptr(),
+ #[cfg(not(feature = "nrf51"))]
+ 0 => &*pac::P0::ptr(),
+ #[cfg(feature = "_gpio-p1")]
+ 1 => &*pac::P1::ptr(),
+ _ => unreachable_unchecked(),
}
}
+ }
- #[inline]
- fn conf(&self) -> &gpio::PIN_CNF {
- &self.block().pin_cnf[self._pin() as usize]
- }
+ #[inline]
+ fn conf(&self) -> &gpio::PIN_CNF {
+ &self.block().pin_cnf[self._pin() as usize]
+ }
- /// Set the output as high.
- #[inline]
- fn set_high(&self) {
- unsafe { self.block().outset.write(|w| w.bits(1u32 << self._pin())) }
- }
+ /// Set the output as high.
+ #[inline]
+ fn set_high(&self) {
+ unsafe { self.block().outset.write(|w| w.bits(1u32 << self._pin())) }
+ }
- /// Set the output as low.
- #[inline]
- fn set_low(&self) {
- unsafe { self.block().outclr.write(|w| w.bits(1u32 << self._pin())) }
- }
+ /// Set the output as low.
+ #[inline]
+ fn set_low(&self) {
+ unsafe { self.block().outclr.write(|w| w.bits(1u32 << self._pin())) }
}
}
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
-pub trait Pin: Peripheral
+ Into + sealed::Pin + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Pin: Peripheral + Into + SealedPin + Sized + 'static {
/// Number of the pin within the port (0..31)
#[inline]
fn pin(&self) -> u8 {
@@ -464,7 +460,7 @@ impl AnyPin {
impl_peripheral!(AnyPin);
impl Pin for AnyPin {}
-impl sealed::Pin for AnyPin {
+impl SealedPin for AnyPin {
#[inline]
fn pin_port(&self) -> u8 {
self.pin_port
@@ -502,7 +498,7 @@ pub(crate) fn deconfigure_pin(psel_bits: u32) {
macro_rules! impl_pin {
($type:ident, $port_num:expr, $pin_num:expr) => {
impl crate::gpio::Pin for peripherals::$type {}
- impl crate::gpio::sealed::Pin for peripherals::$type {
+ impl crate::gpio::SealedPin for peripherals::$type {
#[inline]
fn pin_port(&self) -> u8 {
$port_num * 32 + $pin_num
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs
index 4a28279a9..a74b3157b 100644
--- a/embassy-nrf/src/gpiote.rs
+++ b/embassy-nrf/src/gpiote.rs
@@ -7,8 +7,7 @@ use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin};
+use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin, SealedPin as _};
use crate::interrupt::InterruptExt;
use crate::ppi::{Event, Task};
use crate::{interrupt, pac, peripherals};
@@ -20,9 +19,9 @@ const CHANNEL_COUNT: usize = 4;
/// Amount of GPIOTE channels in the chip.
const CHANNEL_COUNT: usize = 8;
-#[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
+#[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))]
const PIN_COUNT: usize = 48;
-#[cfg(not(any(feature = "nrf52833", feature = "nrf52840")))]
+#[cfg(not(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))]
const PIN_COUNT: usize = 32;
#[allow(clippy::declare_interior_mutable_const)]
@@ -68,9 +67,9 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
// no latched GPIO detect in nrf51.
#[cfg(not(feature = "_nrf51"))]
{
- #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
+ #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))]
let ports = unsafe { &[&*pac::P0::ptr(), &*pac::P1::ptr()] };
- #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840")))]
+ #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))]
let ports = unsafe { &[&*pac::P0::ptr()] };
for &p in ports {
@@ -131,9 +130,9 @@ unsafe fn handle_gpiote_interrupt() {
if g.events_port.read().bits() != 0 {
g.events_port.write(|w| w);
- #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
+ #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))]
let ports = &[&*pac::P0::ptr(), &*pac::P1::ptr()];
- #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840")))]
+ #[cfg(not(any(feature = "_nrf51", feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340")))]
let ports = &[&*pac::P0::ptr()];
#[cfg(feature = "_nrf51")]
let ports = unsafe { &[&*pac::GPIO::ptr()] };
@@ -215,7 +214,7 @@ impl<'d> InputChannel<'d> {
InputChannelPolarity::None => w.mode().event().polarity().none(),
InputChannelPolarity::Toggle => w.mode().event().polarity().toggle(),
};
- #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
+ #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))]
w.port().bit(match pin.pin.pin.port() {
crate::gpio::Port::Port0 => false,
crate::gpio::Port::Port1 => true,
@@ -289,7 +288,7 @@ impl<'d> OutputChannel<'d> {
OutputChannelPolarity::Clear => w.polarity().hi_to_lo(),
OutputChannelPolarity::Toggle => w.polarity().toggle(),
};
- #[cfg(any(feature = "nrf52833", feature = "nrf52840"))]
+ #[cfg(any(feature = "nrf52833", feature = "nrf52840", feature = "_nrf5340"))]
w.port().bit(match pin.pin.pin.port() {
crate::gpio::Port::Port0 => false,
crate::gpio::Port::Port1 => true,
@@ -446,14 +445,13 @@ impl<'d> Flex<'d> {
// =======================
-mod sealed {
- pub trait Channel {}
-}
+trait SealedChannel {}
/// GPIOTE channel trait.
///
/// Implemented by all GPIOTE channels.
-pub trait Channel: sealed::Channel + Into + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Channel: SealedChannel + Into + Sized + 'static {
/// Get the channel number.
fn number(&self) -> usize;
@@ -478,7 +476,7 @@ pub struct AnyChannel {
number: u8,
}
impl_peripheral!(AnyChannel);
-impl sealed::Channel for AnyChannel {}
+impl SealedChannel for AnyChannel {}
impl Channel for AnyChannel {
fn number(&self) -> usize {
self.number as usize
@@ -487,7 +485,7 @@ impl Channel for AnyChannel {
macro_rules! impl_channel {
($type:ident, $number:expr) => {
- impl sealed::Channel for peripherals::$type {}
+ impl SealedChannel for peripherals::$type {}
impl Channel for peripherals::$type {
fn number(&self) -> usize {
$number as usize
diff --git a/embassy-nrf/src/i2s.rs b/embassy-nrf/src/i2s.rs
index 907acdf4c..5f565a9b7 100644
--- a/embassy-nrf/src/i2s.rs
+++ b/embassy-nrf/src/i2s.rs
@@ -6,16 +6,17 @@ use core::future::poll_fn;
use core::marker::PhantomData;
use core::mem::size_of;
use core::ops::{Deref, DerefMut};
-use core::sync::atomic::{compiler_fence, Ordering};
+use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::{AnyPin, Pin as GpioPin};
use crate::interrupt::typelevel::Interrupt;
use crate::pac::i2s::RegisterBlock;
-use crate::util::{slice_in_ram_or, slice_ptr_parts};
+use crate::util::slice_in_ram_or;
use crate::{interrupt, Peripheral, EASY_DMA_SIZE};
/// Type alias for `MultiBuffering` with 2 buffers.
@@ -1027,9 +1028,8 @@ impl Device {
}
fn validated_dma_parts(buffer_ptr: *const [S]) -> Result<(u32, u32), Error> {
- let (ptr, len) = slice_ptr_parts(buffer_ptr);
- let ptr = ptr as u32;
- let bytes_len = len * size_of::();
+ let ptr = buffer_ptr as *const S as u32;
+ let bytes_len = buffer_ptr.len() * size_of::();
let maxcnt = (bytes_len / size_of::()) as u32;
trace!("PTR={}, MAXCNT={}", ptr, maxcnt);
@@ -1140,50 +1140,45 @@ impl MultiBuffering {
}
}
-pub(crate) mod sealed {
- use core::sync::atomic::AtomicBool;
+/// Peripheral static state
+pub(crate) struct State {
+ started: AtomicBool,
+ rx_waker: AtomicWaker,
+ tx_waker: AtomicWaker,
+ stop_waker: AtomicWaker,
+}
- use embassy_sync::waitqueue::AtomicWaker;
-
- /// Peripheral static state
- pub struct State {
- pub started: AtomicBool,
- pub rx_waker: AtomicWaker,
- pub tx_waker: AtomicWaker,
- pub stop_waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- started: AtomicBool::new(false),
- rx_waker: AtomicWaker::new(),
- tx_waker: AtomicWaker::new(),
- stop_waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ started: AtomicBool::new(false),
+ rx_waker: AtomicWaker::new(),
+ tx_waker: AtomicWaker::new(),
+ stop_waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static crate::pac::i2s::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::i2s::RegisterBlock;
+ fn state() -> &'static State;
}
/// I2S peripheral instance.
-pub trait Instance: Peripheral + sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_i2s {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::i2s::sealed::Instance for peripherals::$type {
+ impl crate::i2s::SealedInstance for peripherals::$type {
fn regs() -> &'static crate::pac::i2s::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::i2s::sealed::State {
- static STATE: crate::i2s::sealed::State = crate::i2s::sealed::State::new();
+ fn state() -> &'static crate::i2s::State {
+ static STATE: crate::i2s::State = crate::i2s::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 3457dd933..05b52f687 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -50,6 +50,8 @@ pub mod gpiote;
#[cfg(not(any(feature = "_nrf9160", feature = "_nrf5340-app")))]
pub mod radio;
+#[cfg(not(feature = "nrf51"))]
+pub mod egu;
#[cfg(any(feature = "nrf52832", feature = "nrf52833", feature = "nrf52840"))]
pub mod i2s;
pub mod nvmc;
diff --git a/embassy-nrf/src/pdm.rs b/embassy-nrf/src/pdm.rs
index 754d38310..c1501e02e 100644
--- a/embassy-nrf/src/pdm.rs
+++ b/embassy-nrf/src/pdm.rs
@@ -1,4 +1,4 @@
-//! Pulse Density Modulation (PDM) mirophone driver
+//! Pulse Density Modulation (PDM) microphone driver
#![macro_use]
@@ -9,11 +9,11 @@ use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::I7F1;
use crate::chip::EASY_DMA_SIZE;
-use crate::gpio::sealed::Pin;
-use crate::gpio::{AnyPin, Pin as GpioPin};
+use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin};
use crate::interrupt::typelevel::Interrupt;
use crate::pac::pdm::mode::{EDGE_A, OPERATION_A};
pub use crate::pac::pdm::pdmclkctrl::FREQ_A as Frequency;
@@ -451,42 +451,39 @@ impl<'d, T: Instance> Drop for Pdm<'d, T> {
}
}
-pub(crate) mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
+/// Peripheral static state
+pub(crate) struct State {
+ waker: AtomicWaker,
+}
- /// Peripheral static state
- pub struct State {
- pub waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static crate::pac::pdm::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::pdm::RegisterBlock;
+ fn state() -> &'static State;
}
/// PDM peripheral instance
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_pdm {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::pdm::sealed::Instance for peripherals::$type {
+ impl crate::pdm::SealedInstance for peripherals::$type {
fn regs() -> &'static crate::pac::pdm::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::pdm::sealed::State {
- static STATE: crate::pdm::sealed::State = crate::pdm::sealed::State::new();
+ fn state() -> &'static crate::pdm::State {
+ static STATE: crate::pdm::State = crate::pdm::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/ppi/mod.rs b/embassy-nrf/src/ppi/mod.rs
index f5764b8b7..13f7dcc83 100644
--- a/embassy-nrf/src/ppi/mod.rs
+++ b/embassy-nrf/src/ppi/mod.rs
@@ -210,13 +210,12 @@ unsafe impl Send for Event<'_> {}
// ======================
// traits
-pub(crate) mod sealed {
- pub trait Channel {}
- pub trait Group {}
-}
+pub(crate) trait SealedChannel {}
+pub(crate) trait SealedGroup {}
/// Interface for PPI channels.
-pub trait Channel: sealed::Channel + Peripheral
+ Sized + 'static {
+#[allow(private_bounds)]
+pub trait Channel: SealedChannel + Peripheral
+ Sized + 'static {
/// Returns the number of the channel
fn number(&self) -> usize;
}
@@ -234,7 +233,8 @@ pub trait StaticChannel: Channel + Into {
}
/// Interface for a group of PPI channels.
-pub trait Group: sealed::Group + Peripheral + Into + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Group: SealedGroup + Peripheral + Into + Sized + 'static {
/// Returns the number of the group.
fn number(&self) -> usize;
/// Convert into a type erased group.
@@ -254,7 +254,7 @@ pub struct AnyStaticChannel {
pub(crate) number: u8,
}
impl_peripheral!(AnyStaticChannel);
-impl sealed::Channel for AnyStaticChannel {}
+impl SealedChannel for AnyStaticChannel {}
impl Channel for AnyStaticChannel {
fn number(&self) -> usize {
self.number as usize
@@ -272,7 +272,7 @@ pub struct AnyConfigurableChannel {
pub(crate) number: u8,
}
impl_peripheral!(AnyConfigurableChannel);
-impl sealed::Channel for AnyConfigurableChannel {}
+impl SealedChannel for AnyConfigurableChannel {}
impl Channel for AnyConfigurableChannel {
fn number(&self) -> usize {
self.number as usize
@@ -287,7 +287,7 @@ impl ConfigurableChannel for AnyConfigurableChannel {
#[cfg(not(feature = "nrf51"))]
macro_rules! impl_ppi_channel {
($type:ident, $number:expr) => {
- impl crate::ppi::sealed::Channel for peripherals::$type {}
+ impl crate::ppi::SealedChannel for peripherals::$type {}
impl crate::ppi::Channel for peripherals::$type {
fn number(&self) -> usize {
$number
@@ -338,7 +338,7 @@ pub struct AnyGroup {
number: u8,
}
impl_peripheral!(AnyGroup);
-impl sealed::Group for AnyGroup {}
+impl SealedGroup for AnyGroup {}
impl Group for AnyGroup {
fn number(&self) -> usize {
self.number as usize
@@ -347,7 +347,7 @@ impl Group for AnyGroup {
macro_rules! impl_group {
($type:ident, $number:expr) => {
- impl sealed::Group for peripherals::$type {}
+ impl SealedGroup for peripherals::$type {}
impl Group for peripherals::$type {
fn number(&self) -> usize {
$number
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs
index 833370d4b..8e8f166d7 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -6,8 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef};
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
+use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _};
use crate::ppi::{Event, Task};
use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral};
@@ -129,19 +128,23 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
if let Some(pin) = &ch0 {
pin.set_low();
- pin.conf().write(|w| w.dir().output());
+ pin.conf()
+ .write(|w| w.dir().output().drive().variant(convert_drive(config.ch0_drive)));
}
if let Some(pin) = &ch1 {
pin.set_low();
- pin.conf().write(|w| w.dir().output());
+ pin.conf()
+ .write(|w| w.dir().output().drive().variant(convert_drive(config.ch1_drive)));
}
if let Some(pin) = &ch2 {
pin.set_low();
- pin.conf().write(|w| w.dir().output());
+ pin.conf()
+ .write(|w| w.dir().output().drive().variant(convert_drive(config.ch2_drive)));
}
if let Some(pin) = &ch3 {
pin.set_low();
- pin.conf().write(|w| w.dir().output());
+ pin.conf()
+ .write(|w| w.dir().output().drive().variant(convert_drive(config.ch3_drive)));
}
r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) });
@@ -320,6 +323,14 @@ pub struct Config {
pub prescaler: Prescaler,
/// How a sequence is read from RAM and is spread to the compare register
pub sequence_load: SequenceLoad,
+ /// Drive strength for the channel 0 line.
+ pub ch0_drive: OutputDrive,
+ /// Drive strength for the channel 1 line.
+ pub ch1_drive: OutputDrive,
+ /// Drive strength for the channel 2 line.
+ pub ch2_drive: OutputDrive,
+ /// Drive strength for the channel 3 line.
+ pub ch3_drive: OutputDrive,
}
impl Default for Config {
@@ -329,6 +340,10 @@ impl Default for Config {
max_duty: 1000,
prescaler: Prescaler::Div16,
sequence_load: SequenceLoad::Common,
+ ch0_drive: OutputDrive::Standard,
+ ch1_drive: OutputDrive::Standard,
+ ch2_drive: OutputDrive::Standard,
+ ch3_drive: OutputDrive::Standard,
}
}
}
@@ -369,7 +384,7 @@ impl<'s> Sequence<'s> {
}
/// A single sequence that can be started and stopped.
-/// Takes at one sequence along with its configuration.
+/// Takes one sequence along with its configuration.
#[non_exhaustive]
pub struct SingleSequencer<'d, 's, T: Instance> {
sequencer: Sequencer<'d, 's, T>,
@@ -816,6 +831,38 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
let max_duty = self.max_duty() as u32;
clk / max_duty
}
+
+ /// Sets the PWM-Channel0 output drive strength
+ #[inline(always)]
+ pub fn set_ch0_drive(&self, drive: OutputDrive) {
+ if let Some(pin) = &self.ch0 {
+ pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
+ }
+ }
+
+ /// Sets the PWM-Channel1 output drive strength
+ #[inline(always)]
+ pub fn set_ch1_drive(&self, drive: OutputDrive) {
+ if let Some(pin) = &self.ch1 {
+ pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
+ }
+ }
+
+ /// Sets the PWM-Channel2 output drive strength
+ #[inline(always)]
+ pub fn set_ch2_drive(&self, drive: OutputDrive) {
+ if let Some(pin) = &self.ch2 {
+ pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
+ }
+ }
+
+ /// Sets the PWM-Channel3 output drive strength
+ #[inline(always)]
+ pub fn set_ch3_drive(&self, drive: OutputDrive) {
+ if let Some(pin) = &self.ch3 {
+ pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
+ }
+ }
}
impl<'a, T: Instance> Drop for SimplePwm<'a, T> {
@@ -847,23 +894,20 @@ impl<'a, T: Instance> Drop for SimplePwm<'a, T> {
}
}
-pub(crate) mod sealed {
- use super::*;
-
- pub trait Instance {
- fn regs() -> &'static pac::pwm0::RegisterBlock;
- }
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::pwm0::RegisterBlock;
}
/// PWM peripheral instance.
-pub trait Instance: Peripheral + sealed::Instance + 'static {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_pwm {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::pwm::sealed::Instance for peripherals::$type {
+ impl crate::pwm::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::pwm0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
diff --git a/embassy-nrf/src/qdec.rs b/embassy-nrf/src/qdec.rs
index 9455ec925..7409c9b1e 100644
--- a/embassy-nrf/src/qdec.rs
+++ b/embassy-nrf/src/qdec.rs
@@ -7,9 +7,9 @@ use core::marker::PhantomData;
use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{AnyPin, Pin as GpioPin};
+use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral};
@@ -245,42 +245,39 @@ pub enum LedPolarity {
ActiveLow,
}
-pub(crate) mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
+/// Peripheral static state
+pub(crate) struct State {
+ waker: AtomicWaker,
+}
- /// Peripheral static state
- pub struct State {
- pub waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static crate::pac::qdec::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::qdec::RegisterBlock;
+ fn state() -> &'static State;
}
/// qdec peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_qdec {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::qdec::sealed::Instance for peripherals::$type {
+ impl crate::qdec::SealedInstance for peripherals::$type {
fn regs() -> &'static crate::pac::qdec::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::qdec::sealed::State {
- static STATE: crate::qdec::sealed::State = crate::qdec::sealed::State::new();
+ fn state() -> &'static crate::qdec::State {
+ static STATE: crate::qdec::State = crate::qdec::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 4134a4c87..d40096edc 100755
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -9,6 +9,7 @@ use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
use crate::gpio::{self, Pin as GpioPin};
@@ -165,7 +166,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
$pin.conf().write(|w| {
w.dir().output();
w.drive().h0h1();
- #[cfg(feature = "_nrf5340-s")]
+ #[cfg(all(feature = "_nrf5340", feature = "_s"))]
w.mcusel().peripheral();
w
});
@@ -652,42 +653,39 @@ mod _eh1 {
impl<'d, T: Instance> embedded_storage_async::nor_flash::MultiwriteNorFlash for Qspi<'d, T> {}
}
-pub(crate) mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
+/// Peripheral static state
+pub(crate) struct State {
+ waker: AtomicWaker,
+}
- /// Peripheral static state
- pub struct State {
- pub waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static crate::pac::qspi::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::qspi::RegisterBlock;
+ fn state() -> &'static State;
}
/// QSPI peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_qspi {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::qspi::sealed::Instance for peripherals::$type {
+ impl crate::qspi::SealedInstance for peripherals::$type {
fn regs() -> &'static crate::pac::qspi::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::qspi::sealed::State {
- static STATE: crate::qspi::sealed::State = crate::qspi::sealed::State::new();
+ fn state() -> &'static crate::qspi::State {
+ static STATE: crate::qspi::State = crate::qspi::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/radio/ble.rs b/embassy-nrf/src/radio/ble.rs
index 93003fb19..4f0b0641f 100644
--- a/embassy-nrf/src/radio/ble.rs
+++ b/embassy-nrf/src/radio/ble.rs
@@ -335,8 +335,6 @@ impl<'d, T: Instance> Radio<'d, T> {
}
async fn trigger_and_wait_end(&mut self, trigger: impl FnOnce()) {
- //self.trace_state();
-
let r = T::regs();
let s = T::state();
@@ -347,12 +345,10 @@ impl<'d, T: Instance> Radio<'d, T> {
trace!("radio drop: stopping");
r.intenclr.write(|w| w.end().clear());
- r.events_end.reset();
r.tasks_stop.write(|w| unsafe { w.bits(1) });
- // The docs don't explicitly mention any event to acknowledge the stop task
- while r.events_end.read().bits() == 0 {}
+ r.events_end.reset();
trace!("radio drop: stopped");
});
@@ -368,7 +364,6 @@ impl<'d, T: Instance> Radio<'d, T> {
// Trigger the transmission
trigger();
- // self.trace_state();
// On poll check if interrupt happen
poll_fn(|cx| {
@@ -382,7 +377,7 @@ impl<'d, T: Instance> Radio<'d, T> {
.await;
compiler_fence(Ordering::SeqCst);
- r.events_disabled.reset(); // ACK
+ r.events_end.reset(); // ACK
// Everthing ends fine, so it disable the drop
drop.defuse();
diff --git a/embassy-nrf/src/radio/mod.rs b/embassy-nrf/src/radio/mod.rs
index 4c0cc3280..8edca1df2 100644
--- a/embassy-nrf/src/radio/mod.rs
+++ b/embassy-nrf/src/radio/mod.rs
@@ -19,6 +19,7 @@ pub mod ieee802154;
use core::marker::PhantomData;
+use embassy_sync::waitqueue::AtomicWaker;
use pac::radio::state::STATE_A as RadioState;
pub use pac::radio::txpower::TXPOWER_A as TxPower;
@@ -56,36 +57,32 @@ impl interrupt::typelevel::Handler for InterruptHandl
}
}
-pub(crate) mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
-
- pub struct State {
- /// end packet transmission or reception
- pub event_waker: AtomicWaker,
- }
- impl State {
- pub const fn new() -> Self {
- Self {
- event_waker: AtomicWaker::new(),
- }
+pub(crate) struct State {
+ /// end packet transmission or reception
+ event_waker: AtomicWaker,
+}
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ event_waker: AtomicWaker::new(),
}
}
+}
- pub trait Instance {
- fn regs() -> &'static crate::pac::radio::RegisterBlock;
- fn state() -> &'static State;
- }
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::radio::RegisterBlock;
+ fn state() -> &'static State;
}
macro_rules! impl_radio {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::radio::sealed::Instance for peripherals::$type {
+ impl crate::radio::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::radio::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::radio::sealed::State {
- static STATE: crate::radio::sealed::State = crate::radio::sealed::State::new();
+ fn state() -> &'static crate::radio::State {
+ static STATE: crate::radio::State = crate::radio::State::new();
&STATE
}
}
@@ -96,7 +93,8 @@ macro_rules! impl_radio {
}
/// Radio peripheral instance.
-pub trait Instance: Peripheral + sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
diff --git a/embassy-nrf/src/rng.rs b/embassy-nrf/src/rng.rs
index 1c463fb7c..ff61e08f3 100644
--- a/embassy-nrf/src/rng.rs
+++ b/embassy-nrf/src/rng.rs
@@ -2,13 +2,16 @@
#![macro_use]
+use core::cell::{RefCell, RefMut};
use core::future::poll_fn;
use core::marker::PhantomData;
use core::ptr;
use core::task::Poll;
+use critical_section::{CriticalSection, Mutex};
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::WakerRegistration;
use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral};
@@ -205,73 +208,61 @@ impl<'d, T: Instance> rand_core::RngCore for Rng<'d, T> {
impl<'d, T: Instance> rand_core::CryptoRng for Rng<'d, T> {}
-pub(crate) mod sealed {
- use core::cell::{Ref, RefCell, RefMut};
+/// Peripheral static state
+pub(crate) struct State {
+ inner: Mutex>,
+}
- use critical_section::{CriticalSection, Mutex};
- use embassy_sync::waitqueue::WakerRegistration;
+struct InnerState {
+ ptr: *mut u8,
+ end: *mut u8,
+ waker: WakerRegistration,
+}
- use super::*;
+unsafe impl Send for InnerState {}
- /// Peripheral static state
- pub struct State {
- inner: Mutex>,
- }
-
- pub struct InnerState {
- pub ptr: *mut u8,
- pub end: *mut u8,
- pub waker: WakerRegistration,
- }
-
- unsafe impl Send for InnerState {}
-
- impl State {
- pub const fn new() -> Self {
- Self {
- inner: Mutex::new(RefCell::new(InnerState::new())),
- }
- }
-
- pub fn borrow<'cs>(&'cs self, cs: CriticalSection<'cs>) -> Ref<'cs, InnerState> {
- self.inner.borrow(cs).borrow()
- }
-
- pub fn borrow_mut<'cs>(&'cs self, cs: CriticalSection<'cs>) -> RefMut<'cs, InnerState> {
- self.inner.borrow(cs).borrow_mut()
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ inner: Mutex::new(RefCell::new(InnerState::new())),
}
}
- impl InnerState {
- pub const fn new() -> Self {
- Self {
- ptr: ptr::null_mut(),
- end: ptr::null_mut(),
- waker: WakerRegistration::new(),
- }
- }
- }
-
- pub trait Instance {
- fn regs() -> &'static crate::pac::rng::RegisterBlock;
- fn state() -> &'static State;
+ fn borrow_mut<'cs>(&'cs self, cs: CriticalSection<'cs>) -> RefMut<'cs, InnerState> {
+ self.inner.borrow(cs).borrow_mut()
}
}
+impl InnerState {
+ const fn new() -> Self {
+ Self {
+ ptr: ptr::null_mut(),
+ end: ptr::null_mut(),
+ waker: WakerRegistration::new(),
+ }
+ }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static crate::pac::rng::RegisterBlock;
+ fn state() -> &'static State;
+}
+
/// RNG peripheral instance.
-pub trait Instance: Peripheral + sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_rng {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::rng::sealed::Instance for peripherals::$type {
+ impl crate::rng::SealedInstance for peripherals::$type {
fn regs() -> &'static crate::pac::rng::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::rng::sealed::State {
- static STATE: crate::rng::sealed::State = crate::rng::sealed::State::new();
+ fn state() -> &'static crate::rng::State {
+ static STATE: crate::rng::State = crate::rng::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 662b05614..17c65fa3e 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -16,7 +16,6 @@ pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel;
use saadc::oversample::OVERSAMPLE_A;
use saadc::resolution::VAL_A;
-use self::sealed::Input as _;
use crate::interrupt::InterruptExt;
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
@@ -662,16 +661,13 @@ pub enum Resolution {
_14BIT = 3,
}
-pub(crate) mod sealed {
- use super::*;
-
- pub trait Input {
- fn channel(&self) -> InputChannel;
- }
+pub(crate) trait SealedInput {
+ fn channel(&self) -> InputChannel;
}
/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
-pub trait Input: sealed::Input + Into + Peripheral + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Input: SealedInput + Into + Peripheral + Sized + 'static {
/// Convert this SAADC input to a type-erased `AnyInput`.
///
/// This allows using several inputs in situations that might require
@@ -693,7 +689,7 @@ pub struct AnyInput {
impl_peripheral!(AnyInput);
-impl sealed::Input for AnyInput {
+impl SealedInput for AnyInput {
fn channel(&self) -> InputChannel {
self.channel
}
@@ -706,7 +702,7 @@ macro_rules! impl_saadc_input {
impl_saadc_input!(@local, crate::peripherals::$pin, $ch);
};
(@local, $pin:ty, $ch:ident) => {
- impl crate::saadc::sealed::Input for $pin {
+ impl crate::saadc::SealedInput for $pin {
fn channel(&self) -> crate::saadc::InputChannel {
crate::saadc::InputChannel::$ch
}
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs
index c45d45e68..52660711a 100644
--- a/embassy-nrf/src/spim.rs
+++ b/embassy-nrf/src/spim.rs
@@ -4,20 +4,22 @@
use core::future::poll_fn;
use core::marker::PhantomData;
+#[cfg(feature = "_nrf52832_anomaly_109")]
+use core::sync::atomic::AtomicU8;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
pub use pac::spim0::config::ORDER_A as BitOrder;
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits};
+use crate::gpio::{self, convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _};
use crate::interrupt::typelevel::Interrupt;
-use crate::util::{slice_in_ram_or, slice_ptr_len, slice_ptr_parts, slice_ptr_parts_mut};
+use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral};
/// SPIM error
@@ -238,14 +240,12 @@ impl<'d, T: Instance> Spim<'d, T> {
}
// Set up the DMA read.
- let (ptr, len) = slice_ptr_parts_mut(rx);
- let (rx_ptr, rx_len) = xfer_params(ptr as _, len as _, offset, length);
+ let (rx_ptr, rx_len) = xfer_params(rx as *mut u8 as _, rx.len() as _, offset, length);
r.rxd.ptr.write(|w| unsafe { w.ptr().bits(rx_ptr) });
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) });
// Set up the DMA write.
- let (ptr, len) = slice_ptr_parts(tx);
- let (tx_ptr, tx_len) = xfer_params(ptr as _, len as _, offset, length);
+ let (tx_ptr, tx_len) = xfer_params(tx as *const u8 as _, tx.len() as _, offset, length);
r.txd.ptr.write(|w| unsafe { w.ptr().bits(tx_ptr) });
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) });
@@ -300,7 +300,7 @@ impl<'d, T: Instance> Spim<'d, T> {
// NOTE: RAM slice check for rx is not necessary, as a mutable
// slice can only be built from data located in RAM.
- let xfer_len = core::cmp::max(slice_ptr_len(rx), slice_ptr_len(tx));
+ let xfer_len = core::cmp::max(rx.len(), tx.len());
for offset in (0..xfer_len).step_by(EASY_DMA_SIZE) {
let length = core::cmp::min(xfer_len - offset, EASY_DMA_SIZE);
self.blocking_inner_from_ram_chunk(rx, tx, offset, length);
@@ -354,7 +354,7 @@ impl<'d, T: Instance> Spim<'d, T> {
// NOTE: RAM slice check for rx is not necessary, as a mutable
// slice can only be built from data located in RAM.
- let xfer_len = core::cmp::max(slice_ptr_len(rx), slice_ptr_len(tx));
+ let xfer_len = core::cmp::max(rx.len(), tx.len());
for offset in (0..xfer_len).step_by(EASY_DMA_SIZE) {
let length = core::cmp::min(xfer_len - offset, EASY_DMA_SIZE);
self.async_inner_from_ram_chunk(rx, tx, offset, length).await;
@@ -487,54 +487,46 @@ impl<'d, T: Instance> Drop for Spim<'d, T> {
}
}
-pub(crate) mod sealed {
+pub(crate) struct State {
+ waker: AtomicWaker,
#[cfg(feature = "_nrf52832_anomaly_109")]
- use core::sync::atomic::AtomicU8;
+ rx: AtomicU8,
+ #[cfg(feature = "_nrf52832_anomaly_109")]
+ tx: AtomicU8,
+}
- use embassy_sync::waitqueue::AtomicWaker;
-
- use super::*;
-
- pub struct State {
- pub waker: AtomicWaker,
- #[cfg(feature = "_nrf52832_anomaly_109")]
- pub rx: AtomicU8,
- #[cfg(feature = "_nrf52832_anomaly_109")]
- pub tx: AtomicU8,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- #[cfg(feature = "_nrf52832_anomaly_109")]
- rx: AtomicU8::new(0),
- #[cfg(feature = "_nrf52832_anomaly_109")]
- tx: AtomicU8::new(0),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
+ #[cfg(feature = "_nrf52832_anomaly_109")]
+ rx: AtomicU8::new(0),
+ #[cfg(feature = "_nrf52832_anomaly_109")]
+ tx: AtomicU8::new(0),
}
}
-
- pub trait Instance {
- fn regs() -> &'static pac::spim0::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::spim0::RegisterBlock;
+ fn state() -> &'static State;
}
/// SPIM peripheral instance
-pub trait Instance: Peripheral
+ sealed::Instance + 'static {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_spim {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::spim::sealed::Instance for peripherals::$type {
+ impl crate::spim::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::spim0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::spim::sealed::State {
- static STATE: crate::spim::sealed::State = crate::spim::sealed::State::new();
+ fn state() -> &'static crate::spim::State {
+ static STATE: crate::spim::State = crate::spim::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs
index 772ca40cc..e98b34369 100644
--- a/embassy-nrf/src/spis.rs
+++ b/embassy-nrf/src/spis.rs
@@ -8,14 +8,14 @@ use core::task::Poll;
use embassy_embedded_hal::SetConfig;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
pub use pac::spis0::config::ORDER_A as BitOrder;
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{self, AnyPin, Pin as GpioPin};
+use crate::gpio::{self, AnyPin, Pin as GpioPin, SealedPin as _};
use crate::interrupt::typelevel::Interrupt;
-use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
+use crate::util::slice_in_ram_or;
use crate::{interrupt, pac, Peripheral};
/// SPIS error
@@ -226,20 +226,18 @@ impl<'d, T: Instance> Spis<'d, T> {
let r = T::regs();
// Set up the DMA write.
- let (ptr, len) = slice_ptr_parts(tx);
- if len > EASY_DMA_SIZE {
+ if tx.len() > EASY_DMA_SIZE {
return Err(Error::TxBufferTooLong);
}
- r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
- r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
+ r.txd.ptr.write(|w| unsafe { w.ptr().bits(tx as *const u8 as _) });
+ r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx.len() as _) });
// Set up the DMA read.
- let (ptr, len) = slice_ptr_parts_mut(rx);
- if len > EASY_DMA_SIZE {
+ if rx.len() > EASY_DMA_SIZE {
return Err(Error::RxBufferTooLong);
}
- r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
- r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
+ r.rxd.ptr.write(|w| unsafe { w.ptr().bits(rx as *mut u8 as _) });
+ r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx.len() as _) });
// Reset end event.
r.events_end.reset();
@@ -456,43 +454,38 @@ impl<'d, T: Instance> Drop for Spis<'d, T> {
}
}
-pub(crate) mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
+pub(crate) struct State {
+ waker: AtomicWaker,
+}
- use super::*;
-
- pub struct State {
- pub waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static pac::spis0::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::spis0::RegisterBlock;
+ fn state() -> &'static State;
}
/// SPIS peripheral instance
-pub trait Instance: Peripheral
+ sealed::Instance + 'static {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_spis {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::spis::sealed::Instance for peripherals::$type {
+ impl crate::spis::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::spis0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::spis::sealed::State {
- static STATE: crate::spis::sealed::State = crate::spis::sealed::State::new();
+ fn state() -> &'static crate::spis::State {
+ static STATE: crate::spis::State = crate::spis::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/timer.rs b/embassy-nrf/src/timer.rs
index 2970ad3f2..ac5328ded 100644
--- a/embassy-nrf/src/timer.rs
+++ b/embassy-nrf/src/timer.rs
@@ -11,30 +11,25 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use crate::ppi::{Event, Task};
use crate::{pac, Peripheral};
-pub(crate) mod sealed {
-
- use super::*;
-
- pub trait Instance {
- /// The number of CC registers this instance has.
- const CCS: usize;
- fn regs() -> &'static pac::timer0::RegisterBlock;
- }
- pub trait ExtendedInstance {}
+pub(crate) trait SealedInstance {
+ /// The number of CC registers this instance has.
+ const CCS: usize;
+ fn regs() -> &'static pac::timer0::RegisterBlock;
}
/// Basic Timer instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: crate::interrupt::typelevel::Interrupt;
}
/// Extended timer instance.
-pub trait ExtendedInstance: Instance + sealed::ExtendedInstance {}
+pub trait ExtendedInstance: Instance {}
macro_rules! impl_timer {
($type:ident, $pac_type:ident, $irq:ident, $ccs:literal) => {
- impl crate::timer::sealed::Instance for peripherals::$type {
+ impl crate::timer::SealedInstance for peripherals::$type {
const CCS: usize = $ccs;
fn regs() -> &'static pac::timer0::RegisterBlock {
unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
@@ -49,7 +44,6 @@ macro_rules! impl_timer {
};
($type:ident, $pac_type:ident, $irq:ident, extended) => {
impl_timer!($type, $pac_type, $irq, 6);
- impl crate::timer::sealed::ExtendedInstance for peripherals::$type {}
impl crate::timer::ExtendedInstance for peripherals::$type {}
};
}
diff --git a/embassy-nrf/src/twim.rs b/embassy-nrf/src/twim.rs
index 24810a08c..c64743ecc 100644
--- a/embassy-nrf/src/twim.rs
+++ b/embassy-nrf/src/twim.rs
@@ -727,41 +727,38 @@ impl<'a, T: Instance> Drop for Twim<'a, T> {
}
}
-pub(crate) mod sealed {
- use super::*;
+pub(crate) struct State {
+ end_waker: AtomicWaker,
+}
- pub struct State {
- pub end_waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- end_waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ end_waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static pac::twim0::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::twim0::RegisterBlock;
+ fn state() -> &'static State;
}
/// TWIM peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_twim {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::twim::sealed::Instance for peripherals::$type {
+ impl crate::twim::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::twim0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::twim::sealed::State {
- static STATE: crate::twim::sealed::State = crate::twim::sealed::State::new();
+ fn state() -> &'static crate::twim::State {
+ static STATE: crate::twim::State = crate::twim::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/twis.rs b/embassy-nrf/src/twis.rs
index 415150447..f3eab008f 100644
--- a/embassy-nrf/src/twis.rs
+++ b/embassy-nrf/src/twis.rs
@@ -754,41 +754,38 @@ impl<'a, T: Instance> Drop for Twis<'a, T> {
}
}
-pub(crate) mod sealed {
- use super::*;
+pub(crate) struct State {
+ waker: AtomicWaker,
+}
- pub struct State {
- pub waker: AtomicWaker,
- }
-
- impl State {
- pub const fn new() -> Self {
- Self {
- waker: AtomicWaker::new(),
- }
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ waker: AtomicWaker::new(),
}
}
-
- pub trait Instance {
- fn regs() -> &'static pac::twis0::RegisterBlock;
- fn state() -> &'static State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::twis0::RegisterBlock;
+ fn state() -> &'static State;
}
/// TWIS peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_twis {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::twis::sealed::Instance for peripherals::$type {
+ impl crate::twis::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::twis0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::twis::sealed::State {
- static STATE: crate::twis::sealed::State = crate::twis::sealed::State::new();
+ fn state() -> &'static crate::twis::State {
+ static STATE: crate::twis::State = crate::twis::State::new();
&STATE
}
}
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index cbd5dccbc..4cf193617 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -15,18 +15,18 @@
use core::future::poll_fn;
use core::marker::PhantomData;
-use core::sync::atomic::{compiler_fence, Ordering};
+use core::sync::atomic::{compiler_fence, AtomicU8, Ordering};
use core::task::Poll;
use embassy_hal_internal::drop::OnDrop;
use embassy_hal_internal::{into_ref, PeripheralRef};
+use embassy_sync::waitqueue::AtomicWaker;
use pac::uarte0::RegisterBlock;
// Re-export SVD variants to allow user to directly set values.
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
+use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits, SealedPin as _};
use crate::interrupt::typelevel::Interrupt;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
@@ -221,6 +221,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
T::Interrupt::unpend();
unsafe { T::Interrupt::enable() };
+ r.enable.write(|w| w.enable().enabled());
let s = T::state();
s.tx_rx_refcount.store(2, Ordering::Relaxed);
@@ -319,9 +320,7 @@ pub(crate) fn configure(r: &RegisterBlock, config: Config, hardware_flow_control
r.psel.cts.write(|w| w.connect().disconnected());
r.psel.rts.write(|w| w.connect().disconnected());
- // Enable
apply_workaround_for_enable_anomaly(r);
- r.enable.write(|w| w.enable().enabled());
}
impl<'d, T: Instance> UarteTx<'d, T> {
@@ -369,6 +368,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
T::Interrupt::unpend();
unsafe { T::Interrupt::enable() };
+ r.enable.write(|w| w.enable().enabled());
let s = T::state();
s.tx_rx_refcount.store(1, Ordering::Relaxed);
@@ -567,6 +567,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
T::Interrupt::unpend();
unsafe { T::Interrupt::enable() };
+ r.enable.write(|w| w.enable().enabled());
let s = T::state();
s.tx_rx_refcount.store(1, Ordering::Relaxed);
@@ -939,7 +940,7 @@ pub(crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::Regist
}
}
-pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) {
+pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &State) {
if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 {
// Finally we can disable, and we do so for the peripheral
// i.e. not just rx concerns.
@@ -954,49 +955,42 @@ pub(crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) {
}
}
-pub(crate) mod sealed {
- use core::sync::atomic::AtomicU8;
-
- use embassy_sync::waitqueue::AtomicWaker;
-
- use super::*;
-
- pub struct State {
- pub rx_waker: AtomicWaker,
- pub tx_waker: AtomicWaker,
- pub tx_rx_refcount: AtomicU8,
- }
- impl State {
- pub const fn new() -> Self {
- Self {
- rx_waker: AtomicWaker::new(),
- tx_waker: AtomicWaker::new(),
- tx_rx_refcount: AtomicU8::new(0),
- }
+pub(crate) struct State {
+ pub(crate) rx_waker: AtomicWaker,
+ pub(crate) tx_waker: AtomicWaker,
+ pub(crate) tx_rx_refcount: AtomicU8,
+}
+impl State {
+ pub(crate) const fn new() -> Self {
+ Self {
+ rx_waker: AtomicWaker::new(),
+ tx_waker: AtomicWaker::new(),
+ tx_rx_refcount: AtomicU8::new(0),
}
}
-
- pub trait Instance {
- fn regs() -> &'static pac::uarte0::RegisterBlock;
- fn state() -> &'static State;
- fn buffered_state() -> &'static crate::buffered_uarte::State;
- }
+}
+
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::uarte0::RegisterBlock;
+ fn state() -> &'static State;
+ fn buffered_state() -> &'static crate::buffered_uarte::State;
}
/// UARTE peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_uarte {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::uarte::sealed::Instance for peripherals::$type {
+ impl crate::uarte::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::uarte0::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
- fn state() -> &'static crate::uarte::sealed::State {
- static STATE: crate::uarte::sealed::State = crate::uarte::sealed::State::new();
+ fn state() -> &'static crate::uarte::State {
+ static STATE: crate::uarte::State = crate::uarte::State::new();
&STATE
}
fn buffered_state() -> &'static crate::buffered_uarte::State {
diff --git a/embassy-nrf/src/usb/mod.rs b/embassy-nrf/src/usb/mod.rs
index e26b49db3..8cbb1a350 100644
--- a/embassy-nrf/src/usb/mod.rs
+++ b/embassy-nrf/src/usb/mod.rs
@@ -471,12 +471,19 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir
}
async fn wait_enabled(&mut self) {
+ self.wait_enabled_state(true).await
+ }
+}
+
+#[allow(private_bounds)]
+impl<'d, T: Instance, Dir: EndpointDir> Endpoint<'d, T, Dir> {
+ async fn wait_enabled_state(&mut self, state: bool) {
let i = self.info.addr.index();
assert!(i != 0);
poll_fn(move |cx| {
Dir::waker(i).register(cx.waker());
- if Dir::is_enabled(T::regs(), i) {
+ if Dir::is_enabled(T::regs(), i) == state {
Poll::Ready(())
} else {
Poll::Pending
@@ -484,6 +491,11 @@ impl<'d, T: Instance, Dir: EndpointDir> driver::Endpoint for Endpoint<'d, T, Dir
})
.await
}
+
+ /// Wait for the endpoint to be disabled
+ pub async fn wait_disabled(&mut self) {
+ self.wait_enabled_state(false).await
+ }
}
impl<'d, T: Instance, Dir> Endpoint<'d, T, Dir> {
@@ -793,23 +805,20 @@ impl Allocator {
}
}
-pub(crate) mod sealed {
- use super::*;
-
- pub trait Instance {
- fn regs() -> &'static pac::usbd::RegisterBlock;
- }
+pub(crate) trait SealedInstance {
+ fn regs() -> &'static pac::usbd::RegisterBlock;
}
/// USB peripheral instance.
-pub trait Instance: Peripheral
+ sealed::Instance + 'static + Send {
+#[allow(private_bounds)]
+pub trait Instance: Peripheral
+ SealedInstance + 'static + Send {
/// Interrupt for this peripheral.
type Interrupt: interrupt::typelevel::Interrupt;
}
macro_rules! impl_usb {
($type:ident, $pac_type:ident, $irq:ident) => {
- impl crate::usb::sealed::Instance for peripherals::$type {
+ impl crate::usb::SealedInstance for peripherals::$type {
fn regs() -> &'static pac::usbd::RegisterBlock {
unsafe { &*pac::$pac_type::ptr() }
}
diff --git a/embassy-nrf/src/util.rs b/embassy-nrf/src/util.rs
index 13aba7dec..78f71719f 100644
--- a/embassy-nrf/src/util.rs
+++ b/embassy-nrf/src/util.rs
@@ -1,42 +1,21 @@
#![allow(dead_code)]
-use core::mem;
const SRAM_LOWER: usize = 0x2000_0000;
const SRAM_UPPER: usize = 0x3000_0000;
-// #![feature(const_slice_ptr_len)]
-// https://github.com/rust-lang/rust/issues/71146
-pub(crate) fn slice_ptr_len(ptr: *const [T]) -> usize {
- use core::ptr::NonNull;
- let ptr = ptr.cast_mut();
- if let Some(ptr) = NonNull::new(ptr) {
- ptr.len()
- } else {
- // We know ptr is null, so we know ptr.wrapping_byte_add(1) is not null.
- NonNull::new(ptr.wrapping_byte_add(1)).unwrap().len()
- }
-}
-
-// TODO: replace transmutes with core::ptr::metadata once it's stable
-pub(crate) fn slice_ptr_parts(slice: *const [T]) -> (*const T, usize) {
- unsafe { mem::transmute(slice) }
-}
-
-pub(crate) fn slice_ptr_parts_mut(slice: *mut [T]) -> (*mut T, usize) {
- unsafe { mem::transmute(slice) }
-}
-
/// Does this slice reside entirely within RAM?
pub(crate) fn slice_in_ram(slice: *const [T]) -> bool {
- let (ptr, len) = slice_ptr_parts(slice);
- let ptr = ptr as usize;
- ptr >= SRAM_LOWER && (ptr + len * core::mem::size_of::()) < SRAM_UPPER
+ if slice.is_empty() {
+ return true;
+ }
+
+ let ptr = slice as *const T as usize;
+ ptr >= SRAM_LOWER && (ptr + slice.len() * core::mem::size_of::()) < SRAM_UPPER
}
/// Return an error if slice is not in RAM. Skips check if slice is zero-length.
pub(crate) fn slice_in_ram_or(slice: *const [T], err: E) -> Result<(), E> {
- let (_, len) = slice_ptr_parts(slice);
- if len == 0 || slice_in_ram(slice) {
+ if slice_in_ram(slice) {
Ok(())
} else {
Err(err)
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml
index 794f1109c..447c96b4d 100644
--- a/embassy-rp/Cargo.toml
+++ b/embassy-rp/Cargo.toml
@@ -79,11 +79,19 @@ boot2-ram-memcpy = []
boot2-w25q080 = []
## Use boot2 with support for Winbond W25X10CL SPI flash.
boot2-w25x10cl = []
+## Have embassy not provide the boot2 so you can use your own.
+## Place your own in the ".boot2" section like:
+## ```
+## #[link_section = ".boot2"]
+## #[used]
+## static BOOT2: [u8; 256] = [0; 256]; // Provide your own with e.g. include_bytes!
+## ```
+boot2-none = []
[dependencies]
-embassy-sync = { version = "0.5.0", path = "../embassy-sync" }
+embassy-sync = { version = "0.6.0", path = "../embassy-sync" }
embassy-time-driver = { version = "0.1", path = "../embassy-time-driver", optional = true }
-embassy-time = { version = "0.3.0", path = "../embassy-time" }
+embassy-time = { version = "0.3.1", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-2"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
@@ -96,7 +104,6 @@ cfg-if = "1.0.0"
cortex-m-rt = ">=0.6.15,<0.8"
cortex-m = "0.7.6"
critical-section = "1.1"
-futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
chrono = { version = "0.4", default-features = false, optional = true }
embedded-io = { version = "0.6.1" }
embedded-io-async = { version = "0.6.1" }
diff --git a/embassy-rp/src/adc.rs b/embassy-rp/src/adc.rs
index 4c01fe195..eb1cc9a66 100644
--- a/embassy-rp/src/adc.rs
+++ b/embassy-rp/src/adc.rs
@@ -8,8 +8,7 @@ use core::task::Poll;
use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
-use crate::gpio::sealed::Pin as GpioPin;
-use crate::gpio::{self, AnyPin, Pull};
+use crate::gpio::{self, AnyPin, Pull, SealedPin as GpioPin};
use crate::interrupt::typelevel::Binding;
use crate::interrupt::InterruptExt;
use crate::peripherals::{ADC, ADC_TEMP_SENSOR};
@@ -220,18 +219,30 @@ impl<'d> Adc<'d, Async> {
}
}
+ // Note for refactoring: we don't require the actual Channels here, just the channel numbers.
+ // The public api is responsible for asserting ownership of the actual Channels.
async fn read_many_inner(
&mut self,
- ch: &mut Channel<'_>,
+ channels: impl Iterator- ,
buf: &mut [W],
fcs_err: bool,
div: u16,
dma: impl Peripheral
,
) -> Result<(), Error> {
+ let mut rrobin = 0_u8;
+ for c in channels {
+ rrobin |= 1 << c;
+ }
+ let first_ch = rrobin.trailing_zeros() as u8;
+ if rrobin.count_ones() == 1 {
+ rrobin = 0;
+ }
+
let r = Self::regs();
// clear previous errors and set channel
r.cs().modify(|w| {
- w.set_ainsel(ch.channel());
+ w.set_ainsel(first_ch);
+ w.set_rrobin(rrobin);
w.set_err_sticky(true); // clear previous errors
w.set_start_many(false);
});
@@ -284,7 +295,49 @@ impl<'d> Adc<'d, Async> {
}
}
+ /// Sample multiple values from multiple channels using DMA.
+ /// Samples are stored in an interleaved fashion inside the buffer.
+ /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate * num_channels - 1)`
+ /// Any `div` value of less than 96 will have the same effect as setting it to 0
+ #[inline]
+ pub async fn read_many_multichannel(
+ &mut self,
+ ch: &mut [Channel<'_>],
+ buf: &mut [S],
+ div: u16,
+ dma: impl Peripheral,
+ ) -> Result<(), Error> {
+ self.read_many_inner(ch.iter().map(|c| c.channel()), buf, false, div, dma)
+ .await
+ }
+
+ /// Sample multiple values from multiple channels using DMA, with errors inlined in samples.
+ /// Samples are stored in an interleaved fashion inside the buffer.
+ /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate * num_channels - 1)`
+ /// Any `div` value of less than 96 will have the same effect as setting it to 0
+ #[inline]
+ pub async fn read_many_multichannel_raw(
+ &mut self,
+ ch: &mut [Channel<'_>],
+ buf: &mut [Sample],
+ div: u16,
+ dma: impl Peripheral
,
+ ) {
+ // errors are reported in individual samples
+ let _ = self
+ .read_many_inner(
+ ch.iter().map(|c| c.channel()),
+ unsafe { mem::transmute::<_, &mut [u16]>(buf) },
+ true,
+ div,
+ dma,
+ )
+ .await;
+ }
+
/// Sample multiple values from a channel using DMA.
+ /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate - 1)`
+ /// Any `div` value of less than 96 will have the same effect as setting it to 0
#[inline]
pub async fn read_many(
&mut self,
@@ -293,10 +346,13 @@ impl<'d> Adc<'d, Async> {
div: u16,
dma: impl Peripheral,
) -> Result<(), Error> {
- self.read_many_inner(ch, buf, false, div, dma).await
+ self.read_many_inner([ch.channel()].into_iter(), buf, false, div, dma)
+ .await
}
- /// Sample multiple values from a channel using DMA with errors inlined in samples.
+ /// Sample multiple values from a channel using DMA, with errors inlined in samples.
+ /// `div` is the integer part of the clock divider and can be calculated with `floor(48MHz / sample_rate - 1)`
+ /// Any `div` value of less than 96 will have the same effect as setting it to 0
#[inline]
pub async fn read_many_raw(
&mut self,
@@ -307,7 +363,13 @@ impl<'d> Adc<'d, Async> {
) {
// errors are reported in individual samples
let _ = self
- .read_many_inner(ch, unsafe { mem::transmute::<_, &mut [u16]>(buf) }, true, div, dma)
+ .read_many_inner(
+ [ch.channel()].into_iter(),
+ unsafe { mem::transmute::<_, &mut [u16]>(buf) },
+ true,
+ div,
+ dma,
+ )
.await;
}
}
@@ -334,29 +396,28 @@ impl interrupt::typelevel::Handler for Inter
}
}
-mod sealed {
- pub trait AdcSample: crate::dma::Word {}
-
- pub trait AdcChannel {}
-}
+trait SealedAdcSample: crate::dma::Word {}
+trait SealedAdcChannel {}
/// ADC sample.
-pub trait AdcSample: sealed::AdcSample {}
+#[allow(private_bounds)]
+pub trait AdcSample: SealedAdcSample {}
-impl sealed::AdcSample for u16 {}
+impl SealedAdcSample for u16 {}
impl AdcSample for u16 {}
-impl sealed::AdcSample for u8 {}
+impl SealedAdcSample for u8 {}
impl AdcSample for u8 {}
/// ADC channel.
-pub trait AdcChannel: sealed::AdcChannel {}
+#[allow(private_bounds)]
+pub trait AdcChannel: SealedAdcChannel {}
/// ADC pin.
pub trait AdcPin: AdcChannel + gpio::Pin {}
macro_rules! impl_pin {
($pin:ident, $channel:expr) => {
- impl sealed::AdcChannel for peripherals::$pin {}
+ impl SealedAdcChannel for peripherals::$pin {}
impl AdcChannel for peripherals::$pin {}
impl AdcPin for peripherals::$pin {}
};
@@ -367,5 +428,5 @@ impl_pin!(PIN_27, 1);
impl_pin!(PIN_28, 2);
impl_pin!(PIN_29, 3);
-impl sealed::AdcChannel for peripherals::ADC_TEMP_SENSOR {}
+impl SealedAdcChannel for peripherals::ADC_TEMP_SENSOR {}
impl AdcChannel for peripherals::ADC_TEMP_SENSOR {}
diff --git a/embassy-rp/src/clocks.rs b/embassy-rp/src/clocks.rs
index b7f6aeac9..d0c6c19bd 100644
--- a/embassy-rp/src/clocks.rs
+++ b/embassy-rp/src/clocks.rs
@@ -6,8 +6,7 @@ use core::sync::atomic::{AtomicU16, AtomicU32, Ordering};
use embassy_hal_internal::{into_ref, PeripheralRef};
use pac::clocks::vals::*;
-use crate::gpio::sealed::Pin;
-use crate::gpio::AnyPin;
+use crate::gpio::{AnyPin, SealedPin};
use crate::pac::common::{Reg, RW};
use crate::{pac, reset, Peripheral};
@@ -715,10 +714,6 @@ pub fn clk_rtc_freq() -> u16 {
}
fn start_xosc(crystal_hz: u32, delay_multiplier: u32) {
- pac::XOSC
- .ctrl()
- .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
-
let startup_delay = (((crystal_hz / 1000) * delay_multiplier) + 128) / 256;
pac::XOSC.startup().write(|w| w.set_delay(startup_delay as u16));
pac::XOSC.ctrl().write(|w| {
@@ -788,14 +783,14 @@ impl_gpinpin!(PIN_20, 20, 0);
impl_gpinpin!(PIN_22, 22, 1);
/// General purpose clock input driver.
-pub struct Gpin<'d, T: Pin> {
+pub struct Gpin<'d, T: GpinPin> {
gpin: PeripheralRef<'d, AnyPin>,
_phantom: PhantomData,
}
-impl<'d, T: Pin> Gpin<'d, T> {
+impl<'d, T: GpinPin> Gpin<'d, T> {
/// Create new gpin driver.
- pub fn new(gpin: impl Peripheral + 'd) -> Gpin<'d, P> {
+ pub fn new(gpin: impl Peripheral
+ 'd) -> Self {
into_ref!(gpin);
gpin.gpio().ctrl().write(|w| w.set_funcsel(0x08));
@@ -811,7 +806,7 @@ impl<'d, T: Pin> Gpin<'d, T> {
// }
}
-impl<'d, T: Pin> Drop for Gpin<'d, T> {
+impl<'d, T: GpinPin> Drop for Gpin<'d, T> {
fn drop(&mut self) {
self.gpin
.gpio()
@@ -1028,7 +1023,7 @@ pub fn dormant_sleep() {
let _stop_adc = set(pac::CLOCKS.clk_adc_ctrl(), |w| w.set_enable(false));
let _stop_usb = set(pac::CLOCKS.clk_usb_ctrl(), |w| w.set_enable(false));
let _stop_peri = set(pac::CLOCKS.clk_peri_ctrl(), |w| w.set_enable(false));
- // set up rosc. we could ask the use to tell us which clock source to wake from like
+ // set up rosc. we could ask the user to tell us which clock source to wake from like
// the C SDK does, but that seems rather unfriendly. we *may* disturb rtc by changing
// rosc configuration if it's currently the rtc clock source, so we'll configure rosc
// to the slowest frequency to minimize that impact.
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 44aabce6b..8c04b43a1 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -47,12 +47,11 @@ pub unsafe fn read<'a, C: Channel, W: Word>(
to: *mut [W],
dreq: u8,
) -> Transfer<'a, C> {
- let (to_ptr, len) = crate::dma::slice_ptr_parts(to);
copy_inner(
ch,
from as *const u32,
- to_ptr as *mut u32,
- len,
+ to as *mut W as *mut u32,
+ to.len(),
W::size(),
false,
true,
@@ -69,12 +68,11 @@ pub unsafe fn write<'a, C: Channel, W: Word>(
to: *mut W,
dreq: u8,
) -> Transfer<'a, C> {
- let (from_ptr, len) = crate::dma::slice_ptr_parts(from);
copy_inner(
ch,
- from_ptr as *const u32,
+ from as *const W as *const u32,
to as *mut u32,
- len,
+ from.len(),
W::size(),
true,
false,
@@ -114,13 +112,13 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(
from: &[W],
to: &mut [W],
) -> Transfer<'a, C> {
- let (from_ptr, from_len) = crate::dma::slice_ptr_parts(from);
- let (to_ptr, to_len) = crate::dma::slice_ptr_parts_mut(to);
+ let from_len = from.len();
+ let to_len = to.len();
assert_eq!(from_len, to_len);
copy_inner(
ch,
- from_ptr as *const u32,
- to_ptr as *mut u32,
+ from.as_ptr() as *const u32,
+ to.as_mut_ptr() as *mut u32,
from_len,
W::size(),
true,
@@ -208,14 +206,12 @@ pub(crate) const CHANNEL_COUNT: usize = 12;
const NEW_AW: AtomicWaker = AtomicWaker::new();
static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [NEW_AW; CHANNEL_COUNT];
-mod sealed {
- pub trait Channel {}
-
- pub trait Word {}
-}
+trait SealedChannel {}
+trait SealedWord {}
/// DMA channel interface.
-pub trait Channel: Peripheral
+ sealed::Channel + Into + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Channel: Peripheral + SealedChannel + Into + Sized + 'static {
/// Channel number.
fn number(&self) -> u8;
@@ -231,26 +227,27 @@ pub trait Channel: Peripheral + sealed::Channel + Into + S
}
/// DMA word.
-pub trait Word: sealed::Word {
+#[allow(private_bounds)]
+pub trait Word: SealedWord {
/// Word size.
fn size() -> vals::DataSize;
}
-impl sealed::Word for u8 {}
+impl SealedWord for u8 {}
impl Word for u8 {
fn size() -> vals::DataSize {
vals::DataSize::SIZE_BYTE
}
}
-impl sealed::Word for u16 {}
+impl SealedWord for u16 {}
impl Word for u16 {
fn size() -> vals::DataSize {
vals::DataSize::SIZE_HALFWORD
}
}
-impl sealed::Word for u32 {}
+impl SealedWord for u32 {}
impl Word for u32 {
fn size() -> vals::DataSize {
vals::DataSize::SIZE_WORD
@@ -264,7 +261,7 @@ pub struct AnyChannel {
impl_peripheral!(AnyChannel);
-impl sealed::Channel for AnyChannel {}
+impl SealedChannel for AnyChannel {}
impl Channel for AnyChannel {
fn number(&self) -> u8 {
self.number
@@ -273,7 +270,7 @@ impl Channel for AnyChannel {
macro_rules! channel {
($name:ident, $num:expr) => {
- impl sealed::Channel for peripherals::$name {}
+ impl SealedChannel for peripherals::$name {}
impl Channel for peripherals::$name {
fn number(&self) -> u8 {
$num
@@ -288,17 +285,6 @@ macro_rules! channel {
};
}
-// TODO: replace transmutes with core::ptr::metadata once it's stable
-#[allow(unused)]
-pub(crate) fn slice_ptr_parts(slice: *const [T]) -> (usize, usize) {
- unsafe { core::mem::transmute(slice) }
-}
-
-#[allow(unused)]
-pub(crate) fn slice_ptr_parts_mut(slice: *mut [T]) -> (usize, usize) {
- unsafe { core::mem::transmute(slice) }
-}
-
channel!(DMA_CH0, 0);
channel!(DMA_CH1, 1);
channel!(DMA_CH2, 2);
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs
index 422b77400..6e2a823d8 100644
--- a/embassy-rp/src/flash.rs
+++ b/embassy-rp/src/flash.rs
@@ -374,6 +374,11 @@ impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> ReadNorFlash for Flash<'
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> MultiwriteNorFlash for Flash<'d, T, M, FLASH_SIZE> {}
+impl<'d, T: Instance, const FLASH_SIZE: usize> embedded_storage_async::nor_flash::MultiwriteNorFlash
+ for Flash<'d, T, Async, FLASH_SIZE>
+{
+}
+
impl<'d, T: Instance, M: Mode, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, M, FLASH_SIZE> {
const WRITE_SIZE: usize = WRITE_SIZE;
@@ -903,22 +908,22 @@ pub(crate) unsafe fn in_ram(operation: impl FnOnce()) -> Result<(), Error> {
Ok(())
}
-mod sealed {
- pub trait Instance {}
- pub trait Mode {}
-}
+trait SealedInstance {}
+trait SealedMode {}
/// Flash instance.
-pub trait Instance: sealed::Instance {}
+#[allow(private_bounds)]
+pub trait Instance: SealedInstance {}
/// Flash mode.
-pub trait Mode: sealed::Mode {}
+#[allow(private_bounds)]
+pub trait Mode: SealedMode {}
-impl sealed::Instance for FLASH {}
+impl SealedInstance for FLASH {}
impl Instance for FLASH {}
macro_rules! impl_mode {
($name:ident) => {
- impl sealed::Mode for $name {}
+ impl SealedMode for $name {}
impl Mode for $name {}
};
}
diff --git a/embassy-rp/src/fmt.rs b/embassy-rp/src/fmt.rs
index 2ac42c557..35b929fde 100644
--- a/embassy-rp/src/fmt.rs
+++ b/embassy-rp/src/fmt.rs
@@ -6,6 +6,7 @@ use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
+#[collapse_debuginfo(yes)]
macro_rules! assert {
($($x:tt)*) => {
{
@@ -17,6 +18,7 @@ macro_rules! assert {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! assert_eq {
($($x:tt)*) => {
{
@@ -28,6 +30,7 @@ macro_rules! assert_eq {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! assert_ne {
($($x:tt)*) => {
{
@@ -39,6 +42,7 @@ macro_rules! assert_ne {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert {
($($x:tt)*) => {
{
@@ -50,6 +54,7 @@ macro_rules! debug_assert {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert_eq {
($($x:tt)*) => {
{
@@ -61,6 +66,7 @@ macro_rules! debug_assert_eq {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug_assert_ne {
($($x:tt)*) => {
{
@@ -72,6 +78,7 @@ macro_rules! debug_assert_ne {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! todo {
($($x:tt)*) => {
{
@@ -84,6 +91,7 @@ macro_rules! todo {
}
#[cfg(not(feature = "defmt"))]
+#[collapse_debuginfo(yes)]
macro_rules! unreachable {
($($x:tt)*) => {
::core::unreachable!($($x)*)
@@ -91,12 +99,14 @@ macro_rules! unreachable {
}
#[cfg(feature = "defmt")]
+#[collapse_debuginfo(yes)]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
+#[collapse_debuginfo(yes)]
macro_rules! panic {
($($x:tt)*) => {
{
@@ -108,6 +118,7 @@ macro_rules! panic {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -121,6 +132,7 @@ macro_rules! trace {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -134,6 +146,7 @@ macro_rules! debug {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -147,6 +160,7 @@ macro_rules! info {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -160,6 +174,7 @@ macro_rules! warn {
};
}
+#[collapse_debuginfo(yes)]
macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => {
{
@@ -174,6 +189,7 @@ macro_rules! error {
}
#[cfg(feature = "defmt")]
+#[collapse_debuginfo(yes)]
macro_rules! unwrap {
($($x:tt)*) => {
::defmt::unwrap!($($x)*)
@@ -181,6 +197,7 @@ macro_rules! unwrap {
}
#[cfg(not(feature = "defmt"))]
+#[collapse_debuginfo(yes)]
macro_rules! unwrap {
($arg:expr) => {
match $crate::fmt::Try::into_result($arg) {
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index a84c00a2c..ea87fd9da 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -8,7 +8,6 @@ use core::task::{Context, Poll};
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker;
-use self::sealed::Pin as _;
use crate::interrupt::InterruptExt;
use crate::pac::common::{Reg, RW};
use crate::pac::SIO;
@@ -802,68 +801,65 @@ impl<'w> Drop for DormantWake<'w> {
}
}
-pub(crate) mod sealed {
- use super::*;
+pub(crate) trait SealedPin: Sized {
+ fn pin_bank(&self) -> u8;
- pub trait Pin: Sized {
- fn pin_bank(&self) -> u8;
+ #[inline]
+ fn _pin(&self) -> u8 {
+ self.pin_bank() & 0x1f
+ }
- #[inline]
- fn _pin(&self) -> u8 {
- self.pin_bank() & 0x1f
+ #[inline]
+ fn _bank(&self) -> Bank {
+ match self.pin_bank() >> 5 {
+ #[cfg(feature = "qspi-as-gpio")]
+ 1 => Bank::Qspi,
+ _ => Bank::Bank0,
}
+ }
- #[inline]
- fn _bank(&self) -> Bank {
- match self.pin_bank() >> 5 {
- #[cfg(feature = "qspi-as-gpio")]
- 1 => Bank::Qspi,
- _ => Bank::Bank0,
- }
+ fn io(&self) -> pac::io::Io {
+ match self._bank() {
+ Bank::Bank0 => crate::pac::IO_BANK0,
+ #[cfg(feature = "qspi-as-gpio")]
+ Bank::Qspi => crate::pac::IO_QSPI,
}
+ }
- fn io(&self) -> pac::io::Io {
- match self._bank() {
- Bank::Bank0 => crate::pac::IO_BANK0,
- #[cfg(feature = "qspi-as-gpio")]
- Bank::Qspi => crate::pac::IO_QSPI,
- }
- }
+ fn gpio(&self) -> pac::io::Gpio {
+ self.io().gpio(self._pin() as _)
+ }
- fn gpio(&self) -> pac::io::Gpio {
- self.io().gpio(self._pin() as _)
- }
+ fn pad_ctrl(&self) -> Reg {
+ let block = match self._bank() {
+ Bank::Bank0 => crate::pac::PADS_BANK0,
+ #[cfg(feature = "qspi-as-gpio")]
+ Bank::Qspi => crate::pac::PADS_QSPI,
+ };
+ block.gpio(self._pin() as _)
+ }
- fn pad_ctrl(&self) -> Reg {
- let block = match self._bank() {
- Bank::Bank0 => crate::pac::PADS_BANK0,
- #[cfg(feature = "qspi-as-gpio")]
- Bank::Qspi => crate::pac::PADS_QSPI,
- };
- block.gpio(self._pin() as _)
- }
+ fn sio_out(&self) -> pac::sio::Gpio {
+ SIO.gpio_out(self._bank() as _)
+ }
- fn sio_out(&self) -> pac::sio::Gpio {
- SIO.gpio_out(self._bank() as _)
- }
+ fn sio_oe(&self) -> pac::sio::Gpio {
+ SIO.gpio_oe(self._bank() as _)
+ }
- fn sio_oe(&self) -> pac::sio::Gpio {
- SIO.gpio_oe(self._bank() as _)
- }
+ fn sio_in(&self) -> Reg {
+ SIO.gpio_in(self._bank() as _)
+ }
- fn sio_in(&self) -> Reg {
- SIO.gpio_in(self._bank() as _)
- }
-
- fn int_proc(&self) -> pac::io::Int {
- let proc = SIO.cpuid().read();
- self.io().int_proc(proc as _)
- }
+ fn int_proc(&self) -> pac::io::Int {
+ let proc = SIO.cpuid().read();
+ self.io().int_proc(proc as _)
}
}
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
-pub trait Pin: Peripheral + Into + sealed::Pin + Sized + 'static {
+#[allow(private_bounds)]
+pub trait Pin: Peripheral + Into + SealedPin + Sized + 'static {
/// Degrade to a generic pin struct
fn degrade(self) -> AnyPin {
AnyPin {
@@ -903,7 +899,7 @@ impl AnyPin {
impl_peripheral!(AnyPin);
impl Pin for AnyPin {}
-impl sealed::Pin for AnyPin {
+impl SealedPin for AnyPin {
fn pin_bank(&self) -> u8 {
self.pin_bank
}
@@ -914,7 +910,7 @@ impl sealed::Pin for AnyPin {
macro_rules! impl_pin {
($name:ident, $bank:expr, $pin_num:expr) => {
impl Pin for peripherals::$name {}
- impl sealed::Pin for peripherals::$name {
+ impl SealedPin for peripherals::$name {
#[inline]
fn pin_bank(&self) -> u8 {
($bank as u8) * 32 + $pin_num
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 26a819b25..10d3c86b3 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -12,7 +12,7 @@ use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral};
/// I2C error abort reason
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum AbortReason {
/// A bus operation was not acknowledged, e.g. due to the addressed device
@@ -28,7 +28,7 @@ pub enum AbortReason {
}
/// I2C error
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
/// I2C abort with error
@@ -313,25 +313,29 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
}
/// Read from address into buffer using DMA.
- pub async fn read_async(&mut self, addr: u16, buffer: &mut [u8]) -> Result<(), Error> {
- Self::setup(addr)?;
+ pub async fn read_async(&mut self, addr: impl Into, buffer: &mut [u8]) -> Result<(), Error> {
+ Self::setup(addr.into())?;
self.read_async_internal(buffer, true, true).await
}
/// Write to address from buffer using DMA.
- pub async fn write_async(&mut self, addr: u16, bytes: impl IntoIterator- ) -> Result<(), Error> {
- Self::setup(addr)?;
+ pub async fn write_async(
+ &mut self,
+ addr: impl Into,
+ bytes: impl IntoIterator
- ,
+ ) -> Result<(), Error> {
+ Self::setup(addr.into())?;
self.write_async_internal(bytes, true).await
}
/// Write to address from bytes and read from address into buffer using DMA.
pub async fn write_read_async(
&mut self,
- addr: u16,
+ addr: impl Into,
bytes: impl IntoIterator
- ,
buffer: &mut [u8],
) -> Result<(), Error> {
- Self::setup(addr)?;
+ Self::setup(addr.into())?;
self.write_async_internal(bytes, false).await?;
self.read_async_internal(buffer, true, true).await
}
@@ -595,20 +599,20 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
// =========================
/// Read from address into buffer blocking caller until done.
- pub fn blocking_read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Error> {
+ pub fn blocking_read(&mut self, address: impl Into, read: &mut [u8]) -> Result<(), Error> {
Self::setup(address.into())?;
self.read_blocking_internal(read, true, true)
// Automatic Stop
}
/// Write to address from buffer blocking caller until done.
- pub fn blocking_write(&mut self, address: u8, write: &[u8]) -> Result<(), Error> {
+ pub fn blocking_write(&mut self, address: impl Into, write: &[u8]) -> Result<(), Error> {
Self::setup(address.into())?;
self.write_blocking_internal(write, true)
}
/// Write to address from bytes and read from address into buffer blocking caller until done.
- pub fn blocking_write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
+ pub fn blocking_write_read(&mut self, address: impl Into, write: &[u8], read: &mut [u8]) -> Result<(), Error> {
Self::setup(address.into())?;
self.write_blocking_internal(write, false)?;
self.read_blocking_internal(read, true, true)
@@ -719,25 +723,15 @@ where
T: Instance + 'd,
{
async fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> {
- let addr: u16 = address.into();
-
- Self::setup(addr)?;
- self.read_async_internal(read, false, true).await
+ self.read_async(address, read).await
}
async fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> {
- let addr: u16 = address.into();
-
- Self::setup(addr)?;
- self.write_async_internal(write.iter().copied(), true).await
+ self.write_async(address, write.iter().copied()).await
}
async fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
- let addr: u16 = address.into();
-
- Self::setup(addr)?;
- self.write_async_internal(write.iter().cloned(), false).await?;
- self.read_async_internal(read, true, true).await
+ self.write_read_async(address, write.iter().copied(), read).await
}
async fn transaction(
@@ -784,34 +778,24 @@ pub fn i2c_reserved_addr(addr: u16) -> bool {
((addr & 0x78) == 0 || (addr & 0x78) == 0x78) && addr != 0
}
-mod sealed {
- use embassy_sync::waitqueue::AtomicWaker;
+pub(crate) trait SealedInstance {
+ const TX_DREQ: u8;
+ const RX_DREQ: u8;
- use crate::interrupt;
-
- pub trait Instance {
- const TX_DREQ: u8;
- const RX_DREQ: u8;
-
- type Interrupt: interrupt::typelevel::Interrupt;
-
- fn regs() -> crate::pac::i2c::I2c;
- fn reset() -> crate::pac::resets::regs::Peripherals;
- fn waker() -> &'static AtomicWaker;
- }
-
- pub trait Mode {}
-
- pub trait SdaPin {}
- pub trait SclPin {}
+ fn regs() -> crate::pac::i2c::I2c;
+ fn reset() -> crate::pac::resets::regs::Peripherals;
+ fn waker() -> &'static AtomicWaker;
}
+trait SealedMode {}
+
/// Driver mode.
-pub trait Mode: sealed::Mode {}
+#[allow(private_bounds)]
+pub trait Mode: SealedMode {}
macro_rules! impl_mode {
($name:ident) => {
- impl sealed::Mode for $name {}
+ impl SealedMode for $name {}
impl Mode for $name {}
};
}
@@ -825,16 +809,18 @@ impl_mode!(Blocking);
impl_mode!(Async);
/// I2C instance.
-pub trait Instance: sealed::Instance {}
+#[allow(private_bounds)]
+pub trait Instance: SealedInstance {
+ /// Interrupt for this peripheral.
+ type Interrupt: interrupt::typelevel::Interrupt;
+}
macro_rules! impl_instance {
($type:ident, $irq:ident, $reset:ident, $tx_dreq:expr, $rx_dreq:expr) => {
- impl sealed::Instance for peripherals::$type {
+ impl SealedInstance for peripherals::$type {
const TX_DREQ: u8 = $tx_dreq;
const RX_DREQ: u8 = $rx_dreq;
- type Interrupt = crate::interrupt::typelevel::$irq;
-
#[inline]
fn regs() -> pac::i2c::I2c {
pac::$type
@@ -854,7 +840,9 @@ macro_rules! impl_instance {
&WAKER
}
}
- impl Instance for peripherals::$type {}
+ impl Instance for peripherals::$type {
+ type Interrupt = crate::interrupt::typelevel::$irq;
+ }
};
}
@@ -862,13 +850,12 @@ impl_instance!(I2C0, I2C0_IRQ, set_i2c0, 32, 33);
impl_instance!(I2C1, I2C1_IRQ, set_i2c1, 34, 35);
/// SDA pin.
-pub trait SdaPin: sealed::SdaPin + crate::gpio::Pin {}
+pub trait SdaPin: crate::gpio::Pin {}
/// SCL pin.
-pub trait SclPin: sealed::SclPin + crate::gpio::Pin {}
+pub trait SclPin: crate::gpio::Pin {}
macro_rules! impl_pin {
($pin:ident, $instance:ident, $function:ident) => {
- impl sealed::$function for peripherals::$pin {}
impl $function for peripherals::$pin {}
};
}
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs
index e2d4fbac0..c46a55d2e 100644
--- a/embassy-rp/src/i2c_slave.rs
+++ b/embassy-rp/src/i2c_slave.rs
@@ -13,7 +13,7 @@ use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{pac, Peripheral};
/// I2C error
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum Error {
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index d91cea410..471e7f8b1 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -183,14 +183,14 @@ embassy_hal_internal::peripherals! {
DMA_CH10,
DMA_CH11,
- PWM_CH0,
- PWM_CH1,
- PWM_CH2,
- PWM_CH3,
- PWM_CH4,
- PWM_CH5,
- PWM_CH6,
- PWM_CH7,
+ PWM_SLICE0,
+ PWM_SLICE1,
+ PWM_SLICE2,
+ PWM_SLICE3,
+ PWM_SLICE4,
+ PWM_SLICE5,
+ PWM_SLICE6,
+ PWM_SLICE7,
USB,
@@ -210,6 +210,7 @@ embassy_hal_internal::peripherals! {
BOOTSEL,
}
+#[cfg(not(feature = "boot2-none"))]
macro_rules! select_bootloader {
( $( $feature:literal => $loader:ident, )+ default => $default:ident ) => {
$(
@@ -226,6 +227,7 @@ macro_rules! select_bootloader {
}
}
+#[cfg(not(feature = "boot2-none"))]
select_bootloader! {
"boot2-at25sf128a" => BOOT_LOADER_AT25SF128A,
"boot2-gd25q64cs" => BOOT_LOADER_GD25Q64CS,
@@ -352,12 +354,60 @@ pub fn init(config: config::Config) -> Peripherals {
peripherals
}
+#[cfg(feature = "rt")]
+#[cortex_m_rt::pre_init]
+unsafe fn pre_init() {
+ // SIO does not get reset when core0 is reset with either `scb::sys_reset()` or with SWD.
+ // Since we're using SIO spinlock 31 for the critical-section impl, this causes random
+ // hangs if we reset in the middle of a CS, because the next boot sees the spinlock
+ // as locked and waits forever.
+ //
+ // See https://github.com/embassy-rs/embassy/issues/1736
+ // and https://github.com/rp-rs/rp-hal/issues/292
+ // and https://matrix.to/#/!vhKMWjizPZBgKeknOo:matrix.org/$VfOkQgyf1PjmaXZbtycFzrCje1RorAXd8BQFHTl4d5M
+ //
+ // According to Raspberry Pi, this is considered Working As Intended, and not an errata,
+ // even though this behavior is different from every other ARM chip (sys_reset usually resets
+ // the *system* as its name implies, not just the current core).
+ //
+ // To fix this, reset SIO on boot. We must do this in pre_init because it's unsound to do it
+ // in `embassy_rp::init`, since the user could've acquired a CS by then. pre_init is guaranteed
+ // to run before any user code.
+ //
+ // A similar thing could happen with PROC1. It is unclear whether it's possible for PROC1
+ // to stay unreset through a PROC0 reset, so we reset it anyway just in case.
+ //
+ // Important info from PSM logic (from Luke Wren in above Matrix thread)
+ //
+ // The logic is, each PSM stage is reset if either of the following is true:
+ // - The previous stage is in reset and FRCE_ON is false
+ // - FRCE_OFF is true
+ //
+ // The PSM order is SIO -> PROC0 -> PROC1.
+ // So, we have to force-on PROC0 to prevent it from getting reset when resetting SIO.
+ pac::PSM.frce_on().write_and_wait(|w| {
+ w.set_proc0(true);
+ });
+ // Then reset SIO and PROC1.
+ pac::PSM.frce_off().write_and_wait(|w| {
+ w.set_sio(true);
+ w.set_proc1(true);
+ });
+ // clear force_off first, force_on second. The other way around would reset PROC0.
+ pac::PSM.frce_off().write_and_wait(|_| {});
+ pac::PSM.frce_on().write_and_wait(|_| {});
+}
+
/// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes.
+#[allow(unused)]
trait RegExt {
#[allow(unused)]
fn write_xor(&self, f: impl FnOnce(&mut T) -> R) -> R;
fn write_set(&self, f: impl FnOnce(&mut T) -> R) -> R;
fn write_clear(&self, f: impl FnOnce(&mut T) -> R) -> R;
+ fn write_and_wait(&self, f: impl FnOnce(&mut T) -> R) -> R
+ where
+ T: PartialEq;
}
impl RegExt for pac::common::Reg {
@@ -390,4 +440,17 @@ impl RegExt for pac::common::Reg(&self, f: impl FnOnce(&mut T) -> R) -> R
+ where
+ T: PartialEq,
+ {
+ let mut val = Default::default();
+ let res = f(&mut val);
+ unsafe {
+ self.as_ptr().write_volatile(val);
+ while self.as_ptr().read_volatile() != val {}
+ }
+ res
+ }
}
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index 7eca700ba..1f7adbda3 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -15,8 +15,7 @@ use pac::pio::vals::SmExecctrlStatusSel;
use pio::{Program, SideSet, Wrap};
use crate::dma::{Channel, Transfer, Word};
-use crate::gpio::sealed::Pin as SealedPin;
-use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate};
+use crate::gpio::{self, AnyPin, Drive, Level, Pull, SealedPin, SlewRate};
use crate::interrupt::typelevel::{Binding, Handler, Interrupt};
use crate::pac::dma::vals::TreqSel;
use crate::relocate::RelocatedProgram;
@@ -325,6 +324,10 @@ impl<'d, PIO: Instance, const SM: usize> StateMachineRx<'d, PIO, SM> {
}
/// Pull data from RX FIFO.
+ ///
+ /// This function doesn't check if there is data available to be read.
+ /// If the rx FIFO is empty, an undefined value is returned. If you only
+ /// want to pull if data is available, use `try_pull` instead.
pub fn pull(&mut self) -> u32 {
PIO::PIO.rxf(SM).read()
}
@@ -695,6 +698,12 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
}
}
+ /// Set the clock divider for this state machine.
+ pub fn set_clock_divider(&mut self, clock_divider: FixedU32) {
+ let sm = Self::this_sm();
+ sm.clkdiv().write(|w| w.0 = clock_divider.to_bits() << 8);
+ }
+
#[inline(always)]
fn this_sm() -> crate::pac::pio::StateMachine {
PIO::PIO.sm(SM)
@@ -1148,49 +1157,47 @@ fn on_pio_drop() {
}
}
-mod sealed {
- use super::*;
+trait SealedInstance {
+ const PIO_NO: u8;
+ const PIO: &'static crate::pac::pio::Pio;
+ const FUNCSEL: crate::pac::io::vals::Gpio0ctrlFuncsel;
- pub trait PioPin {}
+ #[inline]
+ fn wakers() -> &'static Wakers {
+ const NEW_AW: AtomicWaker = AtomicWaker::new();
+ static WAKERS: Wakers = Wakers([NEW_AW; 12]);
- pub trait Instance {
- const PIO_NO: u8;
- const PIO: &'static crate::pac::pio::Pio;
- const FUNCSEL: crate::pac::io::vals::Gpio0ctrlFuncsel;
- type Interrupt: crate::interrupt::typelevel::Interrupt;
+ &WAKERS
+ }
- #[inline]
- fn wakers() -> &'static Wakers {
- const NEW_AW: AtomicWaker = AtomicWaker::new();
- static WAKERS: Wakers = Wakers([NEW_AW; 12]);
+ #[inline]
+ fn state() -> &'static State {
+ static STATE: State = State {
+ users: AtomicU8::new(0),
+ used_pins: AtomicU32::new(0),
+ };
- &WAKERS
- }
-
- #[inline]
- fn state() -> &'static State {
- static STATE: State = State {
- users: AtomicU8::new(0),
- used_pins: AtomicU32::new(0),
- };
-
- &STATE
- }
+ &STATE
}
}
/// PIO instance.
-pub trait Instance: sealed::Instance + Sized + Unpin {}
+#[allow(private_bounds)]
+pub trait Instance: SealedInstance + Sized + Unpin {
+ /// Interrupt for this peripheral.
+ type Interrupt: crate::interrupt::typelevel::Interrupt;
+}
macro_rules! impl_pio {
($name:ident, $pio:expr, $pac:ident, $funcsel:ident, $irq:ident) => {
- impl sealed::Instance for peripherals::$name {
+ impl SealedInstance for peripherals::$name {
const PIO_NO: u8 = $pio;
const PIO: &'static pac::pio::Pio = &pac::$pac;
const FUNCSEL: pac::io::vals::Gpio0ctrlFuncsel = pac::io::vals::Gpio0ctrlFuncsel::$funcsel;
+ }
+ impl Instance for peripherals::$name {
type Interrupt = crate::interrupt::typelevel::$irq;
}
- impl Instance for peripherals::$name {}
};
}
@@ -1198,12 +1205,11 @@ impl_pio!(PIO0, 0, PIO0, PIO0_0, PIO0_IRQ_0);
impl_pio!(PIO1, 1, PIO1, PIO1_0, PIO1_IRQ_0);
/// PIO pin.
-pub trait PioPin: sealed::PioPin + gpio::Pin {}
+pub trait PioPin: gpio::Pin {}
macro_rules! impl_pio_pin {
($( $pin:ident, )*) => {
$(
- impl sealed::PioPin for peripherals::$pin {}
impl PioPin for peripherals::$pin {}
)*
};
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs
index e6f3b2aa2..c35e76587 100644
--- a/embassy-rp/src/pwm.rs
+++ b/embassy-rp/src/pwm.rs
@@ -6,8 +6,7 @@ use fixed::FixedU16;
use pac::pwm::regs::{ChDiv, Intr};
use pac::pwm::vals::Divmode;
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{AnyPin, Pin as GpioPin};
+use crate::gpio::{AnyPin, Pin as GpioPin, Pull, SealedPin as _};
use crate::{pac, peripherals, RegExt};
/// The configuration of a PWM slice.
@@ -82,23 +81,22 @@ impl From for Divmode {
}
/// PWM driver.
-pub struct Pwm<'d, T: Channel> {
- inner: PeripheralRef<'d, T>,
+pub struct Pwm<'d> {
pin_a: Option>,
pin_b: Option>,
+ slice: usize,
}
-impl<'d, T: Channel> Pwm<'d, T> {
+impl<'d> Pwm<'d> {
fn new_inner(
- inner: impl Peripheral
+ 'd,
+ slice: usize,
a: Option>,
b: Option>,
+ b_pull: Pull,
config: Config,
divmode: Divmode,
) -> Self {
- into_ref!(inner);
-
- let p = inner.regs();
+ let p = pac::PWM.ch(slice);
p.csr().modify(|w| {
w.set_divmode(divmode);
w.set_en(false);
@@ -111,82 +109,118 @@ impl<'d, T: Channel> Pwm<'d, T> {
}
if let Some(pin) = &b {
pin.gpio().ctrl().write(|w| w.set_funcsel(4));
+ pin.pad_ctrl().modify(|w| {
+ w.set_pue(b_pull == Pull::Up);
+ w.set_pde(b_pull == Pull::Down);
+ });
}
Self {
- inner,
+ // inner: p.into(),
pin_a: a,
pin_b: b,
+ slice,
}
}
/// Create PWM driver without any configured pins.
#[inline]
- pub fn new_free(inner: impl Peripheral + 'd, config: Config) -> Self {
- Self::new_inner(inner, None, None, config, Divmode::DIV)
+ pub fn new_free(slice: impl Peripheral + 'd, config: Config) -> Self {
+ into_ref!(slice);
+ Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV)
}
- /// Create PWM driver with a single 'a' as output.
+ /// Create PWM driver with a single 'a' pin as output.
#[inline]
- pub fn new_output_a(
- inner: impl Peripheral
+ 'd,
- a: impl Peripheral
> + 'd,
+ pub fn new_output_a(
+ slice: impl Peripheral + 'd,
+ a: impl Peripheral
> + 'd,
config: Config,
) -> Self {
- into_ref!(a);
- Self::new_inner(inner, Some(a.map_into()), None, config, Divmode::DIV)
+ into_ref!(slice, a);
+ Self::new_inner(
+ slice.number(),
+ Some(a.map_into()),
+ None,
+ Pull::None,
+ config,
+ Divmode::DIV,
+ )
}
/// Create PWM driver with a single 'b' pin as output.
#[inline]
- pub fn new_output_b(
- inner: impl Peripheral
+ 'd,
- b: impl Peripheral
> + 'd,
+ pub fn new_output_b(
+ slice: impl Peripheral + 'd,
+ b: impl Peripheral
> + 'd,
config: Config,
) -> Self {
- into_ref!(b);
- Self::new_inner(inner, None, Some(b.map_into()), config, Divmode::DIV)
+ into_ref!(slice, b);
+ Self::new_inner(
+ slice.number(),
+ None,
+ Some(b.map_into()),
+ Pull::None,
+ config,
+ Divmode::DIV,
+ )
}
/// Create PWM driver with a 'a' and 'b' pins as output.
#[inline]
- pub fn new_output_ab(
- inner: impl Peripheral
+ 'd,
- a: impl Peripheral
> + 'd,
- b: impl Peripheral
> + 'd,
+ pub fn new_output_ab(
+ slice: impl Peripheral + 'd,
+ a: impl Peripheral
> + 'd,
+ b: impl Peripheral
> + 'd,
config: Config,
) -> Self {
- into_ref!(a, b);
- Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, Divmode::DIV)
+ into_ref!(slice, a, b);
+ Self::new_inner(
+ slice.number(),
+ Some(a.map_into()),
+ Some(b.map_into()),
+ Pull::None,
+ config,
+ Divmode::DIV,
+ )
}
/// Create PWM driver with a single 'b' as input pin.
#[inline]
- pub fn new_input(
- inner: impl Peripheral
+ 'd,
- b: impl Peripheral
> + 'd,
+ pub fn new_input(
+ slice: impl Peripheral + 'd,
+ b: impl Peripheral
> + 'd,
+ b_pull: Pull,
mode: InputMode,
config: Config,
) -> Self {
- into_ref!(b);
- Self::new_inner(inner, None, Some(b.map_into()), config, mode.into())
+ into_ref!(slice, b);
+ Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into())
}
/// Create PWM driver with a 'a' and 'b' pins in the desired input mode.
#[inline]
- pub fn new_output_input(
- inner: impl Peripheral
+ 'd,
- a: impl Peripheral
> + 'd,
- b: impl Peripheral
> + 'd,
+ pub fn new_output_input(
+ slice: impl Peripheral + 'd,
+ a: impl Peripheral
> + 'd,
+ b: impl Peripheral
> + 'd,
+ b_pull: Pull,
mode: InputMode,
config: Config,
) -> Self {
- into_ref!(a, b);
- Self::new_inner(inner, Some(a.map_into()), Some(b.map_into()), config, mode.into())
+ into_ref!(slice, a, b);
+ Self::new_inner(
+ slice.number(),
+ Some(a.map_into()),
+ Some(b.map_into()),
+ b_pull,
+ config,
+ mode.into(),
+ )
}
/// Set the PWM config.
pub fn set_config(&mut self, config: &Config) {
- Self::configure(self.inner.regs(), config);
+ Self::configure(pac::PWM.ch(self.slice), config);
}
fn configure(p: pac::pwm::Channel, config: &Config) {
@@ -208,22 +242,22 @@ impl<'d, T: Channel> Pwm<'d, T> {
});
}
- /// Advances a slice’s output phase by one count while it is running
+ /// Advances a slice's output phase by one count while it is running
/// by inserting a pulse into the clock enable. The counter
/// will not count faster than once per cycle.
#[inline]
pub fn phase_advance(&mut self) {
- let p = self.inner.regs();
+ let p = pac::PWM.ch(self.slice);
p.csr().write_set(|w| w.set_ph_adv(true));
while p.csr().read().ph_adv() {}
}
- /// Retards a slice’s output phase by one count while it is running
+ /// Retards a slice's output phase by one count while it is running
/// by deleting a pulse from the clock enable. The counter will not
- /// count backward when clock enable is permenantly low.
+ /// count backward when clock enable is permanently low.
#[inline]
pub fn phase_retard(&mut self) {
- let p = self.inner.regs();
+ let p = pac::PWM.ch(self.slice);
p.csr().write_set(|w| w.set_ph_ret(true));
while p.csr().read().ph_ret() {}
}
@@ -231,13 +265,13 @@ impl<'d, T: Channel> Pwm<'d, T> {
/// Read PWM counter.
#[inline]
pub fn counter(&self) -> u16 {
- self.inner.regs().ctr().read().ctr()
+ pac::PWM.ch(self.slice).ctr().read().ctr()
}
/// Write PWM counter.
#[inline]
pub fn set_counter(&self, ctr: u16) {
- self.inner.regs().ctr().write(|w| w.set_ctr(ctr))
+ pac::PWM.ch(self.slice).ctr().write(|w| w.set_ctr(ctr))
}
/// Wait for channel interrupt.
@@ -261,22 +295,22 @@ impl<'d, T: Channel> Pwm<'d, T> {
#[inline]
fn bit(&self) -> u32 {
- 1 << self.inner.number() as usize
+ 1 << self.slice as usize
}
}
-/// Batch representation of PWM channels.
+/// Batch representation of PWM slices.
pub struct PwmBatch(u32);
impl PwmBatch {
#[inline]
- /// Enable a PWM channel in this batch.
- pub fn enable(&mut self, pwm: &Pwm<'_, impl Channel>) {
+ /// Enable a PWM slice in this batch.
+ pub fn enable(&mut self, pwm: &Pwm<'_>) {
self.0 |= pwm.bit();
}
#[inline]
- /// Enable channels in this batch in a PWM.
+ /// Enable slices in this batch in a PWM.
pub fn set_enabled(enabled: bool, batch: impl FnOnce(&mut PwmBatch)) {
let mut en = PwmBatch(0);
batch(&mut en);
@@ -288,9 +322,9 @@ impl PwmBatch {
}
}
-impl<'d, T: Channel> Drop for Pwm<'d, T> {
+impl<'d> Drop for Pwm<'d> {
fn drop(&mut self) {
- self.inner.regs().csr().write_clear(|w| w.set_en(false));
+ pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false));
if let Some(pin) = &self.pin_a {
pin.gpio().ctrl().write(|w| w.set_funcsel(31));
}
@@ -300,45 +334,39 @@ impl<'d, T: Channel> Drop for Pwm<'d, T> {
}
}
-mod sealed {
- pub trait Channel {}
+trait SealedSlice {}
+
+/// PWM Slice.
+#[allow(private_bounds)]
+pub trait Slice: Peripheral
+ SealedSlice + Sized + 'static {
+ /// Slice number.
+ fn number(&self) -> usize;
}
-/// PWM Channel.
-pub trait Channel: Peripheral
+ sealed::Channel + Sized + 'static {
- /// Channel number.
- fn number(&self) -> u8;
-
- /// Channel register block.
- fn regs(&self) -> pac::pwm::Channel {
- pac::PWM.ch(self.number() as _)
- }
-}
-
-macro_rules! channel {
+macro_rules! slice {
($name:ident, $num:expr) => {
- impl sealed::Channel for peripherals::$name {}
- impl Channel for peripherals::$name {
- fn number(&self) -> u8 {
+ impl SealedSlice for peripherals::$name {}
+ impl Slice for peripherals::$name {
+ fn number(&self) -> usize {
$num
}
}
};
}
-channel!(PWM_CH0, 0);
-channel!(PWM_CH1, 1);
-channel!(PWM_CH2, 2);
-channel!(PWM_CH3, 3);
-channel!(PWM_CH4, 4);
-channel!(PWM_CH5, 5);
-channel!(PWM_CH6, 6);
-channel!(PWM_CH7, 7);
+slice!(PWM_SLICE0, 0);
+slice!(PWM_SLICE1, 1);
+slice!(PWM_SLICE2, 2);
+slice!(PWM_SLICE3, 3);
+slice!(PWM_SLICE4, 4);
+slice!(PWM_SLICE5, 5);
+slice!(PWM_SLICE6, 6);
+slice!(PWM_SLICE7, 7);
-/// PWM Pin A.
-pub trait PwmPinA: GpioPin {}
-/// PWM Pin B.
-pub trait PwmPinB: GpioPin {}
+/// PWM Channel A.
+pub trait ChannelAPin: GpioPin {}
+/// PWM Channel B.
+pub trait ChannelBPin: GpioPin {}
macro_rules! impl_pin {
($pin:ident, $channel:ident, $kind:ident) => {
@@ -346,33 +374,33 @@ macro_rules! impl_pin {
};
}
-impl_pin!(PIN_0, PWM_CH0, PwmPinA);
-impl_pin!(PIN_1, PWM_CH0, PwmPinB);
-impl_pin!(PIN_2, PWM_CH1, PwmPinA);
-impl_pin!(PIN_3, PWM_CH1, PwmPinB);
-impl_pin!(PIN_4, PWM_CH2, PwmPinA);
-impl_pin!(PIN_5, PWM_CH2, PwmPinB);
-impl_pin!(PIN_6, PWM_CH3, PwmPinA);
-impl_pin!(PIN_7, PWM_CH3, PwmPinB);
-impl_pin!(PIN_8, PWM_CH4, PwmPinA);
-impl_pin!(PIN_9, PWM_CH4, PwmPinB);
-impl_pin!(PIN_10, PWM_CH5, PwmPinA);
-impl_pin!(PIN_11, PWM_CH5, PwmPinB);
-impl_pin!(PIN_12, PWM_CH6, PwmPinA);
-impl_pin!(PIN_13, PWM_CH6, PwmPinB);
-impl_pin!(PIN_14, PWM_CH7, PwmPinA);
-impl_pin!(PIN_15, PWM_CH7, PwmPinB);
-impl_pin!(PIN_16, PWM_CH0, PwmPinA);
-impl_pin!(PIN_17, PWM_CH0, PwmPinB);
-impl_pin!(PIN_18, PWM_CH1, PwmPinA);
-impl_pin!(PIN_19, PWM_CH1, PwmPinB);
-impl_pin!(PIN_20, PWM_CH2, PwmPinA);
-impl_pin!(PIN_21, PWM_CH2, PwmPinB);
-impl_pin!(PIN_22, PWM_CH3, PwmPinA);
-impl_pin!(PIN_23, PWM_CH3, PwmPinB);
-impl_pin!(PIN_24, PWM_CH4, PwmPinA);
-impl_pin!(PIN_25, PWM_CH4, PwmPinB);
-impl_pin!(PIN_26, PWM_CH5, PwmPinA);
-impl_pin!(PIN_27, PWM_CH5, PwmPinB);
-impl_pin!(PIN_28, PWM_CH6, PwmPinA);
-impl_pin!(PIN_29, PWM_CH6, PwmPinB);
+impl_pin!(PIN_0, PWM_SLICE0, ChannelAPin);
+impl_pin!(PIN_1, PWM_SLICE0, ChannelBPin);
+impl_pin!(PIN_2, PWM_SLICE1, ChannelAPin);
+impl_pin!(PIN_3, PWM_SLICE1, ChannelBPin);
+impl_pin!(PIN_4, PWM_SLICE2, ChannelAPin);
+impl_pin!(PIN_5, PWM_SLICE2, ChannelBPin);
+impl_pin!(PIN_6, PWM_SLICE3, ChannelAPin);
+impl_pin!(PIN_7, PWM_SLICE3, ChannelBPin);
+impl_pin!(PIN_8, PWM_SLICE4, ChannelAPin);
+impl_pin!(PIN_9, PWM_SLICE4, ChannelBPin);
+impl_pin!(PIN_10, PWM_SLICE5, ChannelAPin);
+impl_pin!(PIN_11, PWM_SLICE5, ChannelBPin);
+impl_pin!(PIN_12, PWM_SLICE6, ChannelAPin);
+impl_pin!(PIN_13, PWM_SLICE6, ChannelBPin);
+impl_pin!(PIN_14, PWM_SLICE7, ChannelAPin);
+impl_pin!(PIN_15, PWM_SLICE7, ChannelBPin);
+impl_pin!(PIN_16, PWM_SLICE0, ChannelAPin);
+impl_pin!(PIN_17, PWM_SLICE0, ChannelBPin);
+impl_pin!(PIN_18, PWM_SLICE1, ChannelAPin);
+impl_pin!(PIN_19, PWM_SLICE1, ChannelBPin);
+impl_pin!(PIN_20, PWM_SLICE2, ChannelAPin);
+impl_pin!(PIN_21, PWM_SLICE2, ChannelBPin);
+impl_pin!(PIN_22, PWM_SLICE3, ChannelAPin);
+impl_pin!(PIN_23, PWM_SLICE3, ChannelBPin);
+impl_pin!(PIN_24, PWM_SLICE4, ChannelAPin);
+impl_pin!(PIN_25, PWM_SLICE4, ChannelBPin);
+impl_pin!(PIN_26, PWM_SLICE5, ChannelAPin);
+impl_pin!(PIN_27, PWM_SLICE5, ChannelBPin);
+impl_pin!(PIN_28, PWM_SLICE6, ChannelAPin);
+impl_pin!(PIN_29, PWM_SLICE6, ChannelBPin);
diff --git a/embassy-rp/src/rtc/datetime_chrono.rs b/embassy-rp/src/rtc/datetime_chrono.rs
index b3c78dd47..2818e46af 100644
--- a/embassy-rp/src/rtc/datetime_chrono.rs
+++ b/embassy-rp/src/rtc/datetime_chrono.rs
@@ -10,7 +10,7 @@ pub type DayOfWeek = chrono::Weekday;
/// Errors regarding the [`DateTime`] and [`DateTimeFilter`] structs.
///
/// [`DateTimeFilter`]: struct.DateTimeFilter.html
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Error {
/// The [DateTime] has an invalid year. The year must be between 0 and 4095.
InvalidYear,
diff --git a/embassy-rp/src/rtc/datetime_no_deps.rs b/embassy-rp/src/rtc/datetime_no_deps.rs
index ea899c339..5de00e6b4 100644
--- a/embassy-rp/src/rtc/datetime_no_deps.rs
+++ b/embassy-rp/src/rtc/datetime_no_deps.rs
@@ -3,7 +3,7 @@ use crate::pac::rtc::regs::{Rtc0, Rtc1, Setup0, Setup1};
/// Errors regarding the [`DateTime`] and [`DateTimeFilter`] structs.
///
/// [`DateTimeFilter`]: struct.DateTimeFilter.html
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Error {
/// The [DateTime] contains an invalid year value. Must be between `0..=4095`.
InvalidYear,
diff --git a/embassy-rp/src/rtc/mod.rs b/embassy-rp/src/rtc/mod.rs
index c8691bdc2..2ce7ac645 100644
--- a/embassy-rp/src/rtc/mod.rs
+++ b/embassy-rp/src/rtc/mod.rs
@@ -188,16 +188,15 @@ pub enum RtcError {
NotRunning,
}
-mod sealed {
- pub trait Instance {
- fn regs(&self) -> crate::pac::rtc::Rtc;
- }
+trait SealedInstance {
+ fn regs(&self) -> crate::pac::rtc::Rtc;
}
/// RTC peripheral instance.
-pub trait Instance: sealed::Instance {}
+#[allow(private_bounds)]
+pub trait Instance: SealedInstance {}
-impl sealed::Instance for crate::peripherals::RTC {
+impl SealedInstance for crate::peripherals::RTC {
fn regs(&self) -> crate::pac::rtc::Rtc {
crate::pac::RTC
}
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs
index a2a22ffe5..1617c144c 100644
--- a/embassy-rp/src/spi.rs
+++ b/embassy-rp/src/spi.rs
@@ -7,8 +7,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
pub use embedded_hal_02::spi::{Phase, Polarity};
use crate::dma::{AnyChannel, Channel};
-use crate::gpio::sealed::Pin as _;
-use crate::gpio::{AnyPin, Pin as GpioPin};
+use crate::gpio::{AnyPin, Pin as GpioPin, SealedPin as _};
use crate::{pac, peripherals, Peripheral};
/// SPI errors.
@@ -395,17 +394,14 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
self.transfer_inner(words, words).await
}
- async fn transfer_inner(&mut self, rx_ptr: *mut [u8], tx_ptr: *const [u8]) -> Result<(), Error> {
- let (_, tx_len) = crate::dma::slice_ptr_parts(tx_ptr);
- let (_, rx_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
-
+ async fn transfer_inner(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
// Start RX first. Transfer starts when TX starts, if RX
// is not started yet we might lose bytes.
let rx_ch = self.rx_dma.as_mut().unwrap();
let rx_transfer = unsafe {
// If we don't assign future to a variable, the data register pointer
// is held across an await and makes the future non-Send.
- crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx_ptr, T::RX_DREQ)
+ crate::dma::read(rx_ch, self.inner.regs().dr().as_ptr() as *const _, rx, T::RX_DREQ)
};
let mut tx_ch = self.tx_dma.as_mut().unwrap();
@@ -414,10 +410,10 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
let tx_transfer = async {
let p = self.inner.regs();
unsafe {
- crate::dma::write(&mut tx_ch, tx_ptr, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
+ crate::dma::write(&mut tx_ch, tx, p.dr().as_ptr() as *mut _, T::TX_DREQ).await;
- if rx_len > tx_len {
- let write_bytes_len = rx_len - tx_len;
+ if rx.len() > tx.len() {
+ let write_bytes_len = rx.len() - tx.len();
// write dummy data
// this will disable incrementation of the buffers
crate::dma::write_repeated(tx_ch, p.dr().as_ptr() as *mut u8, write_bytes_len, T::TX_DREQ).await
@@ -427,7 +423,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
join(tx_transfer, rx_transfer).await;
// if tx > rx we should clear any overflow of the FIFO SPI buffer
- if tx_len > rx_len {
+ if tx.len() > rx.len() {
let p = self.inner.regs();
while p.sr().read().bsy() {}
@@ -443,28 +439,26 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
}
}
-mod sealed {
- use super::*;
+trait SealedMode {}
- pub trait Mode {}
+trait SealedInstance {
+ const TX_DREQ: u8;
+ const RX_DREQ: u8;
- pub trait Instance {
- const TX_DREQ: u8;
- const RX_DREQ: u8;
-
- fn regs(&self) -> pac::spi::Spi;
- }
+ fn regs(&self) -> pac::spi::Spi;
}
/// Mode.
-pub trait Mode: sealed::Mode {}
+#[allow(private_bounds)]
+pub trait Mode: SealedMode {}
/// SPI instance trait.
-pub trait Instance: sealed::Instance {}
+#[allow(private_bounds)]
+pub trait Instance: SealedInstance {}
macro_rules! impl_instance {
($type:ident, $irq:ident, $tx_dreq:expr, $rx_dreq:expr) => {
- impl sealed::Instance for peripherals::$type {
+ impl SealedInstance for peripherals::$type {
const TX_DREQ: u8 = $tx_dreq;
const RX_DREQ: u8 = $rx_dreq;
@@ -527,7 +521,7 @@ impl_pin!(PIN_29, SPI1, CsPin);
macro_rules! impl_mode {
($name:ident) => {
- impl sealed::Mode for $name {}
+ impl SealedMode for $name {}
impl Mode for $name {}
};
}
diff --git a/embassy-rp/src/uart/buffered.rs b/embassy-rp/src/uart/buffered.rs
index da1157984..c94164040 100644
--- a/embassy-rp/src/uart/buffered.rs
+++ b/embassy-rp/src/uart/buffered.rs
@@ -51,14 +51,20 @@ pub struct BufferedUartTx<'d, T: Instance> {
pub(crate) fn init_buffers<'d, T: Instance + 'd>(
_irq: impl Binding>,
- tx_buffer: &'d mut [u8],
- rx_buffer: &'d mut [u8],
+ tx_buffer: Option<&'d mut [u8]>,
+ rx_buffer: Option<&'d mut [u8]>,
) {
let state = T::buffered_state();
- let len = tx_buffer.len();
- unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
- let len = rx_buffer.len();
- unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
+
+ if let Some(tx_buffer) = tx_buffer {
+ let len = tx_buffer.len();
+ unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
+ }
+
+ if let Some(rx_buffer) = rx_buffer {
+ let len = rx_buffer.len();
+ unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
+ }
// From the datasheet:
// "The transmit interrupt is based on a transition through a level, rather
@@ -95,7 +101,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
into_ref!(tx, rx);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
- init_buffers::(irq, tx_buffer, rx_buffer);
+ init_buffers::(irq, Some(tx_buffer), Some(rx_buffer));
Self {
rx: BufferedUartRx { phantom: PhantomData },
@@ -124,7 +130,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
Some(cts.map_into()),
config,
);
- init_buffers::(irq, tx_buffer, rx_buffer);
+ init_buffers::(irq, Some(tx_buffer), Some(rx_buffer));
Self {
rx: BufferedUartRx { phantom: PhantomData },
@@ -175,7 +181,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
into_ref!(rx);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
- init_buffers::(irq, &mut [], rx_buffer);
+ init_buffers::(irq, None, Some(rx_buffer));
Self { phantom: PhantomData }
}
@@ -192,7 +198,7 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
into_ref!(rx, rts);
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
- init_buffers::(irq, &mut [], rx_buffer);
+ init_buffers::(irq, None, Some(rx_buffer));
Self { phantom: PhantomData }
}
@@ -323,7 +329,7 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
into_ref!(tx);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
- init_buffers::(irq, tx_buffer, &mut []);
+ init_buffers::(irq, Some(tx_buffer), None);
Self { phantom: PhantomData }
}
@@ -340,12 +346,12 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
into_ref!(tx, cts);
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
- init_buffers::(irq, tx_buffer, &mut []);
+ init_buffers::(irq, Some(tx_buffer), None);
Self { phantom: PhantomData }
}
- fn write<'a>(buf: &'a [u8]) -> impl Future