📄 clkrvsim.c
字号:
Return Value : ST_ErrorCode_t
See Also :
****************************************************************************/
static ST_ErrorCode_t CLKRVSIM_EVTTerm(void)
{
STEVT_TermParams_t EVTTermPars_s;
ST_ErrorCode_t EvtError = ST_NO_ERROR;
#ifdef ST_5188
EvtError = STEVT_Unregister(ControlObject_p->Evt.EVTHandlePcr,
(U32)STDEMUX_EVENT_PCR_RECEIVED_EVT);
#else
EvtError = STEVT_Unregister(ControlObject_p->Evt.EVTHandlePcr,
(U32)STPTI_EVENT_PCR_RECEIVED_EVT);
#endif
if(EvtError != ST_NO_ERROR)
{
STTBX_Print(("ERROR:STEVT_Unregister\n"));
}
else
{
EvtError = STEVT_Close(ControlObject_p->Evt.EVTHandlePcr);
if(EvtError != ST_NO_ERROR)
{
STTBX_Print(("ERROR:STEVT_Close\n"));
}
}
EVTTermPars_s.ForceTerminate = FALSE;
EvtError = STEVT_Term(ControlObject_p->Evt.EVTDevNamPcr,&EVTTermPars_s);
if (EvtError != ST_NO_ERROR )
{
STTBX_Print(("Call to STEVT_Term() failed"));
}
return EvtError;
}
/****************************************************************************
Name : CLKRVSIM_Start()
Description : Start generating STC, PCR values.
Parameters : Pointer to STCLKRVSIM_StartParams_t structure
Return Value : ST_ErrorCode_t
See Also :
****************************************************************************/
ST_ErrorCode_t STCLKRVSIM_Start(STCLKRVSIM_StartParams_t* StartParams)
{
/* Validate Parameters */
if((StartParams->File_p == NULL) || (StartParams->PCR_Interval == 0) ||
(StartParams->PCRDriftThreshold == 0))
{
STTBX_Print(("Invalid Parameter to CLKRVSIM_Init:"));
return ST_ERROR_BAD_PARAMETER;
}
ControlObject_p->TaskContext.Logfile_p = StartParams->File_p;
ControlObject_p->PCR_Interval = StartParams->PCR_Interval;
ControlObject_p->PCR_DriftThreshold = StartParams->PCRDriftThreshold;
if(StartParams->FileRead)
{
if(StartParams->TestFile != NULL)
{
ControlObject_p->TestFile_p = fopen(StartParams->TestFile, "r+");
if(ControlObject_p->TestFile_p == NULL)
{
STTBX_Print(( "Could Not Open File To read PCR,STC values\n" ));
return ST_ERROR_BAD_PARAMETER;
}
ControlObject_p->FileTest = 1;
}
else
{
return ST_ERROR_BAD_PARAMETER;
}
}
/* Change the Task State to RUNNING */
ControlObject_p->TaskContext.State = RUNNING;
return ST_NO_ERROR;
}
/****************************************************************************
Name : STCLKRVSIM_Stop()
Description : Stop generating STC, PCR values.
Parameters : Pvoid
Return Value : ST_ErrorCode_t
See Also :
****************************************************************************/
void STCLKRVSIM_Stop(void)
{
ControlObject_p->TaskContext.State = INITIALIZED;
/*ControlObject_p->TaskContext.Logfile_p = NULL;*/
STOS_SemaphoreWait(ControlObject_p->TaskContext.TaskSemaphore_p);
/* Reset Elements to remove side effects from previous Run */
memset( CLKRVSIM_RegArray,0,CLKRVSIM_REG_ARRAY_SIZE );
/* RS memset( &ClkrvData,0,sizeof(STCLKRV_Log_Data_t ));*/
ControlObject_p->Jitter = 0;
ControlObject_p->StreamStatus = 0;
ControlObject_p->PCR_Interval = 0; /* In ms */
ControlObject_p->PCR_DriftThreshold = 0;
ControlObject_p->FileTest = 0;
ControlObject_p->SimReset = 1;
STOS_SemaphoreSignal(ControlObject_p->TaskContext.TaskSemaphore_p);
if(ControlObject_p->TestFile_p)
{
fclose(ControlObject_p->TestFile_p);
ControlObject_p->TestFile_p = NULL;
}
}
/****************************************************************************
Name : STCLKRVSIM_SetTestParameters()
Description : Sets the test Parameters which would be used to generate
(PCR,STC) values
Parameters : Freq - Encoder Frequency
Jitter - Max Jitter Value
StreamStatus - Type of Real Time Disturbance to induce
Return Value : ST_ErrorCode_t
See Also :
*****************************************************************************/
ST_ErrorCode_t STCLKRVSIM_SetTestParameters(U32 Freq ,U32 Jitter ,U8 StreamStatus)
{
if((Freq > CLKRVSIM_ENCODER_MAX_FREQ) || (Freq < CLKRVSIM_ENCODER_MIN_FREQ))
{
return ST_ERROR_BAD_PARAMETER;
}
STOS_SemaphoreWait(ControlObject_p->TaskContext.TaskSemaphore_p);
ControlObject_p->EncoderFrequency = Freq;
ControlObject_p->StreamStatus = StreamStatus;
ControlObject_p->Jitter = Jitter;
STOS_SemaphoreSignal(ControlObject_p->TaskContext.TaskSemaphore_p);
return ST_NO_ERROR;
}
/****************************************************************************
Name : SimulatorTask()
Description : Provides PCR and STC values to clock recovery driver depending
taking the various Real Time Disturbances like Jitter, Glitch,
Packet loss, Channel Change into consideration.
Parameters : NONE
Return Value : NONE
****************************************************************************/
void SimulatorTask(void *voidptr)
{
U32 SDFreq = DEFAULT_SD_FREQUENCY;
U32 PCMFreq = PCM_CLOCK_FREQ1;
U32 SPDIFFreq = PCM_CLOCK_FREQ2;
U32 EncoderFrequency = 0;
U32 DriftThreshold = 0;
U32 PCR_Interval = 0;
U32 PacketDrop = 0;
U32 StreamStatus = 0;
U32 Jitter = 0;
U32 MaxJitter = 0;
U32 PCR_Ticks_To_Increment = 0;
U32 STC_Ticks_To_Increment = 0;
U32 Glitch_Ticks_To_Increment= 0;
U32 STC_Ticks_Elapsed = 0;
U32 PCR_Ticks_Elapsed = 0;
S32 RetVal = 0;
U32 FilePrevSTC = 0, FilePrevPCR = 0;
U32 RefCounter = 0;
U32 PCRCounter = 0;
U32 STCCounter = 0;
U32 RefCntMaxVal = 0;
U32 TempRefCntMaxVal = 0;
U32 CmdReg = 0;
U32 PCMCounter = 0;
U32 SPDIFCounter = 0;
U32 PCMCorrection = 0;
U32 SPDIFCorrection = 0;
U32 STCCorrection = 0;
U32 PCRCorrection = 0;
U32 InterruptAudioticks = 0;
U32 InterruptSPDIFticks = 0;
U32 InterruptPCRticks = 0;
U32 InterruptSTCticks = 0;
double SPDIF_Ratio = 0; /* double type required for precision */
double PCM_Ratio = 0;
while (ControlObject_p->TaskContext.State != NOT_INITIALIZED)
{
/* If Task State RUNNING start generating PCR, STC values */
if(ControlObject_p->TaskContext.State == RUNNING)
{
/* Store values in internal variables */
PCR_Interval = ControlObject_p->PCR_Interval;
DriftThreshold = ControlObject_p->PCR_DriftThreshold;
Glitch_Ticks_To_Increment = 0;
STOS_SemaphoreWait(ControlObject_p->TaskContext.TaskSemaphore_p);
MaxJitter = ControlObject_p->Jitter;
StreamStatus = ControlObject_p->StreamStatus;
EncoderFrequency = ControlObject_p->EncoderFrequency;
ControlObject_p->StreamStatus = 0;
STOS_SemaphoreSignal(ControlObject_p->TaskContext.TaskSemaphore_p);
ClkrvSim_RegRead(CLKRVSIM_RegArray, REF_MAX_CNT,&TempRefCntMaxVal);
/* Check if MaxRefCount Val has changed, if yes reload the value */
if(TempRefCntMaxVal != RefCntMaxVal)
{
RefCounter = RefCntMaxVal = TempRefCntMaxVal;
/* Reset the PCM and SPDIF counters and update the Registers for the same */
SPDIFCounter = 0;
PCMCounter = 0;
/* ClkrvSim_RegWrite(CLKRVSIM_RegArray,OFFSET_DCO_REF_CNT,RefCounter);*/
ClkrvSim_RegWrite(CLKRVSIM_RegArray, CAPTURE_COUNTER_PCM, PCMCounter);
#if defined (ST_5100) || defined (ST_5105) || defined (ST_5301) || defined (ST_5107)
ClkrvSim_RegWrite(CLKRVSIM_RegArray, CAPTURE_COUNTER_SPDIF, SPDIFCounter);
#elif defined (ST_7710) || defined (ST_7100)
ClkrvSim_RegWrite(CLKRVSIM_RegArray, CAPTURE_COUNTER_HD, SPDIFCounter);
#endif
/* Set the Drift Correction bit ON or OFF */
if(RefCntMaxVal != 0)
{
ControlObject_p->DriftCorrection = 1;
}
else
{
STTBX_Print(( "Ref CntMax Val = 0, Turning Off Drift Correction\n" ));
ControlObject_p->DriftCorrection = 0;
}
}
/* ALthough this will never happen, just a safety check */
if((SPDIFFreq == 0) || (PCMFreq == 0))
{
STTBX_Print(("\n\nERROR IN SLAVE FREQ- DIV BY 0\n\n"));
}
else
{
/* Store the ratios */
SPDIF_Ratio = (double)SDFreq / (double)SPDIFFreq;
PCM_Ratio = (double)SDFreq / (double)PCMFreq;
}
/* Check if STC, PCr values have to be generated or read from a file */
if(!ControlObject_p->FileTest)
{
/* Calculate STC and PCR Ticks elapsed */
STC_Ticks_Elapsed = (U32)(((double)SDFreq * (double)PCR_Interval + STCCorrection)/ K);
PCR_Ticks_Elapsed = (U32)(((double)EncoderFrequency * (double)PCR_Interval +
PCRCorrection) / K );
STCCorrection += (((U32)((double)SDFreq * (double)PCR_Interval)) % K );
PCRCorrection += (((U32)((double)EncoderFrequency * (double)PCR_Interval)) % K);
if(STCCorrection >= K)
{
STCCorrection = STCCorrection - K;
}
if(PCRCorrection >= K)
{
PCRCorrection = PCRCorrection - K;
}
/* Introduce Real Time disturbances in the STC, PCR ticks elapsed */
if(StreamStatus & MASK_BIT_PACKET_DROP)
{
PacketDrop = 2;
}
else
{
PacketDrop = 1;
}
Jitter = NetworkJitter(MaxJitter); /* Get the Random value of Jitter */
if(StreamStatus & MASK_BIT_GENERATE_GLITCH)
{
STC_Ticks_To_Increment = STC_Ticks_Elapsed * PacketDrop + Jitter ;
PCR_Ticks_To_Increment = PCR_Ticks_Elapsed * PacketDrop ;
Glitch_Ticks_To_Increment = (ControlObject_p->PCR_DriftThreshold * 2);
}
else if(StreamStatus & MASK_BIT_BASE_CHANGE)
{
STC_Ticks_To_Increment = (STC_Ticks_Elapsed * PacketDrop) + Jitter;
PCR_Ticks_To_Increment = (PCR_Ticks_Elapsed * PacketDrop) + DriftThreshold + 1;
}
else /* i.e No Real time disturbance */
{
STC_Ticks_To_Increment = (STC_Ticks_Elapsed * PacketDrop) + Jitter;
PCR_Ticks_To_Increment = (PCR_Ticks_Elapsed * PacketDrop);
}
}
else
{
if(ControlObject_p->TestFile_p !=NULL)
{
RetVal = fscanf(ControlObject_p->TestFile_p,"%u\t%u",&PCR_Ticks_Elapsed,
&STC_Ticks_Elapsed);
if(RetVal == EOF)
{
ControlObject_p->TaskContext.State = INITIALIZED;
fclose(ControlObject_p->TestFile_p);
ControlObject_p->TestFile_p = NULL;
continue ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -