mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-28 12:50:37 +00:00
Merge pull request #4119 from 0e4ef622/nrf53-wdt
nrf53: add WDT support
This commit is contained in:
commit
fb5ce05b26
1
ci.sh
1
ci.sh
@ -188,6 +188,7 @@ cargo batch \
|
|||||||
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \
|
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \
|
||||||
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \
|
--- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \
|
||||||
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \
|
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \
|
||||||
|
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf5340-app-s \
|
||||||
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \
|
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \
|
||||||
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns \
|
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns \
|
||||||
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9151-ns \
|
--- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9151-ns \
|
||||||
|
@ -8,7 +8,6 @@ pub use embassy_boot::{
|
|||||||
FirmwareUpdater, FirmwareUpdaterConfig,
|
FirmwareUpdater, FirmwareUpdaterConfig,
|
||||||
};
|
};
|
||||||
use embassy_nrf::nvmc::PAGE_SIZE;
|
use embassy_nrf::nvmc::PAGE_SIZE;
|
||||||
use embassy_nrf::peripherals::WDT;
|
|
||||||
use embassy_nrf::{wdt, Peri};
|
use embassy_nrf::{wdt, Peri};
|
||||||
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
|
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
|
||||||
|
|
||||||
@ -113,7 +112,7 @@ pub struct WatchdogFlash<FLASH> {
|
|||||||
|
|
||||||
impl<FLASH> WatchdogFlash<FLASH> {
|
impl<FLASH> WatchdogFlash<FLASH> {
|
||||||
/// Start a new watchdog with a given flash and WDT peripheral and a timeout
|
/// Start a new watchdog with a given flash and WDT peripheral and a timeout
|
||||||
pub fn start(flash: FLASH, wdt: Peri<'static, WDT>, config: wdt::Config) -> Self {
|
pub fn start(flash: FLASH, wdt: Peri<'static, impl wdt::Instance>, config: wdt::Config) -> Self {
|
||||||
let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) {
|
let (_wdt, [wdt]) = match wdt::Watchdog::try_new(wdt, config) {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -109,7 +109,7 @@ nrf9161-ns = ["nrf9120-ns"]
|
|||||||
# Features starting with `_` are for internal use only. They're not intended
|
# Features starting with `_` are for internal use only. They're not intended
|
||||||
# to be enabled by other crates, and are not covered by semver guarantees.
|
# to be enabled by other crates, and are not covered by semver guarantees.
|
||||||
|
|
||||||
_nrf5340-app = ["_nrf5340", "nrf-pac/nrf5340-app"]
|
_nrf5340-app = ["_nrf5340", "_multi_wdt", "nrf-pac/nrf5340-app"]
|
||||||
_nrf5340-net = ["_nrf5340", "nrf-pac/nrf5340-net"]
|
_nrf5340-net = ["_nrf5340", "nrf-pac/nrf5340-net"]
|
||||||
_nrf5340 = ["_gpio-p1", "_dppi"]
|
_nrf5340 = ["_gpio-p1", "_dppi"]
|
||||||
_nrf54l15-app = ["_nrf54l15", "nrf-pac/nrf54l15-app"]
|
_nrf54l15-app = ["_nrf54l15", "nrf-pac/nrf54l15-app"]
|
||||||
@ -136,6 +136,9 @@ _gpio-p2 = []
|
|||||||
# Errata workarounds
|
# Errata workarounds
|
||||||
_nrf52832_anomaly_109 = []
|
_nrf52832_anomaly_109 = []
|
||||||
|
|
||||||
|
# watchdog timer
|
||||||
|
_multi_wdt = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embassy-time-driver = { version = "0.2", path = "../embassy-time-driver", optional = true }
|
embassy-time-driver = { version = "0.2", path = "../embassy-time-driver", optional = true }
|
||||||
embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true }
|
embassy-time-queue-utils = { version = "0.1", path = "../embassy-time-queue-utils", optional = true }
|
||||||
|
@ -145,6 +145,8 @@ impl_pin!(P0_31, 0, 31);
|
|||||||
|
|
||||||
impl_radio!(RADIO, RADIO, RADIO);
|
impl_radio!(RADIO, RADIO, RADIO);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -221,6 +221,8 @@ impl_radio!(RADIO, RADIO, RADIO);
|
|||||||
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
||||||
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -247,6 +247,8 @@ impl_radio!(RADIO, RADIO, RADIO);
|
|||||||
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
||||||
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -249,6 +249,8 @@ impl_radio!(RADIO, RADIO, RADIO);
|
|||||||
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
impl_egu!(EGU0, EGU0, EGU0_SWI0);
|
||||||
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
impl_egu!(EGU1, EGU1, EGU1_SWI1);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -244,6 +244,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -287,6 +287,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -329,6 +329,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -334,6 +334,8 @@ impl_egu!(EGU3, EGU3, EGU3_SWI3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
impl_egu!(EGU4, EGU4, EGU4_SWI4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
impl_egu!(EGU5, EGU5, EGU5_SWI5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -171,7 +171,8 @@ embassy_hal_internal::peripherals! {
|
|||||||
RTC1,
|
RTC1,
|
||||||
|
|
||||||
// WDT
|
// WDT
|
||||||
WDT,
|
WDT0,
|
||||||
|
WDT1,
|
||||||
|
|
||||||
// NVMC
|
// NVMC
|
||||||
NVMC,
|
NVMC,
|
||||||
@ -473,6 +474,9 @@ impl_egu!(EGU3, EGU3, EGU3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4);
|
impl_egu!(EGU4, EGU4, EGU4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5);
|
impl_egu!(EGU5, EGU5, EGU5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT0, WDT0, WDT0, 0);
|
||||||
|
impl_wdt!(WDT1, WDT1, WDT1, 1);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
FPU,
|
FPU,
|
||||||
CACHE,
|
CACHE,
|
||||||
|
@ -299,6 +299,8 @@ impl_radio!(RADIO, RADIO, RADIO);
|
|||||||
|
|
||||||
impl_egu!(EGU0, EGU0, EGU0);
|
impl_egu!(EGU0, EGU0, EGU0);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
RADIO,
|
RADIO,
|
||||||
|
@ -342,6 +342,8 @@ impl_egu!(EGU3, EGU3, EGU3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4);
|
impl_egu!(EGU4, EGU4, EGU4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5);
|
impl_egu!(EGU5, EGU5, EGU5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
SPU,
|
SPU,
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
|
@ -342,6 +342,8 @@ impl_egu!(EGU3, EGU3, EGU3);
|
|||||||
impl_egu!(EGU4, EGU4, EGU4);
|
impl_egu!(EGU4, EGU4, EGU4);
|
||||||
impl_egu!(EGU5, EGU5, EGU5);
|
impl_egu!(EGU5, EGU5, EGU5);
|
||||||
|
|
||||||
|
impl_wdt!(WDT, WDT, WDT, 0);
|
||||||
|
|
||||||
embassy_hal_internal::interrupt_mod!(
|
embassy_hal_internal::interrupt_mod!(
|
||||||
SPU,
|
SPU,
|
||||||
CLOCK_POWER,
|
CLOCK_POWER,
|
||||||
|
@ -169,7 +169,6 @@ pub mod uarte;
|
|||||||
))]
|
))]
|
||||||
pub mod usb;
|
pub mod usb;
|
||||||
#[cfg(not(feature = "_nrf54l"))] // TODO
|
#[cfg(not(feature = "_nrf54l"))] // TODO
|
||||||
#[cfg(not(feature = "_nrf5340"))]
|
|
||||||
pub mod wdt;
|
pub mod wdt;
|
||||||
|
|
||||||
// This mod MUST go last, so that it sees all the `impl_foo!` macros
|
// This mod MUST go last, so that it sees all the `impl_foo!` macros
|
||||||
|
@ -3,11 +3,15 @@
|
|||||||
//! This HAL implements a basic watchdog timer with 1..=8 handles.
|
//! This HAL implements a basic watchdog timer with 1..=8 handles.
|
||||||
//! Once the watchdog has been started, it cannot be stopped.
|
//! Once the watchdog has been started, it cannot be stopped.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
#![macro_use]
|
||||||
|
|
||||||
|
use core::hint::unreachable_unchecked;
|
||||||
|
|
||||||
|
use embassy_hal_internal::PeripheralType;
|
||||||
|
|
||||||
use crate::pac::wdt::vals;
|
use crate::pac::wdt::vals;
|
||||||
pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
|
pub use crate::pac::wdt::vals::{Halt as HaltConfig, Sleep as SleepConfig};
|
||||||
use crate::{peripherals, Peri};
|
use crate::{interrupt, pac, peripherals, Peri};
|
||||||
|
|
||||||
const MIN_TICKS: u32 = 15;
|
const MIN_TICKS: u32 = 15;
|
||||||
|
|
||||||
@ -30,12 +34,12 @@ pub struct Config {
|
|||||||
impl Config {
|
impl Config {
|
||||||
/// Create a config structure from the current configuration of the WDT
|
/// Create a config structure from the current configuration of the WDT
|
||||||
/// peripheral.
|
/// peripheral.
|
||||||
pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> {
|
pub fn try_new<T: Instance>(_wdt: &Peri<'_, T>) -> Option<Self> {
|
||||||
let r = crate::pac::WDT;
|
let r = T::REGS;
|
||||||
|
|
||||||
#[cfg(not(feature = "_nrf91"))]
|
#[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))]
|
||||||
let runstatus = r.runstatus().read().runstatus();
|
let runstatus = r.runstatus().read().runstatus();
|
||||||
#[cfg(feature = "_nrf91")]
|
#[cfg(any(feature = "_nrf91", feature = "_nrf5340"))]
|
||||||
let runstatus = r.runstatus().read().runstatuswdt();
|
let runstatus = r.runstatus().read().runstatuswdt();
|
||||||
|
|
||||||
if runstatus {
|
if runstatus {
|
||||||
@ -62,11 +66,11 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Watchdog driver.
|
/// Watchdog driver.
|
||||||
pub struct Watchdog {
|
pub struct Watchdog<T: Instance> {
|
||||||
_wdt: Peri<'static, peripherals::WDT>,
|
_wdt: Peri<'static, T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Watchdog {
|
impl<T: Instance> Watchdog<T> {
|
||||||
/// Try to create a new watchdog driver.
|
/// Try to create a new watchdog driver.
|
||||||
///
|
///
|
||||||
/// This function will return an error if the watchdog is already active
|
/// This function will return an error if the watchdog is already active
|
||||||
@ -76,19 +80,19 @@ impl Watchdog {
|
|||||||
/// `N` must be between 1 and 8, inclusive.
|
/// `N` must be between 1 and 8, inclusive.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_new<const N: usize>(
|
pub fn try_new<const N: usize>(
|
||||||
wdt: Peri<'static, peripherals::WDT>,
|
wdt: Peri<'static, T>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, peripherals::WDT>> {
|
) -> Result<(Self, [WatchdogHandle; N]), Peri<'static, T>> {
|
||||||
assert!(N >= 1 && N <= 8);
|
assert!(N >= 1 && N <= 8);
|
||||||
|
|
||||||
let r = crate::pac::WDT;
|
let r = T::REGS;
|
||||||
|
|
||||||
let crv = config.timeout_ticks.max(MIN_TICKS);
|
let crv = config.timeout_ticks.max(MIN_TICKS);
|
||||||
let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1);
|
let rren = crate::pac::wdt::regs::Rren((1u32 << N) - 1);
|
||||||
|
|
||||||
#[cfg(not(feature = "_nrf91"))]
|
#[cfg(not(any(feature = "_nrf91", feature = "_nrf5340")))]
|
||||||
let runstatus = r.runstatus().read().runstatus();
|
let runstatus = r.runstatus().read().runstatus();
|
||||||
#[cfg(feature = "_nrf91")]
|
#[cfg(any(feature = "_nrf91", feature = "_nrf5340"))]
|
||||||
let runstatus = r.runstatus().read().runstatuswdt();
|
let runstatus = r.runstatus().read().runstatuswdt();
|
||||||
|
|
||||||
if runstatus {
|
if runstatus {
|
||||||
@ -114,17 +118,9 @@ impl Watchdog {
|
|||||||
|
|
||||||
let this = Self { _wdt: wdt };
|
let this = Self { _wdt: wdt };
|
||||||
|
|
||||||
let mut handles = [const {
|
let mut handles = [const { WatchdogHandle { index: 0 } }; N];
|
||||||
WatchdogHandle {
|
|
||||||
_wdt: PhantomData,
|
|
||||||
index: 0,
|
|
||||||
}
|
|
||||||
}; N];
|
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
handles[i] = WatchdogHandle {
|
handles[i] = unsafe { WatchdogHandle::steal::<T>(i as u8) };
|
||||||
_wdt: PhantomData,
|
|
||||||
index: i as u8,
|
|
||||||
};
|
|
||||||
handles[i].pet();
|
handles[i].pet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +135,7 @@ impl Watchdog {
|
|||||||
/// interrupt has been enabled.
|
/// interrupt has been enabled.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn enable_interrupt(&mut self) {
|
pub fn enable_interrupt(&mut self) {
|
||||||
crate::pac::WDT.intenset().write(|w| w.set_timeout(true));
|
T::REGS.intenset().write(|w| w.set_timeout(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disable the watchdog interrupt.
|
/// Disable the watchdog interrupt.
|
||||||
@ -147,7 +143,7 @@ impl Watchdog {
|
|||||||
/// NOTE: This has no effect on the reset caused by the Watchdog.
|
/// NOTE: This has no effect on the reset caused by the Watchdog.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn disable_interrupt(&mut self) {
|
pub fn disable_interrupt(&mut self) {
|
||||||
crate::pac::WDT.intenclr().write(|w| w.set_timeout(true));
|
T::REGS.intenclr().write(|w| w.set_timeout(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is the watchdog still awaiting pets from any handle?
|
/// Is the watchdog still awaiting pets from any handle?
|
||||||
@ -156,7 +152,7 @@ impl Watchdog {
|
|||||||
/// handles to prevent a reset this time period.
|
/// handles to prevent a reset this time period.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn awaiting_pets(&self) -> bool {
|
pub fn awaiting_pets(&self) -> bool {
|
||||||
let r = crate::pac::WDT;
|
let r = T::REGS;
|
||||||
let enabled = r.rren().read().0;
|
let enabled = r.rren().read().0;
|
||||||
let status = r.reqstatus().read().0;
|
let status = r.reqstatus().read().0;
|
||||||
(status & enabled) == 0
|
(status & enabled) == 0
|
||||||
@ -165,11 +161,26 @@ impl Watchdog {
|
|||||||
|
|
||||||
/// Watchdog handle.
|
/// Watchdog handle.
|
||||||
pub struct WatchdogHandle {
|
pub struct WatchdogHandle {
|
||||||
_wdt: PhantomData<Peri<'static, peripherals::WDT>>,
|
|
||||||
index: u8,
|
index: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WatchdogHandle {
|
impl WatchdogHandle {
|
||||||
|
fn regs(&self) -> pac::wdt::Wdt {
|
||||||
|
match self.index / 8 {
|
||||||
|
#[cfg(not(feature = "_multi_wdt"))]
|
||||||
|
peripherals::WDT::INDEX => peripherals::WDT::REGS,
|
||||||
|
#[cfg(feature = "_multi_wdt")]
|
||||||
|
peripherals::WDT0::INDEX => peripherals::WDT0::REGS,
|
||||||
|
#[cfg(feature = "_multi_wdt")]
|
||||||
|
peripherals::WDT1::INDEX => peripherals::WDT1::REGS,
|
||||||
|
_ => unsafe { unreachable_unchecked() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rr_index(&self) -> usize {
|
||||||
|
usize::from(self.index % 8)
|
||||||
|
}
|
||||||
|
|
||||||
/// Pet the watchdog.
|
/// Pet the watchdog.
|
||||||
///
|
///
|
||||||
/// This function pets the given watchdog handle.
|
/// This function pets the given watchdog handle.
|
||||||
@ -178,14 +189,14 @@ impl WatchdogHandle {
|
|||||||
/// prevent a reset from occurring.
|
/// prevent a reset from occurring.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pet(&mut self) {
|
pub fn pet(&mut self) {
|
||||||
let r = crate::pac::WDT;
|
let r = self.regs();
|
||||||
r.rr(self.index as usize).write(|w| w.set_rr(vals::Rr::RELOAD));
|
r.rr(self.rr_index()).write(|w| w.set_rr(vals::Rr::RELOAD));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has this handle been pet within the current window?
|
/// Has this handle been pet within the current window?
|
||||||
pub fn is_pet(&self) -> bool {
|
pub fn is_pet(&self) -> bool {
|
||||||
let r = crate::pac::WDT;
|
let r = self.regs();
|
||||||
!r.reqstatus().read().rr(self.index as usize)
|
!r.reqstatus().read().rr(self.rr_index())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Steal a watchdog handle by index.
|
/// Steal a watchdog handle by index.
|
||||||
@ -193,10 +204,33 @@ impl WatchdogHandle {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// Watchdog must be initialized and `index` must be between `0` and `N-1`
|
/// Watchdog must be initialized and `index` must be between `0` and `N-1`
|
||||||
/// where `N` is the handle count when initializing.
|
/// where `N` is the handle count when initializing.
|
||||||
pub unsafe fn steal(index: u8) -> Self {
|
pub unsafe fn steal<T: Instance>(index: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_wdt: PhantomData,
|
index: T::INDEX * 8 + index,
|
||||||
index,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) trait SealedInstance {
|
||||||
|
const REGS: pac::wdt::Wdt;
|
||||||
|
const INDEX: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// WDT instance.
|
||||||
|
#[allow(private_bounds)]
|
||||||
|
pub trait Instance: SealedInstance + PeripheralType + 'static + Send {
|
||||||
|
/// Interrupt for this peripheral.
|
||||||
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_wdt {
|
||||||
|
($type:ident, $pac_type:ident, $irq:ident, $index:literal) => {
|
||||||
|
impl crate::wdt::SealedInstance for peripherals::$type {
|
||||||
|
const REGS: pac::wdt::Wdt = pac::$pac_type;
|
||||||
|
const INDEX: u8 = $index;
|
||||||
|
}
|
||||||
|
impl crate::wdt::Instance for peripherals::$type {
|
||||||
|
type Interrupt = crate::interrupt::typelevel::$irq;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user