AD2410開發說明
AD2410的A2B總線
A2B總線具有提供同步時鐘,傳輸數據,總線供電等功能。外設爲A2B總線的MASTER提供BCLK,SYNC時鐘信號,MASTER通過總線爲SLAVE提供時鐘信號。A2B總線的一個超級幀的頭部爲同步控制幀,包含了I2C的下行數據和CRC校驗碼。中間有一個同步響應幀,包含I2C的上行數據,CRC校驗碼和IRQ數據。一個超級幀的時間長度爲一個SYNC週期。SLAVE序號越大,該節點上傳的數據越靠前,下行數據越靠後。
MASTER喚醒
當MSTR引腳爲高電平且VIN電壓大於3.7V時,MASTER已經POWER UP,在等待SYNC信號的到來。在外部供給SYNC信號時,MASTER將時鐘信號在PLL中倍頻鎖存,這個過程最多需要25ms。這之後,MSATER已經可以通過I2C總線進行編程配置了。MASTER的I2C設備地址爲:
I2C地址位圖
當把ADR2和ADR1都拉低時,外圍器件訪問MASTER的地址就爲0x68,時序爲典型的I2C總線時序,需要注意的是,MASTER設備在I2C總線上總是作爲SLAVE存在。
在MASTER進入等待編程狀態後,會產生IRQ信號,使得IRQ引腳由低變高。
/*等待AD2410啓動*/
while(gpio_read(PING_CFG,PING2)==0 ); //等待IRQ信號
tmp= I2C0SlaveRegRead(1,AD2410_I2C_ADDR,0x16); //讀中斷狀態寄存器
if(tmp& 0x80) //判斷中斷類型是否爲MASTER產生
{
tmp= I2C0SlaveRegRead(1,AD2410_I2C_ADDR,0x17); //獲取中斷號
if(tmp!= 0xff)
return0;
}
到這裏,MASTER已經喚醒並且可編程。
SLAVE喚醒
在喚醒MASTER之後,在喚醒SLAVE之前需要給SLAVE供電,也就是幻想供電。需要先設置主機響應週期,然後置位newstrict = 1,之後使能MASTER的幻想電源。這裏需要注意的是:如果幻想電源在本節點禁用了,不管是MASTER還是SLAVE,該節點之後的所有節點都將處於掉電狀態。
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x0f,AD2410_MASTER_RESCYCLE); //設置主機響應週期數
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x12,0x01); //設置newstrict=1
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x09,0x01); //幻想電源使能
在SLAVE上電之後,需要將MASTER的INTMSK2寄存器從屏蔽發現SLAVE中斷狀態轉換到其他狀態,然後設置SLAVE的響應週期,之後等待發現SLAVE的IRQ信號在MASTER產生。
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x1d,0x01); //INTMSK2
count = 0;
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x13,slave_rescycle[count]); //slave0的響應週期
while(gpio_read(PING_CFG,PING2) ==0 ); //等待IRQ信號
tmp =I2C0SlaveRegRead(1,AD2410_I2C_ADDR,0x16);
if(tmp & 0x80) //判斷中斷類型
{
tmp= I2C0SlaveRegRead(1,AD2410_I2C_ADDR,0x17); //tmp = 0x18表示找到slave
}
ret =I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x09,0x21); //mode= 2 ,幻想電源使能
MASTER和SLAVE的響應週期計算:
響應週期與TDM模式和通道大小的關係表
下面舉個例子:
一個A2B系統上有5個節點,8個上行SLOT,6個下行SLOT。那麼他的MASTER得響應週期爲:
MSTR_RESPCYCS> TRUNC ((6*25 + 64 +3)/4) + 1 + 4*(4-1)
MSTR_RESPCYCS> 67
MSTR_RESPCYCS< 248 - TRUNC ((8*25 + 64 +3)/4)
MSTR_RESPCYCSMSTR_RESPCYCS< 182
SLAVE的響應週期爲:
SLV_RESPCYCS[n]= MSTR_RESPCYCS - (4 × n),n表示SLAVE的序號。
SLAVE初始化
先通過I2C總線在MASTER上設置要通信的SLAVE序號
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x01,count); //選擇slave count = 0;
然後通過I2C訪問MASTER來使用A2B來訪問SALVE,這裏I2C的地址爲0x69
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x0a,bcdnslots[count]); //BCDNSLOTS = 0
然後設置SALVE節點的本地下行SLOTS和剩餘下行SLOTS
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x0b,ldnslots[count]);//本地node下行slots
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x0d,dnslots[count]);//本節點後剩餘下行slots
之後設置SLAVE節點的本地上行SLOTS和之前上行SLOTS
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x0c,lupslots[count]);//本地node上行slots
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x0e,upslots[count]);//本節點之前上行slots
設置SLAVE節點的外圍器件的I2C地址,默認爲0x50,外圍器件主要是來自動初始化SLAVE。
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x00,0x50); //設置外圍器件的I2C地址
在這之後,進行SLAVE節點的I2S格式設置,測試中是使用PDM格式的mic進行測試的。
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x41,0x71); //I2S配置爲上升沿爲幀的開始,EARLY=1,16bit,TDM4
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x43,0x00); //reduce = 0,I2SRATE = 1xSFF
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x46,0x00); //0個移位
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x42,0x09); //I2SCFG,I2S,數據不交叉,RX0EN不使能,TX0EN使能,RX1EN,TX1EN不使能
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x44,0x00); //TX移位0個TDM時隙
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x45,0x00); //RX移位0個TDM時隙
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,0x47,0x01); //禁用PDM1,使能PDM0
如果需要對SLAVE外圍器件做初始化,也可以通過A2B總線來進行訪問。
在之前的基礎上,先將MASTER的0x01地址的寄存器上的PERI置1,NODE選擇相應的SLAVE序號,然後通過I2C訪問A2B的形式來訪問SLAVE的外圍器件。如果沒有,可以忽略這步。
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x01,count|(1<<5)); // PERI置1
I2C0SlaveRegWrite(1,AD2410_SLAVEI2C_ADDR,reg_addr,data);//訪問外圍器件相應的地址
MASTER初始化
在完成所有的SLAVE初始化後,進行MASTER的初始化工作。先設置MASTER的上行和SLAVE下行SLOTS。
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x0d,AD2410_DNSLOTS); //master的下行DNSLOTS
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x0e,AD2410_UPSLOTS); //slave的上行總UPSLOTS
這之後進行MASTER的I2S數據流格式設置
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x41,0x52); //I2S配置爲上升沿爲幀的開始,EARLY=1,16bit,TDM8
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x44,0x00); //TX移位0個TDM時隙
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x45,0x00); //RX移位0個TDM時隙
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x42,0x09); //I2SCFG,I2S,數據不交叉,RX0EN,TX0EN使能,RX1EN,TX1EN不使能
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x10,0x22); //UP和DN都是16bit
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x11,0x03); //使能UP和DN
I2C0SlaveRegWrite(1,AD2410_I2C_ADDR,0x12,0x01); //設置newstrict=1
A2B音頻數據傳輸解析
下面已兩個SLAVE和一個MASTER爲例。
在他們都初始化後進行正常工作後,A2B中的音頻數據順序爲
A2B數據流圖
在PDM格式中,單聲道數據會佔據64bit空間,以16bit爲例的話就是4個SLOT,這樣的話,兩個SLAVE都用PDM的話就是8個SLOT,爲方便起見,將下行數據也設置爲8個SLOT,當然,下行SLOTS可以設置爲實際需要的數量。在A2B數據流中,前4個SLOT爲SLAVE1的數據,後4個SLOT爲SLAVE0的數據。在SLAVE1的數據中,DN0爲實際可用的16bit音頻數據流,而其他3個SLOT都爲0。
A2B數據傳輸延遲
A2B傳輸延時圖
在上圖中,MASTER的數據到達SLAVE需要經過這樣的過程:MASTER->A2B總線->SLAVE,也就是說從MASTER到最近的SLAVE0也需要兩個SYNC的週期,SLAVE序號增加1,所需時間也會增加一個SYNC週期。
TDM傳輸
在MASTER與DSP數據交互時,接口採用I2S/TDM,也就是說將I2S數據以TDM的形式進行傳輸。以8個上行和下行SLOT爲例。DSP需要給MASTER提供的時鐘分別爲:SYNC = 48k,BCLK=16bit*8*48k=6.144M。在TDM數據流中,數據也是以一個SLOT爲單位進行傳輸。在一個SYNC時鐘週期內將8個SLOT數據傳輸完畢。I2S格式中,接收數據爲BCLK的上升沿,發送數據爲BCLK的下降沿,數據在同步信號到來後的一個BCLK後開始傳輸。MASTER和DSP需要設置成相同的形式。TDM的同步信號需要設置成一樣的模式。比如在DSP中設置成脈衝模式,在MASTER中也要設置成相同的脈衝模式。而在SLAVE端則不受限制。
系統初始化流程圖
左右聲道數據分開
如上圖所示,INTERLEAVED時,左右聲道是左聲道爲TX0,右聲道爲TX1。在NON-INTERLEVED時,是TX0和TX1都是左右聲道交叉傳輸。這一特性可以在使用32bit的TDM2的PDM麥克風時,在只使用一個MIC時,節約一個slot,在DSP終端實現多從機的傳輸,提高傳輸效率。