⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audiotest.c

📁 基于S3C2440A的IIS的Audio功能实现(测试已通过)
💻 C
📖 第 1 页 / 共 2 页
字号:
/************ 宏定义*************/
#define	GLOBAL_CLK		1
/************* head ******************/

#include <stdlib.h>
#include <string.h>

#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "MyAudioTest.h"
#include "WindowsXP_Wav.h"
#include "Dma.h"

/*************全局变量**********/


volatile U32 downloadAddress;
volatile U32 downloadFileSize;

WAVEHDR hdr[2048];
WAVEFORMATEX fmt;


static U32 save_MPLLCON;
volatile int hdr_len;

static struct{                 
	U16 Freq;	//CDCLK 的频率,这个频率用来供给外部CODEC如UDA1341TS
	U32 MPLL;      //设置S3C2440A的FCLK
	U16 PreScaler;//IIS的分频值(N+1)
	U8	ofs; //CODECLK = 256 or 384fs
}CodecPara[7] = {{8000,(123<<12)|(6<<4)|0,(23<<5)|23,0},
				{11025,(229<<12)|(5<<4)|1,(11<<5)|11,1},
				{16000,(123<<12)|(6<<4)|0,(11<<5)|11,0},
				{22050,(229<<12)|(5<<4)|1,(5<<5)|5,1},
				//{22050,(0x96<<12)|(5<<4)|1,(5<<5)|5,0},
				{32000,(123<<12)|(6<<4)|0,(5<<5)|5,0},
				{44100,(229<<12)|(5<<4)|1,(2<<5)|2,1},
				{48000,(123<<12)|(6<<4)|0,(3<<5)|3,0}};

static struct{
	HWAVEOUT handle;		
	U16 wFormatTag;
	U16 nChannels;	
	U16 wBitsPerSample;
	CallBackProc CallBack;
	U32 CallBackInst;	
	U8 FsIdx;
	U32 DevReq;	
	U8 Status;	
}PlayStatus, RecStatus; 	

typedef struct{						//can't use __packed???
    volatile U32 DISRC;	    //0x0
    volatile U32 DISRCC;    //0x4
    volatile U32 DIDST;	    //0x8
    volatile U32 DIDSTC;    //0xc
    volatile U32 DCON;	    //0x10
    volatile U32 DSTAT;	    //0x14
    volatile U32 DCSRC;	    //0x18
    volatile U32 DCDST;	    //0x1c
    volatile U32 DMASKTRIG; //0x20
}DMAReg;

static struct{
	U16 used;
	U16 DevID;
	DMAReg *pDMA;
}
DMAChannel[MAX_DMA_CHANNEL];

static U16 PlayVolume = 0xffff;

static LPWAVEHDR lpPlayFstBlk, lpRecFstBlk;
static LPWAVEHDR lpPlayLstBlk, lpRecLstBlk;
static LPWAVEHDR lpPlayCurBlk, lpRecCurBlk;
static U32 PlayTotBlks, RecTotBlks;
/************* 声明***************/
void readMusicFile(void);
MMRESULT waveOutOpen(
	LPHWAVEOUT phwo,
	UINT uDeviceID,
	LPWAVEFORMATEX pwfx,
	DWORD dwCallback,
	DWORD dwCallbackInstance,
	DWORD fdwOpen
);

U32 RequestDMA(U32 attr, U32 mode);
static void SetSysFclk( U32 MPLL );
void DbgChgUartDiv(void);
static void IIS_PortSetting(void);
static void _WrL3Addr(U8 data);
static void _WrL3Data(U8 data,int halt);
static void Init1341(char mode);
static void __irq PlayDMA2Done(void);
static void StartPlay(void);
static __inline void SetPlayDma(void);
U16 SetDMARun(U32 attr, U32 src_addr, U32 dst_addr, U32 len);
MMRESULT waveOutSetVolume(HWAVEOUT hwo,	DWORD dwVolume);
static void AdjVolume(U16 volume);
MMRESULT waveOutWrite(HWAVEOUT hwo,	LPWAVEHDR pwh, UINT cbwh);

