24 #include "ui_drawing.h" 25 #include "ui_drawing_soft.h" 33 #if DRAWING_DMA2D_BPP == 16 34 #define DRAWING_DMA2D_FORMAT DMA2D_RGB565 35 #elif DRAWING_DMA2D_BPP == 24 36 #define DRAWING_DMA2D_FORMAT DMA2D_RGB888 37 #elif DRAWING_DMA2D_BPP == 32 38 #define DRAWING_DMA2D_FORMAT DMA2D_ARGB8888 40 #error "Define 'DRAWING_DMA2D_BPP' is required (16, 24 or 32)" 49 typedef void (*t_drawing_notification)(
bool under_isr);
56 static DMA2D_HandleTypeDef g_hdma2d;
61 static t_drawing_notification g_callback_notification;
67 static bool g_dma2d_running;
72 static void* g_dma2d_semaphore;
79 static inline void _drawing_dma2d_wait(
void) {
80 while(g_dma2d_running) {
81 LLUI_DISPLAY_IMPL_binarySemaphoreTake(g_dma2d_semaphore);
88 static inline void _drawing_dma2d_done(
void) {
89 g_dma2d_running =
false;
90 LLUI_DISPLAY_IMPL_binarySemaphoreGive(g_dma2d_semaphore,
true);
96 static inline uint8_t* _drawing_dma2d_adjust_address(uint8_t* address, uint32_t x, uint32_t y, uint32_t stride, uint32_t bpp) {
97 return address + ((((y * stride) + x) * bpp) / 8);
103 static inline void _drawing_dma2d_configure_alpha_image_data(MICROUI_GraphicsContext* gc, jint* alphaAndColor) {
105 *(alphaAndColor) <<= 24;
106 *(alphaAndColor) |= (gc->foreground_color & 0xffffff);
118 static inline void _cleanDCache(
void) {
119 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) 126 void DRAWING_DMA2D_IRQHandler(
void) {
128 HAL_DMA2D_IRQHandler(&g_hdma2d);
131 _drawing_dma2d_done();
134 g_callback_notification(
true);
139 void DRAWING_DMA2D_initialize(
void* binary_semaphore_handle) {
141 g_dma2d_running =
false;
142 g_dma2d_semaphore = binary_semaphore_handle;
145 HAL_NVIC_SetPriority(DMA2D_IRQn, 5, 3);
146 HAL_NVIC_EnableIRQ(DMA2D_IRQn);
149 g_hdma2d.Init.ColorMode = DRAWING_DMA2D_FORMAT;
150 g_hdma2d.Instance = DMA2D;
153 void DRAWING_DMA2D_configure_memcpy(uint8_t* srcAddr, uint8_t* destAddr, uint32_t xmin, uint32_t ymin, uint32_t xmax, uint32_t ymax, uint32_t stride,
DRAWING_DMA2D_memcpy* memcpy_data) {
154 _drawing_dma2d_wait();
156 uint32_t width = (xmax - xmin + (uint32_t)1);
157 uint32_t height = (ymax - ymin + (uint32_t)1);
160 HAL_DMA2D_DeInit(&g_hdma2d);
163 g_hdma2d.LayerCfg[1].InputOffset = stride - width;
164 g_hdma2d.LayerCfg[1].InputColorMode = DRAWING_DMA2D_FORMAT;
165 HAL_DMA2D_ConfigLayer(&g_hdma2d, 1);
168 g_hdma2d.Init.Mode = DMA2D_M2M;
169 g_hdma2d.Init.OutputOffset = stride - width;
170 HAL_DMA2D_Init(&g_hdma2d) ;
173 memcpy_data->src_address = _drawing_dma2d_adjust_address(srcAddr, xmin, ymin, stride, DRAWING_DMA2D_BPP);
174 memcpy_data->dest_address = _drawing_dma2d_adjust_address(destAddr, xmin, ymin, stride, DRAWING_DMA2D_BPP);
175 memcpy_data->width = width;
176 memcpy_data->height = height;
179 g_callback_notification = &LLUI_DISPLAY_flushDone;
180 g_dma2d_running =
true;
187 (uint32_t)memcpy_data->src_address,
188 (uint32_t)memcpy_data->dest_address,
196 DRAWING_Status UI_DRAWING_fillRectangle(MICROUI_GraphicsContext* gc, jint x1, jint y1, jint x2, jint y2) {
197 _drawing_dma2d_wait();
199 LLUI_DISPLAY_setDrawingLimits(x1, y1, x2, y2);
201 uint32_t rectangle_width = x2 - x1 + 1;
202 uint32_t rectangle_height = y2 - y1 + 1;
203 uint32_t stride = LLUI_DISPLAY_getStrideInPixels(&gc->image);
206 HAL_DMA2D_DeInit(&g_hdma2d);
209 g_hdma2d.Init.Mode = DMA2D_R2M;
210 g_hdma2d.Init.OutputOffset = stride - rectangle_width;
211 HAL_DMA2D_Init(&g_hdma2d);
214 g_callback_notification = &LLUI_DISPLAY_notifyAsynchronousDrawingEnd;
215 g_dma2d_running =
true;
219 uint8_t* destination_address = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(&gc->image), x1, y1, stride, DRAWING_DMA2D_BPP);
220 HAL_DMA2D_Start_IT(&g_hdma2d, gc->foreground_color, (uint32_t)destination_address, rectangle_width, rectangle_height);
222 return DRAWING_RUNNING;
225 DRAWING_Status UI_DRAWING_drawImage(MICROUI_GraphicsContext* gc, MICROUI_Image* image, jint x_src, jint y_src, jint width, jint height, jint x_dest, jint y_dest, jint alpha) {
229 if (((uint32_t)&(gc->image) == (uint32_t)image) && (((y_dest > y_src) && (y_dest < (y_src + height))) || ((y_dest == y_src) && (x_dest > x_src) && (x_dest < (x_src + width))))) {
232 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, width, height, x_dest, y_dest, alpha);
237 ret = DRAWING_RUNNING;
238 _drawing_dma2d_wait();
243 switch(image->format) {
244 case MICROUI_IMAGE_FORMAT_RGB565:
248 case MICROUI_IMAGE_FORMAT_ARGB8888:
249 format = CM_ARGB8888;
252 case MICROUI_IMAGE_FORMAT_RGB888:
256 case MICROUI_IMAGE_FORMAT_ARGB1555:
257 format = CM_ARGB1555;
260 case MICROUI_IMAGE_FORMAT_ARGB4444:
261 format = CM_ARGB4444;
264 case MICROUI_IMAGE_FORMAT_A4: {
267 jint xAlign = x_src & 1;
268 jint wAlign = width & 1;
274 UI_DRAWING_SOFT_drawImage(gc, image, x_src + width, y_src, 1, height, x_dest + width, y_dest, alpha);
283 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, 1, height, x_dest, y_dest, alpha);
287 UI_DRAWING_SOFT_drawImage(gc, image, x_src + width, y_src, 1, height, x_dest + width, y_dest, alpha);
295 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, 1, height, x_dest, y_dest, alpha);
302 _drawing_dma2d_configure_alpha_image_data(gc, &alpha);
307 case MICROUI_IMAGE_FORMAT_A8:
308 _drawing_dma2d_configure_alpha_image_data(gc, &alpha);
314 UI_DRAWING_SOFT_drawImage(gc, image, x_src, y_src, width, height, x_dest, y_dest, alpha);
319 if (DRAWING_DONE != ret) {
321 uint32_t srcStride = LLUI_DISPLAY_getStrideInPixels(image);
322 uint32_t destStride = LLUI_DISPLAY_getStrideInPixels(&gc->image);
323 uint8_t* srcAddr = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(image), x_src, y_src, srcStride, bpp);
324 uint8_t* destAddr = _drawing_dma2d_adjust_address(LLUI_DISPLAY_getBufferAddress(&gc->image), x_dest, y_dest, destStride, DRAWING_DMA2D_BPP);
327 HAL_DMA2D_DeInit(&g_hdma2d);
330 g_hdma2d.LayerCfg[0].InputOffset = destStride - width;
331 g_hdma2d.LayerCfg[0].InputColorMode = DRAWING_DMA2D_FORMAT;
332 g_hdma2d.LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA;
333 g_hdma2d.LayerCfg[0].InputAlpha = 255;
334 HAL_DMA2D_ConfigLayer(&g_hdma2d, 0);
337 HAL_DMA2D_DisableCLUT(&g_hdma2d, 1);
338 g_hdma2d.LayerCfg[1].InputOffset = srcStride - width;
339 g_hdma2d.LayerCfg[1].InputColorMode = format;
340 g_hdma2d.LayerCfg[1].AlphaMode = DMA2D_COMBINE_ALPHA;
341 g_hdma2d.LayerCfg[1].InputAlpha = alpha;
342 HAL_DMA2D_ConfigLayer(&g_hdma2d, 1);
345 g_hdma2d.Init.Mode = DMA2D_M2M_BLEND;
346 g_hdma2d.Init.OutputOffset = destStride - width;
347 HAL_DMA2D_Init(&g_hdma2d) ;
350 g_dma2d_running =
true;
351 g_callback_notification = &LLUI_DISPLAY_notifyAsynchronousDrawingEnd;
352 LLUI_DISPLAY_setDrawingLimits(x_dest, y_dest, x_dest + width - 1, y_dest + height - 1);
356 HAL_DMA2D_BlendingStart_IT(&g_hdma2d, (uint32_t)srcAddr, (uint32_t)destAddr, (uint32_t)destAddr, width, height);
Use STM32 DMA2D (ChromART) for MicroEJ ui_drawing.h implementation.