本源代码在Ubuntu9.10环境下用arm-linux-gcc 4.3.2编译通过,并在勤研2440开发板上验证过可以播放采样频率为22050HZ的音频WAV文件
#include "def.h"
#include "iis.h"
#include "s3c24xx.h"
#define L3M (1<<2)
#define L3D (1<<3)
#define L3C (1<<4)
unsigned char *Buf = (unsigned char *)0x31000000;
//data chunk size
unsigned int size = 0;
//sampling frequency
unsigned int fs = 0;
//-------------------------------------------------------------
// S3C2440A IIS Configuration
// GPB4 = L3CLOCK, GPB3 = L3DATA, GPB2 = L3MODE
// GPE0 = I2SLRCK, GPE1 = I2SSCLK, GPE3 = I2SSDI, GPE4 = I2SSDO, GPE2 = CDCLK
//-------------------------------------------------------------
void Play_WAV(void)
{
Printf("[ IIS test using WM8976 CODEC ]/r/n");
IIS_PortSetting();
Init8976();
//set INT_DMA2 interrput service is available
INTMSK &= ~(1 << 19);
fs = *(Buf + 0x18) | *(Buf + 0x19)<<8 | *(Buf + 0x1a)<<16 | *(Buf + 0x1b)<<24;
if(fs == 44100) //11.2896MHz (256fs)
{
// IISPSR = (3<<5) + 3;
}
else if(fs == 22050) //5.6448MHz (256fs)
{
IISPSR = (8<<5) + 8;
size = *(Buf + 0x28) | *(Buf + 0x29)<<8 | *(Buf + 0x2a)<<16 | *(Buf + 0x2b)<<24;
DISRC2 = (int)(Buf + 0x2c);
}
Printf("Sample Size = 0x%x/r/n", size/2);
Printf("Sampling Frequency = %d Hz/r/n", fs);
Printf("/r/n[ Nowing play the wav file ...]/r/n");
//init IIS
IISCON = (1<<5) + (1<<2) + (1<<1); //Tx DMA service request Enable[5], Rx Idle[2], IIS prescaler Enable[1];
IISMOD = (0<<9) + (0<<8) + (2<<6) + (0<<5) + (0<<4) + (1<<3) + (0<<2) + (1<<0);
IISFCON = (1<<15) + (1<<13); //Tx FIFO access mode DMA[15], Tx FIFO Enable[13]
//init DMA2
DISRCC2 = (0<<1) + (0<<0); //the source is in the AHB, increment
DIDST2 = (U32)IISFIFO; //IISFIFO
DIDSTC2 = (1<<1) + (1<<0); //the destination is in the APB, fixed
//Handshake[31], Sync PCLK[30], CURR_TC Interrupt enable[29],Unit Transfer[28],Single Service Mode[27]
//I2SSDO[26:24], DMA Source[23], Auto Reload[22], Half-Word[21:20], TC[19:0]
DCON2 = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<24)+(1<<23)+(1<<22)+(1<<20)+(size/2);
//No-Stop[2], DMA channel is turned on[1], No-Trigger in S/W request mode[0]
DMASKTRIG2 = (0<<2)+(1<<1)+(0<<0);
//IIS Interface Start
IISCON |= 0x1;
}
void IIS_PortSetting(void)
{
//------------------------------------------------------
// Port E Group
//Ports: GPE0 GPE1 GPE2 GPE3 GPE4
//Signal: I2SLRCK I2SSCLK CDCLK I2SSDI I2SSDO
// [1:0] [3:2] [5:4] [7:6] [9:8]
//Binary: 10 10 10 10 10
//------------------------------------------------------
GPEUP = GPEUP | (0x1f);
GPECON = GPECON & ~(0x3ff) | (0x2aa);
}
void Init8976(void)
{
//----------------------------------------
// Port B Group
//Ports: GPB2 GPB3 GPB4
//Signal: L3MODE L3DATA L3CLOCK
//Setting: OUTPUT OUTPUT OUTPUT
// [9:8] [7:6] [5:4]
//Binary: 01 01 01
//----------------------------------------
GPBUP = GPBUP | (0x7<<2); //disable GPB[4:2] pull up function
GPBCON = GPBCON & ~(0x3f<<4) | (0x15<<4);
GPBDAT = GPBDAT & ~(L3M|L3D|L3C) | (L3M|L3C); //L3Mode=H, L3Clock=H
WriteL3Data((0x3<<1)+1,0xef);//RMIXEN,LMIXEN,DACENR,DACENL
WriteL3Data((0x1<<1)+0,0x1f);//biasen,BUFIOEN.VMIDSEL=11b
WriteL3Data((0x2<<1)+1,0x80);//ROUT1EN LOUT1EN
WriteL3Data((0x6<<1)+0,0x0);//SYSCLK=MCLK
WriteL3Data((0x4<<1)+0,0x10);//16bit
WriteL3Data((0x2B<<1)+0,0x10);//BTL OUTPUT
WriteL3Data((0x9<<1)+0,0x50);//Jack detect enable
WriteL3Data((0xD<<1)+0,0x21);//Jack detect
WriteL3Data((0x7<<1)+0,0x01);//Jack detect
}
void WriteL3Data(unsigned char regaddr, unsigned char data)
{
int i, j;
//start condition: L3M = High L3C = High
GPBDAT |= L3M;
GPBDAT |= L3C;
GPBDAT |= L3M;
GPBDAT |= L3C;
for(i=0; i<100; i++); //delay
//control register address
for(j=0; j<8; j++)
{
if(regaddr & 0x80)
{
GPBDAT &= ~L3C;
GPBDAT |= L3D;
for(i=0; i<10; i++); //delay
GPBDAT |= L3C;
for(i=0; i<10; i++); //delay
}
else
{
GPBDAT &= ~L3C;
GPBDAT &= ~L3D;
for(i=0; i<10; i++); //delay
GPBDAT |= L3C;
for(i=0; i<10; i++); //delay
}
regaddr = regaddr << 1;
}
//control register data bits
for(j=0; j<8; j++)
{
if(data & 0x80)
{
GPBDAT &= ~L3C;
GPBDAT |= L3D;
for(i=0; i<10; i++); //delay
GPBDAT |= L3C;
for(i=0; i<10; i++); //delay
}
else
{
GPBDAT &= ~L3C;
GPBDAT &= ~L3D;
for(i=0; i<10; i++); //delay
GPBDAT |= L3C;
for(i=0; i<10; i++); //delay
}
data = data << 1;
}
GPBDAT &= ~L3M;
for(i=0; i<1000; i++);
GPBDAT |= L3M;
GPBDAT |= L3C;
}
void DMA2_Done(void)
{
SRCPND |= (1<<19);
INTPND = (1<<19);
IISCON = 0x0; //IIS Interface stop
DMASKTRIG2 = (1<<2); //DMA2 stop
IISFCON = 0x0; //FIFO flush
INTMSK = INTMSK | (1<<19);
}
上一篇:LPC1768 -- RTC实时时钟
下一篇:STM32之timer1产生PWM(互补通道)
推荐阅读最新更新时间:2024-03-16 16:09