; program to load Silicon Labs synthesizer SL4112-GT from Microchip PIC 16F688
; IK6EIW					RA0 pin4	RA1 pin 5
;	Europe     725	2175 + 144 = 2319    	high		high	freq1
;	VK band    719	2157 + 144 = 2301	low		high	freq2
;	USA        720	2160 + 144 = 2304	high		low	freq3
;	JA         760	2280 + 144 = 2424	low		low	freq4
;
;    SETUP PORTS 1 = INPUT 0 = OUTPUT
;     -----------   PORT A    ----------------------------------------
;	I/O	I	I	I	INT	I	I
;	pins 	2	3	4	11	12	13
;		RA5	RA4	RA3	RA2	RA1	RA0
;	TRISA	1	1	1	1	1	1	0x3F
;	IOCA	0	0	0	0	1	1	Ox03
;	WPUA	0	0	0	0	1	1	0x03
;
;     -----------   PORT C    ----------------------------------------
;	I/O	OUT	O	LED	SEN	CLK	DATA	O
;	pins		5	6	7	8	9	10
;			RC5	RC4	RC3	RC2  	RC1 	RC0
;	TRISC		1	0	0	0	0	0	0x20
;
;     ---------------------------------------------------------------			
; 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 
;
P=16F688
		include P16F688.inc
		errorlevel  -302        ; suppress message 302 from list file
	    				; RC internal clock
	         __config 0x30E4   	; watchdog timer off 
				    	; power-up timer on
	                            	; code protect   off
	                            	; BOD enabled in run
	                            	; MCLR EXTERNAL
	         radix    hex 
;			 
; 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 16F688 
;
reg_H	equ	0x33		; High bits of register
reg_M	equ	0x34		; Mid bits of register
reg_L	equ	0x35		; Low bits of register
regC  	equ 	0x36		; delay register
regD  	equ	0x37		; delay register
regE  	equ	0x38		; delay register
;
w_temp		equ	0x3C		;store a copy of W register while int
status_temp	equ	0x3D		;store a copy of Status Reg while int
;
;************************************************************************
;
	ORG     0x00          	; startup address = 0000
	goto	start	
;
;---------------------------
;
;			store W and STATUS
;
	ORG     0x04       	; interrupt vector location
;
	MOVWF 	w_temp 		;copy W to temp register,
				;could be in either bank
	SWAPF 	STATUS,W	;swap status to be saved into W
	BCF	STATUS,RP0 	;change to bank 0 regardless of
				;current bank
	MOVWF	status_temp 	;save status to bank 0 register
;
	GOTO	PER_INT
;
;---------------------------
;
;			PORTC INIT
;
start	
	CLRF 	STATUS 		; Bank0
	CLRF 	PORTC 		; Initialize PORTC by clearing output data latches
;
	BSF 	STATUS, RP0 	; Bank1
	CLRF	ANSEL		;   clear the analog register pins for digital i/o
	BCF	PCON,ULPWUE 	;   DISable ULP Wake-up
	MOVLW 	0x20		;   Value used to initialize data direction
	MOVWF 	TRISC 		;   ALL outputs except RC5 is input
	CLRF 	STATUS 		; Bank0
	BSF	PORTC, 3	;   HOLD SEN ENABLE HIGH UNTIL WRITING
;
;			PORTA INIT
;
	CLRF	PORTA		;Init PORTA
	MOVLW	07h 		;Set RA<2:0> to
	MOVWF	CMCON0 		;digital I/O
	CLRF	ANSEL		;digital I/O
	MOVLW 	0x3F 		;   5:0 INPUTS
	MOVWF 	TRISA 		;   make all inputs See notes
	BCF	PCON,ULPWUE 	;   DISable ULP Wake-up
	CLRF	CMCON1		;   clear the register
	CLRF	PIR1		;   DISABLE int flags in the PIR REGISTER
	BSF 	STATUS, RP0 	; Bank1
	CLRF	PCON		;   deny that any resets occurred
	CLRF	PIE1		;   disable tmr1 - other stuff we don't need
	MOVLW	0x03		;   IOCA register (is in bank1)
	MOVWF 	IOCA		;   set interrupt-on-change RA2 (NOT)
	BCF	OPTION_REG, 7	;   RAPU - pull ups enable (zero to enable)
	BSF	OPTION_REG, 6	;   set interrupt on RISING edge   (INTEDG)
	MOVLW	0x03		;   weak p/u RA0 and RA1
	MOVWF	WPUA		;   do it (enabled = 1)
	CLRF 	STATUS		; Bank0
	CLRF	INTCON		;  Disable interrupts and clear some flags
