- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Solved! Go to Solution.
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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(;;){};
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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(;;){};