I2S通信
数字音频信号的传输标准,如:
- I2S、PCM (Pulse Code Modulation) 和 PDM (Pulse Density Modulation)主要用于同一块电路板上芯片之间音频信号的传输;
- Intel HDA (Intel High Definition Audio) 用于PC的Audio子系统(声卡)应用;
- S/PDIF 和 Ethernet AVB 主要应用于板间长距离及需要电缆连接的场合。
Philips I2S 标准
I2S的标准文件源自 飞利浦半导体(Philips Semiconductors)发表于1986年的《I2S bus specification(1996年修订版)》。
I2S(Inter-IC Sound)采用了独立的导线传输时钟与数据信号的设计,通过将数据和时钟信号分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。
需要注意:I2S是一种音频编码协议,同时也是一种音频接口,因此采用I2S接口方式的不一定采用I2S编码,还可以采用 左对齐(Left Justifying)编码 或 右对齐(Right Justifying)编码。
特点
支持全双工/半双工
支持主/从模式
和PCM相比,I2S更适合立体声系统。当然,I2S的变体也支持多通道的时分复用,因此可以支持多声道。
硬件特性
总线介绍
To minimize the number of pins required and to keep wiring simple, a 3-line serial bus is used consisting of a line for two time-multiplexed data channels, a word select line(WS) and a clock line (SCK).
从上图得知,I2S总线共需要三个引脚:
- 连续串行时钟线(SCK / SCLK / BCLK),也叫位时钟,即对应数字音频的每一位数据,SCLK都有1个脉冲。SCLK的频率=2×采样频率×采样位数。
- 字选择线(WS / LRCLK),也叫帧时钟,用于切换左右声道的数据。LRCK为“1”表示正在传输的是右声道的数据,为“0”则表示正在传输的是左声道的数据。LRCK的频率等于采样频率。
- 时分多路复用(简称 TDM)数据线,即串行数据(SD 或 SDATA),就是用二进制补码表示的音频数据。
另,有时为了使系统间能够更好地同步,还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟(Sys Clock),是采样频率的256倍或384倍。
注意:能够生成SCK和WS的就是主设备(Master)。
电压要求
VL | VH | |
---|---|---|
输出电平 | <0.4V | >2.4V |
输入电平 | 0.8V | 2.0V |
这是使用的TTL电平标准,随着其他IC(LSI)的流行,其他电平也会支持。
串行数据
I2S格式的信号无论有多少位有效数据,数据的最高位总是出现在LRCK变化(也就是一帧开始)后的第2个SCLK脉冲处。这就使得接收端与发送端的有效位数可以不同。如果接收端能处理的有效位数少于发送端,可以放弃数据帧中多余的低位数据;如果接收端能处理的有效位数多于发送端,可以自行补足剩余的位。这种同步机制使得数字音频设备的互连更加方便,而且不会造成数据错位。
随着技术的发展,在统一的 I2S接口 下,出现了多种不同的数据格式。根据SDATA数据相对于LRCK和SCLK的位置不同,分为左对齐(较少使用)、I2S格式(即飞利浦规定的格式)和右对齐(也叫日本格式、普通格式)。
为了保证数字音频信号的正确传输,发送端和接收端应该采用相同的数据格式和长度。当然,对I2S格式来说数据长度可以不同。
字选择
字选择(word select),也可以叫命令选择线,表明了正在被传输的声道。
WS=0
,表示正在传输的是 左声道 的数据。WS=1
,表示正在传输的是 右声道 的数据。
WS可以在串行时钟的上升沿或者下降沿发生改变,并且WS信号不需要一定是对称的。在从属装置端,WS在时钟信号的上升沿发生改变。WS总是在最高位传输前的一个时钟周期发生改变,这样可以使从属装置得到与被传输的串行数据同步的时间,并且使接收端存储当前的命令以及为下次的命令清除空间。
ADI-Codec I2S移植
以下文章/教程仅针对官方提供的例程《AD1939_I2S_Sample_Based_Talkthru》进行修改。
<ad1939.h>
定义了ADAU1939的宏定义,包括锁相环、时钟、DAC、ADC等的寄存器,与直接从SigmaStudio导出的文件并没有太大差别,应该经过精简。
首先,需要清晰认识1939和1772的硬件差异。ADAU1939和ADAU1772硬件上的异同,都有4个差分输入,但是1939有8个差分输出,1772有2个双声道输出(4个差分输出)。
SPORTS ,即Serial Ports的简称,串行接口。
在<ADDS_21479_EzKit.h>
头文件里,以下声明适用于21479和1939的音频通信通道,定义了
2个双声道输入 和
4个双声道输出 ,正好符合1939的
4个差分输入 和
8个差分输出
的硬件描述,对应修改到1772时需要减少输出的声音通道。本文件仅对一些全局变量、声音通道、函数等做出声明,具体应用在其他.c文件或.asm文件中。
通过 Sport1 A 从Codec接收数据,并通过
Sport0 A/B 和 Sport2
A/B 将音频数据传输至Codec的四个立体声DAC接口。Sport1
接收中断服务程序以在 DMA接收缓存 rx1a_buf
上完成算术运算(arithmetic computations),并将计算结果存放至
DMA传输缓存 tx0a_buf
。
1 | /****************************************************************************************************** |
SPTCL寄存器操作
下方代码是官方示例给出,并经过唐昊整合修改过,其寄存器设置的功能解读和验证如下:
1 | *pSPCTL0 = (SPTRAN | OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A | SPEN_B | SCHEN_B | SDEN_B); |
SPTRAN: Serial port Data Transfer Direction.
Transfer / Receive from both Channel A and Channel B.
需要注意的是,传输和接收功能只有一个会在 SOPRTx_CLK
和
SPORTx_FS
控制
传输/接收位移寄存器(Transmit/Receive shift
register) 时被激活。
OPMODE: SPORT Operation Mode, I2S / packed, left-justified mode
SLEN32: Serial port word length, in I2S / left-justified mode , we used SLEN8 ~ SLEN32. 但实际上,1772输出的I2S声道字长度是24bits。
SPEN_A: Serial port Channel A DMA enabled.
SCHEN_A: Serial port Channel A DMA Chainning enabled.
SDEN_A: Serial port Channel A DMA enabled.
SPEN_B: Serial port Channel B DMA enabled.
SCHEN_B: Serial port Channel B DMA Chainning enabled.
SDEN_B: Serial port Channel B DMA enabled.
通过查询表《HWR》中的表A-84可知,SPORT 0 ~ 2 的设置符合 0用于传输,1和2用于接收的要求。
需要尽可能拉高逻辑分析仪的采样频率,如24MHz以上。
1772下I2S的数据深度为16 ~ 24bit,后面的长度都会由0补齐,采集显示设置时可以设置32bit或24bit皆可。
ASRC OF ADAU1772
ADAU1772 master clock input, but the LRCLK and BCLK must be synchronous to each other. The LRCLK and BCLK pins are used to clock both the serial input and output ports.
ADAU1772 can be set to be either the master or the slave in a system. Because there is only one set of serial data clocks, the input and output ports must always both be either master or slave.
It is recommended to use the high drive settings on the serial port pins.
串行音频接口的通信时序说明图如下,
其中, tSOD 是指:ADC_SDATAx delay; time from BCLK falling (master and slave modes)。从下图中看出PDM( LJ / RJ / I2S )都有 tSOD 。
虽然同样是I2S,且LJ的标准和飞利浦I2S的标准都是左端对齐,但是飞利浦的数据会比LRCLK延时一个完整的时钟周期。而标准LJ则是LRCLK、BCLK 和 SDATA 完全对齐。
通信时钟要求
量产版采用统一的 16.6MHz
为2个codecs和1个DSP主芯片提供时钟。
异步设备通信开发顺利的前提要求是两者的通信时钟能否保持一致,即最关键的通信时钟信号(BCLK / LRCLK)是否符合设定要求(3.072MHz / 48KHz)。
使用逻辑分析仪去测量音频设备的输出 帧时钟(LRCLK)
频率,如果其时钟输出结果符合设置的 48KHz
要求,则说明正确。其 位时钟频率要求 应等于
帧时钟长度 * 数据深度 * 2
,如 帧时钟频率为48KHz的
位时钟频率为 48KHz * 32bits * 2
,大致等于
3.072 MHz
。
注意:逻辑分析仪能否清晰测量和指示波形周期,仍需要该设备自身支持较高频率的采样速率,最好采样速率能与需要采样的目标速率成倍数关系。如果速率过低,则会出现采样变形。如下图中的位时钟采样和测量为
3MHz
,中途会偶然出现 3.429MHz
。
在设置错误时,会出现如下情况:
在21479上设置好I2S的 slave端 代码,被动接收master端音频并转发回给master端,而ADAU1772在使用USBi单独通信设置好通信频率48KHz后,成功与21479实现全双工音频转发。
在评估版用户手册中,提示需要16.625MHz的时钟提供给DSP21479。通过修改量产板上codec的PLL寄存器设置,发现
16.625MHz
无效,设置时不起作用,因为与所提供的时钟频率(16.6MHz)不符。
设置成 16.6MHz
则可以工作,能够顺利采集到数据(暂停时刻查看缓存数据)。
仔细阅读以下寄存器信息。
注意:SigmaStudio中,设置
输入时钟信号(MCLK input)和
输出时钟信号(VCO Output)后,仅有
输入信号分频(input clock divider,下简称
ICD)是可以设置的,其他参数由
load parameters
自动计算。在
输入频率 16.6MHz
和
输出频率 24.576MHz
不变的情况下,改变 输入信号分频 以生成下表:
ICD = 1 | ICD = 2 | ICD = 3 | ICD = 4 | |
---|---|---|---|---|
PLL_CTRL0 | 0x08 | 0x08 | 0x08 | 0x08 |
PLL_CTRL1 | 0x1B | 0x1B | 0x1B | 0x1B |
PLL_CTRL2 | 0x07 | 0x07 | 0x17 | 0x1F |
PLL_CTRL3 | 0xCA | 0x79 | 0x5E | 0x28 |
PLL_CTRL4 | 0x11 | 0x2B | 0x35 | 0x47 |
PLL_CTRL5 | 0x01 | 0x01 | 0x01 | 0x01 |
PLL_CTRL0
和PLL_CTRL1
分别构成 PLL分母(denominator)的高位和低位。PLL_CTRL2
和PLL_CTRL3
分别构成 PLL分子(numerator)的高位和低位。PLL_CTRL4
控制着 PLL类型(整数型/分数型)、输入时钟分频(1 - 4)和 PLL设置的 整数部分。PLL_CTRL5
目前只能是0x00
或0x01
。
以下为PLL_CTRL4寄存器的位描述:n
至于 CLK_CONTROL
寄存器,主要是数值 0x89
和
0x8F
的差别。见下表可知,是关于PLL分频的问题。
通过自行编写的代码,遍历所有可更改的系数进行计算求解,取得小数点后9位精度,并且符合要求的系数如下(含1/2系数):
根据PLL_CTRL4寄存器,ICD=3、IS=8时,该寄存器的值为
01000101
,即 0x45
。(下图IDC更正为ICD)
以下为不含1/2系数的结果:
根据PLL_CTRL4寄存器,ICD=3、IS=4时,该寄存器的值为
00100101
,即 0x25
。
- CLK_IN mean value is 16.6Mhz
- LRCLK mean value is 45.92Khz
ANC主板硬件(量产)
以下为ADAU1772的特征:
Master clock = core clock = 12.288 MHz
serial input sample rate = 48 kHz
measurement bandwidth = 20 Hz to 20 kHz
word width = 24 bits
ambient temperature = 25°C
outputs line loaded with 10 kΩ
Codec A是接了DAC输出的,Codec B没有,其地址分别为 0x3D
与 0x3E
。
TWI (I2C)
Codec A | Codec B | |
---|---|---|
SCK | DPI_P08 | DPI_P08 |
SDA | DPI_P07 | DPI_P07 |
ADDR0 | +3.3VA | AGND |
ADDR1 | AGND | +3.3VA |
I2S
Codec A | Codec B | |
---|---|---|
ADC_SDATA_0 | DAI_P13 | DAI_P15 |
ADC_SDATA_1 (clock) | DAI_P03 | DAI_P16 |
LRCLK | DAI_P02 | DAI_P11 (useless) |
BCLK | DAI_P01 | DAI_P12 (useless) |
DAC_SDATA | DAI_P07 | / |
SPI
FLASH | |
---|---|
SPI_SOMI | DPI_P01 |
SPI_SIMO | DPI_P02 |
SPI_CLK | DPI_P03 |
SPI_SCS | DPI_P05 |