Skip to content

Commit

Permalink
C6: Small updates in wdt (#1)
Browse files Browse the repository at this point in the history
* C6: Update WDT

* C6: Update examples with WDT update
  • Loading branch information
JurajSadel authored and jessebraham committed Feb 10, 2023
1 parent 43cf457 commit 0ada84c
Show file tree
Hide file tree
Showing 28 changed files with 219 additions and 250 deletions.
178 changes: 42 additions & 136 deletions esp-hal-common/src/rtc_cntl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use embedded_hal::watchdog::{Watchdog, WatchdogDisable, WatchdogEnable};
use fugit::{HertzU32, MicrosDurationU64};

use self::rtc::SocResetReason;
#[cfg(not(any(esp32, esp32c6)))]
#[cfg(not(any(esp32)))]
use crate::efuse::Efuse;
#[cfg(esp32c6)]
use crate::peripherals::{LP_AON, LP_CLKRST, LP_WDT, PMU};
Expand Down Expand Up @@ -609,11 +609,14 @@ impl Default for Rwdt {
}
}

#[cfg(not(esp32c6))]
/// RTC Watchdog Timer driver
impl Rwdt {
pub fn listen(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.stg0_action = RwdtStageAction::RwdtStageActionInterrupt;

Expand All @@ -635,7 +638,11 @@ impl Rwdt {
}

pub fn unlisten(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.stg0_action = RwdtStageAction::RwdtStageActionResetRtc;

Expand All @@ -657,7 +664,11 @@ impl Rwdt {
}

pub fn clear_interrupt(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.set_write_protection(false);

Expand All @@ -670,7 +681,11 @@ impl Rwdt {
}

pub fn is_interrupt_set(&self) -> bool {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

cfg_if::cfg_if! {
if #[cfg(esp32)] {
Expand All @@ -683,17 +698,24 @@ impl Rwdt {

/// Enable/disable write protection for WDT registers
fn set_write_protection(&mut self, enable: bool) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };
let wkey = if enable { 0u32 } else { 0x50D8_3AA1 };

rtc_cntl.wdtwprotect.write(|w| unsafe { w.bits(wkey) });
}
}

#[cfg(not(esp32c6))]
impl WatchdogDisable for Rwdt {
fn disable(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.set_write_protection(false);

Expand All @@ -713,9 +735,11 @@ impl WatchdogEnable for Rwdt {
where
T: Into<Self::Time>,
{
#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };
let timeout_raw = (period.into().to_millis() * (RtcClock::cycles_to_1ms() as u64)) as u32;

self.set_write_protection(false);

unsafe {
Expand Down Expand Up @@ -752,119 +776,25 @@ impl WatchdogEnable for Rwdt {
}
}

#[cfg(not(esp32c6))]
impl Watchdog for Rwdt {
fn feed(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.set_write_protection(false);
rtc_cntl.wdtfeed.write(|w| unsafe { w.bits(1) });
self.set_write_protection(true);
}
}

#[cfg(esp32c6)]
/// RTC Watchdog Timer driver
impl Rwdt {
pub fn listen(&mut self) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };

self.stg0_action = RwdtStageAction::RwdtStageActionInterrupt;

self.set_write_protection(false);

// Configure STAGE0 to trigger an interrupt upon expiration
rtc_cntl
.config0
.modify(|_, w| unsafe { w.wdt_stg0().bits(self.stg0_action as u8) });

rtc_cntl.int_ena.modify(|_, w| w.lp_wdt_int_ena().set_bit());

self.set_write_protection(true);
}

pub fn unlisten(&mut self) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };

self.stg0_action = RwdtStageAction::RwdtStageActionResetRtc;

self.set_write_protection(false);

// Configure STAGE0 to reset the main system and the RTC upon expiration.
rtc_cntl
.config0
.modify(|_, w| unsafe { w.wdt_stg0().bits(self.stg0_action as u8) });

rtc_cntl
.int_ena
.modify(|_, w| w.lp_wdt_int_ena().clear_bit());

self.set_write_protection(true);
}

pub fn clear_interrupt(&mut self) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };

self.set_write_protection(false);

rtc_cntl.int_clr.write(|w| w.lp_wdt_int_clr().set_bit());

self.set_write_protection(true);
}

pub fn is_interrupt_set(&self) -> bool {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };
rtc_cntl.int_st.read().lp_wdt_int_st().bit_is_set()
}

/// Enable/disable write protection for WDT registers
fn set_write_protection(&mut self, enable: bool) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };
let wkey = if enable { 0u32 } else { 0x50D8_3AA1 };

rtc_cntl.wprotect.write(|w| unsafe { w.bits(wkey) });
}
}

#[cfg(esp32c6)]
impl WatchdogDisable for Rwdt {
fn disable(&mut self) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };

self.set_write_protection(false);

rtc_cntl
.config0
.modify(|_, w| w.wdt_en().clear_bit().wdt_flashboot_mod_en().clear_bit());

self.set_write_protection(true);
}
}

#[cfg(esp32c6)]
impl WatchdogEnable for Rwdt {
type Time = MicrosDurationU64;

fn start<T>(&mut self, period: T)
where
T: Into<Self::Time>,
{
todo!()
}
}

