Microchip® Advanced Software Framework

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Watchdog Timer Test

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:

  1. CLASSB_ACTIONS_1_WDT() sets up the WDT for the main application,
  2. CLASSB_ACTIONS_2_WDT() processes systems resets caused by a working WDT.
  3. CLASSB_ACTIONS_3_WDT() deals with other reset causes, e.g. brown-out or software reset.

In addition to the error handler and configurable actions, the user should configure the WDT periods CLASSB_WDT_WPER and CLASSB_WDT_PER.

Note
The WDT should be left enabled by this test and be active at all times. There are a number of Class B tests that can potentially take longer time than a WDT, see for example CRC Tests. If this is the case, a possible solution would be to increase the WDT period before the Class B test and decrease it afterwards.

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

Attention
These should not be modified by user!
#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:

  • if PER == 0, only one third of the interrupts are generated
  • if PER == 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.

__always_inline bool rtc_is_busy (   void)    rtc32_is_busy()

Compatibility macro for RTC32.

Referenced by classb_wdt_test(), rtc_init(), and rtc_set_time().

Enum of valid test states for the WDT test.

Enum of valid test states for the WDT test.

Enumerator
FAULT_WDT 
TEST_WDT_1 
TEST_WDT_2 
TEST_WDT_3 
TEST_WDT_OK 

void classb_wdt_test ( void  )

Perform self-diagnostic test of watchdog timer (WDT).

Basically this functions tests the following:

  1. that WDT issues a system reset after timeout.
  2. the WDT timing and that it can be reset.
  3. that WDT issues a system reset if it is untimely reset in window mode.

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:

  1. Power-on or external reset has occurred.
  2. Check that WDT can issue a system reset. Set test state 1 then issue a system reset.
  3. Check that WDT can be reset. Set test state 2 then issue a system reset.
  4. Check that window mode works correctly. Set test state 3 then issue a system reset.
  5. Set up WDT according to settings, i.e., CLASSB_ACTIONS_1_WDT(). Set test state "ok" and continue to main().

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.

Note
This test is executed before the main function. The method to achieve this depends on the specific compiler that is used.

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, counter, 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 __always_inline bool rtc32_is_busy ( void  )
static

Check if RTC32 is busy synchronizing.

Return values
trueIs busy
falseIs ready

References RTC32.

static void udelay ( uint16_t  us)
static

Delay for us microseconds.

Parameters
usnumber of microseconds to busy wait

References sysclk_get_cpu_hz().

Referenced by vbat_init().

static void vbat_init ( void  )
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().