📄 drv0370qam.c
字号:
/*----------------------------------------------------------------------------
File Name : drv0370QAM.c
Description : STB0370QAM front-end driver routines.
Copyright (C) 2005-2006 STMicroelectronics
date:
version:
author:
comment:
Revision History:
Reference:
ST API Definition "TUNER Driver API" DVD-API-06
----------------------------------------------------------------------------*/
/* Includes ---------------------------------------------------------------- */
/* C libs */
#include <string.h>
#include <stdlib.h> /* for abs() */
/* STAPI common includes */
#include "stlite.h" /* Standard includes */
#include "stddefs.h"
/* STAPI */
#include "sttuner.h"
#include "sti2c.h"
#include "stcommon.h"
#include "sttbx.h"
#include "stevt.h"
/* local to sttuner */
#include "util.h" /* generic utility functions for sttuner */
#include "dbtypes.h" /* data types for databases */
#include "sysdbase.h" /* functions to accesss system data */
#include "ioarch.h" /* I/O for this driver */
#include "ioreg.h" /* I/O for this driver */
#include "d0370qam.h" /* top level header for this driver */
#include "reg0370qam.h" /* register mappings for the stv0370QAM */
#include "drv0370qam.h" /* header for this file */
/* defines ----------------------------------------------------------------- */
#define STB0370QAM_FAST_SWEEP_SPEED 750
#define STB0370QAM_SLOW_SWEEP_SPEED 400
#define STB0370QAM_SYMBOLRATE_LEVEL 3000000 /* When SR < STV0297J_SYMBOLRATE_LEVEL, Sweep = Sweep/2 */
extern U32 STB0370_DefVal_256QAM_TD1336[STB0370_QAM_NBREGS];
extern U32 STB0370_DefVal_256QAM_DCT7050[STB0370_QAM_NBREGS];
/* private types ----------------------------------------------------------- */
#ifdef ST_OS21
#define WAIT_N_MS_370QAM(X) task_delay( (signed int)(X * (ST_GetClocksPerSecond() / 1000)) ) /*task_delay(X)*/
#else
#define WAIT_N_MS_370QAM(X) task_delay( (unsigned int)(X * (ST_GetClocksPerSecond() / 1000)) ) /*task_delay(X)*/
#endif
/* constants --------------------------------------------------------------- */
/* Current LLA revision */
static ST_Revision_t Revision370QAM = " STB0370QAM-LLA_REL_01.0 ";
U32 POW_370QAM(U32 Number, U32 Power)
{
int i;
long result = 1;
for(i=0;i<Power;i++)
result *= Number;
return (U32)result;
}
const int FE_370QAM_CN_LookUp[80]= {
/*64QAM*/
31778,30778,29778,28778,27778,26778,25778,24778,23778,22778,
21778,20778,19778,18778,17778,16778,15778,14778,13778,12778,
11778,10674,9552,8586,7745,6979,6331,5577,5053,4578,
4184,3773,3461,3188,2942,2741,2559,2405,2309,2176,
/*256QAM*/
37874,36874,35874,34874,33874,32874,31874,30874,29874,28874,
27874,26874,25874,24874,23874,22874,21874,20874,19874,18874,
17874,16874,15874,14874,13874,12874,11874,10874,9866,8950,
8135,7290,6677,6076,5567,5111,4748,4421,4166,3897
};
D0370QAM_SignalStatus_t Driv0370QAMSignalStatus;
/* functions --------------------------------------------------------------- */
/***********************************************************
**FUNCTION :: Drv0370QAM_GetLLARevision
**ACTION :: Returns the 370QAM LLA driver revision
**RETURN :: Revision370QAM
***********************************************************/
ST_Revision_t Drv0370QAM_GetLLARevision(void)
{
return (Revision370QAM);
}
/*----------------------------------------------------
--FUNCTION Drv0370QAM_CarrierWidth
--ACTION Compute the width of the carrier
--PARAMS IN SymbolRate -> Symbol rate of the carrier (Kbauds or Mbauds)
-- RollOff -> Rolloff * 100
--PARAMS OUT NONE
--RETURN Width of the carrier (KHz or MHz)
------------------------------------------------------*/
long Drv0370QAM_CarrierWidth(long SymbolRate, long RollOff)
{
return (SymbolRate + (SymbolRate * RollOff)/100);
}
/*----------------------------------------------------
--FUNCTION Drv0370QAM_CheckAgc
--ACTION Check for Agc
--PARAMS IN Params => Pointer to SEARCHPARAMS structure
--PARAMS OUT Params->State => Result of the check
--RETURN E370QAM_NOAGC carrier not founded, E370QAM_AGCOK otherwise
------------------------------------------------------*/
D0370QAM_SignalType_t Drv0370QAM_CheckAgc(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, D0370QAM_SearchParams_t *Params)
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
const char *identity = "STTUNER drv0370QAM.c Drv0370QAM_CheckAgc()";
#endif
if ( STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0370QAM_WAGC_ACQ) )
{
Params->State = E370QAM_AGCOK;
}
else
{
Params->State = E370QAM_NOAGC;
}
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s\n", identity));
#endif
return(Params->State);
}
/*----------------------------------------------------
FUNCTION Drv0370QAM_CheckData
ACTION Check for data founded
PARAMS IN Params => Pointer to SEARCHPARAMS structure
PARAMS OUT Params->State => Result of the check
RETURN E370QAM_NODATA data not founded, E370QAM_DATAOK otherwise
------------------------------------------------------*/
D0370QAM_SignalType_t Drv0370QAM_CheckData(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, D0370QAM_SearchParams_t *Params)
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
const char *identity = "STTUNER drv0370qam.c Drv0370QAM_CheckData()";
#endif
if ( STTUNER_IOREG_GetField(DeviceMap, IOHandle, F0370QAM_MPEG_LOCK) ) /*Check the actual register use (MPEG_SYNC)??? (MPEG_LOCK--->)It is inverted*/
{
Params->State = E370QAM_NODATA;
}
else
{
Params->State = E370QAM_DATAOK;
}
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s\n", identity));
#endif
return(Params->State);
}
/*----------------------------------------------------
FUNCTION Drv0370QAM_InitSearch
ACTION Set Params fields that are used by the search algorithm
PARAMS IN
PARAMS OUT
RETURN NONE
------------------------------------------------------*/
void Drv0370QAM_InitSearch(STTUNER_tuner_instance_t *TunerInstance, D0370QAM_StateBlock_t *StateBlock,
STTUNER_Modulation_t Modulation, int Frequency, int SymbolRate, STTUNER_Spectrum_t Spectrum,
BOOL ScanExact, STTUNER_J83_t J83)
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
const char *identity = "STTUNER drv0370QAM.c Drv0370QAM_InitSearch()";
#endif
U32 BandWidth;
ST_ErrorCode_t Error;
TUNER_Status_t TunerStatus;
/* Obtain current tuner status */
Error = (TunerInstance->Driver->tuner_GetStatus)(TunerInstance->DrvHandle, &TunerStatus);
/* Select closest bandwidth for tuner */ /* cast to U32 type to match function argument & eliminate compiler warning --SFS */
Error = (TunerInstance->Driver->tuner_SetBandWidth)( TunerInstance->DrvHandle,
(U32)( Drv0370QAM_CarrierWidth(SymbolRate, StateBlock->Params.RollOff) /1000 + 3000),
&BandWidth);
/*
--- Set Parameters
*/
StateBlock->Params.Frequency = Frequency;
StateBlock->Params.SymbolRate = SymbolRate;
StateBlock->Params.TunerBW = (long)BandWidth;
StateBlock->Params.TunerStep = (long)TunerStatus.TunerStep;
StateBlock->Params.TunerIF = (long)TunerStatus.IntermediateFrequency;
StateBlock->Result.SignalType = E370QAM_NOAGC;
StateBlock->Result.Frequency = 0;
StateBlock->Result.SymbolRate = 0;
StateBlock->SpectrumInversion = Spectrum;
StateBlock->Params.Direction = E370QAM_SCANUP;
StateBlock->Params.State = E370QAM_NOAGC;
StateBlock->J83 = STTUNER_J83_B;
StateBlock->Quartz = 27000000; /* 54 (27*2Mhz) MHz quartz check this????*/
if (ScanExact)
{
StateBlock->ScanMode = DEF0370QAM_CHANNEL; /* Subranges are scanned in a zig-zag mode */
}
else
{
StateBlock->ScanMode = DEF0370QAM_SCAN; /* No Subranges */
}
/*
--- Set QAMSize and SweepRate.
--- SweepRate = 1000* (SweepRate (in MHz/s) / Symbol Rate (in MBaud/s))
*/
switch(Modulation)
{
case STTUNER_MOD_16QAM :
case STTUNER_MOD_32QAM :
case STTUNER_MOD_64QAM :
StateBlock->QAMSize = Modulation; /* Set by user */
StateBlock->SweepRate = STB0370QAM_FAST_SWEEP_SPEED;
break;
case STTUNER_MOD_128QAM :
case STTUNER_MOD_256QAM :
StateBlock->QAMSize = Modulation; /* Set by user */
StateBlock->SweepRate = STB0370QAM_SLOW_SWEEP_SPEED;
break;
case STTUNER_MOD_QAM :
default:
StateBlock->QAMSize = STTUNER_MOD_64QAM; /* Most Common Modulation for Scan */
StateBlock->SweepRate = STB0370QAM_FAST_SWEEP_SPEED;
break;
}
/*
--- For low SR, we MUST divide Sweep by 2
*/
if (SymbolRate <= STB0370QAM_SYMBOLRATE_LEVEL)
{
StateBlock->SweepRate /= 2;
}
/*
--- CO
*/
StateBlock->CarrierOffset = DEF0370QAM_CARRIEROFFSET_RATIO * 100; /* in % */
/*
--- Set direction
*/
if ( StateBlock->Params.Direction == E370QAM_SCANUP )
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s ==> SCANUP\n", identity));
#endif
StateBlock->CarrierOffset *= -1;
StateBlock->SweepRate *= 1;
}
else
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s ==> SCANDOWN\n", identity));
#endif
StateBlock->CarrierOffset *= 1;
StateBlock->SweepRate *= -1;
}
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s\n", identity));
#endif
}
/*----------------------------------------------------
FUNCTION Driv0370QAMDemodSetting
ACTION
PARAMS IN NONE
PARAMS OUT NONE
RETURN NONE
------------------------------------------------------*/
void Driv0370QAMDemodSetting(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,
long Offset,int ExtClk,U32 TunerIF)
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
const char *identity = "STTUNER drv0370qam.c Driv0370QAMDemodSetting()";
#endif
long long_tmp;
int int_tmp;
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
STTBX_Print(("%s Offset %d\n", identity, Offset));
#endif
ExtClk/=1000;
long_tmp = TunerIF + Offset - ExtClk ; /* in kHz */
long_tmp *= 512 ;
long_tmp *= 128 ;
long_tmp /= ExtClk;
if(long_tmp > 65535) long_tmp = 65535;
int_tmp = (int)long_tmp;
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F0370QAM_DEM_FREQ_MSB,int_tmp>>8);
STTUNER_IOREG_SetField(DeviceMap,IOHandle,F0370QAM_DEM_FREQ_LSB,int_tmp);
}
/*----------------------------------------------------
FUNCTION Driv0370QAMCNEstimator
ACTION
PARAMS IN NONE
PARAMS OUT NONE
RETURN NONE
------------------------------------------------------*/
void Driv0370QAMCNEstimator(DEMOD_Handle_t Handle,STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle,
int *Mean_p, int *CN_dB100_p, int *CN_Ratio_p)
{
#ifdef STTUNER_DEBUG_MODULE_CABDRV_DRV0370QAM
const char *identity = "STTUNER drv0370qam.c Driv0370QAMCNEstimator()";
#endif
int int_tmp, i;
int idB ;
int iQAM, QAMSize;
int CurrentMean ;
int ComputedMean;
int OldMean;
int Result;
FLAG_370QAM EndOfSearch;
D0370QAM_InstanceData_t *Instance;
/* private driver instance data */
Instance = D0370QAM_GetInstFromHandle(Handle);
QAMSize = Reg0370QAM_GetQAMSize(DeviceMap,IOHandle);
switch (QAMSize)
{
case 64:
iQAM = 0;
break;
case 256:
iQAM = 1;
break;
default:
iQAM = 0;
break;
}
/* the STB0370QAM noise estimation must be filtered. The used filter is :*/
/* Estimation(n) = 63/64*Estimation(n-1) + 1/64*STV0297JNoiseEstimation */
for (i = 0; i < 100; i ++)
{
/*WAIT_N_MS(1);*/ /* 1 ms */
int_tmp = (STTUNER_IOREG_GetField(DeviceMap, IOHandle,F0370QAM_NOISE_EST_MSB)<<8);
int_tmp += STTUNER_IOREG_GetField(DeviceMap, IOHandle,F0370QAM_NOISE_EST_LSB);
Instance->Driv0370QAMCNEstimation = (63*Instance->Driv0370QAMCNEstimation)/64 + int_tmp/64;
}
ComputedMean = Instance->Driv0370QAMCNEstimation - Instance->Driv0370QAMCNEstimatorOffset; /* offset correction if any */
CurrentMean = FE_370QAM_CN_LookUp[iQAM*40] ;
idB = 1;
EndOfSearch = NO;
while (EndOfSearch == NO)
{
OldMean = CurrentMean;
CurrentMean = FE_370QAM_CN_LookUp[iQAM*40+idB];
if ((CurrentMean <= ComputedMean)||(idB >= 39))
EndOfSearch = YES;
else
idB += 1;
}
/* An interpolation is performed in order to increase the result accuracy */
/* Typically, 0.3 dB accuracy is reached. */
Result = 100*idB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -