Skip to content
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 @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add octal PSRAM support for ESP32-S3 (#610)
- Add MD5 functions from ESP ROM (#618)
- Add embassy async `read` support for `uart` (#620)
- Add bare-bones support to run code on ULP-RISCV / LP core (#631)

### Changed

Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/devices/esp32c6.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ peripherals = [
"bt",
"wifi",
"ieee802154",
"lp_core",

# ROM capabilities
"rom_crc_le",
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/devices/esp32s2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ peripherals = [
"phy",
"wifi",
"psram",
"ulp_riscv_core",

# ROM capabilities
"rom_crc_le",
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/devices/esp32s3.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ peripherals = [
"bt",
"wifi",
"psram",
"ulp_riscv_core",

# ROM capabilities
"rom_crc_le",
Expand Down
4 changes: 4 additions & 0 deletions esp-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ pub use self::rtc_cntl::{Rtc, Rwdt};
pub use self::soc::cpu_control;
#[cfg(efuse)]
pub use self::soc::efuse;
#[cfg(lp_core)]
pub use self::soc::lp_core;
pub use self::soc::peripherals;
#[cfg(psram)]
pub use self::soc::psram;
#[cfg(ulp_riscv_core)]
pub use self::soc::ulp_core;
#[cfg(any(spi0, spi1, spi2, spi3))]
pub use self::spi::Spi;
#[cfg(any(timg0, timg1))]
Expand Down
79 changes: 79 additions & 0 deletions esp-hal-common/src/soc/esp32c6/lp_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! Control the LP core

use esp32c6 as pac;

use crate::peripheral::{Peripheral, PeripheralRef};

#[derive(Debug, Clone, Copy)]
pub enum LpCoreWakeupSource {
HpCpu,
}

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

impl<'d> LpCore<'d> {
pub fn new(lp_core: impl Peripheral<P = crate::soc::peripherals::LP_CORE> + 'd) -> Self {
crate::into_ref!(lp_core);
Self { _lp_core: lp_core }
}

pub fn stop(&mut self) {
ulp_lp_core_stop();
}

pub fn run(&mut self, wakeup_src: LpCoreWakeupSource) {
ulp_lp_core_run(wakeup_src);
}
}

fn ulp_lp_core_stop() {
let pmu = unsafe { &*pac::PMU::PTR };
pmu.lp_cpu_pwr1
.modify(|_, w| unsafe { w.lp_cpu_wakeup_en().bits(0) });
pmu.lp_cpu_pwr1
.modify(|_, w| w.lp_cpu_sleep_req().set_bit());
}

fn ulp_lp_core_run(wakeup_src: LpCoreWakeupSource) {
let lp_aon = unsafe { &*pac::LP_AON::PTR };
let pmu = unsafe { &*pac::PMU::PTR };
let lp_peri = unsafe { &*pac::LP_PERI::PTR };

// Enable LP-Core
lp_aon.lpcore.modify(|_, w| w.disable().clear_bit());

// Allow LP core to access LP memory during sleep
lp_aon.lpbus.modify(|_, w| w.fast_mem_mux_sel().clear_bit());
lp_aon
.lpbus
.modify(|_, w| w.fast_mem_mux_sel_update().set_bit());

// Enable stall at sleep request
pmu.lp_cpu_pwr0
.modify(|_, w| w.lp_cpu_slp_stall_en().set_bit());

// Enable reset after wake-up
pmu.lp_cpu_pwr0
.modify(|_, w| w.lp_cpu_slp_reset_en().set_bit());

// Set wake-up sources
let src = match wakeup_src {
LpCoreWakeupSource::HpCpu => 0x01,
};
pmu.lp_cpu_pwr1
.modify(|_, w| w.lp_cpu_wakeup_en().variant(src));

// Enable JTAG debugging
lp_peri
.cpu
.modify(|_, w| w.lpcore_dbgm_unavaliable().clear_bit());

// wake up
match wakeup_src {
LpCoreWakeupSource::HpCpu => {
pmu.hp_lp_cpu_comm.write(|w| w.hp_trigger_lp().set_bit());
}
}
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32c6/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod efuse;
pub mod gpio;
pub mod lp_core;
pub mod peripherals;
pub mod radio_clocks;

Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32c6/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ crate::peripherals! {
UHCI0 => true,
USB_DEVICE => true,
RADIO => false,
LP_CORE => false,
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32s2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod peripherals;
#[cfg(psram)]
pub mod psram;
pub mod radio_clocks;
pub mod ulp_core;

pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32s2/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,5 @@ crate::peripherals! {
XTS_AES => true,
RADIO => false,
PSRAM => false,
ULP_RISCV_CORE => false,
}
2 changes: 1 addition & 1 deletion esp-hal-common/src/soc/esp32s2/psram.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const PSRAM_VADDR: u32 = 0x3f500000;

pub fn psram_vaddr_start() -> usize {
unsafe { PSRAM_VADDR_START as usize }
PSRAM_VADDR_START as usize
}

cfg_if::cfg_if! {
Expand Down
109 changes: 109 additions & 0 deletions esp-hal-common/src/soc/esp32s2/ulp_core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//! Control the ULP RISCV core

use esp32s2 as pac;

use crate::peripheral::{Peripheral, PeripheralRef};

extern "C" {
fn ets_delay_us(delay: u32);
}

#[derive(Debug, Clone, Copy)]
pub enum UlpCoreWakeupSource {
HpCpu,
}

pub struct UlpCore<'d> {
_lp_core: PeripheralRef<'d, crate::soc::peripherals::ULP_RISCV_CORE>,
}

impl<'d> UlpCore<'d> {
pub fn new(lp_core: impl Peripheral<P = crate::soc::peripherals::ULP_RISCV_CORE> + 'd) -> Self {
crate::into_ref!(lp_core);
Self { _lp_core: lp_core }
}

// currently stopping the ULP doesn't work (while following the proedures
// outlines in the TRM) - so don't offer this funtion for now
//
// pub fn stop(&mut self) {
// ulp_stop();
// }

pub fn run(&mut self, wakeup_src: UlpCoreWakeupSource) {
ulp_run(wakeup_src);
}
}

fn ulp_stop() {
let rtc_cntl = unsafe { &*pac::RTC_CNTL::PTR };
rtc_cntl
.ulp_cp_timer
.modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit());

// suspends the ulp operation
rtc_cntl.cocpu_ctrl.modify(|_, w| w.cocpu_done().set_bit());

// Resets the processor
rtc_cntl
.cocpu_ctrl
.modify(|_, w| w.cocpu_shut_reset_en().set_bit());
}

fn ulp_run(wakeup_src: UlpCoreWakeupSource) {
let rtc_cntl = unsafe { &*pac::RTC_CNTL::PTR };

// Reset COCPU when power on
rtc_cntl
.cocpu_ctrl
.modify(|_, w| w.cocpu_shut_reset_en().set_bit());

// Disable ULP timer
rtc_cntl
.ulp_cp_timer
.modify(|_, w| w.ulp_cp_slp_timer_en().clear_bit());

// wait for at least 1 RTC_SLOW_CLK cycle
unsafe {
ets_delay_us(20);
}

// Select ULP-RISC-V to send the DONE signal
rtc_cntl
.cocpu_ctrl
.modify(|_, w| w.cocpu_done_force().set_bit());

ulp_config_wakeup_source(wakeup_src);

// Select RISC-V as the ULP_TIMER trigger target
rtc_cntl.cocpu_ctrl.modify(|_, w| w.cocpu_sel().clear_bit());

// Clear any spurious wakeup trigger interrupts upon ULP startup
unsafe {
ets_delay_us(20);
}

rtc_cntl.int_clr_rtc.write(|w| {
w.cocpu_int_clr()
.set_bit()
.cocpu_trap_int_clr()
.set_bit()
.ulp_cp_int_clr()
.set_bit()
});
}

fn ulp_config_wakeup_source(wakeup_src: UlpCoreWakeupSource) {
match wakeup_src {
UlpCoreWakeupSource::HpCpu => {
// use timer to wake up
let rtc_cntl = unsafe { &*pac::RTC_CNTL::PTR };
rtc_cntl
.ulp_cp_ctrl
.modify(|_, w| w.ulp_cp_force_start_top().clear_bit());
rtc_cntl
.ulp_cp_timer
.modify(|_, w| w.ulp_cp_slp_timer_en().set_bit());
}
}
}
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32s3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod peripherals;
#[cfg(psram)]
pub mod psram;
pub mod radio_clocks;
pub mod ulp_core;

pub(crate) mod constants {
pub const I2S_SCLK: u32 = 160_000_000;
Expand Down
1 change: 1 addition & 0 deletions esp-hal-common/src/soc/esp32s3/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ crate::peripherals! {
XTS_AES => true,
RADIO => false,
PSRAM => false,
ULP_RISCV_CORE => false,
}
Loading