Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable LP Core clock #907

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- ESP32-C6: LP core clock is configurable (#907)

### Changed

Expand Down
36 changes: 36 additions & 0 deletions esp-hal-common/src/soc/esp32c6/lp_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,56 @@ pub enum LpCoreWakeupSource {
HpCpu,
}

/// Clock sources for the LP core
#[derive(Debug, Clone, Copy)]
pub enum LpCoreClockSource {
/// 17.5 MHz clock
///
/// Might not be very accurate
RcFastClk,
/// 20 MHz clock
XtalD2Clk,
}

pub struct LpCore<'d> {
_lp_core: PeripheralRef<'d, crate::soc::peripherals::LP_CORE>,
}

impl<'d> LpCore<'d> {
/// Create a new instance using [LpCoreClockSource::RcFastClk]
pub fn new(lp_core: impl Peripheral<P = crate::soc::peripherals::LP_CORE> + 'd) -> Self {
LpCore::new_with_clock(lp_core, LpCoreClockSource::RcFastClk)
}

/// Create a new instance using the given clock
pub fn new_with_clock(
lp_core: impl Peripheral<P = crate::soc::peripherals::LP_CORE> + 'd,
clk_src: LpCoreClockSource,
) -> Self {
crate::into_ref!(lp_core);

match clk_src {
LpCoreClockSource::RcFastClk => unsafe {
(&*crate::soc::peripherals::LP_CLKRST::PTR)
.lp_clk_conf
.modify(|_, w| w.fast_clk_sel().clear_bit())
},
LpCoreClockSource::XtalD2Clk => unsafe {
(&*crate::soc::peripherals::LP_CLKRST::PTR)
.lp_clk_conf
.modify(|_, w| w.fast_clk_sel().set_bit())
},
}

Self { _lp_core: lp_core }
}

/// Stop the LP core
pub fn stop(&mut self) {
ulp_lp_core_stop();
}

/// Start the LP core
pub fn run(&mut self, wakeup_src: LpCoreWakeupSource) {
ulp_lp_core_run(wakeup_src);
}
Expand Down
2 changes: 1 addition & 1 deletion esp32c6-lp-hal/src/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Delay {
impl Delay {
pub fn new() -> Self {
Self {
rv_delay: riscv::delay::McycleDelay::new(CPU_CLOCK),
rv_delay: riscv::delay::McycleDelay::new(unsafe { CPU_CLOCK }),
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion esp32c6-lp-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ pub mod riscv {
}
pub mod prelude;

const CPU_CLOCK: u32 = 16_000_000;
// LP_FAST_CLK is not very accurate, for now use a rough estimate
const LP_FAST_CLK_HZ: u32 = 16_000_000;
const XTAL_D2_CLK_HZ: u32 = 20_000_000;

pub static mut CPU_CLOCK: u32 = LP_FAST_CLK_HZ;

global_asm!(
r#"
Expand Down Expand Up @@ -60,6 +64,11 @@ unsafe extern "C" fn lp_core_startup() -> ! {
fn main() -> !;
}

let clkrst = &*esp32c6_lp::LP_CLKRST::PTR;
if clkrst.lp_clk_conf.read().fast_clk_sel().bit_is_set() {
CPU_CLOCK = XTAL_D2_CLK_HZ;
}

main();
}

Expand Down