Remove DerefMut from PeripheralRef (#3017)

This commit is contained in:
Dániel Buga 2025-01-24 10:13:19 +01:00 committed by GitHub
parent f247b4099c
commit 24f8458183
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 185 additions and 208 deletions

View File

@ -155,7 +155,7 @@ pub(crate) fn connect_input_signal(
} }
fn connect_pin_to_input_signal( fn connect_pin_to_input_signal(
pin: &mut AnyPin, pin: &AnyPin,
signal: gpio::InputSignal, signal: gpio::InputSignal,
is_inverted: bool, is_inverted: bool,
force_gpio: bool, force_gpio: bool,
@ -176,7 +176,7 @@ fn connect_pin_to_input_signal(
} }
fn connect_peripheral_to_output( fn connect_peripheral_to_output(
pin: &mut AnyPin, pin: &AnyPin,
signal: gpio::OutputSignal, signal: gpio::OutputSignal,
is_inverted: bool, is_inverted: bool,
force_gpio: bool, force_gpio: bool,
@ -217,7 +217,7 @@ fn connect_peripheral_to_output(
}); });
} }
fn disconnect_peripheral_output_from_pin(pin: &mut AnyPin, signal: gpio::OutputSignal) { fn disconnect_peripheral_output_from_pin(pin: &AnyPin, signal: gpio::OutputSignal) {
pin.set_alternate_function(GPIO_FUNCTION); pin.set_alternate_function(GPIO_FUNCTION);
GPIO::regs() GPIO::regs()
@ -307,8 +307,8 @@ impl InputSignal {
/// Since there can only be one input signal connected to a peripheral at a /// Since there can only be one input signal connected to a peripheral at a
/// time, this function will disconnect any previously connected input /// time, this function will disconnect any previously connected input
/// signals. /// signals.
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal) { fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&mut self.pin, signal, self.is_inverted, true); connect_pin_to_input_signal(&self.pin, signal, self.is_inverted, true);
} }
delegate::delegate! { delegate::delegate! {
@ -318,7 +318,7 @@ impl InputSignal {
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)]; pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
pub fn init_input(&self, pull: Pull); pub fn init_input(&self, pull: Pull);
pub fn is_input_high(&self) -> bool; pub fn is_input_high(&self) -> bool;
pub fn enable_input(&mut self, on: bool); pub fn enable_input(&self, on: bool);
} }
} }
} }
@ -346,8 +346,8 @@ impl DirectInputSignal {
/// Since there can only be one input signal connected to a peripheral at a /// Since there can only be one input signal connected to a peripheral at a
/// time, this function will disconnect any previously connected input /// time, this function will disconnect any previously connected input
/// signals. /// signals.
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal) { fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&mut self.pin, signal, false, false); connect_pin_to_input_signal(&self.pin, signal, false, false);
} }
delegate::delegate! { delegate::delegate! {
@ -356,7 +356,7 @@ impl DirectInputSignal {
fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)]; fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
fn init_input(&self, pull: Pull); fn init_input(&self, pull: Pull);
fn is_input_high(&self) -> bool; fn is_input_high(&self) -> bool;
fn enable_input(&mut self, on: bool); fn enable_input(&self, on: bool);
} }
} }
} }
@ -428,8 +428,8 @@ impl OutputSignal {
} }
/// Connect the pin to a peripheral output signal. /// Connect the pin to a peripheral output signal.
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal) { fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&mut self.pin, signal, self.is_inverted, true, true, false); connect_peripheral_to_output(&self.pin, signal, self.is_inverted, true, true, false);
} }
/// Remove this output pin from a connected [signal](`gpio::OutputSignal`). /// Remove this output pin from a connected [signal](`gpio::OutputSignal`).
@ -437,8 +437,8 @@ impl OutputSignal {
/// Clears the entry in the GPIO matrix / Io mux that associates this output /// Clears the entry in the GPIO matrix / Io mux that associates this output
/// pin with a previously connected [signal](`gpio::OutputSignal`). Any /// pin with a previously connected [signal](`gpio::OutputSignal`). Any
/// other outputs connected to the peripheral remain intact. /// other outputs connected to the peripheral remain intact.
fn disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal) { fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&mut self.pin, signal); disconnect_peripheral_output_from_pin(&self.pin, signal);
} }
delegate::delegate! { delegate::delegate! {
@ -448,15 +448,15 @@ impl OutputSignal {
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)]; pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
pub fn init_input(&self, pull: Pull); pub fn init_input(&self, pull: Pull);
pub fn is_input_high(&self) -> bool; pub fn is_input_high(&self) -> bool;
pub fn enable_input(&mut self, on: bool); pub fn enable_input(&self, on: bool);
pub fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)]; pub fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)];
pub fn set_to_open_drain_output(&mut self); pub fn set_to_open_drain_output(&self);
pub fn set_to_push_pull_output(&mut self); pub fn set_to_push_pull_output(&self);
pub fn enable_output(&mut self, on: bool); pub fn enable_output(&self, on: bool);
pub fn set_output_high(&mut self, on: bool); pub fn set_output_high(&self, on: bool);
pub fn set_drive_strength(&mut self, strength: gpio::DriveStrength); pub fn set_drive_strength(&self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&mut self, on: bool); pub fn enable_open_drain(&self, on: bool);
pub fn is_set_high(&self) -> bool; pub fn is_set_high(&self) -> bool;
} }
} }
@ -475,8 +475,8 @@ impl DirectOutputSignal {
} }
/// Connect the pin to a peripheral output signal. /// Connect the pin to a peripheral output signal.
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal) { fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&mut self.pin, signal, false, false, true, false); connect_peripheral_to_output(&self.pin, signal, false, false, true, false);
} }
/// Remove this output pin from a connected [signal](`gpio::OutputSignal`). /// Remove this output pin from a connected [signal](`gpio::OutputSignal`).
@ -484,8 +484,8 @@ impl DirectOutputSignal {
/// Clears the entry in the GPIO matrix / Io mux that associates this output /// Clears the entry in the GPIO matrix / Io mux that associates this output
/// pin with a previously connected [signal](`gpio::OutputSignal`). Any /// pin with a previously connected [signal](`gpio::OutputSignal`). Any
/// other outputs connected to the peripheral remain intact. /// other outputs connected to the peripheral remain intact.
fn disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal) { fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&mut self.pin, signal); disconnect_peripheral_output_from_pin(&self.pin, signal);
} }
delegate::delegate! { delegate::delegate! {
@ -494,15 +494,15 @@ impl DirectOutputSignal {
fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)]; fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
fn init_input(&self, pull: Pull); fn init_input(&self, pull: Pull);
fn is_input_high(&self) -> bool; fn is_input_high(&self) -> bool;
fn enable_input(&mut self, on: bool); fn enable_input(&self, on: bool);
fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)]; fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)];
fn set_to_open_drain_output(&mut self); fn set_to_open_drain_output(&self);
fn set_to_push_pull_output(&mut self); fn set_to_push_pull_output(&self);
fn enable_output(&mut self, on: bool); fn enable_output(&self, on: bool);
fn set_output_high(&mut self, on: bool); fn set_output_high(&self, on: bool);
fn set_drive_strength(&mut self, strength: gpio::DriveStrength); fn set_drive_strength(&self, strength: gpio::DriveStrength);
fn enable_open_drain(&mut self, on: bool); fn enable_open_drain(&self, on: bool);
fn is_set_high(&self) -> bool; fn is_set_high(&self) -> bool;
} }
} }
@ -605,18 +605,10 @@ impl InputConnection {
pub fn init_input(&self, pull: Pull); pub fn init_input(&self, pull: Pull);
pub fn is_input_high(&self) -> bool; pub fn is_input_high(&self) -> bool;
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)]; pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
} pub fn enable_input(&self, on: bool);
#[instability::unstable]
to match &mut self.0 {
InputConnectionInner::Input(pin) => pin,
InputConnectionInner::DirectInput(pin) => pin,
InputConnectionInner::Constant(level) => level,
} {
pub fn enable_input(&mut self, on: bool);
// This doesn't need to be public, the intended way is `connect_to` and `disconnect_from` // This doesn't need to be public, the intended way is `connect_to` and `disconnect_from`
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal); fn connect_input_to_peripheral(&self, signal: gpio::InputSignal);
} }
} }
} }
@ -702,27 +694,20 @@ impl OutputConnection {
pub fn is_set_high(&self) -> bool; pub fn is_set_high(&self) -> bool;
pub fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)]; pub fn output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)];
} pub fn pull_direction(&self, pull: Pull);
#[instability::unstable] pub fn init_input(&self, pull: Pull);
to match &mut self.0 { pub fn enable_input(&self, on: bool);
OutputConnectionInner::Output(pin) => pin,
OutputConnectionInner::DirectOutput(pin) => pin,
OutputConnectionInner::Constant(level) => level,
} {
pub fn pull_direction(&mut self, pull: Pull);
pub fn init_input(&mut self, pull: Pull);
pub fn enable_input(&mut self, on: bool);
pub fn set_to_open_drain_output(&mut self); pub fn set_to_open_drain_output(&self);
pub fn set_to_push_pull_output(&mut self); pub fn set_to_push_pull_output(&self);
pub fn enable_output(&mut self, on: bool); pub fn enable_output(&self, on: bool);
pub fn set_output_high(&mut self, on: bool); pub fn set_output_high(&self, on: bool);
pub fn set_drive_strength(&mut self, strength: gpio::DriveStrength); pub fn set_drive_strength(&self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&mut self, on: bool); pub fn enable_open_drain(&self, on: bool);
// These don't need to be public, the intended way is `connect_to` and `disconnect_from` // These don't need to be public, the intended way is `connect_to` and `disconnect_from`
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal); fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal);
fn disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal); fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal);
} }
} }

