📄 stclkrv.c
字号:
Parameters : STCLKRV_Handle_t Handle
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
See Also : STCLKRV_Disable()
****************************************************************************/
#ifndef STCLKRV_NO_PTI
ST_ErrorCode_t STCLKRV_Enable( STCLKRV_Handle_t Handle )
{
/* Temp ptr into instance list */
STCLKRV_ControlBlock_t *TmpCB_p = NULL;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
{
return (ST_ERROR_FEATURE_NOT_SUPPORTED);
}
/* Protect data and write to PCR control switch */
EnterCriticalSection();
TmpCB_p->ActvRefPcr.PCRHandlingActive = TRUE;
LeaveCriticalSection();
return (ST_NO_ERROR);
}
/****************************************************************************
Name : STCLKRV_SetSTCSource
Description : Sets thes STC source control switch of the clock recovery
instance given to the given value.
Allows selection of either user STC baseline or PCR derived
STC reference value.
Parameters : STCLKRV_Handle_t Handle
STCLKRV_STCSource_t STCSource
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetSTCSource( STCLKRV_Handle_t Handle,
STCLKRV_STCSource_t STCSource)
{
/* Temp ptr into instance list */
STCLKRV_ControlBlock_t *TmpCB_p = NULL;
/* Check handle is valid */
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
{
if ((STCSource != STCLKRV_STC_SOURCE_BASELINE))
{
return (ST_ERROR_BAD_PARAMETER);
}
}
/* Check valid source supplied */
if ((STCSource != STCLKRV_STC_SOURCE_PCR) &&
(STCSource != STCLKRV_STC_SOURCE_BASELINE))
{
return (ST_ERROR_BAD_PARAMETER);
}
/* Protect and update instance data */
EnterCriticalSection();
TmpCB_p->STCBaseline.STCReferenceControl = STCSource;
if (STCSource != STCLKRV_STC_SOURCE_BASELINE)
{
TmpCB_p->FreerunSTC.Active = FALSE;
}
LeaveCriticalSection();
return (ST_NO_ERROR);
}
/****************************************************************************
Name : STCLKRV_SetPCRSource
Description : Sets source for the PCR collection required for clock recovery
and invalidate the decode clock
Parameters : STCLKRV_Handle_t ClkHandle :- Handle identifying instance to set
STCLKRV_SourceParams_t :- PCRSource data regarding PCR
collection
Return Value : ST_NO_ERROR
ST_ERROR_INVALID_HANDLE
ST_ERROR_BAD_PARAMETER
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetPCRSource( STCLKRV_Handle_t Handle,
STCLKRV_SourceParams_t *PCRSource_p)
{
STCLKRV_ControlBlock_t *TmpCB_p;
#ifdef ST_5188
if ( PCRSource_p->Source_u.STPTI_s.Slot == (STDEMUX_Slot_t )NULL)
#else
if ( PCRSource_p->Source_u.STPTI_s.Slot == (STPTI_Slot_t )NULL)
#endif
{
return(ST_ERROR_BAD_PARAMETER);
}
TmpCB_p = FindInstanceByHandle(Handle);
if (TmpCB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
if (TmpCB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
{
return (ST_ERROR_FEATURE_NOT_SUPPORTED);
}
EnterCriticalSection();
TmpCB_p->Slot = PCRSource_p->Source_u.STPTI_s.Slot;
TmpCB_p->SlotEnabled = TRUE;
/* flag reset reference PCR */
TmpCB_p->ActvRefPcr.Valid = FALSE;
TmpCB_p->ActvRefPcr.AwaitingPCR = TRUE;
LeaveCriticalSection();
/* Update state machine and generate STCLKRV_PCR_DISCONTINUOUS_EVT */
UpdateStateMachine(TmpCB_p, TRUE ); /* GNBvd06145 */
return ST_NO_ERROR;
}
#endif /* STCLKRV_NO_PTI */
#if defined (ST_7710) || defined (ST_7100) || defined (ST_7109)
/****************************************************************************
Name : STCLKRV_SetApplicationMode()
Description : Sets the application mode available.
Parameters : STCLKRV_Handle_t Handle
STCLKRV_ApplicationMode_t AppMode
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
See Also : STCLKRV_Enable()
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetApplicationMode( STCLKRV_Handle_t Handle,
STCLKRV_ApplicationMode_t AppMode)
{
STSYS_DU32 *BaseAddress = NULL;
STCLKRV_ControlBlock_t *CB_p = NULL;
U32 RegValue;
/* Check handle is valid */
CB_p = FindInstanceByHandle(Handle);
if (CB_p == NULL)
{
return (ST_ERROR_INVALID_HANDLE);
}
if (CB_p->InitPars.DeviceType==STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
{
return (ST_ERROR_FEATURE_NOT_SUPPORTED);
}
if ( ( AppMode < STCLKRV_APPLICATION_MODE_NORMAL) ||
(AppMode > STCLKRV_APPLICATION_MODE_SD_ONLY) )
{
return( ST_ERROR_BAD_PARAMETER );
}
if (CB_p->HWContext.ApplicationMode == AppMode)
return (ST_NO_ERROR);
BaseAddress = CB_p->InitPars.FSBaseAddress_p;
if (AppMode == STCLKRV_APPLICATION_MODE_SD_ONLY )
{
#ifdef ST_7710
RegValue = 0;
/* Set the EN_PRG bit to Zero */
clkrv_readReg(BaseAddress, FS_CLOCKGEN_CFG_2, &RegValue);
RegValue |= 0x20;
RegValue = (RegValue & 0x0000FFFF) | UNLOCK_KEY; /* key for registers access */
clkrv_writeReg(BaseAddress, FS_CLOCKGEN_CFG_2, RegValue);
#elif defined(ST_7100) || defined (ST_7109)
RegValue = 0;
clkrv_readReg(BaseAddress, CKGB_CLK_SRC, &RegValue);
RegValue &= 0xFFFFFFFD;
clkrv_writeReg(BaseAddress, CKGB_CLK_SRC, RegValue);
/* clk_pix_sd =clk_hd/4 */
clkrv_readReg(BaseAddress, CKGB_DISP_CFG, &RegValue);
RegValue &= 0xFFFFF7FF;
RegValue |= 0x400;
clkrv_writeReg(BaseAddress, CKGB_DISP_CFG, RegValue);
#endif
CB_p->HWContext.ApplicationMode = AppMode;
}
else if (AppMode == STCLKRV_APPLICATION_MODE_NORMAL )
{
#ifdef ST_7710
RegValue = 0;
/* Set the EN_PRG bit to Zero */
clkrv_readReg(BaseAddress, FS_CLOCKGEN_CFG_2, &RegValue);
RegValue &= 0xFFFFFFDF;
RegValue = (RegValue & 0x0000FFFF) | UNLOCK_KEY; /* key for registers access */
clkrv_writeReg(BaseAddress, FS_CLOCKGEN_CFG_2, RegValue);
#elif defined(ST_7100) || defined (ST_7109)
RegValue = 0;
clkrv_readReg(BaseAddress, CKGB_CLK_SRC, &RegValue);
RegValue |= 0x02;
clkrv_writeReg(BaseAddress, CKGB_CLK_SRC, RegValue);
#endif
CB_p->HWContext.ApplicationMode = AppMode;
}
return (ST_NO_ERROR);
}
#endif
/****************************************************************************
Name : STCLKRV_SetNominalFreq()
Description : Programs the FS registers to the Nominal Frequency
It will take around 100-150 WC time to take effect
for the new frequency.
Parameters : STCLKRV_Handle_t Handle
STCLKRV_ClockSource_t ClockSource
U32 Frequency
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors determined
ST_ERROR_INVALID_HANDLE Invalid Handle
STCLKRV_INVALID_FREQUENCY Invalid Frequency
STCLKRV_INVALID_SLAVE Invalid Slave
See Also : STCLKRV_Enable()
****************************************************************************/
ST_ErrorCode_t STCLKRV_SetNominalFreq( STCLKRV_Handle_t Handle,
STCLKRV_ClockSource_t ClockSource,
U32 Frequency )
{
U32 i = 0;
U32 SlaveClock;
U16 CorrectedIPE = 0;
S32 FreqOffsetInSTC = 0;
S32 InitialOffsetInPE = 0;
S8 ChangeInMD=0,CorrectedMD=0;
U32 CorrectedFrequency = 0;
STSYS_DU32 *BaseAddress = NULL;
STCLKRV_ControlBlock_t *CB_p = NULL;
U32 Index = 0;
/* Check handle is valid */
if (NULL == (CB_p = FindInstanceByHandle(Handle)))
return (ST_ERROR_INVALID_HANDLE);
/* No clock programming in base line mode */
if (CB_p->InitPars.DeviceType == STCLKRV_DEVICE_TYPE_BASELINE_ONLY)
return (ST_ERROR_FEATURE_NOT_SUPPORTED);
/* Check if clock is valid on this chip */
if( ! IsClockValid(CB_p, ClockSource) )
return (STCLKRV_ERROR_INVALID_SLAVE);
/* Check if clock is valid on this chip */
/* Search Frequency in Freq. Table */
for(i=0;((i<MAX_NO_IN_FREQ_TABLE)&&(Frequency!= NominalFreqTable[i].Frequency));i++);
if(i == MAX_NO_IN_FREQ_TABLE)
{
/* Could not find the given frequency in the table */
return STCLKRV_ERROR_INVALID_FREQUENCY;
}
/* Valid clock & freq. */
BaseAddress = CB_p->InitPars.FSBaseAddress_p;
EnterCriticalSection();
/* Reset DCO_CMD to 0x01 so that no interrupt occurs */
clkrv_writeReg(BaseAddress, CLKRV_REC_CMD(GetRegIndex(CB_p)), 0x01);
LeaveCriticalSection();
/* Mutually exclusive with FILTER task */
STOS_SemaphoreWait(CB_p->InstanceSemaphore_p);
Index = FindClockIndex(CB_p, ClockSource);
/* Zero Offset in table for STC/SD clock*/
FreqOffsetInSTC = (S32)(CB_p->HWContext.Clocks[0].Frequency
- NominalFreqTable[0].Frequency);
/* Ratio is multiple of 1000 and Step is of 100 so there we placed 10 */
InitialOffsetInPE = (S32)((FreqOffsetInSTC * (S32)NominalFreqTable[0].Ratio)
/ (S32)(NominalFreqTable[0].Step * 10));
/* Calculate change in MD, IPE */
CorrectedIPE = (U16)((S32)NominalFreqTable[i].IPE + (S32)InitialOffsetInPE);
/* if roll over, md needs to be changed */
if(CorrectedIPE&0x8000)
{
/* calculate change in md, +ve or -ve change */
ChangeInMD = (InitialOffsetInPE >= 0 ? 1 : -1);
/* MD change, +1, -1 or 0*/
CorrectedMD = NominalFreqTable[i].MD - ChangeInMD;
}
else
{
CorrectedMD = NominalFreqTable[i].MD;
}
/* Corrected IPE value */
CorrectedIPE = CorrectedIPE & 0x7fff;
/* Reset the clocks in software, HW should take care of itself */
/* Doing this will discard any previous drift of other slave
It is like resetting Drfit correction process */
/* Everything else for other slave must be untouched */
/* Clock[0] - Always Pixel clock */
for ( SlaveClock = 1; SlaveClock < Index; SlaveClock++)
{
CB_p->HWContext.Clocks[SlaveClock].PrevCounter = 0;
CB_p->HWContext.Clocks[SlaveClock].DriftError = 0;
}
/* update Slave clock */
CorrectedFrequency = (S32)NominalFreqTable[i].Frequency +
(S32)((InitialOffsetInPE * (S32)NominalFreqTable[i].Step)/100);
CB_p->HWContext.Clocks[Index].PrevCounter = 0;
CB_p->HWContext.Clocks[Index].DriftError = 0;
CB_p->HWContext.Clocks[Index].MD = CorrectedMD;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -