以前念電子學做擴大機的時候,總會用差動放大電路來做前級,不但可以得到比較好的效能,抗雜訊能力也比較好。但是現在我們週遭已經很多產品或介面,利用差動的概念達到高速的傳輸的目的,舉凡USB,PCI-E,SATA,.....
差動應用在傳輸介面相當好用。早期的電腦,由於當時技術不好所以像RS-232 為了達到抗雜訊的能力,就把TTL 準位的的信號,轉成+-12V 的信號。這也就是為神麼PC 當初在訂定規格時還需要有+- 12V 的原因。(後來有些公司覺得負壓很麻煩所以就SWITCHing 的方式轉出+- 10V 的介面IC)。為神麼將TTL 準位的信號轉換成+-12V就可以抗雜訊呢? 舉例來說:如果在TTL 準位中受到2V 雜訊的干擾,讓信號到達臨界電壓,是無法判斷出高電位或低電位的,但轉換到+-12V 之後,就可以輕易分辨出高電位或低電位,但我們並不能一昧拉高電壓,因為半導體也有其最大電壓的設計,所以就有差動傳輸的概念出來。
差動就是利用CMRR共模的效果,透過兩條線(一對雙絞線)來傳輸,並使其絞線在一起,當雜訊來的時候他會同時在兩條線上,且會被互相抵銷,藉以達到抗雜訊的能力。注意:差動傳輸只能解決雜訊的問題,但是線長所造成的衰減是無法徹底解決,這部分必須靠驅動力與終端電阻才可以改善。
1. 最早的差動介面 RS-485, RS422
RS485 與RS422 是RS-232 的延伸應用,由於RS232 雖然可以有幾米的傳輸距離但若是要更遠距離的傳輸,因為線電阻造成的衰減,RS232並不適合遠距離傳輸。由於RS-485 可以將線長延伸到200M~500M 所以在工業界應用相當廣泛,單因為RS-485 只有一對絞線所以只能支援半雙工(就是同一時間只能做傳送或接收)。所以利用兩對信號的RS-422 也常被工業界所使用。http://focus.ti.com/lit/ds/symlink/sn75176a.pdf
在實務應用中,RS485,與RS422 終端電阻很重要,這個端終端電阻不但可以讓穩定電流回路,也有降低雜訊的能力。由時候此電阻也必須看整個BUS 的負載狀況加以調整。
2. CAN-BUS
Can bus 最早被應用在車用控制上,後來也被廣泛應用在工業控制上。最早支援的Can bus 的有Philips (NXP) SJA1000http://www.nxp.com/pip/SJA1000_3.html,目前也有很多MCU 以內建CAN bus interface.
3. Data Highway
Data highway 是CAN BUS 的延伸,只是走不同的通訊協定,傳輸接面是一樣的,常被應用在工業控制的PLC 中。
4. Camera Link
Camera Link 被應用在高速Line CCD 中,主要用於工業檢測。http://www.compumodules.com/pdf/CameraLinkOfficial.pdf
5. LVDS
並應用於LCD controller 與LCD panel 之間的傳輸介面。http://www.national.com/mpf/DS/DS90LV031A.html LVDS 傳送IC 內建了一個7 倍頻的PLL,當CLOCK input 為High 的時候送4 個bits 出去,當Clock input 為Low 的時候送3 個bits ,合計7 個bits。由於PLL 之後接收端無法同步這個新的Clock , 所以在LVDS 信號傳輸中,必須把CLOCK 也輸出到接收介面。
如果3 對LVDS 信號,合計可以傳送21bits , 在6bits Panel ( 18bits total in RGB) 加上LCD panel 的Hsync,Vsync,Data enable 。所以當要傳送24bits 信號時,則需要4 對LVDS 線及一對CLock 線,合計5 對線。
LVDS 介面由於將頻率產生7倍頻率,所以在速度上最高只能到85MHz ,如果要傳送1920x180P@60Hz 的信號必須使用兩組LVDS 介面才可以傳送。
6. DVI, HDMI
DVI 目前應用於VGA 卡 Monitor 的介面,由於傳統VGA 卡與Monitor 介面是Ananlog RGB 信號,以目前數位化的角度來看,VGA 卡做DAC 然後LCD monitor 再做ADC 反而效果更差,所以從VGA卡直接將新號輸出到monitor , 但因24bits 線材與效果不好所以採用類似LVDS 信號的方法將Pixel clock 做被頻,然後用串列的方式來傳輸,理論上倍的頻率越高,所能傳輸的資料量就越大,頻寬需求也越高。在DVI 信號中總計三對資料線,與一對Clock 線,合計四對線。
HDMI傳輸介面是DVI 介面的延伸,都是使用4 對線,唯一的差異就是HDMI 將Audio 也放到這資料中。
7. Ethernet
Ethernet 可以說是最早將差動信號應用在資料通訊上。在Ethernet 中使用兩對線,Tx+,Tx-,RX+,RX- 組合成全雙工。
2009年3月29日 星期日
AT91SAM9263 VGA output to Monitor
在工業控制的場合中,我們常需要Monitor 的輸出,來顯示使用者控制介面,
但因為AT91SAM9263EK 只有連接一片240x320 LCD Pnael,所以我們將LCD 介面的信號拉出來並接一個Video DAC 將LCD 信號轉換成Analog RGB 2的VGA 信號。

