diff --git a/esp-hal-common/.vscode/settings.json b/esp-hal-common/.vscode/settings.json new file mode 100644 index 000000000..3454a521f --- /dev/null +++ b/esp-hal-common/.vscode/settings.json @@ -0,0 +1,23 @@ +{ + "rust-analyzer.cargo.features": [ + "esp32c3" + ], + "rust-analyzer.cargo.allFeatures": false, + "editor.formatOnSave": true, + "rust-analyzer.checkOnSave.allTargets": false, + "rust-analyzer.checkOnSave.allFeatures": false, + "rust-analyzer.checkOnSave.overrideCommand": [ + "cargo", + "check", + "--features", + "esp32c3", + "--message-format=json", + "-Z", + "build-std=core", + "--target", + "riscv32imac-unknown-none-elf", + "--examples", + "--lib", + ], + "rust-analyzer.cargo.buildScripts.enable": false +} \ No newline at end of file diff --git a/esp-hal-common/src/clock.rs b/esp-hal-common/src/clock.rs new file mode 100644 index 000000000..5005832f4 --- /dev/null +++ b/esp-hal-common/src/clock.rs @@ -0,0 +1,117 @@ +//! # Clock Control +use fugit::MegahertzU32; + +use crate::system::SystemClockControl; + +/// Frozen clock frequencies +/// +/// The existence of this value indicates that the clock configuration can no +/// longer be changed +pub struct Clocks { + _private: (), + pub cpu_clock: MegahertzU32, + pub apb_clock: MegahertzU32, + pub xtal_clock: MegahertzU32, + pub i2c_clock: MegahertzU32, + // TODO chip specific additional ones as needed +} + +#[doc(hidden)] +impl Clocks { + /// This should not be used in user code. + /// The whole point this exists is make it possible to have other crates + /// (i.e. esp-wifi) create `Clocks` + #[doc(hidden)] + pub fn from_raw_clocks(raw_clocks: RawClocks) -> Clocks { + Self { + _private: (), + cpu_clock: raw_clocks.cpu_clock, + apb_clock: raw_clocks.apb_clock, + xtal_clock: raw_clocks.xtal_clock, + i2c_clock: raw_clocks.i2c_clock, + } + } +} + +#[doc(hidden)] +pub struct RawClocks { + pub cpu_clock: MegahertzU32, + pub apb_clock: MegahertzU32, + pub xtal_clock: MegahertzU32, + pub i2c_clock: MegahertzU32, + // TODO chip specific additional ones as needed +} +/// Used to configure the frequencies of the clocks present in the chip. +/// +/// After setting all frequencies, call the freeze function to apply the +/// configuration. +pub struct ClockControl { + _private: (), + desired_rates: RawClocks, +} + +impl ClockControl { + /// Use what is considered the default settings after boot. + #[cfg(feature = "esp32c3")] + #[allow(unused)] + pub fn boot_defaults(clock_control: SystemClockControl) -> ClockControl { + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: MegahertzU32::MHz(80), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(40), + }, + } + } + + #[cfg(feature = "esp32")] + #[allow(unused)] + pub fn boot_defaults(clock_control: SystemClockControl) -> ClockControl { + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: MegahertzU32::MHz(80), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(80), + }, + } + } + + #[cfg(feature = "esp32s2")] + #[allow(unused)] + pub fn boot_defaults(clock_control: SystemClockControl) -> ClockControl { + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: MegahertzU32::MHz(80), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(80), + }, + } + } + + #[cfg(feature = "esp32s3")] + #[allow(unused)] + pub fn boot_defaults(clock_control: SystemClockControl) -> ClockControl { + ClockControl { + _private: (), + desired_rates: RawClocks { + cpu_clock: MegahertzU32::MHz(80), + apb_clock: MegahertzU32::MHz(80), + xtal_clock: MegahertzU32::MHz(40), + i2c_clock: MegahertzU32::MHz(40), + }, + } + } + + /// Applies the clock configuration and returns a Clocks struct that + /// signifies that the clocks are frozen, and contains the frequencies + /// used. After this function is called, the clocks can not change + pub fn freeze(self) -> Clocks { + Clocks::from_raw_clocks(self.desired_rates) + } +} diff --git a/esp-hal-common/src/delay.rs b/esp-hal-common/src/delay.rs index 36bd9624c..4de38e7a4 100644 --- a/esp-hal-common/src/delay.rs +++ b/esp-hal-common/src/delay.rs @@ -32,25 +32,27 @@ where mod delay { use fugit::HertzU64; - use crate::pac::SYSTIMER; + use crate::{clock::Clocks, pac::SYSTIMER}; - // The counters and comparators are driven using `XTAL_CLK`. The average clock - // frequency is fXTAL_CLK/2.5, which is 16 MHz. The timer counting is - // incremented by 1/16 μs on each `CNT_CLK` cycle. - const CLK_FREQ_HZ: HertzU64 = HertzU64::MHz(16); - /// Delay driver - /// /// Uses the `SYSTIMER` peripheral for counting clock cycles, as /// unfortunately the ESP32-C3 does NOT implement the `mcycle` CSR, which is /// how we would normally do this. pub struct Delay { systimer: SYSTIMER, + freq: HertzU64, } impl Delay { /// Create a new Delay instance - pub fn new(systimer: SYSTIMER) -> Self { - Self { systimer } + pub fn new(systimer: SYSTIMER, clocks: &Clocks) -> Self { + // The counters and comparators are driven using `XTAL_CLK`. The average clock + // frequency is fXTAL_CLK/2.5, which is 16 MHz. The timer counting is + // incremented by 1/16 μs on each `CNT_CLK` cycle. + + Self { + systimer, + freq: HertzU64::MHz((clocks.xtal_clock.to_MHz() * 10 / 25) as u64), + } } /// Return the raw interface to the underlying SYSTIMER instance @@ -61,7 +63,7 @@ mod delay { /// Delay for the specified number of microseconds pub fn delay(&self, us: u32) { let t0 = self.unit0_value(); - let clocks = (us as u64 * CLK_FREQ_HZ.raw()) / HertzU64::MHz(1).raw(); + let clocks = (us as u64 * self.freq.raw()) / HertzU64::MHz(1).raw(); while self.unit0_value().wrapping_sub(t0) <= clocks {} } @@ -93,23 +95,26 @@ mod delay { use fugit::HertzU64; - const CLK_FREQ_HZ: HertzU64 = HertzU64::MHz(80); + use crate::clock::Clocks; /// Delay driver /// /// Uses the built-in Xtensa timer from the `xtensa_lx` crate. - #[derive(Default)] - pub struct Delay; + pub struct Delay { + freq: HertzU64, + } impl Delay { /// Instantiate the `Delay` driver - pub fn new() -> Self { - Self + pub fn new(clocks: &Clocks) -> Self { + Self { + freq: HertzU64::MHz(clocks.cpu_clock.to_MHz() as u64), + } } /// Delay for the specified number of microseconds pub fn delay(&self, us: u32) { - let clocks = (us as u64 * CLK_FREQ_HZ.raw()) / HertzU64::MHz(1).raw(); + let clocks = (us as u64 * self.freq.raw()) / HertzU64::MHz(1).raw(); xtensa_lx::timer::delay(clocks as u32); } } diff --git a/esp-hal-common/src/i2c.rs b/esp-hal-common/src/i2c.rs index d451062b9..d04aaf222 100644 --- a/esp-hal-common/src/i2c.rs +++ b/esp-hal-common/src/i2c.rs @@ -7,23 +7,13 @@ use embedded_hal::blocking::i2c::*; use fugit::HertzU32; use crate::{ + clock::Clocks, gpio::{InputPin, OutputPin}, pac::i2c0::{RegisterBlock, COMD}, + system::PeripheralClockControl, types::{InputSignal, OutputSignal}, }; -cfg_if::cfg_if! { - if #[cfg(feature = "esp32c3")] { - const SOURCE_CLK_FREQ: HertzU32 = HertzU32::MHz(40); - } else if #[cfg(feature = "esp32")] { - const SOURCE_CLK_FREQ: HertzU32 = HertzU32::MHz(80); - } else if #[cfg(feature = "esp32s2")] { - const SOURCE_CLK_FREQ: HertzU32 = HertzU32::MHz(80); - } else { - const SOURCE_CLK_FREQ: HertzU32 = HertzU32::MHz(40); - } -} - cfg_if::cfg_if! { if #[cfg(feature = "esp32s2")] { const I2C_LL_INTR_MASK: u32 = 0x1ffff; @@ -200,11 +190,6 @@ where } } -#[cfg(feature = "esp32")] -type System = crate::pac::DPORT; -#[cfg(not(feature = "esp32"))] -type System = crate::pac::SYSTEM; - impl I2C where T: Instance, @@ -220,9 +205,10 @@ where mut sda: SDA, mut scl: SCL, frequency: HertzU32, - system: &mut System, + peripheral_clock_control: &mut PeripheralClockControl, + clocks: &Clocks, ) -> Result { - enable_peripheral(&i2c, system); + enable_peripheral(&i2c, peripheral_clock_control); let mut i2c = I2C { peripheral: i2c }; @@ -238,7 +224,7 @@ where .connect_peripheral_to_output(OutputSignal::I2CEXT0_SCL) .connect_input_to_peripheral(InputSignal::I2CEXT0_SCL); - i2c.peripheral.setup(frequency)?; + i2c.peripheral.setup(frequency, clocks)?; Ok(i2c) } @@ -249,59 +235,12 @@ where } } -fn enable_peripheral(i2c: &T, system: &mut System) { +fn enable_peripheral(i2c: &T, peripheral_clock_control: &mut PeripheralClockControl) { // enable peripheral - #[cfg(feature = "esp32")] match i2c.i2c_number() { - 0 => { - system - .perip_clk_en - .modify(|_, w| w.i2c0_ext0_clk_en().set_bit()); - system - .perip_rst_en - .modify(|_, w| w.i2c0_ext0_rst().clear_bit()); - } - 1 => { - system - .perip_clk_en - .modify(|_, w| w.i2c_ext1_clk_en().set_bit()); - system - .perip_rst_en - .modify(|_, w| w.i2c_ext1_rst().clear_bit()); - } - _ => panic!(), // will never happen - } - #[cfg(not(feature = "esp32"))] - match i2c.i2c_number() { - 0 => { - system - .perip_clk_en0 - .modify(|_, w| w.i2c_ext0_clk_en().set_bit()); - - // Take the I2C peripheral out of any pre-existing reset state - // (shouldn't be the case after a fresh startup, but better be safe) - system - .perip_rst_en0 - .modify(|_, w| w.i2c_ext0_rst().clear_bit()); - } - 1 => { - cfg_if::cfg_if! { - if #[cfg(not(feature = "esp32c3"))] { - system - .perip_clk_en0 - .modify(|_, w| w.i2c_ext1_clk_en().set_bit()); - - // Take the I2C peripheral out of any pre-existing reset state - // (shouldn't be the case after a fresh startup, but better be safe) - system - .perip_rst_en0 - .modify(|_, w| w.i2c_ext1_rst().clear_bit()); - } else { - () - } - - } - } + 0 => peripheral_clock_control.enable(crate::system::Peripheral::I2cExt0), + #[cfg(not(feature = "esp32c3"))] + 1 => peripheral_clock_control.enable(crate::system::Peripheral::I2cExt1), _ => unreachable!(), // will never happen } } @@ -312,7 +251,7 @@ pub trait Instance { fn i2c_number(&self) -> usize; - fn setup(&mut self, frequency: HertzU32) -> Result<(), SetupError> { + fn setup(&mut self, frequency: HertzU32, clocks: &Clocks) -> Result<(), SetupError> { // Reset entire peripheral (also resets fifo) self.reset(); @@ -346,7 +285,7 @@ pub trait Instance { self.set_filter(Some(7), Some(7)); // Configure frequency - self.set_frequency(SOURCE_CLK_FREQ, frequency)?; + self.set_frequency(clocks.i2c_clock.convert(), frequency)?; // Propagate configuration changes (only necessary with C3 and S3) #[cfg(any(feature = "esp32c3", feature = "esp32s3"))] diff --git a/esp-hal-common/src/lib.rs b/esp-hal-common/src/lib.rs index 3084be0c7..78315bbe3 100644 --- a/esp-hal-common/src/lib.rs +++ b/esp-hal-common/src/lib.rs @@ -59,6 +59,9 @@ pub use timer::Timer; #[cfg(any(feature = "esp32c3", feature = "esp32s3"))] pub use usb_serial_jtag::UsbSerialJtag; +pub mod clock; +pub mod system; + /// Enumeration of CPU cores /// The actual number of available cores depends on the target. pub enum Cpu { diff --git a/esp-hal-common/src/prelude.rs b/esp-hal-common/src/prelude.rs index f48c252d8..0abd9c16e 100644 --- a/esp-hal-common/src/prelude.rs +++ b/esp-hal-common/src/prelude.rs @@ -14,3 +14,5 @@ pub use embedded_hal::{ prelude::*, }; pub use fugit::{ExtU32 as _, ExtU64 as _, RateExtU32 as _, RateExtU64 as _}; + +pub use crate::system::SystemExt; diff --git a/esp-hal-common/src/pulse_control.rs b/esp-hal-common/src/pulse_control.rs index f7b9db6c7..cb59dc85f 100644 --- a/esp-hal-common/src/pulse_control.rs +++ b/esp-hal-common/src/pulse_control.rs @@ -85,6 +85,7 @@ use fugit::NanosDurationU32; use crate::{ gpio::{types::OutputSignal, OutputPin}, pac::RMT, + system::PeripheralClockControl, }; /// Errors that can occur when the peripheral is configured @@ -210,11 +211,6 @@ impl From for u32 { } } -#[cfg(feature = "esp32")] -type System = crate::pac::DPORT; -#[cfg(not(feature = "esp32"))] -type System = crate::pac::SYSTEM; - /// Functionality that every OutputChannel must support pub trait OutputChannel { /// Set the logical level that the connected pin is pulled to @@ -819,7 +815,7 @@ macro_rules! rmt { #[cfg(any(feature = "esp32c3", feature = "esp32s3"))] pub fn new( instance: RMT, - system: &mut System, + peripheral_clock_control: &mut PeripheralClockControl, clk_source: ClockSource, div_abs: u8, div_frac_a: u8, @@ -833,7 +829,7 @@ macro_rules! rmt { )+ }; - pc.enable_peripheral(system); + pc.enable_peripheral(peripheral_clock_control); pc.config_global(clk_source, div_abs, div_frac_a, div_frac_b)?; Ok(pc) @@ -843,7 +839,7 @@ macro_rules! rmt { #[cfg(any(feature = "esp32", feature = "esp32s2"))] pub fn new( instance: RMT, - system: &mut System, + peripheral_clock_control: &mut PeripheralClockControl, ) -> Result { let pc = PulseControl { @@ -853,7 +849,7 @@ macro_rules! rmt { )+ }; - pc.enable_peripheral(system); + pc.enable_peripheral(peripheral_clock_control); pc.config_global()?; Ok(pc) @@ -865,24 +861,8 @@ macro_rules! rmt { } // Enable the RMT peripherals clock in the system peripheral - fn enable_peripheral(&self, system: &mut System) { - cfg_if::cfg_if! { - if #[cfg(feature = "esp32")] { - system - .perip_clk_en - .modify(|_, w| w.rmt_clk_en().set_bit()); - system - .perip_rst_en - .modify(|_, w| w.rmt_rst().clear_bit()); - } else { - system - .perip_clk_en0 - .modify(|_, w| w.rmt_clk_en().set_bit()); - system - .perip_rst_en0 - .modify(|_, w| w.rmt_rst().clear_bit()); - } - } + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Rmt); } /// Assign the global (peripheral-wide) configuration. This diff --git a/esp-hal-common/src/spi.rs b/esp-hal-common/src/spi.rs index 3f5aa7974..046c0d260 100644 --- a/esp-hal-common/src/spi.rs +++ b/esp-hal-common/src/spi.rs @@ -24,20 +24,17 @@ use core::convert::Infallible; use embedded_hal::spi::{FullDuplex, Mode}; -use fugit::{HertzU32, RateExtU32}; +use fugit::HertzU32; use crate::{ + clock::Clocks, pac::spi2::RegisterBlock, + system::PeripheralClockControl, types::{InputSignal, OutputSignal}, InputPin, OutputPin, }; -#[cfg(feature = "esp32")] -type System = crate::pac::DPORT; -#[cfg(not(feature = "esp32"))] -type System = crate::pac::SYSTEM; - pub struct Spi { spi: T, } @@ -60,7 +57,8 @@ where mut cs: CS, frequency: HertzU32, mode: Mode, - system: &mut System, + peripheral_clock_control: &mut PeripheralClockControl, + clocks: &Clocks, ) -> Self { sck.set_to_push_pull_output() .connect_peripheral_to_output(spi.sclk_signal()); @@ -74,10 +72,10 @@ where cs.set_to_push_pull_output() .connect_peripheral_to_output(spi.cs_signal()); - spi.enable_peripheral(system); + spi.enable_peripheral(peripheral_clock_control); let mut spi = Self { spi }; - spi.spi.setup(frequency); + spi.spi.setup(frequency, clocks); spi.spi.init(); spi.spi.set_data_mode(mode); @@ -141,7 +139,7 @@ pub trait Instance { fn cs_signal(&self) -> OutputSignal; - fn enable_peripheral(&self, system: &mut System); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl); fn init(&mut self) { let reg_block = self.register_block(); @@ -185,9 +183,9 @@ pub trait Instance { } // taken from https://github.com/apache/incubator-nuttx/blob/8267a7618629838231256edfa666e44b5313348e/arch/risc-v/src/esp32c3/esp32c3_spi.c#L496 - fn setup(&mut self, frequency: HertzU32) { + fn setup(&mut self, frequency: HertzU32, clocks: &Clocks) { // FIXME: this might not be always true - let apb_clk_freq: HertzU32 = 80u32.MHz(); + let apb_clk_freq: HertzU32 = HertzU32::Hz(clocks.apb_clock.to_Hz()); let reg_val: u32; let duty_cycle = 128; @@ -450,15 +448,8 @@ impl Instance for crate::pac::SPI2 { } #[inline(always)] - fn enable_peripheral(&self, system: &mut System) { - // enable peripheral - system - .perip_clk_en0 - .modify(|_, w| w.spi2_clk_en().set_bit()); - - // Take the peripheral out of any pre-existing reset state - // (shouldn't be the case after a fresh startup, but better be safe) - system.perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit()); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Spi2); } } @@ -490,9 +481,8 @@ impl Instance for crate::pac::SPI2 { } #[inline(always)] - fn enable_peripheral(&self, system: &mut System) { - system.perip_clk_en.modify(|_, w| w.spi2_clk_en().set_bit()); - system.perip_rst_en.modify(|_, w| w.spi2_rst().clear_bit()); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Spi2); } } @@ -524,9 +514,8 @@ impl Instance for crate::pac::SPI3 { } #[inline(always)] - fn enable_peripheral(&self, system: &mut System) { - system.perip_clk_en.modify(|_, w| w.spi3_clk_en().set_bit()); - system.perip_rst_en.modify(|_, w| w.spi3_rst().clear_bit()); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Spi3) } } @@ -558,11 +547,8 @@ impl Instance for crate::pac::SPI2 { } #[inline(always)] - fn enable_peripheral(&self, system: &mut System) { - system - .perip_clk_en0 - .modify(|_, w| w.spi2_clk_en().set_bit()); - system.perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit()); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Spi2) } } @@ -594,10 +580,7 @@ impl Instance for crate::pac::SPI3 { } #[inline(always)] - fn enable_peripheral(&self, system: &mut System) { - system - .perip_clk_en0 - .modify(|_, w| w.spi3_clk_en().set_bit()); - system.perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit()); + fn enable_peripheral(&self, peripheral_clock_control: &mut PeripheralClockControl) { + peripheral_clock_control.enable(crate::system::Peripheral::Spi3) } } diff --git a/esp-hal-common/src/system.rs b/esp-hal-common/src/system.rs new file mode 100644 index 000000000..96f6bc263 --- /dev/null +++ b/esp-hal-common/src/system.rs @@ -0,0 +1,104 @@ +//! 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: () }, + } + } +} diff --git a/esp32-hal/.vscode/settings.json b/esp32-hal/.vscode/settings.json index 7b7f1b89f..e0839ba9d 100644 --- a/esp32-hal/.vscode/settings.json +++ b/esp32-hal/.vscode/settings.json @@ -4,7 +4,6 @@ "editor.formatOnSave": true, "rust-analyzer.checkOnSave.allTargets": false, "rust-analyzer.checkOnSave.allFeatures": false, - "rust-analyzer.cargo.runBuildScripts": false, "rust-analyzer.checkOnSave.overrideCommand": [ "cargo", "check", @@ -12,5 +11,6 @@ "-Z", "build-std=core", "--examples" - ] + ], + "rust-analyzer.cargo.buildScripts.enable": false } \ No newline at end of file diff --git a/esp32-hal/examples/blinky.rs b/esp32-hal/examples/blinky.rs index 6bfcb2d0d..e13b70b4f 100644 --- a/esp32-hal/examples/blinky.rs +++ b/esp32-hal/examples/blinky.rs @@ -1,13 +1,23 @@ #![no_std] #![no_main] -use esp32_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Timer}; +use esp32_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); @@ -24,7 +34,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { led.toggle().unwrap(); diff --git a/esp32-hal/examples/gpio_interrupt.rs b/esp32-hal/examples/gpio_interrupt.rs index 908c7afa8..d16728c18 100644 --- a/esp32-hal/examples/gpio_interrupt.rs +++ b/esp32-hal/examples/gpio_interrupt.rs @@ -4,6 +4,7 @@ use core::{cell::RefCell, fmt::Write}; use esp32_hal::{ + clock::ClockControl, gpio::{Gpio0, IO}, pac::{self, Peripherals, UART0}, prelude::*, @@ -31,6 +32,8 @@ static mut BUTTON: SpinLockMutex>>>> = #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the TIMG watchdog timer. let mut timer0 = Timer::new(peripherals.TIMG0); @@ -62,7 +65,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); unsafe { xtensa_lx::interrupt::enable_mask(1 << 1); diff --git a/esp32-hal/examples/hello_rgb.rs b/esp32-hal/examples/hello_rgb.rs index 87de849c0..f3092862a 100644 --- a/esp32-hal/examples/hello_rgb.rs +++ b/esp32-hal/examples/hello_rgb.rs @@ -14,6 +14,7 @@ #![no_main] use esp32_hal::{ + clock::ClockControl, pac, prelude::*, utils::{smartLedAdapter, SmartLedsAdapter}, @@ -35,7 +36,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = pac::Peripherals::take().unwrap(); + let peripherals = pac::Peripherals::take().unwrap(); + let mut system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); @@ -46,7 +49,7 @@ fn main() -> ! { rtc_cntl.set_wdt_global_enable(false); // Configure RMT peripheral globally - let pulse = PulseControl::new(peripherals.RMT, &mut peripherals.DPORT).unwrap(); + let pulse = PulseControl::new(peripherals.RMT, &mut system.peripheral_clock_control).unwrap(); // We use one of the RMT channels to instantiate a `SmartLedsAdapter` which can // be used directly with all `smart_led` implementations @@ -57,7 +60,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); let mut color = Hsv { hue: 0, diff --git a/esp32-hal/examples/i2c_display.rs b/esp32-hal/examples/i2c_display.rs index cc36dbc2d..d6144f3c3 100644 --- a/esp32-hal/examples/i2c_display.rs +++ b/esp32-hal/examples/i2c_display.rs @@ -21,7 +21,16 @@ use embedded_graphics::{ prelude::*, text::{Alignment, Text}, }; -use esp32_hal::{gpio::IO, i2c::I2C, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32_hal::{ + clock::ClockControl, + gpio::IO, + i2c::I2C, + pac::Peripherals, + prelude::*, + RtcCntl, + Serial, + Timer, +}; use nb::block; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -29,7 +38,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut serial0 = Serial::new(peripherals.UART0).unwrap(); @@ -50,7 +61,8 @@ fn main() -> ! { io.pins.gpio32, io.pins.gpio33, 100u32.kHz(), - &mut peripherals.DPORT, + &mut system.peripheral_clock_control, + &clocks, ) .unwrap(); diff --git a/esp32-hal/examples/spi_loopback.rs b/esp32-hal/examples/spi_loopback.rs index a22bc63c4..1922df161 100644 --- a/esp32-hal/examples/spi_loopback.rs +++ b/esp32-hal/examples/spi_loopback.rs @@ -18,13 +18,24 @@ use core::fmt::Write; -use esp32_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Serial, Timer}; +use esp32_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Serial, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.DPORT.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -49,10 +60,11 @@ fn main() -> ! { cs, 100u32.kHz(), embedded_hal::spi::MODE_0, - &mut peripherals.DPORT, + &mut system.peripheral_clock_control, + &clocks, ); - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { let mut data = [0xde, 0xca, 0xfb, 0xad]; diff --git a/esp32-hal/src/lib.rs b/esp32-hal/src/lib.rs index 0eab8916a..dece84a3e 100644 --- a/esp32-hal/src/lib.rs +++ b/esp32-hal/src/lib.rs @@ -2,6 +2,7 @@ pub use embedded_hal as ehal; pub use esp_hal_common::{ + clock, i2c, interrupt, pac, diff --git a/esp32c3-hal/.vscode/settings.json b/esp32c3-hal/.vscode/settings.json index 7b7f1b89f..e0839ba9d 100644 --- a/esp32c3-hal/.vscode/settings.json +++ b/esp32c3-hal/.vscode/settings.json @@ -4,7 +4,6 @@ "editor.formatOnSave": true, "rust-analyzer.checkOnSave.allTargets": false, "rust-analyzer.checkOnSave.allFeatures": false, - "rust-analyzer.cargo.runBuildScripts": false, "rust-analyzer.checkOnSave.overrideCommand": [ "cargo", "check", @@ -12,5 +11,6 @@ "-Z", "build-std=core", "--examples" - ] + ], + "rust-analyzer.cargo.buildScripts.enable": false } \ No newline at end of file diff --git a/esp32c3-hal/examples/blinky.rs b/esp32c3-hal/examples/blinky.rs index dadd1f0fd..903aba019 100644 --- a/esp32c3-hal/examples/blinky.rs +++ b/esp32c3-hal/examples/blinky.rs @@ -1,13 +1,24 @@ #![no_std] #![no_main] -use esp32c3_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Timer}; +use esp32c3_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + system::SystemExt, + Delay, + RtcCntl, + Timer, +}; use panic_halt as _; use riscv_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -28,7 +39,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(peripherals.SYSTIMER); + let mut delay = Delay::new(peripherals.SYSTIMER, &clocks); loop { led.toggle().unwrap(); diff --git a/esp32c3-hal/examples/gpio_interrupt.rs b/esp32c3-hal/examples/gpio_interrupt.rs index 8a7938007..e59869836 100644 --- a/esp32c3-hal/examples/gpio_interrupt.rs +++ b/esp32c3-hal/examples/gpio_interrupt.rs @@ -5,6 +5,7 @@ use core::{cell::RefCell, fmt::Write}; use bare_metal::Mutex; use esp32c3_hal::{ + clock::ClockControl, gpio::{Gpio9, IO}, pac::{self, Peripherals, UART0}, prelude::*, @@ -30,6 +31,8 @@ static mut BUTTON: Mutex>>>> = Mutex::new(R #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -76,7 +79,7 @@ fn main() -> ! { riscv::interrupt::enable(); } - let mut delay = Delay::new(peripherals.SYSTIMER); + let mut delay = Delay::new(peripherals.SYSTIMER, &clocks); loop { led.toggle().unwrap(); delay.delay_ms(500u32); diff --git a/esp32c3-hal/examples/hello_rgb.rs b/esp32c3-hal/examples/hello_rgb.rs index 5df4b8eb9..69ec94faa 100644 --- a/esp32c3-hal/examples/hello_rgb.rs +++ b/esp32c3-hal/examples/hello_rgb.rs @@ -12,6 +12,7 @@ #![no_main] use esp32c3_hal::{ + clock::ClockControl, pac, prelude::*, pulse_control::ClockSource, @@ -34,7 +35,9 @@ use smart_leds::{ #[entry] fn main() -> ! { - let mut peripherals = pac::Peripherals::take().unwrap(); + let peripherals = pac::Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); @@ -48,7 +51,7 @@ fn main() -> ! { // Configure RMT peripheral globally let pulse = PulseControl::new( peripherals.RMT, - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, ClockSource::APB, 0, 0, @@ -62,7 +65,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(peripherals.SYSTIMER); + let mut delay = Delay::new(peripherals.SYSTIMER, &clocks); let mut color = Hsv { hue: 0, diff --git a/esp32c3-hal/examples/i2c_display.rs b/esp32c3-hal/examples/i2c_display.rs index c0bf1171c..7df4346e3 100644 --- a/esp32c3-hal/examples/i2c_display.rs +++ b/esp32c3-hal/examples/i2c_display.rs @@ -19,7 +19,15 @@ use embedded_graphics::{ prelude::*, text::{Alignment, Text}, }; -use esp32c3_hal::{gpio::IO, i2c::I2C, pac::Peripherals, prelude::*, RtcCntl, Timer}; +use esp32c3_hal::{ + clock::ClockControl, + gpio::IO, + i2c::I2C, + pac::Peripherals, + prelude::*, + RtcCntl, + Timer, +}; use nb::block; use panic_halt as _; use riscv_rt::entry; @@ -27,7 +35,9 @@ use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); @@ -48,7 +58,8 @@ fn main() -> ! { io.pins.gpio1, io.pins.gpio2, 100u32.kHz(), - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ) .unwrap(); diff --git a/esp32c3-hal/examples/spi_loopback.rs b/esp32c3-hal/examples/spi_loopback.rs index 7aa8688ac..26df6f27e 100644 --- a/esp32c3-hal/examples/spi_loopback.rs +++ b/esp32c3-hal/examples/spi_loopback.rs @@ -18,13 +18,24 @@ use core::fmt::Write; -use esp32c3_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Serial, Timer}; +use esp32c3_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Serial, + Timer, +}; use panic_halt as _; use riscv_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -38,11 +49,6 @@ fn main() -> ! { timer0.disable(); timer1.disable(); - peripherals - .SYSTEM - .sysclk_conf - .modify(|_, w| unsafe { w.soc_clk_sel().bits(1) }); - let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); let sclk = io.pins.gpio6; let miso = io.pins.gpio2; @@ -57,10 +63,11 @@ fn main() -> ! { cs, 100u32.kHz(), embedded_hal::spi::MODE_0, - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ); - let mut delay = Delay::new(peripherals.SYSTIMER); + let mut delay = Delay::new(peripherals.SYSTIMER, &clocks); loop { let mut data = [0xde, 0xca, 0xfb, 0xad]; diff --git a/esp32c3-hal/examples/usb_serial_jtag.rs b/esp32c3-hal/examples/usb_serial_jtag.rs index 2e4e66dab..abae1dc84 100644 --- a/esp32c3-hal/examples/usb_serial_jtag.rs +++ b/esp32c3-hal/examples/usb_serial_jtag.rs @@ -3,15 +3,25 @@ use core::fmt::Write; -use esp32c3_hal::{pac::Peripherals, prelude::*, Delay, RtcCntl, Timer, UsbSerialJtag}; +use esp32c3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Timer, + UsbSerialJtag, +}; use panic_halt as _; use riscv_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut delay = Delay::new(peripherals.SYSTIMER); + let mut delay = Delay::new(peripherals.SYSTIMER, &clocks); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); let mut timer1 = Timer::new(peripherals.TIMG1); diff --git a/esp32c3-hal/src/lib.rs b/esp32c3-hal/src/lib.rs index 4c770df9e..39ddc7cf8 100644 --- a/esp32c3-hal/src/lib.rs +++ b/esp32c3-hal/src/lib.rs @@ -4,6 +4,7 @@ use core::arch::global_asm; pub use embedded_hal as ehal; pub use esp_hal_common::{ + clock, i2c, interrupt, pac, @@ -11,6 +12,7 @@ pub use esp_hal_common::{ pulse_control, ram, spi, + system, utils, Cpu, Delay, diff --git a/esp32s2-hal/examples/blinky.rs b/esp32s2-hal/examples/blinky.rs index 69fee7ee0..581546fb6 100644 --- a/esp32s2-hal/examples/blinky.rs +++ b/esp32s2-hal/examples/blinky.rs @@ -1,13 +1,23 @@ #![no_std] #![no_main] -use esp32s2_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Timer}; +use esp32s2_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); @@ -24,7 +34,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { led.toggle().unwrap(); diff --git a/esp32s2-hal/examples/gpio_interrupt.rs b/esp32s2-hal/examples/gpio_interrupt.rs index 95a0ebddf..aeaeedf1f 100644 --- a/esp32s2-hal/examples/gpio_interrupt.rs +++ b/esp32s2-hal/examples/gpio_interrupt.rs @@ -4,6 +4,7 @@ use core::{cell::RefCell, fmt::Write}; use esp32s2_hal::{ + clock::ClockControl, gpio::{Gpio0, IO}, pac::{self, Peripherals, UART0}, prelude::*, @@ -31,6 +32,8 @@ static mut BUTTON: CriticalSectionMutex>>>> #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); @@ -61,7 +64,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); unsafe { xtensa_lx::interrupt::enable_mask(1 << 19); diff --git a/esp32s2-hal/examples/hello_rgb.rs b/esp32s2-hal/examples/hello_rgb.rs index 4aca40082..d98a049e4 100644 --- a/esp32s2-hal/examples/hello_rgb.rs +++ b/esp32s2-hal/examples/hello_rgb.rs @@ -12,7 +12,8 @@ #![no_main] use esp32s2_hal::{ - pac, + clock::ClockControl, + pac::Peripherals, prelude::*, utils::{smartLedAdapter, SmartLedsAdapter}, Delay, @@ -33,7 +34,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = pac::Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); @@ -44,7 +47,7 @@ fn main() -> ! { rtc_cntl.set_wdt_global_enable(false); // Configure RMT peripheral globally - let pulse = PulseControl::new(peripherals.RMT, &mut peripherals.SYSTEM).unwrap(); + let pulse = PulseControl::new(peripherals.RMT, &mut system.peripheral_clock_control).unwrap(); // We use one of the RMT channels to instantiate a `SmartLedsAdapter` which can // be used directly with all `smart_led` implementations @@ -52,7 +55,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); let mut color = Hsv { hue: 0, diff --git a/esp32s2-hal/examples/i2c_display.rs b/esp32s2-hal/examples/i2c_display.rs index 83eab78ba..5a2aa3985 100644 --- a/esp32s2-hal/examples/i2c_display.rs +++ b/esp32s2-hal/examples/i2c_display.rs @@ -21,7 +21,16 @@ use embedded_graphics::{ prelude::*, text::{Alignment, Text}, }; -use esp32s2_hal::{gpio::IO, i2c::I2C, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32s2_hal::{ + clock::ClockControl, + gpio::IO, + i2c::I2C, + pac::Peripherals, + prelude::*, + RtcCntl, + Serial, + Timer, +}; use nb::block; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -29,7 +38,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut serial0 = Serial::new(peripherals.UART0).unwrap(); @@ -50,7 +61,8 @@ fn main() -> ! { io.pins.gpio35, io.pins.gpio36, 100u32.kHz(), - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ) .unwrap(); diff --git a/esp32s2-hal/examples/spi_loopback.rs b/esp32s2-hal/examples/spi_loopback.rs index f12ab2521..5460efb89 100644 --- a/esp32s2-hal/examples/spi_loopback.rs +++ b/esp32s2-hal/examples/spi_loopback.rs @@ -2,8 +2,8 @@ //! //! Folowing pins are used: //! SCLK GPIO36 -//! MISO GPIO35 -//! MOSI GPIO37 +//! MISO GPIO37 +//! MOSI GPIO35 //! CS GPIO34 //! //! Depending on your target and the board you are using you have to change the @@ -18,13 +18,24 @@ use core::fmt::Write; -use esp32s2_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Serial, Timer}; +use esp32s2_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Serial, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -49,10 +60,11 @@ fn main() -> ! { cs, 100u32.kHz(), embedded_hal::spi::MODE_0, - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ); - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { let mut data = [0xde, 0xca, 0xfb, 0xad]; diff --git a/esp32s2-hal/src/lib.rs b/esp32s2-hal/src/lib.rs index 676425a84..f78a85f11 100644 --- a/esp32s2-hal/src/lib.rs +++ b/esp32s2-hal/src/lib.rs @@ -2,6 +2,7 @@ pub use embedded_hal as ehal; pub use esp_hal_common::{ + clock, i2c::{self, I2C}, interrupt, pac, diff --git a/esp32s3-hal/examples/blinky.rs b/esp32s3-hal/examples/blinky.rs index 5692d3dd9..c59e12e54 100644 --- a/esp32s3-hal/examples/blinky.rs +++ b/esp32s3-hal/examples/blinky.rs @@ -1,13 +1,23 @@ #![no_std] #![no_main] -use esp32s3_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Timer}; +use esp32s3_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); @@ -24,7 +34,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { led.toggle().unwrap(); diff --git a/esp32s3-hal/examples/gpio_interrupt.rs b/esp32s3-hal/examples/gpio_interrupt.rs index b138f535c..b36496025 100644 --- a/esp32s3-hal/examples/gpio_interrupt.rs +++ b/esp32s3-hal/examples/gpio_interrupt.rs @@ -4,6 +4,7 @@ use core::{cell::RefCell, fmt::Write}; use esp32s3_hal::{ + clock::ClockControl, gpio::{Gpio0, IO}, pac::{self, Peripherals, UART0}, prelude::*, @@ -31,6 +32,8 @@ static mut BUTTON: SpinLockMutex>>>> = #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); @@ -61,7 +64,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); unsafe { xtensa_lx::interrupt::enable_mask(1 << 19); diff --git a/esp32s3-hal/examples/hello_rgb.rs b/esp32s3-hal/examples/hello_rgb.rs index 014afa7e6..948eb4c9e 100644 --- a/esp32s3-hal/examples/hello_rgb.rs +++ b/esp32s3-hal/examples/hello_rgb.rs @@ -12,7 +12,8 @@ #![no_main] use esp32s3_hal::{ - pac, + clock::ClockControl, + pac::Peripherals, prelude::*, pulse_control::ClockSource, utils::{smartLedAdapter, SmartLedsAdapter}, @@ -34,7 +35,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = pac::Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); @@ -47,7 +50,7 @@ fn main() -> ! { // Configure RMT peripheral globally let pulse = PulseControl::new( peripherals.RMT, - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, ClockSource::APB, 0, 0, @@ -61,7 +64,7 @@ fn main() -> ! { // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); let mut color = Hsv { hue: 0, diff --git a/esp32s3-hal/examples/i2c_display.rs b/esp32s3-hal/examples/i2c_display.rs index e7ea8d6ef..308b7ff9e 100644 --- a/esp32s3-hal/examples/i2c_display.rs +++ b/esp32s3-hal/examples/i2c_display.rs @@ -21,7 +21,16 @@ use embedded_graphics::{ prelude::*, text::{Alignment, Text}, }; -use esp32s3_hal::{gpio::IO, i2c::I2C, pac::Peripherals, prelude::*, RtcCntl, Serial, Timer}; +use esp32s3_hal::{ + clock::ClockControl, + gpio::IO, + i2c::I2C, + pac::Peripherals, + prelude::*, + RtcCntl, + Serial, + Timer, +}; use nb::block; use panic_halt as _; use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306}; @@ -29,7 +38,9 @@ use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let mut timer0 = Timer::new(peripherals.TIMG0); let mut serial0 = Serial::new(peripherals.UART0).unwrap(); @@ -50,7 +61,8 @@ fn main() -> ! { io.pins.gpio1, io.pins.gpio2, 100u32.kHz(), - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ) .unwrap(); diff --git a/esp32s3-hal/examples/spi_loopback.rs b/esp32s3-hal/examples/spi_loopback.rs index 157861f4d..aa669fd57 100644 --- a/esp32s3-hal/examples/spi_loopback.rs +++ b/esp32s3-hal/examples/spi_loopback.rs @@ -18,13 +18,24 @@ use core::fmt::Write; -use esp32s3_hal::{gpio::IO, pac::Peripherals, prelude::*, Delay, RtcCntl, Serial, Timer}; +use esp32s3_hal::{ + clock::ClockControl, + gpio::IO, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Serial, + Timer, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { - let mut peripherals = Peripherals::take().unwrap(); + let peripherals = Peripherals::take().unwrap(); + let mut system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); // Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT, // the RTC WDT, and the TIMG WDTs. @@ -49,10 +60,11 @@ fn main() -> ! { cs, 100u32.kHz(), embedded_hal::spi::MODE_0, - &mut peripherals.SYSTEM, + &mut system.peripheral_clock_control, + &clocks, ); - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); loop { let mut data = [0xde, 0xca, 0xfb, 0xad]; diff --git a/esp32s3-hal/examples/usb_serial_jtag.rs b/esp32s3-hal/examples/usb_serial_jtag.rs index c7554be4d..d4ac44f7e 100644 --- a/esp32s3-hal/examples/usb_serial_jtag.rs +++ b/esp32s3-hal/examples/usb_serial_jtag.rs @@ -3,15 +3,25 @@ use core::fmt::Write; -use esp32s3_hal::{pac::Peripherals, prelude::*, Delay, RtcCntl, Timer, UsbSerialJtag}; +use esp32s3_hal::{ + clock::ClockControl, + pac::Peripherals, + prelude::*, + Delay, + RtcCntl, + Timer, + UsbSerialJtag, +}; use panic_halt as _; use xtensa_lx_rt::entry; #[entry] fn main() -> ! { let peripherals = Peripherals::take().unwrap(); + let system = peripherals.SYSTEM.split(); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); - let mut delay = Delay::new(); + let mut delay = Delay::new(&clocks); let mut rtc_cntl = RtcCntl::new(peripherals.RTC_CNTL); let mut timer0 = Timer::new(peripherals.TIMG0); diff --git a/esp32s3-hal/src/lib.rs b/esp32s3-hal/src/lib.rs index cf409fadf..b6fe8450f 100644 --- a/esp32s3-hal/src/lib.rs +++ b/esp32s3-hal/src/lib.rs @@ -2,6 +2,7 @@ pub use embedded_hal as ehal; pub use esp_hal_common::{ + clock, i2c, interrupt, pac,