diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 47ff2831a..211c4af44 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - SPI: Added support for 3-wire SPI (#2919) -- Add separate config for Rx and Tx (UART) #2965 +- UART: Add separate config for Rx and Tx (#2965) ### Changed @@ -25,12 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Rng` and `Trng` now implement `Peripheral

` (#2992) - SPI, UART, I2C: `with_` functions of peripheral drivers now disconnect the previously assigned pins from the peripheral. (#3012) - SPI, UART, I2C: Dropping a driver now disconnects pins from their peripherals. (#3012) - - `Async` drivers are no longer `Send` (#2980) -- GPIO drivers now take configuration structs, and their constructors are fallible (#2990) -- `flip-link` feature is now a config option -- `flip-link` feature is now a config option (`ESP_HAL_CONFIG_FLIP_LINK`) - +- GPIO drivers now take configuration structs (#2990, #3029) - `flip-link` feature is now a config option (`ESP_HAL_CONFIG_FLIP_LINK`) (#3001) - Removed features `psram-quad` and `psram-octal` - replaced by `psram` and the `ESP_HAL_CONFIG_PSRAM_MODE` (`quad`/`octal`) (#3001) @@ -44,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - Removed `Pin`, `RtcPin` and `RtcPinWithResistors` implementations from `Flex` (#2938) +- OutputOpenDrain has been removed (#3029) ## [0.23.1] - 2025-01-15 diff --git a/esp-hal/MIGRATING-0.23.md b/esp-hal/MIGRATING-0.23.md index 86cb55ddb..97696bb9a 100644 --- a/esp-hal/MIGRATING-0.23.md +++ b/esp-hal/MIGRATING-0.23.md @@ -177,15 +177,26 @@ config/config.toml ## GPIO changes -GPIO drivers now take configuration structs, and their constructors are fallible. +GPIO drivers now take configuration structs. ```diff - Input::new(peripherals.GPIO0, Pull::Up); -+ Input::new(peripherals.GPIO0, InputConfig::default().with_pull(Pull::Up)).unwrap(); ++ Input::new(peripherals.GPIO0, InputConfig::default().with_pull_direction(Pull::Up)); + - Output::new(peripherals.GPIO0, Level::Low); -+ Output::new(peripherals.GPIO0, OutputConfig::default().with_level(Level::Low)).unwrap(); -- OutputOpenDrain::new(peripherals.GPIO0, Level::Low, Pull::Up); -+ OutputOpenDrain::new( -+ peripherals.GPIO0, -+ OutputOpenDrainConfig::default().with_level(Level::Low).with_pull(Pull::Up) -+ ).unwrap(); \ No newline at end of file ++ Output::new(peripherals.GPIO0, Level::Low, OutputConfig::default()); +``` + +The OutputOpenDrain driver has been removed. You can use `Output` instead with +`DriveMode::OpenDrain`. The input-related methods of `OutputOpenDrain` (`level`, +`is_high`, `is_low`) are available through the (unstable) `Flex` driver. + +```diff +- OutputOpenDrain::new(peripherals.GPIO0, Level::Low); ++ Output::new( + peripherals.GPIO0, + Level::Low, + OutputConfig::default() + .with_drive_mode(DriveMode::OpenDrain), + ); +``` diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index c521c1f50..af0f17334 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -17,12 +17,15 @@ //! (such as SPI, UART, I2C, etc.), or can be [`GpioPin::split`] //! into peripheral signals for advanced use. //! -//! Pin drivers can be created using [`Flex::new`], [`Input::new`], -//! [`Output::new`] and [`OutputOpenDrain::new`]. +//! Pin drivers can be created using [`Flex::new`], [`Input::new`] and +//! [`Output::new`]. //! -//! Each pin is a different type initially. Internally, `esp-hal` will often -//! erase their types automatically, but they can also be converted into -//! [`AnyPin`] manually by calling [`Pin::degrade`]. +//! Output pins can be configured to either push-pull or open-drain (active low) +//! mode, with configurable drive strength and pull-up/pull-down resistors. +//! +//! Each pin is a different type initially. Internally, `esp-hal` will erase +//! their types automatically, but they can also be converted into [`AnyPin`] +//! manually by calling [`Pin::degrade`]. //! //! The [`Io`] struct can also be used to configure the interrupt handler for //! GPIO interrupts. For more information, see the @@ -253,12 +256,6 @@ impl From for bool { } } -/// A configuration error. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[non_exhaustive] -pub enum ConfigError {} - /// Errors that can occur when configuring a pin to be a wakeup source. #[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -285,7 +282,7 @@ impl Display for WakeConfigError { impl core::error::Error for WakeConfigError {} -/// Pull setting for an input. +/// Pull setting for a GPIO. #[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Pull { @@ -427,12 +424,14 @@ pub trait Pin: Sealed { /// let [red, blue] = pins; /// let mut red = Output::new( /// red, - /// OutputConfig::default().with_level(Level::High) - /// ).unwrap(); + /// Level::High, + /// OutputConfig::default(), + /// ); /// let mut blue = Output::new( /// blue, - /// OutputConfig::default().with_level(Level::Low) - /// ).unwrap(); + /// Level::Low, + /// OutputConfig::default(), + /// ); /// /// loop { /// red.toggle(); @@ -1075,26 +1074,59 @@ macro_rules! gpio { }; } +/// The drive mode of the output pin. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum DriveMode { + /// Push-pull output. + /// + /// The driver actively sets the output voltage level for both high and low + /// logical [`Level`]s. + PushPull, + + /// Open drain output. + /// + /// The driver actively pulls the output voltage level low for the low + /// logical [`Level`], but leaves the high level floating, which is then + /// determined by external hardware, or internal pull-up/pull-down + /// resistors. + OpenDrain, +} + /// Output pin configuration. +/// +/// This struct is used to configure the drive mode, drive strength, and pull +/// direction of an output pin. By default, the configuration is set to: +/// - Drive mode: [`DriveMode::PushPull`] +/// - Drive strength: [`DriveStrength::_20mA`] +/// - Pull direction: [`Pull::None`] (no pull resistors connected) #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[derive(Debug, Clone, Copy, PartialEq, Eq, procmacros::BuilderLite)] #[non_exhaustive] pub struct OutputConfig { - /// Initial output level of the pin. - pub level: Level, + /// Output drive mode. + pub drive_mode: DriveMode, + + /// Pin drive strength. + pub drive_strength: DriveStrength, + + /// Pin pull direction. + pub pull: Pull, } impl Default for OutputConfig { fn default() -> Self { - Self { level: Level::Low } + Self { + drive_mode: DriveMode::PushPull, + drive_strength: DriveStrength::_20mA, + pull: Pull::None, + } } } /// Push-pull digital output. /// -/// This driver configures the GPIO pin to be a push-pull output driver. -/// Push-pull means that the driver actively sets the output voltage level -/// for both high and low logical [`Level`]s. +/// This driver configures the GPIO pin to be an output driver. #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Output<'d> { @@ -1113,7 +1145,9 @@ impl<'d> Peripheral for Output<'d> { impl<'d> Output<'d> { /// Creates a new GPIO output driver. /// - /// The `initial_output` parameter sets the initial output level of the pin. + /// The `initial_level` parameter sets the initial output level of the pin. + /// The `config` parameter sets the drive mode, drive strength, and pull + /// direction of the pin. /// /// ## Example /// @@ -1132,8 +1166,8 @@ impl<'d> Output<'d> { /// led.set_high(); /// } /// - /// let config = OutputConfig::default().with_level(Level::High); - /// let mut led = Output::new(peripherals.GPIO5, config).unwrap(); + /// let config = OutputConfig::default(); + /// let mut led = Output::new(peripherals.GPIO5, Level::High, config); /// let mut delay = Delay::new(); /// /// blink_once(&mut led, &mut delay); @@ -1142,14 +1176,18 @@ impl<'d> Output<'d> { #[inline] pub fn new( pin: impl Peripheral

+ 'd, + initial_level: Level, config: OutputConfig, - ) -> Result { - let mut pin = Flex::new(pin); + ) -> Self { + // Set up the pin + let mut this = Self { + pin: Flex::new(pin), + }; + this.set_level(initial_level); + this.apply_config(&config); + this.pin.pin.enable_output(true); - pin.set_level(config.level); - pin.set_as_output(); - - Ok(Self { pin }) + this } /// Split the pin into an input and output signal. @@ -1159,8 +1197,8 @@ impl<'d> Output<'d> { /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Output, OutputConfig, Level}; - /// let config = OutputConfig::default().with_level(Level::High); - /// let pin1 = Output::new(peripherals.GPIO1, config).unwrap(); + /// # let config = OutputConfig::default(); + /// let pin1 = Output::new(peripherals.GPIO1, Level::High, config); /// let (input, output) = pin1.split(); /// # } /// ``` @@ -1177,10 +1215,10 @@ impl<'d> Output<'d> { /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Output, OutputConfig, Level}; - /// let config = OutputConfig::default().with_level(Level::High); - /// let pin1_gpio = Output::new(peripherals.GPIO1, config).unwrap(); + /// # let config = OutputConfig::default(); + /// let pin1_gpio = Output::new(peripherals.GPIO1, Level::High, config); /// // Can be passed as an input. - /// let pin1 = pin1_gpio.peripheral_input(); + /// let input = pin1_gpio.peripheral_input(); /// # } /// ``` #[inline] @@ -1197,9 +1235,9 @@ impl<'d> Output<'d> { /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Output, OutputConfig, Level}; - /// let config = OutputConfig::default().with_level(Level::High); - /// let pin1_gpio = Output::new(peripherals.GPIO1, config).unwrap(); - /// let pin1 = pin1_gpio.into_peripheral_output(); + /// # let config = OutputConfig::default(); + /// let pin1_gpio = Output::new(peripherals.GPIO1, Level::High, config); + /// let output = pin1_gpio.into_peripheral_output(); /// # } /// ``` #[inline] @@ -1209,9 +1247,9 @@ impl<'d> Output<'d> { } /// Change the configuration. - pub fn apply_config(&mut self, config: &OutputConfig) -> Result<(), ConfigError> { - self.set_level(config.level); - Ok(()) + #[inline] + pub fn apply_config(&mut self, config: &OutputConfig) { + self.pin.apply_output_config(config) } /// Set the output as high. @@ -1232,34 +1270,47 @@ impl<'d> Output<'d> { self.pin.set_level(level) } - /// Is the output pin set as high? + /// Returns whether the pin is set to high level. + /// + /// This function reads back the value set using `set_level`, `set_high` or + /// `set_low`. It does not need the input stage to be enabled. #[inline] pub fn is_set_high(&self) -> bool { self.output_level() == Level::High } - /// Is the output pin set as low? + /// Returns whether the pin is set to low level. + /// + /// This function reads back the value set using `set_level`, `set_high` or + /// `set_low`. It does not need the input stage to be enabled. #[inline] pub fn is_set_low(&self) -> bool { self.output_level() == Level::Low } - /// What level output is set to + /// Returns which level the pin is set to. + /// + /// This function reads back the value set using `set_level`, `set_high` or + /// `set_low`. It does not need the input stage to be enabled. #[inline] pub fn output_level(&self) -> Level { self.pin.output_level() } - /// Toggle pin output + /// Toggles the pin output. + /// + /// If the pin was previously set to high, it will be set to low, and vice + /// versa. #[inline] pub fn toggle(&mut self) { self.pin.toggle(); } - /// Configure the [DriveStrength] of the pin + /// Converts the pin driver into a [`Flex`] driver. #[inline] - pub fn set_drive_strength(&mut self, strength: DriveStrength) { - self.pin.set_drive_strength(strength); + #[instability::unstable] + pub fn into_flex(self) -> Flex<'d> { + self.pin } } @@ -1327,22 +1378,21 @@ impl<'d> Input<'d> { /// } /// /// let config = InputConfig::default().with_pull(Pull::Up); - /// let mut button = Input::new(peripherals.GPIO5, config).unwrap(); + /// let mut button = Input::new(peripherals.GPIO5, config); /// let mut delay = Delay::new(); /// /// print_when_pressed(&mut button, &mut delay); /// # } /// ``` #[inline] - pub fn new( - pin: impl Peripheral

+ 'd, - config: InputConfig, - ) -> Result { + pub fn new(pin: impl Peripheral

+ 'd, config: InputConfig) -> Self { let mut pin = Flex::new(pin); - pin.set_as_input(config.pull); + pin.pin.enable_output(false); + pin.enable_input(true); + pin.apply_input_config(&config); - Ok(Self { pin }) + Self { pin } } /// Returns a peripheral [input][interconnect::InputSignal] connected to @@ -1353,7 +1403,7 @@ impl<'d> Input<'d> { #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Input, InputConfig, Pull}; /// let config = InputConfig::default().with_pull(Pull::Up); - /// let pin1_gpio = Input::new(peripherals.GPIO1, config).unwrap(); + /// let pin1_gpio = Input::new(peripherals.GPIO1, config); /// let pin1 = pin1_gpio.peripheral_input(); /// # } /// ``` @@ -1382,9 +1432,8 @@ impl<'d> Input<'d> { } /// Change the configuration. - pub fn apply_config(&mut self, config: &InputConfig) -> Result<(), ConfigError> { - self.pin.set_as_input(config.pull); - Ok(()) + pub fn apply_config(&mut self, config: &InputConfig) { + self.pin.apply_input_config(config) } /// Listen for interrupts. @@ -1413,7 +1462,7 @@ impl<'d> Input<'d> { /// // This example uses a push button that is high when not /// // pressed and low when pressed. /// let config = InputConfig::default().with_pull(Pull::Up); - /// let mut button = Input::new(peripherals.GPIO5, config).unwrap(); + /// let mut button = Input::new(peripherals.GPIO5, config); /// /// critical_section::with(|cs| { /// // Here we are listening for a low level to demonstrate @@ -1501,7 +1550,7 @@ impl<'d> Input<'d> { #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Input, InputConfig, Pull}; /// let config = InputConfig::default().with_pull(Pull::Up); - /// let pin1 = Input::new(peripherals.GPIO1, config).unwrap(); + /// let pin1 = Input::new(peripherals.GPIO1, config); /// let (input, output) = pin1.split(); /// # } /// ``` @@ -1520,7 +1569,7 @@ impl<'d> Input<'d> { #[doc = crate::before_snippet!()] /// # use esp_hal::gpio::{Input, InputConfig, Pull}; /// let config = InputConfig::default().with_pull(Pull::Up); - /// let pin1_gpio = Input::new(peripherals.GPIO1, config).unwrap(); + /// let pin1_gpio = Input::new(peripherals.GPIO1, config); /// // Can be passed as an output. /// let pin1 = pin1_gpio.into_peripheral_output(); /// # } @@ -1530,263 +1579,12 @@ impl<'d> Input<'d> { pub fn into_peripheral_output(self) -> interconnect::OutputSignal { self.pin.into_peripheral_output() } -} -/// Open-drain output pin configuration. -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -#[derive(Debug, Clone, Copy, PartialEq, Eq, procmacros::BuilderLite)] -#[non_exhaustive] -pub struct OutputOpenDrainConfig { - /// Initial output level of the pin. - pub level: Level, - /// Initial pull of the pin. - pub pull: Pull, -} - -impl Default for OutputOpenDrainConfig { - fn default() -> Self { - Self { - level: Level::Low, - pull: Pull::None, - } - } -} - -/// Open drain digital output. -/// -/// This driver configures the GPIO pin to be an open drain output driver. -/// Open drain means that the driver actively pulls the output voltage level low -/// for the low logical [`Level`], but leaves the high level floating, which is -/// then determined by external hardware, or internal pull-up/pull-down -/// resistors. -#[derive(Debug)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct OutputOpenDrain<'d> { - pin: Flex<'d>, -} - -impl private::Sealed for OutputOpenDrain<'_> {} - -impl<'d> Peripheral for OutputOpenDrain<'d> { - type P = Flex<'d>; - unsafe fn clone_unchecked(&self) -> Self::P { - self.pin.clone_unchecked() - } -} - -impl<'d> OutputOpenDrain<'d> { - /// Creates a new GPIO output driver. - /// - /// The `initial_output` parameter sets the initial output level of the pin. - /// The `pull` parameter configures internal pull-up or pull-down - /// resistors. - /// - /// ## Example - /// - /// The following example configures `GPIO5` to pulse a LED once. The - /// example assumes that the LED is connected such that it is on when - /// the pin is low. - /// - /// ```rust, no_run - #[doc = crate::before_snippet!()] - /// use esp_hal::gpio::{ - /// Level, OutputOpenDrain, OutputOpenDrainConfig, Pull, - /// }; - /// use esp_hal::delay::Delay; - /// - /// fn blink_once(led: &mut OutputOpenDrain<'_>, delay: &mut Delay) { - /// led.set_low(); - /// delay.delay_millis(500); - /// led.set_high(); - /// } - /// - /// let config = OutputOpenDrainConfig::default() - /// .with_level(Level::High) - /// .with_pull(Pull::Up); - /// let mut led = OutputOpenDrain::new(peripherals.GPIO5, config).unwrap(); - /// let mut delay = Delay::new(); - /// - /// blink_once(&mut led, &mut delay); - /// # } - /// ``` - #[inline] - pub fn new( - pin: impl Peripheral

+ 'd, - config: OutputOpenDrainConfig, - ) -> Result { - let mut pin = Flex::new(pin); - - pin.set_level(config.level); - pin.set_as_open_drain(config.pull); - - Ok(Self { pin }) - } - - /// Change the configuration. - pub fn apply_config(&mut self, config: &OutputOpenDrainConfig) -> Result<(), ConfigError> { - self.set_level(config.level); - self.pin.set_as_open_drain(config.pull); - Ok(()) - } - - /// Split the pin into an input and output signal. - /// - /// Peripheral signals allow connecting peripherals together without using - /// external hardware. - /// ```rust, no_run - #[doc = crate::before_snippet!()] - /// # use esp_hal::gpio::{OutputOpenDrain, OutputOpenDrainConfig, Level, Pull}; - /// let config = OutputOpenDrainConfig::default() - /// .with_level(Level::High) - /// .with_pull(Pull::Up); - /// let pin1 = OutputOpenDrain::new( - /// peripherals.GPIO1, - /// config, - /// ).unwrap(); - /// let (input, output) = pin1.split(); - /// # } - /// ``` + /// Converts the pin driver into a [`Flex`] driver. #[inline] #[instability::unstable] - pub fn split(self) -> (interconnect::InputSignal, interconnect::OutputSignal) { - self.pin.split() - } - - /// Returns a peripheral [input][interconnect::InputSignal] connected to - /// this pin. - /// - /// The input signal can be passed to peripherals in place of an input pin. - /// ```rust, no_run - #[doc = crate::before_snippet!()] - /// # use esp_hal::gpio::{OutputOpenDrain, OutputOpenDrainConfig, Level, Pull}; - /// let config = OutputOpenDrainConfig::default() - /// .with_level(Level::High) - /// .with_pull(Pull::Up); - /// let pin1_gpio = OutputOpenDrain::new( - /// peripherals.GPIO1, - /// config, - /// ).unwrap(); - /// // Can be passed as an input. - /// let pin1 = pin1_gpio.peripheral_input(); - /// # } - /// ``` - #[inline] - #[instability::unstable] - pub fn peripheral_input(&self) -> interconnect::InputSignal { - self.pin.peripheral_input() - } - - /// Turns the pin object into a peripheral - /// [output][interconnect::OutputSignal]. - /// - /// The output signal can be passed to peripherals in place of an output - /// pin. - /// ```rust, no_run - #[doc = crate::before_snippet!()] - /// # use esp_hal::gpio::{OutputOpenDrain, OutputOpenDrainConfig, Level, Pull}; - /// let config = OutputOpenDrainConfig::default() - /// .with_level(Level::High) - /// .with_pull(Pull::Up); - /// let pin1_gpio = OutputOpenDrain::new( - /// peripherals.GPIO1, - /// config, - /// ).unwrap(); - /// // Can be passed as an input. - /// let pin1 = pin1_gpio.into_peripheral_output(); - /// # } - /// ``` - #[inline] - #[instability::unstable] - pub fn into_peripheral_output(self) -> interconnect::OutputSignal { - self.pin.into_peripheral_output() - } - - /// Get whether the pin input level is high. - #[inline] - pub fn is_high(&self) -> bool { - self.level() == Level::High - } - - /// Get whether the pin input level is low. - #[inline] - pub fn is_low(&self) -> bool { - self.level() == Level::Low - } - - /// Get the current pin input level. - #[inline] - pub fn level(&self) -> Level { - self.pin.level() - } - - /// Listen for interrupts. - /// - /// See [`Input::listen`] for more information and an example. - #[inline] - #[instability::unstable] - pub fn listen(&mut self, event: Event) { - self.pin.listen(event); - } - - /// Stop listening for interrupts. - #[inline] - #[instability::unstable] - pub fn unlisten(&mut self) { - self.pin.unlisten(); - } - - /// Clear the interrupt status bit for this Pin - #[inline] - #[instability::unstable] - pub fn clear_interrupt(&mut self) { - self.pin.clear_interrupt(); - } - - /// Set the output as high. - #[inline] - pub fn set_high(&mut self) { - self.set_level(Level::High); - } - - /// Set the output as low. - #[inline] - pub fn set_low(&mut self) { - self.set_level(Level::Low); - } - - /// Set the output level. - #[inline] - pub fn set_level(&mut self, level: Level) { - self.pin.set_level(level); - } - - /// Is the output pin set as high? - #[inline] - pub fn is_set_high(&self) -> bool { - self.output_level() == Level::High - } - - /// Is the output pin set as low? - #[inline] - pub fn is_set_low(&self) -> bool { - self.output_level() == Level::Low - } - - /// What level output is set to - #[inline] - pub fn output_level(&self) -> Level { - self.pin.output_level() - } - - /// Toggle pin output - #[inline] - pub fn toggle(&mut self) { - self.pin.toggle() - } - - /// Configure the [DriveStrength] of the pin - pub fn set_drive_strength(&mut self, strength: DriveStrength) { - self.pin.set_drive_strength(strength); + pub fn into_flex(self) -> Flex<'d> { + self.pin } } @@ -1817,6 +1615,21 @@ impl<'d> Flex<'d> { #[instability::unstable] pub fn new(pin: impl Peripheral

> + 'd) -> Self { crate::into_mapped_ref!(pin); + + #[cfg(usb_device)] + disable_usb_pads(pin.number()); + + GPIO::regs() + .func_out_sel_cfg(pin.number() as usize) + .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); + + // Use RMW to not overwrite sleep configuration + io_mux_reg(pin.number()).modify(|_, w| unsafe { + w.mcu_sel().bits(GPIO_FUNCTION as u8); + w.fun_ie().clear_bit(); + w.slp_sel().clear_bit() + }); + Self { pin } } @@ -1842,14 +1655,6 @@ impl<'d> Flex<'d> { unsafe { AnyPin::steal(self.number()) }.split().0 } - /// Set the GPIO to input mode. - #[inline] - #[instability::unstable] - pub fn set_as_input(&mut self, pull: Pull) { - self.pin.init_input(pull); - self.pin.enable_output(false); - } - /// Get whether the pin input level is high. #[inline] #[instability::unstable] @@ -2019,6 +1824,50 @@ impl<'d> Flex<'d> { self.pin.pull_direction(pull); } + /// Configure pullup/pulldown resistors. + #[inline] + #[instability::unstable] + pub fn pull_direction(&mut self, pull: Pull) { + self.pin.pull_direction(pull); + } + + /// Enable or disable the GPIO pin input buffer. + #[inline] + #[instability::unstable] + pub fn enable_input(&mut self, enable_input: bool) { + self.pin.enable_input(enable_input); + } + + /// Applies the given output configuration to the pin. + #[inline] + #[instability::unstable] + pub fn apply_output_config(&mut self, config: &OutputConfig) { + let pull_up = config.pull == Pull::Up; + let pull_down = config.pull == Pull::Down; + + #[cfg(esp32)] + crate::soc::gpio::errata36(AnyPin(self.pin.0), pull_up, pull_down); + + io_mux_reg(self.number()).modify(|_, w| { + unsafe { w.fun_drv().bits(config.drive_strength as u8) }; + w.fun_wpu().bit(pull_up); + w.fun_wpd().bit(pull_down); + w + }); + + GPIO::regs().pin(self.number() as usize).modify(|_, w| { + w.pad_driver() + .bit(config.drive_mode == DriveMode::OpenDrain) + }); + } + + /// Applies the given input configuration to the pin. + #[inline] + #[instability::unstable] + pub fn apply_input_config(&mut self, config: &InputConfig) { + self.pin.pull_direction(config.pull); + } + /// Split the pin into an input and output signal. /// /// Peripheral signals allow connecting peripherals together without using @@ -2337,7 +2186,9 @@ mod asynch { // We construct the Future first, because its `Drop` implementation // is load-bearing if `wait_for` is dropped during the initialization. let mut future = PinFuture { - pin: Flex::new(unsafe { self.pin.clone_unchecked() }), + pin: Flex { + pin: unsafe { self.pin.clone_unchecked() }, + }, }; // Make sure this pin is not being processed by an interrupt handler. @@ -2585,42 +2436,6 @@ mod embedded_hal_impls { } } - impl digital::InputPin for OutputOpenDrain<'_> { - fn is_high(&mut self) -> Result { - Ok(Self::is_high(self)) - } - - fn is_low(&mut self) -> Result { - Ok(Self::is_low(self)) - } - } - - impl digital::ErrorType for OutputOpenDrain<'_> { - type Error = core::convert::Infallible; - } - - impl digital::OutputPin for OutputOpenDrain<'_> { - fn set_low(&mut self) -> Result<(), Self::Error> { - Self::set_low(self); - Ok(()) - } - - fn set_high(&mut self) -> Result<(), Self::Error> { - Self::set_high(self); - Ok(()) - } - } - - impl digital::StatefulOutputPin for OutputOpenDrain<'_> { - fn is_set_high(&mut self) -> Result { - Ok(Self::is_set_high(self)) - } - - fn is_set_low(&mut self) -> Result { - Ok(Self::is_set_low(self)) - } - } - #[instability::unstable] impl digital::InputPin for Flex<'_> { fn is_high(&mut self) -> Result { diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index af61c53ff..2b489c80e 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -80,8 +80,7 @@ //! let peripherals = esp_hal::init(config); //! //! // Set GPIO0 as an output, and set its state high initially. -//! let config = OutputConfig::default().with_level(Level::High); -//! let mut led = Output::new(peripherals.GPIO0, config).unwrap(); +//! let mut led = Output::new(peripherals.GPIO0, Level::High, OutputConfig::default()); //! //! let delay = Delay::new(); //! diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 8c482cc0f..fb623f65b 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -39,8 +39,8 @@ //! // Set up channels with control and edge signals //! let ch0 = &u0.channel0; //! let config = InputConfig::default().with_pull(Pull::Up); -//! let pin_a = Input::new(peripherals.GPIO4, config).unwrap(); -//! let pin_b = Input::new(peripherals.GPIO5, config).unwrap(); +//! let pin_a = Input::new(peripherals.GPIO4, config); +//! let pin_b = Input::new(peripherals.GPIO5, config); //! let (input_a, _) = pin_a.split(); //! let (input_b, _) = pin_b.split(); //! ch0.set_ctrl_signal(input_a.clone()); diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 25989ec66..d62ebe1e7 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -118,8 +118,11 @@ //! //! const WIDTH: usize = 80; //! -//! let config = OutputConfig::default().with_level(Level::Low); -//! let mut out = Output::new(peripherals.GPIO5, config).unwrap(); +//! let mut out = Output::new( +//! peripherals.GPIO5, +//! Level::Low, +//! OutputConfig::default(), +//! ); //! //! // Configure frequency based on chip type #![cfg_attr(esp32h2, doc = "let freq = 32.MHz();")] diff --git a/esp-hal/src/rtc_cntl/sleep/mod.rs b/esp-hal/src/rtc_cntl/sleep/mod.rs index 5127b4edc..b321c3ced 100644 --- a/esp-hal/src/rtc_cntl/sleep/mod.rs +++ b/esp-hal/src/rtc_cntl/sleep/mod.rs @@ -112,7 +112,7 @@ pub enum Error { /// /// let config = InputConfig::default().with_pull(Pull::None); /// let mut pin_4 = peripherals.GPIO4; -/// let pin_4_input = Input::new(&mut pin_4, config).unwrap(); +/// let pin_4_input = Input::new(&mut pin_4, config); /// /// let reason = /// reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); @@ -167,7 +167,7 @@ impl<'a, P: RtcIoWakeupPinType> Ext0WakeupSource<'a, P> { /// let config = InputConfig::default().with_pull(Pull::None); /// let mut pin_2 = peripherals.GPIO2; /// let mut pin_4 = peripherals.GPIO4; -/// let pin_4_driver = Input::new(&mut pin_4, config).unwrap(); +/// let pin_4_driver = Input::new(&mut pin_4, config); /// /// let reason = reset_reason(Cpu::ProCpu) /// .unwrap_or(SocResetReason::ChipPowerOn); @@ -224,7 +224,7 @@ impl<'a, 'b> Ext1WakeupSource<'a, 'b> { /// let config = InputConfig::default().with_pull(Pull::None); /// let mut pin2 = peripherals.GPIO2; /// let mut pin3 = peripherals.GPIO3; -/// let mut pin2_input = Input::new(&mut pin2, config).unwrap(); +/// let mut pin2_input = Input::new(&mut pin2, config); /// /// let reason = /// reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); diff --git a/examples/src/bin/embassy_multicore.rs b/examples/src/bin/embassy_multicore.rs index 35b0bd3f9..da5b9ee24 100644 --- a/examples/src/bin/embassy_multicore.rs +++ b/examples/src/bin/embassy_multicore.rs @@ -63,8 +63,7 @@ async fn main(_spawner: Spawner) { static LED_CTRL: StaticCell> = StaticCell::new(); let led_ctrl_signal = &*LED_CTRL.init(Signal::new()); - let config = OutputConfig::default().with_level(Level::Low); - let led = Output::new(peripherals.GPIO0, config).unwrap(); + let led = Output::new(peripherals.GPIO0, Level::Low, OutputConfig::default()); let _guard = cpu_control .start_app_core(unsafe { &mut *addr_of_mut!(APP_CORE_STACK) }, move || { diff --git a/examples/src/bin/embassy_multicore_interrupt.rs b/examples/src/bin/embassy_multicore_interrupt.rs index 8b6e5630d..ca160d3fe 100644 --- a/examples/src/bin/embassy_multicore_interrupt.rs +++ b/examples/src/bin/embassy_multicore_interrupt.rs @@ -85,8 +85,7 @@ fn main() -> ! { static LED_CTRL: StaticCell> = StaticCell::new(); let led_ctrl_signal = &*LED_CTRL.init(Signal::new()); - let config = OutputConfig::default().with_level(Level::Low); - let led = Output::new(peripherals.GPIO0, config).unwrap(); + let led = Output::new(peripherals.GPIO0, Level::Low, OutputConfig::default()); static EXECUTOR_CORE_1: StaticCell> = StaticCell::new(); let executor_core1 = InterruptExecutor::new(sw_ints.software_interrupt1); diff --git a/examples/src/bin/embassy_rmt_rx.rs b/examples/src/bin/embassy_rmt_rx.rs index 8f5670b94..d29d77575 100644 --- a/examples/src/bin/embassy_rmt_rx.rs +++ b/examples/src/bin/embassy_rmt_rx.rs @@ -68,13 +68,11 @@ async fn main(spawner: Spawner) { } spawner - .spawn(signal_task( - Output::new( - peripherals.GPIO5, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(), - )) + .spawn(signal_task(Output::new( + peripherals.GPIO5, + Level::Low, + OutputConfig::default(), + ))) .unwrap(); let mut data: [u32; 48] = [PulseCode::empty(); 48]; diff --git a/examples/src/bin/etm_timer.rs b/examples/src/bin/etm_timer.rs index 9dd751994..3e76e6cb1 100644 --- a/examples/src/bin/etm_timer.rs +++ b/examples/src/bin/etm_timer.rs @@ -31,8 +31,7 @@ use esp_hal::{ fn main() -> ! { let peripherals = esp_hal::init(esp_hal::Config::default()); - let config = OutputConfig::default().with_level(Level::Low); - let mut led = Output::new(peripherals.GPIO2, config).unwrap(); + let mut led = Output::new(peripherals.GPIO2, Level::Low, OutputConfig::default()); led.set_high(); let syst = SystemTimer::new(peripherals.SYSTIMER); diff --git a/examples/src/bin/gpio_interrupt.rs b/examples/src/bin/gpio_interrupt.rs index 61c5072a5..288fb30c9 100644 --- a/examples/src/bin/gpio_interrupt.rs +++ b/examples/src/bin/gpio_interrupt.rs @@ -35,8 +35,7 @@ fn main() -> ! { let mut io = Io::new(peripherals.IO_MUX); io.set_interrupt_handler(handler); - let config = OutputConfig::default().with_level(Level::Low); - let mut led = Output::new(peripherals.GPIO2, config).unwrap(); + let mut led = Output::new(peripherals.GPIO2, Level::Low, OutputConfig::default()); cfg_if::cfg_if! { if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] { @@ -47,7 +46,7 @@ fn main() -> ! { } let config = InputConfig::default().with_pull(Pull::Up); - let mut button = Input::new(button, config).unwrap(); + let mut button = Input::new(button, config); critical_section::with(|cs| { button.listen(Event::FallingEdge); diff --git a/examples/src/bin/spi_slave_dma.rs b/examples/src/bin/spi_slave_dma.rs index 8340ffcb0..1077655ff 100644 --- a/examples/src/bin/spi_slave_dma.rs +++ b/examples/src/bin/spi_slave_dma.rs @@ -44,26 +44,13 @@ use esp_println::println; fn main() -> ! { let peripherals = esp_hal::init(esp_hal::Config::default()); - let mut master_sclk = Output::new( - peripherals.GPIO4, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(); + let mut master_sclk = Output::new(peripherals.GPIO4, Level::Low, OutputConfig::default()); let master_miso = Input::new( peripherals.GPIO5, InputConfig::default().with_pull(Pull::None), - ) - .unwrap(); - let mut master_mosi = Output::new( - peripherals.GPIO8, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(); - let mut master_cs = Output::new( - peripherals.GPIO9, - OutputConfig::default().with_level(Level::High), - ) - .unwrap(); + ); + let mut master_mosi = Output::new(peripherals.GPIO8, Level::Low, OutputConfig::default()); + let mut master_cs = Output::new(peripherals.GPIO9, Level::Low, OutputConfig::default()); let slave_sclk = peripherals.GPIO0; let slave_miso = peripherals.GPIO1; diff --git a/examples/src/bin/wifi_ble.rs b/examples/src/bin/wifi_ble.rs index 182d440b6..62038bffc 100644 --- a/examples/src/bin/wifi_ble.rs +++ b/examples/src/bin/wifi_ble.rs @@ -55,9 +55,9 @@ fn main() -> ! { let config = InputConfig::default().with_pull(Pull::Down); cfg_if::cfg_if! { if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] { - let button = Input::new(peripherals.GPIO0, config).unwrap(); + let button = Input::new(peripherals.GPIO0, config); } else { - let button = Input::new(peripherals.GPIO9, config).unwrap(); + let button = Input::new(peripherals.GPIO9, config); } } diff --git a/examples/src/bin/wifi_embassy_ble.rs b/examples/src/bin/wifi_embassy_ble.rs index 5a23cc2c0..3a7c0362d 100644 --- a/examples/src/bin/wifi_embassy_ble.rs +++ b/examples/src/bin/wifi_embassy_ble.rs @@ -70,9 +70,9 @@ async fn main(_spawner: Spawner) -> ! { let config = InputConfig::default().with_pull(Pull::Down); cfg_if::cfg_if! { if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] { - let button = Input::new(peripherals.GPIO0, config).unwrap(); + let button = Input::new(peripherals.GPIO0, config); } else { - let button = Input::new(peripherals.GPIO9, config).unwrap(); + let button = Input::new(peripherals.GPIO9, config); } } diff --git a/hil-test/tests/gpio.rs b/hil-test/tests/gpio.rs index e6d9f69ca..d769cd3ab 100644 --- a/hil-test/tests/gpio.rs +++ b/hil-test/tests/gpio.rs @@ -19,7 +19,7 @@ use esp_hal::gpio::{AnyPin, Input, InputConfig, Level, Output, OutputConfig, Pin use esp_hal::{ // OutputOpenDrain is here because will be unused otherwise delay::Delay, - gpio::{Event, Flex, Io, OutputOpenDrain, OutputOpenDrainConfig}, + gpio::{DriveMode, Event, Flex, Io}, handler, timer::timg::TimerGroup, }; @@ -93,10 +93,8 @@ mod tests { test_gpio2, .. } = ctx; - let mut test_gpio1 = - Input::new(test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); - let mut test_gpio2 = - Output::new(test_gpio2, OutputConfig::default().with_level(Level::Low)).unwrap(); + let mut test_gpio1 = Input::new(test_gpio1, InputConfig::default().with_pull(Pull::Down)); + let mut test_gpio2 = Output::new(test_gpio2, Level::Low, OutputConfig::default()); embassy_futures::select::select( async { loop { @@ -119,8 +117,7 @@ mod tests { #[test] async fn a_pin_can_wait(ctx: Context) { - let mut first = - Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); + let mut first = Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)); embassy_futures::select::select( first.wait_for_rising_edge(), @@ -133,8 +130,7 @@ mod tests { #[test] fn gpio_input(ctx: Context) { - let test_gpio1 = - Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); + let test_gpio1 = Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)); // `InputPin`: assert_eq!(test_gpio1.is_low(), true); assert_eq!(test_gpio1.is_high(), false); @@ -143,23 +139,15 @@ mod tests { #[test] async fn waiting_for_level_does_not_hang(ctx: Context) { let mut test_gpio1 = - Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); - let _test_gpio2 = Output::new( - ctx.test_gpio2, - OutputConfig::default().with_level(Level::High), - ) - .unwrap(); + Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)); + let _test_gpio2 = Output::new(ctx.test_gpio2, Level::High, OutputConfig::default()); test_gpio1.wait_for_high().await; } #[test] fn gpio_output(ctx: Context) { - let mut test_gpio2 = Output::new( - ctx.test_gpio2, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(); + let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low, OutputConfig::default()); // `StatefulOutputPin`: assert_eq!(test_gpio2.is_set_low(), true); @@ -179,13 +167,8 @@ mod tests { #[test] fn gpio_output_embedded_hal_1_0(ctx: Context) { - let test_gpio1 = - Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); - let mut test_gpio2 = Output::new( - ctx.test_gpio2, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(); + let test_gpio1 = Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)); + let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low, OutputConfig::default()); fn set(pin: &mut T, state: bool) where @@ -233,12 +216,8 @@ mod tests { #[cfg(feature = "unstable")] // Interrupts are unstable fn gpio_interrupt(ctx: Context) { let mut test_gpio1 = - Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)).unwrap(); - let mut test_gpio2 = Output::new( - ctx.test_gpio2, - OutputConfig::default().with_level(Level::Low), - ) - .unwrap(); + Input::new(ctx.test_gpio1, InputConfig::default().with_pull(Pull::Down)); + let mut test_gpio2 = Output::new(ctx.test_gpio2, Level::Low, OutputConfig::default()); critical_section::with(|cs| { *COUNTER.borrow_ref_mut(cs) = 0; @@ -275,51 +254,54 @@ mod tests { #[test] #[cfg(feature = "unstable")] // delay is unstable fn gpio_od(ctx: Context) { - let config = OutputOpenDrainConfig::default() - .with_level(Level::High) - .with_pull(Pull::Up); - let mut test_gpio1 = OutputOpenDrain::new(ctx.test_gpio1, config).unwrap(); - let mut test_gpio2 = OutputOpenDrain::new(ctx.test_gpio2, config).unwrap(); + let input_pull_up = InputConfig::default().with_pull(Pull::Up); + let input_pull_down = InputConfig::default().with_pull(Pull::Down); + let input_no_pull = InputConfig::default().with_pull(Pull::None); + + let mut output = Output::new( + ctx.test_gpio1, + Level::High, + OutputConfig::default() + .with_drive_mode(DriveMode::OpenDrain) + .with_pull(Pull::None), + ); + let mut input = Input::new(ctx.test_gpio2, input_pull_up); ctx.delay.delay_millis(1); - assert_eq!(test_gpio1.is_high(), true); - assert_eq!(test_gpio2.is_high(), true); + // With pull up resistor - test_gpio1.set_low(); - test_gpio2.set_high(); + assert_eq!(input.level(), Level::High); + output.set_low(); ctx.delay.delay_millis(1); - - assert_eq!(test_gpio1.is_low(), true); - assert_eq!(test_gpio2.is_low(), true); - - test_gpio1.set_high(); - test_gpio2.set_high(); + assert_eq!(input.level(), Level::Low); + output.set_high(); ctx.delay.delay_millis(1); + assert_eq!(input.level(), Level::High); - assert_eq!(test_gpio1.is_high(), true); - assert_eq!(test_gpio2.is_high(), true); + // With pull down resistor + input.apply_config(&input_pull_down); - test_gpio1.set_high(); - test_gpio2.set_low(); + output.set_high(); ctx.delay.delay_millis(1); - - assert_eq!(test_gpio1.is_low(), true); - assert_eq!(test_gpio2.is_low(), true); - - test_gpio1.set_high(); - test_gpio2.set_high(); + assert_eq!(input.level(), Level::Low); + output.set_low(); ctx.delay.delay_millis(1); + assert_eq!(input.level(), Level::Low); - assert_eq!(test_gpio1.is_high(), true); - assert_eq!(test_gpio2.is_high(), true); + // With pull up on output + input.apply_config(&input_no_pull); + output.apply_config( + &OutputConfig::default() + .with_drive_mode(DriveMode::OpenDrain) + .with_pull(Pull::Up), + ); - test_gpio1.set_low(); - test_gpio2.set_low(); ctx.delay.delay_millis(1); - - assert_eq!(test_gpio1.is_low(), true); - assert_eq!(test_gpio2.is_low(), true); + assert_eq!(input.level(), Level::Low); + output.set_high(); + ctx.delay.delay_millis(1); + assert_eq!(input.level(), Level::High); } #[test] @@ -330,7 +312,7 @@ mod tests { test_gpio1.set_high(); test_gpio1.set_as_output(); - test_gpio2.set_as_input(Pull::None); + test_gpio2.enable_input(true); ctx.delay.delay_millis(1); @@ -343,7 +325,7 @@ mod tests { assert_eq!(test_gpio1.is_set_high(), false); assert_eq!(test_gpio2.is_high(), false); - test_gpio1.set_as_input(Pull::None); + test_gpio1.enable_input(true); test_gpio2.set_as_output(); ctx.delay.delay_millis(1); @@ -370,9 +352,8 @@ mod tests { let any_pin2 = ctx.test_gpio1; let any_pin3 = ctx.test_gpio2; - let out_pin = - Output::new(any_pin2, OutputConfig::default().with_level(Level::High)).unwrap(); - let in_pin = Input::new(any_pin3, InputConfig::default().with_pull(Pull::Down)).unwrap(); + let out_pin = Output::new(any_pin2, Level::High, OutputConfig::default()); + let in_pin = Input::new(any_pin3, InputConfig::default().with_pull(Pull::Down)); assert_eq!(out_pin.is_set_high(), true); assert_eq!(in_pin.is_high(), true); @@ -385,9 +366,8 @@ mod tests { let any_pin2 = ctx.test_gpio1; let any_pin3 = ctx.test_gpio2; - let out_pin = - Output::new(any_pin3, OutputConfig::default().with_level(Level::Low)).unwrap(); - let in_pin = Input::new(any_pin2, InputConfig::default().with_pull(Pull::Down)).unwrap(); + let out_pin = Output::new(any_pin3, Level::Low, OutputConfig::default()); + let in_pin = Input::new(any_pin2, InputConfig::default().with_pull(Pull::Down)); assert_eq!(out_pin.is_set_high(), false); assert_eq!(in_pin.is_high(), false); @@ -398,7 +378,7 @@ mod tests { fn can_configure_rtcio_pins_as_input() { let pin = unsafe { esp_hal::gpio::GpioPin::<37>::steal() }; - _ = Input::new(pin, InputConfig::default().with_pull(Pull::Down)).unwrap(); + _ = Input::new(pin, InputConfig::default().with_pull(Pull::Down)); } #[test] @@ -419,7 +399,7 @@ mod tests { #[embassy_executor::task] async fn test_task(pin: AnyPin) { - let mut pin = Input::new(pin, InputConfig::default().with_pull(Pull::Down)).unwrap(); + let mut pin = Input::new(pin, InputConfig::default().with_pull(Pull::Down)); // This line must return, even if the executor // is running at a higher priority than the GPIO handler. diff --git a/hil-test/tests/gpio_custom_handler.rs b/hil-test/tests/gpio_custom_handler.rs index 5fd2f8283..9ecae662a 100644 --- a/hil-test/tests/gpio_custom_handler.rs +++ b/hil-test/tests/gpio_custom_handler.rs @@ -41,10 +41,8 @@ pub fn interrupt_handler() { async fn drive_pins(gpio1: impl Into, gpio2: impl Into) -> usize { let counter = AtomicUsize::new(0); - let mut test_gpio1 = - Input::new(gpio1.into(), InputConfig::default().with_pull(Pull::Down)).unwrap(); - let mut test_gpio2 = - Output::new(gpio2.into(), OutputConfig::default().with_level(Level::Low)).unwrap(); + let mut test_gpio1 = Input::new(gpio1.into(), InputConfig::default().with_pull(Pull::Down)); + let mut test_gpio2 = Output::new(gpio2.into(), Level::Low, OutputConfig::default()); embassy_futures::select::select( async { loop { diff --git a/hil-test/tests/i2s_parallel.rs b/hil-test/tests/i2s_parallel.rs index a0a81a02b..bd877c768 100644 --- a/hil-test/tests/i2s_parallel.rs +++ b/hil-test/tests/i2s_parallel.rs @@ -7,16 +7,10 @@ #![no_main] use esp_hal::{ - delay::Delay, - dma_buffers, - gpio::{AnyPin, NoPin, Pin}, - i2s::{ - master::{DataFormat, I2s, I2sTx, Standard}, - parallel::{I2sParallel, TxSixteenBits}, - }, + gpio::NoPin, + i2s::parallel::{I2sParallel, TxSixteenBits}, peripherals::I2S0, time::RateExtU32, - Async, }; use hil_test as _; diff --git a/hil-test/tests/pcnt.rs b/hil-test/tests/pcnt.rs index 02ef3eafc..fbd56529b 100644 --- a/hil-test/tests/pcnt.rs +++ b/hil-test/tests/pcnt.rs @@ -47,14 +47,14 @@ mod tests { let unit = ctx.pcnt.unit0; // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Down)).unwrap(), - ); + unit.channel0.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Down), + )); unit.channel0 .set_input_mode(EdgeMode::Hold, EdgeMode::Increment); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::Low)).unwrap(); + let mut output = Output::new(ctx.output, Level::Low, OutputConfig::default()); unit.resume(); @@ -86,14 +86,14 @@ mod tests { let unit = ctx.pcnt.unit1; // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Up)).unwrap(), - ); + unit.channel0.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Up), + )); unit.channel0 .set_input_mode(EdgeMode::Increment, EdgeMode::Hold); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::High)).unwrap(); + let mut output = Output::new(ctx.output, Level::High, OutputConfig::default()); unit.resume(); @@ -127,14 +127,14 @@ 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( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Up)).unwrap(), - ); + unit.channel0.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Up), + )); unit.channel0 .set_input_mode(EdgeMode::Increment, EdgeMode::Hold); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::High)).unwrap(); + let mut output = Output::new(ctx.output, Level::High, OutputConfig::default()); unit.resume(); @@ -190,14 +190,14 @@ mod tests { unit.clear(); // Setup channel 0 to increment the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Up)).unwrap(), - ); + unit.channel0.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Up), + )); unit.channel0 .set_input_mode(EdgeMode::Increment, EdgeMode::Hold); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::High)).unwrap(); + let mut output = Output::new(ctx.output, Level::High, OutputConfig::default()); unit.resume(); @@ -257,14 +257,14 @@ mod tests { unit.clear(); // Setup channel 0 to decrement the count when gpio2 does LOW -> HIGH - unit.channel0.set_edge_signal( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Up)).unwrap(), - ); + unit.channel0.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Up), + )); unit.channel0 .set_input_mode(EdgeMode::Decrement, EdgeMode::Hold); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::High)).unwrap(); + let mut output = Output::new(ctx.output, Level::High, OutputConfig::default()); unit.resume(); @@ -315,14 +315,14 @@ mod tests { let unit = ctx.pcnt.unit2; // Setup channel 1 to increment the count when gpio2 does LOW -> HIGH - unit.channel1.set_edge_signal( - Input::new(ctx.input, InputConfig::default().with_pull(Pull::Up)).unwrap(), - ); + unit.channel1.set_edge_signal(Input::new( + ctx.input, + InputConfig::default().with_pull(Pull::Up), + )); unit.channel1 .set_input_mode(EdgeMode::Increment, EdgeMode::Hold); - let mut output = - Output::new(ctx.output, OutputConfig::default().with_level(Level::High)).unwrap(); + let mut output = Output::new(ctx.output, Level::High, OutputConfig::default()); unit.resume(); diff --git a/hil-test/tests/qspi.rs b/hil-test/tests/qspi.rs index 8ff1e88e2..2497541b9 100644 --- a/hil-test/tests/qspi.rs +++ b/hil-test/tests/qspi.rs @@ -198,9 +198,9 @@ mod tests { // Make sure pins have no pullups let config = InputConfig::default().with_pull(Pull::Down); - let _ = Input::new(&mut pin, config).unwrap(); - let _ = Input::new(&mut pin_mirror, config).unwrap(); - let _ = Input::new(&mut unconnected_pin, config).unwrap(); + let _ = Input::new(&mut pin, config); + let _ = Input::new(&mut pin_mirror, config); + let _ = Input::new(&mut unconnected_pin, config); cfg_if::cfg_if! { if #[cfg(pdma)] { @@ -230,8 +230,7 @@ mod tests { #[test] fn test_spi_reads_correctly_from_gpio_pin_0(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio0(pin).with_dma(ctx.dma_channel); @@ -241,8 +240,7 @@ mod tests { #[test] fn test_spi_reads_correctly_from_gpio_pin_1(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio1(pin).with_dma(ctx.dma_channel); @@ -252,8 +250,7 @@ mod tests { #[test] fn test_spi_reads_correctly_from_gpio_pin_2(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio2(pin).with_dma(ctx.dma_channel); @@ -263,8 +260,7 @@ mod tests { #[test] fn test_spi_reads_correctly_from_gpio_pin_3(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio3(pin).with_dma(ctx.dma_channel); @@ -274,8 +270,7 @@ mod tests { #[test] fn test_spi_writes_and_reads_correctly_pin_0(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio0(pin).with_dma(ctx.dma_channel); @@ -285,8 +280,7 @@ mod tests { #[test] fn test_spi_writes_and_reads_correctly_pin_1(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio1(pin).with_dma(ctx.dma_channel); @@ -296,8 +290,7 @@ mod tests { #[test] fn test_spi_writes_and_reads_correctly_pin_2(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio2(pin).with_dma(ctx.dma_channel); @@ -307,8 +300,7 @@ mod tests { #[test] fn test_spi_writes_and_reads_correctly_pin_3(ctx: Context) { let [pin, pin_mirror, _] = ctx.gpios; - let pin_mirror = - Output::new(pin_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let pin_mirror = Output::new(pin_mirror, Level::High, OutputConfig::default()); let spi = ctx.spi.with_sio3(pin).with_dma(ctx.dma_channel); diff --git a/hil-test/tests/spi_half_duplex_read.rs b/hil-test/tests/spi_half_duplex_read.rs index 7e1482d47..5d1a700a3 100644 --- a/hil-test/tests/spi_half_duplex_read.rs +++ b/hil-test/tests/spi_half_duplex_read.rs @@ -37,8 +37,7 @@ mod tests { let sclk = peripherals.GPIO0; let (miso, miso_mirror) = hil_test::common_test_pins!(peripherals); - let miso_mirror = - Output::new(miso_mirror, OutputConfig::default().with_level(Level::High)).unwrap(); + let miso_mirror = Output::new(miso_mirror, Level::High, OutputConfig::default()); cfg_if::cfg_if! { if #[cfg(pdma)] { diff --git a/hil-test/tests/spi_slave.rs b/hil-test/tests/spi_slave.rs index 2c25acaae..b3ceff02f 100644 --- a/hil-test/tests/spi_slave.rs +++ b/hil-test/tests/spi_slave.rs @@ -115,12 +115,10 @@ mod tests { } } - let mosi_gpio = - Output::new(mosi_pin, OutputConfig::default().with_level(Level::Low)).unwrap(); - let cs_gpio = Output::new(cs_pin, OutputConfig::default().with_level(Level::High)).unwrap(); - let sclk_gpio = - Output::new(sclk_pin, OutputConfig::default().with_level(Level::Low)).unwrap(); - let miso_gpio = Input::new(miso_pin, InputConfig::default().with_pull(Pull::None)).unwrap(); + let mosi_gpio = Output::new(mosi_pin, Level::Low, OutputConfig::default()); + let cs_gpio = Output::new(cs_pin, Level::High, OutputConfig::default()); + let sclk_gpio = Output::new(sclk_pin, Level::Low, OutputConfig::default()); + let miso_gpio = Input::new(miso_pin, InputConfig::default().with_pull(Pull::None)); let cs = cs_gpio.peripheral_input(); let sclk = sclk_gpio.peripheral_input(); diff --git a/qa-test/src/bin/lcd_dpi.rs b/qa-test/src/bin/lcd_dpi.rs index f5f101032..c28b6add1 100644 --- a/qa-test/src/bin/lcd_dpi.rs +++ b/qa-test/src/bin/lcd_dpi.rs @@ -116,11 +116,8 @@ fn main() -> ! { let mut vsync_pin = peripherals.GPIO3; - let vsync_must_be_high_during_setup = Output::new( - &mut vsync_pin, - OutputConfig::default().with_level(Level::High), - ) - .unwrap(); + let vsync_must_be_high_during_setup = + Output::new(&mut vsync_pin, Level::High, OutputConfig::default()); for &init in INIT_CMDS.iter() { match init { InitCmd::Cmd(cmd, args) => { diff --git a/qa-test/src/bin/lcd_i8080.rs b/qa-test/src/bin/lcd_i8080.rs index e8739313a..b8009cbe9 100644 --- a/qa-test/src/bin/lcd_i8080.rs +++ b/qa-test/src/bin/lcd_i8080.rs @@ -53,10 +53,9 @@ fn main() -> ! { let delay = Delay::new(); - let config = OutputConfig::default().with_level(Level::Low); - let mut backlight = Output::new(lcd_backlight, config).unwrap(); - let mut reset = Output::new(lcd_reset, config).unwrap(); - let tear_effect = Input::new(lcd_te, InputConfig::default().with_pull(Pull::None)).unwrap(); + let mut backlight = Output::new(lcd_backlight, Level::Low, OutputConfig::default()); + let mut reset = Output::new(lcd_reset, Level::Low, OutputConfig::default()); + let tear_effect = Input::new(lcd_te, InputConfig::default().with_pull(Pull::None)); let tx_pins = TxEightBits::new( peripherals.GPIO9, diff --git a/qa-test/src/bin/sleep_timer_ext0.rs b/qa-test/src/bin/sleep_timer_ext0.rs index f7248d4f4..ca0f59cba 100644 --- a/qa-test/src/bin/sleep_timer_ext0.rs +++ b/qa-test/src/bin/sleep_timer_ext0.rs @@ -33,7 +33,7 @@ fn main() -> ! { let mut rtc = Rtc::new(peripherals.LPWR); let mut pin4 = peripherals.GPIO4; - let ext0_pin = Input::new(&mut pin4, InputConfig::default().with_pull(Pull::None)).unwrap(); + let ext0_pin = Input::new(&mut pin4, InputConfig::default().with_pull(Pull::None)); println!("up and runnning!"); let reason = reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); diff --git a/qa-test/src/bin/sleep_timer_ext1.rs b/qa-test/src/bin/sleep_timer_ext1.rs index 18cfe4240..bd059b0db 100644 --- a/qa-test/src/bin/sleep_timer_ext1.rs +++ b/qa-test/src/bin/sleep_timer_ext1.rs @@ -34,7 +34,7 @@ fn main() -> ! { let mut pin_2 = peripherals.GPIO2; let mut pin_4 = peripherals.GPIO4; - let input = Input::new(&mut pin_4, InputConfig::default().with_pull(Pull::None)).unwrap(); + let input = Input::new(&mut pin_4, InputConfig::default().with_pull(Pull::None)); println!("up and runnning!"); let reason = reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); diff --git a/qa-test/src/bin/sleep_timer_lpio.rs b/qa-test/src/bin/sleep_timer_lpio.rs index f8f92c38d..126109ddc 100644 --- a/qa-test/src/bin/sleep_timer_lpio.rs +++ b/qa-test/src/bin/sleep_timer_lpio.rs @@ -35,7 +35,7 @@ fn main() -> ! { let mut pin2 = peripherals.GPIO2; let mut pin3 = peripherals.GPIO3; - let input = Input::new(&mut pin2, InputConfig::default().with_pull(Pull::None)).unwrap(); + let input = Input::new(&mut pin2, InputConfig::default().with_pull(Pull::None)); println!("up and runnning!"); let reason = reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); diff --git a/qa-test/src/bin/sleep_timer_rtcio.rs b/qa-test/src/bin/sleep_timer_rtcio.rs index 486408a30..982119017 100644 --- a/qa-test/src/bin/sleep_timer_rtcio.rs +++ b/qa-test/src/bin/sleep_timer_rtcio.rs @@ -51,7 +51,7 @@ fn main() -> ! { if #[cfg(any(feature = "esp32c3", feature = "esp32c2"))] { let mut pin2 = peripherals.GPIO2; let mut pin3 = peripherals.GPIO3; - let _pin2_input = Input::new(&mut pin2, config).unwrap(); + let _pin2_input = Input::new(&mut pin2, config); let wakeup_pins: &mut [(&mut dyn gpio::RtcPinWithResistors, WakeupLevel)] = &mut [ (&mut pin2, WakeupLevel::Low), @@ -60,7 +60,7 @@ fn main() -> ! { } else if #[cfg(feature = "esp32s3")] { let mut pin17 = peripherals.GPIO17; let mut pin18 = peripherals.GPIO18; - let _pin17_input = Input::new(&mut pin17, config).unwrap(); + let _pin17_input = Input::new(&mut pin17, config); let wakeup_pins: &mut [(&mut dyn gpio::RtcPin, WakeupLevel)] = &mut [ (&mut pin17, WakeupLevel::Low),