Test to check that the watchdog timer (WDT) is working.
The WDT is a system function for monitoring correct program operation that allows recovering from error situations such as runaway or deadlocked code. The self-diagnostic test classb_wdt_test() is executed before the main application and it basically makes sure that:
The test relies on the Real Time Counter (RTC) to check the timing of the WDT oscillator and, therefore, this library includes a basic RTC driver (see Real Time Counter Driver). Note that the RTC has a clock source independent from the CPU and the WDT. The RTC module is implicitly tested as well: if the frequency difference between RTC and WDT is more than 50%, the error state is set.
Errors are handled by CLASSB_ERROR_HANDLER_WDT() and there are a number of configurable actions:
In addition to the error handler and configurable actions, the user should configure the WDT periods CLASSB_WDT_WPER and CLASSB_WDT_PER.
Macros | |
#define | NO_INIT __attribute__ ((section (".noinit"))) |
Macro for telling the compiler not to initialize a variable on restart. More... | |
Typedefs | |
typedef enum classb_preinit_teststate | classb_preinit_teststate_t |
Enum of valid test states for the WDT test. More... | |
Enumerations | |
enum | classb_preinit_teststate { FAULT_WDT, TEST_WDT_1, TEST_WDT_2, TEST_WDT_3, TEST_WDT_OK } |
Enum of valid test states for the WDT test. More... | |
Non-initialized Variables | |
These variables need to be preserved between resets, and are therefore not initialized upon device reset. | |
NO_INIT volatile classb_preinit_teststate_t | classb_wdt_teststate |
WDT test state. More... | |
NO_INIT volatile uint16_t | classb_rtc_count |
Number of RTC periods in a WDT period. More... | |
Internal functions | |
static __always_inline bool | rtc32_is_busy (void) |
Check if RTC32 is busy synchronizing. More... | |
static void | udelay (uint16_t us) |
Delay for us microseconds. More... | |
static void | vbat_init (void) |
RTC32 Initialization. More... | |
#define | rtc_is_busy() rtc32_is_busy() |
Compatibility macro for RTC32. More... | |
Configuration settings | |
#define | CLASSB_WDT_PER WDT_PER_512CLK_gc |
Open period, during which WDT has to be reset. More... | |
#define | CLASSB_WDT_WPER WDT_WPER_1KCLK_gc |
Closed period, during which WDT cannot be reset. More... | |
Constants for internal use | |
| |
#define | CLASSB_WDT_PER_CYCLES (8 * (1 << (CLASSB_WDT_PER >> 2))) |
WDT period in cycles. More... | |
#define | CLASSB_WDT_MAX (CLASSB_WDT_PER_CYCLES + (CLASSB_WDT_PER_CYCLES >> 1)) |
Maximum number of WDT cycles to wait for a timeout. More... | |
#define | CLASSB_WDT_MIN (CLASSB_WDT_PER_CYCLES - (CLASSB_WDT_PER_CYCLES >> 1)) |
Minimum number of WDT cycles to wait for a timeout. More... | |
#define | CLASSB_WDT_RTC_PER 2 |
RTC period in cycles. More... | |
Class B Test | |
void | classb_wdt_test (void) |
Perform self-diagnostic test of watchdog timer (WDT). More... | |
#define CLASSB_WDT_MAX (CLASSB_WDT_PER_CYCLES + (CLASSB_WDT_PER_CYCLES >> 1)) |
Maximum number of WDT cycles to wait for a timeout.
The WDT runs from the ULP, which is optimized for power consumption and not accuracy. Here we count with a +50% deviation from the nominal frequency, i.e., CLASSB_WDT_MAX = 1.5 * CLASSB_WDT_PER_CYCLES
.
Referenced by classb_wdt_test().
#define CLASSB_WDT_MIN (CLASSB_WDT_PER_CYCLES - (CLASSB_WDT_PER_CYCLES >> 1)) |
Minimum number of WDT cycles to wait for a timeout.
Here we count with a -50% deviation from the nominal frequency, i.e., CLASSB_WDT_MIN = 0.5 * CLASSB_WDT_PER_CYCLES
Referenced by classb_wdt_test().
#define CLASSB_WDT_PER WDT_PER_512CLK_gc |
Open period, during which WDT has to be reset.
This should be given as one of the group configuration settings. The total timeout period is the sum of the open and closed periods. In order to comply with the standard, this should be no greater than than 50% of the total period.
Referenced by classb_wdt_test().
#define CLASSB_WDT_PER_CYCLES (8 * (1 << (CLASSB_WDT_PER >> 2))) |
WDT period in cycles.
The WDT frequency is set to 1024 Hz. Considering the information in the datasheet, the period is given by T_WDT = 8*(2^PER)
where PER is the value of the WDT Timeout register. However, we also have to consider that the group configuration is defined with two bits shifted to the left.
#define CLASSB_WDT_RTC_PER 2 |
RTC period in cycles.
This setting is only used for the WDT test.
The RTC period should be as small as possible to make the estimate reliable. The RTC frequency is set to 1024 Hz. Note that:
PER == 0
, only one third of the interrupts are generatedPER == 1
, only one half of the interrupts are generated This is not handled by the code, but PER=2
is small enough. That means approximately 3ms (3 ticks/1024KHz): the value in PER is compared with the counter value, which starts at 0, so the real period will be CLASSB_WDT_RTC_PER+1
. Referenced by classb_wdt_test().
#define CLASSB_WDT_WPER WDT_WPER_1KCLK_gc |
Closed period, during which WDT cannot be reset.
This should be given as one of the group configuration settings. The total timeout period is the sum of the open and closed periods. In order to comply with the standard, this should be at least 50% of the total period.
Referenced by classb_wdt_test().
#define NO_INIT __attribute__ ((section (".noinit"))) |
Macro for telling the compiler not to initialize a variable on restart.
#define rtc_is_busy | ( | void | ) | rtc32_is_busy() |
Compatibility macro for RTC32.
Referenced by classb_wdt_test().
typedef enum classb_preinit_teststate classb_preinit_teststate_t |
Enum of valid test states for the WDT test.
void classb_wdt_test | ( | void | ) |
Perform self-diagnostic test of watchdog timer (WDT).
Basically this functions tests the following:
If any of these tests fail, CLASSB_ERROR_HANDLER_WDT() is called. By default the device will then simply hang.
The expected (error-free) execution flow is as follows:
The reset cause is used to decide which actions to take. The user can configure how to process a reset caused by the watchdog when the test is in the "ok" state, i.e., CLASSB_ACTIONS_2_WDT(), or what to do for brown-out or software reset, i.e., CLASSB_ACTIONS_3_WDT().
The real time counter (RTC) is used as an independent clock source, which is necessary for checking the timing of the oscillator used by the WDT.
References CLASSB_ACTIONS_WDT_OTHER_FAILURE, CLASSB_ACTIONS_WDT_RUNTIME_FAILURE, classb_error, CLASSB_ERROR_HANDLER_WDT, CLASSB_ERROR_NONE, classb_rtc_count, CLASSB_WDT_MAX, CLASSB_WDT_MIN, CLASSB_WDT_PER, CLASSB_WDT_RTC_PER, classb_wdt_teststate, CLASSB_WDT_WPER, FAULT_WDT, rtc_is_busy, RTC_TEST, RTC_TEST_OVFIF_bm, RTC_TEST_START_bm, TEST_WDT_1, TEST_WDT_2, TEST_WDT_3, TEST_WDT_OK, vbat_init(), and wdt_reset.
|
static |
|
static |
Delay for us microseconds.
us | number of microseconds to busy wait |
References sysclk_get_cpu_hz().
Referenced by vbat_init().
|
static |
RTC32 Initialization.
This function initializes the VBAT module and enables the oscillator used by the RTC32.
References udelay().
Referenced by classb_wdt_test().
NO_INIT volatile uint16_t classb_rtc_count |
Number of RTC periods in a WDT period.
Referenced by classb_wdt_test().
NO_INIT volatile classb_preinit_teststate_t classb_wdt_teststate |
WDT test state.
Referenced by classb_wdt_test().