📄 iis.c
字号:
PCM_Data_init(IIS_BUFFER, g_oI2SState.pcmsize);
I2S_record_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize, g_oI2SState.LineMic);
//play
if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();
I2S_play_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize);
//deinit
I2S_DisableInt();
IIS_Port_Return();
}
//Record Sound via Line-In
void RecordSound_ViaLineIn_Playit_logic(void)
{
//setting
g_oI2SState.BitperCh = 24;
g_oI2SState.SyncClkFreq = 96000;
g_oI2SState.Totch =2;//(fixed)
g_oI2SState.CDCLKFreqFs = 384;
g_oI2SState.CDCLKFreq = g_oI2SState.CDCLKFreqFs * g_oI2SState.SyncClkFreq;
g_oI2SState.BitClkFS = 48;
Select_EPLL(g_oI2SState.Port, 0);
g_oI2SState.DmaPolling = I2S_POLLING;
g_oI2SState.recordSec=10;
g_oI2SState.pcmsize = g_oI2SState.SyncClkFreq*g_oI2SState.Totch*g_oI2SState.BitperCh/8*g_oI2SState.recordSec;
g_oI2SState.ben24bittest=1;//stop at playing at the half.
//init
IIS_Port_Init();
//record
PCM_Data_init(IIS_BUFFER, g_oI2SState.pcmsize);
if(!I2S_InitCodec( g_oI2SState.CodecID, g_oI2SState.MasterSlave,I2S_MODE_RX, g_oI2SState.Dataformat,g_oI2SState.CDCLKFreqFs, g_oI2SState.SyncClkFreq, g_oI2SState.BitperCh,CODEC_LINEIN) )return;//2450 -OpMode, txr, dataformat, CodecClkFs(slave), BitperCh
I2S_Setting(g_oI2SState.Port, g_oI2SState.MasterSlave, I2S_MODE_RX, g_oI2SState.Dataformat,g_oI2SState.CDCLKFreqFs, g_oI2SState.BitClkFS, g_oI2SState.Totch, g_oI2SState.BitperCh, g_oI2SState.DmaPolling);//Port, trx, i2sformat, rootfs, ch, bit);
IIS_RecSound_Polling_logic(RECORD_LINE_IN, IIS_BUFFER, g_oI2SState.pcmsize);
//play
if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();
I2S_play_main( (void *)IIS_BUFFER, g_oI2SState.pcmsize);
//deinit
I2S_DisableInt();
IIS_Port_Return();
}
void RECORD_PLAY_SIMtaneously(void)
{
printf("\nRecord and Play Simultaneously.\n");
//init
IIS_Port_Init();
//play record pcm & record
PCM_Data_init(IIS_BUFFER2, g_oI2SState.pcmsize);
I2S_playrecord_main((void *)IIS_BUFFER, g_oI2SState.pcmsize, (void *)IIS_BUFFER2, g_oI2SState.pcmsize, g_oI2SState.LineMic);
//play record pcm
if(g_oI2SState.benUnderInt==1)I2S_INT_Underrun_init();
I2S_play_main( (void *)IIS_BUFFER2, g_oI2SState.pcmsize);
I2S_DisableInt();
IIS_Port_Return();
}
// before prior version, byte was written into tc.
// if correct that, it would work. but this version would be more clear
//dma infor, array init.
//ch : channel 0 for tx, 1 for rx for general
void I2S_DMA_arrayinit(unsigned char ch)
{
int i=0;
g_oDmainfo[ch].uIndex=0;
g_oDmainfo[ch].uNums=0;
while(g_oDmainfo[ch].uUnitsizeByte*(i+1) < g_oDmainfo[ch].uTotalsizeByte)
{
g_oDmainfo[ch].oArray[i].uStartAddr =
g_oDmainfo[ch].uStartAddr + g_oDmainfo[ch].uUnitsizeByte*i;
g_oDmainfo[ch].oArray[i].uSizeByte = g_oDmainfo[ch].uUnitsizeByte;
g_oDmainfo[ch].oArray[i].uTC =
g_oDmainfo[ch].oArray[i].uSizeByte / g_oDmainfo[ch].uBytePerTC;
i++;
g_oDmainfo[ch].uNums++;
if(g_oDmainfo[ch].uNums >= MAX_I2S_DMA_array-1 ) break;
}
g_oDmainfo[ch].oArray[i].uStartAddr =
g_oDmainfo[ch].uStartAddr + g_oDmainfo[ch].uUnitsizeByte*i;
g_oDmainfo[ch].oArray[i].uSizeByte =
g_oDmainfo[ch].uTotalsizeByte%g_oDmainfo[ch].uUnitsizeByte;
g_oDmainfo[ch].oArray[i].uTC =
g_oDmainfo[ch].oArray[i].uSizeByte / g_oDmainfo[ch].uBytePerTC;
i++;
g_oDmainfo[ch].uNums++;
//printinfo.
printf("total size %d byte(0x%x), unit size %d byte(0x%x) num of unit %d\n",
g_oDmainfo[ch].uTotalsizeByte, g_oDmainfo[ch].uTotalsizeByte,
g_oDmainfo[ch].uUnitsizeByte, g_oDmainfo[ch].uUnitsizeByte, g_oDmainfo[ch].uNums);
for(i=0; i<g_oDmainfo[ch].uNums; i++)
{
printf("%d . addr:%x size:%d byte(0x%x) tc:%d unit(0x%x)\n",
i, g_oDmainfo[ch].oArray[i].uStartAddr, g_oDmainfo[ch].oArray[i].uSizeByte, g_oDmainfo[ch].oArray[i].uSizeByte,
g_oDmainfo[ch].oArray[i].uTC, g_oDmainfo[0].oArray[i].uTC);
}
}
//address, tc update
//return : true : finised , false : not finished.
bool I2S_DMA_updateTx()
{
bool bret;
if(g_oDmainfo[0].uIndex<g_oDmainfo[0].uNums)
{
printf("at %d th\n", g_oDmainfo[0].uIndex);
rDISRC2 = g_oDmainfo[0].oArray[g_oDmainfo[0].uIndex].uStartAddr;
rDCON2 = rDCON2 & ~(0xfffff) | g_oDmainfo[0].oArray[g_oDmainfo[0].uIndex].uTC;
bret=0;
}
else if(g_oDmainfo[0].uIndex==g_oDmainfo[0].uNums)//before finish
{
printf("before finish\n");
rDCON2 = rDCON2 & ~(1<<22) | (1<<22);//autoreload off;
rDIDSTC2 = rDIDSTC2 & ~(1<<2) | (0<<2);//interrupt occur at tc reach zero
//printf("will be repeated next\n");
//g_oDmainfo[0].uIndex=0;
//I2S_DMA_updateTx();
bret=0;
}
else if(g_oDmainfo[0].uIndex > g_oDmainfo[0].uNums)//at finish
{
//dma done.
Play_Done = 1;
printf("at finish\n");
bret=1;
}
g_oDmainfo[0].uIndex++;
return bret;
}
bool I2S_DMA_updateRx()
{
bool bret;
if(g_oDmainfo[1].uIndex<g_oDmainfo[1].uNums)
{
printf("at %d th\n", g_oDmainfo[1].uIndex);
rDIDST1 = g_oDmainfo[1].oArray[g_oDmainfo[1].uIndex].uStartAddr;
rDCON1 = rDCON1 & ~(0xfffff) | g_oDmainfo[1].oArray[g_oDmainfo[1].uIndex].uTC;
bret=0;
}
else if(g_oDmainfo[1].uIndex==g_oDmainfo[1].uNums)//before finish
{
printf("before finish\n");
rDCON1 = rDCON1 & ~(1<<22) | (1<<22);//autoreload off;
rDIDST1 = rDIDST1 & ~(1<<2) | (0<<2);//interrupt occur at tc reach zero
//printf("will be repeated next\n");
//g_oDmainfo[1].uIndex=0;
//I2S_DMA_updateRx();
bret=0;
}
else if(g_oDmainfo[1].uIndex > g_oDmainfo[1].uNums)//at finish
{
//dma done.
Rec_Done = 1;
printf("at finish\n");
bret=1;
}
g_oDmainfo[1].uIndex++;
return bret;
}
void I2S_DMA_Play_init(int port, unsigned char *start_addr, unsigned int pcm_size, int bitperch)
{
unsigned char Exit_Key;
unsigned char Burst, Datasize;
unsigned char rBurst, rDatasize;
unsigned int estInitialTC;//
unsigned int realInitialTC;
//dma init
//size estimate,
Burst = 1;//1: single, 4 : 4burst - doesn't work?
Datasize = 4;//1:byte, 2:half word 4:word [transfer unit]
rBurst = (Burst == 1)? 0 : 1;//0:single, 1:4 burst
rDatasize = (Datasize==1)?0:
(Datasize==2)?1:2;//0:byte, 1:half word, 2: word.
estInitialTC = pcm_size/ ( Burst*Datasize );// playsize(byte) / ( single or burst * transfer unit ) = tc
pISR_DMA = (unsigned)DMA2_Done;
ClearPending(BIT_DMA);
rSUBSRCPND = BIT_SUB_DMA2;
rINTMSK = ~(BIT_DMA);
rINTSUBMSK = ~(BIT_SUB_DMA2);
printf("\nConnect head-phone plug into speaker-out socket on SMDK2450 and Press any key.\n");
getchar();
printf("If you want to exit, Press the 'x' key.\n");
printf("Now Play...\n");
printf("If you want to disable IIS tx(PAUSE), Press '0' key\n");
printf("If you want to enable IIS tx, Press '1' key\n");
printf("If you want to stop DMA channel(STOP), Press '2' key\n");
printf("If you want to start DMA channel, Press '3' key\n");
printf("If you want to test underrun interrupt, Press 'u' key\n");
//DMA2 Register Setting
//rDISRC2 = (int)(start_addr);
rDISRCC2 = (0<<1) + (0<<0);
if(port == I2S_PORT0) rDIDST2 = ((unsigned int)0x55000010);
else rDIDST2 = ((unsigned int)0x55000110);
rDIDSTC2 = (1<<2)+(1<<1) + (1<<0);//interrup at after autoreload, apb,fixed
// 31: ACK 30: sync pclk 29:curr_tc int setting 28:unit transfer 27:single service 22: 0-auto reload on 20: word
rDCON2 = (U32)((1<<31)+(0<<30)+(1<<29)+(rBurst<<28)+(0<<27)+(0<<22)+(rDatasize<<20) );//+realInitialTC );
// 5:1= 4th bit is the tx iis 0:set = hw zero = sw
rDMAREQSEL2 = (port == I2S_PORT0)? (4<<1)|(1) : (6<<1)|(1);//port0 / 1
g_oDmainfo[0].uStartAddr = (unsigned int )start_addr;
g_oDmainfo[0].uTotalsizeByte = (unsigned int)pcm_size;
//g_oI2Splaybuffer.unitsizeByte = 0xfffff*Burst*Datasize;//byte (due to make 4*6 unit)
g_oDmainfo[0].uUnitsizeTC = 0x80000;
g_oDmainfo[0].uUnitsizeByte = 0x80000*Burst*Datasize;//byte (due to make 4*6 unit)
g_oDmainfo[0].uBytePerTC = Burst*Datasize;
I2S_DMA_arrayinit(0);
}
void I2S_tx_start()
{
if(g_oI2SState.Port == I2S_PORT0)
{
while( (rIISCON & 0x100)==0x000 ) ;//wait during tx0 not full
//even 4ch, 6ch checking one pairs is enough
//ok - fifo are full
rIISCON |= 0x1; //IIS Interface start
}
else
{
while( (rIISCON1 & 0x100)==0x000 ) ;//wait during not full
rIISCON1 |= 0x1; //IIS Interface start
}
}
void I2S_tx_finish()
{
int i;
if(g_oI2SState.Port == I2S_PORT0)
{
while( (rIISCON & 0x400)==0x000 )
{
i++;//wait during tx0 not empty
if(i>0x2000000) {
printf("tx fifo time out \n");
break;
}
}
//even 4ch, 6ch checking one pairs is enough
rIISCON &= ~(1<<0); //IIS Interface stop
}
else
{
while( (rIISCON1 & 0x400)==0x000 )
{
i++;//wait during tx not empty
if(i>0x2000000) {
printf("tx fifo time out \n");
break;
}
}
rIISCON1 &= ~(1<<0); //IIS Interface stop
}
printf("playing is finished\n");
}
void I2S_DMA_finishTX()
{
rDMASKTRIG2 = (1<<2); //DMA2 stop
rINTSUBMSK |= (BIT_SUB_DMA2);
rINTMSK |= (BIT_DMA);
}
//play_size = byte
void IIS_PlayWave_DMA(int port , unsigned char *start_addr)
{
unsigned char Exit_Key;
//dma init, array init.
//already done
Play_Done=0;
g_underruncnt=0;
I2S_DMA_updateTx();
//dma start
rDMASKTRIG2 = (0<<2) + (1<<1) + (0<<0); //No-stop, DMA2 channel On, and No-sw trigger
I2S_DMA_updateTx();
//IIS Tx Start
I2S_tx_start();
rGPHDAT = 0x755f;
while(!Play_Done)
{
#if 1
Exit_Key=Uart_GetKey();
if(Exit_Key == '0'){
if(port == I2S_PORT0) rIISCON |= (1<<4);//tx pause
else rIISCON1 |= (1<<4);
printf("\nPAUSE...\n");
}
if(Exit_Key == '1'){
//rIISCON &= ~(1<<3);//strange
if(port == I2S_PORT0) rIISCON &= ~(1<<4);//tx no pause
else rIISCON1 &= ~(1<<4);
}
if(Exit_Key == '2'){//dma pause
//rDMASKTRIG2 |= (1<<2);
if(port == I2S_PORT0)
{
//rIISFIC &= ~(1<<13); //* tx fifo disable
//while( (rIISCON & 0x800)==0x000 ) ;//wait during left
//rIISCON0 |= (1<<6); // dma pause
//pause after sending right.
//while( (rIISFIC & 0x1F00)!=0x0000 ); //* wait until tx fifo gets empty
rIISCON |= (1<<6); // dma pause
}
else
{
rIISCON1 |= (1<<6); // dma pause
}
printf("\nSTOP...\n");
}
if(Exit_Key == '3'){
//rIISFIC |= (1<<13); //* tx fifo enable
//while( (rIISCON & 0x800)==0x000 ) ;//wait during left
if(port == I2S_PORT0) rIISCON &= ~(1<<6); //dma no pause
else rIISCON1 &= ~(1<<6);//dma no pause
//rDISRC2 = (int)(start_addr);
//rDMASKTRIG2 &= ~(1<<2);
//rDMASKTRIG2 |= (1<<1);
}
if(Exit_Key == '4'){//dma pause
rDMASKTRIG2 = (1<<2); //DMA2 stop
printf("\ndma STOP...\n");
}
if(Exit_Key == '5'){//dma continue
rDMASKTRIG2 &= ~(1<<2);
rDMASKTRIG2 |= (1<<1);
}
if(Exit_Key == 'u'){//fifo flush
if(port == I2S_PORT0)
{
rIISFIC = 0+(1<<15);
rIISFIC = 0+(0<<15);
}
else
{
rIISFIC1 = 0+(1<<15);
rIISFIC1 = 0+(0<<15);
}
}
if( (Exit_Key == 'x') | (Exit_Key == 'X'))
break;
#endif
;
//printf("STAT2: 0x%x CURR_TC: 0x%x DCDST2: 0x%x\n", rDSTAT2&0x300000, rDSTAT2&0xfffff, rDCDST2);
}
//IIS Tx Stop
//Delay(10); //For end of H/W Tx
// I2S_tx_finish(); //already done at dma end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -