香橙派orangepi pc plus h3驱动spi fbtft显示屏

前言

环境介绍:

1.编译环境

Ubuntu 18.04.5 LTS

2.SDK

orangepi Linux 5.4 SDK

3.uboot

v2020.04

4.gcc

gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf

5.单板

orangepi pc plus

6.spi fbtft显示屏

淘宝中景园买的 1.3寸st7789 ips显示屏


一、硬件链接

由于orangepi pc plus排针已经将SPI0引出,这里就用SPI0作为通讯接口,其他管脚随意。

orangepi pc plus ips显示屏
GND GND
3.3V VCC
SPI0_CLK(PC2) SCL
SPI0_MOSI(PC0) SDA
PA7 RES
PA8 DC
PA9 BLK

二、移植

2.1 st7789v修改

初始化函数修改
内核自带的st7789v初始化代码有问题,需要做相应的修改。
文件路径:drivers/staging/fbtft/fb_st7789v.c
修改init_display函数,如下:

static int init_display(struct fbtft_par *par)
{
    par->fbtftops.reset(par);
    mdelay(50);
	write_reg(par,0x11);//Sleep exit
	
    mdelay(120);
    write_reg(par,0x36,0x00);
    write_reg(par,0x3A,0x05);
    write_reg(par,0xB2,0x0C,0x0C,0x00,0x33,0x33);
    write_reg(par,0xB7,0x35);
    write_reg(par,0xBB,0x19);
    write_reg(par,0xC0,0x2C);
    write_reg(par,0xC2,0x01);
    write_reg(par,0xC3,0x12);
    write_reg(par,0xC4,0x20);
    write_reg(par,0xC6,0x0F);
    write_reg(par,0xD0,0xA4,0xA1);
    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);
    // write_reg(par,0x11);
    // mdelay(50);
    write_reg(par,0x29);
    mdelay(200);
	pr_info("fbtft_%s ok!\n", __func__);//内核打印
    return 0;
}

分辨率修改
修改fbtft_display display函数的width、height的值

static struct fbtft_display display = {
	.regwidth = 8,
	.width = 240,//根据自己实际的分辨率修改
	.height = 240,//根据自己实际的分辨率修改
	.gamma_num = 2,
	.gamma_len = 14,
	.gamma = HSD20_IPS_GAMMA,
	.fbtftops = {
		.init_display = init_display,
		.set_var = set_var,
		.set_gamma = set_gamma,
		.blank = blank,
		.set_addr_win = set_addr_win,//设置写入范围回调函数
	},
};

2.2 fbtft-core.c修改

说明:5.2版本之后使用的是另一种方式申请gpio,但是这种方式只是简单的给出了接口,实际并没有申请到gpio,因此当不去修改申请方式的时候,即使内核log提示已经申请成功并注册了驱动,但是实际并没有,导致液晶屏无法驱动起来。
文件路径:drivers/staging/fbtft/fbtft-core.c
添加头文件

#include 
#include 

修改下面这两个函数

static int fbtft_request_one_gpio(struct fbtft_par *par,
                  const char *name, int index,
                  struct gpio_desc **gpiop)
{
    struct device *dev = par->info->device;
    struct device_node *node = dev->of_node;
    int gpio, flags, ret = 0;
    enum of_gpio_flags of_flags;

    if (of_find_property(node, name, NULL)) {
        gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
        if (gpio == -ENOENT)
            return 0;
        if (gpio == -EPROBE_DEFER)
            return gpio;
        if (gpio < 0) {
            dev_err(dev,
                "failed to get '%s' from DT\n", name);
            return gpio;
        }

         //active low translates to initially low 
        flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
                            GPIOF_OUT_INIT_HIGH;
        ret = devm_gpio_request_one(dev, gpio, flags,
                        dev->driver->name);
        if (ret) {
            dev_err(dev,
                "gpio_request_one('%s'=%d) failed with %d\n",
                name, gpio, ret);
            return ret;
        }

        *gpiop = gpio_to_desc(gpio);
        fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
                            __func__, name, gpio);
    }

    return ret;
}
static void fbtft_reset(struct fbtft_par *par)
{
    if (!par->gpio.reset)
        return;
    fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
    gpiod_set_value_cansleep(par->gpio.reset, 1);
    msleep(10);
    gpiod_set_value_cansleep(par->gpio.reset, 0);
    msleep(200);
    gpiod_set_value_cansleep(par->gpio.reset, 1);
    msleep(10);
}

