1 |
60 |
zero_gravi |
<<<
|
2 |
|
|
:sectnums:
|
3 |
|
|
==== Watchdog Timer (WDT)
|
4 |
|
|
|
5 |
|
|
[cols="<3,<3,<4"]
|
6 |
|
|
[frame="topbot",grid="none"]
|
7 |
|
|
|=======================
|
8 |
|
|
| Hardware source file(s): | neorv32_wdt.vhd |
|
9 |
|
|
| Software driver file(s): | neorv32_wdt.c |
|
10 |
|
|
| | neorv32_wdt.h |
|
11 |
|
|
| Top entity port: | none |
|
12 |
|
|
| Configuration generics: | _IO_WDT_EN_ | implement GPIO port when _true_
|
13 |
61 |
zero_gravi |
| CPU interrupts: | fast IRQ channel 0 | watchdog timer overflow (see <<_processor_interrupts>>)
|
14 |
60 |
zero_gravi |
|=======================
|
15 |
|
|
|
16 |
69 |
zero_gravi |
|
17 |
60 |
zero_gravi |
**Theory of Operation**
|
18 |
|
|
|
19 |
|
|
The watchdog (WDT) provides a last resort for safety-critical applications. The WDT has an internal 20-bit
|
20 |
|
|
wide counter that needs to be reset every now and then by the user program. If the counter overflows, either
|
21 |
|
|
a system reset or an interrupt is generated (depending on the configured operation mode).
|
22 |
69 |
zero_gravi |
The _WDT_CTRL_HALF_ flag of the control register `CTRL` indicates that at least half of the maximum timeout
|
23 |
|
|
value has been reached.
|
24 |
60 |
zero_gravi |
|
25 |
69 |
zero_gravi |
The watchdog is enabled by setting the _WDT_CTRL_EN_ bit. The clock used to increment the internal counter
|
26 |
|
|
is selected via the 3-bit _WDT_CTRL_CLK_SELx_ prescaler:
|
27 |
60 |
zero_gravi |
|
28 |
|
|
[cols="^3,^3,>4"]
|
29 |
|
|
[options="header",grid="rows"]
|
30 |
|
|
|=======================
|
31 |
64 |
zero_gravi |
| **`WDT_CTRL_CLK_SELx`** | Main clock prescaler | Timeout period in clock cycles
|
32 |
60 |
zero_gravi |
| `0b000` | 2 | 2 097 152
|
33 |
|
|
| `0b001` | 4 | 4 194 304
|
34 |
|
|
| `0b010` | 8 | 8 388 608
|
35 |
|
|
| `0b011` | 64 | 67 108 864
|
36 |
|
|
| `0b100` | 128 | 134 217 728
|
37 |
|
|
| `0b101` | 1024 | 1 073 741 824
|
38 |
|
|
| `0b110` | 2048 | 2 147 483 648
|
39 |
|
|
| `0b111` | 4096 | 4 294 967 296
|
40 |
|
|
|=======================
|
41 |
|
|
|
42 |
|
|
Whenever the internal timer overflows the watchdog executes one of two possible actions: Either a hard
|
43 |
|
|
processor reset is triggered or an interrupt is requested at CPU's fast interrupt channel #0. The
|
44 |
66 |
zero_gravi |
WDT_CTRL_MODE bit defines the action to be taken on an overflow: When cleared, the Watchdog will assert an
|
45 |
65 |
zero_gravi |
IRQ, when set the WDT will cause a system reset. The configured action can also be triggered manually at
|
46 |
64 |
zero_gravi |
any time by setting the _WDT_CTRL_FORCE_ bit. The watchdog is reset by setting the _WDT_CTRL_RESET_ bit.
|
47 |
60 |
zero_gravi |
|
48 |
65 |
zero_gravi |
A watchdog interrupt can only occur if the watchdog is enabled and interrupt mode is enabled.
|
49 |
69 |
zero_gravi |
A triggered interrupt has to be cleared again by setting the according `mip` CSR bit.
|
50 |
65 |
zero_gravi |
|
51 |
64 |
zero_gravi |
The cause of the last action of the watchdog can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
|
52 |
60 |
zero_gravi |
zero, the processor has been reset via the external reset signal. If this flag is set the last system reset was
|
53 |
|
|
initiated by the watchdog.
|
54 |
|
|
|
55 |
|
|
The Watchdog control register can be locked in order to protect the current configuration. The lock is
|
56 |
64 |
zero_gravi |
activated by setting bit _WDT_CTRL_LOCK_. In the locked state any write access to the configuration flags is
|
57 |
69 |
zero_gravi |
ignored (see table below, "writable if locked"). Read accesses to the control register are not effected. The
|
58 |
60 |
zero_gravi |
lock can only be removed by a system reset (via external reset signal or via a watchdog reset action).
|
59 |
|
|
|
60 |
69 |
zero_gravi |
.Watchdog Operation during Debugging
|
61 |
|
|
[IMPORTANT]
|
62 |
|
|
By default the watchdog pauses operation when the CPU enters debug mode and will resume normal operation after
|
63 |
|
|
the CPU has left debug mode. This will prevent an unintended watchdog timeout (and a hardware reset if configured)
|
64 |
|
|
during a debug session. However, the watchdog can be configured to keep operating even when the CPU is in debug
|
65 |
|
|
mode by setting the control register's _WDT_CTRL_DBEN_ bit. If the CPU's debug mode is not implemented this flag
|
66 |
|
|
is hardwired to zero.
|
67 |
|
|
|
68 |
|
|
|
69 |
64 |
zero_gravi |
.WDT register map (`struct NEORV32_WDT`)
|
70 |
69 |
zero_gravi |
[cols="<2,<2,<4,^1,^1,^2,<4"]
|
71 |
60 |
zero_gravi |
[options="header",grid="all"]
|
72 |
|
|
|=======================
|
73 |
69 |
zero_gravi |
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
|
74 |
|
|
.11+<| `0xffffffbc` .11+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| `0` ^| no <| watchdog enable
|
75 |
|
|
<|`1` _WDT_CTRL_CLK_SEL0_ ^| r/w ^| `0` ^| no .3+<| 3-bit clock prescaler select
|
76 |
|
|
<|`2` _WDT_CTRL_CLK_SEL1_ ^| r/w ^| `0` ^| no
|
77 |
|
|
<|`3` _WDT_CTRL_CLK_SEL2_ ^| r/w ^| `0` ^| no
|
78 |
|
|
<|`4` _WDT_CTRL_MODE_ ^| r/w ^| `0` ^| no <| overflow action: `1`=reset, `0`=IRQ
|
79 |
|
|
<|`5` _WDT_CTRL_RCAUSE_ ^| r/- ^| `0` ^| - <| cause of last system reset: `0`=caused by external reset signal, `1`=caused by watchdog
|
80 |
|
|
<|`6` _WDT_CTRL_RESET_ ^| -/w ^| - ^| yes <| watchdog reset when set, auto-clears
|
81 |
|
|
<|`7` _WDT_CTRL_FORCE_ ^| -/w ^| - ^| yes <| force configured watchdog action when set, auto-clears
|
82 |
|
|
<|`8` _WDT_CTRL_LOCK_ ^| r/w ^| `0` ^| no <| lock access to configuration when set, clears only on system reset (via external reset signal OR watchdog reset action = reset)
|
83 |
|
|
<|`9` _WDT_CTRL_DBEN_ ^| r/w ^| `0` ^| no <| allow WDT to continue operation even when in debug mode
|
84 |
|
|
<|`10` _WDT_CTRL_HALF_ ^| r/- ^| `0` ^| - <| set if at least half of the max. timeout counter value has been reached
|
85 |
60 |
zero_gravi |
|=======================
|