; KD5ZUG telemetry transmitter control program.
; All rights reserved

	list      p=12F675        		; list directive to define processor
	#include <p12f675.inc>          ; processor specific variable definitions
	errorlevel  -302               ; suppress message 302 from list file

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.

;****************************************************************************
;Defines
;****************************************************************************
#define	BANK1		banksel 0x80	;Select Bank1
#define	BANK0		banksel 0x00	;Select Bank0
;#define	Dit			0x40
;#define Dah			0xc0
;#define	Pause		0x08
#define	AtoD1_L		0x20		;A to D reading from pin 7 least significant bits
#define	AtoD1_H		0x21		;A to D reading from pin 7 most significant bits
#define	AtoD2_L		0x22		;A to D reading from pin 6 least significant bits
#define	AtoD2_H		0x23		;A to D reading from pin 6 most significant bits
#define NumH		0x24		; varible to be converted to BCD,High byte
#define NumL		0x25		; varible to be converted to BCD,low byte	
#define TenK		0x26		; BCD ten thousands
#define Thou		0x27		; BCD thousands
#define Hund		0x28		; BCD hundreds
#define Tens		0x29		; BCD tens
#define	Ones		0x2a		; BCD ones
#define digit		0x2b		; digital input
#define count		0x2c		; used to adjust the delay time
#define	Dit			0x2d		; dit length 
#define	Dah			0x2e		; dah length 
#define	Pause		0x2f		; pause length 
#define	count2		0x30		; number of readings before transmit
#define MaxRead1_H	0x31		; Max reading recorded (high order byte)
#define MaxRead1_L	0x32		; Max reading recorded (low order byte)
#define MinRead1_H	0x33		; Min reading recorded (high order byte)
#define MinRead1_L	0x34		; Min reading recorded (low order byte)
#define DestL		0x35		; subtraction varable low byte (source-dest)
#define DestH		0x36		; subtraction varable high byte
#define	SourceL		0x37		; subtraction varable low byte
#define	SourceH		0x38		; subtraction varable high byte
;****************************************************************************
;Reset Vector
;****************************************************************************
	ORG     0x000             ; processor reset vector
	nop						  ; Inserted For ICD2 Use
	goto    Init              ; go to beginning of program
;****************************************************************************
;Initialization
;****************************************************************************
Init

	BANK1				; Switch to Bank1
	call    0x3FF     	; retrieve factory calibration value
	movwf   OSCCAL     	; update register with factory cal value 
	movlw	B'11101011'	; pin 5& 3 are outputs and pins 2,4,7,6 are inputs_
	movwf	TRISIO		;_bit0=7,bit1=6,bit2=5,bit3=4,bit4=3,bit5=2,
						;_1=input, 0=output
	movlw	B'11010101' ; set internal clock(5),prescale =1:256 assigned to TIMER0_
	movwf	OPTION_REG	;_bit0-2=prescale(100=1:32),bit3=prescale=TIMER0 (=0)_
						;_bit4=trailing edge,bit5=internal clock(0)
						;_bit6=int (1=rising), bit7=pullups (diabled=1)
	clrf	VRCON		; Vref Off (power off the comparator voltage,saves power)
	movlw	b'01010011'	; Configure pin 7 as anlog, Tad=16us_
	movwf	ANSEL		;_bit0=7,bit1=6,bit2=5,bit3=3 (1=analog,0=digital)
						;_bit4-6= A/D clock osc value (101=16)
	BANK0				; BANK 0
	clrf	TMR0		; clear TIMER 0
	clrf	GPIO		;Clear all Ports
	movlw	0x07		
	movwf	CMCON		; Comparator Off, bit0,1,2=1 (00000111) 
	bsf		ADCON0,0	; turn A to D converter to "on", bit0=1
	bsf		ADCON0,7	; right justified A/D, bit 7=1
	nop					; _ need at least 4 micro seconds before starting A to D_
	nop
	nop
	nop
