104 lines
5.5 KiB
Plaintext
104 lines
5.5 KiB
Plaintext
<<<
|
|
: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's timeout counter is reset ("feeding the watchdog") by writing the reset **PASSWORD** to the `RESET` register.
|
|
The password is hardwired to hexadecimal `0x709D1AB3`.
|
|
|
|
.Watchdog Interrupt
|
|
[NOTE]
|
|
A watchdog interrupt occurs when the watchdog is enabled and the internal counter reaches _exactly_ half of the programmed
|
|
timeout value. Hence, the interrupt only fires once. However, a triggered WDT 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"). However, read accesses to the control register as well as watchdog resets
|
|
are further possible.
|
|
|
|
The lock bit can only be set if the WDT is already enabled (`WDT_CTRL_EN` is set). Furthermore, the lock bit can
|
|
only be cleared again by a system-wide hardware reset.
|
|
|
|
|
|
**Strict Mode**
|
|
|
|
The _strict operation mode_ provides additional safety functions. If the strict mode is enabled by the `WDT_CTRL_STRICT`
|
|
control register bit an **immediate hardware** reset if enforced if
|
|
|
|
* the `RESET` register is written with an incorrect password or
|
|
* the `CTRL` register is written and the `WDT_CTRL_LOCK` bit is set.
|
|
|
|
|
|
**Cause of last Hardware Reset**
|
|
|
|
The cause of the last system hardware reset can be determined via the `WDT_CTRL_RCAUSE_*` bits:
|
|
|
|
* `0b00`: Reset caused by external reset signal/pin
|
|
* `0b01`: Reset caused by on-chip debugger
|
|
* `0b10`: Reset caused by watchdog
|
|
|
|
|
|
**Register Map**
|
|
|
|
.WDT register map (`struct NEORV32_WDT`)
|
|
[cols="<2,<1,<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+<| `0xfffffb00` .8+<| `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_STRICT` ^| r/w ^| `0` ^| no <| set to enable strict mode (force hardware reset if reset password is incorrect or if write access to locked CTRL register)
|
|
<|`6:5` `WDT_CTRL_RCAUSE_HI : WDT_CTRL_RCAUSE_LO` ^| r/- ^| `0` ^| - <| cause of last system reset; 0=external reset, 1=ocd-reset, 2=watchdog reset
|
|
<|`7` - ^| r/- ^| - ^| - <| _reserved_, reads as zero
|
|
<|`31:8` `WDT_CTRL_TIMEOUT_MSB : WDT_CTRL_TIMEOUT_LSB` ^| r/w ^| 0 ^| no <| 24-bit watchdog timeout value
|
|
| `0xfffffb04` | `RESET` | | -/w | - | yes | Write PASSWORD to reset WDT timeout counter ("feed the watchdog")
|
|
|=======================
|