页次: 1
首先是:root@(none):/# cat /dev/urandom > /dev/fb0
cat: write error: No space left on device
这个不明白怎么会空间不足,那个空间不足也不知道。
其次是:现在屏幕是不亮的,全程都不亮,是背光的问题吧。
我的关于背光的配置(设备树)只有这一行:led-gpios = <&pio PD 20 1 1 2 0>;(led-gpios = <&pio PD 20 1 1 2 1>;也试过,不行)。根据硬件,vcc接集电级(三极管),PD20接基级,发射级接led_A(应该是共基极电路),pd20为低电位时,导通。
我先找一下背光函数,看有没有执行。(屏驱是执行了的)
当前情况:fb0已经生成,运行lvgl的官方例程lv_examples可以运行,最终停在while(),但是屏幕不亮,一直都不亮(屏幕是好的),我添加的屏驱(fb_st77916)也运行了,3个回调函数都运行了。初步猜测是屏驱初始化有问题,设备树有问题。
我有一份应用层屏驱可以点亮屏幕,它点屏只需要两步:
第一步:复位
这是复位代码: void lcd_st77916_reset(void)
{
system("echo PD8 1 > /sys/kernel/debug/sunxi_pinctrl/function");
system("echo PD8 0 > /sys/kernel/debug/sunxi_pinctrl/data");
usleep(10);
system("echo PD8 1 > /sys/kernel/debug/sunxi_pinctrl/data");
}
第二步:屏幕初始化
前提条件:fd = open(“/dev/spidev1.0”, O_RDWR);
struct qspi_lcd_cmd {
uint8_t a ;
uint8_t b ;
uint8_t cmd;
uint8_t c ;
uint8_t param[16];
};
struct qspi_lcd_cmd cmd_tbl[] = {
{0x02,0x00,0xf0,0x00,{0x08}},
{0x02,0x00,0xf2,0x00,{0x08}},
{0x02,0x00,0x9B,0x00,{0x51,0x33,0x44,0x55}},
.
.
.
};
执行代码:for (int i = 0; i < sizeof(cmd_tbl) / sizeof(struct qspi_lcd_cmd); i++)
_transfer(fd, cmd_tbl[i], NULL, strlen(cmd_tbl[i]))
(就是把初始化命令和数据,一次发一行)
这是部分代码: static int _transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
int ret;
int out_fd;
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = len,
.delay_usecs = 0,
.speed_hz = SPI_SPEED,
.bits_per_word = 8,
.tx_nbits = 1,
.rx_nbits = 1
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);(这个不懂,我猜它是发送的函数,在其他地方看过一次)
if (ret < 1)
{
pabort("can't send spi message");
return -EIO;
}
.
.
.
}
现在在fbtft的屏驱:
static int init_display(struct fbtft_par *par)
{
printk(KERN_INFO "屏幕初始化 started.\n");
mdelay(10);
write_reg(par,0xF0,0x08);(这是最初这样的)
write_reg(par,0xF2,0x08);(这是最初这样的)
....
write_reg(par,0x02,0x00,0xF0,0x00,0x08);(这是我根据最初和我的情况改的)
write_reg(par,0x02,0x00,0xF2,0x00,0x08);
...
}(write_reg有3个参数,par,sizeof(0x02,0x00,0xF0,0x00,0x08)/u8 , (0x02,0x00,0xF0,0x00,0x08) 这里经过宏定义,可变变量,变成了两个参数)
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:
break;
case 90:
madctl_par |= (MADCTL_MV | MADCTL_MY);
break;
case 180:
madctl_par |= (MADCTL_MX | MADCTL_MY);
break;
case 270:
madctl_par |= (MADCTL_MV | MADCTL_MX);
break;
default:
return -EINVAL;
}
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
return 0;
}
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
int i;
int j;
int c; /* curve index offset */
const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
0x1F, /* V4[4:0] */
0x1F, /* V6[4:0] */
0x3F, /* J0[1:0], V13[3:0] */
0x7F, /* V20[6:0] */
0x77, /* V36[2:0], V27[2:0] */
0x7F, /* V43[6:0] */
0x3F, /* J1[1:0], V50[3:0] */
0x1F, /* V57[4:0] */
0x1F, /* V59[4:0] */
0x3F, /* V61[5:0] */
0x3F, /* V62[5:0] */
};
for (i = 0; i < par->gamma.num_curves; i++) {
c = i * par->gamma.num_values;
for (j = 0; j < par->gamma.num_values; j++)
curves[c + j] &= gamma_par_mask[j];
write_reg(
par, PVGAMCTRL + i,
curves[c + 0], curves[c + 1], curves[c + 2],
curves[c + 3], curves[c + 4], curves[c + 5],
curves[c + 6], curves[c + 7], curves[c + 8],
curves[c + 9], curves[c + 10], curves[c + 11],
curves[c + 12], curves[c + 13]);
}
return 0;
}
static int blank(struct fbtft_par *par, bool on)
{
if (on)
write_reg(par, MIPI_DCS_SET_DISPLAY_OFF);
else
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
return 0;
}
static struct fbtft_display display = {
.regwidth = 4,
.width = 360,
.height = 360,
.gamma_num = 2,
.gamma_len = 14,
.gamma = DEFAULT_GAMMA,
.fbtftops = {
.init_display = init_display,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st77916", &display);
MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st77916");
MODULE_ALIAS("platform:st77916");
MODULE_DESCRIPTION("FB driver for the st77916 LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");
现在我的需求是怎么把应用层屏驱改成fbtft的驱动层,但是我不会,难受。。。
设备树那边还在尝试。现在改过也不亮。
希望那个大佬帮我看一下,我改的对不对,有哪些需要注意的。
(其实我也想过把应用层驱动添加到库里,我就能直接用了,但是那样可直接在应用层好像没有太大区别,而且我的是fb0,应用层驱动那个是spidev1.0,所以放弃了,还得修改屏驱)
我设备树这边修改了一下
dc-gpios = <&pio PD 5 1 1 2 0>;
//reset-gpios = <&pio PD 8 1 1 2 1>;
led-gpios = <&pio PD 20 1 1 2 1>;
就是把reset-gpios给注销了,然后就生成fb0了。
v851s—datasheet
Function6
(PD1)SP11_CS0/DBI_CSX
(PD2)SPI1_CLK/DBI_SCLK
(PD3)SPI1_MOSI/DBI_SDO
(PD4)SP11_MISO/DBI_SDI/DBI_TE/DBI_ DCX
(PD5)SPI1_HOLD/DBI_DCX/DBI_WRX
(PD6)SPI1_WP/DBI_TE
(PD7)SP11_CS1
因为我的reset引脚连接的是PD8,通过原理图可以看到PD8并没有spi功能,所以我猜测是我配置的reset-gpio溢出了。
还有一点不明的是就是dc引脚,虽然我从我的原理图上没找到dc引脚,但是我从v851s—datasheet上也没找到,但是他支持dc引脚,就应该有spi1_dc吧,没办法,所以我参考的dbi_dcx,配置的PD5。暂时先不管它了,有fb0了就先继续往下吧。
最后很感谢晕哥和lovexulu给予的帮助,好人一生平安
首先我通过cboot跳转到uboot下,在make menuconfig 关闭了 Device Drivers --->
Graphics support --->
[ ] DISP Driver Support(sunxi-disp2) ----
tina-fastboot-v85x/lichee/brandy-2.0/u-boot-2018/configs/sun8iw21p1_fastboot_defconfig(这是我找到的uboot的配置文件)把#CONFIG_DISP2_SUNXI=y(注销了,或者说处于“#”注销下),这应该就是把uboot下的disp2关闭了吧。
[color]在fbtft-core.c文件的fbtft_request_gpios_dt函数下有匹配的名字(有一些列这个函数fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);)"reset-gpios","dc-gpios","cs-gpios","wr-gpios"等等[/color]
[color]我把"dc-gpios"注销掉是因为我的原理图里面没有dc功能的,比较特殊的是有一个LCD_TE,接的是PD7,应该是cs1;其他就是rst;clk;hold;wp;miso;mosi;cs0;pwm10[/color]
情况1:
我配置成这样reset-gpios = <&pio PD 8 1 1 2 1>;
我的终端(xshell)最终打印[ 1.007643] Function entered at [<c013bed1>] from [<c2843b38>]
[ 1.014185] Code: bad PC value
[ 1.017607] ---[ end trace 1c5cdc983d9f73cb ]---
[ 1.022782] Fixing recursive fault but reboot is needed!
然后就死了。
情况2:
我配置成这样dc-gpios = <&pio 3 6 GPIO_ACTIVE_HIGH>; (帖子里我猜他把wp那个引脚配置成dc了,所以我也是,PD6)
reset-gpios = <&pio 3 8 GPIO_ACTIVE_HIGH>;
led-gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>;
我的终端(xshell)(dmesg | less)日志打印OF: /soc@03000000/spi@04026000/st77916@0: arguments longer than property 和 fb_st77916 spi1.0: failed to get 'reset-gpios' from DT
我这边基本已经和那个帖子里的内容保持一致了,因为硬件不同,有一些差异。
有两个大的差异就是1:我的是reset-gpios = <&pio 3 8 GPIO_ACTIVE_HIGH>;
他的是reset-gpios = <&pio PD 4 1 1 2 1>;
2:他的是struct gpio_config gpio_of_flags;其他的是根据这个结构体改的。
我的fbtft-core.c没改,因为我把enum of_gpio_flags of_flags;改成struct gpio_config gpio_of_flags;后,在make就报错找不到struct gpio_config gpio_of_flags,我跳转到gpio_config 的定义下,在/tina-fastboot-v85x--danmuok/lichee/linux-4.9/drivers/media/dvb-frontends/tda1004x.h这个文件下。
我现在也有点迷茫了。。。
fbtft-core.c文件
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;
enum of_gpio_flags of_flags;
if (of_find_property(node, name, NULL)) {
printk(KERN_INFO "of_find_property 11111111111 over.\n");
gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
printk(KERN_INFO "of_get_named_gpio_flags 11111111111 over.\n");
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;
}
.
.
.
.
.
}
現在我找到打印的位置了,
gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
這一步打印了“OF: /soc@03000000/spi@04026000/st77916@0: arguments longer than property”
接着就执行到:if (gpio < 0) {
dev_err(dev,
"failed to get '%s' from DT\n", name);
return gpio;
}
但是我还是判断不了是什么引起的错误,难受。。。
希望大家帮我看一下,万分感谢。
[ 0.168292] 11111111111111111111111111111111111.
[ 0.168298] 解析设备树里的sitronix,st7735r start.
[ 0.168307] fbtft_of_value: regwidth = 16
[ 0.168311] fbtft_of_value: buswidth = 8
[ 0.168316] fbtft_of_value: debug = 1
[ 0.168319] fbtft_of_value: rotate = 0
[ 0.168323] fbtft_of_value: fps = 30
[ 0.168328] 解析设备树里的sitronix,st7735r over.
[ 0.168587] 注册 fb_info star.
[ 0.168591] fbtft_register_framebuffer00000000000.
[ 0.168595] 987987987987.
[ 0.168597] 8888888888888888888.
[ 0.168599] 777777777777777777.
[ 0.168646] OF: /soc@03000000/spi@04026000/st77916@0: arguments longer than p
roperty
[ 0.168657] fb_st77916 spi1.0: failed to get 'reset-gpios' from DT
[ 0.168660] fbtft_register_framebuffer11111111
[ 0.168662] fbtft_register_framebuffer err
[ 0.168664] 注册 fb_info over.
[ 0.178790] fb_st77916: probe of spi1.0 failed with error -22
这是我的启动日志:可以看到我的fbtft-core.此文件已经执行了,去注册framebuffer,最终生成fb0(怎么感觉还行是spi1.0啊)
[ 0.168646] /soc@03000000/spi@04026000/st77916@0: arguments longer than p
roperty
[ 0.168657] fb_st77916 spi1.0: failed to get 'reset-gpios' from DT这两行是日志报的错误,其他一下是我printk打印判断是什么引起的错误(还没找到)
最终我判断应该是我设备树://dc-gpios = <&pio 3 6 GPIO_ACTIVE_HIGH>;
reset-gpios = <&pio 3 8 GPIO_ACTIVE_HIGH>;
led-gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>;
reset-gpios的参数错了(AI也是这样说的)
参考 https://whycan.com/t_6477.html#p63255
你这不是gpios设备树参数太多咩。报错了呗, 你用的sdk应该和他们用的不同,具体gpios的配置情况可以参考已有的例子,如果没有的话可以找下
Documentation\devicetree\bindings 下面对设备树描述的txt看例子怎么使用设备树。就拿贴子上晕哥说的那个buildroot-tiny200 这个的来说,你看你这句
gpios = <&pio 5 5 GPIO_ACTIVE_LOW>; 你这个应该就是这个sdk里面设备树写法。这个&pio中的pio你可以在suniv-f1c100s.dtsi这里找到pio的配置,其中就有compatible = "allwinner,suniv-f1c100s-pinctrl"这个。然后你在Documentation\devicetree\bindings这里面搜索"allwinner,suniv-f1c100s-pinctrl"你就可以打开allwinner,sunxi-pinctrl.txt。这里面就说明了每个参数是什么,并且有一个demo示例。不同的SDK是略有不同的。我知道的tina就不同。
根据这个帖子,我是设备树里的gpios参数太多了,让我到Documentation\devicetree\bindings下面找到设备树参数说明,还有例程。
未通过find . -name "bindings"查找到“Documentation”这个文件夹大写的只有两个路径
./lichee/linux-4.9/modules/gpu/mali-midgard/kernel_mode/driver/Documentation/devicetree/bindings
在这个路径下有: bindings/arm/mali-midgard.txt
bindings/arm/memory_group_manager.txt
bindings/arm/smc-protected-mode-switcher.txt
bindings/power/mali-opp.txt
5个文件
./lichee/linux-4.9/modules/gpu/mali-bifrost/driver/Documentation/devicetree/bindings
在这个路径下有: bindings/arm/mali-midgard.txt
bindings/arm/smc-protected-mode-switcher.txt
bindings/power/mali-opp.txt
3个文件
我都打开看了一下没有我需要的关于spi设备树配置的。是不是我找错了啊?
并且我在我 .dtsi文件下(设备树的)找到spi1: spi@04026000 {compatible = "allwinner,sun8i-spi"; ......}我用grep搜索一下allwinner,sun8i-spi并没有什么收获。
spi1_pins_a: spi1@0 {
allwinner,pins = "PD2", "PD3", "PD4","PD5", "PD6";
allwinner,pname = "spi1_sclk", "spi1_mosi", "spi1_miso", "spi1_hold", "spi1_wp";
allwinner,function = "spi1";
allwinner,muxsel = <6>;
allwinner,drive = <1>;
allwinner,pull = <0>;
};
spi1_pins_b: spi1@1 {
allwinner,pins = "PD1"; //"PF25";
allwinner,pname = "spi1_cs0";
allwinner,function = "spi1";
allwinner,muxsel = <6>;
allwinner,drive = <1>;
allwinner,pull = <1>; // only CS should be pulled up
};
spi1_pins_c: spi1@2 {
allwinner,pins = "PD1", "PD2", "PD3", "PD4", "PD5", "PD6";
allwinner,function = "io_disabled";
allwinner,muxsel = <0x7>;
allwinner,drive = <1>;
allwinner,pull = <0>;
};
&spi1 {
clock-frequency = <100000000>;
pinctrl-0 = <&spi1_pins_a &spi1_pins_b>;
pinctrl-1 = <&spi1_pins_c>;
pinctrl-names = "default", "sleep";
spi_slave_mode = <0>;
spi_dbi_enable = <0>;
spi1_cs_number = <1>;
spi1_cs_bitmap = <1>;
status = "okay";
spi_board1@0 {
device_type = "spi_board1";//"spi_dbi";
compatible = "rohm,dh2228fv";
spi-max-frequency = <0x5f5e100>;
reg = <0x0>;
spi-rx-bus-width = <0x4>;
spi-tx-bus-width = <0x4>;
status = "disabled";
};
st77916@0{
//compatible = "rohm,dh2228fv"; /* 兼容性字符串,指定使用的设备驱动程序 */
compatible = "sitronix,st77916";
//compatible = "lineartechnology,ltc2488";
reg = <0>;
status = "okay";
spi-max-frequency = <32000000>;
fps = <30>; /* 每秒帧数 (Frames Per Second),这里设置为33帧*/
rotate = <0>;
buswidth = <8>; /* 总线宽度,这里设定为4位 */
//dc-gpios = <&pio 3 1 GPIO_ACTIVE_HIGH>; /* 数据/命令引脚,指向第3组GPIO的第1个引脚,活动高电平 */
reset-gpios = <&pio 3 8 GPIO_ACTIVE_HIGH>; /* 复位引脚,指向第3组GPIO的第8个引脚,活动高电平 */
led-gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* LED引脚,指向第3组GPIO的第20个引脚,活动高电平 */
debug = <0x0>;
};
};
Device Drivers --->
Graphics support --->
Frame buffer Devices --->
<*> Support for frame buffer devices
Console display driver support --->
[*] Framebuffer Console support
[*] Map the console to the primary display device
[*] Staging drivers --->
<*> Support for small TFT LCD display modules --->
<*> FB driver for the ST7789V LCD Controller
但我的kenel_menuconfig里面没有(Console display driver support --->)选项,所以下面那两个我也没法配置了。但是我在kennel_menuconfig里面用“?”查找可以找到 Framebuffer Console support Map the console to the primary display device,并且在它提示是kconfig里也看到了,就是我选不了,我查了一下,这两项是: Framebuffer控制台支持 将控制台映射到主显示设备,还是很重要的的。是不是就是因为我没配置这两项,所以才生成不了fb0啊!
参考这个文档配置的帧缓存器 aw-ol.com 全志v851s使用fbtft驱动0.96寸st7735屏分享
设备树配置
&spi1 {
clock-frequency = <100000000>;
pinctrl-0 = <&spi1_pins_a &spi1_pins_b>;
pinctrl-1 = <&spi1_pins_c>;
pinctrl-names = "default", "sleep";
spi_slave_mode = <0>;
spi_dbi_enable = <0>;
spi1_cs_number = <1>;
spi1_cs_bitmap = <1>;
status = "okay";
spi_board1@0 {
device_type = "spi_board1";//"spi_dbi";
compatible = "rohm,dh2228fv";
spi-max-frequency = <0x5f5e100>;
reg = <0x0>;
spi-rx-bus-width = <0x4>;
spi-tx-bus-width = <0x4>;
status = "disabled";
};
st77916@0{
//compatible = "rohm,dh2228fv"; /* 兼容性字符串,指定使用的设备驱动程序 */ 、、用则个会生成spidev1.0
compatible = "sitronix,st77916";//这个也是跟着他配置的,在spidev.c里也添加了
[ins]
/*
static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "rohm,dh2228fv" },
{ .compatible = "lineartechnology,ltc2488" },
{ .compatible = "sitronix,st77916" },
{},
};
*/
[/ins]
//compatible = "lineartechnology,ltc2488";
reg = <0>;
status = "okay";
spi-max-frequency = <32000000>;
fps = <33>; /* 每秒帧数 (Frames Per Second),这里设置为33帧*/
rotate = <0>;
buswidth = <8>; /* 总线宽度,这里设定为4位 */
//dc-gpios = <&pio 3 1 GPIO_ACTIVE_HIGH>; /* 数据/命令引脚,指向第3组GPIO的第1个引脚,活动高电平 */
reset-gpios = <&pio 3 8 GPIO_ACTIVE_HIGH>; /* 复位引脚,指向第3组GPIO的第8个引脚,活动高电平 */
led-gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* LED引脚,指向第3组GPIO的第20个引脚,活动高电平 */
debug = <0x0>;
};
};
通过make kernel_menuconfig 配置了
Device Drivers --->SPI support -》SUNXI SPI Controller (不配置这个会报错,make不成功)
-》User mode SPI device driver support(之前配置spi设备时,配置的)
Device Drivers --->Graphics support ---> Frame buffer Devices ---><*> Support for frame buffer devices --->(就只配置了这个,要不然下面的不会出现)
Device Drivers ---> [*] Staging drivers ---><*> Support for small TFT LCD display modules(第二个配置了才会出现) ---> <*> FB driver for the ST77916 LCD Controller 和 <*> Module to for adding FBTFT devices
然后我只想lvgl例程就卡在了sunxifb_init()这里打不开/dev/fb0(报错没有这个文件),我的dev下根本没有fb0,有一个spidev1.0,用spidev1.0报错 no a tty
问题应该就是没有生成fb0,需要哪些配置吗?
页次: 1