Linux 添加SPI显示屏并取消闪烁光标

发布时间 2023-10-25 13:32:46作者: *^VV^*

1、修改设备树(sun8i-h3-nanopi-m1.dts添加内容,确保SPI接口硬件上拉)

&spi0 {
  status="okay";
  st7735s@0 {
    status = "okay";
    compatible = "sitronix,st7735s";
    reg = <0>;
    spi-max-frequency =<32000000>; //SPI时钟32M
    rotate =<270>; //屏幕旋转270度
    spi-cpol;
    spi-cpha;
    rgb; //颜色格式RGB
    fps =<30>; //刷新30帧率
    buswidth =<8>; //总线宽度8
    reset =<&pio 0 20 GPIO_ACTIVE_LOW>; //PA20
    dc =<&pio 0 21 GPIO_ACTIVE_LOW>; //PA21
    debug =<0>; //不开启调试
  };
};

2、修改驱动文件(linux-5.10.172/drivers/staging/fbtft/fb_st7735r.c)

  2.1、拷贝linux-5.10.172/drivers/staging/fbtft/fb_st7735r.c为linux-5.10.172/drivers/staging/fbtft/fb_st7735s.c

  2.2、修改相关名称内容。一定要修改compatible属性与设备树一致。

  FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735s", &display);

  2.3、显示不全修改显示代码(fb_st7735s.c)添加偏移量

  static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
  {
    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+24) >> 8, (ys+24) & 0xFF, (ye+24) >> 8, (ye+24) & 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);
  }

  2.3、在同目录Kconfig、Makefile中添加编译选项。

  2.4、修改fbtft-core.c文件中的fbtft_request_one_gpio、fbtft_reset函数

  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);
  }

3、Linux显示屏取消闪烁光标

  将linux-5.10.172/drivers/video/fbdev/core/softcursor.c文件里的int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);函数置为空即可。