MCU: MK20DX128VLH5
Maskset: 1N86B
I'm trying to use the internal watchdog of a Kinetis K20, sourced from the LPO clock. My WDOG refresh operations seem to have no effect when I use the LPO clock, but if I use the Bus clock the refresh works fine. I've boiled my application down to a simple bare-metal C program generated by CodeWarrior, shown below. If PET_THE_DOG == 0, then both bus clock and LPO clock variations cause a reset in a few seconds. If PET_THE_DOG ==1, then the bus clock variation does not reset but the LPO clock variation still does reset.
I've seen some other discussions about a similar problem, but no resolution that's worked for me. Anybody know why the WDOG is treating the refresh differently when I run from the LPO clock?
void delay(int n)
{
for (; n > 0; --n) {
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");
}
}
# define WDOG_LPO_CLOCK 1
# define PET_THE_DOG 1
int main(void)
{
__asm("CPSID i"); // Disable interrupts
// Unlock watchdog for write-once register access
WDOG_UNLOCK = 0xC520;
WDOG_UNLOCK = 0xD928;
#if WDOG_LPO_CLOCK == 1
// Enable WDOG with 1kHz LPO clock
WDOG_PRESC = WDOG_PRESC_PRESCVAL(0);
WDOG_TOVALH = (3000 >> 16);
WDOG_TOVALL = (3000 & 0xFFFF);
// STCTRLH : WAITEN=1, STOPEN=1, ALLOWUPDATE=1, CLKSRC=0, WDOGEN=1
WDOG_STCTRLH = 0x1D1;
#else
// Enable WDOG with 21MHz FEI clock
WDOG_PRESC = WDOG_PRESC_PRESCVAL(3);
WDOG_TOVALH = (21000000 >> 16);
WDOG_TOVALL = (21000000 & 0xFFFF);
// STCTRLH : WAITEN=1, STOPEN=1, ALLOWUPDATE=1, CLKSRC=1, WDOGEN=1
WDOG_STCTRLH = 0x1D3;
#endif
__asm("CPSIE i"); // Enable interrupts
// Loop here. Periodically pet the WDOG.
while(1) {
#if PET_THE_DOG == 1
WDOG_REFRESH = 0xA602;
WDOG_REFRESH = 0xB480;
#endif
delay(1000);
}
}
解決済! 解決策の投稿を見る。
Hi Guys,
This maybe a common issure for using LPO as watchdog clock source. The refresh logic in current watchdog implementation, it will take 2-3 WDOG clock to sync refresh command to watchdog coutner domain. For bus clock as the coutner source, it will be 2-3 bus clock with watchdog prescaler set to 1; however, for LPO, it will be 2-3 LPO clock. You know that it is 2-3 ms, very very long time than bus clock situation. In your case, the program is keeping issue refresh clock, and refresh logic keeping sync the comand, and finally, there is no refresh command synced to coutner domain, watchdog timeeout. You must refresh watchdog with the interval longer than the sync time, it is the design requirment.
In your case, please try to use delay() function with a larger value, it should work.
Thanks,
Sandy
Thanks to everyone for the responses. I submitted a service request to Freescale regarding this issue and they gave me a copy of the validation code for the watchdog module in Kinetis K devices. It included a test with these comments:
/*********STARTFUNC**************************************************
* Name: watchdog_enable_in_lpoclk
* Purpose: To verify the bug fix IPGear ticket 20832 .
* Algorithm:
* Inputs: NONE
* Outputs: NONE
* Return value: NONE
* Assumptions : NONE
* Child Functions used: NONE
* PASS Criteria: global_fail_count == 0, global_pass_count==0xC
***********ENDFUNC***************************************************/
//The root cause is that update information need 2-3 watchdog clock synchronized to watchdog counter domain.
//and lpo clock is 1KHZ, divide by 5 to generate watchdog counter clock
//it need 10 ms to synchronize this to watchdog clock domain
//usd ptd10 toggle to check this time gap.
I think this is the same 2-3 watchdog counter domain cycles suggested by zhaohuiliu. I tried adding delay of at least 2-3 counts of the LPO clock between refresh attempts and that solved my problem. In terms of my bus clock, this required that I add a delay of 200,000 bus clock cycles to my application's main loop, in order to make use of the LPO clock.
I've gone back through the "K20 Sub-Family Reference Manual" to try to find some mention of this 2-3 LPO cycle design requirement. The closest thing I've found is in Section 23.9 "Restrictions on watchdog operation":
"You must take care not only to refresh the watchdog within the watchdog timer's actual time-out period, but also provide enough allowance for the time it takes for the refresh sequence to be detected by the watchdog timer, on the watchdog clock."
If this is the section of the reference manual that describes the design requirement, then I think it needs to be made much more clear, especially when the LPO clock is selected, which as Fred Roeber pointed out seems like the natural choice for the watchdog.
I tried to use the LPO clock because I was having trouble with initialization of the MCG and I found that, if I got stuck in a loop waiting for an MCG status bit to be set, the watchdog didn't always cause a reset if the watchdog was being clocked by the same bus clock I was trying to initialize. Using the LPO clock to drive the watchdog seemed like an ideal solution. But I don't want to add a 2-3 ms delay to my application. My MCG problem was caused by a different K20 problem and I have a workaround for that now, so I've gone back to clocking the watchdog from the bus clock.
Jim, I finally came back to this issue after getting all our other code done. I've been using the bus clock for the watchdog and finding occasional cases where our processor gets hung. Since we go into LLS power down mode a lot (which turns off the bus clock) it makes sense that this could happen. I really want/need to use the LPO timer for the watchdog. I see you posted about getting some code after my post back in October. I was wondering if there was any way I might get a look at the code as it might help me figure out what I might have been doing wrong the last time I tried to use the LPO for watchdog? Maybe email froeber@cox.net? Hopefully you will see this. Thanks. Fred
Jim, I've just been spending time too trying to get the watchdog working on a MK20DX128VLH5 processor on a Teensy3 processor board. I've done a lot of code like this but haven't used the watchdog on this particular processor before. I figured I would use the LPO clock source so I could use the watchdog if I used stop or wait power modes (I currently use LLS mode when "powered down" to conserve battery). I did everything "by the book" much as you have but I:
- added 2 nops after the unlock sequence since it's required not to write to the control register in the bus cycle following unlock
- I put interrupt lock/restore around the refresh sequence so it won't be disturbed by interrupt (which would cause reset)
At first I just did the refresh operations every time through my main loop. That resulted in getting resets due, I believe, to updates being too frequent. Then I added code to skip refreshes until the watchdog timer had counted past 10 (to make sure the timing was properly synchronized). In that case I didn't get the continuous resets I had been getting. In fact I no longer got any resets -- even when I diverted the code into an infinite loop with interrupts locked. I wasted yesterday searching online for possible solutions, checking my code, testing all sorts of theories. Nothing worked.
Figuring that using the LPO input to the watchdog was broken I switched to the Alt clock source which is the bus clock on my processor. Then everything worked just fine as expected. So that's my solution. I've concluded the LPO doesn't work with the watchdog. And I suspect someone else at Freescale knows that too because the default power up setting of the clock source bit is not 0 as would typically be expected but is '1' to select the "alternative" clock. There is no mention of any potential watchdog problem in the errata document however.
Hi Guys,
This maybe a common issure for using LPO as watchdog clock source. The refresh logic in current watchdog implementation, it will take 2-3 WDOG clock to sync refresh command to watchdog coutner domain. For bus clock as the coutner source, it will be 2-3 bus clock with watchdog prescaler set to 1; however, for LPO, it will be 2-3 LPO clock. You know that it is 2-3 ms, very very long time than bus clock situation. In your case, the program is keeping issue refresh clock, and refresh logic keeping sync the comand, and finally, there is no refresh command synced to coutner domain, watchdog timeeout. You must refresh watchdog with the interval longer than the sync time, it is the design requirment.
In your case, please try to use delay() function with a larger value, it should work.
Thanks,
Sandy
Hi Jim,
I have tested the code that you posted on a new bare-board project for K20DX128 using a FRDM-K20D50 board, and I didn’t get a Watchdog reset neither using the LPO nor the Bus Clock, if the macro PET_THE_DOG is 1.
However, the root issue could be caused by the additional interrupts that you may have in your entire project, because of an interrupt is asserted exactly between the two writes to WDOG_REFRESH register. I have simulated it by calling the delay(1); function between the two writes, and effectively, a Reset occurs.
Hope this will be useful for you.
Best regards!
/Carlos