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

📄 stclkrv.c

📁 st40 clock driver source code. 用于st40 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
                ExtendedSTC->BaseBit32 = UpdatedSTC.BaseBit32;
                ExtendedSTC->BaseValue = UpdatedSTC.BaseValue;
                ExtendedSTC->Extension = UpdatedSTC.Extension;

                ReturnCode = ST_NO_ERROR;       /* everything OK */
            }

        }/* else failed to obtain STC */

    } /* else not stc baseline mode */

    return ReturnCode;
}

/****************************************************************************
Name         : STCLKRV_GetSTC()

Description  : Returns the decoder clock time 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 baselining is enabled the STCbaseline is incremented based
               on the time elapsed since last update.

Parameters   : STCLKRV_Handle_t Handle
               U32 *STC   pointer to caller's System Time Clock variable

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                   No errors occurred
               ST_ERROR_BAD_PARAMETER        One or more invalid parameters
               ST_ERROR_INVALID_HANDLE       Not open or invalid handle
               STCLKRV_ERROR_PCR_UNAVAILABLE Accurate Decode unavailable

See Also     : STCLKRV_Open()
 ****************************************************************************/

ST_ErrorCode_t STCLKRV_GetSTC( STCLKRV_Handle_t Handle,
                               U32 *STC )
{
    ST_ErrorCode_t ReturnCode = STCLKRV_ERROR_PCR_UNAVAILABLE;
    U32  ArrivalTime;
    U32  ElapsedTime;
    BOOL STCErrorRet = TRUE;
    STCLKRV_ControlBlock_t *TmpCB_p;

    clock_t MicroSecsSinceLastCall;
    STCLKRV_ExtendedSTC_t FreerunIncSTC;
    STCLKRV_ExtendedSTC_t UpdatedSTC;

    U32 STCReferenceControl;
    BOOL FreerunSTCActive;
    BOOL ActvRefPCRValid;
    clock_t FreerunSTCTimer;
    STCLKRV_ExtendedSTC_t STCBaseline;
    U32 ActvRefPCRBaseValue;
    U32 ActvRefPCRTime;
#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 );
    }

    if( STC == NULL )      /* NULL variable ptr? */
    {
        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;
    ActvRefPCRBaseValue = TmpCB_p->ActvRefPcr.PcrBaseValue;
    ActvRefPCRTime      = TmpCB_p->ActvRefPcr.Time;
    STPTISlot           = TmpCB_p->Slot;
    STCOffset           = TmpCB_p->OffsetInSTC;
    LeaveCriticalSection();

    /* For STC basline mode, freerunning is forced  */
    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
#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 data 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 = STCCurrentTime.LSW;
#endif
            LeaveCriticalSection();
        }

        /* Return updated 90kHz baseline value */
        *STC = UpdatedSTC.BaseValue + STCOffset;

        ReturnCode = ST_NO_ERROR;

    }
    else
    {
        if ((STCReferenceControl == (U32)STCLKRV_STC_SOURCE_PCR) && (ActvRefPCRValid))
        {
#ifdef ST_5188
            STCErrorRet = STDEMUX_GetCurrentTimer(TmpCB_p->InitPars.PTIDeviceName,
                                                                   &STCCurrentTime);
            ArrivalTime = STCCurrentTime.LSW*CONV90K_TO_27M;
#else
            STCErrorRet = GetPacketArrivalTime(STPTISlot, &ArrivalTime);
#endif
            if (!STCErrorRet)
            {

                /* Calulate time elapsed since reference point */

                /*  correctly handles wrap */
                ElapsedTime = (STOS_time_minus(ArrivalTime, ActvRefPCRTime)
                                             / CONV90K_TO_27M);

#if defined (CLKRV_FILTERDEBUG)
                STCLKRV_Print(("STCLKRV_GetSTC %u-%u=%u*300\n",
                             ArrivalTime, ActvRefPCRTime, ElapsedTime));
#endif

                /* restrict elapsed time to reasonable level */
                if ((ElapsedTime >> PCR_STALE_SHIFT) == 0)
                {
                    *STC = ActvRefPCRBaseValue + ElapsedTime + STCOffset;
                    ReturnCode = ST_NO_ERROR;       /* everything OK */
                }
                else
                {
                    STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
                                  "%u-%u=%u*300 judged stale\n",
                                  ArrivalTime, ActvRefPCRTime, ElapsedTime));
                }

            }
            else
            {
                STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
                              "STCLKRV_GetSTC: GetPacketArrivalTime failed\n"));
            }
        }
        else
        {
            STTBX_Report((STTBX_REPORT_LEVEL_ERROR,
                          "STCLKRV_GetSTC: no valid PCR reference\n"));
        }
    }

    return ReturnCode;
}

