记录为Linux配置spi屏幕(st7735s)
Posted qq_46604211
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录为Linux配置spi屏幕(st7735s)相关的知识,希望对你有一定的参考价值。
Linux配置spi屏幕(st7735s,使用我的板子需要增加底板)
ps:st7735s可用st7735r的驱动(但是我打算使用7789v的驱动来修改)参考老哥 的文章:https://www.bilibili.com/read/cv9947785
1.修改fb_st7789v.c文件
该文件在:linux-5.10/drivers/staging/fbtft
1.1 修改init_display函数:
static int init_display(struct fbtft_par *par)
{
par->fbtftops.reset(par);//硬复位
mdelay(50);
write_reg(par,0x11);//软复位
mdelay(100);
//下面添加初始化函数write_reg 参数分别为:结构体指针,写命令,写数据....(后都为数据)
//ST7735s Frame Rate
write_reg(par,0xB1,0x05,0x3c,0x3c);
write_reg(par,0xB2,0x05,0x3c,0x3c);
write_reg(par,0xB3,0x05,0x3c,0x3c,0x05,0x3c,0x3c);
write_reg(par,0xB4,0x03); //Column inversion
//ST7735s Power Sequence
write_reg(par,0xC0,0x28,0x08,0x04);
write_reg(par,0xC1,0xc0);
write_reg(par,0xC2,0x0d,0x00);
write_reg(par,0xC3,0x8d,0x2a); //VCOM
write_reg(par,0xc4,0x8d,0xee); //MX, MY, RGB mode
write_reg(par,0xc5,0x1a);
write_reg(par,0x36,0xc0);
//ST7735s Gamma Sequence
write_reg(par,0xe0,0x04,0x22,0x07,0x0a,0x2e,0x30,0x25,0x2a,0x28,0x26,0x2e,0x3a,0x00,0x01,0x03,0x13);
write_reg(par,0xe1,0x04,0x16,0x06,0x0d,0x2d,0x26,0x23,0x27,0x27,0x25,0x2d,0x3b,0x00,0x01,0x04,0x13);
write_reg(par,0x3A,0x05); //65k mode
write_reg(par,0x29);//Display on
mdelay(100);
return 0;
}
1.2 修改struct fbtft_display display
修改屏幕高宽:
static struct fbtft_display display = {
.regwidth = 8,
.width = 128,//屏幕宽度
.height = 160,//屏幕高度
.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,
},
};
若使用st77335s需将set_gamma函数的for循环注释掉
2.修改fbtft-core.c文件(更新驱动的gpio申请函数):
修改以下几个函数:
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 int fbtft_request_gpios(struct fbtft_par *par)
{
int i;
int ret;
ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "rd-gpios", 0, &par->gpio.rd);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "wr-gpios", 0, &par->gpio.wr);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "cs-gpios", 0, &par->gpio.cs);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "latch-gpios", 0, &par->gpio.latch);
if (ret)
return ret;
for (i = 0; i < 16; i++) {
ret = fbtft_request_one_gpio(par, "db-gpios", i,
&par->gpio.db[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "led-gpios", i,
&par->gpio.led[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "aux-gpios", i,
&par->gpio.aux[i]);
if (ret)
return ret;
}
return 0;
}
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-5.10/arch/arm/boot/dts设备节点如下:
&spi0 {
status ="okay";
st7789v@0 {
status ="okay";
compatible = "sitronix,st7789v";
reg = <0>;
spi-max-frequency =<48000000>; //SPI时钟50M
rotate =<90>; //屏幕旋转90度
spi-cpol;
spi-cpha;
rgb; //颜色格式RGB
fps =<30>; //刷新30帧率
buswidth =<8>; //总线宽度8
dc-gpios =<&pio 1 6 GPIO_ACTIVE_LOW>; //GPIOB6
reset-gpios=<&pio 1 5 GPIO_ACTIVE_LOW>; //GPIOB5 暂时测试后面dc板子会改成pb4
debug =<0>; //不开启调试
};
3.配置linux内核:
make ARCH=arm menuconfig
配置如下:
ps:7735s也可直接修改fbtft-core.c文件,然后设备树的st7789v全改为st7783r,内核配置时选中ST7735R即可按照后面做。
4.编译内核:
编译内核:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules_install
编译设备树: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs
将编译的内核zImage 和dtb文件替换tf卡内的文件即可。也可参考我的一片烧录的文章。
5.启动开发板
使用:
cat /dev/urandom > /dev/fb0
看是否屏幕出现雪花点。(如果有就说明驱动上了)
6.添加控制台输出:
修改u-boot的bootargs参数进入u-boot时按任意键进入boot命令,输入:
setenv bootargs "console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw vt.global_cursor_default=0"
saveenv
下一篇文章为使用板子播放BADAPPLE,有屏幕的地方就有BADAPPLE。
以上是关于记录为Linux配置spi屏幕(st7735s)的主要内容,如果未能解决你的问题,请参考以下文章
STM32CubeIDESTM32F103硬件SPI驱动1.8寸TFT LCD128X160 ST7735S屏幕
LVGL移植STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S跑LVGL图形demo
STC32G单片机驱动1.8寸TFT LCD128X160 ST7735S SPI串口驱动示例