📄 i2s_test.c
字号:
uRegValue = I2S_GetRegValue(I2S0, eI2S_CON);
uPcmTxDataSize -= 4;
} // Tx FIFO full check
//----Step 2. I2S0 and I2S1 start.
//IIS0 Start
I2S_SetActive(I2S0, ACTIVE);
//IIS1 Start
I2S_SetActive(I2S1, ACTIVE);
//----Step 3. Remained data might be transmitted.
while( (uPcmTxDataSize > 0 ) || (uPcmRxDataSize > 0 ))
{
if (uPcmTxDataSize > 0 )
{
// Tx
do {
uRegValue = I2S_GetRegValue(I2S0, eI2S_CON);
} while ( uRegValue&(1<<8)); // Tx FIFO full check
I2S_SetRegValue(I2S0, eI2S_TXD, *g_oaI2SInform[I2S0].puRecBuf++);
uPcmTxDataSize -= 4;
}
if (uPcmRxDataSize > 0 )
{
// Rx
do {
uRegValue = I2S_GetRegValue(I2S1, eI2S_CON);
} while ( uRegValue&(1<<9)); // Rx FIFO empty check
uRegValue = I2S_GetRegValue(I2S1, eI2S_RXD);
*g_oaI2SInform[I2S1].puRecBuf++ = uRegValue;
uPcmRxDataSize -= 4;
}
if( (ucExitKey == 'x') | (ucExitKey == 'X'))
break;
Delay(0);
}
//IIS Stop
I2S_SetActive(I2S0, INACTIVE);
I2S_SetActive(I2S1, INACTIVE);
I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, NON_FLUSH);
I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, FLUSH);
I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, NON_FLUSH);
Disp("\nEnd of LoopBack Test!\n");
}
//////////
// Function Name : I2S_PlayWaveInPolling
// Function Description :
// This function implements wave play function in Polling mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_PlayWaveInPolling(void)
{
Disp("\nPlay Wave File.\n");
Disp("Note. The wave file should be uploaded first to 0x51000000 in DRAM space.\n");
Getc();
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_SLAVE_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_PLAY, I2S_STATUS_PLAY, eI2S_CODEC_SLAVE_MODE);
I2S_PlayWaveUsingPolling(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_PlayWaveInDMA
// Function Description :
// This function implements wave play function in DMA mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_PlayWaveInDMA(void)
{
Disp("\nPlay Wave File in Master mode.\n");
Disp("Note. The wave file should be uploaded first to 0x51000000 in DRAM space.\n");
Getc();
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_SLAVE_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_PLAY, I2S_STATUS_PLAY, eI2S_CODEC_SLAVE_MODE);
I2S_PlayWaveUsingDMA(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_PlayWaveInDMASlave
// Function Description :
// This function implements wave play function in I2S Slave and DMA mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_PlayWaveInDMASlave(void)
{
Disp("\nPlay Wave File in Slave mode.\n");
Disp("Note. The wave file should be uploaded first to 0x51000000 in DRAM space.\n");
Getc();
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_TX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_MASTER_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_PLAY, I2S_STATUS_PLAY, eI2S_CODEC_MASTER_MODE);
I2S_PlayWaveUsingDMA(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_RecordInPolling
// Function Description :
// This function implements recording function in Polling mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_RecordInPolling(void)
{
Disp("\nPlay Wave File.\n");
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_SLAVE_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_RECORD_LineIn, I2S_STATUS_RECORD, eI2S_CODEC_SLAVE_MODE);
I2S_RecordUsingPolling(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_RecordSoundViaLineInPlayIt
// Function Description :
// This function implements recording from Line In & play function in DMA mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_RecordSoundViaLineInPlayIt(void)
{
Disp("\nRecord Sound via Line-In and Play it.\n");
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_SLAVE_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_RECORD_LineIn, I2S_STATUS_RECORD, eI2S_CODEC_SLAVE_MODE);
I2S_RecSoundUsingDMA(g_ucI2SPortNum, I2S_MODE_RECORD_LineIn, I2S_RECORD_LENGTH);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_PLAY, I2S_STATUS_RECORD, eI2S_CODEC_SLAVE_MODE);
I2S_PlayWaveUsingDMA(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_RecordSoundViaMICInPlayIt
// Function Description :
// This function implements recording from MIC & play function in DMA mode.
// Input : NONE
// Output : NONE
// Version :
void I2S_RecordSoundViaMICInPlayIt(void)
{
Disp("\nRecord Sound via Mic-In and Play it.\n");
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, FLUSH);
I2S_FlushFIFO(g_ucI2SPortNum, eI2S_FLUSH_RX, NON_FLUSH);
I2S_SelectCDCLK(g_ucI2SPortNum, eI2S_CODEC_SLAVE_MODE);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_RECORD_MICIn, I2S_STATUS_RECORD, eI2S_CODEC_SLAVE_MODE);
I2S_RecSoundUsingDMA(g_ucI2SPortNum, I2S_MODE_RECORD_MICIn, I2S_RECORD_LENGTH);
I2S_Init8753(g_ucI2SPortNum, I2S_MODE_PLAY, I2S_STATUS_RECORD, eI2S_CODEC_SLAVE_MODE);
I2S_PlayWaveUsingDMA(g_ucI2SPortNum, g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_RECORD_LENGTH);
}
//////////
// Function Name : I2S_SelectCDCLK
// Function Description :
// This function implements the selection of CLK source as I2S's master clock.
// Input : ucPort - I2S port number
// Output : NONE
// Version :
void I2S_SelectCDCLK(u8 ucCon, eI2S_CODEC_MODE eCodecMode)
{
s32 iSel;
Disp("\nSelect I2S Root Clock Source\n");
Disp("0:PCLK, 1:I2S EXTCLK, 2:EPLL(D), 3:MPLL, 4.System EXTCLK \n");
iSel = GetIntNum();
switch(iSel)
{
case 0:
I2S_SelectPCLK(ucCon);
break;
case 1:
I2S_SelectEXTCLK(ucCon);
break;
case 2:
I2S_SelectEPLL(ucCon);
break;
case 3:
I2S_SelectMPLL(ucCon);
break;
case 4:
I2S_SelectSysExtCLK(ucCon);
break;
default :
I2S_SelectEPLL(ucCon);
break;
}
switch(iSel)
{
case 0:
if (eCodecMode == eI2S_CODEC_SLAVE_MODE) //IIS Master(Codec Slave) mode selection
I2S_SetMasterSlaveMode(ucCon, eI2S_MS_MASTER_MODE_USING_PCLK);
else if (eCodecMode == eI2S_CODEC_MASTER_MODE) //IIS Slave(Codec Master) mode selection
I2S_SetMasterSlaveMode(ucCon, eI2S_MS_SLAVE_MODE_USING_PCLK);
break;
default:
if (eCodecMode == eI2S_CODEC_SLAVE_MODE) //IIS Master(Codec Slave) mode selection
I2S_SetMasterSlaveMode(ucCon, eI2S_MS_MASTER_MODE_USING_I2SCLK);
else if (eCodecMode == eI2S_CODEC_MASTER_MODE) //IIS Slave(Codec Master) mode selection
I2S_SetMasterSlaveMode(ucCon, eI2S_MS_SLAVE_MODE_USING_I2SCLK);
break;
}
}
//////////
// Function Name : I2S_SelectPCLK
// Function Description :
// This function selects the PCLK source as I2S's master clock.
// Input : ucPort - I2S port number
// Output : NONE
// Version :
void I2S_SelectPCLK(u8 ucCon)
{
u8 ucPsvala = 4;
// u32 uI2SPSR;
// u32 uI2SMOD;
SYSC_CtrlCLKOUT(eCLKOUT_EPLLOUT, 10);
GPIO_SetFunctionEach(eGPIO_F, eGPIO_14, 3);
/*------ Clock Source Selection Code for I2S Must be Here !! ----------*/
// System_SetCLKSRC();
/*------ Clock Division Code for I2S Must be Here !! ----------*/
SYSC_SetDIV2(0, 0, 0, 0, 0, 0);
/*------ Clock Gating Code for I2S Must be Here !! ----------*/
SYSC_CtrlPCLKGate( (P_eGATE)(ePCLK_I2S0 + ucCon), 1); // Gating PCLK for IIS0/IIS1 as PASS
SYSC_CtrlSCLKGate( (S_eGATE)(eSCLK_AUDIO0 + ucCon), 1);
//IIS Pre-scaler Setting
I2S_SetPreScaler(ucCon, ENABLE, ucPsvala);
I2S_SetCodecClkSrc(ucCon, eI2S_CLK_INTERNAL);
g_oaI2SInform[ucCon].fI2SCodecCLK = (float)g_PCLK/(ucPsvala+1); // Set I2S codec clk
Disp("\nI2S Codec Clock = %4.4f MHz\n", g_oaI2SInform[ucCon].fI2SCodecCLK/1000000);
// Disp("\nI2S Bit Clock = %4.4f MHz", g_oaI2SInform[ucPort].fI2SCodecCLK*I2S_BIT_CLK_TIMES/I2S_CODEC_CLK_TIMES/1000000);
// Disp("\nI2S Sampling Rate = %4.4f kHz", g_oaI2SInform[ucPort].fI2SCodecCLK/I2S_CODEC_CLK_TIMES/1000);
}
//////////
// Function Name : I2S_SelectEXTCLK
// Function Description :
// This function selects the External Clock source as I2S's master clock.
// Input : ucPort - I2S port number
// Output : NONE
// Version :
void I2S_SelectEXTCLK(u8 ucCon)
{
SYSC_CtrlCLKOUT(eCLKOUT_EPLLOUT, 10);
GPIO_SetFunctionEach(eGPIO_F, eGPIO_14, 3);
/*------ Clock Source Selection Code for I2S Must be Here !! ----------*/
// Select I2S External Clock as I2SCDCLK
SYSC_ClkSrc((CLKSRC_eId)(eAUDIO0_I2SCDCLK+ucCon*0x30));
/*------ Clock Division Code for I2S Must be Here !! ----------*/
SYSC_SetDIV2(0, 0, 0, 0, 0, 0);
/*------ Clock Gating Code for I2S Must be Here !! ----------*/
SYSC_CtrlSCLKGate( (S_eGATE)(eSCLK_AUDIO0 + ucCon), 1);
//IIS Pre-scaler Setting
I2S_SetPreScaler(ucCon, ENABLE, 1);
// IIS CDCLKCON
I2S_SetCodecClkSrc(ucCon, eI2S_CLK_EXTERNAL);
}
//////////
// Function Name : I2S_SelectEPLL
// Function Description :
// This function selects the EPLL source as I2S's master clock.
// Input : ucPort - I2S port number
// Output : NONE
// Version :
// Example :
// FOUTepll = 84.6666MHz
// Value of Prescaler in I2S block : 4
// --> I2SCDCLK : 84.6666/(4+1) = 16.93333MHz
// RFS : 384fs ( I2SCDCLK/384 = 44.09KHz)
// BFS : 48fs (RFS*48 = 2.116MHz)
void I2S_SelectEPLL(u8 ucCon)
{
float fFOUTepll = 0.;
#if 0 // default for 48KHz
u8 ucPsvala = 4;
u32 uMdiv = 246;
u32 uPdiv = 8;
u32 uSdiv = 2;
u32 uKdiv = 0;
#endif
#if 1 // default for 44.1KHz@LRCK, 16.9344MHz@CDCLK
u8 ucPsvala = 4;
u32 uMdiv = 254;
u32 uPdiv = 9;
u32 uSdiv = 2;
u32 uKdiv = 0;
#endif
#if 0 // for 38.864MHz@CDCLK
u8 ucPsvala = 1;
u32 uMdiv = 98;
u32 uPdiv = 4;
u32 uSdiv = 2;
u32 uKdiv = 19930;
#endif
#if 0 // for 50MHz@CDCLK
u8 ucPsvala = 1;
u32 uMdiv = 133;
u32 uPdiv = 4;
u32 uSdiv = 2;
u32 uKdiv = 21900;
#endif
#if 0 // for 67.7MHz@CDCLK
u8 ucPsvala = 1;
u32 uMdiv = 180;
u32 uPdiv = 4;
u32 uSdiv = 2;
u32 uKdiv = 40000;
#endif
#if 0 // for 73.7MHz@CDCLK
u8 ucPsvala = 1;
u32 uMdiv = 196;
u32 uPdiv = 4;
u32 uSdiv = 2;
u32 uKdiv = 40000;
#endif
SYSC_CtrlCLKOUT(eCLKOUT_EPLLOUT, 0);
// SYSC_CtrlCLKOUT(eCLKOUT_HCLK, 9);
GPIO_SetFunctionEach(eGPIO_F, eGPIO_14, 3);
GPIO_SetPullUpDownEach(eGPIO_F, eGPIO_14, 0);
/*------ Clock Source Selection Code for I2S Must be Here !! ----------*/
// EPLL On
SYSC_SetPLL(eEPLL, uMdiv, uPdiv, uSdiv, uKdiv); // EPLL => 84.6666...MHz
SYSC_ClkSrc(eEPLL_FOUT);
SYSC_ClkSrc((CLKSRC_eId)(eAUDIO0_MOUTEPLL+ucCon*0x30));
/*------ Clock Division Code for I2S Must be Here !! ----------*/
SYSC_SetDIV2(0, 0, 0, 0, 0, 0);
/*------ Clock Gating Code for I2S Must be Here !! ----------*/
SYSC_CtrlPCLKGate( (P_eGATE)(ePCLK_I2S0 + ucCon), 1); // Gating PCLK for IIS0/IIS1 as PASS
SYSC_CtrlSCLKGate( (S_eGATE)(eSCLK_AUDIO0 + ucCon), 1);
//IIS Pre-scaler Setting
I2S_SetPreScaler(ucCon, ENABLE, ucPsvala); // FOUTepll/(value+1) = 83.3333MHz/(4+1) = 16.6666... MHz
// IIS CDCLKCON
I2S_SetCodecClkSrc(ucCon, eI2S_CLK_INTERNAL);
fFOUTepll = ((uMdiv+uKdiv/Pow(2,16))*12000000/(uPdiv*Pow(2,uSdiv)));
g_oaI2SInform[ucCon].fI2SCodecCLK = (float)(fFOUTepll/(ucPsvala+1));
Disp("\nFOUTepll = %4.4f MHz\n", fFOUTepll/1000000);
Disp("I2S Codec Clock = %4.4f MHz\n\n", g_oaI2SInform[ucCon].fI2SCodecCLK/1000000);
}
void I2S_SelectMPLL(u8 ucCon)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -