User access to Watchdog Interrupt?

Discussion of issues related specifically to writing code for native mode devices. This includes ZBasic code as well as assembly language code and C code, both inline and standalone.
Post Reply
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

User access to Watchdog Interrupt?

Post by spamiam »

I did not see the Watchdog interrupt listed as an interrupt for which one can install user-defined code? Is it available? I want to be able to use the watchdog to implement a shutdown feature.

-Tony
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: User access to Watchdog Interrupt?

Post by dkinzer »

spamiam wrote:Is it available?
A watchdog interrupt is available on some AVR devices. It is available on all ZX native mode devices even though it is not shown in the table; the ISR name is WDT.
- Don Kinzer
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Post by spamiam »

Ah, I figured that the list of supported interrupts was quite complete, and therefore the WDT would probably be supported as well.

-Tony
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Hi, is it possible to use the WDT interrupt as a method of periodically waking up from power down rather than having the watchdog reset the processor?

At the moment I have the watchdog resetting the processor every 8sec and then incrementing a persistent var each reset, then when this var reaches a threshold, perform my desired code.

However I would ideally like to just wake up the 328 periodically and do the same thing rather than resetting.

So a watchdog interrupt, rather than reset.

Do you think this is possible to do without external hardware hooked up to an interrupt? Or am I limited to using the watchdog timer to reset?


Cheers

Ben
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

just a case of setting Register.WDTCSR ?
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

this seems to do the trick!

Code: Select all

Register.WDTCSR = Bx0001_1000 'allow prescaler change

Register.WDTCSR = Bx0010_0001 'set prescaler to 1024 = 8s

Register.WDTCSR = Bx0110_0001 'enable watchdog timer interrupt

sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Although, for some reason its only working for the first sleep. If i initiate another CPUSleep() in the WDT after my actions, the watchdog interrupt does not fire again.

Any ideas, code below...

Code: Select all

'OPTIONS
Option Com1Speed 9600
Option TxQueueSize 150
Option RxQueueSize 150
Option SignOn Off

'TASKS
Dim comtaskstack(1 to 200) as Byte 

'SETTINGS
PUBLIC consolelog as byte = 1
PUBLIC watchdog_value as byte = 9
PUBLIC watchdog_seconds as byte = 8
PUBLIC GPS_timeout as single = 50.0
PUBLIC polltime as Byte = 3 'x8seconds
PUBLIC sleepcount as Byte

'Comm setup
PUBLIC com3TXQueue(1 to 150) as Byte
PUBLIC com3RXQueue(1 to 150) as Byte
PUBLIC com4TXQueue(1 to 150) as Byte
PUBLIC com4RXQueue(1 to 150) as Byte

'PINS
PUBLIC CONST scl_pn as Byte = 28
PUBLIC CONST sda_pn as Byte = 27
PUBLIC CONST com3rx_pn as Byte = 24
PUBLIC CONST com3tx_pn as Byte = 23
PUBLIC CONST gps_enable_pn as Byte = 9
PUBLIC CONST com4rx_pn as Byte = 26
PUBLIC CONST com4tx_pn as Byte = 25

PUBLIC CONST pwr_328p_idle as Byte = &H00
PUBLIC CONST pwr_328p_powerdown as Byte = &H05
PUBLIC CONST pwr_328p_powersave as Byte = &H07
PUBLIC CONST pwr_328p_standby as Byte = &H0D
PUBLIC CONST pwr_328p_externalstandby as Byte = &H0F

'COMMONS
PUBLIC CONST pi as single = 3.14159265359
PUBLIC Const CRLF as String = Chr(13) & Chr(10)
PUBLIC Const CR as String = Chr(13)
PUBLIC Const LF as String = Chr(10)
PUBLIC i2c_Result as INTEGER
PUBLIC i2c_Result_bol as BOOLEAN
PUBLIC i2c_OutData(1 to 10) as BYTE
PUBLIC i2c_InData(1 to 10) as BYTE
PUBLIC i2c_ack as BOOLEAN
PUBLIC MSB as BYTE
PUBLIC LSB as BYTE

'GSM
PUBLIC GSM_byte as Byte
PUBLIC GSM_bytearray(1 to 100) as BYTE
PUBLIC GSM_bytearrayi as BYTE = 0
PUBLIC GSM_response as String
PUBLIC GSM_responsearray(1 to 3) as String

'GPS
PUBLIC GPS_byte as Byte
PUBLIC GPS_bytearray(1 to 100) as BYTE
PUBLIC GPS_bytearrayi as BYTE = 0
PUBLIC GPS_string as String
PUBLIC GPS_status as String
PUBLIC GPS_utctime as String
PUBLIC GPS_date as String
PUBLIC GPS_lat as Single
PUBLIC GPS_NS as BoundedString(1)
PUBLIC GPS_lng as Single
PUBLIC GPS_EW as BoundedString(1)
PUBLIC GPS_speed as Single
PUBLIC GPS_heading as Single
PUBLIC GPS_fix as Byte

'RTC SETUP
PUBLIC RTC_hours as byte
PUBLIC RTC_minutes as byte
PUBLIC RTC_seconds as byte
PUBLIC RTC_dd as Byte
PUBLIC RTC_mm as Byte
PUBLIC RTC_yy as Byte


ISR INT1() 'ring interrupt
	'debug.print "interrupt"
End ISR

ISR WDT() 'watchdog timer interrupt
	debug.print "watchdog"
	Call mainpoll()
End ISR


Sub Main()
	debug.print "STARTUP"

	'INITIALISE 328
	'TURN SOME STUFF OFF TO POWER SAVE
	Register.ADCSRA = Bx0111_1111 'disable ADC
	Register.ACSR = Bx1000_0000 'disable analog caomparator
	
        'INTERRUPTS
	Register.EICRA = Bx0000_1000 'falling edge on int0 and int1
	Register.EIMSK = Bx0000_0010 'enable int1
	
	'SETUP WATCHDOG
	Register.WDTCSR = Bx0001_1000 'allow prescaler change
	Register.WDTCSR = Bx0010_0001 'set prescaler to 1024 = 8s
	Register.WDTCSR = Bx0110_0001 'enable watchdog timer interrupt
	
	'SETUP POWERSAVE MODE
	Register.SMCR = pwr_328p_powerdown
	'Register.SMCR = pwr_328p_powersave
	'Register.SMCR = pwr_328p_standby
	
	'INITIALISE VARS
	sleepcount = 0
	
	'START COMMON TASKS
	CallTask comtask, comtaskstack

	'OPEN SOFTWARE COM PORTS
	Call ComChannels(2, 9600)
	Call init_com3() 'GSM
	Call init_com4() 'GPS
	
	Call gotosleep()
End Sub




Sub mainpoll() 
	sleepcount = sleepcount + 1
	console("POLL " & cstr(sleepcount) & " " & cstr(sleepcount * watchdog_seconds) & "s")
	
	'POLLING
		if sleepcount > (polltime-1) then
			console("AWAKE")
                        'DO STUFF
			sleepcount = 0
			Call sleep(2.0)
		end if
	Call gotosleep()
End Sub


Sub gotosleep() 
	'give enough time for serial output to finish
	Call sleep(0.1)
	
	'Go to sleep
	Call CPUSleep()
End Sub



Public Sub comtask() 
    Do 
		debug.print TIMER()
        Call Sleep(0.1) 
    Loop 
End Sub
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Solved this by changing my code so that i have a loop running mainpoll() in my main(), and the WDT now does nothing more than wake it up.

I guess this is the only way. Would be interested as to why the other route did not work though.
Post Reply