📄 audiotest.c
字号:
/************ 宏定义*************/
#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 + -