94 lines
5.1 KiB
Text
94 lines
5.1 KiB
Text
|
<<<
|
||
|
:sectnums:
|
||
|
==== Watchdog Timer (WDT)
|
||
|
|
||
|
[cols="<3,<3,<4"]
|
||
|
[frame="topbot",grid="none"]
|
||
|
|=======================
|
||
|
| Hardware source file(s): | neorv32_wdt.vhd |
|
||
|
| Software driver file(s): | neorv32_wdt.c |
|
||
|
| | neorv32_wdt.h |
|
||
|
| Top entity port: | none |
|
||
|
| Configuration generics: | _IO_WDT_EN_ | implement watchdog when _true_
|
||
|
| CPU interrupts: | fast IRQ channel 0 | watchdog timeout (see <<_processor_interrupts>>)
|
||
|
|=======================
|
||
|
|
||
|
|
||
|
**Theory of Operation**
|
||
|
|
||
|
The watchdog (WDT) provides a last resort for safety-critical applications. The WDT provides a "bark and bite"
|
||
|
concept. The timeout counter first triggers an optional CPU interrupt ("bark") when reaching half of the programmed
|
||
|
interval to inform the application of the imminent timeout. When the full timeout value is reached
|
||
|
a system-wide hardware reset is generated ("bite"). The internal counter has to be reset explicitly by the application
|
||
|
program every now and then to prevent a timeout.
|
||
|
|
||
|
|
||
|
**Configuration**
|
||
|
|
||
|
The watchdog is enabled by setting the control register's `WDT_CTRL_EN_ bit. When this bit is cleared, the internal
|
||
|
timeout counter is reset to zero and no interrupt and no system reset can be triggered.
|
||
|
|
||
|
The internal 32-bit timeout counter is clocked at 1/4096th of the processor's main clock (f~WDT~[Hz] = f~main~[Hz] / 4096).
|
||
|
Whenever this counter reaches the programmed timeout value (_WDT_CTRL_TIMEOUT_ bits in the control register) a
|
||
|
hardware reset is triggered. In order to inform the application of an imminent timeout, an optional CPU interrupt is
|
||
|
triggered when the timeout counter reaches **half** of the programmed timeout value.
|
||
|
|
||
|
The watchdog is "fed" by writing `1` to the _WDT_CTRL_RESET_ control register bit, which
|
||
|
will reset the internal timeout counter back to zero.
|
||
|
|
||
|
[NOTE]
|
||
|
Writing all-zero to the _WDT_CTRL_TIMEOUT_ bits will immediately trigger a system-wide reset.
|
||
|
|
||
|
.Watchdog Interrupt
|
||
|
[NOTE]
|
||
|
A watchdog interrupt occurs when the watchdog is enabled and the internal counter reaches half of the programmed
|
||
|
timeout value. A triggered interrupt has to be explicitly cleared by writing zero to the according <<_mip>> CSR bit.
|
||
|
|
||
|
.Watchdog Operation during Debugging
|
||
|
[IMPORTANT]
|
||
|
By default the watchdog stops operation when the CPU enters debug mode and will resume normal operation after
|
||
|
the CPU has left debug mode again. This will prevent an unintended watchdog timeout during a debug session. However,
|
||
|
the watchdog can also be configured to keep operating even when the CPU is in debug mode by setting the control
|
||
|
register's _WDT_CTRL_DBEN_ bit.
|
||
|
|
||
|
.Watchdog Operation during CPU Sleep
|
||
|
[IMPORTANT]
|
||
|
By default the watchdog stops operating when the CPU enters sleep mode. However, the watchdog can also be configured
|
||
|
to keep operating even when the CPU is in sleep mode by setting the control register's _WDT_CTRL_SEN_ bit.
|
||
|
|
||
|
|
||
|
**Configuration Lock**
|
||
|
|
||
|
The watchdog control register can be locked to protect the current configuration from being modified. The lock is
|
||
|
activated by setting the _WDT_CTRL_LOCK_ bit. In the locked state any write access to the control register is entirely
|
||
|
ignored (see table below, "writable if locked"). Read accesses to the control register as well as watchdog resets
|
||
|
(by setting the _WDT_CTRL_RESET_ flag) are not affected.
|
||
|
|
||
|
The lock bit can only be set if the WDT is already enabled (_WDT_CTRL_EN_ is set).
|
||
|
The lock bit can only be cleared again by a system-wide hardware reset.
|
||
|
|
||
|
|
||
|
**Cause of last Hardware Reset**
|
||
|
|
||
|
The cause of the last system hardware reset can be determined via the _WDT_CTRL_RCAUSE_ flag. If this flag is
|
||
|
zero, the processor has been reset via the external reset signal (or the on-chip debugger). If this flag is set,
|
||
|
the last system reset was caused by the watchdog itself.
|
||
|
|
||
|
|
||
|
**Register Map**
|
||
|
|
||
|
.WDT register map (`struct NEORV32_WDT`)
|
||
|
[cols="<2,<2,<4,^1,^1,^2,<4"]
|
||
|
[options="header",grid="all"]
|
||
|
|=======================
|
||
|
| Address | Name [C] | Bit(s), Name [C] | R/W | Reset value | Writable if locked | Function
|
||
|
.8+<| `0xffffffbc` .8+<| `NEORV32_WDT.CTRL` <|`0` _WDT_CTRL_EN_ ^| r/w ^| `0` ^| no <| watchdog enable
|
||
|
<|`1 _WDT_CTRL_LOCK_ ^| r/w ^| `0` ^| no <| lock configuration when set, clears only on system reset, can only be set if enable bit is set already
|
||
|
<|`2` _WDT_CTRL_DBEN_ ^| r/w ^| `0` ^| no <| set to allow WDT to continue operation even when CPU is in debug mode
|
||
|
<|`3` _WDT_CTRL_SEN_ ^| r/w ^| `0` ^| no <| set to allow WDT to continue operation even when CPU is in sleep mode
|
||
|
<|`4` _WDT_CTRL_RESET_ ^| -/w ^| - ^| yes <| reset watchdog when set, auto-clears
|
||
|
<|`5` _WDT_CTRL_RCAUSE_ ^| r/- ^| `0` ^| - <| cause of last system reset: `0`=caused by external reset signal, `1`=caused by watchdog
|
||
|
<|`7:6` - ^| r/- ^| - ^| - <| _reserved_, reads as zero
|
||
|
<|`31:8` _WDT_CTRL_TIMEOUT_MSB_ : _WDT_CTRL_TIMEOUT_LSB_ ^| r/w ^| 0 ^| no <| 24-bit watchdog timeout value
|
||
|
|=======================
|