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}