;
;  PIC12F675
;    E39 Security and Answer Back  Rev 0.2
;		Programmed by DD
;       2007/10/10
;
;	Data Format
;	+---------------+
;	| | |I|I|O|O|I|I|   GPIO  I:Input   O:Output
;       +---------------+   
;       Input Data
;                           GP0 => LED Blink Pattern 0
;			    GP1 => LED Blink Pattern 1
;                           GP2 => Unlock Signal Input 
;                           GP3 => Lock Signal Input
;
; 	Output Data
;		            GP4 => Security LED Control
;		            GP5 => Hazard Lamp Control
;
;
;       Function
;           
;       Flow Chart
;           (START):
;                    GP4=0
;		     GP_Prev = GP
;           (UNLOCK):
;                    GP4=0
;		     Call Wait
;                    go to UNLOCK
;	    (LOCK):
;		     GP4=0
;		     Load GP1,0
;	 	     Indirect Jump with GP1,0 for PAT0-3
;           (PAT0):
;		     GP4=1
;		     Call Wait
;		     GP4=0
;		     while (19) Call Wait
;		     go to PAT0
;
;       Subroutines
;	    (Wait100ms):
;		     Wait for 100msec
;	    (Wait):
;		     If GP3_Prev=0 && GP3=1 then GP_Prev=GP & Hazard & Go to LOCK
;		     If GP2_Prev=0 && GP2=1 then GP_Prev=GP & Hazard & Go to UNLOCK
;		     GP_Prev = GP
;		     Call Wait100msec
;		     Return


	list    p=pic12F675
	include "p12f675.inc"

; Defining constant


;
	__FUSES _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
;	Configuration Code = 0xFFEA
;	When burning PIC, the following configuration is necessary
;		MCLR is OFF
;		Code Protection(CP) is OFF
;		Watch Dog Timer(WDT) is OFF
;		Clock is Internal RC Oscillator

	cblock  0x20    ;Store variables above control registers
	wcnt1		;Wait Counter1 (For 100ms Wait)
	wcnt2		;Wait Counter2 (For 100ms Wait)
	prev		;Previous GP
	lcnt		;loop counter
	endc


	org 0x00		;Start of Code Space
;=========================================
;  Start Program (& Wake up from Sleep)
;=========================================
START	bsf	STATUS,RP0	;Set Bank1
	movlw	b'00001111'	;Output: GP5,GP4, Input:GP3,GP2,GP1,GP0
	movwf	TRISIO		;Set GPIO Input/Output
	movlw   b'00000000'	;Pull-up Enable
	movwf	OPTION_REG
	movlw	b'00000011'	;GP1,0 are pulled up
	movwf	WPU
	movlw	b'00000000'	;All pins are digital I/O
	movwf	ANSEL
	bcf	STATUS,RP0	;Set Bank0
	movlw	b'00000111'	;
	movwf	CMCON		;CMCON=00000111

	bcf	GPIO,4		;GP4(LED)=0(OFF)
	bcf	GPIO,5		;GP5(Hazard)=0(OFF)
	movf	GPIO,W		;W=GPIO
	movwf	prev		;prev=GPIO

UNLOCK	bcf	GPIO,4		;GP4(LED)=0(OFF)
	call	Waitck		;100msec wait and check
	goto	UNLOCK		

LOCK	bcf	GPIO,4		;GP4(LED)=0(OFF)
	movf	GPIO,W		;W=GPIO
	andlw	b'00000011'	;Pickup Bit 1,0
	addwf	PCL,F		;Indirect Jump
	goto	PAT0		;GP1,0 = 00
	goto	PAT1		;GP1,0 = 01
	goto	PAT2		;GP1,0 = 10
	goto	PAT3		;GP1,0 = 11

; 10000000000000000000
PAT0	bsf	GPIO,4		;GP4(LED)=1(ON)
	call	Waitck		;100msec wait and check
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	movlw	d'19'
	movwf	lcnt		;lcnt=19
PAT0L	call	Waitck		;100msec wait and check
	decfsz	lcnt,F		;Loop 19 times
	goto	PAT0L
	goto	LOCK

; 1000000000
PAT1	bsf	GPIO,4		;GP4(LED)=1(ON)
	call	Waitck		;100msec wait and check
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	movlw	d'9'
	movwf	lcnt		;lcnt=9
PAT1L	call	Waitck		;100msec wait and check
	decfsz	lcnt,F		;Loop 9 times
	goto	PAT1L
	goto	LOCK

; 11111000000000000000
PAT2	bsf	GPIO,4		;GP4(LED)=1(ON)
	call	Waitck		;100msec wait and check
	call	Waitck		;100msec wait and check
	call	Waitck		;100msec wait and check
	call	Waitck		;100msec wait and check
	call	Waitck		;100msec wait and check
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	movlw	d'15'
	movwf	lcnt		;lcnt=15
PAT2L	call	Waitck		;100msec wait and check
	decfsz	lcnt,F		;Loop 15 times
	goto	PAT2L
	goto	LOCK

; 10010000000000000000
PAT3	bsf	GPIO,4		;GP4(LED)=1(ON)
	call	Waitck		;100msec wait and check
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	call	Waitck		;100msec wait and check
	call	Waitck		;100msec wait and check
	bsf	GPIO,4		;GP4(LED)=1(ON)
	call	Waitck		;100msec wait and check
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	movlw	d'16'
	movwf	lcnt		;lcnt=16
PAT3L	call	Waitck		;100msec wait and check
	decfsz	lcnt,F		;Loop 16 times
	goto	PAT3L
	goto	LOCK


;================================
;  Wait for 100ms and Check GP2,3
;================================
Waitck
	call	wait100ms	;wait 100msec
	btfsc   prev,3          ;If GP3_Prev = 1,
	goto    Waitck1		;  go to Waitck1
	btfss	GPIO,3		;If GP3=0,
	goto    Waitck1		;  go to Waitck1
	movf	GPIO,W		;W=GPIO
	movwf	prev		;prev=GPIO
	goto	LKHZD		;Go to LKHZD
Waitck1	
	btfsc   prev,2          ;If GP2_Prev = 1,
	goto	Waitck2		;  go to Waitck2
	btfss	GPIO,2		;If GP2=0,
	goto    Waitck2		;  go to Waitck2
	movf	GPIO,W		;W=GPIO
	movwf	prev		;prev=GPIO
	goto	UNLKHZD		;Go to UNLKHZD
Waitck2
	movf	GPIO,W		;W=GPIO
	movwf	prev		;prev=GPIO
	retlw	0		;return

;================================
;  Lock Hazard (1 flash by hazard relay)
;================================
LKHZD
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	bsf	GPIO,5		;Harzard(GP5)=ON
	call	wait100ms
	bcf	GPIO,5		;Harzard(GP5)=OFF
	call	wait100ms
	call	wait100ms
	call	wait100ms
	bsf	GPIO,5		;Harzard(GP5)=ON
	call	wait100ms
	bcf	GPIO,5		;Harzard(GP5)=OFF
	goto	LOCK

;================================
;  Unlock Hazard (2 flashes by hazard relay)
;================================
UNLKHZD
	bcf	GPIO,4		;GP4(LED)=0(OFF)
	bsf	GPIO,5		;Harzard(GP5)=ON
	call	wait100ms
	bcf	GPIO,5		;Harzard(GP5)=OFF
	call	wait100ms
	call	wait100ms
	call	wait100ms
	call	wait100ms
	call	wait100ms
	call	wait100ms
	call	wait100ms
	bsf	GPIO,5		;Harzard(GP5)=ON
	call	wait100ms
	bcf	GPIO,5		;Harzard(GP5)=OFF
	goto	UNLOCK		;goto UNLOCK	

;================================
;  Wait for 100ms
;================================
wait100ms
	movlw	d'128'		;*128
	movwf	wcnt2
waitlp2	clrf	wcnt1
waitlp1	decfsz	wcnt1,F
	goto	waitlp1
	decfsz	wcnt2,F
	goto	waitlp2
	retlw	0

	end
