How to disable WDOG on FRDM-KE04Z board?

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

How to disable WDOG on FRDM-KE04Z board?

Jump to solution
2,000 Views
dalewheat
Contributor II

I'm trying to disable the watch dog timer (WDOG) on the FRDM-KE04Z board.  My code writes a 0x00 to the WDOG_CS1 register right after boot and even reads it back and confirms it as 0x00 to verify the write occurred.

However, the chip resets predictable about 4ms later with a '1' in the WDOG bit of the SIM_SRSID register, telling me that the reset was caused by a watchdog timer event.

If I add a watchdog reset sequence to my wait loops, the problem goes away, but I'd rather just turn the WDOG off altogether and have it stay off.

I've read everything I can find on the WDOG, including the device reference manual and many examples for other Kinetis devices.

If I single-step my program using the debugger, it works fine.  It's only when I let it free-run from either a power-on or from pressing the reset button on the board that the WDOG fires.

Any ideas what I might be doing wrong or overlooking?  Any help is appreciated.

Labels (1)
0 Kudos
1 Solution
1,479 Views
mjbcswitzerland
Specialist V

Dale

To disable the KE04 watchdog you need to do:

UNLOCK_WDOG();              // open a window to write to watchdog
WDOG_CS2 = 0;               // this is required to disable the watchdog
WDOG_TOVAL = 0xffff;
WDOG_WIN = 0;
WDOG_CS1 = WDOG_CS1_UPDATE; // disable watchdog but allow updates

where
WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_1; WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_2
and
#define WDOG_UNLOCK_SEQUENCE_1  0x20c5 // unlock and re-trigger sequences must be performed with two writes within 16 bus clock
#define WDOG_UNLOCK_SEQUENCE_2  0x28d9

Regards

Mark

For trouble-free KE04 see http://www.utasker.com/kinetis.html

View solution in original post

0 Kudos
10 Replies
1,479 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Dale Wheat,

      WDOG_CS1[EN] is the write once bit after reset.

     After reset, the WDOG_CS1[EN] =1, the watchdog is enabled in default.

     So, please check your start code, did you enable the watchdog again in the start code?

     You can free run to main, then check WDOG_CS1[EN] bit, whether it is 1 or 0, if it is 1, it means you didn't write 0x00 to your WDOG_CS1 successfully, or it is wrote before you write 0x00.

    Please check your code carefully again, if you still have problem, please refer to the official project which can be downloaded from this link:

FRDM-KEXX Driver Library Package 

  void start(void)
{

    /* Disable the watchdog timer but enable update */
    WDOG_DisableWDOGEnableUpdate();    
    
#ifndef __GNUC__
#ifndef KEIL
    /* Copy any vector or data sections that need to be in RAM */
    common_startup();
#endif
#endif

    /* Jump to main process */
    main();

    /* No actions to perform after this so wait forever */
    while(1);
}

void WDOG_DisableWDOGEnableUpdate(void)
{
    uint8_t u8Cs1 =  WDOG->CS1;  
    uint8_t u8Cs2 =  WDOG->CS2;  
    uint16_t u16TOVAL =  WDOG->TOVAL;  
    uint16_t u16WIN =  WDOG->WIN;  

    u8Cs1       &= ~WDOG_CS1_EN_MASK;
    u8Cs1       |= WDOG_CS1_UPDATE_MASK;

    /* First unlock the watchdog so that we can write to registers */
    WDOG_Unlock();
    WDOG->CS2    =  u8Cs2;
    WDOG->TOVAL  =  u16TOVAL;
    WDOG->WIN    =  u16WIN;
    WDOG->CS1    =  u8Cs1;
}

Wish it helps you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,479 Views
dalewheat
Contributor II

@kerry:  Another bingo!  Your method also works to disable the WDOG, while carefully preserving the previous WDOG configuration.  I modified your code to fit my present system:

 uint8_t save_cs1 = WDOG_CS1;
 uint8_t save_cs2 = WDOG_CS2;
 uint16_t save_toval = WDOG_TOVAL;
 uint16_t save_win = WDOG_WIN;
 
 save_cs1 &= ~WDOG_EN; // clear WDOG enable bit
 save_cs1 |= WDOG_UPDATE; // set UPDATE bit
 
 WDOG_CNT = 0x20C5; // unlock sequence 1/2
 WDOG_CNT = 0x28D9; // unlock sequence 2/2
 WDOG_CS2 = save_cs2;
 WDOG_TOVAL = save_toval;
 WDOG_WIN = save_win;
 WDOG_CS1 = save_cs1;

Just like Mark's answer, the method does not work if the writes to the CS2 and TOVAL registers are omitted.  I'm still not sure why this is the case, and I don't see in the documentation where this is explained.  I think this peripheral has evolved over time and some of the details might be lost in the mists of the ages.

Thank you for your help.  This single issue had almost turned me against using these devices.

What I find amusing is that now that I know how to disable the watchdog timer, I find that I now want to use it, having already incorporated the reset code into my blocking routines.  At least now I have an option!

0 Kudos
1,479 Views
mjbcswitzerland
Specialist V

Dale

If you do start using the watchdog beware of a further possible confusion due to a documentation error:

https://community.nxp.com/message/417610 

Also try to avoid blocking code since it is both inefficient and, when retriggering the watchdog, could block for an unwanted reason yet not cause a watchdog timeout (unsafe).

Regards

Mark

0 Kudos
1,479 Views
dalewheat
Contributor II

While that might apply to the KE02 (I can't check that now), it does not seem to apply to the KE04 I am testing today.

I use 16 bit accesses to read and write the WDOG_CNT, WDOG_TOVAL and WDOG_WIN registers.  My register access method is this:

#include <stdint.h>

// macros for direct register accesses

#define REG(address) (*((volatile uint32_t *) (address))) // generic 32 bit-aligned access
#define REG16(address) (*((volatile uint16_t *) (address))) // special 16 bit-aligned access
#define REG8(address) (*((volatile uint8_t *) (address))) // special 8 bit-aligned access

I use the REG16() macro to define the addresses of the 16 bit WDOG registers:

// WDOG

#define WDOG_CS1 REG8(0x40052000) // control and status register 1
#define WDOG_UPDATE (1<<5) // 1=allow updates
#define WDOG_EN (1<<7) // watchdog enable 0=disable 1=enabled
#define WDOG_CS2 REG8(0x40052001) // control and status register 2
#define WDOG_CNTH REG8(0x40052002) // counter register high
#define WDOG_CNTL REG8(0x40052003) // counter register low
#define WDOG_CNT REG16(0x40052002) // 16 bit watchdog timer counter
#define WDOG_TOVALH REG8(0x40052004) // time out value high
#define WDOG_TOVALL REG8(0x40052005) // time out value low
#define WDOG_TOVAL REG16(0x40052004) // 16 bit timeout value
#define WDOG_WINH REG8(0x40052006) // window value low
#define WDOG_WINL REG8(0x40052007) // window value high
#define WDOG_WIN REG16(0x40052006) // 16 bit window start value

If the warning expressed in the linked "Confusion..." post were true, my WDOG refreshes would not work, but they do:

void reset_wdog(void) {

 // reset watchdog timer to prevent reset

 WDOG_CNT = 0x02A6; // reset sequence 1/2
 WDOG_CNT = 0x80B4; // reset sequence 2/2
}

I don't swap the high and low bytes, and I don't use 8 bit accesses.  It still seems to work.  Also, I can write 0xFFFE to the WDOG_TOVAL register and it reads back correctly - not swapped.

I did find that this 16 bit access method did not work for setting the baud rate divisor register for the UART, and went back to double 8-bit accesses.

I have tried this in both IAR 7.8.3.12146 and Atollic TrueSTUDIO Lite 7.0.1 with the same results.

I agree with you on the point you make about blocking code.  This is being used in very simple proof-of-concept code and should not see production release.

I still don't understand why the WDOG_CS2 and WDOG_TOVAL registers have to be written as part of the WDOG disable procedure.  I don't _have_ to know.  I'd just _like_ to know.  Any thoughts?

0 Kudos
1,479 Views
mjbcswitzerland
Specialist V

Dale

This applies to all KE and KEA devices.

- The reset sequence that you use works because the bytes in its value are already swapped (the value in the data sheet is correct for 16 bit accesses)
- Writing and reading will always result in the written value being returned (it is not a test of whether the storage is little or big endian)

From the KE04 manual:

pastedImage_18.png

I have no idea why the writer prefers 8 bit read/writes (possibly they can't work out how to swap bytes???)

However the manuals still have the reported error: since the manual's own note is not respected....

pastedImage_20.png

If you want to check, write WDOG_TOVAL = 1000, which you would think gives a 1s watchdog time out. It will give about 1 minute. Then change to WDOG_TOVAL = (unsigned short)((1000 >> 8) | (1000 << 8)); and you will see that it then correctly gives 1s.

I have tested on KE02 [20 and 40MHz parts], KE04, KE06, KEA08, KEA32, KEA64, KEA128 (using KDS, CW, S32, IAR, uVision, Atollic, Rowley Crossworks, CooCox, Green Hills and GCC makefile) and found the same in each case.

I can't explain why the WDOG_S2 write is needed. I wrote the code a few years ago and apart from the note about it being "needed" I don't remember the details. Probably it was found through trial and error (like working out the example's timeout error) since there is nothing specific in the manual.

Regards

Mark

0 Kudos
1,479 Views
dalewheat
Contributor II

Mark,

Already swapped?  That's convenient.  Also, in the long run, quite confusing.

As long as I can get the device to do my modest bidding, I'm happy with it.

Now I wonder what other "features" are hidden in the documentation.

I appreciate your help with this issue.

0 Kudos
1,479 Views
mjbcswitzerland
Specialist V

Dale

The KE/KEA series look to be intended to wean 8-bit users onto 32 bit processors. Much of the documentation is written as if the chip were 8 bit (some peripherals have indeed been taken from previous big-endian 8-bit chips) and also the GPIO ports are named as if they were 8 bit, even though they are in fact full 32 bit impementations.

In most cases this doesn't really matter but in some it complicates and confuses:

- for example the watchdog text gives values for 16 bit writes that respect the fact that the underlying HW is big-endian. No problem as long as all writes are 16 bits (and there is no reason why they shouldn't be) but the same confusion would occur if someone decided to write these values as two bytes writes since they would probably do it wrong the first time (and maybe lose a day or two of work in the process)

- the port naming convention is "Horrible" since it makes code compatibility between K (or KL, KV, KM, KW) parts and KE/KEA quite a challenge whereby if 32 bit naming had been used it would have been simple because the underlying HW is almost identical...

Regards

Mark

0 Kudos
1,479 Views
dalewheat
Contributor II

Mark,

This is the sort of information that really helps me understand the product.  As a technical writer, I understand about the life cycle of technical documents.  It's often much easier to cut & paste the old stuff into the new stuff, than to take the time to do a proper job of it.  Your insight is appreciated.

0 Kudos
1,480 Views
mjbcswitzerland
Specialist V

Dale

To disable the KE04 watchdog you need to do:

UNLOCK_WDOG();              // open a window to write to watchdog
WDOG_CS2 = 0;               // this is required to disable the watchdog
WDOG_TOVAL = 0xffff;
WDOG_WIN = 0;
WDOG_CS1 = WDOG_CS1_UPDATE; // disable watchdog but allow updates

where
WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_1; WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_2
and
#define WDOG_UNLOCK_SEQUENCE_1  0x20c5 // unlock and re-trigger sequences must be performed with two writes within 16 bus clock
#define WDOG_UNLOCK_SEQUENCE_2  0x28d9

Regards

Mark

For trouble-free KE04 see http://www.utasker.com/kinetis.html

0 Kudos
1,479 Views
dalewheat
Contributor II

@mark:  Bingo!  I modified your code to fit my programming paradigm but it works perfectly:

 WDOG_CNT = 0x20C5; // unlock sequence 1/2
 WDOG_CNT = 0x28D9; // unlock sequence 2/2
 WDOG_CS2 = 0; // ???
 WDOG_TOVAL = 0xFFFF;
 WDOG_WIN = 0;
 WDOG_CS1 = WDOG_UPDATE; // disable now but allow updates later

I'm left wondering why WDOG_CS2 has to be cleared?

Also, I can omit the write to the WDOG_WIN register and it still works OK, but the writes to the TOVAL or CS2 registers seem to be required.

This dog is a tricky beast.

Thanks for your help.