基于NXP iMX6ULL 扩展音频解码器 MAX98357A

作者&投稿:貂庆 (若有异议请与网页底部的电邮联系)
~ By Toradex胡珊逢

Colibri iMX6ULL 是 Toradex 面向低成本设备推出的 Arm 计算机模块。该产品没有音频编解码器,无法直接输出模拟音频信号。本文将介绍如何使用模块的数字音频I2S 接口扩展MAX98357A,包括如何配置device tree 和时钟。

在  Colibri iMX6ULL  模块上的i.MX 6ULL SoC 通过synchronous audio interfaces (SAI)接口提供数字音频接口,可以支持AC97 或者I2S 以连接外部音频编解码器。MAX98357A 是一款易于使用的音频解码器,片上带有 D 类功放。无需 I2C 配置和外部 MCLK 时钟,进一步简化电路设计。接下来我们使用Colibri iMX6ULL 搭配  Colibri Evaluation Board ,安装  Linux BSP 5.4  为例进行说明。

Colibri iMX6ULL 总共有三个SAI 接口,这里使用SAI2 连接 MAX98357A。

根据上面的连接关系,对应修改 device tree。在  imx6ull-colibri-eval-v3.dtsi 中首先增加一个codec_ext 节点。

---------------------------------------------

codec_ext: max98357a@0 {    compatible = "maxim,max98357a";    #sound-dai-cells = <0>;};

---------------------------------------------

然后再添加一个simple audio card 的节点 sound。其中的sound-dai 引用了上面的定义的 codec_ext。

---------------------------------------------

sound {    compatible = "simple-audio-card";    status = "okay";    simple-audio-card,name = "max98357a";    simple-audio-card,format = "i2s";    simple-audio-card,bitclock-master = <&dailink_master_cpu>;    simple-audio-card,frame-master = <&dailink_master_cpu>;    simple-audio-card,codec {        sound-dai = <&codec_ext>;    };    dailink_master_cpu: simple-audio-card,cpu {        sound-dai = <&sai2>;    };};

---------------------------------------------

上面的sound 节点中使用了sai2,因此接下来需要对 sai2进行初始化。

---------------------------------------------

&sai2 {    pinctrl-names = "default";    pinctrl-0 = <&pinctrl_sai2>;    assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,              <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;    assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;    assigned-clock-rates = <2>, <196608000>;    fsl,sai-asynchronous;    /*fsl,sai-mclk-direction-output;*/    status = "okay";};

---------------------------------------------

这里有几个关键的参数。pinctrl_sai2 配置了引脚复用关系。对于MAX98357A 实际上只需要前面三个引脚,如前面表格中列出的连接关系。MX6UL_PAD_JTAG_TMS__SAI2_MCLK 和MX6UL_PAD_JTAG_TMS__CCM_CLKO1 为了方便测试相关时钟信号。而这两个其实是同一个引脚,只是复用功能选择不同。sound 节点中fsl,sai-mclk-direction-output; 参数同样也是为了测试SAI 的MCLK 输出,配合MX6UL_PAD_JTAG_TMS__SAI2_MCLK 输出SAI MCLK,但该信号并不用于 MAX98357A。

---------------------------------------------

pinctrl_sai2: sai2grp {        fsl,pins = <            MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK    0x1F089            MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC    0x17088            MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA    0x11088            /*MX6UL_PAD_JTAG_TMS__SAI2_MCLK        0x17088*/            MX6UL_PAD_JTAG_TMS__CCM_CLKO1   0x17088        >;    };};

---------------------------------------------

sound 节点中还有三个重要属性,assigned-clocks,assigned-clock-parents 和 assigned-clock-rates。在介绍这些属性前,我们简单了解下iMX6ULL 的Clock Controller Module(CCM)。

CCM 负责产生和控制 iMX6ULL 上每个模块运行所需的时钟信号,包括从 Arm CPU 核心到各种外设如 USB、Audio、网络等。由于每个模块需要的时钟各不相同,从高频到低频,因此 CCM 内部有多个 PLL 以及分频器提供多种频率的时钟信号。对于本次使用的SAI 模块,根据iMX6ULL 芯片手册Figure 18-2. Clock Tree - Part 1,其时钟关系如下。

SAI2_CLK_ROOT 通过MUX 可以选择三个来源,分别是PLL3,PLL4,PLL5。中间会有多个不同位数的分频器,将 PLL 输出较高的时钟逐级降为较低的频率。这些分频器并不需要手动设置,CCM 驱动会根据期望输出的频率自动计算合适的分频比例。SAI2_CLK_ROOT 最终为SAI2 模块提供运行时钟信号。在SAI 内部,时钟信号经过内部的分频器后产生I2S 的bit block 以及帧同步信号 sync。

对于音频文件,可以计算出所需的 bit clock。例如对于一个双通道,16bit,48K采样率的音频文件,bit clock = 16x2x48000 = 1536000。这个数值是我们所需的最终目标时钟。根据上面的图示, bit clock 源自于 PLL4。根据iMX6ULL 芯片手册18.5.1.3.4 Audio/video PLL 章节,该PLL 的频率范围从650MHz 到 1.3GHz。以 1536000 为基数,取其整数 512 倍,得到 786432000。即 786432000 经过总共 512 倍分频后可以产生 1536000 bit clock 信号。这时我们再回顾 sai2 节点中的一些时钟属性。

---------------------------------------------

assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>,            <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;assigned-clock-rates = <2>, <196608000>;

---------------------------------------------

IMX6UL_CLK_SAI2_SEL 设置的 CCM_CSCMR1 寄存器中的 SAI2_CLK_SEL 位。这里设置为 2, 选择 PLL4 作为时钟源。IMX6UL_CLK_PLL4_AUDIO_DIV 为 PLL4 分频后的时钟,设置为 19660800,这个数值是 1536000 的 24 倍。而PLL4 在分频前为786432000,这是IMX6UL_CLK_PLL4_AUDIO_DIV 的4 倍,在其650MHz 到1.3GHz 的频率范围内。

完成上面device tree 修改后,重新编译,并更新到 Colibri iMX6ULL。下面命令可以直接在模块上覆盖原来的dtb 文件。

---------------------------------------------

root@colibri-imx6ull:~# ubiupdatevol /dev/ubi0_1 imx6ull-colibri-eval-v3.dtb

---------------------------------------------

重启后可以看到max98357a 音频设备。

---------------------------------------------

root@colibri-imx6ull:~# aplay -l**** List of PLAYBACK Hardware Devices ****card 0: max98357a [max98357a], device 0: 202c000.sai-HiFi HiFi-0 []  Subdevices: 1/1  Subdevice #0: subdevice #0

---------------------------------------------

同时在clock tree 中也可以看到sai2 相关时钟。PLL4 输出786432000,4 分频输出196608000Hz 的 pll4_audio_div。MUX 之后通过pred 4 分频输出49152000Hz,再通过podf 2 分频输出24576000Hz 的SAI2_CLK_ROOT,为SAI2 模块运行提供时钟信号。

---------------------------------------------

root@colibri-imx6ull:~# cat /sys/kernel/debug/clk/clk_summary    pll4                              0        0        0   786432000          0     0  50000       pll4_bypass                    0        0        0   786432000          0     0  50000          pll4_audio                  0        0        0   786432000          0     0  50000             pll4_post_div            0        0        0   196608000          0     0  50000                pll4_audio_div        0        0        0   196608000          0     0  50000                   sai2_sel           0        0        0   196608000          0     0  50000                      sai2_pred       0        0        0    49152000          0     0  50000                         sai2_podf       0        0        0    24576000          0     0  50000                            sai2       0        0        0    24576000          0     0  50000

---------------------------------------------

CCM 提供了两个引脚 CCM_CLKO1 和 CCM_CLKO2 可以输出相关时钟进行测试。在上面的device tree SAI2 节点引脚配置中我们也使能该引脚 MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x17088。

