Skip to content

Commit

Permalink
Disable peripherals when unused (#2544)
Browse files Browse the repository at this point in the history
* Disable peripherals when unused

* Fixes

* CHANGELOG.md

* Fix

* Address review comments

* Have dedicated guards for CAM and LCD

* Re-use `Cam`'s guard

* De-duplicate, assert

* fmt

* Require CriticalSection

* Address comments

* Remove redundant guard

* Use `GenericPeripheralGuard`

* Renaming
  • Loading branch information
bjoernQ authored Nov 21, 2024
1 parent 457ed44 commit f9203dc
Show file tree
Hide file tree
Showing 41 changed files with 550 additions and 360 deletions.
1 change: 1 addition & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Trying to send a single-shot RMT transmission will result in an error now, `RMT` deals with `u32` now, `PulseCode` is a convenience trait now (#2463)
- Removed `get_` prefixes from functions (#2528)
- The `Camera` and `I8080` drivers' constructors now only accepts blocking-mode DMA channels. (#2519)
- Many peripherals are now disabled by default and also get disabled when the driver is dropped (#2544)

### Fixed

Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/aes/esp32.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::{
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE};

impl Aes<'_> {
pub(super) fn init(&mut self) {
PeripheralClockControl::enable(PeripheralEnable::Aes);
self.write_endianness(
Endianness::BigEndian,
Endianness::BigEndian,
Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/aes/esp32cX.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::{
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE};

impl Aes<'_> {
pub(super) fn init(&mut self) {
PeripheralClockControl::enable(PeripheralEnable::Aes);
self.write_dma(false);
}

Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/aes/esp32s2.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::{
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE};

impl Aes<'_> {
pub(super) fn init(&mut self) {
PeripheralClockControl::enable(PeripheralEnable::Aes);
self.write_dma(false);
self.write_endianness(
Endianness::BigEndian,
Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/aes/esp32s3.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::{
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
};
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE};

impl Aes<'_> {
pub(super) fn init(&mut self) {
PeripheralClockControl::enable(PeripheralEnable::Aes);
self.write_dma(false);
}

Expand Down
6 changes: 4 additions & 2 deletions esp-hal/src/aes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ use crate::{
peripheral::{Peripheral, PeripheralRef},
peripherals::AES,
reg_access::{AlignmentHelper, NativeEndianess},
system::GenericPeripheralGuard,
};

#[cfg_attr(esp32, path = "esp32.rs")]
Expand Down Expand Up @@ -136,19 +137,20 @@ pub enum Mode {
pub struct Aes<'d> {
aes: PeripheralRef<'d, AES>,
alignment_helper: AlignmentHelper<NativeEndianess>,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Aes as u8 }>,
}

impl<'d> Aes<'d> {
/// Constructs a new `Aes` instance.
pub fn new(aes: impl Peripheral<P = AES> + 'd) -> Self {
crate::into_ref!(aes);

crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Aes);
crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Aes);
let guard = GenericPeripheralGuard::new();

let mut ret = Self {
aes,
alignment_helper: AlignmentHelper::native_endianess(),
_guard: guard,
};
ret.init();

Expand Down
7 changes: 4 additions & 3 deletions esp-hal/src/analog/adc/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::efuse::Efuse;
use crate::{
peripheral::PeripheralRef,
peripherals::APB_SARADC,
system::{Peripheral, PeripheralClockControl},
system::{GenericPeripheralGuard, Peripheral},
};

mod calibration;
Expand Down Expand Up @@ -396,6 +396,7 @@ pub struct Adc<'d, ADCI> {
_adc: PeripheralRef<'d, ADCI>,
attenuations: [Option<Attenuation>; NUM_ATTENS],
active_channel: Option<u8>,
_guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>,
}

impl<'d, ADCI> Adc<'d, ADCI>
Expand All @@ -408,8 +409,7 @@ where
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
config: AdcConfig<ADCI>,
) -> Self {
PeripheralClockControl::reset(Peripheral::ApbSarAdc);
PeripheralClockControl::enable(Peripheral::ApbSarAdc);
let guard = GenericPeripheralGuard::new();

unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe {
w.start_force().set_bit();
Expand All @@ -422,6 +422,7 @@ where
_adc: adc_instance.into_ref(),
attenuations: config.attenuations,
active_channel: None,
_guard: guard,
}
}

Expand Down
8 changes: 4 additions & 4 deletions esp-hal/src/analog/adc/xtensa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::efuse::Efuse;
use crate::{
peripheral::PeripheralRef,
peripherals::{APB_SARADC, SENS},
system::{Peripheral, PeripheralClockControl},
system::{GenericPeripheralGuard, Peripheral},
};

mod calibration;
Expand Down Expand Up @@ -389,6 +389,7 @@ pub struct Adc<'d, ADC> {
_adc: PeripheralRef<'d, ADC>,
active_channel: Option<u8>,
last_init_code: u16,
_guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>,
}

impl<'d, ADCI> Adc<'d, ADCI>
Expand All @@ -401,9 +402,7 @@ where
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
config: AdcConfig<ADCI>,
) -> Self {
PeripheralClockControl::reset(Peripheral::ApbSarAdc);
PeripheralClockControl::enable(Peripheral::ApbSarAdc);

let guard = GenericPeripheralGuard::new();
let sensors = unsafe { &*SENS::ptr() };

// Set attenuation for pins
Expand Down Expand Up @@ -472,6 +471,7 @@ where
_adc: adc_instance.into_ref(),
active_channel: None,
last_init_code: 0,
_guard: guard,
}
}

Expand Down
4 changes: 3 additions & 1 deletion esp-hal/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,9 @@ impl<'d> Dma<'d> {
) -> Dma<'d> {
crate::into_ref!(dma);

PeripheralClockControl::enable(Peripheral::Gdma);
if PeripheralClockControl::enable(Peripheral::Gdma) {
PeripheralClockControl::reset(Peripheral::Gdma);
}
dma.misc_conf().modify(|_, w| w.ahbm_rst_inter().set_bit());
dma.misc_conf()
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
Expand Down
4 changes: 3 additions & 1 deletion esp-hal/src/dma/pdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,9 @@ impl<'d> Dma<'d> {
pub fn new(
dma: impl crate::peripheral::Peripheral<P = crate::peripherals::DMA> + 'd,
) -> Dma<'d> {
PeripheralClockControl::enable(Peripheral::Dma);
if PeripheralClockControl::enable(Peripheral::Dma) {
PeripheralClockControl::reset(Peripheral::Dma);
}

#[cfg(esp32)]
{
Expand Down
7 changes: 4 additions & 3 deletions esp-hal/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::{
peripheral::{Peripheral, PeripheralRef},
peripherals::{Interrupt, ECC},
reg_access::{AlignmentHelper, SocDependentEndianess},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
system::{self, GenericPeripheralGuard},
InterruptConfigurable,
};

Expand All @@ -41,6 +41,7 @@ pub struct Ecc<'d, DM: crate::Mode> {
ecc: PeripheralRef<'d, ECC>,
alignment_helper: AlignmentHelper<SocDependentEndianess>,
phantom: PhantomData<DM>,
_guard: GenericPeripheralGuard<{ system::Peripheral::Ecc as u8 }>,
}

/// ECC interface error
Expand Down Expand Up @@ -102,13 +103,13 @@ impl<'d> Ecc<'d, crate::Blocking> {
pub fn new(ecc: impl Peripheral<P = ECC> + 'd) -> Self {
crate::into_ref!(ecc);

PeripheralClockControl::reset(PeripheralEnable::Ecc);
PeripheralClockControl::enable(PeripheralEnable::Ecc);
let guard = GenericPeripheralGuard::new();

Self {
ecc,
alignment_helper: AlignmentHelper::default(),
phantom: PhantomData,
_guard: guard,
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions esp-hal/src/etm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
use crate::{
peripheral::{Peripheral, PeripheralRef},
system::PeripheralClockControl,
system::GenericPeripheralGuard,
};

/// Unconfigured EtmChannel.
Expand All @@ -76,6 +76,7 @@ impl<const C: u8> EtmChannel<C> {
T: EtmTask,
{
let etm = unsafe { crate::peripherals::SOC_ETM::steal() };
let guard = GenericPeripheralGuard::new();

etm.ch(C as usize)
.evt_id()
Expand All @@ -92,6 +93,7 @@ impl<const C: u8> EtmChannel<C> {
EtmConfiguredChannel {
_event: event,
_task: task,
_guard: guard,
}
}
}
Expand All @@ -117,6 +119,7 @@ where
{
_event: &'a E,
_task: &'a T,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Etm as u8 }>,
}

impl<E, T, const C: u8> Drop for EtmConfiguredChannel<'_, E, T, C>
Expand All @@ -125,7 +128,7 @@ where
T: EtmTask,
{
fn drop(&mut self) {
debug!("drop {}", C);
debug!("Drop ETM channel {}", C);
disable_channel(C);
}
}
Expand All @@ -149,12 +152,9 @@ macro_rules! create_etm {
pub fn new(peripheral: impl Peripheral<P = crate::peripherals::SOC_ETM> + 'd) -> Self {
crate::into_ref!(peripheral);

PeripheralClockControl::reset(crate::system::Peripheral::Etm);
PeripheralClockControl::enable(crate::system::Peripheral::Etm);

Self {
_peripheral: peripheral,
$([< channel $num >]: EtmChannel {},)+
$([< channel $num >]: EtmChannel { },)+
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions esp-hal/src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use crate::{
peripheral::{Peripheral, PeripheralRef},
peripherals::HMAC,
reg_access::{AlignmentHelper, SocDependentEndianess},
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
system::{GenericPeripheralGuard, Peripheral as PeripheralEnable},
};

/// Provides an interface for interacting with the HMAC hardware peripheral.
Expand All @@ -51,6 +51,7 @@ pub struct Hmac<'d> {
alignment_helper: AlignmentHelper<SocDependentEndianess>,
byte_written: usize,
next_command: NextCommand,
_guard: GenericPeripheralGuard<{ PeripheralEnable::Hmac as u8 }>,
}

/// HMAC interface error
Expand Down Expand Up @@ -107,14 +108,14 @@ impl<'d> Hmac<'d> {
pub fn new(hmac: impl Peripheral<P = HMAC> + 'd) -> Self {
crate::into_ref!(hmac);

PeripheralClockControl::reset(PeripheralEnable::Hmac);
PeripheralClockControl::enable(PeripheralEnable::Hmac);
let guard = GenericPeripheralGuard::new();

Self {
hmac,
alignment_helper: AlignmentHelper::default(),
byte_written: 64,
next_command: NextCommand::None,
_guard: guard,
}
}

Expand Down
14 changes: 9 additions & 5 deletions esp-hal/src/i2c/master/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use crate::{
Interrupt,
},
private,
system::PeripheralClockControl,
system::{PeripheralClockControl, PeripheralGuard},
Async,
Blocking,
Cpu,
Expand Down Expand Up @@ -273,6 +273,7 @@ pub struct I2c<'d, DM: Mode, T = AnyI2c> {
i2c: PeripheralRef<'d, T>,
phantom: PhantomData<DM>,
config: Config,
guard: PeripheralGuard,
}

impl<T: Instance, DM: Mode> SetConfig for I2c<'_, DM, T> {
Expand Down Expand Up @@ -352,8 +353,9 @@ where
}

fn internal_recover(&self) {
PeripheralClockControl::reset(self.driver().info.peripheral);
PeripheralClockControl::disable(self.driver().info.peripheral);
PeripheralClockControl::enable(self.driver().info.peripheral);
PeripheralClockControl::reset(self.driver().info.peripheral);

// We know the configuration is valid, we can ignore the result.
_ = self.driver().setup(&self.config);
Expand Down Expand Up @@ -469,15 +471,15 @@ where
pub fn new_typed(i2c: impl Peripheral<P = T> + 'd, config: Config) -> Self {
crate::into_ref!(i2c);

let guard = PeripheralGuard::new(i2c.info().peripheral);

let i2c = I2c {
i2c,
phantom: PhantomData,
config,
guard,
};

PeripheralClockControl::reset(i2c.driver().info.peripheral);
PeripheralClockControl::enable(i2c.driver().info.peripheral);

unwrap!(i2c.driver().setup(&i2c.config));
i2c
}
Expand All @@ -492,6 +494,7 @@ where
i2c: self.i2c,
phantom: PhantomData,
config: self.config,
guard: self.guard,
}
}

Expand Down Expand Up @@ -685,6 +688,7 @@ where
i2c: self.i2c,
phantom: PhantomData,
config: self.config,
guard: self.guard,
}
}

Expand Down
Loading

0 comments on commit f9203dc

Please sign in to comment.