第二十一节 添加LCD 驱动

如果使用我们提供的系统,默认情况下开启了LCD 驱动。LCD 跑起来还需要添加相应的设备节点。如何添加设备树插件以及如何修改LCD 常用配置参数。

LCD 常用参数介绍

LCD 配置参数主要包括LCD 引脚相关配置和LCD 显示参数配置。其中背光控制引脚是独立出来的,修改背光引脚的同时也要修改对应的PWM 设备信息。

LCD 引脚

设备树插件中使用到的引脚。

列表1: lcd 引脚

fragment@3 {
	target=<&pinctrl>;
	__overlay__{
		lcd_backlight_pins_a: lcd-backlight {
			pins {
				pinmux = <STM32_PINMUX('A', 15, AF1)>; /* TIM2_CH1 */
				bias-pull-down;
				drive-push-pull;
				slew-rate = <0>;
			};
	};

	lcd_backlight_sleep_pins_a: lcd-backlight-sleep {
		pins {
			pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* TIM2_CH1 */
		};
	};

	ltdc_pins_a: ltdc-a-0 {
		pins {
			pinmux = <STM32_PINMUX('G', 7, AF14)>, /* LCD_CLK */
					<STM32_PINMUX('I', 10, AF14)>, /* LCD_HSYNC */
					<STM32_PINMUX('I', 9, AF14)>, /* LCD_VSYNC */
					<STM32_PINMUX('E', 13, AF14)>, /* LCD_DE */
					<STM32_PINMUX('H', 2, AF14)>, /* LCD_R0 */
					<STM32_PINMUX('H', 3, AF14)>, /* LCD_R1 */
					<STM32_PINMUX('H', 8, AF14)>, /* LCD_R2 */
					<STM32_PINMUX('B', 0, AF9)>, /* LCD_R3 */
					<STM32_PINMUX('A', 5, AF14)>, /* LCD_R4 */
					<STM32_PINMUX('C', 0, AF14)>, /* LCD_R5 */
					<STM32_PINMUX('H', 12, AF14)>, /* LCD_R6 */
					<STM32_PINMUX('E', 15, AF14)>, /* LCD_R7 */
					<STM32_PINMUX('E', 14, AF13)>, /* LCD_G0 */
					<STM32_PINMUX('E', 6, AF14)>, /* LCD_G1 */
					<STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
					<STM32_PINMUX('H', 14, AF14)>, /* LCD_G3 */
					<STM32_PINMUX('H', 15, AF14)>, /* LCD_G4 */
					<STM32_PINMUX('I', 0, AF14)>, /* LCD_G5 */
					<STM32_PINMUX('I', 1, AF14)>, /* LCD_G6 */
					<STM32_PINMUX('I', 2, AF14)>, /* LCD_G7 */
					<STM32_PINMUX('D', 9, AF14)>, /* LCD_B0 */
					<STM32_PINMUX('G', 12, AF14)>, /* LCD_B1 */
					<STM32_PINMUX('G', 10, AF14)>, /* LCD_B2 */
					<STM32_PINMUX('D', 10, AF14)>, /* LCD_B3 */
					<STM32_PINMUX('I', 4, AF14)>, /* LCD_B4 */
					<STM32_PINMUX('A', 3, AF14)>, /* LCD_B5 */
					<STM32_PINMUX('B', 8, AF14)>, /* LCD_B6 */
					<STM32_PINMUX('D', 8, AF14)>; /* LCD_B7 */
			bias-disable;
			drive-push-pull;
			slew-rate = <1>;
		};
	};

	ltdc_pins_sleep_a: ltdc-a-1 {
		pins {
			pinmux = <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_CLK */
					<STM32_PINMUX('I', 10, ANALOG)>, /* LCD_HSYNC */
					<STM32_PINMUX('I', 9, ANALOG)>, /* LCD_VSYNC */
					<STM32_PINMUX('E', 13, ANALOG)>, /* LCD_DE */
					<STM32_PINMUX('H', 2, ANALOG)>, /* LCD_R0 */
					<STM32_PINMUX('H', 3, ANALOG)>, /* LCD_R1 */
					<STM32_PINMUX('H', 8, ANALOG)>, /* LCD_R2 */
					<STM32_PINMUX('B', 0, ANALOG)>, /* LCD_R3 */
					<STM32_PINMUX('A', 5, ANALOG)>, /* LCD_R4 */
					<STM32_PINMUX('C', 0, ANALOG)>, /* LCD_R5 */
					<STM32_PINMUX('H', 12, ANALOG)>, /* LCD_R6 */
					<STM32_PINMUX('E', 15, ANALOG)>, /* LCD_R7 */
					<STM32_PINMUX('E', 14, ANALOG)>, /* LCD_G0 */
					<STM32_PINMUX('E', 6, ANALOG)>, /* LCD_G1 */
					<STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
					<STM32_PINMUX('H', 14, ANALOG)>, /* LCD_G3 */
					<STM32_PINMUX('H', 15, ANALOG)>, /* LCD_G4 */
					<STM32_PINMUX('I', 0, ANALOG)>, /* LCD_G5 */
					<STM32_PINMUX('I', 1, ANALOG)>, /* LCD_G6 */
					<STM32_PINMUX('I', 2, ANALOG)>, /* LCD_G7 */
					<STM32_PINMUX('D', 9, ANALOG)>, /* LCD_B0 */
					<STM32_PINMUX('G', 12, ANALOG)>, /* LCD_B1 */
					<STM32_PINMUX('G', 10, ANALOG)>, /* LCD_B2 */
					<STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B3 */
					<STM32_PINMUX('I', 4, ANALOG)>, /* LCD_B4 */
					<STM32_PINMUX('A', 3, ANALOG)>, /* LCD_B5 */
					<STM32_PINMUX('B', 8, ANALOG)>, /* LCD_B6 */
					<STM32_PINMUX('D', 8, ANALOG)>; /* LCD_B7 */
			};
		};
	};
};

如果修改了LCD 显示屏的引脚,需要在这里修改对应的引脚。

列表2: lcd 背光pwm 设置

fragment@1 {
	target-path="/";
	__overlay__{
		lcd-backlight {
			compatible = "pwm-backlight";
			pwms = <&pwm2 0 1000000>;
			brightness-levels = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100>;
			default-brightness-level = <90>;
			status = "okay";
		};
	};
};

fragment@2 {
	target=<&timers2>;
	__overlay__{
		/* spare dmas for other usage */
		/delete-property/dmas;
		/delete-property/dma-names;
		status = "okay";
		pwm2: pwm {
			pinctrl-0 = <&lcd_backlight_pins_a>;
			pinctrl-1 = <&lcd_backlight_sleep_pins_a>;
			pinctrl-names = "default", "sleep";
			#pwm-cells = <2>;
			status = "okay";
		};
		timer@1 {
			status = "okay";
		};
	};
};

背光引脚被复用为PWM 的输出,如果修改了背光引脚也要在这里修改使用的pwm。

LCD 属性设置

通常情况我们参考官方开发板设计硬件LCD 使用的引脚和官方一致即可。我们经常要修改的是LCD 一些配置参数,例如分辨率、时钟、无效行数。

列表3: lcd 配置参数

/*-------第一组---------*/
clock-frequency = <27000000>;
hactive = <800>;
vactive = <480>;

/*-------第二组---------*/
hfront-porch = <23>;
hback-porch = <46>;
vback-porch = <22>;
vfront-porch = <22>;

/*-------第三组---------*/
hsync-len = <1>;
vsync-len = <1>;

/*-------第四组---------*/
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;

配置参数可分为四组,第一组是设置分辨率和时钟。第二组设置“可视区域”,它们的缩写就是我们常说的HFP、hbp、vbp、vfp、行同步信号到第一个像素点的延时时间,单位(像素),一行的最后一个像素点到下一个行同步信号的延时时间(单位像素),帧同步信号到第一个有效行之间的时间,最后一行到下一个帧同步信号之间的时间。第三组,设置行同步信号和帧同步信号的脉宽。第四组,设置行同步信号、帧同步信号、数据信号、像素时钟信号的极性。以上内容要根据自己使用的显示屏说明文档配置。

由于野火的LCD 设备树以设备树插件的形式提供,我们可以使用file-config 软件配置屏幕参数。参考《fire-config 修改液晶参数》

测试程序

驱动已经编译进内核中,设备树插件加载成功后,驱动会生成“/dev/fb0”文件,这个文件就是
显示屏的设备节点文件。

测试程序通过读、写这个文件测试显示是否正常。

源码位于“linux_driver/add_lcd_device_tree/test_app”。

测试程序仅针对5 寸800*480 分辨率的显示屏,其他分辨率会出现显示异常及程序异常结束的情况。

进入源码目录,执行“make”命令可编译出测试代码,上传到开发板,使用chmod 添加执行权限后执行即可。


参考资料:嵌入式Linux 驱动开发实战指南-基于STM32MP1 系列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值