在线时间372 小时
UID3135871
注册时间2016-10-9
NXP金币20
TA的每日心情 | 怒 2024-2-5 12:06 |
---|
签到天数: 627 天 [LV.9]以坛为家II
版主
- 积分
- 4429
- 最后登录
- 2024-2-5
|
本帖最后由 胤幻1988 于 2020-12-23 12:59 编辑
今天有空,弄下littleVGL,虽然看到坛里已经有人移植了,但是不自己动手做一遍,将来难保不会出现什么问题。有点受够了MCUXpresso的配置及生成代码的一些莫名的bug。我先转战MDK了,当然我不想浪费它的toolconfig功能,我还是保留它配置的一些外设及程序的框架。这样用toolconfig配置的外设代码也可直接用。 我们直接在官方的littleVGL MDK例程上面修改,替换了board下面的外设的配置,把符合我们开发板的配置写进去。为了更好的移植性,每个外设的引脚配置和外设本身的配置不直接放在pin_mux和peripherals里面,直接打散,放到各种对应的独立的外设文件里面。吐槽一下载ST的Cubemx里面就可以设置,是否为每个外设独立分配文件,但是NXP的却不提供这种配置需求。配置好的程序目录如下:
我们使用新的外设时,先用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指令):
- ili9341_lcd_writ_cmd(0x36); // Memory Access Control
- //ili9341_lcd_writ_data(0x08); //竖屏幕
- ili9341_lcd_writ_data((1<<5)|(0<<6)|(1<<7)|(1<<3));//左横屏
- //ili9341_lcd_writ_data((1<<5)|(1<<6));右横屏幕
- ili9341_lcd_writ_cmd(0x2B); //set the page address 横屏幕设置
- ili9341_lcd_writ_data(0x00);
- ili9341_lcd_writ_data(0x00);
- ili9341_lcd_writ_data(0x00);
- ili9341_lcd_writ_data(0xEF);
- ili9341_lcd_writ_cmd(0x2A); //set the column address
- ili9341_lcd_writ_data(0x00);
- ili9341_lcd_writ_data(0x00);
- ili9341_lcd_writ_data(0x01);
- ili9341_lcd_writ_data(0x3F);
- //ili9341_lcd_writ_cmd(0x2A); //set the page address 竖屏幕设置
- //ili9341_lcd_writ_data(0x00);
- //ili9341_lcd_writ_data(0x00);
- //ili9341_lcd_writ_data(0x00);
- //ili9341_lcd_writ_data(0xEF);
- //ili9341_lcd_writ_cmd(0x2B); //set the column address
- //ili9341_lcd_writ_data(0x00);
- //ili9341_lcd_writ_data(0x00);
- //ili9341_lcd_writ_data(0x01);
- //ili9341_lcd_writ_data(0x3F);
复制代码 littlevgl用的是横屏,我们先把屏设置成横屏。如果不想在这里调节,官方自带库,里面EVK板子也是用的ili9341,里面有匹配好了的fsl_ili9341文件,直接调用里面的代码也可以,理论上是一样的。
littlevgl_support.C 里面把LCD驱动和触摸驱动填到对应函数当中(主意触摸坐标也实际屏坐标位置的对应关系):
- /*
- * Copyright 2019-2020 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "littlevgl_support.h"
- #include "lvgl.h"
- #if defined(FSL_RTOS_FREE_RTOS)
- #include "FreeRTOS.h"
- #include "semphr.h"
- #endif
- #include "littlevgl_support.h"
- #include "fsl_gpio.h"
- #include "fsl_debug_console.h"
- #include "fsl_ili9341.h"
- #include "ili9341_lcd.h"
- #include "ft6366_touch.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- static void DEMO_InitLcd(void);
- static void DEMO_InitTouch(void);
- static bool DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data);
- static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- #if defined(FSL_RTOS_FREE_RTOS)
- static SemaphoreHandle_t s_transferDone;
- #else
- static volatile bool s_transferDone;
- #endif
- SDK_ALIGN(static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL], 4);
- /*******************************************************************************
- * Code
- ******************************************************************************/
- void lv_port_pre_init(void)
- {
- }
- static void DEMO_SPI_LCD_WriteCmd(uint8_t Data)
- {
- ili9341_lcd_writ_cmd(Data);
- }
- static void DEMO_SPI_LCD_WriteData(uint8_t Data)
- {
- ili9341_lcd_writ_data(Data);
- }
- static void DEMO_SPI_LCD_WriteMultiData(const uint8_t* pData, int NumItems)
- {
- ili9341_lcd_writ_databuf8((uint8_t*)pData,NumItems);
- }
- static void DEMO_InitLcd(void)
- {
- ili9341_lcd_init();
- FT9341_Init(DEMO_SPI_LCD_WriteData, DEMO_SPI_LCD_WriteCmd);
- /* Change to landscape view. */
- DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_MAC);
- DEMO_SPI_LCD_WriteData(0x28);
- }
- void lv_port_disp_init(void)
- {
- static lv_disp_buf_t disp_buf;
- memset(s_frameBuffer, 0, sizeof(s_frameBuffer));
- lv_disp_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_VIRTUAL_BUF_SIZE);
- /*-------------------------
- * Initialize your display
- * -----------------------*/
- DEMO_InitLcd();
- /*-----------------------------------
- * Register the display in LittlevGL
- *----------------------------------*/
- lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
- lv_disp_drv_init(&disp_drv); /*Basic initialization*/
- /*Set the resolution of the display*/
- disp_drv.hor_res = LCD_WIDTH;
- disp_drv.ver_res = LCD_HEIGHT;
- /*Used to copy the buffer's content to the display*/
- disp_drv.flush_cb = DEMO_FlushDisplay;
- /*Set a display buffer*/
- disp_drv.buffer = &disp_buf;
- /*Finally register the driver*/
- lv_disp_drv_register(&disp_drv);
- }
- static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
- {
- lv_coord_t x1 = area->x1;
- lv_coord_t y1 = area->y1;
- lv_coord_t x2 = area->x2;
- lv_coord_t y2 = area->y2;
- uint8_t data[4];
- const uint8_t *pdata = (const uint8_t *)color_p;
- uint32_t send_size = (x2 - x1 + 1) * (y2 - y1 + 1) * LCD_FB_BYTE_PER_PIXEL;
- /*Column addresses*/
- DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_COLADDR);
- data[0] = (x1 >> 8) & 0xFF;
- data[1] = x1 & 0xFF;
- data[2] = (x2 >> 8) & 0xFF;
- data[3] = x2 & 0xFF;
- DEMO_SPI_LCD_WriteMultiData(data, 4);
- /*Page addresses*/
- DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_PAGEADDR);
- data[0] = (y1 >> 8) & 0xFF;
- data[1] = y1 & 0xFF;
- data[2] = (y2 >> 8) & 0xFF;
- data[3] = y2 & 0xFF;
- DEMO_SPI_LCD_WriteMultiData(data, 4);
- /*Memory write*/
- DEMO_SPI_LCD_WriteCmd(ILI9341_CMD_GRAM);
- DEMO_SPI_LCD_WriteMultiData(pdata, send_size);
- lv_disp_flush_ready(disp_drv);
- }
- void lv_port_indev_init(void)
- {
- lv_indev_drv_t indev_drv;
- /*------------------
- * Touchpad
- * -----------------*/
- /*Initialize your touchpad */
- DEMO_InitTouch();
- /*Register a touchpad input device*/
- lv_indev_drv_init(&indev_drv);
- indev_drv.type = LV_INDEV_TYPE_POINTER;
- indev_drv.read_cb = DEMO_ReadTouch;
- lv_indev_drv_register(&indev_drv);
- }
- /*Initialize your touchpad*/
- static void DEMO_InitTouch(void)
- {
- ft6366_i2ctouch_Init();
- }
- /* Will be called by the library to read the touchpad */
- static bool DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
- {
- data->state = LV_INDEV_STATE_REL;
- ft6336_i2ctouch_scan();
- if(ftf6336_tpr_structure.touchsta.all != 0)
- {
- data->state = LV_INDEV_STATE_PR;
- }
- /*Set the last pressed coordinates*/
- //data->point.x = LCD_WIDTH - ftf6336_tpr_structure.y[0];
- //data->point.y = ftf6336_tpr_structure.x[0];
-
- data->point.x = ftf6336_tpr_structure.y[0];
- data->point.y = LCD_HEIGHT-ftf6336_tpr_structure.x[0];
- /*Return `false` because we are not buffering and no more data to read*/
- return false;
- }
复制代码 littlevgl_support.h
- /*
- * Copyright 2019 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #ifndef LITTLEVGL_SUPPORT_H
- #define LITTLEVGL_SUPPORT_H
- #include <stdint.h>
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #define LCD_WIDTH 320
- #define LCD_HEIGHT 240
- #define LCD_FB_BYTE_PER_PIXEL 2
- /* The virtual buffer for DBI panel, it should be ~1/10 screen size. */
- #define LCD_VIRTUAL_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT / 10)
- /*******************************************************************************
- * API
- ******************************************************************************/
- #ifdef __cplusplus
- extern "C" {
- #endif
- void lv_port_pre_init(void);
- void lv_port_disp_init(void);
- void lv_port_indev_init(void);
- #if defined(__cplusplus)
- }
- #endif
- #endif /*LITTLEVGL_SUPPORT_H */
复制代码 配置好了后,我们调用litlevgl的一个模版来,显示,看看显示效果怎么样:
第一个键盘,可输入,很漂亮:
第二个滑动菜单:
第三个图表:
看着挺好的。下面又项目,一定要用用它。连着移植了2个GUI,我们发现其实这些个GUI移植起来其实并不难,只要把它给出的交互接口匹配成我们硬件上的就可以了。好了,littlevgl的移植就到这了。谢谢观看,也希望NXP的MCUXpresso 能够做的更好,那时我还是很愿意用它的。
|
|