一、概述
前段時間看到B站大佬稚暉君發佈的B站小電視,心中無限崇拜,剛好手中有一塊NanoPi-NEO開發板和一塊ST7735S的128X128TFT屏幕,近期又學了朱有鵬老師的嵌入式核心課程,剛好拿這個來練練手!
項目涉及到kernel配置、DTB設備樹、fbtft屏驅動修改移植,驅動模塊自動加載、屏幕調試。
二、準備工作
1、64bit Linux系統,我用的是VMware+ubuntu 16.4 。
2、嵌入式開發板,我用的是NanoPi-NEO,全志H3芯片,256M RAM。
3、TFT屏一塊,我用的是ST7735S,128X128分辨率。
4、網線一根、數據線一根,5V 2A電源一個(一定要2A以上)。
三、開始幹活
1、搭建開發環境
開發環境的搭建、BSP包下載及編譯參照全志H2/H3 Linux Mainline介紹及下載,需要關心的是,全志原廠BSP和Linux Mainline的區別,全志BSP沒有涉及到設備樹,而Linux Mainline不僅用到了設備樹,而且在uboot配置都採用類似kernel那樣的圖形界面,之前用全志原廠BSP,資料比較少,走了很多彎路,所以現在使用的是Linux Mainline。
2、修改設備樹文件
在linux/arch/arm/boot/dts目錄下,目錄中有很多dts文件和dtsi文件,找到sun8i-h3-nanopi.dtsi,由於nanopi 引出了spi0的引腳,所以我們在spi0節點下添加 fbtft相關代碼(matrix: matrix@0),同時disable其他spi0設備:
&spi0 {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
pinctrl-names = "default";
//pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
pinctrl-0 = <&spi0_pins &spi0_cs_pins>;//<&spi0_pins &spi0_cs_pins>
cs-gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;//<&pio 2 3 GPIO_ACTIVE_HIGH>, <&pio 0 6 GPIO_ACTIVE_HIGH>;
spidev0: spi@0 {
compatible = "nanopi,spidev";
reg = <0>;
status = "disabled";
spi-max-frequency = <10000000>;
};
matrix: matrix@0{
compatible = "fa,st7735s";
reg = <0>;
status = "okay";
spi-max-frequency = <32000000>;
fps = <33>;
rotate = <90>;
buswidth = <8>;
dc-gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */
reset-gpios = <&pio 0 3 GPIO_ACTIVE_HIGH>; /* PA3 */
led-gpios = <&pio 0 1 GPIO_ACTIVE_HIGH>; /* PA1 */
debug = <0x0>;
};
}
根據代碼中的cs-gpios = <&pio 6 9 GPIO_ACTIVE_HIGH>;推斷spi的cs引腳爲PG9(A B C D…對應0 1 2 3 4…),修改文件中的IO配置
&pio {
leds_npi: led_pins {
pins = "PA10";
function = "gpio_out";
};
spi0_cs_pins: spi0_cs_pins {
//pins = "PC3", "PA6";
pins = "PG9";
function = "gpio_out";
};
};
關閉HDMI,否則設備默認HDMI輸出,tft黑屏
&hdmi {
//status = "okay";
status = "disable";
};
&hdmi_out {
hdmi_out_con: endpoint {
remote-endpoint = <&hdmi_con_in>;
};
};
&sound_hdmi {
//status = "okay";
status = "disable";
};
在設備數表中添加節點
aliases {
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
spi0 = &spi0;
spi1 = &spi1;
pwm0 = &pwm;
mmc0 = &mmc0;
mmc2 = &mmc2;
ethernet0 = &emac;
i2s0 = &i2s0;
pcm5102a = &pcm5102a;
spidev0 = &spidev0;
matrix = &matrix;
kewang = &kewang;
spiflash = &spiflash;
pitft = &pitft;
pitft_ts = &pitft_ts;
ir = &ir;
};
3、移植tft驅動
由於Linux Mainline的BSP包裏面沒有st7735s的驅動文件,但是在全志原廠的BSP裏面有看到過st7735s.c的驅動文件,所以直接複製過來,由於源文件是160x80 的分辨率,所以需要在st7735s.c文件中改兩個地方:
1:修改分辨率
2、由於驅動和dtsi文件設置的屏幕參數旋轉的90°,根據手中屏幕的分辨率128X128,修改起始點位置,否則屏幕上部會有黑條:
修改fbtft_device.c文件,在設備列表裏面增加ft_st7735s設備節點
{
.name = "matrix-st7735s",
.spi = &(struct spi_board_info) {
.modalias = "fb_st7735s",
.max_speed_hz = 32000000,
.bus_num = 0,
.chip_select = 1, // third spi dev
.mode = SPI_MODE_0,
//.controller_data= &spi_config,
.platform_data = &(struct fbtft_platform_data) {
.display = {
.buswidth = 8,
.backlight = 1,
},
.gpios = (const struct fbtft_gpio []) {
{ "reset", 3 },
{ "dc" , 17 },
{ "led", 1 },
{ "cs" , 201 },
},
}
}
}
4、修改st7735s.c和fbtft_device.c目錄(linux\drivers\staging\fbtft)下的Makefile和Kconfig文件
makefile中添加一行
Kconfig文件中添加代碼,否則kernel圖形界面配置選項無法找到
5、主makefile修改,路徑在linux目錄下
如果不修改則每次make 都需要帶ARCH=arm CROSS_COMPILE=arm-linux-,因爲系統默認架構是arm64,爲了方便,所以乾脆直接改主makefile,其中CROSS_COMPILE要填交叉編譯工具所在路徑
6、配置kernel
1、執行make sunxi_defconfig,這個配置文件是BSP自帶的
2、make menuconfig進入圖形配置界面
3、按照順序依次選擇Device Driver->Staging drivers->Support for small TFT LCD display modules
4,、按下圖,將st7735s和tbtft_device選擇成模塊
5、編譯kernel 、dtbs 、驅動模塊 ,執行make zImage dtbs modules,時間比較長
6、更新SD卡kernel、dtbs 、驅動模塊,將驅動模塊複製到根文件系統目錄,具體爲rootfs/lib/modules/4.x.x/kernel/driver/staging/fbtft
7、連接硬件
tft屏幕除了VCC和GND之外,還有
SDA:傳輸的數據,即RGB數據;
SCL:SPI通信時鐘;
RES:復位,模塊上電時拉低,通常情況下置1;
D/C:芯片的數據/命令控制引腳,當DC = 0時寫命令,當DC = 1時寫數據;
CS:從機片選, 僅當CS爲低電平時,芯片纔會被使能;
BLK(led):背光燈,一般直接接高電平即可;
根據代碼和nanopi官方硬件引腳定義連接好
8、開機上電調試
成功啓動後,進入st7735s,ko fbtft_device.ko驅動文件所在徑/lib/modules/4.x.x/kernel/driver/staging/fbtft
執行:
sudo insmod fbtft_device.ko name=matrix-st7735s busnum=0 gpios="reset:3,dc:17" rotate=90 custom=1 height=128 width=128
sudo insmod fb_st7735s.ko
執行成功的話屏幕應該點亮了,通過lsmod
命令就能看到模塊已被加載,在/dev目錄下,會產生fb0設備,如果執行失敗,可以通過dmesg | grep "fb"
來查看內核日誌,分析具體原因,一般都是由於參數錯了導致;
9、設置開機自動加載模塊
1、在st7735s.ko fbtft_device.ko 驅動模塊目錄下(/lib/modules/4.x.x/kernel/driver/staging/fbtft)執行sudo depmod -A
生成map文件。
2、編輯文件 /etc/modules,添加如下:
fb_st7735s
fbtft_device
3、新建配置文件 /etc/modprobe.d/fbtft.conf,內容如下:
options fbtft_device name=matrix-st7735s busnum=0 gpios=reset:3,dc:17 rotate=90 custom=1 height=128 width=128
4、上面 3 步完成後重啓,應該就可以看到屏幕被點亮並顯示了 console,說明驅動被自動加載了
10、參考鏈接:
ZYNQ 移植fbtft屏
nanopi-neo 點亮spi tft