查看: 1488|回复: 1

[分享] 逐飞LPC55S69 IOT开发板之lillleVGL移植及测试

[复制链接]
  • TA的每日心情

    2024-2-5 12:06
  • 签到天数: 627 天

    [LV.9]以坛为家II

    94

    主题

    1628

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4429

    热心会员

    最后登录
    2024-2-5
    发表于 2020-12-23 12:49:04 | 显示全部楼层 |阅读模式
    本帖最后由 胤幻1988 于 2020-12-23 12:59 编辑

           今天有空,弄下littleVGL,虽然看到坛里已经有人移植了,但是不自己动手做一遍,将来难保不会出现什么问题。有点受够了MCUXpresso的配置及生成代码的一些莫名的bug。我先转战MDK了,当然我不想浪费它的toolconfig功能,我还是保留它配置的一些外设及程序的框架。这样用toolconfig配置的外设代码也可直接用。      我们直接在官方的littleVGL MDK例程上面修改,替换了board下面的外设的配置,把符合我们开发板的配置写进去。为了更好的移植性,每个外设的引脚配置和外设本身的配置不直接放在pin_mux和peripherals里面,直接打散,放到各种对应的独立的外设文件里面。吐槽一下载ST的Cubemx里面就可以设置,是否为每个外设独立分配文件,但是NXP的却不提供这种配置需求。配置好的程序目录如下:
        SS1.png
    我们使用新的外设时,先用toolconfig配置好它的代码,然后在在MDK的board文件夹下新建外设的h和C文件,然后把toolconfig配置的代码再移到MDK的board文件夹下新建外设的h和C文件里面。虽然有点小麻烦,但是还能接受。这样兼顾了我对二者的需求。
    官方的LCP55S69_EVK与我们的板子外设引脚有些许差异,LCD的驱动芯片一致,但触摸芯片不一样。然后它对这两者用的SPI和IIC都调用的CMSIS里面的SPI和IIC的文件。有点没用过,也不习惯,看不到源代码。
    关于LCD驱动,我用的是SPI的轮寻方式,之前在MCUXPresso上面,死活刷屏很慢。我把他原封不动的移植到MDK上面,却发现,刷屏正常,到目前也没明白啥问题。不去想了,搞的差点有点崩溃。
    用系统自带的库实现,速度也能接受:
    static uint8_t lcd_base_write_byte(uint8_t data)
    {
           
            SPI_WriteData(FLEXCOMM8_PERIPHERAL, data, kSPI_FrameDelay);//需应答
           //SPI_WriteData(FLEXCOMM8_PERIPHERAL, data, kSPI_FrameDelay|SPI_FIFOWR_RXIGNORE_MASK);
            while (1)
            {
                    //if rxFIFO is not empty
                    if ((FLEXCOMM8_PERIPHERAL->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)
                    {
                            return SPI_ReadData(FLEXCOMM8_PERIPHERAL);
                    }
            }
           
            return 0;
    }

    用寄存器实现,速度可能更快些:
    static uint8_t lcd_base_write_byte(uint8_t data)
    {
        uint32_t temp;
        /* send byte */
        FLEXCOMM8_PERIPHERAL->FIFOWR = data | 0x07300000;
        /* wait if TX FIFO of previous transfer is not empty */
        while ((FLEXCOMM8_PERIPHERAL->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK) == 0) {
        }
        temp = (FLEXCOMM8_PERIPHERAL->FIFORD)&0x000000FF;
        return temp;
    }



    复制代码
    对ili9341控制的LCD屏幕的方向进行切换(给出横竖屏及扫描起点的设置。主要是0X36指令):
    1. ili9341_lcd_writ_cmd(0x36);    // Memory Access Control
    2.         //ili9341_lcd_writ_data(0x08); //竖屏幕
    3.         ili9341_lcd_writ_data((1<<5)|(0<<6)|(1<<7)|(1<<3));//左横屏
    4.         //ili9341_lcd_writ_data((1<<5)|(1<<6));右横屏幕

    5.         ili9341_lcd_writ_cmd(0x2B);     //set the page address 横屏幕设置
    6.         ili9341_lcd_writ_data(0x00);
    7.         ili9341_lcd_writ_data(0x00);
    8.         ili9341_lcd_writ_data(0x00);
    9.         ili9341_lcd_writ_data(0xEF);
    10.         ili9341_lcd_writ_cmd(0x2A);    //set the column address
    11.         ili9341_lcd_writ_data(0x00);
    12.         ili9341_lcd_writ_data(0x00);
    13.         ili9341_lcd_writ_data(0x01);
    14.         ili9341_lcd_writ_data(0x3F);

    15. //ili9341_lcd_writ_cmd(0x2A);     //set the page address 竖屏幕设置
    16. //ili9341_lcd_writ_data(0x00);
    17. //ili9341_lcd_writ_data(0x00);
    18. //ili9341_lcd_writ_data(0x00);
    19. //ili9341_lcd_writ_data(0xEF);
    20. //ili9341_lcd_writ_cmd(0x2B);    //set the column address
    21. //ili9341_lcd_writ_data(0x00);
    22. //ili9341_lcd_writ_data(0x00);
    23. //ili9341_lcd_writ_data(0x01);
    24. //ili9341_lcd_writ_data(0x3F);
    复制代码
    littlevgl用的是横屏,我们先把屏设置成横屏。如果不想在这里调节,官方自带库,里面EVK板子也是用的ili9341,里面有匹配好了的fsl_ili9341文件,直接调用里面的代码也可以,理论上是一样的。
    littlevgl_support.C 里面把LCD驱动和触摸驱动填到对应函数当中(主意触摸坐标也实际屏坐标位置的对应关系):
    1. /*
    2. * Copyright 2019-2020 NXP
    3. * All rights reserved.
    4. *
    5. * SPDX-License-Identifier: BSD-3-Clause
    6. */

    7. #include "littlevgl_support.h"
    8. #include "lvgl.h"
    9. #if defined(FSL_RTOS_FREE_RTOS)
    10. #include "FreeRTOS.h"
    11. #include "semphr.h"
    12. #endif


    13. #include "littlevgl_support.h"
    14. #include "fsl_gpio.h"
    15. #include "fsl_debug_console.h"

    16. #include "fsl_ili9341.h"
    17. #include "ili9341_lcd.h"
    18. #include "ft6366_touch.h"

    19. /*******************************************************************************
    20. * Definitions
    21. ******************************************************************************/



    22. /*******************************************************************************
    23. * Prototypes
    24. ******************************************************************************/
    25. static void DEMO_InitLcd(void);
    26. static void DEMO_InitTouch(void);
    27. static bool DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data);
    28. static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
    29. /*******************************************************************************
    30. * Variables
    31. ******************************************************************************/
    32. #if defined(FSL_RTOS_FREE_RTOS)
    33. static SemaphoreHandle_t s_transferDone;
    34. #else
    35. static volatile bool s_transferDone;
    36. #endif
    37. SDK_ALIGN(static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL], 4);
    38. /*******************************************************************************
    39. * Code
    40. ******************************************************************************/
    41. void lv_port_pre_init(void)
    42. {
    43. }


    44. static void DEMO_SPI_LCD_WriteCmd(uint8_t Data)
    45. {
    46.     ili9341_lcd_writ_cmd(Data);
    47. }

    48. static void DEMO_SPI_LCD_WriteData(uint8_t Data)
    49. {
    50.     ili9341_lcd_writ_data(Data);
    51. }

    52. static void DEMO_SPI_LCD_WriteMultiData(const uint8_t* pData, int NumItems)
    53. {
    54.     ili9341_lcd_writ_databuf8((uint8_t*)pData,NumItems);
    55. }

    56. static void DEMO_InitLcd(void)
    57. {
    58.         ili9341_lcd_init();
    59.     FT9341_Init(DEMO_SPI_LCD_WriteData, DEMO_SPI_LCD_WriteCmd);
    60.     /* Change to landscape view. */
    61.     DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_MAC);
    62.     DEMO_SPI_LCD_WriteData(0x28);
    63. }

    64. void lv_port_disp_init(void)
    65. {
    66.     static lv_disp_buf_t disp_buf;

    67.     memset(s_frameBuffer, 0, sizeof(s_frameBuffer));
    68.     lv_disp_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_VIRTUAL_BUF_SIZE);

    69.     /*-------------------------
    70.      * Initialize your display
    71.      * -----------------------*/
    72.     DEMO_InitLcd();

    73.     /*-----------------------------------
    74.      * Register the display in LittlevGL
    75.      *----------------------------------*/

    76.     lv_disp_drv_t disp_drv;      /*Descriptor of a display driver*/
    77.     lv_disp_drv_init(&disp_drv); /*Basic initialization*/

    78.     /*Set the resolution of the display*/
    79.     disp_drv.hor_res = LCD_WIDTH;
    80.     disp_drv.ver_res = LCD_HEIGHT;

    81.     /*Used to copy the buffer's content to the display*/
    82.     disp_drv.flush_cb = DEMO_FlushDisplay;

    83.     /*Set a display buffer*/
    84.     disp_drv.buffer = &disp_buf;

    85.     /*Finally register the driver*/
    86.     lv_disp_drv_register(&disp_drv);
    87. }

    88. static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
    89. {
    90.     lv_coord_t x1 = area->x1;
    91.     lv_coord_t y1 = area->y1;
    92.     lv_coord_t x2 = area->x2;
    93.     lv_coord_t y2 = area->y2;

    94.     uint8_t data[4];
    95.     const uint8_t *pdata = (const uint8_t *)color_p;
    96.     uint32_t send_size   = (x2 - x1 + 1) * (y2 - y1 + 1) * LCD_FB_BYTE_PER_PIXEL;

    97.     /*Column addresses*/
    98.     DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_COLADDR);
    99.     data[0] = (x1 >> 8) & 0xFF;
    100.     data[1] = x1 & 0xFF;
    101.     data[2] = (x2 >> 8) & 0xFF;
    102.     data[3] = x2 & 0xFF;
    103.     DEMO_SPI_LCD_WriteMultiData(data, 4);

    104.     /*Page addresses*/
    105.     DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_PAGEADDR);
    106.     data[0] = (y1 >> 8) & 0xFF;
    107.     data[1] = y1 & 0xFF;
    108.     data[2] = (y2 >> 8) & 0xFF;
    109.     data[3] = y2 & 0xFF;
    110.     DEMO_SPI_LCD_WriteMultiData(data, 4);

    111.     /*Memory write*/
    112.     DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_GRAM);
    113.     DEMO_SPI_LCD_WriteMultiData(pdata, send_size);

    114.     lv_disp_flush_ready(disp_drv);
    115. }

    116. void lv_port_indev_init(void)
    117. {
    118.     lv_indev_drv_t indev_drv;

    119.     /*------------------
    120.      * Touchpad
    121.      * -----------------*/

    122.     /*Initialize your touchpad */
    123.     DEMO_InitTouch();

    124.     /*Register a touchpad input device*/
    125.     lv_indev_drv_init(&indev_drv);
    126.     indev_drv.type    = LV_INDEV_TYPE_POINTER;
    127.     indev_drv.read_cb = DEMO_ReadTouch;
    128.     lv_indev_drv_register(&indev_drv);
    129. }

    130. /*Initialize your touchpad*/
    131. static void DEMO_InitTouch(void)
    132. {
    133.     ft6366_i2ctouch_Init();
    134. }

    135. /* Will be called by the library to read the touchpad */
    136. static bool DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
    137. {
    138.     data->state = LV_INDEV_STATE_REL;

    139.     ft6336_i2ctouch_scan();
    140.     if(ftf6336_tpr_structure.touchsta.all != 0)
    141.     {
    142.         data->state = LV_INDEV_STATE_PR;
    143.     }

    144.     /*Set the last pressed coordinates*/
    145.     //data->point.x = LCD_WIDTH - ftf6336_tpr_structure.y[0];
    146.     //data->point.y = ftf6336_tpr_structure.x[0];
    147.         
    148.         data->point.x = ftf6336_tpr_structure.y[0];
    149.     data->point.y = LCD_HEIGHT-ftf6336_tpr_structure.x[0];

    150.     /*Return `false` because we are not buffering and no more data to read*/
    151.     return false;
    152. }
    复制代码
    littlevgl_support.h
    1. /*
    2. * Copyright 2019 NXP
    3. * All rights reserved.
    4. *
    5. * SPDX-License-Identifier: BSD-3-Clause
    6. */

    7. #ifndef LITTLEVGL_SUPPORT_H
    8. #define LITTLEVGL_SUPPORT_H

    9. #include <stdint.h>
    10. /*******************************************************************************
    11. * Definitions
    12. ******************************************************************************/
    13. #define LCD_WIDTH             320
    14. #define LCD_HEIGHT            240
    15. #define LCD_FB_BYTE_PER_PIXEL 2
    16. /* The virtual buffer for DBI panel, it should be ~1/10 screen size. */
    17. #define LCD_VIRTUAL_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT / 10)

    18. /*******************************************************************************
    19. * API
    20. ******************************************************************************/

    21. #ifdef __cplusplus
    22. extern "C" {
    23. #endif

    24. void lv_port_pre_init(void);
    25. void lv_port_disp_init(void);
    26. void lv_port_indev_init(void);

    27. #if defined(__cplusplus)
    28. }
    29. #endif

    30. #endif /*LITTLEVGL_SUPPORT_H */
    复制代码
    配置好了后,我们调用litlevgl的一个模版来,显示,看看显示效果怎么样:
    第一个键盘,可输入,很漂亮:
    CC1.jpg
    第二个滑动菜单:
    CC2.jpg
    第三个图表:
    CC3.jpg
    看着挺好的。下面又项目,一定要用用它。连着移植了2个GUI,我们发现其实这些个GUI移植起来其实并不难,只要把它给出的交互接口匹配成我们硬件上的就可以了。好了,littlevgl的移植就到这了。谢谢观看,也希望NXP的MCUXpresso 能够做的更好,那时我还是很愿意用它的。









    哎...今天够累的,签到来了~
    回复

    使用道具 举报

    该用户从未签到

    35

    主题

    356

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2576
    最后登录
    2023-6-23
    发表于 2020-12-26 10:35:53 | 显示全部楼层
    不错,过几天也玩一把
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-26 19:07 , Processed in 0.107322 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表