/************ function ****************/
/************************* main Function***********************/
void Main(void)
{
	int i;
    U8 key;
	U32 mpll_val = 0 ;

	HWAVEOUT hwo;
	volatile int err,j;

    Port_Init();  //端口初始化
    Isr_Init();   //中断初始化
    
    i = 2 ;	//don't use 100M!
		//boot_params.cpu_clk.val = 3;
	switch ( i ) {
	case 0:	//200
		key = 12;
		mpll_val = (92<<12)|(4<<4)|(1);
		break;
	case 1:	//300
		key = 13;
		mpll_val = (67<<12)|(1<<4)|(1);
		break;
	case 2:	//400
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	case 3:	//440!!!
		key = 14;
		mpll_val = (102<<12)|(1<<4)|(1);
		break;
	default:
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	}
	
	//init FCLK=400M, so change MPLL first
	ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
	ChangeClockDivider(key, 12);
	cal_cpu_bus_clk();

    Uart_Init(0,115200);  //串口初始化 波特率为115200
    Uart_Select(0);  //选者串口0
    
	Clk0_Disable();
	Clk1_Disable();

	
	Uart_Printf("\n======  UDA1341 Test start ======\n");
	
	/******TODO*******/
	readMusicFile();
	hwo = 0;
	err = waveOutOpen(&hwo,
				0,
				&fmt,
				0,
				0,
				0);
	
	Uart_Printf("\nerr = %x\n", err);	

	for(j=0;j<hdr_len;j++)
		waveOutWrite(0,	&hdr[j], 0);

	
	Uart_Printf("\n====== UDA1341 Test end ======\n");


}

/*********read wave file function*********/
void readMusicFile(void)
{
	volatile int size=0,i=0;
	unsigned char *buf;
	
	
	/*****将文件内容读入到内存缓冲区中*****/
	downloadAddress = _NONCACHE_STARTADDRESS;
	buf = (unsigned char*)downloadAddress;
	for(i=0;i<243552;i++)
	{
		buf[i] = WindowsXP_Wav[i];
	}
	downloadFileSize = 243552;
      
	size = *(U32 *)(downloadAddress+0x28); // 语音数据的长度

	/***********让WAVEHDR 结构体中的数据指针分别指向每一个块****************/
      i=0;
	while(size>0)
	{
		hdr[i].lpData =(LPSTR)( downloadAddress+0x2C+i*BUF_SIZE);
		hdr[i].dwBufferLength = (BUF_SIZE>size)?size:BUF_SIZE;
		size -= BUF_SIZE;
		i++;
	}
	hdr_len = i;

	/*************填充WAVE 头数据结构体****************/
	fmt.wFormatTag = *(U16 *)(downloadAddress+0x14);
	fmt.nChannels = *(U16 *)(downloadAddress+0x16);
	fmt.nSamplesPerSec = *(U32 *)(downloadAddress+0x18);
	fmt.nAvgBytesPerSec = *(U32 *)(downloadAddress+0x1C);
	fmt.nBlockAlign = *(U16 *)(downloadAddress+0x20);
	fmt.wBitsPerSample = *(U16 *)(downloadAddress+0x22);


}






/************************* Play Function ***********************/
MMRESULT waveOutOpen(
	LPHWAVEOUT phwo,
	UINT uDeviceID,
	LPWAVEFORMATEX pwfx,
	DWORD dwCallback,
	DWORD dwCallbackInstance,
	DWORD fdwOpen
)
{
	U8 i;
	U8 err = 0;	
	
	if(pwfx->wFormatTag!=WAVE_FORMAT_PCM)	//only support PCM    格式必须是PCM
		err = 1;
	if(pwfx->nChannels!=2)					//must be stero        必须是双通道
		err = 1;
	if(pwfx->wBitsPerSample%8)				//8 or 16 bits            每个采样需要的bit数,必须是8 bit或16 bit
		err = 1;
	for(i=0; i<7; i++)
		if(pwfx->nSamplesPerSec==CodecPara[i].Freq)  //如果采用频率和CodecPara结构体中的Freq参数都不同则错误
			break;
	if(i==7)
		err = 1;		
	if((pwfx->nChannels*pwfx->wBitsPerSample)/8!=pwfx->nBlockAlign)
	//数据块的调整数(按字节算的)= 通道数×每样本的数据位值/8,如果不相等则错误
		err = 1;
	if(pwfx->nAvgBytesPerSec!=pwfx->nSamplesPerSec*pwfx->nBlockAlign)
       //波形音频数据传送速率=每秒数据位数×数据块的调整数,如果不相等则错误
		err = 1;		
	if(err)											
		return WAVERR_BADFORMAT;	//check format parameters
	
	PlayStatus.Status = DEVICE_FREE;
	if(PlayStatus.Status!=DEVICE_FREE)
	{
		Uart_Printf("errrrrr!\n");
		return MMSYSERR_BADDEVICEID;
		}
	PlayStatus.DevReq = RequestDMA(PLAY_DMA_ATTR, PLAY_DMA_MODE);				
	if(PlayStatus.DevReq==REQUEST_DMA_FAIL)
	{
		Uart_Printf("errrrrr11!\n");
		return MMSYSERR_BADDEVICEID;	
		}					
	
	PlayStatus.handle		  =	*phwo; 
	PlayStatus.wFormatTag     = pwfx->wFormatTag;
	PlayStatus.nChannels      = pwfx->nChannels;	
	PlayStatus.wBitsPerSample = pwfx->wBitsPerSample;
	PlayStatus.FsIdx          = i;
	PlayStatus.CallBack		  = (CallBackProc)dwCallback;
	PlayStatus.CallBackInst	  = dwCallbackInstance;
	PlayStatus.Status		  = DEVICE_PLAY;
			
	save_MPLLCON = rMPLLCON;		//save MPLLCON value 保存原来的MPLLCON值
	//rMPLLCON = CodecPara[PlayStatus.FsIdx].MPLL;
	SetSysFclk(CodecPara[PlayStatus.FsIdx].MPLL);  //根据文件中的采样频率设置MPLLCON值
	rCLKCON |= 0x20000;				//enable IIS clock	将时钟PCLK输入IIS
	
	DbgChgUartDiv();		//调整uART波特率
	
//	ChangeClockDivider(1,1);        //1:2:4
//	ChangeMPllValue(0x96,0x5,0x1);  //FCLK=135.428571MHz (PCLK=33.857142MHz)    	
//		Uart_Init(33857142,115200); 
			
	IIS_PortSetting();	    //初始化IIS端口
      pISR_DMA2 = (U32)PlayDMA2Done;//设置DMA2的中断程序入口
      EnableIrq(BIT_DMA2);              //开启DMA2的中断
	PlayTotBlks = 0;
	Init1341(PLAY);                 //初始化1341
	waveOutSetVolume(PlayStatus.handle, PlayVolume);//设置音量
	
	return MMSYSERR_NOERROR;
}

MMRESULT waveOutWrite(HWAVEOUT hwo,	LPWAVEHDR pwh, UINT cbwh)
{
	if((PlayStatus.handle!=hwo)||(PlayStatus.Status!=DEVICE_PLAY))
		return MMSYSERR_INVALHANDLE;//检测是否属于播放模式
	
	if(!PlayTotBlks)
	{
		lpPlayFstBlk = pwh;
		lpPlayCurBlk = lpPlayFstBlk;
		StartPlay();					
	}
	else
	{
		lpPlayLstBlk -> lpNext = pwh ;
	}

	lpPlayLstBlk = pwh;
	pwh->lpNext = 0;
	PlayTotBlks++;		

	return MMSYSERR_NOERROR;
}


void DbgChgUartDiv(void)
{
	Uart_Init(0, 115200);        		
}

static void SetSysFclk( U32 MPLL )
{
	U32 mdiv, pdiv, sdiv, val;
    U32 mclk;

    mdiv = (MPLL>>12)&0xff;
    pdiv = (MPLL>>4)&0xff;
    sdiv = MPLL&0xf;
    
    val = 1;
    while(sdiv--)
    {
    	val *= 2;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -