pub enum WatchdogPeriod {
Off,
Millis8,
Millis16,
Millis32,
Millis64,
Millis128,
Millis256,
Millis512,
Millis1024,
Millis2048,
Millis4096,
Millis8192
}
pub trait WatchdogController {
fn disable(&mut self);
fn enable(&mut self, min_gap: WatchdogPeriod, max_gap: WatchdogPeriod);
fn protect(&mut self);
fn kick(&self);
}
#[cfg(target_arch="avr")]
pub mod base {
use avr_oxide::hal::generic::watchdog::WatchdogPeriod;
#[repr(C)]
pub struct AvrWatchdogControlBlock {
pub(crate) ctrla: u8,
pub(crate) status: u8
}
impl WatchdogPeriod {
pub(crate) fn to_bits(&self) -> u8 {
match self {
WatchdogPeriod::Off => 0x00,
WatchdogPeriod::Millis8 => 0x01,
WatchdogPeriod::Millis16 => 0x02,
WatchdogPeriod::Millis32 => 0x03,
WatchdogPeriod::Millis64 => 0x04,
WatchdogPeriod::Millis128 => 0x05,
WatchdogPeriod::Millis256 => 0x06,
WatchdogPeriod::Millis512 => 0x07,
WatchdogPeriod::Millis1024 => 0x08,
WatchdogPeriod::Millis2048 => 0x09,
WatchdogPeriod::Millis4096 => 0x0A,
WatchdogPeriod::Millis8192 => 0x0B
}
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! atmel_watchdog_tpl {
($ref:expr, $cpu:expr) => {
use avr_oxide::hal::generic::cpu::{Cpu, ConfigurationChange};
use avr_oxide::hal::generic::watchdog::{WatchdogController,WatchdogPeriod};
use avr_oxide::hal::generic::watchdog::base::AvrWatchdogControlBlock;
use core::arch::asm;
pub type WatchdogImpl = AvrWatchdogControlBlock;
impl WatchdogController for AvrWatchdogControlBlock {
fn disable(&mut self) {
unsafe {
$cpu.write_protected(ConfigurationChange::ProtectedRegister,
&mut self.ctrla, 0x00);
}
}
fn enable(&mut self, min_gap: WatchdogPeriod, max_gap: WatchdogPeriod) {
unsafe {
$cpu.write_protected(ConfigurationChange::ProtectedRegister,
&mut self.ctrla,
min_gap.to_bits() << 4 | max_gap.to_bits());
}
}
fn protect(&mut self) {
unsafe {
$cpu.write_protected(ConfigurationChange::ProtectedRegister,
&mut self.status, 0b10000000);
}
}
#[inline(always)]
fn kick(&self) {
unsafe {
asm!("wdr")
}
}
}
pub fn instance() -> &'static mut AvrWatchdogControlBlock {
unsafe {
core::mem::transmute($ref)
}
}
}
}
}
#[cfg(not(target_arch="avr"))]
pub mod base {
#[repr(C)]
pub struct DummyWatchdogControlBlock {
}
#[doc(hidden)]
#[macro_export]
macro_rules! atmel_watchdog_tpl {
($ref:expr, $cpu:expr) => {
use avr_oxide::hal::generic::watchdog::{WatchdogController,WatchdogPeriod};
use avr_oxide::hal::generic::watchdog::base::DummyWatchdogControlBlock;
pub type WatchdogImpl = DummyWatchdogControlBlock;
impl WatchdogController for DummyWatchdogControlBlock {
fn disable(&mut self) {
println!("*** WATCHDOG: Disabled");
}
fn enable(&mut self, _min_gap: WatchdogPeriod, _max_gap: WatchdogPeriod) {
println!("*** WATCHDOG: Enabled");
}
fn protect(&mut self) {
println!("*** WATCHDOG: Configuration protected");
}
fn kick(&self) {
println!("*** WATCHDOG: kicked");
}
}
static mut INSTANCE : DummyWatchdogControlBlock = DummyWatchdogControlBlock {
};
pub fn instance() -> &'static mut DummyWatchdogControlBlock {
unsafe {
&mut INSTANCE
}
}
}
}
}