?? driv0299.c
字號:
/* **************************************************************************************
* Copyright (c) 2004 ZORAN Corporation, All Rights Reserved
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
*
* File: $Workfile: .c $
*
* Description:
* ============
* DECLARATIONS FOR THE STV0299 DRIVER
*
* Log:
* ====
* $Revision: $
* Last Modified by $Author: $ at $Modtime: $
**************************************************************************************** */
#include "Config.h" // Global Configuration - do not remove!
#ifdef FTA_SUPPORT
#ifdef SATELLITE_299
#include "Include\SysDefs.h"
#include "devices\demodulator\0299\def.h"
#include "Kernel\Ker_API.h"
#include "Playcore\Exception\Exception.h"
#include "devices\demodulator\0299\reg0299.h"
#include "devices\demodulator\0299\tun0299.h"
#include "devices\demodulator\0299\driv0299.h"
#include "devices\demodulator\0299\0229.h"
#include "Services\Include\_heap.h"
#include "Kernel\EventDef.h"
static int lnbGTfreq;
extern BOOL bAutoScanStarted;
static UINT32 LO_FILTER(UINT32 freq, UINT32 lnb)
{
if (lnb > freq)
{
lnbGTfreq = 1;
freq = lnb-freq;
}
else
{
lnbGTfreq = 0;
freq = freq-lnb;
}
return freq;
}
/*****************************************************
--FUNCTION :: WaitTuner
--ACTION :: Wait for tuner locked
--PARAMS IN :: TimeOut -> Maximum waiting time (in ms)
--PARAMS OUT:: NONE
--RETURN :: NONE
--***************************************************/
void WaitTuner(DEMOD_HANDLE handle, INT32 TimeOut)
{
INT32 Time=0;
INT32 TunerLocked = FALSE;
while(!TunerLocked && (Time<TimeOut))
{
Ker_SleepUs(1000UL);
TunerLocked = TunerGetTunerLock(handle);
Time++;
}
Time--;
}
/****************************************************
--FUNCTION :: CheckAgc1
--ACTION :: Check agc1 value
--PARAMS IN :: pParams -> Pointer to SEARCHPARAMS structure
--PARAMS OUT:: pParams->State is modified
--RETURN :: NOAGC1 if AGC1=-128, AGC1SATURATION
-- if AGC1=127, AGC1OK otherwise
--**************************************************/
SIGNALTYPE CheckAgc1(DEMOD_HANDLE handle, SEARCHPARAMS *pParams)
{
INT32 AGC1Value;
INT32 Agc1Threshold = -128;
AGC1Value = RegGetField(handle,AGCINTEGRATORVALUE);
if (AGC1Value == Agc1Threshold)
{
pParams->State = NOAGC1;
}
else if (AGC1Value == 127)
{
pParams->State = AGC1SATURATION;
}
else
{
pParams->State = AGC1OK;
}
return pParams->State;
}
/*****************************************************
--FUNCTION :: CheckTiming
--ACTION :: Check for timing locked
--PARAMS IN :: pParams->Ttiming => Time to wait for timing loop locked
--PARAMS OUT:: pParams->State => result of the check
--RETURN :: NOTIMING if timing not locked, TIMINGOK otherwise
--***************************************************/
SIGNALTYPE CheckTiming(DEMOD_HANDLE handle, SEARCHPARAMS *pParams)
{
INT32 locked, timing;
Ker_SleepUs(pParams->Ttiming * 1000UL);
locked=RegGetField(handle,TLIR);
timing=abs(RegGetField(handle,RTF));
if (locked >= 43)
{
if ((locked > 48) && (timing >= 110))
{
pParams->State = ANALOGCARRIER;
}
else
{
pParams->State = TIMINGOK;
}
}
else
{
pParams->State = NOTIMING;
}
return pParams->State;
}
/*****************************************************
--FUNCTION :: CheckCarrier
--ACTION :: Check for carrier founded
--PARAMS IN :: pParams => Pointer to SEARCHPARAMS structure
--PARAMS OUT:: pParams->State => Result of the check
--RETURN :: NOCARRIER carrier not founded, CARRIEROK otherwise
--***************************************************/
SIGNALTYPE CheckCarrier(DEMOD_HANDLE handle, SEARCHPARAMS *pParams)
{
Ker_SleepUs(pParams->Tderot * 1000UL);
RegSetField(handle, CFD_ALGO, 0);
if (RegGetField(handle, CF))
{
pParams->State = CARRIEROK;
}
else
{
pParams->State = NOCARRIER;
}
return pParams->State;
}
/****************************************************
--FUNCTION :: GetPacketErrors
--ACTION :: Set error counter in packet error mode and check for packet errors
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: Content of error count
--**************************************************/
INT32 GetPacketErrors(DEMOD_HANDLE handle)
{
INT32 PacketErrors, i;
unsigned char CounterMode;
CounterMode = RegGetOneRegister(handle, R_ERRCNT); /* Save error counter mode */
RegSetOneRegister(handle,R_ERRCNT, 0x30); /* Error counter in Rate mode, packet error, count period 2^12 */
Ker_SleepUs(1000UL * 4UL);
for (i=0; i<2; i++) /* Do not remove the for loop : bug work around */
PacketErrors = RegGetErrorCount(handle); /* Error counter must be read twice before returning valid value */
RegSetOneRegister(handle,R_ERRCNT,CounterMode); /* restore error counter mode */
tr_printf(("Errors - %d\n", PacketErrors));
return PacketErrors;
}
/*****************************************************
--FUNCTION :: CheckData
--ACTION :: Check for data founded
--PARAMS IN :: pParams => Pointer to SEARCHPARAMS structure
--PARAMS OUT:: pParams->State => Result of the check
--RETURN :: NODATA data not founded, DATAOK otherwise
--***************************************************/
SIGNALTYPE CheckData(DEMOD_HANDLE handle, SEARCHPARAMS *pParams)
{
INT32 lock;
pParams->State = NODATA;
Ker_SleepUs(1000UL * pParams->Tdata); /* Wait for data */
lock = RegGetField(handle, LK); /* Read DATA LOCK indicator */
//tr_printf(("DEMOD is %sLocked\n", (lock) ? "" : "NOT "));
if (RegGetField(handle, FECMODE) != 0x04) /* Read FEC mode */
{
/* DVB Mode, Test DATA LOCK indicator */
if (lock)
{
pParams->State = DATAOK;
}
}
else
{
/* DSS Mode */
if (lock && GetPacketErrors(handle) <= 10)
{
/* Test DATA LOCK and Packet errors */
pParams->State = DATAOK;
}
}
return pParams->State;
}
/*****************************************************
--FUNCTION :: IQInvertion
--ACTION :: Invert I and Q
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: NONE
--***************************************************/
void IQInvertion(DEMOD_HANDLE handle)
{
if (RegGetField(handle,IQ) == 0)
{
RegSetField(handle, IQ, 1);
}
else
{
RegSetField(handle, IQ, 0);
}
}
/*****************************************************
--FUNCTION :: CalcTimingTimeConstant
--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 CalcTimingTimeConstant(long SymbolRate)
{
return (200000L/(SymbolRate/1000L));
}
/*****************************************************
--FUNCTION :: CalcDerotTimeConstant
--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 CalcDerotTimeConstant(long SymbolRate)
{
return (10000L/(SymbolRate/1000L));
}
/*****************************************************
--FUNCTION :: CalcDataTimeConstant
--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
--***************************************************/
UINT32 CalcDataTimeConstant(DEMOD_HANDLE handle, UINT8 Er, UINT8 Sn,UINT8 To,UINT8 Hy,UINT32 SymbolRate)
{
UINT8 PhaseNumberDVB[5] = {2,6,4,6,8};
UINT8 PhaseNumberDSS[5] = {2,6,4,6,14};
UINT32 averaging[4] = {1024L,4096L,16384L,65536L};
UINT16 InnerCode = 1000;
UINT16 HigherRate = 1000;
UINT32 Tviterbi = 0;
UINT32 TimeOut =0;
UINT32 THysteresis = 0;
int i,DSS_Mode;
/* =======================================================================
-- 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. */
DSS_Mode = (RegGetField(handle,FECMODE) == 0x04);
for (i=0; i<5; i++)
{
if (((Er >> 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 7/8(DVB) 6/7(DSS) */
if (!DSS_Mode)
{
InnerCode = 1143; /* 1.143 */
}
else
{
InnerCode = 1167; /* 1.167 */
}
break;
}
if (!DSS_Mode)
{
Tviterbi +=(UINT32)((PhaseNumberDVB[i]*averaging[Sn]*InnerCode)/SymbolRate);
}
else
{
Tviterbi +=(UINT32)((PhaseNumberDSS[i]*averaging[Sn]*InnerCode)/SymbolRate);
}
if (HigherRate < InnerCode)
{
HigherRate = InnerCode;
}
}
}
/* Time out calculation (TimeOut)
* This value indicates the maximum duration of the synchro word research.
*/
TimeOut = (UINT32)((HigherRate * 16384L * (To + 1))/(2*SymbolRate));
/* Hysteresis duration */
THysteresis = (UINT32)((HigherRate * 26112L * (Hy +1))/(2*SymbolRate)); /* 26112 = 16*204*8 bits */
/* a guard time of 1 mS is added */
return (1 + Tviterbi + TimeOut + THysteresis);
}
/*****************************************************
--FUNCTION :: 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 CarrierWidth(long SymbolRate, long RollOff)
{
return (SymbolRate + (SymbolRate*RollOff)/100);
}
/*****************************************************
--FUNCTION :: InitParams
--ACTION :: Set Params fields that are never changed during search algorithm
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: NONE
--***************************************************/
void InitParams(DEMOD_HANDLE handle)
{
DEMOD_SAT_DATA *sDemodData = (DEMOD_SAT_DATA*)handle;
INT32 stdby, dirclk, k, m, p, m1, betaagc1, agc2coef;
long MasterClock;
/* Read registers (in burst mode) */
RegGetRegisters(handle, R_RCR, 2); /* Read RCR and MCR registers */
RegGetOneRegister(handle, R_AGC1C);
RegGetRegisters(handle, R_AGC1R, 2); /* Read AGC1R and AGC2O registers */
/* Get fields values */
stdby = FieldGetVal(handle, STDBY);
dirclk = FieldGetVal(handle, DIRCLK);
k = FieldGetVal(handle, K);
m = FieldGetVal(handle, M);
p = FieldGetVal(handle, P);
m1 = FieldGetVal(handle, AGC1_REF);
betaagc1 = FieldGetVal(handle, BETA_AGC1);
agc2coef = FieldGetVal(handle, AGC2COEF);
/* Initial calculations */
MasterClock = CalcMasterClkFrequency(handle,stdby,dirclk,k,m,p);
sDemodData->Params.Tagc1 = CalcAGC1TimeConstant(m1,MasterClock,betaagc1)/20L;
sDemodData->Params.Tagc2 = CalcAGC2TimeConstant(agc2coef,m1,MasterClock)/1000000L;
sDemodData->Params.MasterClock = MasterClock;
sDemodData->Params.Mclk = MasterClock/65536L;
sDemodData->Params.RollOff = RegGetRollOff(handle);
}
/*****************************************************
--FUNCTION :: InitSearch
--ACTION :: Set Params fields that are used by the search algorithm
--PARAMS IN :: Frequency => Frequency used to start zig zag
-- SymbolRate => searched symbol rate
-- SearchRange => Range of the search
-- DerotStep => Size of derotator's steps used in the carrier search (in per thousand of symbol frequency)
-- Mode => Search context (SCAN or SEARCH)
--PARAMS OUT:: NONE
--RETURN :: NONE
--***************************************************/
void InitSearch(DEMOD_HANDLE handle, INT32 Frequency, long SymbolRate, long SearchRange, INT32 DerotStep,SCANMODE Mode)
{
DEMOD_SAT_DATA *sDemodData = (DEMOD_SAT_DATA*)handle;
TUNER_PROP Tnr;
sDemodData->Params.BaseFreq = Frequency;
sDemodData->Params.SymbolRate = SymbolRate;
sDemodData->Params.SearchRange = SearchRange;
sDemodData->Params.DerotPercent = DerotStep;
TunerGetProperties(&Tnr);
sDemodData->Params.TunerStep = Tnr.StepSize;
sDemodData->Params.TunerBW = TunerSelectBandwidth(CarrierWidth(SymbolRate,sDemodData->Params.RollOff)/1000 + 3000)*1000;
sDemodData->Params.TunerIF = Tnr.IF;
sDemodData->Params.TunerIQ = Tnr.I_Q;
sDemodData->Params.ScanMode = Mode;
sDemodData->Result.SignalType = NOAGC1;
sDemodData->Result.Frequency = 0;
sDemodData->Result.SymbolRate = 0;
}
/*****************************************************
--FUNCTION :: SearchTiming
--ACTION :: Perform an Fs/2 zig zag to found timing
--PARAMS IN :: NONE
--PARAMS OUT:: NONE
--RETURN :: NOTIMING if no valid timing had been found, TIMINGOK otherwise
--***************************************************/
SIGNALTYPE SearchTiming(DEMOD_HANDLE handle, SEARCHPARAMS *pParams, SEARCHRESULT *pResult)
{
long DerotFreq = 0L;
long DerotLimit;
long NextDerotStep = 3L;
long DerotStep;
long index = 0;
/* timing loop computation & symbol rate optimisation */
DerotLimit = (pParams->SubRange/2L)/pParams->Mclk;
DerotStep = (pParams->SymbolRate/2L)/pParams->Mclk;
pParams->State = NOTIMING;
do
{
if (CheckTiming(handle, pParams) == NOTIMING)
{
index++;
DerotFreq += index*pParams->Direction*pParams->TunerIQ*DerotStep; /* Compute the next derotator position for the zig zag */
if (ABS(DerotFreq) > DerotLimit)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -