📄 stclkrv.c
字号:
{
return (ST_ERROR_BAD_PARAMETER);
}
if(InitParams->DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
/* required for all*/
#if defined(ST_7100) || defined(ST_7109)
if( (InitParams->FSBaseAddress_p == NULL) ||
((InitParams->DeviceType == STCLKRV_DEVICE_TYPE_7100) &&
(InitParams->AUDCFGBaseAddress_p == NULL)) )
#else
if( (InitParams->FSBaseAddress_p == NULL) ||
((InitParams->DeviceType == STCLKRV_DEVICE_TYPE_7710) &&
(InitParams->ADSCBaseAddress_p == NULL)) )
#endif
{
return (ST_ERROR_BAD_PARAMETER);
}
/* Check For EVT Device Name */
if((InitParams->EVTDeviceName[0] == '\0')||
( strlen( InitParams->EVTDeviceName ) >= ST_MAX_DEVICE_NAME ))
{
return( ST_ERROR_BAD_PARAMETER );
}
}
#ifndef STCLKRV_NO_PTI
#if defined (ST_7710) || defined (ST_5105)|| defined (ST_5188) || defined (ST_5107)
/* Check For PTI Device Name C1 core limitation
STC needs to be read in free run mode */
if((InitParams->PTIDeviceName[0] == '\0')||
( strlen( InitParams->PTIDeviceName ) >= ST_MAX_DEVICE_NAME ))
{
return( ST_ERROR_BAD_PARAMETER );
}
#endif
#endif /* STCLKRV_NO_PTI */
/* Check For Memory parition */
if (InitParams->Partition_p == NULL)
{
return (ST_ERROR_BAD_PARAMETER);
}
if(InitParams->DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
/* Check averaging window parameters */
if ((InitParams->MaxWindowSize == 0) ||
(InitParams->MinSampleThres > InitParams->MaxWindowSize))
{
return (ST_ERROR_BAD_PARAMETER);
}
}
if(InitParams->DeviceType == STCLKRV_DEVICE_TYPE_5525 )
{
/* Check averaging window parameters */
if( !((InitParams->DecodeType == STCLKRV_DECODE_PRIMARY) ||
(InitParams->DecodeType == STCLKRV_DECODE_SECONDARY)))
{
return (ST_ERROR_BAD_PARAMETER);
}
}
/* All parameters ok, so Start the initialization process
* Create instance list, Set FS and DCO HW, Start Filter task, Install interrupt,
* register events and callbacks
*/
if (ClkrvList_p == NULL)
{
TmpCB_p = (STCLKRV_ControlBlock_t *) memory_allocate(InitParams->Partition_p,
sizeof(STCLKRV_ControlBlock_t));
}
else
{
/* check whether hardware has been initialized before?? */
if(InitParams->DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
NextElem = ClkrvList_p;
while(NextElem != NULL)
{
if ( NextElem->InitPars.DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
if ( NextElem->InitPars.DeviceType != STCLKRV_DEVICE_TYPE_5525)
return (ST_ERROR_FEATURE_NOT_SUPPORTED); /* only one hardware init */
}
NextElem = NextElem->Next;
}
}
TmpCB_p = (STCLKRV_ControlBlock_t *) memory_allocate(InitParams->Partition_p,
sizeof(STCLKRV_ControlBlock_t));
}
if (TmpCB_p == NULL)
{
return ST_ERROR_NO_MEMORY;
}
memset(TmpCB_p, 0x00, sizeof(STCLKRV_ControlBlock_t));
/* If no list already created, init global semap */
STOS_TaskLock();
if (AccessSemaphore_p == NULL)
{
AccessSemaphore_p = STOS_SemaphoreCreateFifo(NULL, 1);
}
STOS_TaskUnlock();
/* Take semap for duration of function - to block another simultaneous init */
STOS_SemaphoreWait(AccessSemaphore_p);
/* Create and take instance semaphore to protect private data write */
TmpCB_p->InstanceSemaphore_p = STOS_SemaphoreCreateFifo(NULL, 1);
STOS_SemaphoreWait(TmpCB_p->InstanceSemaphore_p);
/* Load init data to instance */
TmpCB_p->SlotEnabled = FALSE;
strcpy(TmpCB_p->DeviceName, Name);
TmpCB_p->OpenCount = 0;
TmpCB_p->InitPars = *InitParams;
TmpCB_p->ActvContext = InitContext;
TmpCB_p->ActvContext.MaxFrequencyError = (PCRTIMEFACTOR * TmpCB_p->InitPars.PCRDriftThres);
TmpCB_p->ActvRefPcr = InitRefPcr;
TmpCB_p->SlaveCorrectionBeingApplied = FALSE;
#ifndef STCLKRV_NO_PTI
/* Initialise STC baseline inactive */
TmpCB_p->STCBaseline.STC.BaseBit32 = 0;
TmpCB_p->STCBaseline.STC.BaseValue = 0;
TmpCB_p->STCBaseline.STC.Extension = 0;
TmpCB_p->FreerunSTC.Timer = 0;
TmpCB_p->FreerunSTC.Active = FALSE;
if(InitParams->DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
TmpCB_p->STCBaseline.STCReferenceControl = STCLKRV_STC_SOURCE_PCR;
}
else
{
TmpCB_p->STCBaseline.STCReferenceControl = STCLKRV_STC_SOURCE_BASELINE;
}
TmpCB_p->OffsetInSTC = 0;
#endif /* STCLKRV_NO_PTI */
if(InitParams->DeviceType != STCLKRV_DEVICE_TYPE_BASELINE_ONLY )
{
/* Create array for PCR-STC error storage in Filter*/
TmpCB_p->ActvContext.ErrorStore_p = (S32*) memory_allocate(InitParams->Partition_p,
(InitParams->MaxWindowSize * 4));
if (TmpCB_p->ActvContext.ErrorStore_p == NULL)
{
/* No memory for filter. Cannot continue... clean up and exit */
STOS_SemaphoreSignal(TmpCB_p->InstanceSemaphore_p);
STOS_SemaphoreDelete(NULL,TmpCB_p->InstanceSemaphore_p);
STOS_SemaphoreSignal(AccessSemaphore_p);
memory_deallocate(InitParams->Partition_p,TmpCB_p);
return ST_ERROR_NO_MEMORY;
}
else
{
for (i=0; i!=TmpCB_p->InitPars.MaxWindowSize; i++)
{
/* Initialize to Zeroes */
TmpCB_p->ActvContext.ErrorStore_p[i] = 0;
}
}
/* setup of STC/SD video frequency to nominal 27 MHz*/
/* + Invalidate Slaves */
RetCode = clkrv_InitHW(TmpCB_p);
#ifndef STCLKRV_NO_PTI
/* Set PCR callback function for pcr event subscription from STPTI */
if (RetCode == ST_NO_ERROR)
{
/* Set pcr event subscription for STPTI */
if (SubscribePCR(TmpCB_p) != ST_NO_ERROR)
{
ReturnCode = STCLKRV_ERROR_HANDLER_INSTALL;
RetCode = STCLKRV_ERROR_HANDLER_INSTALL;
}
}
#endif
if (RetCode == ST_NO_ERROR)
{
/* Register Events */
RetCode = RegisterEvents(TmpCB_p);
if (RetCode != ST_NO_ERROR)
{
ReturnCode = STCLKRV_ERROR_EVT_REGISTER;
}
}
#ifndef STCLKRV_NO_PTI
/* Filter Task Creation */
if (ReturnCode == ST_NO_ERROR)
{
/* Create the Filter idle semaphore required to control the timer task */
TmpCB_p->FilterSemaphore_p = STOS_SemaphoreCreateFifo(NULL, 0);
TmpCB_p->FilterTaskActive = TRUE;
RetCode = STOS_TaskCreate((void(*)(void *))ClockRecoveryFilterTask,
TmpCB_p,
TmpCB_p->InitPars.Partition_p,
STCLKRV_FILTER_STACK_SIZE,
&TmpCB_p->FilterTaskStack_p,
TmpCB_p->InitPars.Partition_p,
&TmpCB_p->FilterTask_p,
&TmpCB_p->FilterTaskDescriptor,
STCLKRV_FILTER_TASK_PRIORITY,
Name,
(task_flags_t)0);
if (RetCode != ST_NO_ERROR)
{
/* Flag the timer as waiting to be deleted */
TmpCB_p->FilterTaskActive = FALSE;
STOS_SemaphoreSignal(TmpCB_p->FilterSemaphore_p);
/* The task should be in the process of returning, but wait for
* it first before deleting it. */
if (STOS_TaskWait(&TmpCB_p->FilterTask_p,TIMEOUT_INFINITY) == 0)
{
/* Now it should be safe to delete the task */
if (STOS_TaskDelete(TmpCB_p->FilterTask_p,
(partition_t *)TmpCB_p->InitPars.Partition_p,
TmpCB_p->FilterTaskStack_p,
(partition_t *)TmpCB_p->InitPars.Partition_p
) == 0)
{
/* Delete all semaphores associated with the task */
STOS_SemaphoreDelete(NULL,TmpCB_p->FilterSemaphore_p);
}
}
ReturnCode = ST_ERROR_NO_MEMORY;
}
}
#endif /* STCLKRV_NO_PTI */
/* Install DCO Interrupt */
EnterCriticalSection();
if (ReturnCode == ST_NO_ERROR)
{
IntReturn = STOS_InterruptInstall( TmpCB_p->InitPars.InterruptNumber,
TmpCB_p->InitPars.InterruptLevel,
ClkrvTrackingInterruptHandler,
"CLKRV",
TmpCB_p);
if (IntReturn == 0)
{
IntReturn = STOS_InterruptEnable(TmpCB_p->InitPars.InterruptNumber,
TmpCB_p->InitPars.InterruptLevel);
if(IntReturn != 0)
{
ReturnCode = ST_ERROR_INTERRUPT_INSTALL;
}
}
else
{
ReturnCode = ST_ERROR_INTERRUPT_INSTALL;
}
}
LeaveCriticalSection();
}
/* subscription and regsitration ok - insert in linked list - Already under protection */
if (ReturnCode == ST_NO_ERROR)
{
AddToInstanceList(TmpCB_p); /* also sets up global ptr */
STOS_SemaphoreSignal(TmpCB_p->InstanceSemaphore_p);
}
else
{
/* Init failed, so give up memory */
STOS_SemaphoreSignal(TmpCB_p->InstanceSemaphore_p);
STOS_SemaphoreDelete(NULL,TmpCB_p->InstanceSemaphore_p);
memory_deallocate(InitParams->Partition_p,TmpCB_p->ActvContext.ErrorStore_p);
memory_deallocate(InitParams->Partition_p,TmpCB_p);
}
STOS_SemaphoreSignal(AccessSemaphore_p);
return (ReturnCode);
}
/****************************************************************************
Name : STCLKRV_Open()
Description : Opens the Clock Recovery Interface for operation.
MUST have been preceded by a successful Init call.
Note that this routine must cater for multi-thread usage.
The first call actually "opens" the device. Subsequent calls
just return the same handle as the first call & increment an
open count.
Parameters : STCLKRV_DeviceName_t name (matching name given to Init)
Pointer to STCLKRV_OpenParams_t,
Pointer to STCLKRV_Handle_t for return of the Handle.
Return Value : ST_ErrorCode_t specified as
ST_NO_ERROR No errors occurred
ST_ERROR_UNKNOWN_DEVICE Invalid Name/no prior Init
ST_ERROR_BAD_PARAMETER One or more invalid parameters
See Also : STCLKRV_Handle_t
STCLKRV_Init()
STCLKRV_Close()
****************************************************************************/
ST_ErrorCode_t STCLKRV_Open( const ST_DeviceName_t Name,
const STCLKRV_OpenParams_t *OpenParams,
STCLKRV_Handle_t *Handle )
{
STCLKRV_ControlBlock_t *TmpCB_p = NULL; /* Temp ptr into instance list */
/* Perform parameter validity checks */
if ((Name == NULL) || /* Name ptr uninitialised? */
(Handle == NULL)) /* Handle ptr uninitialised? */
{
return( ST_ERROR_BAD_PARAMETER );
}
/* Device must already exist in list ie, had prior call to init */
TmpCB_p = FindInstanceByName(Name);
if (TmpCB_p == NULL)
{
return (ST_ERROR_UNKNOWN_DEVICE);
}
/* Return ptr to block */
*Handle = (STCLKRV_Handle_t )TmpCB_p;
/* Protect and open status */
EnterCriticalSection();
TmpCB_p->OpenCount++;
LeaveCriticalSection();
return (ST_NO_ERROR);
}
/****************************************************************************
Name : STCLKRV_Enable()
Description : Enables the clock recovery handling of PCR's by setting
the PCRHandlingActive flag in given instance ControlBlock.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -