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(
pin: &mut AnyPin,
pin: &AnyPin,
signal: gpio::InputSignal,
is_inverted: bool,
force_gpio: bool,
@ -176,7 +176,7 @@ fn connect_pin_to_input_signal(
}
fn connect_peripheral_to_output(
pin: &mut AnyPin,
pin: &AnyPin,
signal: gpio::OutputSignal,
is_inverted: 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);
GPIO::regs()
@ -307,8 +307,8 @@ impl InputSignal {
/// Since there can only be one input signal connected to a peripheral at a
/// time, this function will disconnect any previously connected input
/// signals.
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&mut self.pin, signal, self.is_inverted, true);
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&self.pin, signal, self.is_inverted, true);
}
delegate::delegate! {
@ -318,7 +318,7 @@ impl InputSignal {
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
pub fn init_input(&self, pull: Pull);
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
/// time, this function will disconnect any previously connected input
/// signals.
fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&mut self.pin, signal, false, false);
fn connect_input_to_peripheral(&self, signal: gpio::InputSignal) {
connect_pin_to_input_signal(&self.pin, signal, false, false);
}
delegate::delegate! {
@ -356,7 +356,7 @@ impl DirectInputSignal {
fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
fn init_input(&self, pull: Pull);
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.
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&mut self.pin, signal, self.is_inverted, true, true, false);
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&self.pin, signal, self.is_inverted, true, true, false);
}
/// 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
/// pin with a previously connected [signal](`gpio::OutputSignal`). Any
/// other outputs connected to the peripheral remain intact.
fn disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&mut self.pin, signal);
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&self.pin, signal);
}
delegate::delegate! {
@ -448,15 +448,15 @@ impl OutputSignal {
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
pub fn init_input(&self, pull: Pull);
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 set_to_open_drain_output(&mut self);
pub fn set_to_push_pull_output(&mut self);
pub fn enable_output(&mut self, on: bool);
pub fn set_output_high(&mut self, on: bool);
pub fn set_drive_strength(&mut self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&mut self, on: bool);
pub fn set_to_open_drain_output(&self);
pub fn set_to_push_pull_output(&self);
pub fn enable_output(&self, on: bool);
pub fn set_output_high(&self, on: bool);
pub fn set_drive_strength(&self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&self, on: bool);
pub fn is_set_high(&self) -> bool;
}
}
@ -475,8 +475,8 @@ impl DirectOutputSignal {
}
/// Connect the pin to a peripheral output signal.
fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&mut self.pin, signal, false, false, true, false);
fn connect_peripheral_to_output(&self, signal: gpio::OutputSignal) {
connect_peripheral_to_output(&self.pin, signal, false, false, true, false);
}
/// 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
/// pin with a previously connected [signal](`gpio::OutputSignal`). Any
/// other outputs connected to the peripheral remain intact.
fn disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&mut self.pin, signal);
fn disconnect_from_peripheral_output(&self, signal: gpio::OutputSignal) {
disconnect_peripheral_output_from_pin(&self.pin, signal);
}
delegate::delegate! {
@ -494,15 +494,15 @@ impl DirectOutputSignal {
fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
fn init_input(&self, pull: Pull);
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 set_to_open_drain_output(&mut self);
fn set_to_push_pull_output(&mut self);
fn enable_output(&mut self, on: bool);
fn set_output_high(&mut self, on: bool);
fn set_drive_strength(&mut self, strength: gpio::DriveStrength);
fn enable_open_drain(&mut self, on: bool);
fn set_to_open_drain_output(&self);
fn set_to_push_pull_output(&self);
fn enable_output(&self, on: bool);
fn set_output_high(&self, on: bool);
fn set_drive_strength(&self, strength: gpio::DriveStrength);
fn enable_open_drain(&self, on: bool);
fn is_set_high(&self) -> bool;
}
}
@ -605,18 +605,10 @@ impl InputConnection {
pub fn init_input(&self, pull: Pull);
pub fn is_input_high(&self) -> bool;
pub fn input_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::InputSignal)];
}
#[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);
pub fn enable_input(&self, on: bool);
// 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 output_signals(&self, _internal: private::Internal) -> &'static [(AlternateFunction, gpio::OutputSignal)];
}
#[instability::unstable]
to match &mut self.0 {
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 pull_direction(&self, pull: Pull);
pub fn init_input(&self, pull: Pull);
pub fn enable_input(&self, on: bool);
pub fn set_to_open_drain_output(&mut self);
pub fn set_to_push_pull_output(&mut self);
pub fn enable_output(&mut self, on: bool);
pub fn set_output_high(&mut self, on: bool);
pub fn set_drive_strength(&mut self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&mut self, on: bool);
pub fn set_to_open_drain_output(&self);
pub fn set_to_push_pull_output(&self);
pub fn enable_output(&self, on: bool);
pub fn set_output_high(&self, on: bool);
pub fn set_drive_strength(&self, strength: gpio::DriveStrength);
pub fn enable_open_drain(&self, on: bool);
// 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 disconnect_from_peripheral_output(&mut self, signal: gpio::OutputSignal);
fn connect_peripheral_to_output(&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> {
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();
lp_io.pin($gpionum).modify(|_, w| {
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;
unsafe {
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
/// 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;
unsafe {
let lp_aon = $crate::peripherals::LP_AON::regs();
@ -251,12 +251,12 @@ macro_rules! lp_gpio {
}
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();
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();
lp_io.gpio($gpionum).modify(|_, w| w.fun_wpd().bit(enable));
}

View File

@ -376,17 +376,20 @@ pub trait RtcPin: Pin {
/// Configure the pin
#[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
fn rtcio_pad_hold(&mut self, enable: bool);
#[doc(hidden)]
fn rtcio_pad_hold(&self, enable: bool);
/// # Safety
///
/// The `level` argument needs to be a valid setting for the
/// `rtc_cntl.gpio_wakeup.gpio_pinX_int_type`.
#[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
@ -395,9 +398,11 @@ pub trait RtcPin: Pin {
#[cfg(any(lp_io, rtc_cntl))]
pub trait RtcPinWithResistors: RtcPin {
/// 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
fn rtcio_pulldown(&mut self, enable: bool);
#[doc(hidden)]
fn rtcio_pulldown(&self, enable: bool);
}
/// Common trait implemented by pins
@ -1800,7 +1805,7 @@ impl Peripheral for Flex<'_> {
type P = Self;
unsafe fn clone_unchecked(&self) -> Self::P {
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
#[inline]
pub(crate) fn init_output(
&mut self,
&self,
alternate: AlternateFunction,
open_drain: bool,
input_enable: Option<bool>,
@ -2182,31 +2187,31 @@ impl AnyPin {
/// Configure open-drain mode
#[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));
}
/// Configure output mode
#[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);
}
/// Set the pin's level to high or low
#[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);
}
/// Configure the [DriveStrength] of the pin
#[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) });
}
/// Enable/disable open-drain mode
#[inline]
pub(crate) fn enable_open_drain(&mut self, on: bool) {
pub(crate) fn enable_open_drain(&self, on: bool) {
GPIO::regs()
.pin(self.number() as usize)
.modify(|_, w| w.pad_driver().bit(on));
@ -2244,43 +2249,42 @@ impl OutputPin for AnyPin {}
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPin for AnyPin {
#[cfg(xtensa)]
#[allow(unused_braces)] // False positive :/
#[allow(unused_braces, reason = "False positive")]
fn rtc_number(&self) -> u8 {
handle_rtcio!(self, target, { RtcPin::rtc_number(&target) })
}
#[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, {
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) {
handle_rtcio!(self, target, {
RtcPin::rtcio_pad_hold(&mut target, enable)
})
#[allow(unused_braces, reason = "False positive")]
fn rtcio_pad_hold(&self, enable: bool) {
handle_rtcio!(self, target, { RtcPin::rtcio_pad_hold(&target, enable) })
}
#[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, {
RtcPin::apply_wakeup(&mut target, wakeup, level)
RtcPin::apply_wakeup(&target, wakeup, level)
})
}
}
#[cfg(any(lp_io, rtc_cntl))]
impl RtcPinWithResistors for AnyPin {
fn rtcio_pullup(&mut self, enable: bool) {
fn rtcio_pullup(&self, enable: bool) {
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, {
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
// is load-bearing if `wait_for` is dropped during the initialization.
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.

View File

@ -28,13 +28,13 @@ impl Level {
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 {
*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 {
Level::High => ONE_INPUT,
Level::Low => ZERO_INPUT,
@ -43,12 +43,12 @@ impl Level {
connect_input_signal(signal, value, false, true);
}
pub(crate) fn set_to_open_drain_output(&mut self) {}
pub(crate) fn set_to_push_pull_output(&mut self) {}
pub(crate) fn enable_output(&mut self, _on: bool) {}
pub(crate) fn set_output_high(&mut self, _on: bool) {}
pub(crate) fn set_drive_strength(&mut self, _strength: DriveStrength) {}
pub(crate) fn enable_open_drain(&mut self, _on: bool) {}
pub(crate) fn set_to_open_drain_output(&self) {}
pub(crate) fn set_to_push_pull_output(&self) {}
pub(crate) fn enable_output(&self, _on: bool) {}
pub(crate) fn set_output_high(&self, _on: bool) {}
pub(crate) fn set_drive_strength(&self, _strength: DriveStrength) {}
pub(crate) fn enable_open_drain(&self, _on: bool) {}
pub(crate) fn is_set_high(&self) -> bool {
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.

View File

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

View File

@ -7,17 +7,19 @@ use core::{
/// An exclusive reference to a peripheral.
///
/// This is functionally the same as a `&'a mut T`. The reason for having a
/// dedicated struct is memory efficiency:
/// This is functionally the same as a `&'a mut T`. There's a few advantages in
/// having a dedicated struct instead:
///
/// Peripheral singletons are typically either zero-sized (for concrete
/// peripherals like `SPI2` or `UART0`) or very small (for example `AnyPin`
/// which is 1 byte). However `&mut T` is always 4 bytes for 32-bit targets,
/// even if T is zero-sized. PeripheralRef stores a copy of `T` instead, so it's
/// the same size.
///
/// but it is the size of `T` not the size
/// of a pointer. This is useful if T is a zero sized type.
/// - Memory efficiency: Peripheral singletons are typically either zero-sized
/// (for concrete peripherals like `GpioPin<5>` or `SPI2`) or very small (for
/// example `AnyPin`, which is 1 byte). However `&mut T` is always 4 bytes for
/// 32-bit targets, even if T is zero-sized. PeripheralRef stores a copy of
/// `T` instead, so it's the same size.
/// - Code size efficiency. If the user uses the same driver with both `SPI2`
/// and `&mut SPI2`, the driver code would be monomorphized two times. With
/// 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)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
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`.
///
/// 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 `&'a mut T` yields a `PeripheralRef<'a, T>`.
pub trait Peripheral: Sized + crate::private::Sealed {
pub trait Peripheral: Sized {
/// Peripheral singleton type
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
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 {
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> {
type P = T::P;

View File

@ -74,7 +74,7 @@ impl Ext1WakeupSource<'_, '_> {
fn wake_io_reset() {
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 {
pin.rtcio_pad_hold(false);
pin.rtc_set_config(false, false, RtcFunction::Rtc);

View File

@ -56,7 +56,7 @@
//! ## Implementation State
//! - 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
#[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
/// 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,
alignment_helper: AlignmentHelper<SocDependentEndianess>,
cursor: usize,
@ -145,13 +145,13 @@ pub struct ShaDigest<'d, A, S: BorrowMut<Sha<'d>>> {
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
#[allow(unused_mut)]
pub fn new(mut sha: S) -> Self {
#[cfg(not(esp32))]
// Setup SHA Mode.
sha.borrow_mut()
sha.borrow()
.regs()
.mode()
.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.
#[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.
sha.borrow_mut()
sha.borrow()
.regs()
.mode()
.write(|w| unsafe { w.mode().bits(A::MODE_AS_BITS) });
// Restore the message buffer
unsafe {
core::ptr::copy_nonoverlapping(
ctx.buffer.as_ptr(),
m_mem(&sha.borrow_mut().sha, 0),
32,
);
core::ptr::copy_nonoverlapping(ctx.buffer.as_ptr(), m_mem(&sha.borrow().sha, 0), 32);
}
let mut ah = ctx.alignment_helper.clone();
// 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 {
sha,
@ -241,7 +237,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
}
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 = self.cursor.wrapping_add(flushed);
@ -259,7 +255,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> ShaDigest<'d, A, S> {
// buffer
let pad_len = A::CHUNK_LENGTH - mod_cursor;
self.alignment_helper.volatile_write_bytes(
m_mem(&self.sha.borrow_mut().sha, 0),
m_mem(&self.sha.borrow().sha, 0),
0_u8,
pad_len / 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>();
self.alignment_helper.volatile_write_bytes(
m_mem(&self.sha.borrow_mut().sha, 0),
m_mem(&self.sha.borrow().sha, 0),
0,
pad_len / self.alignment_helper.align_size(),
mod_cursor / self.alignment_helper.align_size(),
);
self.alignment_helper.aligned_volatile_copy(
m_mem(&self.sha.borrow_mut().sha, 0),
m_mem(&self.sha.borrow().sha, 0),
&length,
A::CHUNK_LENGTH / 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
#[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
while self.is_busy() {}
}
self.alignment_helper.volatile_read_regset(
h_mem(&self.sha.borrow_mut().sha, 0),
h_mem(&self.sha.borrow().sha, 0),
output,
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.
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,
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.
unsafe {
core::ptr::copy_nonoverlapping(
m_mem(&self.sha.borrow_mut().sha, 0),
m_mem(&self.sha.borrow().sha, 0),
context.buffer.as_mut_ptr(),
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
/// platforms.
fn process_buffer(&mut self) {
let sha = self.sha.borrow_mut();
let sha = self.sha.borrow();
cfg_if::cfg_if! {
if #[cfg(esp32)] {
if self.first_run {
A::start(&mut sha.sha);
A::start(&sha.sha);
self.first_run = false;
} else {
A::r#continue(&mut sha.sha);
A::r#continue(&sha.sha);
}
} else {
if self.first_run {
@ -507,17 +503,17 @@ pub trait ShaAlgorithm: crate::private::Sealed {
#[cfg(esp32)]
#[doc(hidden)]
// Initiate the operation
fn start(sha: &mut crate::peripherals::SHA);
fn start(sha: &crate::peripherals::SHA);
#[cfg(esp32)]
#[doc(hidden)]
// Continue the operation
fn r#continue(sha: &mut crate::peripherals::SHA);
fn r#continue(sha: &crate::peripherals::SHA);
#[cfg(esp32)]
#[doc(hidden)]
// Calculate the final hash
fn load(sha: &mut crate::peripherals::SHA);
fn load(sha: &crate::peripherals::SHA);
#[cfg(esp32)]
#[doc(hidden)]
@ -529,15 +525,15 @@ pub trait ShaAlgorithm: crate::private::Sealed {
/// Note: digest has a blanket trait implementation for [digest::Digest] for any
/// element that implements FixedOutput + Default + Update + HashMarker
#[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")]
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;
}
#[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]) {
let mut remaining = data.as_ref();
while !remaining.is_empty() {
@ -547,7 +543,7 @@ impl<'d, A: ShaAlgorithm, S: BorrowMut<Sha<'d>>> digest::Update for ShaDigest<'d
}
#[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>) {
nb::block!(self.finish(out)).unwrap();
}
@ -587,21 +583,21 @@ macro_rules! impl_sha {
type DigestOutputSize = paste::paste!(digest::consts::[< U $digest_length >]);
#[cfg(esp32)]
fn start(sha: &mut crate::peripherals::SHA) {
fn start(sha: &crate::peripherals::SHA) {
paste::paste! {
sha.register_block().[< $name:lower _start >]().write(|w| w.[< $name:lower _start >]().set_bit());
}
}
#[cfg(esp32)]
fn r#continue(sha: &mut crate::peripherals::SHA) {
fn r#continue(sha: &crate::peripherals::SHA) {
paste::paste! {
sha.register_block().[< $name:lower _continue >]().write(|w| w.[< $name:lower _continue >]().set_bit());
}
}
#[cfg(esp32)]
fn load(sha: &mut crate::peripherals::SHA) {
fn load(sha: &crate::peripherals::SHA) {
paste::paste! {
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
/// 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
paste::paste!{
$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()
.hold_force()
.modify(|_, w| w.$hold().bit(enable));
@ -565,14 +565,14 @@ macro_rules! rtcio_analog {
// FIXME: replace with $(ignore($rue)) once stable
$crate::ignore!($rue);
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! {
$crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
}
}
fn rtcio_pulldown(&mut self, enable: bool) {
fn rtcio_pulldown(&self, enable: bool) {
paste::paste! {
$crate::peripherals::RTC_IO::regs()
.$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 )?);
)+
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};
let has_pullups = match pin.number() {

View File

@ -178,7 +178,7 @@ macro_rules! rtc_pins {
( $( $pin_num:expr )+ ) => {
$(
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();
paste::paste! {
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! {
$crate::peripherals::LPWR::regs()
.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
Self: crate::gpio::RtcPin,
{
fn rtcio_pullup(&mut self, enable: bool) {
fn rtcio_pullup(&self, enable: bool) {
IO_MUX::regs()
.gpio(N as usize)
.modify(|_, w| w.fun_wpu().bit(enable));
}
fn rtcio_pulldown(&mut self, enable: bool) {
fn rtcio_pulldown(&self, enable: bool) {
IO_MUX::regs()
.gpio(N as usize)
.modify(|_, w| w.fun_wpd().bit(enable));

View File

@ -206,7 +206,7 @@ macro_rules! rtc_pins {
( $( $pin_num:expr )+ ) => {
$(
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 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! {
$crate::peripherals::LPWR::regs()
.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
Self: crate::gpio::RtcPin,
{
fn rtcio_pullup(&mut self, enable: bool) {
fn rtcio_pullup(&self, enable: bool) {
IO_MUX::regs()
.gpio(N as usize)
.modify(|_, w| w.fun_wpu().bit(enable));
}
fn rtcio_pulldown(&mut self, enable: bool) {
fn rtcio_pulldown(&self, enable: bool) {
IO_MUX::regs()
.gpio(N as usize)
.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
/// 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();
// 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()
.pad_hold()
.modify(|_, w| w.$hold().bit(enable));
@ -351,14 +351,14 @@ macro_rules! rtcio_analog {
impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num>
{
fn rtcio_pullup(&mut self, enable: bool) {
fn rtcio_pullup(&self, enable: bool) {
paste::paste! {
$crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
}
}
fn rtcio_pulldown(&mut self, enable: bool) {
fn rtcio_pulldown(&self, enable: bool) {
paste::paste! {
$crate::peripherals::RTC_IO::regs()
.$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
/// 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();
// 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()
.pad_hold()
.modify(|_, w| w.$hold().bit(enable));
@ -429,14 +429,14 @@ macro_rules! rtcio_analog {
impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num>
{
fn rtcio_pullup(&mut self, enable: bool) {
fn rtcio_pullup(&self, enable: bool) {
paste::paste! {
$crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit(enable));
}
}
fn rtcio_pulldown(&mut self, enable: bool) {
fn rtcio_pulldown(&self, enable: bool) {
paste::paste! {
$crate::peripherals::RTC_IO::regs()
.$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit(enable));

View File

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

View File

@ -74,29 +74,37 @@ pub enum Error {
}
/// 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.
#[doc(hidden)]
fn start(&self);
/// Stop the timer.
#[doc(hidden)]
fn stop(&self);
/// Reset the timer value to 0.
#[doc(hidden)]
fn reset(&self);
/// Is the timer running?
#[doc(hidden)]
fn is_running(&self) -> bool;
/// The current timer value.
#[doc(hidden)]
fn now(&self) -> Instant<u64, 1, 1_000_000>;
/// Load a target value into the timer.
#[doc(hidden)]
fn load_value(&self, value: MicrosDurationU64) -> Result<(), Error>;
/// Enable auto reload of the loaded value.
#[doc(hidden)]
fn enable_auto_reload(&self, auto_reload: bool);
/// Enable or disable the timer's interrupt.
#[doc(hidden)]
fn enable_interrupt(&self, state: bool);
/// 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
/// correctly.
#[doc(hidden)]
async fn wait(&self);
/// Returns the HAL provided async interrupt handler
#[doc(hidden)]
fn async_interrupt_handler(&self) -> InterruptHandler;
/// Returns the interrupt source for the underlying timer
fn peripheral_interrupt(&self) -> Interrupt;
/// Configures the interrupt handler.
#[doc(hidden)]
fn set_interrupt_handler(&self, handler: InterruptHandler);
}
/// A one-shot timer.
@ -137,7 +151,7 @@ impl<'d> OneShotTimer<'d, Blocking> {
impl<'d> OneShotTimer<'d, Blocking> {
/// 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();
self.inner.set_interrupt_handler(handler);
OneShotTimer {
@ -385,18 +399,7 @@ impl Timer for AnyTimer {
async fn wait(&self);
fn async_interrupt_handler(&self) -> InterruptHandler;
fn peripheral_interrupt(&self) -> Interrupt;
}
}
}
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);
fn set_interrupt_handler(&self, handler: InterruptHandler);
}
}
}

View File

@ -23,7 +23,7 @@ use fugit::{Instant, MicrosDurationU64};
use super::{Error, Timer as _};
use crate::{
interrupt::{self, InterruptConfigurable, InterruptHandler},
interrupt::{self, InterruptHandler},
peripheral::Peripheral,
peripherals::{Interrupt, SYSTIMER},
sync::{lock, RawMutex},
@ -386,7 +386,7 @@ impl Alarm {
}
/// 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() {
0 => Interrupt::SYSTIMER_TARGET0,
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.
#[derive(Copy, Clone)]
enum ComparatorMode {
@ -587,6 +581,10 @@ impl super::Timer for Alarm {
_ => unreachable!(),
}
}
fn set_interrupt_handler(&self, handler: InterruptHandler) {
self.set_interrupt_handler(handler)
}
}
impl Peripheral for Alarm {

View File

@ -351,10 +351,8 @@ impl super::Timer for Timer {
_ => unreachable!(),
}
}
}
impl InterruptConfigurable for Timer {
fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
fn set_interrupt_handler(&self, handler: InterruptHandler) {
self.set_interrupt_handler(handler)
}
}
@ -382,7 +380,7 @@ unsafe impl Send for Timer {}
/// Timer peripheral instance
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()) {
(0, 0) => Interrupt::TG0_T0_LEVEL,
#[cfg(timg_timer1)]