;*****************************************************
;COMBINATION LOCK MkII                               *
;  16-5-2011                                         *
;Press A and B  8 times to unlock a combination      *
;*****************************************************
;
;       --+--------------+---------------------- +5v     
;		  |              |   |  |
;         |              +---|[]|----+
;         |Vdd ---v---       |  |    |
;         +---|1   Gnd|      piezo   |
;             |    GP0|----+         |
;   +---------|GP5    |    |         |
;   |         |       |   | |100R    |        
;   |     +---|GP4 GP1|---| |-------------+    
;   |     |   |       |    |         |    |
;   |     |   |GP3 GP2|--------------+   | |100R 
;   |     |    -------     |             | |
;   o     o   PIC12F629   _|_            _|_
;  A /   B  /             \ / green      \ / red
;   /      /              ---  lock      --- 5 incorrect
;  |      |                |   open       |   tries
; -+------+----------------+--------------+--------------- 0v

	list	p=12F629
	radix	dec
	include	"p12f629.inc"
	
		errorlevel	-224	; Don't complain about tris
		errorlevel	-302	; Don't complain about BANK 1 Registers

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;==========================================================================
;
;       Configuration Bits
;
;==========================================================================

D1			equ		20h	;delay value
D2			equ		21h	;delay value
temp1		equ		22h ;
code_EEPROM	equ		23h ;
code8		equ		24h ;SwA&B puts new code into "code"
count		equ		25h ;to count 8 presses
codetry  	equ		26h	;holds current "try" of 8 presses
_40loops    equ     27h ;creates 10 sec delay
_5wrong		equ     28h ;counts 5 wrong tries
tone		equ     29h ;loops for piezo tone
alarmloops  equ     2Ah ;loops for alarm before resetting

;****************************************************************
;Beginning of program
;****************************************************************
		org		0x00				
SetUp	bsf		status, rp0 	;Bank 1			
       	movlw	b'00111000'		;Set TRIS  
		movwf	TRISIO	   	    ;GP0,1,2 outputs	GP4,5 input
		bcf		option_reg,7	;pull-ups enabled		
		bcf		status, rp0		;bank 0		
		movlw   07h         	;turn off Comparator 
        movwf   CMCON       	;must be placed in bank 0 
        clrf	gpio			;clear gpio of junk
        movlw   5
        movwf    _5wrong         ;put 5 into the wrong-try file
        btfsc	gpio,5			;Is swA pressed?  pressed=0
		goto	Main							
		goto	entercode		;both sw pressed at turn-on 
								;then waits for project turn-off
		
;********************
;* Delays 			*
;********************
	
_1mS	decfsz 	D1,f
		goto 	$-1			
		retlw 	00	
			

_10mS	movlw	0Ah
		movwf	D2
		nop
		decfsz 	D1,f
		goto 	$-2
		decfsz 	D2,f
		goto 	$-4	
		retlw 	00			
		
		
		;250mS second delay
		
_250mS	decfsz 	D1,1
		goto 	_250mS
		decfsz 	D2,1
		goto 	_250mS		
		retlw 	00	
		
		
_10Sec	movlw	.40
		movwf	_40loops
		call	_250mS		
		decfsz  _40loops,f
		goto	$-2
		retlw 	00	
			

;************************
;* Subroutines			*
;************************		
		
	;entercode puts 8-bit code into EEPROM via "code8"
	
entercode 
		call    _10mS
		btfss	gpio,5	;Is swA not pressed?
        goto	$-2							
		btfss	gpio,4	;Is swB not pressed?
		goto	$-4
		movlw	08
	    movwf	temp1    ;4 loops of flashing LEDs
	    clrf	gpio
	    movlw	0ffh	    
	    xorwf	gpio,f
	    call    _250mS
	    decfsz	temp1,f
	    goto	$-4
	    clrf	gpio	;turn off LEDs
	    clrf	code8   ;code8 holds new code	    
	    movlw	8
	    movwf	count	;to count 8 presses
	    rlf		code8,f	;shift "count" to the left. 
	    call    _10mS   ;
	    btfss	gpio,5	;SwA produces 0
        goto	$+5							
		btfsc	gpio,4	;swB produces 1
		goto	$-4	
		bsf		code8,0 
		goto	$+2
	    bcf		code8,0 
	    call    _10mS
	    btfss	gpio,5	;Is swA not pressed?
        goto	$-2							
		btfss	gpio,4	;Is swB not pressed?
	    goto	$-4		    
	    decfsz	count,f
	    goto	$-15
	    movf	code8,w  ;move code8 to w
	    call	write   ;put code8 into EEPROM location 0
	    goto	$		;waiting for project to be turned off
	    
	
		
			;read code from EEPROM 
readEEPROM	
		bsf		status,rp0			
		clrf	EEADR		;to read first location in EEPROM !!!							
		bsf		EECON1,0	;starts EEPROM read operation - result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0
		movwf	code_EEPROM ;put code from EEPROM into "code_EEPROM"  
		retlw	00
		
	;try generates value in "codetry" for 8 presses
	
try	    movlw	8
	    movwf	count	;to count 8 presses
	    rlf		codetry,f	;shift "codetry" to the left
	    call    _10mS   ;
	    btfss	gpio,5	;SwA produces 0
        goto	$+5							
		btfsc	gpio,4	;swB produces 1
		goto	$-4	
		bsf		codetry,0 
		goto	$+2
	    bcf		codetry,0 
	    call    _10mS
	    btfss	gpio,5	;Is swA not pressed?
        goto	$-2							
		btfss	gpio,4	;Is swB not pressed?
	    goto	$-4	
	    decfsz	count,f
	    goto	$-15
		retlw	00		;returns with 8 presses in codetry
		

		
write	bsf		status,rp0	;select bank1
		clrf	eeadr		;to load into first location
		movwf	eedata		;w will have new code value		
		bsf		eecon1,wren	;enable write		
		movlw	55h 		;unlock codes
		movwf	eecon2
		movlw	0aah
		movwf	eecon2
		bsf		eecon1,wr	;write begins
		bcf		status,rp0	;select bank0		
    	btfss	pir1,eeif	;wait for write to complete
		goto	$-1
		bcf		pir1,eeif
		bsf		status,rp0	;select bank1
		bcf		eecon1,wren	;disable other writes
		bcf		status,rp0	;select bank0					
		retlw	00		
		

;************************
;*Main			        *
;************************		

        
Main	call	try				;creates value in "codetry" for 8 presses
		call    readEEPROM		;first value in EEPROM into code_EEPROM
        movf	codetry,w       ;try from 8 presses is compared with
		subwf	code_EEPROM,w   ;value in EEPROM
		btfss	status,z   		;zero set if yes
		goto	$+.15			;no
		movlw	.10
	    movwf	temp1    		;5 loops of flashing green LED
	    clrf	gpio
	    movlw	01		 		;to flash green LED   
	    xorwf	gpio,f
	    call    _250mS
	    decfsz	temp1,f
	    goto	$-4
	    bsf		gpio,0			;turn on green LED for 10 seconds
	    call	_10Sec
	    bcf		gpio,0
	    movlw   5
        movwf    _5wrong        ;put 5 into the wrong-try file
        goto	Main
		call    _10Sec			;wait 10 seconds
		decfsz  _5wrong         ;decrementing the 5 wrong tries file		
		goto	Main
		
		movlw	.20             ;20 Alarm loops before resetting
		movwf   alarmloops						 
		bsf		gpio,1			;turn on red LED
		call    _250mS
		bcf		gpio,1			;turn off red LED
		call    _250mS	
		movlw   0ffh
		movwf	tone
		call    _1mS
		bsf		gpio,2
		call    _1mS
		bcf		gpio,2
		decfsz	tone,f
		goto	$-5
		decfsz  alarmloops,f		
		goto	$-.13	
		goto	SetUp

				
;************************************
;*EEPROM     						*
;************************************
								
		org		2100h			
		
		de		33h				;initial value of loaction0 = b'00110011'		
							    ; = Sw "A A B B A A B B" as file is rlf
		END
		
		