#include "fc2580.h" /*============================================================================== FILE NAME : FC2580_driver_v1400.c VERSION : 1.400 UPDATE : September 22. 2008 ==============================================================================*/ /*============================================================================== milisecond delay function EXTERNAL FUNCTION This function is a generic function which write a byte into fc2580's specific address. a length of wanted delay in milisecond unit ==============================================================================*/ void wait_msec (unsigned long msec) { User_delay (FCI_FC2580_demodulator, msec); } static fc2580_band_type curr_band = NO_BAND; static unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E; /*============================================================================== fc2580 i2c write This function is a generic function which write a byte into fc2580's specific address. addr fc2580's memory address type : byte data target data type : byte ==============================================================================*/ void fc2580_i2c_write( unsigned char addr, unsigned char data ) { Standard_writeTunerRegisters (FCI_FC2580_demodulator, FCI_FC2580_chip, addr, 1, &data); } /*============================================================================== fc2580 i2c read This function is a generic function which gets called to read data from fc2580's target memory address. addr fc2580's memory address type : byte data a byte of data read out of target address 'addr' type : byte ==============================================================================*/ unsigned char fc2580_i2c_read( unsigned char addr ) { Byte value; Standard_readTunerRegisters (FCI_FC2580_demodulator, FCI_FC2580_chip, addr, 1, &value); return (value); } /*============================================================================== fc2580 I2C Test This function is a generic function which tests I2C interface's availability by reading out it's I2C id data from reg. address '0x01'. None int 1 : success - communication is avilable 0 : fail - communication is unavailable ==============================================================================*/ int fc2580_i2c_test( void ) { return ( fc2580_i2c_read( 0x01 ) == 0x56 )? 0x01 : 0x00; } /*============================================================================== fc2580 initial setting This function is a generic function which gets called to initialize fc2580 in DVB-H mode or L-Band TDMB mode ifagc_mode type : integer 1 : Internal AGC 2 : Voltage Control Mode ==============================================================================*/ void fc2580_set_init( int ifagc_mode ) { fc2580_i2c_write(0x00, 0x00); /*** Confidential ***/ fc2580_i2c_write(0x12, 0x86); fc2580_i2c_write(0x14, 0x5C); fc2580_i2c_write(0x16, 0x3C); fc2580_i2c_write(0x1F, 0xD2); fc2580_i2c_write(0x09, 0xD7); fc2580_i2c_write(0x0B, 0xD5); fc2580_i2c_write(0x0C, 0x32); fc2580_i2c_write(0x0E, 0x43); fc2580_i2c_write(0x21, 0x0A); fc2580_i2c_write(0x22, 0x82); if( ifagc_mode == 1 ) { fc2580_i2c_write(0x45, 0x10); /** internal AGC */ fc2580_i2c_write(0x4C, 0x00); /** HOLD_AGC polarity */ } else if( ifagc_mode == 2 ) { fc2580_i2c_write(0x45, 0x20); /** Voltage Control Mode */ fc2580_i2c_write(0x4C, 0x02); /** HOLD_AGC polarity */ } else if( ifagc_mode == 3 ) { fc2580_i2c_write(0x45, 0x30); //Up/Down Control ( Digital AGC ) fc2580_i2c_write(0x4C, 0x02); //HOLD_AGC polarity } fc2580_i2c_write(0x3F, 0x88); fc2580_i2c_write(0x02, 0x0E); fc2580_i2c_write(0x58, 0x14); fc2580_set_filter(8); /** BW = 7.8MHz */ } /*============================================================================== fc2580 frequency setting This function is a generic function which gets called to change LO Frequency of fc2580 in DVB-H mode or L-Band TDMB mode f_lo Value of target LO Frequency in 'kHz' unit ex) 2.6GHz = 2600000 ==============================================================================*/ void fc2580_set_freq( unsigned int f_lo ) { unsigned int f_diff, f_diff_shifted, n_val, k_val; unsigned int f_vco, r_val, f_comp; unsigned char pre_shift_bits = 4; /** number of preshift to prevent overflow in shifting f_diff to f_diff_shifted */ unsigned char data_0x18; fc2580_band_type band = ( f_lo > 1000000 )? L_BAND : ( f_lo > 400000 )? UHF_BAND : VHF_BAND; f_vco = ( band == UHF_BAND )? f_lo * 4 : (( band == L_BAND )? f_lo * 2 : f_lo * 12); r_val = ( f_vco >= 2*76*FREQ_XTAL )? 1 : ( f_vco >= 76*FREQ_XTAL )? 2 : 4; f_comp = FREQ_XTAL/r_val; n_val = ( f_vco / 2 ) / f_comp; f_diff = f_vco - 2* f_comp * n_val; f_diff_shifted = f_diff << ( 20 - pre_shift_bits ); k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits ); if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) ) k_val = k_val + 1; if( f_vco >= BORDER_FREQ ) /** Select VCO Band */ data_0x02 = data_0x02 | 0x08; /** 0x02[3] = 1; */ else data_0x02 = data_0x02 & 0xF7; /** 0x02[3] = 0; */ //if( band != curr_band ) { switch(band) { case UHF_BAND: data_0x02 = (data_0x02 & 0x3F); fc2580_i2c_write(0x25, 0xF0); fc2580_i2c_write(0x27, 0x77); fc2580_i2c_write(0x28, 0x53); fc2580_i2c_write(0x29, 0x60); fc2580_i2c_write(0x30, 0x09); fc2580_i2c_write(0x50, 0x8C); fc2580_i2c_write(0x53, 0x50); if( f_lo < 538000 ) fc2580_i2c_write(0x5F, 0x13); else fc2580_i2c_write(0x5F, 0x15); if( f_lo < 538000 ) { fc2580_i2c_write(0x61, 0x07); fc2580_i2c_write(0x62, 0x06); fc2580_i2c_write(0x67, 0x06); fc2580_i2c_write(0x68, 0x08); fc2580_i2c_write(0x69, 0x10); fc2580_i2c_write(0x6A, 0x12); } else if( f_lo < 794000 ) { fc2580_i2c_write(0x61, 0x03); fc2580_i2c_write(0x62, 0x03); fc2580_i2c_write(0x67, 0x07); fc2580_i2c_write(0x68, 0x08); fc2580_i2c_write(0x69, 0x0C); fc2580_i2c_write(0x6A, 0x0E); } else { fc2580_i2c_write(0x61, 0x07); fc2580_i2c_write(0x62, 0x06); fc2580_i2c_write(0x67, 0x07); fc2580_i2c_write(0x68, 0x09); fc2580_i2c_write(0x69, 0x10); fc2580_i2c_write(0x6A, 0x12); } fc2580_i2c_write(0x63, 0x15); fc2580_i2c_write(0x6B, 0x0F); fc2580_i2c_write(0x6C, 0x11); fc2580_i2c_write(0x6D, 0x78); fc2580_i2c_write(0x6E, 0x32); fc2580_i2c_write(0x6F, 0x14); /*fc2580_set_filter(8);*/ /** BW = 7.8MHz */ break; case VHF_BAND: data_0x02 = (data_0x02 & 0x3F) | 0x80; fc2580_i2c_write(0x27, 0x77); fc2580_i2c_write(0x28, 0x33); fc2580_i2c_write(0x29, 0x40); fc2580_i2c_write(0x50, 0x40); fc2580_i2c_write(0x53, 0x18); fc2580_i2c_write(0x5F, 0x0F); fc2580_i2c_write(0x61, 0x07); fc2580_i2c_write(0x62, 0x00); fc2580_i2c_write(0x63, 0x15); fc2580_i2c_write(0x67, 0x03); fc2580_i2c_write(0x68, 0x05); fc2580_i2c_write(0x69, 0x10); fc2580_i2c_write(0x6A, 0x12); fc2580_i2c_write(0x6B, 0x0F); fc2580_i2c_write(0x6C, 0x11); fc2580_i2c_write(0x6D, 0x78); fc2580_i2c_write(0x6E, 0x32); fc2580_i2c_write(0x6F, 0x54); /*fc2580_set_filter(7);*/ /** BW = 6.8MHz */ break; case L_BAND: data_0x02 = (data_0x02 & 0x3F) | 0x40; fc2580_i2c_write(0x2B, 0x70); fc2580_i2c_write(0x2C, 0x37); fc2580_i2c_write(0x2D, 0xE7); fc2580_i2c_write(0x44, 0x20); fc2580_i2c_write(0x50, 0x40); fc2580_i2c_write(0x53, 0x18); fc2580_i2c_write(0x5F, 0x0F); fc2580_i2c_write(0x61, 0x0F); fc2580_i2c_write(0x62, 0x00); fc2580_i2c_write(0x63, 0x13); fc2580_i2c_write(0x67, 0x00); fc2580_i2c_write(0x68, 0x02); fc2580_i2c_write(0x69, 0x0F); fc2580_i2c_write(0x6A, 0x11); fc2580_i2c_write(0x6B, 0x0F); fc2580_i2c_write(0x6C, 0x11); fc2580_i2c_write(0x6D, 0xA0); fc2580_i2c_write(0x6E, 0x50); fc2580_i2c_write(0x6F, 0x14); /*fc2580_set_filter(1);*/ /** BW = 1.53MHz */ break; default: break; } curr_band = band; //} /** A command about AGC clock's pre-divide ratio */ if( FREQ_XTAL >= 28000 ) fc2580_i2c_write( 0x4B, 0x22 ); /** Commands about VCO Band and PLL setting. */ fc2580_i2c_write(0x02, data_0x02); data_0x18 = ( ( r_val == 1 )? 0x00 : ( ( r_val == 2 )? 0x10 : 0x20 ) ) + (unsigned char)(k_val >> 16); fc2580_i2c_write(0x18, data_0x18); /** Load 'R' value and high part of 'K' values */ fc2580_i2c_write(0x1A, (unsigned char)( k_val >> 8 ) ); /** Load middle part of 'K' value */ fc2580_i2c_write(0x1B, (unsigned char)( k_val ) ); /** Load lower part of 'K' value */ fc2580_i2c_write(0x1C, (unsigned char)( n_val ) ); /** Load 'N' value */ /** A command about UHF LNA Load Cap */ if( band == UHF_BAND ) fc2580_i2c_write(0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F ); /** LNA_OUT_CAP */ } /*============================================================================== fc2580 filter BW setting This function is a generic function which gets called to change Bandwidth frequency of fc2580's channel selection filter filter_bw 1 : 1.53MHz(TDMB) 5 : 5MHz 6 : 6MHz 7 : 6.8MHz 8 : 7.8MHz 9 : 8.0MHz ==============================================================================*/ void fc2580_set_filter(unsigned char filter_bw) { unsigned char cal_mon, i; if(filter_bw == 1) { fc2580_i2c_write(0x36, 0x1C); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (4151 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x00); fc2580_i2c_write(0x2E, 0x09); } if(filter_bw == 5) { fc2580_i2c_write(0x36, 0x18); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (5320 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x00); fc2580_i2c_write(0x2E, 0x09); } else if(filter_bw == 6) { fc2580_i2c_write(0x36, 0x18); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (4400 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x00); fc2580_i2c_write(0x2E, 0x09); } else if(filter_bw == 7) { fc2580_i2c_write(0x36, 0x18); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (3910 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x80); fc2580_i2c_write(0x2E, 0x09); } else if(filter_bw == 8) { fc2580_i2c_write(0x36, 0x18); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (3300 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x80); fc2580_i2c_write(0x2E, 0x09); } else if(filter_bw == 9) { fc2580_i2c_write(0x36, 0x18); fc2580_i2c_write(0x37, (unsigned char) (((unsigned long) (2450 * FREQ_XTAL)) / 1000000)); fc2580_i2c_write(0x39, 0x80); fc2580_i2c_write(0x2E, 0x09); } for(i=0; i<5; i++) { wait_msec(5); /** wait 5ms */ cal_mon = fc2580_i2c_read(0x2F); if( (cal_mon & 0xC0) != 0xC0) { fc2580_i2c_write(0x2E, 0x01); fc2580_i2c_write(0x2E, 0x09); } else break; } fc2580_i2c_write(0x2E, 0x01); } /*============================================================================== fc2580 RSSI function This function is a generic function which returns fc2580's current RSSI value. none int rssi : estimated input power. ==============================================================================*/ int fc2580_get_rssi(void) { int s_lna = fc2580_i2c_read( 0x71 ); int s_rfvga = fc2580_i2c_read( 0x72 ); int s_cfs = fc2580_i2c_read( 0x73 ); int s_ifvga = fc2580_i2c_read( 0x74 ); int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi; ofs_lna = (curr_band==UHF_BAND)? (s_lna==0)? 0 : (s_lna==1)? -6 : (s_lna==2)? -17 : (s_lna==3)? -22 : -30 : (curr_band==VHF_BAND)? (s_lna==0)? 0 : (s_lna==1)? -6 : (s_lna==2)? -19 : (s_lna==3)? -24 : -32 : (curr_band==L_BAND)? (s_lna==0)? 0 : (s_lna==1)? -6 : (s_lna==2)? -11 : (s_lna==3)? -16 : -34 : 0; /** NO_BAND */ ofs_rfvga = -s_rfvga+((s_rfvga>=11)? 1 : 0) + ((s_rfvga>=18)? 1 : 0); ofs_csf = -6*s_cfs; ofs_ifvga = s_ifvga/4; return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI; }