'* Name : SYNTH.BAS * '* Author : [Ian Sumner G3VPX] * '* Notice : Copyright (c) 2005-2007 Ian Sumner * '* : All Rights Reserved * '* Date : 25/02/2007 * '* Version : 1.01 * '* Notes : * '* : * '**************************************************************** ' Define LCD registers and bits define OSC 32 Define LCD_DREG PORTB Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 DEFINE LCD_LINES 2 DEFINE LCD_COMMANDUS 2000 DEFINE LCD_DATAUS 200 ' Define ADCIN parameters Define ADC_BITS 8 ' Set number of bits in result Define ADC_CLOCK 3 ' Set clock source (3=rc) Define ADC_SAMPLEUS 50 ' Set sampling time in uS 'The latch/input buffer selector below are three bit: ' bits 0 and 1 are post A bits 4 and 5 ' bit 2 is port A bit 4 ' (This is because PORT A bits 0,1 and 3 are analog inputs) ' frequeny correctionn DDS clock Hz/10 Trimmer CON 25 'Digiboard Port A address constants IC8ADDR CON %00000000 IC17ADDR CON %00000000 IC2ADDR CON %00010000 IC18ADDR CON %00010000 IC4ADDR CON %00100000 IC23ADDR CON %00100000 IC3ADDR CON %00110000 IC16ADDR CON %00110000 IC1ADDR CON %00000100 IC13ADDR CON %00000100 '3-Port extender board address constants ICE1ADDR CON %00010100 ICE2ADDR CON %00100100 ICE3ADDR CON %00110100 ' First IF - 2khz CIO Offset base ' = (45.0MHz - 2Khz) /10 = 44.998 Mhz FfifL CON $58 FfifM CON $A9 FfifH CON $44 ' 2^48 * 10 / LO DDS ref.freq base '(FMultLO = FMultLOc + MultLOoffs where MultLOoffs = 0 to 2000 - default=1000) FmultLOcL con $B6 FmultLOcM CON $BB FmultLOcH con $D6 ' 2^48 * / CIO DDS ref.freq (ref freq = 106.250056 Mhz) FmultCIOL con $56 FmultCIOM CON $6C FmultCIOH con $28 ' Band control ' Default band data @0, 3 ' Default to 40m band on reprogram data @1, 1 ' Default to VFOa on reprogram DATA @2, 0 ' MultLOoffsL DATA @3, 4 ' MultLOoffsM ' VFOa and VFOb frequencies default A = 7.05 B = 7.07 DATA @6, $E8, $C1, $0A, $B8, $C9, $0A ' Band data in EEPROM - 12 bytes per band ' 0-2 Lower frequency limit ' 3-5 Last frequency used ... set on proramming toa mid band default ' 6-8 Higher frequency limit ' 9 bits 0-2: 1st LO DDS BPF selection control byte ' 9 bits 4-7: RF bandpass filter control (0 to 8) ' 10 Default sideband LSB = 0 USB = 1 ' 11 Transmit LPF control (bitwise) ' 12 Transmit 45Mhz gain - 5 bits (0 - $1F) ' Limits, BPF, MODE ' 1.8Mhz 1.800 to 2.000 0 0 ' 3.5Mhz 3.500 to 3.800 1 0 ' 7Mhz 7.000 to 7.200 1 0 ' 10Mhz 10.100 to 10.150 2 2 ' 14Mhz 14.000 to 14.350 2 1 ' 18Mhz 18.068 to 18.168 3 1 ' 21Mhz 21.000 to 21.450 3 1 ' 24Mhz 24.890 to 24.990 4 1 ' 28Mhz 28.000 to 29.700 4 1 Data @12, $20, $BF, $02, $30, $E6, $02, $40, $0D, $03, $00, 0, $01, $1F DATA @25, $30, $57, $05, $50, $A5, $05, $60, $CC, $05, $11, 0, $02, $1F data @38, $60, $AE, $0A, $E8, $C1, $0A, $80, $FC, $0A, $21, 0, $04, $1F data @51, $50, $69, $0F, $08, $75, $0F, $D8, $7C, $0F, $32, 1, $08, $1F data @64, $C0, $5C, $15, $E0, $AA, $15, $78, $E5, $15, $42, 1, $10, $1F data @77, $D0, $91, $1B, $20, $A6, $1B, $E0, $B8, $1B, $53, 1, $10, $1F data @90, $20, $0B, $20, $C8, $6C, $20, $E8, $BA, $20, $63, 1, $20, $1F DATA @103, $A8, $FA, $25, $48, $0A, $26, $B8, $21, $26, $74, 1, $20, $1F DATA @116, $80, $B9, $2A, $E0, $A3, $2B, $90, $51, $2D, $84, 1, $20, $1F data @129, $1D, $1C, $0F, $01, $1F, $77, $15, $3D ' out-bAnd data @137, $15, $1D, $00, $BD, $E7 ' no dp DAta @142, $00, $00, $00, $77, $09, $1F, $00, $00 ' A = b '455Khz DDS frequencies in Hz 24 bit - byte 0 = CioL, byte 1 = CioM, byte 2 = CioHLO 'LO offset in Hz/20 ( bit 7 = neg, bits 0-6 = offset ie: not 2s comp.) ' USB/LSB refers to signal frequencices and is inverted at 455Khz IF ' Offset is (freq-453000)/20 ' Lo freq = Display freq + (StoredIF -2Khz) + 20*Offset DATA @150, $94, $F6, $06, $A7 ' RxSSB_2.0kHz USB = 456.340 DATA @154, $1C, $EC, $06, $21 ' RxSSB_2.0kHz LSB = 453.660 DATA @158, $D0, $F6, $06, $AA ' RxSSB_2.4kHz USB = 456.400 DATA @162, $E0, $EB, $06, $1E ' RxSSB_2.4kHz LSB = 453.600 DATA @166, $58, $F1, $06, $3C ' RxCW_500Hz (USB) = 455.000 ( Filter =8.215800 > 454.200 800Hz audio tone) DATA @170, $78, $F4, $06, $64 ' RxCW_2.0kHz (USB) = 455.800 ( Filter =8.215000 > 455.000 800Hz audio tone) DATA @174, $78, $F4, $06, $64 ' RxCW_2.4KHz (USB) = 455.800 ( Filter =8.215000 > 455.000 800Hz audio tone) DATA @178, $6C, $F6, $06, $3C ' RxRTTY_500Hz (USB) = 456.300 ( Filter =8.215800 > 454.200 2100Hz audio tone) DATA @182, $8C, $F9, $06, $64 ' RxRTTY_2.0kHz (USB) = 457.100 ( Filter =8.215000 > 455.000 2100Hz audio tone) DATA @186, $8C, $F9, $06, $64 ' RxRTTY_2.4KHz (USB) = 457.100 ( Filter =8.215000 > 455.000 2100Hz audio tone) DATA @190, $94, $F6, $06, $A7 ' Tx_SSB USB = 456.340 DATA @194, $1C, $EC, $06, $21 ' Tx_LSB LSB = 453.660 DATA @198, $38, $EE, $06, $3C ' Tx_CW (USB) = 454.200 DATA @202, $58, $F1, $06, $64 ' Tx_RTTY LSB = 455.000 'Above lookup using Transmit, Filter and m variables 'Where m is mode corrected with SBB = LSB or USB according to band default ' Data index in CioIndex constant array - see above ' Trans Filter Mode decimal CIO function CIO DATA index ' 0 00 00 0 Rx 2.4 LSB 3 ' 0 00 01 1 Rx 2.4 USB 2 ' 0 00 10 2 Rx 2.4 CW 6 ' 0 00 11 3 Rx 2.4 RTTY 9 ' 0 01 00 4 Rx 2.0 LSB 1 ' 0 01 01 5 Rx 2.0 USB 0 ' 0 01 10 6 Rx 2.0 CW 5 ' 0 01 11 7 Rx 2.0 RTTY 8 ' 0 10 00 8 Rx 500 LSB 1 force 2.0kHz Rx filter if SSB mode ' 0 10 01 9 Rx 500 USB 0 force 2.0kHz Rx filter if SSB mode ' 0 10 10 10 Rx 500 CW 4 ' 0 10 11 11 Rx 500 RTTY 7 ' 1 xx 00 16 Tx LSB 11 ' 1 xx 01 17 Tx USB 10 ' 1 xx 10 18 Tx CW 12 ' 1 xx 11 19 Tx RTTY 13 ' 2^48 * 10 / LO DDS ref.freq - 1000 '(fine tuned via key pad F4 Offset is 0 - 2000, centre is 1000) FmultLOL var byte FmultLOM var byte FmultLOH var byte '(FMultLO = FMultLOc + MultLOoffs where MultLOoffs = 0 to 2000) MultLOoffsL Var Byte MultLOoffsM var Byte 'Band limit variables LowL var byte[10] LowM var byte[10] LowH var byte[10] HighL var byte[10] HighM var byte[10] HighH var byte[10] 'Filter control digout bytes BPFX2 VAR BYTE[10] DefaultSB VAR byte[10] TXLPF VAR BYTE[10] Tx45Gain var Byte[10] ' error messages MsgOutBand var byte [8] MsgError VAR byte [8] FunctionDigit Var Byte[4] FunctionData Var WORD ' band store Band var byte ' Stored input data IC2 VAR BYTE IC3 VAR BYTE IC4 VAR BYTE IC1 VAR BYTE VRA0 VAR BYTE ' IF shift VRA1 VAR BYTE ' Clarifier VRA3 VAR BYTE ' Calibrate OLDVRA0 VAR BYTE ' IF shift OLDVRA1 VAR BYTE ' Clarifier OLDVRA3 VAR BYTE ' Calibrate ' Stored output data IC23 VAR BYTE IC16 VAR BYTE ClarifyLed VAR IC23.0 VFObLed var IC23.1 VFOaLed VAR IC23.2 TxLed VAR IC23.3 ICE2DATA VAR BYTE ICE3DATA VAR BYTE ' inputs to calculations 24 bit fx VAR word[3] fy VAR word[3] 'output 48 bit fw VAR BYTE[6] ' temporary variables wx VAR WORD[4] wy VAR WORD[4] ra VAR WORD[3] rb VAR WORD[3] ta VAR BYTE[4] tb VAR BYTE[4] tw VAR WORD ' DDS variables DDSaddress var byte DDSdata var byte DDSdw var byte[6] DDSWRB VAR BYTE DDSUDCLK VAR BYTE ' boolean BoolA var byte Fchanged var BoolA.0 Bchanged VAR BoolA.1 Fswitched var BoolA.2 TxFreqDone VAR BoolA.3 Transmit var BoolA.4 ShowOtherVFO VAR BoolA.5 OldTransmit VAR BoolA.6 Mode VAR byte Filter Var byte OldMode VAR byte OldFilter Var byte FilterCode VAR Byte Function var byte KeysX var byte KeysY var byte KeyBits VAR BYte KeyVal var byte KeyStatus var byte DecPOint var byte KeyedDigits var byte MaxDigit var byte[8] CheckBand VAR Byte BoolK VAR BYTE errL VAR BoolK.0 errH VAR BoolK.1 FreqError var BoolK.2 VFOchanged var BoolK.3 Fupdate VAR BoolK.4 CIOchanged VAR BoolK.5 RencConfig VAR BOOlK.6 Data1 var byte VFOa var Data1.0 VFOb var Data1.1 VFOaHold var Data1.2 NewIFshift VAR Data1.3 NotClarify var Data1.4 OldNotClarify VAR Data1.5 NeedFshow VAR Data1.6 Carry VAR WORD WriteRoot VAR byte ' FREQUENCY MANAGEMENT ' Step = 10Hz = 1kHz per rev of 256 segment rotary encoder ' Frequencies stored in 10Hz - max 30+45 = 75Mhz = 7500000 x 10 Hz ' Three bytes therefore needed Fmult VAR BYTE[3] Fsig var BYTE[3] ' added to 1st IF to give Fmix1 Ftx var byte[3] ' transmit frequency - no IF shift or clarifier offsets ' Ftx is stored in EEPROM Fdisp var byte[3] ' displayed frequency = Ftx (+ clarifier on receive) Fmix1 VAR byte[3] FcioR VAR BYTE[4] ' 3 byte CIO freq in Hz + LO offset in Hz/20 ( sign bit + 7bits) FcioT VAR BYTE[4] ' ditto fL Var word fH var word fM Var word ftL Var word ftH var word ftM Var word DeltaF var word FStep var byte OldFStep var byte HC191 Var word LCDCOUNT VAR BYTE ' general purpose variables i VAR byte j var byte b Var byte c var word ' must be word as used for 8 bit + carry in division d var byte m VAR byte n var word u var word v var word ' MAX7219 fequency display driver FD_LOADBIT VAR PORTC.0 FD_DINBIT VAR PORTC.1 FD_CLKBIT VAR PORTC.2 MaxWord var word ' Progrms starts here '@ __CONFIG _CONFIG1H, 0FEh 'initialise FMultLO using stored offset correction fro Multiplier 'Note: this is an offset for the 2^48 * 10 * F multiplier, ' - i is NOT the frequency/20 offset used by IF shift etc Read 2, MultLOoffsL read 3, MultLOoffsM gosub SetFMultLO RencConfig = 0 ' Digout variable initialise IC23 = 0 IC16 = 0 ShowOtherVFO = 0 Fupdate = 1 ' Force a mode and filter check for Cio frequency OldMode = $FF OldFilter = $FF NewIFshift = 1 ' Set ports A and E for ADC Porta bits 0,1 and 3 only ADCON1 = 4 ' Read in band limits and filter control for i = 1 to 9 READ 13*i - 1, LowL[i] read 13*i + 0, LowM[i] read 13*i + 1, LowH[i] read 13*i + 5, HighL[i] read 13*i + 6, HighM[i] read 13*i + 7, HighH[i] Read 13*i + 8, BPFX2[i] Read 13*i + 9, DefaultSB[i] read 13*i + 10, TXLPF[i] read 13*i + 11, TX45GAIN[i] next read 0, Band ' saved band Read 1, Data1 ' get VFO info gosub LoadVFO gosub GetFtx gosub CheckFreq Band = CheckBand If CheckBand = 0 then ' rescue routine Band = 3 Gosub ReadBandFreq VFOa = 0 VFOb = 1 gosub SaveVFO VFOa = 1 VFOb = 0 gosub SaveVFO write 1, Data1 endif Gosub WriteBandFreq VFOaLed = VFOa VFObLed = VFOb ICE2DATA = tX45gAIN[bAND] TRISA = %00001011 TRISB = %00000000 TRISD = %11111111 TRISC = %00000000 TRISE = %00000111 OLDVRA0 = 128 OLDVRA1 = 128 OLDVRA3 = 128 'Reset the counter PORTB = %00000000 PORTA = %00000100 PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 1 PORTC.6 = 0 Lcdout $fe, 1 ' Clear the LCD PAUSE 1000 OldFStep = 1 ' ensure least sig digit is aligned with actual step gosub InRead OldTransmit = Transmit 'Reset both DDS PORTB = $30 ' LO AND CIO matser reset PORTA = IC13ADDR PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 1 pause 3 PORTC.6 = 0 pause 3 PORTB = $70 ' LO WRB GOSUB DDSINIT PORTB = $50 ' CIO WRB GOSUB DDSINIT 'ADC variables initialise OLDVRA0 = VRA0 ' IF shift oldvra1 = vra1 ' Clarify OLDVRA3 = VRA3 ' Calibrate - unused KeyStatus = 0 Gosub MaxInit GOTO MainLoop SetFMultLO: fL = FMultLOcL + MultLOoffsL FMultLOL = fL//$100 fM = FMultLOcM + MultLOoffsM + fL/$100 FMultLOM = fM//$100 FMultLOH = FMultLOcH + fM/$100 return ReadBandFreq: b = 13*Band read b + 2, Ftx[0] read b + 3, Ftx[1] read b + 4, Ftx[2] return WriteBandFreq: b = 13*Band write b + 2, Ftx[0] write b + 3, Ftx[1] write b + 4, Ftx[2] return SetFtx: Ftx[0] = fL Ftx[1] = fM Ftx[2] = fH return GetFtx: fL = Ftx[0] fM = Ftx[1] fh = Ftx[2] return DDSinit: PORTA = IC13ADDR PORTC.5 = 1 PORTC.5 = 0 DDSdata = $00 'set UD clock to external DDSaddress = $1F gosub DDSbyte DDSdata = $14 'power down Comp and QDAC DDSaddress = $1D gosub DDSbyte DDSdata = $00 'Clear OSK EN bit to switch on DDSaddress = $20 gosub DDSbyte return ReadVFO: if VFOa = 1 then b = 6 if ShowOtherVFO then b = 9 else b= 9 if ShowOtherVFO then b = 6 endif read b, FDisp[0] read b + 1, FDisp[1] read b + 2, FDisp[2] return LoadVFO: Gosub ReadVFO FTx[0] = FDisp[0] FTx[1] = FDisp[1] FTx[2] = FDisp[2] Return SaveVFO: if VFOa = 1 then b = 6 else b= 9 endif write b, Ftx[0] write b + 1, Ftx[1] write b + 2, Ftx[2] return CheckHigh: errH = 1 if fH > HighH[b] then Return errH = 0 if fH < HighH[b] then return errH = 1 if fM > HighM[b] then Return errH = 0 if fM < HighM[b] then return if fL <= HighL[b] then return errH = 1 return CheckLow: errL = 1 if fH < LowH[b] then Return errL = 0 if fH > LowH[b] then return errL = 1 if fM < LowM[b] then Return errL = 0 if fM > LowM[b] then return if fL >= LowL[b] then return errL = 1 return CheckFreq: CheckBand = 0 ' Band number repeat CheckBand = CheckBand + 1 b = CheckBand gosub CheckLow gosub CheckHigh if (errH = 0) AND (errL = 0) then return until Checkband = 9 CheckBand = 0 return MakeFreq: ' calculete and check keypad frequency FreqError = 0 fL = 0 fM = 0 fH = 0 Carry = 0 n = DecPoint + 5 for i = 1 to n 'Multiply by 10 fL = fL*$0A Carry = fL/$100 fL = fL//$100 fM = fM*$0A + Carry Carry = fM/$100 fM = fM//$100 fH = fH*$0A + Carry if fH > (HighH[9] +1) then FreqError = 1 return endif ' Add the next digit fL = fL + MaxDigit[i] Carry = fL/$100 fL = fL//$100 fM = fM + Carry Carry = fM/$100 fM = fM//$100 fH = fH + Carry next return AequalsBShow: MaxWord = $0900 Gosub MaxWrite For i = 1 to 8 Read 150 - i, b Maxword = $100*i + b gosub Maxwrite next pause 3000 MaxWord = $09FF Gosub MaxWrite return MaxOutBandShow: MaxWord = $0900 Gosub MaxWrite For i = 1 to 8 Read 137 - i, b Maxword = $100*i + b gosub Maxwrite next pause 4000 MaxWord = $09FF Gosub MaxWrite return MaxNoDpShow: MaxWord = $09E0 Gosub MaxWrite for i = 1 to 3 if MaxDigit[i] = 0 then MaxDigit[i] = $0F MaxWord = $100*(9-i) + MaxDigit[i] Gosub MaxWrite next For i = 4 to 8 Read 133 + i, b Maxword = $100*(9-i) + b gosub Maxwrite next pause 4000 MaxWord = $09FF Gosub MaxWrite return MaxEntryWrite: For i = 1 to 8 if i <= KeyedDigits then Maxword = $100*(KeyedDigits + 1 - i) + MaxDigit[i] if i = DecPoint Then Maxword = Maxword + $80 else Maxword = $100*i + $0F endif gosub Maxwrite next pause 500 return ChangeCio: fL = $88 '453,000 Hz fM = $E9 fH = $06 d = DeltaF / 20 DeltaF = d*20 ' nearest 20Hz GOSUB IncFreq Write WriteRoot, fL write WriteRoot + 1, fM write WriteRoot + 2, fH write WriteRoot + 3, d FcioT[0] = fL FcioT[1] = fM FcioT[2] = fH Gosub CioChange Gosub SetCio TxFreqDone = 0 GOSUB ChangeFreq GOSUB LoADword DDSWRB = $70 DDSUDCLK = $60 GOSUB DDSLOAD return RencModValue: RencConfig = 1 select case Function 'TX 45Mhz gain control 0 - 31 units (DAC - controls Mosfet Gate 2) Case 1 u = Tx45Gain[Band] u = u + HC191 if u < 129 then u = 129 u = u - 128 if u > $1F then u = $1F TX45Gain[BAnd] = u write 13*BAnd + 11, u ICE2DATA = u HC191 = 128 PORTB = ICE2DATA PORTA = ICE2ADDR PORTC.5 = 1 PORTC.5 = 0 'Transmit LSB carrier offset - entrered in Hz from centre freq (455) CASE 2 read 194+3, v u = 2000 - v*20 u = u + HC191*20 if u < 2580 then u = 2580 u = u - 2560 if u > 2000 then u = 2000 DeltaF = 2000 - u WriteRoot = 194 HC191 = 128 GOSUB ChangeCio 'Transmit USB carrier offset - entrered in Hz from centre freq (455) CASE 3 read 190+3, v u = v*20 - 2000 u = u + HC191*20 if u < 2580 then u = 2580 u = u - 2560 if u > 2000 then u = 2000 DeltaF = 2000 + u WriteRoot = 190 HC191 = 128 GOSUB ChangeCio 'Fine frequency calibration' case 4 u = MultLOoffsL + $100*MultLOoffsM u = u + HC191 if u < 129 then u = 129 u = u - 128 HC191 = 128 Gosub ApplyOffset end select gosub WriteValue Return MaxWriteN: Maxword = $100*(9-i) + n gosub Maxwrite return ShowFunction: MaxWord = $0900 Gosub MaxWrite select case Function 'TX 45Mhz gain control 0 - 31 units (DAC - controls Mosfet Gate 2) Case 1 for i = 1 to 4 lookup i-1, [$33,$5B,$8F,$00],n ' 45t gosub MaxWriteN next i 'Transmit LSB carrier offset - entrered in Hz from centre freq (455) CASE 2 for i = 1 to 4 lookup i-1, [$0E,$5B,$FF,$00],n ' LSb gosub MaxWriteN next i 'Transmit USB carrier offset - entrered in Hz from centre freq (455) CASE 3 for i = 1 to 4 lookup i-1, [$3E,$5B,$FF,$00],n ' USb gosub MaxWriteN next i 'Fine frequency calibration' case 4 for i = 1 to 4 lookup i-1, [$4E,$77,$8E,$00],n ' CAL gosub MaxWriteN next i end select MaxWord = $090F Gosub MaxWrite Gosub ShowValue return WriteValue: 'value passed in u i = 0 v = u repeat FunctionDigit[i] = v//10 v = v/10 i = i + 1 until v = 0 n = i for i = 0 to n - 1 MaxWord = $100*(i+5-n) + FunctionDigit[i] gosub MaxWrite next i if n < 4 then for i = 1 to 4-n MaxWord = $100*(i) + $0F gosub MaxWrite next i endif return ShowValue: select case Function 'TX 45Mhz gain control 0 - 31 units (DAC - controls Mosfet Gate 2) Case 1 u = Tx45Gain[band] 'Transmit LSB carrier offset - entrered in Hz from centre freq (455) CASE 2 read 194+3, v u = 2000 - v*20 'Transmit USB carrier offset - entrered in Hz from centre freq (455) CASE 3 read 190+3, v u = v*20 - 2000 'Fine frequency calibration' case 4 u = MultLOoffsL + $100*MultLOoffsM end select FunctionData = u GOSUB WriteValue return DoFunction: select case Function 'TX 45Mhz gain control 0 - 31 units (DAC - controls Mosfet Gate 2) Case 1 if FunctionData > $1F then FunctionData = $1F TX45Gain[BAnd] = FunctionData write 13*BAnd + 11, FunctionData ICE2DATA = FunctionData 'Transmit LSB carrier offset - entrered in Hz from centre freq (455) CASE 2 if Functiondata > 2000 then FunctionData = 2000 DeltaF = 2000 - FunctionData WriteRoot = 194 GOSUB ChangeCio 'Transmit USB carrier offset - entrered in Hz from centre freq (455) CASE 3 if Functiondata > 2000 then FunctionData = 2000 DeltaF = 2000 + FunctionData WriteRoot = 190 GOSUB ChangeCio 'Fine frequency calibration' case 4 u = FunctionData Gosub ApplyOffset end select REturn ApplyOffset: if u > 2000 then u = 2000 MultLooffsL = u//$100 MultLOoffsM = u/$100 write 2, MultLOoffsL write 3, MultLOoffsM GOSUB SetFmultLO Gosub ChangeFreq GOSUB LoADword DDSWRB = $70 DDSUDCLK = $60 GOSUB DDSLOAD return 'Read the key pad ReadKey: KeyVal = $80 KeyBits = $80 PORTA = IC13ADDR ' also = IC1ADDR PORTB = %00010000 KeysX = 0 KeysY = 0 KeyBits = 0 for i = 0 to 3 PORTB = PORTB >> 1 PORTC.5 = 1 PORTC.5 = 0 IF (PORTD & %00001111) <> 0 THEN KeysY = PORTD & %00001111 KeysX = PORTB KeyBits = (KeysY << 4) + KeysX ENDIF NEXT if KeyBits <> $80 then select case KeyBits case 20 KeyVal = $00 case 136 KeyVal = $01 case 132 KeyVal = $02 case 130 KeyVal = $03 case 72 KeyVal = $04 case 68 KeyVal = $05 case 66 KeyVal = $06 case 40 KeyVal = $07 case 36 KeyVal = $08 case 34 KeyVal = $09 case 24 KeyVal = $0A case 18 KeyVal = $0B case 17 KeyVal = $0C case 33 KeyVal = $0D case 65 KeyVal = $0E case 129 KeyVal = $0F end select endif RETURN RestoreDisplay: KeyStatus = 0 MaxWord = $09FF Gosub MaxWrite gosub FShow return KeyPad: FreqError = 0 gosub ReadKey if KeyVal = $80 then return if (KeyStatus > 31) and (KeyVal = $0C) then gosub RestoreDisplay return endif if (KeyStatus > 32) and (KeyVal = $0E) then i = KeyStatus - 32 FunctionData = 0 for j = 0 to i - 1 FunctionData = FunctionData*10 + FunctionDigit[j] next GOSUB DoFunction gosub RestoreDisplay return endif if (KeyStatus > 31) and (KeyStatus < 36) AND (KeyVal < $0A) then if KeyStatus = 32 then for i = 1 to 4 MaxWord = $100*(i) + $0F 'clear data entry digits gosub MaxWrite next i endif i = KeyStatus - 32 FunctionDigit[i] = KeyVal MaxWord = $100*(4-i) + KeyVal GOSUB MaxWrite KeyStatus = KeyStatus + 1 Pause 200 return endif if KeyStatus = 31 then if (KeyVal < $0A) then Function = KeyVal gosub ShowFunction KeyStatus = 32 Pause 200 else gosub RestoreDisplay endif return endif if (KeyVal = $0C) and (KeyStatus = 1) then KeyStatus = 0 return endif NeedFshow = 1 if (ShowOtherVFO = 1) then if KeyVal = $0D then gosub ReadVFO gosub FShow else ShowOtherVFO = 0 KeyStatus =0 endif return endif if KeyStatus = 0 then if KeyVal = $0D then ShowOtherVFO = 1 KeyStatus = 1 return endif Gosub GetFtx If (KeyVal < 10) and (KeyVal > 0) then MaxDigit[1] = KeyVal for i = 2 to 8 MaxDigit[i] = 0 next KeyedDigits = 1 DecPoint = 0 KeyStatus = 1 ' Frequency input gosub MaxEntryWrite return endif VFOchanged = 0 if (KeyVal = $0A) and (VFOa = 0) then VFOchanged = 1 Gosub SaveVFO VFOa = 1 VFOb = 0 Gosub LoadVFO else if (KeyVal = $0B) and (VFOb = 0) then VFOchanged = 1 GOSUB SaveVFO VFOb = 1 VFOa = 0 gosub LoadVFO endif endif if VFOchanged = 1 then Fupdate = 1 VFOchanged = 0 VFOaLed = VFOa VFObLed = VFOb Gosub GetFtx gosub CheckFreq Band = CheckBand write 0, Band write 1, Data1 endif if (KeyVal = $0C) then pause 1000 gosub ReadKey if KeyVal = $0C THEN VFOaHold = VFOa if VFOa = 1 then VFOa = 0 else VFOa = 1 endif gosub SaveVFO VFOa = VFOaHold Gosub AequalsBShow endif endif if (KeyVal = $0F) then MaxWord = $097F Gosub MaxWrite MaxWord = $847 GOSUB MaxWrite for i = 1 to 7 MaxWord = $100*i + $0F Gosub MaxWrite next KeyStatus = 31 Pause 200 ' Function input - F pressed return endif endif if KeyStatus = 1 then if KeyVal = $0E then GOSUB MakeFreq gosub CheckFreq if CheckBand = 0 then FreqError = 1 KeyStatus = 0 if FreqError = 0 then if Band <> CheckBand then write 0, CheckBand Band = CheckBand GOSUB SetFtx GOSUB WriteBandFreq Fupdate = 1 return else gosub MaxOutBandShow endif endif if KeyVal = $0D then DecPoint = KeyedDigits gosub MaxEntryWrite endif If (KeyVal < 10) AND (KeyedDigits < 7) then KeyedDigits = KeyedDigits + 1 MaxDigit[KeyedDigits] = KeyVal if (DecPoint = 0) AND (KeyedDigits > 2) then FreqError = 1 if (DecPoint = 0) AND (MaxDigit[1] > 3) then FreqError = 1 if FreqError > 0 then KeyStatus = 0 gosub MaxNoDpShow return endif gosub MaxEntryWrite endif endif return StepFix: if FStep <> 1 then if FStep <> OldFStep then ftL = fL ftM = fM ftH = fH gosub Div10 DeltaF = 0 fL = ftL fM = ftM fh = ftH b = c//5 if (FStep = 5) and (b <> 0 ) then DeltaF = 5 - b b = c//10 if (FStep = 20) and (b <> 0) then DeltaF = 20 - b if DeltaF then gosub IncFreq gosub SetFtx endif endif OldFStep = FStep return 'Read and process inputs InRead: PORTA = IC2ADDR PORTA = IC2addr IC2 = PORTD PORTA = IC3ADDR IC3 = PORTD PORTA = IC4ADDR IC4 = PORTD PORTA = IC1ADDR IC1 = PORTD Adcin 0, VRA0 Adcin 1, VRA1 Adcin 3, VRA3 Transmit = IC2.7 TxLed = Transmit ClarifyLed = 0 NotClarify = IC2.4 if NotClarify <> OldNotClarify then Fupdate = 1 OldNotClarify = NotClarify if (IC2.4 = 0) AND (Transmit = 0) then ClarifyLed = 1 if Transmit = 0 then TxFreqDone = 0 Filter = IC3 |/ %11110000 ' - invert all bits Mode = IC4 |/ %00000011 ' NOT OR - ie select and invert bite 2 to 7 ICE3DATA = 0 FilterCode = 0 FilterCode.0 = Filter.0 FilterCode.1 = Filter.1 FilterCode.2 = Filter.2 if Transmit = 0 then ICE3DATA.3 = Filter.0 ' 2.4Khz = Wide filter at 8.215Mhz IF ICE3DATA.2 = Filter.2 ' 500Hz ICE3DATA.1 = Filter.1 ' 2.0Khx else ICE3DATA.0 = 1 ' switch to 8.215Mhz transmit input endif if Mode = $20 then ICE3DATA.4 = 1 NewIfShift = 0 if IC2.7 = 0 THEN 'Receive if (VRA0 < (OLDVRA0 + 2)) AND ((VRA0 + 2) > OLDVRA0) then VRA0 = OLDVRA0 else Fupdate = 1 NewIFshift = 1 OLDVRA0 = VRA0 endif endif RETURN '24 bit add - for 1st mixer freq will not exceed 24bits ' 1st mixer freq into fy[..] FirstMixer: ' Lo offset (based on 433Khc Cio and -2khz offset stored Ffif if Transmit = 1 then c = FcioT[3] else c = FcioR[3] endif tw = FfifL + Fsig[0] + 2*c fy[0] = tw//$100 tw = tw/$100 tw = tw + Ffifm + Fsig[1] fy[1] = tw//$100 tw = tw/$100 fy[2] = Ffifh + Fsig[2] + tw RETURN '48 bit multiplier for AD frequency word Mult48: wx[0] = Fmult[0] + $100*Fmult[1] wx[1] = Fmult[2] wy[0] = fy[0] + $100*fy[1] wy[1] = fy[2] ra[0] = 0 ra[1] = wx[1]*wy[0] ra[2] = wx[1]**wy[0] + wx[1]*wy[1] rb[0] = wx[0]*wy[0] rb[1] = wx[0]**wy[0] + wx[0]*wy[1] rb[2] = wx[0]**wy[1] tw = 0 FOR i = 0 TO 3 j = i/2 IF (i//2) = 0 THEN ta[i] = ra[j]//$100 tb[i] = rb[j]//$100 ELSE ta[i] = ra[j]/$100 tb[i] = rb[j]/$100 ENDIF tw = tw + ta[i] + tb[i] fw[i] = tw//$100 tw = tw/$100 NEXT I tw = ra[2] + rb[2] + tw fw[4] = tw//$100 fw[5] =tw/$100 RETURN MaxWrite: for b = 15 to 0 step -1 if (MaxWord & (DCD b)) > 0 THEN HIGH FD_DINBIT else low FD_DINBIT ENDIF HIGH FD_CLKBIT LOW FD_CLKBIT next b HIGH FD_LOADBIT LOW FD_LOADBIT return MaxInit: LOW FD_CLKBIT TRISC = %00000000 MaxWord = $0C00 ' Shutdown register = 0 = shutdown gosub MaxWrite MaxWord = $0B07 ' scan Limit - all digits Gosub MaxWrite MaxWord = $09FF ' Decode Mode register all bits Code B decode GOSUB MaxWrite MaxWord = $0A01 ' Intensity regsiter = 1 Gosub MaxWrite MaxWord = $0C01 ' Shutdown register = 1 = normal operation gosub MaxWrite MaxWord = $0F00 ' Not test Gosub MaxWrite for i = 1 to 8 MaxWord = i*$100 + 9-i if (i = 7) OR (i = 4) then MaxWord = MaxWord + $80 Gosub MaxWrite next i RETURN Div10: c = fH//10 fH = fH/10 fM = fM + c*$100 c = fM//10 fM = fM/10 fL = fL + c*$100 c = fL//10 fL = fL/10 return Fshow: fL = Fdisp[0] ' fL and fM arre 16 bit (WORD) variables fM = Fdisp[1] ' because of adding the carry from the byte above fH = Fdisp[2] MaxWord = $100 ' FsigL and FsigH store f/10 - so LSD always zero Gosub MaxWrite for i = 2 to 8 ' 24 bit divide by 10 eight times gosub Div10 if (i = 8) and (c = 0) then c = 15 MaxWord = i*$100 + c if (i = 7) OR (i = 4) then MaxWord = MaxWord + $80 'decimal point Gosub MaxWrite next i RETURN LoADword: gosub FirstMixer Fmult[0] = FmultLOL Fmult[1] = FmultLoM Fmult[2] = FmultLOH gosub Mult48 RETURN ' Check rotary encoder Renc: PORTA = %00000000 HC191 = PORTD IF (HC191 <> 128) then PORTB = %00000000 PORTA = %00000100 PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 1 PORTC.6 = 0 ENDIF RETURN IncFreq: fL = fL + DeltaF Carry = fL / $100 fL = fL // $100 fM = fM + Carry Carry = fM /$100 fm = fM //$100 fH = fH + Carry return DecFreq: fL = fL + $1000 fL = fL - DeltaF Carry = fL / $100 fL = fL // $100 fM = fM + $100 fM = fM + Carry - $10 Carry = fM /$100 fM = fM //$100 fH = fH + Carry - 1 return BandSwitch: Bchanged = 0 if Transmit = 1 then return if IC2.2 = 0 then Band = Band - 1 if Band = 0 then Band = 9 Bchanged = 1 endif if IC2.3 = 0 then Band = Band + 1 if Band > 9 then Band = 1 Bchanged = 1 endif if Bchanged then Fupdate = 1 write 0, Band Gosub ReadBandFreq endif return ChangeFreq: Fchanged = 0 Fswitched = 0 if TxFreqDone then return Gosub GetFtx if IC2.1 = 0 THEN DeltaF = 2000 gosub DecFreq Fchanged = 1 endif if IC2.0 = 0 then DeltaF = 2000 gosub IncFreq Fchanged = 1 endif Fswitched = Fchanged if HC191 <> 128 then FSTEP = 1 if IC4.0 = 1 AND IC4.1 = 1 THEN FSTEP = 5 IF IC4.0 = 0 AND IC4.1 = 1 THEN FSTEP = 20 gosub StepFix if (HC191 < 128) then DeltaF = (128 - HC191)*FSTEP gosub DecFreq else DeltaF = (HC191 - 128)*FSTEP gosub IncFreq endif Fchanged = 1 ENDIF if Fchanged = 1 then Fupdate = 1 Gosub SetFtx b = Band gosub CheckLow if errL = 1 then Ftx[0] = LowL[Band] Ftx[1] = LowM[Band] Ftx[2] = LowH[Band] else gosub CheckHigh if errH = 1 then Ftx[0] = HighL[Band] Ftx[1] = HighM[Band] Ftx[2] = HighH[Band] endif endif gosub GetFtx gosub WriteBandFreq if VFOa = 1 then b = 6 else b = 9 endif write b, Ftx[0] ' save VFO write b+1, Ftx[1] write b+2, Ftx[2] endif ' Clarifier if (ClarifyLed = 1) AND (Transmit = 0) then if (VRA1 < (OLDVRA1 + 2)) AND ((VRA1 + 2) > OLDVRA1) then VRA1 = OLDVRA1 else Fupdate = 1 endif OLDVRA1 = VRA1 fL = fL + $C0 + (VRA1/2) ' = $100 + signed offset Carry = fl/$100 fL = fL//$100 fM = fM + $FF + Carry 'add $FF00 Carry = fM/$100 fM = fM//$100 fH = fH + Carry - 1 'subtract $10000 endif Fdisp[0] = fL Fdisp[1] = fM Fdisp[2] = fH if Transmit = 0 then 'IF shift ' VRA0 0 - 255, centre 128 ' Shift +/- 128*5 Hz ' LO in units of 10Hz therefore +/- 64 = $40 units ' middle is +$40 - so add $CO and then $FF in middle byte ' then subtract 1 in high byte ' Cant handle negative but fy[0] and fy[1] are 16 bit ' so add a total of $10000 then subtract it in high byte fL = fL + $C0 + VRA0/2 ' = $100 + signed offset Carry = fl/$100 fL = fL//$100 fM = fM + $FF + Carry Carry = fM/$100 fM = fM//$100 fH = fH + Carry - 1 endif Fsig[0] = fL Fsig[1] = fM Fsig[2] = fH if Transmit then TxFreqDone = 1 return ' Debug - LCD display two numbers 'LcdShow: ' LCDCOUNT = LCDCOUNT + 1 ' IF LCDCOUNT > 5 THEN ' LCDCOUNT = 0 ' Lcdout $fe, 1 ' Clear the LCD ' LCDOUT $FE, $80 ' lcdout " Filt = ",#Filter ' Lcdout " Fsig = ",#fw[5]," ",#fw[4]," ",#FW[3] ' LCDOUT $FE, $C0 ' LCDOUT "X =",#KeysX, " Y=",#KeysY," Val=",#KeyVal ' Lcdout "ADCIN = ",#VRA0," ",#VRA1," ",#VRA3 ' Lcdout "IC 234: ",#IC2," ",#IC3," ",#IC4 ' ENDIF ' RETURN Digout: PORTB = IC23 PORTA = IC23ADDR PORTC.5 = 1 PORTC.5 = 0 PORTB = BPFX2[Band] PORTA = IC16ADDR PORTC.5 = 1 PORTC.5 = 0 'ICE1 - Tx output LPF switching if Transmit = 1 then PORTB = TXLPF[Band] else PORTB = 0 endif PORTA = ICE1ADDR PORTC.5 = 1 PORTC.5 = 0 ' ICE2 - Tx 45Mh gain control PORTB = ICE2DATA PORTA = ICE2ADDR PORTC.5 = 1 PORTC.5 = 0 'ICE3 PORTB = ICE3DATA PORTA = ICE3ADDR PORTC.5 = 1 PORTC.5 = 0 RETURN DDSbyte: PORTB = DDSaddress PORTA = IC17ADDR PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 1 PORTB = DDSdata PORTA = IC18ADDR PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 0 RETURN DDSword: DDSaddress = $04 ' Freq word 1 <47:40> DDSdata = DDSdw[5] gosub DDSbyte DDSaddress = $05 ' Freq word 1 <39:32> DDSdata = DDSdw[4] gosub DDSbyte DDSaddress = $06 ' Freq word 1 <31:24> DDSdata = DDSdw[3] gosub DDSbyte DDSaddress = $07 ' Freq word 1 <23:16> DDSdata = DDSdw[2] gosub DDSbyte DDSaddress = $08 ' Freq word 1 <15::8> DDSdata = 0 gosub DDSbyte DDSaddress = $09 ' Freq word 1 <7:0> DDSdata = 0 gosub DDSbyte return DDSLOAD: DDSdw[5] = Fw[5] DDSdw[4] = Fw[4] DDSdw[3] = Fw[3] DDSdw[2] = Fw[2] PORTB = DDSWRB PORTA = IC13ADDR PORTC.5 = 1 PORTC.5 = 0 gosub DDSword PORTB = DDSUDCLK PORTA = IC13ADDR PORTC.5 = 1 PORTC.5 = 0 PORTC.6 = 1 PORTC.6 = 0 RETURN CioChange: select case Mode ' Mode switch setting case $04 ' LSB m = 0 case $08 ' USB m = 1 case $10 ' SSB m = DefaultSB[Band] case $20 ' CW m = 2 case $40 'RTTY m = 3 case $80 'spare m = DefaultSB[Band] end select n = 0 if FilterCode.1 then n = 4 if FilterCode.2 then n = 8 LOOKUP m, [11,10,12,13], d for i = 0 to 3 read 150 + 4*d + i, FcioT[i] ' three byte CIO + Lo offset Next i m = m + n lookup m, [3,2,6,9,1,0,5,8,1,0,4,7], d for i = 0 to 3 j = 150 + 4*d +i READ j, FcioR[i] next i return SetCio: Fmult[0] = FmultCIOL Fmult[1] = FmultCIOM Fmult[2] = FmultCIOH if Transmit = 1 then fy[0] = FcioT[0] fy[1] = FcioT[1] fy[2] = FcioT[2] else fy[0] = FcioR[0] fy[1] = FcioR[1] fy[2] = FcioR[2] 'IF shift ' VRA0 0 - 255, centre 128 ' Shift +/- 128*5 Hz ' Cant handle negative but fy[0] and fy[1] are 16 bit ' so add a total of $10000 then subtract it in high byte fy[0] = fy[0] + $80 + VRA0*5 Carry = fy[0]/$100 fy[0] = fy[0]//$100 fy[1] = fy[1] + $FD + Carry Carry = fy[1]/$100 fy[1] = fy[1]//$100 fy[2] = fY[2] + Carry - 1 endif Fmult[0] = FmultCIOL Fmult[1] = FmultCIOM Fmult[2] = FmultCIOH gosub Mult48 DDSWRB = $50 DDSUDCLK = $40 gosub DDSLOAD return MainLoop: GOSUB InRead repeat gosub KeyPad if KeyStatus = 32 then gosub Renc if HC191 <> 128 then gosub RencModValue endif if (RencConfig = 1) AND (KeyVal = $0E) then KeyStatus = 0 gosub RestoreDisplay RencConfig = 0 endif UNTIL KeyStatus = 0 gosub BandSwitch gosub renc if (Mode <> OldMode) OR (Filter <> OldFilter) OR (NewIFshift) OR (Transmit <> OldTransmit) then OldMode = Mode OldFilter = Filter OldTransmit = Transmit gosub CioChange gosub SetCio Fupdate = 1 endif if Bchanged then ICE2DATA = Tx45Gain[Band] GOSUB CioChange GOSUB SetCio ENDIF gosub ChangeFreq IF Fupdate = 1 Or NeedFshow then Fupdate = 0 GOSUB LoADword GOSUB Fshow DDSWRB = $70 DDSUDCLK = $60 GOSUB DDSLOAD endif NeedFshow = 0 NewIfShift = 0 ' gosub LcdShow if Bchanged then Pause 500 if Fswitched then pause 200 gosub Digout goto mainloop END