DM8148 McASP接口调试总结_关于接口测试的总结

其他工作总结 时间:2020-02-28 14:21:03 收藏本文下载本文
【www.daodoc.com - 其他工作总结】

DM8148 McASP接口调试总结由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“关于接口测试的总结”。

DM8148 McASP接口调试总结

基础知识:

I2S协议——(Inter-IC Sound或Intergrated Interchip Sound)是飞利浦公司设计的一种用于IC间传输数字音频信号的接口标准。标准的I2S协议由3条线构成:帧时钟、位时钟和数据线。帧时钟用于切换左右声道的数据。位时钟对应每一位数据。有时为了使系统间能够更好的同步还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟。

图1 I2S协议时序

I2S采样率、采样位数和时钟的关系:

位时钟(串行时钟)= 2*采样频率*采样位数 帧时钟 = 采样频率

主时钟 = 采样频率的256倍或384倍(依据codec的配置)

McASP接口——复通道音频接入接口,是TI公司的DSP的一种接入接口,是一种通用的音频接入接口。采用的是时分复用的数据流形式。Mcasp使用I2S协议,也支持DIT协议。mcasp包括发射和接收两部分,他们可以使用不同时钟,不同的传输模式,工作完全独立。发射和接收也能够工作在同步状态。mcasp的管脚都可以配置为通用I/O。

图2 mcasp引脚介绍

DM8148共有6个Mcasp接口,其中mcasp0、1既有接收口(ACLKR、AFSR)也有发送口(ACLKX、AFSX),且可以设置为不同时钟,即接收时钟可以与发送时钟同步,也可以选择异步。而Mcasp2、3、4、5只有发送口(ACLKX、AFSX),因此接收时钟必须与发送时钟同步。

硬件连接: 方式一:

ACLKX——连接I2S的位时钟输入/输出 AFSX——连接I2S的帧时钟输入/输出 AXR——连接I2S的数据输入/输出

方式二:

ACLKR——连接I2S的位时钟输入/输出 AFSR——连接I2S的帧时钟输入/输出 AXR——连接I2S的数据输入/输出

两种情况由于连接方式不同,在McASP时钟配置时也有区别。在TI的DVRRDK_04.00.00.03提供的内核中默认采用的是方式一(DM8148只有mcasp0和mcasp1同时具有发送口与接收口,mcasp2、3、4、5都只有发送口,因此所有mcasp口均可如此连接),时钟设置为了同步模式,不需要再改动。当选择方式二时(DM8148只有mcasp0和mcasp1可以这样连接),需要修改sound/soc/davinci/davinci-mcasp.c,将时钟设置为异步模式。本设备中sii9135连接采用了方式一(mcasp0),tlv320aic3106与tvp5158采用了方式二(mcasp4)。static void davinci_hw_param(struct davinci_audio_dev *dev, int stream, char *name){ ……

if(!strcmp(name, “SII9135AUDIO”))//+14-10-15

mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);//设置时钟为异步

else

mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);//设置时钟为同步

…… }

图3接收与发送时钟配置 mcasp配置:

以tvp5158(连接至mcasp4)为例:

在archarmmach-omap2devices.c中添加mcasp资源: static struct resource ti81xx_mcasp4_resource[] = { {

.name = “mcasp”,.start = TI81XX_ASP4_BASE,.end = TI81XX_ASP4_BASE +(SZ_1K * 12)-1,.flags = IORESOURCE_MEM, }, /* TX event */ {

.start = TI81XX_DMA_MCASP4_AXEVT,.end = TI81XX_DMA_MCASP4_AXEVT,.flags = IORESOURCE_DMA, }, /* RX event */ {

.start = TI81XX_DMA_MCASP4_AREVT,.end = TI81XX_DMA_MCASP4_AREVT,.flags = IORESOURCE_DMA, }, };以上结构体添加了mcasp4的基地址以及EDMA通道,这些值如果没有定义,需要在archarmplat-omapincludeplatasp.h中添加,查阅数据手册。此外还要修改EDMA配置,否者会出现错误信息:

davinci_pcm: Failed to get dma channels asoc: can't open platform davinci-pcm-audio arecord: main:666: audio open error: Device or resource busy 修改如下:

static const s16 ti814x_dma_rsv_chans[][2] = { /*(offset, number)*/ {0, 2}, {14, 2}, {26, 6}, {48, 4}, {56, 6},// change {56,8} to {56,6} on 14-08-29 {-1,-1} };static const s16 ti814x_dma_rsv_slots[][2] = { /*(offset, number)*/ {0, 2}, {14, 2}, {26, 6}, {48, 4}, {56, 6},//change {56,8} to {56,6} on 14-08-29 {64, 127},{248, 264}, {-1,-1} };

同样在archarmmach-omap2devices.c中需要添加: static struct platform_device tvp5158_audio_device = {.name = “tvp5158-audio”,.id =-1, };

static u8 tvp5158_iis_serializer_direction[] = { RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, };tvp5158_iis_serializer_direction里的元素对应着mcasp接口的每个数据接收发送端口AXR的工作模式:RX_MODE(接收), TX_MODE(发送)和INACTIVE_MODE(无效)。本数组表示AXR [0]工作在接收模式,AXR [1]—AXR [15]不工作。static struct snd_platform_data tvp5158_snd_data = {.tx_dma_offset = 0x4A1AB000,.rx_dma_offset = 0x4A1AB000,.asp_chan_q = EVENTQ_0,.tdm_slots = 2, /* number of channels.I2S模式时必须设置为2*/.op_mode = DAVINCI_MCASP_IIS_MODE,.num_serializer = ARRAY_SIZE(tvp5158_iis_serializer_direction),.serial_dir = tvp5158_iis_serializer_direction,.version = MCASP_VERSION_2,.txnumevt = 32,.rxnumevt = 32, };

static struct platform_device ti81xx_mcasp_tvp5158_device = {.name = “davinci-mcasp”, /* driver name */.id = 4,//mcasp端口号

.dev = {

.platform_data = &tvp5158_snd_data,},.num_resources = ARRAY_SIZE(ti81xx_mcasp4_resource),.resource = ti81xx_mcasp4_resource, };

void __init ti81xx_register_mcasp(void)//注册mcasp { ……

#ifdefCONFIG_SND_SOC_TVP5158_AUDIO

printk(KERN_DEBUG “n**** Registering TVP5158 & MCASP4n”);

platform_device_register(&tvp5158_audio_device);

platform_device_register(&ti81xx_mcasp_tvp5158_device);#endif

#ifdef CONFIG_SND_SOC_SII9135_AUDIO

printk(KERN_DEBUG “n**** Registering SiI9135 & MCASP0n”);

platform_device_register(&sii9135_audio_device);

platform_device_register(&ti81xx_mcasp_sii9135_device);#endif }

在soundsocdavinciti81xx-evm.c中:snd_soc_dai_link结构体连接起codec驱动与平台驱动,内核根据名字建立连接,要保证codec_name和codec驱动中的platform_driver中的名字相同;codec_dai_name和codec驱动中的snd_soc_dai_driver中的名字相同。此结构体中成员的顺序决定了ALSA 声卡的设备序号,本程序中: staticstruct snd_soc_dai_link ti81xx_mcasp_dai[] = { {

.name = “TVP5158AUDIO”,.stream_name = “TVP-PCM”,.cpu_dai_name= “davinci-mcasp.4”,.codec_dai_name = “tvp5158-hifi”,.platform_name =“davinci-pcm-audio”,.codec_name = “tvp5158-audio”,.ops = &ti81xx_evm_ops, }, {

.name = “TLV320AIC3X”,.stream_name = “AIC3X”, #if defined(CONFIG_MACH_TI810XEVM)|| defined(CONFIG_MACH_TI810XDVR)|| defined(CONFIG_MACH_UD8107_DVR)

.cpu_dai_name= “davinci-mcasp.1”, #else

.cpu_dai_name= “davinci-mcasp.2”, #endif

.codec_dai_name = “tlv320aic3x-hifi”,.codec_name = “tlv320aic3x-codec.1-0018”,.platform_name = “davinci-pcm-audio”,.init = ti81xx_evm_aic3x_init, };.ops = &ti81xx_evm_ops, }, /*+ljk sii9135 14-9-17*/ {.name = “SII9135AUDIO”,.stream_name = “HDMI-PCM”,.cpu_dai_name= “davinci-mcasp.0”,.codec_dai_name = “sii9135-hifi”,.platform_name =“davinci-pcm-audio”,.codec_name = “sii9135-audio”,.ops = &ti81xx_evm_ops, }, /*end*/ sound/soc/davinci/ti81xx-evm.c中的ti81xx_evm_hw_params函数设定音频为I2S或者DSP模式,以及位时钟与帧时钟的主从模式。(DSP_A模式与I2S模式没有区别)。static int ti81xx_evm_hw_params(struct snd_pcm_substream *substream,struct snd_pcm_hw_params *params){ struct snd_soc_pcm_runtime *rtd = substream->private_data;struct snd_soc_dai *codec_dai = rtd->codec_dai;struct snd_soc_dai *cpu_dai = rtd->cpu_dai;unsigned sysclk, fmt = 0;/* default */ sysclk = 24576000;if(!strcmp(rtd->dai_link->name, “TVP5158AUDIO”)){

/* AFSR-> falling edge, ACLKX-> rising edge, 1 bitclock delay

DSP_A Mode(codec clk & FRM master)*/

fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM |

SND_SOC_DAIFMT_NB_IF;//选择DSP_A模式,主模式

AUDIOPRINT(“TVP5158:DSP_A#codec clk and FRM as master.n”);/*+ljk 14-9-1*/ }

else if(!strcmp(rtd->dai_link->name, “SII9135AUDIO”))//ljk 14-9-29 {

fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM |

SND_SOC_DAIFMT_NB_IF;

AUDIOPRINT(“SII9135:DSP_A#codec clk and FRM as master.n”);//+ljk 14-9-1 } else {

/* DSP_B Mode*/

fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM |

}

SND_SOC_DAIFMT_IB_NF;}

/* set codec DAI configuration */ snd_soc_dai_set_fmt(codec_dai, fmt);/* set cpu DAI configuration */ snd_soc_dai_set_fmt(cpu_dai, fmt);/* set the codec system clock */ snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);return 0;tvp5158已经提供了部分驱动和代码,当一个codec需要从零开始添加时,可以仿照tvp5158,如sii9135(连接至mcasp0的接收端口)的添加: 1.添加sii9135-audio.c文件到sound/soc/codecs/目录。2.修改sound/soc/codecs/Kconfig和Makefile 3.修改sound/soc/davinci/Kconfig 4.其他修改部分与tvp5158修改位置相同

5.不需要修改static const s16 ti814x_dma_rsv_chans[][2] 与static const s16 ti814x_dma_rsv_slots[][2]中与mcasp0对应的值。

6.需要在sound/soc/davinci/davinci-mcasp.c中将接收与发送时钟设置为异步: static void davinci_hw_param(struct davinci_audio_dev *dev, int stream, char *name){ ……

if(!strcmp(name, “SII9135AUDIO”))//+14-10-15

mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);//设置时钟为异步

else

mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);//设置时钟为同步

…… }

codec驱动配置:

需要注意codec驱动所支持的采样率与格式要与codec芯片配置的相同,而且不能超过mcasp所支持的范围。

static struct snd_soc_dai_driver tvp5158_dai = {.name = “tvp5158-hifi”,.capture = {

.stream_name = “Capture”,.channels_min = 2,.channels_max = 16,.rates =(SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000),};.formats = SNDRV_PCM_FMTBIT_S16_LE|SNDRV_PCM_FMTBIT_S32_LE,},.ops = &tvp5158_dai_ops, 测试方法:

首先需要配置音频芯片的寄存器使它们可以正常输出I2S格式音频。这些芯片采用I2C总线通信,所以可以使用i2cset和i2cget工具配置和查询。例如,配置tvp5158地址为0xc3的寄存器为0x68:

i2cset-y 1 0x5b 0xc3 0x68 tvp5158的配置脚本内容:

#!/bin/sh echo “*******TVP5158 set**********” i2cset-y 1 0x5b 0xfe 0x01 echo “0xfe:” i2cget-y 1 0x5b 0xfe #16kHz i2cset-y 1 0x5b 0xc0 0x00 echo “0xc0:” i2cget-y 1 0x5b 0xc0 #mix output i2cset-y 1 0x5b 0xc4 0x01 echo “0xc4:” i2cget-y 1 0x5b 0xc4 i2cset-y 1 0x5b 0xc8 0x00 echo “0xc8:” i2cget-y 1 0x5b 0xc8 #SD_R master i2s 64fs 16bit PCM i2cset-y 1 0x5b 0xc3 0x68 echo “0xc3:” i2cget-y 1 0x5b 0xc3 #-1.5db i2cset-y 1 0x5b 0xc1 0x77 echo “0xc3:” i2cget-y 1 0x5b 0xc3 i2cset-y 1 0x5b 0xc2 0x77 echo “0xc3:” i2cget-y 1 0x5b 0xc3 #mute disable i2cset-y 1 0x5b 0xc5 0x00 echo “0xc5:”

i2cget-y 1 0x5b 0xc5 echo “*******finish*********” 使用ALSA提供的录音工具arecord录取声音。录音的参数需要与芯片对应的配置相同。tvp5158通过I2C配置为了16bit,16KHz。sii9135为32bit,48KHz。使用arecord-l 命令查看录音设备:

tvp5158录音:

arecord-Dplughw:0,0-r16000-fS16_LE test.wav sii9135录音:

arecord-Dplughw:0,2-r48000-fS32_LE test.wav

常见问题:

1、使用arecord 录制的wav格式视频只有44bit。

如果I2S信号正常,则是由于I2S时钟没有匹配mcasp时钟,44bit其实是wav格式的头的大小。检查sound/soc/davinci/davinci-mcasp.c中的时钟同步寄存器配置。

下载DM8148 McASP接口调试总结word格式文档
下载DM8148 McASP接口调试总结.doc
将本文档下载到自己电脑,方便修改和收藏。
点此处下载文档

文档为doc格式

    热门文章
      整站推荐
        点击下载本文