www.pudn.com > hf44b0_TEST.rar > Uda1341.c


//*************************************************************************** 
//	wave文件格式 
//	任何wave文件,从字符串"data"后开始是4字节的PCM数据长度,接着为PCM裸数据 
//	wave文件可以用 advanced mp3/wma recorder 软件生成 
 
//	对于该软件生成的441khz,16bit立体声文件,0x36偏移处开始为4字节的PCM数据长度,接着为PCM裸数据 
//	加上串口接收时的4byte的文件长度头应该是0x3a处开始,PCM数据从0x3e处开始 
 
//	windows格式的wave文件,0x28偏移处开始为4字节的PCM数据长度,接着为PCM裸数据 
//	加上串口接收时的4byte的文件长度头应该是0x2c处开始,PCM数据从0x30处开始 
 
//	samplesize=*(pWave+0x2c) | *(pWave+0x2d)<<8 | *(pWave+0x2e)<<16 | *(pWave+0x2f)<<24; 
//	i=0; 
//	do 
//	{ 
//		memcpy((char *)str_data,(char *)(pWave+i),4); 
//		Uart_Printf("%d = %s",i,(char *)(pWave+i)); 
//		Uart_Printf("str= %s",str_data); 
//		i++; 
//	}while(strncmp(str_data,"data",4)!=0); 
//	i+=3; 
//	samplesize=*(pWave+i) | *(pWave+i+1)<<8 | *(pWave+i+2)<<16 | *(pWave+i+3)<<24; 
//*************************************************************************** 
 
#include "44b.h" 
#include "def.h" 
#include "UDA1341.h" 
#include "utils.h" 
#include "44blib.h" 
#include "WindowsXP_Wav.h" 
void _WrL3Addr(U8 data); 
void _WrL3Data(U8 data,int halt); 
void __irq BDMA0_Done(void); 
void __irq TR_Done(void); 
void __irq RxInt(void); 
void __irq BDMA0_Rec_Done(void); 
 
#define L3M (0x01) 
#define L3D (0x200) 
#define L3C (0x08) 
 
//#define L3D (0x200) 
//#define L3M (0x40) 
//#define L3C (0x80) 
U32 download_addr, download_len; 
unsigned char *Buf,*_temp; 
unsigned char *rec_buf; 
#define PLAY 0 
#define RECORD 1 
#define REC_LEN	0xF0000 
 
volatile unsigned int size=0; 
volatile unsigned int leng,ssize; 
volatile char Rec_Done=0; 
volatile char mute=1; 
typedef struct tWAVEFORMATEX{ 
	U16 wFormatTag; 
	U16 nChannels; 
	U32 nSamplesPerSec; 
	U32 nAvgBytesPerSec; 
	U16 nBlockAlign; 
	U16 wBitsPerSample; 
	U16 cbSize; 
}WAVEFORMATEX, *LPWAVEFORMATEX; 
 
#define	WAVE_FORMAT_PCM	0x0001 
 
void __irq BDMA0_Done(void); 
 
#define	MAX_VOLUME	61 
static void AdjVolume(U16 volume)	 
{	 
	//volume = (volume*MAX_VOLUME)/0xffff;		     
	     
	_WrL3Addr(0x14 + 0);				//DATA0 (000101xx+00) 
   	_WrL3Data(MAX_VOLUME-volume, 0); 
} 
 
 
void Init1341(char mode) 
{    /****** Port Initialize ******/ 
    
 //   rPDATG = L3M|L3C;	//L3M=H(start condition) 
     rPCONA=0x1ff;				//L3C=H(start condition) 
    			 
    rPCONG=0xFF7F; 
    rPUPG=0xf; 
    rPCONE=0x2aaa9;//0x6552a;//0x2B;	 
	rPUPE=0xff;	 
	rPCONF=0x24915a;//0x2A; 
	rPUPF=0xff;; 
	 
    /****** L3 Interface ******/ 
    _WrL3Addr(0x14+2);	//status (000101xx+10) 
    _WrL3Data(0x60,0); //0,1,10,000,0 reset,256fs,no DCfilter,iis 
    _WrL3Addr(0x14+2); //status (000101xx+10) 
    _WrL3Data(0x83,0); 
    //1,0,0,0,0,0,11 OGS=0,IGS=0,ADC_NI,DAC_NI,sngl speed,AonDon 
    AdjVolume(61);      
//record 
    if(mode) 
    { 
	_WrL3Addr(0x14+2); //STATUS (000101xx+10) 
	_WrL3Data(0xe3,0); //1,0,1,0,0,0,10	: OGS=0,IGS=1,ADC_NI,DAC_NI,sngl speed,AonDoff 
 
	_WrL3Addr(0x14+0); //DATA0 (000101xx+00) 
	_WrL3Data(0xc2,0); //11000,010	: DATA0, Extended addr(010)  
	_WrL3Data(0x4d,0); //010,011,01	: DATA0, MS=9dB, Ch1=on Ch2=off,  
     } 
//record 
} 
 
/**************************************************************************** 
Name	:  	Play_SmallWave 
Function:	播放1M以下的wav文件,采用DMA方式 
Input	:	addr----------wav文件起始地址 
			samplesize----wav文件长度 
Return	:	 
说明	:	 
****************************************************************************/ 
void Play_SmallWave(U32 addr, U32 size) 
{ 
    unsigned char *pWave; 
    U32 samplesize; 
    U32 save_PLLCON; 
 
	ChangePllValue(0x69,0x17,0x0);	//MCLK=45.1584MHz <-- 5.6448MHz*8 
	//save_PLLCON = rPLLCON; 
	//rPLLCON = (0x69<<12)|(0x17<<4)|0; 
	Uart_Init(45158400,115200); 
 
    pISR_BDMA0=(unsigned)BDMA0_Done; 
 
    rINTMSK=~(BIT_GLOBAL|BIT_BDMA0); 
 
	pWave=(unsigned char *)addr; 
	pWave+=0x28;	//指向wav采样长度 
    samplesize=*(pWave+0) | *(pWave+1)<<8 | *(pWave+2)<<16 | *(pWave+3)<<24; 
   // pWave+=4;	//指向wav数据 
    samplesize=(samplesize>>1)<<1; 
    Uart_Printf("\nsample start:0x%x",pWave); 
    Uart_Printf("\nsample size:0x%x",samplesize); 
 
    Init1341(PLAY); 
     
      /****** IIS Initialize ******/ 
    rIISCON=0x22;	//Tx DMA enable,Rx idle,prescaler enable 
    rIISMOD=0x89;	//Master,Tx,L-ch=low,iis,16bit ch.,codeclk=256fs,lrck=32fs 
//    rIISPSR=0x11;	//Prescaler_A/B enable, value=1 
    rIISPSR=0x33;	//Prescaler_A/B enable, value=3 
    rIISFCON=0xa00;	//Tx/Rx DMA,Tx/Rx FIFO --> start piling.... 
 
    /****** BDMA0 Initialize ******/ 
    rBDISRC0=(1<<30)+(1<<28)+(U32)pWave;	//Half word,inc,pWave 
    rBDIDES0=(1<<30)+(3<<28)+((U32)rIISFIF);	//M2IO,fix,IISFIF 
    rBDICNT0=(1<<30)+(1<<26)+(3<<22)+(1<<21)+(0<<20)+samplesize; 
    rBDICNT0 |= (1<<20);//enable 
    //iis,reserve,done_int,auto-reload/start,DMA enable,COUNT 
    rBDCON0 = 0x0<<2; 
 
    Uart_Printf("\nNow play the wave file ..."); 
    Uart_Printf("\nPush any key to exit!!!"); 
    /****** IIS Tx Start ******/ 
    rIISCON |=0x1; 
    while(!Uart_GetKey()); 
 
    /****** IIS Tx Stop ******/ 
    rIISCON=0x0;    //IIS stop 
    rBDICNT0=0x0;   //BDMA stop 
 
    rINTMSK=BIT_GLOBAL; 
      
} 
 