其實任何顯示裝置只要是利用掃瞄的方式,其基本的公式即為:
Pixel Clock = H total * V total * Frame Rate
其中 H total = H active + H sync width + H front porch + H back porch
V total =V active + V sync width + V front porch + V back porch
所以一般我們所看到640x480 即為active area (或View area) 其他的都是看不見的區域,那為什麼要這樣做呢,主要的原因在於傳統CRT 螢幕。因為利用電子束來掃瞄所以才會有同步的問題,也因此需要反馳的時間。
Blinking = H sync width + H front porch + H back porch
另一個名詞就是blinking , 當電子束反馳的時候我們不希望看到不該出現的電子束出現,通常我們會產生遮脈信號把輸出給關閉,這個信號我們也稱為Data Enable,真正要輸出的時候為High,其餘時間皆為Low.
但因為AT91SAM9263EK 只有連接一片240x320 LCD Pnael,所以我們將LCD 介面的信號拉出來並接一個Video DAC 將LCD 信號轉換成Analog RGB 2的VGA 信號。
其實任何顯示裝置只要是利用掃瞄的方式,其基本的公式即為:
Pixel Clock = H total * V total * Frame Rate
其中 H total = H active + H sync width + H front porch + H back porch
V total =V active + V sync width + V front porch + V back porch
所以一般我們所看到640x480 即為active area (或View area) 其他的都是看不見的區域,那為什麼要這樣做呢,主要的原因在於傳統CRT 螢幕。因為利用電子束來掃瞄所以才會有同步的問題,也因此需要反馳的時間。
Blinking = H sync width + H front porch + H back porch
另一個名詞就是blinking , 當電子束反馳的時候我們不希望看到不該出現的電子束出現,通常我們會產生遮脈信號把輸出給關閉,這個信號我們也稱為Data Enable,真正要輸出的時候為High,其餘時間皆為Low.
很多LCD panel 不需要Hsync 與 Vsync 單靠Data Enable 就可以正確解出Hsync 與Vsync, 而monitor 就沒有Data enable 只有Hsync 與Vsync。聰明的你也許會問,VGA 卡送出HV 時,由於Monitor 不知道位置,且sync 裡面還有 sync width,front porch, back porch, monitor 怎樣決定Active 的起使位置呢?而VESA 就是在規範這些,而大部分LCD monitor 也會有Auto 的機制來偵測畫面的起使位置。
在有些ASIC 中,LCD controller 通常會有一個獨立的PLL 來產生pixel Clock,與真正data 處理的頻率是不一致的,這當中會透過FIFO memory 來中介,所以我們不能認為只要設定好 active, sync width, front porch & back porch,就會得到所要的頻率,通常Pixel clock PLL 都必須設定一個接近的值,因為這樣的除法器通常會有除不盡的現象。
所以上面的公式就很重要,否則出來的換面部會正確!
Pixel Clock = H total * V total * Frame Rate.
在Embedded system 中,我們不需要向PC 可以支援不同的timing, 大部分我們只需要支援單一解析度或單一timing 就可以了!
參考一下這個Web Site 可以知道VESA timing 有哪些了。
http://tinyvga.com/vga-timing
VESA 是一個Monitor 的標準制訂協會,只要是VESA 制訂的timing 大部分monitor 都可以正確的顯示出來。
AT91SAM92的Display LCD controller 的Clock source 是來自於MCLK.
而MCK的頻率則由 Crystal 產生與PLLA做倍頻而來。由於此PLL頻率供給SDRAM re-flesh timing,且AT91SAM9263 最高的執行頻率為240MHz, 而MCLK 頻率的範圍為48~120MHz, 但在LCD Controller 模組也有一個除頻器,公式為:
Pixel Clock = MCLK/((CKVAL+1)*2)
所以我們可以視為此除法器只能支援/2, /4 或/6 ..
在AT91SAM9263EK 的Crystal是 16.36766MHz, 二在我們的板子上是18.432MHz. 所以PLL 的設定也有一些不一樣!
詳細改的地方如下:
1. BootStrap V1.11
#define CRYSTAL_18_432MHZ 1
//#define CRYSTAL_16_36766MHZ 1
#ifdef CRYSTAL_18_432MHZ
#define MASTER_CLOCK (237568000/2)
#define PLL_LOCK_TIMEOUT 1000000
#define PLLA_SETTINGS 0x2073FF09
#define PLLB_SETTINGS 0x10483F0E
( Bootstrap-v1.11/board/at91sam9263ek/dataflash/at92sam9263ek.h)
在有些ASIC 中,LCD controller 通常會有一個獨立的PLL 來產生pixel Clock,與真正data 處理的頻率是不一致的,這當中會透過FIFO memory 來中介,所以我們不能認為只要設定好 active, sync width, front porch & back porch,就會得到所要的頻率,通常Pixel clock PLL 都必須設定一個接近的值,因為這樣的除法器通常會有除不盡的現象。
所以上面的公式就很重要,否則出來的換面部會正確!
Pixel Clock = H total * V total * Frame Rate.
在Embedded system 中,我們不需要向PC 可以支援不同的timing, 大部分我們只需要支援單一解析度或單一timing 就可以了!
參考一下這個Web Site 可以知道VESA timing 有哪些了。
http://tinyvga.com/vga-timing
VESA 是一個Monitor 的標準制訂協會,只要是VESA 制訂的timing 大部分monitor 都可以正確的顯示出來。
AT91SAM92的Display LCD controller 的Clock source 是來自於MCLK.
而MCK的頻率則由 Crystal 產生與PLLA做倍頻而來。由於此PLL頻率供給SDRAM re-flesh timing,且AT91SAM9263 最高的執行頻率為240MHz, 而MCLK 頻率的範圍為48~120MHz, 但在LCD Controller 模組也有一個除頻器,公式為:
Pixel Clock = MCLK/((CKVAL+1)*2)
所以我們可以視為此除法器只能支援/2, /4 或/6 ..
在AT91SAM9263EK 的Crystal是 16.36766MHz, 二在我們的板子上是18.432MHz. 所以PLL 的設定也有一些不一樣!
詳細改的地方如下:
1. BootStrap V1.11
#define CRYSTAL_18_432MHZ 1
//#define CRYSTAL_16_36766MHZ 1
#ifdef CRYSTAL_18_432MHZ
#define MASTER_CLOCK (237568000/2)
#define PLL_LOCK_TIMEOUT 1000000
#define PLLA_SETTINGS 0x2073FF09
#define PLLB_SETTINGS 0x10483F0E
( Bootstrap-v1.11/board/at91sam9263ek/dataflash/at92sam9263ek.h)
PLLA 的設定為 73Hex 所以得到CPU Clock 為237.568MHz, 而Master Clock 為118.784MHz。所以我們把Master Clock 除四,就會得到 29.696MHz 的Pixel clock ,而pixel clock 的公式為 Pixel Clock = Master clock / (n+1).當然可們也可以選擇 n 為零,即除2, 但這時候,我們會選擇較高的master Clock 頻率,以得到比較好的Performance.
另外AT91SMA9263 支援兩個EBI Bus, 我們在EBI0 由SDRAM 及Flash 來使用,EBI1 我們加了一個SRAM 來當Display 的Frame Buffer 已經低系統對Memory 的頻寬,所以在BootStrap 我們必須把此SRAM Initial 完成,以讓U-Boot 可以使用此Memory.
void hw_init(void)
{
..
writel(readl(AT91C_BASE_CCFG + CCFG_EBI1CSA) (1 << color="#cc33cc">(Bootstrap-v1.11/board/at91sam9263ek/at92sam9263ek.c)
這裡改完之後,當U-boot Access 0x70000000位址時,9263 即會連結到此SRAM。
2. U-Boot1.3.4
改過BootStrap 之後,u-boot 還必須再改一次,U-boot 會再把一些所使用到的週邊重新再Initial 一次。第一步要先改的是Master clock 與CPU Clock:
#define AT91_MAIN_CLOCK 237568000 /* from 16.367 MHz crystal */
#define AT91_MASTER_CLOCK 118784000 /* peripheral = main / 2 */
(u-boot-1.3.4/include/configs/at91sam9263ek.h)
接下來要改的是 GPIO , 原本AT91sam9263 是連接LCD Panel, 所以要接Video DAC 到Monitor , 就必須有H(水平),V(垂直)sync(同步信號)。
static void at91sam9263ek_lcd_hw_init(void)
{
at91_set_A_periph(AT91_PIN_PC0, 0); /* LCDVSYNC */
at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
// For VGA output need to enable HV sync
// For some also need to enable some panel not necessory
at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
..
}
(u-boot-1.3.4/board/atmel/at91sam9263ek/at91sam9263ek.c)
在AT91SAM9263-EK 中,LCD controller 接了一片240x320 的LCD Panel,因其解析度小,所以所需的Frame Buffer 也不需要太大,所以使用Internal 的SRAM 80K 就可以當Frame buffer。Frame buffer 所需要的空間計算公式如下:
Frame buffer = Hwidth * Vheight * bpp
#ifdef Enable_EBI1_SRAM
gd->fb_base = 0x70000000;
#elseif
gd->fb_base = AT91SAM9263_SRAM0_BASE;
#endif
(u-boot-1.3.4/board/atmel/at91sam9263ek/at91sam9263ek.c)
所以我們把Frame buffer 設定在0x70000000 EBI1 的SRAM 上!當然你必須找一的地方把 Enable_EBI1_SRAM #define 成1 或直接改成 gd->fb_base = 0x70000000;
再來就是真正Panel timing的部分,為了得到比較好的執行效率我們把Master Clock 拉到比較高的地方(限制在48~120MHz)所以就沿用前面的Master Clock ,但是這個頻率並不是VESA Standard 的標準頻率,所以要是所接的是LCD monitor , 可能會有Jitter 產生(原因是我們DAC 的頻率,與LCD Monitor 的ADC sampling 的頻率不一致所產生,如果要真正解決這個問題可以依據VESA standard 的頻率來設定PLL 的頻率與Master Clock)
vidinfo_t panel_info = {
vl_col: 640,
vl_row: 480,
vl_clk: 29696000,
vl_sync: ATMEL_LCDC_INVFRAME_INVERTED,
vl_bpix: 3,
vl_tft: 1,
vl_hsync_len: 44,
vl_left_margin: 74,
vl_right_margin: 30,
vl_vsync_len: 2,
vl_upper_margin: 21,
vl_lower_margin: 0,
mmio: AT91SAM9263_LCDC_BASE,
};
(u-boot-1.3.4/board/atmel/at91sam9263ek/at91sam9263ek.c)

3. Linux 2.26.27
所以我們把Frame buffer 設定在0x70000000 EBI1 的SRAM 上!當然你必須找一的地方把 Enable_EBI1_SRAM #define 成1 或直接改成 gd->fb_base = 0x70000000;
再來就是真正Panel timing的部分,為了得到比較好的執行效率我們把Master Clock 拉到比較高的地方(限制在48~120MHz)所以就沿用前面的Master Clock ,但是這個頻率並不是VESA Standard 的標準頻率,所以要是所接的是LCD monitor , 可能會有Jitter 產生(原因是我們DAC 的頻率,與LCD Monitor 的ADC sampling 的頻率不一致所產生,如果要真正解決這個問題可以依據VESA standard 的頻率來設定PLL 的頻率與Master Clock)
vidinfo_t panel_info = {
vl_col: 640,
vl_row: 480,
vl_clk: 29696000,
vl_sync: ATMEL_LCDC_INVFRAME_INVERTED,
vl_bpix: 3,
vl_tft: 1,
vl_hsync_len: 44,
vl_left_margin: 74,
vl_right_margin: 30,
vl_vsync_len: 2,
vl_upper_margin: 21,
vl_lower_margin: 0,
mmio: AT91SAM9263_LCDC_BASE,
};
(u-boot-1.3.4/board/atmel/at91sam9263ek/at91sam9263ek.c)
3. Linux 2.26.27
static struct resource lcdc_resources[] = {
[0] = {.start = AT91SAM9263_LCDC_BASE,
.end = AT91SAM9263_LCDC_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,},
[1] = {.start = AT91SAM9263_ID_LCDC,
.end = AT91SAM9263_ID_LCDC,
.flags = IORESOURCE_IRQ,},
[2] = {.start = 0x70000000,
.end = 0x700BB800,
.flags = IORESOURCE_MEM,},};
(Linux-2.6.27/arch/march-at91/at91sam9263_device.c)
在LCD 的resource 加入Frame buffer 的resource,讓Linux kernel 可以使用 EBI1 上的SRAM 當Frame Buffer.
當然Kernel 在還是必須將 Vsync 的GPIO 設定一次,但是依據經驗不做也可以,因為U-boot 已經Initial 過了!
void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
{
if (!data)
return;
at91_set_A_periph(AT91_PIN_PC0, 0); /* LCDVSYNC */
at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
..
}
再把AT92SAM926EK 的PLL 在設定一次
static void __init ek_map_io(void)
{
/* Initialize processor: 16.367 MHz crystal */
/*at91sam9263_initialize(16367660);*/
/* Initialize processor: 18.432000 MHz crystal */
at91sam9263_initialize(18432000);
..
}
接下來就是Kernel LCD controller 真正timing 的部分,這裡的結構與U-boot 不太一樣,需要設定re-flesh rate, 其他的參數也與u-boot 相同!
static struct fb_videomode at91_tft_vga_modes[] = {
{
.name = "Monitor Output @75Hz ",
.refresh = 75,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(29696),
.left_margin = 74, .right_margin = 30,
.upper_margin = 21, .lower_margin = 0,
.hsync_len = 44, .vsync_len = 2,
.sync = FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED,
},
};
(Linux-2.6.27/arch/march-at91/board-sam9263ek.c)
Pixel Clock = H total * V total * Frame Rate.
Video 的公式很重要,但三個變數我們怎麼來訂定呢?
在一般的情況我們會先選定Frame rate , 通常我們會選擇60Hz timing, 因這為個timing 不管CRT,LCD 或LCD panel 都可以支援,然後Vtotal , 然後pixel clock 有了這三個參數,我們就可以得到H total。但是在這裡由於AT91SAM9263 的PLL 不是那麼好調,能選到的頻率還必須顧及UART baud rate與執行效率,所以我建議先選pixel Clock有可以接受的執行效率, 看接近哪一個timing, 就用那一個timing 來design ,這麼做會比較保險。
2009年3月19日 星期四
Digital Audio I2S & SPDIF
很多人對於Digital Audio 的介面總是搞不清楚,常常不知怎麼Debug ...
在Digital audio 的介面中常用的 I2S , SPDIF , Fiber Optical, Coaxial ...
在此我們把他們分為機器內與機器外:
1. 機器內:I2S
2. 機器外:SPDIF (有光纖與同軸兩種不同介面)。
I2S 是Philips 與Sony 制訂的規格,信號共有三條:
Bit Clock, Data it or Out, Word Strobe..
當我們對一個單音信號做ADC 轉換時,各位都知道有取樣頻率與解析度的問題,而根據取樣定理,取樣頻率必須大於信號變化頻率的兩倍,以人耳可以聽到20Hz~20KHz 而言,一般40Khz 的取樣頻率就可以得到接近不失真的取樣。在目前我們常用的取樣頻率大部分是44.1Khz , 及48Khz。
如果取樣頻率為48KHz, 則我們會在Word strob 量到48KHz , 因為Word Strobe 的High 代表右升到,Word 為LOW 時代表左聲道,所以假如我們要做左右聲道對調是,只要把Word Strobe 反向就可以了。早期ADC 轉換的IC 有些是16bits , 有些是18bits , 後來漸漸統一,最近的IC 大部分是20 bits .. 為了能向下相容所以大部分IC 會在每一個sample 送出32 bits 的空間,以解決bit 數不一的問題,但是這也帶來另一個問題,到底MSB,LSB 怎麼放的問題。在實際上我們建議實際去上定看看,聲音正常代表設定就正常。
在Debug I2S 時我們從上面我們就可以知道bit clock 為Word Strobe 的64 倍,data bit 如果有播放聲音則會呈現不規則狀態,只要確認信號上的Level 足夠就好了。
在I2S 有分Master 與Slave , 很多人也是搞不清此,以為ADC IC一定是Master , DAC IC 一定是Slave , 答案是錯的。大部分DAC 都是Slave 沒錯,但ADC 不見得一定工作在Master mode。有一個簡單的口訣,當Master 必須送出Word Strobe 及Bit Clock , Slave 的Bit clock ,及word strobe 一定必須設定成輸入。
既然I2S 是在機器內IC 與IC 之間的連接就會有取樣頻率不一樣的問題,ADC 工作於96KHz , DSP 工作於48Khz 這是很常見的,這個時候就必須要有SRC (Sampling Rate converter ) ,將96Khz 轉成48KHz , 這樣的SRC 也是有好壞的分別,如上96Khz 轉成48Khz , 最簡單的作法就是將96Khz 的資料丟掉一半,並將Word Strobe 除2 , 其實他們原本的48Khz 沒神麼兩樣,最好的當然是補償除2 囉!
SPDIF 介面將I2S 做一延伸,為了達簡單連接的的傳輸,所以他吧I2S 的data 做bi-phase 的調變,但基本去樣的原則跟I2S 是一樣的。
SPDIF interface 可以接收32K~192K frames/per second ..意似就是說一秒鐘傳32~192K 個聲音封包, 這個值跟audio I2S 的samling clock 是一樣的, 所以我們可以把spdif 的速度看成audio 的取樣速度。這個取樣頻率就等於I2S Word strobe 的頻率。
在I2S 中因為Word Strobe 有high/low , 所以可以知到是左聲道還是右聲道,但在SPDIF 內,則把每一個frame 分成兩個Sub-Frame, Sub-Frame1 & Sub-Frame 2,每一個Sub-frame 為32 bits ,
這32 bits 包含4bits 旗標, 20bits audio sample , 4 bits 輔助位元4bits 同步偵測位元。
V : Validity bit
U : User bit
C : Channel bit
P : Parity bit
這些flags 每秒會有192bits, 24bytes, 詳細可以參考附件。
另外因為SPDIF 經過bi-phase 的調變,所以用示波器並沒辦法問定的trigger, 可以用頻普分析儀,量到其中心頻率,依據bi-phase 的原理應該是Sampling rate 的兩倍頻率。
如果是48Khz 的sampling rate,則為48Khz * 64*2 = 6.144MHz ..
如果是192KHz 則為 192KHz *64*2 = 24.576MHz
... 不知道怎樣放附件....
Wolfson SPDIF receiver IC spec http://www.wolfsonmicro.com/products/WM8804/
Cirrus logic application note http://www.cirrus.com/en/pubs/appNote/an22.pdf
在Digital audio 的介面中常用的 I2S , SPDIF , Fiber Optical, Coaxial ...
在此我們把他們分為機器內與機器外:
1. 機器內:I2S
2. 機器外:SPDIF (有光纖與同軸兩種不同介面)。
I2S 是Philips 與Sony 制訂的規格,信號共有三條:
Bit Clock, Data it or Out, Word Strobe..
當我們對一個單音信號做ADC 轉換時,各位都知道有取樣頻率與解析度的問題,而根據取樣定理,取樣頻率必須大於信號變化頻率的兩倍,以人耳可以聽到20Hz~20KHz 而言,一般40Khz 的取樣頻率就可以得到接近不失真的取樣。在目前我們常用的取樣頻率大部分是44.1Khz , 及48Khz。
如果取樣頻率為48KHz, 則我們會在Word strob 量到48KHz , 因為Word Strobe 的High 代表右升到,Word 為LOW 時代表左聲道,所以假如我們要做左右聲道對調是,只要把Word Strobe 反向就可以了。早期ADC 轉換的IC 有些是16bits , 有些是18bits , 後來漸漸統一,最近的IC 大部分是20 bits .. 為了能向下相容所以大部分IC 會在每一個sample 送出32 bits 的空間,以解決bit 數不一的問題,但是這也帶來另一個問題,到底MSB,LSB 怎麼放的問題。在實際上我們建議實際去上定看看,聲音正常代表設定就正常。
在Debug I2S 時我們從上面我們就可以知道bit clock 為Word Strobe 的64 倍,data bit 如果有播放聲音則會呈現不規則狀態,只要確認信號上的Level 足夠就好了。
在I2S 有分Master 與Slave , 很多人也是搞不清此,以為ADC IC一定是Master , DAC IC 一定是Slave , 答案是錯的。大部分DAC 都是Slave 沒錯,但ADC 不見得一定工作在Master mode。有一個簡單的口訣,當Master 必須送出Word Strobe 及Bit Clock , Slave 的Bit clock ,及word strobe 一定必須設定成輸入。
既然I2S 是在機器內IC 與IC 之間的連接就會有取樣頻率不一樣的問題,ADC 工作於96KHz , DSP 工作於48Khz 這是很常見的,這個時候就必須要有SRC (Sampling Rate converter ) ,將96Khz 轉成48KHz , 這樣的SRC 也是有好壞的分別,如上96Khz 轉成48Khz , 最簡單的作法就是將96Khz 的資料丟掉一半,並將Word Strobe 除2 , 其實他們原本的48Khz 沒神麼兩樣,最好的當然是補償除2 囉!
SPDIF 介面將I2S 做一延伸,為了達簡單連接的的傳輸,所以他吧I2S 的data 做bi-phase 的調變,但基本去樣的原則跟I2S 是一樣的。
SPDIF interface 可以接收32K~192K frames/per second ..意似就是說一秒鐘傳32~192K 個聲音封包, 這個值跟audio I2S 的samling clock 是一樣的, 所以我們可以把spdif 的速度看成audio 的取樣速度。這個取樣頻率就等於I2S Word strobe 的頻率。
在I2S 中因為Word Strobe 有high/low , 所以可以知到是左聲道還是右聲道,但在SPDIF 內,則把每一個frame 分成兩個Sub-Frame, Sub-Frame1 & Sub-Frame 2,每一個Sub-frame 為32 bits ,
這32 bits 包含4bits 旗標, 20bits audio sample , 4 bits 輔助位元4bits 同步偵測位元。
V : Validity bit
U : User bit
C : Channel bit
P : Parity bit
這些flags 每秒會有192bits, 24bytes, 詳細可以參考附件。
另外因為SPDIF 經過bi-phase 的調變,所以用示波器並沒辦法問定的trigger, 可以用頻普分析儀,量到其中心頻率,依據bi-phase 的原理應該是Sampling rate 的兩倍頻率。
如果是48Khz 的sampling rate,則為48Khz * 64*2 = 6.144MHz ..
如果是192KHz 則為 192KHz *64*2 = 24.576MHz
... 不知道怎樣放附件....
Wolfson SPDIF receiver IC spec http://www.wolfsonmicro.com/products/WM8804/
Cirrus logic application note http://www.cirrus.com/en/pubs/appNote/an22.pdf
2009年3月10日 星期二
QT4.5 嘗鮮
1. 下載QT 4.5 for embedded Linux http://www.qtsoftware.com/downloads/embedded-linux-cpp
2. 利用Winscp 複製到Linux 你所建立的root system source code.
3. tar -zxvf qt-embedded-linux-opensource-src-4.5.0.tarqt-embedded-linux-opensource-src-4.5.0.tar
4. cd qt-embedded-linux-opensource-src-4.5.0.tar
5. 檢查一下 qt-embedded-linux-opensource-src-4.5.0.tar/mkspecs/qws/linux-arm-g++/qmake.conf 是不是你所使用的tool chain.
6. ./configure -xplatform qws/linux-arm-g++ -embedded arm -qt-zlib -prefix /qt4 -no-rpath -depths 16,15 -qt-mouse-tslib -I /usr/atmel/arm9.busybox/src/tslib-1.0/install/include -L /usr/atmel/arm9.busybox/src/tslib-1.0/install/lib
重點:利用qt 內的zlib 不要自己編zlib, 16代表支援565 的色盤,15 代表支援555的色盤。
7.make
我用E8400 跑3.2G編了45分鐘左右所以耐心等候。
8. make install
這個也需2~3 分鐘....
9.完成後在/qt4 會有此目錄
10. cd demos/mainwindow
利用arm-linux-objdump -p mainwindow 查詢main 所需的動態Library
NEEDED libQtGui.so.4
NEEDED libts-0.0.so.0
NEEDED libpng12.so.0
NEEDED libQtNetwork.so.4
NEEDED libQtCore.so.4
NEEDED librt.so.1
NEEDED libdl.so.2
NEEDED libpthread.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
在所編譯完成qt4/lib 下,將以上的檔案複製到root file system 目錄下的Library. 並使用連結的方式連結到此library.例如:我們可以複製LibQtCore.so.4.5.0 到目錄下,然後
ln -s libQtCore.so.4.5.0 libQtCore.so.4.0
2. 利用Winscp 複製到Linux 你所建立的root system source code.
3. tar -zxvf qt-embedded-linux-opensource-src-4.5.0.tarqt-embedded-linux-opensource-src-4.5.0.tar
4. cd qt-embedded-linux-opensource-src-4.5.0.tar
5. 檢查一下 qt-embedded-linux-opensource-src-4.5.0.tar/mkspecs/qws/linux-arm-g++/qmake.conf 是不是你所使用的tool chain.
6. ./configure -xplatform qws/linux-arm-g++ -embedded arm -qt-zlib -prefix /qt4 -no-rpath -depths 16,15 -qt-mouse-tslib -I /usr/atmel/arm9.busybox/src/tslib-1.0/install/include -L /usr/atmel/arm9.busybox/src/tslib-1.0/install/lib
重點:利用qt 內的zlib 不要自己編zlib, 16代表支援565 的色盤,15 代表支援555的色盤。
7.make
我用E8400 跑3.2G編了45分鐘左右所以耐心等候。
8. make install
這個也需2~3 分鐘....
9.完成後在/qt4 會有此目錄
10. cd demos/mainwindow
利用arm-linux-objdump -p mainwindow 查詢main 所需的動態Library
NEEDED libQtGui.so.4
NEEDED libts-0.0.so.0
NEEDED libpng12.so.0
NEEDED libQtNetwork.so.4
NEEDED libQtCore.so.4
NEEDED librt.so.1
NEEDED libdl.so.2
NEEDED libpthread.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libgcc_s.so.1
NEEDED libc.so.6
在所編譯完成qt4/lib 下,將以上的檔案複製到root file system 目錄下的Library. 並使用連結的方式連結到此library.例如:我們可以複製LibQtCore.so.4.5.0 到目錄下,然後
ln -s libQtCore.so.4.5.0 libQtCore.so.4.0
11. 在/install 目錄下建立/qt4 的目錄,並建立/qt4/bin, 與/qt4/lib
12. 將/qt4/demos/下的執行檔複製到 /install/qt4/bin, 將所需的library 複製到/install/qt4/lib
13. 在/install/qt4/lib/ 建立fonts 目錄,複製c0419bt_.pfb,DejaVuSans-Oblique.ttf到此目錄.
11 重新將root system 包裝成Jffs2 ..
11 重新將root system 包裝成Jffs2 ..
13. mkfs.jffs2 -n -p -s 0x200 -e 0x4000 -r install/ -o rootfsts.jffs2
0x200 是 page size, 0x4000 是 erase block size.
0x200 是 page size, 0x4000 是 erase block size.
2009年3月8日 星期日
NT9263 與 tslib porint 的問題點
1. share library 的問題:
當初我開始build root system 時因為沒注意shared library 與static library 的問題,所以一直弄不出來,每次都是kernel panic .., 後來我把build 成static library 就開成,那時候真的很高興。
後來就沒有去注意這件事。但當我把tslib build 完之後, 去發現我的ts_calibrate 怎麼都不會變成綠色,也不能執行,每次都出現command not found ...
在google 上也找了很久,好像也沒有發生這樣的問題,真是 ...為神麼學長build 出來的就能跑我build 出來就不能跑難道....
後來我吧busybox 又重新builde 了一次shared library ,tslib 就可以正常跑起來了。
2. 當ts_calibrate 跑起來之後問題又來了,執行時出現Segamentation fault , 然後網路上也沒正解,後來找了好久找到了一篇, 才發現原來是我雞婆在/etc 建立了一個pointercal 的目錄,
拿掉之後就可以正常執行了。
3. ts_calibrate 可以執行後,發現怎麼怎麼ts_calibrate 沒有等我按就五點跑完了,看起來是tslib 收到了不該收到的東西。ts_test,ts_print 也都不正常。也是找了好久才發現原來event 1 要跟input 1 對應,原本的程式都是對應到event0, 及mknod event0 c 13 64 ..
看了一下kernel 的文件才發現,65 才是對應到event 1, ts_calibrate ,ts_test .. 都是event0 , 所以都必須修改,鼻子摸著,重來一次...
4.這次真的可以執行了,ts_calibrate 的游標停在第一點但是完全不bird 我,不管我輕輕按或用力按就是無動於衷,搞了一個通宵之後,把示波器也搬出來了看一下ADS7843 輸出的波形,奇怪照公板抄怎麼就是不會動。
5. 想了另一個辦法,下載Atmel software package , 還好新的V1.5 有支援touch Screen .. 把他改到我的板子上去。結果還是一樣,都是卡在第一點,ADS7843E的PenIRQ 固定都會產生兩個pulse , 整個信號一直有ground 的產生, 真是忍無可忍,把touch panel 的connector 拆掉....然後再是一次。
6. 說也奇怪,整個touch panel 的動作正常了,真是圈圈叉叉...
下次真該improve 一下,我的焊接技術...
TSLib 在 AT91SAM9263 的Porting
在NT9263 的板子上跟AT91SAM9263-EK 的板子一樣都有一個ADS7843E 來做觸控螢幕的ADC 轉換,ADS7843E 再透過SPI interface 連接到AT91SAM9263.
1. 首先下載最新的tslib 從http://tslib.berlios.de/。
2. 在 tslib tar 到你要工作的目錄中(通常是target root source 的子目錄)..
3. 檢查一下Fedora 或ubuntu 系統是否已經安裝了libtool, 及automake
在Fedroa9 下 用yum install libtool, yum install automake
在ubuntu 下用 apt-get install libtool, apt-get install automake
4. 執行 sh autogen.sh
5. $./configure --prefix=$PWD/install CC=arm-linux-gcc --host=arm-linux
這時會產生rpl_malloc未定義的錯誤
6. $./configure --prefix=$PWD/install CC=arm-linux-gcc --host=arm-linuxac_cv_func_malloc_0_nonnull=yes
7. 檢查一下Kernel 系統是否已經將ads7846 driver 選上了,及 Event drive 也開啟了,
若要能成功驅動觸控螢幕,必須確定兩者都選上。若一切都正確linux kernel 會送出如下的字串:
----------------------------------------------
input: gpio-keys as /class/input/input0 ( 這是one 不是o)
ads7846 spi0.3: touchscreen, irq 31
input: ADS784x Touchscreen as /class/input/input1
------------------------------------------------------
搜尋 /test 目錄下的ts_calibrate ,ts_test, test_print,ts_print_raw,ts_harvest 內的event0 的字串,並將其修改成event1, 因為kernel 已經將touch screen 設定成 input1, 如果你的系統是input 2, 你必須改成event2.(這裡很重要,網路上大部分都沒有提到這個)
7. make
8. make install
9. 編譯完成後會自動產生/install 的目錄,我們必須將其複製到系統跟目錄中
bin/ : ts_calibrate, ts_test等校正、測試程式
lib/ : tslib的動態與靜態library
lib/ts/: tslib外加支援的touch screen module
etc/ : tslib的configuration file
10. 建立驅動程式節點
在跟目錄系統 /dev 下建立/input 目錄 mkdir input
並在/input 下 建立一個device 節點 mknod event1 c 13 65 (表示char , input 型的device Driver,
64 代表input 0, 65代表input 1, 這個數字也必須參考linux kenel document 才可以得知)。
11. 修改ts.conf 並複製到系統跟目錄中 /etc 下。
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
12. 修該/etc/rc.d/rc.init 讓 system 可以在開機後自動執行tslib
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_FBDEVICE=/dev/fb0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib
要特別注意,pointercal 是會自動產生的程式,不需事先建立,事先建立的話會產生Segamentation fault.
13. 使用arm-linux-objdump 來看ts_calibrate,ts_test.. 所使用到的動態連結程式庫,
有些版本可能與你用的版本可能不合,可以使用ln 來做連結會比較解省記憶體:
compiler 之後 :libts-0.0.so.0.1.1
我們用 ln -s libts-0.0.so.0.1.1 libts-0.0.so.0
ln -s libts-0.0.so.0.1.1 libts.so
14. 最後將整個root system 打包成ext2 或Jffs2 都可以!大功告成。
最後要感謝學長助教的幫忙,各位也可以參考他的大作:
http://nabeko-notebook.blogspot.com/
1. 首先下載最新的tslib 從http://tslib.berlios.de/。
2. 在 tslib tar 到你要工作的目錄中(通常是target root source 的子目錄)..
3. 檢查一下Fedora 或ubuntu 系統是否已經安裝了libtool, 及automake
在Fedroa9 下 用yum install libtool, yum install automake
在ubuntu 下用 apt-get install libtool, apt-get install automake
4. 執行 sh autogen.sh
5. $./configure --prefix=$PWD/install CC=arm-linux-gcc --host=arm-linux
這時會產生rpl_malloc未定義的錯誤
6. $./configure --prefix=$PWD/install CC=arm-linux-gcc --host=arm-linuxac_cv_func_malloc_0_nonnull=yes
7. 檢查一下Kernel 系統是否已經將ads7846 driver 選上了,及 Event drive 也開啟了,
若要能成功驅動觸控螢幕,必須確定兩者都選上。若一切都正確linux kernel 會送出如下的字串:
----------------------------------------------
input: gpio-keys as /class/input/input0 ( 這是one 不是o)
ads7846 spi0.3: touchscreen, irq 31
input: ADS784x Touchscreen as /class/input/input1
------------------------------------------------------
搜尋 /test 目錄下的ts_calibrate ,ts_test, test_print,ts_print_raw,ts_harvest 內的event0 的字串,並將其修改成event1, 因為kernel 已經將touch screen 設定成 input1, 如果你的系統是input 2, 你必須改成event2.(這裡很重要,網路上大部分都沒有提到這個)
7. make
8. make install
9. 編譯完成後會自動產生/install 的目錄,我們必須將其複製到系統跟目錄中
bin/ : ts_calibrate, ts_test等校正、測試程式
lib/ : tslib的動態與靜態library
lib/ts/: tslib外加支援的touch screen module
etc/ : tslib的configuration file
10. 建立驅動程式節點
在跟目錄系統 /dev 下建立/input 目錄 mkdir input
並在/input 下 建立一個device 節點 mknod event1 c 13 65 (表示char , input 型的device Driver,
64 代表input 0, 65代表input 1, 這個數字也必須參考linux kenel document 才可以得知)。
11. 修改ts.conf 並複製到系統跟目錄中 /etc 下。
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
12. 修該/etc/rc.d/rc.init 讓 system 可以在開機後自動執行tslib
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_FBDEVICE=/dev/fb0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib
要特別注意,pointercal 是會自動產生的程式,不需事先建立,事先建立的話會產生Segamentation fault.
13. 使用arm-linux-objdump 來看ts_calibrate,ts_test.. 所使用到的動態連結程式庫,
有些版本可能與你用的版本可能不合,可以使用ln 來做連結會比較解省記憶體:
compiler 之後 :libts-0.0.so.0.1.1
我們用 ln -s libts-0.0.so.0.1.1 libts-0.0.so.0
ln -s libts-0.0.so.0.1.1 libts.so
14. 最後將整個root system 打包成ext2 或Jffs2 都可以!大功告成。
最後要感謝學長助教的幫忙,各位也可以參考他的大作:
http://nabeko-notebook.blogspot.com/
訂閱:
文章 (Atom)