RT600 I2S外设介绍及应用

恩智浦的i.MX RT600是跨界处理器产品,同样也是i.MX RTxxx系列的开山之作。不同于i.MX RT1xxx系列单片机,i.MX RT600 采用了双核架构,将新一代Cortex-M33内核与高性能Cadence Tensilica HiFi 4 音频DSP内核相结合,适用于32位沉浸式音频播放和视频用户界面应用。i.MX RT600旨在通过安全、功率优化的嵌入式处理器充分挖掘语音辅助终端节点的潜力,因此针对音频数据的采集、传输和处理,i.MX RT600都有丰富的硬件资源进行支持。其中,针对RT600的I2S外设,本文详细地进行了介绍,并基于i.MX RT600 EVK开发板,在RT600的DSP端(HiFi4)实现了一个音频数字回环的demo。

一、I2S介绍

1.1 I2S 接口

I2S总线为数字音频流的传输提供了标准的通信接口,由飞利浦制定。I2S总线规范定义了一种3线串行总线,分别是:

1、串行时钟SCK(也称位时钟BCLK),这是SDA线上数据的位时钟。对应SDA的每一个数据位,SCLK都有产生一个脉冲。

2、帧时钟WS(也称LRCK,或FSYNC),以大多数单一立体声格式的PDM数据来说,WS用于切换左右声道的数据;在DSP或TDM模式下用作帧定界符。此外,I2S的采样频率是由WS频率决定的。

3、串行数据(SDA),就是用二进制表示的音频数据流,单个SDA提供一个音频数据流,该数据流可能具有多种格式。

I2S接口除了以上3个总线外,在实际应用中还需要MCLK(Master CLK)时钟。在某些I2S系统中,I2S从设备可能需要使用MCLK来构建位时钟。一般情况下,它是采样率(fs)的整倍数,例如256fs,64fs等。

1.2 RT600 I2S硬件架构

i.MX RT600一共包含7个可配置的通用串行接口模块(Flexcomm接口),Flexcomms 0至5可以配置为I2S接口用于数字音频数据的传。下图为I2S子系统的整体架构图,每个I2S模块都包含集成的FIFO和DMA支持, 每个I2S接口最多支持四个通道对的数据。

1.3 I2S帧格式

介绍完了I2S的接口定义,下面介绍在我们i.MX RT600上I2S外设提供了哪些帧格式。

首先是经典I2S模式(Classic I2S mode),经典I2S模式规范在SDA上定义了2声道立体声数据,其中WS状态标识左(低)声道和右(高)声道,并且在WS转换后,数据延迟1个SCK时钟。 经典I2S模式的示意图如下所示。

第二种模式是DSP模式(DSP mode)。在DSP模式中,不使用WS来标识左右声道数据,而是将通道的音频数据打包成位流的模式。在这种模式下,一包完整的音频数据流从WS帧的上升沿开始。 通过WS的变化,DSP模式可以演变出如下图所示的三种模式,分别为DSP mode with 50% WS,DSP mode with 1 SCK pulsed WS和DSP mode with 1 slot pulsed WS。

第三种模式为TDM模式。TDM模式能够最多打包4个通道对(左右声道)的音频数据以位流的形式传输, 可以与DSP模式或经典I2S模式结合使用。 经典I2S模式下的TDM示意图如下图所示,一共有4对Slot音频数据(共8声道音频数据),通过如图所示的帧格式由一根SDA总线进行传输。

当然这边需要注意的是,RT600上I2S的SDA总线能发送最多4对Slot音频数据。另外寄存器”Configuration 1“和 ”Configuration register 1 for channel pairs 1, 2, and 3“ 中的ONECHANNEL位决定了I2S的数据通道是否为单通道模式,例如:如果ONECHANNEL设置为0,那么该通道的I2S数据流会被I2S总线视为左右声道数据,如果ONECHANNEL设置为1,那么该通道对的I2S数据流被视为单个声道数据。以上所有举例的帧格式示意图都是以ONECHANNEL=0为基础的。

