esp_hal/gpio/lp_io/low_level/
v4.rs1use crate::{
2 gpio::{LpPin, lp_io::LpFunction},
3 peripherals::LP_AON,
4};
5
6cfg_select! {
7 esp32c6 => {
8 use crate::peripherals::{LP_IO as LP_GPIO, LP_IO as LP_IO_MUX};
9 }
10 any(esp32c5, esp32c61) => {
11 #[cfg(any(
13 ulp_riscv_driver_supported,
14 lp_io_has_gpio_matrix,
15 lp_i2c_master_driver_supported,
16 ))]
17 use crate::peripherals::LP_GPIO;
18 use crate::peripherals::LP_IO_MUX;
19 }
20}
21
22for_each_lp_function! {
23 (($_lp:ident, LP_GPIOn, $pin:literal), $gpio:ident, $_af:ident, $_lp_in:tt $_lp_out:tt) => {
24 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
25 impl LpPin for crate::peripherals::$gpio<'_> {
26 fn lp_number(&self) -> u8 {
27 $pin
28 }
29 }
30 };
31}
32
33pub(crate) fn pad_hold(lp: u8, enable: bool) {
36 digital_pad_hold(lp, enable);
37}
38
39pub(crate) fn is_pad_held(lp: u8) -> bool {
41 is_digital_pad_held(lp)
42}
43
44pub(crate) fn digital_pad_hold(gpio: u8, enable: bool) {
46 let mask = 1 << gpio;
47 LP_AON::regs().gpio_hold0().modify(|r, w| unsafe {
48 let bits = r.gpio_hold0().bits();
49 w.gpio_hold0()
50 .bits(if enable { bits | mask } else { bits & !mask })
51 });
52}
53
54pub(crate) fn is_digital_pad_held(gpio: u8) -> bool {
56 LP_AON::regs().gpio_hold0().read().gpio_hold0().bits() & (1 << gpio) != 0
57}
58
59pub(crate) fn set_config(lp: u8, input_enable: bool, mux: bool, func: LpFunction) {
60 let mask = 1 << lp;
61 LP_AON::regs().gpio_mux().modify(|r, w| unsafe {
62 let bits = r.sel().bits();
63 w.sel().bits(if mux { bits | mask } else { bits & !mask })
64 });
65
66 LP_IO_MUX::regs().gpio(lp as usize).modify(|_, w| unsafe {
67 w.slp_sel().bit(false);
68 w.fun_ie().bit(input_enable);
69 w.mcu_ie().bit(input_enable);
70 w.mcu_sel().bits(func as u8)
71 });
72}
73
74#[cfg(any(ulp_riscv_driver_supported, lp_io_has_gpio_matrix))]
75pub(crate) fn init_pin(lp: u8, input_enable: bool) -> u8 {
76 set_config(lp, input_enable, true, LpFunction::LP_GPIO);
77 lp
78}
79
80#[cfg(any(
81 ulp_riscv_driver_supported,
82 lp_io_has_gpio_matrix,
83 lp_i2c_master_driver_supported,
84))]
85pub(crate) fn output_enable(lp: u8, enable: bool) {
86 if enable {
87 LP_GPIO::regs()
88 .out_enable_w1ts()
89 .write(|w| unsafe { w.enable_w1ts().bits(1 << lp) });
90 } else {
91 LP_GPIO::regs()
92 .out_enable_w1tc()
93 .write(|w| unsafe { w.enable_w1tc().bits(1 << lp) });
94 }
95}
96
97#[cfg(any(ulp_riscv_driver_supported, lp_io_has_gpio_matrix))]
98pub(crate) fn input_enable(lp: u8, enable: bool) {
99 LP_IO_MUX::regs().gpio(lp as usize).modify(|_, w| {
100 w.fun_ie().bit(enable);
101 w.mcu_ie().bit(enable)
102 });
103}
104
105pub(crate) fn pullup_enable(lp: u8, enable: bool) {
106 LP_IO_MUX::regs()
107 .gpio(lp as usize)
108 .modify(|_, w| w.fun_wpu().bit(enable));
109}
110
111pub(crate) fn pulldown_enable(lp: u8, enable: bool) {
112 LP_IO_MUX::regs()
113 .gpio(lp as usize)
114 .modify(|_, w| w.fun_wpd().bit(enable));
115}
116
117#[cfg(any(
120 ulp_riscv_driver_supported,
121 lp_io_has_gpio_matrix,
122 lp_i2c_master_driver_supported,
123))]
124pub(crate) fn set_open_drain_output(lp: u8, enable: bool) {
125 LP_GPIO::regs()
126 .pin(lp as usize)
127 .modify(|_, w| w.pad_driver().bit(enable));
128}
129
130#[cfg(lp_i2c_master_driver_supported)]
131pub(crate) fn reset_pin(lp: u8) {
132 output_enable(lp, false);
133 set_open_drain_output(lp, false);
134
135 LP_IO_MUX::regs().gpio(lp as usize).reset();
137
138 LP_AON::regs()
140 .gpio_mux()
141 .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() & !(1 << lp)) });
142}