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. Watchdog Reset occurs randomly in MK70FN1M0VMJ12.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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. Watchdog Reset occurs randomly in MK70FN1M0VMJ12.

Jump to solution
1,576 Views
navinarsavad
Contributor II

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;

}

0 Kudos
1 Solution
1,008 Views
apanecatl
Senior Contributor II

Usually when the watchdog resets during the refresh process is because the registers are not written within the 128 clock cycle period the module allows for the second register to be written after the first has already been written.

View solution in original post

0 Kudos
5 Replies
973 Views
Oleksii
Contributor I

Would you be so kind to share the formula to calculate  WDOG_TOVALL to be around 4 seconds. I mean value of 0x02ff. I`m newbie. Not everything clear for me. Thank you.

0 Kudos
1,009 Views
apanecatl
Senior Contributor II

Usually when the watchdog resets during the refresh process is because the registers are not written within the 128 clock cycle period the module allows for the second register to be written after the first has already been written.

0 Kudos
1,008 Views
navinarsavad
Contributor II

Yes you are right. I had a couple of interrupts running at high speed, and I am pretty sure that they were causing this problem. In MK70FN1M0VM the refresh cycle must be completed in 20 bus cycles, so now I have made sure that there are no interrupts while watchdog is refreshing. Thanks for your help!! :smileyhappy:

0 Kudos
1,008 Views
lieven
Contributor II

Hi Navinar,

I use a K61@150MHz in similar conditions with similar problems, though only on starting the WDOG (and very rarely on stopping).

I applied your watchdog_delay(1) function and indeed, the frequency of resets caused by starting the WDOG decreased. Using 2 decreased the resets still further.

May I ask how you determined the number of counts to execute in watchdog_delay, or was it purely experimental?

Regards

Lieven

0 Kudos
1,008 Views
navinarsavad
Contributor II

Hi Lieven,

   I have provided that delay because there is supposed to be a delay period of 1 bus cycle after unlocking the watchdog register before we write to the configuration register as per the datasheet. If you are using my delay function then I daresay watchdog_delay(1) should be enough. The reason that you are experiencing frequent resets might be because some interrupt could be occuring between the write operation of the two unlock registers. You have to write the second unlock register within 20 bus cycles after you have written the first, and if something interrupts this process then time might go beyond 20 bus cycles and the watchdog reset occurs. Try to make your code atomic during the init function, unlocking and writing to the configuration register. I hope this answers your question.

Regards,

Navinar

0 Kudos