⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stclkrv.c

📁 st40 clock driver source code. 用于st40 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************

File Name   : stclkrv.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 "sttbx.h"
#include "stsys.h"
#endif

#include "stevt.h"

/* our own includes */
#include "stclkrv.h"
#include "clkrvreg.h"
#include "clkrvdat.h"

/* Private Constants ------------------------------------------------------ */

#ifndef STCLKRV_FILTER_TASK_PRIORITY
#ifdef ST_OSLINUX
#define STCLKRV_FILTER_TASK_PRIORITY  99
#else
#define STCLKRV_FILTER_TASK_PRIORITY  MAX_USER_PRIORITY
#endif
#endif


/* Externs ---------------------------------------------------------------- */
extern stclkrv_Freqtable_t NominalFreqTable[MAX_NO_IN_FREQ_TABLE];

/* Clock recovery Filter & drift correction of slaves clocks Debug Array */
#ifdef CLKRV_FILTERDEBUG
#define CLKRV_MAX_SAMPLES  5000
extern U32 ClkrvDbg[13][CLKRV_MAX_SAMPLES];
extern U32 Clkrv_Slave_Dbg[13][CLKRV_MAX_SAMPLES];
extern U32 SampleCount;
#endif

/* Private Variables ------------------------------------------------------ */

/* Provides mutual exclusion on global data */
static semaphore_t *AccessSemaphore_p = NULL;

/* Initialization Context */
static stclkrv_Context_t InitContext =
{
    TRUE,       /* Reset */
    0,          /* PrevDiff */
    0,          /* PrevPcr*/
    0,          /* Out Standing Error */
    0,          /* ControlValue */
    NULL,       /* ErrorStore_p; */
    0,          /* ErrorStoreCount */
    0,          /* Head */
    0,          /* ErrorSum */
    (PCRTIMEFACTOR * STCLKRV_PCR_DRIFT_THRES) /* Maximum error before a Glitch event is thrown*/
};


static stclkrv_ReferencePCR_t InitRefPcr =
{
    TRUE,                       /* AwaitingPCR         */
    FALSE,                      /* Valid               */
    TRUE,                       /* PCRHandlingActive   */
    0,                          /* PcrBaseBit32        */
    0,                          /* PcrBaseValue        */
    0,                          /* PcrExtension        */
    0,                          /* PcrArrivalBaseBit32 */
    0,                          /* PcrArrvialBaseValue */
    0,                          /* PcrArrivalExtension */
    0,                          /* Total Value         */
    0,                          /* Time                */
    0,                          /* GlitchCount         */
    (U32) STCLKRV_STATE_PCR_UNKNOWN   /* MachineState        */
};

/* Initialise ptr to Control block list */
STCLKRV_ControlBlock_t *ClkrvList_p   = NULL;

#ifdef WA_GNBvd44290
extern void stclkrv_GNBvd44290_ResetClkrvTracking(void);
#endif /* WA_GNBvd44290 */

/* Driver revision number */
static const ST_Revision_t stclkrv_DriverRev = "STCLKRV-REL_5.2.0A4";

/* Private Macros --------------------------------------------------------- */
#if defined (ST_5100)
#define AdjustHPTTicksToMicroSec(Value)                 \
{                                                       \
     /* With 64-bit arithmetic we can do the exact calculation:
        Value' = (Value * 1000000) / ST_GetClocksPerSecondHigh() */         \
    U32 HPTicksPerSec = ST_GetClocksPerSecondHigh();                        \
    __optasm                                                                \
    {                                                                       \
        ldabc Value, 1000000, 0;                                            \
        lmul;                   /* A*B + C (carry) -> A'B' */               \
                                /* should strictly add HPTicksPerSec/2 */   \
        ldl HPTicksPerSec;      /* NOT ld (might corrupt B, C */            \
        ldiv;                   /* B'C' / A -> A remainder B */             \
        st Value;                                                           \
    }                                                                       \
    /* We might want to change and use this code on all chips */            \
}
#endif
/* Private Function prototypes -------------------------------------------- */

#ifndef STCLKRV_NO_PTI
/* Callback Registered with STPTI to notify PCR,STC values */
#ifdef ST_5188
extern 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
extern 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
#if defined(ST_OS20) || defined(ST_OS21) /* linux changes */
extern void ClockRecoveryFilterTask(STCLKRV_ControlBlock_t *CB_p);
#else
extern int ClockRecoveryFilterTask(STCLKRV_ControlBlock_t *CB_p);
#endif
extern void UpdateStateMachine(STCLKRV_ControlBlock_t *Instance_p,BOOL DiscontinuousPCR);

