/********************************************************************** ** ** ** "FM1216.c" ** ** ** **********************************************************************/ #include "FM1216.h" byte *vs_data = (byte *) VS_data; byte *vs_ctrl = (byte *) VS_ctrl; byte Pb, Db1, Db2; int divider, channel, exit_tv, whatison, authorization; extern byte *read (void); extern void *sleep (void); extern void *tuning (void); extern void *error (void); extern void *notauthorized (void); extern int *getABC (void); extern int *getSeven (void); extern int *getNine (void); extern int *getTen (void); extern int *getSBS (void); int main() { *vs_data = 0x0; // Initialize VS data to zero *vs_ctrl = output; // Set VS 8 to 15 as output initi2cbus(); // Initialize I2C bus // Initialize port byte, divider byte 1 and 2, divider Pb = 0; Db1 = 0; Db2 = 0; divider = 0; exit_tv = 0; whatison = 0; authorization = 1; while (1) { tvauthorization(); // Check user authorization if (exit_tv == 1) { break;} // Exit TV tuner application if (channel != whatison && authorization == 1) { whatison = channel; // whatison is the current viewing channel i2cstart(); i2ctrbyte(194); // 11000010 is address select for write mode getfreq(); // get port byte and divider value getdivbytes(); // calculate two divider bytes i2ctrbyte(Db1); // transfer divider byte 1 i2ctrbyte(Db2); // transfer divider byte 2 //Set charge pump to moderate, step size to 62.5KHz, pll to normal //11001110 set second bit (cp) on high for TV mode i2ctrbyte(206); // transfer control byte i2ctrbyte(Pb); // transfer port byte i2cstop(); // stop condition getlock(); // check tuner locking status } } return 0; } /* End of MAIN */ //--------------------------------------------------------------------- void tvauthorization() { int authorized, dummy; *vs_ctrl = input; // change direction to read dummy = read(); *vs_ctrl = output; // change direction to write authorized = dummy & 0xFC; // 11111100, mask VS8 (SDA) and VS9 (SCL) if (authorized == 0x4) // user chose channel 2 (ABC) { channel = getABC(); if (channel != 0x2) { authorization = 0; notauthorized(); // user is not authorized to view this channel } else { authorization = 1;} } else if (authorized == 0x8) // user chose channel 7 { channel = getSeven(); if (channel != 0x7) { authorization = 0; notauthorized(); } else { authorization = 1;} } else if (authorized == 0x10) // user chose channel 9 { channel = getNine(); if (channel != 0x9) { authorization = 0; notauthorized(); } else { authorization = 1;} } else if (authorized == 0x20) // user chose channel 10 { channel = getTen(); if (channel != 0xa) { authorization = 0; notauthorized(); } else { authorization = 1;} } else if (authorized == 0x40) // user chose channel 28 (SBS) { channel = getSBS(); if (channel != 0x1C) { authorization = 0; notauthorized(); } else { authorization = 1;} } else if (authorized == 0x80) // user exits the application { exit_tv = 1; } } //--------------------------------------------------------------------- void getfreq() { // define port byte and divider for the chosen channel if(channel < 6) { Pb = lowband; if (channel == 1) { divider = 1538; } else if (channel == 2) { divider = 1650;} else if (channel == 3) { divider = 2002;} else if (channel == 4) { divider = 2146; } else if (channel == 5) { divider = 2258; } } else if (channel < 28) { Pb = midband; if (channel == 6) { divider = 3426; } else if (channel == 7) { divider = 3538; } else if (channel == 8) { divider = 3650; } else if (channel == 9) { divider = 3762; } else if (channel == 10) { divider = 3970; } else if (channel == 11) { divider = 4082; } } else if (channel < 39) { Pb = hiband; divider = (527 + ((channel - 28) * 7)) * 16 + 627; } else if (channel < 96) { Pb = hiband; divider = (604 + ((channel - 39) * 7)) * 16 + 627; } else { error(); divider = 1; } } //--------------------------------------------------------------------- void getdivbytes() { int div = divider; //to save contents of divider variable if((div - 16384) >= 0) { div = div - 16384; Db1 = 64; } if((div - 8192) >= 0) { div = div - 8192; Db1 = Db1 + 32; } if((div - 4096) >= 0) { div = div - 4096; Db1 = Db1 + 16; } if((div - 2048) >= 0) { div = div - 2048; Db1 = Db1 + 8; } if((div - 1024) >= 0) { div = div - 1024; Db1 = Db1 + 4; } if((div - 512) >= 0) { div = div - 512; Db1 = Db1 + 2; } if((div - 256) >= 0) { div = div - 256; Db1 = Db1 + 1; } if((div - 128) >= 0) { div = div - 128; Db2 = 128; } if((div - 64) >= 0) { div = div - 64; Db2 = Db2 + 64; } if((div - 32) >= 0) { div = div - 32; Db2 = Db2 + 32; } if((div - 16) >= 0) { div = div - 16; Db2 = Db2 + 16; } if((div - 8) >= 0) { div = div - 8; Db2 = Db2 + 8; } if((div - 4) >= 0) { div = div - 4; Db2 = Db2 + 4; } if((div - 2) >= 0) { div = div - 2; Db2 = Db2 + 2; } if((div - 1) >= 0) { div = div - 1; Db2 = Db2 + 1; } } //--------------------------------------------------------------------- void getlock() { int ok, tel; byte status; ok = 0; tel = 0; while (ok == 0) { //read status byte until status shows pll lock i2cstart(); i2ctrbyte(195); //This is the read-address (write-address +1) status = i2creadlastbyte(); i2cstop(); tel = tel + 1; if(status >= 64) //if status = 64 (1000000) { ok = 1; tuning(); } if(tel > 10) { error(); ok = 1; } } } //--------------------------------------------------------------------- void i2cstart() { // A 'start' condition is defined as SDA line goes from high to low // while SCL line is high. i2csetsda(); i2csetscl(); i2cclearsda(); i2cclearscl(); } //--------------------------------------------------------------------- void i2cstop() { // A 'stop' condition is defined as SDA line goes from low to high // while SCL line is high. i2cclearsda(); i2csetscl(); i2csetsda(); } //--------------------------------------------------------------------- void i2ctrbyte(byte trbyte) // byte tranfer function { int i; byte dummy; int compare = 128; for(i = 7; i >= 0; i = i-1) //MSB first, sending bit by bit { if((trbyte & compare) == 0) { i2cclearsda(); } else { i2csetsda(); } //data bit stand on output i2ctrck(); //generate clock pulse compare = compare >> 1; } //data transfer complete, now receive ACK i2csetsda(); i2csetscl(); //slave must reply with an ACK //read VS8-VS15 *vs_ctrl = input; //change direction to read dummy = read(); *vs_ctrl = output; //change direction to write i2cclearscl(); //end clock pulse if((dummy & 0x1) == 0x1) { error(); } } //--------------------------------------------------------------------- void i2ctrck() // generate clock pulse { i2csetscl(); i2cclearscl(); } //--------------------------------------------------------------------- void initi2cbus() { i2csetscl(); i2csetsda(); *vs_ctrl = input; // change direction to read. byte temp = read(); *vs_ctrl = output; // change direction to write. if((temp & 0x3) == 0x3) { } else { error(); } } //--------------------------------------------------------------------- void i2cclearscl() { *vs_data = *vs_data & 0xFD; //FD -> 11111101 sleep(); } //--------------------------------------------------------------------- void i2cclearsda() { *vs_data = *vs_data & 0xFE; //FE -> 11111110 sleep(); } //--------------------------------------------------------------------- void i2csetscl() { *vs_data = *vs_data | 0x2; //set VS9 on high sleep(); } //--------------------------------------------------------------------- void i2csetsda() { *vs_data = *vs_data | 0x1; //set VS8 on high sleep(); } //--------------------------------------------------------------------- byte i2cgetbyte() { int i; int compare = 128; byte dummy; byte temp = 0x0; for(i = 7; i >= 0; i = i-1) { i2csetscl(); *vs_ctrl = input; // change direction to read. dummy = read(); *vs_ctrl = output; // change direction to write. if((dummy & 0x3) == 0x3) { temp = temp + compare; } i2cclearscl(); compare = compare >> 1; } return temp; } //--------------------------------------------------------------------- byte i2creadlastbyte() { byte i2creadlastbyte; //no need to generate ACK i2creadlastbyte = i2cgetbyte(); i2csetsda(); //SDA = 1 --> no ACK i2ctrck(); //generate transmitting clock pulse return i2creadlastbyte; } //---------------------------------------------------------------------