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

📄 tmdlao.c

📁 Nexperia系统声音实现的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003 Koninklijke Philips
 * Electronics N V. All rights reserved.
 *
 * This source code and any compilation or derivative thereof is the proprietary
 * information of Koninklijke Philips Electronics N V and is confidential in
 * nature. Under no circumstances is this software to be exposed to or placed
 * under an Open Source License of any type without the express written
 * permission of Koninklijke Philips Electronics N V.
 *
 * #############################################################################
 *
 * Module: %name:  tmdlAo.c % %version:  51 %
 *
 * %date_created:  Wed May 19 15:15:53 2004 % %created_by:  jchomysz %
 *
 * %date_modified:  % %derived_by:  jchomysz %
 *
 * #############################################################################
 */

/*
 *  Description              :
 *
 *  TriMedia audio output library.
 *  Supports control and use of TriMedia audio output hardware
 *
 *  This is part of the TriMedia device libraries.
 *
 *  The AO driver relies on the board support package.
 *
 *  TO DO: Add new method of memory handling, remove references to "memInitDone",
 *
 */

#include "tmFlags.h" /*DVP build flags*/

/* normally, these come from the Makefile */
#ifndef MAJOR_VERSION
#define MAJOR_VERSION   3
#endif
#ifndef MINOR_VERSION
#define MINOR_VERSION   0
#endif
#ifndef BUILD_VERSION
#define BUILD_VERSION   0
#endif

#include "tmNxTypes.h"
#include "stdlib.h"
#include <string.h>
#include "tmbslCore.h"
#include "tmosal.h"
#include "tmAOmmio.h"
#include "tmbslAo.h"
#include "tmdlAo.h"

// Viper1/Viper2/PNX1500
#if   (TMFL_PNX_ID != 1300)
#include "tmdlGpio.h"
#endif
#include <tmDbg.h>

/*-------------------------------defines-------------------------------------*/
#define AO_MAGIC               0x75289357
#define DATA_INVALID           0xFFFFFFFFU // Data invalid/not initialized

#define tmAssert(x,y) DBG_ASSERT2(x,("%d",y))

#define DBG_UNIT_NAME  TMDL_AO_DBG_VAR
#define DBG_UNIT_STR   TMDL_AO_DBG_STR

DBG_UNIT_STATIC(DBG_UNIT_NAME)

/*--------------------------------types--------------------------------------*/
typedef struct aoInstanceInfo_t {
    UInt32                magic;
    tmdlAoInstanceSetup_t setup;
    Bool                  initialized;
    tmUnitSelect_t        unitName;
    Int                   unitIndex;
    tmbslAoConfig_t      *boardAOConfig;
    tmInstance_t          gpioInstance;
    tmInstance_t          clockInstance;
    tmInstance_t          bslInstance;
    tmosalIntHandle_t     handle;
    UInt32                intState;
    } aoInstVars_t, *paoInstVars_t;

typedef  struct
{
    UInt32                numberOfUnits;
    tmUnitSelect_t        unitNumbers[MAX_AO_UNITS];
    tmdlAoCapabilities_t  unitCapabilities[MAX_AO_UNITS];
} aoCapabilitiesList_t;



/*-------------------------------statics-------------------------------------*/
static aoCapabilitiesList_t aoCaps ;


static UInt8                 noofOpens = 0;
static Bool                  aoInitDone  = False;

static tmErrorCode_t prepareCapabilities(void);

static tmErrorCode_t getUnitIndex(tmUnitSelect_t unitName, Int *unitIndex);

static tmErrorCode_t
aoSetClock(
     tmUnitSelect_t unitName,
     UInt32         mmioBase,
     Float          fOsclk,
     UInt32         cpuFreq);
static tmErrorCode_t
aoGetClock(
     tmUnitSelect_t unitName,
     UInt32         mmioBase,
     Float          *fOsclk,
     UInt32         cpuFreq
     );
static tmErrorCode_t
aoResetClock(
     tmUnitSelect_t unitName,
     UInt32         mmioBase
     );
static tmErrorCode_t
aoUnResetClock(
     tmUnitSelect_t unitName,
     UInt32         mmioBase
     );


/*-------------------------global functions------------------------------------*/
/* TO DO: make it re entrant */
/* TO DO: check the SW version of GPIO,Clock,BSL,OSAL */
extern tmErrorCode_t tmdlAoGetSWVersion (ptmSWVersion_t  pAoVersionInfo)
{
    static tmErrorCode_t aoSwStatus  = DATA_INVALID,err; // AO BSL version status
    tmSWVersion_t        aoSwVersion;                    // AO BSL interface version info
    tmbslAoConfig_t      *dummyConfig;
    UInt8                i           = 0;

   DBG_ATTACH_MODULE(DBG_UNIT_NAME, DBG_UNIT_STR, DBG_PREREGISTER);
   DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetSWVersion(%x)\n", pAoVersionInfo));

    /* Here we verify the SW version of the underlying Audio BSL component. This is done
       only once when aoSwStatus contains invalid data */
    if ((aoSwStatus == DATA_INVALID))
    {
        if (!aoInitDone)
        {
            err = prepareCapabilities();
            if (err != TM_OK)
                return err;
        }
        for (i = 0; i < aoCaps.numberOfUnits; i++)
        {
             tmbslAoGetInterface(aoCaps.unitNumbers[i], &dummyConfig);
             if (dummyConfig->getSWVersionFunc)
             {
                 aoSwStatus = dummyConfig->getSWVersionFunc (&aoSwVersion);
                 if (aoSwStatus == TM_OK)
                 {
                     if (aoSwVersion.compatibilityNr != TMBSL_AO_COMPATIBILITY_EXP)
                     {
                         aoSwStatus = TMDL_ERR_AO_COMPATIBILITY;
                         break;
                     }

                     if (aoSwVersion.majorVersionNr < TMBSL_AO_MAJOR_VERSION_EXP)
                     {
                         aoSwStatus = TMDL_ERR_AO_MAJOR_VERSION;
                         break;
                     }
                 }
             }
        }
        if (i == 0)
            return TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;
    }

    if (aoSwStatus == TM_OK)
    {
        pAoVersionInfo->compatibilityNr = TMDL_AO_COMPATIBILITY_NR;
        pAoVersionInfo->majorVersionNr  = TMDL_AO_MAJOR_VERSION_NR;
        pAoVersionInfo->minorVersionNr  = TMDL_AO_MINOR_VERSION_NR;
    }

    return (aoSwStatus);
}
/**************************************************************************************/
/* TO DO: 1. Make it renterant 2. if number of units in HW is zero still it loops
          everytime this function is called */
