MS_U16 DTV_GetSignalStrength(void)
{
MS_U8 status = true;
MS_U16 u16Strength;
MS_U8 reg_tmp, reg_frz;
MS_U8 rf_agc_val;
MS_U8 if_agc_val;
MS_U8 if_agc_err;
MS_U8 i;
MS_U8 ssi_tbl_len;
MS_U8 err_tbl_len;
MS_U8 tps_cnstl;
MS_U8 tps_cr;
MS_FLOAT ch_power_db;
MS_FLOAT ch_power_rf=0;
MS_FLOAT ch_power_if=0;
MS_FLOAT ch_power_ref=0;
MS_FLOAT ch_power_rel;
S_IFAGC_SSI *ifagc_ssi;
S_IFAGC_ERR *ifagc_err;
DBG_DOMOD_MSB(HB_printf("Get DVB-T signal strength\n"));
if(FECLock == TRUE)
{
status &= ReadReg(0x8512+1, ®_tmp);
DBG_DOMOD_MSB(HB_printf("AGC_REF = %d\n", (int)reg_tmp));
if (reg_tmp > 200)
{
ifagc_ssi = IfagcSsi_HiRef;
ssi_tbl_len = sizeof(IfagcSsi_HiRef)/sizeof(S_IFAGC_SSI);
ifagc_err = IfagcErr_HiRef;
err_tbl_len = sizeof(IfagcErr_HiRef)/sizeof(S_IFAGC_ERR);
}
else
{
ifagc_ssi = IfagcSsi_LoRef;
ssi_tbl_len = sizeof(IfagcSsi_LoRef)/sizeof(S_IFAGC_SSI);
ifagc_err = IfagcErr_LoRef;
err_tbl_len = sizeof(IfagcErr_LoRef)/sizeof(S_IFAGC_ERR);
}
/ RF/IF-AGC Gain Out /
#if 0 // Sidney
//rf_agc_val = MDrv_ReadByte(0x3A1C);
rf_agc_val=MDrv_SAR_Adc_GetValue(2);
#else
rf_agc_val=0x3F;
#endif
WriteReg(0x8522, 0x03); // select IF gain to read
WriteReg(0x8504+1, 0x03); // hold values of 0x8524 and 0x8525
status &= ReadReg(0x8524+1, ®_tmp);
WriteReg(0x8504+1, 0x00); // release values of 0x8524 and 0x8525
if_agc_val = reg_tmp;
DBG_DOMOD_MSB(HB_printf("SSI_RFAGC (SAR-2) = 0x%x\n", rf_agc_val));
DBG_DOMOD_MSB(HB_printf("SSI_IFAGC_H = 0x%x\n", if_agc_val));
for(i = 0; i < sizeof(RfagcSsi)/sizeof(S_RFAGC_SSI); i++)
{
if (rf_agc_val <= RfagcSsi[i].sar3_val)
{
ch_power_rf = RfagcSsi[i].power_db;
break;
}
}
for(i = 0; i < ssi_tbl_len; i++)
{
if (if_agc_val <= ifagc_ssi[i].agc_val)
{
ch_power_if = ifagc_ssi[i].power_db;
break;
}
}
DBG_DOMOD_MSB(HB_printf("ch_power_rf = %f\n", ch_power_rf));
DBG_DOMOD_MSB(HB_printf("ch_power_if = %f\n", ch_power_if));
ch_power_db = (ch_power_rf > ch_power_if)? ch_power_rf : ch_power_if;
/ IF-AGC Error for Add. Attnuation /
// bank 5 0x04 [15] reg_tdp_lat
status &= ReadReg(0x8504+1, ®_frz);
status &= WriteReg(0x8504+1, reg_frz|0x80);
// bank 5 0x2c [9:0] reg_agc_error
status &= ReadReg(0x852C+1, ®_tmp);
if_agc_err = reg_tmp & 0x03;
status &= ReadReg(0x852C, ®_tmp);
if_agc_err = (if_agc_err << 6)|(reg_tmp >> 2);
status &= WriteReg(0x8504+1, reg_frz&(~0x80));
for(i = 0; i < err_tbl_len; i++)
{
if ((MS_S8)if_agc_err <= ifagc_err[i].agc_err) // signed char comparison
{
ch_power_db += ifagc_err[i].attn_db;
break;
}
}
DBG_DOMOD_MSB(HB_printf("if_agc_err = 0x%x\n", if_agc_err));
}
else
{
ch_power_db = -99.0;
}
DBG_DOMOD_MSB(HB_printf(">>> SSI_CH_PWR(dB) = %f <<<\n", ch_power_db));
/ Get Constellation and Code Rate to determine Ref. Power //
/ (refer to Teracom min. spec 2.0 4.1.1.6) /
status &= ReadReg(0x8624, ®_tmp);
tps_cnstl = reg_tmp & 0x03;
status &= ReadReg(0x8624+1, ®_tmp);
tps_cr = (reg_tmp & 0x70) >> 4;
for(i = 0; i < sizeof(SsiPref)/sizeof(S_SSI_PREF); i++)
{
if ( (tps_cnstl == SsiPref[i].constel)
&& (tps_cr == SsiPref[i].code_rate) )
{
ch_power_ref = SsiPref[i].p_ref;
break;
}
}
ch_power_rel = ch_power_db - ch_power_ref;
if (ch_power_rel < -15.0)
u16Strength = 0;
else if (ch_power_rel < 0.0)
u16Strength = (MS_U16)((ch_power_rel + 15.0)*(10.0/15.0));
else if (ch_power_rel < 20.0)
u16Strength = (MS_U16)(ch_power_rel*4.0 + 10.0);
else if (ch_power_rel < 35.0)
u16Strength = (MS_U16)((ch_power_rel - 20.0)*(10.0/15.0) + 90.0);
else
u16Strength = 100;
DBG_DOMOD_MSB(HB_printf(">>> SSI = %d <<<\n", (int)u16Strength));
if (status == true)
return u16Strength;
else
return 0;
}