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 of ROWS> of Columns>   format required 565/24>

使用图片编辑器生成所需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)

重新测试,显示的图片完全正确。

你可能感兴趣的:(BSP)