ariel_os_nrf/
gpio.rs

1//! Provides GPIO access.
2
3pub mod input {
4    //! Input-specific types.
5
6    use embassy_nrf::{
7        Peri,
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<P: InputPin>(
24        pin: Peri<'_, P>,
25        pull: ariel_os_embassy_common::gpio::Pull,
26        _schmitt_trigger: bool, // Not supported by hardware
27    ) -> Result<Input<'_>, 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<P: InputPin>(
35        mut pin: Peri<'_, P>,
36        pull: ariel_os_embassy_common::gpio::Pull,
37        _schmitt_trigger: bool, // Not supported by hardware
38    ) -> Result<IntEnabledInput<'_>, ariel_os_embassy_common::gpio::input::Error> {
39        let pull = from_pull(pull);
40        crate::extint_registry::EXTINT_REGISTRY.use_interrupt_for_pin(&mut pin)?;
41        Ok(Input::new(pin, pull))
42    }
43
44    ariel_os_embassy_common::define_from_pull!();
45    ariel_os_embassy_common::define_into_level!();
46}
47
48pub mod output {
49    //! Output-specific types.
50
51    use embassy_nrf::{
52        Peri,
53        gpio::{Level, OutputDrive},
54    };
55
56    use super::DriveStrength;
57
58    #[doc(hidden)]
59    pub use embassy_nrf::gpio::{Output, Pin as OutputPin};
60
61    /// Whether outputs support configuring their drive strength.
62    pub const DRIVE_STRENGTH_CONFIGURABLE: bool = true;
63    /// Whether outputs support configuring their speed/slew rate.
64    pub const SPEED_CONFIGURABLE: bool = false;
65
66    #[doc(hidden)]
67    pub fn new<P: OutputPin>(
68        pin: Peri<'_, P>,
69        initial_level: ariel_os_embassy_common::gpio::Level,
70        drive_strength: DriveStrength,
71        _speed: super::Speed, // Not supported by hardware
72    ) -> Output<'_> {
73        let output_drive = match drive_strength {
74            DriveStrength::Standard => OutputDrive::Standard,
75            DriveStrength::High => OutputDrive::HighDrive,
76        };
77        let initial_level = match initial_level {
78            ariel_os_embassy_common::gpio::Level::Low => Level::Low,
79            ariel_os_embassy_common::gpio::Level::High => Level::High,
80        };
81        Output::new(pin, initial_level, output_drive)
82    }
83}
84
85pub use ariel_os_embassy_common::gpio::UnsupportedSpeed as Speed;
86
87/// Available drive strength settings.
88#[derive(Copy, Clone, PartialEq, Eq, Default)]
89pub enum DriveStrength {
90    /// Standard.
91    #[default]
92    Standard,
93    /// High.
94    High, // Around 10 mA
95}
96
97impl ariel_os_embassy_common::gpio::FromDriveStrength for DriveStrength {
98    fn from(drive_strength: ariel_os_embassy_common::gpio::DriveStrength<Self>) -> Self {
99        // ESPs are able to output up to 40 mA, so we somewhat normalize this.
100        match drive_strength {
101            ariel_os_embassy_common::gpio::DriveStrength::Hal(drive_strength) => drive_strength,
102            ariel_os_embassy_common::gpio::DriveStrength::Lowest
103            | ariel_os_embassy_common::gpio::DriveStrength::Medium => Self::Standard,
104            ariel_os_embassy_common::gpio::DriveStrength::Standard => Self::default(),
105            ariel_os_embassy_common::gpio::DriveStrength::High
106            | ariel_os_embassy_common::gpio::DriveStrength::Highest => Self::High,
107        }
108    }
109}