Zybo Z7-20 Audio Software Design Memorandum
This is the Software Designing (Petalinux) part of the Zybo Z7-20 audio system project. Appreciated Yuhei Horibe’s reference literature for Zedboard implementation and many of the Q&A for Zybo+I2S+PL300 DMA on “ADI Engineer Zone”.
The tool environments and preparation
Before starting this project, I have confirmed the Petalinux boot on the Zybo Z7-20 Rev. B board with following the tool environments as a preparation.
OS: Ubuntu 18.04 LTS on VirtualMachine 6.1 on MacBook Pro
HW: Xilinx Vivado/Vitis 2020.2
SW: Petalinux 2020.2
Download “sstate-cash-arm” from Xilinx
To speed up the Yocto LINUX building with sstate-cash.
% tar xf ~/Downloads/sstate_arm_2020.2.tar.gz -C /tools/petalinux
Configure the Petalinux
% petalinux-create --type project --template zynq --name Zybo
% cd Zybo
% petalinux-config --get-hw-description ../project_1/<file name>.xsa
Enable SD card as the root file system
Select EXT4 as the “Rootfs” on the configuration menu.
Set “Local sstate feed”
Add “Pre-mirror URL”
Disable “Network sstate feed”
% petalinux-config -c kernel
Add the following additional kernel modules by click “y” on the menu.
Device Driver
Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support -> ASoCo simple sound card support
ADI SSM2602-I2C CODEC driver
Device Drivers -> Sound card support -> Advanced Linux Sound Architecture -> ALSA for SoC audio support -> CODEC drivers -> Analog Devices SSM2602 CODEC — I2C
Then “<Save>” and then “<Exit>”.
% cd components/yocto/workspace/sources/linux-xlnx/oe-local-files
% cat devtool-fragment.cfgCONFIG_SND_SOC_SSM2602=y
CONFIG_SND_SOC_SSM2602_I2C=y
CONFIG_SND_SIMPLE_CARD_UTILS=y
CONFIG_SND_SIMPLE_CARD=y
Userland
% petalinux-config -c rootfs
Filesystem Packages-> console -> utils -> alsa-tuils
Filesystem Packages-> base -> i2c-tuils
Edit the device-tree file
Edit project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi as following;
/include/ "system-conf.dtsi"
/ {
// https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/simple-card.txtsound { // sound/soc/generic/simple-card.c
compatible = "simple-audio-card";
simple-audio-card,name = "Zybo-Sound-Card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&cpu_dai>;
simple-audio-card,frame-master = <&cpu_dai>;cpu_dai: simple-audio-card,cpu {
sound-dai = <&axi_i2s_adi_0>;
clocks = <&misc_clk_0>; // 12288000
};codec_dai: simple-audio-card,codec {
sound-dai = <&ssm2603>;
clocks = <&misc_clk_0>; // 12288000
};
};
};&axi_i2s_adi_0 {
#sound-dai-cells = <0>; // only single DAI
clock-names = "ref", "axi";
clocks = <&misc_clk_0>, <&clkc 15>;
compatible = "adi,axi-i2s-1.00.a";
dmas = <&dmac_s 0 &dmac_s 1>;
dma-names = "tx", "rx";
};&i2c0 {
status = "okay";
ssm2603: ssm2603@1a {
#sound-dai-cells = <0>; // only single DAI
compatible = "adi,ssm2603";
reg = <0x1a>;
};
};
- You may change “clocks” and “dmas” names properly.
Edit ssm2602.c
components/yocto/workspace/sources/linux-xlnx/sound/soc/codec/ssm2602.c
FPGA can only generate 48KHz (12.288MHz/64/4)format, so Codec device driver should declare it to inform LINUX, then ALSA will insert SRC properly in case of 44.1KHz series sampling playback.
496,499c496,499
< #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | \
< SNDRV_PCM_RATE_16000 | \
< SNDRV_PCM_RATE_32000 | \
< SNDRV_PCM_RATE_48000 | \
---
> #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
> SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
> SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
> SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
Build the Linux and BOOT.BIN
% petalinlsux-build
% petalinux-package --boot --force --fsbl images/linux/zynq_fsbl.elf --fpga images/linux/system.bit --u-boot
Copy image and rootfs to SD-card
% cd images/linux
% sudo cp BOOT.BIN boot.scr image.ub /media/sdcard/boot/
% sudo tar xf rootfs.tar.gz -C /media/sdcard/root/
% sudo sync
Boot LINUX and login
We could confirm axi_i2s_adi mapped to ssm2602-hifi OK.
Now we can play the WAV file with “aplay” or “speaker-test” command and ALSA may insert proper Rate Converter as following;
root@Zybo:~# aplay -v FreeVocal12_44k.wav
Playing WAVE ‘FreeVocal12_44k.wav’ : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Plug PCM: Rate conversion PCM (48000, sformat=S32_LE)
Converter: linear-interpolation
Protocol version: 10002
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 16
Slave: Hardware PCM card 0 ‘Zybo-Sound-Card’ device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (96000/2)
msbits : 32root@Zybo:~# aplay -v FreeVocal12_48k.wav
Playing WAVE 'FreeVocal12_48k.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Plug PCM: Linear conversion PCM (S32_LE)
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S16_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (48000/1)
msbits : 16
Slave: Hardware PCM card 0 'Zybo-Sound-Card' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : MMAP_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 48000
exact rate : 48000 (96000/2)
msbits : 32
One problem is that SSM2603 initialization has a problem and generating noise until to communicate first I2C command from the user application such as “aplay -f S32_LE” etc…
Continue to the next memorandum.
Reference Link
https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/simple-card.txt