 TITLE  "wRX.asm"          		
 List P=12F675, R=DEC
 INCLUDE "p12F675.inc"

; data segment
 CBLOCK 0x20                  
 del  					; variables for passing the parameters
 width, cnt				; local vars
 length0, bt
 ENDC

; code segment
 PAGE
 __CONFIG b'110000100'

  org 0                      		; start program at the beginning of mem
	bcf	STATUS, RP0   	        ; switch to BANK 0
	clrf	GPIO			; initialize GPIO
	clrf 	INTCON			; disable all interrupts
	movlw	0x14			
	movwf	CMCON			; setup the comparator
	clrf	ADCON0			; ADC OFF
  	bsf    	STATUS, RP0      	; change to BANK 1
	movlw	0xA7			; comparator reference = 1.5V
	movwf	VRCON ^ 0x80		; setup voltage reference
	movlw	2
	movwf	ANSEL ^ 0x80 		; enable GP1 as analog input
	clrf	PIE1 ^ 0x80		; disable external interrupts
	clrf	IOC  			; disable interrupt on change	
	clrf	WPU 
	bsf	OPTION_REG ^0x80, 7 	; disable pull-ups 
	movlw	0x03
	movwf	TRISIO ^ 0x80		; enable GP<1,0> for input
  	bcf    	STATUS, RP0        	; back to BANK 0

	movlw	184/4
	movwf	length0

	call 	dischargeCAP
	movlw	250
	movwf	del
	call 	delay

state0					; wait for a synch
	clrw
	btfss	CMCON, 6		; check COUT for 1
	goto 	$-1			; NO - keep waiting

	addlw	1			; receiving data
	btfsc	GPIO, 0			; data bit = 0?
	goto 	$-2			; NO - keep measuring the length	

	movwf	width
	call 	dischargeCAP

	movf	width, w	
	addlw	-55			; w = width - 80
	btfsc	STATUS, C
	goto 	state1

	bsf	GPIO, 5			; fail indication
	movlw 	1
	movwf	del
	call 	delay
	bcf	GPIO, 5
	movlw	1
	movwf	del
	call 	delay
	goto 	state0 

state1					; receiving byte of data
	movlw	8
	movwf	cnt			; counter of # bits to receive
	clrf	bt			; initialize received byte	

L1	clrw				; initialize the counter
	btfss	GPIO, 0			; data bit = 1?
	goto	$-1			; NO - wait for data

	addlw	1			; update the counter
	btfsc	GPIO, 0			; data bit = 1?
	goto	$-2	
	movwf	width
	call 	dischargeCAP

	movf	width, w
	addlw	-100/4			; w = w - 25
	btfss	STATUS, C		; impulse is wide enough?
	goto	state0			; NO - start from scratch

L2	addlw	100/4			; compensate w after the first check
	subwf	length0, w		; w = length0 - (width - 25)

	rlf	bt, f			; incorporate the bit into byte
	movlw	1
	xorwf	bt, f

	decfsz	cnt, f
	goto 	L1	

; byte processing
	movlw	48
	subwf	bt, f			; ASCII conversion

L5  bsf		GPIO, 4			; LED ON	
	movlw	200
	movwf	del
	call 	delay
	bcf	GPIO, 4			; LED OFF
	movlw	200
	movwf	del
	call 	delay
	decfsz	bt, f
	goto 	L5

	call 	delayL
	goto 	state0


; subroutines
dischargeCAP
	bsf    	STATUS, RP0      	; change to BANK 1
	bcf	TRISIO ^ 0x80, 1	; enable cap discharge
	bcf	STATUS, RP0		; back to BANK 1
	bcf	GPIO, 1			; discharge the cap

	movlw	2			; cap discharge delay
	addlw	-1
	btfss	STATUS, Z
	goto 	$-2

	bsf	STATUS, RP0
	bsf	TRISIO ^ 0x80, 1	; disable further cap discharge
	bcf	STATUS, RP0		
	return

delay					; a delay for del milliseconds
	movlw 	200
	
	sublw	1			; this loop takes 5us*200 = 1ms
	sublw	0			; for PIC12F675 @ 4 Mhz
	btfss	STATUS, Z
	goto 	$-3

	decfsz	del, f
	goto 	delay
	return

delayL					; a 2 sec delay
	movlw	10
	movwf	cnt

	movlw	200
	movwf	del
	call 	delay
	decfsz	cnt, f
	goto	$-4
	return
 end
