Allow configuring the watchdogs in the init config (#2180)
* feat: Allow configuring the watchdogs in the init config * docs: Update changelog * refactor: Remove unnecesary unsafe * feat: Add a config module * test: Add some init tests * style: Rename all ocurrences to esp_hal::config::Config::default() * style: Fix format * fix: Doc errors * revert: Move Config struct to lib.rs * tests: Add default config test * test: Add a test with CpuClock::max() * test: Add timg1 test * feat: Move Config struct to config module and reexport it in lib.rs * fix: Fix init compilation for C2 * revert: Move Config struct to config module and reexport it in lib.rs * fix: Use proper timergroup
This commit is contained in:
parent
370f54119f
commit
3d0a1998fa
@ -13,7 +13,7 @@ You no longer have to set up clocks and pass them to `esp_hal_embassy::init`.
|
||||
prelude::*,
|
||||
- system::SystemControl,
|
||||
};
|
||||
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(_spawner: Spawner) -> ! {
|
||||
- let peripherals = Peripherals::take();
|
||||
|
||||
@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Implement `TryFrom<u32>` for `ledc::timer::config::Duty` (#1984)
|
||||
- Expose `RtcClock::get_xtal_freq` and `RtcClock::get_slow_freq` publically for all chips (#2183)
|
||||
- TWAI support for ESP32-H2 (#2199)
|
||||
- Added a way to configure watchdogs in `esp_hal::init` (#2180)
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ configure an input pin, and pass it to `set_edge_signal` or `set_ctrl_signal`.
|
||||
- PcntInputConfig { pull: Pull::Up },
|
||||
- ));
|
||||
+ ch0.set_ctrl_signal(Input::new(io.pins.gpio4, Pull::Up));
|
||||
|
||||
|
||||
- let mut pin_b = io.pins.gpio5;
|
||||
- ch0.set_edge_signal(PcntSource::from_pin(
|
||||
- &mut pin_b,
|
||||
|
||||
59
esp-hal/src/config.rs
Normal file
59
esp-hal/src/config.rs
Normal file
@ -0,0 +1,59 @@
|
||||
//! # Configuration
|
||||
//!
|
||||
//! ## Overview
|
||||
//! This module contains the initial configuation for the system.
|
||||
//!
|
||||
//! ## Configuration
|
||||
//! In the esp_hal::init method, we can configure different parameters for the
|
||||
//! system:
|
||||
//! - CPU clock configuration.
|
||||
//! - Watchdog configuration.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! ### Default initialization
|
||||
//!
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! ### Custom initialization
|
||||
//! ```rust, no_run
|
||||
#![doc = crate::before_snippet!()]
|
||||
//! let mut config = esp_hal::Config::default();
|
||||
//! config.cpu_clock = CpuClock::max();
|
||||
//! config.watchdog.rwdt =
|
||||
//! esp_hal::config::WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(1000 as u64));
|
||||
//! let peripherals = esp_hal::init(config);
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
/// Watchdog status.
|
||||
#[derive(Default, PartialEq)]
|
||||
pub enum WatchdogStatus {
|
||||
/// Enables a watchdog timer with the specified timeout.
|
||||
Enabled(fugit::MicrosDurationU64),
|
||||
/// Disables the watchdog timer.
|
||||
#[default]
|
||||
Disabled,
|
||||
}
|
||||
|
||||
/// Watchdogs configuration.
|
||||
#[non_exhaustive]
|
||||
#[derive(Default)]
|
||||
pub struct WatchdogConfig {
|
||||
#[cfg(not(any(esp32, esp32s2)))]
|
||||
/// Enable the super watchdog timer, which is slightly less than one second.
|
||||
pub swd: bool,
|
||||
/// Configures the reset watchdog timer.
|
||||
pub rwdt: WatchdogStatus,
|
||||
/// Configures the timg0 watchdog timer.
|
||||
pub timg0: WatchdogStatus,
|
||||
#[cfg(timg1)]
|
||||
/// Configures the timg1 watchdog timer.
|
||||
///
|
||||
/// By default, the bootloader does not enables this watchdog timer.
|
||||
pub timg1: WatchdogStatus,
|
||||
}
|
||||
@ -168,6 +168,9 @@ pub mod analog;
|
||||
pub mod assist_debug;
|
||||
#[cfg(any(dport, hp_sys, pcr, system))]
|
||||
pub mod clock;
|
||||
|
||||
pub mod config;
|
||||
|
||||
#[cfg(any(xtensa, all(riscv, systimer)))]
|
||||
pub mod delay;
|
||||
#[cfg(any(gdma, pdma))]
|
||||
@ -466,6 +469,7 @@ macro_rules! before_snippet {
|
||||
|
||||
use crate::{
|
||||
clock::{Clocks, CpuClock},
|
||||
config::{WatchdogConfig, WatchdogStatus},
|
||||
peripherals::Peripherals,
|
||||
};
|
||||
|
||||
@ -475,24 +479,58 @@ use crate::{
|
||||
pub struct Config {
|
||||
/// The CPU clock configuration.
|
||||
pub cpu_clock: CpuClock,
|
||||
/// Enable watchdog timer(s).
|
||||
pub watchdog: WatchdogConfig,
|
||||
}
|
||||
|
||||
/// Initialize the system.
|
||||
///
|
||||
/// This function sets up the CPU clock and returns the peripherals and clocks.
|
||||
/// This function sets up the CPU clock and watchdog, then, returns the
|
||||
/// peripherals and clocks.
|
||||
pub fn init(config: Config) -> Peripherals {
|
||||
let mut peripherals = Peripherals::take();
|
||||
|
||||
// RTC domain must be enabled before we try to disable
|
||||
let mut rtc = crate::rtc_cntl::Rtc::new(&mut peripherals.LPWR);
|
||||
#[cfg(not(any(esp32, esp32s2)))]
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
unsafe {
|
||||
crate::timer::timg::Wdt::<self::peripherals::TIMG0>::set_wdt_enabled(false);
|
||||
#[cfg(timg1)]
|
||||
crate::timer::timg::Wdt::<self::peripherals::TIMG1>::set_wdt_enabled(false);
|
||||
#[cfg(not(any(esp32, esp32s2)))]
|
||||
if config.watchdog.swd {
|
||||
rtc.swd.enable();
|
||||
} else {
|
||||
rtc.swd.disable();
|
||||
}
|
||||
|
||||
match config.watchdog.rwdt {
|
||||
WatchdogStatus::Enabled(duration) => {
|
||||
rtc.rwdt.enable();
|
||||
rtc.rwdt.set_timeout(duration);
|
||||
}
|
||||
WatchdogStatus::Disabled => {
|
||||
rtc.rwdt.disable();
|
||||
}
|
||||
}
|
||||
|
||||
match config.watchdog.timg0 {
|
||||
WatchdogStatus::Enabled(duration) => {
|
||||
let mut timg0_wd = crate::timer::timg::Wdt::<self::peripherals::TIMG0>::new();
|
||||
timg0_wd.enable();
|
||||
timg0_wd.set_timeout(duration);
|
||||
}
|
||||
WatchdogStatus::Disabled => {
|
||||
crate::timer::timg::Wdt::<self::peripherals::TIMG0>::new().disable();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(timg1)]
|
||||
match config.watchdog.timg1 {
|
||||
WatchdogStatus::Enabled(duration) => {
|
||||
let mut timg1_wd = crate::timer::timg::Wdt::<self::peripherals::TIMG1>::new();
|
||||
timg1_wd.enable();
|
||||
timg1_wd.set_timeout(duration);
|
||||
}
|
||||
WatchdogStatus::Disabled => {
|
||||
crate::timer::timg::Wdt::<self::peripherals::TIMG1>::new().disable();
|
||||
}
|
||||
}
|
||||
|
||||
Clocks::init(config.cpu_clock);
|
||||
|
||||
@ -988,6 +988,11 @@ impl Swd {
|
||||
Self
|
||||
}
|
||||
|
||||
/// Enable the watchdog timer instance
|
||||
pub fn enable(&mut self) {
|
||||
self.set_enabled(true);
|
||||
}
|
||||
|
||||
/// Disable the watchdog timer instance
|
||||
pub fn disable(&mut self) {
|
||||
self.set_enabled(false);
|
||||
|
||||
@ -15,7 +15,7 @@ You no longer have to set up clocks and pass them to `esp_wifi::initialize`.
|
||||
initialize,
|
||||
// ...
|
||||
};
|
||||
|
||||
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
- let peripherals = Peripherals::take();
|
||||
@ -65,7 +65,7 @@ The size of the heap depends on what you are going to use esp-wifi for and if yo
|
||||
|
||||
E.g. when using `coex` you need around 92k. If not using `coex`, going lower than 72k you will observe some failed allocations but it might still work. Going even lower will make things fail.
|
||||
|
||||
If you see linker errors regarding undefined symbols for `esp_wifi_free_internal_heap` and `esp_wifi_allocate_from_internal_ram` you either want to opt-in to use the `esp-alloc` feature
|
||||
If you see linker errors regarding undefined symbols for `esp_wifi_free_internal_heap` and `esp_wifi_allocate_from_internal_ram` you either want to opt-in to use the `esp-alloc` feature
|
||||
or provide your own allocator (see below)
|
||||
|
||||
### Using your own allocator
|
||||
|
||||
@ -55,6 +55,10 @@ harness = false
|
||||
name = "i2c"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "init"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "i2s"
|
||||
harness = false
|
||||
|
||||
110
hil-test/tests/init.rs
Normal file
110
hil-test/tests/init.rs
Normal file
@ -0,0 +1,110 @@
|
||||
//! Initialization tests
|
||||
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp_hal::{
|
||||
config::WatchdogStatus,
|
||||
delay::Delay,
|
||||
prelude::*,
|
||||
rtc_cntl::Rtc,
|
||||
timer::timg::TimerGroup,
|
||||
Config,
|
||||
};
|
||||
use hil_test as _;
|
||||
|
||||
#[cfg(test)]
|
||||
#[embedded_test::tests]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn test_feeding_timg0_wdt() {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = Config::default();
|
||||
config.watchdog.timg0 =
|
||||
WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(500 as u64));
|
||||
config
|
||||
});
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let mut wdt0 = timg0.wdt;
|
||||
let delay = Delay::new();
|
||||
|
||||
for _ in 0..4 {
|
||||
wdt0.feed();
|
||||
delay.delay(250.millis());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
#[cfg(timg1)]
|
||||
fn test_feeding_timg1_wdt() {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = Config::default();
|
||||
config.watchdog.timg1 =
|
||||
WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(500 as u64));
|
||||
config
|
||||
});
|
||||
|
||||
let timg1 = TimerGroup::new(peripherals.TIMG1);
|
||||
let mut wdt1 = timg1.wdt;
|
||||
let delay = Delay::new();
|
||||
|
||||
for _ in 0..4 {
|
||||
wdt1.feed();
|
||||
delay.delay(250.millis());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn test_feeding_timg0_wdt_max_clock() {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = Config::default();
|
||||
config.cpu_clock = CpuClock::max();
|
||||
config.watchdog.timg0 =
|
||||
WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(500 as u64));
|
||||
config
|
||||
});
|
||||
|
||||
let timg0 = TimerGroup::new(peripherals.TIMG0);
|
||||
let mut wdt0 = timg0.wdt;
|
||||
let delay = Delay::new();
|
||||
|
||||
for _ in 0..4 {
|
||||
wdt0.feed();
|
||||
delay.delay(250.millis());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(4)]
|
||||
fn test_feeding_rtc_wdt() {
|
||||
let peripherals = esp_hal::init({
|
||||
let mut config = Config::default();
|
||||
config.watchdog.rwdt =
|
||||
WatchdogStatus::Enabled(fugit::MicrosDurationU64::millis(3000 as u64));
|
||||
config
|
||||
});
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.LPWR);
|
||||
let delay = Delay::new();
|
||||
|
||||
rtc.rwdt.feed();
|
||||
delay.delay(2500.millis());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[timeout(3)]
|
||||
fn test_default_config() {
|
||||
esp_hal::init(Config::default());
|
||||
|
||||
let delay = Delay::new();
|
||||
delay.delay(2000.millis());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user