📄 tmdlao.c
字号:
/*
* 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 + -