Skip to content

Commit 5927fa9

Browse files
committed
Unify peripheral guard impls, avoid resetting the peripherals multiple times
1 parent deffffb commit 5927fa9

File tree

5 files changed

+39
-22
lines changed

5 files changed

+39
-22
lines changed

esp-hal/src/gpio/dedicated.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,14 @@ for_each_dedicated_gpio!(
177177
impl DedicatedGpio<'_> {
178178
#[cfg(dedicated_gpio_needs_initialization)]
179179
fn initialize() {
180-
crate::system::PeripheralClockControl::enable(crate::system::Peripheral::DedicatedGpio);
180+
use crate::system::{Peripheral, PeripheralClockControl};
181+
if PeripheralClockControl::enable(Peripheral::DedicatedGpio) {
182+
PeripheralClockControl::reset(Peripheral::DedicatedGpio);
183+
} else {
184+
// Refcount was more than 0. Decrement to avoid overflow because we don't handle
185+
// dropping the driver.
186+
PeripheralClockControl::disable(Peripheral::DedicatedGpio);
187+
}
181188

182189
#[cfg(esp32s2)]
183190
{

esp-hal/src/ledc/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ impl<'d> Ledc<'d> {
123123
pub fn new(_instance: LEDC<'d>) -> Self {
124124
if PeripheralClockControl::enable(PeripheralEnable::Ledc) {
125125
PeripheralClockControl::reset(PeripheralEnable::Ledc);
126+
} else {
127+
// Refcount was more than 0. Decrement to avoid overflow because we don't handle
128+
// dropping the driver.
129+
PeripheralClockControl::disable(PeripheralEnable::Ledc);
126130
}
127131

128132
let ledc = LEDC::regs();

esp-hal/src/system.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ pub(crate) struct PeripheralGuard {
6565

6666
impl PeripheralGuard {
6767
pub(crate) fn new_with(p: Peripheral, init: fn()) -> Self {
68-
if PeripheralClockControl::enable(p) {
69-
PeripheralClockControl::reset(p);
70-
init();
71-
}
68+
PeripheralClockControl::request_peripheral(p, init);
7269

7370
Self { peripheral: p }
7471
}
@@ -100,14 +97,8 @@ pub(crate) struct GenericPeripheralGuard<const P: u8> {}
10097

10198
impl<const P: u8> GenericPeripheralGuard<P> {
10299
pub(crate) fn new_with(init: fn()) -> Self {
103-
let peripheral = const { Peripheral::try_from(P).unwrap() };
104-
105-
PERIPHERAL_REF_COUNT.with(|ref_counts| {
106-
if PeripheralClockControl::enable_with_counts(peripheral, ref_counts) {
107-
unsafe { PeripheralClockControl::reset_racey(peripheral) };
108-
init();
109-
}
110-
});
100+
let p = const { Peripheral::try_from(P).unwrap() };
101+
PeripheralClockControl::request_peripheral(p, init);
111102

112103
Self {}
113104
}
@@ -139,6 +130,15 @@ impl<const P: u8> Drop for GenericPeripheralGuard<P> {
139130
pub(crate) struct PeripheralClockControl;
140131

141132
impl PeripheralClockControl {
133+
fn request_peripheral(p: Peripheral, init: fn()) {
134+
PERIPHERAL_REF_COUNT.with(|ref_counts| {
135+
if Self::enable_with_counts(p, ref_counts) {
136+
unsafe { Self::reset_racey(p) };
137+
init();
138+
}
139+
});
140+
}
141+
142142
/// Enables the given peripheral.
143143
///
144144
/// This keeps track of enabling a peripheral - i.e. a peripheral
@@ -165,8 +165,6 @@ impl PeripheralClockControl {
165165
/// gets disabled when the number of enable/disable attempts is balanced.
166166
///
167167
/// Returns `true` if it actually disabled the peripheral.
168-
///
169-
/// Before disabling a peripheral it will also get reset
170168
pub(crate) fn disable(peripheral: Peripheral) -> bool {
171169
PERIPHERAL_REF_COUNT.with(|ref_counts| {
172170
Self::enable_forced_with_counts(peripheral, false, false, ref_counts)
@@ -200,10 +198,6 @@ impl PeripheralClockControl {
200198
assert!(*ref_count == 0);
201199
}
202200

203-
if !enable {
204-
unsafe { Self::reset_racey(peripheral) };
205-
}
206-
207201
debug!("Enable {:?} {}", peripheral, enable);
208202
unsafe { enable_internal_racey(peripheral, enable) };
209203

esp-hal/src/timer/systimer.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,13 @@ impl<'d> SystemTimer<'d> {
222222
/// Create a new instance.
223223
pub fn new(_systimer: SYSTIMER<'d>) -> Self {
224224
// Don't reset Systimer as it will break `time::Instant::now`, only enable it
225-
PeripheralClockControl::enable(PeripheralEnable::Systimer);
225+
if PeripheralClockControl::enable(PeripheralEnable::Systimer) {
226+
PeripheralClockControl::reset(PeripheralEnable::Systimer);
227+
} else {
228+
// Refcount was more than 0. Decrement to avoid overflow because we don't handle
229+
// dropping the driver.
230+
PeripheralClockControl::disable(PeripheralEnable::Systimer);
231+
}
226232

227233
#[cfg(etm_driver_supported)]
228234
etm::enable_etm();

esp-hal/src/usb_serial_jtag.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ use crate::{
130130
asynch::AtomicWaker,
131131
pac::usb_device::RegisterBlock,
132132
peripherals::USB_DEVICE,
133-
system::PeripheralClockControl,
133+
system::{Peripheral, PeripheralClockControl},
134134
};
135135

136136
/// Custom USB serial error type
@@ -351,7 +351,13 @@ where
351351
fn new_inner(usb_device: USB_DEVICE<'d>) -> Self {
352352
// Do NOT reset the peripheral. Doing so will result in a broken USB JTAG
353353
// connection.
354-
PeripheralClockControl::enable(crate::system::Peripheral::UsbDevice);
354+
if PeripheralClockControl::enable(Peripheral::UsbDevice) {
355+
PeripheralClockControl::reset(Peripheral::UsbDevice);
356+
} else {
357+
// Refcount was more than 0. Decrement to avoid overflow because we don't handle
358+
// dropping the driver.
359+
PeripheralClockControl::disable(Peripheral::UsbDevice);
360+
}
355361

356362
usb_device.disable_tx_interrupts();
357363
usb_device.disable_rx_interrupts();

0 commit comments

Comments
 (0)