;
;		Set the interrupts
	BCF	INTCON, 3	; RAIE disable RA int enable 
	BCF	INTCON, 0	; RAIF - Clear Flag Bit Just In Case
	BCF	INTCON, 4	; INTE - external Interrupt Enable (1=enable) enable this after loading registers
	BCF	INTCON, 1	; INTF - Clear Flag Bit Just In Case
	BCF	INTCON, 5	; TIMER OVERFLOW INT ENABLE ( 1 = enable)
	BCF	INTCON, 2	; T0IF  clear TIMER OVERFLOW FLAG
	BCF	INTCON, 6	; disable peripheral interrupts
	
;	
;*************************************************************************
;
; RA0 and RA1 pins are high by pull-up, if high then switch is NOT active
; or there is no switch. simulate with pin stimulus  A0 and  A1
; 4 frequencies are possible with 2 pins
;
	CALL	dly100		; wait for 4112 to settle 
	CALL	ldzero		; load RF registers with zero
	CALL	pins
	GOTO	FLandINT
;
pins
	BTFSS	PORTA, 0	; skip next if RA0 high	
	GOTO	pa10		; RA0 low
	GOTO	pa11		; RA0 high
;-------------------------------------------------------------
pa10	BTFSS	PORTA, 1	; skip next if RA1 high
	GOTO	freq4		; RA0 low and RA1 low
	GOTO	freq3		; RA0 low and RA1 high
				; RA0 is pin 13 of chip, pin 4 of ICSP
pa11	BTFSS	PORTA, 1	; skip next if RA1 high
	GOTO	freq2		; RA0 high and RA1 low
				; RA1 is pin 12 of chip, pin 5 of ICSP
	GOTO	freq1		; RA0 high and RA1 high
;
;*************************************************************************
;
FLandINT
	BCF	INTCON, 1	; Clear INT flag before enabling GIE AND INT
	BSF	INTCON, 3	; enable RA int (RAIE)
	BSF	INTCON, 4	; INTE - external Interrupt Enable
	BSF	INTCON, 7	; GIE – Global interrupt enable (1=enable)
				; hold interrupts until all registers load
;	CALL	BLINK5		; debug	
;
;  BEGIN MAIN LOOP
;
mnlp
	BCF	PORTC, 4	; set pin 6 low LED OFF
	SLEEP
	nop
	goto	mnlp
;
;  END MAIN LOOP
;
;*************************************************************************
;
;   INTERRUPT SERVICE ROUTINE
;------------frequency change ------------------
;
PER_INT 
	BTFSS	INTCON, RAIF	; are we changing freq ?
	GOTO	isINTF		; NO, must be lock problem
	CALL	pins		; YES, read pins 11 and 12 and set new freq
	BCF	INTCON, RAIF 	; Clear the RA interrupt flag.
	GOTO	RESTREG		;
;---------------- - - - Lock LED-------INTERRUPT SEVICE  ROUTINE---------- - - - - - - - - -
; 
isINTF	; an INT ocurred so turn on the light, if I find otherwise
	; then exit the routine and the LED is turned off by the main loop
	; before sleep.
	; this all depends on the status of the lock detect (auxout)
	; while it's high I don't want to clear INTF. So, test RA2
	; to see when it's clear, and keep the LED on 'til then.
	
;
	BTFSS	PORTA, 2	; is LK DET high ? if yes skip next line
	BCF	INTCON, INTF	; clear the INTF interrupt flag
	BTFSC	PORTA, 2	; is LK DET low ? if yes skip next line
	BSF	PORTC, 4	; set pin 6 high LED ON
	BTFSC	PORTA, 2	; is LK DET low ? if yes skip next line
	CALL	dly500		; LED on for 1/2 sec
;
;--------------------------------------------------------------------
;
RESTREG	
	SWAPF 	status_temp,W	; swap STATUS_TEMP register into
				; W, sets bank to original state
	MOVWF	STATUS 		; move W into STATUS register
	SWAPF	w_temp,F 	; swap W_TEMP with F
	SWAPF	w_temp,W 	; swap W_TEMP into W
	RETFIE 			; Return from interrupt
;
;   END INTERRUPT SERVICE ROUTINES
;
;**********************************************************************
; LO for 2301
;
freq2					; 719 MHz
; load registers reg_H reg_M and reg_L	99 mhz
; Load the main register (0)
;
	movlw	0x03			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x40			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the phase det register (1)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x41			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the power down register (2)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			;				  
	movwf	reg_M			;
	movlw	0x22			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF N register (5)
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x2C			; 
	movwf	reg_M			;
	movlw	0xF5			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF R register (8)
; MSB first
; 
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0xA8			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
	CALL	BLINK2		
	RETURN		;
;
;**********************************************************************
; LO for 2304
;
freq3					; 720 MHz
; load registers reg_H reg_M and reg_L	99 mhz
; Load the main register (0)
;
	movlw	0x03			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x40			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the phase det register (1)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x41			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the power down register (2)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			;				  
	movwf	reg_M			;
	movlw	0x22			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF N register (5)
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x2D			; 
	movwf	reg_M			;
	movlw	0x05			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF R register (8)
; MSB first
; 
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0xA8			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
	CALL	BLINK3		
	RETURN		;
;
;**********************************************************************
; LO for 2319
;
freq1					; 725 MHz
; load registers reg_H reg_M and reg_L	99 mhz
; Load the main register (0)
;
	movlw	0x03			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x40			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the phase det register (1)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x41			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the power down register (2)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			;				  
	movwf	reg_M			;
	movlw	0x22			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF N register (5)
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x2D			; 
	movwf	reg_M			;
	movlw	0x55			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF R register (8)
; MSB first
; 
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0xA8			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
	CALL	BLINK1		
	RETURN		;
;
;**********************************************************************
; LO for 2424
;
freq4					; 760 MHz
; load registers reg_H reg_M and reg_L	99 mhz
; Load the main register (0)
;
	movlw	0x03			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x40			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the phase det register (1)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0x41			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the power down register (2)
; MSB first
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			;				  
	movwf	reg_M			;
	movlw	0x22			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF N register (5)
;
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x2F			; 
	movwf	reg_M			;
	movlw	0x85			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the IF R register (8)
; MSB first
; 
	movlw	0x00			; 
	movwf	reg_H			;
	movlw	0x00			; 
	movwf	reg_M			;
	movlw	0xA8			; 
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
	CALL	BLINK4		
	RETURN		;
;
;**********************************************************************
;
sendreg
	bcf   PORTC, 3  	; sen low to enable writing to reg
	NOP
	NOP
	NOP
	NOP
	btfss reg_H,5		; Bit 22
	call 	zero		; 0
	btfsc reg_H,5		;
	call 	one		; 1
	btfss reg_H,4		; Bit 21
	call 	zero		; 0
	btfsc reg_H,4		;
	call 	one		; 1
	btfss reg_H,3		; Bit 20
	call 	zero		; 0
	btfsc reg_H,3		;
	call 	one		; 1
	btfss reg_H,2		; Bit 19
	call 	zero		; 0
	btfsc reg_H,2		;
	call 	one		; 1
	btfss reg_H,1		; Bit 18
	call 	zero		; 0
	btfsc reg_H,1		;
	call 	one		; 1
	btfss reg_H,0		; Bit 17
	call 	zero		; 0
	btfsc reg_H,0		;
	call 	one		; 1
	btfss reg_M,7		; Bit 16
	call 	zero		; 0
	btfsc reg_M,7		;
	call 	one		; 1
	btfss reg_M,6		; Bit 15
	call 	zero		; 0
	btfsc reg_M,6		;
	call 	one		; 1
	btfss reg_M,5		; Bit 14
	call 	zero		; 0
	btfsc reg_M,5		;
	call 	one		; 1
	btfss reg_M,4		; Bit 13
	call 	zero		; 0
	btfsc reg_M,4		;
	call 	one		; 1
	btfss reg_M,3		; Bit 12
	call 	zero		; 0
	btfsc reg_M,3		;
	call 	one		; 1
	btfss reg_M,2		; Bit 11
	call 	zero		; 0
	btfsc reg_M,2		;
	call 	one		; 1
	btfss reg_M,1		; Bit 10
	call 	zero		; 0
	btfsc reg_M,1		;
	call 	one		; 1
	btfss reg_M,0		; Bit 9
	call 	zero		; 0
	btfsc reg_M,0		;
	call 	one		; 1
	btfss reg_L,7		; Bit 8
	call 	zero		; 0
	btfsc reg_L,7		;
	call 	one		; 1
	btfss reg_L,6		; Bit 7
	call 	zero		; 0
	btfsc reg_L,6		;
	call 	one		; 1
	btfss reg_L,5		; Bit 6
	call 	zero		; 0
	btfsc reg_L,5		;
	call 	one		; 1
	btfss reg_L,4		; Bit 5
	call 	zero		; 0
	btfsc reg_L,4		;
	call 	one		; 1
	btfss reg_L,3		; Bit 4
	call 	zero		; 0
	btfsc reg_L,3		;
	call 	one		; 1
	btfss reg_L,2		; Bit 3
	call 	zero		; 0
	btfsc reg_L,2		;
	call 	one		; 1
	btfss reg_L,1		; Bit 2
	call 	zero		; 0
	btfsc reg_L,1		;
	call 	one		; 1
	btfss reg_L,0		; Bit 1
	call 	zero		; 0
	btfsc reg_L,0		;
	call 	one		; 1
;
	bsf   PORTC, 3		; make sen high to enter DATA AND CLOSE REG
	nop
	nop
	nop
	nop
	nop
	RETURN
;
; Subroutines to send 0 and 1
; sen is low while writing
; data clocked in on rising edge
; 	synth		io1		pic
; sen   24		11		7	portc, bit 3
; data  2		13		9	portc, bit 1
; clock 1		15		8	portc, bit 2
;									    
zero    
	bcf   PORTC, 1		; RC1 data LOW
	bsf   PORTC, 2		; set clock RC0 HIGH
	nop
	nop
	nop
	bcf	PORTC, 2	; set clock low
				; all port C outputs are now low
				; sen was low and is still low
	RETURN
;
one     
	bsf	PORTC, 1  	; RC1 data high
	bsf	PORTC, 2 	; set clock bit RC0 HIGH
	nop
	nop
	nop
	bcf	PORTC, 2	; set clock RC0 LOW
	bcf	PORTC, 1	; all port C outputs are now low
				; sen was low and is still low
	RETURN
;
; 100  TO 500 MSEC DELAY ROUTINE 
;
dly500	MOVLW   0x82        	 
        MOVWF   regD		
wait5   DECFSZ  regC, F		     	
        GOTO    wait5		
        DECFSZ  regD, F      	
        GOTO    wait5
dly400	MOVLW   0x82        	 		       	
        MOVWF   regD
wait4   DECFSZ  regC, F     	
        GOTO    wait4
        DECFSZ  regD, F      	
        GOTO    wait4
dly300	MOVLW   0x82        	        	
        MOVWF   regD
wait3   DECFSZ  regC, F     	
        GOTO    wait3
        DECFSZ  regD, F      	
        GOTO    wait3
dly200	MOVLW   0x82        	       	
        MOVWF   regD
wait2   DECFSZ  regC, F     	
        GOTO    wait2
        DECFSZ  regD, F      	
        GOTO    wait2
dly100	MOVLW   0x82        	       	
        MOVWF   regD
wait1   DECFSZ  regC, F     	
        GOTO    wait1
        DECFSZ  regD, F      	
        GOTO    wait1
        RETURN
;
;
; Load the RF1 N register (3)
; MSB first
;
ldzero
	movlw	0x00			
	movwf	reg_H			
	movlw	0x00			
	movwf	reg_M			
	movlw	0x03			
	movwf	reg_L			
	CALL	sendreg			; Send data to REGISTERS
;
; Load the RF2 N register (4)
; MSB first
;
	movlw	0x00			
	movwf	reg_H			;
	movlw	0x00			
	movwf	reg_M			;
	movlw	0x04			
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
;
; Load the RF1 R register (6)
; MSB first
;
	movlw	0x00			
	movwf	reg_H			;
	movlw	0x00			
	movwf	reg_M			;
	movlw	0x06			
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS

;
; Load the RF2 R register (7)
; MSB first
;
	movlw	0x00			
	movwf	reg_H			;
	movlw	0x00			
	movwf	reg_M			;
	movlw	0x07			
	movwf	reg_L			;
	CALL	sendreg			; Send data to REGISTERS
	RETURN
;	
BLINK0
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK9
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK8
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK7
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK6
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK5
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK4
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK3
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK2
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
BLINK1
	BSF	PORTC, 4
	CALL	dly200
	BCF	PORTC, 4
	CALL	dly200
	RETURN
;
        end
