- UID
- 1029342
- 性别
- 男
|
IISFCON寄存器
功能名称
| 位
| 说明
| TX_FIFO_MODE
| [15]
| 传输FIFO访问模式选择
0——普通
1——DMA
| RX_FIFO_MODE
| [14]
| 接收FIFO访问模式选择
0——普通
1——DMA
| TX_FIFO_EN
| [13]
| 传输FIFO使能位
0——关闭
1——使能
| RX_FIFO_EN
| [12]
| 接收FIFO使能位
0——关闭
1——使能
| 传输FIFO数据计数
| [11:6]
| 数据计数值0~32
| 接收FIFO数据计数
| [5:0]
| 数据计数值0~32
| IISFIFO寄存器
功能名称
| 位
| 说明
| FENTRY
| [15:0]
| IIS FIFO寄存器保存传输或者接收的音频数据值
| IIS播放和录音功能的基本实现
在S3C2440上使用IIS有两种方案可以实现,第一种是简单的且基本的方法。通过轮询的方式读取和输出音频数据来分别实现录音和放音的功能。通过寄存器配置好预分频器和音频数据的数据位、主时钟、数据时钟以及FIFO后便可以读或者写FIFO来实现上述功能。不过在正式使用之前还要注意UDA1341TS的配置,只有配置了它(CODEC)模拟信号才能正确的转换为IIS接口的数据或者将IIS接口的数据转换为模拟信号输出。这部分的配置是通过一个叫做“L3”总线接口来实现,关于这部分接口的介绍,参见《UDA1341TS的L3微控制器部分说明翻译》中的描述。
下面这段代码是L3写的一个实现,通过这个我们可以向CODEC发出各种命令进行配置,由于TQ2440将这三个管脚和GPIO相连,所以我们要自行模拟该总线的时序:
01 static void WriteL3(unsigned char data,unsigned char address)
02 {
03 int i,j;
04 /**
05 *地址模式时序,掌握几个要点
06 *数据传输的时候保证L3MODE为低
07 *数据传输开始的信号是保证L3MODE为低L3CLOCK为高
08 *数据传输结束的信号是保证L3MODE为高L3CLOCK为高
09 *数据传输过程中一个L3CLOCK的周期传一个数据位
10 *数据模式时序,掌握几个要点
11 *数据传输的时候保证L3MODE为低
12 *数据传输开始的信号是保证L3MODE为高L3CLOCK为高
13 *数据传输结束的信号是保证L3MODE为高L3CLOCK为高
14 *数据传输过程中一个L3CLOCK的周期传一个数据位
15 */
16 if(1 == address)
17 GPBDAT = (GPBDAT & (~(L3D | L3M | L3C))) | L3C;
18 else
19 GPBDAT = (GPBDAT & (~(L3D | L3M | L3C))) | (L3C | L3M);
20 for(i = 0;i < 10;i++);
21
22 for(i = 0;i < 8;i++)
23 {
24 if(data & 0x01)
25 {
26 GPBDAT &= ~L3C;
27 GPBDAT |= L3D;
28 for(j = 0;j < 5;j++);
29 GPBDAT |= L3C;
30 GPBDAT |= L3D;
31 for(j = 0;j < 5;j++);
32 }
33 else
34 {
35 GPBDAT &= ~L3C;
36 GPBDAT &= ~L3D;
37 for(j = 0;j < 5;j++);
38 GPBDAT |= L3C;
39 GPBDAT &= ~L3D;
40 for(j = 0;j < 5;j++);
41 }
42 data >>= 1;
43 }
44 GPBDAT = (GPBDAT & (~(L3D | L3M | L3C))) | (L3C | L3M);
45 }
IIS功能的轮询方式实现
这部分代码是本次试验录制/播放声音的主控代码,还是在一个简单的串口控制台框架下添加的相关的命令处理。实现本次试验的流程控制(实验的时候先录音再播放):
01 if(!(no_system_strcmp("iis record test",cmd_buf)))
02 {
03 no_system_memset(cmd_buf,0,50);
04 /**
05 *GPIO B的管脚配置用于L3总线
06 *GPIO E的管脚配置用于IIS接口
07 */
08 GPBCON = 0x015550;
09 GPBUP = 0x7ff;
10 GPBDAT = 0x1e4;
11 GPEUP = (GPEUP & (~(0x1f))) | 0x1f;
12 GPECON = (GPECON & (~(0x3ff))) | 0x2aa;
13 uart0_printf("record begin\n\r");
14 record((unsigned char *)0x31000000);//录制的声音存放到外扩内存0x31000000处录制的长度6400 * 400
15 uart0_printf("record end\n\r");
16 }
17 else if(!(no_system_strcmp("iis record play",cmd_buf)))
18 {
19 no_system_memset(cmd_buf,0,50);
20 GPBCON = 0x015550;
21 GPBUP = 0x7ff;
22 GPBDAT = 0x1e4;
23 GPEUP = (GPEUP & (~(0x1f))) | 0x1f;
24 GPECON = (GPECON & (~(0x3ff))) | 0x2aa;
25
26 uart0_printf("play begin\n\r");
27 iis_test_play((unsigned char *)0x31000000,6400);//播放外扩内存0x31000000处的音频
28 uart0_printf("play end\n\r");
29 }
这段代码实现了播放一段2声道、44.1KHz音频数据的功能。参数buffer指明这个数据存放的地方,length只是为了配合录音数据播放而定义的。该函数不具备通用性:
01 void iis_test_play(unsigned char *buffer,unsigned long int length)
02 {
03 unsigned long int count,i;
04 int flag;
05 int music;
06
07 GPBDAT = (GPBDAT & (~(L3M | L3C | L3D))) | (L3M | L3C);
08 //地址操作,定位到STATUS模式
09 WriteL3(0x14 + 2,1);
10 //0,1,10,000,0——UDA1341TS设备重启,系统时钟设置为256fs,数据输入格式设置IIS总线,没有DC滤波
11 WriteL3(0x60,0);
12
13 WriteL3(0x14 + 2,1);
14 //0,0,01,000,0——UDA1341TS设备不重启,系统时钟设置为384fs,数据输入格式设置为IIS总线,没有DC滤波
15 WriteL3(0x10,0);
16
17 WriteL3(0x14 + 2,1);
18 //1,1,0,0,0,0,01——DAC输出增益选择为6db(OGS),ADC输入增益选择为0db(IGS),ADC极性不翻转,DAC极性不翻转,倍速回放关闭,ADC关闭DAC启动
19 WriteL3(0xc1,0);
20
21 IISPSR = PRESCANLER_A(2) | PRESCANLER_B(2);
22 IISCON = RX_CH_IDLE_CMD | IIS_PRESCALER;
23 IISMOD = TX_RX_MODE(2) | S_DATA_BIT(BIT16) | MA_CLOCK(FS384) |\
24 S_CLOCK(FS32);
25
26 IISFCON = TX_FIFO_AC(NORMAL) | TX_FIFO_EN;
27 flag = 1;
28 count = 0;
29 IISCON |= 0x01;
30 while(flag)
31 {
32 /**
33 *放音 长度:400 * length
34 */
35 if(0 == (IISCON & (1 << 7)))
36 {
37 for(i = 0;i < 32;i++)
38 {
39 //这里一定要注意地址的偏移
40 music = buffer[2 * i + count + (flag - 1) * length] + (buffer[2 * i + 1 + count + (flag -1) * length] << 8);
41 IISFIFO = music;
42 }
43 count += 64;
44 if(count >= length)
45 {
46 count = 0;
47 flag++;
48 }
49 }
50 if(400 == flag)
51 flag = 0;
52 }
53 IISCON = 0x00;
54 } |
|