diff --git a/esp-hal-common/src/gpio.rs b/esp-hal-common/src/gpio.rs index a3208fb67..5b57a5c54 100644 --- a/esp-hal-common/src/gpio.rs +++ b/esp-hal-common/src/gpio.rs @@ -6,247 +6,179 @@ //! //! [embedded-hal]: https://docs.rs/embedded-hal/latest/embedded_hal/ +use core::marker::PhantomData; + pub use paste::paste; -#[macro_export] -macro_rules! impl_output { - ( - $gpio_function:ident, - $pxi:ident: - ( - $pin_num:expr, $iomux_reg:expr, $bit:expr, $out_en_set:ident, - $out_en_clear:ident, $out_set:ident, $out_clear:ident, $out_reg:ident - ) - $( ,( $( $af_signal:ident: $af:ident ),* ))? - ) => { - impl embedded_hal::digital::v2::OutputPin for $pxi> { - type Error = Infallible; +#[derive(Copy, Clone)] +pub enum Event { + RisingEdge = 1, + FallingEdge = 2, + AnyEdge = 3, + LowLevel = 4, + HighLevel = 5, +} - fn set_high(&mut self) -> Result<(), Self::Error> { - unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) }; - Ok(()) - } +pub struct Unknown {} - fn set_low(&mut self) -> Result<(), Self::Error> { - unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) }; - Ok(()) - } - } +pub struct Input { + _mode: PhantomData, +} - impl embedded_hal::digital::v2::StatefulOutputPin for $pxi> { - fn is_set_high(&self) -> Result { - unsafe { Ok((*GPIO::ptr()).$out_reg.read().bits() & (1 << $bit) != 0) } - } +pub struct RTCInput { + _mode: PhantomData, +} - fn is_set_low(&self) -> Result { - Ok(!self.is_set_high()?) - } - } +pub struct Floating; - impl embedded_hal::digital::v2::ToggleableOutputPin for $pxi> { - type Error = Infallible; +pub struct PullDown; - fn toggle(&mut self) -> Result<(), Self::Error> { - if self.is_set_high()? { - Ok(self.set_low()?) - } else { - Ok(self.set_high()?) - } - } - } +pub struct PullUp; - impl $pxi { - pub fn into_pull_up_input(self) -> $pxi> { - self.init_input(false, false); - $pxi { _mode: PhantomData } - } +pub struct Output { + _mode: PhantomData, +} - pub fn into_pull_down_input(self) -> $pxi> { - self.init_input(true, false); - $pxi { _mode: PhantomData } - } +pub struct RTCOutput { + _mode: PhantomData, +} - fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { - let gpio = unsafe { &*GPIO::ptr() }; - let iomux = unsafe { &*IO_MUX::ptr() }; +pub struct OpenDrain; - gpio.$out_en_set.write(|w| unsafe { w.bits(1 << $bit) }); - gpio.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(open_drain)); - gpio.func_out_sel_cfg[$pin_num] - .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); +pub struct PushPull; - paste! { - iomux.$iomux_reg.modify(|_, w| unsafe { - w.mcu_sel() - .bits(alternate as u8) - .fun_ie() - .clear_bit() - .fun_wpd() - .clear_bit() - .fun_wpu() - .clear_bit() - .fun_drv() - .bits(DriveStrength::I20mA as u8) - .slp_sel() - .clear_bit() - }); - } - } +pub struct Analog; - pub fn into_push_pull_output(self) -> $pxi> { - self.init_output(AlternateFunction::$gpio_function, false); - $pxi { _mode: PhantomData } - } +pub struct Alternate { + _mode: PhantomData, +} - pub fn into_open_drain_output(self) -> $pxi> { - self.init_output(AlternateFunction::$gpio_function, true); - $pxi { _mode: PhantomData } - } +pub struct AF0; - pub fn into_alternate_1(self) -> $pxi> { - self.init_output(AlternateFunction::Function1, false); - $pxi { _mode: PhantomData } - } +pub struct AF1; - pub fn into_alternate_2(self) -> $pxi> { - self.init_output(AlternateFunction::Function2, false); - $pxi { _mode: PhantomData } - } - } +pub struct AF2; - impl OutputPin for $pxi { - fn set_to_open_drain_output(&mut self) -> &mut Self { - self.init_output(AlternateFunction::$gpio_function, true); - self - } +pub enum DriveStrength { + I5mA = 0, + I10mA = 1, + I20mA = 2, + I40mA = 3, +} - fn set_to_push_pull_output(&mut self) -> &mut Self { - self.init_output(AlternateFunction::$gpio_function, false); - self - } +#[derive(PartialEq)] +pub enum AlternateFunction { + Function0 = 0, + Function1 = 1, + Function2 = 2, + Function3 = 3, + Function4 = 4, + Function5 = 5, +} - fn enable_output(&mut self, on: bool) -> &mut Self { - if on { - unsafe { &*GPIO::ptr() } - .$out_en_set - .write(|w| unsafe { w.bits(1 << $bit) }); - } else { - unsafe { &*GPIO::ptr() } - .$out_en_clear - .write(|w| unsafe { w.bits(1 << $bit) }); - } - self - } +pub trait RTCPin {} - fn set_output_high(&mut self, high: bool) -> &mut Self { - if high { - unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) }; - } else { - unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) }; - } - self - } +pub trait AnalogPin {} - fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self { - paste! { - unsafe { &*IO_MUX::ptr() } - .$iomux_reg - .modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) }); - } - self - } +pub trait Pin { + fn sleep_mode(&mut self, on: bool) -> &mut Self; - fn enable_open_drain(&mut self, on: bool) -> &mut Self { - unsafe { &*GPIO::ptr() }.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(on)); - self - } + fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self; - fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self { - paste! { - unsafe { &*IO_MUX::ptr() } - .$iomux_reg - .modify(|_, w| w.mcu_wpu().bit(on)); - } - self - } + fn listen(&mut self, event: Event) { + self.listen_with_options(event, true, false, false) + } - fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self { - paste!{ - unsafe { &*IO_MUX::ptr() } - .$iomux_reg - .modify(|_, w| w.mcu_wpd().bit(on)); - } - self - } + fn listen_with_options( + &mut self, + event: Event, + int_enable: bool, + nmi_enable: bool, + wake_up_from_light_sleep: bool, + ); - fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self { - paste! { - unsafe { &*IO_MUX::ptr() } - .$iomux_reg - .modify(|_, w| w.mcu_oe().bit(on)); - } - self - } + fn unlisten(&mut self); - fn connect_peripheral_to_output_with_options( - &mut self, - signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, - ) -> &mut Self { - let af = if force_via_gpio_mux { - AlternateFunction::$gpio_function - } else { - match signal { - $( $( - OutputSignal::$af_signal => AlternateFunction::$af, - )* )? - _ => AlternateFunction::$gpio_function - } - }; + fn clear_interrupt(&mut self); - if af == AlternateFunction::$gpio_function && signal as usize > OUTPUT_SIGNAL_MAX as usize { - panic!("Cannot connect this peripheral to GPIO"); - } + fn is_pcore_interrupt_set(&mut self) -> bool; - self.set_alternate_function(af); + fn is_pcore_non_maskable_interrupt_set(&mut self) -> bool; - let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize { signal as OutputSignalType } else { OUTPUT_SIGNAL_MAX }; + fn is_acore_interrupt_set(&mut self) -> bool; - unsafe { &*GPIO::ptr() }.func_out_sel_cfg[$pin_num].modify(|_, w| unsafe { - w - .out_sel().bits(clipped_signal) - .inv_sel().bit(invert) - .oen_sel().bit(enable_from_gpio) - .oen_inv_sel().bit(invert_enable) - }); + fn is_acore_non_maskable_interrupt_set(&mut self) -> bool; - self - } + fn enable_hold(&mut self, on: bool); +} - fn internal_pull_up(&mut self, on: bool) -> &mut Self { - paste!{ - unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpu().bit(on)); - } - self - } +pub trait InputPin: Pin { + type InputSignal; - fn internal_pull_down(&mut self, on: bool) -> &mut Self { - paste! { - unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpd().bit(on)); - } - self - } - } - }; + fn set_to_input(&mut self) -> &mut Self; + + fn enable_input(&mut self, on: bool) -> &mut Self; + + fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self; + + fn is_input_high(&mut self) -> bool; + + fn connect_input_to_peripheral(&mut self, signal: Self::InputSignal) -> &mut Self { + self.connect_input_to_peripheral_with_options(signal, false, false) + } + + fn connect_input_to_peripheral_with_options( + &mut self, + signal: Self::InputSignal, + invert: bool, + force_via_gpio_mux: bool, + ) -> &mut Self; +} + +pub trait OutputPin: Pin { + type OutputSignal; + + fn set_to_open_drain_output(&mut self) -> &mut Self; + + fn set_to_push_pull_output(&mut self) -> &mut Self; + + fn enable_output(&mut self, on: bool) -> &mut Self; + + fn set_output_high(&mut self, on: bool) -> &mut Self; + + fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self; + + fn enable_open_drain(&mut self, on: bool) -> &mut Self; + + fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self; + + fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self; + + fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self; + + fn connect_peripheral_to_output(&mut self, signal: Self::OutputSignal) -> &mut Self { + self.connect_peripheral_to_output_with_options(signal, false, false, false, false) + } + + fn connect_peripheral_to_output_with_options( + &mut self, + signal: Self::OutputSignal, + invert: bool, + invert_enable: bool, + enable_from_gpio: bool, + force_via_gpio_mux: bool, + ) -> &mut Self; + + fn internal_pull_up(&mut self, on: bool) -> &mut Self; + + fn internal_pull_down(&mut self, on: bool) -> &mut Self; } #[macro_export] macro_rules! impl_input { ( $gpio_function:ident, + $input_signal:ty, $pxi:ident: ( $pin_num:expr, $iomux_reg:expr, $bit:expr, $out_en_clear:ident, @@ -301,6 +233,8 @@ macro_rules! impl_input { } impl InputPin for $pxi { + type InputSignal = $input_signal; + fn set_to_input(&mut self) -> &mut Self { self.init_input(false, false); self @@ -330,17 +264,16 @@ macro_rules! impl_input { fn connect_input_to_peripheral_with_options( &mut self, - signal: InputSignal, + signal: Self::InputSignal, invert: bool, force_via_gpio_mux: bool, ) -> &mut Self { - let af = if force_via_gpio_mux { AlternateFunction::$gpio_function } else { match signal { $( $( - InputSignal::$af_signal => AlternateFunction::$af, + Self::InputSignal::$af_signal => AlternateFunction::$af, )* )? _ => AlternateFunction::$gpio_function } @@ -444,11 +377,13 @@ macro_rules! impl_input { #[macro_export] macro_rules! impl_input_wrap { ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, SingleCore + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, SingleCore $( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )? ) => { impl_input!( $gpio_function, + InputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable_w1tc, in_, data_next, @@ -459,11 +394,13 @@ macro_rules! impl_input_wrap { }; ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, SingleCore + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, SingleCore $( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )? ) => { impl_input!( $gpio_function, + InputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable1_w1tc, in1, data_next, @@ -474,11 +411,13 @@ macro_rules! impl_input_wrap { }; ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, DualCore + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank0, DualCore $( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )? ) => { impl_input!( $gpio_function, + InputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable_w1tc, in_, data_next, @@ -489,11 +428,13 @@ macro_rules! impl_input_wrap { }; ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, DualCore + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, Bank1, DualCore $( ,( $( $af_input_signal:ident : $af_input:ident ),* ) )? ) => { impl_input!( $gpio_function, + InputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable1_w1tc, in1, data_next, @@ -504,14 +445,255 @@ macro_rules! impl_input_wrap { }; } +#[macro_export] +macro_rules! impl_output { + ( + $gpio_function:ident, + $output_signal:ty, + $pxi:ident: + ( + $pin_num:expr, $iomux_reg:expr, $bit:expr, $out_en_set:ident, + $out_en_clear:ident, $out_set:ident, $out_clear:ident, $out_reg:ident + ) + $( ,( $( $af_signal:ident: $af:ident ),* ))? + ) => { + impl embedded_hal::digital::v2::OutputPin for $pxi> { + type Error = Infallible; + + fn set_high(&mut self) -> Result<(), Self::Error> { + unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) }; + Ok(()) + } + + fn set_low(&mut self) -> Result<(), Self::Error> { + unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) }; + Ok(()) + } + } + + impl embedded_hal::digital::v2::StatefulOutputPin for $pxi> { + fn is_set_high(&self) -> Result { + unsafe { Ok((*GPIO::ptr()).$out_reg.read().bits() & (1 << $bit) != 0) } + } + + fn is_set_low(&self) -> Result { + Ok(!self.is_set_high()?) + } + } + + impl embedded_hal::digital::v2::ToggleableOutputPin for $pxi> { + type Error = Infallible; + + fn toggle(&mut self) -> Result<(), Self::Error> { + if self.is_set_high()? { + Ok(self.set_low()?) + } else { + Ok(self.set_high()?) + } + } + } + + impl $pxi { + pub fn into_pull_up_input(self) -> $pxi> { + self.init_input(false, false); + $pxi { _mode: PhantomData } + } + + pub fn into_pull_down_input(self) -> $pxi> { + self.init_input(true, false); + $pxi { _mode: PhantomData } + } + + fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { + let gpio = unsafe { &*GPIO::ptr() }; + let iomux = unsafe { &*IO_MUX::ptr() }; + + gpio.$out_en_set.write(|w| unsafe { w.bits(1 << $bit) }); + gpio.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(open_drain)); + + gpio.func_out_sel_cfg[$pin_num] + .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); + + paste! { + iomux.$iomux_reg.modify(|_, w| unsafe { + w.mcu_sel() + .bits(alternate as u8) + .fun_ie() + .clear_bit() + .fun_wpd() + .clear_bit() + .fun_wpu() + .clear_bit() + .fun_drv() + .bits(DriveStrength::I20mA as u8) + .slp_sel() + .clear_bit() + }); + } + } + + pub fn into_push_pull_output(self) -> $pxi> { + self.init_output(AlternateFunction::$gpio_function, false); + $pxi { _mode: PhantomData } + } + + pub fn into_open_drain_output(self) -> $pxi> { + self.init_output(AlternateFunction::$gpio_function, true); + $pxi { _mode: PhantomData } + } + + pub fn into_alternate_1(self) -> $pxi> { + self.init_output(AlternateFunction::Function1, false); + $pxi { _mode: PhantomData } + } + + pub fn into_alternate_2(self) -> $pxi> { + self.init_output(AlternateFunction::Function2, false); + $pxi { _mode: PhantomData } + } + } + + impl OutputPin for $pxi { + type OutputSignal = $output_signal; + + fn set_to_open_drain_output(&mut self) -> &mut Self { + self.init_output(AlternateFunction::$gpio_function, true); + self + } + + fn set_to_push_pull_output(&mut self) -> &mut Self { + self.init_output(AlternateFunction::$gpio_function, false); + self + } + + fn enable_output(&mut self, on: bool) -> &mut Self { + if on { + unsafe { &*GPIO::ptr() } + .$out_en_set + .write(|w| unsafe { w.bits(1 << $bit) }); + } else { + unsafe { &*GPIO::ptr() } + .$out_en_clear + .write(|w| unsafe { w.bits(1 << $bit) }); + } + self + } + + fn set_output_high(&mut self, high: bool) -> &mut Self { + if high { + unsafe { (*GPIO::ptr()).$out_set.write(|w| w.bits(1 << $bit)) }; + } else { + unsafe { (*GPIO::ptr()).$out_clear.write(|w| w.bits(1 << $bit)) }; + } + self + } + + fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self { + paste! { + unsafe { &*IO_MUX::ptr() } + .$iomux_reg + .modify(|_, w| unsafe { w.fun_drv().bits(strength as u8) }); + } + self + } + + fn enable_open_drain(&mut self, on: bool) -> &mut Self { + unsafe { &*GPIO::ptr() }.pin[$pin_num].modify(|_, w| w.pin_pad_driver().bit(on)); + self + } + + fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self { + paste! { + unsafe { &*IO_MUX::ptr() } + .$iomux_reg + .modify(|_, w| w.mcu_wpu().bit(on)); + } + self + } + + fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self { + paste!{ + unsafe { &*IO_MUX::ptr() } + .$iomux_reg + .modify(|_, w| w.mcu_wpd().bit(on)); + } + self + } + + fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self { + paste! { + unsafe { &*IO_MUX::ptr() } + .$iomux_reg + .modify(|_, w| w.mcu_oe().bit(on)); + } + self + } + + fn connect_peripheral_to_output_with_options( + &mut self, + signal: Self::OutputSignal, + invert: bool, + invert_enable: bool, + enable_from_gpio: bool, + force_via_gpio_mux: bool, + ) -> &mut Self { + let af = if force_via_gpio_mux { + AlternateFunction::$gpio_function + } else { + match signal { + $( $( + Self::OutputSignal::$af_signal => AlternateFunction::$af, + )* )? + _ => AlternateFunction::$gpio_function + } + }; + + if af == AlternateFunction::$gpio_function && signal as usize > OUTPUT_SIGNAL_MAX as usize { + panic!("Cannot connect this peripheral to GPIO"); + } + + self.set_alternate_function(af); + + let clipped_signal = if signal as usize <= OUTPUT_SIGNAL_MAX as usize { signal as OutputSignalType } else { OUTPUT_SIGNAL_MAX }; + + unsafe { &*GPIO::ptr() }.func_out_sel_cfg[$pin_num].modify(|_, w| unsafe { + w + .out_sel().bits(clipped_signal) + .inv_sel().bit(invert) + .oen_sel().bit(enable_from_gpio) + .oen_inv_sel().bit(invert_enable) + }); + + self + } + + fn internal_pull_up(&mut self, on: bool) -> &mut Self { + paste!{ + unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpu().bit(on)); + } + self + } + + fn internal_pull_down(&mut self, on: bool) -> &mut Self { + paste! { + unsafe { &*IO_MUX::ptr() }.$iomux_reg.modify(|_, w| w.fun_wpd().bit(on)); + } + self + } + } + }; +} + #[macro_export] macro_rules! impl_output_wrap { ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank0 + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank0 $( ,( $( $af_output_signal:ident : $af_output:ident ),* ))? ) => { impl_output!( $gpio_function, + OutputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable_w1ts, enable_w1tc, @@ -522,11 +704,13 @@ macro_rules! impl_output_wrap { }; ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank1 + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, IO, Bank1 $( ,( $( $af_output_signal:ident : $af_output:ident ),* ))? ) => { impl_output!( $gpio_function, + OutputSignal, $pxi: ( $pin_num, $iomux_reg, $pin_num % 32, enable1_w1ts, enable1_w1tc, @@ -537,7 +721,8 @@ macro_rules! impl_output_wrap { }; ( - $gpio_function:ident, $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, $bank:ident + $gpio_function:ident, + $pxi:ident, $pin_num:expr, $iomux_reg:expr, $type:ident, $bank:ident $( ,( $( $af_output_signal:ident : $af_output:ident ),* ))? ) => {}; } @@ -583,164 +768,16 @@ macro_rules! gpio { fn split(self) -> Self::Parts; } - pub trait Pin { - fn sleep_mode(&mut self, on: bool) -> &mut Self; + impl GpioExt for GPIO { + type Parts = Pins; - fn set_alternate_function(&mut self, alternate: AlternateFunction) -> &mut Self; - - fn listen(&mut self, event: Event) { - self.listen_with_options(event, true, false, false) + fn split(self) -> Self::Parts { + Pins { + $( + $pname: $pxi { _mode: PhantomData }, + )+ + } } - - fn listen_with_options( - &mut self, - event: Event, - int_enable: bool, - nmi_enable: bool, - wake_up_from_light_sleep: bool, - ); - - fn unlisten(&mut self); - - fn clear_interrupt(&mut self); - - fn is_pcore_interrupt_set(&mut self) -> bool; - - fn is_pcore_non_maskable_interrupt_set(&mut self) -> bool; - - fn is_acore_interrupt_set(&mut self) -> bool; - - fn is_acore_non_maskable_interrupt_set(&mut self) -> bool; - - fn enable_hold(&mut self, on: bool); - } - - pub trait InputPin: Pin { - fn set_to_input(&mut self) -> &mut Self; - - fn enable_input(&mut self, on: bool) -> &mut Self; - - fn enable_input_in_sleep_mode(&mut self, on: bool) -> &mut Self; - - fn is_input_high(&mut self) -> bool; - - fn connect_input_to_peripheral(&mut self, signal: InputSignal) -> &mut Self { - self.connect_input_to_peripheral_with_options(signal, false, false) - } - - fn connect_input_to_peripheral_with_options( - &mut self, - signal: InputSignal, - invert: bool, - force_via_gpio_mux: bool, - ) -> &mut Self; - } - - pub trait OutputPin: Pin { - fn set_to_open_drain_output(&mut self) -> &mut Self; - - fn set_to_push_pull_output(&mut self) -> &mut Self; - - fn enable_output(&mut self, on: bool) -> &mut Self; - - fn set_output_high(&mut self, on: bool) -> &mut Self; - - fn set_drive_strength(&mut self, strength: DriveStrength) -> &mut Self; - - fn enable_open_drain(&mut self, on: bool) -> &mut Self; - - fn enable_output_in_sleep_mode(&mut self, on: bool) -> &mut Self; - - fn internal_pull_up_in_sleep_mode(&mut self, on: bool) -> &mut Self; - - fn internal_pull_down_in_sleep_mode(&mut self, on: bool) -> &mut Self; - - fn connect_peripheral_to_output(&mut self, signal: OutputSignal) -> &mut Self { - self.connect_peripheral_to_output_with_options(signal, false, false, false, false) - } - - fn connect_peripheral_to_output_with_options( - &mut self, - signal: OutputSignal, - invert: bool, - invert_enable: bool, - enable_from_gpio: bool, - force_via_gpio_mux: bool, - ) -> &mut Self; - - fn internal_pull_up(&mut self, on: bool) -> &mut Self; - - fn internal_pull_down(&mut self, on: bool) -> &mut Self; - } - - pub trait RTCPin {} - - pub trait AnalogPin {} - - #[derive(Copy, Clone)] - pub enum Event { - RisingEdge = 1, - FallingEdge = 2, - AnyEdge = 3, - LowLevel = 4, - HighLevel = 5, - } - - pub struct Unknown {} - - pub struct Input { - _mode: PhantomData, - } - - pub struct RTCInput { - _mode: PhantomData, - } - - pub struct Floating; - - pub struct PullDown; - - pub struct PullUp; - - pub struct Output { - _mode: PhantomData, - } - - pub struct RTCOutput { - _mode: PhantomData, - } - - pub struct OpenDrain; - - pub struct PushPull; - - pub struct Analog; - - pub struct Alternate { - _mode: PhantomData, - } - - pub struct AF0; - - pub struct AF1; - - pub struct AF2; - - pub enum DriveStrength { - I5mA = 0, - I10mA = 1, - I20mA = 2, - I40mA = 3, - } - - #[derive(PartialEq)] - pub enum AlternateFunction { - Function0 = 0, - Function1 = 1, - Function2 = 2, - Function3 = 3, - Function4 = 4, - Function5 = 5, } pub fn connect_low_to_peripheral(signal: InputSignal) { @@ -765,18 +802,6 @@ macro_rules! gpio { }); } - impl GpioExt for GPIO { - type Parts = Pins; - - fn split(self) -> Self::Parts { - Pins { - $( - $pname: $pxi { _mode: PhantomData }, - )+ - } - } - } - pub struct Pins { $( pub $pname: $pxi,