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),