1. 程式人生 > >S3C2440 IIS操作 uda134x錄放音

S3C2440 IIS操作 uda134x錄放音

進制 人性 無法 qemu 找到 計算 錄制 term 變化

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錄放音