static ST_ErrorCode_t SubscribePCR(STCLKRV_ControlBlock_t *Instance_p);
static ST_ErrorCode_t UnsubscribePCR(STCLKRV_ControlBlock_t *Instance_p);

/* STPTI */
#ifndef ST_5188
static BOOL GetExtendedPacketArrivalTime(STCLKRV_Handle_t Handle,
                                         U32 *BaseBit32,
                                         U32 *BaseValue,
                                         U32 *Extension);
static BOOL GetPacketArrivalTime(STCLKRV_Handle_t Handle, U32 *ArrivalTime);
#endif
static void AddTwoExtSTCValues(STCLKRV_ExtendedSTC_t ExtSTCA,STCLKRV_ExtendedSTC_t ExtSTCB,
                                                    STCLKRV_ExtendedSTC_t *ReturnExtSTC_p);
static void SubtractTwoExtSTCValues(STCLKRV_ExtendedSTC_t ExtSTCA,STCLKRV_ExtendedSTC_t ExtSTCB,
                                                    STCLKRV_ExtendedSTC_t *ReturnExtSTC_p);
#if defined (ST_5100)
static BOOL ConvertMicroSecsToExtSTC(clock_t MicroSecVal, STCLKRV_ExtendedSTC_t *ExtSTC_p);
#endif

#endif

extern STOS_INTERRUPT_DECLARE(ClkrvTrackingInterruptHandler, Data);

/* EVT Related */
static ST_ErrorCode_t RegisterEvents(STCLKRV_ControlBlock_t *Instance_p);
static ST_ErrorCode_t UnregisterEvents(STCLKRV_ControlBlock_t *Instance_p);

/* Utility Functions */
static void AddToInstanceList(STCLKRV_ControlBlock_t *NewItem_p);
static BOOL DelFromInstanceList(ST_DeviceName_t DeviceName);
static STCLKRV_ControlBlock_t *FindInstanceByHandle(STCLKRV_Handle_t ClkHandle);
static STCLKRV_ControlBlock_t *FindInstanceByName(const ST_DeviceName_t DeviceName);
static BOOL IsClockValid(STCLKRV_ControlBlock_t *CB_p, STCLKRV_ClockSource_t ClockSource );

/* Functions -------------------------------------------------------------- */

#if defined(CLKRV_TESTING)

/****************************************************************************
Name         : STCLKRV_GetClocksFrequency()

Description  : Returns the current freq. of various FS clocks.
               NOTE: This function is not documented in the
               API and is not exported in stclkrv.h as it
               is only needed by the test harness

Parameters   : STCLKRV_Handle_t Handle - Valid clock recovery handle
               U32 *                   - Pointer to returned FS0 freq.
               U32 *                   - Pointer to returned FS1 freq.
               U32 *                   - Pointer to returned FS2 freq.

Return Value : ST_ErrorCode_t
               ST_NO_ERROR               Successful completion
               ST_ERROR_INVALID_HANDLE   STCLKRV handle is not open

See Also     :
 ****************************************************************************/
ST_ErrorCode_t STCLKRV_GetClocksFrequency( STCLKRV_Handle_t Handle,
                                        U32 *pSTCFrequency,
                                        U32 *pFS1Frequency,
                                        U32 *pFS2Frequency,
                                        U32 *pFS3Frequency,
                                        U32 *pFS4Frequency,
                                        U32 *pFS5Frequency)
{
    /* Test handle validity */
    STCLKRV_ControlBlock_t *TmpCB_p;

    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);
    }

    /* set to zero all first */
    *pFS1Frequency = 0;
    *pFS2Frequency = 0;
    *pFS3Frequency = 0;
    *pFS4Frequency = 0;
    *pFS5Frequency = 0;

    *pSTCFrequency = TmpCB_p->HWContext.Clocks[0].Frequency;
    /* 5188 has only one slave until cut 1.0 */
    *pFS1Frequency = TmpCB_p->HWContext.Clocks[1].Frequency;

#if defined (ST_5100) || defined (ST_5105) || defined (ST_5301) || defined (ST_5107)\
 || defined (ST_7710) || defined (ST_7100)  || defined (ST_7109)
    *pFS2Frequency = TmpCB_p->HWContext.Clocks[2].Frequency;
