Watchdog Timer in the PSoC® 4000 Family – KBA91373

Version: **


Question: How is the watchdog timer (WDT) in the PSoC® 4000 family different from the one in the PSoC 4100/4200 family? How do you use the PSoC 4000 WDT to generate a periodic ISR?





The PSoC 4000 family has just one 16-bit free-running up counter, as opposed to the three counters (two 16-bit & one 32-bit) for the WDT in the PSoC 4100/4200 family. The configurability of the counter is limited as well. In PSoC 4100/4200, the counters can be configured to generate a reset on the first match event, a reset on the third un-serviced match event, or just generate an interrupt on a match event without any reset. The counters can be cascaded as well. Refer to Chapter 12, “Watchdog Timer” of the PSoC 4000 Family Architecture TRM, for complete details on the WDTs present in these families.


The WDT in the PSoC 4000 family is a simple 16-bit free-running up counter which can generate an interrupt only when the counter equals the match register value. The counter does not reset to “0” on a match, instead it keeps counting up to 0×FFFF and then wraps around to “0”. It runs from the 32 kHz internal low-speed oscillator (ILO) and cannot be stopped or disabled. The interrupt generation or causing the system reset can, however, be disabled. If enabled, the system reset feature of the WDT causes the system to reset on the third un-serviced WDT match event/interrupt.

One more configurability feature offered by the WDT is the option to reduce the counter size (number of bits) from 16 bits to one bit in steps of one bit. This is achieved by making use of the IGNORE_BITS of WDT_MATCH register. Refer to Chapter 13.1, “SRSSLT Register Mapping Details” in PSoC 4000 Family PSoC® 4 Registers Technical Reference Manual (TRM) for details on the WDT registers. Table 1 below summarizes the list of key functions, which are defined in CyLib.c, that can be used to control the working of the WDT in PSoC 4000 (the same can be found in the PSoC® Creator™ System Reference Guide (cy_boot Component)).

Table 1. PSoC 4000 WDT Key Functions

     Function Name
     Disables WDT from resetting the system
     Enables WDT based system reset functionality
     CySysWdtWriteMatch(uint16 match)
     Writes the match value used for generating the WDT match interrupt, the 3rd unserviced match interrupt causes a system reset.
     uint16 CySysWdtReadMatch()
     Reads the currently set match value
     CySysWdtWriteIgnoreBits(uint8 bits)
     Writes the number of bits to ignore for the counter size. Default value of 0 leaves the counter as a 16-bit one, whereas a value of 2 will make the counter a 14-bit counter.
     uint8 CySysWdtReadIgnoreBits()
     Reads the number of bits being ignored in the counter size.
     Disables the WDT interrupt generation but not the reset feature
     Enables the WDT interrupt for CPU service.

When the WDT is enabled to perform a system reset, the time taken by the system before a reset is asserted from a stuck/hung CPU state is given as below,



The above expression assumes that the match value is written only once and not updated in between the match ISRs.

Generating periodic interrupts using the WDT:

Many applications require periodic interrupt generations for coarse-timing and wake-up purposes. This is especially true for applications that need to be low power, where the device enters sleep and is awakened by an interrupt from a low power source such as the ILO. For such applications in PSoC 4000, the only source that can generate an interrupt from the ILO is the WDT. But the WDT cannot generate a periodic ISR by default because of its free-running nature. The steps below describe a way to obtain a periodic ISR using the WDT ISR:

  1.   Write the desired match value into the match register using the API provided in Table 1. For example, 3200 for an approximately 100 ms interrupt for a 32 kHz clock.
  2.   Unmask the WDT interrupt and enable the WDT (if a system reset is desired as well).
  3.   In the WDT ISR, read the current match value (API in Table 1), add the desired match value (interrupt rate) to it and store it back in the match value register. For example, if your WDT ISR triggered at a 3200 match value, read 3200, add 3200 (for a desired ISR rate of 100 ms) to it (6400 total). Now store back 6400 to the match value register such that when the counter reaches 6400, it generates an interrupt again. Note that the counter generates a match interrupt whenever the counter value equals the match value. So changing the match value as needed in the match ISR can be used to generate periodic ISRs. The code snippet below provides a sample for generating interrupts at a rate of approximately 100 ms.

Code Snippet:

CY_ISR(WDT_ISR) {      /* Clear WDT interrupt */     CySysWdtClearInterrupt();           /* Write WDT_MATCH with current match value + desired match value */     CySysWdtWriteMatch((uint16)CySysWdtReadMatch()+3200); }int main() {      /* Write WDT_MATCH with the desired match value */     CySysWdtWriteMatch(3200);         /* Mask WDT interrupt to be available for CPU service */     CySysWdtUnmaskInterrupt();         /* Set the WDT interrupt vector to the WDT ISR*/     CyIntSetVector(4, WDT_ISR);         /* Enable WDT ISR in CPU vectors - which is caused by WDT match */     CyIntEnable(4);         /* Enable global interrupts */     CyGlobalIntEnable;         /* Application Code */}

Note: It is highly recommended to keep the WDT enabled if the power supply can produce sudden brownout events that may compromise the CPU functionality. This ensures that after a brownout that compromises the CPU functionality, the system will always recover.