2 Replies Latest reply on Nov 16, 2018 10:00 AM by JoGr_3357391

    How to reset WDT in PSoc 4200?

    JoGr_3357391

      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.

        • 1. Re: How to reset WDT in PSoc 4200?
          JoGr_3357391

          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.

          • 2. Re: How to reset WDT in PSoc 4200?
            JoGr_3357391

            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(;;){};