Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: LCD_DISCO_F746NG GRecorder BSP_DISCO_F746NG
tft.c
00001 /** 00002 * @file tft.c 00003 * 00004 */ 00005 00006 /********************* 00007 * INCLUDES 00008 *********************/ 00009 #include "lv_conf.h" 00010 #include "lvgl/lvgl.h" 00011 #include <string.h> 00012 #include <stdlib.h> 00013 00014 #include "tft.h " 00015 #include "stm32f7xx.h" 00016 #include "stm32746g_discovery.h" 00017 #include "stm32746g_discovery_sdram.h" 00018 #include "stm32746g_discovery_ts.h" 00019 #include "../Components/rk043fn48h/rk043fn48h.h" 00020 00021 /********************* 00022 * DEFINES 00023 *********************/ 00024 00025 #if LV_COLOR_DEPTH != 16 && LV_COLOR_DEPTH != 24 && LV_COLOR_DEPTH != 32 00026 #error LV_COLOR_DEPTH must be 16, 24, or 32 00027 #endif 00028 00029 #define LV_USE_GPU 0 00030 00031 /** 00032 * @brief LCD status structure definition 00033 */ 00034 #define LCD_OK ((uint8_t)0x00) 00035 #define LCD_ERROR ((uint8_t)0x01) 00036 #define LCD_TIMEOUT ((uint8_t)0x02) 00037 00038 /** 00039 * @brief LCD special pins 00040 */ 00041 /* Display enable pin */ 00042 #define LCD_DISP_PIN GPIO_PIN_12 00043 #define LCD_DISP_GPIO_PORT GPIOI 00044 #define LCD_DISP_GPIO_CLK_ENABLE() __HAL_RCC_GPIOI_CLK_ENABLE() 00045 #define LCD_DISP_GPIO_CLK_DISABLE() __HAL_RCC_GPIOI_CLK_DISABLE() 00046 00047 /* Backlight control pin */ 00048 #define LCD_BL_CTRL_PIN GPIO_PIN_3 00049 #define LCD_BL_CTRL_GPIO_PORT GPIOK 00050 #define LCD_BL_CTRL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOK_CLK_ENABLE() 00051 #define LCD_BL_CTRL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOK_CLK_DISABLE() 00052 00053 #define CPY_BUF_DMA_STREAM DMA2_Stream0 00054 #define CPY_BUF_DMA_CHANNEL DMA_CHANNEL_0 00055 #define CPY_BUF_DMA_STREAM_IRQ DMA2_Stream0_IRQn 00056 #define CPY_BUF_DMA_STREAM_IRQHANDLER DMA2_Stream0_IRQHandler 00057 00058 /********************** 00059 * TYPEDEFS 00060 **********************/ 00061 00062 /********************** 00063 * STATIC PROTOTYPES 00064 **********************/ 00065 00066 /*These 3 functions are needed by LittlevGL*/ 00067 static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p); 00068 #if LV_USE_GPU 00069 static void gpu_mem_blend(lv_disp_drv_t *disp_drv, lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa); 00070 static void gpu_mem_fill(lv_disp_drv_t *disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, const lv_area_t * fill_area, lv_color_t color); 00071 #endif 00072 00073 static uint8_t LCD_Init(void); 00074 static void LCD_LayerRgb565Init(uint32_t FB_Address); 00075 static void LCD_DisplayOn(void); 00076 00077 static void DMA_Config(void); 00078 static void DMA_TransferComplete(DMA_HandleTypeDef *han); 00079 static void DMA_TransferError(DMA_HandleTypeDef *han); 00080 00081 #if LV_USE_GPU 00082 static void DMA2D_Config(void); 00083 #endif 00084 00085 /********************** 00086 * STATIC VARIABLES 00087 **********************/ 00088 #if LV_USE_GPU 00089 static DMA2D_HandleTypeDef Dma2dHandle; 00090 #endif 00091 static LTDC_HandleTypeDef hLtdcHandler; 00092 00093 #if LV_COLOR_DEPTH == 16 00094 typedef uint16_t uintpixel_t; 00095 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00096 typedef uint32_t uintpixel_t; 00097 #endif 00098 00099 /* You can try to change buffer to internal ram by uncommenting line below and commenting 00100 * SDRAM one. */ 00101 //static uintpixel_t my_fb[TFT_HOR_RES * TFT_VER_RES]; 00102 00103 static __IO uintpixel_t * my_fb = (__IO uintpixel_t*) (SDRAM_DEVICE_ADDR); 00104 00105 static DMA_HandleTypeDef DmaHandle; 00106 static int32_t x1_flush; 00107 static int32_t y1_flush; 00108 static int32_t x2_flush; 00109 static int32_t y2_fill; 00110 static int32_t y_fill_act; 00111 static const lv_color_t * buf_to_flush; 00112 static lv_disp_drv_t disp_drv; 00113 00114 static lv_disp_t *our_disp = NULL; 00115 /********************** 00116 * MACROS 00117 **********************/ 00118 00119 /** 00120 * Initialize your display here 00121 */ 00122 00123 void tft_init(void) 00124 { 00125 /* There is only one display on STM32 */ 00126 if(our_disp != NULL) 00127 abort(); 00128 /* LCD Initialization */ 00129 LCD_Init(); 00130 00131 /* LCD Initialization */ 00132 LCD_LayerRgb565Init((uint32_t)my_fb); 00133 00134 /* Enable the LCD */ 00135 LCD_DisplayOn(); 00136 00137 DMA_Config(); 00138 00139 #if LV_USE_GPU != 0 00140 DMA2D_Config(); 00141 #endif 00142 /*----------------------------- 00143 * Create a buffer for drawing 00144 *----------------------------*/ 00145 00146 /* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row*/ 00147 00148 static lv_disp_draw_buf_t buf; 00149 static lv_color_t buf1_1[TFT_HOR_RES * 68]; 00150 static lv_color_t buf1_2[TFT_HOR_RES * 68]; 00151 lv_disp_draw_buf_init(&buf, buf1_1, buf1_2, TFT_HOR_RES * 68); /*Initialize the display buffer*/ 00152 00153 00154 /*----------------------------------- 00155 * Register the display in LittlevGL 00156 *----------------------------------*/ 00157 00158 /*Descriptor of a display driver*/ 00159 lv_disp_drv_init(&disp_drv); /*Basic initialization*/ 00160 00161 /*Set up the functions to access to your display*/ 00162 00163 /*Set the resolution of the display*/ 00164 disp_drv.hor_res = TFT_HOR_RES; 00165 disp_drv.ver_res = TFT_VER_RES; 00166 00167 /*Used to copy the buffer's content to the display*/ 00168 disp_drv.flush_cb = ex_disp_flush; 00169 00170 /*Set a display buffer*/ 00171 disp_drv.draw_buf = &buf; 00172 00173 00174 /*Finally register the driver*/ 00175 our_disp = lv_disp_drv_register(&disp_drv); 00176 } 00177 00178 /********************** 00179 * STATIC FUNCTIONS 00180 **********************/ 00181 00182 /* Flush the content of the internal buffer the specific area on the display 00183 * You can use DMA or any hardware acceleration to do this operation in the background but 00184 * 'lv_flush_ready()' has to be called when finished 00185 * This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/ 00186 static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p) 00187 { 00188 int32_t x1 = area->x1; 00189 int32_t x2 = area->x2; 00190 int32_t y1 = area->y1; 00191 int32_t y2 = area->y2; 00192 /*Return if the area is out the screen*/ 00193 00194 if(x2 < 0) return; 00195 if(y2 < 0) return; 00196 if(x1 > TFT_HOR_RES - 1) return; 00197 if(y1 > TFT_VER_RES - 1) return; 00198 00199 /*Truncate the area to the screen*/ 00200 int32_t act_x1 = x1 < 0 ? 0 : x1; 00201 int32_t act_y1 = y1 < 0 ? 0 : y1; 00202 int32_t act_x2 = x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : x2; 00203 int32_t act_y2 = y2 > TFT_VER_RES - 1 ? TFT_VER_RES - 1 : y2; 00204 00205 x1_flush = act_x1; 00206 y1_flush = act_y1; 00207 x2_flush = act_x2; 00208 y2_fill = act_y2; 00209 y_fill_act = act_y1; 00210 buf_to_flush = color_p; 00211 00212 SCB_CleanInvalidateDCache(); 00213 SCB_InvalidateICache(); 00214 /*##-7- Start the DMA transfer using the interrupt mode #*/ 00215 /* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */ 00216 /* Enable All the DMA interrupts */ 00217 HAL_StatusTypeDef err; 00218 uint32_t length = (x2_flush - x1_flush + 1); 00219 #if LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00220 length *= 2; /* STM32 DMA uses 16-bit chunks so multiply by 2 for 32-bit color */ 00221 #endif 00222 err = HAL_DMA_Start_IT(&DmaHandle,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush], 00223 length); 00224 if(err != HAL_OK) 00225 { 00226 while(1); /*Halt on error*/ 00227 } 00228 } 00229 00230 00231 /** 00232 * @brief Configure LCD pins, and peripheral clocks. 00233 */ 00234 static void LCD_MspInit(void) 00235 { 00236 GPIO_InitTypeDef gpio_init_structure; 00237 00238 /* Enable the LTDC and DMA2D clocks */ 00239 __HAL_RCC_LTDC_CLK_ENABLE(); 00240 #if LV_USE_GPU != 0 00241 __HAL_RCC_DMA2D_CLK_ENABLE(); 00242 #endif 00243 /* Enable GPIOs clock */ 00244 __HAL_RCC_GPIOE_CLK_ENABLE(); 00245 __HAL_RCC_GPIOG_CLK_ENABLE(); 00246 __HAL_RCC_GPIOI_CLK_ENABLE(); 00247 __HAL_RCC_GPIOJ_CLK_ENABLE(); 00248 __HAL_RCC_GPIOK_CLK_ENABLE(); 00249 LCD_DISP_GPIO_CLK_ENABLE(); 00250 LCD_BL_CTRL_GPIO_CLK_ENABLE(); 00251 00252 /*** LTDC Pins configuration ***/ 00253 /* GPIOE configuration */ 00254 gpio_init_structure.Pin = GPIO_PIN_4; 00255 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00256 gpio_init_structure.Pull = GPIO_NOPULL; 00257 gpio_init_structure.Speed = GPIO_SPEED_FAST; 00258 gpio_init_structure.Alternate = GPIO_AF14_LTDC; 00259 HAL_GPIO_Init(GPIOE, &gpio_init_structure); 00260 00261 /* GPIOG configuration */ 00262 gpio_init_structure.Pin = GPIO_PIN_12; 00263 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00264 gpio_init_structure.Alternate = GPIO_AF9_LTDC; 00265 HAL_GPIO_Init(GPIOG, &gpio_init_structure); 00266 00267 /* GPIOI LTDC alternate configuration */ 00268 gpio_init_structure.Pin = GPIO_PIN_9 | GPIO_PIN_10 | \ 00269 GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00270 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00271 gpio_init_structure.Alternate = GPIO_AF14_LTDC; 00272 HAL_GPIO_Init(GPIOI, &gpio_init_structure); 00273 00274 /* GPIOJ configuration */ 00275 gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \ 00276 GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | \ 00277 GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \ 00278 GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; 00279 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00280 gpio_init_structure.Alternate = GPIO_AF14_LTDC; 00281 HAL_GPIO_Init(GPIOJ, &gpio_init_structure); 00282 00283 /* GPIOK configuration */ 00284 gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 | \ 00285 GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; 00286 gpio_init_structure.Mode = GPIO_MODE_AF_PP; 00287 gpio_init_structure.Alternate = GPIO_AF14_LTDC; 00288 HAL_GPIO_Init(GPIOK, &gpio_init_structure); 00289 00290 /* LCD_DISP GPIO configuration */ 00291 gpio_init_structure.Pin = LCD_DISP_PIN; /* LCD_DISP pin has to be manually controlled */ 00292 gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; 00293 HAL_GPIO_Init(LCD_DISP_GPIO_PORT, &gpio_init_structure); 00294 00295 /* LCD_BL_CTRL GPIO configuration */ 00296 gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* LCD_BL_CTRL pin has to be manually controlled */ 00297 gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; 00298 HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure); 00299 } 00300 00301 /** 00302 * @brief Configure LTDC PLL. 00303 */ 00304 static void LCD_ClockConfig(void) 00305 { 00306 static RCC_PeriphCLKInitTypeDef periph_clk_init_struct; 00307 00308 /* RK043FN48H LCD clock configuration */ 00309 /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ 00310 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */ 00311 /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/5 = 38.4 Mhz */ 00312 /* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */ 00313 periph_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; 00314 periph_clk_init_struct.PLLSAI.PLLSAIN = 192; 00315 periph_clk_init_struct.PLLSAI.PLLSAIR = RK043FN48H_FREQUENCY_DIVIDER; 00316 periph_clk_init_struct.PLLSAIDivR = RCC_PLLSAIDIVR_4; 00317 HAL_RCCEx_PeriphCLKConfig(&periph_clk_init_struct); 00318 } 00319 00320 /** 00321 * @brief Initializes the LCD. 00322 * @retval LCD state 00323 */ 00324 static uint8_t LCD_Init(void) 00325 { 00326 /* Select the used LCD */ 00327 00328 /* The RK043FN48H LCD 480x272 is selected */ 00329 /* Timing Configuration */ 00330 hLtdcHandler.Init.HorizontalSync = (RK043FN48H_HSYNC - 1); 00331 hLtdcHandler.Init.VerticalSync = (RK043FN48H_VSYNC - 1); 00332 hLtdcHandler.Init.AccumulatedHBP = (RK043FN48H_HSYNC + RK043FN48H_HBP - 1); 00333 hLtdcHandler.Init.AccumulatedVBP = (RK043FN48H_VSYNC + RK043FN48H_VBP - 1); 00334 hLtdcHandler.Init.AccumulatedActiveH = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP - 1); 00335 hLtdcHandler.Init.AccumulatedActiveW = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP - 1); 00336 hLtdcHandler.Init.TotalHeigh = (RK043FN48H_HEIGHT + RK043FN48H_VSYNC + RK043FN48H_VBP + RK043FN48H_VFP - 1); 00337 hLtdcHandler.Init.TotalWidth = (RK043FN48H_WIDTH + RK043FN48H_HSYNC + RK043FN48H_HBP + RK043FN48H_HFP - 1); 00338 00339 /* LCD clock configuration */ 00340 LCD_ClockConfig(); 00341 00342 /* Initialize the LCD pixel width and pixel height */ 00343 hLtdcHandler.LayerCfg->ImageWidth = RK043FN48H_WIDTH; 00344 hLtdcHandler.LayerCfg->ImageHeight = RK043FN48H_HEIGHT; 00345 00346 /* Background value */ 00347 hLtdcHandler.Init.Backcolor.Blue = 0; 00348 hLtdcHandler.Init.Backcolor.Green = 0; 00349 hLtdcHandler.Init.Backcolor.Red = 0; 00350 00351 /* Polarity */ 00352 hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL; 00353 hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL; 00354 hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL; 00355 hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC; 00356 hLtdcHandler.Instance = LTDC; 00357 00358 if(HAL_LTDC_GetState(&hLtdcHandler) == HAL_LTDC_STATE_RESET) 00359 { 00360 /* Initialize the LCD Msp: this __weak function can be rewritten by the application */ 00361 LCD_MspInit(); 00362 } 00363 HAL_LTDC_Init(&hLtdcHandler); 00364 00365 /* Assert display enable LCD_DISP pin */ 00366 HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET); 00367 00368 /* Assert backlight LCD_BL_CTRL pin */ 00369 HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET); 00370 00371 BSP_SDRAM_Init(); 00372 00373 uint32_t i; 00374 for(i = 0; i < (TFT_HOR_RES * TFT_VER_RES) ; i++) 00375 { 00376 my_fb[i] = 0; 00377 } 00378 00379 return LCD_OK; 00380 } 00381 00382 static void LCD_LayerRgb565Init(uint32_t FB_Address) 00383 { 00384 LTDC_LayerCfgTypeDef layer_cfg; 00385 00386 /* Layer Init */ 00387 layer_cfg.WindowX0 = 0; 00388 layer_cfg.WindowX1 = TFT_HOR_RES; 00389 layer_cfg.WindowY0 = 0; 00390 layer_cfg.WindowY1 = TFT_VER_RES; 00391 00392 #if LV_COLOR_DEPTH == 16 00393 layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565; 00394 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00395 layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888; 00396 #else 00397 #error Unsupported color depth (see tft.c) 00398 #endif 00399 layer_cfg.FBStartAdress = FB_Address; 00400 layer_cfg.Alpha = 255; 00401 layer_cfg.Alpha0 = 0; 00402 layer_cfg.Backcolor.Blue = 0; 00403 layer_cfg.Backcolor.Green = 0; 00404 layer_cfg.Backcolor.Red = 0; 00405 layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; 00406 layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; 00407 layer_cfg.ImageWidth = TFT_HOR_RES; 00408 layer_cfg.ImageHeight = TFT_VER_RES; 00409 00410 HAL_LTDC_ConfigLayer(&hLtdcHandler, &layer_cfg, 0); 00411 } 00412 00413 static void LCD_DisplayOn(void) 00414 { 00415 /* Display On */ 00416 __HAL_LTDC_ENABLE(&hLtdcHandler); 00417 HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET); /* Assert LCD_DISP pin */ 00418 HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET); /* Assert LCD_BL_CTRL pin */ 00419 } 00420 00421 static void DMA_Config(void) 00422 { 00423 /*## -1- Enable DMA2 clock #################################################*/ 00424 __HAL_RCC_DMA2_CLK_ENABLE(); 00425 00426 /*##-2- Select the DMA functional Parameters ###############################*/ 00427 DmaHandle.Init.Channel = CPY_BUF_DMA_CHANNEL; /* DMA_CHANNEL_0 */ 00428 DmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; /* M2M transfer mode */ 00429 DmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; /* Peripheral increment mode Enable */ 00430 DmaHandle.Init.MemInc = DMA_MINC_ENABLE; /* Memory increment mode Enable */ 00431 DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; /* Peripheral data alignment : 16bit */ 00432 DmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; /* memory data alignment : 16bit */ 00433 DmaHandle.Init.Mode = DMA_NORMAL; /* Normal DMA mode */ 00434 DmaHandle.Init.Priority = DMA_PRIORITY_HIGH; /* priority level : high */ 00435 DmaHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; /* FIFO mode enabled */ 00436 DmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; /* FIFO threshold: 1/4 full */ 00437 DmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; /* Memory burst */ 00438 DmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Peripheral burst */ 00439 00440 /*##-3- Select the DMA instance to be used for the transfer : DMA2_Stream0 #*/ 00441 DmaHandle.Instance = CPY_BUF_DMA_STREAM; 00442 00443 /*##-4- Initialize the DMA stream ##########################################*/ 00444 if(HAL_DMA_Init(&DmaHandle) != HAL_OK) 00445 { 00446 while(1) 00447 { 00448 } 00449 } 00450 00451 /*##-5- Select Callbacks functions called after Transfer complete and Transfer error */ 00452 HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, DMA_TransferComplete); 00453 HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_ERROR_CB_ID, DMA_TransferError); 00454 00455 /*##-6- Configure NVIC for DMA transfer complete/error interrupts ##########*/ 00456 HAL_NVIC_SetPriority(CPY_BUF_DMA_STREAM_IRQ, 0, 0); 00457 HAL_NVIC_EnableIRQ(CPY_BUF_DMA_STREAM_IRQ); 00458 } 00459 00460 /** 00461 * @brief DMA conversion complete callback 00462 * @note This function is executed when the transfer complete interrupt 00463 * is generated 00464 * @retval None 00465 */ 00466 static void DMA_TransferComplete(DMA_HandleTypeDef *han) 00467 { 00468 y_fill_act ++; 00469 00470 if(y_fill_act > y2_fill) { 00471 SCB_CleanInvalidateDCache(); 00472 SCB_InvalidateICache(); 00473 lv_disp_flush_ready(&disp_drv); 00474 } else { 00475 uint32_t length = (x2_flush - x1_flush + 1); 00476 buf_to_flush += x2_flush - x1_flush + 1; 00477 /*##-7- Start the DMA transfer using the interrupt mode ####################*/ 00478 /* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */ 00479 /* Enable All the DMA interrupts */ 00480 #if LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00481 length *= 2; /* STM32 DMA uses 16-bit chunks so multiply by 2 for 32-bit color */ 00482 #endif 00483 if(HAL_DMA_Start_IT(han,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush], 00484 length) != HAL_OK) 00485 { 00486 while(1); /*Halt on error*/ 00487 } 00488 } 00489 } 00490 00491 /** 00492 * @brief DMA conversion error callback 00493 * @note This function is executed when the transfer error interrupt 00494 * is generated during DMA transfer 00495 * @retval None 00496 */ 00497 static void DMA_TransferError(DMA_HandleTypeDef *han) 00498 { 00499 00500 } 00501 00502 /** 00503 * @brief This function handles DMA Stream interrupt request. 00504 * @param None 00505 * @retval None 00506 */ 00507 void CPY_BUF_DMA_STREAM_IRQHANDLER(void) 00508 { 00509 /* Check the interrupt and clear flag */ 00510 HAL_DMA_IRQHandler(&DmaHandle); 00511 } 00512 00513 00514 #if LV_USE_GPU != 0 00515 00516 static void Error_Handler(void) 00517 { 00518 while(1) 00519 { 00520 } 00521 } 00522 /** 00523 * @brief DMA2D Transfer completed callback 00524 * @param hdma2d: DMA2D handle. 00525 * @note This example shows a simple way to report end of DMA2D transfer, and 00526 * you can add your own implementation. 00527 * @retval None 00528 */ 00529 static void DMA2D_TransferComplete(DMA2D_HandleTypeDef *hdma2d) 00530 { 00531 00532 } 00533 00534 /** 00535 * @brief DMA2D error callbacks 00536 * @param hdma2d: DMA2D handle 00537 * @note This example shows a simple way to report DMA2D transfer error, and you can 00538 * add your own implementation. 00539 * @retval None 00540 */ 00541 static void DMA2D_TransferError(DMA2D_HandleTypeDef *hdma2d) 00542 { 00543 00544 } 00545 00546 /** 00547 * @brief DMA2D configuration. 00548 * @note This function Configure the DMA2D peripheral : 00549 * 1) Configure the Transfer mode as memory to memory with blending. 00550 * 2) Configure the output color mode as RGB565 pixel format. 00551 * 3) Configure the foreground 00552 * - first image loaded from FLASH memory 00553 * - constant alpha value (decreased to see the background) 00554 * - color mode as RGB565 pixel format 00555 * 4) Configure the background 00556 * - second image loaded from FLASH memory 00557 * - color mode as RGB565 pixel format 00558 * @retval None 00559 */ 00560 static void DMA2D_Config(void) 00561 { 00562 /* Configure the DMA2D Mode, Color Mode and output offset */ 00563 Dma2dHandle.Init.Mode = DMA2D_M2M_BLEND; 00564 #if LV_COLOR_DEPTH == 16 00565 Dma2dHandle.Init.ColorMode = DMA2D_RGB565; 00566 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00567 Dma2dHandle.Init.ColorMode = DMA2D_ARGB8888; 00568 #endif 00569 Dma2dHandle.Init.OutputOffset = 0x0; 00570 00571 /* DMA2D Callbacks Configuration */ 00572 Dma2dHandle.XferCpltCallback = DMA2D_TransferComplete; 00573 Dma2dHandle.XferErrorCallback = DMA2D_TransferError; 00574 00575 /* Foreground Configuration */ 00576 Dma2dHandle.LayerCfg[1].AlphaMode = DMA2D_REPLACE_ALPHA; 00577 Dma2dHandle.LayerCfg[1].InputAlpha = 0xFF; 00578 #if LV_COLOR_DEPTH == 16 00579 Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565; 00580 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00581 Dma2dHandle.LayerCfg[1].InputColorMode = DMA2D_INPUT_ARGB8888; 00582 #endif 00583 00584 Dma2dHandle.LayerCfg[1].InputOffset = 0x0; 00585 00586 /* Background Configuration */ 00587 Dma2dHandle.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA; 00588 Dma2dHandle.LayerCfg[0].InputAlpha = 0xFF; 00589 #if LV_COLOR_DEPTH == 16 00590 Dma2dHandle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565; 00591 #elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32 00592 Dma2dHandle.LayerCfg[0].InputColorMode = DMA2D_INPUT_ARGB8888; 00593 #endif 00594 Dma2dHandle.LayerCfg[0].InputOffset = 0x0; 00595 00596 Dma2dHandle.Instance = DMA2D; 00597 00598 /* DMA2D Initialization */ 00599 if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK) 00600 { 00601 /* Initialization Error */ 00602 Error_Handler(); 00603 } 00604 00605 HAL_DMA2D_ConfigLayer(&Dma2dHandle, 0); 00606 HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1); 00607 } 00608 #endif
Generated on Thu Jul 14 2022 20:43:54 by
1.7.2