|
7 | 7 | static uint32_t lcd_x_size = 0;
|
8 | 8 | static uint32_t lcd_y_size = 0;
|
9 | 9 |
|
10 |
| -uint16_t * fb; |
| 10 | +static uint16_t * fb; |
| 11 | +static lv_disp_drv_t disp_drv; |
11 | 12 |
|
12 | 13 | /* Display flushing */
|
13 | 14 | static void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
|
14 | 15 | {
|
15 |
| - |
16 |
| - uint16_t * fb_start = fb + area->y1 * lcd_x_size + area->x1; |
17 | 16 | uint32_t w = lv_area_get_width(area);
|
18 | 17 | uint32_t h = lv_area_get_height(area);
|
19 |
| - |
20 |
| - //GPU: Has artifacts |
21 |
| - //stm32_LCD_DrawImage((void*)color_p, (void*)fb_start, w, h, DMA2D_INPUT_RGB565); |
22 | 18 |
|
| 19 | +#if 1 |
| 20 | + // SCB_InvalidateICache(); |
| 21 | + |
| 22 | +// SCB_CleanInvalidateDCache(); |
| 23 | + |
| 24 | + DMA2D_HandleTypeDef * dma2d = stm32_get_DMA2D(); |
| 25 | + |
| 26 | + lv_color_t * pDst = (lv_color_t*)fb; |
| 27 | + pDst += area->y1 * lcd_x_size + area->x1; |
| 28 | + |
| 29 | + /*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/ |
| 30 | + dma2d->Init.Mode = DMA2D_M2M; |
| 31 | + dma2d->Init.ColorMode = DMA2D_OUTPUT_RGB565; |
| 32 | + dma2d->Init.OutputOffset = lcd_x_size - w; |
| 33 | + dma2d->Init.AlphaInverted = DMA2D_REGULAR_ALPHA; /* No Output Alpha Inversion*/ |
| 34 | + dma2d->Init.RedBlueSwap = DMA2D_RB_REGULAR; /* No Output Red & Blue swap */ |
| 35 | + |
| 36 | + /*##-2- DMA2D Callbacks Configuration ######################################*/ |
| 37 | + dma2d->XferCpltCallback = NULL; |
| 38 | + |
| 39 | + /*##-3- Foreground Configuration ###########################################*/ |
| 40 | + dma2d->LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; |
| 41 | + dma2d->LayerCfg[1].InputAlpha = 0xFF; |
| 42 | + dma2d->LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; |
| 43 | + dma2d->LayerCfg[1].InputOffset = 0; |
| 44 | + dma2d->LayerCfg[1].RedBlueSwap = DMA2D_RB_REGULAR; /* No ForeGround Red/Blue swap */ |
| 45 | + dma2d->LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; /* No ForeGround Alpha inversion */ |
| 46 | + |
| 47 | + /* DMA2D Initialization */ |
| 48 | + if(HAL_DMA2D_Init(dma2d) == HAL_OK) { |
| 49 | + if(HAL_DMA2D_ConfigLayer(dma2d, 1) == HAL_OK) { |
| 50 | + HAL_DMA2D_Start(dma2d, (uint32_t)color_p, (uint32_t)pDst, w, h); |
| 51 | + HAL_DMA2D_PollForTransfer(dma2d, 1000); |
| 52 | + } |
| 53 | + } |
| 54 | +#else |
23 | 55 | //NO GPU
|
24 | 56 | int32_t y;
|
25 | 57 | for(y = area->y1; y <= area->y2; y++) {
|
26 | 58 | memcpy(&fb[y * lcd_x_size + area->x1], color_p, w * sizeof(lv_color_t));
|
27 | 59 | color_p += w;
|
28 | 60 | }
|
29 |
| - |
30 |
| - lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ |
| 61 | + #endif |
| 62 | +lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ |
31 | 63 | }
|
32 | 64 |
|
33 | 65 |
|
34 | 66 | /* If your MCU has hardware accelerator (GPU) then you can use it to blend to memories using opacity
|
35 | 67 | * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/
|
36 | 68 | static void gpu_blend(lv_disp_drv_t * disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
|
37 | 69 | {
|
38 |
| - stm32_LCD_DrawImage((void*)src, (void*)dest, length, 1, DMA2D_INPUT_RGB565); |
| 70 | + |
| 71 | +// SCB_CleanInvalidateDCache(); |
| 72 | + |
| 73 | + DMA2D_HandleTypeDef * dma2d = stm32_get_DMA2D(); |
| 74 | + |
| 75 | + dma2d->Instance = DMA2D; |
| 76 | + dma2d->Init.Mode = DMA2D_M2M_BLEND; |
| 77 | + dma2d->Init.OutputOffset = 0; |
| 78 | + |
| 79 | + /* Foreground layer */ |
| 80 | + dma2d->LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; |
| 81 | + dma2d->LayerCfg[1].InputAlpha = opa; |
| 82 | + dma2d->LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; |
| 83 | + dma2d->LayerCfg[1].InputOffset = 0; |
| 84 | + dma2d->LayerCfg[1].AlphaInverted = DMA2D_REGULAR_ALPHA; |
| 85 | + |
| 86 | + /* Background layer */ |
| 87 | + dma2d->LayerCfg[0].AlphaMode = DMA2D_NO_MODIF_ALPHA; |
| 88 | + dma2d->LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565; |
| 89 | + dma2d->LayerCfg[0].InputOffset = 0; |
| 90 | + |
| 91 | + /* DMA2D Initialization */ |
| 92 | + if (HAL_DMA2D_Init(dma2d) == HAL_OK) { |
| 93 | + if (HAL_DMA2D_ConfigLayer(dma2d, 0) == HAL_OK && HAL_DMA2D_ConfigLayer(dma2d, 1) == HAL_OK) { |
| 94 | + HAL_DMA2D_BlendingStart(dma2d, (uint32_t) src, (uint32_t) dest, (uint32_t) dest, length, 1); |
| 95 | + HAL_DMA2D_PollForTransfer(dma2d, 1000); |
| 96 | + } |
| 97 | + } |
39 | 98 | }
|
40 | 99 |
|
41 |
| -/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color |
42 |
| - * It can be used only in buffered mode (LV_VDB_SIZE != 0 in lv_conf.h)*/ |
| 100 | +/* If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color */ |
43 | 101 | static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width,
|
44 | 102 | const lv_area_t * fill_area, lv_color_t color)
|
45 | 103 | {
|
46 |
| - uint16_t * fb_start = fb + fill_area->y1 * dest_width + fill_area->x1; |
47 |
| - uint32_t w = lv_area_get_width(fill_area); |
48 |
| - uint32_t h = lv_area_get_height(fill_area); |
49 |
| -// stm32_LCD_FillArea((void*)color_p, (void*)fb_start, w, h, color.full); |
| 104 | +// SCB_CleanInvalidateDCache(); |
| 105 | + |
| 106 | + DMA2D_HandleTypeDef * dma2d = stm32_get_DMA2D(); |
| 107 | + |
| 108 | + |
| 109 | + lv_color_t * destination = dest_buf + (dest_width * fill_area->y1 + fill_area->x1); |
| 110 | + |
| 111 | + uint32_t w = fill_area->x2 - fill_area->x1 + 1; |
| 112 | + dma2d->Instance = DMA2D; |
| 113 | + dma2d->Init.Mode = DMA2D_R2M; |
| 114 | + dma2d->Init.ColorMode = DMA2D_OUTPUT_RGB565; |
| 115 | + dma2d->Init.OutputOffset = dest_width - w; |
| 116 | + dma2d->LayerCfg[1].InputAlpha = DMA2D_NO_MODIF_ALPHA; |
| 117 | + dma2d->LayerCfg[1].InputColorMode = DMA2D_OUTPUT_RGB565; |
| 118 | + |
| 119 | + /* DMA2D Initialization */ |
| 120 | + if (HAL_DMA2D_Init(dma2d) == HAL_OK) { |
| 121 | + if (HAL_DMA2D_ConfigLayer(dma2d, 1) == HAL_OK) { |
| 122 | + lv_coord_t h = lv_area_get_height(fill_area); |
| 123 | + if(HAL_DMA2D_BlendingStart(dma2d, lv_color_to32(color), (uint32_t)destination, (uint32_t)destination, w, h) == HAL_OK) { |
| 124 | + HAL_DMA2D_PollForTransfer(dma2d, 1000); |
| 125 | + } |
| 126 | + } |
| 127 | + } |
50 | 128 | }
|
51 | 129 |
|
52 | 130 |
|
@@ -92,11 +170,10 @@ void setup() {
|
92 | 170 | lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX / 6);
|
93 | 171 |
|
94 | 172 | /*Initialize the display*/
|
95 |
| - lv_disp_drv_t disp_drv; |
96 | 173 | lv_disp_drv_init(&disp_drv);
|
97 | 174 | disp_drv.flush_cb = my_disp_flush;
|
98 |
| - // disp_drv.gpu_fill_cb = gpu_fill; |
99 |
| - // disp_drv.gpu_blend_cb = gpu_blend; |
| 175 | + disp_drv.gpu_fill_cb = gpu_fill; |
| 176 | + disp_drv.gpu_blend_cb = gpu_blend; |
100 | 177 | disp_drv.buffer = &disp_buf;
|
101 | 178 | lv_disp_drv_register(&disp_drv);
|
102 | 179 |
|
|
0 commit comments