;************************************************************************** ; FILE: catcher.asm * ; CONTENTS: SpyCatcher * ; COPYRIGHT: MadLab Ltd. 1999-2002 * ; AUTHOR: James Hutchby * ; UPDATED: 31/12/02 * ;************************************************************************** list p=12C508A include "p12c508a.inc" __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_ON ; __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_OFF __idlocs h'AF20' errorlevel -302,-305 ;************************************************************************** ; * ; Specification * ; * ;************************************************************************** ; power-up self-test - all LEDs flash and double beep sounds ; 6-state machine - ready, arm, detect, trigger, alarm and sleep states ; infra-red mode - breaking light beam or incident light activates ; external mode - external switch break (reed switch) or make (pressure mat) activates ; ready state ; LED1 indicates if silent mode set ; LED2 indicates current sensor state (depends on sensor mode) ; LED3 indicates sensor mode (off = infra-red, on = external) ; button1 toggles silent mode ; button2 toggles sensor mode ; button3 -> arm state ; timeout -> sleep state ; arm state ; LEDs cycle ; accepts optional security code, up to 8 digits ; timeout -> detect state ; detect state ; LED1 indicates if previously triggered ; LED2 flashes ; sensor change -> trigger state ; any button -> trigger state ; trigger state ; LED1 indicates if previously triggered ; LED2 flashes ; correct security code entered -> ready state ; timeout -> alarm state ; alarm state ; LED1 on ; silent mode set -> wait for security code -> ready state ; LED2 and LED3 flash ; alarm sound ; correct security code entered -> ready state ; timeout -> detect state ; sleep state ; wake-up -> previous state ;************************************************************************** ; * ; Port assignments * ; * ;************************************************************************** GPIO_IO equ b'101100' ; port I/O status #define IR GPIO,2 ; infra-red detector #define EXT GPIO,3 ; external switch BUTTON1 equ 4 ; button1 (yellow, marked 'SILENT') BUTTON2 equ 1 ; button2 (green, marked 'MODE') BUTTON3 equ 0 ; button3 (red, marked 'ARM') BUTTONS equ b'010011' ; buttons mask #define LED1 GPIO,0 ; LED1 (yellow, marked 'SILENT') #define LED2 GPIO,1 ; LED2 (red, marked 'SENSOR') #define LED3 GPIO,4 ; LED3 (green, marked 'MODE') SPEAKER equ 5 ; speaker ;************************************************************************** ; * ; Constants and timings * ; * ;************************************************************************** CLOCK equ d'4000000' ; processor clock frequency in Hz DELAY_PERIOD equ d'40' ; button poll period (~1/20 s) READY_DURATION equ d'60' ; ready state duration (~60 s) ALARM_LO equ d'41'<<1 ; alarm ramp low frequency (~2 KHz) ALARM_HI equ d'13'<<1 ; alarm ramp high frequency (~6 KHz) ALARM_RISE equ d'25' ; alarm ramp rise time (~1/10 s) ALARM_DURATION equ d'2' ; alarm duration (~2.5 mins) CLICK_PITCH equ d'30' ; button click pitch CLICK_PERIOD equ d'60' ; button click period BEEP_PITCH equ d'100' ; beep pitch BEEP_PERIOD equ d'100' ; beep period ;************************************************************************** ; * ; File register usage * ; * ;************************************************************************** RAM set h'07' cblock RAM flags ; various flags timer ; timer duration ; duration button ; button pressed, 0 if none security_code:2 ; security code - up to 8 digits security_mask ; security code mask disarm_code:2 ; disarm code alarm_period ; alarm period work1, work2 ; work registers RAM_ endc if RAM_ > h'20' error "File register usage overflow" endif ; flags SENSOR_MODE equ 0 ; sensor mode (0 = infra-red, 1 = external) SENSOR_STATE equ 1 ; sensor state ARM_STATE equ 2 ; sensor state when armed SILENT_MODE equ 3 ; set if silent mode TRIGGERED equ 4 ; set if alarm triggered WAIT_RELEASE equ 5 ; set if waiting for button release DETECT_STATE equ 6 ; set if in detect state ;************************************************************************** ; * ; Macros * ; * ;************************************************************************** routine macro label ; routine label endm table macro label ; define lookup table label addwf PCL endm entry macro value ; define table entry retlw value endm index macro label ; index lookup table call label endm jump macro label ; jump through table goto label endm tstw macro ; test w register iorlw 0 endm movff macro f1,f2 ; move file to file movfw f1 movwf f2 endm movlf macro n,f ; move literal to file movlw n movwf f endm ;-------------------------------------------------------------------------- ; reset vector ;-------------------------------------------------------------------------- org 0 movwf OSCCAL goto main_entry ;************************************************************************** ; * ; Procedures * ; * ;************************************************************************** ;-------------------------------------------------------------------------- ; polls the buttons ;-------------------------------------------------------------------------- routine poll_buttons movlw GPIO_IO|BUTTONS ; initialise port tris GPIO movwf GPIO ; poll the buttons clrf button movff GPIO,work1 clrf GPIO ; re-initialise port movlw GPIO_IO tris GPIO incf button btfss work1,BUTTON1 goto pollb1 incf button btfss work1,BUTTON2 goto pollb1 incf button btfsc work1,BUTTON3 clrf button pollb1 btfss flags,WAIT_RELEASE ; waiting for release ? goto pollb2 ; branch if not tstf button ; wait for button to be released skpnz bcf flags,WAIT_RELEASE clrf button pollb2 tstf button skpz bsf flags,WAIT_RELEASE ; signal waiting for release retlw 0 ; Z flag set if no button pressed ;-------------------------------------------------------------------------- ; polls the infra-red or external sensor ;-------------------------------------------------------------------------- routine poll_sensor movlw GPIO_IO ; re-initialise port tris GPIO btfsc flags,SENSOR_MODE goto polls1 bsf IR ; poll the infra-red sensor bcf flags,SENSOR_STATE btfss IR bsf flags,SENSOR_STATE goto polls2 polls1 bsf EXT ; poll the external sensor bcf flags,SENSOR_STATE btfss EXT bsf flags,SENSOR_STATE polls2 retlw 0 ;-------------------------------------------------------------------------- ; delay ;-------------------------------------------------------------------------- routine delay movlf DELAY_PERIOD,work1 delay1 clrf work2 delay2 clrwdt nop decfsz work2 goto delay2 decfsz work1 goto delay1 retlw 0 ;-------------------------------------------------------------------------- ; button click ;-------------------------------------------------------------------------- routine click movlf CLICK_PERIOD,work1 click1 bcf GPIO,SPEAKER ; speaker on movlw GPIO_IO&~(1< xorwf flags ; toggle silent mode goto ready2 ready1 andlw 1 ; button3 pressed -> bz arm_state ; arm state movlw 1< xorwf flags ; toggle sensor mode ready2 movlw READY_DURATION ; reset duration movwf duration goto ready_loop ; loop ;-------------------------------------------------------------------------- ; arm state ;-------------------------------------------------------------------------- routine arm_state call poll_sensor ; save current sensor state bcf flags,ARM_STATE btfsc flags,SENSOR_STATE bsf flags,ARM_STATE clrf security_code+0 ; clear security code clrf security_code+1 clrf security_mask clrf timer ; clear timer routine arm_loop movlw GPIO_IO ; re-initialise port tris GPIO movfw timer ; cycle LEDs andlw 3 movwf work1 bcf LED1 decf work1 skpnz bsf LED1 bcf LED2 decf work1 skpnz bsf LED2 bcf LED3 decf work1 skpnz bsf LED3 call delay ; poll delay incf timer ; increment timer btfsc timer,6 goto arm1 ; branch if timeout call poll_buttons ; poll the buttons bz arm_loop ; loop if no button pressed call click ; button click rrf button ; add digit to security code rlf security_code+0 rrf button rlf security_code+1 setc rlf security_mask goto arm_loop ; loop arm1 call beep ; indicate armed call delay call beep ; goto detect_state ; detect state ;-------------------------------------------------------------------------- ; detect state ;-------------------------------------------------------------------------- routine detect_state bsf flags,DETECT_STATE ; signal detect state clrf timer ; clear timer routine detect_loop movlw GPIO_IO ; re-initialise port tris GPIO clrf GPIO incf timer ; increment timer movfw timer andlw h'1f' bnz detect1 btfsc flags,TRIGGERED ; display triggered status bsf LED1 bsf LED2 ; flash LED call delay detect1 call poll_sensor ; test sensor movlw 1<