ct202.c
来自「QPSK Tuner details, for conexant chipset」· C语言 代码 · 共 2,621 行 · 第 1/5 页
C
2,621 行
{
for(i=0;i<ALLOWABLE_FS_COUNT;++i)
{
//////////printf("\n%d inband_interferer_div2:%hx inband_interferer_div4:%hx\n", i, inband_interferer_div2[i], inband_interferer_div4[i]);
if( (inband_interferer_div2[i]|inband_interferer_div4[i]) == FALSE)
{
sample_rate=afs[i];
//////////printf("2afs i:%d\n", i);
break;
}
}
}
if(sample_rate>207 || sample_rate<192)
{
sample_rate=200;
}
*/
sample_rate=200;
fine_tune_freq = (ifine_tune_freq/(float)sample_rate)*0x4000;
coarse_tune_freq = icoarse_tune_freq / 10.0;
fine_tune_l_h[0]=fine_tune_freq&0xFF;
fine_tune_l_h[1]=fine_tune_freq>>8&0xFF;
//////////printf("\nWrint Tuer Coarse ValueH:%2hx\n", coarse_tune_freq);
//////////printf("Wrint Tuer Frq ValueH:%2hx L:%2hx\n", fine_tune_l_h[0], fine_tune_l_h[1]);
//////////printf("Wrint Tuer Rate ValueH:%2hx\n", sample_rate);
#ifdef DLL_VERSION
tuner_adc_fs=sample_rate;
#endif
status &= SetReg(g_CTK202A[bTunerIndex], COARSE_TUNE_REG, &coarse_tune_freq, 0x01);
status &= SetReg(g_CTK202A[bTunerIndex], FINE_TUNE_REG_L, fine_tune_l_h, 0x02);
status &= SetReg(g_CTK202A[bTunerIndex], PLL_DIVISOR_REG, &sample_rate, 0x01);
/* #ifdef DLL_VERSION
return sample_rate;
#endif */
return status;
}
//initiates a channel acquisition sequence using the specified symbol rate and code rate
bool8 SetAcquire(u32 symbrate, coderate_t coderate,CSHDITunerIndex bTunerIndex)
{
UINT8 symbolrate_known;
u32 sym_rate;
UCHAR sym_rate_bytes[3];
UINT8 i;
UINT8 coderate_ptr;
bool8 status;
UINT8 start_acq=0x80;
UINT8 reg;
float data_rate;
#ifdef REVC
UINT8 acq_contr_1, acq_contr_2;
UINT8 d,th,regs[3];
UINT8 t[]={197,175,157,150,137,126,116,0};
#endif
status = PASS;
coderate_ptr = coderate;
if(symbrate == 0)symbrate++;
if(symbrate == 0) //unknown
{
symbolrate_known = 0;
symbolrate_known |= 0x80; //start symbol rate estimation
//todo: specify blind scan? (0x40)
status &= SetReg(g_CTK202A[bTunerIndex], SYMBOL_RATE_ESTIMATOR_CONTROL_REG, &symbolrate_known, 0x01);
}
else //known
{
//data_rate = symbrate/1000000.0; //in MS/s
data_rate = symbrate/1000.0; //in MS/s
symbolrate_known = 1;
//sym_rate = ((float)data_rate/(float)hDevice.fs)*0x800000;
//18apr05
#ifdef DLL_VERSION
// sym_rate = floor((float)data_rate/(float)tuner_adc_fs * 0x800000);
data_rate *= 8388608.0;
data_rate /= tuner_adc_fs;
sym_rate = (u32)data_rate;
//sym_rate = floor((float)data_rate / (float)tuner_adc_fs);
#endif
for(i=0;i<3;++i)
{
sym_rate_bytes[i] = (u8)(sym_rate >> (i*8))&0xff;
}
//////////printf("tuner_adc_fs%ld", tuner_adc_fs);
//////////printf("sym_rate_bytes: %hx %hx %hx", sym_rate_bytes[0], sym_rate_bytes[1], sym_rate_bytes[2]);
//write the symbol rate (3 bytes)
status &= SetReg(g_CTK202A[bTunerIndex], SYMBOL_RATE_REG_L, sym_rate_bytes, 0x03);
//if(status != PASS) return status;
//status |= SetReg(hDevice, SYMBOL_RATE_ESTIMATOR_CONTROL_REG, &symbolrate_known, 0x01);
//done only for symbol rate unknown
//if(status != PASS) return status;
}
//start the Viterbi search
coderate = (coderate_t) (coderate | 0x80);
//write code rates to use in the Viterbi search
status &= SetReg(g_CTK202A[bTunerIndex], VITERBI_SEARCH_CONTROL_REG_1,&coderate_ptr,0x01);
//clear acq_start bit
status &= GetReg(g_CTK202A[bTunerIndex], ACQ_CONTROL_REG_2,®,0x01);
reg &= ~start_acq;
status &= SetReg(g_CTK202A[bTunerIndex], ACQ_CONTROL_REG_2,®,0x01);
#if 0
#ifdef REVC
if( u8Version == 3 )
{
acq_contr_1 = 1<<4;
SetReg(g_CTK202A[bTunerIndex],0x13, &acq_contr_1, 1);
acq_contr_2= 1<<7;
SetReg(g_CTK202A[bTunerIndex],0x14, &acq_contr_2, 1);
acq_contr_2= 0;
SetReg(g_CTK202A[bTunerIndex],0x14, &acq_contr_2, 1);
acq_contr_1 = 0;
SetReg(g_CTK202A[bTunerIndex],0x13, &acq_contr_1, 1);
status &= GetReg(g_CTK202A[bTunerIndex], 0x13, ®, 1);
reg|=0x40;
status &= SetReg(g_CTK202A[bTunerIndex], 0x13, ®, 1);
}
#endif
#endif
/*
#ifdef REVD
//use new Carrier Frequency Offset Estimator (QuickLock) for revD
if( u8Version >= 4 )
{
if( symbrate < 10000000 )
{
regs[0] = 0xCB;
regs[1] = 0x40;
regs[2] = 0xCB;
status &= SetReg(g_CTK202A[bTunerIndex], TWO_DB_BANDWIDTH_THRESHOLD_REGISTER, ®s[0], 0x03);
reg = 0x56;
status &= SetReg(g_CTK202A[bTunerIndex], LSA_CONTROL_REGISTER_1, ®, 1);
reg = 0x05;
status &= SetReg(g_CTK202A[bTunerIndex], BLIND_SCAN_CONTROL_REGISTER, ®, 1);
}
else
{
reg = 0x00;
status &= SetReg(g_CTK202A[bTunerIndex], BLIND_SCAN_CONTROL_REGISTER, ®, 1);
}
}
#endif
*/
#if 0//xyh
//start automatic acq
status &= SetReg(TUNER_I2C_ADDRESS, ACQ_CONTROL_REG_2,&start_acq,0x01);
#endif
#if 0
#ifdef REVC
if( u8Version == 3 )
{
reg=0x88;
status &= SetReg(g_CTK202A[bTunerIndex], 0x19, ®, 1);
status &= GetReg(g_CTK202A[bTunerIndex], 0x1a, &d, 1);
status &= GetReg(g_CTK202A[bTunerIndex], 0x1b, &th, 1);
for(i=0;i<8;i++)
{
if(d>t[i])
break;
}
regs[0]=d;
regs[1]=(th&0xc7)|(i<<3);
status &= SetReg(g_CTK202A[bTunerIndex], 0x1a, regs, 2);
reg=0xc8;
status &= SetReg(g_CTK202A[bTunerIndex], 0x19, ®, 1);
status &= GetReg(g_CTK202A[bTunerIndex], 0x13, ®, 1);
reg&=0xbf;
status &= SetReg(g_CTK202A[bTunerIndex], 0x13, ®, 1);
status &= GetReg(g_CTK202A[bTunerIndex], 0x75, ®, 1);
reg|=0x80;
status &= SetReg(g_CTK202A[bTunerIndex], 0x75, ®, 1);
}
#endif
#endif
#if 1//xyh
acq_contr_2= 0x80;
SetReg(g_CTK202A[bTunerIndex],0x14, &acq_contr_2, 1);
#endif
return status;
}
bool8 GetLockStat(lockstat_t *lockstat,CSHDITunerIndex bTunerIndex)
{
UINT8 regs_read[2];
UINT8 reg_read;
UINT8 i;
bool8 status;
//*lockstat = 0x80;
//return PASS;
status = PASS;
status &= GetReg(g_CTK202A[bTunerIndex],ACQ_CONTROL_REG_2, ®_read, 0x01);
if(status != PASS) return status;
if((reg_read & 0x80) == 0x80)
{
*lockstat = 0x00;
return status;
}
//read lock status reg (2 bytes)
status &= GetReg(g_CTK202A[bTunerIndex],LOCK_STATUS_REG_1, ®_read, 0x02);
if(status != PASS)
return status;
//rotate
//reg_read=0;
// for(i = 0; i < 8; ++i)
// {
// reg_read |= ((regs_read[0]>>i)&0x01)<<(7-i);
//}
/*for(i=0;i<=8;++i)
{
if((regs_read[0]>>i)&0x01)
reg_read |= 0x01<<(8-i);
}*/
*lockstat = (lockstat_t) (( regs_read[0] & 0x7f) | (regs_read[1] & 0x80));
//printf("lock status is %x\r\n",*lockstat );
//symbol rate estimation is not present in rev B, ***Must to note
//if( hDevice.revcode[0]<='B' )
//*lockstat = (lockstat_t)(*lockstat & ~SYM_RATE_EST_DONE);
/*status = GetReg(TUNER_I2C_ADDRESS,ACQ_STATUS_REG,®_read,0x01);
if(status != PASS) return status;
//acquisition failure
if(reg_read >> 7)
{
if( (reg_read ) & 0x01)
status = FSYNC_FAILED;
else if( (reg_read >> 1) & 0x01)
status = VIT_SEARCH_FAILED;
else if( (reg_read >> 2) & 0x01)
status = CAR_SEARCH_FAILED;
else if( (reg_read >> 3) & 0x01)
status = SYM_TIMING_FAILED;
//symbol rate estimation is not present in rev B ***Must to note
else if( ((reg_read >> 4) & 0x01) ) //&& hDevice.revcode[0]>'B')
status = SYM_EST_FAILED;
else if( (reg_read >> 5) & 0x01)
status = CAR_EST_FAILED;
else if( (reg_read >> 6) & 0x01)
status = AGC_FAILED;
}*/
return status;
}
//sets the carrier frequency offset search range.
//int SetCFOSearchRange(int cfo_range_req, int *cfo_range_actual)
bool8 SetCFOSearchRange(cfo_range_t cfo_range,CSHDITunerIndex bTunerIndex)
{
UINT8 cforange;
bool8 status;
status = PASS;
for(cforange = 0; cfo_range > 1 ; cfo_range = (cfo_range_t) (cfo_range >> 1))
cforange++;
//automatic est. step mode
cforange |= 0x08;
status = SetReg(g_CTK202A[bTunerIndex],/*CFO_ESTIMATOR_CONTROL_REG*/CFO_ESTIMATOR_CONTROL_REG_1,&cforange,0x01);
return status;
}
bool8 SetSymSearchRange(int sym_min, int sym_max,CSHDITunerIndex bTunerIndex)
{
//TODO: Fix symbol rate divisor question
//TODO: fix hDevice.fs units
UINT8 maxmin[2];
bool8 status;
//input params are in sps
//todo: this is not yet working in hardware
//MDDS: sym_rate_max(min) = Symbol rate max(min) [in Msps?] * 2^8 / Fs
status = PASS;
#ifdef DLL_VERSION
maxmin[0] = ( sym_max ) * (0x100 / tuner_adc_fs);
maxmin[1] = ( sym_min ) * (0x100 / tuner_adc_fs);
#endif
status = SetReg(g_CTK202A[bTunerIndex],SYMBOL_RATE_ESTIMATOR_MAXIMUM_REG,maxmin,0x02);
return status;
}
//gets the carrier frequency offset error.
bool8 GetCFO(s16 *cfoerror,CSHDITunerIndex bTunerIndex)
{
UINT8 byteL_H[2];
bool8 status;
status = PASS;
status = GetReg(g_CTK202A[bTunerIndex],CFO_ERROR_REG_L,byteL_H,0x02);
*cfoerror = ((byteL_H[1] & 0xff) << 8 ) | byteL_H[0];
//2's complement
if( (*cfoerror & 0x8000 ) >> 15)
*cfoerror |= 0xffff0000;
return status;
}
//sets the carrier frequency offset.
bool8 SetCFO(s16 cfo,CSHDITunerIndex bTunerIndex)
{
UINT8 cfoLH[2];
bool8 status;
status = PASS;
cfoLH[0] = (UINT8) (cfo & 0xFF);
cfoLH[1] = (UINT8) ((cfo >> 8) & 0xFF);
status = SetReg(g_CTK202A[bTunerIndex],CFO_ESTIMATOR_OFFSET_REG_L, cfoLH, 0x02);
return status;
}
bool8 GetChInfo(u32 *freq, u32 *symbrate, coderate_t *coderate,CSHDITunerIndex bTunerIndex)
{
//TODO: *freq
//TODO: find out freq units and how coarse/fine tune relates to freq value
// this alg. will be filled in at a later date
// derive from tuning_testnew1.c
// to be added 03Jan05
UINT8 codereg;
bool8 status;
UINT8 sym_rate_bytes[3];
UINT8 fcoarse;
UINT8 ffine[2];
status = PASS;
status = GetReg(g_CTK202A[bTunerIndex],VITERBI_SEARCH_STATUS_REG,&codereg,0x01);
//if(status != PASS) return status;
codereg >>= 0x05;
*coderate = (coderate_t) (1 << codereg);
status = GetReg(g_CTK202A[bTunerIndex],SYMBOL_RATE_REG_L,sym_rate_bytes,0x03);
*symbrate = (float) ( ( (sym_rate_bytes[0] | ((sym_rate_bytes[1] & 0xff) << 8)
| ((sym_rate_bytes[2] & 0xff) << 16)) )
* tuner_adc_fs / 8388608.0 )*1000000;
//0x800000 = 8388608
status|= GetReg(g_CTK202A[bTunerIndex],FINE_TUNE_REG_L,ffine,0x02);
status|= GetReg(g_CTK202A[bTunerIndex],COARSE_TUNE_REG,&fcoarse,0x01);
//int MHz option:
//*freq = floor( ( (((ffine[0]&0xff)|(ffine[1]&0xff)<<8) ) * tuner_adc_fs)/16384.0 + ((fcoarse&0xff) * 10.0) +.5);
// in KHz:
*freq = floor(1000.0 * ( ( (((ffine[0]&0xff)|(ffine[1]&0xff)<<8) ) * tuner_adc_fs)/16384.0 + ((fcoarse&0xff) * 10.0) +.5));
//0x4000 = 16384
return status;
}
bool8 GetCoderate(coderate_t *coderate,CSHDITunerIndex bTunerIndex)
{
UINT8 codereg;
bool8 status;
status = PASS;
status = GetReg(g_CTK202A[bTunerIndex],VITERBI_SEARCH_STATUS_REG,&codereg,0x01);
//if(status != PASS) return status;
codereg >>= 0x05;
*coderate = (coderate_t) (1 << codereg);
return status;
}
//********************************************************************************
//LNB Messaging
//********************************************************************************
bool8 SetLNBmsg_ToneBurst(lnb_cmd_S lnb_cmd,CSHDITunerIndex bTunerIndex)
{
UINT8 lnb_status;
UINT8 lnb_control_1;
bool8 status;
u8 reg, reg2;
status = PASS;
lnb_control_1 = 0;
/*automatic mode tone burst disable//from enale to diaable*/
status &= GetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_2, ®, 0x01);
reg &= 0x00;
//reg |= 0x04;/*disable toneburst in automatic mode*//*在单步模式下同样能控制TONEBURST,所以删掉*/
reg |= 0x40;/*step by step mode*/
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_2, ®, 0x01);
reg2 = 0x00;/*unmodulated tone*/
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_1, ®2, 0x01); //Reset LNB request
status &= GetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_STATUS_REG,&lnb_status,0x01);
if(status != PASS) return status;
//fill the FIFO
status &= SetReg(g_CTK202A[bTunerIndex],LNB_FIFO_REGS_0, lnb_cmd.lnb_msg, lnb_cmd.lnb_msg_len);
if(status != PASS) return status;
lnb_control_1 |= lnb_cmd.lnb_Vsel << 6;
lnb_control_1 |= lnb_cmd.lnb_cont << 5;
lnb_control_1 |= lnb_cmd.lnb_tburst << 4;
lnb_control_1 |= lnb_cmd.lnb_mmsg << 3;
lnb_control_1 |= lnb_cmd.lnb_msg_len;
lnb_control_1 |= 0x80; /*message start!*/
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_1, &lnb_control_1, 0x01);
return status;
}
//LNB messages are sent with this function
bool8 SetLNBmsg(lnb_cmd_S lnb_cmd,CSHDITunerIndex bTunerIndex)
{
UINT8 lnb_status;
UINT8 lnb_control_1;
bool8 status;
u8 reg, reg2;
status = PASS;
lnb_control_1 = 0;
/*automatic mode tone burst disable//from enale to diaable*/
status &= GetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_2, ®, 0x01);
reg &= 0x00;
reg |= 0x04;
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_2, ®, 0x01);
reg2 = 0x00;/*unmodulated tone*/
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_1, ®2, 0x01); //Reset LNB request
status &= GetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_STATUS_REG,&lnb_status,0x01);
if(status != PASS) return status;
//fill the FIFO
status &= SetReg(g_CTK202A[bTunerIndex],LNB_FIFO_REGS_0, lnb_cmd.lnb_msg, lnb_cmd.lnb_msg_len);
if(status != PASS) return status;
lnb_control_1 |= lnb_cmd.lnb_Vsel << 6;
lnb_control_1 |= lnb_cmd.lnb_cont << 5;
lnb_control_1 |= lnb_cmd.lnb_tburst << 4;
lnb_control_1 |= lnb_cmd.lnb_mmsg << 3;
lnb_control_1 |= lnb_cmd.lnb_msg_len;
lnb_control_1 |= 0x80; /*message start!*/
status &= SetReg(g_CTK202A[bTunerIndex],LNB_CONTROL_REG_1, &lnb_control_1, 0x01);
return status;
}
//Received LNB messages are retrieved with this function
bool8 GetLNBmsg(lnb_reply_S *lnb_reply)
{
UINT8 lnb_status;
bool8 status;
status = PASS;
status = GetReg(TUNER_I2C_ADDRESS,LNB_CONTROL_STATUS_REG,&lnb_status,0x01);
if(status != PASS) return status;
if((lnb_status >> 6) & 0x01) //FIFO full
return RXMSG_DEVICE_NOT_READY;
if( (lnb_status & 0x20) >> 5)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?