Skip to content

Commit 8c64b09

Browse files
authored
Allow configuring longer WDT periods (#3816)
* Clean up with new PAC * Allow configuring longer WDT periods * Enable WDT after updating timeout
1 parent 422f232 commit 8c64b09

22 files changed

+144
-170
lines changed

esp-hal/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
### Fixed
1818

1919
- PSRAM on ESP32-S2 (#3811)
20+
- WDT now allows configuring longer timeouts (#3816)
2021

2122
### Removed
2223

esp-hal/Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ ufmt-write = { version = "0.1.0", optional = true }
7373
# IMPORTANT:
7474
# Each supported device MUST have its PAC included below along with a
7575
# corresponding feature.
76-
esp32 = { version = "0.38.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
77-
esp32c2 = { version = "0.27.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
78-
esp32c3 = { version = "0.30.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
79-
esp32c6 = { version = "0.21.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
80-
esp32h2 = { version = "0.17.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
81-
esp32s2 = { version = "0.29.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
82-
esp32s3 = { version = "0.33.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "5eae169" }
76+
esp32 = { version = "0.38.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
77+
esp32c2 = { version = "0.27.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
78+
esp32c3 = { version = "0.30.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
79+
esp32c6 = { version = "0.21.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
80+
esp32h2 = { version = "0.17.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
81+
esp32s2 = { version = "0.29.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
82+
esp32s3 = { version = "0.33.0", features = ["critical-section", "rt"], optional = true, git = "https://github.com/esp-rs/esp-pacs", rev = "7232b3e" }
8383

8484
[target.'cfg(target_arch = "riscv32")'.dependencies]
8585
riscv = { version = "0.12.1" }

esp-hal/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,8 @@ pub fn init(config: Config) -> Peripherals {
649649

650650
match config.watchdog.rwdt() {
651651
WatchdogStatus::Enabled(duration) => {
652+
rtc.rwdt.set_timeout(crate::rtc_cntl::RwdtStage::Stage0, duration);
652653
rtc.rwdt.enable();
653-
rtc.rwdt
654-
.set_timeout(crate::rtc_cntl::RwdtStage::Stage0, duration);
655654
}
656655
WatchdogStatus::Disabled => {
657656
rtc.rwdt.disable();
@@ -662,8 +661,8 @@ pub fn init(config: Config) -> Peripherals {
662661
match config.watchdog.timg0() {
663662
WatchdogStatus::Enabled(duration) => {
664663
let mut timg0_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new();
665-
timg0_wd.enable();
666664
timg0_wd.set_timeout(crate::timer::timg::MwdtStage::Stage0, duration);
665+
timg0_wd.enable();
667666
}
668667
WatchdogStatus::Disabled => {
669668
crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new().disable();
@@ -674,8 +673,8 @@ pub fn init(config: Config) -> Peripherals {
674673
match config.watchdog.timg1() {
675674
WatchdogStatus::Enabled(duration) => {
676675
let mut timg1_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new();
677-
timg1_wd.enable();
678676
timg1_wd.set_timeout(crate::timer::timg::MwdtStage::Stage0, duration);
677+
timg1_wd.enable();
679678
}
680679
WatchdogStatus::Disabled => {
681680
crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new().disable();

esp-hal/src/rtc_cntl/mod.rs

Lines changed: 39 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -562,27 +562,25 @@ impl RtcClock {
562562
let rtc_cntl = LPWR::regs();
563563

564564
if clk_8m_en {
565+
// clk_ll_rc_fast_enable
565566
rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().clear_bit());
566-
unsafe {
567-
rtc_cntl.timer1().modify(|_, w| w.ck8m_wait().bits(5));
568-
}
567+
568+
rtc_cntl
569+
.timer1()
570+
.modify(|_, w| unsafe { w.ck8m_wait().bits(5) });
571+
569572
crate::rom::ets_delay_us(50);
570573
} else {
574+
// clk_ll_rc_fast_disable
571575
rtc_cntl.clk_conf().modify(|_, w| w.enb_ck8m().set_bit());
572576
rtc_cntl
573577
.timer1()
574578
.modify(|_, w| unsafe { w.ck8m_wait().bits(20) });
575579
}
576580

577-
if d256_en {
578-
rtc_cntl
579-
.clk_conf()
580-
.modify(|_, w| w.enb_ck8m_div().clear_bit());
581-
} else {
582-
rtc_cntl
583-
.clk_conf()
584-
.modify(|_, w| w.enb_ck8m_div().set_bit());
585-
}
581+
rtc_cntl
582+
.clk_conf()
583+
.modify(|_, w| w.enb_ck8m_div().bit(!d256_en));
586584
}
587585

588586
pub(crate) fn read_xtal_freq_mhz() -> Option<u32> {
@@ -726,12 +724,9 @@ impl RtcClock {
726724

727725
// Prepare calibration
728726
timg0.rtccalicfg().modify(|_, w| unsafe {
729-
w.rtc_cali_clk_sel()
730-
.bits(cal_clk as u8)
731-
.rtc_cali_start_cycling()
732-
.clear_bit()
733-
.rtc_cali_max()
734-
.bits(slowclk_cycles as u16)
727+
w.rtc_cali_clk_sel().bits(cal_clk as u8);
728+
w.rtc_cali_start_cycling().clear_bit();
729+
w.rtc_cali_max().bits(slowclk_cycles as u16)
735730
});
736731

737732
// Figure out how long to wait for calibration to finish
@@ -1027,20 +1022,13 @@ impl Rwdt {
10271022
// Apply default settings for WDT
10281023
unsafe {
10291024
rtc_cntl.wdtconfig0().modify(|_, w| {
1030-
w.wdt_stg0()
1031-
.bits(RwdtStageAction::ResetSystem as u8)
1032-
.wdt_cpu_reset_length()
1033-
.bits(7)
1034-
.wdt_sys_reset_length()
1035-
.bits(7)
1036-
.wdt_stg1()
1037-
.bits(RwdtStageAction::Off as u8)
1038-
.wdt_stg2()
1039-
.bits(RwdtStageAction::Off as u8)
1040-
.wdt_stg3()
1041-
.bits(RwdtStageAction::Off as u8)
1042-
.wdt_en()
1043-
.set_bit()
1025+
w.wdt_stg0().bits(RwdtStageAction::ResetSystem as u8);
1026+
w.wdt_cpu_reset_length().bits(7);
1027+
w.wdt_sys_reset_length().bits(7);
1028+
w.wdt_stg1().bits(RwdtStageAction::Off as u8);
1029+
w.wdt_stg2().bits(RwdtStageAction::Off as u8);
1030+
w.wdt_stg3().bits(RwdtStageAction::Off as u8);
1031+
w.wdt_en().set_bit()
10441032
});
10451033
}
10461034
}
@@ -1055,63 +1043,17 @@ impl Rwdt {
10551043
let timeout_raw = (timeout.as_millis() * (RtcClock::cycles_to_1ms() as u64)) as u32;
10561044
self.set_write_protection(false);
10571045

1058-
unsafe {
1059-
#[cfg(esp32)]
1060-
match stage {
1061-
RwdtStage::Stage0 => rtc_cntl
1062-
.wdtconfig1()
1063-
.modify(|_, w| w.wdt_stg0_hold().bits(timeout_raw)),
1064-
RwdtStage::Stage1 => rtc_cntl
1065-
.wdtconfig2()
1066-
.modify(|_, w| w.wdt_stg1_hold().bits(timeout_raw)),
1067-
RwdtStage::Stage2 => rtc_cntl
1068-
.wdtconfig3()
1069-
.modify(|_, w| w.wdt_stg2_hold().bits(timeout_raw)),
1070-
RwdtStage::Stage3 => rtc_cntl
1071-
.wdtconfig4()
1072-
.modify(|_, w| w.wdt_stg3_hold().bits(timeout_raw)),
1073-
};
1074-
1075-
#[cfg(any(esp32c6, esp32h2))]
1076-
match stage {
1077-
RwdtStage::Stage0 => rtc_cntl.config1().modify(|_, w| {
1078-
w.wdt_stg0_hold()
1079-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1080-
}),
1081-
RwdtStage::Stage1 => rtc_cntl.config2().modify(|_, w| {
1082-
w.wdt_stg1_hold()
1083-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1084-
}),
1085-
RwdtStage::Stage2 => rtc_cntl.config3().modify(|_, w| {
1086-
w.wdt_stg2_hold()
1087-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1088-
}),
1089-
RwdtStage::Stage3 => rtc_cntl.config4().modify(|_, w| {
1090-
w.wdt_stg3_hold()
1091-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1092-
}),
1093-
};
1094-
1095-
#[cfg(not(any(esp32, esp32c6, esp32h2)))]
1096-
match stage {
1097-
RwdtStage::Stage0 => rtc_cntl.wdtconfig1().modify(|_, w| {
1098-
w.wdt_stg0_hold()
1099-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1100-
}),
1101-
RwdtStage::Stage1 => rtc_cntl.wdtconfig2().modify(|_, w| {
1102-
w.wdt_stg1_hold()
1103-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1104-
}),
1105-
RwdtStage::Stage2 => rtc_cntl.wdtconfig3().modify(|_, w| {
1106-
w.wdt_stg2_hold()
1107-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1108-
}),
1109-
RwdtStage::Stage3 => rtc_cntl.wdtconfig4().modify(|_, w| {
1110-
w.wdt_stg3_hold()
1111-
.bits(timeout_raw >> (1 + Efuse::rwdt_multiplier()))
1112-
}),
1113-
};
1114-
}
1046+
let config_reg = match stage {
1047+
RwdtStage::Stage0 => rtc_cntl.wdtconfig1(),
1048+
RwdtStage::Stage1 => rtc_cntl.wdtconfig2(),
1049+
RwdtStage::Stage2 => rtc_cntl.wdtconfig3(),
1050+
RwdtStage::Stage3 => rtc_cntl.wdtconfig4(),
1051+
};
1052+
1053+
#[cfg(not(esp32))]
1054+
let timeout_raw = timeout_raw >> (1 + Efuse::rwdt_multiplier());
1055+
1056+
config_reg.modify(|_, w| unsafe { w.hold().bits(timeout_raw) });
11151057

11161058
self.set_write_protection(true);
11171059
}
@@ -1121,21 +1063,14 @@ impl Rwdt {
11211063
let rtc_cntl = LP_WDT::regs();
11221064

11231065
self.set_write_protection(false);
1124-
1125-
match stage {
1126-
RwdtStage::Stage0 => rtc_cntl
1127-
.wdtconfig0()
1128-
.modify(|_, w| unsafe { w.wdt_stg0().bits(action as u8) }),
1129-
RwdtStage::Stage1 => rtc_cntl
1130-
.wdtconfig0()
1131-
.modify(|_, w| unsafe { w.wdt_stg1().bits(action as u8) }),
1132-
RwdtStage::Stage2 => rtc_cntl
1133-
.wdtconfig0()
1134-
.modify(|_, w| unsafe { w.wdt_stg2().bits(action as u8) }),
1135-
RwdtStage::Stage3 => rtc_cntl
1136-
.wdtconfig0()
1137-
.modify(|_, w| unsafe { w.wdt_stg3().bits(action as u8) }),
1138-
};
1066+
rtc_cntl.wdtconfig0().modify(|_, w| unsafe {
1067+
match stage {
1068+
RwdtStage::Stage0 => w.wdt_stg0().bits(action as u8),
1069+
RwdtStage::Stage1 => w.wdt_stg1().bits(action as u8),
1070+
RwdtStage::Stage2 => w.wdt_stg2().bits(action as u8),
1071+
RwdtStage::Stage3 => w.wdt_stg3().bits(action as u8),
1072+
}
1073+
});
11391074

11401075
self.set_write_protection(true);
11411076
}

esp-hal/src/timer/timg.rs

Lines changed: 41 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -685,20 +685,13 @@ where
685685

686686
#[cfg_attr(esp32, allow(unused_unsafe))]
687687
reg_block.wdtconfig0().write(|w| unsafe {
688-
w.wdt_en()
689-
.bit(true)
690-
.wdt_stg0()
691-
.bits(MwdtStageAction::ResetSystem as u8)
692-
.wdt_cpu_reset_length()
693-
.bits(7)
694-
.wdt_sys_reset_length()
695-
.bits(7)
696-
.wdt_stg1()
697-
.bits(MwdtStageAction::Off as u8)
698-
.wdt_stg2()
699-
.bits(MwdtStageAction::Off as u8)
700-
.wdt_stg3()
701-
.bits(MwdtStageAction::Off as u8)
688+
w.wdt_en().bit(true);
689+
w.wdt_stg0().bits(MwdtStageAction::ResetSystem as u8);
690+
w.wdt_cpu_reset_length().bits(7);
691+
w.wdt_sys_reset_length().bits(7);
692+
w.wdt_stg1().bits(MwdtStageAction::Off as u8);
693+
w.wdt_stg2().bits(MwdtStageAction::Off as u8);
694+
w.wdt_stg3().bits(MwdtStageAction::Off as u8)
702695
});
703696

704697
#[cfg(any(esp32c2, esp32c3, esp32c6))]
@@ -733,32 +726,39 @@ where
733726

734727
/// Set the timeout, in microseconds, of the watchdog timer
735728
pub fn set_timeout(&mut self, stage: MwdtStage, timeout: Duration) {
736-
let timeout_raw = (timeout.as_micros() * 10_000 / 125) as u32;
729+
// Assume default 80MHz clock source
730+
let timeout_ticks = timeout.as_micros() * 10_000 / 125;
737731

738732
let reg_block = unsafe { &*TG::register_block() };
739733

734+
let (prescaler, timeout) = if timeout_ticks > u32::MAX as u64 {
735+
let prescaler = timeout_ticks
736+
.div_ceil(u32::MAX as u64 + 1)
737+
.min(u16::MAX as u64) as u16;
738+
let timeout = timeout_ticks
739+
.div_ceil(prescaler as u64)
740+
.min(u32::MAX as u64);
741+
(prescaler, timeout as u32)
742+
} else {
743+
(1, timeout_ticks as u32)
744+
};
745+
740746
self.set_write_protection(false);
741747

742-
reg_block
743-
.wdtconfig1()
744-
.write(|w| unsafe { w.wdt_clk_prescale().bits(1) });
748+
reg_block.wdtconfig1().write(|w| unsafe {
749+
#[cfg(timergroup_timg_has_divcnt_rst)]
750+
w.wdt_divcnt_rst().set_bit();
751+
w.wdt_clk_prescale().bits(prescaler)
752+
});
745753

746-
unsafe {
747-
match stage {
748-
MwdtStage::Stage0 => reg_block
749-
.wdtconfig2()
750-
.write(|w| w.wdt_stg0_hold().bits(timeout_raw)),
751-
MwdtStage::Stage1 => reg_block
752-
.wdtconfig3()
753-
.write(|w| w.wdt_stg1_hold().bits(timeout_raw)),
754-
MwdtStage::Stage2 => reg_block
755-
.wdtconfig4()
756-
.write(|w| w.wdt_stg2_hold().bits(timeout_raw)),
757-
MwdtStage::Stage3 => reg_block
758-
.wdtconfig5()
759-
.write(|w| w.wdt_stg3_hold().bits(timeout_raw)),
760-
};
761-
}
754+
let config_register = match stage {
755+
MwdtStage::Stage0 => reg_block.wdtconfig2(),
756+
MwdtStage::Stage1 => reg_block.wdtconfig3(),
757+
MwdtStage::Stage2 => reg_block.wdtconfig4(),
758+
MwdtStage::Stage3 => reg_block.wdtconfig5(),
759+
};
760+
761+
config_register.write(|w| unsafe { w.hold().bits(timeout) });
762762

763763
#[cfg(any(esp32c2, esp32c3, esp32c6))]
764764
reg_block
@@ -779,28 +779,14 @@ where
779779

780780
self.set_write_protection(false);
781781

782-
match stage {
783-
MwdtStage::Stage0 => {
784-
reg_block
785-
.wdtconfig0()
786-
.modify(|_, w| unsafe { w.wdt_stg0().bits(action as u8) });
787-
}
788-
MwdtStage::Stage1 => {
789-
reg_block
790-
.wdtconfig0()
791-
.modify(|_, w| unsafe { w.wdt_stg1().bits(action as u8) });
792-
}
793-
MwdtStage::Stage2 => {
794-
reg_block
795-
.wdtconfig0()
796-
.modify(|_, w| unsafe { w.wdt_stg2().bits(action as u8) });
797-
}
798-
MwdtStage::Stage3 => {
799-
reg_block
800-
.wdtconfig0()
801-
.modify(|_, w| unsafe { w.wdt_stg3().bits(action as u8) });
782+
reg_block.wdtconfig0().modify(|_, w| unsafe {
783+
match stage {
784+
MwdtStage::Stage0 => w.wdt_stg0().bits(action as u8),
785+
MwdtStage::Stage1 => w.wdt_stg1().bits(action as u8),
786+
MwdtStage::Stage2 => w.wdt_stg2().bits(action as u8),
787+
MwdtStage::Stage3 => w.wdt_stg3().bits(action as u8),
802788
}
803-
}
789+
});
804790

805791
self.set_write_protection(true);
806792
}

0 commit comments

Comments
 (0)