' IR Control for FT817
' Version 4 3/30/09
' Copyright (c) 2009 KE8WO, Gary Sargent, 4227 Willow Run Dr., Dayton, Ohio 45430
' All rights reserved
' Code modified by Fred Reiselt, WB5CON, to work with the new 18M2 PICAXE, 10/25/2010

'-----------------------------------------------------------------------------
'
' This program is used to receive commands from a TV remote control using th Sony protocol.
' Commands are translated into that used to control a Yaesu FT817 transceiver.
'
' PICAXE I/O connections expected:
'	Infrared sensor output connected to pin 17 (input 0)
'	Dual color LED connect with 330 ohm series resistor to pins 6 and 7 (outputs 0 and 1)
'	FT817 serial RXD to pin 10 (output 4) (FT817 CAT rate must be 4800 baud)
'	PC connected to pin 2 (serial in) and 3 (serial out)
'
' Commands supported
'
'	<power> ... toggle radio power off/on
'
'	<mmmkkk><Ch+> ... set frequency, all six digits required
'			mmm = megahertz
'			kkk = kilohertz
'
'	<mmm><Ch+> ... 	set frequency, three digits only required
'			mmm = megahertz
'				kilohertz set to zero
'
'	<n><Ch+> ...set receiving mode, toggle VFO's, 
'			0 = LSB
'			1 = USB
'			2 = CW
'			3 = CWR
'			4 = AM
'			5 = FM
'			6 = Digital
'			7 = Packet
'			8 = Toggle VFO A/B
'
'	<n><Ch-> ..	set frequency increment
'			0 = 100 hz
'			1 = 1 khz
'			2 = 5 khz
'			3 = 10 khz
'			4 = 100 khz
'			5 = 1 mhz
'
'	<Ch+>	...	Tune up by current increment
'
'	<Ch->	...	Tune down by current increment
'
'	<nn><Ch+> .	Go to band
'			00 = 160 M
'			01 = 80 M
'			02 = 60 M
'			03 = 40 M
'			04 = 30 M
'			05 = 20 M
'			06 = 17 M
'			07 = 15 M
'			08 = 12 M
'			09 = 10 M
'			10 =  6 M
'			11 =  2 M
'			12 = 70 CM
'
'			13 = AM BCB
'			14 = FM BCB
'			15 = Aircraft Band
'
'			16 = SWBCB 49 M
'			17 = SWBCB 41 M
'			18 = SWBCB 31 M
'			29 = SWBCB 25 M
'			20 = SWBCB 22 M
'			21 = SWBCB 19 M
'			22 = SWBCB 17 M
'			23 = WWV  5 mHz
'			24 = WWV 10 mHz
'
'
'	Sony Infrared Remote Control Codes:
'
'			Key Value
'			Enter	11
'			1 	0
'			2	1
'			3 	2
'			4 	3
'			5 	4
'			6 	5
'			7 	6
'			8 	7
'			9 	8
'			Ch+ 	16
'			0 	9
'			V+ 	18
'			Ch- 	17
'			10+ 	12
'			V- 	19
'			Mute 	20
'			Power	21
'
'-----------------------------------------------------------------------------
' Define and initialize variables and constants
'-----------------------------------------------------------------------------
'
' PICAXE RAM variables
'
symbol Valid_Command 		= bit0
symbol Carry 			= bit1	' Used in arithmetic routine
symbol Borrow			= bit2	' Used in arithmetic routine
symbol Radio_Power		= bit3	' Radio power status
symbol IR_Byte_Counter 		= b2
symbol Command_End_Byte 	= b3
symbol IR_Buffer_Location 	= b4
symbol Temp0 			= b5
symbol Temp1 			= b6
symbol Temp2 			= b7
symbol Temp3 			= b8
'
' Other flags
'
symbol TRUE = 1
symbol FALSE = 0
'
' Some of the IR control key codes
'
symbol Enter 		= 11
symbol Power		= 21
symbol Ch_Plus 		= 16
symbol Ch_Minus 		= 17
symbol Vol_Plus 		= 18
symbol Vol_Minus 		= 19
symbol Mute 		= 20
'
' Basic FT817 CAT command codes
'
symbol Radio_Set_Freq 	= $01
symbol Radio_Turn_On 	= $0F
symbol Radio_Turn_Off 	= $8F
symbol Radio_Toggle_VFO = $81
symbol Radio_Set_Mode 	= $07
symbol Radio_Power_On	= $0F
symbol Radio_Power_Off	= $8F
'
' FT817 CAT command parameters
'
symbol Radio_Mode_LSB	= $00
symbol Radio_Mode_USB	= $01
symbol Radio_Mode_CW	= $02
symbol Radio_Mode_CWR	= $03
symbol Radio_Mode_AM	= $04
symbol Radio_Mode_FM	= $08
symbol Radio_Mode_Dig	= $0A
symbol Radio_Mode_Pkt	= $0C
'
' PICAXE I/O used
'
symbol LED_Pin_Green 	= 0
symbol LED_Pin_Red    	= 1
symbol Serial_Port 	= 2
symbol Radio_Port 	= 4

'-----------------------------------------------------------------------------
' Additional Storage Variables Area $50 to $7F and $C0 to $EF on PICAXE 18X
' These are in RAM and not preserved during power down.
' Accessible only via PEEK and POKE commands.
'-----------------------------------------------------------------------------
'
symbol IR_Buffer_Start 	= $50 	' $50 thru $57
symbol Radio_Mode   	= $58
symbol Radio_Step   	= $59
symbol Radio_Band   	= $5A

symbol Radio_Cmd_B1 	= $60		' Radio Command 5 Byte Strings saved here
symbol Radio_Cmd_B2 	= $61
symbol Radio_Cmd_B3 	= $62
symbol Radio_Cmd_B4 	= $63
symbol Radio_Cmd_B5 	= $64

symbol Radio_Freq_B1	= $C0		' Start of 8 byte BCD current frequency
symbol Radio_Freq_B2	= $C1		' Organized from most significant ($C0) to least ($C7)
symbol Radio_Freq_B3	= $C2
symbol Radio_Freq_B4	= $C3
symbol Radio_Freq_B5	= $C4
symbol Radio_Freq_B6	= $C5
symbol Radio_Freq_B7	= $C6
symbol Radio_Freq_B8	= $C7

symbol Radio_Step_Size_B1= $C8	' Start of 8 byte BCD current frequency step size
symbol Radio_Step_Size_B2= $C9	' Organized from most significant ($C8) to least ($CF)
symbol Radio_Step_Size_B3= $CA
symbol Radio_Step_Size_B4= $CB
symbol Radio_Step_Size_B5= $CC
symbol Radio_Step_Size_B6= $CD
symbol Radio_Step_Size_B7= $CE
symbol Radio_Step_Size_B8= $CF

symbol Radio_New_Freq=$D0		' Start of 8 byte BCD new frequency after increment or decrement by 'step'

'-----------------------------------------------------------------------------
' EEPROM Band and related data storage area $00 to $FF on PICAXE 18X
' These are in the EEPROM data area and are preserved during a power down.
' Accessible via the DATA/EEPROM (when downloading a program) and 
' READ and WRITE commands during program operation.
'-----------------------------------------------------------------------------
'
' 25 bands or memories with the following format:
'	Bytes 1 to 4	Desired frequency in BCD format AB CD EF GH (same as set frequency F817 command)
'				where AB C is the megahertz and D EF is the kilohertz of the frequency.
'	Byte  5		Radio Mode ("M") and Frequency Step ("S") in MS BCD format 
'				(note mode is per radio command requirements .i.e FM=8)
'
data	000,($00,$18,$00,$00,$01)	' Band 00:  160 meters
data	005,($00,$35,$00,$00,$01)	' Band 01:   80 meters
data	010,($00,$53,$35,$00,$11)	' Band 02:   60 meters
data	015,($00,$70,$00,$00,$01)	' Band 03:   40 meters
data	020,($01,$01,$00,$00,$11)	' Band 04:   30 meters
data	025,($01,$40,$00,$00,$11)	' Band 05:   20 meters
data	030,($01,$80,$60,$00,$11)	' Band 06:   17 meters
data	035,($02,$10,$00,$00,$11)	' Band 07:   15 meters
data	040,($02,$48,$90,$00,$11)	' Band 08:   12 meters
data	045,($02,$80,$00,$00,$11)	' Band 09:   10 meters
data	050,($05,$00,$00,$00,$82)	' Band 10:    6 meters		
data	055,($14,$40,$00,$00,$82)	' Band 11:    2 meters
data	060,($43,$00,$00,$00,$82)	' Band 12:   70 cm.
	
data	065,($00,$05,$40,$00,$43)	' Band 13:   BCB 
data	070,($08,$80,$00,$00,$84)	' Band 14:   FM 
data	075,($10,$80,$00,$00,$42)	' Band 15:   Air
	
data	080,($00,$57,$30,$00,$42)	' Band 16:   49 meters SWBCB
data	085,($00,$68,$90,$00,$42)	' Band 17:   41 meters SWBCB
data	090,($00,$92,$50,$00,$42)	' Band 18:   31 meters SWBCB
data	095,($01,$15,$00,$80,$42)	' Band 19:   25 meters SWBCB
data	100,($01,$35,$70,$00,$42)	' Band 20:   22 meters SWBCB
data	105,($01,$50,$30,$00,$42)	' Band 21:   19 meters SWBCB
data	110,($01,$74,$80,$00,$42)	' Band 22:   17 meters SWBCB
	
data	115,($00,$50,$00,$00,$42)	' Band 23:   WWV 5
data	120,($01,$00,$00,$00,$42)	' Band 24:   WWV 10
'
' The following are the six tuning increments/steps supported (in hz)
' Organized from most significant to least 
'
symbol Tuning_Step = 125
data	125,(0,0,0, 0,0,0, 1,0)		' 100 hz
data	133,(0,0,0, 0,0,1, 0,0)		' 1 khz
data	141,(0,0,0, 0,0,5, 0,0)		' 5 khz
data	149,(0,0,0, 0,1,0, 0,0)		' 10 khz
data	157,(0,0,0, 1,0,0, 0,0)		' 100 khz
data	165,(0,0,1, 0,0,0, 0,0)		' 1 mhz
	
'-----------------------------------------------------------------------------
' Main program loop
'-----------------------------------------------------------------------------
Main:
	gosub Initialize
	
Main_Loop:

	poke  Radio_Cmd_B1,0	' Initialize radio command buffer to all zero's
	poke  Radio_Cmd_B2,0	' (Clear and remnants of previous command)
	poke  Radio_Cmd_B3,0
	poke  Radio_Cmd_B4,0
	poke  Radio_Cmd_B5,0
	gosub Get_IR_Command	' Get an IR command
	gosub SetUp_Radio_Cmd	' Set up and process the command
	
	if Valid_Command = TRUE then Main_lOOP	' Go get the next command
	
Main_Error:
	serout Serial_Port,N2400,(13,10,"Main command error")
	goto Main_Loop
	

'-----------------------------------------------------------------------------
' Initialize for operation
'-----------------------------------------------------------------------------
Initialize:

' Basic PIC state
' Variables
' I/O
	Radio_Power = TRUE		' Assume radio is on if got to here
	Temp2 = 5
	gosub  Blink_Green_LED		' Blink Green LED 5 times to show all ok on startup
	gosub  Blink_Red_LED		' Blink Red LED 5 times to show all ok on startup
	Sertxd (13,10,"PICAXE Yaesu FT817 Infrared Controller v4 3/30/09 modified 10/25/10 by WB5CON")
	Sertxd (13,10,"(c) KE8WO")
	Sertxd (13,10," ")	
	pause  1000
	
	SerOut Radio_Port,T4800,($01,$42,$75,$00,$01)	' This to get the attention of the radio
	pause 500
	SerOut Radio_Port,T4800,($01,$00,$00,$00,$07)	' Select USB mode
	pause 500
	SerOut Radio_Port,T4800,($01,$42,$75,$00,$01)	' Tune radio to 14.275
	
	pwmout 3,199,200			' Output a 5 khz squarewave on pin 3 of PICAXE chip
	return


'-----------------------------------------------------------------------------
' Get a command line from the IR remote contol.  Max of 8 bytes long	
'-----------------------------------------------------------------------------
Get_IR_Command:
	IR_Byte_Counter = 0
	Sertxd (13,10,"Keys pressed: ")	' Echo keys to debug window on PC (if used)
	
Get_IR_Command_Loop:
	irin C.0, infra			' Read a byte from IR remote to "infra"
	Temp2 = 1
	gosub Blink_Green_LED	' Blink LED .. also Slow things down a bit (IR remote sends repeat strings of a command while a button is pressed)

	if infra >= 0 AND infra <= 8 then INC infra	' Was key pressed a 1 thru 9? Yes, correct infra byte read
	goto Get_IR_Command_Loop_Not_Enter
	endif		
	
	if infra = 9 then let infra = 0 			' Was key pressed a zero? Yes, correct infra byte read
	goto Get_IR_Command_Loop_Not_Enter
	endif		
								
	if infra = 11 then let infra = Ch_Plus 			' Was the Enter key pressed? Yes, make it equal to Ch+
	goto Get_IR_Command_Loop_Not_Enter
	endif

Get_IR_Command_Loop_Not_Enter:
	IR_Buffer_Location = IR_Buffer_Start + IR_Byte_Counter
	poke IR_Buffer_Location,infra 					' Save IR byte in IR command buffer
	IR_Byte_Counter = IR_Byte_Counter + 1
	Sertxd (#infra," ")							' Send key pressed to PC dubug window
	Temp1 = infra
	Command_End_Byte = 255
	lookdown infra,(Ch_Plus,Ch_Minus,Vol_Plus,Vol_Minus,Power),Command_End_Byte ' Look for valid command terminator
	
	if Command_End_Byte < 255 then Get_IR_Command_Return 		' Done if have a proper command terminator byte
	if Temp1 < 0 or Temp1 > 9 then Get_IR_Command_Error		' Check for valid number key pressed
	if IR_Byte_Counter <8 then  Get_IR_Command_Loop 		' Only accept eight bytes, maximaum
	
Get_IR_Command_Error:
	Valid_Command = FALSE							' No command or invalid key pressed
	Temp2 = 2
	gosub Blink_Red_LED
	return
	
Get_IR_Command_Return:
	Valid_Command = TRUE
	Command_End_Byte = infra
	return 

	
'-----------------------------------------------------------------------------
' Set up the 10 nibble / 5 byte command string to send to the radio
'-----------------------------------------------------------------------------
Setup_Radio_Cmd:
	
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Check for and Process command:
'
'	<mmmkkk><Ch+> ... set frequency, all six digits required
'			mmm = megahertz
'			kkk = kilohertz
'
	if IR_Byte_Counter <> 7 or Command_End_Byte <> Ch_Plus then goto Setup_Radio_Cmd_Set_Mhz

	peek  $50,Temp1		' Move desired frequency from command buffer to radio freq. area
	poke  Radio_Freq_B1,Temp1
	peek  $51,Temp1	
	poke  Radio_Freq_B2,Temp1
	peek  $52,Temp1	
	poke  Radio_Freq_B3,Temp1
	peek  $53,Temp1	
	poke  Radio_Freq_B4,Temp1
	peek  $54,Temp1	
	poke  Radio_Freq_B5,Temp1
	peek  $55,Temp1	
	poke  Radio_Freq_B6,Temp1
	poke  Radio_Freq_B7,0	' Last two frequency digits are 0
	poke  Radio_Freq_B8,0
	gosub Tune_Radio		' Tune radio to this frequency
	
	goto Setup_Radio_Cmd_Finish

		
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Check for and Process command:
'
'	<mmm><Ch+> ... set frequency, three digits only required
'			mmm = megahertz
'				kilohertz set to zero
'
Setup_Radio_Cmd_Set_Mhz:

	if IR_Byte_Counter <> 4 or Command_End_Byte <> Ch_Plus then goto Setup_Radio_Cmd_Set_Mode

	peek  $50,Temp1		' Move desired frequency from command buffer to radio freq. area
	poke  Radio_Freq_B1,Temp1
	peek  $51,Temp1	
	poke  Radio_Freq_B2,Temp1
	peek  $52,Temp1	
	poke  Radio_Freq_B3,Temp1	
	poke  Radio_Freq_B4,0	
	poke  Radio_Freq_B5,0	
	poke  Radio_Freq_B6,0
	poke  Radio_Freq_B7,0	' Last two frequency digits are 0
	poke  Radio_Freq_B8,0
	gosub Tune_Radio		' Tune radio to this frequency
	
	goto Setup_Radio_Cmd_Finish	

		
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Check for and Process command:
'
'	<n><Ch+> ...set receiving mode, toggle VFO's, 
'			0 = LSB
'			1 = USB
'			2 = CW
'			3 = CWR
'			4 = AM
'			5 = FM
'			6 = Digital
'			7 = Packet
'			8 = Toggle VFO A/B
'		
Setup_Radio_Cmd_Set_Mode:
	if IR_Byte_Counter <> 2 or Command_End_Byte <> Ch_Plus then Setup_Radio_Cmd_Power

	peek $50,b7					' Get first command byte
	if b7 > 8 then Setup_Radio_Cmd_Error' Valid values are from 0 thru 8
	
	' Look up corresponding mode byte to be sent to the radio
	lookup b7, (Radio_Mode_LSB,Radio_Mode_USB,Radio_Mode_CW,Radio_Mode_CWR,Radio_Mode_AM,Radio_Mode_FM,Radio_Mode_Dig,Radio_Mode_Pkt,Radio_Toggle_VFO),b8

	poke Radio_Cmd_B1,b8			' Put mode in radio command area
	poke Radio_Cmd_B5,Radio_Set_mode	' Finish the radio command set up
	
	if b8 <> Radio_Toggle_VFO then Setup_Radio_Cmd_Save_Mode
	
	poke Radio_Cmd_B5,Radio_Toggle_VFO	' Handle Toggle VFO special case
	gosub Set_Radio_Toggle_VFO		' Toggle VFO's in radio
	goto Setup_Radio_Cmd_Finish
	
Setup_Radio_Cmd_Save_Mode:			' Was not toggle VFO, so must have been to set mode
	poke Radio_Mode,b8			' Save the new mode
	gosub	Set_Radio_Mode			' Set mode in radio
	goto Setup_Radio_Cmd_Finish


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	
' Check for and Process command:
'
'	<power> ... toggle radio power off/on
'		
Setup_Radio_Cmd_Power:
	if IR_Byte_Counter <> 1 or Command_End_Byte <> Power then Setup_Radio_Cmd_Set_Step
	
	poke Radio_Cmd_B5,Radio_Power_On			' Assume it was to power on .. set radio command to power on
	if Radio_Power = False then Setup_Radio_CMD_On	' Branch if it was (ie. radio power is now off)
	poke Radio_Cmd_B5,Radio_Power_Off			' Else it was power off .. set radio command to power off
	Radio_Power = False					' Remember we are powering radio off
	gosub	Output_Command_To_Radio	
	goto Setup_Radio_Cmd_Finish
	
Setup_Radio_Cmd_On:
	Radio_Power = True					' Remember we are powering radio on
	gosub	Output_Command_To_Radio	
	goto Setup_Radio_Cmd_Finish


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	
' Check for and Process command:
'
'	<n><Ch-> ..	set frequency increment
'			0 = 100 hz
'			1 = 1 khz
'			2 = 5 khz
'			3 = 10 khz
'			4 = 100 khz
'			5 = 1 mhz

Setup_Radio_Cmd_Set_Step:
	if IR_Byte_Counter <> 2 or Command_End_Byte <> Ch_Minus then Setup_Radio_Cmd_Tune_Up
	peek $50,Temp1						' Get first command byte
	if Temp1 > 5 then Setup_Radio_Cmd_Tune_Up
	Sertxd (13,10,"Setup_Radio_Cmd_Set_Step ",Temp1)
	gosub Setup_Frequency_Step	
	goto Setup_Radio_Cmd_Finish


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	
' Check for and Process command:
'
'	<ch+>	...	Tune up by current increment
'		
Setup_Radio_Cmd_Tune_Up:
	if IR_Byte_Counter <> 1 or Command_End_Byte <> Ch_Plus then Setup_Radio_Cmd_Tune_Down
	gosub Add_Tuning_Step
	gosub Tune_Radio
	goto Setup_Radio_Cmd_Finish


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''	
' Check for and Process command:
'	<ch->	...	Tune down by current increment
'
Setup_Radio_Cmd_Tune_Down:
	if IR_Byte_Counter <> 1 or Command_End_Byte <> Ch_Minus then Setup_Radio_Cmd_Goto_Band
	gosub Subtract_Tuning_Step
	gosub Tune_Radio
	goto Setup_Radio_Cmd_Finish

	
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Check for and Process command:
'	
'	<nn><Ch+> ..Go to band
'			00 = 160
'			01 = 80
'			02 = 60
'			03 = 40
'			04 = 30
'			05 = 20
'			06 = 17
'			07 = 15
'			08 = 10
'			09 = 6m
'			10 = 2 m
'			11 = 450
'
'			12 = BCB
'			13 = FM BCB
'			14 = Air Band
'
'			15 = Band 0
'			16 = Band 1
'			17 = Band 2
'			18 = Band 3
'			29 = Band 4
'			20 = Band 5
'			21 = Band 6
'			22 = Band 7
'			23 = Band 8
'			24 = Band 9
'
Setup_Radio_Cmd_Goto_Band:
	if IR_Byte_Counter <> 3 or Command_End_Byte <> Ch_Plus then Setup_Radio_Cmd_Error
	
	peek $50,Temp1			' Get first command byte
	peek $51,Temp2			' Get second command byte
	Temp1 =Temp1*10+Temp2		' Compute the band number 
	
	if Temp1 > 24 then Setup_Radio_Cmd_Error	' Error if not a valid band number
	
	' Move the desired band frequency, mode and step size from EEPROM to RAM
	
	poke Radio_Band,Temp1		' Save the radio band
	
	Temp1=Temp1*5			' Starting address of band in EEPROM memory
	read Temp1,Temp2			' Get BCD frequency digits
	Temp3=Temp2/16			' Get the most significant BCD digit
	poke Radio_Freq_B1,Temp3	' Save it
	poke $50,Temp3			' Also put it in IR command buffer	
	Temp3=Temp2 & $0F			' Get the least significant BCD digit
	poke Radio_Freq_B2,Temp3	' Save it
	poke $51,Temp3			' Also put it in IR command buffer	
	
	Temp1=Temp1+1			' Point to next band frequency byte
	read Temp1,Temp2			' Get BCD frequency digits
	Temp3=Temp2/16			' Get the most significant BCD digit
	poke Radio_Freq_B3,Temp3	' Save it	
	poke $52,Temp3			' Also put it in IR command buffer	
	Temp3=Temp2 & $0F			' Get the least significant BCD digit
	poke Radio_Freq_B4,Temp3	' Save it
	poke $53,Temp3			' Also put it in IR command buffer	
	
	Temp1=Temp1+1			' Point to next band frequency byte
	read Temp1,Temp2			' Get BCD frequency digits
	Temp3=Temp2/16			' Get the most significant BCD digit
	poke Radio_Freq_B5,Temp3	' Save it	
	poke $54,Temp3			' Also put it in IR command buffer	
	Temp3=Temp2 & $0F			' Get the least significant BCD digit
	poke Radio_Freq_B6,Temp3	' Save it
	poke $55,Temp3			' Also put it in IR command buffer	

	Temp1=Temp1+1			' Point to next band frequency byte
	read Temp1,Temp2			' Get BCD frequency digits
	Temp3=Temp2/16			' Get the most significant BCD digit
	poke Radio_Freq_B7,Temp3	' Save it	
	poke $56,Temp3			' Also put it in IR command buffer	
	Temp3=Temp2 & $0F			' Get the least significant BCD digit
	poke Radio_Freq_B8,Temp3	' Save it
	poke $57,Temp3			' Also put it in IR command buffer	
	
	Temp1=Temp1+1			' Point to next band frequency byte
	read Temp1,Temp2			' Get BCD mode and frequency step digits
	Temp3=Temp2/16			' Get the mode BCD digit
	poke Radio_Mode,Temp3		' Save the mode
	Temp1=Temp2 & $0F			' Get the tuning step size
	poke Radio_Step,Temp1		' Save it
	
	gosub	Setup_Frequency_Step	' Go complete the set up for the step size
	
	gosub	Tune_Radio			' Tune radio to this frequency
	gosub Set_Radio_Mode		' And set this band's mode
	
	return

Setup_Radio_Cmd_Finish:	
	Valid_Command = TRUE
	Temp2 = 1
	gosub Blink_Green_LED
	return 

Setup_Radio_Cmd_Error:
	Sertxd (13,10,"Setup_Radio_Cmd_Error ")
	Valid_Command = FALSE
	Temp2 = 1
	gosub Blink_Red_LED
	return

		
'-----------------------------------------------------------------------------
' Output the ten nibble command string to the radio via the serial port
'-----------------------------------------------------------------------------
	
Output_Command_To_Radio:
	Sertxd (13,10,"Output_Command_To_Radio: ")
	peek   Radio_Cmd_B1,Temp2
	serout Radio_Port,T4800,(Temp2)
	gosub  SerOutByteHex
	
	Sertxd (",")
	peek   Radio_Cmd_B2,Temp2
	serout Radio_Port,T4800,(Temp2)
	gosub  SerOutByteHex
	
	Sertxd (",")
	peek   Radio_Cmd_B3,Temp2
	serout Radio_Port,T4800,(Temp2)
	gosub  SerOutByteHex
	
	Sertxd (",")
	peek   Radio_Cmd_B4,Temp2
	serout Radio_Port,T4800,(Temp2)
	gosub  SerOutByteHex
	
	Sertxd (",")
	peek   Radio_Cmd_B5,Temp2
	serout Radio_Port,T4800,(Temp2)
	gosub  SerOutByteHex

	return	


'-----------------------------------------------------------------------------
' Set up the command to tune the radio to the current frequency 
' (per the Radio_Freq buffer) and then send it to the radio
'-----------------------------------------------------------------------------
	
Tune_Radio:
'	Sertxd (13,10,"Tune_Radio ")
	peek Radio_Freq_B1,Temp1
	peek Radio_Freq_B2,Temp2
	Temp1 = Temp1*16 + Temp2	' Set up BCD byte 1
	poke Radio_Cmd_B1,Temp1
'	
	peek Radio_Freq_B3,Temp1
	peek Radio_Freq_B4,Temp2
	Temp1 = Temp1*16 + Temp2	' Set up BCD byte 2
	poke Radio_Cmd_B2,Temp1
'
	peek Radio_Freq_B5,Temp1
	peek Radio_Freq_B6,Temp2
	Temp1 = Temp1*16 + Temp2	' Set up BCD byte 3
	poke Radio_Cmd_B3,Temp1
'
	peek Radio_Freq_B7,Temp1
	peek Radio_Freq_B8,Temp2
	Temp1 = Temp1*16 + Temp2	' Set up BCD byte 4
	poke Radio_Cmd_B4,Temp1

	poke Radio_Cmd_B5,Radio_Set_Freq	
	gosub	Output_Command_To_Radio
	return


'-----------------------------------------------------------------------------
' Set up the command to tune the radio to the current mode specified 
' and then send it to the radio
'-----------------------------------------------------------------------------

Set_Radio_Mode:
'	Sertxd (13,10,"Set_Radio_Mode ")
	peek Radio_mode,Temp1		' Get the mode desired
	poke Radio_Cmd_B1,Temp1		' Set up the radio commnd to set the mode
	poke Radio_Cmd_B2,0
	poke Radio_Cmd_B3,0
	poke Radio_Cmd_B4,0
	poke Radio_Cmd_B5,Radio_Set_Mode	
	gosub	Output_Command_To_Radio
	return


'-----------------------------------------------------------------------------
' Set up the command to toggle the radio's VFO 
' and then send it to the radio
'-----------------------------------------------------------------------------

Set_Radio_Toggle_VFO:
'	Sertxd (13,10,"Set_Radio_Toggle_VFO ")
	poke Radio_Cmd_B1,0		' Set up the radio commnd to toggle the VFO A/B
	poke Radio_Cmd_B2,0
	poke Radio_Cmd_B3,0
	poke Radio_Cmd_B4,0
	poke Radio_Cmd_B5,Radio_Toggle_VFO	
	gosub	Output_Command_To_Radio
	return


'-----------------------------------------------------------------------------
' Blink the red LED to indicate error conditions
'-----------------------------------------------------------------------------
	
Blink_Red_LED:

	for Temp1 = 1 to Temp2	' blink led 'Temp2' times
		pause 100 		' .1 seconds on
		high LED_Pin_Red
		low LED_Pin_Green
		pause 100 		' .1 seconds off
		low LED_Pin_Red
		low LED_Pin_Green
	next Temp1
	return

	
'-----------------------------------------------------------------------------
' Blink the green LED to indicate normal conditions
'-----------------------------------------------------------------------------
	
Blink_Green_LED:

	for Temp1 = 1 to Temp2	' blink led 'Temp2' times
		pause 100 		' .1 seconds on
		high LED_Pin_Green
		low LED_Pin_Red
		pause 100 		' .1 seconds off
		low LED_Pin_Red
		low LED_Pin_Green
	next Temp1
	return
	
	
'-----------------------------------------------------------------------------
' Set up a standard frequency step (move from EEPROM to RAM)
'-----------------------------------------------------------------------------

Setup_Frequency_Step:

	Temp1=8*Temp1+Tuning_Step	' Compute start of tuning step to move
	
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B1,Temp2
	
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B2,Temp2
	
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B3,Temp2
		
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B4,Temp2
		
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B5,Temp2
		
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B6,Temp2
		
	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B7,Temp2	

	Temp1=Temp1+1
	read Temp1,Temp2			' Move a byte
	poke Radio_Step_Size_B8,Temp2
		
	return

		
'-----------------------------------------------------------------------------
' Add tuning step to the current radio frequency
'
' Note there is no checking to ensure this is a valid frequency
'-----------------------------------------------------------------------------	

Add_Tuning_Step:		' Process all 8 BCD frequency digits, from least to most significant

	Carry =FALSE
	peek  Radio_Freq_B8,Temp1	
	peek  Radio_Step_Size_B8,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B8,Temp1
	
	peek  Radio_Freq_B7,Temp1	
	peek  Radio_Step_Size_B7,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B7,Temp1

	peek  Radio_Freq_B6,Temp1	
	peek  Radio_Step_Size_B6,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B6,Temp1

	peek  Radio_Freq_B5,Temp1	
	peek  Radio_Step_Size_B5,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B5,Temp1

	peek  Radio_Freq_B4,Temp1	
	peek  Radio_Step_Size_B4,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B4,Temp1

	peek  Radio_Freq_B3,Temp1	
	peek  Radio_Step_Size_B3,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B3,Temp1

	peek  Radio_Freq_B2,Temp1	
	peek  Radio_Step_Size_B2,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B2,Temp1

	peek  Radio_Freq_B1,Temp1	
	peek  Radio_Step_Size_B1,Temp2
	gosub Add_BCD
	poke  Radio_Freq_B1,Temp1

	Return	


'-----------------------------------------------------------------------------
' Subtract tuning step to the current radio frequency
'
' Note there is no checking to ensure this is a valid frequency
'-----------------------------------------------------------------------------	

Subtract_Tuning_Step:		' Process all 8 BCD frequency digits, from least to most significant

	Borrow=FALSE
	peek  Radio_Freq_B8,Temp1	
	peek  Radio_Step_Size_B8,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B8,Temp1
	
	peek  Radio_Freq_B7,Temp1	
	peek  Radio_Step_Size_B7,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B7,Temp1

	peek  Radio_Freq_B6,Temp1	
	peek  Radio_Step_Size_B6,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B6,Temp1

	peek  Radio_Freq_B5,Temp1	
	peek  Radio_Step_Size_B5,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B5,Temp1

	peek  Radio_Freq_B4,Temp1	
	peek  Radio_Step_Size_B4,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B4,Temp1

	peek  Radio_Freq_B3,Temp1	
	peek  Radio_Step_Size_B3,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B3,Temp1

	peek  Radio_Freq_B2,Temp1	
	peek  Radio_Step_Size_B2,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B2,Temp1

	peek  Radio_Freq_B1,Temp1	
	peek  Radio_Step_Size_B1,Temp2
	gosub Subtract_BCD
	poke  Radio_Freq_B1,Temp1

	Return
	
	
'-----------------------------------------------------------------------------
' Hexadecimal Output Subroutines
'-----------------------------------------------------------------------------	

SerOutByteHex:
    Temp1 = Temp2 / 16	' high nibble
    Temp1 = Temp1 + 48	' add the character '0'
    
    If Temp1 <= 57 Then SerOutByteHex_1
    Temp1 = Temp1 + 7	' it is alphabetic; A, B, C, D, E, F
    
SerOutByteHex_1:
    Sertxd (Temp1)
    Temp1 = Temp2 % 16	' low nibble
    Temp1 = Temp1 + 48	' add the character '0'
    
    If Temp1 <= 57 Then SerOutByteHex_2
    
    Temp1 = Temp1 + 7	' it is alphabetic; A, B, C, D, E, F
    
SerOutByteHex_2:
    Sertxd (Temp1)
    Return


'-----------------------------------------------------------------------------
' BCD Arithmetic Subroutines
'
' Temp1, Temp2 and Carry/Borrow are bytes used
'-----------------------------------------------------------------------------

Add_BCD:
	Temp1=Temp1+Temp2
	if Carry = FALSE then Add_BCD_Next
	
	Temp1=Temp1+1	' This adds the carry 
	Carry=FALSE		' Assume no new carry
	
Add_BCD_Next:
	if Temp1 <10 then Add_BCD_Return	' Was there a carry?
	
	Temp1=Temp1-10	' Yes, process
	Carry=TRUE
	
Add_BCD_Return:
	Return
	
	
Subtract_BCD:
	if Borrow = FALSE then Subtract_BCD_Main
	
	if Temp1 > 0 then Subtract_BCD_Do_Borrow
	
	Temp1 = 9
	Borrow = TRUE
	goto Subtract_BCD_Main

Subtract_BCD_Do_Borrow:
	Temp1 = Temp1 - 1
	Borrow = FALSE
	
Subtract_BCD_Main:
	if Temp1 <> Temp2 then Subtract_BCD_Less
	
	Temp1 = Temp1 - Temp2
	Return
	
Subtract_BCD_Less:
	if Temp1 > Temp2 then Subtract_BCD_Greater
	
	Temp1 = Temp1 + 10 - Temp2
	Borrow = TRUE
	Return
				
Subtract_BCD_Greater:
	Temp1 = Temp1 - Temp2
	return
		
	





















