Disable peripherals when unused (#2544)
* 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
This commit is contained in:
parent
457ed44802
commit
f9203dc523
@ -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)
|
- 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)
|
- Removed `get_` prefixes from functions (#2528)
|
||||||
- The `Camera` and `I8080` drivers' constructors now only accepts blocking-mode DMA channels. (#2519)
|
- 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
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
use crate::{
|
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE};
|
||||||
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
|
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Aes<'_> {
|
impl Aes<'_> {
|
||||||
pub(super) fn init(&mut self) {
|
pub(super) fn init(&mut self) {
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Aes);
|
|
||||||
self.write_endianness(
|
self.write_endianness(
|
||||||
Endianness::BigEndian,
|
Endianness::BigEndian,
|
||||||
Endianness::BigEndian,
|
Endianness::BigEndian,
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
use crate::{
|
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE};
|
||||||
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
|
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Aes<'_> {
|
impl Aes<'_> {
|
||||||
pub(super) fn init(&mut self) {
|
pub(super) fn init(&mut self) {
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Aes);
|
|
||||||
self.write_dma(false);
|
self.write_dma(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
use crate::{
|
use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE};
|
||||||
aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE},
|
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Aes<'_> {
|
impl Aes<'_> {
|
||||||
pub(super) fn init(&mut self) {
|
pub(super) fn init(&mut self) {
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Aes);
|
|
||||||
self.write_dma(false);
|
self.write_dma(false);
|
||||||
self.write_endianness(
|
self.write_endianness(
|
||||||
Endianness::BigEndian,
|
Endianness::BigEndian,
|
||||||
|
|||||||
@ -1,11 +1,7 @@
|
|||||||
use crate::{
|
use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE};
|
||||||
aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE},
|
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
|
||||||
};
|
|
||||||
|
|
||||||
impl Aes<'_> {
|
impl Aes<'_> {
|
||||||
pub(super) fn init(&mut self) {
|
pub(super) fn init(&mut self) {
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Aes);
|
|
||||||
self.write_dma(false);
|
self.write_dma(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::AES,
|
peripherals::AES,
|
||||||
reg_access::{AlignmentHelper, NativeEndianess},
|
reg_access::{AlignmentHelper, NativeEndianess},
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg_attr(esp32, path = "esp32.rs")]
|
#[cfg_attr(esp32, path = "esp32.rs")]
|
||||||
@ -136,6 +137,7 @@ pub enum Mode {
|
|||||||
pub struct Aes<'d> {
|
pub struct Aes<'d> {
|
||||||
aes: PeripheralRef<'d, AES>,
|
aes: PeripheralRef<'d, AES>,
|
||||||
alignment_helper: AlignmentHelper<NativeEndianess>,
|
alignment_helper: AlignmentHelper<NativeEndianess>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Aes as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Aes<'d> {
|
impl<'d> Aes<'d> {
|
||||||
@ -143,12 +145,12 @@ impl<'d> Aes<'d> {
|
|||||||
pub fn new(aes: impl Peripheral<P = AES> + 'd) -> Self {
|
pub fn new(aes: impl Peripheral<P = AES> + 'd) -> Self {
|
||||||
crate::into_ref!(aes);
|
crate::into_ref!(aes);
|
||||||
|
|
||||||
crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Aes);
|
let guard = GenericPeripheralGuard::new();
|
||||||
crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Aes);
|
|
||||||
|
|
||||||
let mut ret = Self {
|
let mut ret = Self {
|
||||||
aes,
|
aes,
|
||||||
alignment_helper: AlignmentHelper::native_endianess(),
|
alignment_helper: AlignmentHelper::native_endianess(),
|
||||||
|
_guard: guard,
|
||||||
};
|
};
|
||||||
ret.init();
|
ret.init();
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use crate::efuse::Efuse;
|
|||||||
use crate::{
|
use crate::{
|
||||||
peripheral::PeripheralRef,
|
peripheral::PeripheralRef,
|
||||||
peripherals::APB_SARADC,
|
peripherals::APB_SARADC,
|
||||||
system::{Peripheral, PeripheralClockControl},
|
system::{GenericPeripheralGuard, Peripheral},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod calibration;
|
mod calibration;
|
||||||
@ -396,6 +396,7 @@ pub struct Adc<'d, ADCI> {
|
|||||||
_adc: PeripheralRef<'d, ADCI>,
|
_adc: PeripheralRef<'d, ADCI>,
|
||||||
attenuations: [Option<Attenuation>; NUM_ATTENS],
|
attenuations: [Option<Attenuation>; NUM_ATTENS],
|
||||||
active_channel: Option<u8>,
|
active_channel: Option<u8>,
|
||||||
|
_guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, ADCI> Adc<'d, ADCI>
|
impl<'d, ADCI> Adc<'d, ADCI>
|
||||||
@ -408,8 +409,7 @@ where
|
|||||||
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
|
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
|
||||||
config: AdcConfig<ADCI>,
|
config: AdcConfig<ADCI>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
PeripheralClockControl::reset(Peripheral::ApbSarAdc);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(Peripheral::ApbSarAdc);
|
|
||||||
|
|
||||||
unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe {
|
unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe {
|
||||||
w.start_force().set_bit();
|
w.start_force().set_bit();
|
||||||
@ -422,6 +422,7 @@ where
|
|||||||
_adc: adc_instance.into_ref(),
|
_adc: adc_instance.into_ref(),
|
||||||
attenuations: config.attenuations,
|
attenuations: config.attenuations,
|
||||||
active_channel: None,
|
active_channel: None,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::efuse::Efuse;
|
|||||||
use crate::{
|
use crate::{
|
||||||
peripheral::PeripheralRef,
|
peripheral::PeripheralRef,
|
||||||
peripherals::{APB_SARADC, SENS},
|
peripherals::{APB_SARADC, SENS},
|
||||||
system::{Peripheral, PeripheralClockControl},
|
system::{GenericPeripheralGuard, Peripheral},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod calibration;
|
mod calibration;
|
||||||
@ -389,6 +389,7 @@ pub struct Adc<'d, ADC> {
|
|||||||
_adc: PeripheralRef<'d, ADC>,
|
_adc: PeripheralRef<'d, ADC>,
|
||||||
active_channel: Option<u8>,
|
active_channel: Option<u8>,
|
||||||
last_init_code: u16,
|
last_init_code: u16,
|
||||||
|
_guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, ADCI> Adc<'d, ADCI>
|
impl<'d, ADCI> Adc<'d, ADCI>
|
||||||
@ -401,9 +402,7 @@ where
|
|||||||
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
|
adc_instance: impl crate::peripheral::Peripheral<P = ADCI> + 'd,
|
||||||
config: AdcConfig<ADCI>,
|
config: AdcConfig<ADCI>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
PeripheralClockControl::reset(Peripheral::ApbSarAdc);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(Peripheral::ApbSarAdc);
|
|
||||||
|
|
||||||
let sensors = unsafe { &*SENS::ptr() };
|
let sensors = unsafe { &*SENS::ptr() };
|
||||||
|
|
||||||
// Set attenuation for pins
|
// Set attenuation for pins
|
||||||
@ -472,6 +471,7 @@ where
|
|||||||
_adc: adc_instance.into_ref(),
|
_adc: adc_instance.into_ref(),
|
||||||
active_channel: None,
|
active_channel: None,
|
||||||
last_init_code: 0,
|
last_init_code: 0,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -753,7 +753,9 @@ impl<'d> Dma<'d> {
|
|||||||
) -> Dma<'d> {
|
) -> Dma<'d> {
|
||||||
crate::into_ref!(dma);
|
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().set_bit());
|
||||||
dma.misc_conf()
|
dma.misc_conf()
|
||||||
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
|
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
|
||||||
|
|||||||
@ -942,7 +942,9 @@ impl<'d> Dma<'d> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
dma: impl crate::peripheral::Peripheral<P = crate::peripherals::DMA> + 'd,
|
dma: impl crate::peripheral::Peripheral<P = crate::peripherals::DMA> + 'd,
|
||||||
) -> Dma<'d> {
|
) -> Dma<'d> {
|
||||||
PeripheralClockControl::enable(Peripheral::Dma);
|
if PeripheralClockControl::enable(Peripheral::Dma) {
|
||||||
|
PeripheralClockControl::reset(Peripheral::Dma);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
{
|
{
|
||||||
|
|||||||
@ -32,7 +32,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::{Interrupt, ECC},
|
peripherals::{Interrupt, ECC},
|
||||||
reg_access::{AlignmentHelper, SocDependentEndianess},
|
reg_access::{AlignmentHelper, SocDependentEndianess},
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
system::{self, GenericPeripheralGuard},
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ pub struct Ecc<'d, DM: crate::Mode> {
|
|||||||
ecc: PeripheralRef<'d, ECC>,
|
ecc: PeripheralRef<'d, ECC>,
|
||||||
alignment_helper: AlignmentHelper<SocDependentEndianess>,
|
alignment_helper: AlignmentHelper<SocDependentEndianess>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::Ecc as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ECC interface error
|
/// ECC interface error
|
||||||
@ -102,13 +103,13 @@ impl<'d> Ecc<'d, crate::Blocking> {
|
|||||||
pub fn new(ecc: impl Peripheral<P = ECC> + 'd) -> Self {
|
pub fn new(ecc: impl Peripheral<P = ECC> + 'd) -> Self {
|
||||||
crate::into_ref!(ecc);
|
crate::into_ref!(ecc);
|
||||||
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Ecc);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Ecc);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ecc,
|
ecc,
|
||||||
alignment_helper: AlignmentHelper::default(),
|
alignment_helper: AlignmentHelper::default(),
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
system::PeripheralClockControl,
|
system::GenericPeripheralGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unconfigured EtmChannel.
|
/// Unconfigured EtmChannel.
|
||||||
@ -76,6 +76,7 @@ impl<const C: u8> EtmChannel<C> {
|
|||||||
T: EtmTask,
|
T: EtmTask,
|
||||||
{
|
{
|
||||||
let etm = unsafe { crate::peripherals::SOC_ETM::steal() };
|
let etm = unsafe { crate::peripherals::SOC_ETM::steal() };
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
etm.ch(C as usize)
|
etm.ch(C as usize)
|
||||||
.evt_id()
|
.evt_id()
|
||||||
@ -92,6 +93,7 @@ impl<const C: u8> EtmChannel<C> {
|
|||||||
EtmConfiguredChannel {
|
EtmConfiguredChannel {
|
||||||
_event: event,
|
_event: event,
|
||||||
_task: task,
|
_task: task,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,6 +119,7 @@ where
|
|||||||
{
|
{
|
||||||
_event: &'a E,
|
_event: &'a E,
|
||||||
_task: &'a T,
|
_task: &'a T,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Etm as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, T, const C: u8> Drop for EtmConfiguredChannel<'_, E, T, C>
|
impl<E, T, const C: u8> Drop for EtmConfiguredChannel<'_, E, T, C>
|
||||||
@ -125,7 +128,7 @@ where
|
|||||||
T: EtmTask,
|
T: EtmTask,
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
debug!("drop {}", C);
|
debug!("Drop ETM channel {}", C);
|
||||||
disable_channel(C);
|
disable_channel(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,12 +152,9 @@ macro_rules! create_etm {
|
|||||||
pub fn new(peripheral: impl Peripheral<P = crate::peripherals::SOC_ETM> + 'd) -> Self {
|
pub fn new(peripheral: impl Peripheral<P = crate::peripherals::SOC_ETM> + 'd) -> Self {
|
||||||
crate::into_ref!(peripheral);
|
crate::into_ref!(peripheral);
|
||||||
|
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::Etm);
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Etm);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_peripheral: peripheral,
|
_peripheral: peripheral,
|
||||||
$([< channel $num >]: EtmChannel {},)+
|
$([< channel $num >]: EtmChannel { },)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::HMAC,
|
peripherals::HMAC,
|
||||||
reg_access::{AlignmentHelper, SocDependentEndianess},
|
reg_access::{AlignmentHelper, SocDependentEndianess},
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
system::{GenericPeripheralGuard, Peripheral as PeripheralEnable},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Provides an interface for interacting with the HMAC hardware peripheral.
|
/// Provides an interface for interacting with the HMAC hardware peripheral.
|
||||||
@ -51,6 +51,7 @@ pub struct Hmac<'d> {
|
|||||||
alignment_helper: AlignmentHelper<SocDependentEndianess>,
|
alignment_helper: AlignmentHelper<SocDependentEndianess>,
|
||||||
byte_written: usize,
|
byte_written: usize,
|
||||||
next_command: NextCommand,
|
next_command: NextCommand,
|
||||||
|
_guard: GenericPeripheralGuard<{ PeripheralEnable::Hmac as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HMAC interface error
|
/// HMAC interface error
|
||||||
@ -107,14 +108,14 @@ impl<'d> Hmac<'d> {
|
|||||||
pub fn new(hmac: impl Peripheral<P = HMAC> + 'd) -> Self {
|
pub fn new(hmac: impl Peripheral<P = HMAC> + 'd) -> Self {
|
||||||
crate::into_ref!(hmac);
|
crate::into_ref!(hmac);
|
||||||
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Hmac);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Hmac);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
hmac,
|
hmac,
|
||||||
alignment_helper: AlignmentHelper::default(),
|
alignment_helper: AlignmentHelper::default(),
|
||||||
byte_written: 64,
|
byte_written: 64,
|
||||||
next_command: NextCommand::None,
|
next_command: NextCommand::None,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ use crate::{
|
|||||||
Interrupt,
|
Interrupt,
|
||||||
},
|
},
|
||||||
private,
|
private,
|
||||||
system::PeripheralClockControl,
|
system::{PeripheralClockControl, PeripheralGuard},
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
Cpu,
|
Cpu,
|
||||||
@ -273,6 +273,7 @@ pub struct I2c<'d, DM: Mode, T = AnyI2c> {
|
|||||||
i2c: PeripheralRef<'d, T>,
|
i2c: PeripheralRef<'d, T>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Instance, DM: Mode> SetConfig for I2c<'_, DM, T> {
|
impl<T: Instance, DM: Mode> SetConfig for I2c<'_, DM, T> {
|
||||||
@ -352,8 +353,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn internal_recover(&self) {
|
fn internal_recover(&self) {
|
||||||
PeripheralClockControl::reset(self.driver().info.peripheral);
|
PeripheralClockControl::disable(self.driver().info.peripheral);
|
||||||
PeripheralClockControl::enable(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.
|
// We know the configuration is valid, we can ignore the result.
|
||||||
_ = self.driver().setup(&self.config);
|
_ = self.driver().setup(&self.config);
|
||||||
@ -469,15 +471,15 @@ where
|
|||||||
pub fn new_typed(i2c: impl Peripheral<P = T> + 'd, config: Config) -> Self {
|
pub fn new_typed(i2c: impl Peripheral<P = T> + 'd, config: Config) -> Self {
|
||||||
crate::into_ref!(i2c);
|
crate::into_ref!(i2c);
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(i2c.info().peripheral);
|
||||||
|
|
||||||
let i2c = I2c {
|
let i2c = I2c {
|
||||||
i2c,
|
i2c,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
config,
|
config,
|
||||||
|
guard,
|
||||||
};
|
};
|
||||||
|
|
||||||
PeripheralClockControl::reset(i2c.driver().info.peripheral);
|
|
||||||
PeripheralClockControl::enable(i2c.driver().info.peripheral);
|
|
||||||
|
|
||||||
unwrap!(i2c.driver().setup(&i2c.config));
|
unwrap!(i2c.driver().setup(&i2c.config));
|
||||||
i2c
|
i2c
|
||||||
}
|
}
|
||||||
@ -492,6 +494,7 @@ where
|
|||||||
i2c: self.i2c,
|
i2c: self.i2c,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
config: self.config,
|
config: self.config,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,6 +688,7 @@ where
|
|||||||
i2c: self.i2c,
|
i2c: self.i2c,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
config: self.config,
|
config: self.config,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,7 +100,7 @@ use crate::{
|
|||||||
gpio::interconnect::PeripheralOutput,
|
gpio::interconnect::PeripheralOutput,
|
||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
@ -284,8 +284,11 @@ where
|
|||||||
// could be configured totally independently but for now handle all
|
// could be configured totally independently but for now handle all
|
||||||
// the targets the same and force same configuration for both, TX and RX
|
// the targets the same and force same configuration for both, TX and RX
|
||||||
|
|
||||||
PeripheralClockControl::reset(i2s.peripheral());
|
// make sure the peripheral is enabled before configuring it
|
||||||
PeripheralClockControl::enable(i2s.peripheral());
|
let peripheral = i2s.peripheral();
|
||||||
|
let rx_guard = PeripheralGuard::new(peripheral);
|
||||||
|
let tx_guard = PeripheralGuard::new(peripheral);
|
||||||
|
|
||||||
i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));
|
i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits()));
|
||||||
i2s.configure(&standard, &data_format);
|
i2s.configure(&standard, &data_format);
|
||||||
i2s.set_master();
|
i2s.set_master();
|
||||||
@ -297,11 +300,13 @@ where
|
|||||||
i2s: unsafe { i2s.clone_unchecked() },
|
i2s: unsafe { i2s.clone_unchecked() },
|
||||||
rx_channel: channel.rx,
|
rx_channel: channel.rx,
|
||||||
descriptors: rx_descriptors,
|
descriptors: rx_descriptors,
|
||||||
|
guard: rx_guard,
|
||||||
},
|
},
|
||||||
i2s_tx: TxCreator {
|
i2s_tx: TxCreator {
|
||||||
i2s,
|
i2s,
|
||||||
tx_channel: channel.tx,
|
tx_channel: channel.tx,
|
||||||
descriptors: tx_descriptors,
|
descriptors: tx_descriptors,
|
||||||
|
guard: tx_guard,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -432,11 +437,13 @@ where
|
|||||||
i2s: self.i2s_rx.i2s,
|
i2s: self.i2s_rx.i2s,
|
||||||
rx_channel: self.i2s_rx.rx_channel.into_async(),
|
rx_channel: self.i2s_rx.rx_channel.into_async(),
|
||||||
descriptors: self.i2s_rx.descriptors,
|
descriptors: self.i2s_rx.descriptors,
|
||||||
|
guard: self.i2s_rx.guard,
|
||||||
},
|
},
|
||||||
i2s_tx: TxCreator {
|
i2s_tx: TxCreator {
|
||||||
i2s: self.i2s_tx.i2s,
|
i2s: self.i2s_tx.i2s,
|
||||||
tx_channel: self.i2s_tx.tx_channel.into_async(),
|
tx_channel: self.i2s_tx.tx_channel.into_async(),
|
||||||
descriptors: self.i2s_tx.descriptors,
|
descriptors: self.i2s_tx.descriptors,
|
||||||
|
guard: self.i2s_tx.guard,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,6 +472,7 @@ where
|
|||||||
i2s: PeripheralRef<'d, T>,
|
i2s: PeripheralRef<'d, T>,
|
||||||
tx_channel: ChannelTx<'d, DmaMode, T::Dma>,
|
tx_channel: ChannelTx<'d, DmaMode, T::Dma>,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DmaMode, T> core::fmt::Debug for I2sTx<'_, DmaMode, T>
|
impl<DmaMode, T> core::fmt::Debug for I2sTx<'_, DmaMode, T>
|
||||||
@ -597,6 +605,7 @@ where
|
|||||||
i2s: PeripheralRef<'d, T>,
|
i2s: PeripheralRef<'d, T>,
|
||||||
rx_channel: ChannelRx<'d, DmaMode, T::Dma>,
|
rx_channel: ChannelRx<'d, DmaMode, T::Dma>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DmaMode, T> core::fmt::Debug for I2sRx<'_, DmaMode, T>
|
impl<DmaMode, T> core::fmt::Debug for I2sRx<'_, DmaMode, T>
|
||||||
@ -742,6 +751,7 @@ mod private {
|
|||||||
I2sInterrupt,
|
I2sInterrupt,
|
||||||
I2sRx,
|
I2sRx,
|
||||||
I2sTx,
|
I2sTx,
|
||||||
|
PeripheralGuard,
|
||||||
RegisterAccess,
|
RegisterAccess,
|
||||||
Standard,
|
Standard,
|
||||||
I2S_LL_MCLK_DIVIDER_MAX,
|
I2S_LL_MCLK_DIVIDER_MAX,
|
||||||
@ -774,6 +784,7 @@ mod private {
|
|||||||
pub i2s: PeripheralRef<'d, T>,
|
pub i2s: PeripheralRef<'d, T>,
|
||||||
pub tx_channel: ChannelTx<'d, M, T::Dma>,
|
pub tx_channel: ChannelTx<'d, M, T::Dma>,
|
||||||
pub descriptors: &'static mut [DmaDescriptor],
|
pub descriptors: &'static mut [DmaDescriptor],
|
||||||
|
pub(crate) guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> TxCreator<'d, M, T>
|
impl<'d, M, T> TxCreator<'d, M, T>
|
||||||
@ -782,10 +793,12 @@ mod private {
|
|||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
pub fn build(self) -> I2sTx<'d, M, T> {
|
pub fn build(self) -> I2sTx<'d, M, T> {
|
||||||
|
let peripheral = self.i2s.peripheral();
|
||||||
I2sTx {
|
I2sTx {
|
||||||
i2s: self.i2s,
|
i2s: self.i2s,
|
||||||
tx_channel: self.tx_channel,
|
tx_channel: self.tx_channel,
|
||||||
tx_chain: DescriptorChain::new(self.descriptors),
|
tx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: PeripheralGuard::new(peripheral),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,6 +844,7 @@ mod private {
|
|||||||
pub i2s: PeripheralRef<'d, T>,
|
pub i2s: PeripheralRef<'d, T>,
|
||||||
pub rx_channel: ChannelRx<'d, M, T::Dma>,
|
pub rx_channel: ChannelRx<'d, M, T::Dma>,
|
||||||
pub descriptors: &'static mut [DmaDescriptor],
|
pub descriptors: &'static mut [DmaDescriptor],
|
||||||
|
pub(crate) guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> RxCreator<'d, M, T>
|
impl<'d, M, T> RxCreator<'d, M, T>
|
||||||
@ -839,10 +853,12 @@ mod private {
|
|||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
{
|
{
|
||||||
pub fn build(self) -> I2sRx<'d, M, T> {
|
pub fn build(self) -> I2sRx<'d, M, T> {
|
||||||
|
let peripheral = self.i2s.peripheral();
|
||||||
I2sRx {
|
I2sRx {
|
||||||
i2s: self.i2s,
|
i2s: self.i2s,
|
||||||
rx_channel: self.rx_channel,
|
rx_channel: self.rx_channel,
|
||||||
rx_chain: DescriptorChain::new(self.descriptors),
|
rx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: PeripheralGuard::new(peripheral),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -60,7 +60,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::{i2s0::RegisterBlock, I2S0, I2S1},
|
peripherals::{i2s0::RegisterBlock, I2S0, I2S1},
|
||||||
private::Internal,
|
private::Internal,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
Async,
|
Async,
|
||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
@ -177,6 +177,7 @@ where
|
|||||||
{
|
{
|
||||||
instance: PeripheralRef<'d, I>,
|
instance: PeripheralRef<'d, I>,
|
||||||
tx_channel: ChannelTx<'d, DM, I::Dma>,
|
tx_channel: ChannelTx<'d, DM, I::Dma>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, DM> I2sParallel<'d, DM>
|
impl<'d, DM> I2sParallel<'d, DM>
|
||||||
@ -220,8 +221,8 @@ where
|
|||||||
channel.runtime_ensure_compatible(&i2s);
|
channel.runtime_ensure_compatible(&i2s);
|
||||||
let channel = channel.degrade();
|
let channel = channel.degrade();
|
||||||
|
|
||||||
PeripheralClockControl::reset(i2s.peripheral());
|
let guard = PeripheralGuard::new(i2s.peripheral());
|
||||||
PeripheralClockControl::enable(i2s.peripheral());
|
|
||||||
// configure the I2S peripheral for parallel mode
|
// configure the I2S peripheral for parallel mode
|
||||||
i2s.setup(frequency, pins.bus_width());
|
i2s.setup(frequency, pins.bus_width());
|
||||||
// setup the clock pin
|
// setup the clock pin
|
||||||
@ -232,6 +233,7 @@ where
|
|||||||
Self {
|
Self {
|
||||||
instance: i2s,
|
instance: i2s,
|
||||||
tx_channel: channel.tx,
|
tx_channel: channel.tx,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,7 @@ use crate::{
|
|||||||
lcd_cam::{calculate_clkm, BitOrder, ByteOrder},
|
lcd_cam::{calculate_clkm, BitOrder, ByteOrder},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::LCD_CAM,
|
peripherals::LCD_CAM,
|
||||||
|
system::{self, GenericPeripheralGuard},
|
||||||
Blocking,
|
Blocking,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -121,12 +122,14 @@ pub enum VsyncFilterThreshold {
|
|||||||
pub struct Cam<'d> {
|
pub struct Cam<'d> {
|
||||||
/// The LCD_CAM peripheral reference for managing the camera functionality.
|
/// The LCD_CAM peripheral reference for managing the camera functionality.
|
||||||
pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
||||||
|
pub(super) _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the camera interface with DMA support.
|
/// Represents the camera interface with DMA support.
|
||||||
pub struct Camera<'d> {
|
pub struct Camera<'d> {
|
||||||
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
||||||
rx_channel: ChannelRx<'d, Blocking, <LCD_CAM as DmaEligible>::Dma>,
|
rx_channel: ChannelRx<'d, Blocking, <LCD_CAM as DmaEligible>::Dma>,
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Camera<'d> {
|
impl<'d> Camera<'d> {
|
||||||
@ -187,6 +190,7 @@ impl<'d> Camera<'d> {
|
|||||||
Self {
|
Self {
|
||||||
lcd_cam,
|
lcd_cam,
|
||||||
rx_channel: channel.degrade(),
|
rx_channel: channel.degrade(),
|
||||||
|
_guard: cam._guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,12 @@
|
|||||||
//! ## Implementation State
|
//! ## Implementation State
|
||||||
//! - RGB is not supported yet
|
//! - RGB is not supported yet
|
||||||
|
|
||||||
use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM};
|
use super::GenericPeripheralGuard;
|
||||||
|
use crate::{
|
||||||
|
peripheral::PeripheralRef,
|
||||||
|
peripherals::LCD_CAM,
|
||||||
|
system::{self},
|
||||||
|
};
|
||||||
|
|
||||||
pub mod dpi;
|
pub mod dpi;
|
||||||
pub mod i8080;
|
pub mod i8080;
|
||||||
@ -22,6 +27,8 @@ pub struct Lcd<'d, DM: crate::Mode> {
|
|||||||
|
|
||||||
/// A marker for the mode of operation (blocking or asynchronous).
|
/// A marker for the mode of operation (blocking or asynchronous).
|
||||||
pub(crate) _mode: core::marker::PhantomData<DM>,
|
pub(crate) _mode: core::marker::PhantomData<DM>,
|
||||||
|
|
||||||
|
pub(super) _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use crate::{
|
|||||||
macros::handler,
|
macros::handler,
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
peripherals::{Interrupt, LCD_CAM},
|
peripherals::{Interrupt, LCD_CAM},
|
||||||
system::{self, PeripheralClockControl},
|
system::GenericPeripheralGuard,
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
Cpu,
|
Cpu,
|
||||||
@ -38,15 +38,19 @@ impl<'d> LcdCam<'d, Blocking> {
|
|||||||
pub fn new(lcd_cam: impl Peripheral<P = LCD_CAM> + 'd) -> Self {
|
pub fn new(lcd_cam: impl Peripheral<P = LCD_CAM> + 'd) -> Self {
|
||||||
crate::into_ref!(lcd_cam);
|
crate::into_ref!(lcd_cam);
|
||||||
|
|
||||||
PeripheralClockControl::reset(system::Peripheral::LcdCam);
|
let lcd_guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(system::Peripheral::LcdCam);
|
let cam_guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
lcd: Lcd {
|
lcd: Lcd {
|
||||||
lcd_cam: unsafe { lcd_cam.clone_unchecked() },
|
lcd_cam: unsafe { lcd_cam.clone_unchecked() },
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
_guard: lcd_guard,
|
||||||
|
},
|
||||||
|
cam: Cam {
|
||||||
|
lcd_cam,
|
||||||
|
_guard: cam_guard,
|
||||||
},
|
},
|
||||||
cam: Cam { lcd_cam },
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +61,7 @@ impl<'d> LcdCam<'d, Blocking> {
|
|||||||
lcd: Lcd {
|
lcd: Lcd {
|
||||||
lcd_cam: self.lcd.lcd_cam,
|
lcd_cam: self.lcd.lcd_cam,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
_guard: self.lcd._guard,
|
||||||
},
|
},
|
||||||
cam: self.cam,
|
cam: self.cam,
|
||||||
}
|
}
|
||||||
@ -87,6 +92,7 @@ impl<'d> LcdCam<'d, Async> {
|
|||||||
lcd: Lcd {
|
lcd: Lcd {
|
||||||
lcd_cam: self.lcd.lcd_cam,
|
lcd_cam: self.lcd.lcd_cam,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
_guard: self.lcd._guard,
|
||||||
},
|
},
|
||||||
cam: self.cam,
|
cam: self.cam,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,8 +111,9 @@ impl<'d> Ledc<'d> {
|
|||||||
pub fn new(_instance: impl Peripheral<P = crate::peripherals::LEDC> + 'd) -> Self {
|
pub fn new(_instance: impl Peripheral<P = crate::peripherals::LEDC> + 'd) -> Self {
|
||||||
crate::into_ref!(_instance);
|
crate::into_ref!(_instance);
|
||||||
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Ledc);
|
if PeripheralClockControl::enable(PeripheralEnable::Ledc) {
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Ledc);
|
PeripheralClockControl::reset(PeripheralEnable::Ledc);
|
||||||
|
}
|
||||||
|
|
||||||
let ledc = unsafe { &*crate::peripherals::LEDC::ptr() };
|
let ledc = unsafe { &*crate::peripherals::LEDC::ptr() };
|
||||||
Ledc { _instance, ledc }
|
Ledc { _instance, ledc }
|
||||||
|
|||||||
@ -515,6 +515,8 @@ pub struct Config {
|
|||||||
/// This function sets up the CPU clock and watchdog, then, returns the
|
/// This function sets up the CPU clock and watchdog, then, returns the
|
||||||
/// peripherals and clocks.
|
/// peripherals and clocks.
|
||||||
pub fn init(config: Config) -> Peripherals {
|
pub fn init(config: Config) -> Peripherals {
|
||||||
|
system::disable_peripherals();
|
||||||
|
|
||||||
let mut peripherals = Peripherals::take();
|
let mut peripherals = Peripherals::take();
|
||||||
|
|
||||||
// RTC domain must be enabled before we try to disable
|
// RTC domain must be enabled before we try to disable
|
||||||
|
|||||||
@ -94,7 +94,7 @@ use crate::{
|
|||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
gpio::OutputSignal,
|
gpio::OutputSignal,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
system::{self, PeripheralGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// MCPWM operators
|
/// MCPWM operators
|
||||||
@ -115,11 +115,12 @@ pub struct McPwm<'d, PWM> {
|
|||||||
/// Timer2
|
/// Timer2
|
||||||
pub timer2: Timer<2, PWM>,
|
pub timer2: Timer<2, PWM>,
|
||||||
/// Operator0
|
/// Operator0
|
||||||
pub operator0: Operator<0, PWM>,
|
pub operator0: Operator<'d, 0, PWM>,
|
||||||
/// Operator1
|
/// Operator1
|
||||||
pub operator1: Operator<1, PWM>,
|
pub operator1: Operator<'d, 1, PWM>,
|
||||||
/// Operator2
|
/// Operator2
|
||||||
pub operator2: Operator<2, PWM>,
|
pub operator2: Operator<'d, 2, PWM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> {
|
impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> {
|
||||||
@ -131,8 +132,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(peripheral);
|
crate::into_ref!(peripheral);
|
||||||
|
|
||||||
PWM::reset();
|
let guard = PeripheralGuard::new(PWM::peripheral());
|
||||||
PWM::enable();
|
|
||||||
|
|
||||||
#[cfg(not(esp32c6))]
|
#[cfg(not(esp32c6))]
|
||||||
{
|
{
|
||||||
@ -181,6 +181,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> {
|
|||||||
operator0: Operator::new(),
|
operator0: Operator::new(),
|
||||||
operator1: Operator::new(),
|
operator1: Operator::new(),
|
||||||
operator2: Operator::new(),
|
operator2: Operator::new(),
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,26 +314,16 @@ pub struct FrequencyError;
|
|||||||
|
|
||||||
/// A MCPWM peripheral
|
/// A MCPWM peripheral
|
||||||
pub trait PwmPeripheral: Deref<Target = RegisterBlock> + crate::private::Sealed {
|
pub trait PwmPeripheral: Deref<Target = RegisterBlock> + crate::private::Sealed {
|
||||||
/// Enable peripheral
|
|
||||||
fn enable();
|
|
||||||
/// Reset peripheral
|
|
||||||
fn reset();
|
|
||||||
/// Get a pointer to the peripheral RegisterBlock
|
/// Get a pointer to the peripheral RegisterBlock
|
||||||
fn block() -> *const RegisterBlock;
|
fn block() -> *const RegisterBlock;
|
||||||
/// Get operator GPIO mux output signal
|
/// Get operator GPIO mux output signal
|
||||||
fn output_signal<const OP: u8, const IS_A: bool>() -> OutputSignal;
|
fn output_signal<const OP: u8, const IS_A: bool>() -> OutputSignal;
|
||||||
|
/// Peripheral
|
||||||
|
fn peripheral() -> system::Peripheral;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(mcpwm0)]
|
#[cfg(mcpwm0)]
|
||||||
impl PwmPeripheral for crate::peripherals::MCPWM0 {
|
impl PwmPeripheral for crate::peripherals::MCPWM0 {
|
||||||
fn enable() {
|
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Mcpwm0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset() {
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Mcpwm0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block() -> *const RegisterBlock {
|
fn block() -> *const RegisterBlock {
|
||||||
Self::PTR
|
Self::PTR
|
||||||
}
|
}
|
||||||
@ -348,18 +339,14 @@ impl PwmPeripheral for crate::peripherals::MCPWM0 {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peripheral() -> system::Peripheral {
|
||||||
|
system::Peripheral::Mcpwm0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(mcpwm1)]
|
#[cfg(mcpwm1)]
|
||||||
impl PwmPeripheral for crate::peripherals::MCPWM1 {
|
impl PwmPeripheral for crate::peripherals::MCPWM1 {
|
||||||
fn enable() {
|
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Mcpwm1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reset() {
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Mcpwm1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block() -> *const RegisterBlock {
|
fn block() -> *const RegisterBlock {
|
||||||
Self::PTR
|
Self::PTR
|
||||||
}
|
}
|
||||||
@ -375,4 +362,8 @@ impl PwmPeripheral for crate::peripherals::MCPWM1 {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peripheral() -> system::Peripheral {
|
||||||
|
system::Peripheral::Mcpwm1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use super::PeripheralGuard;
|
||||||
use crate::{
|
use crate::{
|
||||||
gpio::interconnect::{OutputConnection, PeripheralOutput},
|
gpio::interconnect::{OutputConnection, PeripheralOutput},
|
||||||
mcpwm::{timer::Timer, PwmPeripheral},
|
mcpwm::{timer::Timer, PwmPeripheral},
|
||||||
@ -167,12 +168,15 @@ impl DeadTimeCfg {
|
|||||||
/// * Superimposes a carrier on the PWM signal, if configured to do so. (Not yet
|
/// * Superimposes a carrier on the PWM signal, if configured to do so. (Not yet
|
||||||
/// implemented)
|
/// implemented)
|
||||||
/// * Handles response under fault conditions. (Not yet implemented)
|
/// * Handles response under fault conditions. (Not yet implemented)
|
||||||
pub struct Operator<const OP: u8, PWM> {
|
pub struct Operator<'d, const OP: u8, PWM> {
|
||||||
phantom: PhantomData<PWM>,
|
phantom: PhantomData<&'d PWM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
|
let guard = PeripheralGuard::new(PWM::peripheral());
|
||||||
|
|
||||||
// Side note:
|
// Side note:
|
||||||
// It would have been nice to deselect any timer reference on peripheral
|
// It would have been nice to deselect any timer reference on peripheral
|
||||||
// initialization.
|
// initialization.
|
||||||
@ -181,6 +185,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
|||||||
// written.
|
// written.
|
||||||
Operator {
|
Operator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +209,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Use the A output with the given pin and configuration
|
/// Use the A output with the given pin and configuration
|
||||||
pub fn with_pin_a<'d>(
|
pub fn with_pin_a(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
config: PwmPinConfig<true>,
|
config: PwmPinConfig<true>,
|
||||||
@ -213,7 +218,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Use the B output with the given pin and configuration
|
/// Use the B output with the given pin and configuration
|
||||||
pub fn with_pin_b<'d>(
|
pub fn with_pin_b(
|
||||||
self,
|
self,
|
||||||
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
config: PwmPinConfig<false>,
|
config: PwmPinConfig<false>,
|
||||||
@ -222,7 +227,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Use both the A and the B output with the given pins and configurations
|
/// Use both the A and the B output with the given pins and configurations
|
||||||
pub fn with_pins<'d>(
|
pub fn with_pins(
|
||||||
self,
|
self,
|
||||||
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
config_a: PwmPinConfig<true>,
|
config_a: PwmPinConfig<true>,
|
||||||
@ -236,7 +241,7 @@ impl<const OP: u8, PWM: PwmPeripheral> Operator<OP, PWM> {
|
|||||||
///
|
///
|
||||||
/// This is useful for complementary or mirrored signals with or without
|
/// This is useful for complementary or mirrored signals with or without
|
||||||
/// configured deadtime
|
/// configured deadtime
|
||||||
pub fn with_linked_pins<'d>(
|
pub fn with_linked_pins(
|
||||||
self,
|
self,
|
||||||
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
pin_a: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
config_a: PwmPinConfig<true>,
|
config_a: PwmPinConfig<true>,
|
||||||
@ -283,6 +288,7 @@ impl<const IS_A: bool> PwmPinConfig<IS_A> {
|
|||||||
pub struct PwmPin<'d, PWM, const OP: u8, const IS_A: bool> {
|
pub struct PwmPin<'d, PWM, const OP: u8, const IS_A: bool> {
|
||||||
pin: PeripheralRef<'d, OutputConnection>,
|
pin: PeripheralRef<'d, OutputConnection>,
|
||||||
phantom: PhantomData<PWM>,
|
phantom: PhantomData<PWM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP, IS_A> {
|
impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP, IS_A> {
|
||||||
@ -291,9 +297,13 @@ impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP,
|
|||||||
config: PwmPinConfig<IS_A>,
|
config: PwmPinConfig<IS_A>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_mapped_ref!(pin);
|
crate::into_mapped_ref!(pin);
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(PWM::peripheral());
|
||||||
|
|
||||||
let mut pin = PwmPin {
|
let mut pin = PwmPin {
|
||||||
pin,
|
pin,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
};
|
};
|
||||||
pin.set_actions(config.actions);
|
pin.set_actions(config.actions);
|
||||||
pin.set_update_method(config.update_method);
|
pin.set_update_method(config.update_method);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use fugit::HertzU32;
|
use fugit::HertzU32;
|
||||||
|
|
||||||
|
use super::PeripheralGuard;
|
||||||
use crate::mcpwm::{FrequencyError, PeripheralClockConfig, PwmPeripheral};
|
use crate::mcpwm::{FrequencyError, PeripheralClockConfig, PwmPeripheral};
|
||||||
|
|
||||||
/// A MCPWM timer
|
/// A MCPWM timer
|
||||||
@ -17,12 +18,15 @@ use crate::mcpwm::{FrequencyError, PeripheralClockConfig, PwmPeripheral};
|
|||||||
/// [`Operator`](super::operator::Operator) of that peripheral
|
/// [`Operator`](super::operator::Operator) of that peripheral
|
||||||
pub struct Timer<const TIM: u8, PWM> {
|
pub struct Timer<const TIM: u8, PWM> {
|
||||||
pub(super) phantom: PhantomData<PWM>,
|
pub(super) phantom: PhantomData<PWM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const TIM: u8, PWM: PwmPeripheral> Timer<TIM, PWM> {
|
impl<const TIM: u8, PWM: PwmPeripheral> Timer<TIM, PWM> {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
|
let guard = PeripheralGuard::new(PWM::peripheral());
|
||||||
Timer {
|
Timer {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ use crate::{
|
|||||||
gpio::InputSignal,
|
gpio::InputSignal,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals,
|
peripherals,
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
system::{GenericPeripheralGuard, Peripheral as PeripheralEnable},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -57,6 +57,7 @@ pub trait UsbDm: crate::private::Sealed {}
|
|||||||
/// USB peripheral.
|
/// USB peripheral.
|
||||||
pub struct Usb<'d> {
|
pub struct Usb<'d> {
|
||||||
_usb0: PeripheralRef<'d, peripherals::USB0>,
|
_usb0: PeripheralRef<'d, peripherals::USB0>,
|
||||||
|
_guard: GenericPeripheralGuard<{ PeripheralEnable::Usb as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Usb<'d> {
|
impl<'d> Usb<'d> {
|
||||||
@ -70,11 +71,11 @@ impl<'d> Usb<'d> {
|
|||||||
P: UsbDp + Send + Sync,
|
P: UsbDp + Send + Sync,
|
||||||
M: UsbDm + Send + Sync,
|
M: UsbDm + Send + Sync,
|
||||||
{
|
{
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Usb);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Usb);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_usb0: usb0.into_ref(),
|
_usb0: usb0.into_ref(),
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,7 @@ use crate::{
|
|||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{self, Peripheral},
|
peripheral::{self, Peripheral},
|
||||||
peripherals::{self, Interrupt, PARL_IO},
|
peripherals::{self, Interrupt, PARL_IO},
|
||||||
system::PeripheralClockControl,
|
system::{self, GenericPeripheralGuard},
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
@ -767,6 +767,7 @@ where
|
|||||||
Ok(ParlIoTx {
|
Ok(ParlIoTx {
|
||||||
tx_channel: self.tx_channel,
|
tx_channel: self.tx_channel,
|
||||||
tx_chain: DescriptorChain::new(self.descriptors),
|
tx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: self._guard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,6 +799,7 @@ where
|
|||||||
Ok(ParlIoTx {
|
Ok(ParlIoTx {
|
||||||
tx_channel: self.tx_channel,
|
tx_channel: self.tx_channel,
|
||||||
tx_chain: DescriptorChain::new(self.descriptors),
|
tx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: self._guard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -809,6 +811,7 @@ where
|
|||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DM> core::fmt::Debug for ParlIoTx<'_, DM>
|
impl<DM> core::fmt::Debug for ParlIoTx<'_, DM>
|
||||||
@ -836,6 +839,8 @@ where
|
|||||||
P: FullDuplex + RxPins + ConfigurePins,
|
P: FullDuplex + RxPins + ConfigurePins,
|
||||||
CP: RxClkPin,
|
CP: RxClkPin,
|
||||||
{
|
{
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
rx_pins.configure()?;
|
rx_pins.configure()?;
|
||||||
clk_pin.configure();
|
clk_pin.configure();
|
||||||
|
|
||||||
@ -845,6 +850,7 @@ where
|
|||||||
Ok(ParlIoRx {
|
Ok(ParlIoRx {
|
||||||
rx_channel: self.rx_channel,
|
rx_channel: self.rx_channel,
|
||||||
rx_chain: DescriptorChain::new(self.descriptors),
|
rx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: guard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,6 +880,7 @@ where
|
|||||||
Ok(ParlIoRx {
|
Ok(ParlIoRx {
|
||||||
rx_channel: self.rx_channel,
|
rx_channel: self.rx_channel,
|
||||||
rx_chain: DescriptorChain::new(self.descriptors),
|
rx_chain: DescriptorChain::new(self.descriptors),
|
||||||
|
_guard: self._guard,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -885,6 +892,7 @@ where
|
|||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DM> core::fmt::Debug for ParlIoRx<'_, DM>
|
impl<DM> core::fmt::Debug for ParlIoRx<'_, DM>
|
||||||
@ -1007,6 +1015,8 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> {
|
|||||||
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
||||||
Channel<'d, Blocking, CH>: From<Channel<'d, DM, CH>>,
|
Channel<'d, Blocking, CH>: From<Channel<'d, DM, CH>>,
|
||||||
{
|
{
|
||||||
|
let tx_guard = GenericPeripheralGuard::new();
|
||||||
|
let rx_guard = GenericPeripheralGuard::new();
|
||||||
let dma_channel = Channel::<Blocking, CH>::from(dma_channel);
|
let dma_channel = Channel::<Blocking, CH>::from(dma_channel);
|
||||||
internal_init(frequency)?;
|
internal_init(frequency)?;
|
||||||
|
|
||||||
@ -1014,10 +1024,12 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> {
|
|||||||
tx: TxCreatorFullDuplex {
|
tx: TxCreatorFullDuplex {
|
||||||
tx_channel: dma_channel.tx.degrade(),
|
tx_channel: dma_channel.tx.degrade(),
|
||||||
descriptors: tx_descriptors,
|
descriptors: tx_descriptors,
|
||||||
|
_guard: tx_guard,
|
||||||
},
|
},
|
||||||
rx: RxCreatorFullDuplex {
|
rx: RxCreatorFullDuplex {
|
||||||
rx_channel: dma_channel.rx.degrade(),
|
rx_channel: dma_channel.rx.degrade(),
|
||||||
descriptors: rx_descriptors,
|
descriptors: rx_descriptors,
|
||||||
|
_guard: rx_guard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1028,10 +1040,12 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> {
|
|||||||
tx: TxCreatorFullDuplex {
|
tx: TxCreatorFullDuplex {
|
||||||
tx_channel: self.tx.tx_channel.into_async(),
|
tx_channel: self.tx.tx_channel.into_async(),
|
||||||
descriptors: self.tx.descriptors,
|
descriptors: self.tx.descriptors,
|
||||||
|
_guard: self.tx._guard,
|
||||||
},
|
},
|
||||||
rx: RxCreatorFullDuplex {
|
rx: RxCreatorFullDuplex {
|
||||||
rx_channel: self.rx.rx_channel.into_async(),
|
rx_channel: self.rx.rx_channel.into_async(),
|
||||||
descriptors: self.rx.descriptors,
|
descriptors: self.rx.descriptors,
|
||||||
|
_guard: self.rx._guard,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1080,10 +1094,12 @@ impl<'d> ParlIoFullDuplex<'d, Async> {
|
|||||||
tx: TxCreatorFullDuplex {
|
tx: TxCreatorFullDuplex {
|
||||||
tx_channel: self.tx.tx_channel.into_blocking(),
|
tx_channel: self.tx.tx_channel.into_blocking(),
|
||||||
descriptors: self.tx.descriptors,
|
descriptors: self.tx.descriptors,
|
||||||
|
_guard: self.tx._guard,
|
||||||
},
|
},
|
||||||
rx: RxCreatorFullDuplex {
|
rx: RxCreatorFullDuplex {
|
||||||
rx_channel: self.rx.rx_channel.into_blocking(),
|
rx_channel: self.rx.rx_channel.into_blocking(),
|
||||||
descriptors: self.rx.descriptors,
|
descriptors: self.rx.descriptors,
|
||||||
|
_guard: self.rx._guard,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1114,12 +1130,14 @@ where
|
|||||||
where
|
where
|
||||||
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
||||||
{
|
{
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
internal_init(frequency)?;
|
internal_init(frequency)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
tx: TxCreator {
|
tx: TxCreator {
|
||||||
tx_channel: dma_channel.tx.degrade(),
|
tx_channel: dma_channel.tx.degrade(),
|
||||||
descriptors,
|
descriptors,
|
||||||
|
_guard: guard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1188,12 +1206,14 @@ where
|
|||||||
where
|
where
|
||||||
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
CH: DmaChannelConvert<<PARL_IO as DmaEligible>::Dma>,
|
||||||
{
|
{
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
internal_init(frequency)?;
|
internal_init(frequency)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
rx: RxCreator {
|
rx: RxCreator {
|
||||||
rx_channel: dma_channel.rx.degrade(),
|
rx_channel: dma_channel.rx.degrade(),
|
||||||
descriptors,
|
descriptors,
|
||||||
|
_guard: guard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1242,9 +1262,6 @@ fn internal_init(frequency: HertzU32) -> Result<(), Error> {
|
|||||||
return Err(Error::UnreachableClockRate);
|
return Err(Error::UnreachableClockRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::ParlIo);
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::ParlIo);
|
|
||||||
|
|
||||||
let pcr = unsafe { &*crate::peripherals::PCR::PTR };
|
let pcr = unsafe { &*crate::peripherals::PCR::PTR };
|
||||||
|
|
||||||
let divider = crate::soc::constants::PARL_IO_SCLK / frequency.raw();
|
let divider = crate::soc::constants::PARL_IO_SCLK / frequency.raw();
|
||||||
@ -1458,6 +1475,7 @@ where
|
|||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a RX channel
|
/// Creates a RX channel
|
||||||
@ -1467,6 +1485,7 @@ where
|
|||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a TX channel
|
/// Creates a TX channel
|
||||||
@ -1476,6 +1495,7 @@ where
|
|||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
tx_channel: ChannelTx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a RX channel
|
/// Creates a RX channel
|
||||||
@ -1485,6 +1505,7 @@ where
|
|||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
rx_channel: ChannelRx<'d, DM, <PARL_IO as DmaEligible>::Dma>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|||||||
@ -13,6 +13,7 @@ pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE
|
|||||||
use crate::{
|
use crate::{
|
||||||
gpio::{interconnect::PeripheralInput, InputSignal},
|
gpio::{interconnect::PeripheralInput, InputSignal},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a channel within a pulse counter unit.
|
/// Represents a channel within a pulse counter unit.
|
||||||
@ -20,14 +21,18 @@ pub struct Channel<'d, const UNIT: usize, const NUM: usize> {
|
|||||||
_phantom: PhantomData<&'d ()>,
|
_phantom: PhantomData<&'d ()>,
|
||||||
// Individual channels are not Send, since they share registers.
|
// Individual channels are not Send, since they share registers.
|
||||||
_not_send: PhantomData<*const ()>,
|
_not_send: PhantomData<*const ()>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
|
impl<const UNIT: usize, const NUM: usize> Channel<'_, UNIT, NUM> {
|
||||||
/// return a new Channel
|
/// return a new Channel
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
_not_send: PhantomData,
|
_not_send: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ use crate::{
|
|||||||
interrupt::{self, InterruptHandler},
|
interrupt::{self, InterruptHandler},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::{self, Interrupt},
|
peripherals::{self, Interrupt},
|
||||||
system::PeripheralClockControl,
|
system::GenericPeripheralGuard,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,6 +56,8 @@ pub struct Pcnt<'d> {
|
|||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
/// Unit 7
|
/// Unit 7
|
||||||
pub unit7: Unit<'d, 7>,
|
pub unit7: Unit<'d, 7>,
|
||||||
|
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Pcnt<'d> {
|
impl<'d> Pcnt<'d> {
|
||||||
@ -63,10 +65,7 @@ impl<'d> Pcnt<'d> {
|
|||||||
pub fn new(_instance: impl Peripheral<P = peripherals::PCNT> + 'd) -> Self {
|
pub fn new(_instance: impl Peripheral<P = peripherals::PCNT> + 'd) -> Self {
|
||||||
crate::into_ref!(_instance);
|
crate::into_ref!(_instance);
|
||||||
|
|
||||||
// Enable the PCNT peripherals clock in the system peripheral
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::Pcnt);
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Pcnt);
|
|
||||||
|
|
||||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||||
|
|
||||||
// disable filter, all events, and channel settings
|
// disable filter, all events, and channel settings
|
||||||
@ -105,6 +104,7 @@ impl<'d> Pcnt<'d> {
|
|||||||
unit6: Unit::new(),
|
unit6: Unit::new(),
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
unit7: Unit::new(),
|
unit7: Unit::new(),
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use critical_section::CriticalSection;
|
use critical_section::CriticalSection;
|
||||||
|
|
||||||
use crate::pcnt::channel::Channel;
|
use crate::{pcnt::channel::Channel, system::GenericPeripheralGuard};
|
||||||
|
|
||||||
/// Invalid filter threshold value
|
/// Invalid filter threshold value
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
@ -82,15 +82,20 @@ pub struct Unit<'d, const NUM: usize> {
|
|||||||
pub channel0: Channel<'d, NUM, 0>,
|
pub channel0: Channel<'d, NUM, 0>,
|
||||||
/// The second channel in PCNT unit.
|
/// The second channel in PCNT unit.
|
||||||
pub channel1: Channel<'d, NUM, 1>,
|
pub channel1: Channel<'d, NUM, 1>,
|
||||||
|
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const NUM: usize> Unit<'_, NUM> {
|
impl<const NUM: usize> Unit<'_, NUM> {
|
||||||
/// return a new Unit
|
/// return a new Unit
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
counter: Counter::new(),
|
counter: Counter::new(),
|
||||||
channel0: Channel::new(),
|
channel0: Channel::new(),
|
||||||
channel1: Channel::new(),
|
channel1: Channel::new(),
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ use crate::{
|
|||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
peripherals::Interrupt,
|
peripherals::Interrupt,
|
||||||
soc::constants,
|
soc::constants,
|
||||||
system::PeripheralClockControl,
|
system::{self, GenericPeripheralGuard},
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
@ -228,9 +228,6 @@ where
|
|||||||
return Err(Error::UnreachableTargetFrequency);
|
return Err(Error::UnreachableTargetFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::Rmt);
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Rmt);
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(esp32, esp32s2))] {
|
if #[cfg(any(esp32, esp32s2))] {
|
||||||
self::chip_specific::configure_clock();
|
self::chip_specific::configure_clock();
|
||||||
@ -603,7 +600,10 @@ macro_rules! impl_rx_channel_creator {
|
|||||||
mod impl_for_chip {
|
mod impl_for_chip {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
use crate::{
|
||||||
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
|
};
|
||||||
|
|
||||||
/// RMT Instance
|
/// RMT Instance
|
||||||
pub struct Rmt<'d, M>
|
pub struct Rmt<'d, M>
|
||||||
@ -635,15 +635,19 @@ mod impl_for_chip {
|
|||||||
peripheral,
|
peripheral,
|
||||||
channel0: ChannelCreator {
|
channel0: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel1: ChannelCreator {
|
channel1: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel2: ChannelCreator {
|
channel2: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel3: ChannelCreator {
|
channel3: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -656,6 +660,7 @@ mod impl_for_chip {
|
|||||||
M: crate::Mode,
|
M: crate::Mode,
|
||||||
{
|
{
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_tx_channel_creator!(0);
|
impl_tx_channel_creator!(0);
|
||||||
@ -675,7 +680,10 @@ mod impl_for_chip {
|
|||||||
mod impl_for_chip {
|
mod impl_for_chip {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
use crate::{
|
||||||
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
|
};
|
||||||
|
|
||||||
/// RMT Instance
|
/// RMT Instance
|
||||||
pub struct Rmt<'d, M>
|
pub struct Rmt<'d, M>
|
||||||
@ -710,32 +718,39 @@ mod impl_for_chip {
|
|||||||
peripheral: impl Peripheral<P = crate::peripherals::RMT> + 'd,
|
peripheral: impl Peripheral<P = crate::peripherals::RMT> + 'd,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::into_ref!(peripheral);
|
crate::into_ref!(peripheral);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
peripheral,
|
peripheral,
|
||||||
channel0: ChannelCreator {
|
channel0: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel1: ChannelCreator {
|
channel1: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel2: ChannelCreator {
|
channel2: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel3: ChannelCreator {
|
channel3: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel4: ChannelCreator {
|
channel4: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel5: ChannelCreator {
|
channel5: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel6: ChannelCreator {
|
channel6: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel7: ChannelCreator {
|
channel7: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -748,6 +763,7 @@ mod impl_for_chip {
|
|||||||
M: crate::Mode,
|
M: crate::Mode,
|
||||||
{
|
{
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_tx_channel_creator!(0);
|
impl_tx_channel_creator!(0);
|
||||||
@ -791,7 +807,10 @@ mod impl_for_chip {
|
|||||||
mod impl_for_chip {
|
mod impl_for_chip {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
use crate::{
|
||||||
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
|
};
|
||||||
|
|
||||||
/// RMT Instance
|
/// RMT Instance
|
||||||
pub struct Rmt<'d, M>
|
pub struct Rmt<'d, M>
|
||||||
@ -823,15 +842,19 @@ mod impl_for_chip {
|
|||||||
peripheral,
|
peripheral,
|
||||||
channel0: ChannelCreator {
|
channel0: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel1: ChannelCreator {
|
channel1: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel2: ChannelCreator {
|
channel2: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel3: ChannelCreator {
|
channel3: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -844,6 +867,7 @@ mod impl_for_chip {
|
|||||||
M: crate::Mode,
|
M: crate::Mode,
|
||||||
{
|
{
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_tx_channel_creator!(0);
|
impl_tx_channel_creator!(0);
|
||||||
@ -871,7 +895,10 @@ mod impl_for_chip {
|
|||||||
mod impl_for_chip {
|
mod impl_for_chip {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::peripheral::{Peripheral, PeripheralRef};
|
use crate::{
|
||||||
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
|
system::GenericPeripheralGuard,
|
||||||
|
};
|
||||||
|
|
||||||
/// RMT Instance
|
/// RMT Instance
|
||||||
pub struct Rmt<'d, M>
|
pub struct Rmt<'d, M>
|
||||||
@ -911,27 +938,35 @@ mod impl_for_chip {
|
|||||||
peripheral,
|
peripheral,
|
||||||
channel0: ChannelCreator {
|
channel0: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel1: ChannelCreator {
|
channel1: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel2: ChannelCreator {
|
channel2: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel3: ChannelCreator {
|
channel3: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel4: ChannelCreator {
|
channel4: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel5: ChannelCreator {
|
channel5: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel6: ChannelCreator {
|
channel6: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
channel7: ChannelCreator {
|
channel7: ChannelCreator {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: GenericPeripheralGuard::new(),
|
||||||
},
|
},
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -944,6 +979,7 @@ mod impl_for_chip {
|
|||||||
M: crate::Mode,
|
M: crate::Mode,
|
||||||
{
|
{
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_tx_channel_creator!(0);
|
impl_tx_channel_creator!(0);
|
||||||
@ -968,13 +1004,14 @@ mod impl_for_chip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// RMT Channel
|
/// RMT Channel
|
||||||
#[non_exhaustive]
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct Channel<M, const CHANNEL: u8>
|
pub struct Channel<M, const CHANNEL: u8>
|
||||||
where
|
where
|
||||||
M: crate::Mode,
|
M: crate::Mode,
|
||||||
{
|
{
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
_guard: GenericPeripheralGuard<{ system::Peripheral::Rmt as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Channel in TX mode
|
/// Channel in TX mode
|
||||||
@ -1594,8 +1631,10 @@ mod chip_specific {
|
|||||||
const CHANNEL: u8 = $ch_num;
|
const CHANNEL: u8 = $ch_num;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
Self {
|
Self {
|
||||||
phantom: core::marker::PhantomData,
|
phantom: core::marker::PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1755,8 +1794,10 @@ mod chip_specific {
|
|||||||
const CHANNEL: u8 = $ch_num;
|
const CHANNEL: u8 = $ch_num;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
Self {
|
Self {
|
||||||
phantom: core::marker::PhantomData,
|
phantom: core::marker::PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1944,8 +1985,10 @@ mod chip_specific {
|
|||||||
const CHANNEL: u8 = $ch_num;
|
const CHANNEL: u8 = $ch_num;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
Self {
|
Self {
|
||||||
phantom: core::marker::PhantomData,
|
phantom: core::marker::PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2095,8 +2138,10 @@ mod chip_specific {
|
|||||||
const CHANNEL: u8 = $ch_num;
|
const CHANNEL: u8 = $ch_num;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
Self {
|
Self {
|
||||||
phantom: core::marker::PhantomData,
|
phantom: core::marker::PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ use crate::{
|
|||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::{Interrupt, RSA},
|
peripherals::{Interrupt, RSA},
|
||||||
system::{Peripheral as PeripheralEnable, PeripheralClockControl},
|
system::{GenericPeripheralGuard, Peripheral as PeripheralEnable},
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
Cpu,
|
Cpu,
|
||||||
@ -48,6 +48,7 @@ pub use rsa_spec_impl::operand_sizes;
|
|||||||
pub struct Rsa<'d, DM: crate::Mode> {
|
pub struct Rsa<'d, DM: crate::Mode> {
|
||||||
rsa: PeripheralRef<'d, RSA>,
|
rsa: PeripheralRef<'d, RSA>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
|
_guard: GenericPeripheralGuard<{ PeripheralEnable::Rsa as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Rsa<'d, Blocking> {
|
impl<'d> Rsa<'d, Blocking> {
|
||||||
@ -64,6 +65,7 @@ impl<'d> Rsa<'d, Blocking> {
|
|||||||
Rsa {
|
Rsa {
|
||||||
rsa: self.rsa,
|
rsa: self.rsa,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: self._guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,6 +89,7 @@ impl<'d> Rsa<'d, Async> {
|
|||||||
Rsa {
|
Rsa {
|
||||||
rsa: self.rsa,
|
rsa: self.rsa,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: self._guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,12 +98,12 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> {
|
|||||||
fn new_internal(rsa: impl Peripheral<P = RSA> + 'd) -> Self {
|
fn new_internal(rsa: impl Peripheral<P = RSA> + 'd) -> Self {
|
||||||
crate::into_ref!(rsa);
|
crate::into_ref!(rsa);
|
||||||
|
|
||||||
PeripheralClockControl::reset(PeripheralEnable::Rsa);
|
let guard = GenericPeripheralGuard::new();
|
||||||
PeripheralClockControl::enable(PeripheralEnable::Rsa);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
rsa,
|
rsa,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,23 +68,22 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::SHA,
|
peripherals::SHA,
|
||||||
reg_access::{AlignmentHelper, SocDependentEndianess},
|
reg_access::{AlignmentHelper, SocDependentEndianess},
|
||||||
system::PeripheralClockControl,
|
system::GenericPeripheralGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The SHA Accelerator driver instance
|
/// The SHA Accelerator driver instance
|
||||||
pub struct Sha<'d> {
|
pub struct Sha<'d> {
|
||||||
sha: PeripheralRef<'d, SHA>,
|
sha: PeripheralRef<'d, SHA>,
|
||||||
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::Sha as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Sha<'d> {
|
impl<'d> Sha<'d> {
|
||||||
/// Create a new instance of the SHA Accelerator driver.
|
/// Create a new instance of the SHA Accelerator driver.
|
||||||
pub fn new(sha: impl Peripheral<P = SHA> + 'd) -> Self {
|
pub fn new(sha: impl Peripheral<P = SHA> + 'd) -> Self {
|
||||||
crate::into_ref!(sha);
|
crate::into_ref!(sha);
|
||||||
|
let guard = GenericPeripheralGuard::new();
|
||||||
|
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::Sha);
|
Self { sha, _guard: guard }
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Sha);
|
|
||||||
|
|
||||||
Self { sha }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start a new digest.
|
/// Start a new digest.
|
||||||
|
|||||||
@ -85,7 +85,7 @@ use crate::{
|
|||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
private,
|
private,
|
||||||
spi::AnySpi,
|
spi::AnySpi,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
Mode,
|
Mode,
|
||||||
@ -462,6 +462,7 @@ pub enum ConfigError {}
|
|||||||
pub struct Spi<'d, M, T = AnySpi> {
|
pub struct Spi<'d, M, T = AnySpi> {
|
||||||
spi: PeripheralRef<'d, T>,
|
spi: PeripheralRef<'d, T>,
|
||||||
_mode: PhantomData<M>,
|
_mode: PhantomData<M>,
|
||||||
|
guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, M, T> Spi<'d, M, T>
|
impl<'d, M, T> Spi<'d, M, T>
|
||||||
@ -543,6 +544,7 @@ impl<'d> Spi<'d, Blocking> {
|
|||||||
Spi {
|
Spi {
|
||||||
spi: self.spi,
|
spi: self.spi,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -553,6 +555,7 @@ impl<'d> Spi<'d, Async> {
|
|||||||
Spi {
|
Spi {
|
||||||
spi: self.spi,
|
spi: self.spi,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,14 +576,14 @@ where
|
|||||||
) -> Spi<'d, M, T> {
|
) -> Spi<'d, M, T> {
|
||||||
crate::into_ref!(spi);
|
crate::into_ref!(spi);
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(spi.info().peripheral);
|
||||||
|
|
||||||
let mut this = Spi {
|
let mut this = Spi {
|
||||||
spi,
|
spi,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
guard,
|
||||||
};
|
};
|
||||||
|
|
||||||
PeripheralClockControl::enable(this.driver().peripheral);
|
|
||||||
PeripheralClockControl::reset(this.driver().peripheral);
|
|
||||||
|
|
||||||
this.driver().init();
|
this.driver().init();
|
||||||
unwrap!(this.apply_config(&config)); // FIXME: update based on the resolution of https://github.com/esp-rs/esp-hal/issues/2416
|
unwrap!(this.apply_config(&config)); // FIXME: update based on the resolution of https://github.com/esp-rs/esp-hal/issues/2416
|
||||||
|
|
||||||
@ -885,6 +888,7 @@ mod dma {
|
|||||||
rx_transfer_in_progress: bool,
|
rx_transfer_in_progress: bool,
|
||||||
#[cfg(all(esp32, spi_address_workaround))]
|
#[cfg(all(esp32, spi_address_workaround))]
|
||||||
address_buffer: DmaTxBuf,
|
address_buffer: DmaTxBuf,
|
||||||
|
guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, T> crate::private::Sealed for SpiDma<'_, M, T>
|
impl<M, T> crate::private::Sealed for SpiDma<'_, M, T>
|
||||||
@ -907,6 +911,7 @@ mod dma {
|
|||||||
rx_transfer_in_progress: self.rx_transfer_in_progress,
|
rx_transfer_in_progress: self.rx_transfer_in_progress,
|
||||||
#[cfg(all(esp32, spi_address_workaround))]
|
#[cfg(all(esp32, spi_address_workaround))]
|
||||||
address_buffer: self.address_buffer,
|
address_buffer: self.address_buffer,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -924,6 +929,7 @@ mod dma {
|
|||||||
rx_transfer_in_progress: self.rx_transfer_in_progress,
|
rx_transfer_in_progress: self.rx_transfer_in_progress,
|
||||||
#[cfg(all(esp32, spi_address_workaround))]
|
#[cfg(all(esp32, spi_address_workaround))]
|
||||||
address_buffer: self.address_buffer,
|
address_buffer: self.address_buffer,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1015,6 +1021,8 @@ mod dma {
|
|||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(spi.info().peripheral);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
spi,
|
spi,
|
||||||
channel: channel.degrade(),
|
channel: channel.degrade(),
|
||||||
@ -1022,6 +1030,7 @@ mod dma {
|
|||||||
address_buffer,
|
address_buffer,
|
||||||
tx_transfer_in_progress: false,
|
tx_transfer_in_progress: false,
|
||||||
rx_transfer_in_progress: false,
|
rx_transfer_in_progress: false,
|
||||||
|
guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -88,7 +88,7 @@ use crate::{
|
|||||||
peripherals::spi2::RegisterBlock,
|
peripherals::spi2::RegisterBlock,
|
||||||
private,
|
private,
|
||||||
spi::AnySpi,
|
spi::AnySpi,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
Blocking,
|
Blocking,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,6 +102,7 @@ pub struct Spi<'d, M, T = AnySpi> {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
data_mode: SpiMode,
|
data_mode: SpiMode,
|
||||||
_mode: PhantomData<M>,
|
_mode: PhantomData<M>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Spi<'d, Blocking> {
|
impl<'d> Spi<'d, Blocking> {
|
||||||
@ -119,15 +120,15 @@ where
|
|||||||
pub fn new_typed(spi: impl Peripheral<P = T> + 'd, mode: SpiMode) -> Spi<'d, M, T> {
|
pub fn new_typed(spi: impl Peripheral<P = T> + 'd, mode: SpiMode) -> Spi<'d, M, T> {
|
||||||
crate::into_ref!(spi);
|
crate::into_ref!(spi);
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(spi.info().peripheral);
|
||||||
|
|
||||||
let this = Spi {
|
let this = Spi {
|
||||||
spi,
|
spi,
|
||||||
data_mode: mode,
|
data_mode: mode,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
|
_guard: guard,
|
||||||
};
|
};
|
||||||
|
|
||||||
PeripheralClockControl::reset(this.spi.info().peripheral);
|
|
||||||
PeripheralClockControl::enable(this.spi.info().peripheral);
|
|
||||||
|
|
||||||
this.spi.info().init();
|
this.spi.info().init();
|
||||||
this.spi.info().set_data_mode(mode, false);
|
this.spi.info().set_data_mode(mode, false);
|
||||||
|
|
||||||
@ -226,6 +227,7 @@ pub mod dma {
|
|||||||
pub(crate) channel: Channel<'d, M, T::Dma>,
|
pub(crate) channel: Channel<'d, M, T::Dma>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DmaMode, T> core::fmt::Debug for SpiDma<'_, DmaMode, T>
|
impl<DmaMode, T> core::fmt::Debug for SpiDma<'_, DmaMode, T>
|
||||||
@ -304,11 +306,14 @@ pub mod dma {
|
|||||||
CH: DmaChannelConvert<T::Dma>,
|
CH: DmaChannelConvert<T::Dma>,
|
||||||
{
|
{
|
||||||
channel.runtime_ensure_compatible(&spi);
|
channel.runtime_ensure_compatible(&spi);
|
||||||
|
let guard = PeripheralGuard::new(spi.info().peripheral);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
spi,
|
spi,
|
||||||
channel: channel.degrade(),
|
channel: channel.degrade(),
|
||||||
rx_chain: DescriptorChain::new(rx_descriptors),
|
rx_chain: DescriptorChain::new(rx_descriptors),
|
||||||
tx_chain: DescriptorChain::new(tx_descriptors),
|
tx_chain: DescriptorChain::new(tx_descriptors),
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,23 @@
|
|||||||
//! This `system` module defines the available radio peripherals and provides an
|
//! This `system` module defines the available radio peripherals and provides an
|
||||||
//! interface to control and configure radio clocks.
|
//! interface to control and configure radio clocks.
|
||||||
|
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
use critical_section::CriticalSection;
|
||||||
|
use portable_atomic::AtomicUsize;
|
||||||
|
use strum::{EnumCount, EnumIter, IntoEnumIterator};
|
||||||
|
|
||||||
use crate::peripherals::SYSTEM;
|
use crate::peripherals::SYSTEM;
|
||||||
|
|
||||||
|
pub(crate) const KEEP_ENABLED: &[Peripheral] = &[
|
||||||
|
Peripheral::Uart0,
|
||||||
|
#[cfg(usb_device)]
|
||||||
|
Peripheral::UsbDevice,
|
||||||
|
#[cfg(systimer)]
|
||||||
|
Peripheral::Systimer,
|
||||||
|
Peripheral::Timg0,
|
||||||
|
];
|
||||||
|
|
||||||
/// Peripherals which can be enabled via `PeripheralClockControl`.
|
/// Peripherals which can be enabled via `PeripheralClockControl`.
|
||||||
///
|
///
|
||||||
/// This enum represents various hardware peripherals that can be enabled
|
/// This enum represents various hardware peripherals that can be enabled
|
||||||
@ -15,7 +30,8 @@ use crate::peripherals::SYSTEM;
|
|||||||
// FIXME: This enum needs to be public because it's exposed via a bunch of traits, but it's not
|
// FIXME: This enum needs to be public because it's exposed via a bunch of traits, but it's not
|
||||||
// useful to users.
|
// useful to users.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, EnumCount, EnumIter)]
|
||||||
|
#[repr(u8)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum Peripheral {
|
pub enum Peripheral {
|
||||||
/// SPI2 peripheral.
|
/// SPI2 peripheral.
|
||||||
@ -78,9 +94,6 @@ pub enum Peripheral {
|
|||||||
/// Timer Group 1 peripheral.
|
/// Timer Group 1 peripheral.
|
||||||
#[cfg(timg1)]
|
#[cfg(timg1)]
|
||||||
Timg1,
|
Timg1,
|
||||||
/// Low-power watchdog timer (WDT) peripheral.
|
|
||||||
#[cfg(lp_wdt)]
|
|
||||||
Wdt,
|
|
||||||
/// SHA peripheral (Secure Hash Algorithm).
|
/// SHA peripheral (Secure Hash Algorithm).
|
||||||
#[cfg(sha)]
|
#[cfg(sha)]
|
||||||
Sha,
|
Sha,
|
||||||
@ -122,234 +135,256 @@ pub enum Peripheral {
|
|||||||
Systimer,
|
Systimer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Peripheral {
|
||||||
|
pub fn try_from(value: u8) -> Option<Peripheral> {
|
||||||
|
if value >= Peripheral::COUNT as u8 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(unsafe { core::mem::transmute::<u8, Peripheral>(value) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PERIPHERAL_REF_COUNT: [AtomicUsize; Peripheral::COUNT] =
|
||||||
|
[const { AtomicUsize::new(0) }; Peripheral::COUNT];
|
||||||
|
|
||||||
|
/// Disable all peripherals.
|
||||||
|
///
|
||||||
|
/// Peripherals listed in [KEEP_ENABLED] are NOT disabled.
|
||||||
|
pub(crate) fn disable_peripherals() {
|
||||||
|
for p in Peripheral::iter() {
|
||||||
|
if KEEP_ENABLED.contains(&p) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PeripheralClockControl::enable_forced(p, false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct PeripheralGuard {
|
||||||
|
peripheral: Peripheral,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PeripheralGuard {
|
||||||
|
pub(crate) fn new(p: Peripheral) -> Self {
|
||||||
|
if !KEEP_ENABLED.contains(&p) && PeripheralClockControl::enable(p) {
|
||||||
|
PeripheralClockControl::reset(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self { peripheral: p }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PeripheralGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !KEEP_ENABLED.contains(&self.peripheral) {
|
||||||
|
PeripheralClockControl::disable(self.peripheral);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct GenericPeripheralGuard<const P: u8> {}
|
||||||
|
|
||||||
|
impl<const P: u8> GenericPeripheralGuard<P> {
|
||||||
|
pub(crate) fn new() -> Self {
|
||||||
|
let peripheral = unwrap!(Peripheral::try_from(P));
|
||||||
|
if !KEEP_ENABLED.contains(&peripheral) && PeripheralClockControl::enable(peripheral) {
|
||||||
|
PeripheralClockControl::reset(peripheral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const P: u8> Drop for GenericPeripheralGuard<P> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let peripheral = unwrap!(Peripheral::try_from(P));
|
||||||
|
if !KEEP_ENABLED.contains(&peripheral) {
|
||||||
|
PeripheralClockControl::disable(peripheral);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Controls the enablement of peripheral clocks.
|
/// Controls the enablement of peripheral clocks.
|
||||||
pub(crate) struct PeripheralClockControl;
|
pub(crate) struct PeripheralClockControl;
|
||||||
|
|
||||||
#[cfg(not(any(esp32c6, esp32h2)))]
|
#[cfg(not(any(esp32c6, esp32h2)))]
|
||||||
impl PeripheralClockControl {
|
impl PeripheralClockControl {
|
||||||
/// Enables and resets the given peripheral
|
fn enable_internal(peripheral: Peripheral, enable: bool, _cs: &CriticalSection<'_>) {
|
||||||
pub(crate) fn enable(peripheral: Peripheral) {
|
debug!("Enable {:?} {}", peripheral, enable);
|
||||||
|
|
||||||
let system = unsafe { &*SYSTEM::PTR };
|
let system = unsafe { &*SYSTEM::PTR };
|
||||||
|
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
let (perip_clk_en0, perip_rst_en0, peri_clk_en, peri_rst_en) = {
|
let (perip_clk_en0, peri_clk_en) = { (&system.perip_clk_en(), &system.peri_clk_en()) };
|
||||||
(
|
|
||||||
&system.perip_clk_en(),
|
|
||||||
&system.perip_rst_en(),
|
|
||||||
&system.peri_clk_en(),
|
|
||||||
&system.peri_rst_en(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
#[cfg(not(esp32))]
|
#[cfg(not(esp32))]
|
||||||
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en0(), &system.perip_rst_en0()) };
|
let perip_clk_en0 = &system.perip_clk_en0();
|
||||||
|
|
||||||
#[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))]
|
#[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))]
|
||||||
let (perip_clk_en1, perip_rst_en1) = { (&system.perip_clk_en1(), &system.perip_rst_en1()) };
|
let perip_clk_en1 = &system.perip_clk_en1();
|
||||||
|
|
||||||
critical_section::with(|_cs| match peripheral {
|
match peripheral {
|
||||||
#[cfg(spi2)]
|
#[cfg(spi2)]
|
||||||
Peripheral::Spi2 => {
|
Peripheral::Spi2 => {
|
||||||
perip_clk_en0.modify(|_, w| w.spi2_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(spi3)]
|
#[cfg(spi3)]
|
||||||
Peripheral::Spi3 => {
|
Peripheral::Spi3 => {
|
||||||
perip_clk_en0.modify(|_, w| w.spi3_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(all(i2c0, esp32))]
|
#[cfg(all(i2c0, esp32))]
|
||||||
Peripheral::I2cExt0 => {
|
Peripheral::I2cExt0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(all(i2c0, not(esp32)))]
|
#[cfg(all(i2c0, not(esp32)))]
|
||||||
Peripheral::I2cExt0 => {
|
Peripheral::I2cExt0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(i2c1)]
|
#[cfg(i2c1)]
|
||||||
Peripheral::I2cExt1 => {
|
Peripheral::I2cExt1 => {
|
||||||
perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(rmt)]
|
#[cfg(rmt)]
|
||||||
Peripheral::Rmt => {
|
Peripheral::Rmt => {
|
||||||
perip_clk_en0.modify(|_, w| w.rmt_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(ledc)]
|
#[cfg(ledc)]
|
||||||
Peripheral::Ledc => {
|
Peripheral::Ledc => {
|
||||||
perip_clk_en0.modify(|_, w| w.ledc_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(mcpwm0)]
|
#[cfg(mcpwm0)]
|
||||||
Peripheral::Mcpwm0 => {
|
Peripheral::Mcpwm0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.pwm0_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.pwm0_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(mcpwm1)]
|
#[cfg(mcpwm1)]
|
||||||
Peripheral::Mcpwm1 => {
|
Peripheral::Mcpwm1 => {
|
||||||
perip_clk_en0.modify(|_, w| w.pwm1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.pwm1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(pcnt)]
|
#[cfg(pcnt)]
|
||||||
Peripheral::Pcnt => {
|
Peripheral::Pcnt => {
|
||||||
perip_clk_en0.modify(|_, w| w.pcnt_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.pcnt_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(apb_saradc)]
|
#[cfg(apb_saradc)]
|
||||||
Peripheral::ApbSarAdc => {
|
Peripheral::ApbSarAdc => {
|
||||||
perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(gdma)]
|
#[cfg(gdma)]
|
||||||
Peripheral::Gdma => {
|
Peripheral::Gdma => {
|
||||||
perip_clk_en1.modify(|_, w| w.dma_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
Peripheral::Dma => {
|
Peripheral::Dma => {
|
||||||
perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.spi_dma_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32s2)]
|
#[cfg(esp32s2)]
|
||||||
Peripheral::Dma => {
|
Peripheral::Dma => {
|
||||||
perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.spi2_dma_rst().clear_bit());
|
perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable));
|
||||||
perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().set_bit());
|
|
||||||
perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32c3)]
|
#[cfg(esp32c3)]
|
||||||
Peripheral::I2s0 => {
|
Peripheral::I2s0 => {
|
||||||
// on ESP32-C3 note that i2s1_clk_en / rst is really I2s0
|
// on ESP32-C3 note that i2s1_clk_en / rst is really I2s0
|
||||||
perip_clk_en0.modify(|_, w| w.i2s1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(any(esp32s3, esp32, esp32s2))]
|
#[cfg(any(esp32s3, esp32, esp32s2))]
|
||||||
Peripheral::I2s0 => {
|
Peripheral::I2s0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.i2s0_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2s0_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(any(esp32s3, esp32))]
|
#[cfg(any(esp32s3, esp32))]
|
||||||
Peripheral::I2s1 => {
|
Peripheral::I2s1 => {
|
||||||
perip_clk_en0.modify(|_, w| w.i2s1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(usb0)]
|
#[cfg(usb0)]
|
||||||
Peripheral::Usb => {
|
Peripheral::Usb => {
|
||||||
perip_clk_en0.modify(|_, w| w.usb_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(twai0)]
|
#[cfg(twai0)]
|
||||||
Peripheral::Twai0 => {
|
Peripheral::Twai0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.twai_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.twai_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
Peripheral::Aes => {
|
Peripheral::Aes => {
|
||||||
peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | 1) });
|
peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) });
|
||||||
peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & (!1)) });
|
|
||||||
}
|
}
|
||||||
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
||||||
Peripheral::Aes => {
|
Peripheral::Aes => {
|
||||||
perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(timg0)]
|
#[cfg(timg0)]
|
||||||
Peripheral::Timg0 => {
|
Peripheral::Timg0 => {
|
||||||
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
||||||
perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable));
|
||||||
perip_clk_en0.modify(|_, w| w.timergroup_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable));
|
||||||
|
|
||||||
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
|
||||||
perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
|
|
||||||
perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(timg1)]
|
#[cfg(timg1)]
|
||||||
Peripheral::Timg1 => {
|
Peripheral::Timg1 => {
|
||||||
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
||||||
perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable));
|
||||||
perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable));
|
||||||
|
|
||||||
#[cfg(any(esp32c3, esp32s2, esp32s3))]
|
|
||||||
perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit());
|
|
||||||
perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(sha)]
|
#[cfg(sha)]
|
||||||
Peripheral::Sha => {
|
Peripheral::Sha => {
|
||||||
#[cfg(not(esp32))]
|
#[cfg(not(esp32))]
|
||||||
perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable));
|
||||||
#[cfg(not(esp32))]
|
|
||||||
perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32c3)]
|
#[cfg(esp32c3)]
|
||||||
Peripheral::UsbDevice => {
|
Peripheral::UsbDevice => {
|
||||||
perip_clk_en0.modify(|_, w| w.usb_device_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
Peripheral::UsbDevice => {
|
Peripheral::UsbDevice => {
|
||||||
perip_clk_en1.modify(|_, w| w.usb_device_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(uart0)]
|
#[cfg(uart0)]
|
||||||
Peripheral::Uart0 => {
|
Peripheral::Uart0 => {
|
||||||
perip_clk_en0.modify(|_, w| w.uart_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(uart1)]
|
#[cfg(uart1)]
|
||||||
Peripheral::Uart1 => {
|
Peripheral::Uart1 => {
|
||||||
perip_clk_en0.modify(|_, w| w.uart1_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(all(uart2, esp32s3))]
|
#[cfg(all(uart2, esp32s3))]
|
||||||
Peripheral::Uart2 => {
|
Peripheral::Uart2 => {
|
||||||
perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit());
|
||||||
perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(all(uart2, esp32))]
|
#[cfg(all(uart2, esp32))]
|
||||||
Peripheral::Uart2 => {
|
Peripheral::Uart2 => {
|
||||||
perip_clk_en0.modify(|_, w| w.uart2_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(all(rsa, esp32))]
|
#[cfg(all(rsa, esp32))]
|
||||||
Peripheral::Rsa => {
|
Peripheral::Rsa => {
|
||||||
peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | 1 << 2) });
|
peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | (enable as u32) << 2) });
|
||||||
peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) });
|
|
||||||
}
|
}
|
||||||
#[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))]
|
#[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))]
|
||||||
Peripheral::Rsa => {
|
Peripheral::Rsa => {
|
||||||
perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit());
|
|
||||||
system
|
system
|
||||||
.rsa_pd_ctrl()
|
.rsa_pd_ctrl()
|
||||||
.modify(|_, w| w.rsa_mem_pd().clear_bit());
|
.modify(|_, w| w.rsa_mem_pd().bit(!enable));
|
||||||
}
|
}
|
||||||
#[cfg(hmac)]
|
#[cfg(hmac)]
|
||||||
Peripheral::Hmac => {
|
Peripheral::Hmac => {
|
||||||
perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(ecc)]
|
#[cfg(ecc)]
|
||||||
Peripheral::Ecc => {
|
Peripheral::Ecc => {
|
||||||
perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(lcd_cam)]
|
#[cfg(lcd_cam)]
|
||||||
Peripheral::LcdCam => {
|
Peripheral::LcdCam => {
|
||||||
perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().set_bit());
|
perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable));
|
||||||
perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(systimer)]
|
#[cfg(systimer)]
|
||||||
Peripheral::Systimer => {
|
Peripheral::Systimer => {
|
||||||
perip_clk_en0.modify(|_, w| w.systimer_clk_en().set_bit());
|
perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable));
|
||||||
perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit());
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets the given peripheral
|
/// Resets the given peripheral
|
||||||
pub(crate) fn reset(peripheral: Peripheral) {
|
pub(crate) fn reset(peripheral: Peripheral) {
|
||||||
|
debug!("Reset {:?}", peripheral);
|
||||||
let system = unsafe { &*SYSTEM::PTR };
|
let system = unsafe { &*SYSTEM::PTR };
|
||||||
|
|
||||||
#[cfg(esp32)]
|
#[cfg(esp32)]
|
||||||
@ -560,176 +595,132 @@ impl PeripheralClockControl {
|
|||||||
|
|
||||||
#[cfg(any(esp32c6, esp32h2))]
|
#[cfg(any(esp32c6, esp32h2))]
|
||||||
impl PeripheralClockControl {
|
impl PeripheralClockControl {
|
||||||
/// Enables and resets the given peripheral
|
fn enable_internal(peripheral: Peripheral, enable: bool, _cs: &CriticalSection<'_>) {
|
||||||
pub(crate) fn enable(peripheral: Peripheral) {
|
debug!("Enable {:?} {}", peripheral, enable);
|
||||||
let system = unsafe { &*SYSTEM::PTR };
|
let system = unsafe { &*SYSTEM::PTR };
|
||||||
|
|
||||||
match peripheral {
|
match peripheral {
|
||||||
#[cfg(spi2)]
|
#[cfg(spi2)]
|
||||||
Peripheral::Spi2 => {
|
Peripheral::Spi2 => {
|
||||||
system.spi2_conf().modify(|_, w| w.spi2_clk_en().set_bit());
|
|
||||||
system
|
system
|
||||||
.spi2_conf()
|
.spi2_conf()
|
||||||
.modify(|_, w| w.spi2_rst_en().clear_bit());
|
.modify(|_, w| w.spi2_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(i2c0)]
|
#[cfg(i2c0)]
|
||||||
Peripheral::I2cExt0 => {
|
Peripheral::I2cExt0 => {
|
||||||
#[cfg(any(esp32c6, esp32h2))]
|
system
|
||||||
{
|
.i2c0_conf()
|
||||||
system.i2c0_conf().modify(|_, w| w.i2c0_clk_en().set_bit());
|
.modify(|_, w| w.i2c0_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.i2c0_conf()
|
|
||||||
.modify(|_, w| w.i2c0_rst_en().clear_bit());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[cfg(i2c1)]
|
#[cfg(i2c1)]
|
||||||
Peripheral::I2cExt1 => {
|
Peripheral::I2cExt1 => {
|
||||||
#[cfg(esp32h2)]
|
system
|
||||||
{
|
.i2c1_conf()
|
||||||
system.i2c1_conf().modify(|_, w| w.i2c1_clk_en().set_bit());
|
.modify(|_, w| w.i2c1_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.i2c1_conf()
|
|
||||||
.modify(|_, w| w.i2c1_rst_en().clear_bit());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[cfg(rmt)]
|
#[cfg(rmt)]
|
||||||
Peripheral::Rmt => {
|
Peripheral::Rmt => {
|
||||||
system.rmt_conf().modify(|_, w| w.rmt_clk_en().set_bit());
|
system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable));
|
||||||
system.rmt_conf().modify(|_, w| w.rmt_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(ledc)]
|
#[cfg(ledc)]
|
||||||
Peripheral::Ledc => {
|
Peripheral::Ledc => {
|
||||||
system.ledc_conf().modify(|_, w| w.ledc_clk_en().set_bit());
|
|
||||||
system
|
system
|
||||||
.ledc_conf()
|
.ledc_conf()
|
||||||
.modify(|_, w| w.ledc_rst_en().clear_bit());
|
.modify(|_, w| w.ledc_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(mcpwm0)]
|
#[cfg(mcpwm0)]
|
||||||
Peripheral::Mcpwm0 => {
|
Peripheral::Mcpwm0 => {
|
||||||
system.pwm_conf().modify(|_, w| w.pwm_clk_en().set_bit());
|
system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable));
|
||||||
system.pwm_conf().modify(|_, w| w.pwm_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(mcpwm1)]
|
#[cfg(mcpwm1)]
|
||||||
Peripheral::Mcpwm1 => {
|
Peripheral::Mcpwm1 => {
|
||||||
system.pwm_conf.modify(|_, w| w.pwm_clk_en().set_bit());
|
system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable));
|
||||||
system.pwm_conf.modify(|_, w| w.pwm_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(apb_saradc)]
|
#[cfg(apb_saradc)]
|
||||||
Peripheral::ApbSarAdc => {
|
Peripheral::ApbSarAdc => {
|
||||||
system
|
system
|
||||||
.saradc_conf()
|
.saradc_conf()
|
||||||
.modify(|_, w| w.saradc_reg_clk_en().set_bit());
|
.modify(|_, w| w.saradc_reg_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.saradc_conf()
|
|
||||||
.modify(|_, w| w.saradc_reg_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(gdma)]
|
#[cfg(gdma)]
|
||||||
Peripheral::Gdma => {
|
Peripheral::Gdma => {
|
||||||
system.gdma_conf().modify(|_, w| w.gdma_clk_en().set_bit());
|
|
||||||
system
|
system
|
||||||
.gdma_conf()
|
.gdma_conf()
|
||||||
.modify(|_, w| w.gdma_rst_en().clear_bit());
|
.modify(|_, w| w.gdma_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(i2s0)]
|
#[cfg(i2s0)]
|
||||||
Peripheral::I2s0 => {
|
Peripheral::I2s0 => {
|
||||||
system.i2s_conf().modify(|_, w| w.i2s_clk_en().set_bit());
|
system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable));
|
||||||
system.i2s_conf().modify(|_, w| w.i2s_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(twai0)]
|
#[cfg(twai0)]
|
||||||
Peripheral::Twai0 => {
|
Peripheral::Twai0 => {
|
||||||
system
|
system
|
||||||
.twai0_conf()
|
.twai0_conf()
|
||||||
.modify(|_, w| w.twai0_clk_en().set_bit());
|
.modify(|_, w| w.twai0_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.twai0_conf()
|
|
||||||
.modify(|_, w| w.twai0_rst_en().clear_bit());
|
|
||||||
|
|
||||||
// use Xtal clk-src
|
if enable {
|
||||||
system.twai0_func_clk_conf().modify(|_, w| {
|
// use Xtal clk-src
|
||||||
w.twai0_func_clk_en()
|
system.twai0_func_clk_conf().modify(|_, w| {
|
||||||
.set_bit()
|
w.twai0_func_clk_en()
|
||||||
.twai0_func_clk_sel()
|
.set_bit()
|
||||||
.variant(false)
|
.twai0_func_clk_sel()
|
||||||
});
|
.variant(false)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(twai1)]
|
#[cfg(twai1)]
|
||||||
Peripheral::Twai1 => {
|
Peripheral::Twai1 => {
|
||||||
system
|
system
|
||||||
.twai1_conf()
|
.twai1_conf()
|
||||||
.modify(|_, w| w.twai1_clk_en().set_bit());
|
.modify(|_, w| w.twai1_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.twai1_conf()
|
|
||||||
.modify(|_, w| w.twai1_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(aes)]
|
#[cfg(aes)]
|
||||||
Peripheral::Aes => {
|
Peripheral::Aes => {
|
||||||
system.aes_conf().modify(|_, w| w.aes_clk_en().set_bit());
|
system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable));
|
||||||
system.aes_conf().modify(|_, w| w.aes_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(pcnt)]
|
#[cfg(pcnt)]
|
||||||
Peripheral::Pcnt => {
|
Peripheral::Pcnt => {
|
||||||
system.pcnt_conf().modify(|_, w| w.pcnt_clk_en().set_bit());
|
|
||||||
system
|
system
|
||||||
.pcnt_conf()
|
.pcnt_conf()
|
||||||
.modify(|_, w| w.pcnt_rst_en().clear_bit());
|
.modify(|_, w| w.pcnt_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(timg0)]
|
#[cfg(timg0)]
|
||||||
Peripheral::Timg0 => {
|
Peripheral::Timg0 => {
|
||||||
system
|
system
|
||||||
.timergroup0_timer_clk_conf()
|
.timergroup0_timer_clk_conf()
|
||||||
.modify(|_, w| w.tg0_timer_clk_en().set_bit());
|
.modify(|_, w| w.tg0_timer_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(timg1)]
|
#[cfg(timg1)]
|
||||||
Peripheral::Timg1 => {
|
Peripheral::Timg1 => {
|
||||||
system
|
system
|
||||||
.timergroup1_timer_clk_conf()
|
.timergroup1_timer_clk_conf()
|
||||||
.modify(|_, w| w.tg1_timer_clk_en().set_bit());
|
.modify(|_, w| w.tg1_timer_clk_en().bit(enable));
|
||||||
}
|
|
||||||
#[cfg(lp_wdt)]
|
|
||||||
Peripheral::Wdt => {
|
|
||||||
system
|
|
||||||
.timergroup0_wdt_clk_conf()
|
|
||||||
.modify(|_, w| w.tg0_wdt_clk_en().set_bit());
|
|
||||||
system
|
|
||||||
.timergroup1_timer_clk_conf()
|
|
||||||
.modify(|_, w| w.tg1_timer_clk_en().set_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(sha)]
|
#[cfg(sha)]
|
||||||
Peripheral::Sha => {
|
Peripheral::Sha => {
|
||||||
system.sha_conf().modify(|_, w| w.sha_clk_en().set_bit());
|
system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable));
|
||||||
system.sha_conf().modify(|_, w| w.sha_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(usb_device)]
|
#[cfg(usb_device)]
|
||||||
Peripheral::UsbDevice => {
|
Peripheral::UsbDevice => {
|
||||||
system
|
system
|
||||||
.usb_device_conf()
|
.usb_device_conf()
|
||||||
.modify(|_, w| w.usb_device_clk_en().set_bit());
|
.modify(|_, w| w.usb_device_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.usb_device_conf()
|
|
||||||
.modify(|_, w| w.usb_device_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(uart0)]
|
#[cfg(uart0)]
|
||||||
Peripheral::Uart0 => {
|
Peripheral::Uart0 => {
|
||||||
system
|
system
|
||||||
.uart0_conf()
|
.uart0_conf()
|
||||||
.modify(|_, w| w.uart0_clk_en().set_bit());
|
.modify(|_, w| w.uart0_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.uart0_conf()
|
|
||||||
.modify(|_, w| w.uart0_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(uart1)]
|
#[cfg(uart1)]
|
||||||
Peripheral::Uart1 => {
|
Peripheral::Uart1 => {
|
||||||
system
|
system
|
||||||
.uart1_conf()
|
.uart1_conf()
|
||||||
.modify(|_, w| w.uart1_clk_en().set_bit());
|
.modify(|_, w| w.uart1_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.uart1_conf()
|
|
||||||
.modify(|_, w| w.uart1_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(rsa)]
|
#[cfg(rsa)]
|
||||||
Peripheral::Rsa => {
|
Peripheral::Rsa => {
|
||||||
system.rsa_conf().modify(|_, w| w.rsa_clk_en().set_bit());
|
system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable));
|
||||||
system.rsa_conf().modify(|_, w| w.rsa_rst_en().clear_bit());
|
|
||||||
system
|
system
|
||||||
.rsa_pd_ctrl()
|
.rsa_pd_ctrl()
|
||||||
.modify(|_, w| w.rsa_mem_pd().clear_bit());
|
.modify(|_, w| w.rsa_mem_pd().clear_bit());
|
||||||
@ -738,54 +729,41 @@ impl PeripheralClockControl {
|
|||||||
Peripheral::ParlIo => {
|
Peripheral::ParlIo => {
|
||||||
system
|
system
|
||||||
.parl_io_conf()
|
.parl_io_conf()
|
||||||
.modify(|_, w| w.parl_clk_en().set_bit());
|
.modify(|_, w| w.parl_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.parl_io_conf()
|
|
||||||
.modify(|_, w| w.parl_rst_en().set_bit());
|
|
||||||
system
|
|
||||||
.parl_io_conf()
|
|
||||||
.modify(|_, w| w.parl_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(hmac)]
|
#[cfg(hmac)]
|
||||||
Peripheral::Hmac => {
|
Peripheral::Hmac => {
|
||||||
system.hmac_conf().modify(|_, w| w.hmac_clk_en().set_bit());
|
|
||||||
system
|
system
|
||||||
.hmac_conf()
|
.hmac_conf()
|
||||||
.modify(|_, w| w.hmac_rst_en().clear_bit());
|
.modify(|_, w| w.hmac_clk_en().bit(enable));
|
||||||
}
|
}
|
||||||
#[cfg(ecc)]
|
#[cfg(ecc)]
|
||||||
Peripheral::Ecc => {
|
Peripheral::Ecc => {
|
||||||
system.ecc_conf().modify(|_, w| w.ecc_clk_en().set_bit());
|
system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable));
|
||||||
system.ecc_conf().modify(|_, w| w.ecc_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(soc_etm)]
|
#[cfg(soc_etm)]
|
||||||
Peripheral::Etm => {
|
Peripheral::Etm => {
|
||||||
system.etm_conf().modify(|_, w| w.etm_clk_en().set_bit());
|
system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable));
|
||||||
system.etm_conf().modify(|_, w| w.etm_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(trace0)]
|
#[cfg(trace0)]
|
||||||
Peripheral::Trace0 => {
|
Peripheral::Trace0 => {
|
||||||
system
|
system
|
||||||
.trace_conf()
|
.trace_conf()
|
||||||
.modify(|_, w| w.trace_clk_en().set_bit());
|
.modify(|_, w| w.trace_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.trace_conf()
|
|
||||||
.modify(|_, w| w.trace_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
#[cfg(systimer)]
|
#[cfg(systimer)]
|
||||||
Peripheral::Systimer => {
|
Peripheral::Systimer => {
|
||||||
system
|
system
|
||||||
.systimer_conf()
|
.systimer_conf()
|
||||||
.modify(|_, w| w.systimer_clk_en().set_bit());
|
.modify(|_, w| w.systimer_clk_en().bit(enable));
|
||||||
system
|
|
||||||
.systimer_conf()
|
|
||||||
.modify(|_, w| w.systimer_rst_en().clear_bit());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets the given peripheral
|
/// Resets the given peripheral
|
||||||
pub(crate) fn reset(peripheral: Peripheral) {
|
pub(crate) fn reset(peripheral: Peripheral) {
|
||||||
|
debug!("Reset {:?}", peripheral);
|
||||||
|
|
||||||
let system = unsafe { &*SYSTEM::PTR };
|
let system = unsafe { &*SYSTEM::PTR };
|
||||||
|
|
||||||
match peripheral {
|
match peripheral {
|
||||||
@ -897,10 +875,6 @@ impl PeripheralClockControl {
|
|||||||
Peripheral::Timg1 => {
|
Peripheral::Timg1 => {
|
||||||
// no reset?
|
// no reset?
|
||||||
}
|
}
|
||||||
#[cfg(lp_wdt)]
|
|
||||||
Peripheral::Wdt => {
|
|
||||||
// no reset?
|
|
||||||
}
|
|
||||||
#[cfg(sha)]
|
#[cfg(sha)]
|
||||||
Peripheral::Sha => {
|
Peripheral::Sha => {
|
||||||
system.sha_conf().modify(|_, w| w.sha_rst_en().set_bit());
|
system.sha_conf().modify(|_, w| w.sha_rst_en().set_bit());
|
||||||
@ -986,6 +960,61 @@ impl PeripheralClockControl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PeripheralClockControl {
|
||||||
|
/// Enables the given peripheral.
|
||||||
|
///
|
||||||
|
/// This keeps track of enabling a peripheral - i.e. a peripheral
|
||||||
|
/// is only enabled with the first call attempt to enable it.
|
||||||
|
///
|
||||||
|
/// Returns `true` if it actually enabled the peripheral.
|
||||||
|
pub(crate) fn enable(peripheral: Peripheral) -> bool {
|
||||||
|
Self::enable_forced(peripheral, true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disables the given peripheral.
|
||||||
|
///
|
||||||
|
/// This keeps track of disabling a peripheral - i.e. it only
|
||||||
|
/// gets disabled when the number of enable/disable attempts is balanced.
|
||||||
|
///
|
||||||
|
/// Returns `true` if it actually disabled the peripheral.
|
||||||
|
///
|
||||||
|
/// Before disabling a peripheral it will also get reset
|
||||||
|
pub(crate) fn disable(peripheral: Peripheral) -> bool {
|
||||||
|
Self::enable_forced(peripheral, false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool {
|
||||||
|
critical_section::with(|cs| {
|
||||||
|
if !force {
|
||||||
|
if enable {
|
||||||
|
let prev =
|
||||||
|
PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed);
|
||||||
|
if prev > 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let prev =
|
||||||
|
PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed);
|
||||||
|
assert!(prev != 0);
|
||||||
|
if prev > 1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if !enable {
|
||||||
|
assert!(PERIPHERAL_REF_COUNT[peripheral as usize].swap(0, Ordering::Relaxed) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !enable {
|
||||||
|
Self::reset(peripheral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::enable_internal(peripheral, enable, &cs);
|
||||||
|
|
||||||
|
true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Enumeration of the available radio peripherals for this chip.
|
/// Enumeration of the available radio peripherals for this chip.
|
||||||
#[cfg(any(bt, ieee802154, wifi))]
|
#[cfg(any(bt, ieee802154, wifi))]
|
||||||
pub enum RadioPeripherals {
|
pub enum RadioPeripherals {
|
||||||
|
|||||||
@ -152,7 +152,7 @@ impl TimerGroupInstance for TIMG0 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn enable_peripheral() {
|
fn enable_peripheral() {
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Timg0)
|
PeripheralClockControl::enable(crate::system::Peripheral::Timg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_peripheral() {
|
fn reset_peripheral() {
|
||||||
@ -215,7 +215,7 @@ impl TimerGroupInstance for crate::peripherals::TIMG1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn enable_peripheral() {
|
fn enable_peripheral() {
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Timg1)
|
PeripheralClockControl::enable(crate::system::Peripheral::Timg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_peripheral() {
|
fn reset_peripheral() {
|
||||||
@ -929,9 +929,6 @@ where
|
|||||||
{
|
{
|
||||||
/// Construct a new instance of [`Wdt`]
|
/// Construct a new instance of [`Wdt`]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
#[cfg(lp_wdt)]
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Wdt);
|
|
||||||
|
|
||||||
TG::configure_wdt_src_clk();
|
TG::configure_wdt_src_clk();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@ -22,8 +22,8 @@
|
|||||||
//! ```rust, no_run
|
//! ```rust, no_run
|
||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::trace::Trace;
|
//! # use esp_hal::trace::Trace;
|
||||||
//! let mut trace = Trace::new(peripherals.TRACE0);
|
|
||||||
//! let mut buffer = [0_u8; 1024];
|
//! let mut buffer = [0_u8; 1024];
|
||||||
|
//! let mut trace = Trace::new(peripherals.TRACE0);
|
||||||
//! trace.start_trace(&mut buffer);
|
//! trace.start_trace(&mut buffer);
|
||||||
//! // traced code
|
//! // traced code
|
||||||
//!
|
//!
|
||||||
@ -36,7 +36,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::trace::RegisterBlock,
|
peripherals::trace::RegisterBlock,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Errors returned from [Trace::stop_trace]
|
/// Errors returned from [Trace::stop_trace]
|
||||||
@ -56,9 +56,13 @@ pub struct TraceResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// TRACE Encoder Instance
|
/// TRACE Encoder Instance
|
||||||
pub struct Trace<'d, T> {
|
pub struct Trace<'d, T>
|
||||||
|
where
|
||||||
|
T: Instance,
|
||||||
|
{
|
||||||
peripheral: PeripheralRef<'d, T>,
|
peripheral: PeripheralRef<'d, T>,
|
||||||
buffer: Option<&'d mut [u8]>,
|
buffer: Option<&'d mut [u8]>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T> Trace<'d, T>
|
impl<'d, T> Trace<'d, T>
|
||||||
@ -68,13 +72,12 @@ where
|
|||||||
/// Construct a new instance
|
/// Construct a new instance
|
||||||
pub fn new(peripheral: impl Peripheral<P = T> + 'd) -> Self {
|
pub fn new(peripheral: impl Peripheral<P = T> + 'd) -> Self {
|
||||||
crate::into_ref!(peripheral);
|
crate::into_ref!(peripheral);
|
||||||
|
let guard = PeripheralGuard::new(peripheral.peripheral());
|
||||||
PeripheralClockControl::reset(crate::system::Peripheral::Trace0);
|
|
||||||
PeripheralClockControl::enable(crate::system::Peripheral::Trace0);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
peripheral,
|
peripheral,
|
||||||
buffer: None,
|
buffer: None,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,10 +210,17 @@ where
|
|||||||
pub trait Instance: crate::private::Sealed {
|
pub trait Instance: crate::private::Sealed {
|
||||||
/// Get a reference to the peripheral's underlying register block
|
/// Get a reference to the peripheral's underlying register block
|
||||||
fn register_block(&self) -> &RegisterBlock;
|
fn register_block(&self) -> &RegisterBlock;
|
||||||
|
|
||||||
|
/// Peripheral
|
||||||
|
fn peripheral(&self) -> crate::system::Peripheral;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance for crate::peripherals::TRACE0 {
|
impl Instance for crate::peripherals::TRACE0 {
|
||||||
fn register_block(&self) -> &RegisterBlock {
|
fn register_block(&self) -> &RegisterBlock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peripheral(&self) -> crate::system::Peripheral {
|
||||||
|
crate::system::Peripheral::Trace0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,7 +134,7 @@ use crate::{
|
|||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::twai0::RegisterBlock,
|
peripherals::twai0::RegisterBlock,
|
||||||
system::PeripheralClockControl,
|
system::PeripheralGuard,
|
||||||
twai::filter::SingleStandardFilter,
|
twai::filter::SingleStandardFilter,
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
@ -751,6 +751,7 @@ pub struct TwaiConfiguration<'d, DM: crate::Mode, T = AnyTwai> {
|
|||||||
filter: Option<(FilterType, [u8; 8])>,
|
filter: Option<(FilterType, [u8; 8])>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
mode: TwaiMode,
|
mode: TwaiMode,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, DM, T> TwaiConfiguration<'d, DM, T>
|
impl<'d, DM, T> TwaiConfiguration<'d, DM, T>
|
||||||
@ -769,15 +770,14 @@ where
|
|||||||
crate::into_ref!(twai);
|
crate::into_ref!(twai);
|
||||||
crate::into_mapped_ref!(tx_pin, rx_pin);
|
crate::into_mapped_ref!(tx_pin, rx_pin);
|
||||||
|
|
||||||
// Enable the peripheral clock for the TWAI peripheral.
|
let guard = PeripheralGuard::new(twai.peripheral());
|
||||||
PeripheralClockControl::enable(twai.peripheral());
|
|
||||||
PeripheralClockControl::reset(twai.peripheral());
|
|
||||||
|
|
||||||
let mut this = TwaiConfiguration {
|
let mut this = TwaiConfiguration {
|
||||||
twai,
|
twai,
|
||||||
filter: None, // We'll immediately call `set_filter`
|
filter: None, // We'll immediately call `set_filter`
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
mode,
|
mode,
|
||||||
|
_guard: guard,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Accept all messages by default.
|
// Accept all messages by default.
|
||||||
@ -1035,10 +1035,12 @@ where
|
|||||||
rx: TwaiRx {
|
rx: TwaiRx {
|
||||||
twai: unsafe { self.twai.clone_unchecked() },
|
twai: unsafe { self.twai.clone_unchecked() },
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: PeripheralGuard::new(self.twai.peripheral()),
|
||||||
},
|
},
|
||||||
tx: TwaiTx {
|
tx: TwaiTx {
|
||||||
twai: unsafe { self.twai.clone_unchecked() },
|
twai: unsafe { self.twai.clone_unchecked() },
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
_guard: PeripheralGuard::new(self.twai.peripheral()),
|
||||||
},
|
},
|
||||||
twai: unsafe { self.twai.clone_unchecked() },
|
twai: unsafe { self.twai.clone_unchecked() },
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -1116,6 +1118,7 @@ where
|
|||||||
filter: self.filter,
|
filter: self.filter,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
mode: self.mode,
|
mode: self.mode,
|
||||||
|
_guard: self._guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1136,6 +1139,7 @@ where
|
|||||||
filter: self.filter,
|
filter: self.filter,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
mode: self.mode,
|
mode: self.mode,
|
||||||
|
_guard: self._guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1191,11 +1195,13 @@ where
|
|||||||
|
|
||||||
let mode = self.mode();
|
let mode = self.mode();
|
||||||
|
|
||||||
|
let guard = PeripheralGuard::new(self.twai.peripheral());
|
||||||
TwaiConfiguration {
|
TwaiConfiguration {
|
||||||
twai: self.twai,
|
twai: self.twai,
|
||||||
filter: None, // filter already applied, no need to restore it
|
filter: None, // filter already applied, no need to restore it
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
mode,
|
mode,
|
||||||
|
_guard: guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1277,6 +1283,7 @@ where
|
|||||||
pub struct TwaiTx<'d, DM: crate::Mode, T = AnyTwai> {
|
pub struct TwaiTx<'d, DM: crate::Mode, T = AnyTwai> {
|
||||||
twai: PeripheralRef<'d, T>,
|
twai: PeripheralRef<'d, T>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DM, T> TwaiTx<'_, DM, T>
|
impl<DM, T> TwaiTx<'_, DM, T>
|
||||||
@ -1319,6 +1326,7 @@ where
|
|||||||
pub struct TwaiRx<'d, DM: crate::Mode, T = AnyTwai> {
|
pub struct TwaiRx<'d, DM: crate::Mode, T = AnyTwai> {
|
||||||
twai: PeripheralRef<'d, T>,
|
twai: PeripheralRef<'d, T>,
|
||||||
phantom: PhantomData<DM>,
|
phantom: PhantomData<DM>,
|
||||||
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DM, T> TwaiRx<'_, DM, T>
|
impl<DM, T> TwaiRx<'_, DM, T>
|
||||||
|
|||||||
@ -132,7 +132,7 @@ use crate::{
|
|||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
peripherals::{uart0::RegisterBlock, Interrupt},
|
peripherals::{uart0::RegisterBlock, Interrupt},
|
||||||
private::Internal,
|
private::Internal,
|
||||||
system::PeripheralClockControl,
|
system::{PeripheralClockControl, PeripheralGuard},
|
||||||
Async,
|
Async,
|
||||||
Blocking,
|
Blocking,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
@ -462,14 +462,19 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init(self, config: Config) -> Result<Uart<'d, M, T>, Error> {
|
fn init(self, config: Config) -> Result<Uart<'d, M, T>, Error> {
|
||||||
|
let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
|
||||||
|
let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral);
|
||||||
|
|
||||||
let mut serial = Uart {
|
let mut serial = Uart {
|
||||||
rx: UartRx {
|
rx: UartRx {
|
||||||
uart: unsafe { self.uart.clone_unchecked() },
|
uart: unsafe { self.uart.clone_unchecked() },
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: rx_guard,
|
||||||
},
|
},
|
||||||
tx: UartTx {
|
tx: UartTx {
|
||||||
uart: self.uart,
|
uart: self.uart,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: tx_guard,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
serial.init(config)?;
|
serial.init(config)?;
|
||||||
@ -488,12 +493,14 @@ pub struct Uart<'d, M, T = AnyUart> {
|
|||||||
pub struct UartTx<'d, M, T = AnyUart> {
|
pub struct UartTx<'d, M, T = AnyUart> {
|
||||||
uart: PeripheralRef<'d, T>,
|
uart: PeripheralRef<'d, T>,
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// UART (Receive)
|
/// UART (Receive)
|
||||||
pub struct UartRx<'d, M, T = AnyUart> {
|
pub struct UartRx<'d, M, T = AnyUart> {
|
||||||
uart: PeripheralRef<'d, T>,
|
uart: PeripheralRef<'d, T>,
|
||||||
phantom: PhantomData<M>,
|
phantom: PhantomData<M>,
|
||||||
|
guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M, T> SetConfig for Uart<'_, M, T>
|
impl<M, T> SetConfig for Uart<'_, M, T>
|
||||||
@ -698,6 +705,7 @@ where
|
|||||||
UartTx {
|
UartTx {
|
||||||
uart: self.uart,
|
uart: self.uart,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -719,6 +727,7 @@ where
|
|||||||
UartTx {
|
UartTx {
|
||||||
uart: self.uart,
|
uart: self.uart,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -951,6 +960,7 @@ where
|
|||||||
UartRx {
|
UartRx {
|
||||||
uart: self.uart,
|
uart: self.uart,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -972,6 +982,7 @@ where
|
|||||||
UartRx {
|
UartRx {
|
||||||
uart: self.uart,
|
uart: self.uart,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
|
guard: self.guard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1197,8 +1208,8 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PeripheralClockControl::enable(self.tx.uart.info().peripheral);
|
|
||||||
self.uart_peripheral_reset();
|
self.uart_peripheral_reset();
|
||||||
|
|
||||||
self.rx.disable_rx_interrupts();
|
self.rx.disable_rx_interrupts();
|
||||||
self.tx.disable_tx_interrupts();
|
self.tx.disable_tx_interrupts();
|
||||||
|
|
||||||
@ -1242,7 +1253,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
|
fn rst_core(_reg_block: &RegisterBlock, _enable: bool) {
|
||||||
#[cfg(not(any(esp32, esp32s2)))]
|
#[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))]
|
||||||
_reg_block
|
_reg_block
|
||||||
.clk_conf()
|
.clk_conf()
|
||||||
.modify(|_, w| w.rst_core().bit(_enable));
|
.modify(|_, w| w.rst_core().bit(_enable));
|
||||||
|
|||||||
@ -46,8 +46,8 @@ fn main() -> ! {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_mosi(miso_mosi)
|
.with_miso(miso) // order matters
|
||||||
.with_miso(miso)
|
.with_mosi(miso_mosi) // order matters
|
||||||
.with_cs(cs);
|
.with_cs(cs);
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|||||||
@ -112,7 +112,8 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
transfer.wait();
|
// dropping SPI would make us see an additional edge - so let's keep SPI alive
|
||||||
|
let (_spi, _) = transfer.wait();
|
||||||
|
|
||||||
assert_eq!(unit.value(), (6 * DMA_BUFFER_SIZE) as _);
|
assert_eq!(unit.value(), (6 * DMA_BUFFER_SIZE) as _);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user