Luckfox Pico SPI驱动LCD模式下移植LVGL8.3记录

本文详细描述了如何在LuckfoxPico硬件平台上移植LCD显示驱动,涉及设备树文件修改、SPI通信配置和LVGL的集成,以实现在Linux虚拟机Ubuntu22.04LTS中显示和操作LCD屏幕。
摘要由CSDN通过智能技术生成

硬件平台:Luckfox Pico不带网口的那个硬件版本,LCD采用的是2.0in SPI驱动的LCD,显示芯片为ST7789VW,显示分辨率为320*240

软件平台:虚拟机中运行Ubuntu 22.04LTS

1. 首先第一步是移植LCD的驱动 

下面的步骤是参与的官方tutorial:https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-LVGL

(1) 首先确定LCD模块与Luckfox开发板的连接线,然后修改设备树文件,设备树文件的目录在:

/luckfox-pico/sysdrv/source/kernel/arch/arm/boot/dts

这个luckfox-pico是下载的SDK解压后的根目录。Luckfox Pico对应的设备树文件为:

rv1103g-luckfox-pico.dts

要处理的管脚包括LCD的控制引脚:

       // LCD_DC pin      
        gpio1pa2:gpio1pa2 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pa2>;
                regulator-name = "gpio1_pa2";
                regulator-always-on;
        };

      // LCD_CS pin
        gpio1pc0:gpio1pc0 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pc0>;
                regulator-name = "gpio1_pc0";
                regulator-always-on;
        };
      // LCD_RST pin
        gpio1pc3:gpio1pc3 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pc3>;
                regulator-name = "gpio1_pc3";
                regulator-always-on;
        };


      // LCD_BL pin
        gpio0pa4:gpio0pa4 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio0_pa4>;
                regulator-name = "gpio0_pa4";
                regulator-always-on;
        };


&pinctrl {

    // for LCD control

        gpio1-pa2 {
                gpio1_pa2:gpio1-pa2 {
                        rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        gpio1-pc0 {
                gpio1_pc0:gpio1-pc0 {
                        rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        gpio1-pc3 {
                gpio1_pc3:gpio1-pc3 {
                        rockchip,pins = <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };

        gpio0-pa4 {
                gpio0_pa4:gpio0-pa4 {
                        rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };


};

以及与SPI通信的管脚:

// /**********SPI**********/
&spi0 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&spi0m0_pins>;
        //cs-gpios = <&gpio1 RK_PC0 1>;
        // cs-gpios = <&gpio1 26 1>;
        #address-cells = <1>;
        #size-cells = <0>;
        //spidev@0 {
        //      compatible = "rockchip,spidev";
        //      spi-max-frequency = <1000000000>;
        //      reg = <0>;
        //};

  lcd: lcd@0{
        status = "okay";
        compatible = "sitronix,st7789v";
        reg = <0>;
        spi-max-frequency = <20000000>;
        spi-cpol;
        spi-cpha;
        rotate = <0>;
        fps = <30>;
        rgb;
        buswidth = <8>;

        cs = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;       //spi0_miso
        led = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;      //BL
        dc = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;      //DC
        reset = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>;    //RES

        debug = <0x7>;
        };
};


&pinctrl{
       spi0{

                spi0m0_pins: spi0m0-pins{
                        rockchip,pins =
                        // SPI0 CLK0
                        <1 RK_PC1 4 &pcfg_pull_none>,
                        // SPIO MISO is not useful hence can not be set
//                      <1 RK_PC3 6 &pcfg_pull_none>,
                        // SPIO MOSI
                        <1 RK_PC2 6 &pcfg_pull_none>;
                };
        };
};

有一点要注意的是它这里LCD的CS与主机的SPI管脚的MISO冲突了,在配置SPI的时候,千万不要打开MISO了,否则驱动异常(可通过dmesg查看打印信息看到冲突)。

另个,这块LCD屏上还有4个按键,为了使用它们,也把它们的管脚给使能了。设备树中添加的文件如下:

      // for key control
        gpio1pc7:gpio1pc7 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pc7>;
                regulator-name = "gpio1_pc7";
                regulator-always-on;
        };


        gpio1pc6:gpio1pc6 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pc6>;
                regulator-name = "gpio1_pc6";
                regulator-always-on;
        };


        gpio1pd1:gpio1pd1 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio1_pd1>;
                regulator-name = "gpio1_pd1";
                regulator-always-on;
        };

        gpio4pb0:gpio4pb0 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&gpio4_pb0>;
                regulator-name = "gpio4_pb0";
                regulator-always-on;
        };

&pinctrl {

        gpio1-pc7 {
                gpio1_pc7:gpio1-pc7 {
                        rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };

        gpio1-pc6 {
                gpio1_pc6:gpio1-pc6 {
                        rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };

        gpio1-pd1 {
                gpio1_pd1:gpio1-pd1 {
                        rockchip,pins = <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };

        gpio4-pb0 {
                gpio4_pb0:gpio4-pb0 {
                        rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
};

多余的IO口跟不需要的功能,如IIC等,能去掉的就去掉

(2) 添加FB的支持:

在下面的目录中找到config文件:

luckfox-pico/sysdrv/source/kernel/arch/arm/configs/luckfox_rv1106_linux_defconfig

添加FB的支持:

CONFIG_SPI_MASTER=y
CONFIG_FB=y

(3)完成上述步骤后,可以make image了,将生成的Image烧录到SD卡上后启动系统。然后将开发板上电,利用adb shell登陆到开发板上后可以查看FB驱动是否正常:

如果先前有在LCD上显示过内容,那么输入下面的指令后会看到大量的输出:

dmesg | grep fb_

输出如下:

[   62.298523] fb_st7789v spi0.0: Display update: 1520 kB/s, fps=1
[   62.335201] fb_st7789v spi0.0: fbtft_update_display(start_line=34, end_line=290)
[   62.335249] fb_st7789v spi0.0: fbtft_write_reg8_bus8: 2a 00 00 00 ef
[   62.335296] fb_st7789v spi0.0: fbtft_write_spi(len=1): 2a
[   62.335372] fb_st7789v spi0.0: fbtft_write_spi(len=4): 00 00 00 ef
[   62.339520] fb_st7789v spi0.0: fbtft_write_reg8_bus8: 2b 00 22 01 22
[   62.339555] fb_st7789v spi0.0: fbtft_write_spi(len=1): 2b
[   62.339612] fb_st7789v spi0.0: fbtft_write_spi(len=4): 00 22 01 22
[   62.341238] fb_st7789v spi0.0: fbtft_write_reg8_bus8: 2c
[   62.341278] fb_st7789v spi0.0: fbtft_write_spi(len=1): 2c
[   62.341326] fb_st7789v spi0.0: fbtft_write_vmem16_bus8(offset=16320, len=123360)
[   62.341387] fb_st7789v spi0.0: fbtft_write_spi(len=4096): f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be f7 be ...
[   62.346744] fb_st7789v spi0.0: fbtft_write_spi(len=4096): 21 49 21 49 19 49 29 8a 29 8b 29 ab 39 ec 42 4d 29 8a 29 8a 21 49 42 2c 29 69 29 69 21 48 31 aa ...
[   62.348924] fb_st7789v spi0.0: fbtft_write_spi(len=4096): 18 e7 18 e8 18 c7 18 e7 20 e8 21 09 29 29 39 8b 41 cd 49 ee 41 cd 41 cd 39 8c 31 6b 39 ac 4a 0e ...
[   62.351013] fb_st7789v spi0.0: fbtft_write_spi(len=4096): 31 ab 42 0d 39 cc 31 ab 31 8b 41 ed 42 2d 41 ec 39 cc 41 ed 52 90 42 0d 42 0e 39 ed 42 2e 42 0e ...
[   62.353523] fb_st7789v spi0.0: fbtft_write_spi(len=4096): 41 ad 31 2b 29 09 39 cc 39 cc 31 8b 29 29 31 6a 31 8b 29 09 29 29 31 6a 31 49 29 28 31 49 39 cc ...
[   62.355524] fb_st7789v spi0.0: fbtft_write_spi(len=4096): 94 37 9c 98 4a 2e 39 8b 39 8b 39 8a 31 6a 39 ab 41 ab 39 ab 39 ab 39 aa 39 aa 39 8a 31 69 31 49 ...

利用下面的指令可以检测屏上显示是否正常,下面的指令可以令屏幕显示花屏:

cat /dev/urandom > /dev/fb0

下面的指令可以清屏:

cat /dev/zero > /dev/fb0

由于是采用SPI驱动显示的,在更新屏幕的时候,是明显的可以看到屏幕的扫描过程中,比较的慢。上述过程完成了LCD的驱动移植,下面移植LVGL

2. 移植LVGL

LVGL的移植相对容易,官方给出了基于FB的一个demo,直接clone到本地编译就能成功。地址为:Embedded GUI Using Linux Frame Buffer Device with LVGL | LVGL’s Blog

输入以下指令,先把demo工程拷贝下来:

git clone https://github.com/lvgl/lv_port_linux_frame_buffer.git

git clone --recurse-submodules

这样就能下载所有的LVGL相关的库文件,如果编译环境搭得没有问题的话,那个这个时候,在Makefile里面指定好GCC编译器的位置后,就能直接编译出demo程序了:

为了偷个懒,不去移植硬件相 关的驱动程序,我这里直接把Luckfox pico官方的那个LVGL 8.1版本的文件都拷到了demo工程来了,除了与lvgl配置相关的文件,包括lv_conf.h以及lv_drv_conf.h,这两个文件要用新,老版本跟新版本差别很大:

利用LVGL新版本,即8.3库里面自带的template来做配置

cp lvgl/lvgl/lv_conf_template.h ./lv_conf.h
cp lvgl/lv_drivers/lv_drv_conf_template.h  ./lv_drv_conf.h

第一个要改的是使能文件配置:

/* clang-format off */
#if 1 /*Set it to "1" to enable content*/

再来修改下LCD的color depth,这里用的是65K的LCD,那么是16bit的,所以这个也要改:

/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16

将TICK的函数名与main.c中的函数名写得一致:

#define LV_TICK_CUSTOM 1
#if LV_TICK_CUSTOM
    #define LV_TICK_CUSTOM_INCLUDE <stdint.h>         /*Header for the system time function*/
    #define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get())    /*Expression evaluating to current system time in ms*/
#endif   /*LV_TICK_CUSTOM*/

使能文件系统:

/*API for open, read, etc*/
#define LV_USE_FS_POSIX 1
#if LV_USE_FS_POSIX
    #define LV_FS_POSIX_LETTER 'A'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_POSIX_PATH ""         /*Set the working directory. File/directory paths will be appended to it.*/
    #define LV_FS_POSIX_CACHE_SIZE  0   /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

使能一些第三方的解码库文件:

/*PNG decoder library*/
#define LV_USE_PNG 1

/*BMP decoder library*/
#define LV_USE_BMP 1

/* JPG + split JPG decoder library.
 * Split JPG is a custom format optimized for embedded systems. */
#define LV_USE_SJPG 1

/*GIF decoder library*/
#define LV_USE_GIF 1

/*QR code library*/
#define LV_USE_QRCODE 1

再在lv_drv_conf.h中使能FB并指定FB的名称:

/*-----------------------------------------
 *  Linux frame buffer device (/dev/fbx)
 *-----------------------------------------*/
#ifndef USE_FBDEV
#  define USE_FBDEV          1 
#endif

#if USE_FBDEV
#  define FBDEV_PATH          "/dev/fb0"
#endif

FB的设备名称可以这么来看

ls /dev/fb*

最后一步是在Makefile中加一项编译项:

CFLAGS                  += -D_DEFAULT_SOURCE

如果你是用的官方的makefile文件,那么下面的一行也要改一下,官方只有一个main source,其它的文件都没有加的:

#Collect the files to compile
MAINSRC = $(wildcard ./*.c)

main.c函数里面还有些要改的内容,就是LCD显示的大小:

#define DISP_BUF_SIZE (320 * 240)

    /*Initialize and register a display driver*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf   = &disp_buf;
    disp_drv.flush_cb   = fbdev_flush;
    disp_drv.hor_res    = 240;
    disp_drv.ver_res    = 320;
    lv_disp_drv_register(&disp_drv);

至此,可以make生成工程。

大家可以看下我的显示效果,按不同的键可以显示不同的照片:

LuckFox Pico是一款基于ARM架构的嵌入式开发板,它支持烧录Linux操作系统。下面是烧录LinuxLuckFox Pico的一般步骤: 1. 准备开发环境:首先,你需要安装交叉编译工具链和相关的开发工具,例如GCC编译器、Make工具等。 2. 获取Linux内核源代码:你可以从Linux内核官方网站或者其他适配了LuckFox Pico的开源项目中获取适用于该开发板的Linux内核源代码。 3. 配置内核:进入内核源代码目录,使用交叉编译工具链进行配置。你可以使用make menuconfig命令来选择适合LuckFox Pico的配置选项,例如选择正确的处理器架构、设备驱动等。 4. 编译内核:使用make命令进行内核编译。这个过程可能需要一些时间,取决于你的电脑性能和内核源代码的大小。 5. 生成根文件系统:除了内核,你还需要一个根文件系统来运行Linux。你可以选择使用已有的根文件系统,或者自己构建一个。根文件系统包含了Linux所需的各种库、工具和配置文件。 6. 烧录内核和根文件系统:将编译好的内核和根文件系统烧录到LuckFox Pico的存储介质中,例如SD卡或者eMMC。你可以使用烧录工具,如dd命令或者专门的烧录软件来完成这个步骤。 7. 启动LuckFox Pico:将烧录好的存储介质插入LuckFox Pico,然后通过串口或者其他方式连接到开发板。启动开发板后,它将加载内核并运行Linux操作系统。 希望以上步骤对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值