/****************************************************************************
Name         : STCLKRV_SetSTCBaseline

Description  : Loads given STC baseline value to UserBaseline storage area.
               Takes time stamp for reference.

Parameters   : STCLKRV_Handle_t Handle
               STCLKRV_ExtendedSTC_t STC comprising 90KHz base value, bit32
               and 27Mhz extension value.

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_SetSTCBaseline(STCLKRV_Handle_t Handle,
                                      STCLKRV_ExtendedSTC_t *STC)
{
    /* Temp ptr into instance list */
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;
#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
#endif
    ST_ErrorCode_t ReturnCode = ST_NO_ERROR;

    /* Check handle is valid */
    TmpCB_p = FindInstanceByHandle(Handle);

    if (TmpCB_p  == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }

#if !defined (ST_5100)
#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 (ST_ERROR_UNKNOWN_DEVICE);
    }
#endif


    /* Exclusive access to data */
    EnterCriticalSection();

    /* Write given value to user baseline */
    TmpCB_p->STCBaseline.STC.BaseBit32 = STC->BaseBit32;
    TmpCB_p->STCBaseline.STC.BaseValue = STC->BaseValue;
    TmpCB_p->STCBaseline.STC.Extension = STC->Extension;
    /* Free run control */
    TmpCB_p->FreerunSTC.Active = TRUE;
#if defined (ST_5100)
    GetHPTimer(HPTTicks);
    TmpCB_p->FreerunSTC.Timer = HPTTicks;
#else
    TmpCB_p->FreerunSTC.Timer = STCCurrentTime.LSW;
#endif

    LeaveCriticalSection();

    return (ReturnCode);
}

/****************************************************************************
Name         : STCLKRV_SetSTCOffset

Description  : Sets the offset to be added in base value of returned STC
               value from GET_XXXSTC APIs.

Parameters   : STCLKRV_Handle_t Handle
               S32 Offset given in 90kHz units

Return Value : ST_ErrorCode_t specified as
               ST_NO_ERROR                     No errors determined
               ST_ERROR_INVALID_HANDLE         Invalid Handle

See Also     : STCLKRV_GetExtendedSTC()
 ****************************************************************************/
ST_ErrorCode_t STCLKRV_SetSTCOffset( STCLKRV_Handle_t Handle,
                                     S32 Offset)
{
    /* Temp ptr into instance list */
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;
    ST_ErrorCode_t ReturnCode = ST_NO_ERROR;

    /* Check handle is valid */
    TmpCB_p = FindInstanceByHandle(Handle);

    if (TmpCB_p  == NULL)
    {
        return (ST_ERROR_INVALID_HANDLE);
    }

    EnterCriticalSection();
    TmpCB_p->OffsetInSTC = Offset;
    LeaveCriticalSection();

    return ReturnCode;

}


/****************************************************************************
Name         : STCLKRV_InvDecodeClk()

Description  : Invalidates the PCR reference valid flag internally, causing
               rapid PCR re-basing.

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_Open()
 ****************************************************************************/

ST_ErrorCode_t STCLKRV_InvDecodeClk( STCLKRV_Handle_t Handle )
{
    STCLKRV_ControlBlock_t *TmpCB_p = NULL;     /* Temp ptr into instance list */

    /* 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)
    {
        /* Protect and update data */
        EnterCriticalSect

⌨️ 快捷键说明

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