ariel_os_esp/
gpio.rs

1//! Provides GPIO access.
2
3pub mod input {
4    //! Input-specific types.
5
6    use esp_hal::gpio::{Level, Pull};
7
8    #[doc(hidden)]
9    pub use esp_hal::gpio::{Input, InputConfig, InputPin};
10
11    #[cfg(feature = "external-interrupts")]
12    use ariel_os_embassy_common::gpio::input::InterruptError;
13
14    // Re-export `Input` as `IntEnabledInput` as they are interrupt-enabled.
15    #[cfg(feature = "external-interrupts")]
16    #[doc(hidden)]
17    pub use esp_hal::gpio::Input as IntEnabledInput;
18
19    /// Whether inputs support configuring whether a Schmitt trigger is enabled.
20    pub const SCHMITT_TRIGGER_CONFIGURABLE: bool = false;
21
22    #[doc(hidden)]
23    pub fn new<'a>(
24        pin: impl InputPin + 'a,
25        pull: ariel_os_embassy_common::gpio::Pull,
26        _schmitt_trigger: bool, // Not supported by hardware
27    ) -> Result<Input<'a>, core::convert::Infallible> {
28        let pull = from_pull(pull);
29        let config = InputConfig::default().with_pull(pull);
30
31        Ok(Input::new(pin, config))
32    }
33
34    #[cfg(feature = "external-interrupts")]
35    #[doc(hidden)]
36    pub fn new_int_enabled<'a>(
37        pin: impl InputPin + 'a,
38        pull: ariel_os_embassy_common::gpio::Pull,
39        _schmitt_trigger: bool, // Not supported by hardware
40    ) -> Result<IntEnabledInput<'a>, InterruptError> {
41        #[expect(clippy::used_underscore_binding, reason = "just propagating")]
42        match new(pin, pull, _schmitt_trigger) {
43            Ok(input) => Ok(input),
44            Err(err) => match err {
45                // Compile-time check that this never happens as the Result is Infallible.
46            },
47        }
48    }
49
50    ariel_os_embassy_common::define_from_pull!();
51    ariel_os_embassy_common::define_into_level!();
52}
53
54pub mod output {
55    //! Output-specific types.
56
57    use esp_hal::gpio::Level;
58
59    #[doc(hidden)]
60    pub use esp_hal::gpio::{Output, OutputConfig, OutputPin};
61
62    /// Whether outputs support configuring their drive strength.
63    pub const DRIVE_STRENGTH_CONFIGURABLE: bool = true;
64    /// Whether outputs support configuring their speed/slew rate.
65    pub const SPEED_CONFIGURABLE: bool = false;
66
67    #[doc(hidden)]
68    pub fn new<'a>(
69        pin: impl OutputPin + 'a,
70        initial_level: ariel_os_embassy_common::gpio::Level,
71        drive_strength: super::DriveStrength,
72        _speed: super::Speed, // Not supported by hardware
73    ) -> Output<'a> {
74        let initial_level = match initial_level {
75            ariel_os_embassy_common::gpio::Level::Low => Level::Low,
76            ariel_os_embassy_common::gpio::Level::High => Level::High,
77        };
78        let config = OutputConfig::default().with_drive_strength(drive_strength.into());
79        Output::new(pin, initial_level, config)
80    }
81}
82
83pub use ariel_os_embassy_common::gpio::UnsupportedSpeed as Speed;
84
85/// Available drive strength settings.
86// We do not provide a `Default` impl as not all pins have the same reset value.
87#[derive(Copy, Clone, PartialEq, Eq)]
88pub enum DriveStrength {
89    /// 5 mA.
90    _5mA,
91    /// 10 mA.
92    _10mA,
93    /// 20 mA.
94    _20mA,
95    /// 40 mA.
96    _40mA,
97}
98
99impl From<DriveStrength> for esp_hal::gpio::DriveStrength {
100    fn from(drive_strength: DriveStrength) -> Self {
101        match drive_strength {
102            DriveStrength::_5mA => Self::_5mA,
103            DriveStrength::_10mA => Self::_10mA,
104            DriveStrength::_20mA => Self::_20mA,
105            DriveStrength::_40mA => Self::_40mA,
106        }
107    }
108}
109
110impl ariel_os_embassy_common::gpio::FromDriveStrength for DriveStrength {
111    fn from(drive_strength: ariel_os_embassy_common::gpio::DriveStrength<Self>) -> Self {
112        // ESPs are able to output up to 40 mA, so we somewhat normalize this.
113        match drive_strength {
114            ariel_os_embassy_common::gpio::DriveStrength::Hal(drive_strength) => drive_strength,
115            ariel_os_embassy_common::gpio::DriveStrength::Lowest => Self::_5mA,
116            ariel_os_embassy_common::gpio::DriveStrength::Standard
117            | ariel_os_embassy_common::gpio::DriveStrength::Medium => Self::_10mA,
118            ariel_os_embassy_common::gpio::DriveStrength::High => Self::_20mA,
119            ariel_os_embassy_common::gpio::DriveStrength::Highest => Self::_40mA,
120        }
121    }
122}