void __irq BDMA0_Done(void) 
{ 
    rI_ISPC=BIT_BDMA0;	//clear pending bit 
    WrUTXH0('#'); 
} 
 
/**************************************************************************** 
Name	:  	Play_BigWave 
Function:	播放1M以上的wav文件,采用normal方式 
Input	:	addr----------wav文件起始地址 
			samplesize----wav文件长度 
Return	:	 
说明	:	 
****************************************************************************/ 
void Play_BigWave(U32 addr, U32 size) 
{ 
	int i; 
    unsigned char *pWave; 
    unsigned short *pSteroWave; 
    U32 samplesize,start; 
    U32 save_PLLCON; 
    LPWAVEFORMATEX pWav; 
     
    if(!download_len) 
    	return; 
   	 
	pWav = (LPWAVEFORMATEX)(addr+0x14); 
	if(pWav->wFormatTag!=WAVE_FORMAT_PCM) { 
		puts("Supported PCM format only\n"); 
		return; 
	} 
	if(pWav->nChannels!=2) { 
		puts("Support stereo wave only\n"); 
		return; 
	}	 
	Uart_Printf("Sample rate =%dHz\n", pWav->nSamplesPerSec); 
	 
	 	ChangePllValue(0x69,0x17,0x0);	//MCLK=45.1584MHz <-- 5.6448MHz*8 
	//save_PLLCON = rPLLCON; 
	//rPLLCON = (0x69<<12)|(0x17<<4)|0; 
	Uart_Init(45158400,115200); 
 
	pWave=(unsigned char *)addr; 
	pWave+=0x28;	//指向wav采样长度 
    samplesize=*(pWave+0) | *(pWave+1)<<8 | *(pWave+2)<<16 | *(pWave+3)<<24; 
    //pWave+=4; 
    start=(U32)(unsigned char *)pWave;	//指向wav数据 
    pSteroWave=(U16 *)start; 
    samplesize=(samplesize>>1)<<1; 
    Uart_Printf("\nsample start:0x%x",pWave); 
    Uart_Printf("\nsample size:0x%x",samplesize); 
 
    Init1341(PLAY); 
     /****** IIS Initialize ******/ 
    rIISCON=0x02;	//Tx DMA disable,Rx idle,prescaler enable 
    rIISMOD=0x89;	//Master,Tx,L-ch=low,iis,16bit ch.,codeclk=256fs,lrck=32fs 
//    rIISPSR=0x11;	//Prescaler_A/B enable, value=1 
    rIISPSR=0x33;	//Prescaler_A/B enable, value=3 
    rIISFCON=0x200;	//Tx/Rx normal,Tx FIFO enable--> start piling.... 
 
    Uart_Printf("\nNow play the wave file ..."); 
    Uart_Printf("\nPush ESC key to exit!!!"); 
    /****** IIS Tx Start ******/ 
    rIISCON |=0x1; 
    while(Uart_GetKey()!=ESC_KEY) 
    { 
    	if(IIS_FIFOREADY) 
    	{ 
    		for(i=0;i<8;i++) 
    		{ 
    			*rIISFIF = *pSteroWave++; 
//    			Uart_Printf("\n0x%x:0x%x",pSteroWave,*pSteroWave); 
    		} 
    			 
    		if( ((U32)pSteroWave-start) > samplesize ) 
    		{ 
//    			Uart_Printf("\n0x%x-0x%x=0x%x:0x%x",pSteroWave,start,((U32)pSteroWave-start),samplesize); 
    			pSteroWave=(U16 *)start; 
    			WrUTXH0('#'); 
    		} 
    	} 
    } 
 
    /****** IIS Tx Stop ******/ 
    rIISCON=0x0;    //IIS stop 
 
	 Uart_TxEmpty(0); 
	 
	 
} 
void _WrL3Addr(U8 data) 
{ 
     U32 vPdata = 0x0;	//L3D=L	 
    U32 vPdatg = 0x0;	//L3M=L(in address mode)/L3C=L 
    S32 i,j; 
 
    rPDATE = vPdatg;	//L3M=L 
    rPDATG |= L3C;	//L3C=H 
 
    for(j=0;j<4;j++);		//tsu(L3) > 190ns 
 
    //PA9:L3D PGE0:L3M PG3:L3C 
    for(i=0;i<8;i++)		 
    { 
	if(data&0x1)//if data bit is 'H' 
	{ 
	    rPDATG = vPdatg;	//L3C=L 
	    rPDATA = L3D;	//L3D=H		     
	    for(j=0;j<4;j++);	//tcy(L3) > 500ns 
	    rPDATG = L3C;	//L3C=H 
	    rPDATA = L3D;	//L3D=H 
	    for(j=0;j<4;j++);	//tcy(L3) > 500ns 
	} 
	else		//if data bit is 'L' 
	{ 
	    rPDATG=vPdatg;	//L3C=L 
	    rPDATA=vPdata;	//L3D=L 
	    for(j=0;j<4;j++);	//tcy(L3) > 500ns 
	    rPDATG=L3C;		//L3C=H 
	    rPDATA=vPdata;	//L3D=L 
	    for(j=0;j<4;j++);	//tcy(L3) > 500ns 
	} 
	data >>=1; 
    } 
    rPDATG = L3C;	//L3C=H 
	rPDATE=L3M; 
} 
 
void _WrL3Data(U8 data,int halt) 
{ 
    U32 vPdata = 0x0;   //L3D=L 
    U32 vPdatg = 0x0;	//L3M/L3C=L 
    S32 i,j; 
    if(halt) 
    { 
        rPDATG=L3C;	    //L3C=H(while tstp, L3 interface halt condition) 
        for(j=0;j<4;j++);   //tstp(L3) > 190ns 
    } 
     rPDATE=L3M; 
     rPDATG=L3C;	//L3C=H,L3D=H 
     for(j=0;j<4;j++);	 
    
    
   //PA9:L3D PGE0:L3M PG3:L3C 
    for(i=0;i<8;i++) 
    { 
        if(data&0x1)	//if data bit is 'H' 
        { 
	        rPDATG=vPdatg;		//L3C=L 
            rPDATA=L3D;		//L3D=H 
            for(j=0;j<4;j++);	//tcy(L3) > 500ns 
            rPDATG=L3C;	//L3C=H,L3D=H 
            rPDATE=L3M; 
	        rPDATA=L3D; 
            for(j=0;j<4;j++);	//tcy(L3) > 500ns 
        } 
        else		//if data bit is 'L' 
        { 
            rPDATG=L3M;		//L3C=L 
	    rPDATA=vPdatg;	//L3D=L 
            for(j=0;j<4;j++);	//tcy(L3) > 500ns 
            rPDATG=L3C;	//L3C=H,L3D=H 
            rPDATE=L3M; 
	    rPDATA=vPdatg;	//L3D=L 
            for(j=0;j<4;j++);	//tcy(L3) > 500ns 
        } 
        data>>=1; 
    } 
   rPDATG=L3C;	//L3C=H,L3D=H 
// //   
   rPDATE=L3M; 
} 
 
 
void __irq BDMA0_Rec_Done(void) 
{ 
    rI_ISPC=BIT_BDMA0;	//clear pending bit 
    WrUTXH0('#'); 
     
} 
void IISMain(void) 
{ 
		unsigned char *buf; 
		int i; 
	 
		download_addr = 0xc400000; 
		buf = (unsigned char *)download_addr; 
		for( i = 0; i < 243552; i++ )  buf[i] = WindowsXP_Wav[i] ; 
		download_len = 243552 ; 
	 
	//Play_BigWave(download_addr, download_len); 
	Play_SmallWave(download_addr, download_len); 
}