首页 > 其他分享 >TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示

TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示

时间:2023-02-01 22:36:57浏览次数:43  
标签:TQ2440 lcd LCD lcdenv CONFIG 移植 define


TQ2440移植u-boot2016.11-LCD驱动移植并显示


LCD初始化流程分析

u-boot的LCD初始化代码是在common/lcd.c中,我们找到​lcd_init​函数:

TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示_#define


该函数功能流程为:lcd_ctrl_init初始化了LCD的硬件参数---->开辟LCD的帧缓冲(缓冲基地址保存在了​gd->fs_base​变量中)—>清屏—>使能LCD—>设置LCD控制台参数

lcd_ctrl_init​lcd_enable​函数是u-boot抽离出的函数接口,需要根据LCD的实际情况进行底层硬件的初始化操作实现这两个函数;除此之外还需要定义一个名为​panel_info​​vidinfo_t​结构类型变量,该结构变量保存了LCD屏幕的大小和颜色位深,用于LCD屏幕的控制台显示。


LCD驱动移植

我的屏幕是W43,分辨率480x272,驱动编写参考的TQ2440官方的LCD屏幕驱动代码修改而来。

添加LCD的相关配置宏:
​​​gedit include/configs/tq2440.h​

末尾添加如下代码:

/*
* LCD configuration
*/
#define CONFIG_LCD /* 该宏用于添加进LCD相关的编译项 */
#define LCD_BPP LCD_COLOR16 /* 每像素为16bits */
#define CONFIG_LCD_LOGO /* 显示LOGO */
#define CONFIG_LCD_INFO /* 显示用户自定义信息 */
#define CONFIG_LCD_INFO_BELOW_LOGO /* 用户自定义信息与LOGO的位置无关 */
#define CONFIG_SYS_WHITE_ON_BLACK /* 黑底白字 */
#define CONFIG_SYS_CONSOLE_IS_IN_ENV /* 控制台接收自环境变量 */
#define CONFIG_CONSOLE_MUX /* 定义该宏可支持将打印信息同时输出到串口和LCD */
#define CONFIG_CONSOLE_SCROLL_LINES 16 /* 屏幕显示总行数 */

/* 以下三个宏为我自己定义的 */
#define CONFIG_TQ2440_LCD /* 该宏用于将tq2440_lcd.c文件编译进来 */
#define LCD_XSIZE_TFT 480 /* LCD行数 */
#define LCD_YSIZE_TFT 272 /* LCD列数 */

#define MVAL 13
#define MVAL_USED 0 /* 0:each frame 1:rate by MVAL */
#define INVVDEN 1 /* 0:normal 1:inverted */
#define BSWP 0 /* byte swap control */
#define HWSWP 1 /* half word swap control */

#define CONFIG_TQ2440_LCD_VBPD 1
#define CONFIG_TQ2440_LCD_VFPD 1
#define CONFIG_TQ2440_LCD_VSPW 9
#define CONFIG_TQ2440_LCD_HBPD 1
#define CONFIG_TQ2440_LCD_HFPD 1
#define CONFIG_TQ2440_LCD_HSPW 40
#define CONFIG_TQ2440_LCD_CLKVAL 4

添加tq2440的LCD文件:

​gedit drivers/video/tq2440_lcd.c​

粘贴进如下代码:

#include <common.h>
#include <lcd.h>
#include <asm/system.h>
#include <asm/gpio.h>
#include <asm/arch/s3c24x0_cpu.h>
#include <lcd.h>
#include <version.h>

DECLARE_GLOBAL_DATA_PTR; /* 导入gd_t结构变量gd */

/* to get lower 21bits */
#define M5D(n) ((n) & 0x1FFFFF)

vidinfo_t panel_info =
{
.vl_col = LCD_XSIZE_TFT, /* 列数 */
.vl_row = LCD_YSIZE_TFT, /* 行数 */
.vl_bpix = LCD_BPP, /* 像素位数为16bits,该宏在tq2440.h中被定义 */
};

/* 将LCD缓冲数组转为二维数组来用 */
#define tq2440_lcd_frame_pbuf ((volatile unsigned short (*)[LCD_XSIZE_TFT])(gd->fb_base))

void tq2440_lcd_clear_screen(unsigned short color)
{
int x = 0, y = 0;

for (y = 0; y < LCD_YSIZE_TFT; y++)
{
for (x = 0; x < LCD_XSIZE_TFT; x++)
{
tq2440_lcd_frame_pbuf[y][x] = color;
}
}
}

