一,硬件部分1.物理连接
本次使用的tft模块是微雪家的:
LCD与pocketbeagle2的连接方式如下:


Pico-LCDpocketbeagle2-P2
| DIN | P2.25 |
| CLK | P2.29 |
| CS | P2.31 |
| DC | p2.32 |
| RST | p2.30 |
| BL | 没使用 |
二,软件部分
1.设备树修改
/dts-v1/;
/plugin/;
#include <dt-bindings/leds/common.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include "k3-pinctrl.h"
/*
* Helper to show loaded overlays under: /proc/device-tree/chosen/overlays/
*/
&{/chosen} {
overlays {
kone-pocketbeagle2.kernel = __TIMESTAMP__;
};
};
&{/} {
transceiver1: can-phy0 {
compatible = "ti,tcan1042";
#phy-cells = <0>;
max-bitrate = <5000000>;
};
};
&main_pmx0 {
main_mcan0_pins_default: main-mcan0-pins-default {
pinctrl-single,pins = <
AM62X_IOPAD(0x01dc, PIN_INPUT, 0) /* (E15) MCAN0_RX */
AM62X_IOPAD(0x01d8, PIN_OUTPUT, 0) /* (C15) MCAN0_TX */
>;
};
main_spi0_pins_default: main-spi0-default-pins {
pinctrl-single,pins = <
AM62X_IOPAD(0x01bc, PIN_OUTPUT, 0) /* (A14) SPI0_CLK */
AM62X_IOPAD(0x01c0, PIN_INPUT, 0) /* (B13) SPI0_D0 */
AM62X_IOPAD(0x01c4, PIN_OUTPUT, 0) /* (B14) SPI0_D1 */
AM62X_IOPAD(0x01b4, PIN_OUTPUT, 0) /* (A13) SPI0_CS0 */
>;
};
P2_30_gpio: P2-30-gpio-pins {
pinctrl-single,pins = <
AM62X_IOPAD(0x00EC, PIN_OUTPUT, 7) /* (AA24) VOUT0_DATA13.GPIO0_58 */
>;
};
P2_32_gpio: P2-32-gpio-pins {
pinctrl-single,pins = <
AM62X_IOPAD(0x00E8, PIN_OUTPUT, 7) /* (AB25) VOUT0_DATA12.GPIO0_57 */
>;
};
// P2_09_D4_gpio: P2-09-D4-gpio-pins {
// pinctrl-single,pins = <
// AM62X_MCU_IOPAD(0x0040, PIN_OUTPUT, 7) /* (D4) MCU_MCAN1_RX.MCU_GPIO0_16 */
// >;
// };
};
&main_mcan0 {
/* RX pin 8 & TX pin 10 of J3 */
pinctrl-names = "default";
pinctrl-0 = <&main_mcan0_pins_default>;
phys = <&transceiver1>;
status = "okay";
};
&main_spi0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_spi0_pins_default>;
#address-cells = <1>;
#size-cells = <0>;
/* spidev@0 {
compatible = "rohm,dh2228fv";
reg = <0>;
spi-max-frequency = <16000000>;
};*/
st7789v: st7789v@0 {
status = "okay";
compatible = "sitronix,st7789v";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&P2_30_gpio &P2_32_gpio>;
reset-gpios = <&main_gpio0 58 GPIO_ACTIVE_HIGH>; // 低电平复位
dc-gpios = <&main_gpio0 57 GPIO_ACTIVE_HIGH>; // 低电平为命令,高电平为数据
spi-max-frequency = <10000000>;
rgb;
width = <240>;
height = <320>;
rotate = <90>;
buswidth = <8>;
fps = <60>;
spi-cpol;
spi-cpha;
debug = <1>;
};
};
&main_i2c2 {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
mpu6050@68 {
status = "okay";
compatible = "kone,i2c_mpu6050";
reg = <0x68>;
};
bmp180@77 {
status = "okay";
compatible = "kone,BMP180";
reg = <0x77>;
};
aht30@38 {
status = "okay";
compatible = "kone,AHT30";
reg = <0x38>;
};
};这里一定要注意io口的方向,在设备树k3-am62-pocketbeagle2-pinmux.dtsi文件中有包含spi0的节点,我直接引用了,结果查了很多天才发现io的方向不对,最好是每次都重新覆盖掉。
2,修改驱动源码
修改初始化序列
根据自己的屏幕参数修改,drivers/staging/fbtft/fb_st7789v.c
static int init_display(struct fbtft_par *par)
{
int rc;
par->fbtftops.reset(par);
rc = init_tearing_effect_line(par);
if (rc)
return rc;
/* 原厂初始化序列开始 */
write_reg(par, 0x11); // Sleep out
mdelay(120); // 等待电源稳定
write_reg(par, 0x36, 0x00); // MADCTL: Memory Data Access Control
write_reg(par, 0x3A, 0x05); // COLMOD: Interface Pixel Format, 16bit/pixel
write_reg(par, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33); // PORCTRL: Porch setting
write_reg(par, 0xB7, 0x35); // GCTRL: Gate Control
write_reg(par, 0xBB, 0x19); // VCOMS: VCOM setting
write_reg(par, 0xC0, 0x2C); // LCMCTRL: LCM Control
write_reg(par, 0xC2, 0x01); // VDVVRHEN: VDV and VRH Command Enable
write_reg(par, 0xC3, 0x12); // VRHS: VRH Set
write_reg(par, 0xC4, 0x20); // VDVS: VDV Set
write_reg(par, 0xC6, 0x0F); // FRCTRL2: Frame Rate Control in Normal Mode
write_reg(par, 0xD0, 0xA4, 0xA1); // PWCTRL1: Power Control 1
/* Gamma setting */
write_reg(par, 0xE0, 0xD0, 0x04, 0x0D, 0x11, 0x13, 0x2B, 0x3F,
0x54, 0x4C, 0x18, 0x0D, 0x0B, 0x1F, 0x23);
write_reg(par, 0xE1, 0xD0, 0x04, 0x0C, 0x11, 0x13, 0x2C, 0x3F,
0x44, 0x51, 0x2F, 0x1F, 0x1F, 0x20, 0x23);
write_reg(par, 0x21); // Display Inversion On
write_reg(par, 0x29); // Display On
mdelay(100);
return 0;
}修改显示方向设置
static int set_var(struct fbtft_par *par)
{
u8 madctl_par = 0;
if (par->bgr)
madctl_par |= MADCTL_BGR;
switch (par->info->var.rotate) {
case 0:
madctl_par |= 0x00; // 原厂可能使用不同的值
break;
case 90:
madctl_par |= 0x60; // MV | MX
break;
case 180:
madctl_par |= 0xC0; // MX | MY
break;
case 270:
madctl_par |= 0xA0; // MV | MY
break;
default:
return -EINVAL;
}
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
return 0;
}修改display参数
static struct fbtft_display display = {
.regwidth = 8,
.width = 240,
.height = 320,
.gamma_num = 2,
.gamma_len = 14,
.gamma = DEFAULT_GAMMA, // 或使用原厂Gamma值
.fbtftops = {
.init_display = init_display,
.write_vmem = write_vmem,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};3,内核编译
开启fb驱动。路径在:Device Drivers -> Graphics support -> Frame buffer Devices --->


开启控制台映射到fb选项,路径在:Device Drivers -> Graphics support -> Console display driver support --->


将ST7789V编译进内核。路径:Device Drivers -> Staging drivers -> Support for small TFT LCD display modules --->


三,演示
将编译好的系统重新烧录,修改以下内容:
label Linux kernel /Image.gz fdtdir / append console=tty0,console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02860000 root=/dev/mmcblk1p2 ro rootfstype=ext4 rootwait net.ifnames=0 fdtoverlays /overlays/kone-pocketbeagle2.dtbo
上电启动:


可以看到屏幕以成功驱动。
我要赚赏金
