esp_hal/soc/esp32c6/
lp_core.rs1use crate::peripherals::{LP_AON, LP_CORE, LP_PERI, LPWR, PMU};
23
24#[derive(Debug, Clone, Copy)]
26pub enum LpCoreWakeupSource {
27 HpCpu,
29}
30
31#[derive(Debug, Clone, Copy)]
33pub enum LpCoreClockSource {
34 RcFastClk,
38 XtalD2Clk,
40}
41
42pub struct LpCore<'d> {
44 _lp_core: LP_CORE<'d>,
45}
46
47impl<'d> LpCore<'d> {
48 pub fn new(lp_core: LP_CORE<'d>) -> Self {
50 LpCore::new_with_clock(lp_core, LpCoreClockSource::RcFastClk)
51 }
52
53 pub fn new_with_clock(lp_core: LP_CORE<'d>, clk_src: LpCoreClockSource) -> Self {
55 match clk_src {
56 LpCoreClockSource::RcFastClk => LPWR::regs()
57 .lp_clk_conf()
58 .modify(|_, w| w.fast_clk_sel().clear_bit()),
59 LpCoreClockSource::XtalD2Clk => LPWR::regs()
60 .lp_clk_conf()
61 .modify(|_, w| w.fast_clk_sel().set_bit()),
62 };
63
64 let mut this = Self { _lp_core: lp_core };
65 this.stop();
66
67 let lp_ram =
69 unsafe { core::slice::from_raw_parts_mut(0x5000_0000 as *mut u32, 16 * 1024 / 4) };
70 lp_ram.fill(0u32);
71
72 this
73 }
74
75 pub fn stop(&mut self) {
77 ulp_lp_core_stop();
78 }
79
80 pub fn run(&mut self, wakeup_src: LpCoreWakeupSource) {
82 ulp_lp_core_run(wakeup_src);
83 }
84}
85
86fn ulp_lp_core_stop() {
87 PMU::regs()
88 .lp_cpu_pwr1()
89 .modify(|_, w| unsafe { w.lp_cpu_wakeup_en().bits(0) });
90 PMU::regs()
91 .lp_cpu_pwr1()
92 .modify(|_, w| w.lp_cpu_sleep_req().set_bit());
93}
94
95fn ulp_lp_core_run(wakeup_src: LpCoreWakeupSource) {
96 let lp_aon = LP_AON::regs();
97 let pmu = PMU::regs();
98 let lp_peri = LP_PERI::regs();
99
100 lp_aon.lpcore().modify(|_, w| w.disable().clear_bit());
102
103 lp_aon
105 .lpbus()
106 .modify(|_, w| w.fast_mem_mux_sel().clear_bit());
107 lp_aon
108 .lpbus()
109 .modify(|_, w| w.fast_mem_mux_sel_update().set_bit());
110
111 pmu.lp_cpu_pwr0()
113 .modify(|_, w| w.lp_cpu_slp_stall_en().set_bit());
114
115 pmu.lp_cpu_pwr0()
117 .modify(|_, w| w.lp_cpu_slp_reset_en().set_bit());
118
119 let src = match wakeup_src {
121 LpCoreWakeupSource::HpCpu => 0x01,
122 };
123 pmu.lp_cpu_pwr1()
124 .modify(|_, w| unsafe { w.lp_cpu_wakeup_en().bits(src) });
125
126 lp_peri
128 .cpu()
129 .modify(|_, w| w.lpcore_dbgm_unavaliable().clear_bit());
130
131 match wakeup_src {
133 LpCoreWakeupSource::HpCpu => {
134 pmu.hp_lp_cpu_comm().write(|w| w.hp_trigger_lp().set_bit());
135 }
136 }
137}