;********************************************************************
; 		VK5TM Frequency Dependant Switch
;			VK5TM_FDS_PTTV0_3.asm
;
; Original code & hardware design by Peter Rhodes, BSc, G3XJP
; See RSGB Radcom magazine Sep to Dec 2001
;
; Modified by Terry Mowles VK5TM Aug 2019
;
; Modifications:
;	Remove EEProm storage of variables - converted to tables.
;	Remove changing variables using jumper method.
;	Works from PTT activation only.
;	Converted to 16F628A running on internal oscillator.
;	Changed filter outputs to all PortB.
;	Rearranged all other inputs/outputs to PortA.
;********************************************************************
	errorlevel -302, -305  ; Skip nuisance messages

	LIST 		P=PIC16F628A

	INCLUDE		P16F628A.inc

	__config _CP_OFF&_LVP_OFF&_BODEN_OFF&_MCLRE_OFF&_PWRTE_ON&_WDT_OFF&_INTOSC_OSC_NOCLKOUT

#define	PTT		PORTA,1
#define	TR_relay	PORTA,2
#define	bias		PORTA,3
#define	RF		PORTA,4	
#define	LED1		PORTA,6	; Frequency measured
#define	LED2		PORTA,7	; Channel change

	

;	decimal #'s following equal time in mS (approx)
#define tA		d'15'		; T/R relay operate delay time
#define tB		d'15'		; bandsw relay operate time
#define tC		d'8'		; bandsw relay release time
#define tD		d'20'		; Bias operate delay
#define tE		d'10'		; Debounce time

	CBLOCK	0x20	; Start Data Block

	delay1		; misc counters for use in time delays
	delay2
	delay3
	freq		; cache for freq count
	repeat		; number of extra times freq is counted
	oldCh		; last channel in use
	temp		; general purpose transient variable
	r_data

	endc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	org	0
	goto	main
	org	4
	goto	main

channel;		   	
	addwf	PCL,f		; Band Count	Dest
	retlw	b'00100000'	; 10m -> initial start-up band
	retlw	b'00000001'	; 160m	1	RB0
	retlw	b'00000010'	; 80m	2	RB1
	retlw	0		;	3	error
	retlw	b'00000100'	; 40m	4	RB2
	retlw	b'00001000'	; 30m	5	RB3
	retlw	b'00001000'	; 30m	6	RB3
	retlw	0		;	7	error
	retlw	b'00001000' 	; 20m	8	RB3
	retlw	0		;	9	error
	retlw	b'00010000'	; 17m	10	RB4
	retlw	0		;	11	error
	retlw	b'00010000'	; 15m	12	RB4
	retlw	0		;	13	error
	retlw	b'00100000'	; 12m	14	RB5
	retlw	0		;	15	error
	retlw	b'00100000'	; 10m	16	RB5
	retlw	b'00100000'	; 10m	17	RB5

main
	clrf	PORTA		; initialise
	clrf	PORTB		; initialise
	movlw	0x07		; 
	movwf	CMCON		; Turn off comparators
	bsf	STATUS,RP0	; to Bank 1
	movlw	b'10100111'	; prescale /256 to RA4, no pull-ups
	movwf	OPTION_REG
	movlw	b'00010010'	; RA1 & RA4=input
	movwf	TRISA
	clrf	TRISB		; PortB all outputs
	bcf	STATUS,RP0	; back to Bank 0

	movlw	0		; initialise startup band
	call	channel
	movwf	r_data
	call	new_Ch		; do it!

initialise 			; clear all outputs (except filter) to Rx state

	bcf	bias		; turn off bias output
	movlw	tC		; Relay release time
	call	w_mS		;
	bcf	TR_relay	; turn off T/R relay after delay
	nop			; nop for port read/modify/write problem
	bcf	LED2
	nop
	bcf	LED1

wait_Tx
	btfsc	PTT		; is PTT activated?
	goto	wait_Tx		; if not, go back and wait 

	movlw	tE		; PTT debounce
	call	w_mS
	btfsc	PTT
	goto 	wait_Tx

	btfsc	RF		; Wait for RF input
	goto	$-1

;  Measure freq.  Potential errors are:- 
; 	Tx stops/starts while measuring 
; 	out of band measure
; 	no count, not enough power
; 	successive counts not same
	movlw	d'4'
	movwf	repeat		; # times to repeat
	call	freqcount	; measure once
	movwf	freq		; and retain
	btfsc	STATUS,Z	; test for zero
	goto	initialise	; zero or > 10m error
	bsf	LED1		; light Frequency measured LED
freq_again
	call	freqcount	; measure again
	subwf	freq,w		; compare
	btfss	STATUS,Z	; same?
	goto	initialise	; not same freq error
	decfsz	repeat		; all done?
	goto	freq_again	; no, so loop
	movf	freq,w		; yes, all OK, continue
	
	call	channel
	movwf	r_data
	iorlw	0x00		; Test if 'W' is 0
	btfsc	STATUS,Z	; zero?
	goto	initialise	; yes out of band error

	subwf	oldCh,w		; compare old
	btfss	STATUS,Z	; same?
	call	new_Ch		; it is different

	movlw	tA		; T/R relay time
	call	w_mS		; and delay for w mS
	bsf	TR_relay	; to transmit

	movlw	tD		; Bias relay delay time
	call	w_mS		; and delay for w mS
	bsf	bias		; turn bias on
	nop
	bcf	LED2		; and LED2 Channel change off

	btfss	PTT		; wait for PTT to be released
	goto	$-1

	goto	initialise

; FREQUENCY COUNT
freqcount
	clrf	TMR0		; reset & start count
	call	delay_150uS
	movf	TMR0,w		; end & latch result
	movwf	temp		; preserve w
	sublw	d'17'		; max legal count
	btfss	STATUS,C	; test for >max?
	clrf	temp		; count was >max
	movf	temp,w		; recover w
	return			; with count in w (0 if error)

new_Ch	; NEW CHANNEL NEEDED
	bsf	LED2		; Channel change LED on
	movf	r_data,w	; get new Ch
	movwf	oldCh		; overwrite old
	iorwf	PORTB,f		; start 'make' new
	movlw	tB 		; operate time
	call	w_mS		; complete 'make'
				; break old channel
	movf	oldCh,w		; now current Ch
	movwf	PORTB
	return

delay_150uS
;PIC Time Delay = 0.00014900 s with Osc = 4,000,000 Hz
	movlw	D'48'		; Adjust up or down if BIAS LED
	movwf	delay1		; doesn't light on some channels
				; or band switching is intermittent on some bands
loop
	decfsz	delay1,f
	goto	loop
	return
;
; DELAY LOOP 1 millisecond 
one_mS
	movlw	d'4'
	movwf	delay1
loop1
	movlw	d'81'
	movwf	delay2
loop2
	decfsz	delay2
	goto	loop2
	decfsz	delay1
	goto	loop1
	return

; DELAY LOOP w milliseconds (roughly)
w_mS
	movwf	delay3
w_mS_loop
	call	one_mS
	decfsz	delay3
	goto	w_mS_loop
	return

	END
;--------------------------------------------------------------------------------