;****************************************************************************
;MAIN - Main Routine
;****************************************************************************
Main
	movlw	0x0f		;number of long delay cycles between transmissions
	movwf	count2		;if pin 4 is high.
	call	Speed_L		;set speed at 8 words per minute.
	btfsc	GPIO,5		;if switch on pin 2 is high set at 50 WPM.
	call	Speed_H		;if pin 4 is high set as 50 WPM.
	btfsc	GPIO,3		;if switch on pin 4 is high set as timed transmittion
	call	Wait
	;***************************************************************
	call	xmit_on		; turn transmitter on
	call	Delay_S
	call	Read_A		; read the sensor A to D reading on pin 7
	call	BCD_A		; convert the 10 bit A to D reading to BCD
	call	_A			; transmit the letter "A"
	call	Morse_Thou	; transmit the BCD A to D reading. 3 digits_
						; starting with the hundreds digit
	call	Read_A		; read the sensor A to D reading on pin 7
						
	call	Delay_S		; Short delay
	call	Min1		; record if value is the lowest since power "on"
	call	BCD_Min1	; convert the 10 bit A to D reading to BCD
	call	_A			; transmit the letter "A"
	call	_T			; transmit the letter "T"
	call	Morse_Thou	; transmit the BCD A to D reading. 3 digits_
						; starting with the hundreds digit
	
	call	Read_A		; read the sensor A to D reading on pin 7
	call	Min1		; record if value is the lowest since power "on"
	
	call	Delay_S		; Short delay
	call	Read_B		; read the sensor A to D reading on pin 6
	call	BCD_B		; convert the 10 bit A to D reading to BCD
	call	_B			; transmit the letter "B"
	call	Morse_Thou	; transmit the BCD A to D reading. 3 digits_
						; starting with the hundreds digit
	
	call	Read_A		; read the sensor A to D reading on pin 7
	call	Min1		; record if value is the lowest since power "on"
						
	call	Delay_S		; Short delay
	call	C_sign		; transmit call sign					
	goto	Main 		; do it again

;********************************************************************
; Sub Routines
;********************************************************************
Speed_L					; set at 5 WPM
	movlw	0x55		
	movwf	Dit
	movlw	0xff		
	movwf	Dah
	movlw	0x0b		
	movwf	Pause
	return
;*******************************************************************
Speed_H					;set at 10 WPM
	movlw	0x10
	movwf	Dit
	movlw	0x30
	movwf	Dah
	movlw	0x02
	movwf	Pause
	return
;*******************************************************************
Read_A					; read A/D sensor inputs on pin 7
	bcf		ADCON0,3	;set AtoD on pin 7 (bit 3 and 4 =00) 
	bcf		ADCON0,2	;
	nop
	nop
	nop
	nop
	bsf		ADCON0,1	; start the A to D conversion
AtoD1
	btfss	PIR1,6
	goto	AtoD1
	bcf		PIR1,6
	BANK1
	movf	ADRESL,0
	BANK0
	movwf	AtoD1_L
	movf	ADRESH,0
	movwf	AtoD1_H
	return
;******************************************************************
Read_B	
	bcf		ADCON0,3	;set AtoD on pin 6 (bit 3 and 4 =01) 
	bsf		ADCON0,2	;
	nop
	nop
	nop
	nop
	bsf		ADCON0,1	; start the A to D conversion
AtoD2
	btfss	PIR1,6
	goto	AtoD2
	bcf		PIR1,6
	BANK1
	movf	ADRESL,0
	BANK0
	movwf	AtoD2_L
	movf	ADRESH,0
	movwf	AtoD2_H
	return
;*******************************************************************	
Read_C						; read switch on pin 2
	btfss	GPIO,5
	bsf		digit,0
	bcf		digit,0
	return
Read_D						; read switch on pin 4
	btfss	GPIO,3
	bsf		digit,1
	bcf		digit,1
	return
;******************************************************************
BCD_A						; prepare A/D pin 7 for BCD conversion
	movf	AtoD1_H,0
	movwf	NumH
	movf	AtoD1_L,0
	movwf	NumL
	call	BCD
	return
;******************************************************************
BCD_B						; prepare A/D on pin 6 for BCD conversion
	movf	AtoD2_H,0
	movwf	NumH
	movf	AtoD2_L,0
	movwf	NumL
	Call	BCD
	return
;*****************************************************************
BCD_Min1					; prepare Minimum reading BCD conversion
	movf	MinRead1_H,0
	movwf	NumH
	movf	MinRead1_L,0
	movwf	NumL
	Call	BCD
	return
	
	
;******************************************************************
BCD						; convert number in NumH and NumL converts
						; to 5 digit BCD number contained in 
						; registers TenK, Thou, Hund, Tens, Ones
	swapf	NumH,w
	andlw	b'00001111'
	addlw	b'11110000'
	movwf	Thou
	addwf	Thou,f
	addlw	b'11100010'
	movwf	Hund
	addlw	b'00110010'
	movwf	Ones
	
	movf	NumH,w
	andlw	b'00001111'
	addwf	Hund,f
	addwf	Hund,f
	addwf	Ones,f
	addlw	b'11101001'
	movwf	Tens
	addwf	Tens,f
	addwf	Tens,f
	
	swapf	NumL,w
	andlw	b'00001111'
	addwf	Tens,f
	addwf	Ones,f
	
	rlf		Tens,f
	rlf		Ones,f
	comf	Ones,f
	rlf		Ones,f
	
	movf	NumL,w
	andlw	b'00001111'
	addwf	Ones,f
	rlf		Thou,f
	
	movlw	b'00000111'
	movwf	TenK
	movlw	b'00001010'
Lb1
	addwf	Ones,f
	decf	Tens,f
	btfss	STATUS,0
	goto	Lb1
Lb2
	addwf	Tens,f
	decf	Hund,f
	btfss	STATUS,0
	goto	Lb2
Lb3
	addwf	Hund,f
	decf	Thou,f
	btfss	STATUS,0
	goto	Lb3
Lb4
	addwf	Thou,f
	decf	TenK,f
	btfss	STATUS,0
	goto	Lb4
	
	return
;***************************************************************
Morse_TenK				; Convert BCD number to Morse code
	movlw	0x09
	subwf	TenK,0
	Btfsc	STATUS,2
	call	nine
	movlw	0x08
	subwf	TenK,0
	Btfsc	STATUS,2
	call	eight
	movlw	0x07
	subwf	TenK,0
	Btfsc	STATUS,2
	call	seven
	movlw	0x06
	subwf	TenK,0
	Btfsc	STATUS,2
	call	six
	movlw	0x05
	subwf	TenK,0
	Btfsc	STATUS,2
	call	five
	movlw	0x04
	subwf	TenK,0
	Btfsc	STATUS,2
	call	four
	movlw	0x03
	subwf	TenK,0
	Btfsc	STATUS,2
	call	three
	movlw	0x02
	subwf	TenK,0
	Btfsc	STATUS,2
	call	two
	movlw	0x01
	subwf	TenK,0
	Btfsc	STATUS,2
	call	one
	movlw	0x00
	subwf	TenK,0
	Btfsc	STATUS,2
	call	zero
Morse_Thou
	movlw	0x09
	subwf	Thou,0
	Btfsc	STATUS,2
	call	nine
	movlw	0x08
	subwf	Thou,0
	Btfsc	STATUS,2
	call	eight
	movlw	0x07
	subwf	Thou,0
	Btfsc	STATUS,2
	call	seven
	movlw	0x06
	subwf	Thou,0
	Btfsc	STATUS,2
	call	six
	movlw	0x05
	subwf	Thou,0
	Btfsc	STATUS,2
	call	five
	movlw	0x04
	subwf	Thou,0
	Btfsc	STATUS,2
	call	four
	movlw	0x03
	subwf	Thou,0
	Btfsc	STATUS,2
	call	three
	movlw	0x02
	subwf	Thou,0
	Btfsc	STATUS,2
	call	two
	movlw	0x01
	subwf	Thou,0
	Btfsc	STATUS,2
	call	one
	movlw	0x00
	subwf	Thou,0
	Btfsc	STATUS,2
	call	zero
Morse_Hund	
	movlw	0x09
	subwf	Hund,0
	Btfsc	STATUS,2
	call	nine
	movlw	0x08
	subwf	Hund,0
	Btfsc	STATUS,2
	call	eight
	movlw	0x07
	subwf	Hund,0
	Btfsc	STATUS,2
	call	seven
	movlw	0x06
	subwf	Hund,0
	Btfsc	STATUS,2
	call	six
	movlw	0x05
	subwf	Hund,0
	Btfsc	STATUS,2
	call	five
	movlw	0x04
	subwf	Hund,0
	Btfsc	STATUS,2
	call	four
	movlw	0x03
	subwf	Hund,0
	Btfsc	STATUS,2
	call	three
	movlw	0x02
	subwf	Hund,0
	Btfsc	STATUS,2
	call	two
	movlw	0x01
	subwf	Hund,0
	Btfsc	STATUS,2
	call	one
	movlw	0x00
	subwf	Hund,0
	Btfsc	STATUS,2
	call	zero
Morse_Tens	
	movlw	0x09
	subwf	Tens,0
	Btfsc	STATUS,2
	call	nine
	movlw	0x08
	subwf	Tens,0
	Btfsc	STATUS,2
	call	eight
	movlw	0x07
	subwf	Tens,0
	Btfsc	STATUS,2
	call	seven
	movlw	0x06
	subwf	Tens,0
	Btfsc	STATUS,2
	call	six
	movlw	0x05
	subwf	Tens,0
	Btfsc	STATUS,2
	call	five
	movlw	0x04
	subwf	Tens,0
	Btfsc	STATUS,2
	call	four
	movlw	0x03
	subwf	Tens,0
	Btfsc	STATUS,2
	call	three
	movlw	0x02
	subwf	Tens,0
	Btfsc	STATUS,2
	call	two
	movlw	0x01
	subwf	Tens,0
	Btfsc	STATUS,2
	call	one
	movlw	0x00
	subwf	Tens,0
	Btfsc	STATUS,2
	call	zero
Morse_Ones	
	movlw	0x09
	subwf	Ones,0
	Btfsc	STATUS,2
	call	nine
	movlw	0x08
	subwf	Ones,0
	Btfsc	STATUS,2
	call	eight
	movlw	0x07
	subwf	Ones,0
	Btfsc	STATUS,2
	call	seven
	movlw	0x06
	subwf	Ones,0
	Btfsc	STATUS,2
	call	six
	movlw	0x05
	subwf	Ones,0
	Btfsc	STATUS,2
	call	five
	movlw	0x04
	subwf	Ones,0
	Btfsc	STATUS,2
	call	four
	movlw	0x03
	subwf	Ones,0
	Btfsc	STATUS,2
	call	three
	movlw	0x02
	subwf	Ones,0
	Btfsc	STATUS,2
	call	two
	movlw	0x01
	subwf	Ones,0
	Btfsc	STATUS,2
	call	one
	movlw	0x00
	subwf	Ones,0
	Btfsc	STATUS,2
	call	zero
	return
;******************************************************************	
xmit_on					; Turns transmitter on
	bsf		GPIO,2		; turn pin5 high, turns transmitter carrier "on"
	call	pause
	call	pause
	call	pause
	nop
	nop
	nop
	nop
	nop
	return
;*******************************************************************	
xmit_off	
	bcf		GPIO,2		; turns transmitter "off"
	return

;*******************************************************************
dit
	movf	Dit,0		; load dit duration value
	movwf	count		; load the dit duration time into the countdown file
	call	Tone		; call the tone generation subroutine
	call	pause		; space
	return
;******************************************************************
dah
	movf	Dah,0		; load dit duration value
	movwf	count		; load the dit duration time into the countdown file
	call	Tone		; call the tone generation subroutine
	call	pause		; space
	return

;******************************************************************
pause					; Pause between Morcse characters
	movf	Pause,0
	movwf	count
pause_1
	bcf		INTCON,2
P_loop
	btfss	INTCON,2
	goto	P_loop
	decfsz	count,1
	goto	pause_1
	return
;***************************************************************	
Tone					; 700 Hertz tone
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xf5		;f4=640Hz
	movwf	TMR0
	bsf		GPIO,4		; start tone modulation, turn pin4 "on"
high_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	high_		; delay loop
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xf5
	movwf	TMR0
	bcf		GPIO,4		;turn pin4 "off"
low_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	low_			;delay loop
	decfsz	count,1
	goto	Tone
	return
	
	;***************************************************************	
Tone2					; extra tone not used
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xd0
	movwf	TMR0
	bsf		GPIO,4		; start tone modulation, turn pin4 "on"
high2_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	high2_		; delay loop
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xd0
	movwf	TMR0
	bcf		GPIO,4		;turn pin4 "off"
low2_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	low2_			;delay loop
	decfsz	count,1
	goto	Tone2
	return
	;***************************************************************	
Tone3					; extra tone not used
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xe0
	movwf	TMR0
	bsf		GPIO,4		; start tone modulation, turn pin4 "on"
high3_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	high3_		; delay loop
	bcf		INTCON,2	;clear timer interupt flag
	movlw	0xe0
	movwf	TMR0
	bcf		GPIO,4		;turn pin4 "off"
low3_
	btfss	INTCON,2	; timer 0 overflow interup flag
	goto	low3_			;delay loop
	decfsz	count,1
	goto	Tone3
	return
;*****************************************************************
Delay_S						; Short delay
	movlw	0x40
	movwf	count
DS_Delay
	bcf		INTCON,2
DS_loop
	btfss	INTCON,2
	goto	DS_loop
	decfsz	count,1
	goto	DS_Delay
	return
;*****************************************************************
Delay_L						; Long delay
	movlw	0xff
	movwf	count
DL_Delay
	bcf		INTCON,2
DL_loop
	btfss	INTCON,2
	goto	DL_loop
	decfsz	count,1
	goto	DL_Delay
	return
;********************************************************************
Wait					; One minute delay
	bcf		GPIO,2		; turns transmitter "off"
	call	Delay_L
	decfsz 	count2,1
	goto	Wait
	return
;*******************************************************************
C_sign					; input call sigh characters here
	call	_X
	call	_X
	call	five
	call	_X
	call	_X
	call	_X
	return
;*******************************************************************
Max1						; Used to capature Maximum value
	movf	AtoD1_L,0
	movwf	SourceL
	movf	AtoD1_H,0
	movwf	SourceH
	movf	MaxRead1_H,0
	movwf	DestH
	movf	MaxRead1_L,0
	movwf	DestL
	call	Subtract
	btfss	STATUS,0
	call	MaxUpdate1
	return
;*******************************************************************
Min1						; Record Minimum value
	movf	AtoD1_L,0
	movwf	SourceL
	movf	AtoD1_H,0
	movwf	SourceH
	movf	MinRead1_H,0
	movwf	DestH
	movf	MinRead1_L,0
	movwf	DestL
	call	Subtract
	btfsc	STATUS,0
	call	MinUpdate1
	return	
;********************************************************************
Subtract	; a 16 bit subtraction sub program.  Source - Dest.  
			; will return a STATUS,0=1 if a negative result is produced.
			; the high order byte is in "H" the low order byte is in "L"
	movf	SourceL,W	
	subwf	DestL,1		
	movf	SourceH,W	
	btfss	STATUS,C
	incfsz	SourceH,W	
	subwf	DestH,1		
	return
