📄 stclkrv.c
字号:
CB_p->HWContext.Clocks[Index].IPE = CorrectedIPE;
CB_p->HWContext.Clocks[Index].SDIV = NominalFreqTable[i].SDIV;
CB_p->HWContext.Clocks[Index].Step = NominalFreqTable[i].Step;
CB_p->HWContext.Clocks[Index].Ratio = NominalFreqTable[i].Ratio;
CB_p->HWContext.Clocks[Index].ClockType = ClockSource;
CB_p->HWContext.Clocks[Index].Frequency = CorrectedFrequency;
CB_p->HWContext.Clocks[Index].SlaveWithCounter = SlaveHaveCounter(ClockSource);
CB_p->HWContext.Clocks[Index].TicksToElapse =
(NominalFreqTable[i].Frequency * STCLKRV_INTERRUPT_TIME_SPAN );
/* Update HW to reflect glitch free new freq. */
clkrv_setClockFreq(CB_p, ClockSource, Index);
/* Load referenece Counter **********************************/
#ifdef WA_GNBvd44290
/* otherwise we will have some audio issues during vtg mode change */
stclkrv_GNBvd44290_ResetClkrvTracking();
clkrv_writeReg( BaseAddress, CLKRV_REF_MAX_CNT(GetRegIndex(CB_p)),
(U32)(ENCODER_FREQUENCY * STCLKRV_INTERRUPT_TIME_FIRST ));
#else
/* Load referenece Counter **********************************/
clkrv_writeReg( BaseAddress, CLKRV_REF_MAX_CNT(GetRegIndex(CB_p)),
(U32)(ENCODER_FREQUENCY * STCLKRV_INTERRUPT_TIME_SPAN ));
#endif /* WA_GNBvd44290 */
EnterCriticalSection();
/* ReSet DCO_CMD to 0x01 */
clkrv_writeReg(BaseAddress, CLKRV_REC_CMD(GetRegIndex(CB_p)), 0x01);
LeaveCriticalSection();
/* Delay not required for 7710 */
#if defined (ST_5100) || defined (ST_5105) || defined (ST_5301) || defined (ST_5107) \
|| defined (ST_7100) || defined (ST_7109) || defined (ST_5188) \
|| defined (ST_5525)
CLKRV_DELAY(10);
#endif
EnterCriticalSection();
clkrv_writeReg(BaseAddress, CLKRV_REC_CMD(GetRegIndex(CB_p)), 0x00);
LeaveCriticalSection();
/* END - Loading referenece Counter */
/* This slave is valid from now ON */
CB_p->HWContext.Clocks[Index].Valid = TRUE;
if( Index == CB_p->HWContext.ClockIndex )
{
CB_p->HWContext.ClockIndex++;
}
STOS_SemaphoreSignal(CB_p->InstanceSemaphore_p);
return ST_NO_ERROR;
}
/****************************************************************************
Name : STCLKRV_GetExtendedSTC()
Description : If in Clock recovery mode returns the full precision STC value
if a recent PCR update has been received. This is the addition
of the PCR value and elapsed time since the last packet
(non PCR) was received.
If in STC baselining mode returns the given STC baseline value
plus the time elapsed since the last update.
Parameters : STCLKRV_Handle_t Handle
STCLKRV_ExtendedSTC_t Pointer to returned STC value.
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors occurred
ST_ERROR_INVALID_HANDLE Not open or invalid handle
ST_ERROR_BAD_PARAMETER One or more invalid parameters
STCLKRV_ERROR_PCR_UNAVAILABLE Accurate Decode unavailable
See Also : STCLKRV_Open()
****************************************************************************/
#ifndef STCLKRV_NO_PTI
ST_ErrorCode_t STCLKRV_GetExtendedSTC(STCLKRV_Handle_t Handle,
STCLKRV_ExtendedSTC_t *ExtendedSTC )
{
BOOL STCErrorRet = TRUE;
STCLKRV_ControlBlock_t *TmpCB_p;
ST_ErrorCode_t ReturnCode = STCLKRV_ERROR_PCR_UNAVAILABLE;
S32 Temp1_s32, Temp2_s32;
S32 Carry;
U32 ArrivalTimeBaseBit32 = 0;
U32 ArrivalTimeBaseValue = 0;
U32 ArrivalTimeExtension = 0;
U32 ElapsedTime;
U32 RefSTCBaseValue;
U32 RefSTCBaseBit32;
U32 RefSTCExtension;
U32 RefArrivalTimeBaseValue;
U32 RefArrivalTimeBaseBit32;
U32 RefArrivalTimeExtension;
clock_t MicroSecsSinceLastCall;
STCLKRV_ExtendedSTC_t FreerunIncSTC;
STCLKRV_ExtendedSTC_t UpdatedSTC;
U32 STCReferenceControl;
BOOL FreerunSTCActive;
BOOL ActvRefPCRValid;
clock_t FreerunSTCTimer;
STCLKRV_ExtendedSTC_t STCBaseline;
STCLKRV_ExtendedSTC_t STCPcrSync;
STCLKRV_ExtendedSTC_t OffsetInExtSTC;
#ifdef ST_5188
STDEMUX_Slot_t STPTISlot;
#else
STPTI_Slot_t STPTISlot;
#endif
#if defined (ST_5100)
clock_t HPTTicks;
#else
#ifdef ST_5188
STDEMUX_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#else
STPTI_TimeStamp_t STCCurrentTime; /* @ 90 kHz*/
#endif
clock_t TimeIn90kHzUnits;
#endif
S32 STCOffset;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return( ST_ERROR_INVALID_HANDLE );
}
/* NULL variable ptr? */
if( ExtendedSTC == NULL )
{
return( ST_ERROR_BAD_PARAMETER );
}
/* Protect access and get shared data */
EnterCriticalSection();
STCReferenceControl = (U32) TmpCB_p->STCBaseline.STCReferenceControl;
FreerunSTCActive = TmpCB_p->FreerunSTC.Active;
FreerunSTCTimer = TmpCB_p->FreerunSTC.Timer;
STCBaseline = TmpCB_p->STCBaseline.STC;
ActvRefPCRValid = TmpCB_p->ActvRefPcr.Valid;
RefSTCBaseValue = TmpCB_p->ActvRefPcr.PcrBaseValue;
RefSTCBaseBit32 = TmpCB_p->ActvRefPcr.PcrBaseBit32;
RefSTCExtension = TmpCB_p->ActvRefPcr.PcrExtension;
RefArrivalTimeBaseValue = TmpCB_p->ActvRefPcr.PcrArrivalBaseValue;
RefArrivalTimeBaseBit32 = TmpCB_p->ActvRefPcr.PcrArrivalBaseBit32;
RefArrivalTimeExtension = TmpCB_p->ActvRefPcr.PcrArrivalExtension;
STCOffset = TmpCB_p->OffsetInSTC;
STPTISlot = TmpCB_p->Slot;
LeaveCriticalSection();
/* When in baseline mode, always freerun */
if ((STCReferenceControl == (U32) STCLKRV_STC_SOURCE_BASELINE) && (FreerunSTCActive == TRUE))
{
#if defined (ST_5100)
/* Get high priority timer ticks */
GetHPTimer(HPTTicks);
/* calc time elapsed in ticks */
MicroSecsSinceLastCall = STOS_time_minus(HPTTicks, FreerunSTCTimer);
/* Adjust to usecs */
AdjustHPTTicksToMicroSec(MicroSecsSinceLastCall);
/* Convert elapsed time to ExtSTC format */
ConvertMicroSecsToExtSTC(MicroSecsSinceLastCall, &FreerunIncSTC);
#else /* 7710, 5105, 5188,5107 C1 cores */
#ifdef ST_5188
if (STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#else
if (STPTI_GetCurrentPTITimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime) != ST_NO_ERROR)
#endif
{
return STCLKRV_ERROR_PCR_UNAVAILABLE;
}
TimeIn90kHzUnits = STOS_time_minus(STCCurrentTime.LSW, FreerunSTCTimer);
/* Convert elapsed time to ExtSTC format */
FreerunIncSTC.BaseValue = TimeIn90kHzUnits;
FreerunIncSTC.BaseBit32 = 0;
FreerunIncSTC.Extension = 0;
/* Approx value will work */
MicroSecsSinceLastCall = (TimeIn90kHzUnits * 11);
#endif
/* Add elapsed time in ExtSTC format to baseline */
AddTwoExtSTCValues(FreerunIncSTC, STCBaseline, &UpdatedSTC);
if (MicroSecsSinceLastCall >= STC_REBASELINE_TIME)
{
/* Protect access and update control values */
EnterCriticalSection();
TmpCB_p->STCBaseline.STC.BaseValue = UpdatedSTC.BaseValue;
TmpCB_p->STCBaseline.STC.BaseBit32 = UpdatedSTC.BaseBit32;
TmpCB_p->STCBaseline.STC.Extension = UpdatedSTC.Extension;
#if defined (ST_5100)
TmpCB_p->FreerunSTC.Timer = HPTTicks;
#else
TmpCB_p->FreerunSTC.Timer = (clock_t)STCCurrentTime.LSW;
#endif
LeaveCriticalSection();
}
/* Add Offset in returned value */
OffsetInExtSTC.BaseValue = abs(STCOffset);
OffsetInExtSTC.BaseBit32 = 0;
OffsetInExtSTC.Extension = 0;
if( STCOffset == 0)
{
/* Copy result to passed locations */
ExtendedSTC->BaseBit32 = UpdatedSTC.BaseBit32;
ExtendedSTC->BaseValue = UpdatedSTC.BaseValue;
ExtendedSTC->Extension = UpdatedSTC.Extension;
}
else if( STCOffset > 0)
{
/* Add elapsed time in ExtSTC format to baseline */
AddTwoExtSTCValues(OffsetInExtSTC, UpdatedSTC, ExtendedSTC);
}
else if ( STCOffset < 0)
{
/* Subtract elapsed time in ExtSTC format to baseline */
SubtractTwoExtSTCValues(OffsetInExtSTC, UpdatedSTC, ExtendedSTC);
}
ReturnCode = ST_NO_ERROR;
}
else /* If not in baseline mode....*/
{
if ((STCReferenceControl == (U32) STCLKRV_STC_SOURCE_PCR) && (ActvRefPCRValid))
{
#ifdef ST_5188
STCErrorRet = STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
&STCCurrentTime);
ArrivalTimeBaseBit32 = STCCurrentTime.Bit32;
ArrivalTimeBaseValue = STCCurrentTime.LSW;
ArrivalTimeExtension = 0;
#else
STCErrorRet = GetExtendedPacketArrivalTime(STPTISlot,
&ArrivalTimeBaseBit32,
&ArrivalTimeBaseValue,
&ArrivalTimeExtension );
#endif
}
if (!STCErrorRet)
{
/* Calculate time elapsed between previous reference and current reference point */
ElapsedTime = STOS_time_minus( ArrivalTimeBaseValue, RefArrivalTimeBaseValue );
/* restrict elapsed time to reasonable level */
if( ( ElapsedTime >> PCR_STALE_SHIFT ) == 0 )
{
/* In order to calculate the correct STC we use
the following formula:
((Packet Arrival Time) - (PCR Arrival Time)) + (PCR)
or for STC baselining scenario....
((Packet Arrival Time) - (time of last baseline update)) + (baseline)
*/
/* Start with modulo 300, 27MHz part */
Temp1_s32 = (((S32)ArrivalTimeExtension - (S32)(RefArrivalTimeExtension)) +
(S32)(RefSTCExtension) );
/* Test for over/underflow */
if( Temp1_s32 > CONV90K_TO_27M )
{
Carry = 1; /* Overflow */
Temp1_s32 -= CONV90K_TO_27M;
}
else if( Temp1_s32 < 0 )
{
Carry = -1; /* Underflow */
Temp1_s32 += CONV90K_TO_27M;
}
else
{
Carry = 0;
}
ArrivalTimeExtension = (U32)Temp1_s32;
/* Calculate 90KHz, 32 bit value in two stages
in order to allow for overflow Carry/Borrow
is brought forward from previous stage */
Temp1_s32 = ( (S32)(ArrivalTimeBaseValue & 0xffff) -
(S32)(RefArrivalTimeBaseValue & 0xffff) +
(S32)(RefSTCBaseValue & 0xffff) +
Carry );
Carry = ( Temp1_s32 > 0x0000ffffL ) ? 1 : 0;
Carry = ( Temp1_s32 < 0 ) ? -1 : Carry;
/* High 16 bits of BaseValue + carry from low 16 */
Temp2_s32 = ( (S32)( (ArrivalTimeBaseValue >> 16) & 0xffff ) -
(S32)( (RefArrivalTimeBaseValue >> 16) & 0xffff ) +
(S32)( (RefSTCBaseValue >> 16) & 0xffff ) +
Carry );
Carry = ( Temp2_s32 > 0x0000ffffL ) ? 1 : 0;
Carry = ( Temp2_s32 < 0 ) ? -1 : Carry;
ArrivalTimeBaseValue = ((Temp2_s32 & 0xffff) << 16 |
(Temp1_s32 & 0xffff));
/* Calculate top bit with carry from previous stage */
ArrivalTimeBaseBit32 = (((S32)ArrivalTimeBaseBit32 -
(S32)(RefArrivalTimeBaseBit32)) +
((S32)(RefSTCBaseBit32 + Carry ) & 1));
/* Add Offset in returned value */
OffsetInExtSTC.BaseValue = abs(STCOffset);
OffsetInExtSTC.BaseBit32 = 0;
OffsetInExtSTC.Extension = 0;
STCPcrSync.BaseBit32 = ArrivalTimeBaseBit32;
STCPcrSync.BaseValue = ArrivalTimeBaseValue;
STCPcrSync.Extension = ArrivalTimeExtension;
if( STCOffset == 0)
{
/* Copy result to passed locations */
ExtendedSTC->BaseBit32 = ArrivalTimeBaseBit32;
ExtendedSTC->BaseValue = ArrivalTimeBaseValue;
ExtendedSTC->Extension = ArrivalTimeExtension;
ReturnCode = ST_NO_ERROR; /* everything OK */
return ReturnCode;
}
else if( STCOffset > 0)
{
/* Add elapsed time in ExtSTC format to baseline */
AddTwoExtSTCValues(OffsetInExtSTC, STCPcrSync, &UpdatedSTC);
}
else if ( STCOffset < 0)
{
/* Subtract elapsed time in ExtSTC format to baseline */
SubtractTwoExtSTCValues(OffsetInExtSTC, STCPcrSync, &UpdatedSTC);
}
/* Copy result to passed locations */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -