Startup code provided to disable the watchdogs

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

Startup code provided to disable the watchdogs

1,061 Views
johnadriaan
Contributor III
When you create a new MCUX Managed project, it includes a number of pre-written files for you.
The file startup/startup_mimxrt1011.c defines a function ResetISR().
That function uses a #ifdef to either call CMSIS's SystemInit(), or disable the three watchdogs:
// Disable Watchdog
volatile unsigned int *WDOG1_WCR = (unsigned int *) 0x400B8000;
*WDOG1_WCR = *WDOG1_WCR & ~(1 << 2);
volatile unsigned int *WDOG2_WCR = (unsigned int *) 0x400D0000;
*WDOG2_WCR = *WDOG2_WCR & ~(1 << 2);
...
// RTWDOG (WDOG3) disable code here
  1. WDOG1 and WDOG2 are both 16-bit peripherals, yet the reads and writes are through an unsigned int *. The documentation states:
    If a 32-bit access is performed, the WDOG will not generate a peripheral bus error but will behave normally, like a 16-Bit access, making read/write possible. A 32-Bit access should be avoided, as the system may go to an unknown state.
    Surely these definitions should be unsigned short *?
  2.  To turn off WDOG1 and WDOG2, the code resets bit #2 in each WCR register.
    There's a distinction in the documentation between "write once" and "write one once":
    The former means "Only the first write, of 0 or 1, will succeed. After that it cannot be changed."
    The latter means "You can write 0 as often as you like - but once a 1 is written, it cannot be set back to 0."
    According to the documentation, bit #2 (the WDE "WatchDog Enable" bit) is
    "a write one once only bit. It is not possible to clear this bit by a software write, once the bit is set."

In other words, the above code is completely pointless: either it's already 0, or it's a 1 and can't be changed back to 0. Worse, other bits in those registers are write once - WDW, WDBG and WDZST - and this code has just written to them.

Or am I misunderstanding the documentation?
Tags (2)
0 Kudos
2 Replies

932 Views
johnadriaan
Contributor III

I've now had a chance to look at the next Watchdog disable code, that of RTWDOG (WDOG3). This is a 32-bit peripheral rather than the above 16-bit ones, and has a different register set.

The code to disable the RTWDOG is directly after the above quoted code, where I put the comment

...
// RTWDOG (WDOG3) disable code here

Let's take a look at that code:

// Write watchdog update key to unlock

*((volatile unsigned int *)0x400BC004) = 0xD928C520;
// Set timeout value
*((volatile unsigned int *)0x400BC008) = 0xFFFF;
// Now disable watchdog via control register
volatile unsigned int *RTWDOG_CS = (unsigned int *) 0x400BC000;
*RTWDOG_CS = (*RTWDOG_CS & ~(1 << 7)) | (1 << 5);

To safeguard the Watchdog against inadvertent access, the registers are disabled until an unlock sequence is written to the CNT register (@ 0x400BC004). Actually, according to the documentation it's more involved than that:

  • RTWDOG is started at system reset with a default configuration.
  • Within 255 bus clocks of that Reset, you can change that configuration - once. Most of the bits are marked "Write Once" for that very reason. Since that is very early on in the boot sequence, the Boot ROM has to quickly choose a configuration for the Watchdog - if it didn't, the default configuration would become permanent until the next Reset.
  • Since that's not very friendly, the RTWDOG offers the UPDATE bit. During that single write above, the Boot ROM can set UPDATE to 1. If it leaves it at zero, then that configuration is permanent until the next Reset. If it sets it to one, then future code is allowed to unlock the RTWDOGs described below.

I have confirmed that the Boot ROM does indeed set the UPDATE bit, although I have a question in to confirm what else it sets. According to the documentation, to unlock the RTWDOG you need to write a specific sequence to CNT, and there are three options:

  1. The four bytes 0x20 0xC5 0x28 0xD9 in that order;
  2. The two half-words 0xC520 0xD928 in that order;
  3. The single word 0xD928C520.

The above provided code decided to use Option 3 - but again there's a complication! Before you can use Option 3, you need to tell the RTWDOG that you're going to do so by enabling the (write-once) CMD32EN bit:

13

CMDEN

Enables or disables WDOG support for 32-bit (otherwise 16-bit or 8-bit) refresh/unlock command write words.
This is write-once field, and the user needs to unlock WDOG after writing this field for reconfiguration.
0b - Disables support for 32-bit refresh/unlock command write words. Only 16-bit or 8-bit is supported.
1b - Enables support for 32-bit refresh/unlock command write words. 16-bit or 8-bit is NOT supported.

Note that if 32-bit is enabled, then 8-bit and 16-bit is disabled! And since it's write-once, whatever the Boot ROM wrote when it set UPDATE is what is needed to be used to unlock it later. I assume it can be changed - but only after it is unlocked correctly.

So, I read RTWDOG[CS] to find out the current state of the UPDATE and CMDEN bits. Luckily, UPDATE is 1. Unfortunately, CMD32EN is 0. Therefore, the above provided code is also incorrect - and I haven't the faintest idea of the implications of "is NOT supported": is the code merely a NOP? And all the reconfiguration code too? Or could it cause a bus fault sometimes?

0 Kudos

932 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi John,

WDOG1 and WDOG2 is default disable. So, SystemInit() won't write WCR. User can write it.
RTWDOG->CMD32EN default is 1. I checked this value in RTWOG demo. It isn't changed by ROM bootloader. It is still 1.

Regards,

Jing

0 Kudos