📄 tmdlao.c
字号:
aoOpenExit:
tmosalSystemMutexExit();
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoInstanceSetup(Int instance, ptmdlAoInstanceSetup_t pSetup)
{
paoInstVars_t instVars = (paoInstVars_t) instance;
tmbslAoParam_t param;
tmbslAoConfig_t *boardAOConfig = instVars->boardAOConfig;
UInt32 mmioBase = boardAOConfig->mmioBase;
tmErrorCode_t err = TM_OK;
Float fOsclk;
ptmbslCoreSystemInfo_t SysInfo;
UInt32 frameLength;
UInt32 sckDiv;
UInt32 rightPos;
tmosalIntDescriptor_t descriptor;
UInt8 cpuIndex;
DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoInstanceSetup(%x,%x)\n", instance, pSetup));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
tmAssert (pSetup, TMDL_ERR_AO_NULL_PARAMETER);
tmAssert ((pSetup->size % AO_SIZE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);
tmAssert (((UInt) pSetup->base1 % AO_BASE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);
tmAssert (((UInt) pSetup->base2 % AO_BASE_GRANULARITY) == 0, TMDL_ERR_AO_INVALID_SIZE);
if (instVars->magic != AO_MAGIC)
return TMDL_ERR_AO_NOT_OWNER;
//tmosalSystemMutexEnter();
param.aoUnit = instVars->unitName;
/*devlib is not bothered about the DAC this is used by the channel
component to tell the ABSL component about the DAC nr for the unit */
param.dacNr = 0;
param.audioTypeFormat = pSetup->audioTypeFormat;
param.audioSubtypeFormat = pSetup->audioSubtypeFormat;
param.sRate = pSetup->sRate;
param.size = pSetup->size;
param.output = pSetup->output;
param.callBack = pSetup->callBack;
param.pContextArgument = pSetup->pContextArgumentToCallBack;
param.eventsTobeEnabled = pSetup->eventsTobeEnabled;
if (!(param.audioTypeFormat & boardAOConfig->audioTypeFormats))
{
err = TMDL_ERR_AO_UNSUPPORTED_DATATYPE;
goto aoInstanceSetupExit;
}
if (!(param.audioSubtypeFormat & boardAOConfig->audioSubtypeFormats))
{
err = TMDL_ERR_AO_UNSUPPORTED_DATASUBTYPE;
goto aoInstanceSetupExit;
}
if (!(param.output & boardAOConfig->audioAdapters))
{
err = TMDL_ERR_AO_UNSUPPORTED_OUTPUT;
goto aoInstanceSetupExit;
}
if (param.sRate > boardAOConfig->maxSRate)
{
err = TMDL_ERR_AO_SRATE_TOO_HIGH;
goto aoInstanceSetupExit;
}
if (param.sRate < boardAOConfig->minSRate)
{
err = TMDL_ERR_AO_SRATE_TOO_LOW;
goto aoInstanceSetupExit;
}
/* get the processor type of the TriMedia CPU */
err = tmbslCoreGetSystemInfo(&SysInfo);
if (err) return err;
for(cpuIndex=0; cpuIndex < SysInfo->numCpu; cpuIndex++)
if(SysInfo->pCpuInfo[cpuIndex].cpuType == tmbslCoreCpuTypeTM) break;
/*calculate the required oversampling clock */
fOsclk = boardAOConfig->osclkFactor * param.sRate; /* n X Fs */
if(boardAOConfig->enableOsclk)
{
if(err =(aoSetClock(instVars->unitName, mmioBase, fOsclk,
SysInfo->pCpuInfo[cpuIndex].cpuClockFreq)))
return err;
}
/* setup audio out unit as per the requirement by audio board config structure */
//Enable Audio out serial Clock ie,SCK
if(boardAOConfig->enableSerialMaster)
aoEnableSER_MASTERM(mmioBase); /* audio out is the serial master */
else
aoDisableSER_MASTERM(mmioBase); /* audio out is the serial slave */
/* setup for I2S transfer ie MSB first and left channel data on falling edge*/
aoMsbFirstM(mmioBase); /* MSB bit is transmitted first (I2S standard) */
aoStartFallingEdgeWSM(mmioBase); /* send left channel sample on Falling edge(I2S standard) */
aoSampleRisingCLOCK_EDGEM(mmioBase); /* sample on rising edge */
aoSetSSPOSM(mmioBase, 0); /* Left and right channel start at bit 0 */
aoDisableSIGN_CONVERTM(mmioBase); /* Disable Sign Convert for MSB */
aoDisableWS_PULSEM(mmioBase); /* word strobe in pulse mode */
#if (TMFL_PNX_ID == 1300) // PNX1300/TM1300
#ifdef __LITTLE_ENDIAN__
aoEnableLITTLE_ENDIANM(mmioBase);
#else
aoDisableLITTLE_ENDIANM(mmioBase);
#endif
#endif
/*Initial state of the device */
// aoDisableTRANS_ENABLEM(mmioBase); /* intially disabeled */
aoSetSIZEM(mmioBase, pSetup->size);
/* setup for I2S transfer physical parameters */
switch (param.audioSubtypeFormat) {
case apfMono16: /* one channel Audio */
{
frameLength = boardAOConfig->frameLength[MONO16];
aoSetTRANS_MODEM(mmioBase, 2); /* transfer mode is mono 16*/
aoSetNR_CHANM(mmioBase, 0);
break;
}
case apfMono32: /* one channel Audio, 32-bit */
{
frameLength = boardAOConfig->frameLength[MONO32];
aoSetTRANS_MODEM(mmioBase, 0); /* transfer mode is mono 32*/
aoSetNR_CHANM(mmioBase, 0);
break;
}
case apfStereo16: /* Two channel Audio */
{
frameLength = boardAOConfig->frameLength[STEREO16];
aoSetTRANS_MODEM(mmioBase, 3); /* transfer mode is Stereo 16*/
aoSetNR_CHANM(mmioBase, 0);
break;
}
case apfStereo32: /* Two channel Audio, 32-bit */
{
frameLength = boardAOConfig->frameLength[STEREO32];
aoSetTRANS_MODEM(mmioBase, 1); /* transfer mode is Stereo 32*/
aoSetNR_CHANM(mmioBase, 0);
break;
}
case apfFourCh_3_1_0_16: /* Four channel Audio */
case apfFourCh_2_2_0_16: /* Four channel Audio */
case apfFourCh_2_1_1_16: /* Four channel Audio */
case apfFourCh_3_0_1_16: /* Four channel Audio */
{
frameLength = boardAOConfig->frameLength[STEREO16];
aoSetTRANS_MODEM(mmioBase, 3); /* transfer mode is stereo 16*/
aoSetNR_CHANM(mmioBase, 1); /* no of channels 4 ie, 2 stereo */
break;
}
case apfFourCh_3_1_0_32: /* Four channel Audio, 32-bit */
case apfFourCh_2_2_0_32: /* Four channel Audio, 32-bit */
case apfFourCh_2_1_1_32: /* Four channel Audio, 32-bit */
case apfFourCh_3_0_1_32: /* Four channel Audio, 32-bit */
{
frameLength = boardAOConfig->frameLength[STEREO32];
aoSetTRANS_MODEM(mmioBase, 1); /* transfer mode is Stereo 32*/
aoSetNR_CHANM(mmioBase, 1); /* no of channels 4 ie, 2 stereo */
break;
}
case apfFiveDotOne16: /* Six Channel Audio */
{
frameLength = boardAOConfig->frameLength[STEREO16];
aoSetTRANS_MODEM(mmioBase, 3); /* transfer mode is stereo 16*/
aoSetNR_CHANM(mmioBase, 2); /* no of channels 6 ie, 3 stereo */
break;
}
case apfFiveDotOne32: /* Six Channel Audio, 32-bit */
{
frameLength = boardAOConfig->frameLength[STEREO32];
aoSetTRANS_MODEM(mmioBase, 1); /* transfer mode is Stereo 32*/
aoSetNR_CHANM(mmioBase, 2); /* no of channels 6 ie, 3 stereo */
break;
}
case apfSevenDotOne16: /* Eight Channel Audio */
{
frameLength = boardAOConfig->frameLength[STEREO16];
aoSetTRANS_MODEM(mmioBase, 3); /* transfer mode is stereo 16*/
aoSetNR_CHANM(mmioBase, 3); /* no of channels 5 ie, 4 stereo */
break;
}
case apfSevenDotOne32: /* Eight Channel Audio, 32-bit */
{
frameLength = boardAOConfig->frameLength[STEREO32];
aoSetTRANS_MODEM(mmioBase, 1); /* transfer mode is Stereo 32*/
aoSetNR_CHANM(mmioBase, 3); /* no of channels 8 ie, 4 stereo */
break;
}
default:
/* unsupported subtype */
return(TMDL_ERR_AO_UNSUPPORTED_FORMAT);
}
sckDiv = (boardAOConfig->osclkFactor/frameLength)-1;
rightPos = frameLength/2;
aoSetWSDIVM(mmioBase, (frameLength-1));
aoSetSCKDIVM(mmioBase, sckDiv);
aoSetLEFTPOSM(mmioBase, 0+15); /* position of left channel in the word is bit 0*/
aoSetRIGHTPOSM(mmioBase, rightPos+15); /* position of Right channel in the word is bit 0*/
if (instVars->boardAOConfig->initFunc)
{
if (!instVars->initialized)
{
err = instVars->boardAOConfig->initFunc(&(instVars->bslInstance), ¶m);
if (err != TM_OK)
goto aoInstanceSetupExit;
}
}
/* clear all interrupt sources to be sure */
MMIO(mmioBase + AO_CTL_OFFSET) |= AO_ACK_UDR | AO_ACK_HBE | AO_ACK_HBE | AO_ACK2 | AO_ACK1;
aoSetBASE1M(mmioBase, pSetup->base1);
aoSetBASE2M(mmioBase, pSetup->base2);
MMIO(mmioBase + AO_CTL_OFFSET) = (MMIO(mmioBase + AO_CTL_OFFSET) &
~(AO_BUF1_INTEN | AO_BUF2_INTEN | AO_UDR_INTEN | AO_HBE_INTEN))
| (pSetup->buf1emptyEnable ? AO_BUF1_INTEN : 0)
| (pSetup->buf2emptyEnable ? AO_BUF2_INTEN : 0)
| (pSetup->underrunEnable ? AO_UDR_INTEN : 0)
| (pSetup->hbeEnable ? AO_HBE_INTEN : 0);
/*Extract the current Interrupt state */
instVars->intState = MMIO(mmioBase + AO_CTL_OFFSET) & (0xF << 4);
if (!instVars->initialized) /* To avoid the following calls being made in ISR */
{
/* get osal interrupt instance */
err = tmosalIntInstanceGetSetup (instVars->handle, &descriptor);
if (err != TM_OK)
goto aoInstanceSetupExit;
if (pSetup->isr) /* Null means poll - no ISR */
{
descriptor.pHandler = (void (*)(void *))pSetup->isr;
descriptor.pContextArgument = pSetup->pContextArgumentToIsr;
descriptor.enabled = True;
descriptor.interruptible = False;
err = tmosalIntInstanceSetup(instVars->handle, &descriptor);
if (err != TM_OK)
goto aoInstanceSetupExit;
}
instVars->setup = *pSetup; /* Last possible error past, so copy to
* static storage */
instVars->initialized = True;
/*Now setup the output */
tmdlAoInstanceConfig(instance,TMBSL_CMD_AO_SET_OUTPUT,(Pointer)pSetup->output);
}
aoInstanceSetupExit:
//tmosalSystemMutexExit();
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoClose(Int instance)
{
paoInstVars_t instVars = (paoInstVars_t) instance;
tmErrorCode_t err = TM_OK;
UInt32 mmioBase = instVars->boardAOConfig->mmioBase;
DBG_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoClose(%x)\n", instance));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
if (instVars->magic != AO_MAGIC)
return TMDL_ERR_AO_NOT_OWNER;
tmosalSystemMutexEnter();
/* set to system clock ( 27 MHz ) for soft aoRESETM() */
aoResetClock(instVars->unitName, mmioBase ); /* to workaround hardware PR */
/* reset aoDevice */
aoRESETM(mmioBase);
// Viper1/Viper2/PNX1500
#if (TMFL_PNX_ID != 1300)
if (instVars->gpioInstance != 0)
err = tmdlGpioClose(instVars->gpioInstance);
#endif
err = tmosalIntDestroy(instVars->handle);
/* shutdown external peripheral driver */
if (instVars->boardAOConfig->deinitFunc)
err = instVars->boardAOConfig->deinitFunc(instVars->unitName);
aoCaps.unitCapabilities[instVars->unitIndex].numCurrentInstances--;
instVars->magic = 0;
free(instVars);
if( --noofOpens == 0)
{
noofOpens = 0;
aoInitDone = False;
memset(&aoCaps, 0, sizeof(aoCapabilitiesList_t));
}
tmosalSystemMutexExit();
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoStop(Int instance)
{
paoInstVars_t instVars = (paoInstVars_t) instance;
tmErrorCode_t err = TM_OK;
UInt32 mmioBase = instVars->boardAOConfig->mmioBase;
DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoStop(%x)\n", instance));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
if (instVars->magic != AO_MAGIC)
return TMDL_ERR_AO_NOT_OWNER;
if (!instVars->initialized)
{
return TMDL_ERR_AO_INIT_REQUIRED;
}
aoDisableTRANS_ENABLEM(mmioBase);
/* Disable clock Here */
if (instVars->boardAOConfig->stopFunc)
{
err = instVars->boardAOConfig->stopFunc(instVars->unitName);
}
return err;
}
/**************************************************************************************/
extern tmErrorCode_t tmdlAoStart(Int instance)
{
paoInstVars_t instVars = (paoInstVars_t) instance;
tmErrorCode_t err = TM_OK;
UInt32 mmioBase = instVars->boardAOConfig->mmioBase;
DBG_ISR_PRINT((DBG_UNIT_NAME, DBG_LEVEL_1,"Entered tmdlAoStart(%x)\n", instance));
tmAssert (instance, TMDL_ERR_AO_NOT_OWNER);
if (instVars->magic != AO_MAGIC)
return TMDL_ERR_AO_NOT_OWNER;
if (!instVars->initialized)
{
return TMDL_ERR_AO_INIT_REQUIRED;
}
/* Enable the clock Here */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -