📄 audio_aic23.c
字号:
/**************************************************************
程序说明 :AIC23数字音频处理控制系统实验
说 明 :
FreeDev 数字应用开发板采用了TI公司的TVL320AIC23
1、控制接口使用I2C,Quartus中将CS置低(器件地址0011010)。
2、数字音频接口使用了组件FreeDev_aic23,可实现轮训方式读写,
中断方式读写,录音、和放音
3、I2C IP 和 FreeDev_aic23 IP分别在Quartus 工程目录中
**************************************************************/
#include <stdio.h>
#include <system.h>
#include <io.h>
#include <alt_types.h>
#include <sys/alt_irq.h>
#include <sys/alt_dma.h>
#include "fast_dma.h"
#include <altera_avalon_dma_regs.h>
#define AUDIO_BUFF_SIZE 0x80000
extern void *dma_base;
extern int gControl_bits;
unsigned int infifo_count;
/*********************************************
函数名:audio_irq
功 能:音频中断处理函数
输 入:context:相关内容指针,中断号
返 回:
备 注:
读取音频外设数据,并回放写入到音频外设中
**********************************************/
void audio_irq(void *context,alt_u32 interrupt)
{
unsigned int fifo_status;
unsigned int len;
fifo_status=IORD(FREEDEV_AIC23_0_BASE,0x03);
infifo_count=IORD(FREEDEV_AIC23_0_BASE,0x04);
if(fifo_status & 0x04)
len=512;
else
len=infifo_count;
// 启动DMA传输
IOWR_ALTERA_AVALON_DMA_LENGTH(dma_base,len);
IOWR_ALTERA_AVALON_DMA_CONTROL(dma_base, gControl_bits|ALTERA_AVALON_DMA_CONTROL_GO_MSK);
}
int main()
{
FILE * hostfile ;
int iRet;
unsigned char ch;
unsigned int v1,v2,v3,v4,i;
static int irq_flag=0;
unsigned int *audioBuff=(unsigned int *)(SDRAM_BASE+0x200000);
// 初始化DMA参数
iRet=fast_dma_init(
DMA_BASE,
4,
__IO_CALC_ADDRESS_NATIVE(FREEDEV_AIC23_0_BASE, 0x07),
__IO_CALC_ADDRESS_NATIVE(FREEDEV_AIC23_0_BASE, 0x07),
512,
ALTERA_AVALON_DMA_CONTROL_RCON_MSK|ALTERA_AVALON_DMA_CONTROL_WCON_MSK);
//初始化I2C控制器
init_i2c(FREEDEV_I2C_0_BASE);
// 屏蔽音频中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x03);
/* 注册音频中断处理函数 */
if (alt_irq_register( FREEDEV_AIC23_0_IRQ, NULL,audio_irq))
{
printf("alt_irq_register audio_irq error\n");
return -1;
}
// 提示菜单
menu:
MenuHeader();
ch=ShowSelect( "进入测试系统? Y OR N",'y','n' );
if(ch=='n')
exit(0);
//复位音频处理芯片
aic23_reset();
ch=ShowSelect( "需要测试模拟环路音频处理吗?y OR n",'y','n' );
if(ch=='y'){
// 屏蔽输入中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x03);
//模拟环路测试参数设置,如需要测试模拟环路,打开下列函数注解
//模拟环路说明:模拟信号由LINE IN接入,经TLV320AIC23内部
//模拟开关短接到LINE OUT和PHONE OUT输出
aic23_analog_bypass_test();
goto menu;
}else{
// 屏蔽输入中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x03);
//TLV320AIC23常规工作参数设置
aic23_normal_setup();
//FreeDev_aic模块工作模式切换实验
ch=ShowSelect( "需要测试NIOS II系统软件轮训方式实时采集和回放处理吗?y OR n",'y','n' );
if(ch=='y'){
//FreeDev_aic接口模块控制切换到DMA模式
//DMA模式说明:FreeDev_aic模块通过TLV320AIC23的串行数字接口接收数据,变换成32BIT左右
//声道数据,经异步FIFO送到Avalone接口端,供Nios II DMA方式读取数据。Nios II输出数据经
//Avalone接口写入FIFO传输到并串转换模块,由TLV320AIC23串行数字接口输出。
IOWR(FREEDEV_AIC23_0_BASE,0x00,0x0201);
//复位FreeDev_aic23外设FIFO
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x01);
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x00);
// 启动数据接收
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x02);
//循环读入并输出音频信号
while(1){
//读音频外设状态
v1=IORD(FREEDEV_AIC23_0_BASE,0x03);
// 输入FIFO不为空 或 输入FIFO为满
if(!(v1 & 0x08) || (v1 & 0x04) )
{
v2=IORD(FREEDEV_AIC23_0_BASE,0x07);
IOWR(FREEDEV_AIC23_0_BASE,0x07,v2);
}
}
}
ch=ShowSelect( "需要测试NIOS II系统中断方式实时采集和回放处理吗?y OR n",'y','n' );
if(ch=='y'){
//FreeDev_aic接口模块控制切换到DMA模式
//DMA模式说明:FreeDev_aic模块通过TLV320AIC23的串行数字接口接收数据,变换成32BIT左右
//声道数据,经异步FIFO送到Avalone接口端,供Nios II DMA方式读取数据。Nios II输出数据经
//Avalone接口写入FIFO传输到并串转换模块,由TLV320AIC23串行数字接口输出。
IOWR(FREEDEV_AIC23_0_BASE,0x00,0x0201);
//复位FreeDev_aic23外设
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x01);
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x00);
// 开放输入中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x02);
// 启动数据接收
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x02);
}
ch=ShowSelect( "需要测试NIOS II系统录音和回放处理吗?y OR n",'y','n' );
if(ch=='y'){
IOWR(FREEDEV_AIC23_0_BASE,0x00,0x0201);
// 屏蔽输入中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x03);
//复位FreeDev_aic23外设
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x01);
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x00);
// 启动数据接收
IOWR(FREEDEV_AIC23_0_BASE,0x01,0x02);
for(i=0;i<AUDIO_BUFF_SIZE;)
{
//读音频外设状态
v1=IORD(FREEDEV_AIC23_0_BASE,0x03);
// 输入FIFO不为空 或 输入FIFO为满
if(!(v1 & 0x08) || (v1 & 0x04) )
{
audioBuff[i]=IORD(FREEDEV_AIC23_0_BASE,0x07);
IOWR(FREEDEV_AIC23_0_BASE,0x07,audioBuff[i]);
i++;
}
}
ch=ShowSelect( "播放刚才的录音吗?y OR n",'y','n' );
if(ch=='y'){
for(i=0;i<AUDIO_BUFF_SIZE;)
{
//读音频外设状态
v1=IORD(FREEDEV_AIC23_0_BASE,0x03);
// 输出FIFO不为满
if(!(v1 & 0x01))
{
IOWR(FREEDEV_AIC23_0_BASE,0x07,audioBuff[i]);
i++;
}
}
}
ch=ShowSelect( "录音数据保存到文件audio.dat?y OR n \n 存取HOSTFS需要较长时间,请耐心等待",'y','n' );
if(ch=='y'){
// 打开主机文件
hostfile = fopen("/mnt/host/audio.dat", "w");
// 写音频数据
for(i=0;i<AUDIO_BUFF_SIZE;i++)
{
fwrite(audioBuff[i],4,1,hostfile);
}
// 关闭文件
fclose(hostfile);
}
}
ch=ShowSelect( "播放音频文件audio.dat?y OR n \n存取HOSTFS需要较长时间,请耐心等待",'y','n' );
if(ch=='y'){
// 屏蔽输入中断
IOWR(FREEDEV_AIC23_0_BASE,0x02,0x03);
// 打开主机文件
hostfile = fopen("/mnt/host/audio.dat", "r");
// 读音频数据到内存
for(i=0;i<AUDIO_BUFF_SIZE;i++)
{
fread(audioBuff[i],4,1,hostfile);
}
// 关闭文件
fclose(hostfile);
//播放内存音频数据
for(i=0;i<AUDIO_BUFF_SIZE;)
{
//读音频外设状态
v1=IORD(FREEDEV_AIC23_0_BASE,0x03);
// 输出FIFO不为满
if(!(v1 & 0x01))
{
IOWR(FREEDEV_AIC23_0_BASE,0x07,audioBuff[i]);
i++;
}
}
}
goto menu;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -