×
单片机 > 单片机程序设计 > 详情

S3C2440裸板WM8976声卡驱动实现

发布时间:2020-06-16 发布时间:
|

本源代码在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);  


关键字:S3C2440  裸板  WM8976  声卡驱动 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32单片机的复用端口初始化的步骤及方法