;******************************************************
;******************************************************

; Main Project     : OCRG
; Project Name     : OCRG CWVM - CW Voltmeter
; File Name        : comm.asm
; Version          : A03
; PIC Used         : PIC12HV615
; Assembler        : MPLAB MPASMWIN from Microchip Technology, Inc.
; Initial Date     : Nov 19, 2009
; Last Update date : Dec 22, 2009
; Firmware Eng.    : WA7ZVY
; HW Design Eng.   : WA7ZVY
; Copyright 2009   : WA7ZVY
;
;******************************************************
;
; Description of this code:
;
; This routine sends morse code characters out the GP2 port. 
;
;******************************************************
;
;	Function List (in top-2-bottom order):
;		void delay_dit_times(char number_of_dits)
;		void send_morse_element(char element)
;
;******************************************************
;
;	Modification History:
;	=-=-=-=-=-=-=-=-=-=-=
;	11-19-09 pm - Initial creation.
;	
;******************************************************
;******************************************************

; *****************************************************
;   === Include files ===
;*****************************************************
	LIST   P=12HV615			;List directive to define processor

#include	P12HV615.INC		;Processor specific variable definitions
#include	constants.inc		;Coding constants
#include	micro_bits.inc		;Hardware defined bits
#include	variable_def.inc	;Variable definitions


COMM_CODE	CODE			;comm code space

;*****************************************************
;*****************************************************
;
;	Name:		delay_dit_times
;	
;	Abstract:	Delays for a number of morse dits amount of time.
;				Using the word PARIS, we get 50 dit amounts of time per each word per minute.
;				For 1 WPM we would need 50 dits in 60 seconds, and for 20 WPM we would need
;				1000 dits in 60 seconds. This routine uses Timer 2 to create the delays.
;				Timer 2's time delay is dependent upon the position of the speed potentiometer,
;				which is sampled at the beginning of each voltage report.
;				50 dits/min/WPM ==> 0.833 dits/sec/WPM.
;				Timer 2 is set to use a prescale and postscale of 16.  The PR2 is determined
;				by the ADC conversion of the speed potentiometer. The needed value is looked
;				up in a table (see cwvm_main.asm). We also need a software postscale of 8 to
;				get down to a reasonable Morse code speed.
;
;	Callable Routines:
		global	delay_dit_times
;
;	Called Routines:  None.
;
;	Global Variables Used:
;		arg1_lo		contains the number of "morse element times" to delay
;		
;	Local Variables Used:
;		b0_tmp1_lo	used for a software postscaler counter
;		b0_tmp1_hi	used as a count down counter for the actual number of morse element times to delay
;
;	Return Values:	None.
;		
;*****************************************************
;*****************************************************
delay_dit_times
	banksel	BANK0
	movf	arg1_lo,W
	movwf	b0_tmp1_hi
	movlw	0x08				;Set the software postscaler for 8
	movwf	b0_tmp1_lo
	clrf	TMR2				;Clear Timer 2, which clears the pre and post scalers too
	bsf		T2CON,TMR2ON		;Turn on Timer 2, which clears the pre and post scalers too

ddt_1
	btfss	PIR1,TMR2IF			;Wait for the timer to match PR2
	goto	ddt_1
	bcf		T2CON,TMR2ON		;Turn off Timer 2
	bcf		PIR1,TMR2IF			;Clear the flag
	clrf	TMR2				;Clear Timer 2, which clears the pre and post scalers too
	bsf		T2CON,TMR2ON		;Turn on Timer 2
	decfsz	b0_tmp1_lo,F
	goto	ddt_1				;Loop until the software postscaler has expired
	movlw	0x08				;Reload the software postscaler counter
	movwf	b0_tmp1_lo
	decfsz	b0_tmp1_hi,F
	goto	ddt_1				;Loop for the number of dit times to delay

	bcf		T2CON,TMR2ON		;Turn off Timer 2
	return



;*****************************************************
;*****************************************************
;
;	Name:		send_morse_element
;	
;	Abstract:	Sends out a morse dah, dit, or character space.
;
;	Callable Routines:
		global	send_morse_element
;
;	Called Routines:
;		extern	delay_dit_times
;
;	Global Variables:
;		arg1_lo		Contains the ASCII character of the type of element to send: "-", ".", " ".
;		b0_ToneOn	Contains the flag to turn on, or off, the sound tone going to the speaker.
;					The b0_ToneOn variable is read inside the interrupt service routine.
;		
;	Local Variables:
;	
;	Return Values:	None.
;		
;*****************************************************
;*****************************************************
send_morse_element
	banksel	BANK0
	movf	arg1_lo,W
	xorlw	'-'				;is it a morse dah
	btfsc	STATUS,Z
	goto	sme_dah
	movf	arg1_lo,W
	xorlw	'.'				;is it a morse dit
	btfsc	STATUS,Z
	goto	sme_dit
	movf	arg1_lo,W
	xorlw	' '				;is it a morse space
	btfsc	STATUS,Z
	goto	sme_space
	return					;its none of the above so just return; Note! this shouldn't happen

sme_dah						;send a morse dah
	movlw	TRUE
	movwf	b0_ToneOn
	movlw	0x03
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	banksel	BANK0
	movlw	FALSE
	movwf	b0_ToneOn
	movlw	0x01
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	return

sme_dit						;send morse dit
	movlw	TRUE
	movwf	b0_ToneOn
	movlw	0x01
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	banksel	BANK0
	movlw	FALSE
	movwf	b0_ToneOn
	movlw	0x01
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	return

sme_space					;send morse space
	movlw	FALSE
	movwf	b0_ToneOn
	movlw	0x03
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	banksel	BANK0
	movlw	FALSE
	movwf	b0_ToneOn
	movlw	0x01
	movwf	arg1_lo
	pagesel	delay_dit_times
	call	delay_dit_times
	return



;*****************************************************
;*****************************************************
;
;	Name:		send_morse_char
;	
;	Abstract:	Sends out a morse code character ("0" to "9", ".", "V", or "?").
;
;	Callable Routines:
		global	send_morse_char
;
;	Called Routines:
;		extern	send_morse_element
		extern	morse_table
		extern	morse_one,  morse_two,    morse_three,    morse_four, morse_five
		extern	morse_six,  morse_seven,  morse_eight,    morse_nine, morse_zero
		extern	morse_v,    morse_period, morse_question, morse_error
;
;	Global Variables:
;		arg1_lo		Contains the binary value of the character to send
;		
;	Local Variables:
;		b0_tmp1_index
;		b0_tmp1_counter
;	
;	Return Values:	None.
;		
;*****************************************************
;*****************************************************
send_morse_char
	banksel	BANK0
	movlw	0x00			;Is the character a zero
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_1
	movlw	morse_zero		;Yes, so setup the index to point at the elements
	movwf	b0_tmp1_index
smc_1
	movlw	0x01			;Is the character a one
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_2
	movlw	morse_one
	movwf	b0_tmp1_index
smc_2
	movlw	0x02			;Is the character a two
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_3
	movlw	morse_two
	movwf	b0_tmp1_index
smc_3
	movlw	0x03			;Is the character a three
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_4
	movlw	morse_three
	movwf	b0_tmp1_index
smc_4
	movlw	0x04			;Is the character a four
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_5
	movlw	morse_four
	movwf	b0_tmp1_index
smc_5
	movlw	0x05			;Is the character a five
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_6
	movlw	morse_five
	movwf	b0_tmp1_index
smc_6
	movlw	0x06			;Is the character a six
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_7
	movlw	morse_six
	movwf	b0_tmp1_index
smc_7
	movlw	0x07			;Is the character a seven
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_8
	movlw	morse_seven
	movwf	b0_tmp1_index
smc_8
	movlw	0x08			;Is the character a eight
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_9
	movlw	morse_eight
	movwf	b0_tmp1_index
smc_9
	movlw	0x09			;Is the character a nine
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_10
	movlw	morse_nine
	movwf	b0_tmp1_index
smc_10
	movlw	0x0f			;Is the character a period (we use 0x0f for a period)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_11
	movlw	morse_period
	movwf	b0_tmp1_index
smc_11
	movlw	0x0e			;Is the character a V (we use 0x0e for a V)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_12
	movlw	morse_v
	movwf	b0_tmp1_index
smc_12
	movlw	0x0d			;Is the character an unused character (we currently don't use 0x0d)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_13
	movlw	morse_error
	movwf	b0_tmp1_index
smc_13
	movlw	0x0c			;Is the character an unused character (we currently don't use 0x0c)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_14
	movlw	morse_error
	movwf	b0_tmp1_index
smc_14
	movlw	0x0b			;Is the character an unused character (we currently don't use 0x0b)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_15
	movlw	morse_error
	movwf	b0_tmp1_index
smc_15
	movlw	0x0a			;Is the character an unused character (we currently don't use 0x0a)
	xorwf	arg1_lo,W
	btfss	STATUS,Z
	goto	smc_16
	movlw	morse_error
	movwf	b0_tmp1_index
smc_16
	movf	b0_OverRange,F	;If the OverRange condition exists, send that instead (uses a "?" mark)
	btfsc	STATUS,Z
	goto	smc_17
	movlw	morse_question
	movwf	b0_tmp1_index
smc_17

; Now look up the character elements in the data tables and send them, but
; first calculate the real overall offset into the complete morse_table
	movlw	morse_table
	subwf	b0_tmp1_index,F
; Now get the "number of elements in the character to send" and put that value into the counter
;	pageselw	morse_table
	movlw	0x00
	movwf	PCLATH
	movf	b0_tmp1_index,W
	call	morse_table			;On return, W contains the number of elements in character,
	movwf	b0_tmp1_counter		; put that into the access counter
; Now get the individual elements that make up the character and send each one
smc_18
;	pageselw	morse_table
	movlw	0x00
	movwf	PCLATH
	incf	b0_tmp1_index,F		;Increment the index to the next element
	movf	b0_tmp1_index,W
	call	morse_table			;On return, W contains the element to send
	movwf	arg1_lo
	pagesel	send_morse_element
	call	send_morse_element
	banksel	BANK0
	decfsz	b0_tmp1_counter,F
	goto	smc_18

	return


	end
;End of File (comm.asm)
