Hi All ,
I have been trying to implement Watchdog in MK70FN1M0VMJ12 (the controller in K70 tower board) for the past week, and I am referring to the Software watchdog, not the External Watchdog Monitor. The reference portion to the software watchdog is available in the controller's reference manual Pg 611(the 2259 page manual). I am initializing the watchdog timer at startup in the disabled state, setting the ALLOWUPDATE bit as I need to enable and disable it at specific times as I need the watchdog to monitor my task only during a specific time. The watchdog runs using the LPO clock (1 Khz), and it works without any issues 90 percent of the time. I have set the refresh period for around 4 seconds, but am periodically refreshing it at a rate of .5 - 2 seconds max. I am not using any timer interrupt for refreshing the watchdog, but rather I have provided the refreshing function intermittently throughout the code where I want the monitor task to work. During the 10 percent of the time, the watchdog is resetting randomly, mostly during the time I refresh the watchdog timer, or when I enable the watchdog timer. I am posting the watchdog timer init, enable and disable routines here. I would appreciate it if someone can help me with my problem.
#include <mqx.h>
#include <bsp.h>
#include <watchdog.h>
#include "watchdog_timer.h"
#include "Hw_Init.h"
//MQX_TICK_STRUCT ticks;
LWSEM_STRUCT shutdown_sem;
uint8_t watchdog_timer_status = WATCHDOG_TIMER_ON;
/*FUNCTION*------------------------------------------------------
*
* Function Name : watchdog_timer_init
* Returned Value :
* Comments :
* Clock: PLO
*END*-----------------------------------------------------------*/
void watchdog_timer_init(void)
{
_int_disable(); /./Enter atomic mode: Disable all interrupts.
watchdog_unlock();
watchdog_delay(1); //One bus cycle delay after unlocking is required for updating the configuration register.
WDOG_TOVALH = 0x0000;
WDOG_TOVALL = 0x02FF; //Corresponds to around 4 sec delay
WDOG_STCTRLH = WDOG_STCTRLH_DISTESTWDOG_MASK | WDOG_STCTRLH_ALLOWUPDATE_MASK ; // Disabled functional test, and set the allowupdate mask to enable unlocking // the registers later for enabling and disabling watchdog timer later. The enable mask is not set during initialization so it starts in a disable state.
WDOG_WINL = WDOG_WINH = 0; // Window mode is not used.
_int_enable(); //Enable interrupts to exit atomic mode
_time_delay(4); //Provide 4ms delay - not required but as a safety measure
}
void watchdog_enable(void)
{
if(watchdog_timer_status == WATCHDOG_TIMER_ON)
{
watchdog_delay(60);
_int_disable();
watchdog_unlock();
watchdog_delay(1);
WDOG_STCTRLH |= WDOG_STCTRLH_WDOGEN_MASK; //Enable watchdog
_int_enable();
printf("\n\n Watchdog Timer Enabled and Timer Started!!!");
}
else
printf("\nEnable the watchdog_timer_status bit to enable watchdog timer!!!");
}
void watchdog_disable(void)
{
if(watchdog_timer_status == WATCHDOG_TIMER_ON)
{
/* First unlock the watchdog so that we can write to registers */
watchdog_delay(60);
_int_disable();
watchdog_unlock();
watchdog_delay(1);
WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK; //Disable watchdog
_int_enable();
watchdog_delay(20);
printf("\n\n WATCHDOG TIMER DISABLED!!!");
}
else
printf("\nEnable the watchdog_timer_status bit to disable watchdog timer!!!");
}
void watchdog_unlock(void)
{
// _int_disable();
WDOG_UNLOCK = 0xC520;
WDOG_UNLOCK = 0xD928;
// _int_enable();
}
/*
* A sequence of 0xA602 followed by 0xB480 within 20 bus clock cycles when
* written to this register, refreshes the WDOG and prevents it from resetting the system. Writing a value
* other than the above mentioned sequence or if the sequence is longer than 20 bus cycles, resets the
* system or if IRQRSTEN is set, it interrupts and then resets the system).
*/
void watchdog_refresh(void)
{
if(watchdog_timer_status == WATCHDOG_TIMER_ON)
{
_int_disable();
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
_int_enable();
}
else
printf("\nEnable the watchdog_timer_status bit to refresh watchdog timer!!!");
}
void watchdog_delay(uint16_t nCount)
{
uint16_t delay = 0;
for (delay=0;delay<nCount*10;delay++)
{
NULL;
}
return;
}