1use kernel::utilities::cells::OptionalCell;
6use kernel::utilities::registers::interfaces::{ReadWriteable, Writeable};
7use kernel::utilities::registers::{register_bitfields, register_structs, ReadWrite};
8use kernel::utilities::StaticRef;
9
10use crate::resets;
11
12register_structs! {
13
14    WatchdogRegisters {
15        (0x000 => ctrl: ReadWrite<u32, CTRL::Register>),
19        (0x004 => load: ReadWrite<u32>),
21        (0x008 => reason: ReadWrite<u32, REASON::Register>),
23        (0x00C => scratch0: ReadWrite<u32, SCRATCH0::Register>),
25        (0x010 => scratch1: ReadWrite<u32, SCRATCH1::Register>),
27        (0x014 => scratch2: ReadWrite<u32, SCRATCH2::Register>),
29        (0x018 => scratch3: ReadWrite<u32, SCRATCH3::Register>),
31        (0x01C => scratch4: ReadWrite<u32, SCRATCH4::Register>),
33        (0x020 => scratch5: ReadWrite<u32, SCRATCH5::Register>),
35        (0x024 => scratch6: ReadWrite<u32, SCRATCH6::Register>),
37        (0x028 => scratch7: ReadWrite<u32, SCRATCH7::Register>),
39        (0x02C => tick: ReadWrite<u32, TICK::Register>),
41        (0x030 => @END),
42    }
43}
44register_bitfields![u32,
45    CTRL [
46        TRIGGER OFFSET(31) NUMBITS(1) [],
48        ENABLE OFFSET(30) NUMBITS(1) [],
50        PAUSE_DBG1 OFFSET(26) NUMBITS(1) [],
52        PAUSE_DBG0 OFFSET(25) NUMBITS(1) [],
54        PAUSE_JTAG OFFSET(24) NUMBITS(1) [],
56        TIME OFFSET(0) NUMBITS(24) []
58    ],
59    LOAD [
60
61        LOAD OFFSET(0) NUMBITS(24) []
62    ],
63    REASON [
64
65        FORCE OFFSET(1) NUMBITS(1) [],
66
67        TIMER OFFSET(0) NUMBITS(1) []
68    ],
69    SCRATCH0 [
70        VALUE OFFSET (0) NUMBITS (32) []
71    ],
72    SCRATCH1 [
73        VALUE OFFSET (0) NUMBITS (32) []
74    ],
75    SCRATCH2 [
76        VALUE OFFSET (0) NUMBITS (32) []
77    ],
78    SCRATCH3 [
79        VALUE OFFSET (0) NUMBITS (32) []
80    ],
81    SCRATCH4 [
82        VALUE OFFSET (0) NUMBITS (32) []
83    ],
84    SCRATCH5 [
85        VALUE OFFSET (0) NUMBITS (32) []
86    ],
87    SCRATCH6 [
88        VALUE OFFSET (0) NUMBITS (32) []
89    ],
90    SCRATCH7 [
91        VALUE OFFSET (0) NUMBITS (32) []
92    ],
93    TICK [
94        COUNT OFFSET(11) NUMBITS(9) [],
96        RUNNING OFFSET(10) NUMBITS(1) [],
98        ENABLE OFFSET(9) NUMBITS(1) [],
100        CYCLES OFFSET(0) NUMBITS(9) []
102    ]
103];
104const WATCHDOG_BASE: StaticRef<WatchdogRegisters> =
105    unsafe { StaticRef::new(0x40058000 as *const WatchdogRegisters) };
106
107pub struct Watchdog<'a> {
108    registers: StaticRef<WatchdogRegisters>,
109    resets: OptionalCell<&'a resets::Resets>,
110}
111
112impl<'a> Watchdog<'a> {
113    pub const fn new() -> Watchdog<'a> {
114        Watchdog {
115            registers: WATCHDOG_BASE,
116            resets: OptionalCell::empty(),
117        }
118    }
119
120    pub fn resolve_dependencies(&self, resets: &'a resets::Resets) {
121        self.resets.set(resets);
122    }
123
124    pub fn start_tick(&self, cycles_in_mhz: u32) {
125        self.registers
126            .tick
127            .modify(TICK::CYCLES.val(cycles_in_mhz) + TICK::ENABLE::SET);
128    }
129
130    pub fn reboot(&self) {
131        self.resets
132            .map(|resets| resets.watchdog_reset_all_except(&[]));
133        self.registers.ctrl.write(CTRL::TRIGGER::SET);
134    }
135}