/*L3MODE:J7(GPB2);L3DATA:K3(GPB3);L3CLOCK:K4(GPB4)*/
#define L3DATA (1<<3)
#define L3CLOCK (1<<4)
void uda_io_init()
{
/*IISLRCLK=GPE0,IISSCLK=GPE1,CDCLK=GPE2,IISSDI=GPE3,IISSDO=GP4*/
GPECON|=(1<<1)|(1<<3)|(1<<5)|(1<<7)|(1<<9);
GPEUP|=(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0);;
GPBCON|=(1<<4)|(1<<6)|(1<<8);
GPBUP|=(1<<4)|(1<<3)|(1<<2);
}
void WriteL3(unsigned char data, unsigned char mode)
{
//mode = 0,地址模式;mode = 1,数据传输模式
int i, k;
uda_io_init();
if(mode == 0) //地址模式时序
{
GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK )|L3CLOCK;
}
else //数据模式时序
{
GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);
}
for(k = 0; k < 5; k++); //延时
for(i = 0; i < 8; i++)
{
if(data & 0x1)
{
GPBDAT &= ~L3CLOCK;
GPBDAT |= L3DATA; //发送高电平
for(k = 0; k < 5; k++);
GPBDAT |= L3CLOCK;
GPBDAT |= L3DATA;
for(k = 0; k < 5; k++);
}
else
{
GPBDAT &= ~L3CLOCK;
GPBDAT &= ~L3DATA; //发送低电平
for(k = 0; k < 5; k++);
GPBDAT |= L3CLOCK;
GPBDAT &= ~L3DATA;
for(k = 0; k < 5; k++);
}
data >>= 1;
}
GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);
}
void record()
{
unsigned short int temp;
unsigned int i,stop=0,count=0;
GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);
WriteL3(0x14+2,0);
WriteL3(0x60,1); //复位
WriteL3(0x14+2,0);
WriteL3(0x10,1); //00010000 系统时钟频率384fs
WriteL3(0x14+2,0);
WriteL3(0xa2,1); //10100010 输入增益6db,ADC开,DAC关
WriteL3(0x14+0,0);
WriteL3(0x0,1); //音量衰减0db
WriteL3(0x7b,1); //01,1110,11 (BB 18dB~24dB) Treble 6dB
WriteL3(0x14+0,0);
WriteL3(0x90,1); //采样频率为44.1khz
WriteL3(0xc0,1);
WriteL3(0xe0,1); //000,00000 MA 0dB
WriteL3(0xc4,1);
WriteL3(0xf0,1); //100,1,00,00 AGC使能
WriteL3(0xc2,1);
WriteL3(0xf9,1); //010,110,11 MIC 27dB input 1选择 通道2关闭
WriteL3(0xc6,1);
WriteL3(0xe0,1); //output lever -9db ATTACK TIME=11ms,DECAY TIME=100ms
/*IIS配置*/
IISCON = (0<<5)|(0<<4)|(1<<3)|(0<<2)|(1<<1); //DMA禁止,在接受空闲状态,不产生IISLRCK信号,IIS预分频使能
IISMOD = (0<<9)|(0<<8)|(1<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0); //主设备时钟PCLK,主设备模式,接收模式,串行数据16位,主时钟是384fs,串行位时钟32fs
IISPSR = (2<<5)|2; //预分频都是N=2
IISFCON = (0<<14)|(1<<12); //发送FIFO正常,发送FIFO使能
IISCON|=(1<<0); //iis开启
while(stop==0)
if((IISCON & (1<<6))==0) //检查输入FIFO是否为满
record_buffer[count+2*i+1]=(temp>>8);
}
count+=64;
}
}
IISCON = 0x0; //关闭IIS
GPBDAT|=1; //蜂鸣器输出高点平
}
void playsound(unsigned char *buffer, int length)
char flag;
GPBDAT = GPBDAT & ~(L3MODE|L3CLOCK|L3DATA) |(L3MODE|L3CLOCK); //L3开始传输:L3M=H, L3C=H
//配置UDA1341
WriteL3(0x14 + 2,0); //状态模式(000101xx+10)
WriteL3(0x60,1); //0,1,10, 000,0 : 状态0,复位
WriteL3(0x14 + 2,0); //状态模式 (000101xx+10)
WriteL3(0x10,1); //0,0,01, 000,0 : 状态0, 384fs,IIS,no DC-filtering
WriteL3(0x14 + 2,0); //状态模式 (000101xx+10)
WriteL3(0xc1,1); //1,0,0,0, 0,0,01:状态1,
//Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,
//DAC non-inverting,Single speed playback,ADC-Off DAC-On
//配置s3c2440的IIS寄存器
//预分频器为2,所以CDCLK=PCLK/(3+1)=16.928kHz
IISPSR = 2<<5|2;
//无效DMA,输入空闲,预分频器有效
IISCON = (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);
//PCLK为时钟源,输出模式,IIS模式,每个声道16位,CODECLK=384fs,SCLK=32fs
IISMOD = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);
IISFCON = (0<<15)|(1<<13); //输出FIFO正常模式,输出FIFO使能
flag=1;
count=0;
//开启IIS
IISCON |= 0x1;
while(flag)
{
if((IISCON & (1<<7))==0) //检查输出FIFO是否为空
{
//FIFO中的数据为16位,深度为32
//当输出FIFO为空时,一次性向FIFO写入32个16位数据
for(i=0;i<32;i++)
{
IISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8);
}
count+=64;
if(count>length)
flag=0; //音频数据传输完,则退出
}
}
IISCON = 0x0; //关闭IIS
}