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