前言
虽然添加好了tinyplay工具,以及pcm设备,但是依然无法播放。
目前看起来问题出现在i2s2的添加上,i2s2 tx reset失败。
如果有了解如何解决的方法,请多指教。
tinyalsa
duo-buildroot-sdk-develop\buildroot-2021.05\package\tinyalsa\Config.in
有依赖关系
BR2_PACKAGE_TINYALSA
BR2_STATIC_LIBS
config BR2_PACKAGE_TINYALSA
bool "tinyalsa"
depends on !BR2_STATIC_LIBS
help
a small library to interface with ALSA in the Linux kernel
The aims are:
- Provide a basic pcm and mixer API
- If it's not absolutely needed, don't add it to the API
- Avoid supporting complex and unnecessary operations that
could be dealt with at a higher level
https://github.com/tinyalsa/tinyalsa
comment "tinyalsa needs a toolchain w/ dynamic library"
depends on BR2_STATIC_LIBS
duo的br配置
duo-buildroot-sdk-develop\buildroot-2021.05\configs\milkv_duo_musl_riscv64_defconfig
BR2_PACKAGE_TINYALSA=y
查看最终打开的br config
duo-buildroot-sdk-develop\buildroot-2021.05\Config.in
打开后生成在dl目录下
duo-buildroot-sdk-develop\buildroot-2021.05\dl
参考资料:https://zhuanlan.zhihu.com/p/508579943
tinyalsa.mk
这里指定了版本
选择下载1.1.1的zip文件
################################################################################
#
# tinyalsa
#
################################################################################
TINYALSA_VERSION = 1.1.1
TINYALSA_SITE = $(call github,tinyalsa,tinyalsa,$(TINYALSA_VERSION))
TINYALSA_LICENSE = BSD-3-Clause
TINYALSA_LICENSE_FILES = NOTICE
TINYALSA_INSTALL_STAGING = YES
define TINYALSA_BUILD_CMDS
$(TARGET_MAKE_ENV) $(MAKE) CROSS_COMPILE="$(TARGET_CROSS)" -C $(@D)
endef
define TINYALSA_INSTALL_STAGING_CMDS
$(TARGET_MAKE_ENV) $(MAKE) \
-C $(@D) \
PREFIX="/usr" \
CROSS_COMPILE="$(TARGET_CROSS)" \
DESTDIR="$(STAGING_DIR)" install
endef
define TINYALSA_INSTALL_TARGET_CMDS
$(TARGET_MAKE_ENV) $(MAKE) \
-C $(@D) \
PREFIX="/usr" \
CROSS_COMPILE="$(TARGET_CROSS)" \
DESTDIR="$(TARGET_DIR)" install
endef
$(eval $(generic-package))
问题1:tinyplay无法执行,缺失so
文件是生成了的,但是没有办法运行。
执行file tinyplay可以看到依赖一个库ld-musl-riscv64.so.1
去sdk中搜索
路径:duo-buildroot-sdk\host-tools\gcc\riscv64-linux-musl-x86_64\sysroot\lib\ld-musl-riscv64.so.1
方法1:拷贝so
将这个依赖的so放到设备中,可以运行tinyplay了,但是提醒权限
没有将so设置权限
chmod 777 /lib/ld-musl-riscv64.so.1
设置完权限后,执行tinyplay命令,可以看到命令可以执行成功并提示需要的参数。
方法2:软连接指向
duo-buildroot-sdk-develop\milkv\overlay\mnt\system\rndis.sh
#!/bin/sh
ln -s /lib/ld-musl-riscv64v0p7_xthead.so.1 /lib/ld-musl-riscv64.so.1
问题2:I2S tx重置失败
pcm设备创建成功可以在两个地方看。
ls -l /dev/snd
cat /proc/asound/pcm
tinyplay可以执行,但是发现tx reset失败。
tinyplay /root/cut76.wav -D 0 -d 0
发现执行后提示播放失败。
log来看提示I2S TX RESET failed.
推测1:i2s2的dma配置
推测可能是dtsi中的默认定义i2s2有tx和rx,我暂时只用了rx,导致tx没有reset。
duo-buildroot-sdk-develop\build\boards\default\dts\cv180x\cv180x_base.dtsi
i2s2: i2s@04120000 {
compatible = "cvitek,cv1835-i2s";
reg = <0x0 0x04120000 0x0 0x2000>;
clocks = <&i2s_mclk 0>;
clock-names = "i2sclk";
dev-id = <2>;
#sound-dai-cells = <0>;
dmas = <&dmac 6 1 1 /* read channel */
&dmac 1 1 1>; /* write channel */
dma-names = "rx", "tx";
capability = "txrx";
mclk_out = "false";
};
默认i2s2是打开了tx和rx的。
tx为传输数据(播放),rx为接收数据(录制)
所以合理的配置应该是
i2s2: i2s@04120000 {
compatible = "cvitek,cv1835-i2s";
reg = <0x0 0x04120000 0x0 0x2000>;
clocks = <&i2s_mclk 0>;
clock-names = "i2sclk";
dev-id = <2>;
#sound-dai-cells = <0>;
dmas = <&dmac 1 1 1>; /* write channel */
dma-names = "tx";
capability = "tx";
mclk_out = "false";
};
这样配置,i2s2就只支持一个dma,也可以看到pcmc0d0。
&i2s2 {
status = "okay";
#sound-dai-cells = <0>;
};
&i2s1 {
status = "okay";
#sound-dai-cells = <0>;
};
ðernet0 {
status="disabled";
};
未解
问题依旧存在。
查看debug信息
如图,i2s2其实没有真的起来,查看代码
duo-buildroot-sdk\linux_5.10\sound\soc\cvitek\cv1835_i2s.c
static int i2s_proc_show(struct seq_file *m, void *v)
{
struct cvi_i2s_dev *dev = m->private;
if (i2s_read_reg(dev->i2s_base, I2S_ENABLE))
seq_printf(m, "\ni2s%d is enabled\n", dev->dev_id);
else
seq_printf(m, "\ni2s%d is disabled\n", dev->dev_id);
seq_printf(m, "\n===== Dump I2S%d register status =====\n", dev->dev_id);
seq_printf(m, "\nblk_mode=0x%08x, clk_ctrl=0x%08x, int_en=0x%08x\n",
i2s_read_reg(dev->i2s_base, BLK_MODE_SETTING),
i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0),
i2s_read_reg(dev->i2s_base, I2S_INT_EN));
seq_printf(m, "\nframe_setting=0x%08x, slot_setting=0x%08x, data_format=0x%08x\n",
i2s_read_reg(dev->i2s_base, FRAME_SETTING),
i2s_read_reg(dev->i2s_base, SLOT_SETTING1),
i2s_read_reg(dev->i2s_base, DATA_FORMAT));
seq_printf(m, "\ni2s_int=0x%08x, rx_status=0x%08x, tx_status=0x%08x\n",
i2s_read_reg(dev->i2s_base, I2S_INT),
i2s_read_reg(dev->i2s_base, RX_STATUS),
i2s_read_reg(dev->i2s_base, TX_STATUS));
seq_printf(m, "\ndma_req=0x%08x, dma_ack=0x%08x\n",
i2s_read_reg(dev->i2s_base, DMA_REQ_COUNT),
i2s_read_reg(dev->i2s_base, DMA_ACK_COUNT));
seq_printf(m, "\nclk_ctrl0=0x%08x, clk_ctrl1=0x%08x\n",
i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0),
i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL1));
return 0;
}