extern tmErrorCode_t tmdlAoGetNumberOfUnits(UInt32 *pNumberOfUnits)
{
    UInt32 i = 0;
    tmbslAoConfig_t *dummyConfig;
    static UInt32 numberOfUnits = 0;

   DBG_ATTACH_MODULE(DBG_UNIT_NAME, DBG_UNIT_STR, DBG_PREREGISTER);
    DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetNumberOfUnits(%x)\n", pNumberOfUnits));
    tmAssert (pNumberOfUnits, TMDL_ERR_AO_NULL_PARAMETER);

    if (numberOfUnits == 0)
       for (i=0; i <= MAX_AO_UNITS; i++)
            if (tmbslAoGetInterface((tmUnitSelect_t)i, &dummyConfig) == TM_OK)
                numberOfUnits++;

    *pNumberOfUnits = numberOfUnits;
    return TM_OK;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoGetCapabilitiesM(ptmdlAoCapabilities_t *pCap, tmUnitSelect_t unitName)
{
    tmErrorCode_t    err        = TM_OK;
    tmbslAoConfig_t *AOConfig;
    Int              unitIndex  = 0;

   DBG_ATTACH_MODULE(DBG_UNIT_NAME, DBG_UNIT_STR, DBG_PREREGISTER);
    DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoGetCapabilitiesM(%x,%d)\n", pCap, unitName));
    tmAssert (pCap, TMDL_ERR_AO_NULL_PARAMETER);

    if (!aoInitDone)
    {
        err = prepareCapabilities();
        if (err != TM_OK)
            return err;
    }

    if (getUnitIndex(unitName, &unitIndex))
        return TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;

    if (TM_OK != tmbslAoGetInterface(unitName, &AOConfig))
    {
        /* this should never happen, since we have just checked the */
        /* number of units */
        /* FIXME : anyway, the error code should not be not supported */
        return TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;
    }

    /* Update capabilities, prepareCapabilities() only writes initial values into this struct.
       Some of the values can change (depending on the selected input). */
    aoCaps.unitCapabilities[unitIndex].maxSRate = (Float) AOConfig->maxSRate;
    aoCaps.unitCapabilities[unitIndex].minSRate = (Float) AOConfig->minSRate;

    if ((AOConfig->codecName != Null))
    {
        strncpy(aoCaps.unitCapabilities[unitIndex].codecName, AOConfig->codecName, HAL_DEVICE_NAME_LENGTH);
    }

    *pCap = &aoCaps.unitCapabilities[unitIndex];

    return TM_OK;
}

/**************************************************************************************/
extern tmErrorCode_t tmdlAoOpenM(Int *instance, tmUnitSelect_t unitName)
{
    paoInstVars_t                   instVars   = Null;
    tmbslAoConfig_t                *aoBoardConfig;
    tmErrorCode_t                   err        = TM_OK;
    tmosalIntCreateFlags_t          flags;
    // Viper1/Viper2/PNX1500
#if   (TMFL_PNX_ID != 1300)
    tmdlGpioPinsInstanceSetup_t     gpioPinsSetup;
#endif
    Int                             unitIndex = 0;
    ptmbslCoreSystemInfo_t          SysInfo;
    UInt8                           cpuIndex;

    DBG_ATTACH_MODULE(DBG_UNIT_NAME, DBG_UNIT_STR, DBG_PREREGISTER);
    DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoOpenM(%x,%d)\n", instance, unitName));
    tmAssert (instance != Null, TMDL_ERR_AO_NULL_PARAMETER);

    err = tmbslAoGetInterface(unitName, &aoBoardConfig);
    if (err != TM_OK)
        return TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;

    tmosalSystemMutexEnter();

    if (!aoInitDone)
    {
        /* make sure the capabilities are valid */
        err = prepareCapabilities();
        if (err != TM_OK)
            goto aoOpenExit;
    }

    if (getUnitIndex(unitName, &unitIndex))
    {
        err = TMDL_ERR_AO_NOT_AVAILABLE_IN_HW;
        goto aoOpenExit;
    }

    if (aoCaps.unitCapabilities[unitIndex].numCurrentInstances >=
        aoCaps.unitCapabilities[unitIndex].numSupportedInstances)
    {
        err = TMDL_ERR_AO_NO_MORE_INSTANCES;
        goto aoOpenExit;
    }

    /* set to system clock ( 27 MHz ) for soft aoRESETM() */
    aoResetClock(instVars->unitName, aoBoardConfig->mmioBase ); /* to workaround hardware PR */

    /* allocate and initialize instVars struct */
    instVars = (paoInstVars_t)calloc(1,sizeof(aoInstVars_t));
    if(instVars == Null)
        {
            err = TMDL_ERR_AO_MEMALLOC_FAILED;
            goto aoOpenExit;
        }

    /* claim your Interrupts from the OSAL */
    flags = tmosalIntCreateFlagNone;
    err = tmosalIntCreate(aoBoardConfig->intName,&instVars->handle,flags);
    if (err != TM_OK)
    {
        free(instVars);
        goto aoOpenExit;
    }


    instVars->magic         = AO_MAGIC;
    instVars->unitName      = unitName;
    instVars->unitIndex     = unitIndex;
    instVars->boardAOConfig = aoBoardConfig;
    instVars->initialized   = False;
    instVars->gpioInstance  = 0;

    /**Get processor capabilities ****/
    tmbslCoreGetSystemInfo(&SysInfo);
    for(cpuIndex=0; cpuIndex < SysInfo->numCpu; cpuIndex++)
    	  if(SysInfo->pCpuInfo[cpuIndex].cpuType == tmbslCoreCpuTypeTM) break;

// Viper1/Viper2/PNX1500
#if   (TMFL_PNX_ID != 1300)
    //if (SysInfo->pCpuInfo[cpuIndex].cpuModel == tmbslCoreCpuModelTM32)
    {

       /* Claim your GPIO pins from gpio devlib */
       if (aoBoardConfig->noOfGpioPins)
       {

         /* Get the default instance setup */
         // tmdlGpioGetModuleInfo(TMDL_CALLING_MODULE_ID,TMDL_CALLING_UNIT_ID, gpioPinBuf, &gpioCount);
         err = tmdlGpioOpen(&(instVars->gpioInstance));

         if(err) goto aoOpenExit;

         gpioPinsSetup.mode    = tmdlGpioModePrimary;
         gpioPinsSetup.count   = aoBoardConfig->noOfGpioPins;
         gpioPinsSetup.pPinBuf = aoBoardConfig->gpioPins;

         err = tmdlGpioPinsInstanceSetup(instVars->gpioInstance, &gpioPinsSetup);
         if (err != TM_OK)
         {
            tmdlGpioClose(instVars->gpioInstance);
            tmosalIntDestroy(instVars->handle);
            free(instVars);
            goto aoOpenExit;
         }
       }
    }
#endif

    /* reset the audio output peripheral */
    aoRESETM(aoBoardConfig->mmioBase);

    *instance = (Int) instVars;
    aoCaps.unitCapabilities[unitIndex].numCurrentInstances++;
    noofOpens++;

⌨️ 快捷键说明

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