/**
* @file lv_port_disp.c
*
*/
/*Copy this file as "lv_port_disp.c" and set this value to "1" to enable content*/
#if 1
/*********************
* INCLUDES
*********************/
#include "lv_port_disp.h"
#include "SWM320.h"
#include "dev_rgblcd.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void disp_init(void);
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
/**********************
* STATIC VARIABLES
**********************/
//.SDRAM 段定义在 SWM320_stdperiph_lib.sct.Bak(16行) => 仅定义了放置在 SDRAM 的范围内(默认 从低地址放起)
//static uint32_t LCD_GUI_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((section(".SDRAM")));
//static uint32_t LCD_Show_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((section(".SDRAM")));
// 数组除于 2 的原因是因为在 lv_color.h 中定义的 lv_color_t 变量为 uint16_t
/* 详见:
* #elif LV_COLOR_DEPTH == 16
* typedef uint16_t lv_color_int_t;
* typedef lv_color16_t lv_color_t;
*/
#if 0// 480 * 272 全屏缓冲区参数
static uint32_t LCD_GUI_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE))) = {0x00000000};
// 该数组内存占用 4B * 480 * 272 / 2 = 0x3FC00 => 255 KB
static uint32_t LCD_Show_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE + 0x3FC00))) = {0x00000000};
// 0x3FC00 + 0x3FC00 = 0x7F800 => 510 KB
#endif
#if 1// 800 * 480 全屏缓冲区参数
#define LCD_FRAME_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX * 2)
static uint32_t LCD_GUI_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE))) = {0x00000000};
// 该数组内存占用 4B * 800 * 480 / 2 = 0xBB800 => 750 KB
static uint32_t LCD_Show_FBuffer[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE + 0xBB800))) = {0x00000000};
// 0xBB800 + 0xBB800 = 0x177000 => 1500 KB
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_port_disp_init(void)
{
/*-------------------------
* Initialize your display
* -----------------------*/
disp_init();
/*-----------------------------
* Create a buffer for drawing
*----------------------------*/
/* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row
*
* There are three buffering configurations:
* 1. Create ONE buffer with some rows:
* LittlevGL will draw the display's content here and writes it to your display
*
* 2. Create TWO buffer with some rows:
* LittlevGL will draw the display's content to a buffer and writes it your display.
* You should use DMA to write the buffer's content to the display.
* It will enable LittlevGL to draw the next part of the screen to the other buffer while
* the data is being sent form the first buffer. It makes rendering and flushing parallel.
*
* 3. Create TWO screen-sized buffer:
* Similar to 2) but the buffer have to be screen sized. When LittlevGL is ready it will give the
* whole frame to display. This way you only need to change the frame buffer's address instead of
* copying the pixels.
* */
static lv_disp_buf_t disp_buf;
/* //双缓冲区
#ifdef SWM_USING_SRAM
static lv_color_t lcdbuf_1[LV_HOR_RES_MAX * LV_VER_RES_MAX] __attribute__((at(SRAMM_BASE))) = {0x00000000};
static lv_color_t lcdbuf_2[LV_HOR_RES_MAX * LV_VER_RES_MAX] __attribute__((at(SRAMM_BASE + 0x3FC00))) = {0x00000000};
#endif
#ifdef SWM_USING_SDRAM
static uint32_t lcdbuf_1[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE))) = {0x00000000};
static uint32_t lcdbuf_2[LV_HOR_RES_MAX * LV_VER_RES_MAX / 2] __attribute__((at(SDRAMM_BASE + 0xBB800))) = {0x00000000};
#endif
lv_disp_buf_init(&disp_buf, lcdbuf_1, lcdbuf_2, LV_HOR_RES_MAX * LV_VER_RES_MAX); //Initialize the display buffer
*/
static lv_color_t buf2_1[LV_HOR_RES_MAX * 10]; //A buffer for 10 rows
static lv_color_t buf2_2[LV_HOR_RES_MAX * 10]; //An other buffer for 10 rows
lv_disp_buf_init(&disp_buf, buf2_1, buf2_2, LV_HOR_RES_MAX * 10); //Initialize the display buffer
//lv_disp_buf_init(&disp_buf, LCD_Show_FBuffer, LCD_GUI_FBuffer, LV_HOR_RES_MAX * LV_VER_RES_MAX); //Initialize the display buffer
/*-----------------------------------
* 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 up the functions to access to your display*/
/*Set the resolution of the display*/
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Set a display buffer*/
disp_drv.buffer = &disp_buf;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
/* Initialize your display and the required peripherals. */
static void disp_init(void)
{
/*You code here*/
LCD_TFT_Init();
LCD->SRCADDR = (uint32_t)LCD_GUI_FBuffer;//改为 LCD_GUI_FBuffer 会导致出现刷窗帘的效果
LCD_Start(LCD);
// LCD_Start(LCD);
// NVIC_EnableIRQ(LCD_IRQn);
}
/*
memcpy 搬运800*480*2,时间71ms,显示正常
按照uint32_T自写函数,搬运800*480*2,时间95ms,显示正常
按照uint8_T 自写函数,搬运800*480*2,时间300ms,显示颜色不对
按照uint16_T自写函数,搬运800*480*2,时间150ms,显示颜色不对
*/
void gui2show(void)
{
// 800*480*2, 71ms
memcpy(LCD_Show_FBuffer,LCD_GUI_FBuffer,sizeof(LCD_GUI_FBuffer));
}
#define USE_MY_CODE
#define USE_RAM_RUN
#ifdef USE_MY_CODE
typedef union{
uint32_t d32;
struct{
uint16_t l16;
uint16_t h16;
}d16;
}LCDRAM_QBytes_t;
void MemCpy32(uint32_t* dest, uint32_t* src, uint32_t words)
{
while(words){
*dest++ = *src++;
words--;
}
}
#endif
#ifdef USE_RAM_RUN
#pragma arm section code = "RAMCODE"
#endif
#ifdef USE_MY_CODE
// 用于优化打点函数的行缓存
__align(4) uint16_t LineBuf[800];
#else
static inline void drawpoint(int16_t x, int16_t y, uint32_t c)
{
uint32_t temp = 0;
uint32_t index = (y*LV_HOR_RES+x) >> 1;
uint32_t pos = ((x%2) == 0 ? 0 : 16);
temp = LCD_GUI_FBuffer[index];
temp &= ~(0xFFFF << pos);
temp |= (c << pos);
LCD_GUI_FBuffer[index] = temp;
}
#endif
/* Flush the content of the internal buffer the specific area on the display
* You can use DMA or any hardware acceleration to do this operation in the background but
* 'lv_disp_flush_ready()' has to be called when finished. */
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
//把指定区域的显示缓冲区内容写入到屏幕
//LCD->SRCADDR = (uint32_t)disp_drv->buffer->buf_act;
//LCD_Start(LCD);
#ifdef USE_MY_CODE
LCDRAM_QBytes_t t;
uint32_t vlines,hdps,i,h_sta_pos,h_end_pos,m;
// 前对齐,后未4字节对齐
if(((area->x1) % 2 == 0) && ((area->x2) % 2 == 0))
{
h_sta_pos = area->y1 * 800;
h_sta_pos += area->x1;
h_end_pos = area->y1 * 800;
h_end_pos += area->x2;
h_sta_pos /= 2;
h_end_pos /= 2; // 得到显存4字节为单位的偏移位置
vlines = area->y2 - area->y1;
vlines++;
hdps = area->x2 - area->x1;
hdps += 1;
m = hdps;
hdps ++;
hdps *= 2;
while(vlines)
{
//行缓存格式 xxxxxxxxx-
i = 0;
while(i<m){
LineBuf[i++] = color_p->full;
color_p++;
}
t.d32 = LCD_GUI_FBuffer[h_end_pos];
LineBuf[m] = t.d16.h16;
//MemCpy32(&LCD_GUI_FBuffer[h_st
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
华芯微特SWM32SRET6集成了TFT和内部的SDRAM,但是没有硬件加速单元,TFT没有硬件加速单元,而且无法使用DMA传输,这点太窝火了,LittleVGL驱动接口部分,只能使用纯软件打点,占用CPU资源,而且由于只能字访问SDRAM,由于使用的RGB565色彩模式,打点的时候,需要软件判断图形边界,然后做读-改-写的操作,进一步降低了FPS,本人在官方的打点函数进行了重写优化,有一定的效果,有兴趣的朋友可以下载测试一下,就只有lv_port_disp.c文件,配置的单缓冲,通过宏定义开关,可以将打点函数,加载到内存运行。
资源详情
资源评论
资源推荐
收起资源包目录
lv_port_disp.zip (1个子文件)
lv_port_disp.c 13KB
共 1 条
- 1
皮皮几
- 粉丝: 6
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论5