全志v851s使用fbtft驱动0.96寸st7735屏分享
-
最近打算做个小玩意,需要驱动0.96寸的st7735,为此也踩了些坑,特此记录分享。
直接上配置吧:
1.电路图:
这里使用到spi0 以及 PD2 PD4 还有PH0 作为pwm0 没截图显示。
2.board.dts配置&pio{ ..... spi0_pins_a: spi0@0 { allwinner,pins = "PC0", "PC2"; allwinner,pname = "spi0_sclk", "spi0_mosi"; allwinner,function = "spi0"; allwinner,muxsel = <4>; allwinner,drive = <1>; allwinner,pull = <0>; }; spi0_pins_b: spi0@1 { allwinner,pins = "PC1"; allwinner,pname = "spi0_cs0"; allwinner,function = "spi0"; allwinner,muxsel = <4>; allwinner,drive = <1>; allwinner,pull = <1>; // only CS should be pulled up }; spi0_pins_c: spi0@2 { allwinner,pins = "PC0", "PC1", "PC2"; allwinner,function = "io_disabled"; allwinner,muxsel = <0xf>; allwinner,drive = <1>; allwinner,pull = <0>; }; ................ };
以上为引脚配置,
&spi0 { clock-frequency = <100000000>; pinctrl-0 = <&spi0_pins_a &spi0_pins_b>; pinctrl-1 = <&spi0_pins_c>; pinctrl-names = "default", "sleep"; spi0_cs_number = <1>; spi1_cs_bitmap = <1>; spi_slave_mode = <0>; spi_dbi_enable = <0>; status = "okay"; st7789v@0 { status = "okay"; compatible = "sitronix,st7735r"; reg = <0>; spi-max-frequency = <32000000>; rotate = <90>; bgr; fps = <60>; buswidth = <8>; reset-gpios = <&pio PD 2 1 1 2 1>; dc-gpios = <&pio PD 4 1 1 2 0>; led-gpios = <&pio PH 0 1 1 2 1>; debug = <1>; }; };
这里是spi0配置。
2.内核配置(可以选择关闭disp2,以及 设备树 删除disp lcd0 部分)
切记。一定要关闭uboot disp2 。
3.修改驱动代码
.../linux-4.9/drivers/staging/fbtft/fbtft-core.c 文件中
static int fbtft_request_one_gpio(struct fbtft_par *par, const char *name, int index, int *gpiop) 函数,修改后代码如下:static int fbtft_request_one_gpio(struct fbtft_par *par, const char *name, int index, int *gpiop) { struct device *dev = par->info->device; struct device_node *node = dev->of_node; int gpio, flags, ret = 0; struct gpio_config gpio_of_flags; if (of_find_property(node, name, NULL)) { gpio = of_get_named_gpio_flags(node, name, index, (enum of_gpio_flags *)&gpio_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 = (gpio_of_flags.data & 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; } if (gpiop) *gpiop = gpio; fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n", __func__, name, gpio); } return ret; }
修改 .../linux-4.9/drivers/staging/fbtft/fb_st7735r.c 文件
主要修改一下驱动初始化代码列表:
static int default_init_sequence[] = { -1, MIPI_DCS_SOFT_RESET, -2, 150, /* delay */ -1, MIPI_DCS_EXIT_SLEEP_MODE, -2, 500, /* delay */ /* FRMCTR1 - frame rate control: normal mode * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */ -1, 0xB1, 0x05, 0x3C, 0x3C, /* FRMCTR2 - frame rate control: idle mode * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */ -1, 0xB2, 0x05, 0x3C, 0x3C, /* FRMCTR3 - frame rate control - partial mode * dot inversion mode, line inversion mode */ -1, 0xB3, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C, /* INVCTR - display inversion control * no inversion */ -1, 0xB4, 0x03, /* PWCTR1 - Power Control * -4.6V, AUTO mode */ -1, 0xC0, 0xAB, 0x0B, 0x04, /* PWCTR2 - Power Control * VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */ -1, 0xC1, 0xC5, /* PWCTR3 - Power Control * Opamp current small, Boost frequency */ -1, 0xC2, 0x0D, 0x00, /* PWCTR4 - Power Control * BCLK/2, Opamp current small & Medium low */ -1, 0xC3, 0x8D, 0x6A, /* PWCTR5 - Power Control */ -1, 0xC4, 0x8D, 0xEE, /* VMCTR1 - Power Control */ -1, 0xC5, 0x0F, -1, 0x21, -1, 0x3A, 0x05, -1, MIPI_DCS_SET_DISPLAY_ON, -2, 100, /* delay */ -1, MIPI_DCS_ENTER_NORMAL_MODE, -2, 10, /* delay */ /* end marker */ -3 };
!!修改屏偏移
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) { xs = xs + 1 ; xe = xe + 1 ; ys = ys + 26 ; ye = ye + 26; write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF); write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF); write_reg(par, MIPI_DCS_WRITE_MEMORY_START); }
修改屏参数:
static struct fbtft_display display = { .regwidth = 8, .width = 80, .height = 160, .init_sequence = default_init_sequence, .gamma_num = 2, .gamma_len = 16, .gamma = DEFAULT_GAMMA, .fbtftops = { .set_addr_win = set_addr_win, .set_var = set_var, .set_gamma = set_gamma, }, };
至此编译即可在小机端看到有fb0生成,屏幕点亮。
最后一图:
如有疑问,请跟贴。
-
@whycanservice2 可以支持多个 tft 吗
-
@whycanservice2
老哥 问两个问题
1.你的PH0做pwm调好了吗
2.屏幕会显示启动log嘛 -
@frank 这改完 lcd0 不能用了啊
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号