 TITLE  "wTX.asm"          		; weather station controller
 List P=12F683, R=DEC
 INCLUDE "p12F683.inc"

pulseWidth  	EQU 20		; 20*5usec = 100usec
pulseRate   	EQU 90		; gap unit width (3*value usec)
width0		EQU 3		; # of gap units for transmitting a 0 
width1		EQU 7		; # of gap units for transmitting a 1
refWidth	EQU 5		; # of gap units for the reference
sepWidth	EQU 15		; # of gap units burst separation intervals
TXEN		EQU 1		; TX enable bit in GPIO
RFOUT		EQU 2		; RF carrier send bit in GPIO

; data segment
 CBLOCK 0x20                
 bt:2, cnt, temp, i, del	; local variables	
 debounce:2			; debouncing counter
 ENDC

; code segment
 __CONFIG _BOD_ON & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

  ORG 0                      	; start program at the beginning of mem
	bcf	STATUS, RP0     ; switch to BANK 0
	clrf	GPIO		; initialize GPIO
	movlw	7
	movwf	CMCON0		; disable the comparator
	clrf	ADCON0		; ADC OFF
  	bsf    	STATUS, RP0    	; change to BANK 1
	clrf	VRCON ^ 0x80	; disable the voltage reference
	clrf	ANSEL ^ 0x80 	; all inputs digital
	movlw	1
	movwf	TRISIO ^ 0x80	; initialize GPIO:0 for input
	bcf	OPTION_REG ^0x80, 7	; enable weak pull-ups
  	bcf    	STATUS, RP0    	; back to BANK 0


loop
	call 	wait4Release	; wait 64msec for the button release
	call	wait4Press	; wait 64msec for the button press

	bsf 	GPIO, TXEN	; turn TX on
	call 	sendMSG
	bcf 	GPIO, TXEN	; turn TX OFF
	goto 	loop

sendData			; send data in WREG to TX
	movwf	bt
	movlw	8		; bits counter
	movwf	cnt
	movlw	sepWidth	; separation delay between the burst series
	call	pulse		; 250usec
	movlw	refWidth		
	call	pulse		; reference pulse

sendLoop	
	movlw	width0
	btfsc	bt, 7	
	 movlw	width1
	call	pulse
	rlf	bt, f
	decfsz	cnt, f
	 goto	sendLoop
	return

pulse				; generate pulse of width in Wreg
	movwf	temp
	movlw	pulseRate	
	movwf	del
	decfsz	del, f		; a 3*pulseRate gap unit (3*50=150us)
	 goto	$-1
	decfsz	temp, f
	 goto	$-5

	movlw	pulseWidth
	movwf	del		; setting the pulse width

	bsf	GPIO, RFOUT	; start pulse
	nop			; a 5usec*del loop
	nop
	decfsz	del, f
	 goto	$-3
	bcf	GPIO,RFOUT	; stop pulse
	return

wait4Release
	clrf 	debounce	; wait for the button release
	clrf	debounce+1

	btfss	GPIO, 0		; button released?
	 goto 	wait4Release	; NO - wait for release
	incf	debounce, f
	btfsc	STATUS, Z
	 incf	debounce+1, f
	btfss	debounce+1, 5	; 4096*16 = 64msec
	 goto	$-6
	return

wait4Press
	clrf 	debounce	; wait for the button press
	clrf	debounce+1

	btfsc	GPIO, 0		; button pressed?
	 goto 	wait4Press	; NO - wait for press
	incf	debounce, f
	btfsc	STATUS, Z
	 incf	debounce+1, f
	btfss	debounce+1, 5	; 4096*16 = 64msec
	 goto	$-6
	return

; this code is for sending a test message only
msg1				; first message to display
	addwf	PCL, f
	dt "  Welcome to", 0

msg2				; second message to display
	addwf	PCL, f
	dt "PIC programming", 0

sendMSG
; output of the top row (msg1)
	movlw	b'10000001'	; clear display
	call	sendData

	clrf 	i			
_L1	movf	i, w
	call	msg1		; get the next char
	iorlw	0		; end of string?
	btfsc	STATUS, Z	
	goto 	_L2		; YES - jump out of the loop
	call 	sendData	; NO - send it to LCD
	incf	i, f		; update the char index
	goto 	_L1

_L2	movlw	0xC0
	call 	sendData	; move the cursor to the second line
	clrf	i		; clear the index of the second string

; output the bottom row (msg2)
_L3 	movf	i, w					
	call	msg2		; get the next char
	iorlw	0		; end of string?
	btfsc	STATUS, Z	
	goto 	_L4		; YES - jump out of the loop
	call 	sendData	; NO - send it to LCD
	incf	i, f		; update the char index
	goto 	_L3

_L4	return

 end
