hints for using '#const _wdt_type', option WDT, and system
Posted: Mon Jul 06, 2015 2:48 pm
The new SystemConvert utility adds a '#const _wdt_type' to the device files that can be used to determine the proper watchdog config type for the device.
note: the K40 devices add a new wdt config type, so now it's 'config WDT/WDTE/WDTEN'
Here's the settings and their meanings:
What would you do with that? Several existing modules were written before WDTEN existed, and have to be modified to account for the changing config bit name in more recent devices.
For example, here's the code from the existing System.bas module:
As you can see, there's a device-specific check to determine using 'Config WDTEN' vs 'Config WDT', and it only works for the 18F66J16.
Note: don't confuse '#option WDT' with 'Config WDT'... they're two different things. The '#option WDT' is a boolean true/false value. The compiler checks this value to determine if it will add a 'clrwdt' instruction to routines like DelayMS/DelayUS, and also how the ClrWDT() sub functions. If the value is true then the compiler inserts asm 'clrwdt' instructions, otherwise it doesn't.
That code above could be made a bit more generic by checking the value of '_wdt_type' instead of the device name...
That fixes selecting 'Config WDT/WDTEN' for you, but the only problem with it is you're stuck using the value ON, and depending on the device you may want to use one of the other WDTEN settings.
EDIT: you probably don't want to use the following mods. See the later post as to why these aren't a good idea
Since the '#option WDT' needs to remain a boolean for the compiler, you can add a new '#option _WDT' that lets you set the desired WDT/WDTEN config setting and let it take care of '#option WDT' for you...
This lets you use the new option to set the desired config setting...
note: the K40 devices add a new wdt config type, so now it's 'config WDT/WDTE/WDTEN'
Here's the settings and their meanings:
Code: Select all
'#const _wdt_type' can be used to identify the watchdog config type
0 WDT(WDT) = [OFF, ON]
1 WDTEN(WDTEN) = [OFF, ON]
2 WDTEN(WDTEN) = [OFF, NOSLP, SWON, ON]
3 WDTEN(WDTEN) = [OFF, NOSLP, ON, SWDTDIS]
4 WDTE(WDTE) = [OFF, SWDTEN, NSLEEP, ON]
for _wdt_type = 0 (18F4520 SF default device):
config WDT: Watchdog Timer Enable bit
1 = WDT enabled
0 = WDT disabled (control is placed on the SWDTEN bit)
for _wdt_type = 1 (18F14K50):
config WDTEN: Watchdog Timer Enable bit
1 = WDT is always enabled. SWDTEN bit has no effect
0 = WDT is controlled by SWDTEN bit of the WDTCON register
for _wdt_type = 2 (18F2xK22):
config WDTEN<1:0>: Watchdog Timer Enable bits
11 (ON) = WDT enabled in hardware (SWDTEN ignored)
10 (SWON) = WDT controlled by firmware (SWDTEN enabled)
01 (NOSLP) = WDT enabled in hardware, disabled in Sleep mode (SWDTEN ignored)
00 (OFF) = WDT disabled in hardware (SWDTEN ignored)
for _wdt_type = 3 (18F2xK80):
WDTEN<1:0>: Watchdog Timer Enable bits
11 (SWDTDIS)= WDT is enabled in hardware; SWDTEN bit is disabled
10 (ON) = WDT is controlled by the SWDTEN bit setting
01 (NOSLP) = WDT is enabled only while the device is active and is disabled in Sleep mode; SWDTEN bit is disabled
00 (OFF) = WDT is disabled in hardware; SWDTEN bit is disabled
for _wdt_type = 4 (18FxxK40):
WDTE<1:0>: WDT Operating Mode bits
00 (OFF) = WDT is disabled, SWDTEN is ignored
01 (SWDTEN) = WDT is enabled/disabled by the SWDTEN bit in WDTCON0
10 (NSLEEP) = WDT is enabled while sleep=0, suspended when sleep=1; SWDTEN is ignored
11 (ON) = WDT is enabled regardless of sleep; SWDTEN is ignored
most devices have a register bit SWDTEN somewhere that allows for software control of the wdt...
usually found in WDTCON.bits(0) except for the J94/J99 family where it's RCON2.bits(5)
_wdt_types 0 and 1 are similar, except that the config bit changes names from WDT to WDTEN.
likewise, _wdt_types 2 and 3 are similar except the settings change meanings slightly, esp ON
For example, here's the code from the existing System.bas module:
Code: Select all
#option WDT = false
#if IsOption(WDT) And Not (WDT in (true, false))
#error WDT, "Invalid option. WDT must be true or false."
#endif
#if WDT
#if _device in (18F66J16)
Config WDTEN = on
#else
Config WDT = on
#endif
#endif
Public Inline Sub ClrWDT()
#if WDT
Asm-
ClrWDT
End Asm
#endif
End Sub
Note: don't confuse '#option WDT' with 'Config WDT'... they're two different things. The '#option WDT' is a boolean true/false value. The compiler checks this value to determine if it will add a 'clrwdt' instruction to routines like DelayMS/DelayUS, and also how the ClrWDT() sub functions. If the value is true then the compiler inserts asm 'clrwdt' instructions, otherwise it doesn't.
That code above could be made a bit more generic by checking the value of '_wdt_type' instead of the device name...
Code: Select all
// account for WDT/WDTEN
#option WDT = false
#if IsOption(WDT) and not (WDT in (true, false))
#error WDT, "Invalid option. WDT must be true or false."
#endif
#if (WDT) // check option setting...
// get _wdt_type from device file so we use the correct config
#if (_wdt_type = 0) // the config bit is named WDT
config WDT = ON
#elseif (_wdt_type = 4) // the config bit is named WDTE
config WDTE = ON
#else // the config bit is named WDTEN
config WDTEN = ON
#endif
#endif
public inline sub ClrWDT()
// check the #option setting. only add clrwdt if option is true (config = ON)
#if (WDT)
asm
CLRWDT
end asm
#endif
end sub
EDIT: you probably don't want to use the following mods. See the later post as to why these aren't a good idea
Since the '#option WDT' needs to remain a boolean for the compiler, you can add a new '#option _WDT' that lets you set the desired WDT/WDTEN config setting and let it take care of '#option WDT' for you...
Code: Select all
// account for WDT/WDTEN and setting
// add new '#option _WDT' for the setting
#option _WDT = OFF
// make sure no one's using '#option WDT'... we need it later
#if (IsOption(WDT))
#error "#option WDT no longer used...replace with #option _WDT"
#endif
// set old WDT boolean option based on _WDT setting
// this option controls internal libray usage of 'clrwdt'
#if (_WDT = OFF)
#option WDT = false
#else
#option WDT = true
#endif
// get _wdt_type from device file so we use the correct config
#if (_wdt_type = 0) // the config bit is named WDT
config WDT = _WDT
#else // the config bit is named WDTEN
config WDTEN = _WDT
#endif
public inline sub ClrWDT()
// check the #option setting... only add clrwdt if not OFF
#if (_WDT <> OFF)
asm
CLRWDT
end asm
#endif
end sub
Code: Select all
device = 18f25k22 ' _wdt_type 2
// set '#option _WDT' to the desired config setting for your device (ie ON, OFF, NOSLP, SWON, etc)
// as long as it's not OFF then system.bas will enable the code to use the wdt and clrwdt
// (it defaults to OFF if not specified)
#option _WDT = SWON
include "system.bas"
// check to see if ClrWDT() produces a 'clrwdt' instruction (look at the asm code)
ClrWDT()
// check system SBDLYUS16 for clrwdt
delayus(100)