;******************************************************************	
MaxUpdate1
	movf	AtoD1_L,0	; the CurrentReading lower bits register.
	movwf	MaxRead1_L	; move the maxium presure reading lower bits to _
	movf	AtoD1_H,0	; move current presure reading lower bits back into W register.
	movwf	MaxRead1_H	;skip this step else replace maxRead with CurrentRead
	return
;*******************************************************************
MinUpdate1
	movf	AtoD1_L,0	; the CurrentReading lower bits register.
	movwf	MinRead1_L	; move the maxium presure reading lower bits to _
	movf	AtoD1_H,0	; move current presure reading lower bits back into W register.
	movwf	MinRead1_H	;skip this step else replace maxRead with CurrentRead
	return
;*************************MORSE Code***********************************
one
	call	dit
	call	dah
	call	dah
	call	dah
	call	dah
	call	pause
	return
two
	call	dit
	call	dit
	call	dah
	call	dah
	call	dah
	call	pause
	return
three
	call	dit
	call	dit
	call	dit
	call	dah
	call	dah
	call	pause
	return
four
	call	dit
	call	dit
	call	dit
	call	dit
	call	dah
	call	pause
	return
five
	call	dit
	call	dit
	call	dit
	call	dit
	call	dit
	call	pause
	return
six
	call	dah
	call	dit
	call	dit
	call	dit
	call	dit
	call	pause
	return
seven
	call	dah
	call	dah
	call	dit
	call	dit
	call	dit
	call	pause
	return
eight
	call	dah
	call	dah
	call	dah
	call	dit
	call	dit
	call	pause
	return
nine
	call	dah
	call	dah
	call	dah
	call	dah
	call	dit
	call	pause
	return
zero
	call	dah
	call	dah
	call	dah
	call	dah
	call	dah
	call	pause
	return	
_A
	call	dit
	call	dah
	call	pause
	return
_B
	call	dah
	call	dit
	call	dit
	call	dit
	call	pause
	return
_C
	call	dah
	call	dit
	call	dah
	call	dit
	call	pause
	return
_D
	call	dah
	call	dit
	call	dit
	call	pause
	return
_E
	call	dit
	call	pause
	return
_F
	call	dit
	call	dit
	call	dah
	call	dit
	call	pause
	return
_G	
	call	dah			;G
	call	dah	
	call	dit
	call	pause
	return
_H
	call	dit			;H
	call	dit	
	call	dit
	call	dit
	call	pause
	return
_I
	call	dit			;I
	call	dit	
	call	pause
	return
_J
	call	dit			;J
	call	dah
	call	dah	
	call	pause
	return
_K
	call	dah			;K
	call	dit	
	call	dah
	call	pause
	return
_L
	call	dit			;L
	call	dah
	call	dit
	call	dit
	call	pause
	return
_M
	call	dah
	call	dah
	call	pause
	return
_N
	call	dah
	call	dit
	call	pause
	return
_O
	call	dah
	call	dah
	call	dah
	call	pause
	return
_P	
	call	dit
	call	dah
	call	dah
	call	dit
	call	pause
	return
_Q
	call	dah
	call	dah
	call	dit
	call	dah
	call	pause
	return
_R
	call	dit
	call	dah
	call	dit
	call	pause
	return
_S
	call	dit
	call	dit
	call	dit
	call	pause
	return
_T
	call	dah
	call	pause
	return
_U
	call	dit
	call	dit
	call	dah
	call	pause
	return
_V
	call	dit
	call	dit
	call	dit
	call	dah
	call	pause
	return
_W
	call	dit
	call	dah
	call	dah
	call	pause
	return
_X
	call	dah
	call	dit
	call	dit
	call	dah
	call	pause
	return
_Y
	call	dah
	call	dit
	call	dah
	call	dah
	call	pause
	return
_Z	
	call	dah		;Z
	call	dah	
	call	dit
	call	dit
	call	pause
	return
;**************************************************************
	END

