S3C2440 IIS操作 uda134x錄放音
IIS(Inter-IC Sound)由飛利浦公司開發。是一種經常使用的音頻設備接口,主要用於CD、MD、MP3等設備。
s3c2440一共同擁有5個引腳用於IIS:IISDO、IISDI、IISSCLK、IISLRCK和CDCLK。前兩個引腳用於數字音頻信號的輸出和輸入,另外三個引腳都與音頻信號的頻率有關,可
見要用好IIS,就要把信號頻率設置正確。IIS僅僅負責數字音頻信號的傳輸。而要真正實現音頻信號的放、錄,還須要額外的處理芯片(在這裏,我們使用的是UDA1341)。
IISSCLK為串行時鐘,這條線路在 codec 芯片 uda134x 內部是BCK也就是 bit clock input。
每個時鐘信號傳送一位音頻信號
因此IISSCLK的頻率=聲道數×採樣頻率×採樣位數,如採樣頻率fs為44.1kHz,採樣的位數為16位。聲道數2個(左、右兩個聲道),則IISSCLK的頻率=32fs=1411.2kHz。
IISLRCK為幀時鐘。用於切換左、右聲道,如IISLRCK為高電平表示正在傳輸的是左聲道數據,為低電平表示正在傳輸的是右聲道數據,因此IISLRCK的頻率應該正好等於
採樣頻率fs。從上面兩幅圖能夠清除的看出來。
CDCLK 也就是 uda134x 內部的sysclk 在 uda134芯片手冊能夠設置為system clock 256fs , 384fs or 512fs。 在s3c2440裏面僅僅能設置成256fs或384fs。這個引腳為該芯
片提供系統同步時鐘。即編解碼時鐘。主要用於音頻的A/D、D/A採樣時的採樣時鐘。
通過以上分析能夠發現,採樣頻率fs對頻率的設置至關重要。
而fs不是隨意設置的。對於特定的音頻數據這個值是固定的,而設置不同的幾個固定的值。如8kHz、16kHz、22.05kHz、44.1kHz、48kHz、96kHz等。常見的wav 文件都是 44.1khz。
為了使系統得到以fs為基數的各類時鐘信號,就要又一次調整系統時鐘。
s3c2440用於IIS的時鐘源有PCLK和MPLLin。我們這裏選擇PCLK作為IIS的時鐘源。PCLK經過兩個
預分頻器處理後分別得到IISSCLK、IISLRCK和CDCLK(預分頻器A得到IISSCLK、IISLRCK。預分頻器B得到CDCLK)。
寄存器IISPSR是IIS預分頻器寄存器,5~9位是預分頻器A。0~4位是預分頻器B,一般來說,這兩個預分頻器的值N相等。即僅僅要知道一個,還有一個也就知道。而這裏我們
是通過CDCLK來計算預分頻器B的值N的,即 CDCLK= PCLK / (N+1)。
註意在整個寄存器組裏面沒有直接設置fs,由於PCLK是已經設置好的,假如取值400Mhz,再通過這裏的N 得到CDCLK。 而CDCLK 和fs關系也是通過設置IISMOD寄存器
得到。所以fs也就確定了,然後 IISSCLK 也能夠通過 IISMOD 寄存器設置得到。
假設直接用預分頻器A的N值和PCLK來計算IISSCLK和IISLRCK似乎沒有給出一個方式。
當 fs=44.1khz 的時候CDCLK=384fs=16.9344MHz,對於PCLK 有非常多取值,依照最小誤差的原則能夠算出
MPLLCON = (150<<12) | (5<<4) | 0; 分頻數 N = 3此時 CDCLK = 16.92857 誤差也算比較小的了。
另外在 官方給出的 2440test 裸機文件裏也有一組數值:
MPLLCON = (229<<12)|(5<<4)|1 N = 2<<5 PCLK = 406.2857/8; CDCLK = 16.92857假設使用經常使用的頻率數值PCLK=50Mhz。此時取 N = 2,CDCLK=16.666Mhz 有些誤差,可是通過我的測試音質變化差點兒聽不出來。
因此這裏就選擇這一組了。
另外上面的2組都會導致 FCLK > 400Mhz,會不會導致cpu不穩定?
IISCON 和 IISMOD 寄存器每一個位含義例如以下所看到的:
對於處理器和 uda134x 通信,正常的音頻傳輸是通過IIS 來進行的,上面已經說了。還要配置 uda134x 內部寄存器,uda134x 支持I2C 和L3總線模式等模式配置,記得以
前在mips 架構上 是通過I2c 寄存器來設置的。這裏我們選擇 L3總線來設置。
因為s3c2440不具備L3總線接口,因此我們是用三個通用IO口來模擬L3,從而實現L3總線的傳輸。UDA1341有兩種模式:地址模式和傳輸數據模式。
地址模式表示傳輸的是地址信息,它的高6位永遠是000101。低兩位表示的是傳輸的模式,是狀態模式、數據0模式還是數據1模式,當中狀態模式主要用於配置UDA1341
的各類初始狀態,數據模式主要用於改善音頻輸入、輸出的效果。
地址模式和數據模式主要通過 L3MODE 線來區分。
l3 線 數據寫 模式代碼例如以下:
codec 配置 代碼例如以下(與上面的時序圖相應):
//L3總線接口的寫函數 //輸入參數data為要寫入的數據 //輸入參數address,為1表示地址模式,為0表示傳輸數據模式 static void WriteL3(byte data,byte address) { int i,j; if(address == 1) rGPBDAT = (rGPBDAT & ~(L3D | L3M | L3C)) | L3C; //L3D=L, L3M=L(地址模式), L3C=H else rGPBDAT = (rGPBDAT & ~(L3D | L3M | L3C)) | (L3C | L3M); //L3M=H(傳輸數據模式) for(i=0;i<10;i++) ; //等待一段時間 //並行數據轉串行數據輸出,以低位在前、高位在後的順序 for(i=0;i<8;i++) { if(data & 0x1) // H { rGPBDAT &= ~L3C; //L3C=L rGPBDAT |= L3D; //L3D=H for(j=0;j<5;j++) ; //等待一段時間 rGPBDAT |= L3C; //L3C=H rGPBDAT |= L3D; //L3D=H for(j=0;j<5;j++) ; //等待一段時間 } else // L { rGPBDAT &= ~L3C; //L3C=L rGPBDAT &= ~L3D; //L3D=L for(j=0;j<5;j++) ; //等待一段時間 rGPBDAT |= L3C; //L3C=H rGPBDAT &= ~L3D; //L3D=L for(j=0;j<5;j++) ; //等待一段時間 } data >>= 1; } rGPBDAT = (rGPBDAT & ~(L3D | L3M | L3C)) | (L3C | L3M); //L3M=H,L3C=H }
//配置UDA1341 WriteL3(0x14 + 2,1); //狀態模式(000101xx+10) WriteL3(0x60,0); //0,1,10, 000,0 : 狀態0,復位 WriteL3(0x14 + 2,1); //狀態模式 (000101xx+10) WriteL3(0x10,0); //0,0,01, 000,0 : 狀態0, 384fs,IIS,no DC-filtering WriteL3(0x14 + 2,1); //狀態模式 (000101xx+10) WriteL3(0xc1,0); //1,0,0,0, 0,0,01:狀態1,
上面設置codec 寄存器含義要從datasheet 裏面找到解釋 比方說 WriteL3(0xc1,0); 0xc1 轉換成二進制就是:
1 1 0 0 0 0 0 1b
上面簡介了IIS 音頻播放各種配置,事實上對於錄音也要配置頻率。跟對應的codec寄存器,這裏實現了錄制一段音頻數據。然後再播出的功能。
這個能夠參考曾經的博文 qemu模擬alsa聲卡 制作一個wav 文件,然後再把wav文件轉換成c數組這一步能夠用winhex完畢:首先打開須要提取的wav文件,然後再在數
據部分的開始處右鍵點擊“Beginning of Block”。在數據結束部分右鍵點擊“End of block”。這時就選中了所需的數據。然後右鍵點擊“Edit”->"Copy block"->"C source"。這時
數據就以unsigned char數組的形式拷貝到了剪貼板上。接下來新建一個文本文件粘貼進去就能夠了。粘貼進去你會發現,xinhex已經幫你定義好了數組,能夠直接用到c
代碼中。相當人性化,對於前面的bmp位圖制作數組也能夠用這樣的方式。
音頻播放代碼:
buffer = music_buffer; length = 564000; //sizeof(music_buffer); init_iis(); //開啟IIS rIISCON |= 0x1; while(1) { i++; if(i>99)i=0; count = 0; while(1) { if((rIISCON & (1<<7))==0) //檢查輸出FIFO是否為空 { //FIFO中的數據為16位,深度為32這個數值能夠參考s3c2440 //當輸出FIFO為空時,一次性向FIFO寫入32個16位數據 for(i=0;i<32;i++) { *IISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8); } count+=64; //OSTimeDly( 1 ); 這裏1等於5ms ,可是連這5ms也無法歇息,否則 會導致音樂全然聽不出來 /// cpu 在播放的時候是無法休眠了,假設用dma 那麽這個傳輸數據的過程就不用cpu管理,cpu就能夠休眠了。if(count>length) break; //音頻傳輸數據完,則退出 } } //rIISCON = 0x0; //關閉IIS OSTimeDly(OS_TICKS_PER_SEC); }
完整代碼間例如以下鏈接:
參考:
blog.csdn.net/zhaocj/article/details/5570424
s3c2440文檔
S3C2440 IIS操作 uda134x錄放音