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

📄 audio_aic23.c

📁 在开发FPGA上比较有用
💻 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 + -