void lcd_ctrl_init(void* lcdbase)
{
char vbpd = 0;
char vfpd = 0;
char vspw = 0;
char hbpd = 0;
char hfpd = 0;
char hspw = 0;
char clkval = 0;
char* lcdenv = NULL;
struct s3c24x0_gpio* const gpio = s3c24x0_get_base_gpio();
struct s3c24x0_lcd* const lcd = s3c24x0_get_base_lcd();

/* set lcd frame buffer start adddress */
lcd->lcdsaddr1 = (((unsigned int)tq2440_lcd_frame_pbuf >> 22) << 21) | M5D((unsigned int)tq2440_lcd_frame_pbuf >> 1);

/* set lcd frame buffer end adddress */
lcd->lcdsaddr2 = M5D(((unsigned int)tq2440_lcd_frame_pbuf + (LCD_XSIZE_TFT * LCD_YSIZE_TFT * 2)) >> 1);

/* set virtul screen page wigth */
lcd->lcdsaddr3 = (((LCD_XSIZE_TFT - LCD_XSIZE_TFT) / 1) << 11) | (LCD_XSIZE_TFT / 1);

lcdenv = getenv("dwVBPD");
vbpd = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_VBPD;

lcdenv = getenv("dwVFPD");
vfpd = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_VFPD;

lcdenv = getenv("dwVSPW");
vspw = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_VSPW;

lcdenv = getenv("dwHBPD");
hbpd = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_HBPD;

lcdenv = getenv("dwHFPD");
hfpd = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_HFPD;

lcdenv = getenv("dwHSPW");
hspw = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_HSPW;

lcdenv = getenv("dwCLKVAL");
clkval = lcdenv ? (int)simple_strtol(lcdenv, NULL, 10) : CONFIG_TQ2440_LCD_CLKVAL;

/* clear screen */
tq2440_lcd_clear_screen(0x0000);

/* initialize VD[7:0] */
gpio->gpcup = 0xFFFFFFFF;
gpio->gpccon = 0xAAAAAAAA;

/* initialize VD[15:8] */
gpio->gpdup = 0xFFFFFFFF;
gpio->gpdcon = 0xAAAAAAAA;

/* lcd config */
lcd->lcdcon1 = (clkval << 8) | (MVAL_USED << 7) | (3 << 5) | (12 << 1) | 0;
lcd->lcdcon2 = (vbpd << 24) | ((LCD_YSIZE_TFT - 1) << 14) | (vfpd << 6) | vspw;
lcd->lcdcon3 = (hbpd << 19) | ((LCD_XSIZE_TFT - 1) << 8) | hfpd;
lcd->lcdcon4 = (MVAL << 8) | hspw;
lcd->lcdcon5 = (1 << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 7) | (0 << 6) | (1 << 3) | (BSWP << 1) | HWSWP;

/* make lcd sub interrupt */
lcd->lcdintmsk |= 0x3;

/* disable lpc3480 */
lcd->lpcsel &= ~(0x7);

/* disbale temp palette */
lcd->tpal = 0x0;

/* disable gpg4 pull-up */
gpio->gpgup &= ~(1 << 4);

/* set gpg4 mode to lcd_pwrdn */
gpio->gpgcon |= 3 << 8;

/* set gpg4 to high */
gpio->gpgdat |= 1 << 4;

/* enable pwren signal */
lcd->lcdcon5 |= 1 << 3;

/* set signal polarity to normal */
lcd->lcdcon5 &= ~(1 << 5);
}

void lcd_enable(void)
{
struct s3c24x0_lcd* const lcd = s3c24x0_get_base_lcd();

/* Enable the video output and the LCD control signal. */
lcd->lcdcon1 |= (1 << 0);
}

#ifdef CONFIG_LCD_INFO
void lcd_show_board_info(void)
{
lcd_printf("%s (%s - %s)\n", U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME);
}
#endif

添加进编译项:
​​​gedit drivers/video/Makefile​

末尾添加一行:

obj-$(CONFIG_TQ2440_LCD) += tq2440_lcd.o

测试

编译后使用tftp下载到内存0x30008000处并运行程序,查看效果:

TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示_#define_02


下面操作将输出信息重定向到LCD上显示:使用以下命令查看可以将输出信息重定向到哪些设备:

​coninfo​

TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示_#include_03


可以看到可以将输出信息重定向到串口和LCD,serial就是我们使用的串口一,标志为IO,也就是说可以输入输出,LCD为.O,也就是说只能输出不能输入。

将输出信息同时重定向到LCD和串口一:

​setenv stdout 'lcd,serial'​

TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示_#include_04


TQ2440移植u-boot2016.11全过程记录-【4】LCD驱动移植并显示_#include_05


ends…


标签:TQ2440,lcd,LCD,lcdenv,CONFIG,移植,define
From: https://blog.51cto.com/u_15950551/6031933

相关文章