esp_hal/gpio/lp_io/low_level/
v3.rs1use crate::{
2 gpio::{AlternateFunction, Level, LpPin, lp_io::LpFunction},
3 peripherals::{GPIO, IO_MUX, LPWR},
4};
5
6for_each_lp_function! {
7 (($_lp:ident, LP_GPIOn, $pin:literal), $gpio:ident, $_af:ident, $_lp_in:tt $_lp_out:tt) => {
8 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
9 impl LpPin for crate::peripherals::$gpio<'_> {
10 fn lp_number(&self) -> u8 {
11 $pin
12 }
13 }
14 };
15
16 (LP_GPIOn $( (($_lp:ident, LP_GPIOn, $pin:literal), $gpio:ident, $_af:ident, $_lp_in:tt $_lp_out:tt) ),*) => {
19 paste::paste! {
20 pub(crate) fn apply_wakeup(lp: u8, wakeup: bool, level: Level) {
21 let trigger = crate::gpio::lp_io::wake_trigger(level);
22
23 let gpio_wakeup = cfg_select! {
24 esp32c2 => LPWR::regs().cntl_gpio_wakeup(),
25 esp32c3 => LPWR::regs().gpio_wakeup(),
26 };
27
28 gpio_wakeup.modify(|_, w| unsafe {
29 match lp {
30 $(
31 $pin => {
32 w.[<gpio_pin $pin _wakeup_enable>]().bit(wakeup);
33 w.[<gpio_pin $pin _int_type>]().bits(trigger)
34 }
35 )*
36 _ => unreachable!(),
37 }
38 });
39 }
40
41 pub(crate) fn pad_hold(lp: u8, enable: bool) {
42 LPWR::regs().pad_hold().modify(|_, w| {
43 match lp {
44 $( $pin => w.[<gpio_pin $pin _hold>]().bit(enable), )*
45 _ => unreachable!(),
46 }
47 });
48 }
49
50 pub(crate) fn is_pad_held(lp: u8) -> bool {
52 let r = LPWR::regs().pad_hold().read();
53 match lp {
54 $( $pin => r.[<gpio_pin $pin _hold>]().bit_is_set(), )*
55 _ => unreachable!(),
56 }
57 }
58
59 #[cfg(sleep_driver_supported)]
62 pub(crate) fn wakeup_enabled_mask() -> u32 {
63 let gpio_wakeup = cfg_select! {
64 esp32c2 => LPWR::regs().cntl_gpio_wakeup().read(),
65 esp32c3 => LPWR::regs().gpio_wakeup().read(),
66 };
67
68 let mut mask = 0;
69 $(
70 if gpio_wakeup.[<gpio_pin $pin _wakeup_enable>]().bit_is_set() {
71 mask |= 1 << $pin;
72 }
73 )*
74 mask
75 }
76 }
77 };
78}
79
80pub(crate) fn digital_pad_hold(gpio: u8, enable: bool) {
85 let mask = 1 << gpio;
86 LPWR::regs().dig_pad_hold().modify(|r, w| unsafe {
87 let bits = r.dig_pad_hold().bits();
88 w.dig_pad_hold()
89 .bits(if enable { bits | mask } else { bits & !mask })
90 });
91}
92
93pub(crate) fn is_digital_pad_held(gpio: u8) -> bool {
95 LPWR::regs().dig_pad_hold().read().dig_pad_hold().bits() & (1 << gpio) != 0
96}
97
98pub(crate) fn set_config(lp: u8, input_enable: bool, _mux: bool, _func: LpFunction) {
103 IO_MUX::regs().gpio(lp as usize).modify(|_, w| unsafe {
104 w.slp_sel().bit(false);
105 w.mcu_sel().bits(AlternateFunction::GPIO as u8);
106 w.fun_ie().bit(input_enable)
107 });
108}
109
110#[expect(dead_code)]
111pub(crate) fn init_pin(lp: u8, enable_input: bool) -> u8 {
112 input_enable(lp, enable_input);
113 lp
114}
115
116#[expect(dead_code)]
117pub(crate) fn output_enable(lp: u8, enable: bool) {
118 if enable {
119 GPIO::regs()
120 .enable_w1ts()
121 .write(|w| unsafe { w.enable_w1ts().bits(1 << lp) });
122 } else {
123 GPIO::regs()
124 .enable_w1tc()
125 .write(|w| unsafe { w.enable_w1tc().bits(1 << lp) });
126 }
127}
128
129pub(crate) fn input_enable(lp: u8, enable: bool) {
130 IO_MUX::regs()
131 .gpio(lp as usize)
132 .modify(|_, w| w.fun_ie().bit(enable));
133}
134
135#[expect(dead_code)]
136pub(crate) fn set_open_drain_output(lp: u8, enable: bool) {
137 GPIO::regs()
138 .pin(lp as usize)
139 .modify(|_, w| w.pad_driver().bit(enable));
140}