From 07b7eea56c048a0654c254cadebee8caf5f7933b Mon Sep 17 00:00:00 2001 From: woody Date: Mon, 25 Apr 2022 21:13:19 +0800 Subject: [PATCH] feat(gpu): add SWM341 gpu support (synwit) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- Kconfig | 14 +- README.md | 3 +- README_zh.md | 3 +- docs/intro/index.md | 2 +- env_support/cmsis-pack/LVGL.lvgl.pdsc | 14 + env_support/cmsis-pack/lv_conf_cmsis.h | 5 + lv_conf_template.h | 6 + src/core/lv_obj.c | 9 + src/draw/lv_draw.mk | 1 + src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c | 4 +- src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk | 6 + src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c | 241 ++++++++++++++++++ src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h | 64 +++++ src/hal/lv_hal_disp.c | 5 + src/lv_conf_internal.h | 18 ++ 15 files changed, 388 insertions(+), 7 deletions(-) create mode 100644 src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk create mode 100644 src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c create mode 100644 src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h diff --git a/Kconfig b/Kconfig index 658d8af57..a39144309 100644 --- a/Kconfig +++ b/Kconfig @@ -210,12 +210,12 @@ menu "LVGL configuration" config LV_USE_GPU_ARM2D bool "Enable Arm's 2D image processing library (Arm-2D) for all Cortex-M processors." - config LV_USE_GPU_STM32_DMA2D - bool "Enable STM32 DMA2D (aka Chrom Art) GPU." default n help Must deploy arm-2d library to your project and add include PATH for "arm_2d.h". + config LV_USE_GPU_STM32_DMA2D + bool "Enable STM32 DMA2D (aka Chrom Art) GPU." config LV_GPU_DMA2D_CMSIS_INCLUDE string "include path of CMSIS header of target processor" depends on LV_USE_GPU_STM32_DMA2D @@ -224,6 +224,16 @@ menu "LVGL configuration" Must be defined to include path of CMSIS header of target processor e.g. "stm32f769xx.h" or "stm32f429xx.h" + config LV_USE_GPU_SWM341_DMA2D + bool "Enable SWM341 DMA2D GPU." + config LV_GPU_SWM341_DMA2D_INCLUDE + string "include path of CMSIS header of target processor" + depends on LV_USE_GPU_SWM341_DMA2D + default "SWM341.h" + help + Must be defined to include path of CMSIS header of target processor + e.g. "SWM341.h" + config LV_USE_GPU_NXP_PXP bool "Use NXP's PXP GPU iMX RTxxx platforms." config LV_USE_GPU_NXP_PXP_AUTO_INIT diff --git a/README.md b/README.md index 8a478ec3c..c4224400c 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ LVGL provides everything you need to create an embedded GUI with easy-to-use gra * Multi-language support with UTF-8 handling, CJK, Bidirectional and Arabic script support * Fully customizable graphical elements via [CSS-like styles](https://docs.lvgl.io/master/overview/style.html) * Powerful layouts inspired by CSS: [Flexbox](https://docs.lvgl.io/master/layouts/flex.html) and [Grid](https://docs.lvgl.io/master/layouts/grid.html) -* OS, External memory and GPU are supported but not required. (built in support for STM32 DMA2D, and NXP PXP and VGLite) +* OS, External memory and GPU are supported but not required. (built in support for STM32 DMA2D, SWM341 DMA2D, and NXP PXP and VGLite) * Smooth rendering even with a [single frame buffer](https://docs.lvgl.io/master/porting/display.html) * Written in C and compatible with C++ * Micropython Binding exposes [LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings) @@ -104,6 +104,7 @@ Just to mention some platforms: - [Infineon Aurix](https://github.com/lvgl/lv_port_aurix) - Nordic NRF52 Bluetooth modules - Quectel modems +- [SYNWIT SWM341](https://www.synwit.cn/) LVGL is also available as: - [Arduino library](https://docs.lvgl.io/master/get-started/platforms/arduino.html) diff --git a/README_zh.md b/README_zh.md index efa94037c..5488de706 100644 --- a/README_zh.md +++ b/README_zh.md @@ -42,7 +42,7 @@ LVGL是一个高度可裁剪、低资源占用、界面美观且易用的嵌入 * 配置可裁剪(最低资源占用:64 kB Flash,16 kB RAM) * 基于UTF-8的多语种支持,例如中文、日文、韩文、阿拉伯文等 * 可以通过[类CSS](https://docs.lvgl.io/master/overview/style.html)的方式来设计、布局图形界面(例如:[Flexbox](https://docs.lvgl.io/master/layouts/flex.html)、[Grid](https://docs.lvgl.io/master/layouts/grid.html)) -* 支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32 DMA2D、NXP PXP和VGLite) +* 支持操作系统、外置内存、以及硬件加速(LVGL已内建支持STM32 DMA2D、SWM341 DMA2D、NXP PXP和VGLite) * 即便仅有[单缓冲区(frame buffer)](https://docs.lvgl.io/master/porting/display.html)的情况下,也可保证渲染如丝般顺滑 * 全部由C编写完成,并支持C++调用 * 支持Micropython编程,参见:[LVGL API in Micropython](https://blog.lvgl.io/2019-02-20/micropython-bindings) @@ -107,6 +107,7 @@ LVGL本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求 - [Infineon Aurix](https://github.com/lvgl/lv_port_aurix) - Nordic NRF52 Bluetooth modules - Quectel modems +- [SYNWIT SWM341](https://www.synwit.cn/) LVGL也支持: - [Arduino library](https://docs.lvgl.io/master/get-started/platforms/arduino.html) diff --git a/docs/intro/index.md b/docs/intro/index.md index 195ab3711..ee12db0f2 100644 --- a/docs/intro/index.md +++ b/docs/intro/index.md @@ -126,7 +126,7 @@ Before posting a question, please ready this FAQ section as you might find answe Every MCU which is capable of driving a display via parallel port, SPI, RGB interface or anything else and fulfills the [Requirements](#requirements) is supported by LVGL. This includes: -- "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32 etc. +- "Common" MCUs like STM32F, STM32H, NXP Kinetis, LPC, iMX, dsPIC33, PIC32, SWM341 etc. - Bluetooth, GSM, Wi-Fi modules like Nordic NRF and Espressif ESP32 - Linux with frame buffer device such as /dev/fb0. This includes Single-board computers like the Raspberry Pi - Anything else with a strong enough MCU and a peripheral to drive a display diff --git a/env_support/cmsis-pack/LVGL.lvgl.pdsc b/env_support/cmsis-pack/LVGL.lvgl.pdsc index 805619e42..dad409eb2 100644 --- a/env_support/cmsis-pack/LVGL.lvgl.pdsc +++ b/env_support/cmsis-pack/LVGL.lvgl.pdsc @@ -359,6 +359,20 @@ + + An hardware acceleration from SWM341-DMA2D + + + + + + +/*! \brief enable SWM341 DMA2D */ +#define LV_USE_GPU_SWM341_DMA2D 1 + + + + An hardware acceleration from NXP-PXP diff --git a/env_support/cmsis-pack/lv_conf_cmsis.h b/env_support/cmsis-pack/lv_conf_cmsis.h index cd9626e7c..6f0fab3f6 100644 --- a/env_support/cmsis-pack/lv_conf_cmsis.h +++ b/env_support/cmsis-pack/lv_conf_cmsis.h @@ -171,6 +171,11 @@ #define LV_GPU_DMA2D_CMSIS_INCLUDE #endif +/*Use SWM341's DMA2D GPU*/ +#if LV_USE_GPU_SWM341_DMA2D + #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" +#endif + /*Use NXP's PXP GPU iMX RTxxx platforms*/ #if LV_USE_GPU_NXP_PXP /*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) diff --git a/lv_conf_template.h b/lv_conf_template.h index 9fb9181f4..bf21ba4f9 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -168,6 +168,12 @@ #define LV_GPU_DMA2D_CMSIS_INCLUDE #endif +/*Use SWM341's DMA2D GPU*/ +#define LV_USE_GPU_SWM341_DMA2D 0 +#if LV_USE_GPU_SWM341_DMA2D + #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" +#endif + /*Use NXP's PXP GPU iMX RTxxx platforms*/ #define LV_USE_GPU_NXP_PXP 0 #if LV_USE_GPU_NXP_PXP diff --git a/src/core/lv_obj.c b/src/core/lv_obj.c index a8daaa80d..5b6fe112f 100644 --- a/src/core/lv_obj.c +++ b/src/core/lv_obj.c @@ -30,6 +30,10 @@ #include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h" #endif +#if LV_USE_GPU_SWM341_DMA2D + #include "../draw/swm341_dma2d/lv_gpu_swm341_dma2d.h" +#endif + #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT #include "../gpu/lv_gpu_nxp_pxp.h" #include "../gpu/lv_gpu_nxp_pxp_osa.h" @@ -116,6 +120,11 @@ void lv_init(void) lv_draw_stm32_dma2d_init(); #endif +#if LV_USE_GPU_SWM341_DMA2D + /*Initialize DMA2D GPU*/ + lv_draw_swm341_dma2d_init(); +#endif + #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT if(lv_gpu_nxp_pxp_init(&pxp_default_cfg) != LV_RES_OK) { LV_LOG_ERROR("PXP init error. STOP.\n"); diff --git a/src/draw/lv_draw.mk b/src/draw/lv_draw.mk index 3409a5ea4..635afe3f6 100644 --- a/src/draw/lv_draw.mk +++ b/src/draw/lv_draw.mk @@ -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 diff --git a/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c b/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c index 3398cc8ee..4eb1940ef 100644 --- a/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c +++ b/src/draw/stm32_dma2d/lv_gpu_stm32_dma2d.c @@ -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*/ diff --git a/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk b/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk new file mode 100644 index 000000000..bc19e3802 --- /dev/null +++ b/src/draw/swm341_dma2d/lv_draw_swm341_dma2d.mk @@ -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" diff --git a/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c b/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c new file mode 100644 index 000000000..74a539467 --- /dev/null +++ b/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.c @@ -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 diff --git a/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h b/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h new file mode 100644 index 000000000..20b892260 --- /dev/null +++ b/src/draw/swm341_dma2d/lv_gpu_swm341_dma2d.h @@ -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*/ diff --git a/src/hal/lv_hal_disp.c b/src/hal/lv_hal_disp.c index dbdc5dce7..56f6b3acb 100644 --- a/src/hal/lv_hal_disp.c +++ b/src/hal/lv_hal_disp.c @@ -21,6 +21,7 @@ #include "../draw/sw/lv_draw_sw.h" #include "../draw/sdl/lv_draw_sdl.h" #include "../draw/stm32_dma2d/lv_gpu_stm32_dma2d.h" +#include "../draw/swm341_dma2d/lv_gpu_swm341_dma2d.h" #include "../draw/arm2d/lv_gpu_arm2d.h" #if LV_USE_THEME_DEFAULT @@ -97,6 +98,10 @@ void lv_disp_drv_init(lv_disp_drv_t * driver) driver->draw_ctx_init = lv_draw_stm32_dma2d_ctx_init; driver->draw_ctx_deinit = lv_draw_stm32_dma2d_ctx_init; driver->draw_ctx_size = sizeof(lv_draw_stm32_dma2d_ctx_t); +#elif LV_USE_GPU_SWM341_DMA2D + driver->draw_ctx_init = lv_draw_swm341_dma2d_ctx_init; + driver->draw_ctx_deinit = lv_draw_swm341_dma2d_ctx_init; + driver->draw_ctx_size = sizeof(lv_draw_swm341_dma2d_ctx_t); #elif LV_USE_GPU_NXP_PXP driver->draw_ctx_init = lv_draw_nxp_pxp_init; driver->draw_ctx_deinit = lv_draw_nxp_pxp_init; diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index ddad1db4e..b8ab370d6 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -402,6 +402,24 @@ #endif #endif +/*Use SWM341's DMA2D GPU*/ +#ifndef LV_USE_GPU_SWM341_DMA2D + #ifdef CONFIG_LV_USE_GPU_SWM341_DMA2D + #define LV_USE_GPU_SWM341_DMA2D CONFIG_LV_USE_GPU_SWM341_DMA2D + #else + #define LV_USE_GPU_SWM341_DMA2D 0 + #endif +#endif +#if LV_USE_GPU_SWM341_DMA2D + #ifndef LV_GPU_SWM341_DMA2D_INCLUDE + #ifdef CONFIG_LV_GPU_SWM341_DMA2D_INCLUDE + #define LV_GPU_SWM341_DMA2D_INCLUDE CONFIG_LV_GPU_SWM341_DMA2D_INCLUDE + #else + #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" + #endif + #endif +#endif + /*Use NXP's PXP GPU iMX RTxxx platforms*/ #ifndef LV_USE_GPU_NXP_PXP #ifdef CONFIG_LV_USE_GPU_NXP_PXP