|
昨天下载了最最最新的LVGL源程序,移植了一把,显示的不对应该还是显示的接口没有处理好
下面是注册显示驱动器的代码
他们提供的F429探索板demo的程序是新建了tft和touchpad源文件及头文件,然后重新注册一个显示驱动,在这里面设置显示以及读取触摸的回调函数
例如tft
void tft_init(void)
{
static lv_color_t disp_buf1[TFT_HOR_RES * 40];
static lv_disp_buf_t buf;
lv_disp_buf_init(&buf, disp_buf1, NULL, TFT_HOR_RES * 40);
lv_disp_drv_init(&disp_drv);
/*Set the resolution of the display*/
disp_drv.hor_res = 480;
disp_drv.ver_res = 272;
disp_drv.buffer = &buf;
disp_drv.flush_cb = tft_flush;
disp_drv.set_px_cb = tft_set_px;
lv_disp_drv_register(&disp_drv);
}
标红的就是刷新以及填充像素的接口,这里是不使用硬件加速器的情况,否则跟硬件相关性太大了,不便移植
读取触摸很好理解,跟之前版本没什么变化
但是显示器这俩回调函数入口函数被实在看不懂什么意思
描述如下:
/** MANDATORY: Write the internal buffer (VDB) to the display. 'lv_disp_flush_ready()' has to be
* called when finished */
void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
/** OPTIONAL: Extend the invalidated areas to match with the display drivers requirements
* E.g. round `y` to, 8, 16 ..) on a monochrome display*/
void (*rounder_cb)(struct _disp_drv_t * disp_drv, lv_area_t * area);
/** OPTIONAL: Set a pixel in a buffer according to the special requirements of the display
* Can be used for color format not supported in LittelvGL. E.g. 2 bit -> 4 gray scales
* @note Much slower then drawing with supported color formats. */
void (*set_px_cb)(struct _disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa);
/** OPTIONAL: Called after every refresh cycle to tell the rendering and flushing time + the
* number of flushed pixels */
void (*monitor_cb)(struct _disp_drv_t * disp_drv, uint32_t time, uint32_t px);
比较常用的就是较大的字体的两个了
这是demo里面的例子
/**
* Flush a color buffer
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors
*/
static void tft_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
/*Return if the area is out the screen*/
if(area->x2 < 0) return;
if(area->y2 < 0) return;
if(area->x1 > lcddev.width - 1) return;
if(area->y1 > lcddev.height - 1) return;
/*Truncate the area to the screen*/
int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
int32_t act_x2 = area->x2 > lcddev.width - 1 ? lcddev.width - 1 : area->x2;
int32_t act_y2 = area->y2 > lcddev.height - 1 ? lcddev.height - 1 : area->y2;
...
}
尝试直接把color_p的full挨个填充到区域内是有问题的,值显示了一个小的条,而且可以看出是访问越界那种五彩斑斓的错误数据
找到了库里面的画点的调用
/**
* Put a pixel in the Virtual Display Buffer
* @param x pixel x coordinate
* @param y pixel y coordinate
* @param mask_p fill only on this mask (truncated to VDB area)
* @param color pixel color
* @param opa opacity of the area (0..255)
*/
void lv_draw_px(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
{
if(opa < LV_OPA_MIN) return;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
/*Pixel out of the mask*/
if(x < mask_p->x1 || x > mask_p->x2 || y < mask_p->y1 || y > mask_p->y2) {
return;
}
lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
uint32_t vdb_width = lv_area_get_width(&vdb->area);
/*Make the coordinates relative to VDB*/
x -= vdb->area.x1;
y -= vdb->area.y1;
if(disp->driver.set_px_cb) {
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width, x, y, color, opa);
} else {
bool scr_transp = false;
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
scr_transp = disp->driver.screen_transp;
#endif
lv_color_t * vdb_px_p = vdb->buf_act;
vdb_px_p += y * vdb_width + x;
if(scr_transp == false) {
if(opa == LV_OPA_COVER) {
*vdb_px_p = color;
} else {
*vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);
}
} else {
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
*vdb_px_p = color_mix_2_alpha(*vdb_px_p, (*vdb_px_p).ch.alpha, color, opa);
#endif
}
}
}
可以看到是首先调用的是填充像素函数
实现一下
static void tft_set_px(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
lv_color_t color, lv_opa_t opa)
这里的x,y可以理解应该是填充像素的位置,opa可以通过
if(opa < LV_OPA_MIN) return;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
得出应该是透明度吧,在极限值的时候显示底色还是直接显示颜色,即跳过不必要的计算
disp_drv应该是显示驱动器,看样子可以支持好多不同类型或者多个屏幕吧
buf应该是填充像素的缓存吧
buf_w是填充的宽度吧,不太明白
不知道大家有没有什么指导意见,欢迎一起讨论下
|
|