Watchdog timer

Questions about the BASICtools and MakeItC
Post Reply
YahooArchive
Posts: 1462
Joined: Fri Oct 19, 2012 5:11 am

Watchdog timer

Post by YahooArchive »

>from the help line
>I am interested in using the Watchdog Timer (WDT) on the Pro+. I noticed that
hasn\'t been implemented in the ARMBASIC, so is there a way to:

yep, write directly to the registers (this is untested, but straight out of
user manual(
first

#include

>enable the WDT

WD_WDMOD = 3 'enable watchdog and have it reset the CPU
WD_WDFEED = &HAA
WD_WDFEED = &H55 ' first feed turns it on

>feed the WDT

WD_WDFEED = &HAA
WD_WDFEED = &H55 ' normal feed

>have the WDT reset the processor if the program gets lost and doesn\'t feed the
WDT.

you might want to set

WD_WDTC = something larger than &HFF ' in counts of 4 MHz IRC



TodWulff
Posts: 70
Joined: Fri Oct 19, 2012 4:03 am
Location: The Mitten State - Shores of Lake Huron

Re: Watchdog timer [54102 - Reset]

Post by TodWulff »

For the 54102, there are a couple of additional steps needed:
  • Clear the PDRUNCFG bit for the WDT Oscillator, so it becomes powered
  • Enable the WDT Clock in the AHBCLKCTRL register
    <...then...>
  • Set the WDT Time Constant register (a 4 cycle divisor on a 500KHz clock source | 625000 (0x98968) is 5 sec)
    One can think of it as a 125KHz clock (a cycle period of .000008 sec) - 625000 x .000008s = 5.0 seconds.
  • Set the WDT Mode to 0x3 (enables the WDT and configs to force a reset when it starves)
  • Then feed the WDT to start it
The following is tested w/ BT 6.1, PC Compiler 9.37m, and 8.36h on the 54102:

Code: Select all

#define CORE_M4
#include "LPC54102.bas"

main:
	dim userinput as integer
	
	print "Recovery:  'Stop' here if you need to recover device, else Enter to test WDT> "
	debugin userinput

	SCB_PDRUNCFGCLR or= (1<<20)	' power up the WDT Osc - b20 PDEN_WDT_OSC Watchdog oscillator. 
					' 0 = Powered; 1 = Powered down; Resets to 1;  Write a 1 to the 'clear' register to clear it.
	SCB_AHBCLKCTRL(0) or= SYSCON_CLOCK_WWDT ' enable the WDT clock to run from the WDT Osc.
	WD_WDTC = 0x00098968	'Twdclk * 625000 * 4 = Twdclk * 2500000 = 5 sec (500KHz clock)
	WD_WDMOD or= 0x00000003	' enables WDT (once fed) & reset if it starves (b0 & b1) 
	WD_WDFEED = 0xAA	' WDT init'd - feeding now to start it up...
	WD_WDFEED = 0x55
	print "WDT fed."
	
	do ' enter a 0 in the console to feed else the device should reset when WDT expires.
		print "WDT Count Down Register Value: ";WD_WDTV
		print "You've <5 seconds before reset - 0 refeeds, 1 displays WDTV> "
		debugin userinput
		if userinput = 1 ' display timer count register
			print "WDT Count Down Register Value: ";WD_WDTV
			print
		else 'feed the dog
			WD_WDFEED = 0xAA
			WD_WDFEED = 0x55
			print "WDT fed"
			print
		endif
	loop
end

TodWulff
Posts: 70
Joined: Fri Oct 19, 2012 4:03 am
Location: The Mitten State - Shores of Lake Huron

Re: Watchdog timer [54102 - Interrupt]

Post by TodWulff »

The following is tested w/ BT 6.1, PC Compiler 9.37m, and 8.36h on the 54102:

Code: Select all

' initial run last for ~6-10 seconds, wdt will starve, firing the isr & then the handler w/ a console emission 
' second and subsequent periods should be ~3-5s between interrupts/console emissions

#define CORE_M4					' needed for this dual core device, & given we're working with the NVIC on the M4
#include "LPC54102.bas"				' needed for the header #defs 

_WDT_InitGlobals:
	dim WDT_INT_Flag as integer		' this is a wdt user flag
	return
	
interrupt sub _WDT_INT_ISR			' this isr only sets a flag, clears the interrupt and exits - a handler will perform outside of an interrupt context
	WDT_INT_Flag = 1				' assert the user flag during the ISR
	WD_WDMOD and= 0xFFFFFFFB		' clear the wdt interrupt in the wwdt mode register ("software cleared...")
	endsub
	
sub _WDT_INT_Handler				' this is the handler to do more stuff at time of interrupt, outside the isr
	print "Interrupt Fired:", timer
	
	WDT_INT_Flag = 0				' clear the user flag
	
	WD_WDTC = 0x00098968			' ~3-5 secs wdt timer constant
	WD_WDMOD = 0x00000001			' clears int bit(b2=0) and enables wwdt (once fed) & config to force an interrupt if it starves (b1=0=Int & b0=1=Enabled) 
	
	WD_WDFEED = 0xAA				' feed the wdt
	WD_WDFEED = 0x55

	endsub
	
main:
	print "Started @ Timer:", timer
	
	call _WDT_InitGlobals
	WDT_INT_Flag = 0				' deassert the wdt user flag

	SCB_PDRUNCFGCLR or= (1<<20) 			' power up the wdt osc
	SCB_AHBCLKCTRL(0) or= SYSCON_CLOCK_WWDT	' enable the wdt clk
	WD_WDTC = 0x001312D0 					' ~6-10 secs wdt timer constant for initial interrupt
	WD_WDMOD = 0x00000001					' clears int bit(b2=0) and enables wwdt (once fed) & config to force an interrupt if it starves (b1=0=Int & b0=1=Enabled) 

	' default wdt int priority is fine - so noeffwidit
	WWDT_IRQn = (addressof _WDT_INT_ISR) or 1	' assign the isr sub addy to the NVIC vector table for wdt_irq  (the 'or 1' is for thumb code purposes)
	VICIntEnable0 or= 0x00000001				' enable the wdt interrupt

	WD_WDFEED = 0xAA						' feed the wdt to start it
	WD_WDFEED = 0x55

	do
		if WDT_INT_Flag then _WDT_INT_Handler
	loop
	
end

Post Reply