📄 drv399e.c
字号:
--ACTION :: Check for carrier founded
--PARAMS IN :: pParams => Pointer to FE_399_InternalParams_t structure
--PARAMS OUT:: pParams->State => Result of the check
--RETURN :: NOCARRIER_399E carrier not founded, CARRIEROK_399E otherwise
--***************************************************/
FE_399_SIGNALTYPE_t FE_399_CheckCarrier(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_InternalParams_t *pParams)
{
#ifndef STTUNER_MINIDRIVER /* wait for derotator ok */
pParams->State = NOCARRIER_399E;
WAIT_N_MS_399(pParams->Tderot);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_CFD_ON,0);
if (STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_CF))
pParams->State = CARRIEROK_399E;
else
pParams->State = NOCARRIER_399E;
#endif
#ifdef STTUNER_MINIDRIVER /* wait for derotator ok */
U8 Data;
pParams->State = NOCARRIER_399E;
WAIT_N_MS_399(pParams->Tderot);
Data = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_CFD, F399_CFD_ON, F399_CFD_ON_L, &Data, 1, FALSE);
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_VSTATUS, F399_CF, F399_CF_L, &Data, 1, FALSE);
if (Data)
pParams->State = CARRIEROK_399E;
else
pParams->State = NOCARRIER_399E;
#endif
return pParams->State;
}
#ifndef STTUNER_MINIDRIVER
U32 FE_399_GetErrorCount(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_ERRORCOUNTER_t Counter)
{
U32 lsb,msb;
if(Counter == COUNTER1)
{
lsb = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_ERROR_COUNT_LSB);
msb = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_ERROR_COUNT_MSB);
}
else
{
lsb = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_ERROR_COUNT2_LSB);
msb = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_ERROR_COUNT2_MSB);
}
return (MAKEWORD(msb,lsb));
}
#endif
#ifdef STTUNER_MINIDRIVER
U32 FE_399_GetErrorCount(FE_399_ERRORCOUNTER_t Counter)
{
U8 Data;
U32 lsb,msb;
if(Counter == COUNTER1)
{
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_ECNTL, F399_ERROR_COUNT_LSB, F399_ERROR_COUNT_LSB_L, &Data, 1, FALSE);
lsb = Data;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_ECNTM, F399_ERROR_COUNT_MSB, F399_ERROR_COUNT_MSB_L, &Data, 1, FALSE);
msb = Data;
}
else
{
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_ECNTL2, F399_ERROR_COUNT2_LSB, F399_ERROR_COUNT2_LSB_L, &Data, 1, FALSE);
lsb = Data;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_ECNTM2, F399_ERROR_COUNT2_MSB, F399_ERROR_COUNT2_LSB_L, &Data, 1, FALSE);
msb = Data;
}
return (MAKEWORD(msb,lsb));
}
#endif
/****************************************************
--FUNCTION :: FE_399_GetPacketErrors
--ACTION :: Set error counter 2 in packet error mode and check for packet errors
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: Content of error count
--**************************************************/
#ifndef STTUNER_MINIDRIVER
int FE_399_GetPacketErrors(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
int PacketErrors,i;
unsigned char CounterMode;
CounterMode = STTUNER_IOREG_GetRegister(DeviceMap,IOHandle,R399_ERRCTRL2); /* Save error counter mode */
STTUNER_IOREG_SetRegister(DeviceMap,IOHandle,R399_ERRCTRL2,0x30); /* Error counter in Rate mode, packet error, count period 2^12 */
WAIT_N_MS_399(4);
for(i=0;i<2;i++) /* Do not remove the for loop : bug work around */
PacketErrors = FE_399_GetErrorCount(DeviceMap,IOHandle,COUNTER2); /* Error counter must be read twice before returning valid value */
STTUNER_IOREG_SetRegister(DeviceMap,IOHandle,R399_ERRCTRL2,CounterMode); /* restore error counter mode */
return PacketErrors;
}
#endif
#ifdef STTUNER_MINIDRIVER
int FE_399_GetPacketErrors( )
{
int PacketErrors,i;
U8 Data;
unsigned char CounterMode;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_ERRCTRL2, 0, 0, &Data, 1, FALSE);
CounterMode = (unsigned char)Data;
Data = 0x30;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_ERRCTRL2, 0, 0, &Data, 1, FALSE);
WAIT_N_MS_399(4);
for(i=0;i<2;i++)/* Do not remove the for loop : bug work around */
PacketErrors = FE_399_GetErrorCount(COUNTER2);/*Errorcounter must be read twice before returning valid value */
Data = CounterMode;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_ERRCTRL2, 0, 0, &Data, 1, FALSE);
return PacketErrors;
}
#endif
/*****************************************************
--FUNCTION :: FE_399_CheckData
--ACTION :: Check for data founded
--PARAMS IN :: pParams => Pointer to FE_399_InternalParams_t structure
--PARAMS OUT:: pParams->State => Result of the check
--RETURN :: NODATA_399E data not founded, DATAOK_399E otherwise
--***************************************************/
FE_399_SIGNALTYPE_t FE_399_CheckData(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_InternalParams_t *pParams)
{
int lock =0,i;
#ifndef STTUNER_MINIDRIVER
pParams->State = NODATA_399E;
for(i=0;i<20;i++)
{
lock = STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_LK); /* Read DATA LOCK indicator */
if(lock)
break;
else
WAIT_N_MS_399(1);
}
if(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_FECMODE) != 0x04) /* Read FEC mode */
{
/* DVB Mode */
if(lock) /* Test DATA LOCK indicator */
pParams->State = DATAOK_399E;
}
else
{
/* DSS Mode */
if(lock && FE_399_GetPacketErrors(DeviceMap,IOHandle) <= 10) /* Test DATA LOCK and Packet errors */
pParams->State = DATAOK_399E;
}
#endif
#ifdef STTUNER_MINIDRIVER
U8 Data;
pParams->State = NODATA_399E;
for(i=0;i<20;i++)
{
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_VSTATUS, F399_LK, F399_LK_L, &Data, 1, FALSE);
lock = Data;
if(lock)
break;
else
WAIT_N_MS_399(1);
}
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_FECM, F399_FECMODE, F399_FECMODE_L, &Data, 1, FALSE);
if(Data != 0x04) /* Read FEC mode */
{
/* DVB Mode */
if(lock) /* Test DATA LOCK indicator */
pParams->State = DATAOK_399E;
}
else
{
/* DSS Mode */
if(lock && FE_399_GetPacketErrors( ) <= 10) /* Test DATA LOCK and Packet errors */
pParams->State = DATAOK_399E;
}
#endif
return pParams->State;
}
/*****************************************************
--FUNCTION :: FE_399_IQInvertion
--ACTION :: Invert I and Q
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: NONE
--***************************************************/
void FE_399_IQInvertion(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,FE_399_InternalParams_t *pParams)
{
#ifndef STTUNER_MINIDRIVER
if(STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_SYM)==0)
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_SYM,1);
else
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F399_SYM,0);
#endif
#ifdef STTUNER_MINIDRIVER
U8 Data;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_FECM, F399_SYM, F399_SYM_L, &Data, 1, FALSE);
if(Data==0)
{Data = 1;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_FECM, F399_SYM, F399_SYM_L, &Data, 1, FALSE);}
else
{Data = 0;
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_WRITE, R399_FECM, F399_SYM, F399_SYM_L, &Data, 1, FALSE);}
#endif
}
/*****************************************************
--FUNCTION :: FE_399_TimingTimeConstant
--ACTION :: Compute the amount of time needed by the timing loop to lock
--PARAMS IN :: SymbolRate -> symbol rate value
--PARAMS OUT:: NONE
--RETURN :: Timing loop time constant (ms)
--***************************************************/
long FE_399_TimingTimeConstant(long SymbolRate)
{
if(SymbolRate > 0)
return (100000/(SymbolRate/1000));
else
return 0;
}
/*****************************************************
--FUNCTION :: FE_399_DerotTimeConstant
--ACTION :: Compute the amount of time needed by the Derotator to lock
--PARAMS IN :: SymbolRate -> symbol rate value
--PARAMS OUT:: NONE
--RETURN :: Derotator time constant (ms)
--***************************************************/
long FE_399_DerotTimeConstant(long SymbolRate)
{
if(SymbolRate > 0)
return (10000/(SymbolRate/1000));
else
return 0;
}
/*****************************************************
--FUNCTION :: FE_399_DataTimeConstant
--ACTION :: Compute the amount of time needed to capture data
--PARAMS IN :: Er -> Viterbi rror rate
-- Sn -> viterbi averaging period
-- To -> viterbi time out
-- Hy -> viterbi hysteresis
-- SymbolRate -> symbol rate value
--PARAMS OUT:: NONE
--RETURN :: Data time constant
--***************************************************/
long FE_399_DataTimeConstant(int Pr, int Sn,int To,int Hy,long SymbolRate)
{
U32 Tviterbi = 0,
TimeOut = 0,
THysteresis = 0,
Tdata = 0,
PhaseNumber[6] = {2,6,4,6,14,8},
averaging[4] = {1024,4096,16384,65536},
InnerCode = 1000,
HigherRate = 1000;
U32 i;
/*=======================================================================
-- Data capture time (in ms)
-- -------------------------
-- This time is due to the Viterbi synchronisation.
--
-- For each authorized inner code, the Viterbi search time is calculated,
-- and the results are cumulated in ViterbiSearch.
-- InnerCode is multiplied by 1000 in order to obtain timings in ms
=======================================================================*/
for(i=0;i<6;i++)
{
if (((Pr >> i)& 0x01) == 0x01)
{
switch(i)
{
case 0: /* inner code 1/2 */
InnerCode = 2000; /* 2.0 */
break;
case 1: /* inner code 2/3 */
InnerCode = 1500; /* 1.5 */
break;
case 2: /* inner code 3/4 */
InnerCode = 1333; /* 1.333 */
break;
case 3: /* inner code 5/6 */
InnerCode = 1200; /* 1.2 */
break;
case 4: /* inner code 6/7 */
InnerCode = 1167; /* 1.667 */
break;
case 5: /* inner code 7/8 */
InnerCode = 1143; /* 1.143 */
break;
}
Tviterbi += (2*PhaseNumber[i]*averaging[Sn]*InnerCode);
if(HigherRate < InnerCode)
HigherRate = InnerCode;
}
}
/* Time out calculation (TimeOut)
-- ------------------------------
-- This value indicates the maximum duration of the synchro word research. */
TimeOut = (U32)(HigherRate * 16384L * (1L<<To)); /* 16384= 16x1024 bits */
/* Hysteresis duration (Hysteresis)
-- ------------------------------ */
THysteresis = (U32)(HigherRate * 26112L * (1L<<Hy)); /* 26112= 16x204x8 bits */
Tdata =((Tviterbi + TimeOut + THysteresis) / (2*(U32)SymbolRate));
/* a guard time of 1 mS is added */
return (1L + (long)Tdata);
}
#ifndef STTUNER_MINIDRIVER
/****************************************************
**FUNCTION :: FE_399_GetRollOff
**ACTION :: Read the rolloff value
**PARAMS IN :: hChip ==> Handle for the chip
**PARAMS OUT:: NONE
**RETURN :: rolloff
*****************************************************/
int FE_399_GetRollOff(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
if (STTUNER_IOREG_GetField(DeviceMap,IOHandle,F399_MODE_COEF) == 1)
return 20;
else
return 35;
}
/****************************************************
**FUNCTION :: FE_399_Trigger
**ACTION :: Set trigger state
**PARAMS IN :: hChip ==> Handle for the chip
** State ==> 0 / 1
**PARAMS OUT:: NONE
*****************************************************/
void FE_399_Trigger(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,BOOL State)
{
}
#endif
/*****************************************************
**FUNCTION :: FE_399_CalcDerotFreq
**ACTION :: Compute Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
S32 FE_399_CalcDerotFreq(U8 derotmsb,U8 derotlsb,U32 fm)
{
S32 dfreq;
S32 Itmp;
Itmp = (S16)(derotmsb<<8)+derotlsb;
dfreq = (S32)(Itmp*(fm/10000L));
dfreq = (S32)(dfreq / 65536L);
dfreq *= 10;
return dfreq;
}
/*****************************************************
**FUNCTION :: FE_399_GetDerotFreq
**ACTION :: Read current Derotator frequency
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
#ifndef STTUNER_MINIDRIVER
S32 FE_399_GetDerotFreq(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,U32 MasterClock)
{
U8 temp[2];
/* Read registers */
STTUNER_IOREG_GetContigousRegisters(DeviceMap,IOHandle,R399_CFRM,2,temp);
return FE_399_CalcDerotFreq(temp[0],temp[1],MasterClock);
}
#endif
#ifdef STTUNER_MINIDRIVER
S32 FE_399_GetDerotFreq(U32 MasterClock)
{
U8 nsbuffer[2];
/* Read registers */
STTUNER_IODIRECT_ReadWrite(STTUNER_IO_SA_READ, R399_CFRM, 0, 0, nsbuffer, 2, FALSE);
return FE_399_CalcDerotFreq(nsbuffer[0],nsbuffer[1],MasterClock);
}
#endif
/*****************************************************
**FUNCTION :: FE_399_BinaryFloatDiv
**ACTION :: float division (with integer)
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: Derotator frequency (KHz)
*****************************************************/
long FE_399_BinaryFloatDiv(long n1, long n2, int precision)
{
int i=0;
long result=0;
/* division de N1 par N2 avec N1<N2 */
while(i<=precision) /* n1>0 */
{
if(n1<n2)
{
result*=2;
n1*=2;
}
else
{
result=result*2+1;
n1=(n1-n2)*2;
}
i++;
}
return result;
}
/*****************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -