' 'C.Potma PA3CKR 2002/1/27 'Control a Philips SF1216 Tuner. 'Aim is to extract the VCO signal. 'Frequency entered is converted to: '-pll divisor 'which is subsequently sent to the tuner through 'a I2C interface ' 'Using PC LPT-port I2C routines written by Arne van Belle. ' 'The program is written for using the SF1216 in the '125KHz step mode. The Philips datasheet gives a formula for 'the calculation of the PLL divisor as: divisor=Fvco*8 'where Fvco is in MHz. DECLARE SUB i2cstart () DECLARE FUNCTION i2creadlastbyte! () DECLARE FUNCTION i2cgetbyte! () DECLARE FUNCTION i2creadbyte! () DEFINT A-Z DECLARE SUB initi2cbus () DECLARE SUB i2csetscl () DECLARE SUB i2cclearscl () DECLARE SUB i2csetsda () DECLARE SUB i2cclearsda () DECLARE SUB i2cstop () DECLARE SUB i2ctrck () DECLARE SUB i2ctrbyte (trbyte) DECLARE SUB getdivbytes (divisor, b2, b3) DECLARE SUB getlock () CONST lptbase = &H378 '&H378 for LPT1 CONST stepfactor = 8 '8, fixed for SF1216 CONST stepsize = .125 '125KHz CONST lowband = 1417.5 'vco low limit in MHz CONST hihband = 2547.5 'vco upper limit in MHz CLS CALL initi2cbus 'optioneel eenmalig bij start van basic programma 'test op aanwezig zijn hardware / bus vrij DO 'while 1 CALL i2cstart CALL i2ctrbyte(192) '11000000 is SF1216 address with pin 11 grounded PRINT "VCO range is "; lowband; " to: "; hihband INPUT "Enter SF1216 VCO Frequency in MHz: (0=stop) :"; freq! IF freq! = 0 THEN END IF (freq! < lowband) OR (freq! > hihband) THEN PRINT "Frequency out of range: limits are: "; lowband; "and:"; hihband; " MHz" ELSE divisor = freq! * stepfactor 'calculate two bytes from this number: CALL getdivbytes(divisor, b2, b3) 'PRINT "divisor: "; divisor; "b2/b3: "; b2, b3 'send these bytes to the tuner CALL i2ctrbyte(b2) 'byte2 CALL i2ctrbyte(b3) 'byte3 'ctrl byte 1: set charge pump to moderate, pll to normal CALL i2ctrbyte(128 + 8 + 4 + 2) 'control info byte4 'ctrl byte 2: input rf1, IF bandwith ??? MHz CALL i2ctrbyte(0) CALL i2cstop CALL getlock END IF INPUT "Sweep? (j/n): "; sweep$ IF sweep$ = "j" THEN PRINT "VCO range is "; lowband; " to: "; hihband INPUT "Sweep width (MHz): "; sweepwidth! nrswp = sweepwidth! / stepsize PRINT "Sweeping around: "; freq!; " in: "; nrswp; " "; stepsize; " (MHz) steps" startsweep! = freq! - sweepwidth! / 2 stopsweep! = freq! + sweepwidth! / 2 IF (startsweep! < lowband) OR (stopsweep! < lowband) OR (startsweep! > hihband) OR (stopsweep! > hihband) THEN PRINT "Either start, or stopvalue of sweepfrequency are out-of-range" PRINT "Try again!" ELSE PRINT "Sweeping from: "; freq! - sweepwidth! / 2; " to: "; freq! + sweepwidth! / 2; " MHz" stopsweeping$ = "" PRINT "Hit s key to stop sweeping" DO FOR sweepfreq! = freq! - sweepwidth! / 2 TO freq! + sweepwidth! / 2 STEP stepsize PRINT "Sweeping now at: "; sweepfreq! LOCATE (CSRLIN - 1), 1 divisor = sweepfreq! * stepfactor 'calculate two bytes from this number: CALL getdivbytes(divisor, b2, b3) 'PRINT "divisor: "; divisor; "b2/b3: "; b2, b3 'send these bytes to the tuner CALL i2cstart CALL i2ctrbyte(192) '11000000 is SF1216 with pin 11 grounded CALL i2ctrbyte(b2) 'byte2 CALL i2ctrbyte(b3) 'byte3 'ctrl byte 1: set charge pump to moderate, pll to normal CALL i2ctrbyte(128 + 8 + 4 + 2)'control info byte4 'ctrl byte 2: input rf1, IF bandwith ??? NHz CALL i2ctrbyte(0) CALL i2cstop CALL getlock NEXT sweepfreq! stopsweeping$ = INKEY$ LOOP WHILE stopsweeping$ = "" END IF END IF LOOP WHILE (1) END SUB getdivbytes (divisor, b2, b3) 'from divisor to byte2 and byte3 ' byte2: 64 32 16 8 4 2 1 'divisor: 16384+8192+4096+2048+1024+512+256+128+64+32+16+8+4+2+1 ' byte3: 128 64 32 16 8 4 2 1 b2 = 0 b3 = 0 div = divisor'(to save contents of divisor variable... IF div - 16384 >= 0 THEN div = div - 16384 b2 = 64 END IF IF div - 8192 >= 0 THEN div = div - 8192 b2 = b2 + 32 END IF IF div - 4096 >= 0 THEN div = div - 4096 b2 = b2 + 16 END IF IF div - 2048 >= 0 THEN div = div - 2048 b2 = b2 + 8 END IF IF div - 1024 >= 0 THEN div = div - 1024 b2 = b2 + 4 END IF IF div - 512 >= 0 THEN div = div - 512 b2 = b2 + 2 END IF IF div - 256 >= 0 THEN div = div - 256 b2 = b2 + 1 END IF IF div - 128 >= 0 THEN div = div - 128 b3 = 128 END IF IF div - 64 >= 0 THEN div = div - 64 b3 = b3 + 64 END IF IF div - 32 >= 0 THEN div = div - 32 b3 = b3 + 32 END IF IF div - 16 >= 0 THEN div = div - 16 b3 = b3 + 16 END IF IF div - 8 >= 0 THEN div = div - 8 b3 = b3 + 8 END IF IF div - 4 >= 0 THEN div = div - 4 b3 = b3 + 4 END IF IF div - 2 >= 0 THEN div = div - 2 b3 = b3 + 2 END IF IF div - 1 >= 0 THEN div = div - 1 b3 = b3 + 1 END IF END SUB SUB getlock 'De eerste keer status bit TSA5511 lezen na POR: MSB is altijd=1?? 'Waarom is niet in Philips doc te vinden '-IIC<--> LPT1 Base=378, ' PC-lezen: Base+1 bit7&3 Bit3=SCL Bit3=SDA ' PC-schrijven: Base bit7 Geinverteerd! =SDA ' Base+2 bit3 NIET geinverteerd! =SCL ' na PC-POR en boot staat er op I/O &H379 47 decimaal ' Op iic hardware na boot:SCL=1,SDA=0 'bij "call i2csetscl" direct gevolgd door "call i2cclearscl" wordt 'op 486-dx50/2 een puls van 20us breed geleverd. ok = 0 tel = 0 DO 'Read TSA5510 status byte until status shows pll lock CALL i2cstart CALL i2ctrbyte(193) 'This is TSA5510 read-address (write-address +1) status = i2creadlastbyte CALL i2cstop 'PRINT "TSA5511 Status byte:", status tel = tel + 1 IF (status AND 2 ^ 6) = 2 ^ 6 THEN 'PRINT "PLL is locked" ok = 1 END IF IF tel > 25 THEN PRINT "TSA5511 PLL is not locking! Check connections." ok = 1 END IF LOOP UNTIL ok = 1 END SUB SUB i2cclearscl OUT (lptbase + 2), 228 END SUB SUB i2cclearsda OUT lptbase, 170 END SUB DEFSNG A-Z FUNCTION i2cgetbyte dummy = 0 'initialize FOR i = 7 TO 0 STEP -1 'msb first! CALL i2csetscl IF (INP(lptbase + 1) AND 2 ^ 7) THEN dummy = dummy + 2 ^ i END IF CALL i2cclearscl NEXT i i2cgetbyte = dummy END FUNCTION FUNCTION i2creadbyte i2creadbyte = i2cgetbyte 'genereer acknowledge CALL i2cclearsda 'SDA:0 = acknowledge CALL i2ctrck 'generate transmit klokpuls CALL i2csetsda 'Laat SDA "vrij" om volgende byte te kunnen lezen END FUNCTION FUNCTION i2creadlastbyte i2creadlastbyte = i2cgetbyte 'genereer geen acknowledge CALL i2csetsda 'SDA:1 = no acknowledge CALL i2ctrck 'generate transmit klokpuls END FUNCTION DEFINT A-Z SUB i2csetscl OUT (lptbase + 2), 236 END SUB SUB i2csetsda OUT lptbase, 42 END SUB DEFSNG A-Z SUB i2cstart CALL i2csetsda 'definieer begintoestand CALL i2csetscl 'definieer begintoestand CALL i2cclearsda 'Genereer start conditie CALL i2cclearscl 'klok laag END SUB SUB i2cstop CALL i2cclearsda 'maak SDA laag CALL i2csetscl CALL i2csetsda '=stop conditie END SUB DEFINT A-Z SUB i2ctrbyte (trbyte) FOR i = 7 TO 0 STEP -1 'MSB's first IF (trbyte AND 2 ^ i) = 0 THEN CALL i2cclearsda ELSE CALL i2csetsda END IF ' data bit staat nu op output CALL i2csetscl 'genereer klokpuls CALL i2cclearscl NEXT i 'data transfer compleet, nu acknowledge ontvangen: CALL i2csetsda 'SDA=1 : High-Z CALL i2csetscl 'slave moet nu antwoorden met acknowledge dummy = INP(lptbase + 1) CALL i2cclearscl 'einde klokpuls IF (dummy AND 2 ^ 7) = 2 ^ 7 THEN PRINT "ERROR 002: subroutine -i2ctrbyte-" PRINT "NO ACKNOWLEDGE FROM SLAVE !!" END END IF END SUB DEFSNG A-Z SUB i2ctrck CALL i2csetscl '0->1 flank CALL i2cclearscl '1->0 flank END SUB SUB initi2cbus CALL i2csetscl CALL i2csetsda IF (INP(lptbase + 1) AND (2 ^ 7 + 2 ^ 3)) = (2 ^ 7 + 2 ^ 3) THEN ELSE CLS PRINT "I2C Error 001 -initi2cbus" PRINT " Mogelijke oorzaken:" PRINT " 1) I2C Hardware niet aanwezig op printer poort" PRINT " 2) I2C Hardware +5 volt ontbreekt" PRINT " 3) Slave houdt de bus vast (laag)" END END IF END SUB