diff --git a/src/omv/boards/OPENMV1/imlib_config.h b/src/omv/boards/OPENMV1/imlib_config.h index 77bc75183..70125bc60 100644 --- a/src/omv/boards/OPENMV1/imlib_config.h +++ b/src/omv/boards/OPENMV1/imlib_config.h @@ -74,4 +74,7 @@ // Enable Tensor Flow //#define IMLIB_ENABLE_TF +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/OPENMV2/imlib_config.h b/src/omv/boards/OPENMV2/imlib_config.h index d6da11984..d8bb4f782 100644 --- a/src/omv/boards/OPENMV2/imlib_config.h +++ b/src/omv/boards/OPENMV2/imlib_config.h @@ -138,4 +138,7 @@ // Enable find_hog() //#define IMLIB_ENABLE_HOG +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/OPENMV3/imlib_config.h b/src/omv/boards/OPENMV3/imlib_config.h index 5869026d6..b5eba1c37 100644 --- a/src/omv/boards/OPENMV3/imlib_config.h +++ b/src/omv/boards/OPENMV3/imlib_config.h @@ -148,4 +148,7 @@ // Enable find_hog() #define IMLIB_ENABLE_HOG +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/OPENMV4/imlib_config.h b/src/omv/boards/OPENMV4/imlib_config.h index 2eb6459ca..8f92da13c 100644 --- a/src/omv/boards/OPENMV4/imlib_config.h +++ b/src/omv/boards/OPENMV4/imlib_config.h @@ -151,4 +151,7 @@ // Enable selective_search() #define IMLIB_ENABLE_SELECTIVE_SEARCH +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/OPENMV4P/imlib_config.h b/src/omv/boards/OPENMV4P/imlib_config.h index fa2560890..4a59bbc15 100644 --- a/src/omv/boards/OPENMV4P/imlib_config.h +++ b/src/omv/boards/OPENMV4P/imlib_config.h @@ -151,4 +151,7 @@ // Enable selective_search() // #define IMLIB_ENABLE_SELECTIVE_SEARCH +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/OPENMVPURETHERMAL/imlib_config.h b/src/omv/boards/OPENMVPURETHERMAL/imlib_config.h index ccafd7516..6a804cfbb 100644 --- a/src/omv/boards/OPENMVPURETHERMAL/imlib_config.h +++ b/src/omv/boards/OPENMVPURETHERMAL/imlib_config.h @@ -151,4 +151,7 @@ // Enable selective_search() // #define IMLIB_ENABLE_SELECTIVE_SEARCH +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/boards/PORTENTA/imlib_config.h b/src/omv/boards/PORTENTA/imlib_config.h index bedd28724..b4a4a881c 100644 --- a/src/omv/boards/PORTENTA/imlib_config.h +++ b/src/omv/boards/PORTENTA/imlib_config.h @@ -151,4 +151,7 @@ // Enable selective_search() #define IMLIB_ENABLE_SELECTIVE_SEARCH +// Enable STM32 DMA2D +#define IMLIB_ENABLE_DMA2D + #endif //__IMLIB_CONFIG_H__ diff --git a/src/omv/img/draw.c b/src/omv/img/draw.c index dd8a4ddf0..d9e46ff78 100644 --- a/src/omv/img/draw.c +++ b/src/omv/img/draw.c @@ -8,6 +8,8 @@ * * Basic drawing functions. */ +#include STM32_HAL_H +#include "dma.h" #include "font.h" #include "imlib.h" @@ -431,95 +433,121 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int } } -#ifdef __IMLIB_ENABLE_DMA2D__ -DMA2D_HandleTypeDef dma2d; -#endif - void imlib_draw_row_setup(imlib_draw_row_data_t *data) { size_t image_row_size = image_size(data->dst_img) / data->dst_img->h; data->toggle = 0; data->row_buffer[0] = fb_alloc(image_row_size, FB_ALLOC_NO_HINT); -#ifdef __IMLIB_ENABLE_DMA2D__ - data->row_buffer[1] = fb_alloc(image_row_size, FB_ALLOC_NO_HINT); + +#ifdef IMLIB_ENABLE_DMA2D + data->dma2d_enabled = false; + data->dma2d_initialized = false; + + void *dst_buff = data->dst_row_override ? data->dst_row_override : data->dst_img->data; + + if ((data->dst_img->bpp == IMAGE_BPP_RGB565) && DMA_BUFFER(dst_buff) && + ((data->src_img_bpp == IMAGE_BPP_GRAYSCALE) || + ((data->src_img_bpp == IMAGE_BPP_RGB565) && (data->rgb_channel < 0) && (data->alpha != 256) && (!data->color_palette) && (!data->alpha_palette)))) { + data->row_buffer[1] = fb_alloc(image_row_size, FB_ALLOC_NO_HINT); + data->dma2d_enabled = true; + data->dma2d_initialized = true; + + memset(&data->dma2d, 0, sizeof(data->dma2d)); + + data->dma2d.Instance = DMA2D; + data->dma2d.Init.Mode = DMA2D_M2M; + if (data->dst_img->bpp != data->src_img_bpp) data->dma2d.Init.Mode = DMA2D_M2M_PFC; + if ((data->alpha != 256) || data->alpha_palette) data->dma2d.Init.Mode = DMA2D_M2M_BLEND; + data->dma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; + data->dma2d.Init.OutputOffset = 0; + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + data->dma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; + data->dma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR; + #endif + HAL_DMA2D_Init(&data->dma2d); + + data->dma2d.LayerCfg[0].InputOffset = 0; + data->dma2d.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565; + data->dma2d.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA; + data->dma2d.LayerCfg[0].InputAlpha = data->black_background ? 0x00 : 0xff; + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + data->dma2d.LayerCfg[0].AlphaInverted = DMA2D_REGULAR_ALPHA; + data->dma2d.LayerCfg[0].RedBlueSwap = DMA2D_RB_REGULAR; + #endif + #if defined(MCU_SERIES_H7) + data->dma2d.LayerCfg[0].ChromaSubSampling = DMA2D_NO_CSS; + #endif + HAL_DMA2D_ConfigLayer(&data->dma2d, 0); + + switch (data->src_img_bpp) { + case IMAGE_BPP_GRAYSCALE: { + data->dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_L8; + data->dma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA; + uint32_t *clut = fb_alloc(256 * sizeof(uint32_t), FB_ALLOC_NO_HINT); + + if (!data->alpha_palette) { + if (!data->color_palette) { + for (int i = 0; i < 256; i++) { + clut[i] = (0xff << 24) | COLOR_Y_TO_RGB888(i); + } + } else { + for (int i = 0; i < 256; i++) { + int pixel = data->color_palette[i]; + clut[i] = (0xff << 24) | (COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(pixel); + } + } + } else { + if (!data->color_palette) { + for (int i = 0; i < 256; i++) { + clut[i] = (data->alpha_palette[i] << 24) | COLOR_Y_TO_RGB888(i); + } + } else { + for (int i = 0; i < 256; i++) { + int pixel = data->color_palette[i]; + clut[i] = (data->alpha_palette[i] << 24) | (COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(pixel); + } + } + } + + DMA2D_CLUTCfgTypeDef cfg; + cfg.pCLUT = clut; + cfg.CLUTColorMode = DMA2D_CCM_ARGB8888; + cfg.Size = 255; + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + SCB_CleanDCache_by_Addr(clut, 256 * sizeof(uint32_t)); + #endif + HAL_DMA2D_CLUTLoad(&data->dma2d, cfg, 1); + HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + break; + } + case IMAGE_BPP_RGB565: { + data->dma2d.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; + data->dma2d.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; + break; + } + default: { + break; + } + } + + data->dma2d.LayerCfg[1].InputOffset = 0; + data->dma2d.LayerCfg[1].InputAlpha = fast_roundf((data->alpha * 255) / 256.f); + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + data->dma2d.LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; + data->dma2d.LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; + #endif + #if defined(MCU_SERIES_H7) + data->dma2d.LayerCfg[1].ChromaSubSampling = DMA2D_NO_CSS; + #endif + HAL_DMA2D_ConfigLayer(&data->dma2d, 1); + } else { + data->row_buffer[1] = data->row_buffer[0]; + } #else data->row_buffer[1] = data->row_buffer[0]; #endif -#ifdef __IMLIB_ENABLE_DMA2D__ - dma2d.Init.Mode = DMA2D_M2M_BLEND; - dma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; - dma2d.Init.OutputOffset = 0; - dma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; - dma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR; - HAL_DMA2D_Init(&dma2d); - - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].InputOffset = 0; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].InputColorMode = DMA2D_INPUT_RGB565; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].AlphaMode = DMA2D_NO_MODIF_ALPHA; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].InputAlpha = 0xff; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].AlphaInverted = DMA2D_REGULAR_ALPHA; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].RedBlueSwap = DMA2D_RB_REGULAR; - dma2d.LayerCfg[DMA2D_BACKGROUND_LAYER].ChromaSubSampling = DMA2D_NO_CSS; - HAL_DMA2D_ConfigLayer(&dma2d, DMA2D_BACKGROUND_LAYER); - - switch (data->src_img_bpp) { - case IMAGE_BPP_GRAYSCALE: { - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].InputColorMode = DMA2D_INPUT_L8; - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].AlphaMode = DMA2D_COMBINE_ALPHA; - uint32_t *clut = fb_alloc(256 * sizeof(uint32_t), FB_ALLOC_NO_HINT); - - if (!data->alpha_palette) { - if (!data->color_palette) { - for (int i = 0; i < 256; i++) { - clut[i] = (0xff << 24) | COLOR_Y_TO_RGB888(i); - } - } else { - for (int i = 0; i < 256; i++) { - int pixel = color_palette[i]; - clut[i] = (0xff << 24) | (COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(pixel); - } - } - } else { - if (!data->color_palette) { - for (int i = 0; i < 256; i++) { - clut[i] = (alpha_palette[i] << 24) | COLOR_Y_TO_RGB888(i); - } - } else { - for (int i = 0; i < 256; i++) { - int pixel = color_palette[i]; - clut[i] = (alpha_palette[i] << 24) | (COLOR_RGB565_TO_R8(pixel) << 16) | (COLOR_RGB565_TO_G8(pixel) << 8) | COLOR_RGB565_TO_B8(pixel); - } - } - } - - DMA2D_CLUTCfgTypeDef cfg; - cfg.pCLUT = clut; - cfg.CLUTColorMode = DMA2D_CCM_ARGB8888; - cfg.size = 256; - HAL_DMA2D_CLUTLoad(&dma2d, &cfg, DMA2D_FOREGROUND_LAYER); - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - break; - } - case IMAGE_BPP_RGB565: { - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].InputColorMode = DMA2D_INPUT_RGB565; - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].AlphaMode = DMA2D_REPLACE_ALPHA; - break; - } - default: { - break; - } - } - - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].InputOffset = 0; - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].InputAlpha = fast_roundf((data->alpha * 255) / 256.f); - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].AlphaInverted = DMA2D_REGULAR_ALPHA; - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].RedBlueSwap = DMA2D_RB_REGULAR; - dma2d.LayerCfg[DMA2D_FOREGROUND_LAYER].ChromaSubSampling = DMA2D_NO_CSS; - HAL_DMA2D_ConfigLayer(&dma2d, DMA2D_FOREGROUND_LAYER); -#endif - int alpha = data->alpha, max = 256; if (data->dst_img->bpp == IMAGE_BPP_RGB565) { @@ -527,6 +555,8 @@ void imlib_draw_row_setup(imlib_draw_row_data_t *data) max = 32; } + // Set smuad_alpha and smuad_alpha_palette even if we don't use them with DMA2D as we may have + // to fallback to using them if the draw_image calls imlib_draw_row_put_row_buffer(). data->smuad_alpha = data->black_background ? alpha : ((alpha << 16) | (max - alpha)); if (data->alpha_palette) { @@ -544,16 +574,26 @@ void imlib_draw_row_setup(imlib_draw_row_data_t *data) void imlib_draw_row_teardown(imlib_draw_row_data_t *data) { if (data->smuad_alpha_palette) fb_free(); -#ifdef __IMLIB_ENABLE_DMA2D__ - if (data->src_img_bpp == IMAGE_BPP_GRAYSCALE) fb_free(); - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_DeInit(&dma2d); - SCB_InvalidateDCache_by_Addr((uint32_t*) data->dst_img->data, image_size(data->dst_img)); - fb_free(); // data->row_buffer[1] +#ifdef IMLIB_ENABLE_DMA2D + if (data->dma2d_initialized) { + if (!data->callback) HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + HAL_DMA2D_DeInit(&data->dma2d); + if (data->src_img_bpp == IMAGE_BPP_GRAYSCALE) fb_free(); // clut... + fb_free(); // data->row_buffer[1] + } #endif fb_free(); // data->row_buffer[0] } +#ifdef IMLIB_ENABLE_DMA2D +void imlib_draw_row_deinit_all() +{ + DMA2D_HandleTypeDef dma2d = {}; + dma2d.Instance = DMA2D; + HAL_DMA2D_DeInit(&dma2d); +} +#endif + void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data) { void *result = data->row_buffer[data->toggle]; @@ -565,6 +605,11 @@ void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer { data->row_buffer[data->toggle] = row_buffer; data->toggle = !data->toggle; +#ifdef IMLIB_ENABLE_DMA2D + if (data->dma2d_enabled && (!DMA_BUFFER(row_buffer))) { + data->dma2d_enabled = false; + } +#endif } // Draws (x_end - x_start) pixels. @@ -1894,14 +1939,22 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da } case IMAGE_BPP_GRAYSCALE: { uint8_t *src8 = ((uint8_t *) data->row_buffer[!data->toggle]) + x_start; +#ifdef IMLIB_ENABLE_DMA2D + if (data->dma2d_enabled) { + if (!data->callback) HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + SCB_CleanDCache_by_Addr((uint32_t *) src8, (x_end - x_start) * sizeof(uint8_t)); + SCB_CleanInvalidateDCache_by_Addr((uint32_t *) dst16, (x_end - x_start) * sizeof(uint16_t)); + #endif + HAL_DMA2D_BlendingStart(&data->dma2d, (uint32_t) src8, (uint32_t) dst16, (uint32_t) dst16, x_end - x_start, 1); + if (data->callback) HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + } else if (data->smuad_alpha_palette) { +#else if (data->smuad_alpha_palette) { +#endif const uint32_t *smuad_alpha_palette = data->smuad_alpha_palette; if (!data->color_palette) { if (!data->black_background) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_BlendingStart(&dma2d, src8, dst16, dst16, x_end - x_start, 1); -#else for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; long smuad_alpha = smuad_alpha_palette[src_pixel]; @@ -1909,7 +1962,6 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da int dst_pixel = *dst16; *dst16++ = BLEND_RGB566(src_pixel, dst_pixel, smuad_alpha); } -#endif } else { for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; @@ -1921,10 +1973,6 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da } else { const uint16_t *color_palette = data->color_palette; if (!data->black_background) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_BlendingStart(&dma2d, src8, dst16, dst16, x_end - x_start, 1); -#else for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; long smuad_alpha = smuad_alpha_palette[src_pixel]; @@ -1932,7 +1980,6 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da int dst_pixel = *dst16; *dst16++ = BLEND_RGB566(src_pixel, dst_pixel, smuad_alpha); } -#endif } else { for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; @@ -1958,17 +2005,12 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da long smuad_alpha = data->smuad_alpha; if (!data->color_palette) { if (!data->black_background) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_BlendingStart(&dma2d, src8, dst16, dst16, x_end - x_start, 1); -#else for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; src_pixel = COLOR_Y_TO_RGB565(src_pixel); int dst_pixel = *dst16; *dst16++ = BLEND_RGB566(src_pixel, dst_pixel, smuad_alpha); } -#endif } else { for (int x = x_start; x < x_end; x++) { int src_pixel = *src8++; @@ -1979,16 +2021,11 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da } else { const uint16_t *color_palette = data->color_palette; if (!data->black_background) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_BlendingStart(&dma2d, src8, dst16, dst16, x_end - x_start, 1); -#else for (int x = x_start; x < x_end; x++) { int src_pixel = color_palette[*src8++]; int dst_pixel = *dst16; *dst16++ = BLEND_RGB566(src_pixel, dst_pixel, smuad_alpha); } -#endif } else { for (int x = x_start; x < x_end; x++) { int src_pixel = color_palette[*src8++]; @@ -2042,12 +2079,7 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da } } else if (data->alpha == 256) { if (!data->color_palette) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_Start(&dma2d, src16, dst16, x_end - x_start, 1); -#else unaligned_memcpy(dst16, src16, (x_end - x_start) * sizeof(uint16_t)); -#endif } else { const uint16_t *color_palette = data->color_palette; for (int x = x_start; x < x_end; x++) { @@ -2058,17 +2090,24 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da } else { long smuad_alpha = data->smuad_alpha; if (!data->color_palette) { - if (!data->black_background) { -#ifdef __IMLIB_ENABLE_DMA2D__ - HAL_DMA2D_PollForTransfer(&dma2d, HAL_MAX_DELAY); - HAL_DMA2D_BlendingStart(&dma2d, src16, dst16, dst16, x_end - x_start, 1); +#ifdef IMLIB_ENABLE_DMA2D + if (data->dma2d_enabled) { + if (!data->callback) HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + #if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7) + SCB_CleanDCache_by_Addr((uint32_t *) src16, (x_end - x_start) * sizeof(uint16_t)); + SCB_CleanInvalidateDCache_by_Addr((uint32_t *) dst16, (x_end - x_start) * sizeof(uint16_t)); + #endif + HAL_DMA2D_BlendingStart(&data->dma2d, (uint32_t) src16, (uint32_t) dst16, (uint32_t) dst16, x_end - x_start, 1); + if (data->callback) HAL_DMA2D_PollForTransfer(&data->dma2d, 1000); + } else if (!data->black_background) { #else + if (!data->black_background) { +#endif for (int x = x_start; x < x_end; x++) { int src_pixel = *src16++; int dst_pixel = *dst16; *dst16++ = BLEND_RGB566(src_pixel, dst_pixel, smuad_alpha); } -#endif } else { for (int x = x_start; x < x_end; x++) { int src_pixel = *src16++; diff --git a/src/omv/img/imlib.h b/src/omv/img/imlib.h index ab19981ef..2f76cabd5 100644 --- a/src/omv/img/imlib.h +++ b/src/omv/img/imlib.h @@ -1012,6 +1012,11 @@ typedef struct imlib_draw_row_data { void *dst_row_override; // user int toggle; // private void *row_buffer[2]; // private + #ifdef IMLIB_ENABLE_DMA2D + bool dma2d_enabled; // private + bool dma2d_initialized; // private + DMA2D_HandleTypeDef dma2d; // private + #endif long smuad_alpha; // private uint32_t *smuad_alpha_palette; // private } imlib_draw_row_data_t; @@ -1151,6 +1156,9 @@ void imlib_find_hog(image_t *src, rectangle_t *roi, int cell_size); void imlib_zero(image_t *img, image_t *mask, bool invert); void imlib_draw_row_setup(imlib_draw_row_data_t *data); void imlib_draw_row_teardown(imlib_draw_row_data_t *data); +#ifdef IMLIB_ENABLE_DMA2D +void imlib_draw_row_deinit_all(); +#endif void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data); void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer); void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data); diff --git a/src/omv/main.c b/src/omv/main.c index d9788cca2..8fb625510 100644 --- a/src/omv/main.c +++ b/src/omv/main.c @@ -736,6 +736,9 @@ soft_reset: #if MICROPY_PY_AUDIO py_audio_deinit(); #endif + #ifdef IMLIB_ENABLE_DMA2D + imlib_draw_row_deinit_all(); + #endif first_soft_reset = false; goto soft_reset; } diff --git a/src/omv/stm32fxxx_hal_msp.c b/src/omv/stm32fxxx_hal_msp.c index 034fd1bca..b2e74c043 100644 --- a/src/omv/stm32fxxx_hal_msp.c +++ b/src/omv/stm32fxxx_hal_msp.c @@ -409,6 +409,18 @@ void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc) __HAL_RCC_CRC_CLK_DISABLE(); } +void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d) +{ + __HAL_RCC_DMA2D_CLK_ENABLE(); +} + +void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d) +{ + __HAL_RCC_DMA2D_FORCE_RESET(); + __HAL_RCC_DMA2D_RELEASE_RESET(); + __HAL_RCC_DMA2D_CLK_DISABLE(); +} + #if defined(OMV_LCD_CONTROLLER) && (!defined(OMV_DSI_CONTROLLER)) typedef struct { GPIO_TypeDef *port;