#endif

#if defined (ST_7710) || defined (ST_7100)  || defined (ST_7109)
    *pFS3Frequency = TmpCB_p->HWContext.Clocks[3].Frequency;
#endif

#if defined (ST_7100)  || defined (ST_7109)
    *pFS4Frequency = TmpCB_p->HWContext.Clocks[4].Frequency;
#endif

#if defined (ST_5525)
    *pFS5Frequency = TmpCB_p->HWContext.Clocks[5].Frequency;
#endif

    return ST_NO_ERROR;                  /* Success */
}

#ifndef STCLKRV_NO_PTI
#if CLKRV_TESTING==2
/****************************************************************************
Name         : STPTI_GetPacketArrivalTime

Description  : Stub routine to resolve PTI library reference
               Returns fail to STCLKRV_GetSTC/GetExtSTC functions

Parameters   :

Return Value : Error

See Also     : PTI
****************************************************************************/
ST_ErrorCode_t STPTI_GetPacketArrivalTime(STPTI_Handle_t Hndl, STPTI_TimeStamp_t * ArrivalTime_p,
                                          U16 *ArrivalTimeExtension_p)
{
    STCLKRV_Print(("GPAT dummy function\n"));
    return (ST_NO_ERROR + 1); /* return error */
}

ST_ErrorCode_t STPTI_GetCurrentPTITimer(ST_DeviceName_t DeviceName,
                                          STPTI_TimeStamp_t * TimeStamp)
{
    STCLKRV_Print(("GPAT dummy function\n"));
    return (ST_NO_ERROR + 1); /* return error */
}
#endif /* CLKRV_TESTING==2 */
#endif /* !STCLKRV_NO_PTI */

#endif  /* CLKRV_TESTING */

/****************************************************************************
Name         : STCLKRV_GetRevision()

Description  : Returns a pointer to the Driver Revision String.
               May be called at any time.

Parameters   : None

Return Value : ST_Revision_t

See Also     : ST_Revision_t
 ****************************************************************************/

ST_Revision_t STCLKRV_GetRevision( void )
{
    return( stclkrv_DriverRev );
}

/****************************************************************************
Name         : STCLKRV_Init()

Description  : Initializes the Clock Recovery before use.

Parameters   : ST_DeviceType_t name needs to be supplied - should not be NULL,
               STCLKRV_InitParams_t struct. pointer appropriately filled by app.

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_FEATURE_NOT_SUPPORTED  No multiple instance support(5100)
               ST_ERROR_ALREADY_INITIALIZED    Device already initialized
               ST_ERROR_BAD_PARAMETER          One or more parameters invalid
               ST_ERROR_NO_MEMORY              memory_allocate failed
               STCLKRV_ERROR_HANDLER_INSTALL   Unable to install STPTI Callback
               ST_ERROR_INTERRUPT_INSTALL      Unable to install internal ISR
               STCLKRV_ERROR_EVT_REGISTER      Problem registering events

See Also     : STCLKRV_InitParams_t
               STCLKRV_Term()
 ****************************************************************************/

ST_ErrorCode_t STCLKRV_Init( const ST_DeviceName_t Name,
                             const STCLKRV_InitParams_t *InitParams )
{

    ST_ErrorCode_t ReturnCode              = ST_NO_ERROR;
    ST_ErrorCode_t RetCode                 = ST_NO_ERROR;
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;
    STCLKRV_ControlBlock_t *NextElem = NULL;
    ST_ErrorCode_t IntReturn               = 0;
    U32 i                                  = 0;

    /* Perform parameter validity checks */
    if (( Name                == NULL)   ||           /* NULL Name ptr          */
        (InitParams           == NULL)   ||           /* NULL structure ptr     */
        (Name[0]              == '\0' )  ||           /* Device Name undefined  */
        (strlen( Name )       >= ST_MAX_DEVICE_NAME)) /* string too long?       */
    {
        return( ST_ERROR_BAD_PARAMETER );
    }

    /* Device of that name already init */
    if (FindInstanceByName(Name) != NULL)
    {
        return (ST_ERROR_ALREADY_INITIALIZED);
    }

    if((InitParams->DeviceType < STCLKRV_DEVICE_TYPE_5100) ||
       (InitParams->DeviceType > STCLKRV_DEVICE_TYPE_BASELINE_ONLY))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -