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:
Juraj Sadel 2023-03-24 20:37:24 +01:00 committed by GitHub
parent 91ded64b16
commit 0244c6d6fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 227 additions and 2 deletions

View File

@ -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",
]

View File

@ -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",
]

View File

@ -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",
]

View File

@ -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",
]

View File

@ -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",
]

View File

@ -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",
]

View File

@ -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;

View 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()
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);