📄 audiodriver.c
字号:
*pFlashA_PortA_Dir = 0x1;
static unsigned char ucActive_LED = 0x01;
// write to Port A to reset AD1836
*pFlashA_PortA_Data = 0x00;
// wait to recover from reset
for (i=0; i<0xf0000; i++) asm("nop;");
// write to Port A to enable AD1836
*pFlashA_PortA_Data = ucActive_LED;
// wait to recover from reset
for (i=0; i<0xf0000; i++) asm("nop;");
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
*
* Function: InitAudioDriver
*
* Description: This function open the AD1836 device instance.
* It uses the device instance to initialize registers in the AD1836
* codec and configures them to the TDM 8 channel transferring mode.
* Two buffers (RX and TX) are required and configured
* for the chained loopback DMA transfer buffering mode
* allowing double buffering.
*
*********************************************************************/
#ifndef NO_OPTIMIZE
#pragma optimize_for_space
#endif
static void InitAudioDriver(void)
{
unsigned int result;
// reset audio codec
reset_AD1836();
// open AD1836 CODEC physical driver
result = adi_dev_Open(DevMgrHandle,
&ADIAD1836AEntryPoint, // entry point for the instance API
0, // device instance index
NULL, // client handle callback identifier
&DriverHandle, // device handle for AD1836
ADI_DEV_DIRECTION_BIDIRECTIONAL,// direction for AD1836
DMAMgrHandle, // DMA handle for SPORT
NULL, // Doesn't use deferred callback handle
ProcessAudioCallback); // client's callback function from SPORT-DMA
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("Failed to open AD1836!\n");
// select SPORT device
result = adi_dev_Control(DriverHandle, ADI_AD1836A_CMD_SET_SPORT_DEVICE_NUMBER, (void*)0); // SPORT 0
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("AD1836-SPORT device not available!\n");
// Open dependent device SPORT0 for AD1836A codec.
result = adi_dev_Control(DriverHandle, ADI_AD1836A_CMD_SET_SPORT_STATUS, ADI_AD1836A_SPORT_OPEN);
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("AD1836-SPORT device not opened!\n");
// select CS for AD1836 CODEC
result = adi_dev_Control(DriverHandle, ADI_AD1836A_CMD_SET_SPI_CS, (void*)4);
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("AD1836-SPI slave select failed!\n");
/********* AD1836 configuration setting ******************************************/
// table of ad1836 configuration values
volatile ADI_DEV_ACCESS_REGISTER AD1836A_Config[] =
{
{ AD1836A_DAC_CTRL_1, (u16)0x000 },
{ AD1836A_DAC_CTRL_2, (u16)0x000 },
{ AD1836A_DAC_1L_VOL, (u16)0x3ff },
{ AD1836A_DAC_1R_VOL, (u16)0x3ff },
{ AD1836A_DAC_2L_VOL, (u16)0x3ff },
{ AD1836A_DAC_2R_VOL, (u16)0x3ff },
{ AD1836A_DAC_3L_VOL, (u16)0x3ff },
{ AD1836A_DAC_3R_VOL, (u16)0x3ff },
{ AD1836A_ADC_CTRL_1, (u16)0x000 },
{ AD1836A_ADC_CTRL_2, (u16)0x180 },
{ AD1836A_ADC_CTRL_3, (u16)0x000 },
{ ADI_DEV_REGEND, (u16)0 },
};
// configure the AD1836 with the value from the configuration table
result = adi_dev_Control(DriverHandle, ADI_DEV_CMD_REGISTER_TABLE_WRITE, (void *)AD1836A_Config);
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("AD1836 configuration failed!\n");
/******************* Buffer preparation ***********************************************/
// Make sure the CallbackParameter as non-null to get the callback function working
// This is only needed for RX
rxBuffer_1.Data = &iADCdata[0]; // point to DMA RX buffer
rxBuffer_1.ElementCount = TDM_FRAME_SIZE * Layout1_TICK_SIZE; // size of the first dimension of the DMA buffer
rxBuffer_1.ElementWidth = 4;
rxBuffer_1.CallbackParameter = (void*)1;// indicating which buffer is completed in double buffering scheme
rxBuffer_1.pNext = &rxBuffer_2; // next buffer in the buffer chain
rxBuffer_2.Data = &iADCdata[TDM_FRAME_SIZE * Layout1_TICK_SIZE]; // point to DMA TX buffer
rxBuffer_2.ElementCount = TDM_FRAME_SIZE * Layout1_TICK_SIZE; // size of the first dimension of the DMA buffer
rxBuffer_2.ElementWidth = 4;
rxBuffer_2.CallbackParameter = (void*)2;// indicating which buffer is completed in double buffering scheme
rxBuffer_2.pNext = NULL; // end of buffer chain
txBuffer_1.Data = &iDACdata[0]; // point to DMA TX buffer
txBuffer_1.ElementCount = TDM_FRAME_SIZE * Layout1_TICK_SIZE; // size of the first dimension of the DMA buffer
txBuffer_1.ElementWidth = 4;
txBuffer_1.CallbackParameter = NULL; // no callback needed for TX
txBuffer_1.pNext = &txBuffer_2; // next buffer in the buffer chain
txBuffer_2.Data = &iDACdata[TDM_FRAME_SIZE * Layout1_TICK_SIZE]; // point to DMA TX buffer
txBuffer_2.ElementCount = TDM_FRAME_SIZE * Layout1_TICK_SIZE; // size of the first dimension of the DMA buffer
txBuffer_2.ElementWidth = 4;
txBuffer_2.CallbackParameter = NULL; // no callback needed for TX
txBuffer_2.pNext = NULL; // end of buffer chain
/******************* End of Buffer preparation ***********************************************/
// configure the AD1836 dataflow method to large descriptor chained mode
result = adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CHAINED_LOOPBACK);
// configure Streaming feature for SPORT DMA transfer
result = adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_STREAMING, (void*)TRUE);
// configure the AD1836 operation mode, assuming STREAMING option on for SPORT DMA
result = adi_dev_Control(DriverHandle, ADI_AD1836A_CMD_SET_SPORT_OPERATION_MODE, (void*)ADI_AD1836A_SET_TDM_MODE);
if (result != ADI_DEV_RESULT_SUCCESS) ErrorMessage("AD1836 cmd-set-mode-tdm failed!\n");
////////////////////////////////////////////////////////////////////////////////////////
// workaround for the newer driver support
// make sure secondary data turned off for TDM mode
result = adi_dev_Control(DriverHandle, ADI_SPORT_CMD_SET_TCR2, (void*)31/*SLEN32*/);
result = adi_dev_Control(DriverHandle, ADI_SPORT_CMD_SET_RCR2, (void*)31/*SLEN32*/);
// Set Multichannel Frame Delay
result = adi_dev_Control(DriverHandle, ADI_SPORT_CMD_SET_MC_FRAME_DELAY, (void*)1);
////////////////////////////////////////////////////////////////////////////////////////
}
/*********************************************************************
*
* Function: SYSAudio_Run
*
*********************************************************************/
#ifndef NO_OPTIMIZE
#pragma optimize_for_space
#endif
int SYSAudio_Run(bool bRun)
{
//unsigned int result = 0;
if (bRun == true)
{
// assign rxBuffer and txBuffer for the AD1836 driver
adi_dev_Read(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&rxBuffer_1);
adi_dev_Write(DriverHandle, ADI_DEV_1D, (ADI_DEV_BUFFER *)&txBuffer_1);
// start the data flow
adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE);
}
else
{
// disable data flow
adi_dev_Control(DriverHandle, ADI_DEV_CMD_SET_DATAFLOW, (void*)FALSE);
// clear
SYSAudio_Clear();
}
return 0;
}
/*********************************************************************
*
* Function: SYSAudio_Close
*
*********************************************************************/
// Never called since it runs as infinite loop
#ifndef NO_OPTIMIZE
#pragma optimize_for_space
#endif
void SYSAudio_Close(void)
{
// disable audio system
SYSAudio_Run(false);
// close the device
adi_dev_Close(DriverHandle);
}
/*********************************************************************
*
* Function: SYSAudio_Init
*
*********************************************************************/
#ifndef NO_OPTIMIZE
#pragma optimize_for_space
#endif
int SYSAudio_Init(int iAudioIOMode)
{
// initialize pointer array which is used in Audio callback function
resolveChannelPointers();
// initialize AudioEZExtender and run talkthrough mode
InitAudioDriver();
// run it
SYSAudio_Run(true);
return 0;
}
/*********************************************************************
*
* Function: SYSAudio_ChangeAudioMode
*
*********************************************************************/
#ifndef NO_OPTIMIZE
#pragma optimize_for_space
#endif
int SYSAudio_ChangeMode(int iAudioIOMode)
{
// assume the audio already stopped
// change audio mode
return 0;
}
/*********************************************************************
*
* Function: SYSAudio_Clear
*
*********************************************************************/
#ifndef NO_OPTIMIZE
#pragma optimize_for_speed
#endif
void SYSAudio_Clear(void)
{
memset(iDACdata, 0, sizeof(iDACdata));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -