当前位置: 首页 > news >正文

i.MX 6ULL 驱动开发 十九:RGBLCD

一、RGBLCD 硬件原理

【正点原子MP157连载】第十八章 RGB LCD彩条显示实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7_正点原子的博客-CSDN博客

ATK7016 时序参数:
在这里插入图片描述

二、eLCDIF 接口

eLCDIFI.MX6U 自带的液晶屏幕接口,用于连接 RGB LCD 接口的屏幕。

三、Linux 下 LCD 驱动分析

1、LCD 操作流程

1、初始化 I.MX6UeLCDIF 控制器,重点是 LCD 屏幕宽(width)、高(height)、 hspwhbphfpvspwvbpvfp 等信息。

2、初始化 LCD 像素时钟。

3、设置 RGBLCD 显存。

4、应用程序直接通过操作显存来操作 LCD,实现在 LCD 上显示字符、图片等信息。

2、Framebuffer 设备

Linux 内核中使用 Framebuffer 提供统一的标准接口显示设备。Framebuffer 翻译过来就是帧缓冲,简称 fbfb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个 fb 设备,当我们编写好 LCD 驱动以后会生成一个名为 /dev/fbX(X=0~n) 的设备,应用程序通过访问 /dev/fbX 这个设备就可以访问 LCD

NXP 官方的 Linux 内核默认已经开启了 LCD 驱动,因此我们是可以看到 /dev/fb0 这样一个设备,如下所示:

# ls -l /dev/fb0
crw-rw----    1 root     root       29,   0 Jan  1 00:00 /dev/fb0
#

/dev/fb0 就是 LCD 对应的设备文件, /dev/fb0 是个字符设备,fbfile_operations 操作集定义在 drivers/video/fbdev/core/fbmem.c 文件中。

3、驱动分析

1、通过设备树确定驱动文件

设备树信息如下:

// 文件路径:linux-imx-4.1.15\arch\arm\boot\dts\imx6ull.dtsi

lcdif: lcdif@021c8000 {
    compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
    reg = <0x021c8000 0x4000>;
    interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
         <&clks IMX6UL_CLK_LCDIF_APB>,
         <&clks IMX6UL_CLK_DUMMY>;
    clock-names = "pix", "axi", "disp_axi";
    status = "disabled";
};

通过 fsl,imx6ul-lcdiffsl,imx28-lcdif 查找驱动文件,驱动文件路径:linux-imx-4.1.15\drivers\video\fbdev\mxsfb.c

驱动分析待完成……。

四、重要结构体

1、fb_info

struct fb_info {
	atomic_t count;
	int node;
	int flags;
	struct mutex lock;		/* Lock for open/release/ioctl funcs */
	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
	struct fb_var_screeninfo var;	/* Current var */
	struct fb_fix_screeninfo fix;	/* Current fix */
	struct fb_monspecs monspecs;	/* Current Monitor specs */
	struct work_struct queue;	/* Framebuffer event queue */
	struct fb_pixmap pixmap;	/* Image hardware mapper */
	struct fb_pixmap sprite;	/* Cursor hardware mapper */
	struct fb_cmap cmap;		/* Current cmap */
	struct list_head modelist;      /* mode list */
	struct fb_videomode *mode;	/* current mode */

#ifdef CONFIG_FB_BACKLIGHT
	/* assigned backlight device */
	/* set before framebuffer registration, 
	   remove after unregister */
	struct backlight_device *bl_dev;

	/* Backlight level curve */
	struct mutex bl_curve_mutex;	
	u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	struct delayed_work deferred_work;
	struct fb_deferred_io *fbdefio;
#endif

	struct fb_ops *fbops;
	struct device *device;		/* This is the parent */
	struct device *dev;		/* This is this fb device */
	int class_flag;                    /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
	char __iomem *screen_base;	/* Virtual address */
	unsigned long screen_size;	/* Amount of ioremapped VRAM or 0 */ 
	void *pseudo_palette;		/* Fake palette of 16 colors */ 
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;			/* Hardware state i.e suspend */
	void *fbcon_par;                /* fbcon use-only private area */
	/* From here on everything is device dependent */
	void *par;
	/* we need the PCI or similar aperture base/size not
	   smem_start/size as smem_start may just be an object
	   allocated inside the aperture so may not actually overlap */
	struct apertures_struct {
		unsigned int count;
		struct aperture {
			resource_size_t base;
			resource_size_t size;
		} ranges[0];
	} *apertures;

	bool skip_vt_switch; /* no VT switch on suspend/resume required */
};

2、mxsfb_info

struct mxsfb_info {
	struct fb_info *fb_info;
	struct platform_device *pdev;
	struct clk *clk_pix;
	struct clk *clk_axi;
	struct clk *clk_disp_axi;
	bool clk_pix_enabled;
	bool clk_axi_enabled;
	bool clk_disp_axi_enabled;
	void __iomem *base;	/* registers */
	u32 sync;		/* record display timing polarities */
	unsigned allocated_size;
	int enabled;
	unsigned ld_intf_width;
	unsigned dotclk_delay;
	const struct mxsfb_devdata *devdata;
	struct regulator *reg_lcd;
	bool wait4vsync;
	struct completion vsync_complete;
	struct completion flip_complete;
	int cur_blank;
	int restore_blank;
	char disp_dev[32];
	struct mxc_dispdrv_handle *dispdrv;
	int id;
	struct fb_var_screeninfo var;
};

五、设备树添加

1、设备树添加说明

Linux 驱动开发 六十二:《mxsfb.txt》翻译_lqonlylove的博客-CSDN博客

Linux 驱动开发 六十三:《display-timing.txt》翻译_lqonlylove的博客-CSDN博客

2、添加设备树

lcdif 节点中追加或修改 LCD 时序相关参数,如题内容如下:

lcdif: lcdif@021c8000 {
    compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
    reg = <0x021c8000 0x4000>;
    interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
         <&clks IMX6UL_CLK_LCDIF_APB>,
         <&clks IMX6UL_CLK_DUMMY>;
    clock-names = "pix", "axi", "disp_axi";
    status = "disabled";
};

&lcdif {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_lcdif_dat
		     &pinctrl_lcdif_ctrl>;

	display = <&display0>;
	status = "okay";

	/* 7寸1024*600 */
	display0: display {
		bits-per-pixel = <32>;	// RGB值(RGB888/666)
		bus-width = <24>;		// 数据线数量

		display-timings {
			native-mode = <&timing0>;
			timing0: timing0 {
			clock-frequency = <51200000>;	// 时钟配置
			hactive = <1024>;				// 水平像素点
			vactive = <600>;				// 垂直像素点
			hfront-porch = <160>;			// HFP 配置
			hback-porch = <140>;			// HBP 配置
			hsync-len = <20>;				// HSPW 配置
			vback-porch = <20>;				// VBP 配置
			vfront-porch = <12>;			// VFP 配置
			vsync-len = <3>;				// VSPW 配置

			hsync-active = <0>;				// HSYNC 信号有效电平
			vsync-active = <0>;				// VSYNC 信号有效电平
			de-active = <1>;				// DE 信号有效电平
			pixelclk-active = <0>;			// 数据更新和数据采样有效电平
			};
		};
	};
};

六、LCD 背光配置

1、确定LCD背光使用的 PIN 引脚

通过原理图确定背光使用的 PIN 引脚。LCD 使用引脚为 BLT_PWMGPIO1_IO08)。LCD 背光使用 PWM 驱动。

2、设备树配置

pinctrl_pwm1: pwm1grp {
	fsl,pins = <
		MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
	>;
};

pwm1: pwm@02080000 {
	compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
	reg = <0x02080000 0x4000>;
	interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&clks IMX6UL_CLK_PWM1>,
		 <&clks IMX6UL_CLK_PWM1>;
	clock-names = "ipg", "per";
	#pwm-cells = <2>;
};

&pwm1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_pwm1>;
	status = "okay";
};

backlight {
	compatible = "pwm-backlight";
	pwms = <&pwm1 0 5000000>;
	brightness-levels = <0 4 8 16 32 64 128 255>;
	default-brightness-level = <7>;
	status = "okay";
};

3、Linux 中相关说明

Linux 驱动开发 六十四:《pwm-backlight.txt》翻译_lqonlylove的博客-CSDN博客

七、特别说明

LCD 驱动 Linux 内核已经写好,我们只需要按照硬件参数配置设备树即可使用。

八、LCD 熄屏关闭

Linuxdrivers/tty/vt/vt.c 源码中配置 LCD 熄屏时间,配置项 static int blankinterval = 10*60 配置 LCD 熄屏时间,将 blankinterval 设置为 0,表示 LCD 常亮。

相关文章:

  • 前端谷歌浏览器基本介绍及前后端分离原理分析
  • Day12-尚品汇-trade静态组件
  • 十大排序算法(java实现万字详解)
  • Qt文档阅读笔记-Hello Speak Example
  • 【Golang开发面经】知乎(两轮技术面)
  • 1024程序员节:从关注自身健康开始
  • 负载均衡式在线OJ
  • SQL注入天书笔记(1)布尔盲注
  • 【2022集创赛】安谋科技杯一等奖作品:Cortex-M0智能娱乐收音机
  • python3-python中的多任务处理利器-协程的使用(一),asyncio模块的使用
  • vue06安装vue-cli+使用vue-cli搭建项目+什么是*.vue文件+开发示例+必问面试知识点
  • chrome盗取用户身份
  • 队列(Queue)的详解
  • 快速发布windows上的web项目【免费内网穿透】
  • 【C++笔试强训】第十一天
  • 【译】理解JavaScript:new 关键字
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • cookie和session
  • interface和setter,getter
  • Java的Interrupt与线程中断
  • java第三方包学习之lombok
  • JSONP原理
  • learning koa2.x
  • Linux Process Manage
  • Python学习之路16-使用API
  • tweak 支持第三方库
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 力扣(LeetCode)21
  • 配置 PM2 实现代码自动发布
  • 扑朔迷离的属性和特性【彻底弄清】
  • 用element的upload组件实现多图片上传和压缩
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • 整理一些计算机基础知识!
  • ​linux启动进程的方式
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (javascript)再说document.body.scrollTop的使用问题
  • (层次遍历)104. 二叉树的最大深度
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四) 虚拟摄像头vivi体验
  • (推荐)叮当——中文语音对话机器人
  • (一)WLAN定义和基本架构转
  • (转载)CentOS查看系统信息|CentOS查看命令
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • **CI中自动类加载的用法总结
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net core webapi 大文件上传到wwwroot文件夹
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET 发展历程
  • .NET 反射 Reflect