rp2040/
watchdog.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use 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        /// Watchdog control
16        /// The rst_wdsel register determines which subsystems are reset when th
17        /// The watchdog can be triggered in software.
18        (0x000 => ctrl: ReadWrite<u32, CTRL::Register>),
19        /// Load the watchdog timer. The maximum setting is 0xffffff which corresponds to 0x
20        (0x004 => load: ReadWrite<u32>),
21        /// Logs the reason for the last reset. Both bits are zero for the case of a hardwar
22        (0x008 => reason: ReadWrite<u32, REASON::Register>),
23        /// Scratch register. Information persists through soft reset of the chip.
24        (0x00C => scratch0: ReadWrite<u32, SCRATCH0::Register>),
25        /// Scratch register. Information persists through soft reset of the chip.
26        (0x010 => scratch1: ReadWrite<u32, SCRATCH1::Register>),
27        /// Scratch register. Information persists through soft reset of the chip.
28        (0x014 => scratch2: ReadWrite<u32, SCRATCH2::Register>),
29        /// Scratch register. Information persists through soft reset of the chip.
30        (0x018 => scratch3: ReadWrite<u32, SCRATCH3::Register>),
31        /// Scratch register. Information persists through soft reset of the chip.
32        (0x01C => scratch4: ReadWrite<u32, SCRATCH4::Register>),
33        /// Scratch register. Information persists through soft reset of the chip.
34        (0x020 => scratch5: ReadWrite<u32, SCRATCH5::Register>),
35        /// Scratch register. Information persists through soft reset of the chip.
36        (0x024 => scratch6: ReadWrite<u32, SCRATCH6::Register>),
37        /// Scratch register. Information persists through soft reset of the chip.
38        (0x028 => scratch7: ReadWrite<u32, SCRATCH7::Register>),
39        /// Controls the tick generator
40        (0x02C => tick: ReadWrite<u32, TICK::Register>),
41        (0x030 => @END),
42    }
43}
44register_bitfields![u32,
45    CTRL [
46        /// Trigger a watchdog reset
47        TRIGGER OFFSET(31) NUMBITS(1) [],
48        /// When not enabled the watchdog timer is paused
49        ENABLE OFFSET(30) NUMBITS(1) [],
50        /// Pause the watchdog timer when processor 1 is in debug mode
51        PAUSE_DBG1 OFFSET(26) NUMBITS(1) [],
52        /// Pause the watchdog timer when processor 0 is in debug mode
53        PAUSE_DBG0 OFFSET(25) NUMBITS(1) [],
54        /// Pause the watchdog timer when JTAG is accessing the bus fabric
55        PAUSE_JTAG OFFSET(24) NUMBITS(1) [],
56        /// Indicates the number of ticks / 2 (see errata RP2040-E1) before a watchdog reset
57        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 down timer: the remaining number clk_tick cycles before the next tick is g
95        COUNT OFFSET(11) NUMBITS(9) [],
96        /// Is the tick generator running?
97        RUNNING OFFSET(10) NUMBITS(1) [],
98        /// start / stop tick generation
99        ENABLE OFFSET(9) NUMBITS(1) [],
100        /// Total number of clk_tick cycles before the next tick.
101        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}