From 22810dddb250e5468e629653ff01c200518409c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 11:17:22 +0200 Subject: [PATCH 01/21] Allow accessing signal list via ErasedPin --- esp-hal/src/gpio/any_pin.rs | 2 ++ esp-hal/src/gpio/dummy_pin.rs | 8 +++++ esp-hal/src/gpio/mod.rs | 57 +++++++++++++++++++++-------------- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/esp-hal/src/gpio/any_pin.rs b/esp-hal/src/gpio/any_pin.rs index 93c59da4d9..f8f43c5d1b 100644 --- a/esp-hal/src/gpio/any_pin.rs +++ b/esp-hal/src/gpio/any_pin.rs @@ -78,6 +78,8 @@ impl<'d> Pin for AnyPin<'d> { fn unlisten(&mut self, _internal: private::Internal); fn is_interrupt_set(&self, _internal: private::Internal) -> bool; fn clear_interrupt(&mut self, _internal: private::Internal); + fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; + fn output_signals(&self, _internal: private::Internal) -> [Option; 6]; } } } diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index cbc41d1fc9..e7fc879559 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -61,6 +61,14 @@ impl Pin for DummyPin { } fn clear_interrupt(&mut self, _: private::Internal) {} + + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + [None; 6] + } + + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + [None; 6] + } } impl OutputPin for DummyPin { diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 41dafe45ae..f0f5e6cba7 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -327,6 +327,14 @@ pub trait Pin: private::Sealed { fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) { self.listen_with_options(event.into(), false, false, enable, private::Internal); } + + /// Returns the list of input signals that can be connected to this pin + /// using IO_MUX. + fn input_signals(&self, _: private::Internal) -> [Option; 6]; + + /// Returns the list of output signals that can be connected to this pin + /// using IO_MUX. + fn output_signals(&self, _: private::Internal) -> [Option; 6]; } /// Trait implemented by pins which can be used as inputs @@ -531,12 +539,6 @@ where } } -#[doc(hidden)] -pub trait GpioSignal { - fn output_signals() -> [Option; 6]; - fn input_signals() -> [Option; 6]; -} - #[doc(hidden)] pub struct Bank0GpioRegisterAccess; @@ -804,10 +806,7 @@ where GPIO_FUNCTION } else { let mut res = GPIO_FUNCTION; - for (i, input_signal) in ::Signals::input_signals() - .iter() - .enumerate() - { + for (i, input_signal) in self.input_signals(private::Internal).iter().enumerate() { if let Some(input_signal) = input_signal { if *input_signal == signal { res = match i { @@ -912,6 +911,14 @@ where fn clear_interrupt(&mut self, _: private::Internal) { ::Bank::write_interrupt_status_clear(1 << (GPIONUM % 32)); } + + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + ::input_signals() + } + + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + ::output_signals() + } } impl Peripheral for GpioPin @@ -1038,10 +1045,7 @@ where GPIO_FUNCTION } else { let mut res = GPIO_FUNCTION; - for (i, output_signal) in ::Signals::output_signals() - .iter() - .enumerate() - { + for (i, output_signal) in self.output_signals(private::Internal).iter().enumerate() { if let Some(output_signal) = output_signal { if *output_signal == signal { res = match i { @@ -1174,13 +1178,14 @@ fn on_pin_irq(pin_nr: u8) { pub trait GpioProperties { type Bank: BankGpioRegisterAccess; type InterruptStatus: InterruptStatusRegisterAccess; - type Signals: GpioSignal; type IsOutput: BooleanType; type IsAnalog: BooleanType; type IsTouch: BooleanType; fn degrade_pin(&self, _: private::Internal) -> ErasedPin; + fn output_signals() -> [Option; 6]; + fn input_signals() -> [Option; 6]; } #[doc(hidden)] @@ -1253,21 +1258,15 @@ macro_rules! gpio { impl $crate::gpio::GpioProperties for GpioPin<$gpionum> { type Bank = $crate::gpio::[< Bank $bank GpioRegisterAccess >]; type InterruptStatus = $crate::gpio::[< InterruptStatusRegisterAccessBank $bank >]; - type Signals = [< Gpio $gpionum Signals >]; $crate::pin_types!($type); fn degrade_pin(&self, _: $crate::private::Internal) -> ErasedPin { ErasedPin($crate::gpio::ErasedPinInner::[< Gpio $gpionum >](unsafe { Self::steal() })) } - } - #[doc(hidden)] - pub struct []; - - impl $crate::gpio::GpioSignal for [] { fn output_signals() -> [Option; 6]{ #[allow(unused_mut)] - let mut output_signals = [None, None, None, None, None, None]; + let mut output_signals = [None; 6]; $( $( @@ -1279,7 +1278,7 @@ macro_rules! gpio { } fn input_signals() -> [Option; 6] { #[allow(unused_mut)] - let mut input_signals = [None, None, None, None, None, None]; + let mut input_signals = [None; 6]; $( $( @@ -2309,6 +2308,18 @@ pub(crate) mod internal { Pin::clear_interrupt(target, private::Internal) }) } + + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_input!(&self.0, target, { + Pin::input_signals(target, private::Internal) + }) + } + + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_output!(&self.0, target, { + Pin::output_signals(target, private::Internal) + }) + } } impl InputPin for ErasedPin { From 319bee8783872afae6d6653d9a505c894b15ae3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 11:06:15 +0200 Subject: [PATCH 02/21] Replace AnyPin with more flexible signal config --- esp-hal/src/gpio/any_pin.rs | 171 -------- esp-hal/src/gpio/dummy_pin.rs | 107 +++-- esp-hal/src/gpio/interconnect.rs | 337 ++++++++++++++++ esp-hal/src/gpio/mod.rs | 655 ++++++++++++------------------- esp-hal/src/i2c.rs | 45 ++- esp-hal/src/i2s.rs | 31 +- esp-hal/src/ledc/channel.rs | 17 +- esp-hal/src/mcpwm/operator.rs | 30 +- esp-hal/src/parl_io.rs | 46 +-- esp-hal/src/rmt.rs | 171 ++++---- esp-hal/src/spi/master.rs | 245 ++++++------ esp-hal/src/spi/slave.rs | 20 +- esp-hal/src/twai/mod.rs | 20 +- esp-hal/src/uart.rs | 34 +- 14 files changed, 979 insertions(+), 950 deletions(-) delete mode 100644 esp-hal/src/gpio/any_pin.rs create mode 100644 esp-hal/src/gpio/interconnect.rs diff --git a/esp-hal/src/gpio/any_pin.rs b/esp-hal/src/gpio/any_pin.rs deleted file mode 100644 index f8f43c5d1b..0000000000 --- a/esp-hal/src/gpio/any_pin.rs +++ /dev/null @@ -1,171 +0,0 @@ -use super::*; - -/// A type-erased GPIO pin, with additional configuration options. -/// -/// Note that accessing unsupported pin functions (e.g. trying to use an -/// input-only pin as output) will panic. -pub struct AnyPin<'d> { - pin: ErasedPin, - is_inverted: bool, - _phantom: PhantomData<&'d ()>, -} - -impl<'d> AnyPin<'d> { - /// Create wrapper for the given pin. - #[inline] - pub fn new

(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self - where - P: Pin, - { - crate::into_ref!(pin); - let pin = pin.degrade_internal(private::Internal); - - Self { - pin, - is_inverted: false, - _phantom: PhantomData, - } - } - - /// Create wrapper for the given pin. The peripheral signal will be - /// inverted. - #[inline] - pub fn new_inverted

(pin: impl crate::peripheral::Peripheral

+ 'd) -> Self - where - P: Pin, - { - crate::into_ref!(pin); - let pin = pin.degrade_internal(private::Internal); - - Self { - pin, - is_inverted: true, - _phantom: PhantomData, - } - } -} - -impl<'d> crate::peripheral::Peripheral for AnyPin<'d> { - type P = Self; - - unsafe fn clone_unchecked(&mut self) -> Self::P { - Self { - pin: unsafe { self.pin.clone_unchecked() }, - is_inverted: self.is_inverted, - _phantom: PhantomData, - } - } -} - -impl<'d> private::Sealed for AnyPin<'d> {} - -impl<'d> Pin for AnyPin<'d> { - delegate::delegate! { - to self.pin { - fn number(&self, _internal: private::Internal) -> u8; - fn degrade_internal(&self, _internal: private::Internal) -> ErasedPin; - fn sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn set_alternate_function(&mut self, alternate: AlternateFunction, _internal: private::Internal); - fn is_listening(&self, _internal: private::Internal) -> bool; - fn listen_with_options( - &mut self, - event: Event, - int_enable: bool, - nmi_enable: bool, - wake_up_from_light_sleep: bool, - _internal: private::Internal, - ); - fn unlisten(&mut self, _internal: private::Internal); - fn is_interrupt_set(&self, _internal: private::Internal) -> bool; - fn clear_interrupt(&mut self, _internal: private::Internal); - fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; - fn output_signals(&self, _internal: private::Internal) -> [Option; 6]; - } - } -} - -impl<'d> OutputPin for AnyPin<'d> { - delegate::delegate! { - to self.pin { - fn set_to_open_drain_output(&mut self, _internal: private::Internal); - fn set_to_push_pull_output(&mut self, _internal: private::Internal); - fn enable_output(&mut self, on: bool, _internal: private::Internal); - fn set_output_high(&mut self, on: bool, _internal: private::Internal); - fn set_drive_strength(&mut self, strength: DriveStrength, _internal: private::Internal); - fn enable_open_drain(&mut self, on: bool, _internal: private::Internal); - fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_up(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_down(&mut self, on: bool, _internal: private::Internal); - fn disconnect_peripheral_from_output(&mut self, _internal: private::Internal); - fn is_set_high(&self, _internal: private::Internal) -> bool; - } - } - - fn connect_peripheral_to_output_with_options( - &mut self, - signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, - _internal: private::Internal, - ) { - if self.is_inverted { - self.pin.connect_peripheral_to_output_with_options( - signal, - true, - false, - false, - true, - private::Internal, - ); - } else { - self.pin.connect_peripheral_to_output_with_options( - signal, - invert, - invert_enable, - enable_from_gpio, - force_via_gpio_mux, - private::Internal, - ); - } - } -} - -impl<'d> InputPin for AnyPin<'d> { - delegate::delegate! { - to self.pin { - fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal); - fn enable_input(&mut self, on: bool, _internal: private::Internal); - fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn is_input_high(&self, _internal: private::Internal) -> bool; - fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _internal: private::Internal); - } - } - - fn connect_input_to_peripheral_with_options( - &mut self, - signal: InputSignal, - invert: bool, - force_via_gpio_mux: bool, - _internal: private::Internal, - ) { - if self.is_inverted { - self.pin.connect_input_to_peripheral_with_options( - signal, - true, - true, - private::Internal, - ); - } else { - self.pin.connect_input_to_peripheral_with_options( - signal, - invert, - force_via_gpio_mux, - private::Internal, - ); - } - } -} diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index e7fc879559..c0791b02f9 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -5,7 +5,7 @@ use super::*; /// DummyPin, not useful everywhere as it panics if number() is called -#[derive(Default)] +#[derive(Default, Clone)] pub struct DummyPin { value: bool, } @@ -39,39 +39,52 @@ impl Pin for DummyPin { fn sleep_mode(&mut self, _on: bool, _: private::Internal) {} fn set_alternate_function(&mut self, _alternate: AlternateFunction, _: private::Internal) {} +} - fn is_listening(&self, _: private::Internal) -> bool { - false +impl PeripheralInputPin for DummyPin { + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + [None; 6] } - fn listen_with_options( - &mut self, - _event: Event, - _int_enable: bool, - _nmi_enable: bool, - _wake_up_from_light_sleep: bool, - _: private::Internal, - ) { - } + fn init_input(&self, _pull_down: bool, _pull_up: bool, _: private::Internal) {} - fn unlisten(&mut self, _: private::Internal) {} + fn enable_input(&mut self, _on: bool, _: private::Internal) {} - fn is_interrupt_set(&self, _: private::Internal) -> bool { - false - } + fn enable_input_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {} - fn clear_interrupt(&mut self, _: private::Internal) {} + fn is_input_high(&self, _: private::Internal) -> bool { + self.value + } - fn input_signals(&self, _: private::Internal) -> [Option; 6] { - [None; 6] + fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { + if self.value { + connect_high_to_peripheral(signal); + } else { + connect_low_to_peripheral(signal); + } } - fn output_signals(&self, _: private::Internal) -> [Option; 6] { - [None; 6] + fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} +} + +impl PeripheralInputPin for Level { + delegate::delegate! { + to match self { + Level::High => DummyPin { value: true }, + Level::Low => DummyPin { value: false }, + } { + fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; + fn init_input(&self, _pd: bool, _pu: bool, _internal: private::Internal); + fn enable_input(&mut self, _on: bool, _internal: private::Internal); + fn enable_input_in_sleep_mode(&mut self, _on: bool, _internal: private::Internal); + fn is_input_high(&self, _internal: private::Internal) -> bool; + fn connect_input_to_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal); + fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal); + } } } -impl OutputPin for DummyPin { +impl PeripheralOutputPin for DummyPin { fn set_to_open_drain_output(&mut self, _: private::Internal) {} fn set_to_push_pull_output(&mut self, _: private::Internal) {} @@ -96,51 +109,21 @@ impl OutputPin for DummyPin { fn internal_pull_down(&mut self, _on: bool, _: private::Internal) {} - fn connect_peripheral_to_output(&mut self, _signal: OutputSignal, _: private::Internal) {} - - fn connect_peripheral_to_output_with_options( - &mut self, - _signal: OutputSignal, - _invert: bool, - _invert_enable: bool, - _enable_from_gpio: bool, - _force_via_gpio_mux: bool, - _: private::Internal, - ) { - } - - fn disconnect_peripheral_from_output(&mut self, _: private::Internal) {} - fn is_set_high(&self, _: private::Internal) -> bool { self.value } -} - -impl InputPin for DummyPin { - fn init_input(&self, _pull_down: bool, _pull_up: bool, _: private::Internal) {} - - fn enable_input(&mut self, _on: bool, _: private::Internal) {} - - fn enable_input_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {} - fn is_input_high(&self, _: private::Internal) -> bool { - self.value + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + [None; 6] } - fn connect_input_to_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} - - fn connect_input_to_peripheral_with_options( - &mut self, - _signal: InputSignal, - _invert: bool, - _force_via_gpio_mux: bool, - _: private::Internal, - ) { - } + fn connect_peripheral_to_output(&mut self, _signal: OutputSignal, _: private::Internal) {} - fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} + fn disconnect_from_peripheral_output(&mut self, _signal: OutputSignal, _: private::Internal) {} } +impl OutputPin for DummyPin {} + impl embedded_hal_02::digital::v2::OutputPin for DummyPin { type Error = core::convert::Infallible; @@ -155,10 +138,10 @@ impl embedded_hal_02::digital::v2::OutputPin for DummyPin { } impl embedded_hal_02::digital::v2::StatefulOutputPin for DummyPin { fn is_set_high(&self) -> Result { - Ok(OutputPin::is_set_high(self, private::Internal)) + Ok(PeripheralOutputPin::is_set_high(self, private::Internal)) } fn is_set_low(&self) -> Result { - Ok(!OutputPin::is_set_high(self, private::Internal)) + Ok(!PeripheralOutputPin::is_set_high(self, private::Internal)) } } @@ -180,10 +163,10 @@ impl embedded_hal::digital::OutputPin for DummyPin { impl embedded_hal::digital::StatefulOutputPin for DummyPin { fn is_set_high(&mut self) -> Result { - Ok(OutputPin::is_set_high(self, private::Internal)) + Ok(PeripheralOutputPin::is_set_high(self, private::Internal)) } fn is_set_low(&mut self) -> Result { - Ok(!OutputPin::is_set_high(self, private::Internal)) + Ok(!PeripheralOutputPin::is_set_high(self, private::Internal)) } } diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs new file mode 100644 index 0000000000..2a9120d14e --- /dev/null +++ b/esp-hal/src/gpio/interconnect.rs @@ -0,0 +1,337 @@ +//! Peripheral signal interconnect using IOMUX or GPIOMUX. + +use crate::{ + gpio::{ + self, + AlternateFunction, + DummyPin, + ErasedPin, + GpioPin, + InputPin, + Level, + OutputSignalType, + PeripheralInputPin, + PeripheralOutputPin, + Pin, + FUNC_IN_SEL_OFFSET, + GPIO_FUNCTION, + INPUT_SIGNAL_MAX, + OUTPUT_SIGNAL_MAX, + }, + peripherals::GPIO, + private::{self, Sealed}, +}; + +/// Multiple input signal can be connected to one pin. +pub struct InputSignal { + pin: ErasedPin, + is_inverted: bool, +} + +impl Clone for InputSignal { + fn clone(&self) -> Self { + Self { + pin: unsafe { self.pin.clone_unchecked() }, + is_inverted: self.is_inverted, + } + } +} + +impl Sealed for InputSignal {} + +impl InputSignal { + pub(crate) fn new(pin: ErasedPin) -> Self { + Self { + pin, + is_inverted: false, + } + } + + /// Inverts the peripheral's input signal. + pub fn invert(&mut self) { + self.is_inverted = !self.is_inverted; + } + + fn connect(&self, signal: usize, invert: bool, input: u8) { + unsafe { &*GPIO::PTR } + .func_in_sel_cfg(signal - FUNC_IN_SEL_OFFSET) + .modify(|_, w| unsafe { + w.sel() + .set_bit() + .in_inv_sel() + .bit(invert) + .in_sel() + .bits(input) + }); + } +} + +impl PeripheralInputPin for InputSignal { + /// Connect the pin to a peripheral input signal. + fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal, _: private::Internal) { + let signal_nr = signal as usize; + + let af = if self.is_inverted { + GPIO_FUNCTION + } else if let Some(af) = self + .pin + .input_signals(private::Internal) + .into_iter() + .position(|s| s == Some(signal)) + { + match af { + 0 => AlternateFunction::Function0, + 1 => AlternateFunction::Function1, + 2 => AlternateFunction::Function2, + 3 => AlternateFunction::Function3, + 4 => AlternateFunction::Function4, + 5 => AlternateFunction::Function5, + _ => unreachable!(), + } + } else { + GPIO_FUNCTION + }; + + if af == GPIO_FUNCTION && signal_nr > INPUT_SIGNAL_MAX as usize { + panic!("Cannot connect GPIO to this peripheral"); + } + + self.pin.set_alternate_function(af, private::Internal); + + if signal_nr <= INPUT_SIGNAL_MAX as usize { + self.connect( + signal_nr, + self.is_inverted, + self.pin.number(private::Internal), + ); + } + } + + /// Remove this pin from a connected peripheral input. + /// + /// Clears the entry in the GPIO matrix / Io mux that associates this input + /// pin with the given [input `signal`](`InputSignal`). Any other + /// connected signals remain intact. + fn disconnect_input_from_peripheral( + &mut self, + signal: gpio::InputSignal, + _: private::Internal, + ) { + self.pin + .set_alternate_function(GPIO_FUNCTION, private::Internal); + + unsafe { &*GPIO::PTR } + .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) + .modify(|_, w| w.sel().clear_bit()); + } + + delegate::delegate! { + to self.pin { + fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal); + fn is_input_high(&self, _internal: private::Internal) -> bool; + fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; + fn enable_input(&mut self, on: bool, _internal: private::Internal); + fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); + } + } +} + +/// Multiple pins can be connected to one output signal. +pub struct OutputSignal { + is_inverted: bool, + pin: ErasedPin, +} + +impl Sealed for OutputSignal {} + +impl OutputSignal { + pub(crate) fn new(pin: ErasedPin) -> Self { + Self { + is_inverted: false, + pin, + } + } + + /// Inverts the peripheral's output signal. + pub fn invert(&mut self) { + self.is_inverted = !self.is_inverted; + } + + fn connect( + &self, + signal: OutputSignalType, + invert: bool, + invert_enable: bool, + enable_from_gpio: bool, + output: u8, + ) { + unsafe { &*GPIO::PTR } + .func_out_sel_cfg(output as usize) + .modify(|_, w| unsafe { + w.out_sel() + .bits(signal) + .inv_sel() + .bit(invert) + .oen_sel() + .bit(enable_from_gpio) + .oen_inv_sel() + .bit(invert_enable) + }); + } +} + +impl PeripheralOutputPin for OutputSignal { + /// Connect the pin to a peripheral output signal. + // TODO: the following options should be part of the struct: + /// invert: Configures whether or not to invert the output value + /// + /// invert_enable: Configures whether or not to invert the output enable + /// signal + /// + /// enable_from_gpio: Configures to select the source of output enable + /// signal. + /// - false = Use output enable signal from peripheral + /// - true = Force the output enable signal to be sourced from bit n of + /// GPIO_ENABLE_REG + /// + /// force_via_gpio_mux: if true don't use the alternate function even if it + /// matches + fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal, _: private::Internal) { + let af = if self.is_inverted { + GPIO_FUNCTION + } else if let Some(af) = self + .pin + .output_signals(private::Internal) + .into_iter() + .position(|s| s == Some(signal)) + { + match af { + 0 => AlternateFunction::Function0, + 1 => AlternateFunction::Function1, + 2 => AlternateFunction::Function2, + 3 => AlternateFunction::Function3, + 4 => AlternateFunction::Function4, + 5 => AlternateFunction::Function5, + _ => unreachable!(), + } + } else { + GPIO_FUNCTION + }; + + self.pin.set_alternate_function(af, private::Internal); + + let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize { + signal as OutputSignalType + } else { + OUTPUT_SIGNAL_MAX + }; + + self.connect( + clipped_signal, + self.is_inverted, + false, + true, + self.pin.number(private::Internal), + ); + } + + /// Remove this output pin from a connected [signal](`OutputSignal`). + /// + /// Clears the entry in the GPIO matrix / Io mux that associates this output + /// pin with a previously connected [signal](`OutputSignal`). Any other + /// outputs connected to the signal remain intact. + fn disconnect_from_peripheral_output( + &mut self, + signal: gpio::OutputSignal, + _: private::Internal, + ) { + self.pin + .set_alternate_function(GPIO_FUNCTION, private::Internal); + + unsafe { &*GPIO::PTR } + .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) + .modify(|_, w| w.sel().clear_bit()); + } + + delegate::delegate! { + to self.pin { + fn set_to_open_drain_output(&mut self, _internal: private::Internal); + fn set_to_push_pull_output(&mut self, _internal: private::Internal); + fn enable_output(&mut self, on: bool, _internal: private::Internal); + fn set_output_high(&mut self, on: bool, _internal: private::Internal); + fn set_drive_strength(&mut self, strength: gpio::DriveStrength, _internal: private::Internal); + fn enable_open_drain(&mut self, on: bool, _internal: private::Internal); + fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); + fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); + fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); + fn internal_pull_up(&mut self, on: bool, _internal: private::Internal); + fn internal_pull_down(&mut self, on: bool, _internal: private::Internal); + fn is_set_high(&self, _internal: private::Internal) -> bool; + fn output_signals(&self, _internal: private::Internal) -> [Option; 6]; + } + } +} + +#[derive(Clone)] +enum AnyInputSignalInner { + Input(InputSignal), + Constant(Level), + Dummy(DummyPin), +} + +/// A type-erased input signal. +#[derive(Clone)] +pub struct AnyInputSignal(AnyInputSignalInner); + +impl From for AnyInputSignal { + fn from(input: InputSignal) -> Self { + Self(AnyInputSignalInner::Input(input)) + } +} + +impl From for AnyInputSignal { + fn from(level: Level) -> Self { + Self(AnyInputSignalInner::Constant(level)) + } +} + +impl From for AnyInputSignal { + fn from(pin: DummyPin) -> Self { + Self(AnyInputSignalInner::Dummy(pin)) + } +} + +impl From> for AnyInputSignal +where + GpioPin: InputPin, +{ + fn from(pin: GpioPin) -> Self { + Self(AnyInputSignalInner::Input(pin.peripheral_input())) + } +} + +impl Sealed for AnyInputSignal {} +impl PeripheralInputPin for AnyInputSignal { + delegate::delegate! { + to match &self.0 { + AnyInputSignalInner::Input(pin) => pin, + AnyInputSignalInner::Constant(level) => level, + AnyInputSignalInner::Dummy(pin) => pin, + } { + fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal); + fn is_input_high(&self, _internal: private::Internal) -> bool; + fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; + } + + to match &mut self.0 { + AnyInputSignalInner::Input(pin) => pin, + AnyInputSignalInner::Constant(level) => level, + AnyInputSignalInner::Dummy(pin) => pin, + } { + fn enable_input(&mut self, on: bool, _internal: private::Internal); + fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); + fn connect_input_to_peripheral(&mut self, signal: crate::gpio::InputSignal, _internal: private::Internal); + fn disconnect_input_from_peripheral(&mut self, signal: crate::gpio::InputSignal, _internal: private::Internal); + } + } +} diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index f0f5e6cba7..37664a3a7a 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -52,8 +52,6 @@ //! [Commonly Used Setup]: ../index.html#commonly-used-setup //! [Inverting TX and RX Pins]: ../uart/index.html#inverting-tx-and-rx-pins -use core::marker::PhantomData; - use portable_atomic::{AtomicPtr, Ordering}; use procmacros::ram; @@ -69,14 +67,13 @@ use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{GPIO, IO_MUX}, - private, + private::{self, Sealed}, InterruptConfigurable, }; -mod any_pin; mod dummy_pin; +pub mod interconnect; -pub use any_pin::AnyPin; pub use dummy_pin::DummyPin; #[cfg(soc_etm)] @@ -153,6 +150,8 @@ pub enum Level { High, } +impl Sealed for Level {} + impl core::ops::Not for Level { type Output = Self; @@ -269,7 +268,7 @@ pub trait RtcPinWithResistors: RtcPin { } /// Common trait implemented by pins -pub trait Pin: private::Sealed { +pub trait Pin: Sealed { /// GPIO number fn number(&self, _: private::Internal) -> u8; @@ -293,52 +292,10 @@ pub trait Pin: private::Sealed { /// Configure the alternate function fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal); - - /// Listen for interrupts - fn listen(&mut self, event: Event, _: private::Internal) { - self.listen_with_options(event, true, false, false, private::Internal) - } - - /// Checks if listening for interrupts is enabled for this Pin - fn is_listening(&self, _: private::Internal) -> bool { - is_listening(self.number(private::Internal)) - } - - /// Listen for interrupts - fn listen_with_options( - &mut self, - event: Event, - int_enable: bool, - nmi_enable: bool, - wake_up_from_light_sleep: bool, - _: private::Internal, - ); - - /// Stop listening for interrupts - fn unlisten(&mut self, _: private::Internal); - - /// Checks if the interrupt status bit for this Pin is set - fn is_interrupt_set(&self, _: private::Internal) -> bool; - - /// Clear the interrupt status bit for this Pin - fn clear_interrupt(&mut self, _: private::Internal); - - /// Enable this pin as a wake up source - fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) { - self.listen_with_options(event.into(), false, false, enable, private::Internal); - } - - /// Returns the list of input signals that can be connected to this pin - /// using IO_MUX. - fn input_signals(&self, _: private::Internal) -> [Option; 6]; - - /// Returns the list of output signals that can be connected to this pin - /// using IO_MUX. - fn output_signals(&self, _: private::Internal) -> [Option; 6]; } -/// Trait implemented by pins which can be used as inputs -pub trait InputPin: Pin { +/// Trait implemented by pins which can be used as peripheral inputs. +pub trait PeripheralInputPin: Sealed { /// Init as input with the given pull-up/pull-down fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal); @@ -351,33 +308,19 @@ pub trait InputPin: Pin { /// The current state of the input fn is_input_high(&self, _: private::Internal) -> bool; - /// Connect the pin to a peripheral input signal - fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - self.connect_input_to_peripheral_with_options(signal, false, false, private::Internal); - } + /// Returns the list of input signals that can be connected to this pin + /// using IO_MUX. + fn input_signals(&self, _: private::Internal) -> [Option; 6]; - /// Connect the pin to a peripheral input signal. - /// - /// Optionally invert the signal. When `force_via_gpio_mux` is true it will - /// won't use the alternate function even if it matches - fn connect_input_to_peripheral_with_options( - &mut self, - signal: InputSignal, - invert: bool, - force_via_gpio_mux: bool, - _: private::Internal, - ); + /// Connect the pin to a peripheral. + fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal); - /// Remove a connected `signal` from this input pin. - /// - /// Clears the entry in the GPIO matrix / Io mux that associates this input - /// pin with the given [input `signal`](`InputSignal`). Any other - /// connected signals remain intact. + /// Disconnect the pin from a peripheral. fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal); } -/// Trait implemented by pins which can be used as outputs -pub trait OutputPin: Pin { +/// Trait implemented by pins which can be used as peripheral outputs. +pub trait PeripheralOutputPin: Sealed { /// Configure open-drain mode fn set_to_open_drain_output(&mut self, _: private::Internal); @@ -411,52 +354,71 @@ pub trait OutputPin: Pin { /// Enable/disable internal pull-down resistor for normal operation fn internal_pull_down(&mut self, on: bool, _: private::Internal); - /// Connect the pin to a peripheral output signal - fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { - self.connect_peripheral_to_output_with_options( - signal, - false, - false, - false, - false, - private::Internal, - ) + /// Is the output set to high + fn is_set_high(&self, _: private::Internal) -> bool; + + /// Returns the list of output signals that can be connected to this pin + /// using IO_MUX. + fn output_signals(&self, _: private::Internal) -> [Option; 6]; + + /// Connect the pin to a peripheral. + fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal); + + /// Disconnect the pin from a peripheral. + fn disconnect_from_peripheral_output(&mut self, signal: OutputSignal, _: private::Internal); +} + +/// Trait implemented by pins which can be used as inputs. +pub trait InputPin: Pin + PeripheralInputPin { + /// Listen for interrupts + fn listen(&mut self, event: Event, _: private::Internal) { + self.listen_with_options(event, true, false, false, private::Internal) } - /// Connect the pin to a peripheral output signal. - /// - /// invert: Configures whether or not to invert the output value - /// - /// invert_enable: Configures whether or not to invert the output enable - /// signal - /// - /// enable_from_gpio: Configures to select the source of output enable - /// signal. - /// - false = Use output enable signal from peripheral - /// - true = Force the output enable signal to be sourced from bit n of - /// GPIO_ENABLE_REG - /// - /// force_via_gpio_mux: if true don't use the alternate function even if it - /// matches - fn connect_peripheral_to_output_with_options( + /// Checks if listening for interrupts is enabled for this Pin + fn is_listening(&self, _: private::Internal) -> bool { + is_listening(self.number(private::Internal)) + } + + /// Listen for interrupts + fn listen_with_options( &mut self, - signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, + event: Event, + int_enable: bool, + nmi_enable: bool, + wake_up_from_light_sleep: bool, _: private::Internal, ); - /// Remove this output pin from a connected [signal](`InputSignal`). - /// - /// Clears the entry in the GPIO matrix / Io mux that associates this output - /// pin with a previously connected [signal](`InputSignal`). Any other - /// outputs connected to the signal remain intact. - fn disconnect_peripheral_from_output(&mut self, _: private::Internal); + /// Stop listening for interrupts + fn unlisten(&mut self, _: private::Internal); - /// Is the output set to high - fn is_set_high(&self, _: private::Internal) -> bool; + /// Checks if the interrupt status bit for this Pin is set + fn is_interrupt_set(&self, _: private::Internal) -> bool; + + /// Clear the interrupt status bit for this Pin + fn clear_interrupt(&mut self, _: private::Internal); + + /// Enable this pin as a wake up source + fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) { + self.listen_with_options(event.into(), false, false, enable, private::Internal); + } + + /// Turns the pin object into a peripheral input. + fn peripheral_input(&self) -> interconnect::InputSignal { + interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + } +} + +/// Trait implemented by pins which can be used as outputs. +pub trait OutputPin: Pin + PeripheralOutputPin { + /// Turns the pin object into a peripheral output. + fn into_peripheral_output(self) -> interconnect::OutputSignal + where + Self: Sized, + { + interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + } } /// Trait implemented by pins which can be used as analog pins @@ -751,7 +713,41 @@ fn disable_usb_pads(gpionum: u8) { } } -impl InputPin for GpioPin +impl Peripheral for GpioPin +where + Self: GpioProperties, +{ + type P = GpioPin; + + unsafe fn clone_unchecked(&mut self) -> Self::P { + core::ptr::read(self as *const _) + } +} + +impl private::Sealed for GpioPin where Self: GpioProperties {} + +impl Pin for GpioPin +where + Self: GpioProperties, +{ + fn number(&self, _: private::Internal) -> u8 { + GPIONUM + } + + fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + self.degrade_pin(private::Internal) + } + + fn sleep_mode(&mut self, on: bool, _: private::Internal) { + get_io_mux_reg(GPIONUM).modify(|_, w| w.slp_sel().bit(on)); + } + + fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal) { + get_io_mux_reg(GPIONUM).modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) }); + } +} + +impl PeripheralInputPin for GpioPin where Self: GpioProperties, { @@ -795,82 +791,25 @@ where ::Bank::read_input() & (1 << (GPIONUM % 32)) != 0 } - fn connect_input_to_peripheral_with_options( - &mut self, - signal: InputSignal, - invert: bool, - force_via_gpio_mux: bool, - _: private::Internal, - ) { - let af = if force_via_gpio_mux { - GPIO_FUNCTION - } else { - let mut res = GPIO_FUNCTION; - for (i, input_signal) in self.input_signals(private::Internal).iter().enumerate() { - if let Some(input_signal) = input_signal { - if *input_signal == signal { - res = match i { - 0 => AlternateFunction::Function0, - 1 => AlternateFunction::Function1, - 2 => AlternateFunction::Function2, - 3 => AlternateFunction::Function3, - 4 => AlternateFunction::Function4, - 5 => AlternateFunction::Function5, - _ => unreachable!(), - }; - break; - } - } - } - res - }; - if af == GPIO_FUNCTION && signal as usize > INPUT_SIGNAL_MAX as usize { - panic!("Cannot connect GPIO to this peripheral"); - } - self.set_alternate_function(af, private::Internal); - if (signal as usize) <= INPUT_SIGNAL_MAX as usize { - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) - .modify(|_, w| unsafe { - w.sel() - .set_bit() - .in_inv_sel() - .bit(invert) - .in_sel() - .bits(GPIONUM) - }); - } + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + ::input_signals() } - fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - self.set_alternate_function(GPIO_FUNCTION, private::Internal); + fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { + self.peripheral_input() + .connect_input_to_peripheral(signal, private::Internal); + } - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) - .modify(|_, w| w.sel().clear_bit()); + fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { + self.peripheral_input() + .disconnect_input_from_peripheral(signal, private::Internal); } } -impl Pin for GpioPin +impl InputPin for GpioPin where Self: GpioProperties, { - fn number(&self, _: private::Internal) -> u8 { - GPIONUM - } - - fn degrade_internal(&self, _: private::Internal) -> ErasedPin { - self.degrade_pin(private::Internal) - } - - fn sleep_mode(&mut self, on: bool, _: private::Internal) { - get_io_mux_reg(GPIONUM).modify(|_, w| w.slp_sel().bit(on)); - } - - fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal) { - get_io_mux_reg(GPIONUM).modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) }); - } - fn listen_with_options( &mut self, event: Event, @@ -911,68 +850,9 @@ where fn clear_interrupt(&mut self, _: private::Internal) { ::Bank::write_interrupt_status_clear(1 << (GPIONUM % 32)); } - - fn input_signals(&self, _: private::Internal) -> [Option; 6] { - ::input_signals() - } - - fn output_signals(&self, _: private::Internal) -> [Option; 6] { - ::output_signals() - } } -impl Peripheral for GpioPin -where - Self: GpioProperties, -{ - type P = GpioPin; - - unsafe fn clone_unchecked(&mut self) -> Self::P { - core::ptr::read(self as *const _) - } -} - -impl private::Sealed for GpioPin where Self: GpioProperties {} - -impl GpioPin -where - Self: GpioProperties, -{ - fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { - let gpio = unsafe { &*GPIO::PTR }; - - #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, Some(false), Some(false)); - - self.write_out_en(true); - - gpio.pin(GPIONUM as usize) - .modify(|_, w| w.pad_driver().bit(open_drain)); - - gpio.func_out_sel_cfg(GPIONUM as usize) - .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); - - #[cfg(any(esp32c3, esp32s3))] - disable_usb_pads(GPIONUM); - - get_io_mux_reg(GPIONUM).modify(|_, w| unsafe { - w.mcu_sel() - .bits(alternate as u8) - .fun_ie() - .bit(open_drain) - .fun_wpd() - .clear_bit() - .fun_wpu() - .clear_bit() - .fun_drv() - .bits(DriveStrength::I20mA as u8) - .slp_sel() - .clear_bit() - }); - } -} - -impl OutputPin for GpioPin +impl PeripheralOutputPin for GpioPin where Self: GpioProperties, { @@ -1032,69 +912,62 @@ where get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpd().bit(on)); } - fn connect_peripheral_to_output_with_options( - &mut self, - signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, - _: private::Internal, - ) { - let af = if force_via_gpio_mux { - GPIO_FUNCTION - } else { - let mut res = GPIO_FUNCTION; - for (i, output_signal) in self.output_signals(private::Internal).iter().enumerate() { - if let Some(output_signal) = output_signal { - if *output_signal == signal { - res = match i { - 0 => AlternateFunction::Function0, - 1 => AlternateFunction::Function1, - 2 => AlternateFunction::Function2, - 3 => AlternateFunction::Function3, - 4 => AlternateFunction::Function4, - 5 => AlternateFunction::Function5, - _ => unreachable!(), - }; - break; - } - } - } - res - }; - if af == GPIO_FUNCTION && signal as usize > OUTPUT_SIGNAL_MAX as usize { - panic!("Cannot connect this peripheral to GPIO"); - } - self.set_alternate_function(af, private::Internal); - let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize { - signal as OutputSignalType - } else { - OUTPUT_SIGNAL_MAX - }; - unsafe { &*GPIO::PTR } - .func_out_sel_cfg(GPIONUM as usize) - .modify(|_, w| unsafe { - w.out_sel() - .bits(clipped_signal) - .inv_sel() - .bit(invert) - .oen_sel() - .bit(enable_from_gpio) - .oen_inv_sel() - .bit(invert_enable) - }); + fn is_set_high(&self, _: private::Internal) -> bool { + ::Bank::read_output() & (1 << (GPIONUM % 32)) != 0 } - fn disconnect_peripheral_from_output(&mut self, _: private::Internal) { - self.set_alternate_function(GPIO_FUNCTION, private::Internal); - unsafe { &*GPIO::PTR } - .func_out_sel_cfg(GPIONUM as usize) - .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + ::output_signals() } - fn is_set_high(&self, _: private::Internal) -> bool { - ::Bank::read_output() & (1 << (GPIONUM % 32)) != 0 + fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { + self.degrade_internal(private::Internal) + .connect_peripheral_to_output(signal, private::Internal); + } + + fn disconnect_from_peripheral_output(&mut self, signal: OutputSignal, _: private::Internal) { + self.degrade_internal(private::Internal) + .disconnect_from_peripheral_output(signal, private::Internal); + } +} + +impl OutputPin for GpioPin where Self: GpioProperties {} + +impl GpioPin +where + Self: GpioProperties, +{ + fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { + let gpio = unsafe { &*GPIO::PTR }; + + #[cfg(esp32)] + crate::soc::gpio::errata36(GPIONUM, Some(false), Some(false)); + + self.write_out_en(true); + + gpio.pin(GPIONUM as usize) + .modify(|_, w| w.pad_driver().bit(open_drain)); + + gpio.func_out_sel_cfg(GPIONUM as usize) + .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); + + #[cfg(any(esp32c3, esp32s3))] + disable_usb_pads(GPIONUM); + + get_io_mux_reg(GPIONUM).modify(|_, w| unsafe { + w.mcu_sel() + .bits(alternate as u8) + .fun_ie() + .bit(open_drain) + .fun_wpd() + .clear_bit() + .fun_wpu() + .clear_bit() + .fun_drv() + .bits(DriveStrength::I20mA as u8) + .slp_sel() + .clear_bit() + }); } } @@ -2270,7 +2143,57 @@ pub(crate) mod internal { Pin::set_alternate_function(target, alternate, private::Internal) }) } + } + + impl PeripheralInputPin for ErasedPin { + fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { + handle_gpio_input!(&self.0, target, { + PeripheralInputPin::init_input(target, pull_down, pull_up, private::Internal) + }); + } + + fn enable_input(&mut self, on: bool, _: private::Internal) { + handle_gpio_input!(&mut self.0, target, { + PeripheralInputPin::enable_input(target, on, private::Internal) + }); + } + + fn enable_input_in_sleep_mode(&mut self, on: bool, _: private::Internal) { + handle_gpio_input!(&mut self.0, target, { + PeripheralInputPin::enable_input_in_sleep_mode(target, on, private::Internal) + }); + } + + fn is_input_high(&self, _: private::Internal) -> bool { + handle_gpio_input!(&self.0, target, { + PeripheralInputPin::is_input_high(target, private::Internal) + }) + } + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_input!(&self.0, target, { + PeripheralInputPin::input_signals(target, private::Internal) + }) + } + + fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { + handle_gpio_input!(&mut self.0, target, { + PeripheralInputPin::connect_input_to_peripheral(target, signal, private::Internal) + }) + } + + fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { + handle_gpio_input!(&mut self.0, target, { + PeripheralInputPin::disconnect_input_from_peripheral( + target, + signal, + private::Internal, + ) + }) + } + } + + impl InputPin for ErasedPin { fn listen_with_options( &mut self, event: Event, @@ -2280,7 +2203,7 @@ pub(crate) mod internal { _: private::Internal, ) { handle_gpio_input!(&mut self.0, target, { - Pin::listen_with_options( + InputPin::listen_with_options( target, event, int_enable, @@ -2293,187 +2216,131 @@ pub(crate) mod internal { fn unlisten(&mut self, _: private::Internal) { handle_gpio_input!(&mut self.0, target, { - Pin::unlisten(target, private::Internal) + InputPin::unlisten(target, private::Internal) }) } fn is_interrupt_set(&self, _: private::Internal) -> bool { handle_gpio_input!(&self.0, target, { - Pin::is_interrupt_set(target, private::Internal) + InputPin::is_interrupt_set(target, private::Internal) }) } fn clear_interrupt(&mut self, _: private::Internal) { handle_gpio_input!(&mut self.0, target, { - Pin::clear_interrupt(target, private::Internal) + InputPin::clear_interrupt(target, private::Internal) }) } - fn input_signals(&self, _: private::Internal) -> [Option; 6] { - handle_gpio_input!(&self.0, target, { - Pin::input_signals(target, private::Internal) - }) - } - - fn output_signals(&self, _: private::Internal) -> [Option; 6] { - handle_gpio_output!(&self.0, target, { - Pin::output_signals(target, private::Internal) - }) - } - } - - impl InputPin for ErasedPin { - fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { - handle_gpio_input!(&self.0, target, { - InputPin::init_input(target, pull_down, pull_up, private::Internal) - }) - } - - fn enable_input(&mut self, on: bool, _: private::Internal) { + fn listen(&mut self, event: Event, _: private::Internal) { handle_gpio_input!(&mut self.0, target, { - InputPin::enable_input(target, on, private::Internal) - }); - } - - fn enable_input_in_sleep_mode(&mut self, on: bool, _: private::Internal) { - handle_gpio_input!(&mut self.0, target, { - InputPin::enable_input_in_sleep_mode(target, on, private::Internal) - }); - } - - fn is_input_high(&self, _: private::Internal) -> bool { - handle_gpio_input!(&self.0, target, { - InputPin::is_input_high(target, private::Internal) + InputPin::listen(target, event, private::Internal) }) } - - fn connect_input_to_peripheral_with_options( - &mut self, - signal: InputSignal, - invert: bool, - force_via_gpio_mux: bool, - _: private::Internal, - ) { - handle_gpio_input!(&mut self.0, target, { - InputPin::connect_input_to_peripheral_with_options( - target, - signal, - invert, - force_via_gpio_mux, - private::Internal, - ) - }); - } - - fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - handle_gpio_input!(&mut self.0, target, { - InputPin::disconnect_input_from_peripheral(target, signal, private::Internal) - }); - } } - impl OutputPin for ErasedPin { + impl PeripheralOutputPin for ErasedPin { fn set_to_open_drain_output(&mut self, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::set_to_open_drain_output(target, private::Internal) + PeripheralOutputPin::set_to_open_drain_output(target, private::Internal) }); } fn set_to_push_pull_output(&mut self, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::set_to_push_pull_output(target, private::Internal) + PeripheralOutputPin::set_to_push_pull_output(target, private::Internal) }); } fn enable_output(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::enable_output(target, on, private::Internal) + PeripheralOutputPin::enable_output(target, on, private::Internal) }); } fn set_output_high(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::set_output_high(target, on, private::Internal) + PeripheralOutputPin::set_output_high(target, on, private::Internal) }); } fn set_drive_strength(&mut self, strength: DriveStrength, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::set_drive_strength(target, strength, private::Internal) + PeripheralOutputPin::set_drive_strength(target, strength, private::Internal) }); } fn enable_open_drain(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::enable_open_drain(target, on, private::Internal) + PeripheralOutputPin::enable_open_drain(target, on, private::Internal) }); } fn enable_output_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::enable_output_in_sleep_mode(target, on, private::Internal) + PeripheralOutputPin::enable_output_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::internal_pull_up_in_sleep_mode(target, on, private::Internal) + PeripheralOutputPin::internal_pull_up_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::internal_pull_down_in_sleep_mode(target, on, private::Internal) + PeripheralOutputPin::internal_pull_down_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_up(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::internal_pull_up(target, on, private::Internal) + PeripheralOutputPin::internal_pull_up(target, on, private::Internal) }); } fn internal_pull_down(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - OutputPin::internal_pull_down(target, on, private::Internal) + PeripheralOutputPin::internal_pull_down(target, on, private::Internal) }); } - fn connect_peripheral_to_output_with_options( + fn is_set_high(&self, _: private::Internal) -> bool { + handle_gpio_output!(&self.0, target, { + PeripheralOutputPin::is_set_high(target, private::Internal) + }) + } + + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_output!(&self.0, target, { + PeripheralOutputPin::output_signals(target, private::Internal) + }) + } + + fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { + handle_gpio_output!(&mut self.0, target, { + PeripheralOutputPin::connect_peripheral_to_output(target, signal, private::Internal) + }) + } + + fn disconnect_from_peripheral_output( &mut self, signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, _: private::Internal, ) { handle_gpio_output!(&mut self.0, target, { - OutputPin::connect_peripheral_to_output_with_options( + PeripheralOutputPin::disconnect_from_peripheral_output( target, signal, - invert, - invert_enable, - enable_from_gpio, - force_via_gpio_mux, private::Internal, ) - }); - } - - fn disconnect_peripheral_from_output(&mut self, _: private::Internal) { - handle_gpio_output!(&mut self.0, target, { - OutputPin::disconnect_peripheral_from_output(target, private::Internal) - }); - } - - fn is_set_high(&self, _: private::Internal) -> bool { - handle_gpio_output!(&self.0, target, { - OutputPin::is_set_high(target, private::Internal) }) } } + impl OutputPin for ErasedPin {} + #[cfg(any(xtensa, esp32c2, esp32c3, esp32c6))] impl RtcPin for ErasedPin { #[cfg(xtensa)] diff --git a/esp-hal/src/i2c.rs b/esp-hal/src/i2c.rs index 69bc04ab73..743c8825c3 100644 --- a/esp-hal/src/i2c.rs +++ b/esp-hal/src/i2c.rs @@ -57,7 +57,7 @@ use fugit::HertzU32; use crate::{ clock::Clocks, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::i2c0::{RegisterBlock, COMD}, @@ -321,7 +321,10 @@ impl<'d, T, DM: crate::Mode> I2C<'d, T, DM> where T: Instance, { - fn new_internal( + fn new_internal< + SDA: PeripheralOutputPin + PeripheralInputPin, + SCL: PeripheralOutputPin + PeripheralInputPin, + >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, @@ -356,26 +359,28 @@ where scl.set_to_open_drain_output(crate::private::Internal); scl.enable_input(true, crate::private::Internal); scl.internal_pull_up(true, crate::private::Internal); - scl.connect_peripheral_to_output( - i2c.peripheral.scl_output_signal(), - crate::private::Internal, - ); + scl.connect_input_to_peripheral( i2c.peripheral.scl_input_signal(), crate::private::Internal, ); + scl.connect_peripheral_to_output( + i2c.peripheral.scl_output_signal(), + crate::private::Internal, + ); sda.set_to_open_drain_output(crate::private::Internal); sda.enable_input(true, crate::private::Internal); sda.internal_pull_up(true, crate::private::Internal); - sda.connect_peripheral_to_output( - i2c.peripheral.sda_output_signal(), - crate::private::Internal, - ); + sda.connect_input_to_peripheral( i2c.peripheral.sda_input_signal(), crate::private::Internal, ); + sda.connect_peripheral_to_output( + i2c.peripheral.sda_output_signal(), + crate::private::Internal, + ); i2c.peripheral.setup(frequency, timeout); i2c @@ -396,7 +401,10 @@ where /// Create a new I2C instance /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new( + pub fn new< + SDA: PeripheralOutputPin + PeripheralInputPin, + SCL: PeripheralOutputPin + PeripheralInputPin, + >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, @@ -408,7 +416,10 @@ where /// Create a new I2C instance with a custom timeout value. /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new_with_timeout( + pub fn new_with_timeout< + SDA: PeripheralOutputPin + PeripheralInputPin, + SCL: PeripheralOutputPin + PeripheralInputPin, + >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, @@ -437,7 +448,10 @@ where /// Create a new I2C instance /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new_async( + pub fn new_async< + SDA: PeripheralOutputPin + PeripheralInputPin, + SCL: PeripheralOutputPin + PeripheralInputPin, + >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, @@ -449,7 +463,10 @@ where /// Create a new I2C instance with a custom timeout value. /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new_with_timeout_async( + pub fn new_with_timeout_async< + SDA: PeripheralOutputPin + PeripheralInputPin, + SCL: PeripheralOutputPin + PeripheralInputPin, + >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 3767a1431d..1c8066cb18 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -107,7 +107,7 @@ use crate::{ TxPrivate, WriteBuffer, }, - gpio::OutputPin, + gpio::PeripheralOutputPin, interrupt::InterruptHandler, into_ref, peripheral::Peripheral, @@ -495,10 +495,11 @@ where } /// Configures the I2S peripheral to use a master clock (MCLK) output pin. - pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { + pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal); + self } } @@ -890,7 +891,7 @@ mod private { use crate::peripherals::{i2s1::RegisterBlock, I2S1}; use crate::{ dma::{ChannelRx, ChannelTx, DmaChannel, DmaDescriptor, DmaPeripheral}, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, into_ref, peripherals::I2S0, @@ -923,31 +924,34 @@ mod private { pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: OutputPin, + P: PeripheralOutputPin, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal); + pin.connect_peripheral_to_output(T::bclk_signal(), crate::private::Internal); + self } pub fn with_ws

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: OutputPin, + P: PeripheralOutputPin, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::ws_signal(), private::Internal); + pin.connect_peripheral_to_output(T::ws_signal(), crate::private::Internal); + self } pub fn with_dout

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: OutputPin, + P: PeripheralOutputPin, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::dout_signal(), private::Internal); + pin.connect_peripheral_to_output(T::dout_signal(), crate::private::Internal); + self } } @@ -976,31 +980,34 @@ mod private { pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: OutputPin, + P: PeripheralOutputPin, { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); pin.connect_peripheral_to_output(T::bclk_rx_signal(), crate::private::Internal); + self } pub fn with_ws

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: OutputPin, + P: PeripheralOutputPin, { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); pin.connect_peripheral_to_output(T::ws_rx_signal(), crate::private::Internal); + self } pub fn with_din

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: InputPin, + P: PeripheralInputPin, { into_ref!(pin); pin.init_input(false, false, crate::private::Internal); pin.connect_input_to_peripheral(T::din_signal(), crate::private::Internal); + self } } diff --git a/esp-hal/src/ledc/channel.rs b/esp-hal/src/ledc/channel.rs index a838fccc36..268015627e 100644 --- a/esp-hal/src/ledc/channel.rs +++ b/esp-hal/src/ledc/channel.rs @@ -11,7 +11,7 @@ use super::timer::{TimerIFace, TimerSpeed}; use crate::{ - gpio::{OutputPin, OutputSignal}, + gpio::{OutputSignal, PeripheralOutputPin}, peripheral::{Peripheral, PeripheralRef}, peripherals::ledc::RegisterBlock, }; @@ -95,7 +95,7 @@ pub mod config { } /// Channel interface -pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: OutputPin + 'a> +pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: PeripheralOutputPin + 'a> where Channel<'a, S, O>: ChannelHW, { @@ -118,7 +118,7 @@ where } /// Channel HW interface -pub trait ChannelHW { +pub trait ChannelHW { /// Configure Channel HW except for the duty which is set via /// [`Self::set_duty_hw`]. fn configure_hw(&mut self) -> Result<(), Error>; @@ -144,14 +144,14 @@ pub trait ChannelHW { } /// Channel struct -pub struct Channel<'a, S: TimerSpeed, O: OutputPin> { +pub struct Channel<'a, S: TimerSpeed, O: PeripheralOutputPin> { ledc: &'a RegisterBlock, timer: Option<&'a dyn TimerIFace>, number: Number, output_pin: PeripheralRef<'a, O>, } -impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> { +impl<'a, S: TimerSpeed, O: PeripheralOutputPin> Channel<'a, S, O> { /// Return a new channel pub fn new(number: Number, output_pin: impl Peripheral

