www.pudn.com > USBdiskRW.rar > Iis.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); 
//		printf("%d = %s",i,(char *)(pWave+i)); 
//		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 "iis.h" 
#include "utils.h" 
 
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); 
 
void Init_4334(void) 
{ 
} 
 
/**************************************************************************** 
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; 
	SerialChgBaud(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; 
    printf("\nsample start:0x%x",pWave); 
    printf("\nsample size:0x%x",samplesize); 
 
    Init_4334(); 
    /****** 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; 
 
    printf("\nNow play the wave file ..."); 
    printf("\nPush any key to exit!!!"); 
    /****** IIS Tx Start ******/ 
    rIISCON |=0x1;                         //使能IIS 
    while(!getkey());                       
 
    /****** IIS Tx Stop ******/ 
    rIISCON=0x0;    //IIS stop 
    rBDICNT0=0x0;   //BDMA stop 
 
    rINTMSK=BIT_GLOBAL; 
	//ChangePllValue(136, 8, 1);//Fin=10MHz, Fout=72MHz 
	rPLLCON = save_PLLCON; 
	SerialChgBaud(115200); 
} 
 
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);   
	  /* 
	  文件头 
  00H               4           char            "RIFF"标志  
  04H               4         long int          文件长度  
  08H               4           char             "WAVE"标志  
  0CH              4           char             "fmt"标志  
  10H              4                             过渡字节(不定)  
  14H              2            int               格式类别(10H为PCM形式的声音数据)  
  16H              2            int               通道数,单声道为1,双声道为2  
  18H              2            int               采样率(每秒样本数),表示每个通道的播放速度,  
  1CH             4         long int          波形音频数据传送速率,其值为通道数×每秒数据位数×每  样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。  
  20H             2              int              数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整。  
  22H             2                             每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都一样。  
  24H             4          char             数据标记符"data"  
  28H             4        long int          语音数据的长度  
  PCM数据的存放方式: 
  样本1 样本2  
  8位单声道 0声道 0声道  
  8位立体声 0声道(左) 1声道(右) 0声道(左) 1声道(右)  
  16位单声道 0声道低字节 0声道高字节 0声道低字节 0声道高字节  
  16位立体声 0声道(左)低字节 0声道(左)高字节 1声道(右)低字节 1声道(右)高字节  
 
	  */        
	if(pWav->wFormatTag!=WAVE_FORMAT_PCM) { 
		puts("Supported PCM format only\n");       //(Pulse Code Modulation) 
		return; 
	} 
	if(pWav->nChannels!=2) { 
		puts("Support stereo wave only\n"); 
		return; 
	}	 
	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; 
	SerialChgBaud(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; 
    printf("\nsample start:0x%x",pWave); 
    printf("\nsample size:0x%x",samplesize); 
 
    Init_4334(); 
    /****** 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.... 
 
    printf("\nNow play the wave file ..."); 
    printf("\nPush ESC key to exit!!!"); 
    /****** IIS Tx Start ******/ 
    rIISCON |=0x1; 
    while(getkey()!=ESC_KEY) 
    { 
    	if(IIS_FIFOREADY) 
    	{ 
    		for(i=0;i<8;i++) 
    		{ 
    			*rIISFIF = *pSteroWave++; 
//    			printf("\n0x%x:0x%x",pSteroWave,*pSteroWave); 
    		} 
    			 
    		if( ((U32)pSteroWave-start) > samplesize ) 
    		{ 
//    			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 
 
	SerialTxEmpty();                //等待发送完毕 
	rPLLCON = save_PLLCON; 
	//ChangePllValue(0x2a,0x3,0x1);//Fin=10MHz, Fout=50MHz 
	SerialChgBaud(115200); 
} 
 
void IISMain(void) 
{ 
	Play_BigWave(download_addr, download_len); 
	 
}