资讯详情

音频 :i2s 与pdma 设备树相关

Recording WAVE 'test.wav' : [  137.530635] =========nau8822_set_dai_sysclk clk_id:0,freq:12288000 Signed 16 bit Little Endian, Rat[  137.539005] @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@nau8822_hw_params val_len:0x0,val_rate:0x0 e 48000 Hz, Stereo [  137.550268] =======nau8822_set_bias_level:2 [  137.557970] =======nau8822_set_bias_level:3 [  137.562349] ==============nau8822_mute:0 [  137.567276] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  137.700319] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  137.708499] ==========default_read_copy [  137.713440] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  137.833330] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  137.841502] ==========default_read_copy [  137.846292] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  137.966340] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  137.974564] ==========default_read_copy [  137.979420] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.099356] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.107542] ==========default_read_copy [  138.112395] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.232371] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.240536] ==========default_read_copy [  138.245348] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.365401] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.373584] ==========default_read_copy [  138.378445] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.498411] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.506545] ==========default_read_copy [  138.511380] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.631423] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.639600] ==========default_read_copy [  138.644365] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.764434] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.772596] ==========default_read_copy [  138.777439] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  138.897447] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  138.905579] ==========default_read_copy [  138.910384] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.030457] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.038683] ==========default_read_copy [  139.043492] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.163475] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.171665] ==========default_read_copy [  139.176485] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.296492] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.304701] ==========default_read_copy [  139.309542] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.429518] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.437688] ==========default_read_copy [  139.442532] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.562528] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.570700] ==========default_read_copy [  139.575457] =======__snd_pcm_lib_xfer size:6000,data:0x31940,interleaved:1,in_kernel:0 [  139.695540] k510_peridma_interrupt: process Transfer done irq of phy ch0, int_status(1) [  139.703705] ==========default_read_copy [  139.708673] ==============nau8822_mute:1 [  139.713264] =======nau8822_set_bias_level:2 [  139.719924] =======nau8822_set_bias_level:1 

audio codec 每个寄存器占用两个字节。

#define NAU8822_REG_INPUT_CONTROL  0x2C static const struct snd_kcontrol_new nau8822_right_input_mixer[] = {  SOC_DAPM_SINGLE("R2 Switch", NAU8822_REG_INPUT_CONTROL, 6, 1, 0),  SOC_DAPM_SINGLE("MicN Switch", NAU8822_REG_INPUT_CONTROL, 5, 1, 0),  SOC_DAPM_SINGLE("MicP Switch", NAU8822_REG_INPUT_CONTROL, 4, 1, 0), };
#define AUDIO_BASE_ADDR    (0x96060000U) volatile audio_in_reg_s  *audio_in_reg  = (volatile audio_in_reg_ *)(long)(AUDIO_BASE_ADDR+0x400);
#define AUDIO_BASE_ADDR				(0x96060000U)

audio_i2s_in_init
0x96060400+0x21c = 0x9606061c
devmem 0x9606061c w   ->  0x00000001


i2s_init
ier
devmem 0x96060000 w  -> 0x00000001
irer
devmem 0x96060004 w  ->0x00000001
iter
devmem 0x96060008 w  ->0x00000001
ccr 
0x96060000 + 0x10
devmem 0x96060010 w -> 0x00000B30         ? 0x00000730

imr [0-3 channel]
0x96060000+0x3c+0x40(*0-3)
devmem 0x9606003c w  -> 0x00000033        
devmem 0x9606007c w  -> 0x00000033
devmem 0x960600bc w  -> 0x00000033
devmem 0x960600fc w  -> 0x00000033

ter [0-3 channel]
0x96060000+0x2c+0x40(*0-3)
devmem 0x9606002c w   -> 0x00000001
devmem 0x9606006c w  ->0x00000000
devmem 0x960600ac w  -> 0x00000000
devmem 0x960600ec  w   -> 0x00000000

rer [0-3 channel]
0x96060000+0x28+0x40(*0-3)
devmem 0x96060028 w   -> 0x00000001
devmem 0x96060068 w  ->0x00000000
devmem 0x960600a8 w  -> 0x00000000
devmem 0x960600e8 w   -> 0x00000000

i2s_rx_channel_config
i2s_set_rx_word_length
rcr [0-3 channel]
0x96060000+0x30+0x40(*0-3)   
devmem 0x96060030 w   -> 0x00000005   ?0x00000002
devmem 0x96060070 w   -> 0x00000005
devmem 0x960600b0 w   -> 0x00000005
devmem 0x960600f0 w   ->  0x00000005

i2s_set_tx_word_length
tcr [0-3 channel]
0x96060000+0x34+0x40(*0-3)   
devmem 0x96060034 w   -> 0x00000005  ?0x00000002
devmem 0x96060074 w   -> 0x00000005
devmem 0x960600b4 w   -> 0x00000005
devmem 0x960600f4 w   ->  0x00000005

RFCRx[0-3 channel]
0x96060000+0x48+0x40(*0-3)  
devmem 0x96060048 w   ->0x00000003
devmem 0x96060088 w   ->0x00000005
devmem 0x960600c8 w   ->0x00000005
devmem 0x96060108 w   ->0x00000005
	
TFCRx[0-3 channel]
0x96060000+0x4c+0x40(*0-3)  
devmem 0x9606004c w   ->0x00000003
devmem 0x9606008c w   ->0x00000003
devmem 0x960600cc w   ->0x00000003
devmem 0x9606010c w   ->0x00000003
        	


audio_i2s_out_init
devmem 0x96060000 w   ->0x00000001


x

dma将内存buffer数据拷贝到i2s 的transfer fifo中时, 内存buffer的结构:如果是16位数据,则通过设置i2s_set_dma_divide_16后,可将左右声道各16位拼接到一个32位里面,格式与wav/pcm音频格式相同。 i2s拷贝后完成后将32位数据分离成左右声道各16位(split 32bit data to two 16 bit data and filled in left  and right channel),再按照i2s的协议将 数据放到左右声道中。  

一).整体流程总结:

  1).引脚设置

     查看原理图,设置指定引脚为以下功能:WCLK(采样时钟),BCKL(位时钟),SDIN(数据输入),SDOUT(数据输出)

  2).设置codec参数(nau8822 音频codec)

     设置采样率,word length(每个声道传输多少位),i2s传输模式(左对齐,右对齐,标准),其他音频链路的控制(adc input,adc mix,dac out,dacmix )。

     以此可以保证:i2s in channel fifo上已经有实时的adc转换后的数据,可以随时通多dma拷贝到内存中使用。如果codec没初始化ok,该fifo上的数据拷贝到内存中始终为0.

     i2s out channel fifo上等待输入数据,如果有数据,则触发dac转换,通过audio codec播放。

  3).I2S数据时钟设置(实际就是BCLK)

     时钟配置,通过配置时钟(SYSCTL_CLK_AUDIO_OUT_SERIAL:I2S out channel,SYSCTL_CLK_AUDIO_IN_SERIAL:i2s in channel),

     可以精确控制i2s每秒采样位数,对应于pin:BCK.比如48k,双声道,每个声道16位/32cycle,则时钟为:48000*2(2个声道)*32(每个声道32位,其中16位有效)

  4).设置soc中i2s参数(与codec设置要一致)

     设置word length(每个声道采样位数),word cycles(每个声道采样时钟),传输模式(左对齐,右对齐,标准)等。

  5).启动dma

      1)数据采集: 1)手动配置dma,数据流向:I2S->buffer,启动dma

                             2)触发中断完成内存拷贝后,再次进入步骤1,如此无限循环。

      2) 数据播放:    1)手动配置dma,数据流向:buffer->I2S,启动dma

                             2)触发中断完成内存拷贝后,再次进入步骤1,如此无限循环。

  二).注意事项总结:

     1.数据采集和数据播放可以单独运行也可以同时运行。同时运行时,使用2个不同的dma通道,使用ping pongbuffer会导致延迟极低,不容易听到自己说话声。可以通过 ring buffer来调整延迟。

     2.i2s参数的修改,大部分参数修改2个位置:audio codec 和 soc中i2s模块,且两者修改后要保持一致。比如修改采样率,两边都要修改。

     3.内存分配:

        1)每个声道16位/32cycle的配置,i2s 输入通道默认配置:左声道(低16位有效,高16位为静音数据,值为0或0xffff两者不断切换),右声道同左声道。

        2)每个声道32位/32cycle的配置,i2s 输入通道默认配置:左声道(32位,32位有效),右声道同左声道。

        3)fpga以前的裸机程序每个声道32位/32cycle的,而实际驱动程序使用中都是16位/32cycle的。

            在linux系统下,通过aplay 播放一个wav文件,实际文件为16位/16cycle的格式,如何变成16/32cycle同时避免cpu拷贝内存,可使用i2s函数:i2s_set_dma_divide_16.

           (split 32bit data to two 16 bit data and filled in left and right channel).该函数仅仅适合音频播放(数据从buffer到i2s,指的是buffer中的数据).音频采集无效,采集到的数据仍为(16位/32cycle)。

     4.音频codec:包括音频的控制和数据的传输。数据的传输通过I2S协议。音频的控制(复位,音量,音频参数设置等)通过I2C协议。

标签: s10k510电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台