;==========================================================================================
; Fast Huff Puff VFO Stabiliser
;
; (c) Cumbria Designs
;
; This software is provided free of charge for non commercial use. The software is provided
; without warranty or licence and no liability is accepted by the author or Cumbria Designs
; for any loss, injury, mishap, inconvenience or misdemeanor arising from the use of the
; software in whole or part. In using this software and the code compiled from it, you agree
; to these terms.
;
; We ask that in return for downloading and/or using this software in any way, you make a
; donation to a charity of your choice. How much is up to you!
;
; Ron Taylor, Cumbria Designs
;
;==========================================================================================
;
; Revision History
;
; December 2006 Version 1.0
;
;
;
;
;==========================================================================================
;
; Pin Out
;
; PORT A
;
; Not Used
;
;
; PORT B
;
; 0 Output to Integrator
; 1
; 2
; 3
; 4
; 5
; 6 Input
; 7
;
;==========================================================================================
list p=16F88 ; list directive to define processor
#include ; processor specific variable definitions
;==========================================================================
;
; Configuration Bits
;
;==========================================================================
;_CONFIG1 EQU H'2007'
;_CONFIG2 EQU H'2008'
;Configuration Byte 1 Options
;_CP_ALL EQU H'1FFF'
;_CP_OFF EQU H'3FFF'
;_CCP1_RB0 EQU H'3FFF'
;_CCP1_RB3 EQU H'2FFF'
;_DEBUG_OFF EQU H'3FFF'
;_DEBUG_ON EQU H'37FF'
;_WRT_PROTECT_OFF EQU H'3FFF' ;No program memory write protection
;_WRT_PROTECT_256 EQU H'3DFF' ;First 256 program memory protected
;_WRT_PROTECT_2048 EQU H'3BFF' ;First 2048 program memory protected
;_WRT_PROTECT_ALL EQU H'39FF' ;All of program memory protected
;_CPD_ON EQU H'3EFF'
;_CPD_OFF EQU H'3FFF'
;_LVP_ON EQU H'3FFF'
;_LVP_OFF EQU H'3F7F'
;_BODEN_ON EQU H'3FFF'
;_BODEN_OFF EQU H'3FBF'
;_MCLR_ON EQU H'3FFF'
;_MCLR_OFF EQU H'3FDF'
;_PWRTE_OFF EQU H'3FFF'
;_PWRTE_ON EQU H'3FF7'
;_WDT_ON EQU H'3FFF'
;_WDT_OFF EQU H'3FFB'
;_EXTRC_CLKOUT EQU H'3FFF'
;_EXTRC_IO EQU H'3FFE'
;_INTRC_CLKOUT EQU H'3FFD'
;_INTRC_IO EQU H'3FFC'
;_EXTCLK EQU H'3FEF'
;_HS_OSC EQU H'3FEE'
;_XT_OSC EQU H'3FED'
;_LP_OSC EQU H'3FEC'
;Configuration Byte 2 Options
;_IESO_ON EQU H'3FFF'
;_IESO_OFF EQU H'3FFD'
;_FCMEN_ON EQU H'3FFF'
;_FCMEN_OFF EQU H'3FFE'
;Program Configuration Register 1
__CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC
;Program Configuration Register 2
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
;==========================================================================================
;
; File Register Definitions
;
;
;==========================================================================================
CBLOCK 0x20 ; Start of Program Variables Memory
;
temp ; Used in detect routine
delay ; Delay counter
SR8 ; 2000 Bit Shift Register
SR16 ;
SR24 ; Digit in register name represents higher order bit number of register
SR32 ; Registers must occupy consective memory addresses for the "shift through
SR40 ; carry bit" action to function
SR48
SR56
SR64
SR72
SR80
SR88
SR96
SR104
SR112
SR120
SR128
SR136
SR144
SR152
SR160
SR168
SR176
SR184
SR192
SR200
SR208
SR216
SR224
SR232
SR240
SR248
SR256
SR264
SR272
SR280
SR288
SR296
SR304
SR312
SR320
SR328
SR336
SR344
SR352
SR360
SR368
SR376
SR384
SR392
SR400
SR408
SR416
SR424
SR432
SR440
SR448
SR456
SR464
SR472
SR480
SR488
SR496
SR504
SR512
SR520
SR528
SR536
SR544
SR552
SR560
SR568
SR576
SR584
SR592
SR600
SR608
SR616
SR624
SR632
SR640
SR648
SR656
SR664
SR672
SR680
SR688
SR696
SR704
SR712
SR720
SR728
SR736
SR744
SR752
ENDC
CBLOCK 0xA0 ; Map into next Memory Block
SR760
SR768
SR776
SR784
SR792
SR800
SR808
SR816
SR824
SR832
SR840
SR848
SR856
SR864
SR872
SR880
SR888
SR896
SR904
SR912
SR920
SR928
SR936
SR944
SR952
SR960
SR968
SR976
SR984
SR992
SR1000
SR1008
SR1016
SR1024
SR1032
SR1040
SR1048
SR1056
SR1064
SR1072
SR1080
SR1088
SR1096
SR1104
SR1112
SR1120
SR1128
SR1136
SR1144
SR1152
SR1160
SR1168
SR1176
SR1184
SR1192
SR1200
SR1208
SR1216
SR1224
SR1232
SR1240
SR1248
SR1256
SR1264
SR1272
SR1280
SR1288
SR1296
SR1304
SR1312
SR1320
SR1328
SR1336
SR1344
SR1352
SR1360
SR1368
SR1376
SR1384
ENDC
CBLOCK 0x110 ; Map into next Memory Block
SR1392
SR1400
SR1408
SR1416
SR1424
SR1432
SR1440
SR1448
SR1456
SR1464
SR1472
SR1480
SR1488
SR1496
SR1504
SR1512
SR1520
SR1528
SR1536
SR1544
SR1552
SR1560
SR1568
SR1576
SR1584
SR1592
SR1600
SR1608
SR1616
SR1624
SR1632
SR1640
SR1648
SR1656
SR1664
SR1672
SR1680
SR1688
SR1696
SR1704
SR1712
SR1720
SR1728
SR1736
SR1744
SR1752
SR1760
SR1768
SR1776
SR1784
SR1792
SR1800
SR1808
SR1816
SR1824
SR1832
SR1840
SR1848
SR1856
SR1864
SR1872
SR1880
SR1888
SR1896
SR1904
SR1912
SR1920
SR1928
SR1936
SR1944
SR1952
SR1960
SR1968
SR1976
SR1984
SR1992
SR2000
SR2008
ENDC
;==========================================================================================
;
; MACRO AREA
;
;==========================================================================================
; Bank Select Macros to simplify bank changes
Bank0 MACRO
bcf STATUS,RP0 ; Select Bank 0
bcf STATUS,RP1 ;
ENDM
Bank1 MACRO
bsf STATUS,RP0 ; Select Bank 1
bcf STATUS,RP1 ;
ENDM
Bank2 MACRO
bcf STATUS,RP0 ; Select Bank 2
bsf STATUS,RP1 ;
ENDM
Bank3 MACRO
bsf STATUS,RP0 ; Select Bank 3
bsf STATUS,RP1 ;
ENDM
;================================================================================================
;
; Start of Program
;
; Initialisation of peripherals and ports.
;
;================================================================================================
ORG 0x0000
goto Start
Start ; Initialise ports, modules and variables
clrf INTCON ; No interrupts for now
Bank1
movlw 0x00 ; Digital I/O on PORTS A&B
movwf ANSEL
bcf OPTION_REG,NOT_RBPU ; No weak pull ups
movlw b'11111110' ; PORT B bits 0 and 2 set to outputs, 6 set to input for VFO
movwf TRISB
Bank0
movlw b'00000111' ; Set TMR1ON, TMR1CS and T1SYNC
movwf T1CON ; Timer 1 ON, External Clock, Async Operation, Prescale=1
;================================================================================================
;
; Main
;
; Cyclic loop from which all routines are called. Instruction times are given in machines cycles.
; These are used to form the overall cycle time and hence sampling time.
;
; The program is arranged as a main routine with subroutine calls. This architecture makes the
; program structure easy to follow as the expense of a small amount of additional execution time
; associated with the subroutine calls.
;
;================================================================================================
Main ; Endless loop
bsf SR8,0 ; 1 Set input to shift register
btfss TMR1L,0 ; 2 Test least significant byte of running count
bcf SR8,0 ; 3 Input sample was zero, clear shift register input bit
call Detect ; 17 (2+12)
call Shift ; 279(2+260)
call Sample_Delay ; 281+T (2+T)
goto Main ; 283+T Back round again
;================================================================================================
;
; Detect Routine
;
; The Detect routine compares the input state of the shift register with the output state by
; an XOR function. Unlike a traditional phase detector the XOR will always produce an output
; irrespective of whether one is needed or not. When an "unecessary" decision is made it is
; corrected on the next sample. The very long time constant of the integrator averages out
; the relatively high frequency changes of the XOR to produce a clean, slow changing control
; voltage which is used to drive the drift correction varactor.
;
;================================================================================================
Detect ; Generate Correction Signal
movf SR8,w ; 1 Get input to shift register
andlw 0x01 ; 2 Mask tap 1 ,the shift register input
movwf temp ; 3 Save result
Bank2 ; 5 Point to memory bank holding SR2008
movf SR2008,w ; 6 Move contents of register into w
Bank0 ; 8 Back to Bank 0
xorwf temp,w ; 9 XOR input and output and save result in temp
movwf PORTB ; 10 Put output onto PORTB pin 0
return ; 12 Back to calling routine
;================================================================================================
;
; Delay Routine
;
; The main process times are padded out with an additional delay to produce the required
; sampling rate and hence lock point spacing and correction signal refresh rate. The total
; cyclical process time is chosen such that the total time taken for a bit to traverse the
; shift register and undergo detection produces a gate period that will give the required
; frequency resolution (lock point spacing).
;
; For a 20MHz clock the machine cycle time is 200nSec, the sampling period is the sum of
; all of the process times (Ptot) plus the delay duration. The Sampling Delay period required
; to pad out the process time for a given sampling rate is calculated as follows;
;
; For a 10kHz sampling rate the required clock period is 100uSec
;
; Lock Point Spacing = 2fs/tap number, therefore 2000 shift register taps required
;
; Ptot = Main duration + Shift duration + Detect duration
; = 11*200nSec + 260*200nSEc + 12*200nSec
; = 56600nSec (283 machine cycles)
; Clock period = Ptot + Delay
; Delay = Clock Rate - Ptot
; Delay = 100uSec - 283*200nSec
; Delay = 43400nSec
; Delay = 217 Machine Cycles
;
; Therefore, the additional delay to produce the required sampling rate is 217 machine cycles
;
;================================================================================================
Sample_Delay ; 217 machine cycle delay
movlw 0x15 ; 1 Load Outer counter with 21d
movwf delay ; 2
Delay1
nop ; 1 10 Machine Cycle loop
nop ; 2 x21 = 210 + 2 from initialisation -1 from exit
nop ; 3 = 211
nop ; 4
nop ; 5
nop ; 6
nop ; 7
decfsz delay,f ; 8 211
goto Delay1 ; 10
nop ; 212
nop ; 213
nop ; 214 Pad out with Machine cycles to make up to 217
nop ; 215
return ; 217
;================================================================================================
;
; Shift Register
;
; The 2000 tap shift register is formed in General Purpose Memory using 251 registers arranged
; in consecutive memory addresses. Where a memory bank change is required, the bank change macros
; are called ro point to the next bank. The timing associated with these macro comands must be
; accounted for in the total shift regsiter "end to end" time. For programming convenience the
; input and output sample points are taken from bit 0 of the first register (SR8) and the last
; register (SR2008). The rlf command shifts the content of a register palcing any overflow into
; the STATUS register C (Carry) flag. The next register to be shifted receives the Carry flag flag
; bit as it's input.
;
;================================================================================================
Shift ; Move shift register contents left one bit through carry flag
bcf STATUS,C ; 1 ; Clear Carry bit to prevent any unwanted carry-in
rlf SR8,f ; 2 ; Start of 2000 Bit Shift Register
rlf SR16,f ; 3 ;
rlf SR24,f ; 4 ; Digit in register name represents higher order bit number of register
rlf SR32,f ; 5 ; Registers must occupy consective memory addresses for the "shift through
rlf SR40,f ; carry bit" action to function
rlf SR48,f
rlf SR56,f
rlf SR64,f
rlf SR72,f
rlf SR80,f
rlf SR88,f
rlf SR96,f
rlf SR104,f
rlf SR112,f
rlf SR120,f
rlf SR128,f
rlf SR136,f
rlf SR144,f
rlf SR152,f
rlf SR160,f
rlf SR168,f
rlf SR176,f
rlf SR184,f
rlf SR192,f
rlf SR200,f
rlf SR208,f
rlf SR216,f
rlf SR224,f
rlf SR232,f
rlf SR240,f
rlf SR248,f
rlf SR256,f
rlf SR264,f
rlf SR272,f
rlf SR280,f
rlf SR288,f
rlf SR296,f
rlf SR304,f
rlf SR312,f
rlf SR320,f
rlf SR328,f
rlf SR336,f
rlf SR344,f
rlf SR352,f
rlf SR360,f
rlf SR368,f
rlf SR376,f
rlf SR384,f
rlf SR392,f
rlf SR400,f
rlf SR408,f
rlf SR416,f
rlf SR424,f
rlf SR432,f
rlf SR440,f
rlf SR448,f
rlf SR456,f
rlf SR464,f
rlf SR472,f
rlf SR480,f
rlf SR488,f
rlf SR496,f
rlf SR504,f
rlf SR512,f
rlf SR520,f
rlf SR528,f
rlf SR536,f
rlf SR544,f
rlf SR552,f
rlf SR560,f
rlf SR568,f
rlf SR576,f
rlf SR584,f
rlf SR592,f
rlf SR600,f
rlf SR608,f
rlf SR616,f
rlf SR624,f
rlf SR632,f
rlf SR640,f
rlf SR648,f
rlf SR656,f
rlf SR664,f
rlf SR672,f
rlf SR680,f
rlf SR688,f
rlf SR696,f
rlf SR704,f
rlf SR712,f
rlf SR720,f
rlf SR728,f
rlf SR736,f
rlf SR744,f
rlf SR752,f
Bank1 ; Change to Bank 1
rlf SR760,f
rlf SR768,f
rlf SR776,f
rlf SR784,f
rlf SR792,f
rlf SR800,f
rlf SR808,f
rlf SR816,f
rlf SR824,f
rlf SR832,f
rlf SR840,f
rlf SR848,f
rlf SR856,f
rlf SR864,f
rlf SR872,f
rlf SR880,f
rlf SR888,f
rlf SR896,f
rlf SR904,f
rlf SR912,f
rlf SR920,f
rlf SR928,f
rlf SR936,f
rlf SR944,f
rlf SR952,f
rlf SR960,f
rlf SR968,f
rlf SR976,f
rlf SR984,f
rlf SR992,f
rlf SR1000,f
rlf SR1008,f
rlf SR1016,f
rlf SR1024,f
rlf SR1032,f
rlf SR1040,f
rlf SR1048,f
rlf SR1056,f
rlf SR1064,f
rlf SR1072,f
rlf SR1080,f
rlf SR1088,f
rlf SR1096,f
rlf SR1104,f
rlf SR1112,f
rlf SR1120,f
rlf SR1128,f
rlf SR1136,f
rlf SR1144,f
rlf SR1152,f
rlf SR1160,f
rlf SR1168,f
rlf SR1176,f
rlf SR1184,f
rlf SR1192,f
rlf SR1200,f
rlf SR1208,f
rlf SR1216,f
rlf SR1224,f
rlf SR1232,f
rlf SR1240,f
rlf SR1248,f
rlf SR1256,f
rlf SR1264,f
rlf SR1272,f
rlf SR1280,f
rlf SR1288,f
rlf SR1296,f
rlf SR1304,f
rlf SR1312,f
rlf SR1320,f
rlf SR1328,f
rlf SR1336,f
rlf SR1344,f
rlf SR1352,f
rlf SR1360,f
rlf SR1368,f
rlf SR1376,f
rlf SR1384,f
Bank2 ; Change to Bank 2
rlf SR1392,f
rlf SR1400,f
rlf SR1408,f
rlf SR1416,f
rlf SR1424,f
rlf SR1432,f
rlf SR1440,f
rlf SR1448,f
rlf SR1456,f
rlf SR1464,f
rlf SR1472,f
rlf SR1480,f
rlf SR1488,f
rlf SR1496,f
rlf SR1504,f
rlf SR1512,f
rlf SR1520,f
rlf SR1528,f
rlf SR1536,f
rlf SR1544,f
rlf SR1552,f
rlf SR1560,f
rlf SR1568,f
rlf SR1576,f
rlf SR1584,f
rlf SR1592,f
rlf SR1600,f
rlf SR1608,f
rlf SR1616,f
rlf SR1624,f
rlf SR1632,f
rlf SR1640,f
rlf SR1648,f
rlf SR1656,f
rlf SR1664,f
rlf SR1672,f
rlf SR1680,f
rlf SR1688,f
rlf SR1696,f
rlf SR1704,f
rlf SR1712,f
rlf SR1720,f
rlf SR1728,f
rlf SR1736,f
rlf SR1744,f
rlf SR1752,f
rlf SR1760,f
rlf SR1768,f
rlf SR1776,f
rlf SR1784,f
rlf SR1792,f
rlf SR1800,f
rlf SR1808,f
rlf SR1816,f
rlf SR1824,f
rlf SR1832,f
rlf SR1840,f
rlf SR1848,f
rlf SR1856,f
rlf SR1864,f
rlf SR1872,f
rlf SR1880,f
rlf SR1888,f
rlf SR1896,f
rlf SR1904,f
rlf SR1912,f
rlf SR1920,f
rlf SR1928,f
rlf SR1936,f
rlf SR1944,f
rlf SR1952,f
rlf SR1960,f
rlf SR1968,f
rlf SR1976,f
rlf SR1984,f
rlf SR1992,f
rlf SR2000,f ; 255
rlf SR2008,f ; 256
Bank0 ; 258 Rest to Bank 0
return ; 260 Back to calling routine
END