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

📄 stclkrv.c

📁 st40 clock driver source code. 用于st40 linux
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -