	
	;Whistle (Key Finder) 12F629.asm
	;  9-7-2009  

	list	p=12f629
	radix	dec
	include	"p12f629.inc"
	
		errorlevel	-302	; Don't complain about BANK 1 Registers during assembly
		

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

	
		;Files for 12F629 start at 20h 
 
						 			
temp1		equ 20h	
temp2		equ 21h	
count		equ	22h	
beep		equ	23h		
timer		equ 24h 	;beeps after 1 minute to let you know it's on 

			; globals
			

GPIO		equ	05h

status		equ	03h
option_reg	equ 81h
TRISIO		equ	85h

						; bits 
				
pin7		equ	0	;GP0  
pin6	 	equ	1	;GP1
pin5		equ	2	;GP2 and T0CkI
pin4		equ	3	;GP3 input only
pin3		equ	4	;GP4 
pin2		equ	5	;GP5 

z			equ	2	;zero flag


						;bits
				
rp0		equ	5			;bit 5 of the status register
		

Start	org		0x00		;program starts at location 000
		goto	SetUp
		nop		
		nop		;NOPs to get past reset vector address
		org		4
		goto	isr			
		nop

SetUp	movlw   07h         ;Set up W to turn off Comparator ports
		movwf   CMCON       ;must be placed in bank 0   
		goto 	Main		;Main


	;Delays		
				
_25uS	movlw	.7
		movwf	temp1
		decfsz	temp1,1			 
		goto 	$-1	 	
		retlw	00
		
		
_130uS	movlw	.45
		movwf	temp1
		decfsz	temp1,1			 
		goto 	$-1	 	
		retlw	00		
		
_250uS	movlw	.84
		movwf	temp1
		decfsz	temp1,1			 
		goto 	$-1	 	
		retlw	00	
		

			
				
		
_100mS	movlw	.100
		movwf	temp2
		nop
		decfsz 	temp1,1
		goto 	$-2
		decfsz 	temp2,1
		goto 	$-4	
		retlw 	00	
				
_250mS	movlw	0FFh
		movwf	temp2
		nop
		decfsz 	temp1,1
		goto 	$-2
		decfsz 	temp2,1
		goto 	$-4	
		retlw 	00	
		
		
		;interrupt service routine		

isr		nop
		decfsz	timer,1		;creates 1 min delay to let you know it is on.
		goto	Main1
		movlw	03
		movwf	count
		goto	sss 		
		
Main	bsf		status,rp0 	;Bank 1			
		movlw	b'00100100'	;Set GP2 input  GP5 input
		movwf	TRISIO			
		movlw	b'10010100'; 
		movwf	OPTION_REG	; x000 0000 x=1= weak pull-ups disabled 
							; 0x00 0000 INTDEG Don't care
							; 00x0 0000  x=0 = internal instruction clock
							; 000x 0000 Count on falling edge - dont care
							; 0000 x000 0=prescaler assigned to timer0  
							; 0000 0xxx = 111 = 1:128  x100=1:32							
		bcf		status,rp0	;bank 0 		
		bcf		GPIO,4
		call	_100mS		;(settling time)		
		movlw	b'10100000'	;b'10100000'
		movwf 	INTCON		;,0  1=GP0,5 interrupt flag
							;,1  1=GP2 interrrupt occurred
		;bcf	INTCON,2	;1=TMR0 overflowed. Clear overflow flag 
		;bcf	INTCON,3	;1=enable GPIO port change interrupt
		;bcf	INTCON,4	;1=enable GP2 external interrupt				
		;bsf	INTCON,5	;1=enable TMR0 overflow (interrupt)
		;bcf	INTCON,6	;1=enable all peripheral interrupts
		;bsf	INTCON,7	;1=enable all unmasked interrupts
		
		bcf		INTCON,5	;0=disables TMR0 interrupt
		bsf		INTCON,6	;1=enable all peripheral interrupts
		
		movlw	b'00010101'	;b'00110001'			
		movwf	T1CON		;,7  not used
							;,6 0=Timer1 is ON
							;,5,4  11=8 prescale (max) 01=1:2
							;,3 bit ignored
							;,2 This MUST BE SET!!!!!!
							;,1 0=int clock 
							;,0 1=enable timer 
							
		bsf		status,rp0 	;Bank 1						
		bsf		PIE1,0		;,0 1=enables TMR1 interrupt					
		bcf		status,rp0	;bank 0 
		bcf		PIR1,0		;clear TMR1 overflow flag
		
		clrf	TMR1L		;clear the Timer1 low register
		clrf	TMR1H		;clear the Timer1 high register
		clrf	count		;count the number of cycles
							;Timer0 is not used 		
							; will go to isr when overflow occurs in TMR1	
							;0.13 sec when prescaler=1:2  131,072uS							
		
							;input is LOW when no audio detected.			
			
aa		call	_25uS					
		btfss	GPIO,2		;Is input HIGH?  Start with a HIGH
		goto	aa						
bb		call	_250uS
		btfss	GPIO,2		;Is input LOW?   
		goto	cc
		goto	aa			;freq too low			
		
cc		call	_250uS
		btfsc	GPIO,2		;Is input LOW?
		goto	dd		
		goto	aa			;freq too low

dd		incf	count,1
		goto	bb


Main1	bcf		PIE1,0		;,0 0=disables TMR1 interrupt
		bcf		T1CON,0		;disable timer1
		bsf		status,rp0 	;Bank 1	
		bCf		INTCON,7	;disble all unmasked interrupts	
		bcf		INTCON,5	;disables TMR0 interrupt			
		bcf		status,rp0	;bank 0 		
		swapf	count,1
		rrf		count,1		;
		rrf		count,1		;only use top 2 bits
		movlw	b'00000011'
		andwf	count,1		;max 4 beeps			
		movf	count,1
		btfsc	status,z	;z flag will be SET if file is zero
		goto	Main
		
sss		bsf		status,rp0 	;Bank 1	
		movlw	b'00000100'	;Set GP4,5 output
		movwf	TRISIO	
		bcf		status,rp0	;bank 0 				
		call	_250mS
		movlw	0FFh
		movwf	beep		 		
		bsf		GPIO,4
		bcf		GPIO,5
		call	_130uS
		bcf		GPIO,4
		bsf		GPIO,5
		call	_130uS
		decfsz	beep,1
		goto	$-7
		decfsz	count,1
		goto	$-12		
		call	_250mS
		call	_250mS
		call	_250mS
		call	_250mS		
		goto	Main				

		end
		
		
			