除了经典I2S模式下的TDM,还有在DSP模式下的TDM格式帧,下图展示的是TDM在DSP modes with 1 SCK pulsed WS模式下的帧格式。因此,RT600能够产生的I2S帧格式的种类是非常丰富的,用户可以根据自己的需求进行配置。

二、应用

2.1 系统架构

在此应用中,音频数字回环demo的整个架构如图所示。WM8904编解码器通过音频数据线来接收音频信号。音频信号经过WM8904后会转变成PCM信号。HiFi4通过一路I2S接口连续不断地接收PCM信号,并使用另一个I2S接口将PCM信号发送回WM8904编解码器,最后WM8904编解码器输出的音频信号会给播放设备实时播放。另外,HiFi4利用一路I2C接口对WM8904进行初始化配置操作。

2.2 时钟配置及采样频率计算

在RT600上使用I2S外设做音频数字回环的关键一步是选择I2S外设的时钟源,以及配置I2S的采样频率。

首先需要确定MCLK和I2S的时钟源。 如图所示,MCLK有两个时钟源,分别是48/60m_irc和audio_pll-clk,而I2S至少有5个时钟源。 在此应用中,我们把MCLK和I2S的时钟源均设置为audio_pll_clk。

配置完MCLK和I2S外设的时钟源后,下一步就是根据实际应用需求配置MCLK的时钟频率和I2S的时钟频率。 I2S的采样频率通常有两大类,下表列出了这两类典型的I2S采样频率。一旦I2S的采样频率确定了,那WS信号的频率也就确定了。

Typical Sample Frequency (Hz) Typical Sample Frequency (Hz)
11025 8000
22050 16000
44100 24000
-------- 32000
-------- 48000
-------- 96000

对于RT600来说,I2S采样频率是由I2S的时钟源分频得到的,而WS采样频率有上表所列的两大类,为了能够精确地通过时钟分频系数来计算得到这些典型的采样频率,笔者根据经验总结,将I2S的时钟输入源配置为11.289MHz和24.576MHz是比较容易和推荐的。如果I2S的时钟源为11.289MHZ,那么44.1KHz可以通过对其分频得到;如果I2S的时钟源为24.576MHZ,那么96KHz或者48KHz也可以通过对其分频得到。

在音频数字回环的demo中,选择的信号源为PC端48KHz,16bit的立体声(左右声道)音频信号。我们以此来计算并配置时钟,过程如下:

  • 将时钟源audio_pll_clk配置为24.576MHZ,即audio_pll_clk = 24.576MHZ
  • WS = 48KHz
  • MCLK = audio_pll_clk = 24.576MHZ
  • BCLK = WS * 声道数 * 声道位宽 = 48KHz * 2 * 16 = 1.536MHz
  • I2S_DIV (I2S分频系数) = audio_pll_clk / BCLK = 24.576MHz / 1.536MHz = 16

此外,在本应用中还需要将I2S模式配置为经典I2S模式。
以下代码给出了I2S时钟的具体配置:

#define DEMO_AUDIO_BIT_WIDTH (16)
#define DEMO_AUDIO_SAMPLE_RATE (48000)
#define DEMO_I2S_CLOCK_DIVIDER 24576000/2/16/48000
/* attach AUDIO PLL clock to FLEXCOMM1 (I2S1) */
CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM1);
/* attach AUDIO PLL clock to FLEXCOMM3 (I2S3) */
CLOCK_AttachClk(kAUDIO_PLL_to_FLEXCOMM3);
/* attach AUDIO PLL clock to MCLK */
CLOCK_AttachClk(kAUDIO_PLL_to_MCLK_CLK);
CLOCK_SetClkDiv(kCLOCK_DivMclkClk, 1);
SYSCTL1->MCLKPINDIR = SYSCTL1_MCLKPINDIR_MCLKPINDIR_MASK;
/* Set shared signal set 0: SCK, WS from Flexcomm1 */
SYSCTL1->SHAREDCTRLSET[0] = SYSCTL1_SHAREDCTRLSET_SHAREDSCKSEL(1) | SYSCTL1_SHAREDCTRLSET_SHAREDWSSEL(1);
/* Set flexcomm3 SCK, WS from shared signal set 0 */
SYSCTL1->FCCTRLSEL[3] = SYSCTL1_FCCTRLSEL_SCKINSEL(1) | SYSCTL1_FCCTRLSEL_WSINSEL(1);
s_TxConfig.divider = DEMO_I2S_CLOCK_DIVIDER;
s_RxConfig.divider = DEMO_I2S_CLOCK_DIVIDER;

2.3 WM8904 Codec介绍

WM8904是为便携式音频应用而优化的高性能超低功耗立体声编解码器。 WM8904使用标准的I2C总线控制接口,提供对WM8904所有功能的软件配置。 在本应用中,WM8904作为I2C从设备,HiFi4可以通过I2C接口与编解码器通信,并且可以使用I2C进行编解码器初始化和配置。WM8904的单个寄存器的读写操作时序图如下所示。 为了允许在同一接口上仲裁多个从机(或多个主机),WM8904通过使SDA引脚处于三态(而不是将其拉高)来发送逻辑1,因此需要一个外部上拉电阻来将SDA拉高。

同样WM8904也需要被配置为经典I2S模式,其示意图如下所示。可以对比发现,与我前文介绍的经典I2S模式是一致的。在检测到LRCLK边沿后,MSB在BCLK的第二个上升沿可用。 然后按顺序传输直到最低位。另外,可以看到在一个采样的LSB和下一个采样的MSB之间有可能会存在未使用的BCLK时钟信号,这个跟WM8904被配置的采样位有关。

以下代码给出了WM8904的具体配置:

wm8904_config_t wm8904Config = {
    .i2cConfig          = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock
                        = 19000000U},
    .recordSource       = kWM8904_RecordSourceLineInput,
    .recordChannelLeft  = kWM8904_RecordChannelLeft2,
    .recordChannelRight = kWM8904_RecordChannelRight2,
    .playSource         = kWM8904_PlaySourceDAC,
    .slaveAddress       = WM8904_I2C_ADDRESS,
    .protocol           = kWM8904_ProtocolI2S,
    .format             = {.sampleRate = kWM8904_SampleRate48kHz, .bitWidth
                = kWM8904_BitWidth16},
    .mclk_HZ            = 24576000U,
    .master             = false,
};
static void I2C_Config(void)
{
  PRINTF("Configure WM8904 codec\r\n");
  /* protocol: i2s * sampleRate: 48K  * bitwidth:16*/
  if (CODEC_Init(codecHandle, &boardCodecConfig) != kStatus_Success)
  {
    PRINTF("WM8904_Init failed!\r\n");
  }
  /* Initial volume kept low for hearing safety. */
  CODEC_SetVolume(codecHandle, kCODEC_PlayChannelHeadphoneLeft  |kCODEC_PlayChannelHeadphoneRight, 0x0020);
}

2.4 DMA和中断配置

在RT600上做音频数据的处理推荐用DMA,从而减少对CPU资源的消耗。DMA在RT600上推荐的用法是CM33核使用DMA0,而HiFi4使用DMA1。此外,在HiFi4中使用DMA与在CM33端是有一定区别的,这个主要体现在以下几点:

  • 需要在XOS或XTOS中注册并启用HiFi4中断。
  • 在HiFi4中DMA操作的SRAM地址必须是non-cacheable。
  • 需要由使用INPUTMUX注册HiFi4中断。

这些注册的中断与HiFi4的连接关系如下表所示。表中除了提供所需的中断选择之外,还显示了各个中断的中断优先级。L1中断的优先级最低,而L3中断的优先级最高。

Interrupt Description Priority Interrupt Description Priority Interrupt Description Priority
0 SYS IRQ NMI 11 Interrupt selected by DSP_INT0_SEL6 L1 22 Interrupt selected by DSP_INT0_SEL17 L2
1 SOFTWARE IRQ0 L2 12 Interrupt selected by DSP_INT0_SEL7 L1 23 Interrupt selected by DSP_INT0_SEL18 L2
2 INTERNAL RTOS TIMER0 L2 13 Interrupt selected by DSP_INT0_SEL8 L1 24 Interrupt selected by DSP_INT0_SEL19 L3
3 INTERNAL RTOS TIMER1 L3 14 Interrupt selected by DSP_INT0_SEL9 L1 25 Interrupt selected by DSP_INT0_SEL20 L3
4 PROFILING IRQ L3 15 Interrupt selected by DSP_INT0_SEL10 L1 26 Interrupt selected by DSP_INT0_SEL21 L3
5 Interrupt selected by DSP_INT0_SEL0 L1 16 Interrupt selected by DSP_INT0_SEL11 L2 27 Interrupt selected by DSP_INT0_SEL22 L3
6 Interrupt selected by DSP_INT0_SEL1 L1 17 Interrupt selected by DSP_INT0_SEL12 L2 28 Interrupt selected by DSP_INT0_SEL23 L3
7 Interrupt selected by DSP_INT0_SEL2 L1 18 Interrupt selected by DSP_INT0_SEL13 L2 29 Interrupt selected by DSP_INT0_SEL24 L3
8 Interrupt selected by DSP_INT0_SEL3 L1 19 Interrupt selected by DSP_INT0_SEL14 L2 30 Interrupt selected by DSP_INT0_SEL25 L3
9 Interrupt selected by DSP_INT0_SEL4 L1 20 Interrupt selected by DSP_INT0_SEL15 L2 31 Interrupt selected by DSP_INT0_SEL26 L3
10 Interrupt selected by DSP_INT0_SEL5 L1 21 Interrupt selected by DSP_INT0_SEL16 L2 ------ ------ ------

以下代码给出了HiFi4 DMA和中断的具体配置:

DMA_Init(DMA1);
/* XCHAL_EXTINT19_NUM, intlevel 2 */
INPUTMUX_AttachSignal(INPUTMUX, 18U, kINPUTMUX_Dmac1ToDspInterrupt);
xos_register_interrupt_handler(XCHAL_EXTINT19_NUM,
                       (XosIntFunc *) DMA_IRQHandle,
                     DMA1);
xos_interrupt_enable(XCHAL_EXTINT19_NUM);
DMA_EnableChannel(DMA1, DEMO_I2S_TX_CHANNEL);
DMA_SetChannelPriority(DMA1, DEMO_I2S_TX_CHANNEL, kDMA_ChannelPriority3);
DMA_CreateHandle(&s_DmaTxHandle, DMA1, DEMO_I2S_TX_CHANNEL);
DMA_EnableChannel(DMA1, DEMO_I2S_RX_CHANNEL);
DMA_SetChannelPriority(DMA1, DEMO_I2S_RX_CHANNEL, kDMA_ChannelPriority2);
DMA_CreateHandle(&s_DmaRxHandle, DMA1, DEMO_I2S_RX_CHANNEL);

2.5 音频数据流的处理

MCU在同时接收和发送PCM数据并进行播放的应用场景中,容易出现播放音乐卡顿的情况,为了避免出现这种卡顿,一个好的传输机制是必不可少的,下图就给出了一个处理PCM数据的思路。

如图示,总共3个缓冲区用于PCM数据发送(TX)和接收(RX),数据的发送和接收都是通过I2S通道触发DMA请求完成的,这3个缓冲区构成一个闭环。每当一个缓冲区中的PCM数据接收满时,下一个缓冲区将立即开始接收,发送也同理,而且数据的接收和发送是同步的。通俗易懂的讲,I2S的TX永远追不上I2S的RX,并且TX和RX之间永远有个缓冲区是准备好的。从初始框图中可以看到,一开始连续两次提交了I2S的TX和RX的DMA请求,这是为了能够使PCM发送和接收的DMA请求之间从一开始就是无缝衔接的,这能够保证PCM传输不出现时延。

当然,缓冲区的数量取决于用户的实际需求。 当缓冲区为2时,这就构成了一个典型的乒乓缓冲区(ping-pang buffer)。为什么我这里采用了3个缓冲区构成1个ring buffer而不采用简单的ping-pang buffer呢?肯定有人很疑惑,这是因为当PCM数据较为复杂时,例如我介绍的另一篇8通道DMIC采集的应用中,就需要ring buffer的机制。

在本应用中,1帧PCM数据的位宽为32bit(左右声道各16bit),每个缓冲区设置有8帧PCM数据,也就是说每个缓冲区的PCM数据长度为256bit。每个缓冲区的PCM数据长度也对应了I2S通道每次传输的数据长度,在RT600中I2S一次能够传输的音频数据长度最大支持2048bits,所以不能超过这个范围。

三、RT600 硬件演示平台搭建

为了演示I2S音频数字回环的demo,需要有一块如下图所示的RT600 EVK RevE板子,然后还需要注意以下几点:

  • JP7.1连接到JP7.2。
  • JP8.1连接到JP8.2。
  • J3口作为音频信号的输入,可以连接到PC端。
  • J4口作为音频信号的输出,连到扬声器。
  • 将ISP开关(SW5)切换成0b010,即ON,OFF,ON
  • 将USB插入板上J6口。

原文地址:https://www.cnblogs.com/jamesfan2019/p/12307279.html

时间: 2024-10-11 10:41:08

RT600 I2S外设介绍及应用的相关文章

android下调试声卡驱动之I2S音频通信

一.I2S概述 I2S(Inter-IC Sound)总线是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专责于音频设备之 间的数据传输.由4条线组成的数字音频接口,常用于HiFi,STB便携设备.Tx  和Rx信号线用于音频传输.而位时钟和左右时钟 (LRC)用于同步链接.I2S具有灵活性,因为控制器和解码器都可以控制位时钟和左右时钟.位时钟因采样率和主系统时钟而有不 同.LRCLK与采样率相同.少数设备支持独立的ADC和DAC的LRCLK.这使在不同采样率情况下同步捕

第15章 RCC—使用HSE/HSI配置时钟

本章参考资料:<STM32F7xx参考手册>RCC章节. 学习本章时,配合<STM32F7xx参考手册>RCC章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分. RCC :reset clock control  复位和时钟控制器.本章我们主要讲解时钟部分,特别是要着重理解时钟树,理解了时钟树,F767的一切时钟的来龙去脉都会了如指掌. 15.1  RCC主要作用-时钟部分 设置系统时钟SYSCLK.设置AHB分频因子(决定HCLK等于多少).设置APB2分频因子(决定PCL

RCC—使用HSE/HSI配置时钟

1.1 RCC主要作用—时钟部分 设置系统时钟SYSCLK.设置AHB分频因子(决定HCLK等于多少).设置APB2分频因子(决定PCLK2等于多少).设置APB1分频因子(决定PCLK1等于多少).设置各个外设的分频因子:控制AHB.APB2和APB1这三条总线时钟的开启.控制每个外设的时钟的开启.对于SYSCLK.HCLK.PCLK2.PCLK1这四个时钟的配置一般是:HCLK = SYSCLK=PLLCLK = 180M,PCLK2=HCLK/2 = 90M,PCLK1=HCLK/4 =

nRF5芯片外设GPIO和GPIOTE介绍

nRF51/nRF52同时包含GPIO和GPIOTE两种外设,经常有人将两者搞混,今天我们就来介绍一下这2种外设有什么不同,及使用注意事项. GPIO和GPIOTE都属于芯片外设,但两者功能完全不一样,使用过程中不要将两者混淆.GPIO就大家通常理解的普通IO口,用来对IO口进行读写等操作.因此,如果你需要读某个IO口状态,或者将某个IO口置1,那么请使用nrf_gpio.h里面的API,比如 nrf_gpio_cfg_input用来将IO设为输入模式 nrf_gpio_pin_set用来输出1

Hyper-V 2016 系列教程28 Hyper-v平台USB 外设解决方案介绍

现在企业中,由于虚拟化技术的大力普及,企业的一般用户办公端都是以瘦客户端的形式存在,而瘦客户端一般是采用Linux或者Windows精简版本的系统,体积一般只有5寸平板大小,硬件接口有限,所以这样就带来一个问题,一般不能友好的支持USB接口的使用,不能使用USB存储,移动加密U盾等,另一方面由于虚拟计算机是从一个物理机上虚拟出来的,它自己并没有物理接口.当需要接入设备,如虚拟机上需要用到Ukey.加密狗等设备时,需要把物理机的接口切换给虚拟机才能使用,切换过程比较麻烦.加上物理机的接口是有限的,

Hyper-V 2016 系列教程26 Hyper-v平台并口外设解决方案介绍

一般企业中会有老款的并口设备,这些设备一般用在重要的业务上面,有时不是想淘汰就能淘汰的,所以在服务器虚拟化时,会采用一些转接方案,以便使这些设备能正常运行在虚拟化操作系统中,老款并口设备在企业中一般有工业打印机,财务部门专门的开票和税务打印机,工业测试设备等,这些并口老旧设备在企业虚拟化中是最复杂的,特别是外企环境中财务税控方面和国外的设备兼容性太差,如果将这些并口设备直接接到XenServer物理服务器端口上,可能性不太大,所以我们这里介绍二款常用的网络转并口集线器,可以给有需求的公司作为参考

Hyper-V 2016 系列教程27 Hyper-v平台串口外设解决方案介绍

一般企业中串口在以下设备中比较常见交换机.老款工业设备.PLC控制设备.小型标签打印机.精密电子秤等为了跟上工业4.0的潮流所有工厂内的生产监控数据采集等老旧设备已经跟不上现代流行的趋势原来以串口RS232.RS422.RS485方式管理的串口设备必须通过串口转网络的设备完成升级和系统整合提高管理效率这里我推荐的串口转网络设备的品牌有MoxaZLAN并且这二家厂家都有串口转无线网络设备的解决方案. 串口设备联网服务器有如下的优点 所有设备统一通过TCP/IP的标准方式进行管理集中控制更加方便管理

Android bluetooth介绍(一):基本概念及硬件接口

关键词:蓝牙硬件接口 UART  PCM  blueZ 版本:基于android4.2之前版本 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载,请注明作者,请尊重版权谢谢)欢迎指正错误,共同学习.共同进步!! 一.基本概念补充 1.AP:ApplicationProcessor应用处理器 采用ARM架构的CPU,通常负责运行OS和一些特定设置和载入开机预设.比如一个没有电话功能的平板电脑,只跑android或

Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc) (转载)

[转](转)Linux内核访问外设I/O资源的方式-静态映射(map_desc)方式 Linux内核访问外设I/O资源的方式 Author: Dongas Date: 08-08-02 我们知道默认外设I/O资源是不在Linux内核空间中的(如sram或硬件接口寄存器等),若需要访问该外设I/O资源,必须先将其地址映射到内核空间中来,然后才能在内核空间中访问它. Linux内核访问外设I/O内存资源的方式有两种:动态映射(ioremap)和静态映射(map_desc). 一.动态映射(iorem