#[cfg(esp32c6)]
impl Watchdog for Rwdt {
fn feed(&mut self) {
todo!()
}
}

#[cfg(any(esp32c2, esp32c3, esp32c6, esp32s3))]
/// Super Watchdog
pub struct Swd;

#[cfg(any(esp32c2, esp32c3, esp32s3))]
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32s3))]
/// Super Watchdog driver
impl Swd {
pub fn new() -> Self {
Expand All @@ -873,7 +803,11 @@ impl Swd {

/// Enable/disable write protection for WDT registers
fn set_write_protection(&mut self, enable: bool) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };
let wkey = if enable { 0u32 } else { 0x8F1D_312A };

rtc_cntl
Expand All @@ -882,49 +816,21 @@ impl Swd {
}
}

#[cfg(any(esp32c2, esp32c3, esp32s3))]
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32s3))]
impl WatchdogDisable for Swd {
fn disable(&mut self) {

#[cfg(not(esp32c6))]
let rtc_cntl = unsafe { &*RTC_CNTL::PTR };
#[cfg(esp32c6)]
let rtc_cntl = unsafe { &*LP_WDT::PTR };

self.set_write_protection(false);
rtc_cntl.swd_conf.write(|w| w.swd_auto_feed_en().set_bit());
self.set_write_protection(true);
}
}

#[cfg(esp32c6)]
impl Swd {
pub fn new() -> Self {
Self
}

/// Enable/disable write protection for WDT registers
fn set_write_protection(&mut self, enable: bool) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };
let wkey = if enable { 0u32 } else { 0x50D8_3AA1 };

rtc_cntl
.swd_wprotect
.write(|w| unsafe { w.swd_wkey().bits(wkey) });
}
}

#[cfg(esp32c6)]
impl WatchdogDisable for Swd {
fn disable(&mut self) {
let rtc_cntl = unsafe { &*LP_WDT::ptr() };

self.set_write_protection(false);

rtc_cntl
.swd_config
.write(|w| w.swd_auto_feed_en().set_bit());

self.set_write_protection(true);
}
}

pub fn get_reset_reason(cpu: Cpu) -> Option<SocResetReason> {
let reason = unsafe { rtc_get_reset_reason(cpu as u32) };
let reason = SocResetReason::from_repr(reason as usize);
Expand Down
16 changes: 16 additions & 0 deletions esp-hal-common/src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,11 +566,27 @@ where
{
/// Create a new watchdog timer instance
pub fn new() -> Self {
#[cfg(esp32c6)]
Self::enable_clock();
Self {
phantom: PhantomData::default(),
}
}

#[cfg(esp32c6)]
fn enable_clock() {
let pcr = unsafe { &*crate::peripherals::PCR::ptr() };
pcr.timergroup0_wdt_clk_conf
.write(|w| w.tg0_wdt_clk_en().set_bit());
pcr.timergroup0_wdt_clk_conf
.write(|w| unsafe { w.tg0_wdt_clk_sel().bits(1) });

pcr.timergroup1_timer_clk_conf
.write(|w| w.tg1_timer_clk_en().set_bit());
pcr.timergroup1_timer_clk_conf
.write(|w| unsafe { w.tg1_timer_clk_sel().bits(1) });
}

fn set_wdt_enabled(&mut self, enabled: bool) {
let reg_block = unsafe { &*TG::register_block() };

Expand Down
11 changes: 6 additions & 5 deletions esp32c6-hal/examples/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ fn main() -> ! {

// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let _wdt0 = timer_group0.wdt;
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let _wdt1 = timer_group1.wdt;
let mut wdt1 = timer_group1.wdt;

// Disable MWDT and RWDT (Watchdog) flash boot protection
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
rtc.rwdt.disable();
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();

let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);

Expand Down
9 changes: 6 additions & 3 deletions esp32c6-hal/examples/advanced_serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,19 @@ fn main() -> ! {
let system = peripherals.PCR.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut timer0 = timer_group0.timer0;
let _wdt0 = timer_group0.wdt;
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let _wdt1 = timer_group1.wdt;
let mut wdt1 = timer_group1.wdt;

// Disable watchdog timers
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();

let config = Config {
baudrate: 115200,
Expand Down
14 changes: 8 additions & 6 deletions esp32c6-hal/examples/aes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ fn main() -> ! {

// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
// Disable the watchdog timers. For the ESP32-C6, this includes the Super WDT,
// and the TIMG WDTs.
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let _wdt0 = timer_group0.wdt;
let mut wdt0 = timer_group0.wdt;
let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks);
let _wdt1 = timer_group1.wdt;
let mut wdt1 = timer_group1.wdt;

let mut rtc = Rtc::new(peripherals.LP_CLKRST);

// Disable MWDT and RWDT (Watchdog) flash boot protection
rtc.rwdt.disable();
rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();
wdt1.disable();

let mut aes = Aes::new(peripherals.AES, &mut system.peripheral_clock_control);

Expand Down
Loading

0 comments on commit 0ada84c

Please sign in to comment.