ariel_os_nrf/
gpio.rs

1//! Provides GPIO access.
2
3pub mod input {
4    //! Input-specific types.
5
6    use embassy_nrf::{
7        Peripheral,
8        gpio::{Level, Pull},
9    };
10
11    #[doc(hidden)]
12    pub use embassy_nrf::gpio::{Input, Pin as InputPin};
13
14    // Re-export `Input` as `IntEnabledInput` as they are interrupt-enabled.
15    #[cfg(feature = "external-interrupts")]
16    #[doc(hidden)]
17    pub use embassy_nrf::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(
24        pin: impl Peripheral<P: InputPin> + 'static,
25        pull: ariel_os_embassy_common::gpio::Pull,
26        _schmitt_trigger: bool, // Not supported by hardware
27    ) -> Result<Input<'static>, ariel_os_embassy_common::gpio::input::Error> {
28        let pull = from_pull(pull);
29        Ok(Input::new(pin, pull))
30    }
31
32    #[cfg(feature = "external-interrupts")]
33    #[doc(hidden)]
34    pub fn new_int_enabled(
35        pin: impl Peripheral<P: InputPin> + 'static,
36        pull: ariel_os_embassy_common::gpio::Pull,
37        _schmitt_trigger: bool, // Not supported by hardware
38    ) -> Result<IntEnabledInput<'static>, ariel_os_embassy_common::gpio::input::Error> {
39        let pull = from_pull(pull);
40        let mut pin = pin.into_ref();
41        crate::extint_registry::EXTINT_REGISTRY.use_interrupt_for_pin(&mut pin)?;
42        Ok(Input::new(pin, pull))
43    }
44
45    ariel_os_embassy_common::define_from_pull!();
46    ariel_os_embassy_common::define_into_level!();
47}
48
49pub mod output {
50    //! Output-specific types.
51
52    use embassy_nrf::{
53        Peripheral,
54        gpio::{Level, OutputDrive},
55    };
56
57    use super::DriveStrength;
58
59    #[doc(hidden)]
60    pub use embassy_nrf::gpio::{Output, Pin as 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(
69        pin: impl Peripheral<P: OutputPin> + 'static,
70        initial_level: ariel_os_embassy_common::gpio::Level,
71        drive_strength: DriveStrength,
72        _speed: super::Speed, // Not supported by hardware
73    ) -> Output<'static> {
74        let output_drive = match drive_strength {
75            DriveStrength::Standard => OutputDrive::Standard,
76            DriveStrength::High => OutputDrive::HighDrive,
77        };
78        let initial_level = match initial_level {
79            ariel_os_embassy_common::gpio::Level::Low => Level::Low,
80            ariel_os_embassy_common::gpio::Level::High => Level::High,
81        };
82        Output::new(pin, initial_level, output_drive)
83    }
84}
85
86pub use ariel_os_embassy_common::gpio::UnsupportedSpeed as Speed;
87
88/// Available drive strength settings.
89#[derive(Copy, Clone, PartialEq, Eq, Default)]
90pub enum DriveStrength {
91    /// Standard.
92    #[default]
93    Standard,
94    /// High.
95    High, // Around 10 mA
96}
97
98impl ariel_os_embassy_common::gpio::FromDriveStrength for DriveStrength {
99    fn from(drive_strength: ariel_os_embassy_common::gpio::DriveStrength<Self>) -> Self {
100        // ESPs are able to output up to 40 mA, so we somewhat normalize this.
101        match drive_strength {
102            ariel_os_embassy_common::gpio::DriveStrength::Hal(drive_strength) => drive_strength,
103            ariel_os_embassy_common::gpio::DriveStrength::Lowest
104            | ariel_os_embassy_common::gpio::DriveStrength::Medium => Self::Standard,
105            ariel_os_embassy_common::gpio::DriveStrength::Standard => Self::default(),
106            ariel_os_embassy_common::gpio::DriveStrength::High
107            | ariel_os_embassy_common::gpio::DriveStrength::Highest => Self::High,
108        }
109    }
110}