Skip to content

Commit 3735258

Browse files
committed
S3: Try to fix LowPowerInput out of bounds panic
1 parent d2d9151 commit 3735258

File tree

2 files changed

+54
-65
lines changed

2 files changed

+54
-65
lines changed

esp-hal/src/gpio/rtc_io.rs

Lines changed: 48 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use core::marker::PhantomData;
3333

3434
use super::{InputPin, OutputPin, RtcPin};
3535
use crate::{
36-
gpio::RtcFunction,
36+
gpio::{Pin, RtcFunction, RtcPinWithResistors},
3737
peripherals::{GPIO, RTC_IO},
3838
};
3939

@@ -73,64 +73,57 @@ impl<'d, const PIN: u8> LowPowerOutput<'d, PIN> {
7373
}
7474
}
7575

76-
/// A GPIO input pin configured for low power operation
77-
pub struct LowPowerInput<'d, const PIN: u8> {
78-
phantom: PhantomData<&'d mut ()>,
76+
/// A GPIO input pin configured for low power operation.
77+
pub struct LowPowerInput<'d, P> {
78+
pin: P,
79+
phantom: PhantomData<&'d ()>,
7980
}
8081

81-
impl<'d, const PIN: u8> LowPowerInput<'d, PIN> {
82-
/// Create a new input pin for use by the low-power core
83-
pub fn new<P>(pin: P) -> Self
84-
where
85-
P: InputPin + RtcPin + 'd,
86-
{
82+
impl<'d, P> LowPowerInput<'d, P>
83+
where
84+
P: InputPin + RtcPinWithResistors + 'd,
85+
{
86+
/// Create a new input pin for use by the low-power core.
87+
pub fn new(pin: P) -> Self {
8788
pin.rtc_set_config(true, true, RtcFunction::Rtc);
8889

89-
let this = Self {
90-
phantom: PhantomData,
91-
};
92-
this.input_enable(true);
93-
this.pullup_enable(false);
94-
this.pulldown_enable(false);
95-
96-
this
97-
}
90+
pin.rtcio_pullup(false);
91+
pin.rtcio_pulldown(false);
9892

99-
fn input_enable(&self, enable: bool) {
100-
RTC_IO::regs()
101-
.touch_pad(PIN as usize)
102-
.modify(|_, w| w.fun_ie().bit(enable));
93+
Self {
94+
pin,
95+
phantom: PhantomData,
96+
}
10397
}
10498

105-
/// Sets pull-up enable for the pin
106-
pub fn pullup_enable(&self, enable: bool) {
107-
RTC_IO::regs()
108-
.touch_pad(PIN as usize)
109-
.modify(|_, w| w.rue().bit(enable));
99+
/// Sets pull-up enable for the pin.
100+
pub fn pullup_enable(&mut self, enable: bool) {
101+
self.pin.rtcio_pullup(enable);
110102
}
111103

112-
/// Sets pull-down enable for the pin
113-
pub fn pulldown_enable(&self, enable: bool) {
114-
RTC_IO::regs()
115-
.touch_pad(PIN as usize)
116-
.modify(|_, w| w.rde().bit(enable));
104+
/// Sets pull-down enable for the pin.
105+
pub fn pulldown_enable(&mut self, enable: bool) {
106+
self.pin.rtcio_pulldown(enable);
117107
}
118108
}
119109

120-
/// A GPIO open-drain output pin configured for low power operation
121-
pub struct LowPowerOutputOpenDrain<'d, const PIN: u8> {
110+
/// A GPIO open-drain output pin configured for low power operation.
111+
pub struct LowPowerOutputOpenDrain<'d, P> {
112+
pin: P,
122113
phantom: PhantomData<&'d ()>,
123114
}
124115

125-
impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
126-
/// Create a new output pin for use by the low-power core
127-
pub fn new<P>(pin: P) -> Self
128-
where
129-
P: InputPin + OutputPin + RtcPin + 'd,
130-
{
116+
impl<'d, P> LowPowerOutputOpenDrain<'d, P>
117+
where
118+
P: InputPin + OutputPin + RtcPinWithResistors + Pin + 'd,
119+
{
120+
/// Create a new output pin for use by the low-power core.
121+
pub fn new(pin: P) -> Self {
122+
// We can now call trait methods directly on the pin.
131123
pin.rtc_set_config(true, true, RtcFunction::Rtc);
132124

133-
let this = Self {
125+
let mut this = Self {
126+
pin,
134127
phantom: PhantomData,
135128
};
136129

@@ -143,43 +136,39 @@ impl<'d, const PIN: u8> LowPowerOutputOpenDrain<'d, PIN> {
143136
this
144137
}
145138

146-
fn output_enable(&self, enable: bool) {
139+
fn output_enable(&mut self, enable: bool) {
147140
let rtc_io = RTC_IO::regs();
141+
let rtc_pin = self.pin.rtc_number();
148142

149143
if enable {
150144
rtc_io
151145
.rtc_gpio_enable_w1ts()
152-
.write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << PIN) });
146+
.write(|w| unsafe { w.rtc_gpio_enable_w1ts().bits(1 << rtc_pin) });
153147
} else {
154148
rtc_io
155149
.enable_w1tc()
156-
.write(|w| unsafe { w.enable_w1tc().bits(1 << PIN) });
150+
.write(|w| unsafe { w.enable_w1tc().bits(1 << rtc_pin) });
157151
}
158152
}
159153

160-
fn input_enable(&self, enable: bool) {
161-
RTC_IO::regs()
162-
.touch_pad(PIN as usize)
163-
.modify(|_, w| w.fun_ie().bit(enable));
154+
fn input_enable(&mut self, enable: bool) {
155+
self.pin.rtc_set_config(enable, true, RtcFunction::Rtc);
164156
}
165157

166158
/// Sets pull-up enable for the pin
167-
pub fn pullup_enable(&self, enable: bool) {
168-
RTC_IO::regs()
169-
.touch_pad(PIN as usize)
170-
.modify(|_, w| w.rue().bit(enable));
159+
pub fn pullup_enable(&mut self, enable: bool) {
160+
self.pin.rtcio_pullup(enable);
171161
}
172162

173163
/// Sets pull-down enable for the pin
174-
pub fn pulldown_enable(&self, enable: bool) {
175-
RTC_IO::regs()
176-
.touch_pad(PIN as usize)
177-
.modify(|_, w| w.rde().bit(enable));
164+
pub fn pulldown_enable(&mut self, enable: bool) {
165+
self.pin.rtcio_pulldown(enable);
178166
}
179167

180-
fn set_open_drain_output(&self, enable: bool) {
168+
fn set_open_drain_output(&mut self, enable: bool) {
169+
let pin_number = self.pin.number();
181170
GPIO::regs()
182-
.pin(PIN as usize)
171+
.pin(pin_number as usize)
183172
.modify(|_, w| w.pad_driver().bit(enable));
184173
}
185174
}

esp-hal/src/soc/esp32s3/gpio.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ macro_rules! rtcio_analog {
3535
$pin_num
3636
}
3737

38-
/// Set the RTC properties of the pin. If `mux` is true then then pin is
38+
/// Set the RTC properties of the pin. If `mux` is true then the pin is
3939
/// routed to RTC, when false it is routed to IO_MUX.
4040
fn rtc_set_config(&self, input_enable: bool, mux: bool, func: $crate::gpio::RtcFunction) {
4141
enable_iomux_clk_gate();
4242

43-
// We need `paste` to rewrite something in each function, so that rustc
44-
// doesn't trip over trying to substitute a partial expression as `$pin_reg`
43+
// Access the RTC_IO register for this pin
4544
$crate::peripherals::[<RTC _IO>]::regs()
46-
.$pin_reg.modify(|_,w| unsafe {
45+
.$pin_reg.modify(|_, w| unsafe {
4746
w.fun_ie().bit(input_enable);
4847
w.mux_sel().bit(mux);
4948
w.fun_sel().bits(func as u8)
@@ -85,9 +84,10 @@ macro_rules! rtcio_analog {
8584
rtcio.enable_w1tc().write(|w| unsafe { w.enable_w1tc().bits(1 << self.rtc_number()) });
8685

8786
// disable open drain
88-
rtcio.pin(self.rtc_number() as usize).modify(|_,w| w.pad_driver().bit(false));
87+
rtcio.pin(self.rtc_number() as usize).modify(|_, w| w.pad_driver().bit(false));
8988

90-
rtcio.$pin_reg.modify(|_,w| {
89+
// configure pin register
90+
rtcio.$pin_reg.modify(|_, w| {
9191
w.fun_ie().clear_bit();
9292

9393
// Connect pin to analog / RTC module instead of standard GPIO

0 commit comments

Comments
 (0)