|
楼主 |
发表于 2009-12-11 15:26:23
|
显示全部楼层
static U8 *pcm_dat;
static int pcm_size,pcm_cnt,pcm_pkt;
/*============================================================================*/
/*============================================================================*/
/*============================================================================*/
int PCM_DrvInit(void)
{
rCLKCON |= 0x20000; //enable IIS clock
IIS_PortSetting();
Init1341(PLAY);
AdjVolume(0x8000);
// pISR_DMA2 = (unsigned)DMA2_Done;
// rINTMSK &= ~(BIT_DMA2);
//rINTMSK |= (BIT_DMA2); //DI
//IIS Tx Start
rIISCON |= 0x1; //IIS Interface start
// rDMASKTRIG2 = (1<<2); //DMA2 stop
pcm_cnt=0;
pcm_size=0;
}
/*============================================================================*/
int PCM_SetVolume(U8 vol)
{
AdjVolume(vol<<8);
}
/*============================================================================*/
int PCM_DrvClose(void)
{
rIISCON &= ~(1<<0); //IIS Interface stop
rDMASKTRIG2 = (1<<2); //DMA2 stop
rIISFCON = 0x0; //For FIFO flush
rINTMSK |= (BIT_DMA2);
}
/*============================================================================*/
int PCM_SetSampleRate(int bits,U32 rate)
{
int sel,bit;
U32 Pclk,div;
////
if(bits==16)
{
bit=1;
}
else
{
bit=0;
}
////
Pclk=CPU_GetPclkHZ()/1000000;
switch(rate)
{
case 8000:
div=(float)Pclk/3.0720;
break;
////
case 11025:
div=(float)Pclk/4.2336;
break;
////
case 16000:
div=(float)Pclk/6.1440;
break;
////
case 22050:
div=(float)Pclk/8.4672;
break;
////
case 32000:
div=(float)Pclk/12.2880;
break;
////
case 44100:
div=(float)Pclk/16.9344;
break;
////
case 48000:
div=(float)Pclk/18.4320;
break;
////
case 64000:
div=(float)Pclk/24.5760;
break;
////
case 88200:
div=(float)Pclk/33.8688;
break;
////
case 96000:
div=(float)Pclk/36.8640;
break;
////
default:
div=(float)Pclk/16.9344;
break;
}
////
DbgUart_Printf("div=%d\n",div);
sel=0;
switch(sel)
{
case 0 :
//IIS Pre-scaler Setting
rIISPSR = (div<<5) + div;
//In case PCLK = 50 MHz, IIS Codec CLK = 50/(5+1) = 8.34MHz
IIS_Codec_CLK = Pclk/(div+1);
DbgUart_Printf("IIS Master CLK(PCLK) = %d MHz\n", Pclk);
DbgUart_Printf("IIS Codec CLK = %d MHz\n", IIS_Codec_CLK);
rIISCON = (1<<5)|(1<<2)|(1<<1);
//Bit[1] IIS prescaler enable
//Bit[2] Rx idle
//Bit[5] Tx DMA enable
rIISMOD = (0<<9)+(0<<8) + (2<<6) + (1<<5) + (0<<4) + (bit<<3) + (1<<2) + (1<<0);
//Bit[1:0] Serial bit clock => 32fs,
//Bit[2] Master clock => 384fs,
//Bit[3] Serial data bit per channel => 16bit,
//Bit[4] Serial interface format => IIS compatible format
//Bit[5] Active level of left/right channel => Low for left channel
//Bit[7:6] Tx/Rx mode select => Tx mode
//Bit[8] Master/Slave mode => Master mode
//Bit[9] Master clock => PCLK
rIISFCON = (1<<15) + (1<<13);
//Bit[13] Tx FIFO enable
//Bit[15] Tx FIFO access mode => DMA
DbgUart_Printf("IISLRCK[0] = %d Hz\n", (int) IIS_Codec_CLK*1000000/384);
break;
////
case 1 :
//IIS Pre-scaler Setting
rIISPSR = (div<<5) + div;
IIS_Codec_CLK = FIN;
DbgUart_Printf("IIS Master CLK(MPLLin) = %d MHz\n", FIN/1000000);
DbgUart_Printf("IIS Codec CLK = %d MHz\n", IIS_Codec_CLK/1000000);
rIISCON = (1<<4) + (1<<2) + (1<<1);
//Bit[1] IIS prescaler disable
//Bit[2] Rx idle
//Bit[3] Tx DMA enable
rIISMOD = (1<<9)+(0<<8) + (2<<6) + (0<<5) + (0<<4) + (bit<<3) + (1<<2) + (1<<0);
//Bit[1:0] Serial bit clock => 32fs,
//Bit[2] Master clock => 384fs,
//Bit[3] Serial data bit per channel => 16bit,
//Bit[4] Serial interface format => IIS compatible format
//Bit[5] Active level of left/right channel => Low for left channel
//Bit[7:6] Tx/Rx mode select => Tx mode
//Bit[8] Master/Slave mode => Master mode
//Bit[9] Master clock => MPLLin
rIISFCON = (1<<15) + (1<<13);
//Bit[13] Tx FIFO enable
//Bit[15] Tx FIFO access mode => DMA
DbgUart_Printf("IISLRCK[1] = %d Hz\n", (int) IIS_Codec_CLK*1000000/384);
break;
////
}
////
}
/*============================================================================*/
int PCM_NeedData(void)
{
if((rDSTAT2&(1<<20))==(1<<20))
{ return 0; //DMA正在传输数据
}
else
{ return 1; //DMA已经传输完成
}
}
/*============================================================================*/
static void DMA2_Done(void)
{
//int size;
//DbgUart_Puts("^");
/*
DbgUart_Printf("pcm_size =%d\n",pcm_size);
DbgUart_Printf("pcm_cnt =%d\n",pcm_cnt);
DbgUart_Printf("pcm_dats =%d\n",pcm_size-pcm_cnt);
DbgUart_Printf("pcm_pkt =%d\n",pcm_pkt);
DbgUart_Printf("****\n\n");
*/
if((pcm_cnt+pcm_pkt)<pcm_size)
{
rDMASKTRIG2 |= (1<<2);
pcm_cnt+=pcm_pkt;
if((pcm_cnt+0x3ffff)<pcm_size)
{
pcm_pkt=0x3ffff;
}
else
{
pcm_pkt=pcm_size-pcm_cnt;
}
rDISRC2 = (U32)(pcm_dat)+pcm_cnt;
rDISRCC2 = (0<<1) + (0<<0);
rDIDST2 = ((U32)IISFIFO);
rDIDSTC2 = (0<<2) + (1<<1) + (1<<0);
rDCON2 = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<24)+(1<<23)+(1<<22)+(1<<20)+((pcm_pkt>>1));
rDMASKTRIG2 = (0<<2) + (1<<1) + (0<<0); //No-stop, DMA2 channel On, and No-sw trigger
//IIS Tx Start
rIISCON |= 0x1; //IIS Interface start
}
ClearPending(BIT_DMA2); //Clear pending bit
}
/*============================================================================*/
int PCM_SetSize(U32 size)
{
pcm_size=size;
}
/*============================================================================*/
int PCM_Output(void *pdata,U32 size)
{
////
// DbgUart_Printf("pcm_output ->size =%d\n",size);
rDMASKTRIG2 = (1<<2); //DMA2 stop
pISR_DMA2 =(U32)DMA2_Done;
rINTMSK &=~BIT_DMA2;
////
pcm_dat =pdata;
pcm_size =size;
////
if(size>0x3ffff)
{
pcm_pkt=0x3ffff;
}
else
{
pcm_pkt=size;
}
///
if(pdata)
{
pcm_cnt = 0;
rDISRC2 = (U32)(pdata);
}
rDISRCC2 = (0<<1) + (0<<0);
rDIDST2 = ((U32)IISFIFO);
rDIDSTC2 = (0<<2) + (1<<1) + (1<<0);
rDCON2 = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<24)+(1<<23)+(1<<22)+(1<<20)+((pcm_pkt>>1));
rDMASKTRIG2 = (0<<2) + (1<<1) + (0<<0); //No-stop, DMA2 channel On, and No-sw trigger
//IIS Tx Start
rIISCON |= 0x1; //IIS Interface start
return 1;
}
/*============================================================================*/
补上PCM部分的驱动程序 |
|