mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 12:50:53 +00:00
Feature/reset functionalities (#452)
* add `software_reset`, `software_reset_cpu` and `rtc_get_wakeup_cause` * Add SOC wakeup symbols * Add SleepSource and WakeupReason enums and get_wakeup_cause() function * Add other SOC wakeups * fixups and fmt * address review comments * Update symbols in WakeupReason enum * fmt --------- Co-authored-by: Anthony Grondin <104731965+AnthonyGrondin@users.noreply.github.com>
This commit is contained in:
parent
91ded64b16
commit
0244c6d6fc
@ -53,4 +53,10 @@ peripherals = [
|
||||
"dac",
|
||||
"pdma",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_ext0_wakeup",
|
||||
"pm_support_ext1_wakeup",
|
||||
"pm_support_touch_sensor_wakeup",
|
||||
"ulp_supported",
|
||||
]
|
||||
|
@ -34,4 +34,10 @@ peripherals = [
|
||||
"adc",
|
||||
"gdma",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_wifi_wakeup",
|
||||
"pm_support_bt_wakeup",
|
||||
"uart_support_wakeup_int",
|
||||
"gpio_support_deepsleep_wakeup",
|
||||
]
|
||||
|
@ -45,4 +45,10 @@ peripherals = [
|
||||
"adc",
|
||||
"gdma",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_wifi_wakeup",
|
||||
"pm_support_bt_wakeup",
|
||||
"uart_support_wakeup_int",
|
||||
"gpio_support_deepsleep_wakeup",
|
||||
]
|
||||
|
@ -73,4 +73,12 @@ peripherals = [
|
||||
"large_intr_status",
|
||||
"plic",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_wifi_wakeup",
|
||||
"pm_support_beacon_wakeup",
|
||||
"pm_support_bt_wakeup",
|
||||
"gpio_support_deepsleep_wakeup",
|
||||
"uart_support_wakeup_int",
|
||||
"pm_support_ext1_wakeup",
|
||||
]
|
||||
|
@ -51,4 +51,13 @@ peripherals = [
|
||||
"dac",
|
||||
"pdma",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_ext0_wakeup",
|
||||
"pm_support_ext1_wakeup",
|
||||
"pm_support_touch_sensor_wakeup",
|
||||
"pm_support_wifi_wakeup",
|
||||
"uart_support_wakeup_int",
|
||||
"ulp_supported",
|
||||
"riscv_coproc_supported",
|
||||
]
|
||||
|
@ -61,4 +61,14 @@ peripherals = [
|
||||
"adc",
|
||||
"gdma",
|
||||
"radio",
|
||||
|
||||
# Wakeup SOC based on ESP-IDF:
|
||||
"pm_support_ext0_wakeup",
|
||||
"pm_support_ext1_wakeup",
|
||||
"pm_support_touch_sensor_wakeup",
|
||||
"pm_support_wifi_wakeup",
|
||||
"pm_support_bt_wakeup",
|
||||
"uart_support_wakeup_int",
|
||||
"ulp_supported",
|
||||
"riscv_coproc_supported",
|
||||
]
|
||||
|
@ -99,6 +99,7 @@ pub mod prelude;
|
||||
pub mod pulse_control;
|
||||
#[cfg(radio)]
|
||||
pub mod radio;
|
||||
pub mod reset;
|
||||
#[cfg(rng)]
|
||||
pub mod rng;
|
||||
pub mod rom;
|
||||
|
81
esp-hal-common/src/reset.rs
Normal file
81
esp-hal-common/src/reset.rs
Normal file
@ -0,0 +1,81 @@
|
||||
use crate::rtc_cntl::SocResetReason;
|
||||
|
||||
pub enum SleepSource {
|
||||
/// In case of deep sleep, reset was not caused by exit from deep sleep
|
||||
Undefined = 0,
|
||||
/// Not a wakeup cause, used to disable all wakeup sources with
|
||||
/// esp_sleep_disable_wakeup_source
|
||||
All,
|
||||
/// Wakeup caused by external signal using RTC_IO
|
||||
Ext0,
|
||||
/// Wakeup caused by external signal using RTC_CNTL
|
||||
Ext1,
|
||||
/// Wakeup caused by timer
|
||||
Timer,
|
||||
/// Wakeup caused by touchpad
|
||||
TouchPad,
|
||||
/// Wakeup caused by ULP program
|
||||
Ulp,
|
||||
/// Wakeup caused by GPIO (light sleep only on ESP32, S2 and S3)
|
||||
Gpio,
|
||||
/// Wakeup caused by UART (light sleep only)
|
||||
Uart,
|
||||
/// Wakeup caused by WIFI (light sleep only)
|
||||
Wifi,
|
||||
/// Wakeup caused by COCPU int
|
||||
Cocpu,
|
||||
/// Wakeup caused by COCPU crash
|
||||
CocpuTrapTrig,
|
||||
/// Wakeup caused by BT (light sleep only)
|
||||
BT,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) enum WakeupReason {
|
||||
NoSleep = 0,
|
||||
#[cfg(pm_support_ext0_wakeup)]
|
||||
/// EXT0 GPIO wakeup
|
||||
ExtEvent0Trig = 1 << 0,
|
||||
#[cfg(pm_support_ext1_wakeup)]
|
||||
/// EXT1 GPIO wakeup
|
||||
ExtEvent1Trig = 1 << 1,
|
||||
/// GPIO wakeup (light sleep only)
|
||||
GpioTrigEn = 1 << 2,
|
||||
/// Timer wakeup
|
||||
TimerTrigEn = 1 << 3,
|
||||
#[cfg(pm_support_wifi_wakeup)]
|
||||
/// MAC wakeup (light sleep only)
|
||||
WifiTrigEn = 1 << 5,
|
||||
/// UART0 wakeup (light sleep only)
|
||||
Uart0TrigEn = 1 << 6,
|
||||
/// UART1 wakeup (light sleep only)
|
||||
Uart1TrigEn = 1 << 7,
|
||||
#[cfg(pm_support_touch_sensor_wakeup)]
|
||||
/// Touch wakeup
|
||||
TouchTrigEn = 1 << 8,
|
||||
#[cfg(ulp_supported)]
|
||||
/// ULP wakeup
|
||||
UlpTrigEn = 1 << 9,
|
||||
#[cfg(pm_support_bt_wakeup)]
|
||||
/// BT wakeup (light sleep only)
|
||||
BtTrigEn = 1 << 10,
|
||||
#[cfg(riscv_coproc_supported)]
|
||||
CocpuTrigEn = 1 << 11,
|
||||
#[cfg(riscv_coproc_supported)]
|
||||
CocpuTrapTrigEn = 1 << 13,
|
||||
}
|
||||
|
||||
pub fn software_reset() {
|
||||
unsafe { crate::rtc_cntl::software_reset() }
|
||||
}
|
||||
pub fn software_reset_cpu() {
|
||||
unsafe { crate::rtc_cntl::software_reset_cpu() }
|
||||
}
|
||||
|
||||
pub fn get_reset_reason() -> Option<SocResetReason> {
|
||||
crate::rtc_cntl::get_reset_reason(crate::get_core())
|
||||
}
|
||||
|
||||
pub fn get_wakeup_cause() -> SleepSource {
|
||||
crate::rtc_cntl::get_wakeup_cause()
|
||||
}
|
@ -3,7 +3,7 @@ use embedded_hal::watchdog::{Watchdog, WatchdogDisable, WatchdogEnable};
|
||||
use fugit::HertzU32;
|
||||
use fugit::MicrosDurationU64;
|
||||
|
||||
use self::rtc::SocResetReason;
|
||||
pub use self::rtc::SocResetReason;
|
||||
#[cfg(not(esp32c6))]
|
||||
use crate::clock::{Clock, XtalClock};
|
||||
#[cfg(not(esp32))]
|
||||
@ -14,6 +14,7 @@ use crate::peripherals::LP_WDT;
|
||||
use crate::peripherals::{RTC_CNTL, TIMG0};
|
||||
use crate::{
|
||||
peripheral::{Peripheral, PeripheralRef},
|
||||
reset::{SleepSource, WakeupReason},
|
||||
Cpu,
|
||||
};
|
||||
|
||||
@ -37,6 +38,9 @@ extern "C" {
|
||||
#[allow(dead_code)]
|
||||
fn ets_delay_us(us: u32);
|
||||
fn rtc_get_reset_reason(cpu_num: u32) -> u32;
|
||||
fn rtc_get_wakeup_cause() -> u32;
|
||||
pub fn software_reset_cpu();
|
||||
pub fn software_reset();
|
||||
}
|
||||
|
||||
#[cfg(not(esp32c6))]
|
||||
@ -748,3 +752,79 @@ pub fn get_reset_reason(cpu: Cpu) -> Option<SocResetReason> {
|
||||
|
||||
reason
|
||||
}
|
||||
|
||||
pub fn get_wakeup_cause() -> SleepSource {
|
||||
// FIXME: check s_light_sleep_wakeup
|
||||
// https://github.com/espressif/esp-idf/blob/afbdb0f3ef195ab51690a64e22bfb8a5cd487914/components/esp_hw_support/sleep_modes.c#L1394
|
||||
if get_reset_reason(Cpu::ProCpu).unwrap() != SocResetReason::CoreDeepSleep {
|
||||
return SleepSource::Undefined;
|
||||
}
|
||||
|
||||
#[cfg(esp32c6)]
|
||||
let wakeup_cause = unsafe {
|
||||
(&*crate::peripherals::PMU::PTR)
|
||||
.slp_wakeup_status0
|
||||
.read()
|
||||
.wakeup_cause()
|
||||
.bits()
|
||||
};
|
||||
#[cfg(not(any(esp32, esp32c6)))]
|
||||
let wakeup_cause = unsafe {
|
||||
(&*RTC_CNTL::PTR)
|
||||
.slp_wakeup_cause
|
||||
.read()
|
||||
.wakeup_cause()
|
||||
.bits()
|
||||
};
|
||||
#[cfg(esp32)]
|
||||
let wakeup_cause =
|
||||
unsafe { (&*RTC_CNTL::PTR).wakeup_state.read().wakeup_cause().bits() as u32 };
|
||||
|
||||
if (wakeup_cause & WakeupReason::TimerTrigEn as u32) == 0 {
|
||||
return SleepSource::Timer;
|
||||
}
|
||||
if (wakeup_cause & WakeupReason::GpioTrigEn as u32) == 0 {
|
||||
return SleepSource::Gpio;
|
||||
}
|
||||
if (wakeup_cause & (WakeupReason::Uart0TrigEn as u32 | WakeupReason::Uart1TrigEn as u32)) == 0 {
|
||||
return SleepSource::Uart;
|
||||
}
|
||||
|
||||
#[cfg(pm_support_ext0_wakeup)]
|
||||
if (wakeup_cause & WakeupReason::ExtEvent0Trig as u32) == 0 {
|
||||
return SleepSource::Ext0;
|
||||
}
|
||||
#[cfg(pm_support_ext1_wakeup)]
|
||||
if (wakeup_cause & WakeupReason::ExtEvent1Trig as u32) == 0 {
|
||||
return SleepSource::Ext1;
|
||||
}
|
||||
|
||||
#[cfg(pm_support_touch_sensor_wakeup)]
|
||||
if (wakeup_cause & WakeupReason::TouchTrigEn as u32) == 0 {
|
||||
return SleepSource::TouchPad;
|
||||
}
|
||||
|
||||
#[cfg(ulp_supported)]
|
||||
if (wakeup_cause & WakeupReason::UlpTrigEn as u32) == 0 {
|
||||
return SleepSource::Ulp;
|
||||
}
|
||||
|
||||
#[cfg(pm_support_wifi_wakeup)]
|
||||
if (wakeup_cause & WakeupReason::WifiTrigEn as u32) == 0 {
|
||||
return SleepSource::Wifi;
|
||||
}
|
||||
|
||||
#[cfg(pm_support_bt_wakeup)]
|
||||
if (wakeup_cause & WakeupReason::BtTrigEn as u32) == 0 {
|
||||
return SleepSource::BT;
|
||||
}
|
||||
|
||||
#[cfg(riscv_coproc_supported)]
|
||||
if (wakeup_cause & WakeupReason::CocpuTrigEn as u32) == 0 {
|
||||
return SleepSource::Ulp;
|
||||
} else if (wakeup_cause & WakeupReason::CocpuTrapTrigEn as u32) == 0 {
|
||||
return SleepSource::CocpuTrapTrig;
|
||||
}
|
||||
|
||||
return SleepSource::Undefined;
|
||||
}
|
||||
|
@ -3,3 +3,6 @@ PROVIDE(ets_update_cpu_frequency_rom = 0x40008550);
|
||||
PROVIDE(rom_i2c_writeReg = 0x400041a4);
|
||||
PROVIDE(rom_i2c_writeReg_Mask = 0x400041fc);
|
||||
PROVIDE(rtc_get_reset_reason = 0x400081d4);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x400081f4);
|
||||
PROVIDE(software_reset = 0x4000824c);
|
||||
PROVIDE(software_reset_cpu = 0x40008264);
|
||||
|
@ -3,3 +3,6 @@ PROVIDE(ets_update_cpu_frequency_rom = 0x40000774);
|
||||
PROVIDE(rom_i2c_writeReg = 0x400022f4);
|
||||
PROVIDE(rom_i2c_writeReg_Mask = 0x400022fc);
|
||||
PROVIDE(rtc_get_reset_reason = 0x40000018);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x40000020);
|
||||
PROVIDE(software_reset = 0x40000088);
|
||||
PROVIDE(software_reset_cpu = 0x4000008c);
|
||||
|
@ -10,3 +10,6 @@ PROVIDE(ets_update_cpu_frequency_rom = 0x40000588);
|
||||
PROVIDE(rom_i2c_writeReg = 0x4000195c);
|
||||
PROVIDE(rom_i2c_writeReg_Mask = 0x40001960);
|
||||
PROVIDE(rtc_get_reset_reason = 0x40000018);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x40000024);
|
||||
PROVIDE(software_reset = 0x40000090);
|
||||
PROVIDE(software_reset_cpu = 0x40000094);
|
||||
|
@ -9,4 +9,7 @@ PROVIDE(cache_resume_icache = 0x4000069c);
|
||||
PROVIDE(ets_delay_us = 0x40000040);
|
||||
PROVIDE(ets_update_cpu_frequency_rom = 0x40000048);
|
||||
PROVIDE(rtc_get_reset_reason = 0x40000018);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x40000020);
|
||||
ets_update_cpu_frequency = 0x40000048;
|
||||
PROVIDE(software_reset = 0x40000090);
|
||||
PROVIDE(software_reset_cpu = 0x40000094);
|
||||
|
@ -3,3 +3,6 @@ PROVIDE(ets_update_cpu_frequency_rom = 0x4000d8a4);
|
||||
PROVIDE(rom_i2c_writeReg = 0x4000a9a8);
|
||||
PROVIDE(rom_i2c_writeReg_Mask = 0x4000aa00);
|
||||
PROVIDE(rtc_get_reset_reason = 0x4000ff58);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x4000ff7c);
|
||||
PROVIDE(software_reset = 0x40010068);
|
||||
PROVIDE(software_reset_cpu = 0x40010080);
|
||||
|
@ -3,4 +3,7 @@ PROVIDE(ets_update_cpu_frequency_rom = 0x40043164);
|
||||
PROVIDE(rom_i2c_writeReg = 0x40005d60);
|
||||
PROVIDE(rom_i2c_writeReg_Mask = 0x40005d6c);
|
||||
PROVIDE(rtc_get_reset_reason = 0x4000057c);
|
||||
PROVIDE( rom_config_instruction_cache_mode = 0x40001a1c );
|
||||
PROVIDE(rom_config_instruction_cache_mode = 0x40001a1c);
|
||||
PROVIDE(rtc_get_wakeup_cause = 0x400005a0);
|
||||
PROVIDE(software_reset = 0x400006d8);
|
||||
PROVIDE(software_reset_cpu = 0x400006e4);
|
||||
|
Loading…
x
Reference in New Issue
Block a user