I2S通信

数字音频信号的传输标准,如:

  • I2SPCM (Pulse Code Modulation) 和 PDM (Pulse Density Modulation)主要用于同一块电路板上芯片之间音频信号的传输;
  • Intel HDA (Intel High Definition Audio) 用于PC的Audio子系统(声卡)应用;
  • S/PDIFEthernet AVB 主要应用于板间长距离及需要电缆连接的场合。

Philips I2S 标准

I2S的标准文件源自 飞利浦半导体(Philips Semiconductors)发表于1986年的《I2S bus specification(1996年修订版)》。

I2S(Inter-IC Sound)采用了独立的导线传输时钟与数据信号的设计,通过将数据和时钟信号分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。

需要注意:I2S是一种音频编码协议,同时也是一种音频接口,因此采用I2S接口方式的不一定采用I2S编码,还可以采用 左对齐(Left Justifying)编码 或 右对齐(Right Justifying)编码。

image-20210629145800027

特点

  1. 支持全双工/半双工

  2. 支持主/从模式

  3. 和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).

image-20210629112429113

从上图得知,I2S总线共需要三个引脚:

  • 连续串行时钟线(SCK / SCLK / BCLK),也叫位时钟,即对应数字音频的每一位数据,SCLK都有1个脉冲。SCLK的频率=2×采样频率×采样位数。
  • 字选择线(WS / LRCLK),也叫帧时钟,用于切换左右声道的数据。LRCK为“1”表示正在传输的是右声道的数据,为“0”则表示正在传输的是左声道的数据。LRCK的频率等于采样频率。
  • 时分多路复用(简称 TDM)数据线,即串行数据(SDSDATA),就是用二进制补码表示的音频数据。

另,有时为了使系统间能够更好地同步,还需要另外传输一个信号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个差分输出)。

image-20210628095252103

SPORTS ,即Serial Ports的简称,串行接口。

<ADDS_21479_EzKit.h> 头文件里,以下声明适用于21479和1939的音频通信通道,定义了 2个双声道输入4个双声道输出 ,正好符合1939的 4个差分输入8个差分输出 的硬件描述,对应修改到1772时需要减少输出的声音通道。本文件仅对一些全局变量、声音通道、函数等做出声明,具体应用在其他.c文件或.asm文件中。

通过 Sport1 A 从Codec接收数据,并通过 Sport0 A/BSport2 A/B 将音频数据传输至Codec的四个立体声DAC接口。Sport1 接收中断服务程序以在 DMA接收缓存 rx1a_buf 上完成算术运算(arithmetic computations),并将计算结果存放至 DMA传输缓存 tx0a_buf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/******************************************************************************************************
/ /
/ AD1939 - SPORT1 RX INTERRUPT SERVICE ROUTINE /
/ /
/ Receives input data from the AD1939 ADCs via SPORT1 A and transmits processed audio data /
/ back out to the four AD1939 Stereo DACs/Line Outputs through SPORT0 A/B and SPORT2 A/B /
/ /
/ /
/ This Serial Port 1 Recieve Interrupt Service Routine performs arithmetic computations on /
/ the SPORT1 receive DMA buffer (rx1a_buf) and places results to SPORT0 transmit /
/ DMA buffer (tx0a_buf) /
/ /
/ rx1a_buf[2] - DSP SPORT0 A receive buffer - AD1939 ASDATA1 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 0 Internal ADC 0 Left Channel DM(_rx1a_buf + 0) = DM(_rx1a_buf + Internal_ADC_L1) /
/ 1 Internal ADC 0 Right Channel DM(_rx1a_buf + 1) = DM(_rx1a_buf + Internal_ADC_R1) /
/ /
/ rx1b_buf[2] - DSP SPORT0 B receive buffer - AD1939 ASDATA2 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 0 Internal ADC 1 Left Channel DM(_rx1b_buf + 2) = DM(_rx1b_buf + Internal_ADC_L2) /
/ 1 Internal ADC 1 Right Channel DM(_rx1b_buf + 3) = DM(_rx1b_buf + Internal_ADC_R2) /
/ /
/ tx0a_buf[2] - DSP SPORT0 A transmit buffer - AD1939 DSDATA1 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 0 Internal DAC 1 Left Channel DM(_tx0a_buf + 0) = DM(_tx0a_buf + Internal_DAC_L1) /
/ 1 Internal DAC 1 Right Channel DM(_tx0a_buf + 1) = DM(_tx0a_buf + Internal_DAC_R1) /
/ /
/ tx0a_buf[2] - DSP SPORT0 B transmit buffer - AD1939 DSDATA2 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 2 Internal DAC 2 Left Channel DM(_tx0b_buf + 2) = DM(_tx0b_buf + Internal_DAC_L2) /
/ 3 Internal DAC 2 Right Channel DM(_tx0b_buf + 3) = DM(_tx0b_buf + Internal_DAC_R2) /
/ /
/ tx2a_buf[2] - DSP SPORT2 A transmit buffer - AD1939 DSDATA3 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 4 Internal DAC 3 Left Channel DM(_tx2a_buf + 4) = DM(_tx2a_buf + Internal_DAC_L3) /
/ 5 Internal DAC 3 Right Channel DM(_tx2a_buf + 5) = DM(_tx2a_buf + Internal_DAC_R3) /
/ /
/ tx2b_buf[2] - DSP SPORT2 B transmit buffer - AD1939 DSDATA4 /
/ Slot # Description DSP Data Memory Address /
/ ------ -------------------------------------- -------------------------------------------------- /
/ 6 Internal DAC 4 Left Channel DM(_tx2b_buf + 6) = DM(_tx2b_buf + Internal_DAC_L4) /
/ 7 Internal DAC 4 Right Channel DM(_tx2b_buf + 7) = DM(_tx2b_buf + Internal_DAC_R4) /
/ /
******************************************************************************************************/

SPTCL寄存器操作

下方代码是官方示例给出,并经过唐昊整合修改过,其寄存器设置的功能解读和验证如下:

1
2
3
*pSPCTL0 = (SPTRAN | OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A | SPEN_B | SCHEN_B | SDEN_B);
*pSPCTL1 = (OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A | SPEN_B | SCHEN_B | SDEN_B);
*pSPCTL2 = (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_CLKSPORTx_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用于接收的要求。

image-20210702110559930

需要尽可能拉高逻辑分析仪的采样频率,如24MHz以上。

image-20210702111535166

1772下I2S的数据深度为16 ~ 24bit,后面的长度都会由0补齐,采集显示设置时可以设置32bit或24bit皆可。

image-20210702113249646
image-20210702113540262

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

image-20210702111739875

虽然同样是I2S,且LJ的标准和飞利浦I2S的标准都是左端对齐,但是飞利浦的数据会比LRCLK延时一个完整的时钟周期。而标准LJ则是LRCLK、BCLK 和 SDATA 完全对齐。

通信时钟要求

量产版采用统一的 16.6MHz 为2个codecs和1个DSP主芯片提供时钟。

image-20210705151852538

异步设备通信开发顺利的前提要求是两者的通信时钟能否保持一致,即最关键的通信时钟信号(BCLK / LRCLK)是否符合设定要求(3.072MHz / 48KHz)。

image-20210705084133066

使用逻辑分析仪去测量音频设备的输出 帧时钟(LRCLK) 频率,如果其时钟输出结果符合设置的 48KHz 要求,则说明正确。其 位时钟频率要求 应等于 帧时钟长度 * 数据深度 * 2 ,如 帧时钟频率为48KHz的 位时钟频率为 48KHz * 32bits * 2 ,大致等于 3.072 MHz

注意:逻辑分析仪能否清晰测量和指示波形周期,仍需要该设备自身支持较高频率的采样速率,最好采样速率能与需要采样的目标速率成倍数关系。如果速率过低,则会出现采样变形。如下图中的位时钟采样和测量为 3MHz ,中途会偶然出现 3.429MHz

image-20210705095017424
image-20210705095203461

在设置错误时,会出现如下情况:

image-20210705085041206

在21479上设置好I2S的 slave端 代码,被动接收master端音频并转发回给master端,而ADAU1772在使用USBi单独通信设置好通信频率48KHz后,成功与21479实现全双工音频转发。

在评估版用户手册中,提示需要16.625MHz的时钟提供给DSP21479。通过修改量产板上codec的PLL寄存器设置,发现 16.625MHz 无效,设置时不起作用,因为与所提供的时钟频率(16.6MHz)不符。

image-20210705104426587

image-20210705143238320

设置成 16.6MHz 则可以工作,能够顺利采集到数据(暂停时刻查看缓存数据)。

image-20210705143246050

image-20210705143606164

仔细阅读以下寄存器信息。

image-20210705145709904

注意: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_CTRL0PLL_CTRL1 分别构成 PLL分母(denominator)的高位和低位。
  • PLL_CTRL2PLL_CTRL3 分别构成 PLL分子(numerator)的高位和低位。
  • PLL_CTRL4 控制着 PLL类型(整数型/分数型)、输入时钟分频(1 - 4)和 PLL设置的 整数部分
  • PLL_CTRL5 目前只能是 0x000x01

以下为PLL_CTRL4寄存器的位描述:n

image-20210706101429733

至于 CLK_CONTROL 寄存器,主要是数值 0x890x8F 的差别。见下表可知,是关于PLL分频的问题。

image-20210705153843902

通过自行编写的代码,遍历所有可更改的系数进行计算求解,取得小数点后9位精度,并且符合要求的系数如下(含1/2系数):

根据PLL_CTRL4寄存器,ICD=3、IS=8时,该寄存器的值为 01000101 ,即 0x45 。(下图IDC更正为ICD)

image-20210706001243698

以下为不含1/2系数的结果:

根据PLL_CTRL4寄存器,ICD=3、IS=4时,该寄存器的值为 00100101 ,即 0x25

image-20210706001350802
  • 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没有,其地址分别为 0x3D0x3E

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 /

image-20210702100716720

image-20210702100920210image-20210702101004870

SPI

FLASH
SPI_SOMI DPI_P01
SPI_SIMO DPI_P02
SPI_CLK DPI_P03
SPI_SCS DPI_P05

参考

  1. I2S bus specification

  2. I2S

  3. 【音频】I2S协议详解

  4. I2S/PCM