>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
Watchdog timer
-
- Posts: 70
- Joined: Fri Oct 19, 2012 4:03 am
- Location: The Mitten State - Shores of Lake Huron
Re: Watchdog timer [54102 - Reset]
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
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
-
- Posts: 70
- Joined: Fri Oct 19, 2012 4:03 am
- Location: The Mitten State - Shores of Lake Huron
Re: Watchdog timer [54102 - Interrupt]
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