 TITLE  "Transmitter"         
 List P=12F510, R=DEC
 INCLUDE "p12F510.inc"

ALM	EQU 5
ERR	EQU	4

; data segment
 CBLOCK 0x10                 
 cnt							; pulse length counter
 ref							; ADC value
 del1, del2, del3				; used for delays
 tmp, tol
 ENDC

; code segment
 __CONFIG _CP_OFF & _MCLRE_OFF & _WDT_OFF & _IntRC_OSC & _IOSCFS_OFF 

  ORG 0	                    	
	clrf	GPIO				; initialize GPIO
 	movlw  	b'1000000'			; Disable Internal Pull-Ups
  	option
	movlw	b'00001111'			; set GP<1,0> for input
	tris	6
	movlw	b'01111111'			; comparator setup
	movwf	CM1CON0
	movlw	b'01111001'			; ADC configuration
	movwf	ADCON0	

	clrf	tmp
	movlw	10
	movwf	tol
loop							; main loop
	btfss	CM1CON0, C1OUT		; wait for pulse
	 goto	$-1

	bsf		ADCON0, GO			; start ADC conversion
	btfsc	ADCON0, GO			; wait for the end of ADC conversion	
	 goto	$-1
	movf	ADRES, w
	movwf	ref	
	movlw	4					; add initial 500mksec period
	addwf	ref, f

	btfss	STATUS, C			; set freq = max(freq, 255)
	 goto	$+3
	movlw	255
	movwf	ref	

	btfss	CM1CON0, C1OUT		; pulse still high?
	 goto	loop				; NO
	clrf	cnt					; start timing the pulse
timing
	movf	ref, w
	call	delay
	incf	cnt, f
	btfsc	STATUS, Z			; pulse stuck high?
	 goto	process	
	btfsc	CM1CON0, C1OUT		; pulse still high?
	 goto	timing				; YES - keep timing

process
	decf	cnt, f				; this makes sure that 0 <= cnt <= 255
	movf	ref, w				; compute |cnt - ref|
	subwf	cnt, w
	btfss	STATUS, C
	 subwf	tmp, w				; w = |cnt - ref|

	subwf	tol, w
	btfsc	STATUS, C			; |cnt - ref| <= TOL ?
	 goto	alarm				; YES - raise alarm
wait
	bsf		GPIO, ERR
	btfsc	CM1CON0, C1OUT		; NO  - wait for end of pulse
	 goto	$-1		
	bcf		GPIO, ERR				
	goto	loop				; back to the main loop

alarm
	bsf		GPIO, ALM			; raise alarm for a certain time
	call 	delayL				; then wait for the end of pulse
	bcf		GPIO, ALM			; and start over
	goto	wait		

delay							; a delay for W*100 usec
	movwf	del1
	
dl	movlw	23					; a 100usec delay
	movwf	del2
	decf	del2, f
	btfss	STATUS, Z
	 goto	$-2	
	btfsc	CM1CON0, C1OUT
	 retlw	1	

	decf	del1, f
	btfss	STATUS, Z
	 goto	dl
	nop
	retlw	0

delayS							; a delay for del milliseconds
	movlw 	200
	movwf	del3

	decf	del3, f
	nop	
	btfss	STATUS, Z
	 goto 	$-3

	decfsz	del2, f
	 goto 	delayS
	retlw	0

delayL							; alarm delay of 1 sec
	movlw	10
	movwf	del1

	movlw	100
	movwf	del2
	call 	delayS
	decfsz	del1, f
	 goto	$-4
	retlw	0

 end