2.3 修改设备树

添加st7789v节点
文件路径:scripts/dtc/include-prefixes/arm/sun8i-h3-orangepi-pc-plus.dts

&spi0{
		status="okay";
		st7789v: st7789v@0{
			compatible = "sitronix,st7789v";//这个要跟fb_st7789v.c对应上
			reg = <0>;
			status = "okay";
			spi-max-frequency = <48000000>;//最大速率
			spi-cpol;//spi模式
			spi-cpha;
			rotate = <0>;//屏幕翻转
			fps = <60>;//帧率
			buswidth = <8>;//数据位宽
			rgb;
			dc = <&pio 0 8 GPIO_ACTIVE_HIGH>;  // PA8 h3 gpio 0对应A、1对应B...
			reset = <&pio 0 7 GPIO_ACTIVE_HIGH>; // PA7
			led = <&pio 0 9 GPIO_ACTIVE_LOW>;  // PA9
			debug = <0>;
		};
};
//下面顺便把hdmi输出关闭,要不然spi屏不会有显示的
&hdmi {
	//status = "okay";
	status = "disable";
};
&sound_hdmi {
	//status = "okay";
	status = "disable";
};

spi管脚配置上拉
要是spi管脚不配置上拉,会使数据传输错误,导致屏幕无显示或是刷新超慢,我就在这里被坑了好久。
可以参考一下这篇文章使用h3跑linux上的fbtft,出现spi通信错误
文件路径:scripts/dtc/include-prefixes/arm/sunxi-h3-h5.dtsi
一定在这个文件添加,sun8i-h3-orangepi-pc-plus.dts添加都不行。

spi0_pins: spi0-pins {
	pins = "PC0", "PC1", "PC2", "PC3";
	function = "spi0";
	bias-pull-up;//上拉
};

2.3 编译配置

执行make menuconfig启动图形配置界面

把st7789v驱动并编译进内核中,如下:
Device Drivers —>  
    [*] Staging drivers —>  
        <*> Support for small TFT LCD display modules —>
              <*> FB driver for the ST7789V LCD Controller
开启SPI驱动的A31控制,这个不知道h3有没有这个问题,默认使开启的,要是显示有问题可以尝试一下。
Device Drivers -> SPI support
香橙派orangepi pc plus h3驱动spi fbtft显示屏_第1张图片
内核启动显示linux小企鹅

-> Device Drivers
-> Graphics support
-> Bootup logo (LOGO [=y])
-> Standard black and white Linux logo
-> Standard 16-color Linux logo
-> Standard 224-color Linux logo
香橙派orangepi pc plus h3驱动spi fbtft显示屏_第2张图片

2.4 内核、设备树编译,替换

具体内核编译可移步到另外一篇文章
香橙派orangepi pc plus h3 uboot、内核和根文件系统编译
记得内核、设备树都要替换!!!
设备起来后可以在dev下面看到一个fb设备

root@ubuntu:~# ls /dev/fb*
/dev/fb0

查看内核打印

root@ubuntu:~# dmesg |grep fb
[    1.341652] fbtft_of_value: buswidth = 8
[    1.345598] fbtft_of_value: debug = 0
[    1.349256] fbtft_of_value: rotate = 0
[    1.353000] fbtft_of_value: fps = 60
[    2.004410] fbtft_init_display ok!
[    2.041764] graphics fb0: fb_st7789v frame buffer, 240x240, 112 KiB video memory, 4 KiB buffer memory, fps=100, spi0.0 at 48 MHz

这时显示屏就正常显示啦。

你可能感兴趣的:(香橙派orangepi,内核,嵌入式,fbtft,spi显示屏)