esp-hal/esp-hal-common/src/system.rs
2022-06-09 13:51:17 +01:00

105 lines
3.3 KiB
Rust

//! System
//!
//! The SYSTEM/DPORT peripheral needs to be split into several logical parts.
//!
//! Example
//! ```no_run
//! let peripherals = Peripherals::take().unwrap();
//! let system = peripherals.SYSTEM.split();
//! let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
//! ```
#[cfg(not(feature = "esp32"))]
type SystemPeripheral = crate::pac::SYSTEM;
#[cfg(feature = "esp32")]
type SystemPeripheral = crate::pac::DPORT;
/// Peripherals which can be enabled via [PeripheralClockControl]
pub enum Peripheral {
Spi2,
Spi3,
I2cExt0,
#[cfg(not(feature = "esp32c3"))]
I2cExt1,
Rmt,
}
/// Controls the enablement of peripheral clocks.
pub struct PeripheralClockControl {
_private: (),
}
impl PeripheralClockControl {
/// Enables and resets the given peripheral
pub fn enable(&mut self, peripheral: Peripheral) {
let system = unsafe { &*SystemPeripheral::PTR };
#[cfg(not(feature = "esp32"))]
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en0, &system.perip_rst_en0) };
#[cfg(feature = "esp32")]
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en, &system.perip_rst_en) };
match peripheral {
Peripheral::Spi2 => {
perip_clk_en0.modify(|_, w| w.spi2_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit());
}
Peripheral::Spi3 => {
perip_clk_en0.modify(|_, w| w.spi3_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit());
}
#[cfg(feature = "esp32")]
Peripheral::I2cExt0 => {
perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit());
}
#[cfg(not(feature = "esp32"))]
Peripheral::I2cExt0 => {
perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit());
}
#[cfg(not(feature = "esp32c3"))]
Peripheral::I2cExt1 => {
perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit());
}
Peripheral::Rmt => {
perip_clk_en0.modify(|_, w| w.rmt_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit());
}
}
}
}
/// Controls the configuration of the chip's clocks.
pub struct SystemClockControl {
_private: (),
}
/// The SYSTEM/DPORT splitted into it's different logical parts.
pub struct SystemParts {
_private: (),
pub peripheral_clock_control: PeripheralClockControl,
pub clock_control: SystemClockControl,
}
/// Extension trait to split a SYSTEM/DPORT peripheral in independent logical
/// parts
pub trait SystemExt {
type Parts;
/// Splits the SYSTEM/DPORT peripheral into it's parts.
fn split(self) -> Self::Parts;
}
impl SystemExt for SystemPeripheral {
type Parts = SystemParts;
fn split(self) -> Self::Parts {
Self::Parts {
_private: (),
peripheral_clock_control: PeripheralClockControl { _private: () },
clock_control: SystemClockControl { _private: () },
}
}
}