AM335x u-boot啓動添加開機圖片

問題

AM335X的SDK u-boot中沒有提供開機logo功能。當設備上電後會有幾秒鐘LCD上無任何輸出,影響用戶體驗。爲此需要在u-boot增加開機畫面功能,使得設備上電後LCD能夠儘可能快地輸出圖片信息。
編譯調試版本和環境:
主機: ubuntu 12.04
SDK:
u-boot:
LCD:分辨率800x480, Linux驅動已經調試正常, 在Linux中能夠正確顯示圖片。

解決步驟

1,通過google能夠很容易找到以下資料:
(1)
https://e2e.ti.com/support/arm/sitara_arm/f/791/p/217383/849350#pi316653=2
下載4578.lcd.tar.gz
(2)
https://e2e.ti.com/support/arm/sitara_arm/f/791/t/217383#pi316653=4
下載其中的6114.lcd.zip。

2,LCD驅動編譯。

按照上述網頁的辦法首先移植4578.lcd.tar.gz。拷貝文件到boot/drivers/lcd,修改Makefile,發現該壓縮包文件對應的u-boot版本可能較低。對比一下其中Makefile的寫法和u-boot下drivers的其他目錄(例如driver/led)的Makefile,發現區別比較大。
嘗試修改Makefile後,還是有很多其他編譯錯誤。
故暫時放棄之。

選擇6114.lcd.zip,拷貝文件到u-boot下,編譯,出現錯誤, 指示函數Lcd_Init()中沒有定義image1。這是因爲壓縮包中沒有image.h文件。從第一個壓縮包4578.lcd.tar.gz中拷貝image.h文件到u-boot/drivers/lcd目錄下,然後編譯。結果無編譯錯誤。
將新的u-boot下載到SD卡,上電後發現LCD顯示出了圖片,但是圖片不正常(閃爍錯位)。
初步認定是LCD的寄存器參數不正常。
因爲已經有了圖片輸出,因此決定在6114.lcd.zip壓縮包的基礎上調試自己的LCD開機畫面。

3, 製作開機畫面文件和image.h文件

在步驟2中,爲了測試編譯,我們使用的是一個臨時image.h文件。我們需要製作自己的開機圖片文件。

下載並安裝AM335X_StarterWare_02_00_01_01
或者直接從以下網頁下載:https://github.com/embest-tech/AM335X_StarterWare_02_00_01_01/tree/master/tools/bmpToRaster
刪除文件BitmapReader.h中的

#define COMPRESS

然後直接make即可得到可執行文件a.out:

Steps For Getting the header file:

Step 1: Build the application using 'make' command
$make

Step 2: Get .h file from a .bmp file.
$./a.out <No.of ROWS> <No.of Columns> <Source File Name> <Destination File name> <image format required 565/24><pixel odering RGB/BGR>

使用圖片編輯器生成所需bmp文件Logo_SET800680_for_u-boot.bmp, 並與a.out拷貝到同一個文件夾下然後:

 ./a.out 800 480 ./Logo_SET800680_for_u-boot.bmp image.h 24 RGB

即可獲得image.h文件。
這個文件還不能直接使用。需要修改數組名:

-unsigned int const image[] = {

+#ifndef CONFIG_SPL_BUILD
+unsigned int const image1[] __attribute__((aligned(4)))= {
...
+endif;

重新編譯並下載u-boot到SD卡,圖片內容已經變成自己的logo,不過圖片依然不正常(閃爍錯位)。

4,修改LCD參數

正常調試u-boot的LCD驅動時,需要根據LCD顯示屏的參數來修改CPU LCD控制器的參數。
因爲本人已經在Linux中調試過LCD驅動,參考上述兩個網頁中其他人的經驗,在這裏可以使用比較暴力的辦法:
正常啓動設備到Linux中,使用devmem2工具讀出所有LCD相關的寄存器值(排除狀態寄存器),然後在u-boot中將這些值直接賦值給相關寄存器即可。
附上寄存器參數值的修改部分代碼:

/*
** Configures raster to display image 
*/
static void SetUpLCD(void)
{
    /* Enable clock for LCD Module */ 
    LCDModuleClkConfig();

    LCDPinMuxSetup();

    /* 
    **Clock for DMA,LIDD and for Core(which encompasses
    ** Raster Active Matrix and Passive Matrix logic) 
    ** enabled.
    */
    RasterClocksEnable(SOC_LCDC_0_REGS);

    /* Disable raster */
    RasterDisable(SOC_LCDC_0_REGS);
#if 0    
    /* Configure the pclk */
    //RasterClkConfig(SOC_LCDC_0_REGS, 32000000, 192000000);
//    RasterClkConfig(SOC_LCDC_0_REGS, 30000000, 240000000);
    HWREG(SOC_LCDC_0_REGS + LCDC_LCD_CTRL) = 0x00000201u;



    /* Configuring DMA of LCD controller */ 
   // RasterDMAConfig(SOC_LCDC_0_REGS, RASTER_DOUBLE_FRAME_BUFFER,
    //                RASTER_BURST_SIZE_16, RASTER_FIFO_THRESHOLD_8,
    //                RASTER_BIG_ENDIAN_DISABLE);
     HWREG(SOC_LCDC_0_REGS + LCDC_LCDDMA_CTRL) = 0x40u;


    /* Configuring modes(ex:tft or stn,color or monochrome etc) for raster controller */
   // RasterModeConfig(SOC_LCDC_0_REGS, RASTER_DISPLAY_MODE_TFT_UNPACKED,
    //                 RASTER_PALETTE_DATA, RASTER_COLOR, RASTER_RIGHT_ALIGNED);
    HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_CTRL) = 0x06200081u;


     /* Configuring the polarity of timing parameters of raster controller */
    /* RasterTiming2Configure(SOC_LCDC_0_REGS, RASTER_FRAME_CLOCK_LOW |
                                            RASTER_LINE_CLOCK_LOW  |
                                            RASTER_PIXEL_CLOCK_HIGH|
                                            RASTER_SYNC_EDGE_RISING|
                                            RASTER_SYNC_CTRL_ACTIVE|
                                            RASTER_AC_BIAS_HIGH     , 0, 255);
     */
    // RasterTiming2Configure(SOC_LCDC_0_REGS, RASTER_FRAME_CLOCK_LOW |
      //                                      RASTER_LINE_CLOCK_LOW  |
        //                                    RASTER_PIXEL_CLOCK_HIGH|
          //                                  RASTER_SYNC_EDGE_RISING|
            //                                RASTER_SYNC_CTRL_ACTIVE|
              //                              RASTER_AC_BIAS_LOW     , 0, 255);
     HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_TIMING_2) |= 0x02B0FF00u;

    /* Configuring horizontal timing parameter */
//    RasterHparamConfig(SOC_LCDC_0_REGS, 800, 47, 39, 39);
    //RasterHparamConfig(SOC_LCDC_0_REGS, 800, 47, 214, 42);
    HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_TIMING_0) = 0x29D50F10u; 

    /* Configuring vertical timing parameters */
    //RasterVparamConfig(SOC_LCDC_0_REGS, 480, 2, 13, 29);
    //RasterVparamConfig(SOC_LCDC_0_REGS, 480, 45, 25, 20);
    HWREG(SOC_LCDC_0_REGS + LCDC_RASTER_TIMING_1) = 0x14190DDFu;

    //RasterFIFODMADelayConfig(SOC_LCDC_0_REGS, 128);
#endif

*(volatile unsigned int *)0x4830e004= 0x00000201;
*(volatile unsigned int *)0x4830e00c= 0x00000000;
*(volatile unsigned int *)0x4830e010= 0x00440044;
*(volatile unsigned int *)0x4830e014= 0x00000000; 
*(volatile unsigned int *)0x4830e018= 0x00000000;
*(volatile unsigned int *)0x4830e01c= 0x00440044;
*(volatile unsigned int *)0x4830e020= 0x00000000;
*(volatile unsigned int *)0x4830e024= 0x00000000;
*(volatile unsigned int *)0x4830e028= 0x06200080;
*(volatile unsigned int *)0x4830e02c= 0x29D50F10;
*(volatile unsigned int *)0x4830e030= 0x14190DDF;
*(volatile unsigned int *)0x4830e034= 0x02B0FF00;
*(volatile unsigned int *)0x4830e038= 0x00000000;
*(volatile unsigned int *)0x4830e03c= 0x00000000;
*(volatile unsigned int *)0x4830e040= 0x00000040;
*(volatile unsigned int *)0x4830e044= 0x9eB00000;
*(volatile unsigned int *)0x4830e048= 0x9EC77000;
*(volatile unsigned int *)0x4830e04c= 0x00000000;
*(volatile unsigned int *)0x4830e050= 0x00000000;
*(volatile unsigned int *)0x4830e054= 0x00000014;
//*(volatile unsigned int *)0x4830e058= 
//*(volatile unsigned int *)0x4830e05c= 
*(volatile unsigned int *)0x4830e064= 0x00000325;
*(volatile unsigned int *)0x4830e060= 0x00000325;
*(volatile unsigned int *)0x4830e06c= 0x00000007;
*(volatile unsigned int *)0x4830e070= 0x00000000;
}

測試後,發現,圖片顯示有很大改善,但是還是不正常。圖片中均勻分佈着有一些橫線。
使用示波器測試LCD的像素時鐘,發現竟然達到120 MHz,而本人的設定是30 MHz。

5.,其他幾個重要寄存器

因爲時鐘不正常,查看文檔後發現,除了上述LCD控制器本身的寄存器以外, 還有幾個和LCD相關的寄存器:
CM_CLKMODE_DPLL_DISP 0x44E00498
CM_CLKSEL_DPLL_DISP 0x44E00454
CM_DIV_M2 0x44E004A4
CLKSEL_LCDC_PIXEL_CLK 0x44E00534
對比u-boot和Linux下他們的值發現是CM_DIV_M2的值設置的不對。
在u-boot中是0x201,而在Linux下是0x224.
對比手冊中寄存器的描述,發現時鐘剛好是4倍的關係。
在u-boot中修改宏

#define CM_DIV_M2_DPLL_DISP_DIV   (0x4u)

重新測試,顯示的圖片完全正確。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章