【f1c200s笔记五】点亮屏幕

一、总述

1、做过单片机的小伙伴都知道,想要点亮屏幕,首先是对屏幕做初始化,然后把显示数据传入屏幕,就可以控制屏幕显示了,当然这只是简单描述。

2、实际在控制屏幕的过程中,首先是对屏幕这个外部设备进行初始化,比如扫描方式、行列数目,前后门廊啊等等,当然大部分情况下是供应商直接提供的初始化代码。其次是要对单片机的外设接口进行初始化,外设接口是要和屏幕链接的,其中的扫描方式、行列数目等等是有相当一部分需要和屏幕上的参数一一对应。最后,是把显示数据写入到屏幕里面。

3、类比到Linux,无非也是这三个步骤,对屏幕做初始化,对外设接口初始化,然后是数据写入。只是和单片机上直接初始化不同的是,嵌入式linux的设备和驱动是分离的。

4、设备在设备树体现,驱动是附在linux源码中的。设备树体现了各个设备之间的拓补关系,添加和删除设备可以直接在设备树文件上进行修改。驱动虽然附在Linux源码中,但是需要通过配置菜单进行“加载”。linux开机的时候,会读取设备树,根据设备的相关标签,搜索支持的驱动,并初始化相关的设备。

5、所以第一步,修改设备树添加设备。

二、设备树修改

1、f1c200s有一般的屏幕驱动接口,既然有接口,首先是申请io,打开路径/usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot/dts下的设备树文件suniv-f1c100s.dtsi,在pio节点下添加

			lcd_rgb666_pins: lcd-rgb666-pins {  //分号前是给节点起的别名,分号后是节点的名称。首先是申请RGB驱动的引脚
				pins = "PD0", "PD1", "PD2", "PD3", "PD4",
				       "PD5", "PD6", "PD7", "PD8", "PD9",
				       "PD10", "PD11", "PD12", "PD13", "PD14",
				       "PD15", "PD16", "PD17", "PD18", "PD19",
				       "PD20", "PD21";
				function = "lcd";
			};

申请完io,接下来在soc节点下添加屏驱的节点

		tcon0: lcd-controller@1c0c000 {  //添加显示驱动的节点,即RGB驱动,@后面是设备的物理地址。
			compatible = "allwinner,sun4i-a10-tcon";  //linux5.7.1内,已经没有f1c200s的相关支持,但是实测使用a10型号的驱动依然可用
			reg = <0x01c0c000 0x1000>;  //寄存器地址
			interrupts = <29>;  //中断号,是根据f1c200s手册查询得到的
			clocks = <&ccu CLK_BUS_LCD>,  //这里引用了外部宏定义,所以要添加对应的头文件,默认已经添加过了
				 <&ccu CLK_TCON>,
				 <&osc24M>;	/* Still unknown */
			clock-names = "ahb",
				      "tcon-ch0",
				      "tcon-ch1";
			clock-output-names = "tcon-pixel-clock";
			resets = <&ccu RST_BUS_LCD>;  //指定复位单元
			reset-names = "lcd";  //复位单元名称?
			status = "disabled";  //先禁用设备

			ports {  //port是管道,或者说端口,设备间的数据通过管道传输。
				#address-cells = <1>;  //设置子节点的地址占用大小
				#size-cells = <0>;  //设置子节点寄存器尺寸描述占用大小

				tcon0_in: port@0 {  //port管道端口0是输入口
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <0>;

					tcon0_in_be0: endpoint@0 {  //port管道端口0的对端口为be0_out_tcon0
						reg = <0>;
						remote-endpoint = <&be0_out_tcon0>;
					};
				};

				tcon0_out: port@1 {  //port管道端口1是输出口
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <1>;
				};
			};
		};

2、tcon就是屏驱的设备名称(节点名称)。它的数据来源可以是SDRAM,也可以是be显示后端处理。be显示后端处理是f1c200s的一个功能外设,是专门对图片进行叠加运算的单元。所以接下来是在soc节点下,添加be设备节点

		be0: display-backend@1e60000 {  //be0是显示后端处理,显示后端处理主要针对图片叠加
			compatible = "allwinner,sun4i-a10-display-backend";
			reg = <0x01e60000 0x10000>;
			reg-names = "be";
			interrupts = <31>;
			clocks = <&ccu CLK_BUS_DE_BE>, <&ccu CLK_DE_BE>,
				 <&ccu CLK_DRAM_DE_BE>;
			clock-names = "ahb", "mod",
				      "ram";
			resets = <&ccu RST_BUS_DE_BE>;
			reset-names = "be";
			assigned-clocks = <&ccu CLK_DE_BE>;
			assigned-clock-rates = <300000000>;

			ports {  //be0也是拥有两个端口
				#address-cells = <1>;
				#size-cells = <0>;

				be0_in: port@0 {  //be0管道端口0的对端是fe0_out_be0
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <0>;

					be0_in_fe0: endpoint@0 {
						reg = <0>;
						remote-endpoint = <&fe0_out_be0>;
					};
				};

				be0_out: port@1 {  //be0管道端口1的对端是tcon0_in_be0
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <1>;

					be0_out_tcon0: endpoint@0 {
						reg = <0>;
						remote-endpoint = <&tcon0_in_be0>;
					};
				};
			};
		};

3、be的数据来源同样可以是SDRAM,但也可以是fe显示前端处理,fe显示前端处理是专门对图片进行缩放的mcu外设。于是还要在soc节点下添加fe设备节点。

		fe0: display-frontend@1e00000 {  //fe0是显示前端处理,显示前端主要针对图片的缩放。
			compatible = "allwinner,sun4i-a10-display-frontend";  //这里也是借用a10的驱动
			reg = <0x01e00000 0x20000>;
			interrupts = <30>;
			clocks = <&ccu CLK_BUS_DE_FE>, <&ccu CLK_DE_FE>,
				 <&ccu CLK_DRAM_DE_FE>;
			clock-names = "ahb", "mod",
				      "ram";
			resets = <&ccu RST_BUS_DE_FE>;
			status = "disabled";

			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				fe0_out: port@1 {  //fe0管道端口1是输出口,其对端口为be0_in_fe0
					#address-cells = <1>;
					#size-cells = <0>;
					reg = <1>;

					fe0_out_be0: endpoint@0 {
						reg = <0>;
						remote-endpoint = <&be0_in_fe0>;
					};
				};
			};
		};

4、当然不能忘记配置显示引擎总开关,在根节点下添加de(显示引擎)设备。

	de: display-engine {
		compatible = "allwinner,sun4i-a10-display-engine";
		allwinner,pipelines = <&fe0>;
		status = "disabled";
	};

因为在设备树里使用了a10相关的宏定义,所以还不能忘记在文件开头的位置添加相关头文件

#include <dt-bindings/dma/sun4i-a10.h>

保存退出,文件suniv-f1c100s.dtsi就修改完了。

5、总结上述并忽略SDRAM的影响,那么数据在屏驱上的流向是,SDRAM->fe->be->tcon。如果再忽略tcon的物理层面上操作液晶的意义,并且把显示屏抽象为一个面板设备panel,那么数据在linux主机上的流向就变成了SDRAM->fe->be->tcon->panel ,这就是几个设备间管道的链接关系。

6、panel的设备节点需要在文件usr/local/f1c200s/kernel/linux-5.7.1/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts内添加。打开文件并在根节点下添加

	panel: panel {  //面板设备节点
		compatible = "ampire,am-480272h3tmqw-t01h", "simple-panel";  //这里是套用了现成的驱动,驱动型号需要根据具体的显示屏进行修改
		#address-cells = <1>;
		#size-cells = <0>;
		enable-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>;  //指定背光脚位,引用了函数,所以需要添加宏定义

		port@0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;

			panel_input: endpoint@0 {  //panel作为驱动tft的设备,数据来源只有一处,就是tcon的输出,也是通过管道获取
				reg = <0>;
				remote-endpoint = <&tcon0_out_lcd>;
			};
		};
	};

7、然后在根节点之外,也就是文件末尾添加几个设备的状态变更

&de {  //启动显示处理功能
	status = "okay";
};
&tcon0 {  //启动tcon
	pinctrl-names = "default";
	pinctrl-0 = <&lcd_rgb666_pins>;
	status = "okay";
};

&tcon0_out {  //接通管道
	tcon0_out_lcd: endpoint@0 {
		reg = <0>;
		remote-endpoint = <&panel_input>;
	};
};

8、最后在文件开头添加头文件。保存并退出。就完成了所有的设备树编辑。

#include <dt-bindings/gpio/gpio.h>

三、配置菜单

1、配置好设备树,就需要在配置菜单处,把panel的驱动打开,也就是屏幕设备的相关驱动。

首先执行make menuconfig进入配置菜单,依次选择Device Drivers > Graphics support > Display Panels,然后把光标移动到support for simple panels,点击空格键直到<>中出现*,也就是打开simple panels功能。

2、因为博主的液晶是裸屏面板,所以不需要对屏幕初始化,于是就选择support for simple panels,小伙伴们选择的时候根据自己的设备进行选择。并且在2.6节,对panel设备节点进行配置的时候,compatible项目也要根据对应的设备进行修改,甚至需要修改对应的驱动文件。

3、做完这些,驱动层已经支持了显示,但是应用层还没有调用,所以可以临时打开logo进行验证。

在make menuconfig中,依次选择Device Drivers > Graphics support,光标移动到最下面Bootup logo的位置,按空格选中即可打开logo。

3、最后,保存退出,执行make,然后把生成的zImage和suniv-f1c100s-licheepi-nano.dtb复制到u盘的boot分区,上电就可以看到屏幕左上角的小企鹅啦。

博客内容均系原创,未经允许严禁转载!

评论

  1. 4 天前
    2024-12-07 20:31:51

    设备的物理地址如何得知?

    • 博主
      OTREE
      4 天前
      2024-12-08 8:02:00

      设备地址,可以通过数据手册获得

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