; ********************************************************* ; 12F629 / 12F675 Test for presence of Internal Oscillator Calibration Word ; ; ; Pete Griffiths, March 2008 ; Version 1.00 ; For hardware schematic and details see http://picprojects.org.uk/projects/calcheck/ ; Code tests for presence of calibration word at program memory address 0x3FFF. ; ; For 99.9% of situations where the RETLW calibration instruction has been erased ; this code will correctly identify the problem. ; ; Note: ; There are two scenarios where this code will indicate a correct calibration value when ; in fact it the value being returned is not correct. ; 1. If someone has modified the value returned by the RETLW instruction at 0x3FFF ; 2. The RETLW has been replaced with a RETURN instruction. ; ;#include "p12f629.inc" #include "p12f675.inc" __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _CPD_OFF errorlevel -302 ; suppress banksel warning messages cblock 0x20 saveCMCON saveCAL shiftCount shiftData dtime ltime endc #define bank0 bcf STATUS,RP0 ; Sel Bank 0 #define bank1 bsf STATUS,RP0 ; Sel Bank 1 #define srDat GPIO,0 #define srClk GPIO,1 #define laClk GPIO,2 #define LEDbad GPIO,4 #define LEDgood GPIO,5 ; reset vector org 0x000 nop nop clrf PCLATH ; clear PCLATH, very important _main movfw CMCON ; read value in CMCON register movwf saveCMCON ; and save in temp variable ; we will test this later to see if the code ; has wrapped movlw 0x07 ; setup the CMCON register movwf CMCON ; Disable Comparator on GPIO pins clrf GPIO ; set GPIO output pins low. bank1 IFDEF __12F675 clrf ANSEL ; Disable analogue inputs ENDIF movlw b'11001000' ; Specifiy GPIO port direction movwf TRISIO bank0 clrw ; set W reg to 0; call _showCal ; clear 74HC595 shift register outputs movfw saveCMCON ; test if value in CMCON that was read andlw b'00011111' ; back at reset is the POR value xorlw 0x07 ; or the one written into the register skpnz ; by this application goto _wrapped ; If it's not the POR value then the code ; has wrapped due to a missing calibration word bank1 call 0x3FF ; Attempt to read the calibration word bank0 ; If we've come back to this point then we can call _showCal ; assume the calibration word was present ; so we'll output it to the 74HC595 _good bsf LEDgood ; blink the Green LED to show calibration word found movlw .3 call _LDelay bcf LEDgood movlw .3 call _LDelay goto _good ; loop this code forever _wrapped bsf LEDbad ; blink the Red LED to show calibration word missing movlw .3 call _LDelay bcf LEDbad movlw .3 call _LDelay goto _wrapped ; loop this code forever ; ******************************************** ; SUBROUTINE ; 74HC595 Loader _showCal bcf laClk ; set latch clock input low movwf shiftData ; save data to be shifted in temp register bcf srClk ; set shift clock input low movlw .8 ; preset shift counter variable to 8 movwf shiftCount _shiftLoop bcf srDat ; set srDat input low rlf shiftData,F ; shift data left skpnc ; test if carry flag set bsf srDat ; set srData input high nop ; avoid read-modify-right issues bsf srClk ; _| shifts data in nop ; avoid read-modify-right issues bcf srClk ; set srClk low again ready for next shift decfsz shiftCount,F ; decrement shift count and skip next if done goto _shiftLoop ; else shift next bit bsf laClk ; all data shifted, now _| latches data to outputs return ; ******************************************** ; SUBROUTINE ; Delay loop _Delay movwf dtime ; Call for W x 1mS __Dcall call __1mS decfsz dtime,F goto __Dcall __DlyEnd return _LDelay movwf ltime ; Call for W x 100mS __Dlcall movlw d'100' call _Delay decfsz ltime,F goto __Dlcall return __1mS movlw 0xC6 _next nop addlw 0xFF btfss STATUS,Z goto _next nop nop nop return dt "Copyright Pete Griffiths (C) 2008 " dt "12F629/675 OSCCAL test utility 1.00 " dt "http://picprojects.org.uk " end