PIC Microcontoller Methods

Hardware Restart from Software

Detecting the cause of a reset/restart

Morgan Olsson [morgans.rt at telia.com] Morgans Reglerteknik, Hällekås, 277 35 KIVIK, SWEDEN tel +46(0)414-446620, fax +46(0)414-672324 Says:

If I implement a "system health scanner", and it detects a corrupted register, a routine finding an anomalyty, strange error, or something... Then i want to reboot the system immediately rather than wait for watchdog.

So I want to effectively assert a hardware reset signal, that is guaranteed to reset every pheripheral, also any state that is not writeable as register.

If we can force Wdog reset we can also do some tricks:

There are in the PIC status bits that can tell wether it was a Watchdog reset. So the boot rotine checks that, and if it finds it was a watchdog reset it continues by reading a special flag that we keep clear always except we set it just before we force a watchdog reset. That flag might even be a whole register loaded with a message code from the routine that triggered the reset, and the boot routine may then report or log the specific error, or decide to do a special fastboot or whatever.

I have implemented the suggestion of Simon Nield, that makes it insensitive of the level and use of Porta pin 4 by sensing, adapting, and then retries if RA4 changed and made it fail this time.

To top it off, it is now failsafe even if PA4 has some signal/noise of a frequency that makes even the x number of retries fail and then reverts to just waiting for normal Watchdog reset at shortest prescaler.

        LIST
        messg "  * FAST FORCED RESET * prototyping file, revision 2.0 "
        messg " This program resets the PIC 31k times/second  @ 4MHz Xtal "
        messg " Rigorously tested on an PIC16F877 datecode 9921BSL "
        messg " Morgan Olsson, morgans.rt@telia.com, November 2000 "
        NOLIST
;******************************* CONFIGURE ***********************************
        list      p=16f877
        __CONFIG _CP_OFF & _WDT_ON & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF
        errorlevel      -306 ;no Crossing page boundary warnings
        errorlevel      -302 ;no bank warnings
        radix           dec
;********************************** DEFINITION FILES *************************
        include p16f877.inc
        LIST
;********************************** REGISTERS ********************************
T1      EQU     0x20    ;general Temporary register 1
;********************************** RESET ************************************
        ORG     0x000
        nop     ;Needed for ICD debugger
        clrf    PCLATH
        goto    Init
;********************************* INTERRUPT *********************************
        ORG     0x004
        goto $  ;if false interrupt stop here to indicate (never happens)
;********************************* INIT **************************************
Init:
        clrf    STATUS

;Set up watchdog realistically as we normally use it
        clrwdt
        movlw   b'11011101'; TMR0 on fosc/4, prescaler  /32 to Watchdog
        movwf   OPTION_REG

;PortE is used for monitoring
        clrf    PORTE
        bsf     STATUS,RP0      ;Bank 1
        movlw   b'00000010'     ;Make Port E a digital port,
        movwf   ADCON1          ;not analog inputs!

;-Indicator of personal taste. (PortE is made output later, see below)
        bcf     STATUS,RP0      ;Bank 0
        bsf     PORTE,2

;********************************* FAST RESET *********************************
;Design Morgan Olsson, morgans.rt@telia.com

FastReset:

;-Prepare
        clrf INTCON     ;disable interrupts
                        ;(Just to avoid spending time in an int)

        clrwdt  ;without this line the reset fails peridically -with the
                ;wdog freqency- probably depending on Wdog OSC output phase.
                ;-some undocumented connection.

        movlw   3  ;max number of tries (use higher value in final code!)
        movwf   T1 ;loop counter      (works first time if RA4 is steady)

FastResetLoop:

;-Setup registers
        bcf     STATUS,RP0      ;Bank 0
        movlw   (1<<NOT_RBPU)|(1<<INTEDG)|(1<<T0CS)|(1<<T0SE)|(0<<PSA)|(0<<PS0)
; ( = set prescaler in from RA4 XOR T0SE, T0SE=High and prescale select = "/2")
        btfsc   PORTA,4         ;Read state of the XOR gate's input from PA4,
          xorlw (1<<T0SE)       ;set the other XOR input so XOR output is "1"
        bsf     STATUS,RP0      ;Bank 1
        movwf   OPTION_REG      ;Effectuate the setup
        bcf     STATUS,RP0      ;Bank 0
        clrf    TMR0            ;clear prescaler (also TMR0, but irrelevant)

;-Now clock the prescaler by toggling T0SE, thus prescaler input go from 1 to 0
        bsf     STATUS,RP0      ;Bank 1
        movlw   (1<<T0SE)
        xorwf   OPTION_REG,F

;-For testing, make Port E outputs in order to measure time from here,
        clrf    TRISE   ;until reset tristates portE again!
                        ;Measured: 6 Xtal OSC cycles.  Note; clrf effectuates
        ;during Q4, next instr during Q4 in next cycle, and from there
        ;to reset it is obviously only 2Q or one half instr time :)

;-Now the prescaler output apparently is "1", because...
        bsf     OPTION_REG,PSA  ;...assigning it to wdt cause immediate reset!

;--- if it did not work (maybe PORTA,4 have changed during this process): ---

        bcf     STATUS,RP0      ;Bank 0

;-Indicator of personal taste:
        bsf     PORTE,1         ;FastReset failed at least once

;-Retry a few times!
;It might fail due to RA4 is changing, therefor we try again, but not forever!
        decfsz  T1, F
          goto  FastResetLoop

;-Indicator of personal taste:
        bsf     PORTE,0         ;FastReset failed, waiting for Watchdog

        goto $  ;As last resort leave the Wdog in peace to time out as normal
                ;with shortest prescaler (already selected above).

;Because we are fiddling with the prescaler in the routine, and there are
;already some undocumented effects, and may be more, I do not feel sure that
;the watchdog will time out during theese conditions, therefor we just wait.

;Hard testing has proven it works as described!

;Testing have been performed feeding RA4 with 50% duty cycle square wave,
;sweeping from DC and up, and using max three tries (setting T1 = 3)
;The routine then begin "failing" (getting to goto $ and using normal Wdog)
;at first at about 22kHz, and then working again at 30-31kHz, then... etc.
;(all at 4MHz Xtal)
;Increasing the number of retries will narrow the non-working frequency bands,
;and increase the frequency of first "failure", thus increasing functionality.

;WATCHDOG NEED TO BE ENABLED IN CONFIG DIRECTIVE (AND/OR PROGRAMMER)

        END


See: