S3C2440之IIS操作---MDK4.22,可烧写在NANDFLASH和NORFLASH运行

IIS基本原理:


由图可知,有发送器,也有接收器,发送器和接收器都可以作为控制器。谁发出WS和SCK,谁就是控制器。

SCK为IIS串行数据的位时钟,WS为声道切换时钟,WS的频率等于采样频率fs。SCK频率=WS*每个数据的位数*通道数。

MSB先发送,由于收发对于字长的规定可以不一样,所以最终的长度需要根据实际情况而定。


2440具有64深度,且位长为16bit的FIFO。PCLK进过预分频A和B产生SCLK和LRCK。PCLK和MPLLin共同产生CDCLK,供给音频编码译码器使用。

因为2440的IIS接口仅仅是单纯的传输数据,依从IIS协议而已,实际使用中,需要将数据转换为模拟音频,或者将外界的音频转换为数字信号给系统使用。

3种模式:DMA模式,同时传输和接收模式,仅传输和接收模式。

这里采用的编码译码器是UDA1314TS。仅为从模式,需要主设备供应时钟,为256fs、384fs、512fs。

UDA1314具有L3线接口与微控制器通信。L3DATA L3MODE L3CLOCK。具有2种模式,地址模式和数据模式。地址模式通过L3选择通信的设备且定义数据传输模式访问的目的寄存器。数据模式是双向的,输入到UDA1314中编程它的声音处理和系统控制特性和从UDA1314输出提供声音的峰值水平值。


先传低位,再传高位,2440不具备该接口,需要用GPIO模拟使用。



依据上面的实际图来配置硬件。


音频数据所给出的信息:

根据wav格式从数据中读出采样频率。声道数。量化位数。根据这些来配置IIS相关寄存器。


程序:

本例程,PCLK=100MHZ,音频数据的fs=22.05Khz,2通道,16bit。由于音频文件过大,所以放在类似硬盘的nandflash中,且不占用前4k。本文利用了MDK的库函数。


IIS.C文件


#include "S3C2440.h"
#include "iis.h"


/******Ä£ÄâUDA1314µÄ3Ïß²Ù×÷£¬Óë2440ͨÐÅ*********/
/******data : Ðè´«ÊäµÄÊý¾Ý****/
/******address : ÊǵØַģʽ»¹ÊÇÊý¾Ýģʽ****/
void WriteL3(unsigned char data,unsigned char address) 
{ 
	int i,j; 
      /** 
       *µØַģʽʱÐò£¬ÕÆÎÕ¼¸¸öÒªµã 
       *Êý¾Ý´«ÊäµÄʱºò±£Ö¤L3MODEΪµÍ 
       *Êý¾Ý´«Ê俪ʼµÄÐźÅÊDZ£Ö¤L3MODEΪµÍL3CLOCKΪ¸ß 
       *Êý¾Ý´«Êä½áÊøµÄÐźÅÊDZ£Ö¤L3MODEΪ¸ßL3CLOCKΪ¸ß 
       *Êý¾Ý´«Êä¹ý³ÌÖÐÒ»¸öL3CLOCKµÄÖÜÆÚ´«Ò»¸öÊý¾Ýλ 
       *Êý¾ÝģʽʱÐò£¬ÕÆÎÕ¼¸¸öÒªµã 
       *Êý¾Ý´«ÊäµÄʱºò±£Ö¤L3MODEΪµÍ 
       *Êý¾Ý´«Ê俪ʼµÄÐźÅÊDZ£Ö¤L3MODEΪ¸ßL3CLOCKΪ¸ß 
       *Êý¾Ý´«Êä½áÊøµÄÐźÅÊDZ£Ö¤L3MODEΪ¸ßL3CLOCKΪ¸ß 
       *Êý¾Ý´«Êä¹ý³ÌÖÐÒ»¸öL3CLOCKµÄÖÜÆÚ´«Ò»¸öÊý¾Ýλ 
       **/ 
  	if(1 == address) 
    	rGPBDAT = (rGPBDAT & (~(L3D | L3M | L3C))) | L3C; 
  	else 
      	rGPBDAT = (rGPBDAT & (~(L3D | L3M | L3C))) | (L3C | L3M); 
  	for(i = 0;i < 10;i++); 
   
    for(i = 0;i < 8;i++) 
    { 
    	if(data & 0x01) 
      	{ 
        	rGPBDAT &= ~L3C; 
          	rGPBDAT |= L3D; 
          	for(j = 0;j < 5;j++); 
          	rGPBDAT |= L3C; 
          	rGPBDAT |= L3D; 
          	for(j = 0;j < 5;j++); 
     	 } 
         else
		 { 
         	rGPBDAT &= ~L3C; 
            rGPBDAT &= ~L3D; 
            for(j = 0;j < 5;j++); 
            rGPBDAT |= L3C; 
            rGPBDAT &= ~L3D; 
            for(j = 0;j < 5;j++); 
          } 
          data >>= 1; 
	} 
    rGPBDAT = (rGPBDAT & (~(L3D | L3M | L3C))) | (L3C | L3M); 
}  




void playsound(unsigned char *buffer, int length)
{
	int count,i;
   	char flag;
  
   	rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //L3¿ªÊ¼´«Ê䣺L3M=H, L3C=H

   //ÅäÖÃUDA1341
   	WriteL3(0x14 + 2,1);            //״̬ģʽ(000101xx+10)
   	WriteL3(0x60,0);          //0,1,10, 000,0 : ״̬0,¸´Î»
  
   	WriteL3(0x14 + 2,1);            //״̬ģʽ (000101xx+10)
   	WriteL3(0x10,0);          //0,0,01, 000,0 : ״̬0, 384fs,IIS,no DC-filtering
  
   	WriteL3(0x14 + 2,1);     //״̬ģʽ (000101xx+10)
   	WriteL3(0xc1,0);           //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¼Ä´æÆ÷
	//Ô¤·ÖƵÆ÷Ϊ5£¬ËùÒÔCDCLK=PCLK/(5+1)=384fs=384*22.05khz=50Mhz/N+1 ---->	N=5
    rIISPSR = 5<<5|5;
       //ÎÞЧDMA£¬ÊäÈë¿ÕÏУ¬Ô¤·ÖƵÆ÷ÓÐЧ,²¥·ÅÏÖÓеÄÒôƵÊý¾Ý£¬ËùÒÔ²»ÐèÒª´ÓUDA1314ÖнÓÊÕÈκÎÊý¾Ý£¬ËùÒÔÉèÖÃÊäÈë¿ÕÏС£
	rIISCON  = (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);   
       //PCLKΪʱÖÓÔ´£¬Êä³öģʽ£¬IISģʽ£¬Ã¿¸öÉùµÀ16룬CODECLK=384fs£¬SCLK=32fs
   	rIISMOD  = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);     
   	rIISFCON = (0<<15)|(1<<13);           //Êä³öFIFOÕý³£Ä£Ê½£¬Êä³öFIFOʹÄÜ
  
 	flag=1;
   	count=0;
   	//¿ªÆôIIS
   	rIISCON |= 0x1;
    while(flag)
    {
    	if((rIISCON & (1<<7))==0)               //¼ì²éÊä³öFIFOÊÇ·ñΪ¿Õ
      	{    
             //FIFOÖеÄÊý¾ÝΪ16룬Éî¶ÈΪ32
             //µ±Êä³öFIFOΪ¿Õʱ£¬Ò»´ÎÐÔÏòFIFOдÈë32¸ö16λÊý¾Ý
			for(i=0;i<32;i++)
            {
            	rIISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8);
            }                  
			count+=64;
            if(count>length)
            	flag=0;                  //ÒôƵÊý¾Ý´«ÊäÍ꣬ÔòÍ˳ö
        }
	}
    rIISCON = 0x0;            //¹Ø±ÕIIS
}

main.c文件

int main(void)
{	
	init_uart0();
	NF_Init();

	NF_Read((u8*)0x33000000, (ulong)0x1000, 0x100000);

	printf("\r\ntest music......\r\n");
	playsound(music + 44,sizeof(music) - 44);
}

scatter文件:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************


LR_ROM1 0x00000000 0x00100000  {    ; load region size_region
  ER_ROM1 0x00000000 0x000001000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }


  RW_RAM1 0x30000000 0x40000000  {  ; RW data
   .ANY (+RW +ZI)
}
  




  OTHERS 0x31000000{
   uart.o(*)
iis.o(*)
  }

  HEAP  0x32000800 {
  S3C2440A.o(HEAP)
  }


  STACK 0x32000c00{
  S3C2440A.o(STACK)
  }


}


LD_ROM2 0x1000
{
MUSIC 0x33000000{
   *(wav)
  }
}

scatter文件中采用了2个加载域,单独把音频数据放到了4k后,运行在0x33000000.

烧写到nandflash中,可以正常运行,播放歌曲。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值