From b5dd5aed17495ee209610c227826db29f199d1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 16 Sep 2024 12:14:34 +0200 Subject: [PATCH] Gpio cleanup (#2157) * InterruptStatusRegisterAccess * GpioRegisterAccess * Remove GpioProperties * Hide private methods * Simplify the analog macro * Fix typo * Remove unused NMI status read * Hide ISRA * Fix macro syntax * Simplify rtc_pins macro * Fix type name --- esp-hal/src/gpio/etm.rs | 12 +- esp-hal/src/gpio/interconnect.rs | 27 +- esp-hal/src/gpio/mod.rs | 616 +++++++++++++------------- esp-hal/src/rtc_cntl/sleep/esp32c6.rs | 7 +- esp-hal/src/rtc_cntl/sleep/esp32s3.rs | 14 +- esp-hal/src/soc/esp32/gpio.rs | 132 +++--- esp-hal/src/soc/esp32c2/gpio.rs | 25 +- esp-hal/src/soc/esp32c3/gpio.rs | 26 +- esp-hal/src/soc/esp32c6/gpio.rs | 25 +- esp-hal/src/soc/esp32h2/gpio.rs | 25 +- esp-hal/src/soc/esp32s2/gpio.rs | 126 +++--- esp-hal/src/soc/esp32s3/gpio.rs | 142 +++--- 12 files changed, 525 insertions(+), 652 deletions(-) diff --git a/esp-hal/src/gpio/etm.rs b/esp-hal/src/gpio/etm.rs index 8e4da7b71..bc5958256 100644 --- a/esp-hal/src/gpio/etm.rs +++ b/esp-hal/src/gpio/etm.rs @@ -154,7 +154,7 @@ impl GpioEtmEventChannel { pin.init_input(pin_config.pull, private::Internal); - enable_event_channel(C, pin.number(private::Internal)); + enable_event_channel(C, pin.number()); GpioEtmEventChannelRising { _pin: pin } } @@ -171,7 +171,7 @@ impl GpioEtmEventChannel { pin.init_input(pin_config.pull, private::Internal); - enable_event_channel(C, pin.number(private::Internal)); + enable_event_channel(C, pin.number()); GpioEtmEventChannelFalling { _pin: pin } } @@ -188,7 +188,7 @@ impl GpioEtmEventChannel { pin.init_input(pin_config.pull, private::Internal); - enable_event_channel(C, pin.number(private::Internal)); + enable_event_channel(C, pin.number()); GpioEtmEventChannelAny { _pin: pin } } } @@ -312,7 +312,7 @@ impl GpioEtmTaskChannel { pin.set_to_push_pull_output(private::Internal); } - enable_task_channel(C, pin.number(private::Internal)); + enable_task_channel(C, pin.number()); GpioEtmTaskSet { _pin: pin } } @@ -335,7 +335,7 @@ impl GpioEtmTaskChannel { pin.set_to_push_pull_output(private::Internal); } - enable_task_channel(C, pin.number(private::Internal)); + enable_task_channel(C, pin.number()); GpioEtmTaskClear { _pin: pin } } @@ -358,7 +358,7 @@ impl GpioEtmTaskChannel { pin.set_to_push_pull_output(private::Internal); } - enable_task_channel(C, pin.number(private::Internal)); + enable_task_channel(C, pin.number()); GpioEtmTaskToggle { _pin: pin } } } diff --git a/esp-hal/src/gpio/interconnect.rs b/esp-hal/src/gpio/interconnect.rs index e046694ac..4919dfcad 100644 --- a/esp-hal/src/gpio/interconnect.rs +++ b/esp-hal/src/gpio/interconnect.rs @@ -6,7 +6,6 @@ use crate::{ AlternateFunction, AnyPin, GpioPin, - GpioProperties, InputPin, Level, NoPin, @@ -117,8 +116,7 @@ impl PeripheralInput for InputSignal { let af = if self.is_inverted { GPIO_FUNCTION } else { - self.pin - .input_signals(private::Internal) + self.input_signals(private::Internal) .into_iter() .position(|s| s == Some(signal)) .ok_or(()) @@ -133,11 +131,7 @@ impl PeripheralInput for InputSignal { 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), - ); + self.connect(signal_nr, self.is_inverted, self.pin.number()); } } @@ -159,11 +153,14 @@ impl PeripheralInput for InputSignal { .modify(|_, w| w.sel().clear_bit()); } + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + PeripheralInput::input_signals(&self.pin, private::Internal) + } + delegate::delegate! { to self.pin { 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); fn enable_input_in_sleep_mode(&mut self, on: bool, _internal: private::Internal); } @@ -266,8 +263,7 @@ impl PeripheralOutput for OutputSignal { let af = if self.is_inverted { GPIO_FUNCTION } else { - self.pin - .output_signals(private::Internal) + self.output_signals(private::Internal) .into_iter() .position(|s| s == Some(signal)) .ok_or(()) @@ -288,7 +284,7 @@ impl PeripheralOutput for OutputSignal { self.is_inverted, false, false, - self.pin.number(private::Internal), + self.pin.number(), ); } @@ -310,6 +306,10 @@ impl PeripheralOutput for OutputSignal { .modify(|_, w| w.sel().clear_bit()); } + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + PeripheralOutput::output_signals(&self.pin, private::Internal) + } + delegate::delegate! { to self.pin { fn set_to_open_drain_output(&mut self, _internal: private::Internal); @@ -322,7 +322,6 @@ impl PeripheralOutput for OutputSignal { 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 is_set_high(&self, _internal: private::Internal) -> bool; - fn output_signals(&self, _internal: private::Internal) -> [Option; 6]; } } } @@ -372,7 +371,7 @@ impl From for AnyInputSignal { impl From> for AnyInputSignal where - GpioPin: InputPin + GpioProperties, + GpioPin: InputPin, { fn from(pin: GpioPin) -> Self { Self(AnyInputSignalInner::Input(pin.peripheral_input())) diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 45505445f..9168914dd 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -299,7 +299,7 @@ pub trait RtcPinWithResistors: RtcPin { /// Common trait implemented by pins pub trait Pin: Sealed { /// GPIO number - fn number(&self, _: private::Internal) -> u8; + fn number(&self) -> u8; /// Type-erase (degrade) this pin into an AnyPin. /// @@ -310,110 +310,158 @@ pub trait Pin: Sealed { where Self: Sized, { - self.degrade_internal(private::Internal) + self.degrade_pin(private::Internal) } #[doc(hidden)] - fn degrade_internal(&self, _: private::Internal) -> AnyPin; + fn degrade_pin(&self, _: private::Internal) -> AnyPin; /// Enable/disable sleep-mode - fn sleep_mode(&mut self, on: bool, _: private::Internal); + #[doc(hidden)] + fn sleep_mode(&mut self, on: bool, _: private::Internal) { + get_io_mux_reg(self.number()).modify(|_, w| w.slp_sel().bit(on)); + } /// Configure the alternate function - fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal); + #[doc(hidden)] + fn set_alternate_function(&mut self, alternate: AlternateFunction, _: private::Internal) { + get_io_mux_reg(self.number()).modify(|_, w| unsafe { w.mcu_sel().bits(alternate as u8) }); + } /// Enable or disable the GPIO pin output buffer. - fn output_enable(&mut self, enable: bool, _: private::Internal); + #[doc(hidden)] + fn output_enable(&self, enable: bool, _: private::Internal) { + let bank = self.gpio_bank(private::Internal); + let mask = 1 << (self.number() % 32); + if enable { + bank.write_out_en_set(mask); + } else { + bank.write_out_en_clear(mask); + } + } + + #[doc(hidden)] + fn output_signals(&self, _: private::Internal) -> [Option; 6]; + + #[doc(hidden)] + fn input_signals(&self, _: private::Internal) -> [Option; 6]; + + #[doc(hidden)] + fn gpio_bank(&self, _: private::Internal) -> GpioRegisterAccess; } /// Common trait implemented by signals which can be used as peripheral inputs /// or outputs. pub trait PeripheralSignal: Sealed { /// Configure the pullup and pulldown resistors + #[doc(hidden)] fn pull_direction(&self, pull: Pull, _: private::Internal); } /// Trait implemented by pins which can be used as peripheral inputs. pub trait PeripheralInput: PeripheralSignal { /// Init as input with the given pull-up/pull-down + #[doc(hidden)] fn init_input(&self, pull: Pull, _: private::Internal); /// Enable input for the pin + #[doc(hidden)] fn enable_input(&mut self, on: bool, _: private::Internal); /// Enable input in sleep mode for the pin + #[doc(hidden)] fn enable_input_in_sleep_mode(&mut self, on: bool, _: private::Internal); /// The current state of the input + #[doc(hidden)] fn is_input_high(&self, _: private::Internal) -> bool; /// Returns the list of input signals that can be connected to this pin /// using IO_MUX. + #[doc(hidden)] fn input_signals(&self, _: private::Internal) -> [Option; 6]; /// Connect the pin to a peripheral. + #[doc(hidden)] fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal); /// Disconnect the pin from a peripheral. + #[doc(hidden)] fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal); } /// Trait implemented by pins which can be used as peripheral outputs. pub trait PeripheralOutput: PeripheralSignal { /// Configure open-drain mode + #[doc(hidden)] fn set_to_open_drain_output(&mut self, _: private::Internal); /// Configure output mode + #[doc(hidden)] fn set_to_push_pull_output(&mut self, _: private::Internal); /// Enable/disable the pin as output + #[doc(hidden)] fn enable_output(&mut self, on: bool, _: private::Internal); /// Set the pin's level to high or low + #[doc(hidden)] fn set_output_high(&mut self, on: bool, _: private::Internal); /// Configure the [DriveStrength] of the pin + #[doc(hidden)] fn set_drive_strength(&mut self, strength: DriveStrength, _: private::Internal); /// Enable/disable open-drain mode + #[doc(hidden)] fn enable_open_drain(&mut self, on: bool, _: private::Internal); /// Enable/disable output in sleep mode + #[doc(hidden)] fn enable_output_in_sleep_mode(&mut self, on: bool, _: private::Internal); /// Configure internal pull-up resistor in sleep mode + #[doc(hidden)] fn internal_pull_up_in_sleep_mode(&mut self, on: bool, _: private::Internal); /// Configure internal pull-down resistor in sleep mode + #[doc(hidden)] fn internal_pull_down_in_sleep_mode(&mut self, on: bool, _: private::Internal); /// Is the output set to high + #[doc(hidden)] fn is_set_high(&self, _: private::Internal) -> bool; /// Returns the list of output signals that can be connected to this pin /// using IO_MUX. + #[doc(hidden)] fn output_signals(&self, _: private::Internal) -> [Option; 6]; /// Connect the pin to a peripheral. + #[doc(hidden)] fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal); /// Disconnect the pin from a peripheral. + #[doc(hidden)] 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 + PeripheralInput { /// Listen for interrupts + #[doc(hidden)] 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 + #[doc(hidden)] fn is_listening(&self, _: private::Internal) -> bool { - is_listening(self.number(private::Internal)) + is_listening(self.number()) } /// Listen for interrupts + #[doc(hidden)] fn listen_with_options( &mut self, event: Event, @@ -421,18 +469,49 @@ pub trait InputPin: Pin + PeripheralInput { nmi_enable: bool, wake_up_from_light_sleep: bool, _: private::Internal, - ); + ) { + if wake_up_from_light_sleep { + match event { + Event::AnyEdge | Event::RisingEdge | Event::FallingEdge => { + panic!("Edge triggering is not supported for wake-up from light sleep"); + } + _ => {} + } + } + + set_int_enable( + self.number(), + gpio_intr_enable(int_enable, nmi_enable), + event as u8, + wake_up_from_light_sleep, + ) + } /// Stop listening for interrupts - fn unlisten(&mut self, _: private::Internal); + #[doc(hidden)] + fn unlisten(&mut self, _: private::Internal) { + unsafe { + (*GPIO::PTR) + .pin(self.number() as usize) + .modify(|_, w| w.int_ena().bits(0).int_type().bits(0).int_ena().bits(0)); + } + } /// Checks if the interrupt status bit for this Pin is set - fn is_interrupt_set(&self, _: private::Internal) -> bool; + #[doc(hidden)] + fn is_interrupt_set(&self, _: private::Internal) -> bool { + self.gpio_bank(private::Internal).read_interrupt_status() & 1 << (self.number() % 32) != 0 + } /// Clear the interrupt status bit for this Pin - fn clear_interrupt(&mut self, _: private::Internal); + #[doc(hidden)] + fn clear_interrupt(&mut self, _: private::Internal) { + self.gpio_bank(private::Internal) + .write_interrupt_status_clear(1 << (self.number() % 32)); + } /// Enable this pin as a wake up source + #[doc(hidden)] fn wakeup_enable(&mut self, enable: bool, event: WakeEvent, _: private::Internal) { self.listen_with_options(event.into(), false, false, enable, private::Internal); } @@ -444,109 +523,106 @@ pub trait OutputPin: Pin + PeripheralOutput {} /// Trait implemented by pins which can be used as analog pins pub trait AnalogPin: Pin { /// Configure the pin for analog operation + #[doc(hidden)] fn set_analog(&self, _: private::Internal); } /// Trait implemented by pins which can be used as Touchpad pins pub trait TouchPin: Pin { /// Configure the pin for analog operation + #[doc(hidden)] fn set_touch(&self, _: private::Internal); /// Reads the pin's touch measurement register + #[doc(hidden)] fn get_touch_measurement(&self, _: private::Internal) -> u16; /// Maps the pin nr to the touch pad nr + #[doc(hidden)] fn get_touch_nr(&self, _: private::Internal) -> u8; /// Set a pins touch threshold for interrupts. + #[doc(hidden)] fn set_threshold(&self, threshold: u16, _: private::Internal); } #[doc(hidden)] -pub trait InterruptStatusRegisterAccess { - fn pro_cpu_interrupt_status_read() -> u32; +#[derive(Clone, Copy)] +pub enum GpioRegisterAccess { + Bank0, + #[cfg(any(esp32, esp32s2, esp32s3))] + Bank1, +} - fn pro_cpu_nmi_status_read() -> u32; - - fn app_cpu_interrupt_status_read() -> u32 { - Self::pro_cpu_interrupt_status_read() - } - - fn app_cpu_nmi_status_read() -> u32 { - Self::pro_cpu_nmi_status_read() - } - - fn interrupt_status_read() -> u32 { - match crate::get_core() { - crate::Cpu::ProCpu => Self::pro_cpu_interrupt_status_read(), - #[cfg(multi_core)] - crate::Cpu::AppCpu => Self::app_cpu_interrupt_status_read(), +impl GpioRegisterAccess { + fn write_out_en_clear(self, word: u32) { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::write_out_en_clear(word), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::write_out_en_clear(word), } } - fn nmi_status_read() -> u32 { - match crate::get_core() { - crate::Cpu::ProCpu => Self::pro_cpu_nmi_status_read(), - #[cfg(multi_core)] - crate::Cpu::AppCpu => Self::app_cpu_nmi_status_read(), + fn write_out_en_set(self, word: u32) { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::write_out_en_set(word), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::write_out_en_set(word), + } + } + + fn read_input(self) -> u32 { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::read_input(), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::read_input(), + } + } + + fn read_output(self) -> u32 { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::read_output(), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::read_output(), + } + } + + fn read_interrupt_status(self) -> u32 { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::read_interrupt_status(), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::read_interrupt_status(), + } + } + + fn write_interrupt_status_clear(self, word: u32) { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::write_interrupt_status_clear(word), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::write_interrupt_status_clear(word), + } + } + + fn write_output_set(self, word: u32) { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::write_output_set(word), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::write_output_set(word), + } + } + + fn write_output_clear(self, word: u32) { + match self { + Self::Bank0 => Bank0GpioRegisterAccess::write_output_clear(word), + #[cfg(any(esp32, esp32s2, esp32s3))] + Self::Bank1 => Bank1GpioRegisterAccess::write_output_clear(word), } } } -#[doc(hidden)] -pub struct InterruptStatusRegisterAccessBank0; +struct Bank0GpioRegisterAccess; -#[doc(hidden)] -pub struct InterruptStatusRegisterAccessBank1; - -#[doc(hidden)] -pub trait InterruptStatusRegisters -where - RegisterAccess: InterruptStatusRegisterAccess, -{ - fn pro_cpu_interrupt_status_read() -> u32 { - RegisterAccess::pro_cpu_interrupt_status_read() - } - - fn pro_cpu_nmi_status_read() -> u32 { - RegisterAccess::pro_cpu_nmi_status_read() - } - - fn app_cpu_interrupt_status_read() -> u32 { - RegisterAccess::app_cpu_interrupt_status_read() - } - - fn app_cpu_nmi_status_read() -> u32 { - RegisterAccess::app_cpu_nmi_status_read() - } -} - -#[doc(hidden)] -pub struct Bank0GpioRegisterAccess; - -#[doc(hidden)] -pub struct Bank1GpioRegisterAccess; - -#[doc(hidden)] -pub trait BankGpioRegisterAccess { - fn write_out_en_clear(word: u32); - - fn write_out_en_set(word: u32); - - fn read_input() -> u32; - - fn read_output() -> u32; - - fn read_interrupt_status() -> u32; - - fn write_interrupt_status_clear(word: u32); - - fn write_output_set(word: u32); - - fn write_output_clear(word: u32); -} - -impl BankGpioRegisterAccess for Bank0GpioRegisterAccess { +impl Bank0GpioRegisterAccess { fn write_out_en_clear(word: u32) { unsafe { &*GPIO::PTR } .enable_w1tc() @@ -590,8 +666,11 @@ impl BankGpioRegisterAccess for Bank0GpioRegisterAccess { } } -#[cfg(not(any(esp32c2, esp32c3, esp32c6, esp32h2)))] -impl BankGpioRegisterAccess for Bank1GpioRegisterAccess { +#[cfg(any(esp32, esp32s2, esp32s3))] +struct Bank1GpioRegisterAccess; + +#[cfg(any(esp32, esp32s2, esp32s3))] +impl Bank1GpioRegisterAccess { fn write_out_en_clear(word: u32) { unsafe { &*GPIO::PTR } .enable1_w1tc() @@ -635,23 +714,12 @@ impl BankGpioRegisterAccess for Bank1GpioRegisterAccess { } } -#[doc(hidden)] -pub trait BooleanType {} - -#[doc(hidden)] -pub struct True {} -impl BooleanType for True {} - -#[doc(hidden)] -pub struct False {} -impl BooleanType for False {} - /// GPIO pin pub struct GpioPin; impl GpioPin where - Self: GpioProperties, + Self: Pin, { pub(crate) fn new() -> Self { Self @@ -666,21 +734,13 @@ where Self::new() } - fn write_out_en(&self, enable: bool) { - if enable { - ::Bank::write_out_en_set(1 << (GPIONUM % 32)); - } else { - ::Bank::write_out_en_clear(1 << (GPIONUM % 32)); - } - } - /// 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)) + interconnect::InputSignal::new(self.degrade_pin(private::Internal)) } } @@ -716,7 +776,7 @@ fn disable_usb_pads(gpionum: u8) { impl Peripheral for GpioPin where - Self: GpioProperties, + Self: Pin, { type P = GpioPin; @@ -725,36 +785,11 @@ where } } -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) -> AnyPin { - 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 output_enable(&mut self, enable: bool, _: private::Internal) { - self.write_out_en(enable); - } -} +impl private::Sealed for GpioPin {} impl PeripheralSignal for GpioPin where - Self: GpioProperties, + Self: Pin, { fn pull_direction(&self, pull: Pull, _: private::Internal) { let pull_up = pull == Pull::Up; @@ -769,7 +804,7 @@ where impl PeripheralInput for GpioPin where - Self: GpioProperties, + Self: Pin, { fn init_input(&self, pull: Pull, _: private::Internal) { self.pull_direction(pull, private::Internal); @@ -796,11 +831,11 @@ where } fn is_input_high(&self, _: private::Internal) -> bool { - ::Bank::read_input() & (1 << (GPIONUM % 32)) != 0 + self.gpio_bank(private::Internal).read_input() & (1 << (GPIONUM % 32)) != 0 } fn input_signals(&self, _: private::Internal) -> [Option; 6] { - ::input_signals() + ::input_signals(self, private::Internal) } fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { @@ -814,55 +849,9 @@ where } } -impl InputPin for GpioPin -where - Self: GpioProperties, -{ - fn listen_with_options( - &mut self, - event: Event, - int_enable: bool, - nmi_enable: bool, - wake_up_from_light_sleep: bool, - _: private::Internal, - ) { - if wake_up_from_light_sleep { - match event { - Event::AnyEdge | Event::RisingEdge | Event::FallingEdge => { - panic!("Edge triggering is not supported for wake-up from light sleep"); - } - _ => {} - } - } - - set_int_enable( - GPIONUM, - gpio_intr_enable(int_enable, nmi_enable), - event as u8, - wake_up_from_light_sleep, - ) - } - - fn unlisten(&mut self, _: private::Internal) { - unsafe { - (*GPIO::PTR) - .pin(GPIONUM as usize) - .modify(|_, w| w.int_ena().bits(0).int_type().bits(0).int_ena().bits(0)); - } - } - - fn is_interrupt_set(&self, _: private::Internal) -> bool { - ::Bank::read_interrupt_status() & 1 << (GPIONUM % 32) != 0 - } - - fn clear_interrupt(&mut self, _: private::Internal) { - ::Bank::write_interrupt_status_clear(1 << (GPIONUM % 32)); - } -} - impl PeripheralOutput for GpioPin where - Self: GpioProperties, + Self: OutputPin + Pin, { fn set_to_open_drain_output(&mut self, _: private::Internal) { self.init_output(GPIO_FUNCTION, true); @@ -873,14 +862,16 @@ where } fn enable_output(&mut self, on: bool, _: private::Internal) { - self.write_out_en(on); + self.output_enable(on, private::Internal); } fn set_output_high(&mut self, high: bool, _: private::Internal) { + let bank = self.gpio_bank(private::Internal); + let mask = 1 << (GPIONUM % 32); if high { - ::Bank::write_output_set(1 << (GPIONUM % 32)); + bank.write_output_set(mask); } else { - ::Bank::write_output_clear(1 << (GPIONUM % 32)); + bank.write_output_clear(mask); } } @@ -907,32 +898,30 @@ where } fn is_set_high(&self, _: private::Internal) -> bool { - ::Bank::read_output() & (1 << (GPIONUM % 32)) != 0 + self.gpio_bank(private::Internal).read_output() & (1 << (GPIONUM % 32)) != 0 } fn output_signals(&self, _: private::Internal) -> [Option; 6] { - ::output_signals() + ::output_signals(self, private::Internal) } fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { - self.degrade_internal(private::Internal) + self.degrade_pin(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) + self.degrade_pin(private::Internal) .disconnect_from_peripheral_output(signal, private::Internal); } } -impl OutputPin for GpioPin where Self: GpioProperties {} - impl GpioPin where - Self: GpioProperties, + Self: OutputPin, { fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { - self.write_out_en(true); + self.output_enable(true, private::Internal); let gpio = unsafe { &*GPIO::PTR }; @@ -964,7 +953,7 @@ where /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { - interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + interconnect::OutputSignal::new(self.degrade_pin(private::Internal)) } } @@ -1044,57 +1033,36 @@ fn on_pin_irq(pin_nr: u8) { asynch::PIN_WAKERS[pin_nr as usize].wake(); // wake task } -#[doc(hidden)] -pub trait GpioProperties { - type Bank: BankGpioRegisterAccess; - type InterruptStatus: InterruptStatusRegisterAccess; - - type IsOutput: BooleanType; - type IsAnalog: BooleanType; - type IsTouch: BooleanType; - - fn degrade_pin(&self, _: private::Internal) -> AnyPin; - fn output_signals() -> [Option; 6]; - fn input_signals() -> [Option; 6]; -} - #[doc(hidden)] #[macro_export] macro_rules! if_output_pin { - (InputOnlyAnalog, { $($then:tt)* } else { $($else:tt)* } ) => { $($else)* }; (InputOutputAnalog, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; (InputOutputAnalogTouch, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; (InputOutput, { $($then:tt)* } else { $($else:tt)* } ) => { $($then)* }; + ($other:ident, { $($then:tt)* } else { $($else:tt)* } ) => { $($else)* }; } pub(crate) use if_output_pin; #[doc(hidden)] #[macro_export] -macro_rules! pin_types { - (InputOnly) => { - type IsOutput = $crate::gpio::False; - type IsAnalog = $crate::gpio::False; - type IsTouch = $crate::gpio::False; +macro_rules! io_types { + (InputOnly, $gpionum:literal) => { + impl $crate::gpio::InputPin for GpioPin<$gpionum> {} }; - (InputOnlyAnalog) => { - type IsOutput = $crate::gpio::False; - type IsAnalog = $crate::gpio::True; - type IsTouch = $crate::gpio::False; + (InputOnlyAnalog, $gpionum:literal) => { + impl $crate::gpio::InputPin for GpioPin<$gpionum> {} }; - (InputOutput) => { - type IsOutput = $crate::gpio::True; - type IsAnalog = $crate::gpio::False; - type IsTouch = $crate::gpio::False; + (InputOutput, $gpionum:literal) => { + impl $crate::gpio::InputPin for GpioPin<$gpionum> {} + impl $crate::gpio::OutputPin for GpioPin<$gpionum> {} }; - (InputOutputAnalog) => { - type IsOutput = $crate::gpio::True; - type IsAnalog = $crate::gpio::True; - type IsTouch = $crate::gpio::False; + (InputOutputAnalog, $gpionum:literal) => { + impl $crate::gpio::InputPin for GpioPin<$gpionum> {} + impl $crate::gpio::OutputPin for GpioPin<$gpionum> {} }; - (InputOutputAnalogTouch) => { - type IsOutput = $crate::gpio::True; - type IsAnalog = $crate::gpio::True; - type IsTouch = $crate::gpio::True; + (InputOutputAnalogTouch, $gpionum:literal) => { + impl $crate::gpio::InputPin for GpioPin<$gpionum> {} + impl $crate::gpio::OutputPin for GpioPin<$gpionum> {} }; } @@ -1112,29 +1080,41 @@ macro_rules! gpio { )+ ) => { paste::paste! { + /// Pins available on this chip + pub struct Pins { + $( + #[doc = concat!("GPIO pin number ", $gpionum, ".")] + pub [< gpio $gpionum >] : GpioPin<$gpionum>, + )+ + } + impl GPIO { pub(crate) fn pins(self) -> Pins { Pins { $( - [< gpio $gpionum >]: { - GpioPin::new() - }, + [< gpio $gpionum >]: GpioPin::new(), )+ } } } $( - impl $crate::gpio::GpioProperties for GpioPin<$gpionum> { - type Bank = $crate::gpio::[< Bank $bank GpioRegisterAccess >]; - type InterruptStatus = $crate::gpio::[< InterruptStatusRegisterAccessBank $bank >]; - $crate::pin_types!($type); + $crate::io_types!($type, $gpionum); + + impl $crate::gpio::Pin for GpioPin<$gpionum> { + fn number(&self) -> u8 { + $gpionum + } fn degrade_pin(&self, _: $crate::private::Internal) -> AnyPin { AnyPin($crate::gpio::AnyPinInner::[< Gpio $gpionum >](unsafe { Self::steal() })) } - fn output_signals() -> [Option; 6]{ + fn gpio_bank(&self, _: $crate::private::Internal) -> $crate::gpio::GpioRegisterAccess { + $crate::gpio::GpioRegisterAccess::[] + } + + fn output_signals(&self, _: $crate::private::Internal) -> [Option; 6]{ #[allow(unused_mut)] let mut output_signals = [None; 6]; @@ -1146,7 +1126,7 @@ macro_rules! gpio { output_signals } - fn input_signals() -> [Option; 6] { + fn input_signals(&self, _: $crate::private::Internal) -> [Option; 6] { #[allow(unused_mut)] let mut input_signals = [None; 6]; @@ -1161,14 +1141,6 @@ macro_rules! gpio { } )+ - /// Pins available on this chip - pub struct Pins { - $( - #[doc = concat!("GPIO pin number ", $gpionum, ".")] - pub [< gpio $gpionum >] : GpioPin<$gpionum>, - )+ - } - pub(crate) enum AnyPinInner { $( [](GpioPin<$gpionum>), @@ -1236,8 +1208,10 @@ macro_rules! gpio { #[doc(hidden)] #[macro_export] macro_rules! rtc_pins { + ( @ignore $rue:literal ) => {}; + ( - $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat, $hold:ident $(, $rue:ident, $rde:ident)? + $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat, $hold:ident $(, $rue:literal)? ) => { impl $crate::gpio::RtcPin for GpioPin<$pin_num> { @@ -1267,22 +1241,28 @@ macro_rules! rtc_pins { fn rtcio_pad_hold(&mut self, enable: bool) { let rtc_ctrl = unsafe { &*$crate::peripherals::LPWR::PTR }; - #[cfg(esp32)] - rtc_ctrl.hold_force().modify(|_, w| w.$hold().bit(enable)); + cfg_if::cfg_if! { + if #[cfg(esp32)] { + let pad_hold = rtc_ctrl.hold_force(); + } else { + let pad_hold = rtc_ctrl.pad_hold(); + } + }; - #[cfg(not(esp32))] - rtc_ctrl.pad_hold().modify(|_, w| w.$hold().bit(enable)); + pad_hold.modify(|_, w| w.$hold().bit(enable)); } } $( + // FIXME: replace with $(ignore($rue)) once stable + $crate::rtc_pins!(@ignore $rue); impl $crate::gpio::RtcPinWithResistors for GpioPin<$pin_num> { fn rtcio_pullup(&mut self, enable: bool) { let rtcio = unsafe { &*$crate::peripherals::RTC_IO::PTR }; paste::paste! { - rtcio.$pin_reg.modify(|_, w| w.$rue().bit([< enable >])); + rtcio.$pin_reg.modify(|_, w| w.[< $prefix rue >]().bit([< enable >])); } } @@ -1290,7 +1270,7 @@ macro_rules! rtc_pins { let rtcio = unsafe { &*$crate::peripherals::RTC_IO::PTR }; paste::paste! { - rtcio.$pin_reg.modify(|_, w| w.$rde().bit([< enable >])); + rtcio.$pin_reg.modify(|_, w| w.[< $prefix rde >]().bit([< enable >])); } } } @@ -1298,10 +1278,10 @@ macro_rules! rtc_pins { }; ( - $( ( $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat, $hold:ident $(, $rue:ident, $rde:ident)? ) )+ + $( ( $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat, $hold:ident $(, $rue:literal )? ) )+ ) => { $( - $crate::gpio::rtc_pins!($pin_num, $rtc_pin, $pin_reg, $prefix, $hold $(, $rue, $rde)?); + $crate::gpio::rtc_pins!($pin_num, $rtc_pin, $pin_reg, $prefix, $hold $(, $rue )?); )+ #[doc(hidden)] @@ -1323,14 +1303,14 @@ macro_rules! rtc_pins { #[doc(hidden)] #[macro_export] macro_rules! handle_rtcio_with_resistors { - (@ignore $a:ident, $b:ident) => {}; + (@ignore $a:tt) => {}; ($this:expr, $inner:ident, $code:tt) => { match $this { $( $( paste::paste! { AnyPinInner::[]($inner) } => { // FIXME: replace with $(ignore($rue)) once stable - handle_rtcio_with_resistors!(@ignore $rue, $rde); + handle_rtcio_with_resistors!(@ignore $rue); $code }, )? @@ -1349,25 +1329,22 @@ macro_rules! rtc_pins { #[doc(hidden)] #[macro_export] macro_rules! rtc_pins { - ( - $pin_num:expr - ) => { + ( $pin_num:expr ) => { impl $crate::gpio::RtcPin for GpioPin<$pin_num> { unsafe fn apply_wakeup(&mut self, wakeup: bool, level: u8) { let rtc_cntl = unsafe { &*$crate::peripherals::RTC_CNTL::ptr() }; cfg_if::cfg_if! { if #[cfg(esp32c2)] { - paste::paste! { - rtc_cntl.cntl_gpio_wakeup().modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup)); - rtc_cntl.cntl_gpio_wakeup().modify(|_, w| w.[< gpio_pin $pin_num _int_type >]().bits(level)); - } + let gpio_wakeup = rtc_cntl.cntl_gpio_wakeup(); } else { - paste::paste! { - rtc_cntl.gpio_wakeup().modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup)); - rtc_cntl.gpio_wakeup().modify(|_, w| w.[< gpio_pin $pin_num _int_type >]().bits(level)); - } + let gpio_wakeup = rtc_cntl.gpio_wakeup(); } - }; + } + + paste::paste! { + gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _wakeup_enable >]().bit(wakeup)); + gpio_wakeup.modify(|_, w| w.[< gpio_pin $pin_num _int_type >]().bits(level)); + } } fn rtcio_pad_hold(&mut self, enable: bool) { @@ -1436,20 +1413,17 @@ pub fn enable_iomux_clk_gate() { #[doc(hidden)] #[macro_export] macro_rules! analog { + (@ignore $rue:literal) => {}; ( $( ( - $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, - $mux_sel:ident, $fun_sel:ident, $fun_ie:ident $(, $rue:ident, $rde:ident)? + $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat $(, $rue:literal)? ) )+ ) => { $( #[cfg(any(adc, dac))] - impl $crate::gpio::AnalogPin for GpioPin<$pin_num> - where - Self: $crate::gpio::GpioProperties, - { + impl $crate::gpio::AnalogPin for GpioPin<$pin_num> { /// Configures the pin for analog mode. fn set_analog(&self, _: $crate::private::Internal) { let rtcio = unsafe{ &*$crate::peripherals::RTC_IO::ptr() }; @@ -1461,7 +1435,7 @@ macro_rules! analog { // handle indexed pins. paste::paste! { // disable input - rtcio.$pin_reg.modify(|_,w| w.$fun_ie().bit([< false >])); + rtcio.$pin_reg.modify(|_,w| w.[<$prefix fun_ie>]().bit(false)); // disable output rtcio.enable_w1tc().write(|w| unsafe { w.enable_w1tc().bits(1 << $rtc_pin) }); @@ -1470,18 +1444,20 @@ macro_rules! analog { rtcio.pin($rtc_pin).modify(|_,w| w.pad_driver().bit(false)); rtcio.$pin_reg.modify(|_,w| { - w.$fun_ie().clear_bit(); + w.[<$prefix fun_ie>]().clear_bit(); // Connect pin to analog / RTC module instead of standard GPIO - w.$mux_sel().set_bit(); + w.[<$prefix mux_sel>]().set_bit(); // Select function "RTC function 1" (GPIO) for analog use - unsafe { w.$fun_sel().bits(0b00) }; + unsafe { w.[<$prefix fun_sel>]().bits(0b00) }; // Disable pull-up and pull-down resistors on the pin, if it has them $( - w.$rue().bit(false); - w.$rde().bit(false); + // FIXME: replace with $(ignore($rue)) once stable + $crate::analog!( @ignore $rue ); + w.[<$prefix rue>]().bit(false); + w.[<$prefix rde>]().bit(false); )? w @@ -1502,10 +1478,7 @@ macro_rules! analog { ) => { $( #[cfg(any(adc, dac))] - impl $crate::gpio::AnalogPin for GpioPin<$pin_num> - where - Self: $crate::gpio::GpioProperties, - { + impl $crate::gpio::AnalogPin for GpioPin<$pin_num> { /// Configures the pin for analog mode. fn set_analog(&self, _: $crate::private::Internal) { use $crate::peripherals::{GPIO}; @@ -1565,10 +1538,7 @@ macro_rules! touch { )+ ) => { $( - impl $crate::gpio::TouchPin for GpioPin<$pin_num> - where - Self: $crate::gpio::GpioProperties, - { + impl $crate::gpio::TouchPin for GpioPin<$pin_num> { fn set_touch(&self, _: $crate::private::Internal) { use $crate::peripherals::{GPIO, RTC_IO, SENS}; @@ -1996,7 +1966,7 @@ impl<'d> Flex<'d> { #[inline] pub fn new(pin: impl Peripheral

+ 'd) -> Self { crate::into_ref!(pin); - let pin = pin.degrade_internal(private::Internal); + let pin = pin.degrade_pin(private::Internal); Self::new_typed(pin) } } @@ -2079,7 +2049,7 @@ where /// 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)) + interconnect::InputSignal::new(self.pin.degrade_pin(private::Internal)) } } @@ -2148,7 +2118,7 @@ where /// pin. #[inline] pub fn into_peripheral_output(self) -> interconnect::OutputSignal { - interconnect::OutputSignal::new(self.pin.degrade_internal(private::Internal)) + interconnect::OutputSignal::new(self.pin.degrade_pin(private::Internal)) } } @@ -2191,11 +2161,11 @@ pub(crate) mod internal { } impl Pin for AnyPin { - fn number(&self, _: private::Internal) -> u8 { - handle_gpio_input!(&self.0, target, { Pin::number(target, private::Internal) }) + fn number(&self) -> u8 { + handle_gpio_input!(&self.0, target, { Pin::number(target) }) } - fn degrade_internal(&self, _: private::Internal) -> AnyPin { + fn degrade_pin(&self, _: private::Internal) -> AnyPin { unsafe { self.clone_unchecked() } } @@ -2211,11 +2181,29 @@ pub(crate) mod internal { }) } - fn output_enable(&mut self, enable: bool, _: private::Internal) { - handle_gpio_input!(&mut self.0, target, { + fn output_enable(&self, enable: bool, _: private::Internal) { + handle_gpio_input!(&self.0, target, { Pin::output_enable(target, enable, private::Internal) }) } + + fn output_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_input!(&self.0, target, { + Pin::output_signals(target, private::Internal) + }) + } + + fn input_signals(&self, _: private::Internal) -> [Option; 6] { + handle_gpio_input!(&self.0, target, { + Pin::input_signals(target, private::Internal) + }) + } + + fn gpio_bank(&self, _: private::Internal) -> GpioRegisterAccess { + handle_gpio_input!(&self.0, target, { + Pin::gpio_bank(target, private::Internal) + }) + } } impl PeripheralSignal for AnyPin { @@ -2258,12 +2246,12 @@ pub(crate) mod internal { } fn connect_input_to_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + interconnect::InputSignal::new(self.degrade_pin(private::Internal)) .connect_input_to_peripheral(signal, private::Internal); } fn disconnect_input_from_peripheral(&mut self, signal: InputSignal, _: private::Internal) { - interconnect::InputSignal::new(self.degrade_internal(private::Internal)) + interconnect::InputSignal::new(self.degrade_pin(private::Internal)) .disconnect_input_from_peripheral(signal, private::Internal); } } @@ -2382,7 +2370,7 @@ pub(crate) mod internal { } fn connect_peripheral_to_output(&mut self, signal: OutputSignal, _: private::Internal) { - interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + interconnect::OutputSignal::new(self.degrade_pin(private::Internal)) .connect_peripheral_to_output(signal, private::Internal); } @@ -2391,7 +2379,7 @@ pub(crate) mod internal { signal: OutputSignal, _: private::Internal, ) { - interconnect::OutputSignal::new(self.degrade_internal(private::Internal)) + interconnect::OutputSignal::new(self.degrade_pin(private::Internal)) .disconnect_from_peripheral_output(signal, private::Internal); } } @@ -2466,10 +2454,10 @@ fn set_int_enable(gpio_num: u8, int_ena: u8, int_type: u8, wake_up_from_light_sl #[ram] fn handle_pin_interrupts(handle: impl Fn(u8)) { - let intrs_bank0 = InterruptStatusRegisterAccessBank0::interrupt_status_read(); + let intrs_bank0 = InterruptStatusRegisterAccess::Bank0.interrupt_status_read(); #[cfg(any(esp32, esp32s2, esp32s3))] - let intrs_bank1 = InterruptStatusRegisterAccessBank1::interrupt_status_read(); + let intrs_bank1 = InterruptStatusRegisterAccess::Bank1.interrupt_status_read(); let mut intr_bits = intrs_bank0; while intr_bits != 0 { @@ -2512,32 +2500,32 @@ mod asynch { /// immediately. pub async fn wait_for_high(&mut self) { self.listen(Event::HighLevel); - PinFuture::new(self.pin.number(private::Internal)).await + PinFuture::new(self.pin.number()).await } /// Wait until the pin is low. If it is already low, return immediately. pub async fn wait_for_low(&mut self) { self.listen(Event::LowLevel); - PinFuture::new(self.pin.number(private::Internal)).await + PinFuture::new(self.pin.number()).await } /// Wait for the pin to undergo a transition from low to high. pub async fn wait_for_rising_edge(&mut self) { self.listen(Event::RisingEdge); - PinFuture::new(self.pin.number(private::Internal)).await + PinFuture::new(self.pin.number()).await } /// Wait for the pin to undergo a transition from high to low. pub async fn wait_for_falling_edge(&mut self) { self.listen(Event::FallingEdge); - PinFuture::new(self.pin.number(private::Internal)).await + PinFuture::new(self.pin.number()).await } /// Wait for the pin to undergo any transition, i.e low to high OR high /// to low. pub async fn wait_for_any_edge(&mut self) { self.listen(Event::AnyEdge); - PinFuture::new(self.pin.number(private::Internal)).await + PinFuture::new(self.pin.number()).await } } diff --git a/esp-hal/src/rtc_cntl/sleep/esp32c6.rs b/esp-hal/src/rtc_cntl/sleep/esp32c6.rs index af051b074..9d602eae3 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32c6.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32c6.rs @@ -5,7 +5,6 @@ use crate::{ efuse::Efuse, gpio::{Pins, RtcFunction}, peripherals::Peripherals, - private, rtc_cntl::{ rtc::{ rtc_clk_cpu_freq_set_xtal, @@ -77,7 +76,7 @@ impl Ext1WakeupSource<'_, '_> { use crate::gpio::RtcPin; fn uninit_pin(pin: &mut impl RtcPin, wakeup_pins: u8) { - if wakeup_pins & (1 << pin.number(private::Internal)) != 0 { + if wakeup_pins & (1 << pin.number()) != 0 { pin.rtcio_pad_hold(false); pin.rtc_set_config(false, false, RtcFunction::Rtc); } @@ -110,9 +109,9 @@ impl WakeSource for Ext1WakeupSource<'_, '_> { let mut pin_mask = 0u8; let mut level_mask = 0u8; for (pin, level) in pins.iter_mut() { - pin_mask |= 1 << pin.number(private::Internal); + pin_mask |= 1 << pin.number(); level_mask |= match level { - WakeupLevel::High => 1 << pin.number(private::Internal), + WakeupLevel::High => 1 << pin.number(), WakeupLevel::Low => 0, }; diff --git a/esp-hal/src/rtc_cntl/sleep/esp32s3.rs b/esp-hal/src/rtc_cntl/sleep/esp32s3.rs index 65c70abe8..e4ebfeb05 100644 --- a/esp-hal/src/rtc_cntl/sleep/esp32s3.rs +++ b/esp-hal/src/rtc_cntl/sleep/esp32s3.rs @@ -240,14 +240,12 @@ impl<'a, 'b> RtcioWakeupSource<'a, 'b> { pin.rtc_set_config(true, true, RtcFunction::Rtc); - rtcio - .pin(pin.number(crate::private::Internal) as usize) - .modify(|_, w| unsafe { - w.wakeup_enable().set_bit().int_type().bits(match level { - WakeupLevel::Low => 4, - WakeupLevel::High => 5, - }) - }); + rtcio.pin(pin.number() as usize).modify(|_, w| unsafe { + w.wakeup_enable().set_bit().int_type().bits(match level { + WakeupLevel::Low => 4, + WakeupLevel::High => 5, + }) + }); } } diff --git a/esp-hal/src/soc/esp32/gpio.rs b/esp-hal/src/soc/esp32/gpio.rs index 8ec00b04a..bc5474690 100644 --- a/esp-hal/src/soc/esp32/gpio.rs +++ b/esp-hal/src/soc/esp32/gpio.rs @@ -36,11 +36,6 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. @@ -48,13 +43,7 @@ use core::mem::transmute; use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - InterruptStatusRegisterAccessBank1, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::{io_mux, GPIO, IO_MUX}, Cpu, }; @@ -804,45 +793,45 @@ crate::gpio::gpio! { } crate::gpio::analog! { - (36, 0, sensor_pads(), sense1_mux_sel, sense1_fun_sel, sense1_fun_ie) - (37, 1, sensor_pads(), sense2_mux_sel, sense2_fun_sel, sense2_fun_ie) - (38, 2, sensor_pads(), sense3_mux_sel, sense3_fun_sel, sense3_fun_ie) - (39, 3, sensor_pads(), sense4_mux_sel, sense4_fun_sel, sense4_fun_ie) - (34, 4, adc_pad(), adc1_mux_sel, adc1_fun_sel, adc1_fun_ie) - (35, 5, adc_pad(), adc2_mux_sel, adc2_fun_sel, adc1_fun_ie) - (25, 6, pad_dac1(), mux_sel, fun_sel, fun_ie, rue, rde) - (26, 7, pad_dac2(), mux_sel, fun_sel, fun_ie, rue, rde) - (33, 8, xtal_32k_pad(), x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_rue, x32n_rde ) - (32, 9, xtal_32k_pad(), x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_rue, x32p_rde ) - (4, 10, touch_pad0(), mux_sel, fun_sel, fun_ie, rue, rde ) - (0, 11, touch_pad1(), mux_sel, fun_sel, fun_ie, rue, rde ) - (2, 12, touch_pad2(), mux_sel, fun_sel, fun_ie, rue, rde ) - (15, 13, touch_pad3(), mux_sel, fun_sel, fun_ie, rue, rde ) - (13, 14, touch_pad4(), mux_sel, fun_sel, fun_ie, rue, rde ) - (12, 15, touch_pad5(), mux_sel, fun_sel, fun_ie, rue, rde ) - (14, 16, touch_pad6(), mux_sel, fun_sel, fun_ie, rue, rde ) - (27, 17, touch_pad7(), mux_sel, fun_sel, fun_ie, rue, rde ) + (36, 0, sensor_pads(), "sense1_" ) + (37, 1, sensor_pads(), "sense2_" ) + (38, 2, sensor_pads(), "sense3_" ) + (39, 3, sensor_pads(), "sense4_" ) + (34, 4, adc_pad(), "adc1_" ) + (35, 5, adc_pad(), "adc2_" ) + (25, 6, pad_dac1(), "", true) + (26, 7, pad_dac2(), "", true) + (33, 8, xtal_32k_pad(), "x32p_", true) + (32, 9, xtal_32k_pad(), "x32n_", true) + (4, 10, touch_pad0(), "", true) + (0, 11, touch_pad1(), "", true) + (2, 12, touch_pad2(), "", true) + (15, 13, touch_pad3(), "", true) + (13, 14, touch_pad4(), "", true) + (12, 15, touch_pad5(), "", true) + (14, 16, touch_pad6(), "", true) + (27, 17, touch_pad7(), "", true) } crate::gpio::rtc_pins! { - (36, 0, sensor_pads(), sense1_, sense1_hold_force ) - (37, 1, sensor_pads(), sense2_, sense2_hold_force ) - (38, 2, sensor_pads(), sense3_, sense3_hold_force ) - (39, 3, sensor_pads(), sense4_, sense4_hold_force ) - (34, 4, adc_pad(), adc1_, adc1_hold_force ) - (35, 5, adc_pad(), adc2_, adc2_hold_force ) - (25, 6, pad_dac1(), "", pdac1_hold_force, rue, rde ) - (26, 7, pad_dac2(), "", pdac2_hold_force, rue, rde ) - (33, 8, xtal_32k_pad(), x32n_, x32n_hold_force, x32n_rue, x32n_rde ) - (32, 9, xtal_32k_pad(), x32p_, x32p_hold_force, x32p_rue, x32p_rde ) - (4, 10, touch_pad0(), "", touch_pad0_hold_force, rue, rde ) - (0, 11, touch_pad1(), "", touch_pad1_hold_force, rue, rde ) - (2, 12, touch_pad2(), "", touch_pad2_hold_force, rue, rde ) - (15, 13, touch_pad3(), "", touch_pad3_hold_force, rue, rde ) - (13, 14, touch_pad4(), "", touch_pad4_hold_force, rue, rde ) - (12, 15, touch_pad5(), "", touch_pad5_hold_force, rue, rde ) - (14, 16, touch_pad6(), "", touch_pad6_hold_force, rue, rde ) - (27, 17, touch_pad7(), "", touch_pad7_hold_force, rue, rde ) + (36, 0, sensor_pads(), sense1_, sense1_hold_force ) + (37, 1, sensor_pads(), sense2_, sense2_hold_force ) + (38, 2, sensor_pads(), sense3_, sense3_hold_force ) + (39, 3, sensor_pads(), sense4_, sense4_hold_force ) + (34, 4, adc_pad(), adc1_, adc1_hold_force ) + (35, 5, adc_pad(), adc2_, adc2_hold_force ) + (25, 6, pad_dac1(), "", pdac1_hold_force, true) + (26, 7, pad_dac2(), "", pdac2_hold_force, true) + (33, 8, xtal_32k_pad(), x32n_, x32n_hold_force, true) + (32, 9, xtal_32k_pad(), x32p_, x32p_hold_force, true) + (4, 10, touch_pad0(), "", touch_pad0_hold_force, true) + (0, 11, touch_pad1(), "", touch_pad1_hold_force, true) + (2, 12, touch_pad2(), "", touch_pad2_hold_force, true) + (15, 13, touch_pad3(), "", touch_pad3_hold_force, true) + (13, 14, touch_pad4(), "", touch_pad4_hold_force, true) + (12, 15, touch_pad5(), "", touch_pad5_hold_force, true) + (14, 16, touch_pad6(), "", touch_pad6_hold_force, true) + (27, 17, touch_pad7(), "", touch_pad7_hold_force, true) } crate::gpio::touch! { @@ -860,38 +849,23 @@ crate::gpio::touch! { (9, 32, 9, sar_touch_out5, touch_meas_out9, sar_touch_thres5, touch_out_th9, false) } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } - - fn app_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.acpu_int().read().bits() - } - - fn app_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.acpu_nmi_int().read().bits() - } +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, + Bank1, } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int1().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int1().read().bits() - } - - fn app_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.acpu_int1().read().bits() - } - - fn app_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.acpu_nmi_int1().read().bits() +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { + match self { + Self::Bank0 => match crate::get_core() { + crate::Cpu::ProCpu => unsafe { &*GPIO::PTR }.pcpu_int().read().bits(), + crate::Cpu::AppCpu => unsafe { &*GPIO::PTR }.acpu_int().read().bits(), + }, + Self::Bank1 => match crate::get_core() { + crate::Cpu::ProCpu => unsafe { &*GPIO::PTR }.pcpu_int1().read().bits(), + crate::Cpu::AppCpu => unsafe { &*GPIO::PTR }.acpu_int1().read().bits(), + }, + } } } diff --git a/esp-hal/src/soc/esp32c2/gpio.rs b/esp-hal/src/soc/esp32c2/gpio.rs index 630befe48..384128b20 100644 --- a/esp-hal/src/soc/esp32c2/gpio.rs +++ b/esp-hal/src/soc/esp32c2/gpio.rs @@ -32,21 +32,11 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::GPIO, }; @@ -215,12 +205,13 @@ crate::gpio::analog! { 4 } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, +} + +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { unsafe { &*GPIO::PTR }.pcpu_int().read().bits() } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } } diff --git a/esp-hal/src/soc/esp32c3/gpio.rs b/esp-hal/src/soc/esp32c3/gpio.rs index 4c6a30913..a7152b2f7 100644 --- a/esp-hal/src/soc/esp32c3/gpio.rs +++ b/esp-hal/src/soc/esp32c3/gpio.rs @@ -32,22 +32,12 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::GPIO, }; @@ -233,6 +223,7 @@ crate::gpio::gpio! { (21, 0, InputOutput () (0 => U0TXD)) } +// RTC pins 0 through 5 (inclusive) support GPIO wakeup crate::gpio::rtc_pins! { 0 1 @@ -251,14 +242,13 @@ crate::gpio::analog! { 5 } -// RTC pins 0 through 5 (inclusive) support GPIO wakeup +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, +} -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { unsafe { &*GPIO::PTR }.pcpu_int().read().bits() } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } } diff --git a/esp-hal/src/soc/esp32c6/gpio.rs b/esp-hal/src/soc/esp32c6/gpio.rs index 4e688237e..ea3c69c5c 100644 --- a/esp-hal/src/soc/esp32c6/gpio.rs +++ b/esp-hal/src/soc/esp32c6/gpio.rs @@ -32,22 +32,12 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::GPIO, }; @@ -350,12 +340,13 @@ crate::gpio::lp_io::lp_gpio! { 7 } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, +} + +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { unsafe { &*GPIO::PTR }.pcpu_int().read().bits() } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } } diff --git a/esp-hal/src/soc/esp32h2/gpio.rs b/esp-hal/src/soc/esp32h2/gpio.rs index 519b6f56b..cfa065d4f 100644 --- a/esp-hal/src/soc/esp32h2/gpio.rs +++ b/esp-hal/src/soc/esp32h2/gpio.rs @@ -32,22 +32,12 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::GPIO, }; @@ -298,12 +288,13 @@ crate::gpio::analog! { 5 } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, +} + +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { unsafe { &*GPIO::PTR }.pcpu_int().read().bits() } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } } diff --git a/esp-hal/src/soc/esp32s2/gpio.rs b/esp-hal/src/soc/esp32s2/gpio.rs index 3b5d3daac..12db78eed 100644 --- a/esp-hal/src/soc/esp32s2/gpio.rs +++ b/esp-hal/src/soc/esp32s2/gpio.rs @@ -43,11 +43,6 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. @@ -55,13 +50,7 @@ use core::mem::transmute; use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - InterruptStatusRegisterAccessBank1, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::{io_mux, GPIO, IO_MUX}, }; @@ -373,72 +362,67 @@ crate::gpio::gpio! { } crate::gpio::analog! { - ( 0, 0, touch_pad(0), mux_sel, fun_sel, fun_ie, rue, rde) - ( 1, 1, touch_pad(1), mux_sel, fun_sel, fun_ie, rue, rde) - ( 2, 2, touch_pad(2), mux_sel, fun_sel, fun_ie, rue, rde) - ( 3, 3, touch_pad(3), mux_sel, fun_sel, fun_ie, rue, rde) - ( 4, 4, touch_pad(4), mux_sel, fun_sel, fun_ie, rue, rde) - ( 5, 5, touch_pad(5), mux_sel, fun_sel, fun_ie, rue, rde) - ( 6, 6, touch_pad(6), mux_sel, fun_sel, fun_ie, rue, rde) - ( 7, 7, touch_pad(7), mux_sel, fun_sel, fun_ie, rue, rde) - ( 8, 8, touch_pad(8), mux_sel, fun_sel, fun_ie, rue, rde) - ( 9, 9, touch_pad(9), mux_sel, fun_sel, fun_ie, rue, rde) - (10, 10, touch_pad(10), mux_sel, fun_sel, fun_ie, rue, rde) - (11, 11, touch_pad(11), mux_sel, fun_sel, fun_ie, rue, rde) - (12, 12, touch_pad(12), mux_sel, fun_sel, fun_ie, rue, rde) - (13, 13, touch_pad(13), mux_sel, fun_sel, fun_ie, rue, rde) - (14, 14, touch_pad(14), mux_sel, fun_sel, fun_ie, rue, rde) - (15, 15, xtal_32p_pad(), x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_rue, x32p_rde) - (16, 16, xtal_32n_pad(), x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_rue, x32n_rde) - (17, 17, pad_dac1(), mux_sel, fun_sel, fun_ie, rue, rde) - (18, 18, pad_dac2(), mux_sel, fun_sel, fun_ie, rue, rde) - (19, 19, rtc_pad19(), mux_sel, fun_sel, fun_ie, rue, rde) - (20, 20, rtc_pad20(), mux_sel, fun_sel, fun_ie, rue, rde) - (21, 21, rtc_pad21(), mux_sel, fun_sel, fun_ie, rue, rde) + ( 0, 0, touch_pad(0), "", true) + ( 1, 1, touch_pad(1), "", true) + ( 2, 2, touch_pad(2), "", true) + ( 3, 3, touch_pad(3), "", true) + ( 4, 4, touch_pad(4), "", true) + ( 5, 5, touch_pad(5), "", true) + ( 6, 6, touch_pad(6), "", true) + ( 7, 7, touch_pad(7), "", true) + ( 8, 8, touch_pad(8), "", true) + ( 9, 9, touch_pad(9), "", true) + (10, 10, touch_pad(10), "", true) + (11, 11, touch_pad(11), "", true) + (12, 12, touch_pad(12), "", true) + (13, 13, touch_pad(13), "", true) + (14, 14, touch_pad(14), "", true) + (15, 15, xtal_32p_pad(), "x32p_", true) + (16, 16, xtal_32n_pad(), "x32n_", true) + (17, 17, pad_dac1(), "", true) + (18, 18, pad_dac2(), "", true) + (19, 19, rtc_pad19(), "", true) + (20, 20, rtc_pad20(), "", true) + (21, 21, rtc_pad21(), "", true) } crate::gpio::rtc_pins! { - ( 0, 0, touch_pad(0), "", touch_pad0_hold, rue, rde) - ( 1, 1, touch_pad(1), "", touch_pad1_hold, rue, rde) - ( 2, 2, touch_pad(2), "", touch_pad2_hold, rue, rde) - ( 3, 3, touch_pad(3), "", touch_pad3_hold, rue, rde) - ( 4, 4, touch_pad(4), "", touch_pad4_hold, rue, rde) - ( 5, 5, touch_pad(5), "", touch_pad5_hold, rue, rde) - ( 6, 6, touch_pad(6), "", touch_pad6_hold, rue, rde) - ( 7, 7, touch_pad(7), "", touch_pad7_hold, rue, rde) - ( 8, 8, touch_pad(8), "", touch_pad8_hold, rue, rde) - ( 9, 9, touch_pad(9), "", touch_pad9_hold, rue, rde) - (10, 10, touch_pad(10), "", touch_pad10_hold, rue, rde) - (11, 11, touch_pad(11), "", touch_pad11_hold, rue, rde) - (12, 12, touch_pad(12), "", touch_pad12_hold, rue, rde) - (13, 13, touch_pad(13), "", touch_pad13_hold, rue, rde) - (14, 14, touch_pad(14), "", touch_pad14_hold, rue, rde) - (15, 15, xtal_32p_pad(), x32p_, x32p_hold, x32p_rue, x32p_rde) - (16, 16, xtal_32n_pad(), x32n_, x32n_hold, x32n_rue, x32n_rde) - (17, 17, pad_dac1(), "", pdac1_hold, rue, rde) - (18, 18, pad_dac2(), "", pdac2_hold, rue, rde) - (19, 19, rtc_pad19(), "", pad19_hold, rue, rde) - (20, 20, rtc_pad20(), "", pad20_hold, rue, rde) - (21, 21, rtc_pad21(), "", pad21_hold, rue, rde) + ( 0, 0, touch_pad(0), "", touch_pad0_hold, true) + ( 1, 1, touch_pad(1), "", touch_pad1_hold, true) + ( 2, 2, touch_pad(2), "", touch_pad2_hold, true) + ( 3, 3, touch_pad(3), "", touch_pad3_hold, true) + ( 4, 4, touch_pad(4), "", touch_pad4_hold, true) + ( 5, 5, touch_pad(5), "", touch_pad5_hold, true) + ( 6, 6, touch_pad(6), "", touch_pad6_hold, true) + ( 7, 7, touch_pad(7), "", touch_pad7_hold, true) + ( 8, 8, touch_pad(8), "", touch_pad8_hold, true) + ( 9, 9, touch_pad(9), "", touch_pad9_hold, true) + (10, 10, touch_pad(10), "", touch_pad10_hold, true) + (11, 11, touch_pad(11), "", touch_pad11_hold, true) + (12, 12, touch_pad(12), "", touch_pad12_hold, true) + (13, 13, touch_pad(13), "", touch_pad13_hold, true) + (14, 14, touch_pad(14), "", touch_pad14_hold, true) + (15, 15, xtal_32p_pad(), x32p_, x32p_hold, true) + (16, 16, xtal_32n_pad(), x32n_, x32n_hold, true) + (17, 17, pad_dac1(), "", pdac1_hold, true) + (18, 18, pad_dac2(), "", pdac2_hold, true) + (19, 19, rtc_pad19(), "", pad19_hold, true) + (20, 20, rtc_pad20(), "", pad20_hold, true) + (21, 21, rtc_pad21(), "", pad21_hold, true) } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, + Bank1, } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int1().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int1().read().bits() +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { + match self { + Self::Bank0 => unsafe { &*GPIO::PTR }.pcpu_int().read().bits(), + Self::Bank1 => unsafe { &*GPIO::PTR }.pcpu_int1().read().bits(), + } } } diff --git a/esp-hal/src/soc/esp32s3/gpio.rs b/esp-hal/src/soc/esp32s3/gpio.rs index 9c4598bfe..7bfd24ad5 100644 --- a/esp-hal/src/soc/esp32s3/gpio.rs +++ b/esp-hal/src/soc/esp32s3/gpio.rs @@ -32,23 +32,12 @@ //! * This enumeration defines output signals for the GPIO mux. Each //! output signal is assigned a specific value. //! -//! This module also implements the `InterruptStatusRegisterAccess` trait for -//! two different banks: -//! * `InterruptStatusRegisterAccessBank0` -//! * `InterruptStatusRegisterAccessBank1`. -//! //! This trait provides functions to read the interrupt status and NMI status //! registers for both the `PRO CPU` and `APP CPU`. The implementation uses the //! `gpio` peripheral to access the appropriate registers. use crate::{ - gpio::{ - AlternateFunction, - GpioPin, - InterruptStatusRegisterAccess, - InterruptStatusRegisterAccessBank0, - InterruptStatusRegisterAccessBank1, - }, + gpio::{AlternateFunction, GpioPin}, peripherals::GPIO, }; @@ -405,90 +394,69 @@ crate::gpio::gpio! { } crate::gpio::analog! { - ( 0, 0, touch_pad(0), mux_sel, fun_sel, fun_ie, rue, rde) - ( 1, 1, touch_pad(1), mux_sel, fun_sel, fun_ie, rue, rde) - ( 2, 2, touch_pad(2), mux_sel, fun_sel, fun_ie, rue, rde) - ( 3, 3, touch_pad(3), mux_sel, fun_sel, fun_ie, rue, rde) - ( 4, 4, touch_pad(4), mux_sel, fun_sel, fun_ie, rue, rde) - ( 5, 5, touch_pad(5), mux_sel, fun_sel, fun_ie, rue, rde) - ( 6, 6, touch_pad(6), mux_sel, fun_sel, fun_ie, rue, rde) - ( 7, 7, touch_pad(7), mux_sel, fun_sel, fun_ie, rue, rde) - ( 8, 8, touch_pad(8), mux_sel, fun_sel, fun_ie, rue, rde) - ( 9, 9, touch_pad(9), mux_sel, fun_sel, fun_ie, rue, rde) - (10, 10, touch_pad(10), mux_sel, fun_sel, fun_ie, rue, rde) - (11, 11, touch_pad(11), mux_sel, fun_sel, fun_ie, rue, rde) - (12, 12, touch_pad(12), mux_sel, fun_sel, fun_ie, rue, rde) - (13, 13, touch_pad(13), mux_sel, fun_sel, fun_ie, rue, rde) - (14, 14, touch_pad(14), mux_sel, fun_sel, fun_ie, rue, rde) - (15, 15, xtal_32p_pad(), x32p_mux_sel, x32p_fun_sel, x32p_fun_ie, x32p_rue, x32p_rde) - (16, 16, xtal_32n_pad(), x32n_mux_sel, x32n_fun_sel, x32n_fun_ie, x32n_rue, x32n_rde) - (17, 17, pad_dac1(), pdac1_mux_sel,pdac1_fun_sel,pdac1_fun_ie, pdac1_rue, pdac1_rde) - (18, 18, pad_dac2(), pdac2_mux_sel,pdac2_fun_sel,pdac2_fun_ie, pdac2_rue, pdac2_rde) - (19, 19, rtc_pad19(), mux_sel, fun_sel, fun_ie, rue, rde) - (20, 20, rtc_pad20(), mux_sel, fun_sel, fun_ie, rue, rde) - (21, 21, rtc_pad21(), mux_sel, fun_sel, fun_ie, rue, rde) + ( 0, 0, touch_pad(0), "", true) + ( 1, 1, touch_pad(1), "", true) + ( 2, 2, touch_pad(2), "", true) + ( 3, 3, touch_pad(3), "", true) + ( 4, 4, touch_pad(4), "", true) + ( 5, 5, touch_pad(5), "", true) + ( 6, 6, touch_pad(6), "", true) + ( 7, 7, touch_pad(7), "", true) + ( 8, 8, touch_pad(8), "", true) + ( 9, 9, touch_pad(9), "", true) + (10, 10, touch_pad(10), "", true) + (11, 11, touch_pad(11), "", true) + (12, 12, touch_pad(12), "", true) + (13, 13, touch_pad(13), "", true) + (14, 14, touch_pad(14), "", true) + (15, 15, xtal_32p_pad(), "x32p_", true) + (16, 16, xtal_32n_pad(), "x32n_", true) + (17, 17, pad_dac1(), "pdac1_", true) + (18, 18, pad_dac2(), "pdac2_", true) + (19, 19, rtc_pad19(), "", true) + (20, 20, rtc_pad20(), "", true) + (21, 21, rtc_pad21(), "", true) } crate::gpio::rtc_pins! { - ( 0, 0, touch_pad(0), "", touch_pad0_hold, rue, rde) - ( 1, 1, touch_pad(1), "", touch_pad1_hold, rue, rde) - ( 2, 2, touch_pad(2), "", touch_pad2_hold, rue, rde) - ( 3, 3, touch_pad(3), "", touch_pad3_hold, rue, rde) - ( 4, 4, touch_pad(4), "", touch_pad4_hold, rue, rde) - ( 5, 5, touch_pad(5), "", touch_pad5_hold, rue, rde) - ( 6, 6, touch_pad(6), "", touch_pad6_hold, rue, rde) - ( 7, 7, touch_pad(7), "", touch_pad7_hold, rue, rde) - ( 8, 8, touch_pad(8), "", touch_pad8_hold, rue, rde) - ( 9, 9, touch_pad(9), "", touch_pad9_hold, rue, rde) - (10, 10, touch_pad(10), "", touch_pad10_hold, rue, rde) - (11, 11, touch_pad(11), "", touch_pad11_hold, rue, rde) - (12, 12, touch_pad(12), "", touch_pad12_hold, rue, rde) - (13, 13, touch_pad(13), "", touch_pad13_hold, rue, rde) - (14, 14, touch_pad(14), "", touch_pad14_hold, rue, rde) - (15, 15, xtal_32p_pad(), x32p_, x32p_hold, x32p_rue, x32p_rde) - (16, 16, xtal_32n_pad(), x32n_, x32n_hold, x32n_rue, x32n_rde) - (17, 17, pad_dac1(), pdac1_, pdac1_hold, pdac1_rue, pdac1_rde) - (18, 18, pad_dac2(), pdac2_, pdac2_hold, pdac2_rue, pdac2_rde) - (19, 19, rtc_pad19(), "", pad19_hold, rue, rde) - (20, 20, rtc_pad20(), "", pad20_hold, rue, rde) - (21, 21, rtc_pad21(), "", pad21_hold, rue, rde) + ( 0, 0, touch_pad(0), "", touch_pad0_hold, true) + ( 1, 1, touch_pad(1), "", touch_pad1_hold, true) + ( 2, 2, touch_pad(2), "", touch_pad2_hold, true) + ( 3, 3, touch_pad(3), "", touch_pad3_hold, true) + ( 4, 4, touch_pad(4), "", touch_pad4_hold, true) + ( 5, 5, touch_pad(5), "", touch_pad5_hold, true) + ( 6, 6, touch_pad(6), "", touch_pad6_hold, true) + ( 7, 7, touch_pad(7), "", touch_pad7_hold, true) + ( 8, 8, touch_pad(8), "", touch_pad8_hold, true) + ( 9, 9, touch_pad(9), "", touch_pad9_hold, true) + (10, 10, touch_pad(10), "", touch_pad10_hold, true) + (11, 11, touch_pad(11), "", touch_pad11_hold, true) + (12, 12, touch_pad(12), "", touch_pad12_hold, true) + (13, 13, touch_pad(13), "", touch_pad13_hold, true) + (14, 14, touch_pad(14), "", touch_pad14_hold, true) + (15, 15, xtal_32p_pad(), x32p_, x32p_hold, true) + (16, 16, xtal_32n_pad(), x32n_, x32n_hold, true) + (17, 17, pad_dac1(), pdac1_, pdac1_hold, true) + (18, 18, pad_dac2(), pdac2_, pdac2_hold, true) + (19, 19, rtc_pad19(), "", pad19_hold, true) + (20, 20, rtc_pad20(), "", pad20_hold, true) + (21, 21, rtc_pad21(), "", pad21_hold, true) } // Whilst the S3 is a dual core chip, it shares the enable registers between // cores so treat it as a single core device -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank0 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int().read().bits() - } - - fn interrupt_status_read() -> u32 { - Self::pro_cpu_interrupt_status_read() - } - - fn nmi_status_read() -> u32 { - Self::pro_cpu_nmi_status_read() - } +#[derive(Clone, Copy)] +pub(crate) enum InterruptStatusRegisterAccess { + Bank0, + Bank1, } -impl InterruptStatusRegisterAccess for InterruptStatusRegisterAccessBank1 { - fn pro_cpu_interrupt_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_int1().read().bits() - } - - fn pro_cpu_nmi_status_read() -> u32 { - unsafe { &*GPIO::PTR }.pcpu_nmi_int1().read().bits() - } - - fn interrupt_status_read() -> u32 { - Self::pro_cpu_interrupt_status_read() - } - - fn nmi_status_read() -> u32 { - Self::pro_cpu_nmi_status_read() +impl InterruptStatusRegisterAccess { + pub(crate) fn interrupt_status_read(self) -> u32 { + match self { + Self::Bank0 => unsafe { &*GPIO::PTR }.pcpu_int().read().bits(), + Self::Bank1 => unsafe { &*GPIO::PTR }.pcpu_int1().read().bits(), + } } }