1. 程式人生 > >HI3521D外接audio codec轉I2S音訊採集

HI3521D外接audio codec轉I2S音訊採集

經過幾天的不斷的閱讀文件,問人,嘗試終於除錯成功。反過來一想,原來如此簡單。

1.硬體原理圖

a.外接codec部分

b.時鐘MCLK部分,由海思提供

c.海思對接codec部分

對原理圖的理解:外接codec通過由海思GPIO9_3/I2S2_MCLK連線MCLK引腳提供時鐘,I2S的SD,WS,BCLK線連線海思I2S0的SD,WS,BCLK。

2.暫存器配置邏輯

海思文件摘要:

       AI 裝置支援擴充套件的多路接收的I2S及PCM 介面時序。對接時,Codec 的時序模式選擇、同步時鐘、取樣位寬等配置必須與AI 裝置的配置保持一致,否則可能採集不到正確的資料。

     由於時序的問題,在AI/AO 裝置從模式下,建議使用者先配置好對接的Codec,再配置AI 或AO 裝置;而在AI/AO 裝置主模式下,建議使用者先配置好AI 或AO 裝置,再配置對接的Codec。

由於外接codec電路把外接codec設定為了主模式,那麼海思即為從模式。

所以先設定外接codec的時鐘等引數。

暫存器設定:

a.外接codec主時鐘的設定,因為MCLK連線的GPIO9_3,所以先把GPIO9_3複用為外接codec的主時鐘

即:

himm 0x120F00AC 0x2   #GPIO9_3  I2S1_BCLK_RX  I2S2_MCLK

注意:上面暫存器配置第一個圖,我個人覺得海思文件有問題,不應該是I2S0/PCM的接收時鐘。海思家大業大,對於技術支援,呵呵,我等小散就不要想了。

b.把外接MCLK設定多少?我是設定為12.288MHz,怎麼去設定~~~

下面這張圖對時鐘設定很重要,可以多看多理解。

從GPIO9_3引腳複用看出,我們用的是I2S2時鐘,那麼根據上圖,我們將配置CRG8,即我們配置I2S_CRG_CFG0_08和I2S_CRG_CFG1_08。具體可以參考文件檢視這兩個暫存器配置的內容。

我的配置如下:

#crg8
himm 0x13140140 0x003254E7
himm 0x13140144 0x00000133

根據外接codec的晶片的說明,設定好MCLK,他們會自動把BCLK,取樣率WS都設定好。BCLK=MCLK/4 ,WS=BCLK/64

現在codec時鐘設定好了,就要設定與codec連線的I2S0的時鐘。

從上圖可以看到,I2S0介面的配置暫存器位CRG0,即我們配置I2S_CRG_CFG0_00和I2S_CRG_CFG1_00暫存器。具體可以參考文件檢視這兩個暫存器配置的內容。

我的配置如下:

#crg0
himm 0x13140100 0x003254E7   #此時第0路時鐘輸出mclk 頻率為12.288MHz。
himm 0x13140104 0x00000133   #時使能第0路時鐘,同時把bclk 配置為mclk 的4分頻,
                             #fclk配置為bclk的64分頻,此時fclk頻率為48KHz

海思I2S0與外接codec對接的配置基本如上。

c.I2S0的引腳複用為I2S0_WS_RX,I2S0_BCLK_RX,I2S0_SD_RX

具體方式,可以檢視MCLK複用的方式。

我的值:

himm 0x120F00A0 0x1   #GPIO9_0  I2S0_BCLK_RX
himm 0x120F00A4 0x1   #GPIO9_1  I2S0_WS_RX
himm 0x120F00A8 0x1   #GPIO9_2  I2S0_SD_RX

綜上是為我的暫存器配置。

3.海思應用程式的編寫

1.海思採集程式,主要是通過海思sample裡面的audio程式來改,具體改了AIO_ATTR_S的值。

如下:

AIO_ATTR_S stAioAttr;

stAioAttr.enSamplerate   = AUDIO_SAMPLE_RATE_48000;
stAioAttr.enBitwidth     = AUDIO_BIT_WIDTH_16;
stAioAttr.enWorkmode     = AIO_MODE_I2S_SLAVE;
stAioAttr.enSoundmode    = AUDIO_SOUND_MODE_MONO;
stAioAttr.u32EXFlag      = 1;
stAioAttr.u32FrmNum      = 30;
stAioAttr.u32PtNumPerFrm = SAMPLE_AUDIO_PTNUMPERFRM;
stAioAttr.u32ChnCnt      = 1;
stAioAttr.u32ClkChnCnt   = 1;
stAioAttr.u32ClkSel      = 0;

if(PT_AAC == gs_enPayloadType)
{
     stAioAttr.u32PtNumPerFrm = AACLC_SAMPLES_PER_FRAME;
}

這篇文件,是我採集海思HI3521D音訊過程,如有錯誤,請多多指教。