+ 'a) -> Self { crate::into_ref!(output_pin); @@ -165,7 +165,7 @@ impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> { } } -impl<'a, S: TimerSpeed, O: OutputPin> ChannelIFace<'a, S, O> for Channel<'a, S, O> +impl<'a, S: TimerSpeed, O: PeripheralOutputPin> ChannelIFace<'a, S, O> for Channel<'a, S, O> where Channel<'a, S, O>: ChannelHW, { @@ -337,7 +337,7 @@ mod ehal1 { } } -impl<'a, O: OutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> { +impl<'a, O: PeripheralOutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> { #[cfg(esp32)] fn set_channel(&mut self, timer_number: u8) { if S::IS_HS { @@ -537,7 +537,7 @@ impl<'a, O: OutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> { impl<'a, O, S> ChannelHW for Channel<'a, S, O> where - O: OutputPin, + O: PeripheralOutputPin, S: crate::ledc::timer::TimerSpeed, { /// Configure Channel HW @@ -604,6 +604,7 @@ where #[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))] Number::Channel7 => OutputSignal::LEDC_LS_SIG7, }; + self.output_pin .connect_peripheral_to_output(signal, crate::private::Internal); } else { diff --git a/esp-hal/src/mcpwm/operator.rs b/esp-hal/src/mcpwm/operator.rs index 8f4a153631..c08b9e19ee 100644 --- a/esp-hal/src/mcpwm/operator.rs +++ b/esp-hal/src/mcpwm/operator.rs @@ -12,7 +12,7 @@ use core::marker::PhantomData; use crate::{ - gpio::OutputPin, + gpio::PeripheralOutputPin, mcpwm::{timer::Timer, PwmPeripheral}, peripheral::{Peripheral, PeripheralRef}, private, @@ -204,7 +204,7 @@ impl Operator { } /// Use the A output with the given pin and configuration - pub fn with_pin_a<'d, Pin: OutputPin>( + pub fn with_pin_a<'d, Pin: PeripheralOutputPin>( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -213,7 +213,7 @@ impl Operator { } /// Use the B output with the given pin and configuration - pub fn with_pin_b<'d, Pin: OutputPin>( + pub fn with_pin_b<'d, Pin: PeripheralOutputPin>( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -222,7 +222,7 @@ impl Operator { } /// Use both the A and the B output with the given pins and configurations - pub fn with_pins<'d, PinA: OutputPin, PinB: OutputPin>( + pub fn with_pins<'d, PinA: PeripheralOutputPin, PinB: PeripheralOutputPin>( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -239,7 +239,7 @@ impl Operator { /// /// This is useful for complementary or mirrored signals with or without /// configured deadtime - pub fn with_linked_pins<'d, PinA: OutputPin, PinB: OutputPin>( + pub fn with_linked_pins<'d, PinA: PeripheralOutputPin, PinB: PeripheralOutputPin>( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -288,7 +288,7 @@ pub struct PwmPin<'d, Pin, PWM, const OP: u8, const IS_A: bool> { phantom: PhantomData, } -impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, Pin, PWM, OP, IS_A> { fn new(pin: impl Peripheral

+ 'd, config: PwmPinConfig) -> Self { @@ -304,6 +304,7 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> pin.pin .connect_peripheral_to_output(output_signal, private::Internal); pin.pin.enable_output(true, private::Internal); + pin } @@ -414,8 +415,8 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> } } -impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal_02::PwmPin - for PwmPin<'d, Pin, PWM, OP, IS_A> +impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> + embedded_hal_02::PwmPin for PwmPin<'d, Pin, PWM, OP, IS_A> { type Duty = u16; @@ -448,14 +449,14 @@ impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> emb } /// Implement no error type for the PwmPin because the method are infallible -impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal::pwm::ErrorType for PwmPin<'d, Pin, PWM, OP, IS_A> { type Error = core::convert::Infallible; } /// Implement the trait SetDutyCycle for PwmPin -impl<'d, Pin: OutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal::pwm::SetDutyCycle for PwmPin<'d, Pin, PWM, OP, IS_A> { /// Get the max duty of the PwmPin @@ -522,8 +523,13 @@ pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> { pin_b: PwmPin<'d, PinB, PWM, OP, false>, } -impl<'d, PinA: OutputPin, PinB: OutputPin, PWM: PwmPeripheral, const OP: u8> - LinkedPins<'d, PinA, PinB, PWM, OP> +impl< + 'd, + PinA: PeripheralOutputPin, + PinB: PeripheralOutputPin, + PWM: PwmPeripheral, + const OP: u8, + > LinkedPins<'d, PinA, PinB, PWM, OP> { fn new( pin_a: impl Peripheral

+ 'd, diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 4105acb19b..1a6fe2943e 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -49,7 +49,7 @@ use crate::{ TxPrivate, WriteBuffer, }, - gpio::{InputPin, OutputPin}, + gpio::{PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::{self, Peripheral}, peripherals, @@ -279,13 +279,13 @@ pub fn no_clk_pin() -> &'static mut NoClkPin { /// Wraps a GPIO pin which will be used as the clock output signal pub struct ClkOutPin<'d, P> where - P: OutputPin, + P: PeripheralOutputPin, { pin: PeripheralRef<'d, P>, } impl<'d, P> ClkOutPin<'d, P> where - P: OutputPin, + P: PeripheralOutputPin, { /// Create a ClkOutPin pub fn new(pin: impl Peripheral

+ 'd) -> Self { @@ -295,7 +295,7 @@ where } impl<'d, P> TxClkPin for ClkOutPin<'d, P> where - P: OutputPin, + P: PeripheralOutputPin, { fn configure(&mut self) { self.pin.set_to_push_pull_output(crate::private::Internal); @@ -309,13 +309,13 @@ where /// Wraps a GPIO pin which will be used as the TX clock input signal pub struct ClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { pin: PeripheralRef<'d, P>, } impl<'d, P> ClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { /// Create a new ClkInPin pub fn new(pin: impl Peripheral

+ 'd) -> Self { @@ -325,7 +325,7 @@ where } impl<'d, P> TxClkPin for ClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { fn configure(&mut self) { let pcr = unsafe { &*crate::peripherals::PCR::PTR }; @@ -343,14 +343,14 @@ where /// Wraps a GPIO pin which will be used as the RX clock input signal pub struct RxClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { pin: PeripheralRef<'d, P>, sample_edge: SampleEdge, } impl<'d, P> RxClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { /// Create a new RxClkInPin pub fn new(pin: impl Peripheral

+ 'd, sample_edge: SampleEdge) -> Self { @@ -360,7 +360,7 @@ where } impl<'d, P> RxClkPin for RxClkInPin<'d, P> where - P: InputPin, + P: PeripheralInputPin, { fn configure(&mut self) { let pcr = unsafe { &*crate::peripherals::PCR::PTR }; @@ -381,7 +381,7 @@ where pub struct TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: OutputPin, + VP: PeripheralOutputPin, { tx_pins: P, valid_pin: PeripheralRef<'d, VP>, @@ -390,7 +390,7 @@ where impl<'d, P, VP> TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: OutputPin, + VP: PeripheralOutputPin, { /// Create a [TxPinConfigWithValidPin] pub fn new(tx_pins: P, valid_pin: impl Peripheral

+ 'd) -> Self { @@ -402,14 +402,14 @@ where impl<'d, P, VP> TxPins for TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: OutputPin, + VP: PeripheralOutputPin, { } impl<'d, P, VP> ConfigurePins for TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: OutputPin, + VP: PeripheralOutputPin, { fn configure(&mut self) -> Result<(), Error> { self.tx_pins.configure()?; @@ -472,7 +472,7 @@ macro_rules! tx_pins { impl<'d, $($pin),+> $name<'d, $($pin),+> where - $($pin: OutputPin),+ + $($pin: PeripheralOutputPin),+ { /// Create a new TX pin #[allow(clippy::too_many_arguments)] @@ -488,7 +488,7 @@ macro_rules! tx_pins { impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+> where - $($pin: OutputPin),+ + $($pin: PeripheralOutputPin),+ { fn configure(&mut self) -> Result<(), Error>{ $( @@ -590,7 +590,7 @@ impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> pub struct RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: InputPin, + VP: PeripheralInputPin, { rx_pins: P, valid_pin: PeripheralRef<'d, VP>, @@ -601,7 +601,7 @@ where impl<'d, P, VP> RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: InputPin, + VP: PeripheralInputPin, { /// Create a new [RxPinConfigWithValidPin] pub fn new( @@ -623,14 +623,14 @@ where impl<'d, P, VP> RxPins for RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: InputPin, + VP: PeripheralInputPin, { } impl<'d, P, VP> ConfigurePins for RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: InputPin, + VP: PeripheralInputPin, { fn configure(&mut self) -> Result<(), Error> { self.rx_pins.configure()?; @@ -719,7 +719,7 @@ macro_rules! rx_pins { impl<'d, $($pin),+> $name<'d, $($pin),+> where - $($pin: InputPin),+ + $($pin: PeripheralInputPin),+ { /// Create a new RX pin #[allow(clippy::too_many_arguments)] @@ -735,12 +735,12 @@ macro_rules! rx_pins { impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+> where - $($pin: InputPin),+ + $($pin: PeripheralInputPin),+ { fn configure(&mut self) -> Result<(), Error> { $( self.[< pin_ $pin:lower >].init_input(false, false, $crate::private::Internal); - self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, $crate::private::Internal); + self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, crate::private::Internal); )+ private::Instance::set_rx_bit_width( private::WidSel::[< Bits $width >]); diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 7ea901626c..e98390d328 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -85,7 +85,7 @@ use core::marker::PhantomData; use fugit::HertzU32; use crate::{ - gpio::{InputPin, OutputPin}, + gpio::{PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::Peripheral, rmt::private::CreateInstance, @@ -295,10 +295,77 @@ impl<'d> Rmt<'d, crate::Async> { } } +fn configure_rx_channel< + 'd, + P: PeripheralInputPin, + T: private::RxChannelInternal, + M: crate::Mode, +>( + pin: impl Peripheral

+ 'd, + config: RxChannelConfig, +) -> Result { + if config.filter_threshold > 0b111_1111 { + return Err(Error::InvalidArgument); + } + + cfg_if::cfg_if! { + if #[cfg(any(esp32, esp32s2))] { + let threshold = 0b111_1111_1111_1111; + } else { + let threshold = 0b11_1111_1111_1111; + } + } + + if config.idle_threshold > threshold { + return Err(Error::InvalidArgument); + } + + crate::into_ref!(pin); + pin.init_input(false, false, crate::private::Internal); + pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal); + + T::set_divider(config.clk_divider); + T::set_carrier( + config.carrier_modulation, + config.carrier_high, + config.carrier_low, + config.carrier_level, + ); + T::set_filter_threshold(config.filter_threshold); + T::set_idle_threshold(config.idle_threshold); + + Ok(T::new()) +} + +fn configure_tx_channel< + 'd, + P: PeripheralOutputPin, + T: private::TxChannelInternal, + M: crate::Mode, +>( + pin: impl Peripheral

+ 'd, + config: TxChannelConfig, +) -> Result { + crate::into_ref!(pin); + pin.set_to_push_pull_output(crate::private::Internal); + pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal); + + T::set_divider(config.clk_divider); + T::set_carrier( + config.carrier_modulation, + config.carrier_high, + config.carrier_low, + config.carrier_level, + ); + T::set_idle_output(config.idle_output, config.idle_output_level); + + Ok(T::new()) +} + /// Creates a TX channel pub trait TxChannelCreator<'d, T, P> where - P: OutputPin, + P: PeripheralOutputPin, T: TxChannel, { /// Configure the TX channel @@ -310,26 +377,14 @@ where where Self: Sized, { - crate::into_ref!(pin); - pin.set_to_push_pull_output(crate::private::Internal); - pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal); - T::set_divider(config.clk_divider); - T::set_carrier( - config.carrier_modulation, - config.carrier_high, - config.carrier_low, - config.carrier_level, - ); - T::set_idle_output(config.idle_output, config.idle_output_level); - - Ok(T::new()) + configure_tx_channel(pin, config) } } /// Creates a TX channel in async mode pub trait TxChannelCreatorAsync<'d, T, P> where - P: OutputPin, + P: PeripheralOutputPin, T: TxChannelAsync, { /// Configure the TX channel @@ -341,26 +396,14 @@ where where Self: Sized, { - crate::into_ref!(pin); - pin.set_to_push_pull_output(crate::private::Internal); - pin.connect_peripheral_to_output(T::output_signal(), crate::private::Internal); - T::set_divider(config.clk_divider); - T::set_carrier( - config.carrier_modulation, - config.carrier_high, - config.carrier_low, - config.carrier_level, - ); - T::set_idle_output(config.idle_output, config.idle_output_level); - - Ok(T::new()) + configure_tx_channel(pin, config) } } /// Creates a RX channel pub trait RxChannelCreator<'d, T, P> where - P: InputPin, + P: PeripheralInputPin, T: RxChannel, { /// Configure the RX channel @@ -372,41 +415,14 @@ where where Self: Sized, { - if config.filter_threshold > 0b111_1111 { - return Err(Error::InvalidArgument); - } - - #[cfg(any(esp32, esp32s2))] - if config.idle_threshold > 0b111_1111_1111_1111 { - return Err(Error::InvalidArgument); - } - - #[cfg(not(any(esp32, esp32s2)))] - if config.idle_threshold > 0b11_1111_1111_1111 { - return Err(Error::InvalidArgument); - } - - crate::into_ref!(pin); - pin.init_input(false, false, crate::private::Internal); - pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal); - T::set_divider(config.clk_divider); - T::set_carrier( - config.carrier_modulation, - config.carrier_high, - config.carrier_low, - config.carrier_level, - ); - T::set_filter_threshold(config.filter_threshold); - T::set_idle_threshold(config.idle_threshold); - - Ok(T::new()) + configure_rx_channel(pin, config) } } /// Creates a RX channel in async mode pub trait RxChannelCreatorAsync<'d, T, P> where - P: InputPin, + P: PeripheralInputPin, T: RxChannelAsync, { /// Configure the RX channel @@ -418,34 +434,7 @@ where where Self: Sized, { - if config.filter_threshold > 0b111_1111 { - return Err(Error::InvalidArgument); - } - - #[cfg(any(esp32, esp32s2))] - if config.idle_threshold > 0b111_1111_1111_1111 { - return Err(Error::InvalidArgument); - } - - #[cfg(not(any(esp32, esp32s2)))] - if config.idle_threshold > 0b11_1111_1111_1111 { - return Err(Error::InvalidArgument); - } - - crate::into_ref!(pin); - pin.init_input(false, false, crate::private::Internal); - pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal); - T::set_divider(config.clk_divider); - T::set_carrier( - config.carrier_modulation, - config.carrier_high, - config.carrier_low, - config.carrier_level, - ); - T::set_filter_threshold(config.filter_threshold); - T::set_idle_threshold(config.idle_threshold); - - Ok(T::new()) + configure_rx_channel(pin, config) } } @@ -586,7 +575,7 @@ macro_rules! impl_tx_channel_creator { impl<'d, P> $crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P> for ChannelCreator<$crate::Blocking, $channel> where - P: $crate::gpio::OutputPin, + P: $crate::gpio::PeripheralOutputPin, { } @@ -595,7 +584,7 @@ macro_rules! impl_tx_channel_creator { impl<'d, P> $crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P> for ChannelCreator<$crate::Async, $channel> where - P: $crate::gpio::OutputPin, + P: $crate::gpio::PeripheralOutputPin, { } @@ -608,7 +597,7 @@ macro_rules! impl_rx_channel_creator { impl<'d, P> $crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P> for ChannelCreator<$crate::Blocking, $channel> where - P: $crate::gpio::InputPin, + P: $crate::gpio::PeripheralInputPin, { } @@ -617,7 +606,7 @@ macro_rules! impl_rx_channel_creator { impl<'d, P> $crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P> for ChannelCreator<$crate::Async, $channel> where - P: $crate::gpio::InputPin, + P: $crate::gpio::PeripheralInputPin, { } diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 6943ddeccd..fa485229c4 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -82,7 +82,7 @@ use super::{ use crate::{ clock::Clocks, dma::{DmaPeripheral, DmaRxBuffer, DmaTxBuffer, Rx, Tx}, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::spi2::RegisterBlock, @@ -457,6 +457,35 @@ pub struct Spi<'d, T, M> { _mode: PhantomData, } +impl<'d, T, M> Spi<'d, T, M> +where + T: Instance, +{ + /// Assign the SCK (Serial Clock) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI + /// clock signal. + pub fn with_sck(self, sclk: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(sclk); + sclk.set_to_push_pull_output(private::Internal); + sclk.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); + + self + } + + /// Assign the CS (Chip Select) pin for the SPI instance. + /// + /// Sets the specified pin to push-pull output and connects it to the SPI CS + /// signal. + pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(cs); + cs.set_to_push_pull_output(private::Internal); + cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); + + self + } +} + impl<'d, T> Spi<'d, T, FullDuplexMode> where T: Instance, @@ -513,23 +542,14 @@ where Self::new_internal(spi, frequency, mode) } - /// Assign the SCK (Serial Clock) pin for the SPI instance. - /// - /// Sets the specified pin to push-pull output and connects it to the SPI - /// clock signal. - pub fn with_sck(self, sck: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(sck); - sck.set_to_push_pull_output(private::Internal); - sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); - - self - } - /// Assign the MOSI (Master Out Slave In) pin for the SPI instance. /// /// Sets the specified pin to push-pull output and connects it to the SPI /// MOSI signal. - pub fn with_mosi(self, mosi: impl Peripheral

+ 'd) -> Self { + pub fn with_mosi( + self, + mosi: impl Peripheral

+ 'd, + ) -> Self { crate::into_ref!(mosi); mosi.set_to_push_pull_output(private::Internal); mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); @@ -540,7 +560,7 @@ where /// Assign the MISO (Master In Slave Out) pin for the SPI instance. /// /// Sets the specified pin to input and connects it to the SPI MISO signal. - pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { + pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { crate::into_ref!(miso); miso.init_input(false, false, private::Internal); miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); @@ -548,18 +568,6 @@ where self } - /// Assign the CS (Chip Select) pin for the SPI instance. - /// - /// Sets the specified pin to push-pull output and connects it to the SPI CS - /// signal. - pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(cs); - cs.set_to_push_pull_output(private::Internal); - cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); - - self - } - /// Set the bit order for the SPI instance. /// /// The default is MSB first for both read and write. @@ -572,38 +580,43 @@ where /// /// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the /// given pin. - pub fn with_pins( + pub fn with_pins< + SCK: PeripheralOutputPin, + MOSI: PeripheralOutputPin, + MISO: PeripheralInputPin, + CS: PeripheralOutputPin, + >( self, sck: Option + 'd>, mosi: Option + 'd>, miso: Option + 'd>, cs: Option + 'd>, ) -> Self { - if let Some(sck) = sck { - crate::into_ref!(sck); - sck.set_to_push_pull_output(private::Internal); - sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); - } + let this = if let Some(sck) = sck { + self.with_sck(sck) + } else { + self + }; - if let Some(mosi) = mosi { - crate::into_ref!(mosi); - mosi.set_to_push_pull_output(private::Internal); - mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); - } + let this = if let Some(mosi) = mosi { + this.with_mosi(mosi) + } else { + this + }; - if let Some(miso) = miso { - crate::into_ref!(miso); - miso.init_input(false, false, private::Internal); - miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); - } + let this = if let Some(miso) = miso { + this.with_miso(miso) + } else { + this + }; - if let Some(cs) = cs { - crate::into_ref!(cs); - cs.set_to_push_pull_output(private::Internal); - cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); - } + let this = if let Some(cs) = cs { + this.with_cs(cs) + } else { + this + }; - self + this } pub(crate) fn new_internal( @@ -651,32 +664,21 @@ where Self::new_internal(spi, frequency, mode) } - /// Assign the SCK (Serial Clock) pin for the SPI instance. - /// - /// Sets the specified pin to push-pull output and connects it to the SPI - /// clock signal. - pub fn with_sck(self, sck: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(sck); - sck.set_to_push_pull_output(private::Internal); - sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); - - self - } - /// Assign the MOSI (Master Out Slave In) pin for the SPI instance in /// half-duplex mode. /// /// Enables both input and output functionality for the pin, and connects it /// to the MOSI signal and SIO0 input signal. - pub fn with_mosi( + pub fn with_mosi( self, mosi: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(mosi); - mosi.enable_output(true, private::Internal); - mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); mosi.enable_input(true, private::Internal); + mosi.enable_output(true, private::Internal); + mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal); + mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); self } @@ -686,15 +688,16 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the MISO signal and SIO1 input signal. - pub fn with_miso( + pub fn with_miso( self, miso: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(miso); - miso.enable_output(true, private::Internal); - miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal); miso.enable_input(true, private::Internal); + miso.enable_output(true, private::Internal); + miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); + miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal); self } @@ -703,15 +706,16 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the SIO2 output and input signals. - pub fn with_sio2( + pub fn with_sio2( self, sio2: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(sio2); - sio2.enable_output(true, private::Internal); - sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal); sio2.enable_input(true, private::Internal); + sio2.enable_output(true, private::Internal); + sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal); + sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal); self } @@ -720,27 +724,16 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the SIO3 output and input signals. - pub fn with_sio3( + pub fn with_sio3( self, sio3: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(sio3); - sio3.enable_output(true, private::Internal); - sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal); sio3.enable_input(true, private::Internal); - sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal); - - self - } + sio3.enable_output(true, private::Internal); - /// Assign the CS (Chip Select) pin for the SPI instance. - /// - /// Sets the specified pin to push-pull output and connects it to the SPI CS - /// signal. - pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(cs); - cs.set_to_push_pull_output(private::Internal); - cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); + sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal); + sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal); self } @@ -750,12 +743,12 @@ where /// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the /// given pin. pub fn with_pins< - SCK: OutputPin, - MOSI: OutputPin + InputPin, - MISO: OutputPin + InputPin, - SIO2: OutputPin + InputPin, - SIO3: OutputPin + InputPin, - CS: OutputPin, + SCK: PeripheralOutputPin, + MOSI: PeripheralOutputPin + PeripheralInputPin, + MISO: PeripheralOutputPin + PeripheralInputPin, + SIO2: PeripheralOutputPin + PeripheralInputPin, + SIO3: PeripheralOutputPin + PeripheralInputPin, + CS: PeripheralOutputPin, >( self, sck: Option + 'd>, @@ -765,51 +758,43 @@ where sio3: Option + 'd>, cs: Option + 'd>, ) -> Self { - if let Some(sck) = sck { - crate::into_ref!(sck); - sck.set_to_push_pull_output(private::Internal); - sck.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); - } + let this = if let Some(sck) = sck { + self.with_sck(sck) + } else { + self + }; - if let Some(mosi) = mosi { - crate::into_ref!(mosi); - mosi.enable_output(true, private::Internal); - mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); - mosi.enable_input(true, private::Internal); - mosi.connect_input_to_peripheral(self.spi.sio0_input_signal(), private::Internal); - } + let this = if let Some(mosi) = mosi { + this.with_mosi(mosi) + } else { + this + }; - if let Some(miso) = miso { - crate::into_ref!(miso); - miso.enable_output(true, private::Internal); - miso.connect_peripheral_to_output(self.spi.sio1_output_signal(), private::Internal); - miso.enable_input(true, private::Internal); - miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); - } + let this = if let Some(miso) = miso { + this.with_miso(miso) + } else { + this + }; - if let Some(sio2) = sio2 { - crate::into_ref!(sio2); - sio2.enable_output(true, private::Internal); - sio2.connect_peripheral_to_output(self.spi.sio2_output_signal(), private::Internal); - sio2.enable_input(true, private::Internal); - sio2.connect_input_to_peripheral(self.spi.sio2_input_signal(), private::Internal); - } + let this = if let Some(sio2) = sio2 { + this.with_sio2(sio2) + } else { + this + }; - if let Some(sio3) = sio3 { - crate::into_ref!(sio3); - sio3.enable_output(true, private::Internal); - sio3.connect_peripheral_to_output(self.spi.sio3_output_signal(), private::Internal); - sio3.enable_input(true, private::Internal); - sio3.connect_input_to_peripheral(self.spi.sio3_input_signal(), private::Internal); - } + let this = if let Some(sio3) = sio3 { + this.with_sio3(sio3) + } else { + this + }; - if let Some(cs) = cs { - crate::into_ref!(cs); - cs.set_to_push_pull_output(private::Internal); - cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); - } + let this = if let Some(cs) = cs { + this.with_cs(cs) + } else { + this + }; - self + this } pub(crate) fn new_internal( diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 3a915d7f41..4ffbcda650 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -73,7 +73,7 @@ use core::marker::PhantomData; use super::{Error, FullDuplexMode, SpiMode}; use crate::{ dma::{DescriptorChain, DmaPeripheral, Rx, Tx}, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, peripheral::{Peripheral, PeripheralRef}, peripherals::spi2::RegisterBlock, private, @@ -106,17 +106,23 @@ where T: Instance, { /// Constructs an SPI instance in 8bit dataframe mode. - pub fn new( + pub fn new< + SCK: PeripheralInputPin, + MOSI: PeripheralInputPin, + MISO: PeripheralOutputPin, + CS: PeripheralInputPin, + >( spi: impl Peripheral

+ 'd, - sck: impl Peripheral

+ 'd, + sclk: impl Peripheral

+ 'd, mosi: impl Peripheral

+ 'd, miso: impl Peripheral

+ 'd, cs: impl Peripheral

+ 'd, mode: SpiMode, ) -> Spi<'d, T, FullDuplexMode> { - crate::into_ref!(spi, sck, mosi, miso, cs); - sck.init_input(false, false, private::Internal); - sck.connect_input_to_peripheral(spi.sclk_signal(), private::Internal); + crate::into_ref!(spi, sclk, mosi, miso, cs); + + sclk.init_input(false, false, private::Internal); + sclk.connect_input_to_peripheral(spi.sclk_signal(), private::Internal); mosi.init_input(false, false, private::Internal); mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal); @@ -148,7 +154,7 @@ where } } -/// DMA (Direct Memory Access) funtionality (Slave). +/// DMA (Direct Memory Access) functionality (Slave). pub mod dma { use super::*; #[cfg(spi3)] diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index c8e3d943c3..da9f45a95e 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -133,7 +133,7 @@ use core::marker::PhantomData; use self::filter::{Filter, FilterType}; use crate::{ - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::twai0::RegisterBlock, @@ -716,7 +716,7 @@ where T: Instance, DM: crate::Mode, { - fn new_internal( + fn new_internal( _peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -736,13 +736,15 @@ where .mode() .write(|w| w.reset_mode().set_bit()); + rx_pin.init_input(false, false, crate::private::Internal); + rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal); + if no_transceiver { tx_pin.set_to_open_drain_output(crate::private::Internal); + } else { + tx_pin.set_to_push_pull_output(crate::private::Internal); } - tx_pin.set_to_push_pull_output(crate::private::Internal); tx_pin.connect_peripheral_to_output(T::OUTPUT_SIGNAL, crate::private::Internal); - rx_pin.init_input(false, false, crate::private::Internal); - rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal); // Set the operating mode based on provided option match mode { @@ -903,7 +905,7 @@ where /// Create a new instance of [TwaiConfiguration] /// /// You will need to use a transceiver to connect to the TWAI bus - pub fn new( + pub fn new( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -918,7 +920,7 @@ where /// /// You don't need a transceiver by following the description in the /// `twai.rs` example - pub fn new_no_transceiver( + pub fn new_no_transceiver( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -947,7 +949,7 @@ where /// Create a new instance of [TwaiConfiguration] in async mode /// /// You will need to use a transceiver to connect to the TWAI bus - pub fn new_async( + pub fn new_async( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -964,7 +966,7 @@ where /// /// You don't need a transceiver by following the description in the /// `twai.rs` example - pub fn new_async_no_transceiver( + pub fn new_async_no_transceiver( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index b17858627d..8db09b1df9 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -131,7 +131,7 @@ use core::marker::PhantomData; use self::config::Config; use crate::{ clock::Clocks, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{uart0::RegisterBlock, Interrupt}, @@ -536,7 +536,7 @@ where } /// Configure RTS pin - pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { + pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rts); rts.set_to_push_pull_output(Internal); rts.connect_peripheral_to_output(T::rts_signal(), Internal); @@ -581,7 +581,7 @@ where T: Instance + 'd, { /// Create a new UART TX instance in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { @@ -590,7 +590,7 @@ where /// Create a new UART TX instance with configuration options in /// [`Blocking`] mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, @@ -620,7 +620,7 @@ where } /// Configure CTS pin - pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { + pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); cts.init_input(false, false, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); @@ -794,7 +794,7 @@ where T: Instance + 'd, { /// Create a new UART RX instance in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, ) -> Result { @@ -803,7 +803,7 @@ where /// Create a new UART RX instance with configuration options in /// [`Blocking`] mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -820,7 +820,7 @@ where { /// Create a new UART instance with configuration options in [`Blocking`] /// mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -835,7 +835,7 @@ where } /// Create a new UART instance with defaults in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, @@ -857,7 +857,7 @@ where } /// Configure CTS pin - pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { + pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); cts.init_input(false, false, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); @@ -866,7 +866,7 @@ where } /// Configure RTS pin - pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { + pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rts); rts.set_to_push_pull_output(Internal); rts.connect_peripheral_to_output(T::rts_signal(), Internal); @@ -2058,7 +2058,7 @@ mod asynch { { /// Create a new UART instance with configuration options in [`Async`] /// mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -2086,7 +2086,7 @@ mod asynch { } /// Create a new UART instance with defaults in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, @@ -2121,7 +2121,7 @@ mod asynch { T: Instance + 'd, { /// Create a new UART TX instance in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { @@ -2130,7 +2130,7 @@ mod asynch { /// Create a new UART TX instance with configuration options in /// [`Async`] mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, @@ -2202,7 +2202,7 @@ mod asynch { T: Instance + 'd, { /// Create a new UART RX instance in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, ) -> Result { @@ -2211,7 +2211,7 @@ mod asynch { /// Create a new UART RX instance with configuration options in /// [`Async`] mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, From 6bcf58e7f46cfc33c5ee3aaf1d2353ad875ba199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 20:22:31 +0200 Subject: [PATCH 03/21] Update tests and examples --- esp-hal/src/gpio/interconnect.rs | 36 +++++++++- esp-hal/src/pcnt/channel.rs | 74 +++++---------------- examples/src/bin/pcnt_encoder.rs | 20 +++--- examples/src/bin/spi_loopback.rs | 14 ++-- hil-test/tests/gpio.rs | 14 ++-- hil-test/tests/pcnt.rs | 22 +++--- hil-test/tests/qspi_write.rs | 36 ++++------ hil-test/tests/spi_full_duplex_dma_async.rs | 21 +++--- hil-test/tests/spi_full_duplex_dma_pcnt.rs | 20 ++---- hil-test/tests/spi_half_duplex_write.rs | 22 +++--- 10 files changed, 120 insertions(+), 159 deletions(-) diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index 2a9120d14e..fb5e285c58 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -18,6 +18,7 @@ use crate::{ INPUT_SIGNAL_MAX, OUTPUT_SIGNAL_MAX, }, + peripheral::Peripheral, peripherals::GPIO, private::{self, Sealed}, }; @@ -37,6 +38,14 @@ impl Clone for InputSignal { } } +impl Peripheral for InputSignal { + type P = Self; + + unsafe fn clone_unchecked(&mut self) -> Self::P { + self.clone() + } +} + impl Sealed for InputSignal {} impl InputSignal { @@ -138,8 +147,19 @@ impl PeripheralInputPin for InputSignal { /// Multiple pins can be connected to one output signal. pub struct OutputSignal { - is_inverted: bool, pin: ErasedPin, + is_inverted: bool, +} + +impl Peripheral for OutputSignal { + type P = Self; + + unsafe fn clone_unchecked(&mut self) -> Self::P { + Self { + pin: self.pin.clone_unchecked(), + is_inverted: self.is_inverted, + } + } } impl Sealed for OutputSignal {} @@ -283,6 +303,14 @@ enum AnyInputSignalInner { #[derive(Clone)] pub struct AnyInputSignal(AnyInputSignalInner); +impl Peripheral for AnyInputSignal { + type P = Self; + + unsafe fn clone_unchecked(&mut self) -> Self::P { + self.clone() + } +} + impl From for AnyInputSignal { fn from(input: InputSignal) -> Self { Self(AnyInputSignalInner::Input(input)) @@ -301,6 +329,12 @@ impl From for AnyInputSignal { } } +impl From for AnyInputSignal { + fn from(input: ErasedPin) -> Self { + Self(AnyInputSignalInner::Input(input.peripheral_input())) + } +} + impl From> for AnyInputSignal where GpioPin: InputPin, diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index d0a2782486..b265d54242 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -9,11 +9,7 @@ use core::marker::PhantomData; -use crate::{ - gpio::{InputPin, InputSignal, Pull, ONE_INPUT, ZERO_INPUT}, - peripheral::Peripheral, - peripherals::GPIO, -}; +use crate::gpio::{interconnect::AnyInputSignal, InputSignal, PeripheralInputPin, Pull}; /// Configuration for an PCNT input pin #[derive(Clone, Copy, Debug)] @@ -32,55 +28,23 @@ impl Default for PcntInputConfig { pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode}; /// PcntPin can be always high, always low, or an actual pin -#[derive(Clone, Copy)] +#[derive(Clone)] pub struct PcntSource { - source: u8, - inverted: bool, + source: AnyInputSignal, } impl PcntSource { /// Creates a `PcntSource` from an input pin with the specified /// configuration. - pub fn from_pin<'a, P: InputPin>( - pin: impl Peripheral

+ 'a, - pin_config: PcntInputConfig, - ) -> Self { - crate::into_ref!(pin); - - pin.init_input( + pub fn from(source: impl Into, pin_config: PcntInputConfig) -> Self { + let source = source.into(); + source.init_input( pin_config.pull == Pull::Down, pin_config.pull == Pull::Up, crate::private::Internal, ); - Self { - source: pin.number(crate::private::Internal), - inverted: false, - } - } - - /// Creates a `PcntSource` that is always high. - pub fn always_high() -> Self { - Self { - source: ONE_INPUT, - inverted: false, - } - } - - /// Creates a `PcntSource` that is always low. - pub fn always_low() -> Self { - Self { - source: ZERO_INPUT, - inverted: false, - } - } - - /// Inverts the `PcntSource` signal. - pub fn invert(self) -> Self { - Self { - source: self.source, - inverted: !self.inverted, - } + Self { source } } } @@ -135,7 +99,7 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> { } /// Set the control signal (pin/high/low) for this channel - pub fn set_ctrl_signal(&self, source: PcntSource) -> &Self { + pub fn set_ctrl_signal(&self, mut source: PcntSource) -> &Self { let signal = match UNIT { 0 => match NUM { 0 => InputSignal::PCNT0_CTRL_CH0, @@ -185,19 +149,15 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> { }; if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize { - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize) - .modify(|_, w| unsafe { - w.sel().set_bit(); - w.in_inv_sel().bit(source.inverted); - w.in_sel().bits(source.source) - }); + source + .source + .connect_input_to_peripheral(signal, crate::private::Internal); } self } /// Set the edge signal (pin/high/low) for this channel - pub fn set_edge_signal(&self, source: PcntSource) -> &Self { + pub fn set_edge_signal(&self, mut source: PcntSource) -> &Self { let signal = match UNIT { 0 => match NUM { 0 => InputSignal::PCNT0_SIG_CH0, @@ -247,13 +207,9 @@ impl<'d, const UNIT: usize, const NUM: usize> Channel<'d, UNIT, NUM> { }; if (signal as usize) <= crate::gpio::INPUT_SIGNAL_MAX as usize { - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize) - .modify(|_, w| unsafe { - w.sel().set_bit(); - w.in_inv_sel().bit(source.inverted); - w.in_sel().bits(source.source) - }); + source + .source + .connect_input_to_peripheral(signal, crate::private::Internal); } self } diff --git a/examples/src/bin/pcnt_encoder.rs b/examples/src/bin/pcnt_encoder.rs index f02c0ddbdd..07f10b5a26 100644 --- a/examples/src/bin/pcnt_encoder.rs +++ b/examples/src/bin/pcnt_encoder.rs @@ -53,15 +53,15 @@ fn main() -> ! { println!("setup channel 0"); let ch0 = &u0.channel0; - let mut pin_a = io.pins.gpio4; - let mut pin_b = io.pins.gpio5; + let pin_a = io.pins.gpio4; + let pin_b = io.pins.gpio5; - ch0.set_ctrl_signal(PcntSource::from_pin( - &mut pin_a, + ch0.set_ctrl_signal(PcntSource::from( + pin_a.peripheral_input(), PcntInputConfig { pull: Pull::Up }, )); - ch0.set_edge_signal(PcntSource::from_pin( - &mut pin_b, + ch0.set_edge_signal(PcntSource::from( + pin_b.peripheral_input(), PcntInputConfig { pull: Pull::Up }, )); ch0.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep); @@ -69,12 +69,12 @@ fn main() -> ! { println!("setup channel 1"); let ch1 = &u0.channel1; - ch1.set_ctrl_signal(PcntSource::from_pin( - &mut pin_b, + ch1.set_ctrl_signal(PcntSource::from( + pin_b.peripheral_input(), PcntInputConfig { pull: Pull::Up }, )); - ch1.set_edge_signal(PcntSource::from_pin( - &mut pin_a, + ch1.set_edge_signal(PcntSource::from( + pin_a.peripheral_input(), PcntInputConfig { pull: Pull::Up }, )); ch1.set_ctrl_mode(channel::CtrlMode::Reverse, channel::CtrlMode::Keep); diff --git a/examples/src/bin/spi_loopback.rs b/examples/src/bin/spi_loopback.rs index fca0d8b2f9..c24dd894e2 100644 --- a/examples/src/bin/spi_loopback.rs +++ b/examples/src/bin/spi_loopback.rs @@ -2,16 +2,13 @@ //! //! The following wiring is assumed: //! - SCLK => GPIO0 -//! - MISO => GPIO2 -//! - MOSI => GPIO4 +//! - MISO/MOSI => GPIO2 //! - CS => GPIO5 //! //! Depending on your target and the board you are using you have to change the //! pins. //! //! This example transfers data via SPI. -//! Connect MISO and MOSI pins to see the outgoing data is read as incoming -//! data. //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 @@ -21,7 +18,7 @@ use esp_backtrace as _; use esp_hal::{ delay::Delay, - gpio::{AnyPin, Io}, + gpio::Io, prelude::*, spi::{master::Spi, SpiMode}, }; @@ -33,12 +30,11 @@ fn main() -> ! { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; - let miso = io.pins.gpio2; - let mosi = io.pins.gpio4; + let miso_mosi = io.pins.gpio2; let cs = io.pins.gpio5; - let miso = AnyPin::new(miso); - let mosi = AnyPin::new(mosi); + let miso = miso_mosi.peripheral_input(); + let mosi = miso_mosi.into_peripheral_output(); let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0).with_pins( Some(sclk), diff --git a/hil-test/tests/gpio.rs b/hil-test/tests/gpio.rs index 9db23d2c71..f07682b2bd 100644 --- a/hil-test/tests/gpio.rs +++ b/hil-test/tests/gpio.rs @@ -11,7 +11,7 @@ use core::cell::RefCell; use critical_section::Mutex; use esp_hal::{ delay::Delay, - gpio::{AnyPin, ErasedPin, Input, Io, Level, Output, Pin, Pull}, + gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull}, macros::handler, timer::timg::TimerGroup, InterruptConfigurable, @@ -263,12 +263,12 @@ mod tests { assert_eq!(test_gpio2.is_set_low(), true); } - // Tests touch pin (GPIO2) as AnyPin and Output + // Tests touch pin (GPIO2) as ErasedPin and Output // https://github.com/esp-rs/esp-hal/issues/1943 #[test] fn test_gpio_touch_anypin_output(ctx: Context) { - let any_pin2 = AnyPin::new(ctx.test_gpio1); - let any_pin3 = AnyPin::new(ctx.test_gpio2); + let any_pin2 = ctx.test_gpio1; + let any_pin3 = ctx.test_gpio2; let out_pin = Output::new(any_pin2, Level::High); let in_pin = Input::new(any_pin3, Pull::Down); @@ -277,12 +277,12 @@ mod tests { assert_eq!(in_pin.is_high(), true); } - // Tests touch pin (GPIO2) as AnyPin and Input + // Tests touch pin (GPIO2) as ErasedPin and Input // https://github.com/esp-rs/esp-hal/issues/1943 #[test] fn test_gpio_touch_anypin_input(ctx: Context) { - let any_pin2 = AnyPin::new(ctx.test_gpio1); - let any_pin3 = AnyPin::new(ctx.test_gpio2); + let any_pin2 = ctx.test_gpio1; + let any_pin3 = ctx.test_gpio2; let out_pin = Output::new(any_pin3, Level::Low); let in_pin = Input::new(any_pin2, Pull::Down); diff --git a/hil-test/tests/pcnt.rs b/hil-test/tests/pcnt.rs index 638c12817d..8836573605 100644 --- a/hil-test/tests/pcnt.rs +++ b/hil-test/tests/pcnt.rs @@ -7,7 +7,7 @@ use esp_hal::{ delay::Delay, - gpio::{AnyPin, Io, Level, Output, Pull}, + gpio::{ErasedPin, Io, Level, Output, Pin, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, Pcnt, @@ -17,8 +17,8 @@ use hil_test as _; struct Context<'d> { pcnt: Pcnt<'d>, - input: AnyPin<'d>, - output: AnyPin<'d>, + input: ErasedPin, + output: ErasedPin, delay: Delay, } @@ -35,8 +35,8 @@ mod tests { let (din, dout) = hil_test::common_test_pins!(io); - let din = AnyPin::new(din); - let dout = AnyPin::new(dout); + let din = din.degrade(); + let dout = dout.degrade(); Context { pcnt: Pcnt::new(peripherals.PCNT), @@ -51,7 +51,7 @@ mod tests { let unit = ctx.pcnt.unit0; // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal(PcntSource::from_pin( + unit.channel0.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Down }, )); @@ -90,7 +90,7 @@ mod tests { let unit = ctx.pcnt.unit1; // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal(PcntSource::from_pin( + unit.channel0.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Up }, )); @@ -131,7 +131,7 @@ mod tests { unit.set_high_limit(Some(3)).unwrap(); // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal(PcntSource::from_pin( + unit.channel0.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Up }, )); @@ -194,7 +194,7 @@ mod tests { unit.clear(); // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal(PcntSource::from_pin( + unit.channel0.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Up }, )); @@ -261,7 +261,7 @@ mod tests { unit.clear(); // Setup channel 0 to decrement the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal(PcntSource::from_pin( + unit.channel0.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Up }, )); @@ -319,7 +319,7 @@ mod tests { let unit = ctx.pcnt.unit2; // Setup channel 1 to increment the count when gpio2 does LOW -> HIGH - unit.channel1.set_edge_signal(PcntSource::from_pin( + unit.channel1.set_edge_signal(PcntSource::from( ctx.input, PcntInputConfig { pull: Pull::Up }, )); diff --git a/hil-test/tests/qspi_write.rs b/hil-test/tests/qspi_write.rs index 2b035a3456..02f8913efc 100644 --- a/hil-test/tests/qspi_write.rs +++ b/hil-test/tests/qspi_write.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaTxBuf}, dma_buffers, - gpio::{AnyPin, Io, Pull}, + gpio::{ErasedPin, Io, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -38,10 +38,10 @@ cfg_if::cfg_if! { struct Context { spi: esp_hal::peripherals::SPI2, + pcnt_source: PcntSource, pcnt: esp_hal::peripherals::PCNT, dma_channel: Channel<'static, DmaChannel0, Blocking>, - mosi: AnyPin<'static>, - mosi_mirror: AnyPin<'static>, + mosi: ErasedPin, } fn execute( @@ -103,10 +103,9 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); - let (mosi, mosi_mirror) = hil_test::common_test_pins!(io); + let (mosi, _) = hil_test::common_test_pins!(io); - let mosi = AnyPin::new(mosi); - let mosi_mirror = AnyPin::new(mosi_mirror); + let mosi = mosi.degrade(); let dma = Dma::new(peripherals.DMA); @@ -122,10 +121,13 @@ mod tests { Context { spi: peripherals.SPI2, + pcnt_source: PcntSource::from( + mosi.peripheral_input(), + PcntInputConfig { pull: Pull::None }, + ), pcnt: peripherals.PCNT, dma_channel, mosi, - mosi_mirror, } } @@ -146,10 +148,7 @@ mod tests { let pcnt = Pcnt::new(ctx.pcnt); let unit = pcnt.unit0; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::None }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -173,10 +172,7 @@ mod tests { let pcnt = Pcnt::new(ctx.pcnt); let unit = pcnt.unit0; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::None }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -200,10 +196,7 @@ mod tests { let pcnt = Pcnt::new(ctx.pcnt); let unit = pcnt.unit0; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::None }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -227,10 +220,7 @@ mod tests { let pcnt = Pcnt::new(ctx.pcnt); let unit = pcnt.unit0; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::None }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); diff --git a/hil-test/tests/spi_full_duplex_dma_async.rs b/hil-test/tests/spi_full_duplex_dma_async.rs index 1758751891..f8edb71a20 100644 --- a/hil-test/tests/spi_full_duplex_dma_async.rs +++ b/hil-test/tests/spi_full_duplex_dma_async.rs @@ -42,9 +42,9 @@ const DMA_BUFFER_SIZE: usize = 5; struct Context { spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>, + pcnt_source: PcntSource, pcnt_unit: Unit<'static, 0>, out_pin: Output<'static>, - mosi_mirror: ErasedPin, } #[cfg(test)] @@ -62,9 +62,8 @@ mod tests { let pcnt = Pcnt::new(peripherals.PCNT); let sclk = io.pins.gpio0; - let (mosi_mirror, mosi) = hil_test::common_test_pins!(io); + let (_, mosi) = hil_test::common_test_pins!(io); let miso = io.pins.gpio4; - let mosi_mirror = mosi_mirror.degrade(); let mut out_pin = Output::new(io.pins.gpio5, Level::Low); out_pin.set_low(); @@ -84,6 +83,7 @@ mod tests { let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); + let mosi_loopback = mosi.peripheral_input(); let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) @@ -93,19 +93,19 @@ mod tests { Context { spi, + pcnt_source: PcntSource::from( + mosi_loopback, + PcntInputConfig { pull: Pull::Down }, + ), pcnt_unit: pcnt.unit0, out_pin, - mosi_mirror, } } #[test] #[timeout(3)] async fn test_async_dma_read_dma_write_pcnt(mut ctx: Context) { - ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source); ctx.pcnt_unit .channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -130,10 +130,7 @@ mod tests { #[test] #[timeout(3)] async fn test_async_dma_read_dma_transfer_pcnt(mut ctx: Context) { - ctx.pcnt_unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source); ctx.pcnt_unit .channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); diff --git a/hil-test/tests/spi_full_duplex_dma_pcnt.rs b/hil-test/tests/spi_full_duplex_dma_pcnt.rs index 403f3a75cd..d8106b52f7 100644 --- a/hil-test/tests/spi_full_duplex_dma_pcnt.rs +++ b/hil-test/tests/spi_full_duplex_dma_pcnt.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{ErasedPin, Io, Level, Output, Pull}, + gpio::{Io, Level, Output, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -38,9 +38,9 @@ cfg_if::cfg_if! { struct Context { spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>, + pcnt_source: PcntSource, pcnt_unit: Unit<'static, 0>, out_pin: Output<'static>, - mosi_mirror: ErasedPin, } #[cfg(test)] @@ -56,7 +56,7 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; - let (mosi_mirror, mosi) = hil_test::common_test_pins!(io); + let (_, mosi) = hil_test::common_test_pins!(io); let miso = io.pins.gpio4; let dma = Dma::new(peripherals.DMA); @@ -69,6 +69,7 @@ mod tests { } } + let mosi_loopback = mosi.peripheral_input(); let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) @@ -80,13 +81,12 @@ mod tests { let mut out_pin = Output::new(io.pins.gpio5, Level::Low); out_pin.set_low(); assert_eq!(out_pin.is_set_low(), true); - let mosi_mirror = mosi_mirror.degrade(); Context { spi, + pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }), pcnt_unit: pcnt.unit0, out_pin, - mosi_mirror, } } @@ -101,10 +101,7 @@ mod tests { let unit = ctx.pcnt_unit; let mut spi = ctx.spi; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -136,10 +133,7 @@ mod tests { let unit = ctx.pcnt_unit; let mut spi = ctx.spi; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs index af77205261..787ce803af 100644 --- a/hil-test/tests/spi_half_duplex_write.rs +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{AnyPin, Io, Pull}, + gpio::{Io, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -40,7 +40,7 @@ cfg_if::cfg_if! { struct Context { spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>, pcnt_unit: Unit<'static, 0>, - mosi_mirror: AnyPin<'static>, + pcnt_source: PcntSource, } #[cfg(test)] @@ -59,9 +59,7 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; - let (mosi, mosi_mirror) = hil_test::common_test_pins!(io); - - let mosi_mirror = AnyPin::new(mosi_mirror); + let (mosi, _) = hil_test::common_test_pins!(io); let pcnt = Pcnt::new(peripherals.PCNT); let dma = Dma::new(peripherals.DMA); @@ -74,6 +72,8 @@ mod tests { } } + let mosi_loopback = mosi.peripheral_input(); + let spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) @@ -81,7 +81,7 @@ mod tests { Context { spi, - mosi_mirror, + pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }), pcnt_unit: pcnt.unit0, } } @@ -97,10 +97,7 @@ mod tests { let unit = ctx.pcnt_unit; let mut spi = ctx.spi; - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); @@ -148,10 +145,7 @@ mod tests { let unit = ctx.pcnt_unit; let mut spi = ctx.spi.with_buffers(dma_rx_buf, dma_tx_buf); - unit.channel0.set_edge_signal(PcntSource::from_pin( - ctx.mosi_mirror, - PcntInputConfig { pull: Pull::Down }, - )); + unit.channel0.set_edge_signal(ctx.pcnt_source); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); From c3e0199fe3a76675f6635f6eddadb281a67f8509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 21:06:12 +0200 Subject: [PATCH 04/21] Fix enable_from_gpio value --- esp-hal/src/gpio/interconnect.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index fb5e285c58..a3c4561b30 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -250,7 +250,7 @@ impl PeripheralOutputPin for OutputSignal { clipped_signal, self.is_inverted, false, - true, + false, self.pin.number(private::Internal), ); } From 2f65b6745419cbdd8bd11b60f2df6236afe4a3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 21:19:26 +0200 Subject: [PATCH 05/21] Access signals from pin drivers --- esp-hal/src/gpio/mod.rs | 74 +++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 14 deletions(-) diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 37664a3a7a..fed2736a3d 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -403,23 +403,10 @@ pub trait InputPin: Pin + PeripheralInputPin { fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) { self.listen_with_options(event.into(), false, false, enable, private::Internal); } - - /// Turns the pin object into a peripheral input. - fn peripheral_input(&self) -> interconnect::InputSignal { - interconnect::InputSignal::new(self.degrade_internal(private::Internal)) - } } /// Trait implemented by pins which can be used as outputs. -pub trait OutputPin: Pin + PeripheralOutputPin { - /// Turns the pin object into a peripheral output. - fn into_peripheral_output(self) -> interconnect::OutputSignal - where - Self: Sized, - { - interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) - } -} +pub trait OutputPin: Pin + PeripheralOutputPin {} /// Trait implemented by pins which can be used as analog pins pub trait AnalogPin: Pin { @@ -681,6 +668,12 @@ where ::Bank::write_out_en_clear(1 << (GPIONUM % 32)); } } + + /// Turns the pin object into a peripheral input. + #[inline] + pub fn peripheral_input(&self) -> interconnect::InputSignal { + interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + } } /// Workaround to make D+ and D- work on the ESP32-C3 and ESP32-S3, which by @@ -969,6 +962,12 @@ where .clear_bit() }); } + + /// Turns the pin object into a peripheral output. + #[inline] + pub fn into_peripheral_output(self) -> interconnect::OutputSignal { + interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + } } /// General Purpose Input/Output driver @@ -1720,9 +1719,16 @@ where } /// Configure the [DriveStrength] of the pin + #[inline] pub fn set_drive_strength(&mut self, strength: DriveStrength) { self.pin.set_drive_strength(strength); } + + /// Turns the pin object into a peripheral output. + #[inline] + pub fn into_peripheral_output(self) -> interconnect::OutputSignal { + self.pin.into_peripheral_output() + } } /// GPIO input driver. @@ -1794,6 +1800,7 @@ where } /// Stop listening for interrupts + #[inline] pub fn unlisten(&mut self) { self.pin.unlisten(); } @@ -1817,6 +1824,12 @@ where pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) { self.pin.wakeup_enable(enable, event); } + + /// Turns the pin object into a peripheral input. + #[inline] + pub fn peripheral_input(&self) -> interconnect::InputSignal { + self.pin.peripheral_input() + } } /// GPIO open-drain output driver. @@ -1946,6 +1959,12 @@ where pub fn set_drive_strength(&mut self, strength: DriveStrength) { self.pin.set_drive_strength(strength); } + + /// Turns the pin object into a peripheral output. + #[inline] + pub fn into_peripheral_output(self) -> interconnect::OutputSignal { + self.pin.into_peripheral_output() + } } /// Flexible pin driver. @@ -2044,6 +2063,12 @@ where pub fn wakeup_enable(&mut self, enable: bool, event: WakeEvent) { self.pin.wakeup_enable(enable, event, private::Internal); } + + /// Turns the pin object into a peripheral input. + #[inline] + pub fn peripheral_input(&self) -> interconnect::InputSignal { + interconnect::InputSignal::new(self.pin.degrade_internal(private::Internal)) + } } impl<'d, P> Flex<'d, P> @@ -2099,9 +2124,16 @@ where } /// Configure the [DriveStrength] of the pin + #[inline] pub fn set_drive_strength(&mut self, strength: DriveStrength) { self.pin.set_drive_strength(strength, private::Internal); } + + /// Turns the pin object into a peripheral output. + #[inline] + pub fn into_peripheral_output(self) -> interconnect::OutputSignal { + interconnect::OutputSignal::new(self.pin.degrade_internal(private::Internal)) + } } impl<'d, P> Flex<'d, P> @@ -2123,6 +2155,20 @@ pub(crate) mod internal { impl private::Sealed for ErasedPin {} + impl ErasedPin { + /// Turns the pin object into a peripheral output. + #[inline] + pub fn peripheral_input(self) -> interconnect::InputSignal { + handle_gpio_input!(&self.0, target, { target.peripheral_input() }) + } + + /// Turns the pin object into a peripheral output. + #[inline] + pub fn into_peripheral_output(self) -> interconnect::OutputSignal { + handle_gpio_output!(self.0, target, { target.into_peripheral_output() }) + } + } + impl Pin for ErasedPin { fn number(&self, _: private::Internal) -> u8 { handle_gpio_input!(&self.0, target, { Pin::number(target, private::Internal) }) From 82059a4b613621254033df09fe1bfa4274aa8bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 21:33:56 +0200 Subject: [PATCH 06/21] DummyPin is not a pin --- esp-hal/src/gpio/dummy_pin.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index c0791b02f9..dc5f14c797 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -1,4 +1,5 @@ -//! "Dummy" pins". +//! Placeholder pins. +//! //! These are useful to pass them into peripheral drivers where you don't want //! an actual pin but one is required. @@ -27,20 +28,6 @@ impl crate::peripheral::Peripheral for DummyPin { impl private::Sealed for DummyPin {} -impl Pin for DummyPin { - fn number(&self, _: private::Internal) -> u8 { - panic!("DummyPin not supported here!"); - } - - fn degrade_internal(&self, _: private::Internal) -> ErasedPin { - panic!("Can not type erase the DummyPin!"); - } - - fn sleep_mode(&mut self, _on: bool, _: private::Internal) {} - - fn set_alternate_function(&mut self, _alternate: AlternateFunction, _: private::Internal) {} -} - impl PeripheralInputPin for DummyPin { fn input_signals(&self, _: private::Internal) -> [Option; 6] { [None; 6] @@ -122,8 +109,6 @@ impl PeripheralOutputPin for DummyPin { fn disconnect_from_peripheral_output(&mut self, _signal: OutputSignal, _: private::Internal) {} } -impl OutputPin for DummyPin {} - impl embedded_hal_02::digital::v2::OutputPin for DummyPin { type Error = core::convert::Infallible; From c6ce7ecbc13ec4fd0904b248551224416a16320c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 21:36:10 +0200 Subject: [PATCH 07/21] Remove redundant public fns --- esp-hal/src/gpio/dummy_pin.rs | 17 ++++++++++++----- esp-hal/src/gpio/mod.rs | 28 ---------------------------- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index dc5f14c797..caf0e8c111 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -44,11 +44,18 @@ impl PeripheralInputPin for DummyPin { } fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - if self.value { - connect_high_to_peripheral(signal); - } else { - connect_low_to_peripheral(signal); - } + let value = if self.value { ONE_INPUT } else { ZERO_INPUT }; + + unsafe { &*GPIO::PTR } + .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) + .modify(|_, w| unsafe { + w.sel() + .set_bit() + .in_inv_sel() + .bit(false) + .in_sel() + .bits(value) + }); } fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index fed2736a3d..a6559c9583 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -602,34 +602,6 @@ impl BankGpioRegisterAccess for Bank1GpioRegisterAccess { } } -/// Connect an always-low signal to the peripheral input signal -pub fn connect_low_to_peripheral(signal: InputSignal) { - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) - .modify(|_, w| unsafe { - w.sel() - .set_bit() - .in_inv_sel() - .bit(false) - .in_sel() - .bits(ZERO_INPUT) - }); -} - -/// Connect an always-high signal to the peripheral input signal -pub fn connect_high_to_peripheral(signal: InputSignal) { - unsafe { &*GPIO::PTR } - .func_in_sel_cfg(signal as usize - FUNC_IN_SEL_OFFSET) - .modify(|_, w| unsafe { - w.sel() - .set_bit() - .in_inv_sel() - .bit(false) - .in_sel() - .bits(ONE_INPUT) - }); -} - #[doc(hidden)] pub trait BooleanType {} From 38dfa3d1605adcda2675c4a21aa1e0cb5aa26d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 22:10:16 +0200 Subject: [PATCH 08/21] Various fixes, rename ErasedPin --- esp-hal/src/gpio/interconnect.rs | 29 +++++--- esp-hal/src/gpio/lp_io.rs | 2 +- esp-hal/src/gpio/mod.rs | 70 +++++++++---------- esp-hal/src/otg_fs.rs | 11 +-- esp-hal/src/peripheral.rs | 8 +-- esp-hal/src/uart.rs | 8 +-- examples/src/bin/blinky_erased_pins.rs | 4 +- examples/src/bin/embassy_multicore.rs | 4 +- .../src/bin/embassy_multicore_interrupt.rs | 4 +- hil-test/tests/gpio.rs | 10 +-- hil-test/tests/pcnt.rs | 6 +- hil-test/tests/qspi_read.rs | 4 +- hil-test/tests/qspi_write.rs | 4 +- hil-test/tests/qspi_write_read.rs | 4 +- hil-test/tests/spi_full_duplex_dma_async.rs | 2 +- 15 files changed, 93 insertions(+), 77 deletions(-) diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index a3c4561b30..1e712ec757 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -4,9 +4,10 @@ use crate::{ gpio::{ self, AlternateFunction, + AnyPin, DummyPin, - ErasedPin, GpioPin, + GpioProperties, InputPin, Level, OutputSignalType, @@ -25,7 +26,7 @@ use crate::{ /// Multiple input signal can be connected to one pin. pub struct InputSignal { - pin: ErasedPin, + pin: AnyPin, is_inverted: bool, } @@ -49,7 +50,7 @@ impl Peripheral for InputSignal { impl Sealed for InputSignal {} impl InputSignal { - pub(crate) fn new(pin: ErasedPin) -> Self { + pub(crate) fn new(pin: AnyPin) -> Self { Self { pin, is_inverted: false, @@ -61,6 +62,12 @@ impl InputSignal { self.is_inverted = !self.is_inverted; } + /// Inverts the peripheral's input signal. + pub fn inverted(mut self) -> Self { + self.invert(); + self + } + fn connect(&self, signal: usize, invert: bool, input: u8) { unsafe { &*GPIO::PTR } .func_in_sel_cfg(signal - FUNC_IN_SEL_OFFSET) @@ -147,7 +154,7 @@ impl PeripheralInputPin for InputSignal { /// Multiple pins can be connected to one output signal. pub struct OutputSignal { - pin: ErasedPin, + pin: AnyPin, is_inverted: bool, } @@ -165,7 +172,7 @@ impl Peripheral for OutputSignal { impl Sealed for OutputSignal {} impl OutputSignal { - pub(crate) fn new(pin: ErasedPin) -> Self { + pub(crate) fn new(pin: AnyPin) -> Self { Self { is_inverted: false, pin, @@ -177,6 +184,12 @@ impl OutputSignal { self.is_inverted = !self.is_inverted; } + /// Inverts the peripheral's input signal. + pub fn inverted(mut self) -> Self { + self.invert(); + self + } + fn connect( &self, signal: OutputSignalType, @@ -329,15 +342,15 @@ impl From for AnyInputSignal { } } -impl From for AnyInputSignal { - fn from(input: ErasedPin) -> Self { +impl From for AnyInputSignal { + fn from(input: AnyPin) -> Self { Self(AnyInputSignalInner::Input(input.peripheral_input())) } } impl From> for AnyInputSignal where - GpioPin: InputPin, + GpioPin: InputPin + GpioProperties, { fn from(pin: GpioPin) -> Self { Self(AnyInputSignalInner::Input(pin.peripheral_input())) diff --git a/esp-hal/src/gpio/lp_io.rs b/esp-hal/src/gpio/lp_io.rs index bf59e9164c..8f1fd6e715 100644 --- a/esp-hal/src/gpio/lp_io.rs +++ b/esp-hal/src/gpio/lp_io.rs @@ -264,7 +264,7 @@ macro_rules! lp_gpio { ($this:expr, $inner:ident, $code:tt) => { match $this { $( - ErasedPinInner::[]($inner) => { + AnyPinInner::[]($inner) => { $code }, )+ diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index a6559c9583..8c6780738e 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -272,12 +272,12 @@ pub trait Pin: Sealed { /// GPIO number fn number(&self, _: private::Internal) -> u8; - /// Type-erase (degrade) this pin into an ErasedPin. + /// Type-erase (degrade) this pin into an AnyPin. /// /// This converts pin singletons (`GpioPin<0>`, …), which are all different /// types, into the same type. It is useful for creating arrays of pins, /// or avoiding generics. - fn degrade(self) -> ErasedPin + fn degrade(self) -> AnyPin where Self: Sized, { @@ -285,7 +285,7 @@ pub trait Pin: Sealed { } #[doc(hidden)] - fn degrade_internal(&self, _: private::Internal) -> ErasedPin; + fn degrade_internal(&self, _: private::Internal) -> AnyPin; /// Enable/disable sleep-mode fn sleep_mode(&mut self, on: bool, _: private::Internal); @@ -699,7 +699,7 @@ where GPIONUM } - fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + fn degrade_internal(&self, _: private::Internal) -> AnyPin { self.degrade_pin(private::Internal) } @@ -1027,7 +1027,7 @@ pub trait GpioProperties { type IsAnalog: BooleanType; type IsTouch: BooleanType; - fn degrade_pin(&self, _: private::Internal) -> ErasedPin; + fn degrade_pin(&self, _: private::Internal) -> AnyPin; fn output_signals() -> [Option; 6]; fn input_signals() -> [Option; 6]; } @@ -1104,8 +1104,8 @@ macro_rules! gpio { type InterruptStatus = $crate::gpio::[< InterruptStatusRegisterAccessBank $bank >]; $crate::pin_types!($type); - fn degrade_pin(&self, _: $crate::private::Internal) -> ErasedPin { - ErasedPin($crate::gpio::ErasedPinInner::[< Gpio $gpionum >](unsafe { Self::steal() })) + fn degrade_pin(&self, _: $crate::private::Internal) -> AnyPin { + AnyPin($crate::gpio::AnyPinInner::[< Gpio $gpionum >](unsafe { Self::steal() })) } fn output_signals() -> [Option; 6]{ @@ -1143,29 +1143,29 @@ macro_rules! gpio { )+ } - pub(crate) enum ErasedPinInner { + pub(crate) enum AnyPinInner { $( [](GpioPin<$gpionum>), )+ } /// Type-erased GPIO pin - pub struct ErasedPin(pub(crate) ErasedPinInner); + pub struct AnyPin(pub(crate) AnyPinInner); - impl ErasedPin { + impl AnyPin { pub(crate) unsafe fn clone_unchecked(&self) -> Self { match self.0 { - $(ErasedPinInner::[](_) => { - Self(ErasedPinInner::[< Gpio $gpionum >](unsafe { GpioPin::steal() })) + $(AnyPinInner::[](_) => { + Self(AnyPinInner::[< Gpio $gpionum >](unsafe { GpioPin::steal() })) })+ } } } - impl $crate::peripheral::Peripheral for ErasedPin { - type P = ErasedPin; + impl $crate::peripheral::Peripheral for AnyPin { + type P = AnyPin; unsafe fn clone_unchecked(&mut self) -> Self { - ErasedPin::clone_unchecked(self) + AnyPin::clone_unchecked(self) } } @@ -1177,7 +1177,7 @@ macro_rules! gpio { ($this:expr, $inner:ident, $code:tt) => { match $this { $( - ErasedPinInner::[]($inner) => if_output_pin!($type, { + AnyPinInner::[]($inner) => if_output_pin!($type, { $code } else {{ let _ = $inner; @@ -1194,7 +1194,7 @@ macro_rules! gpio { ($this:expr, $inner:ident, $code:tt) => { match $this { $( - ErasedPinInner::[]($inner) => $code + AnyPinInner::[]($inner) => $code )+ } } @@ -1284,7 +1284,7 @@ macro_rules! rtc_pins { ($this:expr, $inner:ident, $code:tt) => { match $this { $( - paste::paste! { ErasedPinInner::[]($inner) } => { + paste::paste! { AnyPinInner::[]($inner) } => { $code }, )+ @@ -1302,7 +1302,7 @@ macro_rules! rtc_pins { match $this { $( $( - paste::paste! { ErasedPinInner::[]($inner) } => { + paste::paste! { AnyPinInner::[]($inner) } => { // FIXME: replace with $(ignore($rue)) once stable handle_rtcio_with_resistors!(@ignore $rue, $rde); $code @@ -1374,7 +1374,7 @@ macro_rules! rtc_pins { ($this:expr, $inner:ident, $code:tt) => { match $this { $( - paste::paste! { ErasedPinInner::[]($inner) } => { + paste::paste! { AnyPinInner::[]($inner) } => { $code }, )+ @@ -1604,7 +1604,7 @@ macro_rules! touch { } /// GPIO output driver. -pub struct Output<'d, P = ErasedPin> { +pub struct Output<'d, P = AnyPin> { pin: Flex<'d, P>, } @@ -1704,7 +1704,7 @@ where } /// GPIO input driver. -pub struct Input<'d, P = ErasedPin> { +pub struct Input<'d, P = AnyPin> { pin: Flex<'d, P>, } @@ -1805,7 +1805,7 @@ where } /// GPIO open-drain output driver. -pub struct OutputOpenDrain<'d, P = ErasedPin> { +pub struct OutputOpenDrain<'d, P = AnyPin> { pin: Flex<'d, P>, } @@ -1940,7 +1940,7 @@ where } /// Flexible pin driver. -pub struct Flex<'d, P = ErasedPin> { +pub struct Flex<'d, P = AnyPin> { pin: PeripheralRef<'d, P>, } @@ -2125,12 +2125,12 @@ where pub(crate) mod internal { use super::*; - impl private::Sealed for ErasedPin {} + impl private::Sealed for AnyPin {} - impl ErasedPin { + impl AnyPin { /// Turns the pin object into a peripheral output. #[inline] - pub fn peripheral_input(self) -> interconnect::InputSignal { + pub fn peripheral_input(&self) -> interconnect::InputSignal { handle_gpio_input!(&self.0, target, { target.peripheral_input() }) } @@ -2141,12 +2141,12 @@ pub(crate) mod internal { } } - impl Pin for ErasedPin { + impl Pin for AnyPin { fn number(&self, _: private::Internal) -> u8 { handle_gpio_input!(&self.0, target, { Pin::number(target, private::Internal) }) } - fn degrade_internal(&self, _: private::Internal) -> ErasedPin { + fn degrade_internal(&self, _: private::Internal) -> AnyPin { unsafe { self.clone_unchecked() } } @@ -2163,7 +2163,7 @@ pub(crate) mod internal { } } - impl PeripheralInputPin for ErasedPin { + impl PeripheralInputPin for AnyPin { fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { handle_gpio_input!(&self.0, target, { PeripheralInputPin::init_input(target, pull_down, pull_up, private::Internal) @@ -2211,7 +2211,7 @@ pub(crate) mod internal { } } - impl InputPin for ErasedPin { + impl InputPin for AnyPin { fn listen_with_options( &mut self, event: Event, @@ -2257,7 +2257,7 @@ pub(crate) mod internal { } } - impl PeripheralOutputPin for ErasedPin { + impl PeripheralOutputPin for AnyPin { fn set_to_open_drain_output(&mut self, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { PeripheralOutputPin::set_to_open_drain_output(target, private::Internal) @@ -2357,10 +2357,10 @@ pub(crate) mod internal { } } - impl OutputPin for ErasedPin {} + impl OutputPin for AnyPin {} #[cfg(any(xtensa, esp32c2, esp32c3, esp32c6))] - impl RtcPin for ErasedPin { + impl RtcPin for AnyPin { #[cfg(xtensa)] #[allow(unused_braces)] // False positive :/ fn rtc_number(&self) -> u8 { @@ -2389,7 +2389,7 @@ pub(crate) mod internal { } #[cfg(any(esp32c2, esp32c3, esp32c6, xtensa))] - impl RtcPinWithResistors for ErasedPin { + impl RtcPinWithResistors for AnyPin { fn rtcio_pullup(&mut self, enable: bool) { handle_rtcio_with_resistors!(&mut self.0, target, { RtcPinWithResistors::rtcio_pullup(target, enable) diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 22a4c9b0fe..84debd3162 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -43,6 +43,7 @@ use crate::{ gpio::InputSignal, peripheral::{Peripheral, PeripheralRef}, peripherals, + private::Internal, system::{Peripheral as PeripheralEnable, PeripheralClockControl}, }; @@ -101,10 +102,12 @@ impl<'d> Usb<'d> { .modify(|_, w| w.sw_hw_usb_phy_sel().set_bit().sw_usb_phy_sel().set_bit()); } - crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_IDDIG); // connected connector is mini-B side - crate::gpio::connect_high_to_peripheral(InputSignal::USB_SRP_BVALID); // HIGH to force USB device mode - crate::gpio::connect_high_to_peripheral(InputSignal::USB_OTG_VBUSVALID); // receiving a valid Vbus from device - crate::gpio::connect_low_to_peripheral(InputSignal::USB_OTG_AVALID); + use crate::gpio::{Level, PeripheralInputPin}; + + Level::High.connect_input_to_peripheral(InputSignal::USB_OTG_IDDIG, Internal); // connected connector is mini-B side + Level::High.connect_input_to_peripheral(InputSignal::USB_SRP_BVALID, Internal); // HIGH to force USB device mode + Level::High.connect_input_to_peripheral(InputSignal::USB_OTG_VBUSVALID, Internal); // receiving a valid Vbus from device + Level::Low.connect_input_to_peripheral(InputSignal::USB_OTG_AVALID, Internal); } } diff --git a/esp-hal/src/peripheral.rs b/esp-hal/src/peripheral.rs index 3f56ab9a3f..2f1a966c0c 100644 --- a/esp-hal/src/peripheral.rs +++ b/esp-hal/src/peripheral.rs @@ -35,10 +35,10 @@ use core::{ /// dedicated struct is memory efficiency: /// /// Peripheral singletons are typically either zero-sized (for concrete -/// peripherals like `PA9` or `Spi4`) 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. +/// peripherals like `PA9` or `Spi4`) 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. diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 8db09b1df9..90d912c69b 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -94,12 +94,12 @@ //! ```rust, no_run #![doc = crate::before_snippet!()] //! # use esp_hal::uart::Uart; -//! use esp_hal::gpio::{AnyPin, Io}; +//! use esp_hal::gpio::Io; //! //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! -//! let rx = AnyPin::new_inverted(io.pins.gpio2); -//! let tx = AnyPin::new_inverted(io.pins.gpio1); +//! let rx = io.pins.gpio2.peripheral_input().inverted(); +//! let tx = io.pins.gpio1.into_peripheral_output().inverted(); //! let mut uart1 = Uart::new( //! peripherals.UART1, //! rx, @@ -112,7 +112,7 @@ //! ```rust, no_run #![doc = crate::before_snippet!()] //! # use esp_hal::uart::{UartTx, UartRx}; -//! use esp_hal::gpio::{AnyPin, Io}; +//! use esp_hal::gpio::Io; //! //! let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); //! diff --git a/examples/src/bin/blinky_erased_pins.rs b/examples/src/bin/blinky_erased_pins.rs index 93d23e56f9..34cf9c0fc8 100644 --- a/examples/src/bin/blinky_erased_pins.rs +++ b/examples/src/bin/blinky_erased_pins.rs @@ -14,7 +14,7 @@ use esp_backtrace as _; use esp_hal::{ delay::Delay, - gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull}, + gpio::{AnyPin, Input, Io, Level, Output, Pin, Pull}, prelude::*, }; @@ -47,7 +47,7 @@ fn main() -> ! { } } -fn toggle_pins(leds: &mut [Output], button: &Input) { +fn toggle_pins(leds: &mut [Output], button: &Input) { for pin in leds.iter_mut() { pin.toggle(); } diff --git a/examples/src/bin/embassy_multicore.rs b/examples/src/bin/embassy_multicore.rs index 7d871f2b00..585decaf98 100644 --- a/examples/src/bin/embassy_multicore.rs +++ b/examples/src/bin/embassy_multicore.rs @@ -21,7 +21,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{ErasedPin, Io, Level, Output, Pin}, + gpio::{AnyPin, Io, Level, Output, Pin}, timer::{timg::TimerGroup, ErasedTimer}, }; use esp_hal_embassy::Executor; @@ -34,7 +34,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: Output<'static, ErasedPin>, + mut led: Output<'static, AnyPin>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize); diff --git a/examples/src/bin/embassy_multicore_interrupt.rs b/examples/src/bin/embassy_multicore_interrupt.rs index 0c69a468f3..ac1881a4b6 100644 --- a/examples/src/bin/embassy_multicore_interrupt.rs +++ b/examples/src/bin/embassy_multicore_interrupt.rs @@ -20,7 +20,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{ErasedPin, Io, Level, Output, Pin}, + gpio::{AnyPin, Io, Level, Output, Pin}, interrupt::{software::SoftwareInterruptControl, Priority}, prelude::*, timer::{timg::TimerGroup, ErasedTimer}, @@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: Output<'static, ErasedPin>, + mut led: Output<'static, AnyPin>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize); diff --git a/hil-test/tests/gpio.rs b/hil-test/tests/gpio.rs index f07682b2bd..6c23d33118 100644 --- a/hil-test/tests/gpio.rs +++ b/hil-test/tests/gpio.rs @@ -11,7 +11,7 @@ use core::cell::RefCell; use critical_section::Mutex; use esp_hal::{ delay::Delay, - gpio::{ErasedPin, Input, Io, Level, Output, Pin, Pull}, + gpio::{AnyPin, Input, Io, Level, Output, Pin, Pull}, macros::handler, timer::timg::TimerGroup, InterruptConfigurable, @@ -22,8 +22,8 @@ static COUNTER: Mutex> = Mutex::new(RefCell::new(0)); static INPUT_PIN: Mutex>> = Mutex::new(RefCell::new(None)); struct Context { - test_gpio1: ErasedPin, - test_gpio2: ErasedPin, + test_gpio1: AnyPin, + test_gpio2: AnyPin, delay: Delay, } @@ -263,7 +263,7 @@ mod tests { assert_eq!(test_gpio2.is_set_low(), true); } - // Tests touch pin (GPIO2) as ErasedPin and Output + // Tests touch pin (GPIO2) as AnyPin and Output // https://github.com/esp-rs/esp-hal/issues/1943 #[test] fn test_gpio_touch_anypin_output(ctx: Context) { @@ -277,7 +277,7 @@ mod tests { assert_eq!(in_pin.is_high(), true); } - // Tests touch pin (GPIO2) as ErasedPin and Input + // Tests touch pin (GPIO2) as AnyPin and Input // https://github.com/esp-rs/esp-hal/issues/1943 #[test] fn test_gpio_touch_anypin_input(ctx: Context) { diff --git a/hil-test/tests/pcnt.rs b/hil-test/tests/pcnt.rs index 8836573605..fbf35341fd 100644 --- a/hil-test/tests/pcnt.rs +++ b/hil-test/tests/pcnt.rs @@ -7,7 +7,7 @@ use esp_hal::{ delay::Delay, - gpio::{ErasedPin, Io, Level, Output, Pin, Pull}, + gpio::{AnyPin, Io, Level, Output, Pin, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, Pcnt, @@ -17,8 +17,8 @@ use hil_test as _; struct Context<'d> { pcnt: Pcnt<'d>, - input: ErasedPin, - output: ErasedPin, + input: AnyPin, + output: AnyPin, delay: Delay, } diff --git a/hil-test/tests/qspi_read.rs b/hil-test/tests/qspi_read.rs index 6328465fce..e910e2653a 100644 --- a/hil-test/tests/qspi_read.rs +++ b/hil-test/tests/qspi_read.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaRxBuf}, dma_buffers, - gpio::{ErasedPin, Io, Level, Output}, + gpio::{AnyPin, Io, Level, Output}, prelude::*, spi::{ master::{Address, Command, Spi, SpiDma}, @@ -34,7 +34,7 @@ cfg_if::cfg_if! { struct Context { spi: esp_hal::peripherals::SPI2, dma_channel: Channel<'static, DmaChannel0, Blocking>, - miso: ErasedPin, + miso: AnyPin, miso_mirror: Output<'static>, } diff --git a/hil-test/tests/qspi_write.rs b/hil-test/tests/qspi_write.rs index 02f8913efc..e362e773b3 100644 --- a/hil-test/tests/qspi_write.rs +++ b/hil-test/tests/qspi_write.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaTxBuf}, dma_buffers, - gpio::{ErasedPin, Io, Pull}, + gpio::{AnyPin, Io, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -41,7 +41,7 @@ struct Context { pcnt_source: PcntSource, pcnt: esp_hal::peripherals::PCNT, dma_channel: Channel<'static, DmaChannel0, Blocking>, - mosi: ErasedPin, + mosi: AnyPin, } fn execute( diff --git a/hil-test/tests/qspi_write_read.rs b/hil-test/tests/qspi_write_read.rs index 65bb660e58..5d4d19d765 100644 --- a/hil-test/tests/qspi_write_read.rs +++ b/hil-test/tests/qspi_write_read.rs @@ -10,7 +10,7 @@ use esp_hal::{ dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{ErasedPin, Io, Level, Output}, + gpio::{AnyPin, Io, Level, Output}, prelude::*, spi::{ master::{Address, Command, Spi, SpiDma}, @@ -36,7 +36,7 @@ cfg_if::cfg_if! { struct Context { spi: esp_hal::peripherals::SPI2, dma_channel: Channel<'static, DmaChannel0, Blocking>, - mosi: ErasedPin, + mosi: AnyPin, mosi_mirror: Output<'static>, } diff --git a/hil-test/tests/spi_full_duplex_dma_async.rs b/hil-test/tests/spi_full_duplex_dma_async.rs index f8edb71a20..bf1eee2d75 100644 --- a/hil-test/tests/spi_full_duplex_dma_async.rs +++ b/hil-test/tests/spi_full_duplex_dma_async.rs @@ -10,7 +10,7 @@ use embedded_hal_async::spi::SpiBus; use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{ErasedPin, Io, Level, Output, Pull}, + gpio::{Io, Level, Output, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, From 95fc9a39df2de5dea8aced3f9adebeafb7c8921f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 22:10:21 +0200 Subject: [PATCH 09/21] Changelog --- esp-hal/CHANGELOG.md | 2 ++ esp-wifi/CHANGELOG.md | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 23dd6c16a8..987ffddec3 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Previously unavailable memory is available via `.dram2_uninit` section (#2079) - You can now use `Input`, `Output`, `OutputOpenDrain` and `Flex` pins as EXTI and RTCIO wakeup sources (#2095) - Added `Rtc::set_current_time` to allow setting RTC time, and `Rtc::current_time` to getting RTC time while taking into account boot time (#1883) +- Added APIs to allow connecting signals through the GPIO matrix. (#2128) ### Changed @@ -37,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The (previously undocumented) `ErasedPin` enum has been replaced with the `ErasedPin` struct. (#2094) - Renamed and merged `Rtc::get_time_us` and `Rtc::get_time_ms` into `Rtc::time_since_boot` (#1883) - ESP32: Added support for touch sensing on GPIO32 and 33 (#2109) +- Renamed `ErasedPin` to `AnyPin` (#2128) ### Fixed diff --git a/esp-wifi/CHANGELOG.md b/esp-wifi/CHANGELOG.md index 0b3a39694d..9fe985aab4 100644 --- a/esp-wifi/CHANGELOG.md +++ b/esp-wifi/CHANGELOG.md @@ -12,13 +12,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `have-strchr` feature to disable including `strchr` (#2096) ### Changed + - esp-wifi now allocates memory from the global allocator provided by `esp-alloc` (#2099) ### Fixed + - Feature `wifi-logs` doesn't break the build anymore (#2117) ### Removed +- Removed the `clocks` parameter from `esp_wifi::initialize` (#1999) + ## 0.9.1 - 2024-09-03 ### Added @@ -43,8 +47,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed -- Removed the `clocks` parameter from `esp_wifi::initialize` (#1999) - ## 0.8.0 - 2024-08-29 ### Added From 321d3426e7e10d9b17bf6852f8998e7110372704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 22:14:05 +0200 Subject: [PATCH 10/21] rustfmt --- hil-test/tests/spi_full_duplex_dma_async.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hil-test/tests/spi_full_duplex_dma_async.rs b/hil-test/tests/spi_full_duplex_dma_async.rs index bf1eee2d75..29d5e630c8 100644 --- a/hil-test/tests/spi_full_duplex_dma_async.rs +++ b/hil-test/tests/spi_full_duplex_dma_async.rs @@ -93,10 +93,7 @@ mod tests { Context { spi, - pcnt_source: PcntSource::from( - mosi_loopback, - PcntInputConfig { pull: Pull::Down }, - ), + pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }), pcnt_unit: pcnt.unit0, out_pin, } From 816561f5181babdfa503e5c18387d6d6a7231c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 22:24:14 +0200 Subject: [PATCH 11/21] Update i8080 --- esp-hal/src/lcd_cam/lcd/i8080.rs | 102 +++++++++++++++---------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index 8539bd7a3e..a4d6b2a91b 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -76,7 +76,7 @@ use crate::{ ReadBuffer, TxPrivate, }, - gpio::{OutputPin, OutputSignal}, + gpio::{OutputSignal, PeripheralOutputPin}, lcd_cam::{ asynch::LcdDoneFuture, lcd::{i8080::private::TxPins, ClockMode, DelayMode, Phase, Polarity}, @@ -309,7 +309,7 @@ where } /// Associates a CS pin with the I8080 interface. - pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { + pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(crate::private::Internal); cs.connect_peripheral_to_output(OutputSignal::LCD_CS, crate::private::Internal); @@ -318,7 +318,7 @@ where } /// Configures the control pins for the I8080 interface. - pub fn with_ctrl_pins( + pub fn with_ctrl_pins( self, dc: impl Peripheral

+ 'd, wrx: impl Peripheral

+ 'd, @@ -593,14 +593,14 @@ pub struct TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> { impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> where - P0: OutputPin, - P1: OutputPin, - P2: OutputPin, - P3: OutputPin, - P4: OutputPin, - P5: OutputPin, - P6: OutputPin, - P7: OutputPin, + P0: PeripheralOutputPin, + P1: PeripheralOutputPin, + P2: PeripheralOutputPin, + P3: PeripheralOutputPin, + P4: PeripheralOutputPin, + P5: PeripheralOutputPin, + P6: PeripheralOutputPin, + P7: PeripheralOutputPin, { #[allow(clippy::too_many_arguments)] /// Creates a new `TxEightBits` instance with the provided output pins. @@ -638,14 +638,14 @@ where impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxPins for TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> where - P0: OutputPin, - P1: OutputPin, - P2: OutputPin, - P3: OutputPin, - P4: OutputPin, - P5: OutputPin, - P6: OutputPin, - P7: OutputPin, + P0: PeripheralOutputPin, + P1: PeripheralOutputPin, + P2: PeripheralOutputPin, + P3: PeripheralOutputPin, + P4: PeripheralOutputPin, + P5: PeripheralOutputPin, + P6: PeripheralOutputPin, + P7: PeripheralOutputPin, { type Word = u8; @@ -701,22 +701,22 @@ pub struct TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> where - P0: OutputPin, - P1: OutputPin, - P2: OutputPin, - P3: OutputPin, - P4: OutputPin, - P5: OutputPin, - P6: OutputPin, - P7: OutputPin, - P8: OutputPin, - P9: OutputPin, - P10: OutputPin, - P11: OutputPin, - P12: OutputPin, - P13: OutputPin, - P14: OutputPin, - P15: OutputPin, + P0: PeripheralOutputPin, + P1: PeripheralOutputPin, + P2: PeripheralOutputPin, + P3: PeripheralOutputPin, + P4: PeripheralOutputPin, + P5: PeripheralOutputPin, + P6: PeripheralOutputPin, + P7: PeripheralOutputPin, + P8: PeripheralOutputPin, + P9: PeripheralOutputPin, + P10: PeripheralOutputPin, + P11: PeripheralOutputPin, + P12: PeripheralOutputPin, + P13: PeripheralOutputPin, + P14: PeripheralOutputPin, + P15: PeripheralOutputPin, { #[allow(clippy::too_many_arguments)] /// Creates a new `TxSixteenBits` instance with the provided output pins. @@ -779,22 +779,22 @@ where impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> TxPins for TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> where - P0: OutputPin, - P1: OutputPin, - P2: OutputPin, - P3: OutputPin, - P4: OutputPin, - P5: OutputPin, - P6: OutputPin, - P7: OutputPin, - P8: OutputPin, - P9: OutputPin, - P10: OutputPin, - P11: OutputPin, - P12: OutputPin, - P13: OutputPin, - P14: OutputPin, - P15: OutputPin, + P0: PeripheralOutputPin, + P1: PeripheralOutputPin, + P2: PeripheralOutputPin, + P3: PeripheralOutputPin, + P4: PeripheralOutputPin, + P5: PeripheralOutputPin, + P6: PeripheralOutputPin, + P7: PeripheralOutputPin, + P8: PeripheralOutputPin, + P9: PeripheralOutputPin, + P10: PeripheralOutputPin, + P11: PeripheralOutputPin, + P12: PeripheralOutputPin, + P13: PeripheralOutputPin, + P14: PeripheralOutputPin, + P15: PeripheralOutputPin, { type Word = u16; fn configure(&mut self) { From fceaf0305a48938d1865bba6a0c574b6374d3027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 9 Sep 2024 23:06:40 +0200 Subject: [PATCH 12/21] Typos and endless recursion --- esp-hal/src/gpio/mod.rs | 28 ++++++------------- examples/src/bin/embassy_i2c.rs | 2 +- .../embassy_i2c_bmp180_calibration_data.rs | 2 +- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 8c6780738e..f1d65ed10b 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -2195,19 +2195,13 @@ pub(crate) mod internal { } fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - handle_gpio_input!(&mut self.0, target, { - PeripheralInputPin::connect_input_to_peripheral(target, signal, private::Internal) - }) + interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + .connect_input_to_peripheral(signal, private::Internal); } fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - handle_gpio_input!(&mut self.0, target, { - PeripheralInputPin::disconnect_input_from_peripheral( - target, - signal, - private::Internal, - ) - }) + interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + .disconnect_input_from_peripheral(signal, private::Internal); } } @@ -2337,9 +2331,8 @@ pub(crate) mod internal { } fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { - handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::connect_peripheral_to_output(target, signal, private::Internal) - }) + interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + .connect_peripheral_to_output(signal, private::Internal); } fn disconnect_from_peripheral_output( @@ -2347,13 +2340,8 @@ pub(crate) mod internal { signal: OutputSignal, _: private::Internal, ) { - handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::disconnect_from_peripheral_output( - target, - signal, - private::Internal, - ) - }) + interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + .disconnect_from_peripheral_output(signal, private::Internal); } } diff --git a/examples/src/bin/embassy_i2c.rs b/examples/src/bin/embassy_i2c.rs index f9352e1fda..604cac1c18 100644 --- a/examples/src/bin/embassy_i2c.rs +++ b/examples/src/bin/embassy_i2c.rs @@ -6,7 +6,7 @@ //! This is an example of running the embassy executor with IC2. It uses an //! LIS3DH to get accelerometer data. //! -//! Folowing pins are used: +//! Following pins are used: //! - SDA => GPIO4 //! - SCL => GPIO5 diff --git a/examples/src/bin/embassy_i2c_bmp180_calibration_data.rs b/examples/src/bin/embassy_i2c_bmp180_calibration_data.rs index f1e5299f17..d725f2a7db 100644 --- a/examples/src/bin/embassy_i2c_bmp180_calibration_data.rs +++ b/examples/src/bin/embassy_i2c_bmp180_calibration_data.rs @@ -3,7 +3,7 @@ //! This example dumps the calibration data from a BMP180 sensor by reading by reading //! with the direct I2C API and the embedded-hal-async I2C API. //! -//! Folowing pins are used: +//! Following pins are used: //! - SDA => GPIO4 //! - SCL => GPIO5 //! From f643e38ac348e5a5ec3d259e05bec2a0949551e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 10:11:10 +0200 Subject: [PATCH 13/21] Drop Pin suffix from traits --- esp-hal/src/gpio/dummy_pin.rs | 14 ++--- esp-hal/src/gpio/interconnect.rs | 10 +-- esp-hal/src/gpio/mod.rs | 52 ++++++++-------- esp-hal/src/i2c.rs | 23 +++---- esp-hal/src/i2s.rs | 18 +++--- esp-hal/src/lcd_cam/lcd/i8080.rs | 102 +++++++++++++++---------------- esp-hal/src/ledc/channel.rs | 16 ++--- esp-hal/src/mcpwm/operator.rs | 27 ++++---- esp-hal/src/otg_fs.rs | 2 +- esp-hal/src/parl_io.rs | 44 ++++++------- esp-hal/src/pcnt/channel.rs | 2 +- esp-hal/src/rmt.rs | 22 +++---- esp-hal/src/spi/master.rs | 41 ++++++------- esp-hal/src/spi/slave.rs | 10 +-- esp-hal/src/twai/mod.rs | 12 ++-- esp-hal/src/uart.rs | 38 ++++++------ 16 files changed, 211 insertions(+), 222 deletions(-) diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index caf0e8c111..59cd6de415 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -28,7 +28,7 @@ impl crate::peripheral::Peripheral for DummyPin { impl private::Sealed for DummyPin {} -impl PeripheralInputPin for DummyPin { +impl PeripheralInput for DummyPin { fn input_signals(&self, _: private::Internal) -> [Option; 6] { [None; 6] } @@ -61,7 +61,7 @@ impl PeripheralInputPin for DummyPin { fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} } -impl PeripheralInputPin for Level { +impl PeripheralInput for Level { delegate::delegate! { to match self { Level::High => DummyPin { value: true }, @@ -78,7 +78,7 @@ impl PeripheralInputPin for Level { } } -impl PeripheralOutputPin for DummyPin { +impl PeripheralOutput for DummyPin { fn set_to_open_drain_output(&mut self, _: private::Internal) {} fn set_to_push_pull_output(&mut self, _: private::Internal) {} @@ -130,10 +130,10 @@ impl embedded_hal_02::digital::v2::OutputPin for DummyPin { } impl embedded_hal_02::digital::v2::StatefulOutputPin for DummyPin { fn is_set_high(&self) -> Result { - Ok(PeripheralOutputPin::is_set_high(self, private::Internal)) + Ok(PeripheralOutput::is_set_high(self, private::Internal)) } fn is_set_low(&self) -> Result { - Ok(!PeripheralOutputPin::is_set_high(self, private::Internal)) + Ok(!PeripheralOutput::is_set_high(self, private::Internal)) } } @@ -155,10 +155,10 @@ impl embedded_hal::digital::OutputPin for DummyPin { impl embedded_hal::digital::StatefulOutputPin for DummyPin { fn is_set_high(&mut self) -> Result { - Ok(PeripheralOutputPin::is_set_high(self, private::Internal)) + Ok(PeripheralOutput::is_set_high(self, private::Internal)) } fn is_set_low(&mut self) -> Result { - Ok(!PeripheralOutputPin::is_set_high(self, private::Internal)) + Ok(!PeripheralOutput::is_set_high(self, private::Internal)) } } diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index 1e712ec757..3036a472a8 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -11,8 +11,8 @@ use crate::{ InputPin, Level, OutputSignalType, - PeripheralInputPin, - PeripheralOutputPin, + PeripheralInput, + PeripheralOutput, Pin, FUNC_IN_SEL_OFFSET, GPIO_FUNCTION, @@ -82,7 +82,7 @@ impl InputSignal { } } -impl PeripheralInputPin for InputSignal { +impl PeripheralInput for InputSignal { /// Connect the pin to a peripheral input signal. fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal, _: private::Internal) { let signal_nr = signal as usize; @@ -213,7 +213,7 @@ impl OutputSignal { } } -impl PeripheralOutputPin for OutputSignal { +impl PeripheralOutput for OutputSignal { /// Connect the pin to a peripheral output signal. // TODO: the following options should be part of the struct: /// invert: Configures whether or not to invert the output value @@ -358,7 +358,7 @@ where } impl Sealed for AnyInputSignal {} -impl PeripheralInputPin for AnyInputSignal { +impl PeripheralInput for AnyInputSignal { delegate::delegate! { to match &self.0 { AnyInputSignalInner::Input(pin) => pin, diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index f1d65ed10b..dd606af2dc 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -295,7 +295,7 @@ pub trait Pin: Sealed { } /// Trait implemented by pins which can be used as peripheral inputs. -pub trait PeripheralInputPin: Sealed { +pub trait PeripheralInput: Sealed { /// Init as input with the given pull-up/pull-down fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal); @@ -320,7 +320,7 @@ pub trait PeripheralInputPin: Sealed { } /// Trait implemented by pins which can be used as peripheral outputs. -pub trait PeripheralOutputPin: Sealed { +pub trait PeripheralOutput: Sealed { /// Configure open-drain mode fn set_to_open_drain_output(&mut self, _: private::Internal); @@ -369,7 +369,7 @@ pub trait PeripheralOutputPin: Sealed { } /// Trait implemented by pins which can be used as inputs. -pub trait InputPin: Pin + PeripheralInputPin { +pub trait InputPin: Pin + PeripheralInput { /// Listen for interrupts fn listen(&mut self, event: Event, _: private::Internal) { self.listen_with_options(event, true, false, false, private::Internal) @@ -406,7 +406,7 @@ pub trait InputPin: Pin + PeripheralInputPin { } /// Trait implemented by pins which can be used as outputs. -pub trait OutputPin: Pin + PeripheralOutputPin {} +pub trait OutputPin: Pin + PeripheralOutput {} /// Trait implemented by pins which can be used as analog pins pub trait AnalogPin: Pin { @@ -712,7 +712,7 @@ where } } -impl PeripheralInputPin for GpioPin +impl PeripheralInput for GpioPin where Self: GpioProperties, { @@ -817,7 +817,7 @@ where } } -impl PeripheralOutputPin for GpioPin +impl PeripheralOutput for GpioPin where Self: GpioProperties, { @@ -2163,34 +2163,34 @@ pub(crate) mod internal { } } - impl PeripheralInputPin for AnyPin { + impl PeripheralInput for AnyPin { fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { handle_gpio_input!(&self.0, target, { - PeripheralInputPin::init_input(target, pull_down, pull_up, private::Internal) + PeripheralInput::init_input(target, pull_down, pull_up, private::Internal) }); } fn enable_input(&mut self, on: bool, _: private::Internal) { handle_gpio_input!(&mut self.0, target, { - PeripheralInputPin::enable_input(target, on, private::Internal) + PeripheralInput::enable_input(target, on, private::Internal) }); } fn enable_input_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_input!(&mut self.0, target, { - PeripheralInputPin::enable_input_in_sleep_mode(target, on, private::Internal) + PeripheralInput::enable_input_in_sleep_mode(target, on, private::Internal) }); } fn is_input_high(&self, _: private::Internal) -> bool { handle_gpio_input!(&self.0, target, { - PeripheralInputPin::is_input_high(target, private::Internal) + PeripheralInput::is_input_high(target, private::Internal) }) } fn input_signals(&self, _: private::Internal) -> [Option; 6] { handle_gpio_input!(&self.0, target, { - PeripheralInputPin::input_signals(target, private::Internal) + PeripheralInput::input_signals(target, private::Internal) }) } @@ -2251,82 +2251,82 @@ pub(crate) mod internal { } } - impl PeripheralOutputPin for AnyPin { + impl PeripheralOutput for AnyPin { fn set_to_open_drain_output(&mut self, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::set_to_open_drain_output(target, private::Internal) + PeripheralOutput::set_to_open_drain_output(target, private::Internal) }); } fn set_to_push_pull_output(&mut self, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::set_to_push_pull_output(target, private::Internal) + PeripheralOutput::set_to_push_pull_output(target, private::Internal) }); } fn enable_output(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::enable_output(target, on, private::Internal) + PeripheralOutput::enable_output(target, on, private::Internal) }); } fn set_output_high(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::set_output_high(target, on, private::Internal) + PeripheralOutput::set_output_high(target, on, private::Internal) }); } fn set_drive_strength(&mut self, strength: DriveStrength, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::set_drive_strength(target, strength, private::Internal) + PeripheralOutput::set_drive_strength(target, strength, private::Internal) }); } fn enable_open_drain(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::enable_open_drain(target, on, private::Internal) + PeripheralOutput::enable_open_drain(target, on, private::Internal) }); } fn enable_output_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::enable_output_in_sleep_mode(target, on, private::Internal) + PeripheralOutput::enable_output_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::internal_pull_up_in_sleep_mode(target, on, private::Internal) + PeripheralOutput::internal_pull_up_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::internal_pull_down_in_sleep_mode(target, on, private::Internal) + PeripheralOutput::internal_pull_down_in_sleep_mode(target, on, private::Internal) }); } fn internal_pull_up(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::internal_pull_up(target, on, private::Internal) + PeripheralOutput::internal_pull_up(target, on, private::Internal) }); } fn internal_pull_down(&mut self, on: bool, _: private::Internal) { handle_gpio_output!(&mut self.0, target, { - PeripheralOutputPin::internal_pull_down(target, on, private::Internal) + PeripheralOutput::internal_pull_down(target, on, private::Internal) }); } fn is_set_high(&self, _: private::Internal) -> bool { handle_gpio_output!(&self.0, target, { - PeripheralOutputPin::is_set_high(target, private::Internal) + PeripheralOutput::is_set_high(target, private::Internal) }) } fn output_signals(&self, _: private::Internal) -> [Option; 6] { handle_gpio_output!(&self.0, target, { - PeripheralOutputPin::output_signals(target, private::Internal) + PeripheralOutput::output_signals(target, private::Internal) }) } diff --git a/esp-hal/src/i2c.rs b/esp-hal/src/i2c.rs index 743c8825c3..4438818d54 100644 --- a/esp-hal/src/i2c.rs +++ b/esp-hal/src/i2c.rs @@ -57,7 +57,7 @@ use fugit::HertzU32; use crate::{ clock::Clocks, - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::i2c0::{RegisterBlock, COMD}, @@ -322,8 +322,8 @@ where T: Instance, { fn new_internal< - SDA: PeripheralOutputPin + PeripheralInputPin, - SCL: PeripheralOutputPin + PeripheralInputPin, + SDA: PeripheralOutput + PeripheralInput, + SCL: PeripheralOutput + PeripheralInput, >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, @@ -401,10 +401,7 @@ where /// Create a new I2C instance /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. - pub fn new< - SDA: PeripheralOutputPin + PeripheralInputPin, - SCL: PeripheralOutputPin + PeripheralInputPin, - >( + pub fn new( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, scl: impl Peripheral

+ 'd, @@ -417,8 +414,8 @@ where /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. pub fn new_with_timeout< - SDA: PeripheralOutputPin + PeripheralInputPin, - SCL: PeripheralOutputPin + PeripheralInputPin, + SDA: PeripheralOutput + PeripheralInput, + SCL: PeripheralOutput + PeripheralInput, >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, @@ -449,8 +446,8 @@ where /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. pub fn new_async< - SDA: PeripheralOutputPin + PeripheralInputPin, - SCL: PeripheralOutputPin + PeripheralInputPin, + SDA: PeripheralOutput + PeripheralInput, + SCL: PeripheralOutput + PeripheralInput, >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, @@ -464,8 +461,8 @@ where /// This will enable the peripheral but the peripheral won't get /// automatically disabled when this gets dropped. pub fn new_with_timeout_async< - SDA: PeripheralOutputPin + PeripheralInputPin, - SCL: PeripheralOutputPin + PeripheralInputPin, + SDA: PeripheralOutput + PeripheralInput, + SCL: PeripheralOutput + PeripheralInput, >( i2c: impl Peripheral

+ 'd, sda: impl Peripheral

+ 'd, diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 1c8066cb18..b6ceedf693 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -107,7 +107,7 @@ use crate::{ TxPrivate, WriteBuffer, }, - gpio::PeripheralOutputPin, + gpio::PeripheralOutput, interrupt::InterruptHandler, into_ref, peripheral::Peripheral, @@ -495,7 +495,7 @@ where } /// Configures the I2S peripheral to use a master clock (MCLK) output pin. - pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { + pub fn with_mclk(self, pin: impl Peripheral

+ 'd) -> Self { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); pin.connect_peripheral_to_output(I::mclk_signal(), crate::private::Internal); @@ -891,7 +891,7 @@ mod private { use crate::peripherals::{i2s1::RegisterBlock, I2S1}; use crate::{ dma::{ChannelRx, ChannelTx, DmaChannel, DmaDescriptor, DmaPeripheral}, - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, into_ref, peripherals::I2S0, @@ -924,7 +924,7 @@ mod private { pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralOutputPin, + P: PeripheralOutput, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); @@ -935,7 +935,7 @@ mod private { pub fn with_ws

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralOutputPin, + P: PeripheralOutput, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); @@ -946,7 +946,7 @@ mod private { pub fn with_dout

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralOutputPin, + P: PeripheralOutput, { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); @@ -980,7 +980,7 @@ mod private { pub fn with_bclk

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralOutputPin, + P: PeripheralOutput, { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); @@ -991,7 +991,7 @@ mod private { pub fn with_ws

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralOutputPin, + P: PeripheralOutput, { into_ref!(pin); pin.set_to_push_pull_output(crate::private::Internal); @@ -1002,7 +1002,7 @@ mod private { pub fn with_din

(self, pin: impl crate::peripheral::Peripheral

+ 'd) -> Self where - P: PeripheralInputPin, + P: PeripheralInput, { into_ref!(pin); pin.init_input(false, false, crate::private::Internal); diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs index a4d6b2a91b..37316afad9 100644 --- a/esp-hal/src/lcd_cam/lcd/i8080.rs +++ b/esp-hal/src/lcd_cam/lcd/i8080.rs @@ -76,7 +76,7 @@ use crate::{ ReadBuffer, TxPrivate, }, - gpio::{OutputSignal, PeripheralOutputPin}, + gpio::{OutputSignal, PeripheralOutput}, lcd_cam::{ asynch::LcdDoneFuture, lcd::{i8080::private::TxPins, ClockMode, DelayMode, Phase, Polarity}, @@ -309,7 +309,7 @@ where } /// Associates a CS pin with the I8080 interface. - pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { + pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(crate::private::Internal); cs.connect_peripheral_to_output(OutputSignal::LCD_CS, crate::private::Internal); @@ -318,7 +318,7 @@ where } /// Configures the control pins for the I8080 interface. - pub fn with_ctrl_pins( + pub fn with_ctrl_pins( self, dc: impl Peripheral

+ 'd, wrx: impl Peripheral

+ 'd, @@ -593,14 +593,14 @@ pub struct TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> { impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> where - P0: PeripheralOutputPin, - P1: PeripheralOutputPin, - P2: PeripheralOutputPin, - P3: PeripheralOutputPin, - P4: PeripheralOutputPin, - P5: PeripheralOutputPin, - P6: PeripheralOutputPin, - P7: PeripheralOutputPin, + P0: PeripheralOutput, + P1: PeripheralOutput, + P2: PeripheralOutput, + P3: PeripheralOutput, + P4: PeripheralOutput, + P5: PeripheralOutput, + P6: PeripheralOutput, + P7: PeripheralOutput, { #[allow(clippy::too_many_arguments)] /// Creates a new `TxEightBits` instance with the provided output pins. @@ -638,14 +638,14 @@ where impl<'d, P0, P1, P2, P3, P4, P5, P6, P7> TxPins for TxEightBits<'d, P0, P1, P2, P3, P4, P5, P6, P7> where - P0: PeripheralOutputPin, - P1: PeripheralOutputPin, - P2: PeripheralOutputPin, - P3: PeripheralOutputPin, - P4: PeripheralOutputPin, - P5: PeripheralOutputPin, - P6: PeripheralOutputPin, - P7: PeripheralOutputPin, + P0: PeripheralOutput, + P1: PeripheralOutput, + P2: PeripheralOutput, + P3: PeripheralOutput, + P4: PeripheralOutput, + P5: PeripheralOutput, + P6: PeripheralOutput, + P7: PeripheralOutput, { type Word = u8; @@ -701,22 +701,22 @@ pub struct TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> where - P0: PeripheralOutputPin, - P1: PeripheralOutputPin, - P2: PeripheralOutputPin, - P3: PeripheralOutputPin, - P4: PeripheralOutputPin, - P5: PeripheralOutputPin, - P6: PeripheralOutputPin, - P7: PeripheralOutputPin, - P8: PeripheralOutputPin, - P9: PeripheralOutputPin, - P10: PeripheralOutputPin, - P11: PeripheralOutputPin, - P12: PeripheralOutputPin, - P13: PeripheralOutputPin, - P14: PeripheralOutputPin, - P15: PeripheralOutputPin, + P0: PeripheralOutput, + P1: PeripheralOutput, + P2: PeripheralOutput, + P3: PeripheralOutput, + P4: PeripheralOutput, + P5: PeripheralOutput, + P6: PeripheralOutput, + P7: PeripheralOutput, + P8: PeripheralOutput, + P9: PeripheralOutput, + P10: PeripheralOutput, + P11: PeripheralOutput, + P12: PeripheralOutput, + P13: PeripheralOutput, + P14: PeripheralOutput, + P15: PeripheralOutput, { #[allow(clippy::too_many_arguments)] /// Creates a new `TxSixteenBits` instance with the provided output pins. @@ -779,22 +779,22 @@ where impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> TxPins for TxSixteenBits<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> where - P0: PeripheralOutputPin, - P1: PeripheralOutputPin, - P2: PeripheralOutputPin, - P3: PeripheralOutputPin, - P4: PeripheralOutputPin, - P5: PeripheralOutputPin, - P6: PeripheralOutputPin, - P7: PeripheralOutputPin, - P8: PeripheralOutputPin, - P9: PeripheralOutputPin, - P10: PeripheralOutputPin, - P11: PeripheralOutputPin, - P12: PeripheralOutputPin, - P13: PeripheralOutputPin, - P14: PeripheralOutputPin, - P15: PeripheralOutputPin, + P0: PeripheralOutput, + P1: PeripheralOutput, + P2: PeripheralOutput, + P3: PeripheralOutput, + P4: PeripheralOutput, + P5: PeripheralOutput, + P6: PeripheralOutput, + P7: PeripheralOutput, + P8: PeripheralOutput, + P9: PeripheralOutput, + P10: PeripheralOutput, + P11: PeripheralOutput, + P12: PeripheralOutput, + P13: PeripheralOutput, + P14: PeripheralOutput, + P15: PeripheralOutput, { type Word = u16; fn configure(&mut self) { diff --git a/esp-hal/src/ledc/channel.rs b/esp-hal/src/ledc/channel.rs index 268015627e..dd3bd18cd2 100644 --- a/esp-hal/src/ledc/channel.rs +++ b/esp-hal/src/ledc/channel.rs @@ -11,7 +11,7 @@ use super::timer::{TimerIFace, TimerSpeed}; use crate::{ - gpio::{OutputSignal, PeripheralOutputPin}, + gpio::{OutputSignal, PeripheralOutput}, peripheral::{Peripheral, PeripheralRef}, peripherals::ledc::RegisterBlock, }; @@ -95,7 +95,7 @@ pub mod config { } /// Channel interface -pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: PeripheralOutputPin + 'a> +pub trait ChannelIFace<'a, S: TimerSpeed + 'a, O: PeripheralOutput + 'a> where Channel<'a, S, O>: ChannelHW, { @@ -118,7 +118,7 @@ where } /// Channel HW interface -pub trait ChannelHW { +pub trait ChannelHW { /// Configure Channel HW except for the duty which is set via /// [`Self::set_duty_hw`]. fn configure_hw(&mut self) -> Result<(), Error>; @@ -144,14 +144,14 @@ pub trait ChannelHW { } /// Channel struct -pub struct Channel<'a, S: TimerSpeed, O: PeripheralOutputPin> { +pub struct Channel<'a, S: TimerSpeed, O: PeripheralOutput> { ledc: &'a RegisterBlock, timer: Option<&'a dyn TimerIFace>, number: Number, output_pin: PeripheralRef<'a, O>, } -impl<'a, S: TimerSpeed, O: PeripheralOutputPin> Channel<'a, S, O> { +impl<'a, S: TimerSpeed, O: PeripheralOutput> Channel<'a, S, O> { /// Return a new channel pub fn new(number: Number, output_pin: impl Peripheral

+ 'a) -> Self { crate::into_ref!(output_pin); @@ -165,7 +165,7 @@ impl<'a, S: TimerSpeed, O: PeripheralOutputPin> Channel<'a, S, O> { } } -impl<'a, S: TimerSpeed, O: PeripheralOutputPin> ChannelIFace<'a, S, O> for Channel<'a, S, O> +impl<'a, S: TimerSpeed, O: PeripheralOutput> ChannelIFace<'a, S, O> for Channel<'a, S, O> where Channel<'a, S, O>: ChannelHW, { @@ -337,7 +337,7 @@ mod ehal1 { } } -impl<'a, O: PeripheralOutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> { +impl<'a, O: PeripheralOutput, S: crate::ledc::timer::TimerSpeed> Channel<'a, S, O> { #[cfg(esp32)] fn set_channel(&mut self, timer_number: u8) { if S::IS_HS { @@ -537,7 +537,7 @@ impl<'a, O: PeripheralOutputPin, S: crate::ledc::timer::TimerSpeed> Channel<'a, impl<'a, O, S> ChannelHW for Channel<'a, S, O> where - O: PeripheralOutputPin, + O: PeripheralOutput, S: crate::ledc::timer::TimerSpeed, { /// Configure Channel HW diff --git a/esp-hal/src/mcpwm/operator.rs b/esp-hal/src/mcpwm/operator.rs index c08b9e19ee..31d7e55fb7 100644 --- a/esp-hal/src/mcpwm/operator.rs +++ b/esp-hal/src/mcpwm/operator.rs @@ -12,7 +12,7 @@ use core::marker::PhantomData; use crate::{ - gpio::PeripheralOutputPin, + gpio::PeripheralOutput, mcpwm::{timer::Timer, PwmPeripheral}, peripheral::{Peripheral, PeripheralRef}, private, @@ -204,7 +204,7 @@ impl Operator { } /// Use the A output with the given pin and configuration - pub fn with_pin_a<'d, Pin: PeripheralOutputPin>( + pub fn with_pin_a<'d, Pin: PeripheralOutput>( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -213,7 +213,7 @@ impl Operator { } /// Use the B output with the given pin and configuration - pub fn with_pin_b<'d, Pin: PeripheralOutputPin>( + pub fn with_pin_b<'d, Pin: PeripheralOutput>( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -222,7 +222,7 @@ impl Operator { } /// Use both the A and the B output with the given pins and configurations - pub fn with_pins<'d, PinA: PeripheralOutputPin, PinB: PeripheralOutputPin>( + pub fn with_pins<'d, PinA: PeripheralOutput, PinB: PeripheralOutput>( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -239,7 +239,7 @@ impl Operator { /// /// This is useful for complementary or mirrored signals with or without /// configured deadtime - pub fn with_linked_pins<'d, PinA: PeripheralOutputPin, PinB: PeripheralOutputPin>( + pub fn with_linked_pins<'d, PinA: PeripheralOutput, PinB: PeripheralOutput>( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -288,7 +288,7 @@ pub struct PwmPin<'d, Pin, PWM, const OP: u8, const IS_A: bool> { phantom: PhantomData, } -impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, Pin, PWM, OP, IS_A> { fn new(pin: impl Peripheral

+ 'd, config: PwmPinConfig) -> Self { @@ -415,7 +415,7 @@ impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: } } -impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal_02::PwmPin for PwmPin<'d, Pin, PWM, OP, IS_A> { type Duty = u16; @@ -449,14 +449,14 @@ impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: } /// Implement no error type for the PwmPin because the method are infallible -impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal::pwm::ErrorType for PwmPin<'d, Pin, PWM, OP, IS_A> { type Error = core::convert::Infallible; } /// Implement the trait SetDutyCycle for PwmPin -impl<'d, Pin: PeripheralOutputPin, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> +impl<'d, Pin: PeripheralOutput, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> embedded_hal::pwm::SetDutyCycle for PwmPin<'d, Pin, PWM, OP, IS_A> { /// Get the max duty of the PwmPin @@ -523,13 +523,8 @@ pub struct LinkedPins<'d, PinA, PinB, PWM, const OP: u8> { pin_b: PwmPin<'d, PinB, PWM, OP, false>, } -impl< - 'd, - PinA: PeripheralOutputPin, - PinB: PeripheralOutputPin, - PWM: PwmPeripheral, - const OP: u8, - > LinkedPins<'d, PinA, PinB, PWM, OP> +impl<'d, PinA: PeripheralOutput, PinB: PeripheralOutput, PWM: PwmPeripheral, const OP: u8> + LinkedPins<'d, PinA, PinB, PWM, OP> { fn new( pin_a: impl Peripheral

+ 'd, diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 84debd3162..4883daa152 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -102,7 +102,7 @@ impl<'d> Usb<'d> { .modify(|_, w| w.sw_hw_usb_phy_sel().set_bit().sw_usb_phy_sel().set_bit()); } - use crate::gpio::{Level, PeripheralInputPin}; + use crate::gpio::{Level, PeripheralInput}; Level::High.connect_input_to_peripheral(InputSignal::USB_OTG_IDDIG, Internal); // connected connector is mini-B side Level::High.connect_input_to_peripheral(InputSignal::USB_SRP_BVALID, Internal); // HIGH to force USB device mode diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 1a6fe2943e..1c1d790a2b 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -49,7 +49,7 @@ use crate::{ TxPrivate, WriteBuffer, }, - gpio::{PeripheralInputPin, PeripheralOutputPin}, + gpio::{PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{self, Peripheral}, peripherals, @@ -279,13 +279,13 @@ pub fn no_clk_pin() -> &'static mut NoClkPin { /// Wraps a GPIO pin which will be used as the clock output signal pub struct ClkOutPin<'d, P> where - P: PeripheralOutputPin, + P: PeripheralOutput, { pin: PeripheralRef<'d, P>, } impl<'d, P> ClkOutPin<'d, P> where - P: PeripheralOutputPin, + P: PeripheralOutput, { /// Create a ClkOutPin pub fn new(pin: impl Peripheral

+ 'd) -> Self { @@ -295,7 +295,7 @@ where } impl<'d, P> TxClkPin for ClkOutPin<'d, P> where - P: PeripheralOutputPin, + P: PeripheralOutput, { fn configure(&mut self) { self.pin.set_to_push_pull_output(crate::private::Internal); @@ -309,13 +309,13 @@ where /// Wraps a GPIO pin which will be used as the TX clock input signal pub struct ClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { pin: PeripheralRef<'d, P>, } impl<'d, P> ClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { /// Create a new ClkInPin pub fn new(pin: impl Peripheral

+ 'd) -> Self { @@ -325,7 +325,7 @@ where } impl<'d, P> TxClkPin for ClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { fn configure(&mut self) { let pcr = unsafe { &*crate::peripherals::PCR::PTR }; @@ -343,14 +343,14 @@ where /// Wraps a GPIO pin which will be used as the RX clock input signal pub struct RxClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { pin: PeripheralRef<'d, P>, sample_edge: SampleEdge, } impl<'d, P> RxClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { /// Create a new RxClkInPin pub fn new(pin: impl Peripheral

+ 'd, sample_edge: SampleEdge) -> Self { @@ -360,7 +360,7 @@ where } impl<'d, P> RxClkPin for RxClkInPin<'d, P> where - P: PeripheralInputPin, + P: PeripheralInput, { fn configure(&mut self) { let pcr = unsafe { &*crate::peripherals::PCR::PTR }; @@ -381,7 +381,7 @@ where pub struct TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: PeripheralOutputPin, + VP: PeripheralOutput, { tx_pins: P, valid_pin: PeripheralRef<'d, VP>, @@ -390,7 +390,7 @@ where impl<'d, P, VP> TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: PeripheralOutputPin, + VP: PeripheralOutput, { /// Create a [TxPinConfigWithValidPin] pub fn new(tx_pins: P, valid_pin: impl Peripheral

+ 'd) -> Self { @@ -402,14 +402,14 @@ where impl<'d, P, VP> TxPins for TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: PeripheralOutputPin, + VP: PeripheralOutput, { } impl<'d, P, VP> ConfigurePins for TxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + TxPins + ConfigurePins, - VP: PeripheralOutputPin, + VP: PeripheralOutput, { fn configure(&mut self) -> Result<(), Error> { self.tx_pins.configure()?; @@ -472,7 +472,7 @@ macro_rules! tx_pins { impl<'d, $($pin),+> $name<'d, $($pin),+> where - $($pin: PeripheralOutputPin),+ + $($pin: PeripheralOutput),+ { /// Create a new TX pin #[allow(clippy::too_many_arguments)] @@ -488,7 +488,7 @@ macro_rules! tx_pins { impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+> where - $($pin: PeripheralOutputPin),+ + $($pin: PeripheralOutput),+ { fn configure(&mut self) -> Result<(), Error>{ $( @@ -590,7 +590,7 @@ impl<'d, P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> pub struct RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: PeripheralInputPin, + VP: PeripheralInput, { rx_pins: P, valid_pin: PeripheralRef<'d, VP>, @@ -601,7 +601,7 @@ where impl<'d, P, VP> RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: PeripheralInputPin, + VP: PeripheralInput, { /// Create a new [RxPinConfigWithValidPin] pub fn new( @@ -623,14 +623,14 @@ where impl<'d, P, VP> RxPins for RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: PeripheralInputPin, + VP: PeripheralInput, { } impl<'d, P, VP> ConfigurePins for RxPinConfigWithValidPin<'d, P, VP> where P: NotContainsValidSignalPin + RxPins + ConfigurePins, - VP: PeripheralInputPin, + VP: PeripheralInput, { fn configure(&mut self) -> Result<(), Error> { self.rx_pins.configure()?; @@ -719,7 +719,7 @@ macro_rules! rx_pins { impl<'d, $($pin),+> $name<'d, $($pin),+> where - $($pin: PeripheralInputPin),+ + $($pin: PeripheralInput),+ { /// Create a new RX pin #[allow(clippy::too_many_arguments)] @@ -735,7 +735,7 @@ macro_rules! rx_pins { impl<'d, $($pin),+> ConfigurePins for $name<'d, $($pin),+> where - $($pin: PeripheralInputPin),+ + $($pin: PeripheralInput),+ { fn configure(&mut self) -> Result<(), Error> { $( diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index b265d54242..434599f9e0 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -9,7 +9,7 @@ use core::marker::PhantomData; -use crate::gpio::{interconnect::AnyInputSignal, InputSignal, PeripheralInputPin, Pull}; +use crate::gpio::{interconnect::AnyInputSignal, InputSignal, PeripheralInput, Pull}; /// Configuration for an PCNT input pin #[derive(Clone, Copy, Debug)] diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index e98390d328..c29c9c592e 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -85,7 +85,7 @@ use core::marker::PhantomData; use fugit::HertzU32; use crate::{ - gpio::{PeripheralInputPin, PeripheralOutputPin}, + gpio::{PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::Peripheral, rmt::private::CreateInstance, @@ -297,7 +297,7 @@ impl<'d> Rmt<'d, crate::Async> { fn configure_rx_channel< 'd, - P: PeripheralInputPin, + P: PeripheralInput, T: private::RxChannelInternal, M: crate::Mode, >( @@ -339,7 +339,7 @@ fn configure_rx_channel< fn configure_tx_channel< 'd, - P: PeripheralOutputPin, + P: PeripheralOutput, T: private::TxChannelInternal, M: crate::Mode, >( @@ -365,7 +365,7 @@ fn configure_tx_channel< /// Creates a TX channel pub trait TxChannelCreator<'d, T, P> where - P: PeripheralOutputPin, + P: PeripheralOutput, T: TxChannel, { /// Configure the TX channel @@ -384,7 +384,7 @@ where /// Creates a TX channel in async mode pub trait TxChannelCreatorAsync<'d, T, P> where - P: PeripheralOutputPin, + P: PeripheralOutput, T: TxChannelAsync, { /// Configure the TX channel @@ -403,7 +403,7 @@ where /// Creates a RX channel pub trait RxChannelCreator<'d, T, P> where - P: PeripheralInputPin, + P: PeripheralInput, T: RxChannel, { /// Configure the RX channel @@ -422,7 +422,7 @@ where /// Creates a RX channel in async mode pub trait RxChannelCreatorAsync<'d, T, P> where - P: PeripheralInputPin, + P: PeripheralInput, T: RxChannelAsync, { /// Configure the RX channel @@ -575,7 +575,7 @@ macro_rules! impl_tx_channel_creator { impl<'d, P> $crate::rmt::TxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P> for ChannelCreator<$crate::Blocking, $channel> where - P: $crate::gpio::PeripheralOutputPin, + P: $crate::gpio::PeripheralOutput, { } @@ -584,7 +584,7 @@ macro_rules! impl_tx_channel_creator { impl<'d, P> $crate::rmt::TxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P> for ChannelCreator<$crate::Async, $channel> where - P: $crate::gpio::PeripheralOutputPin, + P: $crate::gpio::PeripheralOutput, { } @@ -597,7 +597,7 @@ macro_rules! impl_rx_channel_creator { impl<'d, P> $crate::rmt::RxChannelCreator<'d, $crate::rmt::Channel<$crate::Blocking, $channel>, P> for ChannelCreator<$crate::Blocking, $channel> where - P: $crate::gpio::PeripheralInputPin, + P: $crate::gpio::PeripheralInput, { } @@ -606,7 +606,7 @@ macro_rules! impl_rx_channel_creator { impl<'d, P> $crate::rmt::RxChannelCreatorAsync<'d, $crate::rmt::Channel<$crate::Async, $channel>, P> for ChannelCreator<$crate::Async, $channel> where - P: $crate::gpio::PeripheralInputPin, + P: $crate::gpio::PeripheralInput, { } diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index fa485229c4..af3f229012 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -82,7 +82,7 @@ use super::{ use crate::{ clock::Clocks, dma::{DmaPeripheral, DmaRxBuffer, DmaTxBuffer, Rx, Tx}, - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::spi2::RegisterBlock, @@ -465,7 +465,7 @@ where /// /// Sets the specified pin to push-pull output and connects it to the SPI /// clock signal. - pub fn with_sck(self, sclk: impl Peripheral

+ 'd) -> Self { + pub fn with_sck(self, sclk: impl Peripheral

+ 'd) -> Self { crate::into_ref!(sclk); sclk.set_to_push_pull_output(private::Internal); sclk.connect_peripheral_to_output(self.spi.sclk_signal(), private::Internal); @@ -477,7 +477,7 @@ where /// /// Sets the specified pin to push-pull output and connects it to the SPI CS /// signal. - pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { + pub fn with_cs(self, cs: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cs); cs.set_to_push_pull_output(private::Internal); cs.connect_peripheral_to_output(self.spi.cs_signal(), private::Internal); @@ -546,10 +546,7 @@ where /// /// Sets the specified pin to push-pull output and connects it to the SPI /// MOSI signal. - pub fn with_mosi( - self, - mosi: impl Peripheral

+ 'd, - ) -> Self { + pub fn with_mosi(self, mosi: impl Peripheral

+ 'd) -> Self { crate::into_ref!(mosi); mosi.set_to_push_pull_output(private::Internal); mosi.connect_peripheral_to_output(self.spi.mosi_signal(), private::Internal); @@ -560,7 +557,7 @@ where /// Assign the MISO (Master In Slave Out) pin for the SPI instance. /// /// Sets the specified pin to input and connects it to the SPI MISO signal. - pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { + pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { crate::into_ref!(miso); miso.init_input(false, false, private::Internal); miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); @@ -581,10 +578,10 @@ where /// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the /// given pin. pub fn with_pins< - SCK: PeripheralOutputPin, - MOSI: PeripheralOutputPin, - MISO: PeripheralInputPin, - CS: PeripheralOutputPin, + SCK: PeripheralOutput, + MOSI: PeripheralOutput, + MISO: PeripheralInput, + CS: PeripheralOutput, >( self, sck: Option + 'd>, @@ -669,7 +666,7 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the MOSI signal and SIO0 input signal. - pub fn with_mosi( + pub fn with_mosi( self, mosi: impl Peripheral

+ 'd, ) -> Self { @@ -688,7 +685,7 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the MISO signal and SIO1 input signal. - pub fn with_miso( + pub fn with_miso( self, miso: impl Peripheral

+ 'd, ) -> Self { @@ -706,7 +703,7 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the SIO2 output and input signals. - pub fn with_sio2( + pub fn with_sio2( self, sio2: impl Peripheral

+ 'd, ) -> Self { @@ -724,7 +721,7 @@ where /// /// Enables both input and output functionality for the pin, and connects it /// to the SIO3 output and input signals. - pub fn with_sio3( + pub fn with_sio3( self, sio3: impl Peripheral

+ 'd, ) -> Self { @@ -743,12 +740,12 @@ where /// All pins are optional. Pass [crate::gpio::NO_PIN] if you don't need the /// given pin. pub fn with_pins< - SCK: PeripheralOutputPin, - MOSI: PeripheralOutputPin + PeripheralInputPin, - MISO: PeripheralOutputPin + PeripheralInputPin, - SIO2: PeripheralOutputPin + PeripheralInputPin, - SIO3: PeripheralOutputPin + PeripheralInputPin, - CS: PeripheralOutputPin, + SCK: PeripheralOutput, + MOSI: PeripheralOutput + PeripheralInput, + MISO: PeripheralOutput + PeripheralInput, + SIO2: PeripheralOutput + PeripheralInput, + SIO3: PeripheralOutput + PeripheralInput, + CS: PeripheralOutput, >( self, sck: Option + 'd>, diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 4ffbcda650..efb7a350c1 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -73,7 +73,7 @@ use core::marker::PhantomData; use super::{Error, FullDuplexMode, SpiMode}; use crate::{ dma::{DescriptorChain, DmaPeripheral, Rx, Tx}, - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, peripheral::{Peripheral, PeripheralRef}, peripherals::spi2::RegisterBlock, private, @@ -107,10 +107,10 @@ where { /// Constructs an SPI instance in 8bit dataframe mode. pub fn new< - SCK: PeripheralInputPin, - MOSI: PeripheralInputPin, - MISO: PeripheralOutputPin, - CS: PeripheralInputPin, + SCK: PeripheralInput, + MOSI: PeripheralInput, + MISO: PeripheralOutput, + CS: PeripheralInput, >( spi: impl Peripheral

+ 'd, sclk: impl Peripheral

+ 'd, diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index da9f45a95e..b37e4c88dd 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -133,7 +133,7 @@ use core::marker::PhantomData; use self::filter::{Filter, FilterType}; use crate::{ - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::twai0::RegisterBlock, @@ -716,7 +716,7 @@ where T: Instance, DM: crate::Mode, { - fn new_internal( + fn new_internal( _peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -905,7 +905,7 @@ where /// Create a new instance of [TwaiConfiguration] /// /// You will need to use a transceiver to connect to the TWAI bus - pub fn new( + pub fn new( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -920,7 +920,7 @@ where /// /// You don't need a transceiver by following the description in the /// `twai.rs` example - pub fn new_no_transceiver( + pub fn new_no_transceiver( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -949,7 +949,7 @@ where /// Create a new instance of [TwaiConfiguration] in async mode /// /// You will need to use a transceiver to connect to the TWAI bus - pub fn new_async( + pub fn new_async( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, @@ -966,7 +966,7 @@ where /// /// You don't need a transceiver by following the description in the /// `twai.rs` example - pub fn new_async_no_transceiver( + pub fn new_async_no_transceiver( peripheral: impl Peripheral

+ 'd, rx_pin: impl Peripheral

+ 'd, tx_pin: impl Peripheral

+ 'd, diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 90d912c69b..bcbe4ca6a5 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -131,7 +131,7 @@ use core::marker::PhantomData; use self::config::Config; use crate::{ clock::Clocks, - gpio::{InputSignal, OutputSignal, PeripheralInputPin, PeripheralOutputPin}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{uart0::RegisterBlock, Interrupt}, @@ -451,7 +451,7 @@ where } } - fn with_rx(self, rx: impl Peripheral

+ 'd) -> Self { + fn with_rx(self, rx: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rx); rx.init_input(false, false, Internal); rx.connect_input_to_peripheral(T::rx_signal(), Internal); @@ -459,7 +459,7 @@ where self } - fn with_tx(self, tx: impl Peripheral

+ 'd) -> Self { + fn with_tx(self, tx: impl Peripheral

+ 'd) -> Self { crate::into_ref!(tx); tx.set_to_push_pull_output(Internal); tx.connect_peripheral_to_output(T::tx_signal(), Internal); @@ -536,7 +536,7 @@ where } /// Configure RTS pin - pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { + pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rts); rts.set_to_push_pull_output(Internal); rts.connect_peripheral_to_output(T::rts_signal(), Internal); @@ -581,7 +581,7 @@ where T: Instance + 'd, { /// Create a new UART TX instance in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { @@ -590,7 +590,7 @@ where /// Create a new UART TX instance with configuration options in /// [`Blocking`] mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, @@ -620,7 +620,7 @@ where } /// Configure CTS pin - pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { + pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); cts.init_input(false, false, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); @@ -794,7 +794,7 @@ where T: Instance + 'd, { /// Create a new UART RX instance in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, ) -> Result { @@ -803,7 +803,7 @@ where /// Create a new UART RX instance with configuration options in /// [`Blocking`] mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -820,7 +820,7 @@ where { /// Create a new UART instance with configuration options in [`Blocking`] /// mode. - pub fn new_with_config( + pub fn new_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -835,7 +835,7 @@ where } /// Create a new UART instance with defaults in [`Blocking`] mode. - pub fn new( + pub fn new( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, @@ -857,7 +857,7 @@ where } /// Configure CTS pin - pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { + pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); cts.init_input(false, false, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); @@ -866,7 +866,7 @@ where } /// Configure RTS pin - pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { + pub fn with_rts(self, rts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rts); rts.set_to_push_pull_output(Internal); rts.connect_peripheral_to_output(T::rts_signal(), Internal); @@ -2058,7 +2058,7 @@ mod asynch { { /// Create a new UART instance with configuration options in [`Async`] /// mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, @@ -2086,7 +2086,7 @@ mod asynch { } /// Create a new UART instance with defaults in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, @@ -2121,7 +2121,7 @@ mod asynch { T: Instance + 'd, { /// Create a new UART TX instance in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, tx: impl Peripheral

+ 'd, ) -> Result { @@ -2130,7 +2130,7 @@ mod asynch { /// Create a new UART TX instance with configuration options in /// [`Async`] mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, tx: impl Peripheral

+ 'd, @@ -2202,7 +2202,7 @@ mod asynch { T: Instance + 'd, { /// Create a new UART RX instance in [`Async`] mode. - pub fn new_async( + pub fn new_async( uart: impl Peripheral

+ 'd, rx: impl Peripheral

+ 'd, ) -> Result { @@ -2211,7 +2211,7 @@ mod asynch { /// Create a new UART RX instance with configuration options in /// [`Async`] mode. - pub fn new_async_with_config( + pub fn new_async_with_config( uart: impl Peripheral

+ 'd, config: Config, rx: impl Peripheral

+ 'd, From 60a2581cb607dd1ed68e7c1305113149b28d7a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 10:17:54 +0200 Subject: [PATCH 14/21] Extract AF conversion --- esp-hal/src/gpio/interconnect.rs | 46 ++++++++++---------------------- esp-hal/src/gpio/mod.rs | 16 +++++++++++ 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index 3036a472a8..a220177b8a 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -89,23 +89,14 @@ impl PeripheralInput for InputSignal { let af = if self.is_inverted { GPIO_FUNCTION - } else if let Some(af) = self - .pin - .input_signals(private::Internal) - .into_iter() - .position(|s| s == Some(signal)) - { - match af { - 0 => AlternateFunction::Function0, - 1 => AlternateFunction::Function1, - 2 => AlternateFunction::Function2, - 3 => AlternateFunction::Function3, - 4 => AlternateFunction::Function4, - 5 => AlternateFunction::Function5, - _ => unreachable!(), - } } else { - GPIO_FUNCTION + self.pin + .input_signals(private::Internal) + .into_iter() + .position(|s| s == Some(signal)) + .ok_or(()) + .and_then(AlternateFunction::try_from) + .unwrap_or(GPIO_FUNCTION) }; if af == GPIO_FUNCTION && signal_nr > INPUT_SIGNAL_MAX as usize { @@ -232,23 +223,14 @@ impl PeripheralOutput for OutputSignal { fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal, _: private::Internal) { let af = if self.is_inverted { GPIO_FUNCTION - } else if let Some(af) = self - .pin - .output_signals(private::Internal) - .into_iter() - .position(|s| s == Some(signal)) - { - match af { - 0 => AlternateFunction::Function0, - 1 => AlternateFunction::Function1, - 2 => AlternateFunction::Function2, - 3 => AlternateFunction::Function3, - 4 => AlternateFunction::Function4, - 5 => AlternateFunction::Function5, - _ => unreachable!(), - } } else { - GPIO_FUNCTION + self.pin + .output_signals(private::Internal) + .into_iter() + .position(|s| s == Some(signal)) + .ok_or(()) + .and_then(AlternateFunction::try_from) + .unwrap_or(GPIO_FUNCTION) }; self.pin.set_alternate_function(af, private::Internal); diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index dd606af2dc..bd49225e7c 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -228,6 +228,22 @@ pub enum AlternateFunction { Function5 = 5, } +impl TryFrom for AlternateFunction { + type Error = (); + + fn try_from(value: usize) -> Result { + match value { + 0 => Ok(AlternateFunction::Function0), + 1 => Ok(AlternateFunction::Function1), + 2 => Ok(AlternateFunction::Function2), + 3 => Ok(AlternateFunction::Function3), + 4 => Ok(AlternateFunction::Function4), + 5 => Ok(AlternateFunction::Function5), + _ => Err(()), + } + } +} + /// RTC function #[derive(PartialEq)] pub enum RtcFunction { From dfdcda4fd14fd06c322f8eaacba5b6bea4a75794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 10:19:22 +0200 Subject: [PATCH 15/21] Touch up changelog --- esp-hal/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 987ffddec3..8716696d97 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -38,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The (previously undocumented) `ErasedPin` enum has been replaced with the `ErasedPin` struct. (#2094) - Renamed and merged `Rtc::get_time_us` and `Rtc::get_time_ms` into `Rtc::time_since_boot` (#1883) - ESP32: Added support for touch sensing on GPIO32 and 33 (#2109) -- Renamed `ErasedPin` to `AnyPin` (#2128) +- Replaced `AnyPin` with `InputSignal` and `OutputSignal` and renamed `ErasedPin` to `AnyPin` (#2128) ### Fixed From 0221b7306ff9106d60eed7bd58bc733e399c9236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 10:31:43 +0200 Subject: [PATCH 16/21] Clean up spi tests --- hil-test/tests/spi_full_duplex.rs | 7 ++++--- hil-test/tests/spi_full_duplex_dma.rs | 5 +++-- hil-test/tests/spi_full_duplex_dma_async.rs | 18 ++++-------------- hil-test/tests/spi_full_duplex_dma_pcnt.rs | 18 ++++-------------- 4 files changed, 15 insertions(+), 33 deletions(-) diff --git a/hil-test/tests/spi_full_duplex.rs b/hil-test/tests/spi_full_duplex.rs index 5578a89125..ce77f8b8a8 100644 --- a/hil-test/tests/spi_full_duplex.rs +++ b/hil-test/tests/spi_full_duplex.rs @@ -31,12 +31,13 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; - let (miso, mosi) = hil_test::common_test_pins!(io); + let (_, mosi) = hil_test::common_test_pins!(io); - let spi = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0) + let mosi_loopback = mosi.peripheral_input(); + let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) - .with_miso(miso); + .with_miso(mosi_loopback); Context { spi } } diff --git a/hil-test/tests/spi_full_duplex_dma.rs b/hil-test/tests/spi_full_duplex_dma.rs index 6781261e02..34c53bb50d 100644 --- a/hil-test/tests/spi_full_duplex_dma.rs +++ b/hil-test/tests/spi_full_duplex_dma.rs @@ -48,7 +48,7 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; - let (miso, mosi) = hil_test::common_test_pins!(io); + let (_, mosi) = hil_test::common_test_pins!(io); let dma = Dma::new(peripherals.DMA); @@ -60,10 +60,11 @@ mod tests { } } + let mosi_loopback = mosi.peripheral_input(); let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) - .with_miso(miso) + .with_miso(mosi_loopback) .with_dma(dma_channel.configure(false, DmaPriority::Priority0)); Context { spi } diff --git a/hil-test/tests/spi_full_duplex_dma_async.rs b/hil-test/tests/spi_full_duplex_dma_async.rs index 29d5e630c8..593ccce953 100644 --- a/hil-test/tests/spi_full_duplex_dma_async.rs +++ b/hil-test/tests/spi_full_duplex_dma_async.rs @@ -10,7 +10,7 @@ use embedded_hal_async::spi::SpiBus; use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{Io, Level, Output, Pull}, + gpio::{Io, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -44,7 +44,6 @@ struct Context { spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>, pcnt_source: PcntSource, pcnt_unit: Unit<'static, 0>, - out_pin: Output<'static>, } #[cfg(test)] @@ -63,11 +62,6 @@ mod tests { let sclk = io.pins.gpio0; let (_, mosi) = hil_test::common_test_pins!(io); - let miso = io.pins.gpio4; - - let mut out_pin = Output::new(io.pins.gpio5, Level::Low); - out_pin.set_low(); - assert_eq!(out_pin.is_set_low(), true); let dma = Dma::new(peripherals.DMA); @@ -84,18 +78,18 @@ mod tests { let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); let mosi_loopback = mosi.peripheral_input(); + let mosi_loopback_pcnt = mosi.peripheral_input(); let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) - .with_miso(miso) + .with_miso(mosi_loopback) .with_dma(dma_channel.configure_for_async(false, DmaPriority::Priority0)) .with_buffers(dma_rx_buf, dma_tx_buf); Context { spi, - pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }), + pcnt_source: PcntSource::from(mosi_loopback_pcnt, PcntInputConfig { pull: Pull::Down }), pcnt_unit: pcnt.unit0, - out_pin, } } @@ -112,8 +106,6 @@ mod tests { // Fill the buffer where each byte has 3 pos edges. let transmit = [0b0110_1010; DMA_BUFFER_SIZE]; - assert_eq!(ctx.out_pin.is_set_low(), true); - for i in 1..4 { receive.copy_from_slice(&[5, 5, 5, 5, 5]); SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap(); @@ -137,8 +129,6 @@ mod tests { // Fill the buffer where each byte has 3 pos edges. let transmit = [0b0110_1010; DMA_BUFFER_SIZE]; - assert_eq!(ctx.out_pin.is_set_low(), true); - for i in 1..4 { receive.copy_from_slice(&[5, 5, 5, 5, 5]); SpiBus::read(&mut ctx.spi, &mut receive).await.unwrap(); diff --git a/hil-test/tests/spi_full_duplex_dma_pcnt.rs b/hil-test/tests/spi_full_duplex_dma_pcnt.rs index d8106b52f7..59fbc30260 100644 --- a/hil-test/tests/spi_full_duplex_dma_pcnt.rs +++ b/hil-test/tests/spi_full_duplex_dma_pcnt.rs @@ -8,7 +8,7 @@ use esp_hal::{ dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma_buffers, - gpio::{Io, Level, Output, Pull}, + gpio::{Io, Pull}, pcnt::{ channel::{EdgeMode, PcntInputConfig, PcntSource}, unit::Unit, @@ -40,7 +40,6 @@ struct Context { spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>, pcnt_source: PcntSource, pcnt_unit: Unit<'static, 0>, - out_pin: Output<'static>, } #[cfg(test)] @@ -57,7 +56,6 @@ mod tests { let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio0; let (_, mosi) = hil_test::common_test_pins!(io); - let miso = io.pins.gpio4; let dma = Dma::new(peripherals.DMA); @@ -70,23 +68,19 @@ mod tests { } let mosi_loopback = mosi.peripheral_input(); + let mosi_loopback_pcnt = mosi.peripheral_input(); let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0) .with_sck(sclk) .with_mosi(mosi) - .with_miso(miso) + .with_miso(mosi_loopback) .with_dma(dma_channel.configure(false, DmaPriority::Priority0)); let pcnt = Pcnt::new(peripherals.PCNT); - let mut out_pin = Output::new(io.pins.gpio5, Level::Low); - out_pin.set_low(); - assert_eq!(out_pin.is_set_low(), true); - Context { spi, - pcnt_source: PcntSource::from(mosi_loopback, PcntInputConfig { pull: Pull::Down }), + pcnt_source: PcntSource::from(mosi_loopback_pcnt, PcntInputConfig { pull: Pull::Down }), pcnt_unit: pcnt.unit0, - out_pin, } } @@ -108,8 +102,6 @@ mod tests { // Fill the buffer where each byte has 3 pos edges. dma_tx_buf.as_mut_slice().fill(0b0110_1010); - assert_eq!(ctx.out_pin.is_set_low(), true); - for i in 1..4 { dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]); let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap(); @@ -140,8 +132,6 @@ mod tests { // Fill the buffer where each byte has 3 pos edges. dma_tx_buf.as_mut_slice().fill(0b0110_1010); - assert_eq!(ctx.out_pin.is_set_low(), true); - for i in 1..4 { dma_rx_buf.as_mut_slice().copy_from_slice(&[5, 5, 5, 5, 5]); let transfer = spi.dma_read(dma_rx_buf).map_err(|e| e.0).unwrap(); From a68ad026ffe5b71e7371e4405dbdce060e4dbb31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 11:26:28 +0200 Subject: [PATCH 17/21] Refactor pull resistor handling --- esp-hal/src/gpio/dummy_pin.rs | 27 ++++++--- esp-hal/src/gpio/etm.rs | 27 ++------- esp-hal/src/gpio/interconnect.rs | 36 ++++++++++-- esp-hal/src/gpio/mod.rs | 97 +++++++++++++------------------- esp-hal/src/i2c.rs | 6 +- esp-hal/src/i2s.rs | 18 +++--- esp-hal/src/lcd_cam/cam.rs | 62 ++++++++++---------- esp-hal/src/parl_io.rs | 10 ++-- esp-hal/src/pcnt/channel.rs | 6 +- esp-hal/src/rmt.rs | 2 +- esp-hal/src/spi/master.rs | 2 +- esp-hal/src/spi/slave.rs | 8 +-- esp-hal/src/twai/mod.rs | 4 +- esp-hal/src/uart.rs | 8 +-- 14 files changed, 159 insertions(+), 154 deletions(-) diff --git a/esp-hal/src/gpio/dummy_pin.rs b/esp-hal/src/gpio/dummy_pin.rs index 59cd6de415..478628c647 100644 --- a/esp-hal/src/gpio/dummy_pin.rs +++ b/esp-hal/src/gpio/dummy_pin.rs @@ -33,7 +33,7 @@ impl PeripheralInput for DummyPin { [None; 6] } - fn init_input(&self, _pull_down: bool, _pull_up: bool, _: private::Internal) {} + fn init_input(&self, _pull: Pull, _: private::Internal) {} fn enable_input(&mut self, _on: bool, _: private::Internal) {} @@ -61,23 +61,38 @@ impl PeripheralInput for DummyPin { fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _: private::Internal) {} } +impl PeripheralSignal for Level { + delegate::delegate! { + to match self { + Level::High => DummyPin { value: true }, + Level::Low => DummyPin { value: false }, + } { + fn pull_direction(&self, pull: Pull, _internal: private::Internal); + } + } +} + impl PeripheralInput for Level { delegate::delegate! { to match self { Level::High => DummyPin { value: true }, Level::Low => DummyPin { value: false }, - } { - fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; - fn init_input(&self, _pd: bool, _pu: bool, _internal: private::Internal); + } { + fn init_input(&self, _pull: Pull, _internal: private::Internal); fn enable_input(&mut self, _on: bool, _internal: private::Internal); fn enable_input_in_sleep_mode(&mut self, _on: bool, _internal: private::Internal); fn is_input_high(&self, _internal: private::Internal) -> bool; fn connect_input_to_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal); fn disconnect_input_from_peripheral(&mut self, _signal: InputSignal, _internal: private::Internal); + fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; } } } +impl PeripheralSignal for DummyPin { + fn pull_direction(&self, _pull: Pull, _internal: private::Internal) {} +} + impl PeripheralOutput for DummyPin { fn set_to_open_drain_output(&mut self, _: private::Internal) {} @@ -99,10 +114,6 @@ impl PeripheralOutput for DummyPin { fn internal_pull_down_in_sleep_mode(&mut self, _on: bool, _: private::Internal) {} - fn internal_pull_up(&mut self, _on: bool, _: private::Internal) {} - - fn internal_pull_down(&mut self, _on: bool, _: private::Internal) {} - fn is_set_high(&self, _: private::Internal) -> bool { self.value } diff --git a/esp-hal/src/gpio/etm.rs b/esp-hal/src/gpio/etm.rs index 7cfe6d8b6a..8e4da7b712 100644 --- a/esp-hal/src/gpio/etm.rs +++ b/esp-hal/src/gpio/etm.rs @@ -152,11 +152,7 @@ impl GpioEtmEventChannel { { crate::into_ref!(pin); - pin.init_input( - pin_config.pull == Pull::Down, - pin_config.pull == Pull::Up, - private::Internal, - ); + pin.init_input(pin_config.pull, private::Internal); enable_event_channel(C, pin.number(private::Internal)); GpioEtmEventChannelRising { _pin: pin } @@ -173,11 +169,7 @@ impl GpioEtmEventChannel { { crate::into_ref!(pin); - pin.init_input( - pin_config.pull == Pull::Down, - pin_config.pull == Pull::Up, - private::Internal, - ); + pin.init_input(pin_config.pull, private::Internal); enable_event_channel(C, pin.number(private::Internal)); GpioEtmEventChannelFalling { _pin: pin } @@ -194,11 +186,7 @@ impl GpioEtmEventChannel { { crate::into_ref!(pin); - pin.init_input( - pin_config.pull == Pull::Down, - pin_config.pull == Pull::Up, - private::Internal, - ); + pin.init_input(pin_config.pull, private::Internal); enable_event_channel(C, pin.number(private::Internal)); GpioEtmEventChannelAny { _pin: pin } @@ -318,8 +306,7 @@ impl GpioEtmTaskChannel { pin.set_output_high(pin_config.initial_state.into(), private::Internal); if pin_config.open_drain { - pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal); - pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal); + pin.pull_direction(pin_config.pull, private::Internal); pin.set_to_open_drain_output(private::Internal); } else { pin.set_to_push_pull_output(private::Internal); @@ -342,8 +329,7 @@ impl GpioEtmTaskChannel { pin.set_output_high(pin_config.initial_state.into(), private::Internal); if pin_config.open_drain { - pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal); - pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal); + pin.pull_direction(pin_config.pull, private::Internal); pin.set_to_open_drain_output(private::Internal); } else { pin.set_to_push_pull_output(private::Internal); @@ -366,8 +352,7 @@ impl GpioEtmTaskChannel { pin.set_output_high(pin_config.initial_state.into(), private::Internal); if pin_config.open_drain { - pin.internal_pull_down(pin_config.pull == Pull::Down, private::Internal); - pin.internal_pull_up(pin_config.pull == Pull::Up, private::Internal); + pin.pull_direction(pin_config.pull, private::Internal); pin.set_to_open_drain_output(private::Internal); } else { pin.set_to_push_pull_output(private::Internal); diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index a220177b8a..f5f4909fd4 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -13,7 +13,9 @@ use crate::{ OutputSignalType, PeripheralInput, PeripheralOutput, + PeripheralSignal, Pin, + Pull, FUNC_IN_SEL_OFFSET, GPIO_FUNCTION, INPUT_SIGNAL_MAX, @@ -82,6 +84,14 @@ impl InputSignal { } } +impl PeripheralSignal for InputSignal { + delegate::delegate! { + to self.pin { + fn pull_direction(&self, pull: Pull, _internal: private::Internal); + } + } +} + impl PeripheralInput for InputSignal { /// Connect the pin to a peripheral input signal. fn connect_input_to_peripheral(&mut self, signal: gpio::InputSignal, _: private::Internal) { @@ -134,7 +144,7 @@ impl PeripheralInput for InputSignal { delegate::delegate! { to self.pin { - fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal); + fn init_input(&self, pull: Pull, _internal: private::Internal); fn is_input_high(&self, _internal: private::Internal) -> bool; fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; fn enable_input(&mut self, on: bool, _internal: private::Internal); @@ -204,6 +214,14 @@ impl OutputSignal { } } +impl PeripheralSignal for OutputSignal { + delegate::delegate! { + to self.pin { + fn pull_direction(&self, pull: Pull, _internal: private::Internal); + } + } +} + impl PeripheralOutput for OutputSignal { /// Connect the pin to a peripheral output signal. // TODO: the following options should be part of the struct: @@ -279,8 +297,6 @@ impl PeripheralOutput for OutputSignal { fn enable_output_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_up(&mut self, on: bool, _internal: private::Internal); - fn internal_pull_down(&mut self, on: bool, _internal: private::Internal); fn is_set_high(&self, _internal: private::Internal) -> bool; fn output_signals(&self, _internal: private::Internal) -> [Option; 6]; } @@ -340,6 +356,18 @@ where } impl Sealed for AnyInputSignal {} +impl PeripheralSignal for AnyInputSignal { + delegate::delegate! { + to match &self.0 { + AnyInputSignalInner::Input(pin) => pin, + AnyInputSignalInner::Constant(level) => level, + AnyInputSignalInner::Dummy(pin) => pin, + } { + fn pull_direction(&self, pull: Pull, _internal: private::Internal); + } + } +} + impl PeripheralInput for AnyInputSignal { delegate::delegate! { to match &self.0 { @@ -347,7 +375,7 @@ impl PeripheralInput for AnyInputSignal { AnyInputSignalInner::Constant(level) => level, AnyInputSignalInner::Dummy(pin) => pin, } { - fn init_input(&self, pull_down: bool, pull_up: bool, _internal: private::Internal); + fn init_input(&self, pull: Pull, _internal: private::Internal); fn is_input_high(&self, _internal: private::Internal) -> bool; fn input_signals(&self, _internal: private::Internal) -> [Option; 6]; } diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index bd49225e7c..bc7be5ad50 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -310,10 +310,17 @@ pub trait Pin: Sealed { fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal); } +/// Common trait implemented by signals which can be used as peripheral inputs +/// or outputs. +pub trait PeripheralSignal: Sealed { + /// Configure the pullup and pulldown resistors + fn pull_direction(&self, pull: Pull, _: private::Internal); +} + /// Trait implemented by pins which can be used as peripheral inputs. -pub trait PeripheralInput: Sealed { +pub trait PeripheralInput: PeripheralSignal { /// Init as input with the given pull-up/pull-down - fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal); + fn init_input(&self, pull: Pull, _: private::Internal); /// Enable input for the pin fn enable_input(&mut self, on: bool, _: private::Internal); @@ -336,7 +343,7 @@ pub trait PeripheralInput: Sealed { } /// Trait implemented by pins which can be used as peripheral outputs. -pub trait PeripheralOutput: Sealed { +pub trait PeripheralOutput: PeripheralSignal { /// Configure open-drain mode fn set_to_open_drain_output(&mut self, _: private::Internal); @@ -364,12 +371,6 @@ pub trait PeripheralOutput: Sealed { /// Configure internal pull-down resistor in sleep mode fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _: private::Internal); - /// Enable/disable internal pull-up resistor for normal operation - fn internal_pull_up(&mut self, on: bool, _: private::Internal); - - /// Enable/disable internal pull-down resistor for normal operation - fn internal_pull_down(&mut self, on: bool, _: private::Internal); - /// Is the output set to high fn is_set_high(&self, _: private::Internal) -> bool; @@ -728,11 +729,26 @@ where } } +impl PeripheralSignal for GpioPin +where + Self: GpioProperties, +{ + fn pull_direction(&self, pull: Pull, _: private::Internal) { + let pull_up = pull == Pull::Up; + let pull_down = pull == Pull::Down; + + #[cfg(esp32)] + crate::soc::gpio::errata36(GPIONUM, Some(pull_up), Some(pull_down)); + + get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpd().bit(pull_down).fun_wpu().bit(pull_up)); + } +} + impl PeripheralInput for GpioPin where Self: GpioProperties, { - fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { + fn init_input(&self, pull: Pull, _: private::Internal) { let gpio = unsafe { &*GPIO::PTR }; self.write_out_en(false); @@ -740,8 +756,7 @@ where gpio.func_out_sel_cfg(GPIONUM as usize) .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); - #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, Some(pull_up), Some(pull_down)); + self.pull_direction(pull, private::Internal); #[cfg(any(esp32c3, esp32s3))] disable_usb_pads(GPIONUM); @@ -751,10 +766,6 @@ where .bits(GPIO_FUNCTION as u8) .fun_ie() .set_bit() - .fun_wpd() - .bit(pull_down) - .fun_wpu() - .bit(pull_up) .slp_sel() .clear_bit() }); @@ -879,20 +890,6 @@ where get_io_mux_reg(GPIONUM).modify(|_, w| w.mcu_oe().bit(on)); } - fn internal_pull_up(&mut self, on: bool, _: private::Internal) { - #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, Some(on), None); - - get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpu().bit(on)); - } - - fn internal_pull_down(&mut self, on: bool, _: private::Internal) { - #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, None, Some(on)); - - get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpd().bit(on)); - } - fn is_set_high(&self, _: private::Internal) -> bool { ::Bank::read_output() & (1 << (GPIONUM % 32)) != 0 } @@ -921,10 +918,8 @@ where fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { let gpio = unsafe { &*GPIO::PTR }; - #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, Some(false), Some(false)); - self.write_out_en(true); + self.pull_direction(Pull::None, private::Internal); gpio.pin(GPIONUM as usize) .modify(|_, w| w.pad_driver().bit(open_drain)); @@ -940,10 +935,6 @@ where .bits(alternate as u8) .fun_ie() .bit(open_drain) - .fun_wpd() - .clear_bit() - .fun_wpu() - .clear_bit() .fun_drv() .bits(DriveStrength::I20mA as u8) .slp_sel() @@ -1999,8 +1990,7 @@ where { /// Set the GPIO to input mode. pub fn set_as_input(&mut self, pull: Pull) { - self.pin - .init_input(pull == Pull::Down, pull == Pull::Up, private::Internal); + self.pin.init_input(pull, private::Internal); } /// Get whether the pin input level is high. @@ -2131,10 +2121,7 @@ where /// Set the GPIO to open-drain mode. pub fn set_as_open_drain(&mut self, pull: Pull) { self.pin.set_to_open_drain_output(private::Internal); - self.pin - .internal_pull_down(pull == Pull::Down, private::Internal); - self.pin - .internal_pull_up(pull == Pull::Up, private::Internal); + self.pin.pull_direction(pull, private::Internal); } } @@ -2179,10 +2166,18 @@ pub(crate) mod internal { } } + impl PeripheralSignal for AnyPin { + fn pull_direction(&self, pull: Pull, _: private::Internal) { + handle_gpio_input!(&self.0, target, { + PeripheralSignal::pull_direction(target, pull, private::Internal) + }) + } + } + impl PeripheralInput for AnyPin { - fn init_input(&self, pull_down: bool, pull_up: bool, _: private::Internal) { + fn init_input(&self, pull: Pull, _: private::Internal) { handle_gpio_input!(&self.0, target, { - PeripheralInput::init_input(target, pull_down, pull_up, private::Internal) + PeripheralInput::init_input(target, pull, private::Internal) }); } @@ -2322,18 +2317,6 @@ pub(crate) mod internal { }); } - fn internal_pull_up(&mut self, on: bool, _: private::Internal) { - handle_gpio_output!(&mut self.0, target, { - PeripheralOutput::internal_pull_up(target, on, private::Internal) - }); - } - - fn internal_pull_down(&mut self, on: bool, _: private::Internal) { - handle_gpio_output!(&mut self.0, target, { - PeripheralOutput::internal_pull_down(target, on, private::Internal) - }); - } - fn is_set_high(&self, _: private::Internal) -> bool { handle_gpio_output!(&self.0, target, { PeripheralOutput::is_set_high(target, private::Internal) diff --git a/esp-hal/src/i2c.rs b/esp-hal/src/i2c.rs index 4438818d54..d7a73fc205 100644 --- a/esp-hal/src/i2c.rs +++ b/esp-hal/src/i2c.rs @@ -57,7 +57,7 @@ use fugit::HertzU32; use crate::{ clock::Clocks, - gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::i2c0::{RegisterBlock, COMD}, @@ -358,7 +358,7 @@ where scl.set_to_open_drain_output(crate::private::Internal); scl.enable_input(true, crate::private::Internal); - scl.internal_pull_up(true, crate::private::Internal); + scl.pull_direction(Pull::Up, crate::private::Internal); scl.connect_input_to_peripheral( i2c.peripheral.scl_input_signal(), @@ -371,7 +371,7 @@ where sda.set_to_open_drain_output(crate::private::Internal); sda.enable_input(true, crate::private::Internal); - sda.internal_pull_up(true, crate::private::Internal); + sda.pull_direction(Pull::Up, crate::private::Internal); sda.connect_input_to_peripheral( i2c.peripheral.sda_input_signal(), diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index b6ceedf693..b6a196a620 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -928,7 +928,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::bclk_signal(), crate::private::Internal); + pin.connect_peripheral_to_output(T::bclk_signal(), private::Internal); self } @@ -939,7 +939,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::ws_signal(), crate::private::Internal); + pin.connect_peripheral_to_output(T::ws_signal(), private::Internal); self } @@ -950,7 +950,7 @@ mod private { { into_ref!(pin); pin.set_to_push_pull_output(private::Internal); - pin.connect_peripheral_to_output(T::dout_signal(), crate::private::Internal); + pin.connect_peripheral_to_output(T::dout_signal(), private::Internal); self } @@ -983,8 +983,8 @@ mod private { P: PeripheralOutput, { into_ref!(pin); - pin.set_to_push_pull_output(crate::private::Internal); - pin.connect_peripheral_to_output(T::bclk_rx_signal(), crate::private::Internal); + pin.set_to_push_pull_output(private::Internal); + pin.connect_peripheral_to_output(T::bclk_rx_signal(), private::Internal); self } @@ -994,8 +994,8 @@ mod private { P: PeripheralOutput, { into_ref!(pin); - pin.set_to_push_pull_output(crate::private::Internal); - pin.connect_peripheral_to_output(T::ws_rx_signal(), crate::private::Internal); + pin.set_to_push_pull_output(private::Internal); + pin.connect_peripheral_to_output(T::ws_rx_signal(), private::Internal); self } @@ -1005,8 +1005,8 @@ mod private { P: PeripheralInput, { into_ref!(pin); - pin.init_input(false, false, crate::private::Internal); - pin.connect_input_to_peripheral(T::din_signal(), crate::private::Internal); + pin.init_input(crate::gpio::Pull::None, private::Internal); + pin.connect_input_to_peripheral(T::din_signal(), private::Internal); self } diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 41e30c1b6b..2eefd8d7ff 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -81,7 +81,7 @@ use crate::{ RxPrivate, WriteBuffer, }, - gpio::{InputPin, InputSignal, OutputPin, OutputSignal}, + gpio::{InputPin, InputSignal, OutputPin, OutputSignal, Pull}, lcd_cam::{cam::private::RxPins, private::calculate_clkm, BitOrder, ByteOrder}, peripheral::{Peripheral, PeripheralRef}, peripherals::LCD_CAM, @@ -311,7 +311,7 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { pub fn with_pixel_clock(self, pclk: impl Peripheral

+ 'd) -> Self { crate::into_ref!(pclk); - pclk.init_input(false, false, crate::private::Internal); + pclk.init_input(Pull::None, crate::private::Internal); pclk.connect_input_to_peripheral(InputSignal::CAM_PCLK, crate::private::Internal); self @@ -327,9 +327,9 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { crate::into_ref!(vsync); crate::into_ref!(h_enable); - vsync.init_input(false, false, crate::private::Internal); + vsync.init_input(Pull::None, crate::private::Internal); vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal); - h_enable.init_input(false, false, crate::private::Internal); + h_enable.init_input(Pull::None, crate::private::Internal); h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal); self.lcd_cam @@ -351,11 +351,11 @@ impl<'d, CH: DmaChannel> Camera<'d, CH> { crate::into_ref!(hsync); crate::into_ref!(h_enable); - vsync.init_input(false, false, crate::private::Internal); + vsync.init_input(Pull::None, crate::private::Internal); vsync.connect_input_to_peripheral(InputSignal::CAM_V_SYNC, crate::private::Internal); - hsync.init_input(false, false, crate::private::Internal); + hsync.init_input(Pull::None, crate::private::Internal); hsync.connect_input_to_peripheral(InputSignal::CAM_H_SYNC, crate::private::Internal); - h_enable.init_input(false, false, crate::private::Internal); + h_enable.init_input(Pull::None, crate::private::Internal); h_enable.connect_input_to_peripheral(InputSignal::CAM_H_ENABLE, crate::private::Internal); self.lcd_cam @@ -475,21 +475,21 @@ impl RxEightBits { crate::into_ref!(pin_6); crate::into_ref!(pin_7); - pin_0.init_input(false, false, crate::private::Internal); + pin_0.init_input(Pull::None, crate::private::Internal); pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal); - pin_1.init_input(false, false, crate::private::Internal); + pin_1.init_input(Pull::None, crate::private::Internal); pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal); - pin_2.init_input(false, false, crate::private::Internal); + pin_2.init_input(Pull::None, crate::private::Internal); pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal); - pin_3.init_input(false, false, crate::private::Internal); + pin_3.init_input(Pull::None, crate::private::Internal); pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal); - pin_4.init_input(false, false, crate::private::Internal); + pin_4.init_input(Pull::None, crate::private::Internal); pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal); - pin_5.init_input(false, false, crate::private::Internal); + pin_5.init_input(Pull::None, crate::private::Internal); pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal); - pin_6.init_input(false, false, crate::private::Internal); + pin_6.init_input(Pull::None, crate::private::Internal); pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal); - pin_7.init_input(false, false, crate::private::Internal); + pin_7.init_input(Pull::None, crate::private::Internal); pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal); Self { _pins: () } @@ -563,37 +563,37 @@ impl RxSixteenBits { crate::into_ref!(pin_14); crate::into_ref!(pin_15); - pin_0.init_input(false, false, crate::private::Internal); + pin_0.init_input(Pull::None, crate::private::Internal); pin_0.connect_input_to_peripheral(InputSignal::CAM_DATA_0, crate::private::Internal); - pin_1.init_input(false, false, crate::private::Internal); + pin_1.init_input(Pull::None, crate::private::Internal); pin_1.connect_input_to_peripheral(InputSignal::CAM_DATA_1, crate::private::Internal); - pin_2.init_input(false, false, crate::private::Internal); + pin_2.init_input(Pull::None, crate::private::Internal); pin_2.connect_input_to_peripheral(InputSignal::CAM_DATA_2, crate::private::Internal); - pin_3.init_input(false, false, crate::private::Internal); + pin_3.init_input(Pull::None, crate::private::Internal); pin_3.connect_input_to_peripheral(InputSignal::CAM_DATA_3, crate::private::Internal); - pin_4.init_input(false, false, crate::private::Internal); + pin_4.init_input(Pull::None, crate::private::Internal); pin_4.connect_input_to_peripheral(InputSignal::CAM_DATA_4, crate::private::Internal); - pin_5.init_input(false, false, crate::private::Internal); + pin_5.init_input(Pull::None, crate::private::Internal); pin_5.connect_input_to_peripheral(InputSignal::CAM_DATA_5, crate::private::Internal); - pin_6.init_input(false, false, crate::private::Internal); + pin_6.init_input(Pull::None, crate::private::Internal); pin_6.connect_input_to_peripheral(InputSignal::CAM_DATA_6, crate::private::Internal); - pin_7.init_input(false, false, crate::private::Internal); + pin_7.init_input(Pull::None, crate::private::Internal); pin_7.connect_input_to_peripheral(InputSignal::CAM_DATA_7, crate::private::Internal); - pin_8.init_input(false, false, crate::private::Internal); + pin_8.init_input(Pull::None, crate::private::Internal); pin_8.connect_input_to_peripheral(InputSignal::CAM_DATA_8, crate::private::Internal); - pin_9.init_input(false, false, crate::private::Internal); + pin_9.init_input(Pull::None, crate::private::Internal); pin_9.connect_input_to_peripheral(InputSignal::CAM_DATA_9, crate::private::Internal); - pin_10.init_input(false, false, crate::private::Internal); + pin_10.init_input(Pull::None, crate::private::Internal); pin_10.connect_input_to_peripheral(InputSignal::CAM_DATA_10, crate::private::Internal); - pin_11.init_input(false, false, crate::private::Internal); + pin_11.init_input(Pull::None, crate::private::Internal); pin_11.connect_input_to_peripheral(InputSignal::CAM_DATA_11, crate::private::Internal); - pin_12.init_input(false, false, crate::private::Internal); + pin_12.init_input(Pull::None, crate::private::Internal); pin_12.connect_input_to_peripheral(InputSignal::CAM_DATA_12, crate::private::Internal); - pin_13.init_input(false, false, crate::private::Internal); + pin_13.init_input(Pull::None, crate::private::Internal); pin_13.connect_input_to_peripheral(InputSignal::CAM_DATA_13, crate::private::Internal); - pin_14.init_input(false, false, crate::private::Internal); + pin_14.init_input(Pull::None, crate::private::Internal); pin_14.connect_input_to_peripheral(InputSignal::CAM_DATA_14, crate::private::Internal); - pin_15.init_input(false, false, crate::private::Internal); + pin_15.init_input(Pull::None, crate::private::Internal); pin_15.connect_input_to_peripheral(InputSignal::CAM_DATA_15, crate::private::Internal); Self { _pins: () } diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 1c1d790a2b..0be79817c8 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -332,7 +332,8 @@ where pcr.parl_clk_tx_conf() .modify(|_, w| unsafe { w.parl_clk_tx_sel().bits(3).parl_clk_tx_div_num().bits(0) }); // PAD_CLK_TX, no divider - self.pin.init_input(false, false, crate::private::Internal); + self.pin + .init_input(crate::gpio::Pull::None, crate::private::Internal); self.pin.connect_input_to_peripheral( crate::gpio::InputSignal::PARL_TX_CLK, crate::private::Internal, @@ -367,7 +368,8 @@ where pcr.parl_clk_rx_conf() .modify(|_, w| unsafe { w.parl_clk_rx_sel().bits(3).parl_clk_rx_div_num().bits(0) }); // PAD_CLK_TX, no divider - self.pin.init_input(false, false, crate::private::Internal); + self.pin + .init_input(crate::gpio::Pull::None, crate::private::Internal); self.pin.connect_input_to_peripheral( crate::gpio::InputSignal::PARL_RX_CLK, crate::private::Internal, @@ -635,7 +637,7 @@ where fn configure(&mut self) -> Result<(), Error> { self.rx_pins.configure()?; self.valid_pin - .init_input(false, false, crate::private::Internal); + .init_input(crate::gpio::Pull::None, crate::private::Internal); self.valid_pin .connect_input_to_peripheral(Instance::rx_valid_pin_signal(), crate::private::Internal); Instance::set_rx_sw_en(false); @@ -739,7 +741,7 @@ macro_rules! rx_pins { { fn configure(&mut self) -> Result<(), Error> { $( - self.[< pin_ $pin:lower >].init_input(false, false, $crate::private::Internal); + self.[< pin_ $pin:lower >].init_input(crate::gpio::Pull::None, crate::private::Internal); self.[< pin_ $pin:lower >].connect_input_to_peripheral(crate::gpio::InputSignal::$signal, crate::private::Internal); )+ diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index 434599f9e0..6a0b13862e 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -38,11 +38,7 @@ impl PcntSource { /// configuration. pub fn from(source: impl Into, pin_config: PcntInputConfig) -> Self { let source = source.into(); - source.init_input( - pin_config.pull == Pull::Down, - pin_config.pull == Pull::Up, - crate::private::Internal, - ); + source.init_input(pin_config.pull, crate::private::Internal); Self { source } } diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index c29c9c592e..fcd765c077 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -321,7 +321,7 @@ fn configure_rx_channel< } crate::into_ref!(pin); - pin.init_input(false, false, crate::private::Internal); + pin.init_input(crate::gpio::Pull::None, crate::private::Internal); pin.connect_input_to_peripheral(T::input_signal(), crate::private::Internal); T::set_divider(config.clk_divider); diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index af3f229012..e62b0588e6 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -559,7 +559,7 @@ where /// Sets the specified pin to input and connects it to the SPI MISO signal. pub fn with_miso(self, miso: impl Peripheral

+ 'd) -> Self { crate::into_ref!(miso); - miso.init_input(false, false, private::Internal); + miso.init_input(crate::gpio::Pull::None, private::Internal); miso.connect_input_to_peripheral(self.spi.miso_signal(), private::Internal); self diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index efb7a350c1..ca3d1ed2f6 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -73,7 +73,7 @@ use core::marker::PhantomData; use super::{Error, FullDuplexMode, SpiMode}; use crate::{ dma::{DescriptorChain, DmaPeripheral, Rx, Tx}, - gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull}, peripheral::{Peripheral, PeripheralRef}, peripherals::spi2::RegisterBlock, private, @@ -121,16 +121,16 @@ where ) -> Spi<'d, T, FullDuplexMode> { crate::into_ref!(spi, sclk, mosi, miso, cs); - sclk.init_input(false, false, private::Internal); + sclk.init_input(Pull::None, private::Internal); sclk.connect_input_to_peripheral(spi.sclk_signal(), private::Internal); - mosi.init_input(false, false, private::Internal); + mosi.init_input(Pull::None, private::Internal); mosi.connect_input_to_peripheral(spi.mosi_signal(), private::Internal); miso.set_to_push_pull_output(private::Internal); miso.connect_peripheral_to_output(spi.miso_signal(), private::Internal); - cs.init_input(false, false, private::Internal); + cs.init_input(Pull::None, private::Internal); cs.connect_input_to_peripheral(spi.cs_signal(), private::Internal); Self::new_internal(spi, mode) diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index b37e4c88dd..30c451cd1a 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -133,7 +133,7 @@ use core::marker::PhantomData; use self::filter::{Filter, FilterType}; use crate::{ - gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::twai0::RegisterBlock, @@ -736,7 +736,7 @@ where .mode() .write(|w| w.reset_mode().set_bit()); - rx_pin.init_input(false, false, crate::private::Internal); + rx_pin.init_input(Pull::None, crate::private::Internal); rx_pin.connect_input_to_peripheral(T::INPUT_SIGNAL, crate::private::Internal); if no_transceiver { diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index bcbe4ca6a5..0f3ee6c4e5 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -131,7 +131,7 @@ use core::marker::PhantomData; use self::config::Config; use crate::{ clock::Clocks, - gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput}, + gpio::{InputSignal, OutputSignal, PeripheralInput, PeripheralOutput, Pull}, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{uart0::RegisterBlock, Interrupt}, @@ -453,7 +453,7 @@ where fn with_rx(self, rx: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rx); - rx.init_input(false, false, Internal); + rx.init_input(Pull::Up, Internal); rx.connect_input_to_peripheral(T::rx_signal(), Internal); self @@ -622,7 +622,7 @@ where /// Configure CTS pin pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); - cts.init_input(false, false, Internal); + cts.init_input(Pull::None, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); self @@ -859,7 +859,7 @@ where /// Configure CTS pin pub fn with_cts(self, cts: impl Peripheral

+ 'd) -> Self { crate::into_ref!(cts); - cts.init_input(false, false, Internal); + cts.init_input(Pull::None, Internal); cts.connect_input_to_peripheral(T::cts_signal(), Internal); self From f8763ae07f9bf0e5fbebcb60a09add82bbfba523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 11:37:38 +0200 Subject: [PATCH 18/21] Don't disable configured output functionality --- esp-hal/src/gpio/mod.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index bc7be5ad50..29917876ce 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -308,6 +308,9 @@ pub trait Pin: Sealed { /// Configure the alternate function fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal); + + /// Enable or disable the GPIO pin output buffer. + fn output_enable(&mut self, enable: bool, _: private::Internal); } /// Common trait implemented by signals which can be used as peripheral inputs @@ -727,6 +730,10 @@ where fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal) { get_io_mux_reg(GPIONUM).modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) }); } + + fn output_enable(&mut self, enable: bool, _: private::Internal) { + self.write_out_en(enable); + } } impl PeripheralSignal for GpioPin @@ -749,13 +756,6 @@ where Self: GpioProperties, { fn init_input(&self, pull: Pull, _: private::Internal) { - let gpio = unsafe { &*GPIO::PTR }; - - self.write_out_en(false); - - gpio.func_out_sel_cfg(GPIONUM as usize) - .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); - self.pull_direction(pull, private::Internal); #[cfg(any(esp32c3, esp32s3))] @@ -916,10 +916,9 @@ where Self: GpioProperties, { fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { - let gpio = unsafe { &*GPIO::PTR }; - self.write_out_en(true); - self.pull_direction(Pull::None, private::Internal); + + let gpio = unsafe { &*GPIO::PTR }; gpio.pin(GPIONUM as usize) .modify(|_, w| w.pad_driver().bit(open_drain)); @@ -1991,6 +1990,7 @@ where /// Set the GPIO to input mode. pub fn set_as_input(&mut self, pull: Pull) { self.pin.init_input(pull, private::Internal); + self.pin.output_enable(false, private::Internal); } /// Get whether the pin input level is high. @@ -2164,6 +2164,12 @@ pub(crate) mod internal { Pin::set_alternate_function(target, alternate, private::Internal) }) } + + fn output_enable(&mut self, enable: bool, _: private::Internal) { + handle_gpio_input!(&mut self.0, target, { + Pin::output_enable(target, enable, private::Internal) + }) + } } impl PeripheralSignal for AnyPin { From 37bab00fad6cb3932e4efe0fd77ab66bd2b0d0f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 16:02:58 +0200 Subject: [PATCH 19/21] Clean up TODO --- esp-hal/src/gpio/interconnect.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index f5f4909fd4..1eba046566 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -70,6 +70,9 @@ impl InputSignal { self } + /// - signal: The input signal to connect to the pin + /// - invert: Configures whether or not to invert the input value + /// - input: The GPIO number to connect to the input signal fn connect(&self, signal: usize, invert: bool, input: u8) { unsafe { &*GPIO::PTR } .func_in_sel_cfg(signal - FUNC_IN_SEL_OFFSET) @@ -175,8 +178,8 @@ impl Sealed for OutputSignal {} impl OutputSignal { pub(crate) fn new(pin: AnyPin) -> Self { Self { - is_inverted: false, pin, + is_inverted: false, } } @@ -191,6 +194,16 @@ impl OutputSignal { self } + /// - signal: The output signal to connect to the pin + /// - invert: Configures whether or not to invert the output value + /// - invert_enable: Configures whether or not to invert the output enable + /// signal + /// - enable_from_gpio: Configures to select the source of output enable + /// signal. + /// - false: Use output enable signal from peripheral + /// - true: Force the output enable signal to be sourced from bit n of + /// GPIO_ENABLE_REG + /// - output: The GPIO number to connect to the output signal fn connect( &self, signal: OutputSignalType, @@ -224,20 +237,6 @@ impl PeripheralSignal for OutputSignal { impl PeripheralOutput for OutputSignal { /// Connect the pin to a peripheral output signal. - // TODO: the following options should be part of the struct: - /// invert: Configures whether or not to invert the output value - /// - /// invert_enable: Configures whether or not to invert the output enable - /// signal - /// - /// enable_from_gpio: Configures to select the source of output enable - /// signal. - /// - false = Use output enable signal from peripheral - /// - true = Force the output enable signal to be sourced from bit n of - /// GPIO_ENABLE_REG - /// - /// force_via_gpio_mux: if true don't use the alternate function even if it - /// matches fn connect_peripheral_to_output(&mut self, signal: gpio::OutputSignal, _: private::Internal) { let af = if self.is_inverted { GPIO_FUNCTION From 381b0a6e87de495b8189ece49fcf997347cd8940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 19:06:02 +0200 Subject: [PATCH 20/21] Tweak docs --- esp-hal/MIGRATING-0.20.md | 2 +- esp-hal/src/gpio/interconnect.rs | 33 +++++++++++++++-- esp-hal/src/gpio/mod.rs | 63 ++++++++++++++++++++++++++------ 3 files changed, 81 insertions(+), 17 deletions(-) diff --git a/esp-hal/MIGRATING-0.20.md b/esp-hal/MIGRATING-0.20.md index c1907594fd..52b1a7a0c4 100644 --- a/esp-hal/MIGRATING-0.20.md +++ b/esp-hal/MIGRATING-0.20.md @@ -48,7 +48,7 @@ You no longer have to spell out the GPIO pin type for `Input`, `Output`, `Output However, if you want to, you can keep using their typed form! ```rust -let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, ErasedPin>` if you want to be explicit about it) +let pin = Input::new(io.gpio0); // pin will have the type `Input<'some>` (or `Input<'some, AnyPin>` if you want to be explicit about it) let pin = Input::new_typed(io.gpio0); // pin will have the type `Input<'some, GpioPin<0>>` ``` diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index 1eba046566..cc9333598c 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -26,7 +26,12 @@ use crate::{ private::{self, Sealed}, }; -/// Multiple input signal can be connected to one pin. +/// A configurable input signal between a peripheral and a GPIO pin. +/// +/// Obtained by calling [`GpioPin::peripheral_input()`], +/// [`super::Flex::peripheral_input()`] or [`super::Input::peripheral_input()`]. +/// +/// Multiple input signals can be connected to one pin. pub struct InputSignal { pin: AnyPin, is_inverted: bool, @@ -60,11 +65,16 @@ impl InputSignal { } /// Inverts the peripheral's input signal. + /// + /// Calling this function multiple times toggles the setting. pub fn invert(&mut self) { self.is_inverted = !self.is_inverted; } - /// Inverts the peripheral's input signal. + /// Consumed the signal and returns a new one that inverts the peripheral's + /// input signal. + /// + /// Calling this function multiple times toggles the setting. pub fn inverted(mut self) -> Self { self.invert(); self @@ -97,6 +107,10 @@ impl PeripheralSignal for InputSignal { impl PeripheralInput for InputSignal { /// Connect the pin to a peripheral input signal. + /// + /// 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, _: private::Internal) { let signal_nr = signal as usize; @@ -156,6 +170,12 @@ impl PeripheralInput for InputSignal { } } +/// A configurable output signal between a peripheral and a GPIO pin. +/// +/// Obtained by calling [`GpioPin::into_peripheral_output()`], +/// [`super::Flex::into_peripheral_output()`] or +/// [`super::Output::into_peripheral_output()`]. +/// /// Multiple pins can be connected to one output signal. pub struct OutputSignal { pin: AnyPin, @@ -184,11 +204,16 @@ impl OutputSignal { } /// Inverts the peripheral's output signal. + /// + /// Calling this function multiple times toggles the setting. pub fn invert(&mut self) { self.is_inverted = !self.is_inverted; } - /// Inverts the peripheral's input signal. + /// Consumed the signal and returns a new one that inverts the peripheral's + /// output signal. + /// + /// Calling this function multiple times toggles the setting. pub fn inverted(mut self) -> Self { self.invert(); self @@ -271,7 +296,7 @@ impl PeripheralOutput for OutputSignal { /// /// Clears the entry in the GPIO matrix / Io mux that associates this output /// pin with a previously connected [signal](`OutputSignal`). Any other - /// outputs connected to the signal remain intact. + /// outputs connected to the peripheral remain intact. fn disconnect_from_peripheral_output( &mut self, signal: gpio::OutputSignal, diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 29917876ce..8965533a3b 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -2,8 +2,8 @@ //! //! ## Overview //! -//! Each pin can be used as a general-purpose I/O, or be connected to an -//! internal peripheral signal. +//! Each pin can be used as a general-purpose I/O, or be connected to one or +//! more internal peripheral signals. //! //! ## Configuration //! @@ -18,7 +18,7 @@ //! provide a common interface for GPIO pins. //! //! To get access to the pins, you first need to convert them into a HAL -//! designed struct from the pac struct `GPIO` and `IO_MUX` using `Io::new`. +//! designed struct from the pac struct `GPIO` and `IO_MUX` using [`Io::new`]. //! //! ### Pin Types //! @@ -29,6 +29,12 @@ //! - [DummyPin] is a useful for cases where peripheral driver requires a pin, //! but real pin cannot be used. //! +//! ### GPIO interconnect +//! +//! Each GPIO can be connected to one output signal and any number of input +//! signals. This allows connections inside of the MCU without allocating and +//! connecting multiple pins for loopback functionality. +//! //! ## Examples //! //! ### Set up a GPIO as an Output @@ -661,7 +667,10 @@ where } } - /// Turns the pin object into a peripheral input. + /// Returns a peripheral [input][interconnect::InputSignal] connected to + /// this pin. + /// + /// The input signal can be passed to peripherals in place of an input pin. #[inline] pub fn peripheral_input(&self) -> interconnect::InputSignal { interconnect::InputSignal::new(self.degrade_internal(private::Internal)) @@ -941,7 +950,11 @@ where }); } - /// Turns the pin object into a peripheral output. + /// Turns the pin object into a peripheral + /// [output][interconnect::OutputSignal]. + /// + /// The output signal can be passed to peripherals in place of an output + /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) @@ -1702,7 +1715,11 @@ where self.pin.set_drive_strength(strength); } - /// Turns the pin object into a peripheral output. + /// Turns the pin object into a peripheral + /// [output][interconnect::OutputSignal]. + /// + /// The output signal can be passed to peripherals in place of an output + /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { self.pin.into_peripheral_output() @@ -1803,7 +1820,10 @@ where self.pin.wakeup_enable(enable, event); } - /// Turns the pin object into a peripheral input. + /// Returns a peripheral [input][interconnect::InputSignal] connected to + /// this pin. + /// + /// The input signal can be passed to peripherals in place of an input pin. #[inline] pub fn peripheral_input(&self) -> interconnect::InputSignal { self.pin.peripheral_input() @@ -1938,7 +1958,11 @@ where self.pin.set_drive_strength(strength); } - /// Turns the pin object into a peripheral output. + /// Turns the pin object into a peripheral + /// [output][interconnect::OutputSignal]. + /// + /// The output signal can be passed to peripherals in place of an output + /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { self.pin.into_peripheral_output() @@ -2042,7 +2066,10 @@ where self.pin.wakeup_enable(enable, event, private::Internal); } - /// Turns the pin object into a peripheral input. + /// Returns a peripheral [input][interconnect::InputSignal] connected to + /// this pin. + /// + /// The input signal can be passed to peripherals in place of an input pin. #[inline] pub fn peripheral_input(&self) -> interconnect::InputSignal { interconnect::InputSignal::new(self.pin.degrade_internal(private::Internal)) @@ -2107,7 +2134,11 @@ where self.pin.set_drive_strength(strength, private::Internal); } - /// Turns the pin object into a peripheral output. + /// Turns the pin object into a peripheral + /// [output][interconnect::OutputSignal]. + /// + /// The output signal can be passed to peripherals in place of an output + /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { interconnect::OutputSignal::new(self.pin.degrade_internal(private::Internal)) @@ -2131,13 +2162,21 @@ pub(crate) mod internal { impl private::Sealed for AnyPin {} impl AnyPin { - /// Turns the pin object into a peripheral output. + /// Returns a peripheral [input][interconnect::InputSignal] connected to + /// this pin. + /// + /// The input signal can be passed to peripherals in place of an input + /// pin. #[inline] pub fn peripheral_input(&self) -> interconnect::InputSignal { handle_gpio_input!(&self.0, target, { target.peripheral_input() }) } - /// Turns the pin object into a peripheral output. + /// Turns the pin object into a peripheral + /// [output][interconnect::OutputSignal]. + /// + /// The output signal can be passed to peripherals in place of an output + /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { handle_gpio_output!(self.0, target, { target.into_peripheral_output() }) From 001e2350ff695949461c94a44f5c3025562339e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 10 Sep 2024 21:33:25 +0200 Subject: [PATCH 21/21] Clean up examples --- examples/src/bin/blinky_erased_pins.rs | 4 ++-- examples/src/bin/embassy_multicore.rs | 4 ++-- examples/src/bin/embassy_multicore_interrupt.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/src/bin/blinky_erased_pins.rs b/examples/src/bin/blinky_erased_pins.rs index 34cf9c0fc8..48d9309f08 100644 --- a/examples/src/bin/blinky_erased_pins.rs +++ b/examples/src/bin/blinky_erased_pins.rs @@ -14,7 +14,7 @@ use esp_backtrace as _; use esp_hal::{ delay::Delay, - gpio::{AnyPin, Input, Io, Level, Output, Pin, Pull}, + gpio::{Input, Io, Level, Output, Pin, Pull}, prelude::*, }; @@ -47,7 +47,7 @@ fn main() -> ! { } } -fn toggle_pins(leds: &mut [Output], button: &Input) { +fn toggle_pins(leds: &mut [Output], button: &Input) { for pin in leds.iter_mut() { pin.toggle(); } diff --git a/examples/src/bin/embassy_multicore.rs b/examples/src/bin/embassy_multicore.rs index 585decaf98..8efe9ff3ae 100644 --- a/examples/src/bin/embassy_multicore.rs +++ b/examples/src/bin/embassy_multicore.rs @@ -21,7 +21,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{AnyPin, Io, Level, Output, Pin}, + gpio::{Io, Level, Output, Pin}, timer::{timg::TimerGroup, ErasedTimer}, }; use esp_hal_embassy::Executor; @@ -34,7 +34,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: Output<'static, AnyPin>, + mut led: Output<'static>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize); diff --git a/examples/src/bin/embassy_multicore_interrupt.rs b/examples/src/bin/embassy_multicore_interrupt.rs index ac1881a4b6..7b99a85fe8 100644 --- a/examples/src/bin/embassy_multicore_interrupt.rs +++ b/examples/src/bin/embassy_multicore_interrupt.rs @@ -20,7 +20,7 @@ use esp_backtrace as _; use esp_hal::{ cpu_control::{CpuControl, Stack}, get_core, - gpio::{AnyPin, Io, Level, Output, Pin}, + gpio::{Io, Level, Output, Pin}, interrupt::{software::SoftwareInterruptControl, Priority}, prelude::*, timer::{timg::TimerGroup, ErasedTimer}, @@ -35,7 +35,7 @@ static mut APP_CORE_STACK: Stack<8192> = Stack::new(); /// duration of time. #[embassy_executor::task] async fn control_led( - mut led: Output<'static, AnyPin>, + mut led: Output<'static>, control: &'static Signal, ) { println!("Starting control_led() on core {}", get_core() as usize);