View File

@ -200,14 +200,14 @@ macro_rules! lp_gpio {
) => { ) => {
$( $(
impl $crate::gpio::RtcPin for GpioPin<$gpionum> { impl $crate::gpio::RtcPin for GpioPin<$gpionum> {
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
let lp_io = $crate::peripherals::LP_IO::regs(); let lp_io = $crate::peripherals::LP_IO::regs();
lp_io.pin($gpionum).modify(|_, w| { lp_io.pin($gpionum).modify(|_, w| {
w.wakeup_enable().bit(wakeup).int_type().bits(level) w.wakeup_enable().bit(wakeup).int_type().bits(level)
}); });
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
let mask = 1 << $gpionum; let mask = 1 << $gpionum;
unsafe { unsafe {
let lp_aon = $crate::peripherals::LP_AON::regs(); let lp_aon = $crate::peripherals::LP_AON::regs();
@ -224,7 +224,7 @@ macro_rules! lp_gpio {
/// Set the LP properties of the pin. If `mux` is true then then pin is /// Set the LP properties of the pin. If `mux` is true then then pin is
/// routed to LP_IO, when false it is routed to IO_MUX. /// routed to LP_IO, when false it is routed to IO_MUX.
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) { fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
let mask = 1 << $gpionum; let mask = 1 << $gpionum;
unsafe { unsafe {
let lp_aon = $crate::peripherals::LP_AON::regs(); let lp_aon = $crate::peripherals::LP_AON::regs();
@ -251,12 +251,12 @@ macro_rules! lp_gpio {
} }
impl $crate::gpio::RtcPinWithResistors for GpioPin<$gpionum> { impl $crate::gpio::RtcPinWithResistors for GpioPin<$gpionum> {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
let lp_io = $crate::peripherals::LP_IO::regs(); let lp_io = $crate::peripherals::LP_IO::regs();
lp_io.gpio($gpionum).modify(|_, w| w.fun_wpu().bit(enable)); lp_io.gpio($gpionum).modify(|_, w| w.fun_wpu().bit(enable));
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
let lp_io = $crate::peripherals::LP_IO::regs(); let lp_io = $crate::peripherals::LP_IO::regs();
lp_io.gpio($gpionum).modify(|_, w| w.fun_wpd().bit(enable)); lp_io.gpio($gpionum).modify(|_, w| w.fun_wpd().bit(enable));
} }

View File

@ -376,17 +376,20 @@ pub trait RtcPin: Pin {
/// Configure the pin /// Configure the pin
#[cfg(any(xtensa, esp32c6))] #[cfg(any(xtensa, esp32c6))]
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: RtcFunction); #[doc(hidden)]
fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction);
/// Enable or disable PAD_HOLD /// Enable or disable PAD_HOLD
fn rtcio_pad_hold(&mut self, enable: bool); #[doc(hidden)]
fn rtcio_pad_hold(&self, enable: bool);
/// # Safety /// # Safety
/// ///
/// The `level` argument needs to be a valid setting for the /// The `level` argument needs to be a valid setting for the
/// `rtc_cntl.gpio_wakeup.gpio_pinX_int_type`. /// `rtc_cntl.gpio_wakeup.gpio_pinX_int_type`.
#[cfg(any(esp32c3, esp32c2, esp32c6))] #[cfg(any(esp32c3, esp32c2, esp32c6))]
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8); #[doc(hidden)]
unsafe fn apply_wakeup(&self, wakeup: bool, level: u8);
} }
/// Trait implemented by RTC pins which supporting internal pull-up / pull-down /// Trait implemented by RTC pins which supporting internal pull-up / pull-down
@ -395,9 +398,11 @@ pub trait RtcPin: Pin {
#[cfg(any(lp_io, rtc_cntl))] #[cfg(any(lp_io, rtc_cntl))]
pub trait RtcPinWithResistors: RtcPin { pub trait RtcPinWithResistors: RtcPin {
/// Enable/disable the internal pull-up resistor /// Enable/disable the internal pull-up resistor
fn rtcio_pullup(&mut self, enable: bool); #[doc(hidden)]
fn rtcio_pullup(&self, enable: bool);
/// Enable/disable the internal pull-down resistor /// Enable/disable the internal pull-down resistor
fn rtcio_pulldown(&mut self, enable: bool); #[doc(hidden)]
fn rtcio_pulldown(&self, enable: bool);
} }
/// Common trait implemented by pins /// Common trait implemented by pins
@ -1800,7 +1805,7 @@ impl Peripheral for Flex<'_> {
type P = Self; type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P { unsafe fn clone_unchecked(&self) -> Self::P {
Self { Self {
pin: PeripheralRef::new(core::ptr::read(&*self.pin as *const AnyPin)), pin: PeripheralRef::new(AnyPin(self.pin.number())),
} }
} }
} }
@ -2152,7 +2157,7 @@ impl AnyPin {
/// Set up as output /// Set up as output
#[inline] #[inline]
pub(crate) fn init_output( pub(crate) fn init_output(
&mut self, &self,
alternate: AlternateFunction, alternate: AlternateFunction,
open_drain: bool, open_drain: bool,
input_enable: Option<bool>, input_enable: Option<bool>,
@ -2182,31 +2187,31 @@ impl AnyPin {
/// Configure open-drain mode /// Configure open-drain mode
#[inline] #[inline]
pub(crate) fn set_to_open_drain_output(&mut self) { pub(crate) fn set_to_open_drain_output(&self) {
self.init_output(GPIO_FUNCTION, true, Some(true)); self.init_output(GPIO_FUNCTION, true, Some(true));
} }
/// Configure output mode /// Configure output mode
#[inline] #[inline]
pub(crate) fn set_to_push_pull_output(&mut self) { pub(crate) fn set_to_push_pull_output(&self) {
self.init_output(GPIO_FUNCTION, false, None); self.init_output(GPIO_FUNCTION, false, None);
} }
/// Set the pin's level to high or low /// Set the pin's level to high or low
#[inline] #[inline]
pub(crate) fn set_output_high(&mut self, high: bool) { pub(crate) fn set_output_high(&self, high: bool) {
self.bank().write_output(self.mask(), high); self.bank().write_output(self.mask(), high);
} }
/// Configure the [DriveStrength] of the pin /// Configure the [DriveStrength] of the pin
#[inline] #[inline]
pub(crate) fn set_drive_strength(&mut self, strength: DriveStrength) { pub(crate) fn set_drive_strength(&self, strength: DriveStrength) {
io_mux_reg(self.number()).modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) }); io_mux_reg(self.number()).modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) });
} }
/// Enable/disable open-drain mode /// Enable/disable open-drain mode
#[inline] #[inline]
pub(crate) fn enable_open_drain(&mut self, on: bool) { pub(crate) fn enable_open_drain(&self, on: bool) {
GPIO::regs() GPIO::regs()
.pin(self.number() as usize) .pin(self.number() as usize)
.modify(|_, w| w.pad_driver().bit(on)); .modify(|_, w| w.pad_driver().bit(on));
@ -2244,43 +2249,42 @@ impl OutputPin for AnyPin {}
#[cfg(any(lp_io, rtc_cntl))] #[cfg(any(lp_io, rtc_cntl))]
impl RtcPin for AnyPin { impl RtcPin for AnyPin {
#[cfg(xtensa)] #[cfg(xtensa)]
#[allow(unused_braces)] // False positive :/ #[allow(unused_braces, reason = "False positive")]
fn rtc_number(&self) -> u8 { fn rtc_number(&self) -> u8 {
handle_rtcio!(self, target, { RtcPin::rtc_number(&target) }) handle_rtcio!(self, target, { RtcPin::rtc_number(&target) })
} }
#[cfg(any(xtensa, esp32c6))] #[cfg(any(xtensa, esp32c6))]
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: RtcFunction) { fn rtc_set_config(&self, input_enable: bool, mux: bool, func: RtcFunction) {
handle_rtcio!(self, target, { handle_rtcio!(self, target, {
RtcPin::rtc_set_config(&mut target, input_enable, mux, func) RtcPin::rtc_set_config(&target, input_enable, mux, func)
}) })
} }
fn rtcio_pad_hold(&mut self, enable: bool) { #[allow(unused_braces, reason = "False positive")]
handle_rtcio!(self, target, { fn rtcio_pad_hold(&self, enable: bool) {
RtcPin::rtcio_pad_hold(&mut target, enable) handle_rtcio!(self, target, { RtcPin::rtcio_pad_hold(&target, enable) })
})
} }
#[cfg(any(esp32c2, esp32c3, esp32c6))] #[cfg(any(esp32c2, esp32c3, esp32c6))]
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
handle_rtcio!(self, target, { handle_rtcio!(self, target, {
RtcPin::apply_wakeup(&mut target, wakeup, level) RtcPin::apply_wakeup(&target, wakeup, level)
}) })
} }
} }
#[cfg(any(lp_io, rtc_cntl))] #[cfg(any(lp_io, rtc_cntl))]
impl RtcPinWithResistors for AnyPin { impl RtcPinWithResistors for AnyPin {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
handle_rtcio_with_resistors!(self, target, { handle_rtcio_with_resistors!(self, target, {
RtcPinWithResistors::rtcio_pullup(&mut target, enable) RtcPinWithResistors::rtcio_pullup(&target, enable)
}) })
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
handle_rtcio_with_resistors!(self, target, { handle_rtcio_with_resistors!(self, target, {
RtcPinWithResistors::rtcio_pulldown(&mut target, enable) RtcPinWithResistors::rtcio_pulldown(&target, enable)
}) })
} }
} }
@ -2333,7 +2337,7 @@ mod asynch {
// We construct the Future first, because its `Drop` implementation // We construct the Future first, because its `Drop` implementation
// is load-bearing if `wait_for` is dropped during the initialization. // is load-bearing if `wait_for` is dropped during the initialization.
let mut future = PinFuture { let mut future = PinFuture {
pin: unsafe { self.clone_unchecked() }, pin: Flex::new(unsafe { self.pin.clone_unchecked() }),
}; };
// Make sure this pin is not being processed by an interrupt handler. // Make sure this pin is not being processed by an interrupt handler.

View File

@ -28,13 +28,13 @@ impl Level {
pub(crate) fn init_input(&self, _pull: Pull) {} pub(crate) fn init_input(&self, _pull: Pull) {}
pub(crate) fn enable_input(&mut self, _on: bool) {} pub(crate) fn enable_input(&self, _on: bool) {}
pub(crate) fn is_input_high(&self) -> bool { pub(crate) fn is_input_high(&self) -> bool {
*self == Level::High *self == Level::High
} }
pub(crate) fn connect_input_to_peripheral(&mut self, signal: InputSignal) { pub(crate) fn connect_input_to_peripheral(&self, signal: InputSignal) {
let value = match self { let value = match self {
Level::High => ONE_INPUT, Level::High => ONE_INPUT,
Level::Low => ZERO_INPUT, Level::Low => ZERO_INPUT,
@ -43,12 +43,12 @@ impl Level {
connect_input_signal(signal, value, false, true); connect_input_signal(signal, value, false, true);
} }
pub(crate) fn set_to_open_drain_output(&mut self) {} pub(crate) fn set_to_open_drain_output(&self) {}
pub(crate) fn set_to_push_pull_output(&mut self) {} pub(crate) fn set_to_push_pull_output(&self) {}
pub(crate) fn enable_output(&mut self, _on: bool) {} pub(crate) fn enable_output(&self, _on: bool) {}
pub(crate) fn set_output_high(&mut self, _on: bool) {} pub(crate) fn set_output_high(&self, _on: bool) {}
pub(crate) fn set_drive_strength(&mut self, _strength: DriveStrength) {} pub(crate) fn set_drive_strength(&self, _strength: DriveStrength) {}
pub(crate) fn enable_open_drain(&mut self, _on: bool) {} pub(crate) fn enable_open_drain(&self, _on: bool) {}
pub(crate) fn is_set_high(&self) -> bool { pub(crate) fn is_set_high(&self) -> bool {
false false
@ -61,9 +61,9 @@ impl Level {
&[] &[]
} }
pub(crate) fn connect_peripheral_to_output(&mut self, _signal: OutputSignal) {} pub(crate) fn connect_peripheral_to_output(&self, _signal: OutputSignal) {}
pub(crate) fn disconnect_from_peripheral_output(&mut self, _signal: OutputSignal) {} pub(crate) fn disconnect_from_peripheral_output(&self, _signal: OutputSignal) {}
} }
/// Placeholder pin, used when no pin is required when using a peripheral. /// Placeholder pin, used when no pin is required when using a peripheral.

View File

@ -587,7 +587,7 @@ impl<'d, Dm: DriverMode> I2c<'d, Dm> {
pin.enable_input(true); pin.enable_input(true);
pin.pull_direction(Pull::Up); pin.pull_direction(Pull::Up);
input.connect_to(&mut pin); input.connect_to(pin.reborrow());
*guard = OutputConnection::connect_with_guard(pin, output); *guard = OutputConnection::connect_with_guard(pin, output);
} }

View File

@ -7,17 +7,19 @@ use core::{
/// An exclusive reference to a peripheral. /// An exclusive reference to a peripheral.
/// ///
/// This is functionally the same as a `&'a mut T`. The reason for having a /// This is functionally the same as a `&'a mut T`. There's a few advantages in
/// dedicated struct is memory efficiency: /// having a dedicated struct instead:
/// ///
/// Peripheral singletons are typically either zero-sized (for concrete /// - Memory efficiency: Peripheral singletons are typically either zero-sized
/// peripherals like `SPI2` or `UART0`) or very small (for example `AnyPin` /// (for concrete peripherals like `GpioPin<5>` or `SPI2`) or very small (for
/// which is 1 byte). However `&mut T` is always 4 bytes for 32-bit targets, /// example `AnyPin`, which is 1 byte). However `&mut T` is always 4 bytes for
/// even if T is zero-sized. PeripheralRef stores a copy of `T` instead, so it's /// 32-bit targets, even if T is zero-sized. PeripheralRef stores a copy of
/// the same size. /// `T` instead, so it's the same size.
/// /// - Code size efficiency. If the user uses the same driver with both `SPI2`
/// but it is the size of `T` not the size /// and `&mut SPI2`, the driver code would be monomorphized two times. With
/// of a pointer. This is useful if T is a zero sized type. /// PeripheralRef, the driver is generic over a lifetime only. `SPI2` becomes
/// `PeripheralRef<'static, SPI2>`, and `&mut SPI2` becomes `PeripheralRef<'a,
/// SPI2>`. Lifetimes don't cause monomorphization.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PeripheralRef<'a, T> { pub struct PeripheralRef<'a, T> {
@ -102,13 +104,6 @@ impl<T> Deref for PeripheralRef<'_, T> {
} }
} }
impl<T> DerefMut for PeripheralRef<'_, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
/// Trait for any type that can be used as a peripheral of type `P`. /// Trait for any type that can be used as a peripheral of type `P`.
/// ///
/// This is used in driver constructors, to allow passing either owned /// This is used in driver constructors, to allow passing either owned
@ -151,7 +146,7 @@ impl<T> DerefMut for PeripheralRef<'_, T> {
/// ///
/// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`. /// `.into_ref()` on an owned `T` yields a `PeripheralRef<'static, T>`.
/// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`. /// `.into_ref()` on an `&'a mut T` yields a `PeripheralRef<'a, T>`.
pub trait Peripheral: Sized + crate::private::Sealed { pub trait Peripheral: Sized {
/// Peripheral singleton type /// Peripheral singleton type
type P; type P;
@ -206,20 +201,18 @@ pub trait Peripheral: Sized + crate::private::Sealed {
} }
} }
impl<T, P> Peripheral for &mut T impl<T: DerefMut> Peripheral for T
where where
T: Peripheral<P = P>, T::Target: Peripheral,
{ {
type P = P; type P = <T::Target as Peripheral>::P;
#[inline]
unsafe fn clone_unchecked(&self) -> Self::P { unsafe fn clone_unchecked(&self) -> Self::P {
T::clone_unchecked(self) T::Target::clone_unchecked(self)
} }
} }
impl<T> crate::private::Sealed for &mut T where T: crate::private::Sealed {}
impl<T> crate::private::Sealed for PeripheralRef<'_, T> where T: crate::private::Sealed {}
impl<T: Peripheral> Peripheral for PeripheralRef<'_, T> { impl<T: Peripheral> Peripheral for PeripheralRef<'_, T> {
type P = T::P; type P = T::P;

View File

@ -74,7 +74,7 @@ impl Ext1WakeupSource<'_, '_> {
fn wake_io_reset() { fn wake_io_reset() {
use crate::gpio::{GpioPin, RtcPin}; use crate::gpio::{GpioPin, RtcPin};
fn uninit_pin(mut pin: impl RtcPin, wakeup_pins: u8) { fn uninit_pin(pin: impl RtcPin, wakeup_pins: u8) {
if wakeup_pins & (1 << pin.number()) != 0 { if wakeup_pins & (1 << pin.number()) != 0 {
pin.rtcio_pad_hold(false); pin.rtcio_pad_hold(false);
pin.rtc_set_config(false, false, RtcFunction::Rtc); pin.rtc_set_config(false, false, RtcFunction::Rtc);

View File

@ -56,7 +56,7 @@
//! ## Implementation State //! ## Implementation State
//! - DMA-SHA Mode is not supported. //! - DMA-SHA Mode is not supported.
use core::{borrow::BorrowMut, convert::Infallible, marker::PhantomData, mem::size_of}; use core::{borrow::Borrow, convert::Infallible, marker::PhantomData, mem::size_of};
/// Re-export digest for convenience /// Re-export digest for convenience
#[cfg(feature = "digest")] #[cfg(feature = "digest")]
@ -135,7 +135,7 @@ impl crate::interrupt::InterruptConfigurable for Sha<'_> {
/// ///
/// This implementation might fail after u32::MAX/8 bytes, to increase please /// This implementation might fail after u32::MAX/8 bytes, to increase please
/// see ::finish() length/self.cursor usage /// see ::finish() length/self.cursor usage
pub struct ShaDigest<'d, A, S: BorrowMut<Sha<'d>>> { pub struct ShaDigest<'d, A, S: Borrow<Sha<'d>>> {
sha: S, sha: S,
alignment_helper: AlignmentHelper<SocDependentEndianess>, alignment_helper: AlignmentHelper<SocDependentEndianess>,
cursor: usize, cursor: usize,
@ -145,13 +145,13 @@ pub struct ShaDigest<'d, A, S: BorrowMut<Sha<'d>>> {
phantom: PhantomData<(&'d (), A)>, phantom: PhantomData<(&'d (), A)>,
} }
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> ShaDigest<'d, A, S> {
/// Creates a new digest /// Creates a new digest
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn new(mut sha: S) -> Self { pub fn new(mut sha: S) -> Self {
#[cfg(not(esp32))] #[cfg(not(esp32))]
// Setup SHA Mode. // Setup SHA Mode.
sha.borrow_mut() sha.borrow()
.regs() .regs()
.mode() .mode()
.write(|w| unsafe { w.mode().bits(A::MODE_AS_BITS) }); .write(|w| unsafe { w.mode().bits(A::MODE_AS_BITS) });
@ -169,26 +169,22 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
/// Restores a previously saved digest. /// Restores a previously saved digest.
#[cfg(not(esp32))] #[cfg(not(esp32))]
pub fn restore(mut sha: S, ctx: &mut Context<A>) -> Self { pub fn restore(sha: S, ctx: &mut Context<A>) -> Self {
// Setup SHA Mode. // Setup SHA Mode.
sha.borrow_mut() sha.borrow()
.regs() .regs()
.mode() .mode()
.write(|w| unsafe { w.mode().bits(A::MODE_AS_BITS) }); .write(|w| unsafe { w.mode().bits(A::MODE_AS_BITS) });
// Restore the message buffer // Restore the message buffer
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(ctx.buffer.as_ptr(), m_mem(&sha.borrow().sha, 0), 32);
ctx.buffer.as_ptr(),
m_mem(&sha.borrow_mut().sha, 0),
32,
);
} }
let mut ah = ctx.alignment_helper.clone(); let mut ah = ctx.alignment_helper.clone();
// Restore previously saved hash // Restore previously saved hash
ah.volatile_write_regset(h_mem(&sha.borrow_mut().sha, 0), &ctx.saved_digest, 64); ah.volatile_write_regset(h_mem(&sha.borrow().sha, 0), &ctx.saved_digest, 64);
Self { Self {
sha, sha,
@ -241,7 +237,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
} }
let flushed = self.alignment_helper.flush_to( let flushed = self.alignment_helper.flush_to(
m_mem(&self.sha.borrow_mut().sha, 0), m_mem(&self.sha.borrow().sha, 0),
(self.cursor % A::CHUNK_LENGTH) / self.alignment_helper.align_size(), (self.cursor % A::CHUNK_LENGTH) / self.alignment_helper.align_size(),
); );
self.cursor = self.cursor.wrapping_add(flushed); self.cursor = self.cursor.wrapping_add(flushed);
@ -259,7 +255,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
// buffer // buffer
let pad_len = A::CHUNK_LENGTH - mod_cursor; let pad_len = A::CHUNK_LENGTH - mod_cursor;
self.alignment_helper.volatile_write_bytes( self.alignment_helper.volatile_write_bytes(
m_mem(&self.sha.borrow_mut().sha, 0), m_mem(&self.sha.borrow().sha, 0),
0_u8, 0_u8,
pad_len / self.alignment_helper.align_size(), pad_len / self.alignment_helper.align_size(),
mod_cursor / self.alignment_helper.align_size(), mod_cursor / self.alignment_helper.align_size(),
@ -277,14 +273,14 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
let pad_len = A::CHUNK_LENGTH - mod_cursor - size_of::<u64>(); let pad_len = A::CHUNK_LENGTH - mod_cursor - size_of::<u64>();
self.alignment_helper.volatile_write_bytes( self.alignment_helper.volatile_write_bytes(
m_mem(&self.sha.borrow_mut().sha, 0), m_mem(&self.sha.borrow().sha, 0),
0, 0,
pad_len / self.alignment_helper.align_size(), pad_len / self.alignment_helper.align_size(),
mod_cursor / self.alignment_helper.align_size(), mod_cursor / self.alignment_helper.align_size(),
); );
self.alignment_helper.aligned_volatile_copy( self.alignment_helper.aligned_volatile_copy(
m_mem(&self.sha.borrow_mut().sha, 0), m_mem(&self.sha.borrow().sha, 0),
&length, &length,
A::CHUNK_LENGTH / self.alignment_helper.align_size(), A::CHUNK_LENGTH / self.alignment_helper.align_size(),
(A::CHUNK_LENGTH - size_of::<u64>()) / self.alignment_helper.align_size(), (A::CHUNK_LENGTH - size_of::<u64>()) / self.alignment_helper.align_size(),
@ -297,14 +293,14 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
// ESP32 requires additional load to retrieve output // ESP32 requires additional load to retrieve output
#[cfg(esp32)] #[cfg(esp32)]
{ {
A::load(&mut self.sha.borrow_mut().sha); A::load(&self.sha.borrow().sha);
// Spin wait for result, 8-20 clock cycles according to manual // Spin wait for result, 8-20 clock cycles according to manual
while self.is_busy() {} while self.is_busy() {}
} }
self.alignment_helper.volatile_read_regset( self.alignment_helper.volatile_read_regset(
h_mem(&self.sha.borrow_mut().sha, 0), h_mem(&self.sha.borrow().sha, 0),
output, output,
core::cmp::min(output.len(), 32) / self.alignment_helper.align_size(), core::cmp::min(output.len(), 32) / self.alignment_helper.align_size(),
); );
@ -331,7 +327,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
// Save the content of the current hash. // Save the content of the current hash.
self.alignment_helper.volatile_read_regset( self.alignment_helper.volatile_read_regset(
h_mem(&self.sha.borrow_mut().sha, 0), h_mem(&self.sha.borrow().sha, 0),
&mut context.saved_digest, &mut context.saved_digest,
64 / self.alignment_helper.align_size(), 64 / self.alignment_helper.align_size(),
); );
@ -339,7 +335,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
// Save the content of the current (probably partially written) message. // Save the content of the current (probably partially written) message.
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
m_mem(&self.sha.borrow_mut().sha, 0), m_mem(&self.sha.borrow().sha, 0),
context.buffer.as_mut_ptr(), context.buffer.as_mut_ptr(),
32, 32,
); );
@ -358,15 +354,15 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
/// This method is platform-specific and differs for ESP32 and non-ESP32 /// This method is platform-specific and differs for ESP32 and non-ESP32
/// platforms. /// platforms.
fn process_buffer(&mut self) { fn process_buffer(&mut self) {
let sha = self.sha.borrow_mut(); let sha = self.sha.borrow();
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(esp32)] { if #[cfg(esp32)] {
if self.first_run { if self.first_run {
A::start(&mut sha.sha); A::start(&sha.sha);
self.first_run = false; self.first_run = false;
} else { } else {
A::r#continue(&mut sha.sha); A::r#continue(&sha.sha);
} }
} else { } else {
if self.first_run { if self.first_run {
@ -507,17 +503,17 @@ pub trait ShaAlgorithm: crate::private::Sealed {
#[cfg(esp32)] #[cfg(esp32)]
#[doc(hidden)] #[doc(hidden)]
// Initiate the operation // Initiate the operation
fn start(sha: &mut crate::peripherals::SHA); fn start(sha: &crate::peripherals::SHA);
#[cfg(esp32)] #[cfg(esp32)]
#[doc(hidden)] #[doc(hidden)]
// Continue the operation // Continue the operation
fn r#continue(sha: &mut crate::peripherals::SHA); fn r#continue(sha: &crate::peripherals::SHA);
#[cfg(esp32)] #[cfg(esp32)]
#[doc(hidden)] #[doc(hidden)]
// Calculate the final hash // Calculate the final hash
fn load(sha: &mut crate::peripherals::SHA); fn load(sha: &crate::peripherals::SHA);
#[cfg(esp32)] #[cfg(esp32)]
#[doc(hidden)] #[doc(hidden)]
@ -529,15 +525,15 @@ pub trait ShaAlgorithm: crate::private::Sealed {
/// Note: digest has a blanket trait implementation for [digest::Digest] for any /// Note: digest has a blanket trait implementation for [digest::Digest] for any
/// element that implements FixedOutput + Default + Update + HashMarker /// element that implements FixedOutput + Default + Update + HashMarker
#[cfg(feature = "digest")] #[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::HashMarker for ShaDigest<'d, A, S> {} impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::HashMarker for ShaDigest<'d, A, S> {}
#[cfg(feature = "digest")] #[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::OutputSizeUser for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::OutputSizeUser for ShaDigest<'d, A, S> {
type OutputSize = A::DigestOutputSize; type OutputSize = A::DigestOutputSize;
} }
#[cfg(feature = "digest")] #[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::Update for ShaDigest<'d, A, S> {
fn update(&mut self, data: &[u8]) { fn update(&mut self, data: &[u8]) {
let mut remaining = data.as_ref(); let mut remaining = data.as_ref();
while !remaining.is_empty() { while !remaining.is_empty() {
@ -547,7 +543,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d
} }
#[cfg(feature = "digest")] #[cfg(feature = "digest")]
impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> { impl<'d, A: ShaAlgorithm, S: Borrow<Sha<'d>>> digest::FixedOutput for ShaDigest<'d, A, S> {
fn finalize_into(mut self, out: &mut digest::Output<Self>) { fn finalize_into(mut self, out: &mut digest::Output<Self>) {
nb::block!(self.finish(out)).unwrap(); nb::block!(self.finish(out)).unwrap();
} }
@ -587,21 +583,21 @@ macro_rules! impl_sha {
type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]); type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]);
#[cfg(esp32)] #[cfg(esp32)]
fn start(sha: &mut crate::peripherals::SHA) { fn start(sha: &crate::peripherals::SHA) {
paste::paste! { paste::paste! {
sha.register_block().[< $name:lower _start >]().write(|w| w.[< $name:lower _start >]().set_bit()); sha.register_block().[< $name:lower _start >]().write(|w| w.[< $name:lower _start >]().set_bit());
} }
} }
#[cfg(esp32)] #[cfg(esp32)]
fn r#continue(sha: &mut crate::peripherals::SHA) { fn r#continue(sha: &crate::peripherals::SHA) {
paste::paste! { paste::paste! {
sha.register_block().[< $name:lower _continue >]().write(|w| w.[< $name:lower _continue >]().set_bit()); sha.register_block().[< $name:lower _continue >]().write(|w| w.[< $name:lower _continue >]().set_bit());
} }
} }
#[cfg(esp32)] #[cfg(esp32)]
fn load(sha: &mut crate::peripherals::SHA) { fn load(sha: &crate::peripherals::SHA) {
paste::paste! { paste::paste! {
sha.register_block().[< $name:lower _load >]().write(|w| w.[< $name:lower _load >]().set_bit()); sha.register_block().[< $name:lower _load >]().write(|w| w.[< $name:lower _load >]().set_bit());
} }

View File

@ -542,7 +542,7 @@ macro_rules! rtcio_analog {
/// Set the RTC properties of the pin. If `mux` is true then then pin is /// Set the RTC properties of the pin. If `mux` is true then then pin is
/// routed to RTC, when false it is routed to IO_MUX. /// routed to RTC, when false it is routed to IO_MUX.
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) { fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
// disable input // disable input
paste::paste!{ paste::paste!{
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
@ -554,7 +554,7 @@ macro_rules! rtcio_analog {
} }
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
$crate::peripherals::LPWR::regs() $crate::peripherals::LPWR::regs()
.hold_force() .hold_force()
.modify(|_, w| w.$hold().bit(enable)); .modify(|_, w| w.$hold().bit(enable));
@ -565,14 +565,14 @@ macro_rules! rtcio_analog {
// FIXME: replace with $(ignore($rue)) once stable // FIXME: replace with $(ignore($rue)) once stable
$crate::ignore!($rue); $crate::ignore!($rue);
impl $crate::gpio::RtcPinWithResistors for $crate::gpio::GpioPin<$pin_num> { impl $crate::gpio::RtcPinWithResistors for $crate::gpio::GpioPin<$pin_num> {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
} }
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable));
@ -628,7 +628,7 @@ macro_rules! rtcio_analog {
rtcio_analog!($pin_num, $rtc_pin, $pin_reg, $prefix, $hold $(, $rue )?); rtcio_analog!($pin_num, $rtc_pin, $pin_reg, $prefix, $hold $(, $rue )?);
)+ )+
pub(crate) fn errata36(mut pin: $crate::gpio::AnyPin, pull_up: bool, pull_down: bool) { pub(crate) fn errata36(pin: $crate::gpio::AnyPin, pull_up: bool, pull_down: bool) {
use $crate::gpio::{Pin, RtcPinWithResistors}; use $crate::gpio::{Pin, RtcPinWithResistors};
let has_pullups = match pin.number() { let has_pullups = match pin.number() {

View File

@ -178,7 +178,7 @@ macro_rules! rtc_pins {
( $( $pin_num:expr )+ ) => { ( $( $pin_num:expr )+ ) => {
$( $(
impl $crate::gpio::RtcPin for GpioPin<$pin_num> { impl $crate::gpio::RtcPin for GpioPin<$pin_num> {
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
let gpio_wakeup = $crate::peripherals::LPWR::regs().cntl_gpio_wakeup(); let gpio_wakeup = $crate::peripherals::LPWR::regs().cntl_gpio_wakeup();
paste::paste! { paste::paste! {
gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup)); gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup));
@ -186,7 +186,7 @@ macro_rules! rtc_pins {
} }
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::LPWR::regs() $crate::peripherals::LPWR::regs()
.pad_hold().modify(|_, w| w.[< gpio_pin $pin_num _hold >]().bit(enable)); .pad_hold().modify(|_, w| w.[< gpio_pin $pin_num _hold >]().bit(enable));
@ -201,13 +201,13 @@ impl<const N: u8> crate::gpio::RtcPinWithResistors for GpioPin<N>
where where
Self: crate::gpio::RtcPin, Self: crate::gpio::RtcPin,
{ {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
IO_MUX::regs() IO_MUX::regs()
.gpio(N as usize) .gpio(N as usize)
.modify(|_, w| w.fun_wpu().bit(enable)); .modify(|_, w| w.fun_wpu().bit(enable));
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
IO_MUX::regs() IO_MUX::regs()
.gpio(N as usize) .gpio(N as usize)
.modify(|_, w| w.fun_wpd().bit(enable)); .modify(|_, w| w.fun_wpd().bit(enable));

View File

@ -206,7 +206,7 @@ macro_rules! rtc_pins {
( $( $pin_num:expr )+ ) => { ( $( $pin_num:expr )+ ) => {
$( $(
impl $crate::gpio::RtcPin for GpioPin<$pin_num> { impl $crate::gpio::RtcPin for GpioPin<$pin_num> {
unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) { unsafe fn apply_wakeup(&self, wakeup: bool, level: u8) {
let rtc_cntl = $crate::peripherals::LPWR::regs(); let rtc_cntl = $crate::peripherals::LPWR::regs();
let gpio_wakeup = rtc_cntl.gpio_wakeup(); let gpio_wakeup = rtc_cntl.gpio_wakeup();
@ -216,7 +216,7 @@ macro_rules! rtc_pins {
} }
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::LPWR::regs() $crate::peripherals::LPWR::regs()
.pad_hold().modify(|_, w| w.[< gpio_pin $pin_num _hold >]().bit(enable)); .pad_hold().modify(|_, w| w.[< gpio_pin $pin_num _hold >]().bit(enable));
@ -231,13 +231,13 @@ impl<const N: u8> crate::gpio::RtcPinWithResistors for GpioPin<N>
where where
Self: crate::gpio::RtcPin, Self: crate::gpio::RtcPin,
{ {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
IO_MUX::regs() IO_MUX::regs()
.gpio(N as usize) .gpio(N as usize)
.modify(|_, w| w.fun_wpu().bit(enable)); .modify(|_, w| w.fun_wpu().bit(enable));
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
IO_MUX::regs() IO_MUX::regs()
.gpio(N as usize) .gpio(N as usize)
.modify(|_, w| w.fun_wpd().bit(enable)); .modify(|_, w| w.fun_wpd().bit(enable));

View File

@ -328,7 +328,7 @@ macro_rules! rtcio_analog {
/// Set the RTC properties of the pin. If `mux` is true then then pin is /// Set the RTC properties of the pin. If `mux` is true then then pin is
/// routed to RTC, when false it is routed to IO_MUX. /// routed to RTC, when false it is routed to IO_MUX.
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) { fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
enable_iomux_clk_gate(); enable_iomux_clk_gate();
// disable input // disable input
@ -342,7 +342,7 @@ macro_rules! rtcio_analog {
} }
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
$crate::peripherals::LPWR::regs() $crate::peripherals::LPWR::regs()
.pad_hold() .pad_hold()
.modify(|_, w| w.$hold().bit(enable)); .modify(|_, w| w.$hold().bit(enable));
@ -351,14 +351,14 @@ macro_rules! rtcio_analog {
impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num> impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num>
{ {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
} }
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable));

View File

@ -406,7 +406,7 @@ macro_rules! rtcio_analog {
/// Set the RTC properties of the pin. If `mux` is true then then pin is /// Set the RTC properties of the pin. If `mux` is true then then pin is
/// routed to RTC, when false it is routed to IO_MUX. /// routed to RTC, when false it is routed to IO_MUX.
fn rtc_set_config(&mut self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) { fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
enable_iomux_clk_gate(); enable_iomux_clk_gate();
// disable input // disable input
@ -420,7 +420,7 @@ macro_rules! rtcio_analog {
} }
} }
fn rtcio_pad_hold(&mut self, enable: bool) { fn rtcio_pad_hold(&self, enable: bool) {
$crate::peripherals::LPWR::regs() $crate::peripherals::LPWR::regs()
.pad_hold() .pad_hold()
.modify(|_, w| w.$hold().bit(enable)); .modify(|_, w| w.$hold().bit(enable));
@ -429,14 +429,14 @@ macro_rules! rtcio_analog {
impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num> impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num>
{ {
fn rtcio_pullup(&mut self, enable: bool) { fn rtcio_pullup(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
} }
} }
fn rtcio_pulldown(&mut self, enable: bool) { fn rtcio_pulldown(&self, enable: bool) {
paste::paste! { paste::paste! {
$crate::peripherals::RTC_IO::regs() $crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable)); .$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable));

View File

@ -775,7 +775,7 @@ where
crate::into_mapped_ref!(miso); crate::into_mapped_ref!(miso);
miso.enable_input(true); miso.enable_input(true);
self.driver().info.miso.connect_to(&mut miso); self.driver().info.miso.connect_to(miso);
self self
} }

View File

@ -74,29 +74,37 @@ pub enum Error {
} }
/// Functionality provided by any timer peripheral. /// Functionality provided by any timer peripheral.
pub trait Timer: Into<AnyTimer> + InterruptConfigurable + 'static + crate::private::Sealed { pub trait Timer: Into<AnyTimer> + 'static + crate::private::Sealed {
/// Start the timer. /// Start the timer.
#[doc(hidden)]
fn start(&self); fn start(&self);
/// Stop the timer. /// Stop the timer.
#[doc(hidden)]
fn stop(&self); fn stop(&self);
/// Reset the timer value to 0. /// Reset the timer value to 0.
#[doc(hidden)]
fn reset(&self); fn reset(&self);
/// Is the timer running? /// Is the timer running?
#[doc(hidden)]
fn is_running(&self) -> bool; fn is_running(&self) -> bool;
/// The current timer value. /// The current timer value.
#[doc(hidden)]
fn now(&self) -> Instant<u64, 1, 1_000_000>; fn now(&self) -> Instant<u64, 1, 1_000_000>;
/// Load a target value into the timer. /// Load a target value into the timer.
#[doc(hidden)]
fn load_value(&self, value: MicrosDurationU64) -> Result<(), Error>; fn load_value(&self, value: MicrosDurationU64) -> Result<(), Error>;
/// Enable auto reload of the loaded value. /// Enable auto reload of the loaded value.
#[doc(hidden)]
fn enable_auto_reload(&self, auto_reload: bool); fn enable_auto_reload(&self, auto_reload: bool);
/// Enable or disable the timer's interrupt. /// Enable or disable the timer's interrupt.
#[doc(hidden)]
fn enable_interrupt(&self, state: bool); fn enable_interrupt(&self, state: bool);
/// Clear the timer's interrupt. /// Clear the timer's interrupt.
@ -109,13 +117,19 @@ pub trait Timer: Into<AnyTimer> + InterruptConfigurable + 'static + crate::priva
/// ///
/// Requires the correct `InterruptHandler` to be installed to function /// Requires the correct `InterruptHandler` to be installed to function
/// correctly. /// correctly.
#[doc(hidden)]
async fn wait(&self); async fn wait(&self);
/// Returns the HAL provided async interrupt handler /// Returns the HAL provided async interrupt handler
#[doc(hidden)]
fn async_interrupt_handler(&self) -> InterruptHandler; fn async_interrupt_handler(&self) -> InterruptHandler;
/// Returns the interrupt source for the underlying timer /// Returns the interrupt source for the underlying timer
fn peripheral_interrupt(&self) -> Interrupt; fn peripheral_interrupt(&self) -> Interrupt;
/// Configures the interrupt handler.
#[doc(hidden)]
fn set_interrupt_handler(&self, handler: InterruptHandler);
} }
/// A one-shot timer. /// A one-shot timer.
@ -137,7 +151,7 @@ impl<'d> OneShotTimer<'d, Blocking> {
impl<'d> OneShotTimer<'d, Blocking> { impl<'d> OneShotTimer<'d, Blocking> {
/// Converts the driver to [`Async`] mode. /// Converts the driver to [`Async`] mode.
pub fn into_async(mut self) -> OneShotTimer<'d, Async> { pub fn into_async(self) -> OneShotTimer<'d, Async> {
let handler = self.inner.async_interrupt_handler(); let handler = self.inner.async_interrupt_handler();
self.inner.set_interrupt_handler(handler); self.inner.set_interrupt_handler(handler);
OneShotTimer { OneShotTimer {
@ -385,18 +399,7 @@ impl Timer for AnyTimer {
async fn wait(&self); async fn wait(&self);
fn async_interrupt_handler(&self) -> InterruptHandler; fn async_interrupt_handler(&self) -> InterruptHandler;
fn peripheral_interrupt(&self) -> Interrupt; fn peripheral_interrupt(&self) -> Interrupt;
} fn set_interrupt_handler(&self, handler: InterruptHandler);
}
}
impl InterruptConfigurable for AnyTimer {
delegate::delegate! {
to match &mut self.0 {
AnyTimerInner::TimgTimer(inner) => inner,
#[cfg(systimer)]
AnyTimerInner::SystimerAlarm(inner) => inner,
} {
fn set_interrupt_handler(&mut self, handler: InterruptHandler);
} }
} }
} }

View File

@ -23,7 +23,7 @@ use fugit::{Instant, MicrosDurationU64};
use super::{Error, Timer as _}; use super::{Error, Timer as _};
use crate::{ use crate::{
interrupt::{self, InterruptConfigurable, InterruptHandler}, interrupt::{self, InterruptHandler},
peripheral::Peripheral, peripheral::Peripheral,
peripherals::{Interrupt, SYSTIMER}, peripherals::{Interrupt, SYSTIMER},
sync::{lock, RawMutex}, sync::{lock, RawMutex},
@ -386,7 +386,7 @@ impl Alarm {
} }
/// Set the interrupt handler for this comparator. /// Set the interrupt handler for this comparator.
fn set_interrupt_handler(&mut self, handler: InterruptHandler) { fn set_interrupt_handler(&self, handler: InterruptHandler) {
let interrupt = match self.channel() { let interrupt = match self.channel() {
0 => Interrupt::SYSTIMER_TARGET0, 0 => Interrupt::SYSTIMER_TARGET0,
1 => Interrupt::SYSTIMER_TARGET1, 1 => Interrupt::SYSTIMER_TARGET1,
@ -438,12 +438,6 @@ impl Alarm {
} }
} }
impl InterruptConfigurable for Alarm {
fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
self.set_interrupt_handler(handler)
}
}
/// The modes of a comparator. /// The modes of a comparator.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum ComparatorMode { enum ComparatorMode {
@ -587,6 +581,10 @@ impl super::Timer for Alarm {
_ => unreachable!(), _ => unreachable!(),
} }
} }
fn set_interrupt_handler(&self, handler: InterruptHandler) {
self.set_interrupt_handler(handler)
}
} }
impl Peripheral for Alarm { impl Peripheral for Alarm {

View File

@ -351,10 +351,8 @@ impl super::Timer for Timer {
_ => unreachable!(), _ => unreachable!(),
} }
} }
}
impl InterruptConfigurable for Timer { fn set_interrupt_handler(&self, handler: InterruptHandler) {
fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
self.set_interrupt_handler(handler) self.set_interrupt_handler(handler)
} }
} }
@ -382,7 +380,7 @@ unsafe impl Send for Timer {}
/// Timer peripheral instance /// Timer peripheral instance
impl Timer { impl Timer {
fn set_interrupt_handler(&mut self, handler: InterruptHandler) { pub(crate) fn set_interrupt_handler(&self, handler: InterruptHandler) {
let interrupt = match (self.timer_group(), self.timer_number()) { let interrupt = match (self.timer_group(), self.timer_number()) {
(0, 0) => Interrupt::TG0_T0_LEVEL, (0, 0) => Interrupt::TG0_T0_LEVEL,
#[cfg(timg_timer1)] #[cfg(timg_timer1)]