mic.c
来自「采用32位嵌入式芯片SPCE3200(凌阳)设计的开发板,具有多媒体功能。其中包」· C语言 代码 · 共 401 行
C
401 行
//====================================================================================
//文 件 名:MIC.c
//功能描述: MIC驱动程序(API)
//维护记录:
// 2007.01.17 V0.1 by wangtao <wangtao@sunnorth.com.cn>
//====================================================================================
#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include "MIC.h"
unsigned int gunMIC_transbuf1[DATANUM_SIZES]; // catch range
unsigned int *gunMIC_trans1_ptr;
unsigned int gunMIC_transbuf2[DATANUM_SIZES]; // catch range
unsigned int *gunMIC_trans2_ptr;
unsigned int gunMIC_readbuf1[(DATANUM_COUNT * DATANUM_SIZES)];
unsigned int gunMIC_readbuf2[(DATANUM_COUNT * DATANUM_SIZES)];
unsigned int gunMIC_AUDIO_PCM_BUFFER;
unsigned int gunMIC_DMA_PCM_BUFFER;
unsigned int gunMIC_count1=0;
unsigned int gunMIC_count2=0;
unsigned int gunMIC_PCMDataOffsetPtr=0;
unsigned int gucMIC_BUffFull=0;
//unsigned int DATANUM_SIZES;
#ifdef MOVE_BY_BLOCK
unsigned int gunMIC_RemainDataA=0;
unsigned int gunMIC_RemainDataB=0;
#endif
//=============================================================
//语法格式: unsigned char MICAudioBuffChange(void)
//实现功能: 切换MIC缓冲区
//参数: 无
//返回值: 当前使用的缓冲区
//=============================================================
unsigned char MICAudioBuffChange(void)
{
#ifdef MOVE_BY_BLOCK
unsigned int j;
unsigned int BufferRemainData;
#endif
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
if(gucMIC_BUffFull == 0)
{
if(gunMIC_count1 < (DATANUM_COUNT-1))
{
gucMIC_BUffFull = 0;
return ((unsigned char) gunMIC_AUDIO_PCM_BUFFER) ;
}
else
{
gucMIC_BUffFull = 1;
}
}
if(gunMIC_count1!=0)
{
#ifdef MOVE_BY_BLOCK
BufferRemainData = (gunMIC_count1 * DATANUM_SIZES) + gunMIC_RemainDataA;
gunMIC_RemainDataB = BufferRemainData % DATANUM_BLOCK;
for(j=0;j<gunMIC_RemainDataB;j++)
{
gunMIC_readbuf2[j] = gunMIC_readbuf1[BufferRemainData - gunMIC_RemainDataB + j] ;
}
#endif
gunMIC_AUDIO_PCM_BUFFER = AUDIO_PCM_BUFFER_B;
gunMIC_count2 = 0;
gunMIC_PCMDataOffsetPtr = 0;
gucMIC_BUffFull = 0;
}
else
{
//
}
}
else
{
if(gucMIC_BUffFull == 0)
{
if(gunMIC_count2 < (DATANUM_COUNT-1))
{
gucMIC_BUffFull = 0;
return ((unsigned char) gunMIC_AUDIO_PCM_BUFFER) ;
}
else
{
gucMIC_BUffFull = 1;
}
}
if(gunMIC_count2!=0)
{
#ifdef MOVE_BY_BLOCK
BufferRemainData = (gunMIC_count2 * DATANUM_SIZES) + gunMIC_RemainDataB;
gunMIC_RemainDataA = BufferRemainData % DATANUM_BLOCK;
for(j=0;j<gunMIC_RemainDataA;j++)
{
gunMIC_readbuf1[j] = gunMIC_readbuf2[BufferRemainData - gunMIC_RemainDataA + j] ;
}
#endif
gunMIC_AUDIO_PCM_BUFFER = AUDIO_PCM_BUFFER_A;
gunMIC_count1 = 0;
gunMIC_PCMDataOffsetPtr = 0;
gucMIC_BUffFull = 0;
}
else
{
//
}
}
return ((unsigned char) gunMIC_AUDIO_PCM_BUFFER) ;
}
//=============================================================
//语法格式: void MIC32Init(unsigned int SampleRate)
//实现功能: 初始化MIC
//参数: SampleRate: 采样率
//返回值: 无
//=============================================================
void MIC32Init(unsigned int SampleRate)
{
//init
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_A;
gunMIC_AUDIO_PCM_BUFFER = AUDIO_PCM_BUFFER_A;
gunMIC_count1 = 0;
gunMIC_count2 = 0;
gunMIC_PCMDataOffsetPtr = 0;
gucMIC_BUffFull = 0;
#ifdef MOVE_BY_BLOCK
gunMIC_RemainDataA=0;
gunMIC_RemainDataB=0;
#endif
//end
gunMIC_trans1_ptr = (unsigned int*)(((unsigned int)gunMIC_transbuf1) & 0x8fffffff); // non-catch range
gunMIC_trans2_ptr = (unsigned int*)(((unsigned int)gunMIC_transbuf2) & 0x8fffffff); // non-catch range
*P_INT_MASK_CTRL1 = ~0x40000001;
*P_DAC_CLK_CONF = 0x0003;
*P_ADC_CLK_CONF = 0x0003;//C_ADC_CLK_EN|C_ADC_RST_DIS;
*P_CLK_PLLAU_CONF = 0x00000007; // enable audio pll
*P_ADC_CLK_CONF = 0x00000000; // adc controller clock enable
*P_ADC_CLK_CONF = 0x00000003; // adc controller clock enable
*P_ADC_CLK_SEL = 0x00000001; // adc source clock div 2
*P_DAC_MODE_CTRL1 &= ~0x0003;
*P_DMA_AHB_SA2BA = (unsigned int) gunMIC_trans1_ptr;
*P_DMA_AHB_EA2BA = (unsigned int) gunMIC_trans1_ptr + 4 * DATANUM_SIZES - 4;
*P_DMA_AHB_SA2BB = (unsigned int) gunMIC_trans2_ptr;
*P_DMA_AHB_EA2BB = (unsigned int) gunMIC_trans2_ptr + 4 * DATANUM_SIZES - 4;
*P_DMA_APB_SA2 = (unsigned int)P_ADC_MIC_DATA;
*P_DMA_CHANNEL2_CTRL = DMA_P2M | DMA_REQ | DMA_FIX | DMA_DOUBLE_BUF | DMA_32BIT_BURST | DMA_IRQON | DMA_ON;
//*P_ADC_CLOCK_SET = 47; // for 44.1KHz
*P_ADC_SAMPLE_CLK = (33868800/SampleRate/16)-1;
*P_ADC_SAMPLE_HOLD = 0x2000000F;
*P_ADC_MIC_CTRL1 = ANA_AD_POWON | ANA_AD_ON | ANA_MIC_ON | ANA_MICBST_OFF | ANA_MICBIAS_ON | ANA_ADV_INT |
ANA_MIC_CHANNEL;
*P_ADC_INT_STATUS = DIG_ADCIRQ_CLR | DIG_ADCIRQ_DIS | DIG_ASPIRQ_CLR | DIG_ASPIRQ_DIS | DIG_MICIRQ_CLR |
DIG_MICIRQ_DIS | FIFO_ERR_CLR;
*P_ADC_MIC_CTRL2 = DIG_AD_ON | DIG_AD_AUTO | DIG_MICSIGN_OFF | DIG_MICMUTE_OFF | DIG_DMASIZE_32 |
DIG_SMART_OFF | DIG_FIFO_L0;
*P_ADC_MIC_GAIN = 10; //15
}
//=============================================================
//语法格式: void MIC32_Off(void)
//实现功能: 关闭MIC
//参数: 无
//返回值: 无
//=============================================================
void MIC32_Off(void)
{
*P_ADC_MIC_CTRL1 = ANA_AD_POWOFF | ANA_AD_OFF | ANA_MIC_OFF | ANA_MICBST_OFF | ANA_MICBIAS_OFF | ANA_ADV_INT |
ANA_MIC_CHANNEL;
*P_DMA_CHANNEL2_CTRL = DMA_P2M | DMA_REQ | DMA_FIX | DMA_DOUBLE_BUF | DMA_32BIT_BURST | DMA_IRQON | DMA_OFF;
}
//=============================================================
//语法格式: void MICGetPCMData(void)
//实现功能: 读取MIC数据
//参数: 无
//返回值: 无
//=============================================================
void MICGetPCMData(void)
{
unsigned int j;
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
if(gunMIC_count1>=DATANUM_COUNT)
{
if(gunMIC_DMA_PCM_BUFFER == DMA3_BUFFER_A)
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_B;
}
else
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_A;
}
return;
}
}
else
{
if(gunMIC_count2>=DATANUM_COUNT)
{
if(gunMIC_DMA_PCM_BUFFER == DMA3_BUFFER_A)
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_B;
}
else
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_A;
}
return;
}
}
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
if(gunMIC_DMA_PCM_BUFFER == DMA3_BUFFER_A)
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_B;
for(j = 0; j < DATANUM_SIZES; j++)
{
#ifdef MOVE_BY_BLOCK
gunMIC_readbuf1[gunMIC_count1 * DATANUM_SIZES + j + gunMIC_RemainDataA] = *(gunMIC_trans1_ptr + j);
#else
gunMIC_readbuf1[gunMIC_count1 * DATANUM_SIZES + j] = *(gunMIC_trans1_ptr + j);
#endif
}
}
else
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_A;
for(j = 0; j < DATANUM_SIZES; j++)
{
#ifdef MOVE_BY_BLOCK
gunMIC_readbuf1[gunMIC_count1 * DATANUM_SIZES + j + gunMIC_RemainDataA] = *(gunMIC_trans2_ptr + j);
#else
gunMIC_readbuf1[gunMIC_count1 * DATANUM_SIZES + j] = *(gunMIC_trans2_ptr + j);
#endif
}
}
gunMIC_count1++;
}
else
{
if(gunMIC_DMA_PCM_BUFFER == DMA3_BUFFER_A)
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_B;
for(j = 0; j < DATANUM_SIZES; j++)
{
#ifdef MOVE_BY_BLOCK
gunMIC_readbuf2[gunMIC_count2 * DATANUM_SIZES + j + gunMIC_RemainDataB] = *(gunMIC_trans1_ptr + j);
#else
gunMIC_readbuf2[gunMIC_count2 * DATANUM_SIZES + j] = *(gunMIC_trans1_ptr + j);
#endif
}
}
else
{
gunMIC_DMA_PCM_BUFFER = DMA3_BUFFER_A;
for(j = 0; j < DATANUM_SIZES; j++)
{
#ifdef MOVE_BY_BLOCK
gunMIC_readbuf2[gunMIC_count2 * DATANUM_SIZES + j + gunMIC_RemainDataB] = *(gunMIC_trans2_ptr + j);
#else
gunMIC_readbuf2[gunMIC_count2 * DATANUM_SIZES + j] = *(gunMIC_trans2_ptr + j);
#endif
}
}
gunMIC_count2++;
} //if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
}
//=============================================================
//语法格式: unsigned int MICGetBuffSizes(void)
//实现功能: 得到MIC缓冲区大小
//参数: 无
//返回值: 缓冲区大小
//=============================================================
unsigned int MICGetBuffSizes(void)
{
unsigned int DataSizes;
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
DataSizes = (gunMIC_count2 * DATANUM_SIZES * 4 + (gunMIC_RemainDataB*4)); //unit: bytes;
DataSizes = DataSizes - (DataSizes % (DATANUM_BLOCK*4)) - (gunMIC_PCMDataOffsetPtr*4);
if(DataSizes==0)
{
gucMIC_BUffFull = 1;
}
}
else
{
DataSizes = (gunMIC_count1 * DATANUM_SIZES * 4 + (gunMIC_RemainDataA*4)); //unit: bytes
DataSizes = DataSizes - (DataSizes % (DATANUM_BLOCK*4)) - (gunMIC_PCMDataOffsetPtr*4);
if(DataSizes==0)
{
gucMIC_BUffFull = 1;
}
}
MICAudioBuffChange();
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
#ifdef MOVE_BY_BLOCK
DataSizes = (gunMIC_count2 * DATANUM_SIZES * 4 + (gunMIC_RemainDataB*4)); //unit: bytes;
DataSizes = DataSizes - (DataSizes % (DATANUM_BLOCK*4)) - (gunMIC_PCMDataOffsetPtr*4);
return DataSizes;
#else
return (gunMIC_count2 * DATANUM_SIZES * 4) ; //unit: bytes
#endif
}
else
{
#ifdef MOVE_BY_BLOCK
DataSizes = (gunMIC_count1 * DATANUM_SIZES * 4 + (gunMIC_RemainDataA*4)); //unit: bytes
DataSizes = DataSizes - (DataSizes % (DATANUM_BLOCK*4)) - (gunMIC_PCMDataOffsetPtr*4);
return DataSizes;
#else
return (gunMIC_count1 * DATANUM_SIZES * 4) ; //unit: bytes
#endif
}
}
//=============================================================
//语法格式: unsigned int MICGetDataPtr(unsigned int DataSizes)
//实现功能: 得到MIC缓冲区指针
//参数: DataSizes: 数据大小
//返回值: 缓冲区指针
//=============================================================
unsigned int MICGetDataPtr(unsigned int DataSizes) //DataSizes must be multiple of 4
{
unsigned int gunMIC_PCMDataOffsetPtr_temp;
unsigned int ALLDataSizes;
ALLDataSizes = MICGetBuffSizes();
ALLDataSizes += gunMIC_PCMDataOffsetPtr*4; //bytes
gunMIC_PCMDataOffsetPtr_temp = gunMIC_PCMDataOffsetPtr;
gunMIC_PCMDataOffsetPtr += (DataSizes/4);
if(gunMIC_PCMDataOffsetPtr > (ALLDataSizes/4))
{
gunMIC_PCMDataOffsetPtr -= (DataSizes/4);
return MIC_DATA_NOT_ENOUGH; //allocated Data Sizes too bigger
}
if(gunMIC_AUDIO_PCM_BUFFER==AUDIO_PCM_BUFFER_A)
{
return (unsigned int)&gunMIC_readbuf2[gunMIC_PCMDataOffsetPtr_temp];
}
else
{
return (unsigned int)&gunMIC_readbuf1[gunMIC_PCMDataOffsetPtr_temp];
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?