根据CCM_CCOSR 寄存器CLKO2_SEL 位,sai2_clk_root 位于CCM_CLKO2, CLK_OUT_SEL 位允许CCM_CLKO1 上输出CCM_CLKO1 或 CCM_CLKO2。因此,可以通过向CCM_CCOSR 寄存器写入0x01130180,在 模块SODIMM 71 引脚上启用CCM_CLKO1 ,输出sai2_clk_root 信号。在 Colibri iMX6ULL 上运行下面命令。

---------------------------------------------

root@colibri-imx6ull:~# devmem2 0x020c4060 w 0x01130180

---------------------------------------------

在 Colibri iMX6ULL 上用下面命令播放一个双通道,16bit,48K采样率的音频文件,此时测量 SODIMM 71 引脚上输出的波形。

---------------------------------------------

root@colibri-imx6ull:~# aplay -D sysdefault:CARD=max98357a LRMonoPhase4.wav -vv

---------------------------------------------

上面图中可以看到波形频率为 24.5MHz。即 PLL4 经过多次分频后产生的时钟。再次播放上面的音频文件,测量SODIMM 31 的bit clock 和SODIMM 23 帧同步sync 信号 

bit clock 频率为1.53MHz,帧同步sync 为 48KHz。这也是上面计算双通道,16bit,48K采样率的音频 bit clock 数值。这些信号的实际输出都符合预期。如果开启 SAI 驱动的调试日志输出功能,在播放音频文件后还可以发现其他的一些信息。在  SAI 驱动源码 的第一行添加#define DEBUG,然后重新编译 zImage。

---------------------------------------------

[   49.838293] fsl-sai 202c000.sai: clk_rate 0 Hz,  mclk_clk id 0[   49.838316] fsl-sai 202c000.sai: clk_rate 24576000 Hz,  mclk_clk id 1[   49.838328] fsl-sai 202c000.sai: ratio 16 for freq 1536000Hz based on clock 24576000Hz[   49.838351] fsl-sai 202c000.sai: best fit: clock id=1, ratio=16, deviation=0

---------------------------------------------

1536000Hz 的bit clock 是通过24576000Hz 进行16 分频得到的。这是因为在SAI 内部还有一个分频器可以对sai2_clk_root 再次分频从而输出合适的 bit clock。I2S2_TCR2 寄存器(地址0x0202c008)的最后7 位DIV 可以配置该分频器。分频数值为 (DIV + 1)x2。读取该寄存器,DIV 值为 7,进行 16 分频。对应上面SAI 驱动调试日志的 “ratio 16 for freq 1536000Hz based on clock 24576000Hz”。

---------------------------------------------

root@colibri-imx6ull:~# devmem2 0x0202c008 w/dev/mem opened.Memory mapped at address 0x76f4b000.Read at address  0x0202C008 (0x76f4b008): 0x07000007

---------------------------------------------

最后接上 MAX98357A 和扬声器就可以听到播放的音频文件。

https://v.youku.com/v_show/id_XNTgzMjUxMTg2NA==.html

总结

通过扩展 MAX98357A 我们介绍了 iMX6 ULL SoC 音频驱动 SAI 的工作原理,以及如何配置 device tree 和测试方法。借鉴该方法,用户也可以扩展其他基于 I2S 的音频编解码器。


霸州市13973855658: 急需一款应用于人脸识别的IMX6ULL核心板,因要把控好成本,有没有质量好又不贵的?想听听大家的建议. -
刘风头孢: 明远智睿i.MX6ULLl核心板价格在行业内算是很低的了,如果走批量的话应该还能降一点,作为NXP的IDH合作伙伴,质量无需担心,重要的是看他们的技术支持怎么样,你可以先去了解再做决定.

霸州市13973855658: 汽车音响虚拟6CD是什么意思? -
刘风头孢: 1,所谓虚拟就是能将当前CD碟片刻录到内置flash内,因为CD是标准的,所以可以支持刻录标准CD 6张,刻录完成就可以播放flash内的音乐文件了2,这个方案是最近2年才诞生的,最早有飞利浦,现在是NXP 的APM机芯,现在国内也有自己的方案了3,主要是取代前置,后置碟盒的.

霸州市13973855658: 魅族mx4音质怎么样 -
刘风头孢: 您好, MX4采用第二代 NXP Smart PA 芯片,使外放声音增大 3-5db.全新的扬声孔设计,喇叭出音面积增加 13%,实际外放音量是上一代的 2 倍.这块驱动 IC 还可以根据环境状况调整扬声器振幅,显著提高外放喇叭输出音质.在选择孔位时,我们考虑了单手握持和横屏握持的各种姿态,最终采用现在的方案.这些进化,保证无论是电话会议、还是外放音乐或激烈游戏,你都可以感受到澎湃却毫无毛刺的声音.

霸州市13973855658: 米奇MP3一代到五代分别有什么区别
刘风头孢: 官方才3代 所谓的四代、五代不是正品 第一代用的是飞利浦NXP0103芯片,二代是国产的炬力芯片,第三代是Mplayer EYES,芯片没换,不过好看了 要是听音质,那就买一代,要是喜欢彩色,买二代,要是喜欢代眼睛的,那买三代咯

霸州市13973855658: 魅族opr5和viov哪一款音质好 -
刘风头孢: 魅族PRO5的音质很给力.魅族PRO5在ES9018K2M 和 OPA1612 这种只在 Hi-Fi 播放器才具备的元器件.基础上再增加了 Solo 耳放电路,并引入 4 对 NXP 大电流三极管.使得 PRO 5 的驱动能力大大增强.瞬态表现非常优秀,声音有力而准确,即使是高端大耳机也能游刃有余,推荐用户选择.

霸州市13973855658: can 总线可以烧录mcu 与arm 吗 -
刘风头孢: 1.基于win XP、Win 7、Win 8平台的上位机软件 2.能识别周立功等CAN分析仪的驱动程序 3.通过CAN分析仪烧录用户程序到MCU中,并能跳转到用户程序自动运行.MCU用NXP的LPC1768和LPC1756 4.需编写这两款芯片的BootLoader程序 5.软件运行稳定,烧录的程序正确

霸州市13973855658: 魅族pro5与金立s7的音质对比 -
刘风头孢: 魅族PRO5在ES9018K2M 和 OPA1612 这种只在 Hi-Fi 播放器才具备的元器件.基础上再增加了 Solo 耳放电路,并引入 4 对 NXP 大电流三极管.使得 PRO 5 的驱动能力大大增强.瞬态表现非常优秀,声音有力而准确,即使是高端大耳机也能游刃有余,推荐用户选择.

霸州市13973855658: 什么是Mifare射频卡 -
刘风头孢: Mifare系列是NXP公司开发的基于ISO14443A标准的13.56MHz的射频卡.读写距离最大10cm.temic是125KHz的射频卡.Mifare和TEMIC的射频频率,容量,验证方式,读写方式都不一样. 搜索panchunweiblog,我的博客中有专门RFID介绍.

霸州市13973855658: calyx m和ARM2哪个音质更好 -
刘风头孢: 魅族PRO5音质更好一些. 在MX4Pro上,创造性地在手机上使用了ES9018K2M和OPA1612这种只在Hi-Fi播放器才具备的元器件. 今年,在此基础上再增加了Solo耳放电路,加入了4对NXP大电流三极管. 使得PRO5的驱动能力大大增强,瞬态表现非常优秀,声音有力而准确,即使是高端大耳机也能游刃有余.

霸州市13973855658: 联想Z5音质会有提升吗? -
刘风头孢: Z5采用了NXP(恩智浦,前飞利浦半导体公司)Smart PA扬声器芯片,该芯片能够动态跟踪喇叭的状态并感知其所处环境的变化,在适应后给出改变推动的对策.使用Smart PA后,可以在不超过扬声器本身承受能力的前提下提高其平均音量.听感上,声音洪亮,有低音效果,并且最大音量,喇叭也不会爆音.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网