How to reset WDT in PSoc 4200?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JoGr_3357391
Level 4
Level 4
10 likes given 5 likes given First like received

There are a number of examples that work OK. Watchdog_PSoc4_Example is a great example on how to set up the WDT, and it dutifully resets the processor after six timers interrupts on Timer0:

/* Setup ISR for interrupts at WDT counter 0 events. */

    WdtIsr_StartEx(WdtIsrHandler);

    /* Enable global interrupts. */

    CyGlobalIntEnable;

     /* Set WDT counter 0 to generate interrupt on match */

     CySysWdtWriteMode(CY_SYS_WDT_COUNTER0, CY_SYS_WDT_MODE_INT);

     CySysWdtWriteMatch(CY_SYS_WDT_COUNTER0, WDT_COUNT0_MATCH);

     CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER0, 1u);

     /* Enable WDT counters 0 and 1 cascade */

     CySysWdtWriteCascade(CY_SYS_WDT_CASCADE_01);

   

     /* Set WDT counter 1 to generate reset on match */

     CySysWdtWriteMatch(CY_SYS_WDT_COUNTER1, WDT_COUNT1_MATCH);

     CySysWdtWriteMode(CY_SYS_WDT_COUNTER1, CY_SYS_WDT_MODE_RESET);

    CySysWdtWriteClearOnMatch(CY_SYS_WDT_COUNTER1, 1u);

     /* Enable WDT counters 0 and 1 */

     CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK | CY_SYS_WDT_COUNTER1_MASK);

     /* Lock WDT registers and try to disable WDT counters 0 and 1 */

     CySysWdtLock();

     CySysWdtDisable(CY_SYS_WDT_COUNTER1_MASK);

     CySysWdtUnlock();

As I understand it, a Timer0 match increments Timer1, and when Timer1 gets a match, the processor is reset. I get the requisite number of interrupts before the reset occurs, so I think I get the concept.

I cannot find a description of how to keep the WDT from firing, but it seems that

CySysWdtResetCounters( CY_SYS_WDT_COUNTER1);

in the main loop should do the trick, presuming, of course, that my understanding of the timer relationships is correct, and that I hit it often enough.

That does not appear to work, or something else is going awry.

Am I close?

I'm having a bear of a time debugging as the debugger keeps detaching, which I suppose could be something to do with the WDT, as if I comment out the WDT code, the debugger behaves more rationally.

0 Likes
1 Solution

OK. I finally futzed around with this enough to get it "working".

I don't have a WCO, so ILO feeds LFCLK, which drives Timer0 (65535 divider = ~2 seconds).

Prior to the main loop,

CySysWdtEnable( CY_SYS_WDT_COUNTER0_MASK);

In the main loop:

CySysWatchdogFeed(CY_SYS_WDT_COUNTER0);

I have test code that allows me to push a button to enter a for(;;), and the watchdog trips after ~2 seconds.

So, several days have been spent getting half a dozen lines of code to work. But it's a matter of picking the right half dozen lines of code!

The test code that I got to work ( and ported to my project) is:

int main(void)

{

  uint32 x = 0;

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

  CyGlobalIntEnable;

  CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK);

  if(CySysGetResetReason(CY_SYS_RESET_WDT) == CY_SYS_RESET_WDT )

  {

    CySysWdtDisable(CY_SYS_WDT_COUNTER0_MASK);

    LED_R_ON(); // turn on the red LED

    while(1);     // hang

  }

  for( int i = 0; i < 20; i++)

  {

      LED_B_Write( x & 1);     //     Toggle the Blue LED so we know something's going on

      x++;

      // If you don't feed the WDT it will cause a reset in ~3 seconds

      CySysWatchdogFeed(CY_SYS_WDT_COUNTER0);

      CyDelay(500);

  }

  /*  NOW it will hang, and in about 3 seconds, the

      Watchdog will fire and the red LED will blink.  */

  for(;;){};

View solution in original post

0 Likes
2 Replies
JoGr_3357391
Level 4
Level 4
10 likes given 5 likes given First like received

Further study reveals that the correct call is to CySysWatchdogFeed(), which does call CySysWdtResetCounters(), but with a different register ID, so I was kind of close.

Still working on it, but gaining a bit of ground.

0 Likes

OK. I finally futzed around with this enough to get it "working".

I don't have a WCO, so ILO feeds LFCLK, which drives Timer0 (65535 divider = ~2 seconds).

Prior to the main loop,

CySysWdtEnable( CY_SYS_WDT_COUNTER0_MASK);

In the main loop:

CySysWatchdogFeed(CY_SYS_WDT_COUNTER0);

I have test code that allows me to push a button to enter a for(;;), and the watchdog trips after ~2 seconds.

So, several days have been spent getting half a dozen lines of code to work. But it's a matter of picking the right half dozen lines of code!

The test code that I got to work ( and ported to my project) is:

int main(void)

{

  uint32 x = 0;

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */

  CyGlobalIntEnable;

  CySysWdtEnable(CY_SYS_WDT_COUNTER0_MASK);

  if(CySysGetResetReason(CY_SYS_RESET_WDT) == CY_SYS_RESET_WDT )

  {

    CySysWdtDisable(CY_SYS_WDT_COUNTER0_MASK);

    LED_R_ON(); // turn on the red LED

    while(1);     // hang

  }

  for( int i = 0; i < 20; i++)

  {

      LED_B_Write( x & 1);     //     Toggle the Blue LED so we know something's going on

      x++;

      // If you don't feed the WDT it will cause a reset in ~3 seconds

      CySysWatchdogFeed(CY_SYS_WDT_COUNTER0);

      CyDelay(500);

  }

  /*  NOW it will hang, and in about 3 seconds, the

      Watchdog will fire and the red LED will blink.  */

  for(;;){};

0 Likes