📄 i2s_test.c
字号:
{
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 !! ----------*/
// MPLL On
// SYSC_SetPLL(eAPLL, 400, 3, 2, 0); // APLL => 400MHz
// SYSC_SetPLL(eMPLL, 800, 6, 3, 0); // MPLL => 200MHz
// SYSC_SetDIV0(0, 3, 1, 1, 3, 1, 1,0, 1, 0);
// SYSC_SetPLL(eEPLL, 32, 1, 2, 0); // EPLL => 96MHz
SYSC_ClkSrc(eMPLL_FOUT);
SYSC_ClkSrc(eAUDIO0_DOUTMPLL);
/*------ Clock Division Code for I2S Must be Here !! ----------*/
SYSC_SetDIV2(0, 0, 0, 0, 0, 0);
//IIS Pre-scaler Setting
I2S_SetPreScaler(ucCon, ENABLE, 2);
// IIS CDCLKCON
I2S_SetCodecClkSrc(ucCon, eI2S_CLK_INTERNAL);
}
void I2S_SelectSysExtCLK(u8 ucCon)
{
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 !! ----------*/
// MPLL On
// SYSC_SetPLL(eAPLL, 400, 3, 2, 0); // APLL => 400MHz
// SYSC_SetPLL(eMPLL, 800, 6, 3, 0); // MPLL => 200MHz
// SYSC_SetDIV0(0, 3, 1, 1, 3, 1, 1,0, 1, 0);
// SYSC_SetPLL(eEPLL, 32, 1, 2, 0); // EPLL => 96MHz
// SYSC_ClkSrc(eEPLL_FIN);
SYSC_ClkSrc(eAUDIO0_FINEPLL);
/*------ Clock Division Code for I2S Must be Here !! ----------*/
SYSC_SetDIV2(0, 0, 0, 0, 0, 0);
//IIS Pre-scaler Setting
I2S_SetPreScaler(ucCon, ENABLE, 2);
// IIS CDCLKCON
I2S_SetCodecClkSrc(ucCon, eI2S_CLK_INTERNAL);
}
//////////
// Function Name : I2S_PlayWaveUsingPolling
// Function Description :
// This function implements the I2S play operation using Polling.
// Input : ucPort - I2S port number
// ucStartAddr - start address of memory
// uPlaySize - play size
// Output : NONE
// Version :
void I2S_PlayWaveUsingPolling(u8 ucCon, u32 *ucStartAddr, u32 uPlaySize)
{
u8 ucExitKey=0;
u8 ucCODECLK=0;
u8 ucBCLK=0;
u8 ucBLTH=0;
u32 uCODECFS = 0;
u32 uBCLKFS = 0;
// u32 uPcmDataSize = 0x68000;
u32 uPcmDataSize = 0xC0000;
u32 uRegValue = 0;
u32 *uPlayBuf = (u32*) g_oaI2SInform[ucCon].puRecBuf;
g_oaI2SInform[ucCon].uPlayCount = 0;
g_oaI2SInform[ucCon].uRecLength = uPlaySize;
Disp("\n Root Frequency Sample ( 0:256fs 1:512fs 2:384fs(D) 3:768fs ) = ");
ucCODECLK = GetIntNum();
if (ucCODECLK == 0xff ) ucCODECLK = 2;
uCODECFS = I2S_GetRFS(ucCODECLK);
Disp("\n Bit Frequency Sample (0:32fs 1:48fs(D) 2:16fs 3:24fs) = ");
ucBCLK = GetIntNum();
if (ucBCLK == 0xff ) ucBCLK = 1;
uBCLKFS = I2S_GetBFS(ucBCLK);
Disp("\n BLC (0: 16bit(D) 1:8bit ) = ");
ucBLTH = GetIntNum();
if (ucBLTH == 0xff ) ucBLTH = 0;
Disp("\nuBCLKFS:%d, uCODECFS:%d", uBCLKFS, uCODECFS);
Disp("\nI2S Bit Clock = %4.4f MHz", g_oaI2SInform[ucCon].fI2SCodecCLK*uBCLKFS/uCODECFS/1000000);
Disp("\nI2S Sampling Rate = %4.4f kHz\n", g_oaI2SInform[ucCon].fI2SCodecCLK/uCODECFS/1000);
// rI2SCON : TxDMA
I2S_SetI2STxerMode(ucCon, eI2S_XFER_TX);
// rI2SMOD : TxOnlyMode, I2SRootClk, BitClk, BitLength
I2S_SetInterfaceMode(ucCon, eI2S_XFER_TX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, FLUSH); // rI2SFIC : TxFIFO Flush(15)
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, NON_FLUSH); // rI2SFIC : TxFIFO No Flush(15)
Disp("\nConnect head-phone plug into speaker-out socket on SMDK6400 and Press any key.\n");
Getc();
Disp("If you want to exit, Press the 'x' key.\n");
Disp("Now Play...\n");
Disp("If you want to disable IIS tx(PAUSE), Press '0' key\n");
Disp("If you want to enable IIS tx, Press '1' key\n");
Disp("If you want to stop DMA channel(STOP), Press '2' key\n");
Disp("If you want to start DMA channel, Press '3' key\n");
//IIS Start
I2S_SetActive(ucCon, ACTIVE);
while( uPcmDataSize > 0 )
{
do {
uRegValue = I2S_GetRegValue(ucCon, eI2S_CON);
} while ( uRegValue&(1<<8)); // Tx FIFO full check
// Disp("%d\n", *uPlayBuf);
I2S_SetRegValue(ucCon, eI2S_TXD, *uPlayBuf++);
// Disp("uRecBuf1:0x%x, 0x%x\n",(volatile unsigned *)0x7F002010, *((volatile unsigned *)0x7F002010));
uPcmDataSize -= 4;
if( (ucExitKey == 'x') | (ucExitKey == 'X'))
break;
Delay(0);
}
//IIS Stop
I2S_SetActive(ucCon, INACTIVE);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, NON_FLUSH);
Disp("\nEnd of Play!\n");
}
u32 I2S_GetBFS(u8 ucBClk)
{
u32 uTempFS = 0;
switch(ucBClk)
{
case 0 :
uTempFS = 32;
break;
case 1 :
uTempFS = 48;
break;
case 2 :
uTempFS = 16;
break;
case 3 :
uTempFS = 24;
break;
default :
uTempFS = 48;
break;
}
return uTempFS;
}
u32 I2S_GetRFS(u8 ucCodecClk)
{
u32 uTempFS = 0;
switch(ucCodecClk)
{
case 0 :
uTempFS = 256;
break;
case 1 :
uTempFS = 512;
break;
case 2 :
uTempFS = 384;
break;
case 3 :
uTempFS = 768;
break;
default :
uTempFS = 384;
break;
}
return uTempFS;
}
//////////
// Function Name : I2S_PlayWaveUsingDMA
// Function Description :
// This function implements the I2S play operation using DMA.
// Input : ucPort - I2S port number
// ucStartAddr - start address of memory
// uPlaySize - play size
// Output : NONE
// Version :
void I2S_PlayWaveUsingDMA(u8 ucCon, u32 *ucStartAddr, u32 uPlaySize)
{
u8 ucExitKey=0;
u8 ucCODECLK=0;
u8 ucBCLK=0;
u8 ucBLTH=0;
u32 uCODECFS = 0;
u32 uBCLKFS = 0;
g_oaI2SInform[ucCon].uPlayCount = 0;
g_oaI2SInform[ucCon].uRecLength = uPlaySize;
Disp("\n Root Frequency Sample ( 0:256fs 1:512fs 2:384fs(D) 3:768fs ) = ");
ucCODECLK = GetIntNum();
if (ucCODECLK == 0xff ) ucCODECLK = 2;
uCODECFS = I2S_GetRFS(ucCODECLK);
Disp("\n Bit Frequency Sample (0:32fs 1:48fs(D) 2:16fs 3:24fs) = ");
ucBCLK = GetIntNum();
if (ucBCLK == 0xff ) ucBCLK = 1;
uBCLKFS = I2S_GetBFS(ucBCLK);
Disp("\n BLC (0: 16bit(D) 1:8bit ) = ");
ucBLTH = GetIntNum();
if (ucBLTH == 0xff ) ucBLTH = 0;
Disp("\nuBCLKFS:%d, uCODECFS:%d", uBCLKFS, uCODECFS);
Disp("\nI2S Bit Clock = %4.4f MHz", g_oaI2SInform[ucCon].fI2SCodecCLK*uBCLKFS/uCODECFS/1000000);
Disp("\nI2S Sampling Rate = %4.4f kHz\n", g_oaI2SInform[ucCon].fI2SCodecCLK/uCODECFS/1000);
// DMA1 Initailization
DMAC_InitCh((DMA_UNIT)(g_oaI2SInform[ucCon].ucDMACon) , DMA_ALL, &oI2SDma);
/*---------- DMA1 Interrupt Handler should be registered in here!! ----------*/
INTC_SetVectAddr(g_oaI2SInform[ucCon].ucDMANum ,ISR_DMAPlayDone);
INTC_Disable(g_oaI2SInform[ucCon].ucDMANum );
/*------------------------------------------------------------------*/
// rI2SCON : TxDMA
I2S_SetI2STxerMode(ucCon, eI2S_XFER_TX);
// rI2SMOD : TxOnlyMode, I2SRootClk, BitClk, BitLength
I2S_SetInterfaceMode(ucCon, eI2S_XFER_TX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, FLUSH); // rI2SFIC : TxFIFO Flush(15)
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, NON_FLUSH); // rI2SFIC : TxFIFO No Flush(15)
INTC_Enable(g_oaI2SInform[ucCon].ucDMANum );
// INTC_Enable(NUM_DMA0 );
// INTC_Enable(NUM_DMA1 );
Disp("\nConnect head-phone plug into speaker-out socket on SMDK6400 and Press any key.\n");
Getc();
Disp("If you want to exit, Press the 'x' key.\n");
Disp("Now Play...\n");
Disp("If you want to disable IIS tx(PAUSE), Press '0' key\n");
Disp("If you want to enable IIS tx, Press '1' key\n");
Disp("If you want to stop DMA channel(STOP), Press '2' key\n");
Disp("If you want to start DMA channel, Press '3' key\n");
// Interrupt Clear
DMACH_ClearIntPending(&oI2SDma);
DMACH_ClearErrIntPending(&oI2SDma);
// Channel, LLI_Address, SrcAddr, Src Type, DstAddr, Dst Type, Transfer Width, Transfer Size, OpMode(DEMAND), Src Req, Dst Req, Burst
// Channel Set-up [source increment, dest fixed]
DMACH_Setup(DMA_B, 0x0, (u32)ucStartAddr , 0, I2S_GetRegAddr(ucCon,eI2S_TXD), 1, WORD, g_oaI2SInform[ucCon].uRecLength, DEMAND, MEM, (DREQ_SRC)(g_oaI2SInform[ucCon].ucDMATxSrc), SINGLE, &oI2SDma);
// Enable DMA
DMACH_Start(&oI2SDma);
//IIS Start
I2S_SetActive(ucCon, ACTIVE);
while(1)
{
Disp("Playing...\n");
ucExitKey = Getc();
if(ucExitKey == '0')
{
I2S_SetChPause(ucCon, eI2S_XFER_TX, PAUSE);
Disp("\nPAUSE...\n");
}
else if(ucExitKey == '1')
{
I2S_SetChPause(ucCon, eI2S_XFER_TX, NOPAUSE);
Disp("\nRESUME...\n");
}
else if(ucExitKey == '2')
{
DMACH_Stop(&oI2SDma);
Disp("\nSTOP...\n");
}
else if(ucExitKey == '3')
{
DMACH_Start(&oI2SDma);
Disp("\nSTART...\n");
}
if( (ucExitKey == 'x') | (ucExitKey == 'X'))
break;
}
Delay(10);
//IIS Stop
I2S_SetActive(ucCon, INACTIVE);
DMACH_Stop(&oI2SDma); // DMA stop
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, FLUSH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_TX, NON_FLUSH);
INTC_Disable(g_oaI2SInform[ucCon].ucDMANum);
Disp("\nEnd of Play!\n");
}
//////////
// Function Name : I2S_PlayWaveUsingPolling
// Function Description :
// This function implements the I2S play operation using Polling.
// Input : ucPort - I2S port number
// ucStartAddr - start address of memory
// uPlaySize - play size
// Output : NONE
// Version :
void I2S_RecordUsingPolling(u8 ucCon, u32 *ucStartAddr, u32 uPlaySize)
{
u8 ucExitKey=0;
u8 ucCODECLK=0;
u8 ucBCLK=0;
u8 ucBLTH=0;
u32 uCODECFS = 0;
u32 uBCLKFS = 0;
u32 uPcmDataSize = 0x68000;
u32 uRegValue = 0;
u32 *uRecBuf = (u32*) g_oaI2SInform[ucCon].puRecBuf;
Assert(uPcmDataSize%4 == 0 && uPcmDataSize >= 4);
g_oaI2SInform[ucCon].uPlayCount = 0;
g_oaI2SInform[ucCon].uRecLength = uPlaySize;
Disp("\n Root Frequency Sample ( 0:256fs 1:512fs 2:384fs(D) 3:768fs ) = ");
ucCODECLK = GetIntNum();
if (ucCODECLK == 0xff ) ucCODECLK = 2;
uCODECFS = I2S_GetRFS(ucCODECLK);
Disp("\n Bit Frequency Sample (0:32fs 1:48fs(D) 2:16fs 3:24fs) = ");
ucBCLK = GetIntNum();
if (ucBCLK == 0xff ) ucBCLK = 1;
uBCLKFS = I2S_GetBFS(ucBCLK);
Disp("\n BLC (0: 16bit(D) 1:8bit ) = ");
ucBLTH = GetIntNum();
if (ucBLTH == 0xff ) ucBLTH = 0;
Disp("\nuBCLKFS:%d, uCODECFS:%d", uBCLKFS, uCODECFS);
Disp("\nI2S Bit Clock = %4.4f MHz", g_oaI2SInform[ucCon].fI2SCodecCLK*uBCLKFS/uCODECFS/1000000);
Disp("\nI2S Sampling Rate = %4.4f kHz\n", g_oaI2SInform[ucCon].fI2SCodecCLK/uCODECFS/1000);
// rI2SCON : RxDMA
I2S_SetI2STxerMode(ucCon, eI2S_XFER_RX);
// rI2SMOD : RxOnlyMode, I2SRootClk, BitClk, BitLength
I2S_SetInterfaceMode(ucCon, eI2S_XFER_RX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_RX, FLUSH); // rI2SFIC : RxFIFO Flush(7)
I2S_FlushFIFO(ucCon, eI2S_FLUSH_RX, NON_FLUSH); // rI2SFIC : RxFIFO No Flush(7)
Disp("\nConnect Line-In cable into socket on SMDK6400 and Press any key.\n");
Getc();
Disp("If you want to exit, Press the 'x' key.\n");
Disp("Now Record...\n");
//IIS Start
I2S_SetActive(ucCon, ACTIVE); // I2S active
while( uPcmDataSize > 0 )
{
do {
uRegValue = I2S_GetRegValue(ucCon, eI2S_CON);
} while ( uRegValue&(1<<9)); // Rx FIFO empty check
uRegValue = I2S_GetRegValue(ucCon, eI2S_RXD);
// Disp("uRecBuf:0x%x, 0x%x\n", (*(volatile unsigned *)0x7F002014), uRegValue);
*uRecBuf++ = uRegValue;
uPcmDataSize -= 4;
if( (ucExitKey == 'x') | (ucExitKey == 'X'))
break;
}
//IIS Stop
I2S_SetActive(ucCon, INACTIVE);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_RX, FLUSH);
I2S_FlushFIFO(ucCon, eI2S_FLUSH_RX, NON_FLUSH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -