feat(gpu): add SWM341 gpu support (synwit)

* Update lv_gpu_stm32_dma2d.c

fix stm32 DMA2D blend。

* add SWM341 DMA2D support for lvgl

* add SWM341 DMA2D support for lvgl

* add SWM341 DMA2D support for lvgl

* add SWM341 DMA2D support for lvgl

* add SWM341 DMA2D support for lvgl
This commit is contained in:
woody
2022-04-25 21:13:19 +08:00
committed by GitHub
parent 95620285bd
commit 07b7eea56c
15 changed files with 388 additions and 7 deletions

View File

@@ -21,3 +21,4 @@ include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/nxp_vglite/lv_draw_nxp_vglite.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sdl/lv_draw_sdl.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/stm32_dma2d/lv_draw_stm32_dma2d.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/sw/lv_draw_sw.mk
include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk

View File

@@ -222,8 +222,8 @@ static void lv_draw_stm32_dma2d_blend_map(lv_color_t * dest_buf, const lv_area_t
DMA2D->FGMAR = (uint32_t)src_buf;
DMA2D->FGOR = src_stride - dest_w;
DMA2D->OMAR = (uint32_t)src_buf;
DMA2D->OOR = src_stride - dest_w;
DMA2D->OMAR = (uint32_t)dest_buf;
DMA2D->OOR = dest_stride - dest_w;
DMA2D->NLR = (dest_w << DMA2D_NLR_PL_Pos) | (dest_h << DMA2D_NLR_NL_Pos);
/*start transfer*/

View File

@@ -0,0 +1,6 @@
CSRCS += lv_gpu_swm341_dma2d.c
DEPPATH += --dep-path $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d
VPATH += :$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d
CFLAGS += "-I$(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/swm341_dma2d"

View File

@@ -0,0 +1,241 @@
/**
* @file lv_gpu_swm341_dma2d.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_gpu_swm341_dma2d.h"
#include "../../core/lv_refr.h"
#if LV_USE_GPU_SWM341_DMA2D
#include LV_GPU_SWM341_DMA2D_INCLUDE
/*********************
* DEFINES
*********************/
#if LV_COLOR_16_SWAP
#error "Can't use DMA2D with LV_COLOR_16_SWAP 1"
#endif
#if LV_COLOR_DEPTH == 8
#error "Can't use DMA2D with LV_COLOR_DEPTH == 8"
#endif
#if LV_COLOR_DEPTH == 16
#define LV_DMA2D_COLOR_FORMAT LV_SWM341_DMA2D_RGB565
#elif LV_COLOR_DEPTH == 32
#define LV_DMA2D_COLOR_FORMAT LV_SWM341_DMA2D_ARGB8888
#else
/*Can't use GPU with other formats*/
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_draw_swm341_dma2d_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area,
lv_color_t color);
static void lv_draw_swm341_dma2d_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa);
static void lv_draw_swm341_dma2d_img_decoded(lv_draw_ctx_t * draw, const lv_draw_img_dsc_t * dsc,
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Turn on the peripheral and set output color mode, this only needs to be done once
*/
void lv_draw_swm341_dma2d_init(void)
{
/*Enable DMA2D clock*/
SYS->CLKEN0 |= (1 << SYS_CLKEN0_DMA2D_Pos);
DMA2D->CR &= ~DMA2D_CR_WAIT_Msk;
DMA2D->CR |= (CyclesPerUs << DMA2D_CR_WAIT_Pos);
DMA2D->IF = 0xFF;
DMA2D->IE = (0 << DMA2D_IE_DONE_Pos);
/*set output colour mode*/
DMA2D->L[DMA2D_LAYER_OUT].PFCCR = (LV_DMA2D_COLOR_FORMAT << DMA2D_PFCCR_CFMT_Pos);
}
void lv_draw_swm341_dma2d_ctx_init(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
{
lv_draw_sw_init_ctx(drv, draw_ctx);
lv_draw_swm341_dma2d_ctx_t * dma2d_draw_ctx = (lv_draw_sw_ctx_t *)draw_ctx;
dma2d_draw_ctx->blend = lv_draw_swm341_dma2d_blend;
// dma2d_draw_ctx->base_draw.draw_img_decoded = lv_draw_swm341_dma2d_img_decoded;
dma2d_draw_ctx->base_draw.wait_for_finish = lv_gpu_swm341_dma2d_wait_cb;
}
void lv_draw_swm341_dma2d_ctx_deinit(lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx)
{
LV_UNUSED(drv);
LV_UNUSED(draw_ctx);
}
void lv_draw_swm341_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
{
lv_area_t blend_area;
if(!_lv_area_intersect(&blend_area, dsc->blend_area, draw_ctx->clip_area))
return;
bool done = false;
if(dsc->mask_buf == NULL && dsc->blend_mode == LV_BLEND_MODE_NORMAL && lv_area_get_size(&blend_area) > 100) {
lv_coord_t dest_stride = lv_area_get_width(draw_ctx->buf_area);
lv_color_t * dest_buf = draw_ctx->buf;
dest_buf += dest_stride * (blend_area.y1 - draw_ctx->buf_area->y1) + (blend_area.x1 - draw_ctx->buf_area->x1);
const lv_color_t * src_buf = dsc->src_buf;
if(src_buf) {
lv_draw_sw_blend_basic(draw_ctx, dsc);
lv_coord_t src_stride;
src_stride = lv_area_get_width(dsc->blend_area);
src_buf += src_stride * (blend_area.y1 - dsc->blend_area->y1) + (blend_area.x1 - dsc->blend_area->x1);
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_draw_swm341_dma2d_blend_map(dest_buf, &blend_area, dest_stride, src_buf, src_stride, dsc->opa);
done = true;
}
else if(dsc->opa >= LV_OPA_MAX) {
lv_area_move(&blend_area, -draw_ctx->buf_area->x1, -draw_ctx->buf_area->y1);
lv_draw_swm341_dma2d_blend_fill(dest_buf, dest_stride, &blend_area, dsc->color);
done = true;
}
}
if(!done) lv_draw_sw_blend_basic(draw_ctx, dsc);
}
static void lv_draw_swm341_dma2d_img_decoded(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t * dsc,
const lv_area_t * coords, const uint8_t * map_p, lv_img_cf_t color_format)
{
/*TODO basic ARGB8888 image can be handles here*/
lv_draw_sw_img_decoded(draw_ctx, dsc, coords, map_p, color_format);
}
static void lv_draw_swm341_dma2d_blend_fill(lv_color_t * dest_buf, lv_coord_t dest_stride, const lv_area_t * fill_area,
lv_color_t color)
{
/*Simply fill an area*/
int32_t area_w = lv_area_get_width(fill_area);
int32_t area_h = lv_area_get_height(fill_area);
#if 1
DMA2D->L[DMA2D_LAYER_OUT].COLOR = color.full;
DMA2D->L[DMA2D_LAYER_OUT].MAR = (uint32_t)dest_buf;
DMA2D->L[DMA2D_LAYER_OUT].OR = dest_stride - area_w;
DMA2D->NLR = ((area_w - 1) << DMA2D_NLR_NPIXEL_Pos) | ((area_h - 1) << DMA2D_NLR_NLINE_Pos);
/*start transfer*/
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
DMA2D->CR |= (3 << DMA2D_CR_MODE_Pos) |
(1 << DMA2D_CR_START_Pos);
#else
for(uint32_t y = 0; y < area_h; y++) {
for(uint32_t x = 0; x < area_w; x++) {
dest_buf[y * dest_stride + x] = color;
}
}
#endif
}
static void lv_draw_swm341_dma2d_blend_map(lv_color_t * dest_buf, const lv_area_t * dest_area, lv_coord_t dest_stride,
const lv_color_t * src_buf, lv_coord_t src_stride, lv_opa_t opa)
{
/*Simple copy*/
int32_t dest_w = lv_area_get_width(dest_area);
int32_t dest_h = lv_area_get_height(dest_area);
if(opa >= LV_OPA_MAX) {
#if 1
/*copy output colour mode, this register controls both input and output colour format*/
DMA2D->L[DMA2D_LAYER_FG].MAR = (uint32_t)src_buf;
DMA2D->L[DMA2D_LAYER_FG].OR = src_stride - dest_w;
DMA2D->L[DMA2D_LAYER_FG].PFCCR = (LV_DMA2D_COLOR_FORMAT << DMA2D_PFCCR_CFMT_Pos);
DMA2D->L[DMA2D_LAYER_OUT].MAR = (uint32_t)dest_buf;
DMA2D->L[DMA2D_LAYER_OUT].OR = dest_stride - dest_w;
DMA2D->NLR = ((dest_w - 1) << DMA2D_NLR_NPIXEL_Pos) | ((dest_h - 1) << DMA2D_NLR_NLINE_Pos);
/*start transfer*/
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
DMA2D->CR |= (0 << DMA2D_CR_MODE_Pos) |
(1 << DMA2D_CR_START_Pos);
#else
lv_color_t temp_buf[1024];
for(uint32_t y = 0; y < dest_h; y++) {
memcpy(temp_buf, &src_buf[y * src_stride], dest_w * sizeof(lv_color_t));
memcpy(&dest_buf[y * dest_stride], temp_buf, dest_w * sizeof(lv_color_t));
}
#endif
}
else {
DMA2D->L[DMA2D_LAYER_FG].MAR = (uint32_t)src_buf;
DMA2D->L[DMA2D_LAYER_FG].OR = src_stride - dest_w;
DMA2D->L[DMA2D_LAYER_FG].PFCCR = (LV_DMA2D_COLOR_FORMAT << DMA2D_PFCCR_CFMT_Pos)
/*alpha mode 2, replace with foreground * alpha value*/
| (2 << DAM2D_PFCCR_AMODE_Pos)
/*alpha value*/
| (opa << DMA2D_PFCCR_ALPHA_Pos);
DMA2D->L[DMA2D_LAYER_BG].MAR = (uint32_t)dest_buf;
DMA2D->L[DMA2D_LAYER_BG].OR = dest_stride - dest_w;
DMA2D->L[DMA2D_LAYER_BG].PFCCR = (LV_DMA2D_COLOR_FORMAT << DMA2D_PFCCR_CFMT_Pos);
DMA2D->L[DMA2D_LAYER_OUT].MAR = (uint32_t)dest_buf;
DMA2D->L[DMA2D_LAYER_OUT].OR = dest_stride - dest_w;
DMA2D->NLR = ((dest_w - 1) << DMA2D_NLR_NPIXEL_Pos) | ((dest_h - 1) << DMA2D_NLR_NLINE_Pos);
/*start transfer*/
DMA2D->CR &= ~DMA2D_CR_MODE_Msk;
DMA2D->CR |= (2 << DMA2D_CR_MODE_Pos) |
(1 << DMA2D_CR_START_Pos);
}
}
void lv_gpu_swm341_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx)
{
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
if(disp->driver && disp->driver->wait_cb) {
while(DMA2D->CR & DMA2D_CR_START_Msk) {
disp->driver->wait_cb(disp->driver);
}
}
else {
while(DMA2D->CR & DMA2D_CR_START_Msk);
}
lv_draw_sw_wait_for_finish(draw_ctx);
}
#endif

View File

@@ -0,0 +1,64 @@
/**
* @file lv_gpu_swm341_dma2d.h
*
*/
#ifndef LV_GPU_SWM341_DMA2D_H
#define LV_GPU_SWM341_DMA2D_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../misc/lv_color.h"
#include "../../hal/lv_hal_disp.h"
#include "../sw/lv_draw_sw.h"
#if LV_USE_GPU_SWM341_DMA2D
/*********************
* DEFINES
*********************/
#define LV_SWM341_DMA2D_ARGB8888 0
#define LV_SWM341_DMA2D_RGB888 1
#define LV_SWM341_DMA2D_RGB565 2
/**********************
* TYPEDEFS
**********************/
typedef lv_draw_sw_ctx_t lv_draw_swm341_dma2d_ctx_t;
struct _lv_disp_drv_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Turn on the peripheral and set output color mode, this only needs to be done once
*/
void lv_draw_swm341_dma2d_init(void);
void lv_draw_swm341_dma2d_ctx_init(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
void lv_draw_swm341_dma2d_ctx_deinit(struct _lv_disp_drv_t * drv, lv_draw_ctx_t * draw_ctx);
void lv_draw_swm341_dma2d_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
void lv_gpu_swm341_dma2d_wait_cb(lv_draw_ctx_t * draw_ctx);
/**********************
* MACROS
**********************/
#endif /*LV_USE_GPU_SWM341_DMA2D*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_GPU_SWM341_DMA2D_H*/