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

📄 stclkrv.c

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