在工業控制的場合中,我們常需要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 ,這麼做會比較保險。
改回來正常的年齡了!不然大家會以為你是65歲的老南人耶!
回覆刪除希望你的部落格能持續經營下去, 也期待看到你的下一篇作品出現...
這是一項有全球化事業的商機,
回覆刪除而且潛力無窮,任何人都可以去從事。
現在只要在家工作,越早加入就能越早贏得改變人生的機會。
請先免費 註冊體驗12周:
網址登入:
http://joe80411.weebly.com/
祝~天天都是有美好的一天˙快樂與您同在