PropBasic: Simple reboot timer
VonSzarvas
Posts: 3,622
Here is a simple timer for a project that requires the Propeller to reboot every few minutes, regardless of what it is doing.
Set the required timeout period by adjusting:
wdTimerLoopSecs - which is the innerloop timer and can be up to 50 seconds
wdTimerReps - which is the outerloop timer, and so is multiplied by the innerloop time seconds to get the timeout value (in my example 30 seconds * 2 reps = 60 seconds timeout period)
When the task expires the propeller will reboot. You might not want the reboot, but the code might be useful for re-purposing!
Of interest is the code to make adjustments when the wdTimerEnd is calculated negative. This is necessary so that the internal timer loop can run for more than 26 seconds! This is the main reason I am posting this solution, as this "number wraparound" took some moments to solve!
Without the negative-adjustment code you must keep the wdTimerLoopSecs LESS than 26 seconds. You could remove the code, reduce the internal loop to, say 20 seconds, then increase the wdTimerReps appropriately if you wanted to save some code space. This time I wanted to solve the problem both ways and to provide a full example!
If might be fun to experiment by setting different values and logging the results.
Set the required timeout period by adjusting:
wdTimerLoopSecs - which is the innerloop timer and can be up to 50 seconds
wdTimerReps - which is the outerloop timer, and so is multiplied by the innerloop time seconds to get the timeout value (in my example 30 seconds * 2 reps = 60 seconds timeout period)
When the task expires the propeller will reboot. You might not want the reboot, but the code might be useful for re-purposing!
Of interest is the code to make adjustments when the wdTimerEnd is calculated negative. This is necessary so that the internal timer loop can run for more than 26 seconds! This is the main reason I am posting this solution, as this "number wraparound" took some moments to solve!
Without the negative-adjustment code you must keep the wdTimerLoopSecs LESS than 26 seconds. You could remove the code, reduce the internal loop to, say 20 seconds, then increase the wdTimerReps appropriately if you wanted to save some code space. This time I wanted to solve the problem both ways and to provide a full example!
If might be fun to experiment by setting different values and logging the results.
' ----------------------------------------------------------------------
'{$CODE}
' ----------------------------------------------------------------------
TASK TASK_WDTIMER_REBOOT
' ----------------------------------------------------------------------
' VARIABLES / CONSTANTS
' ----------------------------------------------------------------------
wdTimerLoopSecs CON 30 ' ~30 seconds (Maximum ~50 seconds!)
wdTimerReps VAR Long = 2 ' Reps * LoopSecs = timeout delay
wdTimerStart VAR Long = 0
wdTimerEnd VAR Long = 0
wdTimerTmp VAR Long = 0
' ----------------------------------------------------------------------
' TASK MAIN
' ----------------------------------------------------------------------
DO UNTIL wdTimerReps = 0
wdTimerStart = CNT
wdTimerEnd = _FREQ * wdTimerLoopSecs
' If wdTimerEnd is negative, make some adjustments
' Include this code if wdTimerLoopSecs > 26 seconds
wdTimerTmp = SGN wdTimerEnd
IF wdTimerTmp = -1 THEN
DEC wdTimerEnd, $7FFFFFFF
INC wdTimerStart, $7FFFFFFF
ENDIF
DO
wdTimerTmp = CNT
DEC wdTimerTmp, wdTimerStart
IF wdTimerTmp > wdTimerEnd THEN ' timeout exceeded!
EXIT ' Exit the inner loop, start next rep.
ENDIF
' Do something here, or just pause a little if nothing else to do!
PAUSE 500
LOOP
DEC wdTimerReps
LOOP
' Timer expired so REBOOT the propeller!
CLKSET 128
ENDTASK
