📄 clkrvfilter.c
字号:
/****************************************************************************
File Name : clkrvfilter.c
Description : Clock Recovery API Routines
Copyright (C) 2006, STMicroelectronics
Revision History :
[...]
References :
$ClearCase (VOB: stclkrv)S
stclkrv.fm "Clock Recovery API" Reference DVD-API-072 Revision 5.0
****************************************************************************/
/* Includes --------------------------------------------------------------- */
#if defined(ST_OS20) || defined(ST_OS21) /* linux changes */
#include <string.h>
#include <stdlib.h>
#include "stlite.h" /* MUST be included BEFORE stpti.h */
#include "stsys.h"
#include "sttbx.h"
#include "stdevice.h"
#endif
#include "stevt.h"
#include "stclkrv.h"
#include "clkrvdat.h"
#include "clkrvreg.h"
/* Private Constants ------------------------------------------------------ */
/* Clock recovery Filter & drift correction of slaves clocks Debug Array */
#ifdef CLKRV_FILTERDEBUG
#define CLKRV_MAX_SAMPLES 5000
U32 ClkrvDbg[13][CLKRV_MAX_SAMPLES];
U32 Clkrv_Slave_Dbg[5][CLKRV_MAX_SAMPLES];
U32 SampleCount = 0;
U32 ClkrvCounters[6];
#endif
#ifdef WA_GNBvd44290
static U32 Count_PCM = 0;
static U32 Count_PixelHD = 0;
void stclkrv_GNBvd44290_ResetClkrvTracking(void);
#endif /* WA_GNBvd44290 */
/* Nominal Frequency Table */
/* First Frequency is SD/STC frequency */
#if defined (ST_5100) || defined (ST_5105) ||defined (ST_5301) || defined (ST_5107)|| \
defined (ST_7710)
#define CLKRV_CRYSTAL_27MHZ 1
#define CLKRV_CRYSTAL_30MHZ 0
#elif defined (ST_5188) || defined (ST_5525)
#define CLKRV_CRYSTAL_27MHZ 0
#define CLKRV_CRYSTAL_30MHZ 1
#endif
#if defined (ST_7100) || defined (ST_7109)
#if (STCLKRV_EXT_CLK_MHZ == 30)
#define CLKRV_CRYSTAL_30MHZ 1
#elif (STCLKRV_EXT_CLK_MHZ == 27)
#define CLKRV_CRYSTAL_27MHZ 1
#elif (STCLKRV_EXT_CLK_MHZ == 0x00)
#define CLKRV_CRYSTAL_30MHZ 1
#endif
#endif
#if CLKRV_CRYSTAL_27MHZ
stclkrv_Freqtable_t NominalFreqTable[MAX_NO_IN_FREQ_TABLE] =
{
/* Freq sdiv md ipe StepX100 Ratio/1000 */
/* SD */
{ 27000000, 16, -17, 0, 5100, 1000},
/* PCM */
{ 2048000, 128, -6, 20736, 236, 75},
{ 2822400, 128, -13, 28421, 450, 104},
{ 3072000, 128, -15, 13824, 533, 113},
{ 4096000, 64, -6, 20736, 474, 151},
{ 4233600, 64, -7, 16050, 506, 156},
{ 4608000, 64, -9, 18432, 600, 170},
{ 5644800, 64, -13, 28421, 900, 209},
{ 6144000, 64, -15, 13824, 1066, 227},
{ 8192000, 32, -6, 20736, 948, 303},
{ 8200000, 32, -6, 21579, 950, 303},
{ 8467200, 32, -7, 16050, 1012, 313},
{ 9216000, 32, -9, 18432, 1200, 341},
{ 11289600, 32, -13, 28421, 1800, 418},
{ 11300000, 32, -13, 28998, 1804, 418},
{ 12288000, 32, -15, 13824, 2133, 455},
{ 12300000, 32, -15, 14386, 2137, 455},
{16384000, 16, -6, 20736, 1896, 606},
{16934400, 16, -7, 16050, 2025, 627},
{18432000, 16, -9, 18432, 2400, 682},
{22579200, 16, -13, 28421, 3601, 836},
{24576000, 16, -15, 13824, 4267, 910},
{24600000, 16, -15, 14386, 4275, 911},
/* SPDIF */
{32768000, 8, -6, 20736, 3792, 1213},
{33868800, 8, -7, 16050, 4051, 1254},
{36864000, 8, -9, 18432, 4800, 1365},
{45158400, 8, -13, 28421, 7203, 1672},
{49140000, 8, -15, 13683, 8529, 1820},
{49152000, 8, -15, 13824, 8534, 1820},
/* For 640*480P video format */
{50350000, 8, -15, 27529, 8954, 1865}, /* Frame frequency 59.94Hz*/
{50400000, 8, -15, 28087, 8973, 1867}, /* Frame frequency 60Hz*/
/* 54Mhz configuration for 480P/576P/576I on HDMI */
{54000000, 8, -17, 0, 10300, 2000},
{54054000, 4, -1, 1048, 5160, 2002},
{59000000, 4, -3, 23327, 6147, 2185},
{67737600, 4, -7, 16050, 8103, 2508},
{73728000, 4, -9, 18432, 9601, 2730},
{74250000, 4, -9, 23831, 9737, 2750},
/* HD */
{ 96000000, 4, -15, 0, 16276, 3555 },
{108000000, 4, -17, 0, 20599, 4000 },
{108108000, 4, -17, 524, 20641, 4004 }, /* (108000000 * 1001 / 1000) */
{118800000, 2, -3, 29789, 12462, 4400 },
{144000000, 2, -9, 0, 18310, 5333 },
{148351648, 2, -9, 23069, 19435, 5494 }, /* (148500000 * 1000 / 1001) */
{148500000, 2, -9, 23831, 19474, 5500 }
};
#elif CLKRV_CRYSTAL_30MHZ
stclkrv_Freqtable_t NominalFreqTable[MAX_NO_IN_FREQ_TABLE] =
{
/* Freq sdiv md ipe StepX100 Ratio/1000 */
/* SD */
{ 27000000, 16, -15, 7282, 4600, 1000},
/* PCM */
{ 2048000, 128, -3, 23040, 213, 75},
{ 2822400, 128, -11, 24298, 405, 104},
{ 3072000, 128, -13, 15360, 480, 113},
{ 4096000, 64, -3, 23040, 426, 151},
{ 4233600, 64, -4, 21474, 455, 156},
{ 4608000, 64, -6, 31403, 540, 170},
{ 5644800, 64, -11, 24297, 810, 209},
{ 6144000, 64, -13, 15360, 960, 227},
{ 8192000, 32, -3, 23040, 853, 303},
{ 8200000, 32, -3, 23977, 855, 303},
{ 8467200, 32, -4, 21474, 911, 313},
{ 9216000, 32, -6, 31403, 1080, 341},
{ 11289600, 32, -11, 24297, 1620, 418},
{ 11300000, 32, -11, 24939, 1623, 418},
{ 12288000, 32, -13, 15360, 1920, 455},
{ 12300000, 32, -13, 15984, 1924, 455},
{16384000, 16, -3, 23040, 1706, 606},
{16934400, 16, -4, 21474, 1823, 627},
{18432000, 16, -6, 31403, 2160, 682},
{22579200, 16, -11, 24297, 3241, 836},
{24576000, 16, -13, 15360, 3840, 910},
{24600000, 16, -13, 15984, 3847, 911},
/* SPDIF */
{32768000, 8, -3, 23040, 3413, 1213},
{33868800, 8, -4, 21474, 3646, 1254},
{36864000, 8, -6, 31403, 4320, 1365},
{45158400, 8, -11, 24297, 6482, 1672},
{49140000, 8, -13, 15204, 7676, 1820},
{49152000, 8, -13, 15360, 7680, 1820},
/* For 640*480P video format */
{50350000, 8, -13, 30588, 8059, 1865}, /* Frame frequency 59.94Hz*/
{50400000, 8, -13, 31208, 8076, 1867}, /* Frame frequency 60Hz*/
/* STFAE - Add 54Mhz configuration for 480P/576P/576I on HDMI */
{54000000, 8, -15, 7282, 9270, 2000},
{54054000, 8, -15, 7864, 9288, 2002}, /* (54000000 * 1001 / 1000) */
{59000000, 8, -16, 23882, 11066, 2185},
{67737600, 4, -4, 21474, 7293, 2508},
{73728000, 4, -6, 31403, 8640, 2730},
{74250000, 4, -7, 4634, 8762, 2750},
/* HD */
{ 96000000, 4, -13, 0, 14648, 3555 },
{108000000, 4, -15, 7282, 18534, 4000 },
{108108000, 4, -15, 7864, 18550, 4004 }, /* (108000000 * 1001 / 1000) */
{118800000, 4, -16, 27472, 20153, 4400 },
{144000000, 2, -6, 10923, 16479, 5333 },
{148351648, 2, -7, 3787, 17490, 5494 }, /* (148500000 * 1000 / 1001) */
{148500000, 2, -7, 4634, 17525, 5500 }
};
#else
#error "error in crystal freq. selection"
#endif
/* Private Macros --------------------------------------------------------- */
/* Private Function prototypes -------------------------------------------- */
/* Program FS registers*/
ST_ErrorCode_t clkrv_Program_FS_Registers( STCLKRV_ControlBlock_t *CB_p,
STCLKRV_ClockSource_t Clock);
/* Change Clocks by Control value */
void clkrv_ChangeClockFreqBy( STCLKRV_ControlBlock_t *CB_p,
STCLKRV_ClockSource_t Clock,
S32 Control );
/* Calculate new values of Sdiv, Mde and Ipe to apply the correction value */
void clkrv_CorrectSlaveClocks( STCLKRV_ControlBlock_t *CB_p,
S32 CntrlVal,
STCLKRV_ClockSource_t Clock );
/* Correctio for crystal error typically on 7100/7109 */
#if (STCLKRV_CRYSTAL_ERROR != 0x00)
void clkrv_CorrectCrystalError(void);
#endif
/* Reset 5100 H/W Block */
ST_ErrorCode_t clkrv_InitHW( STCLKRV_ControlBlock_t *CB_p );
/* Register Read Write Function */
__inline void clkrv_writeReg(STSYS_DU32 *Base, U32 Reg, U32 Value);
__inline void clkrv_writeRegUnLock(STSYS_DU32 *Base, U32 Reg, U32 Value);
__inline void clkrv_readReg (STSYS_DU32 *Base, U32 Reg, U32 *Value);
#ifndef STCLKRV_NO_PTI
/* Filter Functions */
U32 ClockRecoveryFilter(U32 ExtdPCRTime, U32 ExtdSTCTime, STCLKRV_ControlBlock_t *Instance_p);
/* Filter related internal functions */
static ST_ErrorCode_t CalculateFrequencyError(FilterData *FilterData_p,
STCLKRV_ControlBlock_t *CB_p);
static ST_ErrorCode_t LowPassFilter(FilterData *FilterData_p,
STCLKRV_ControlBlock_t *CB_p);
static void ApplyWeighingFilter(STCLKRV_ControlBlock_t *CB_p);
#if defined(ST_OS20) || defined(ST_OS21) /* linux changes */
#ifdef ST_5188
void STCLKRV_ActionPCR(STEVT_CallReason_t EventReason,
ST_DeviceName_t RegistrantName,
STEVT_EventConstant_t EventOccured,
STDEMUX_EventData_t *PcrData_p,
STCLKRV_Handle_t *InstanceHandle_p);
#else
void STCLKRV_ActionPCR(STEVT_CallReason_t EventReason,
ST_DeviceName_t RegistrantName,
STEVT_EventConstant_t EventOccured,
STPTI_EventData_t *PcrData_p,
STCLKRV_Handle_t *InstanceHandle_p);
#endif
#endif
void ActionPCR( STCLKRV_ControlBlock_t *InstanceHandle_p);
#if defined(ST_OS20) || defined(ST_OS21) /* linux changes */
void ClockRecoveryFilterTask(STCLKRV_ControlBlock_t *CB_p);
#else
int ClockRecoveryFilterTask(STCLKRV_ControlBlock_t *CB_p);
#endif
/* Utility Functions */
static S32 DivideAndRound(S32 Num, U32 Denom);
U32 FindClockIndex(STCLKRV_ControlBlock_t *CB_p, STCLKRV_ClockSource_t Clock);
#endif /* STCLKRV_NO_PTI */
/* Utility Functions */
void UpdateStateMachine(STCLKRV_ControlBlock_t *Instance_p,BOOL DiscontinuousPCR);
/* Functions -------------------------------------------------------------- */
#ifdef WA_GNBvd44290
void stclkrv_GNBvd44290_ResetClkrvTracking(void)
{
Count_PCM = 0;
Count_PixelHD = 0;
}
#endif /* stclkrv_GNBvd44290_ResetClkrvTracking */
/****************************************************************************
Name : FindClockIndex
Description : Find the given clock in clock array
Parameters : Pointer to STCLKRV_ControlBlock_t, Clock
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_BAD_PARAMETER Bad parameter
See Also :
****************************************************************************/
U32 FindClockIndex(STCLKRV_ControlBlock_t *CB_p, STCLKRV_ClockSource_t Clock)
{
U32 i=0;
/* Start from 0 as pixel at Zero */
for (i=0;i<CB_p->HWContext.ClockIndex;i++){
if (Clock == CB_p->HWContext.Clocks[i].ClockType)
break;
}
return (i);
}
/****************************************************************************
Name : GetRegIndex
Description : Find the given clock recovery instance (Primary/Secondary)
Parameters : Pointer to STCLKRV_ControlBlock_t, Clock
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_BAD_PARAMETER Bad parameter
See Also :
****************************************************************************/
U32 GetRegIndex(STCLKRV_ControlBlock_t *CB_p)
{
#if !defined (ST_5525)
return 0;
#elif defined (ST_5525)
if (CB_p->InitPars.DecodeType == STCLKRV_DECODE_PRIMARY)
return 0;
else if (CB_p->InitPars.DecodeType == STCLKRV_DECODE_SECONDARY)
return 1;
else
return 0;
#endif
}
/****************************************************************************
Name : GetCounterOffset
Description : Find the given clock counter register offset
Parameters : Pointer to STCLKRV_ControlBlock_t, Clock
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_BAD_PARAMETER Bad parameter
See Also :
****************************************************************************/
static U32 GetCounterOffset(STCLKRV_ControlBlock_t *CB_p, STCLKRV_ClockSource_t Clock)
{
U32 CaptureCntOffset = 0;
#if defined (ST_5100) || defined (ST_5105) || defined (ST_5301) || defined (ST_5107)
switch(Clock)
{
case STCLKRV_CLOCK_PCM_0:
CaptureCntOffset = CAPTURE_COUNTER_PCM;
break;
case STCLKRV_CLOCK_SPDIF_0:
CaptureCntOffset = CAPTURE_COUNTER_SPDIF;
break;
default:
/* what else */
CaptureCntOffset = CAPTURE_COUNTER_PCM;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -