BSP files for STM32H747I-Discovery Copy from ST Cube delivery
Dependents: DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo
stm32h747i_discovery_lcd.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h747i_discovery_lcd.c 00004 * @author MCD Application Team 00005 * @brief This file includes the driver for Liquid Crystal Display (LCD) module 00006 * mounted on STM32H747I_DISCOVERY board. 00007 ****************************************************************************** 00008 * @attention 00009 * 00010 * <h2><center>© Copyright (c) 2019 STMicroelectronics. 00011 * All rights reserved.</center></h2> 00012 * 00013 * This software component is licensed by ST under BSD 3-Clause license, 00014 * the "License"; You may not use this file except in compliance with the 00015 * License. You may obtain a copy of the License at: 00016 * opensource.org/licenses/BSD-3-Clause 00017 * 00018 ****************************************************************************** 00019 */ 00020 00021 /* File Info: ------------------------------------------------------------------ 00022 User NOTES 00023 1. How To use this driver: 00024 -------------------------- 00025 - This driver is used to drive directly in video mode a LCD TFT using the DSI interface. 00026 The following IPs are implied : DSI Host IP block working 00027 in conjunction to the LTDC controller. 00028 - This driver is linked by construction to LCD KoD mounted on board MB1166. 00029 00030 2. Driver description: 00031 --------------------- 00032 + Initialization steps: 00033 o Initialize the LCD using the BSP_LCD_Init() function. 00034 o Select the LCD layer to be used using the BSP_LCD_SelectLayer() function. 00035 o Enable the LCD display using the BSP_LCD_DisplayOn() function. 00036 00037 + Options 00038 o Configure and enable the color keying functionality using the 00039 BSP_LCD_SetColorKeying() function. 00040 o Modify in the fly the transparency and/or the frame buffer address 00041 using the following functions: 00042 - BSP_LCD_SetTransparency() 00043 - BSP_LCD_SetLayerAddress() 00044 00045 + Display on LCD 00046 o Clear the whole LCD using BSP_LCD_Clear() function or only one specified string 00047 line using the BSP_LCD_ClearStringLine() function. 00048 o Display a character on the specified line and column using the BSP_LCD_DisplayChar() 00049 function or a complete string line using the BSP_LCD_DisplayStringAtLine() function. 00050 o Display a string line on the specified position (x,y in pixel) and align mode 00051 using the BSP_LCD_DisplayStringAtLine() function. 00052 o Draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap) 00053 on LCD using the available set of functions. 00054 00055 ------------------------------------------------------------------------------*/ 00056 00057 /* Includes ------------------------------------------------------------------*/ 00058 #include "stm32h747i_discovery_lcd.h" 00059 #include "../Utilities/Fonts/fonts.h" 00060 // #include "../Utilities/Fonts/font24.c" 00061 // #include "../Utilities/Fonts/font20.c" 00062 // #include "../Utilities/Fonts/font16.c" 00063 // #include "../Utilities/Fonts/font12.c" 00064 // #include "../Utilities/Fonts/font8.c" 00065 00066 /** @addtogroup BSP 00067 * @{ 00068 */ 00069 00070 /** @addtogroup STM32H747I_DISCOVERY 00071 * @{ 00072 */ 00073 00074 /** @defgroup STM32H747I_DISCOVERY_LCD STM32H747I_DISCOVERY_LCD 00075 * @{ 00076 */ 00077 00078 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_Defines Private Defines 00079 * @{ 00080 */ 00081 00082 #if defined(USE_LCD_HDMI) 00083 #define HDMI_ASPECT_RATIO_16_9 ADV7533_ASPECT_RATIO_16_9 00084 #define HDMI_ASPECT_RATIO_4_3 ADV7533_ASPECT_RATIO_4_3 00085 #endif /* USE_LCD_HDMI */ 00086 #define LCD_DSI_ID 0x11 00087 #define LCD_DSI_ID_REG 0xA8 00088 /** 00089 * @} 00090 */ 00091 00092 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_Types Private Types 00093 * @{ 00094 */ 00095 00096 #if defined(USE_LCD_HDMI) 00097 /** 00098 * @brief DSI timming params used for different HDMI adpater 00099 */ 00100 typedef struct 00101 { 00102 uint16_t HACT; 00103 uint16_t HSYNC; 00104 uint16_t HBP; 00105 uint16_t HFP; 00106 uint16_t VACT; 00107 uint16_t VSYNC; 00108 uint16_t VBP; 00109 uint16_t VFP; 00110 uint8_t ASPECT_RATIO; 00111 uint8_t RGB_CODING; 00112 } HDMI_FormatTypeDef; 00113 00114 /** 00115 * @brief DSI packet params used for different HDMI adpater 00116 */ 00117 typedef struct 00118 { 00119 uint16_t NullPacketSize; 00120 uint16_t NumberOfChunks; 00121 uint16_t PacketSize; 00122 } HDMI_DSIPacketTypeDef; 00123 00124 /** 00125 * @brief LTDC PLL params used for different HDMI adpater 00126 */ 00127 typedef struct 00128 { 00129 uint16_t PLL_LTDC_N; 00130 uint16_t PLL_LTDC_R; 00131 uint32_t PCLK; 00132 uint16_t IDF; 00133 uint16_t NDIV; 00134 uint16_t ODF; 00135 uint16_t LaneByteClock; 00136 uint16_t TXEscapeCkdiv; 00137 } HDMI_PLLConfigTypeDef; 00138 00139 #endif /* USE_LCD_HDMI */ 00140 /** 00141 * @} 00142 */ 00143 00144 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_Macros Private Macros 00145 * @{ 00146 */ 00147 #define ABS(X) ((X) > 0 ? (X) : -(X)) 00148 #define POLY_X(Z) ((int32_t)((Points + (Z))->X)) 00149 #define POLY_Y(Z) ((int32_t)((Points + (Z))->Y)) 00150 /** 00151 * @} 00152 */ 00153 00154 /** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Variables Exported Variables 00155 * @{ 00156 */ 00157 DMA2D_HandleTypeDef hdma2d_discovery; 00158 LTDC_HandleTypeDef hltdc_discovery; 00159 DSI_HandleTypeDef hdsi_discovery; 00160 00161 /** 00162 * @} 00163 */ 00164 00165 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_Variables Private Variables 00166 * @{ 00167 */ 00168 static DSI_VidCfgTypeDef hdsivideo_handle; 00169 uint32_t lcd_x_size = OTM8009A_800X480_WIDTH; 00170 uint32_t lcd_y_size = OTM8009A_800X480_HEIGHT; 00171 00172 #if defined(USE_LCD_HDMI) 00173 /** 00174 * @brief DSI timming used for different HDMI resolution (720x480 and 720x576) 00175 */ 00176 HDMI_FormatTypeDef HDMI_Format[2] = 00177 { 00178 /* HA HS HB HF VA VS VB VF ASPECT BPP */ 00179 {720, 62, 60, 30, 480, 6, 19, 9, HDMI_ASPECT_RATIO_4_3, LCD_DSI_PIXEL_DATA_FMT_RBG888}, 00180 {720, 64, 68, 12, 576, 5, 39, 5, HDMI_ASPECT_RATIO_16_9, LCD_DSI_PIXEL_DATA_FMT_RBG888} 00181 00182 }; 00183 00184 /** 00185 * @brief DSI packet size used for different HDMI resolution (720x480 and 720x576) 00186 */ 00187 HDMI_DSIPacketTypeDef HDMI_DSIPacket[2] = 00188 { 00189 /* NP NC VP */ 00190 {0, 1, 720}, 00191 {0, 1, 720} 00192 }; 00193 00194 /** 00195 * @brief LTDC PLL settings used for different HDMI resolution (720x480 and 720x576) 00196 */ 00197 HDMI_PLLConfigTypeDef HDMI_PLLConfig[4] = 00198 { 00199 /* N DIV Pclk IDF NDIV ODF LBClk TXEscapeCkdiv*/ 00200 {13, 12, 27083, DSI_PLL_IN_DIV5, 65, DSI_PLL_OUT_DIV1, 40625, 3}, 00201 {13, 12, 27083, DSI_PLL_IN_DIV5, 65, DSI_PLL_OUT_DIV1, 40625, 3}, 00202 00203 }; 00204 #endif /* USE_LCD_HDMI */ 00205 00206 /** 00207 * @brief Default Active LTDC Layer in which drawing is made is LTDC Layer Background 00208 */ 00209 static uint32_t ActiveLayer = LTDC_ACTIVE_LAYER_BACKGROUND; 00210 00211 /** 00212 * @brief Current Drawing Layer properties variable 00213 */ 00214 static LCD_DrawPropTypeDef DrawProp[LTDC_MAX_LAYER_NUMBER]; 00215 /** 00216 * @} 00217 */ 00218 00219 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_FunctionPrototypes Private FunctionPrototypes 00220 * @{ 00221 */ 00222 static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c); 00223 static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3); 00224 static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex); 00225 static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode); 00226 static uint16_t LCD_IO_GetID(void); 00227 /** 00228 * @} 00229 */ 00230 00231 /** @defgroup STM32H747I_DISCOVERY_LCD_Exported_Functions Exported Functions 00232 * @{ 00233 */ 00234 00235 /** 00236 * @brief Initializes the DSI LCD. 00237 * @retval LCD state 00238 */ 00239 uint8_t BSP_LCD_Init(void) 00240 { 00241 return (BSP_LCD_InitEx(LCD_ORIENTATION_LANDSCAPE)); 00242 } 00243 00244 /** 00245 * @brief Initializes the DSI LCD. 00246 * The ititialization is done as below: 00247 * - DSI PLL ititialization 00248 * - DSI ititialization 00249 * - LTDC ititialization 00250 * - OTM8009A LCD Display IC Driver ititialization 00251 * @param orientation Display orientation 00252 * @retval LCD state 00253 */ 00254 uint8_t BSP_LCD_InitEx(LCD_OrientationTypeDef orientation) 00255 { 00256 DSI_PLLInitTypeDef dsiPllInit; 00257 DSI_PHY_TimerTypeDef PhyTimings; 00258 static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; 00259 uint32_t LcdClock = 26400; /*!< LcdClk = 26400 kHz */ 00260 uint16_t read_id = 0; 00261 00262 uint32_t laneByteClk_kHz = 0; 00263 uint32_t VSA; /*!< Vertical start active time in units of lines */ 00264 uint32_t VBP; /*!< Vertical Back Porch time in units of lines */ 00265 uint32_t VFP; /*!< Vertical Front Porch time in units of lines */ 00266 uint32_t VACT; /*!< Vertical Active time in units of lines = imageSize Y in pixels to display */ 00267 uint32_t HSA; /*!< Horizontal start active time in units of lcdClk */ 00268 uint32_t HBP; /*!< Horizontal Back Porch time in units of lcdClk */ 00269 uint32_t HFP; /*!< Horizontal Front Porch time in units of lcdClk */ 00270 uint32_t HACT; /*!< Horizontal Active time in units of lcdClk = imageSize X in pixels to display */ 00271 00272 /* Toggle Hardware Reset of the DSI LCD using 00273 * its XRES signal (active low) */ 00274 BSP_LCD_Reset(); 00275 00276 /* Check the connected monitor */ 00277 read_id = LCD_IO_GetID(); 00278 00279 #if defined(USE_LCD_HDMI) 00280 if(read_id == ADV7533_ID) 00281 { 00282 return BSP_LCD_HDMIInitEx(HDMI_FORMAT_720_576); 00283 } 00284 else if(read_id != LCD_DSI_ID) 00285 { 00286 return LCD_ERROR; 00287 } 00288 #else 00289 if(read_id != LCD_DSI_ID) 00290 { 00291 return LCD_ERROR; 00292 } 00293 #endif /* USE_LCD_HDMI */ 00294 00295 /* Call first MSP Initialize only in case of first initialization 00296 * This will set IP blocks LTDC, DSI and DMA2D 00297 * - out of reset 00298 * - clocked 00299 * - NVIC IRQ related to IP blocks enabled 00300 */ 00301 BSP_LCD_MspInit(); 00302 00303 /*************************DSI Initialization***********************************/ 00304 00305 /* Base address of DSI Host/Wrapper registers to be set before calling De-Init */ 00306 hdsi_discovery.Instance = DSI; 00307 00308 HAL_DSI_DeInit(&(hdsi_discovery)); 00309 00310 dsiPllInit.PLLNDIV = 100; 00311 dsiPllInit.PLLIDF = DSI_PLL_IN_DIV5; 00312 dsiPllInit.PLLODF = DSI_PLL_OUT_DIV1; 00313 laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */ 00314 00315 /* Set number of Lanes */ 00316 hdsi_discovery.Init.NumberOfLanes = DSI_TWO_DATA_LANES; 00317 00318 /* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 */ 00319 hdsi_discovery.Init.TXEscapeCkdiv = laneByteClk_kHz/15620; 00320 00321 HAL_DSI_Init(&(hdsi_discovery), &(dsiPllInit)); 00322 00323 /* Timing parameters for all Video modes 00324 * Set Timing parameters of LTDC depending on its chosen orientation 00325 */ 00326 if(orientation == LCD_ORIENTATION_PORTRAIT) 00327 { 00328 lcd_x_size = OTM8009A_480X800_WIDTH; /* 480 */ 00329 lcd_y_size = OTM8009A_480X800_HEIGHT; /* 800 */ 00330 } 00331 else 00332 { 00333 /* lcd_orientation == LCD_ORIENTATION_LANDSCAPE */ 00334 lcd_x_size = OTM8009A_800X480_WIDTH; /* 800 */ 00335 lcd_y_size = OTM8009A_800X480_HEIGHT; /* 480 */ 00336 } 00337 00338 HACT = lcd_x_size; 00339 VACT = lcd_y_size; 00340 00341 /* The following values are same for portrait and landscape orientations */ 00342 VSA = OTM8009A_480X800_VSYNC; /* 10 */ 00343 VBP = OTM8009A_480X800_VBP; /* 15 */ 00344 VFP = OTM8009A_480X800_VFP; /* 16 */ 00345 HSA = OTM8009A_480X800_HSYNC; /* 2 */ 00346 HBP = OTM8009A_480X800_HBP; /* 20 */ 00347 HFP = OTM8009A_480X800_HFP; /* 20 */ 00348 00349 00350 hdsivideo_handle.VirtualChannelID = LCD_OTM8009A_ID; 00351 hdsivideo_handle.ColorCoding = LCD_DSI_PIXEL_DATA_FMT_RBG888; 00352 hdsivideo_handle.VSPolarity = DSI_VSYNC_ACTIVE_HIGH; 00353 hdsivideo_handle.HSPolarity = DSI_HSYNC_ACTIVE_HIGH; 00354 hdsivideo_handle.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH; 00355 hdsivideo_handle.Mode = DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */ 00356 hdsivideo_handle.NullPacketSize = 0xFFF; 00357 hdsivideo_handle.NumberOfChunks = 0; 00358 hdsivideo_handle.PacketSize = HACT; /* Value depending on display orientation choice portrait/landscape */ 00359 hdsivideo_handle.HorizontalSyncActive = (HSA * laneByteClk_kHz)/LcdClock; 00360 hdsivideo_handle.HorizontalBackPorch = (HBP * laneByteClk_kHz)/LcdClock; 00361 hdsivideo_handle.HorizontalLine = ((HACT + HSA + HBP + HFP) * laneByteClk_kHz)/LcdClock; /* Value depending on display orientation choice portrait/landscape */ 00362 hdsivideo_handle.VerticalSyncActive = VSA; 00363 hdsivideo_handle.VerticalBackPorch = VBP; 00364 hdsivideo_handle.VerticalFrontPorch = VFP; 00365 hdsivideo_handle.VerticalActive = VACT; /* Value depending on display orientation choice portrait/landscape */ 00366 00367 /* Enable or disable sending LP command while streaming is active in video mode */ 00368 hdsivideo_handle.LPCommandEnable = DSI_LP_COMMAND_ENABLE; /* Enable sending commands in mode LP (Low Power) */ 00369 00370 /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */ 00371 /* Only useful when sending LP packets is allowed while streaming is active in video mode */ 00372 hdsivideo_handle.LPLargestPacketSize = 16; 00373 00374 /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */ 00375 /* Only useful when sending LP packets is allowed while streaming is active in video mode */ 00376 hdsivideo_handle.LPVACTLargestPacketSize = 0; 00377 00378 00379 /* Specify for each region of the video frame, if the transmission of command in LP mode is allowed in this region */ 00380 /* while streaming is active in video mode */ 00381 hdsivideo_handle.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE; /* Allow sending LP commands during HFP period */ 00382 hdsivideo_handle.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE; /* Allow sending LP commands during HBP period */ 00383 hdsivideo_handle.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE; /* Allow sending LP commands during VACT period */ 00384 hdsivideo_handle.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE; /* Allow sending LP commands during VFP period */ 00385 hdsivideo_handle.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE; /* Allow sending LP commands during VBP period */ 00386 hdsivideo_handle.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE; /* Allow sending LP commands during VSync = VSA period */ 00387 00388 /* Configure DSI Video mode timings with settings set above */ 00389 HAL_DSI_ConfigVideoMode(&(hdsi_discovery), &(hdsivideo_handle)); 00390 00391 /* Configure DSI PHY HS2LP and LP2HS timings */ 00392 PhyTimings.ClockLaneHS2LPTime = 35; 00393 PhyTimings.ClockLaneLP2HSTime = 35; 00394 PhyTimings.DataLaneHS2LPTime = 35; 00395 PhyTimings.DataLaneLP2HSTime = 35; 00396 PhyTimings.DataLaneMaxReadTime = 0; 00397 PhyTimings.StopWaitTime = 10; 00398 HAL_DSI_ConfigPhyTimer(&hdsi_discovery, &PhyTimings); 00399 00400 /*************************End DSI Initialization*******************************/ 00401 00402 00403 /************************LTDC Initialization***********************************/ 00404 00405 /* Timing Configuration */ 00406 hltdc_discovery.Init.HorizontalSync = (HSA - 1); 00407 hltdc_discovery.Init.AccumulatedHBP = (HSA + HBP - 1); 00408 hltdc_discovery.Init.AccumulatedActiveW = (lcd_x_size + HSA + HBP - 1); 00409 hltdc_discovery.Init.TotalWidth = (lcd_x_size + HSA + HBP + HFP - 1); 00410 00411 /* Initialize the LCD pixel width and pixel height */ 00412 hltdc_discovery.LayerCfg->ImageWidth = lcd_x_size; 00413 hltdc_discovery.LayerCfg->ImageHeight = lcd_y_size; 00414 00415 00416 /* LCD clock configuration */ 00417 /* PLL3_VCO Input = HSE_VALUE/PLL3M = 5 Mhz */ 00418 /* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 480 Mhz */ 00419 /* PLLLCDCLK = PLL3_VCO Output/PLL3R = 480/18 = 26.666 Mhz */ 00420 /* LTDC clock frequency = PLLLCDCLK = 26.666 Mhz */ 00421 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; 00422 PeriphClkInitStruct.PLL3.PLL3M = 5; 00423 PeriphClkInitStruct.PLL3.PLL3N = 96; 00424 PeriphClkInitStruct.PLL3.PLL3P = 2; 00425 PeriphClkInitStruct.PLL3.PLL3Q = 10; 00426 PeriphClkInitStruct.PLL3.PLL3R = 18; 00427 HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); 00428 00429 /* Background value */ 00430 hltdc_discovery.Init.Backcolor.Blue = 0; 00431 hltdc_discovery.Init.Backcolor.Green = 0; 00432 hltdc_discovery.Init.Backcolor.Red = 0; 00433 hltdc_discovery.Init.PCPolarity = LTDC_PCPOLARITY_IPC; 00434 hltdc_discovery.Instance = LTDC; 00435 00436 /* Get LTDC Configuration from DSI Configuration */ 00437 HAL_LTDC_StructInitFromVideoConfig(&(hltdc_discovery), &(hdsivideo_handle)); 00438 00439 /* Initialize the LTDC */ 00440 HAL_LTDC_Init(&hltdc_discovery); 00441 00442 /* Enable the DSI host and wrapper : after LTDC */ 00443 /* To avoid any synchronization issue, the DSI shall be started after enabling the LTDC */ 00444 HAL_DSI_Start(&hdsi_discovery); 00445 00446 #if !defined(DATA_IN_ExtSDRAM) 00447 /* Initialize the SDRAM */ 00448 BSP_SDRAM_Init(); 00449 #endif /* DATA_IN_ExtSDRAM */ 00450 00451 /* Initialize the font */ 00452 BSP_LCD_SetFont(&LCD_DEFAULT_FONT); 00453 00454 /************************End LTDC Initialization*******************************/ 00455 00456 00457 /***********************OTM8009A Initialization********************************/ 00458 00459 /* Initialize the OTM8009A LCD Display IC Driver (KoD LCD IC Driver) 00460 * depending on configuration set in 'hdsivideo_handle'. 00461 */ 00462 OTM8009A_Init(OTM8009A_FORMAT_RGB888, orientation); 00463 00464 /***********************End OTM8009A Initialization****************************/ 00465 00466 return LCD_OK; 00467 } 00468 00469 #if defined(USE_LCD_HDMI) 00470 /** 00471 * @brief Initializes the DSI for HDMI monitor. 00472 * The ititialization is done as below: 00473 * - DSI PLL ititialization 00474 * - DSI ititialization 00475 * - LTDC ititialization 00476 * - DSI-HDMI ADV7533 adapter device ititialization 00477 * @param format : HDMI format could be HDMI_FORMAT_720_480 or HDMI_FORMAT_720_576 00478 * @retval LCD state 00479 */ 00480 uint8_t BSP_LCD_HDMIInitEx(uint8_t format) 00481 { 00482 /************************ADV7533 Initialization******************************/ 00483 00484 /* Initialize the ADV7533 HDMI Bridge 00485 depending on configuration set in 'hdsivideo_handle'. */ 00486 adv7533ConfigTypeDef adv7533_config; 00487 00488 adv7533_config.DSI_LANES = 2; 00489 adv7533_config.HACT = HDMI_Format[format].HACT; 00490 adv7533_config.HSYNC = HDMI_Format[format].HSYNC; 00491 adv7533_config.HBP = HDMI_Format[format].HBP; 00492 adv7533_config.HFP = HDMI_Format[format].HFP; 00493 adv7533_config.VACT = HDMI_Format[format].VACT; 00494 adv7533_config.VSYNC = HDMI_Format[format].VSYNC; 00495 adv7533_config.VBP = HDMI_Format[format].VBP; 00496 adv7533_config.VFP = HDMI_Format[format].VFP; 00497 00498 ADV7533_Init(); 00499 ADV7533_Configure(&adv7533_config); 00500 ADV7533_PowerOn(); 00501 00502 /************************ Update hdmi_x_size and hdmi_y_size *****************/ 00503 lcd_x_size = HDMI_Format[format].HACT; 00504 lcd_y_size = HDMI_Format[format].VACT; 00505 00506 /***********************End ADV7533 Initialization****************************/ 00507 00508 DSI_PLLInitTypeDef dsiPllInit; 00509 DSI_PHY_TimerTypeDef dsiPhyInit; 00510 static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; 00511 00512 /* Call first MSP Initialize only in case of first initialization 00513 * This will set IP blocks LTDC and DSI 00514 * - out of reset 00515 * - clocked 00516 * - NVIC IRQ related to IP blocks enabled 00517 */ 00518 BSP_LCD_MspInit(); 00519 00520 /*************************DSI Initialization***********************************/ 00521 00522 /* Base address of DSI Host/Wrapper registers to be set before calling De-Init */ 00523 hdsi_discovery.Instance = DSI; 00524 00525 HAL_DSI_DeInit(&(hdsi_discovery)); 00526 00527 /* Configure the DSI PLL */ 00528 dsiPllInit.PLLNDIV = HDMI_PLLConfig[format].NDIV; 00529 dsiPllInit.PLLIDF = HDMI_PLLConfig[format].IDF; 00530 dsiPllInit.PLLODF = HDMI_PLLConfig[format].ODF; 00531 00532 /* Set number of Lanes */ 00533 hdsi_discovery.Init.NumberOfLanes = DSI_TWO_DATA_LANES; 00534 /* Set the TX escape clock division ratio */ 00535 hdsi_discovery.Init.TXEscapeCkdiv = HDMI_PLLConfig[format].TXEscapeCkdiv; 00536 /* Disable the automatic clock lane control (the ADV7533 must be clocked) */ 00537 hdsi_discovery.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE; 00538 00539 /* Init the DSI */ 00540 HAL_DSI_Init(&hdsi_discovery, &dsiPllInit); 00541 00542 /* Configure the D-PHY Timings */ 00543 dsiPhyInit.ClockLaneHS2LPTime = 0x14; 00544 dsiPhyInit.ClockLaneLP2HSTime = 0x14; 00545 dsiPhyInit.DataLaneHS2LPTime = 0x0A; 00546 dsiPhyInit.DataLaneLP2HSTime = 0x0A; 00547 dsiPhyInit.DataLaneMaxReadTime = 0x00; 00548 dsiPhyInit.StopWaitTime = 0x0; 00549 HAL_DSI_ConfigPhyTimer(&hdsi_discovery, &dsiPhyInit); 00550 00551 /* Virutal channel used by the ADV7533 */ 00552 hdsivideo_handle.VirtualChannelID = HDMI_ADV7533_ID; 00553 00554 /* Timing parameters for Video modes 00555 Set Timing parameters of DSI depending on its chosen format */ 00556 hdsivideo_handle.ColorCoding = HDMI_Format[format].RGB_CODING; 00557 hdsivideo_handle.LooselyPacked = DSI_LOOSELY_PACKED_DISABLE; 00558 hdsivideo_handle.VSPolarity = DSI_VSYNC_ACTIVE_LOW; 00559 hdsivideo_handle.HSPolarity = DSI_HSYNC_ACTIVE_LOW; 00560 hdsivideo_handle.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH; 00561 hdsivideo_handle.Mode = DSI_VID_MODE_NB_PULSES; 00562 hdsivideo_handle.NullPacketSize = HDMI_DSIPacket[format].NullPacketSize; 00563 hdsivideo_handle.NumberOfChunks = HDMI_DSIPacket[format].NumberOfChunks; 00564 hdsivideo_handle.PacketSize = HDMI_DSIPacket[format].PacketSize; 00565 hdsivideo_handle.HorizontalSyncActive = HDMI_Format[format].HSYNC*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK; 00566 hdsivideo_handle.HorizontalBackPorch = HDMI_Format[format].HBP*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK; 00567 hdsivideo_handle.HorizontalLine = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP + HDMI_Format[format].HFP)*HDMI_PLLConfig[format].LaneByteClock/HDMI_PLLConfig[format].PCLK; 00568 hdsivideo_handle.VerticalSyncActive = HDMI_Format[format].VSYNC; 00569 hdsivideo_handle.VerticalBackPorch = HDMI_Format[format].VBP; 00570 hdsivideo_handle.VerticalFrontPorch = HDMI_Format[format].VFP; 00571 hdsivideo_handle.VerticalActive = HDMI_Format[format].VACT; 00572 00573 /* Enable or disable sending LP command while streaming is active in video mode */ 00574 hdsivideo_handle.LPCommandEnable = DSI_LP_COMMAND_DISABLE; /* Enable sending commands in mode LP (Low Power) */ 00575 00576 /* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */ 00577 /* Only useful when sending LP packets is allowed while streaming is active in video mode */ 00578 hdsivideo_handle.LPLargestPacketSize = 4; 00579 00580 /* Largest packet size possible to transmit in LP mode in HFP region during VACT period */ 00581 /* Only useful when sending LP packets is allowed while streaming is active in video mode */ 00582 hdsivideo_handle.LPVACTLargestPacketSize = 4; 00583 00584 /* Specify for each region, if the going in LP mode is allowed */ 00585 /* while streaming is active in video mode */ 00586 hdsivideo_handle.LPHorizontalFrontPorchEnable = DSI_LP_HFP_DISABLE; 00587 hdsivideo_handle.LPHorizontalBackPorchEnable = DSI_LP_HBP_DISABLE; 00588 hdsivideo_handle.LPVerticalActiveEnable = DSI_LP_VACT_DISABLE; 00589 hdsivideo_handle.LPVerticalFrontPorchEnable = DSI_LP_VFP_DISABLE; 00590 hdsivideo_handle.LPVerticalBackPorchEnable = DSI_LP_VBP_DISABLE; 00591 hdsivideo_handle.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_DISABLE; 00592 00593 /* No acknoledge at the end of a frame */ 00594 hdsivideo_handle.FrameBTAAcknowledgeEnable = DSI_FBTAA_DISABLE; 00595 00596 /* Configure DSI Video mode timings with settings set above */ 00597 HAL_DSI_ConfigVideoMode(&hdsi_discovery, &hdsivideo_handle); 00598 00599 /* Enable the DSI host and wrapper : but LTDC is not started yet at this stage */ 00600 HAL_DSI_Start(&hdsi_discovery); 00601 00602 /*************************End DSI Initialization*******************************/ 00603 00604 00605 /************************LTDC Initialization***********************************/ 00606 00607 /* LCD clock configuration */ 00608 /* LCD clock configuration */ 00609 /* PLL3_VCO Input = HSE_VALUE/PLL3M = 25 Mhz */ 00610 /* PLL3_VCO Output = PLL3_VCO Input * PLL3N */ 00611 /* PLLLCDCLK = PLL3_VCO Output/PLL3R */ 00612 /* LTDC clock frequency = PLLLCDCLK */ 00613 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC; 00614 PeriphClkInitStruct.PLL3.PLL3M = 1; 00615 PeriphClkInitStruct.PLL3.PLL3N = HDMI_PLLConfig[format].PLL_LTDC_N; 00616 PeriphClkInitStruct.PLL3.PLL3P = 2; 00617 PeriphClkInitStruct.PLL3.PLL3Q = 2; 00618 PeriphClkInitStruct.PLL3.PLL3R = HDMI_PLLConfig[format].PLL_LTDC_R; 00619 HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); 00620 00621 /* Base address of LTDC registers to be set before calling De-Init */ 00622 hltdc_discovery.Instance = LTDC; 00623 00624 HAL_LTDC_DeInit(&(hltdc_discovery)); 00625 00626 /* Timing Configuration */ 00627 hltdc_discovery.Init.HorizontalSync = (HDMI_Format[format].HSYNC - 1); 00628 hltdc_discovery.Init.AccumulatedHBP = (HDMI_Format[format].HSYNC + HDMI_Format[format].HBP - 1); 00629 hltdc_discovery.Init.AccumulatedActiveW = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP - 1); 00630 hltdc_discovery.Init.TotalWidth = (HDMI_Format[format].HACT + HDMI_Format[format].HSYNC + HDMI_Format[format].HBP + HDMI_Format[format].HFP - 1); 00631 hltdc_discovery.Init.VerticalSync = (HDMI_Format[format].VSYNC - 1); 00632 hltdc_discovery.Init.AccumulatedVBP = (HDMI_Format[format].VSYNC + HDMI_Format[format].VBP - 1); 00633 hltdc_discovery.Init.AccumulatedActiveH = (HDMI_Format[format].VACT + HDMI_Format[format].VSYNC + HDMI_Format[format].VBP - 1); 00634 hltdc_discovery.Init.TotalHeigh = (HDMI_Format[format].VACT + HDMI_Format[format].VSYNC + HDMI_Format[format].VBP + HDMI_Format[format].VFP - 1); 00635 00636 /* background value */ 00637 hltdc_discovery.Init.Backcolor.Blue = 0x00; 00638 hltdc_discovery.Init.Backcolor.Green = 0xFF; 00639 hltdc_discovery.Init.Backcolor.Red = 0xFF; 00640 00641 /* Polarity */ 00642 hltdc_discovery.Init.HSPolarity = LTDC_HSPOLARITY_AL; 00643 hltdc_discovery.Init.VSPolarity = LTDC_VSPOLARITY_AL; 00644 hltdc_discovery.Init.DEPolarity = LTDC_DEPOLARITY_AL; 00645 hltdc_discovery.Init.PCPolarity = LTDC_PCPOLARITY_IPC; 00646 00647 /* Initialize & Start the LTDC */ 00648 HAL_LTDC_Init(&hltdc_discovery); 00649 00650 #if !defined(DATA_IN_ExtSDRAM) 00651 /* Initialize the SDRAM */ 00652 BSP_SDRAM_Init(); 00653 #endif /* DATA_IN_ExtSDRAM */ 00654 00655 /* Initialize the font */ 00656 BSP_LCD_SetFont(&LCD_DEFAULT_FONT); 00657 /************************End LTDC Initialization*******************************/ 00658 00659 return LCD_OK; 00660 } 00661 #endif /* USE_LCD_HDMI */ 00662 00663 /** 00664 * @brief BSP LCD Reset 00665 * Hw reset the LCD DSI activating its XRES signal (active low for some time) 00666 * and deactivating it later. 00667 * @retval None 00668 */ 00669 void BSP_LCD_Reset(void) 00670 { 00671 GPIO_InitTypeDef gpio_init_structure; 00672 00673 __HAL_RCC_GPIOG_CLK_ENABLE(); 00674 00675 /* Configure the GPIO on PG3 */ 00676 gpio_init_structure.Pin = GPIO_PIN_3; 00677 gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP; 00678 gpio_init_structure.Pull = GPIO_PULLUP; 00679 gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00680 00681 HAL_GPIO_Init(GPIOG, &gpio_init_structure); 00682 00683 /* Activate XRES active low */ 00684 HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_RESET); 00685 00686 HAL_Delay(20); /* wait 20 ms */ 00687 00688 /* Desactivate XRES */ 00689 HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_SET); 00690 00691 /* Wait for 10ms after releasing XRES before sending commands */ 00692 HAL_Delay(10); 00693 } 00694 00695 /** 00696 * @brief Gets the LCD X size. 00697 * @retval Used LCD X size 00698 */ 00699 uint32_t BSP_LCD_GetXSize(void) 00700 { 00701 return (lcd_x_size); 00702 } 00703 00704 /** 00705 * @brief Gets the LCD Y size. 00706 * @retval Used LCD Y size 00707 */ 00708 uint32_t BSP_LCD_GetYSize(void) 00709 { 00710 return (lcd_y_size); 00711 } 00712 00713 /** 00714 * @brief Set the LCD X size. 00715 * @param imageWidthPixels : uint32_t image width in pixels unit 00716 * @retval None 00717 */ 00718 void BSP_LCD_SetXSize(uint32_t imageWidthPixels) 00719 { 00720 hltdc_discovery.LayerCfg[ActiveLayer].ImageWidth = imageWidthPixels; 00721 } 00722 00723 /** 00724 * @brief Set the LCD Y size. 00725 * @param imageHeightPixels : uint32_t image height in lines unit 00726 */ 00727 void BSP_LCD_SetYSize(uint32_t imageHeightPixels) 00728 { 00729 hltdc_discovery.LayerCfg[ActiveLayer].ImageHeight = imageHeightPixels; 00730 } 00731 00732 00733 /** 00734 * @brief Initializes the LCD layers. 00735 * @param LayerIndex: Layer foreground or background 00736 * @param FB_Address: Layer frame buffer 00737 * @retval None 00738 */ 00739 void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address) 00740 { 00741 LCD_LayerCfgTypeDef Layercfg; 00742 00743 /* Layer Init */ 00744 Layercfg.WindowX0 = 0; 00745 Layercfg.WindowX1 = BSP_LCD_GetXSize(); 00746 Layercfg.WindowY0 = 0; 00747 Layercfg.WindowY1 = BSP_LCD_GetYSize(); 00748 Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888; 00749 Layercfg.FBStartAdress = FB_Address; 00750 Layercfg.Alpha = 255; 00751 Layercfg.Alpha0 = 0; 00752 Layercfg.Backcolor.Blue = 0; 00753 Layercfg.Backcolor.Green = 0; 00754 Layercfg.Backcolor.Red = 0; 00755 Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; 00756 Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; 00757 Layercfg.ImageWidth = BSP_LCD_GetXSize(); 00758 Layercfg.ImageHeight = BSP_LCD_GetYSize(); 00759 00760 HAL_LTDC_ConfigLayer(&hltdc_discovery, &Layercfg, LayerIndex); 00761 00762 DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE; 00763 DrawProp[LayerIndex].pFont = &Font24; 00764 DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK; 00765 } 00766 00767 00768 /** 00769 * @brief Selects the LCD Layer. 00770 * @param LayerIndex: Layer foreground or background 00771 */ 00772 void BSP_LCD_SelectLayer(uint32_t LayerIndex) 00773 { 00774 ActiveLayer = LayerIndex; 00775 } 00776 00777 /** 00778 * @brief Sets an LCD Layer visible 00779 * @param LayerIndex: Visible Layer 00780 * @param State: New state of the specified layer 00781 * This parameter can be one of the following values: 00782 * @arg ENABLE 00783 * @arg DISABLE 00784 */ 00785 void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State) 00786 { 00787 if(State == ENABLE) 00788 { 00789 __HAL_LTDC_LAYER_ENABLE(&(hltdc_discovery), LayerIndex); 00790 } 00791 else 00792 { 00793 __HAL_LTDC_LAYER_DISABLE(&(hltdc_discovery), LayerIndex); 00794 } 00795 __HAL_LTDC_RELOAD_CONFIG(&(hltdc_discovery)); 00796 00797 } 00798 00799 /** 00800 * @brief Configures the transparency. 00801 * @param LayerIndex: Layer foreground or background. 00802 * @param Transparency: Transparency 00803 * This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF 00804 */ 00805 void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency) 00806 { 00807 00808 HAL_LTDC_SetAlpha(&(hltdc_discovery), Transparency, LayerIndex); 00809 00810 } 00811 00812 /** 00813 * @brief Sets an LCD layer frame buffer address. 00814 * @param LayerIndex: Layer foreground or background 00815 * @param Address: New LCD frame buffer value 00816 */ 00817 void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address) 00818 { 00819 00820 HAL_LTDC_SetAddress(&(hltdc_discovery), Address, LayerIndex); 00821 00822 } 00823 00824 /** 00825 * @brief Sets display window. 00826 * @param LayerIndex: Layer index 00827 * @param Xpos: LCD X position 00828 * @param Ypos: LCD Y position 00829 * @param Width: LCD window width 00830 * @param Height: LCD window height 00831 */ 00832 void BSP_LCD_SetLayerWindow(uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) 00833 { 00834 /* Reconfigure the layer size */ 00835 HAL_LTDC_SetWindowSize(&(hltdc_discovery), Width, Height, LayerIndex); 00836 00837 /* Reconfigure the layer position */ 00838 HAL_LTDC_SetWindowPosition(&(hltdc_discovery), Xpos, Ypos, LayerIndex); 00839 00840 } 00841 00842 /** 00843 * @brief Configures and sets the color keying. 00844 * @param LayerIndex: Layer foreground or background 00845 * @param RGBValue: Color reference 00846 */ 00847 void BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue) 00848 { 00849 /* Configure and Enable the color Keying for LCD Layer */ 00850 HAL_LTDC_ConfigColorKeying(&(hltdc_discovery), RGBValue, LayerIndex); 00851 HAL_LTDC_EnableColorKeying(&(hltdc_discovery), LayerIndex); 00852 } 00853 00854 /** 00855 * @brief Disables the color keying. 00856 * @param LayerIndex: Layer foreground or background 00857 */ 00858 void BSP_LCD_ResetColorKeying(uint32_t LayerIndex) 00859 { 00860 /* Disable the color Keying for LCD Layer */ 00861 HAL_LTDC_DisableColorKeying(&(hltdc_discovery), LayerIndex); 00862 } 00863 00864 /** 00865 * @brief Sets the LCD text color. 00866 * @param Color: Text color code ARGB(8-8-8-8) 00867 */ 00868 void BSP_LCD_SetTextColor(uint32_t Color) 00869 { 00870 DrawProp[ActiveLayer].TextColor = Color; 00871 } 00872 00873 /** 00874 * @brief Gets the LCD text color. 00875 * @retval Used text color. 00876 */ 00877 uint32_t BSP_LCD_GetTextColor(void) 00878 { 00879 return DrawProp[ActiveLayer].TextColor; 00880 } 00881 00882 /** 00883 * @brief Sets the LCD background color. 00884 * @param Color: Layer background color code ARGB(8-8-8-8) 00885 */ 00886 void BSP_LCD_SetBackColor(uint32_t Color) 00887 { 00888 DrawProp[ActiveLayer].BackColor = Color; 00889 } 00890 00891 /** 00892 * @brief Gets the LCD background color. 00893 * @retval Used background color 00894 */ 00895 uint32_t BSP_LCD_GetBackColor(void) 00896 { 00897 return DrawProp[ActiveLayer].BackColor; 00898 } 00899 00900 /** 00901 * @brief Sets the LCD text font. 00902 * @param fonts: Layer font to be used 00903 */ 00904 void BSP_LCD_SetFont(sFONT *fonts) 00905 { 00906 DrawProp[ActiveLayer].pFont = fonts; 00907 } 00908 00909 /** 00910 * @brief Gets the LCD text font. 00911 * @retval Used layer font 00912 */ 00913 sFONT *BSP_LCD_GetFont(void) 00914 { 00915 return DrawProp[ActiveLayer].pFont; 00916 } 00917 00918 /** 00919 * @brief Reads an LCD pixel. 00920 * @param Xpos: X position 00921 * @param Ypos: Y position 00922 * @retval RGB pixel color 00923 */ 00924 uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos) 00925 { 00926 uint32_t ret = 0; 00927 00928 if(hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) 00929 { 00930 /* Read data value from SDRAM memory */ 00931 ret = *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos))); 00932 } 00933 else if(hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB888) 00934 { 00935 /* Read data value from SDRAM memory */ 00936 ret = (*(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos))) & 0x00FFFFFF); 00937 } 00938 else if((hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \ 00939 (hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \ 00940 (hltdc_discovery.LayerCfg[ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_AL88)) 00941 { 00942 /* Read data value from SDRAM memory */ 00943 ret = *(__IO uint16_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*BSP_LCD_GetXSize() + Xpos))); 00944 } 00945 else 00946 { 00947 /* Read data value from SDRAM memory */ 00948 ret = *(__IO uint8_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (2*(Ypos*BSP_LCD_GetXSize() + Xpos))); 00949 } 00950 00951 return ret; 00952 } 00953 00954 /** 00955 * @brief Clears the whole currently active layer of LTDC. 00956 * @param Color: Color of the background 00957 * @retval None 00958 */ 00959 void BSP_LCD_Clear(uint32_t Color) 00960 { 00961 /* Clear the LCD */ 00962 LL_FillBuffer(ActiveLayer, (uint32_t *)(hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress), BSP_LCD_GetXSize(), BSP_LCD_GetYSize(), 0, Color); 00963 } 00964 00965 /** 00966 * @brief Clears the selected line in currently active layer. 00967 * @param Line: Line to be cleared 00968 * @retval None 00969 */ 00970 void BSP_LCD_ClearStringLine(uint32_t Line) 00971 { 00972 uint32_t color_backup = DrawProp[ActiveLayer].TextColor; 00973 DrawProp[ActiveLayer].TextColor = DrawProp[ActiveLayer].BackColor; 00974 00975 /* Draw rectangle with background color */ 00976 BSP_LCD_FillRect(0, (Line * DrawProp[ActiveLayer].pFont->Height), BSP_LCD_GetXSize(), DrawProp[ActiveLayer].pFont->Height); 00977 00978 DrawProp[ActiveLayer].TextColor = color_backup; 00979 BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor); 00980 } 00981 00982 /** 00983 * @brief Displays one character in currently active layer. 00984 * @param Xpos: Start column address 00985 * @param Ypos: Line where to display the character shape. 00986 * @param Ascii: Character ascii code 00987 * This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E 00988 * @retval None 00989 */ 00990 void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii) 00991 { 00992 DrawChar(Xpos, Ypos, &DrawProp[ActiveLayer].pFont->table[(Ascii-' ') *\ 00993 DrawProp[ActiveLayer].pFont->Height * ((DrawProp[ActiveLayer].pFont->Width + 7) / 8)]); 00994 } 00995 00996 /** 00997 * @brief Displays characters in currently active layer. 00998 * @param Xpos: X position (in pixel) 00999 * @param Ypos: Y position (in pixel) 01000 * @param Text: Pointer to string to display on LCD 01001 * @param Mode: Display mode 01002 * This parameter can be one of the following values: 01003 * @arg CENTER_MODE 01004 * @arg RIGHT_MODE 01005 * @arg LEFT_MODE 01006 * @retval None 01007 */ 01008 void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode) 01009 { 01010 uint16_t refcolumn = 1, i = 0; 01011 uint32_t size = 0, xsize = 0; 01012 uint8_t *ptr = Text; 01013 01014 /* Get the text size */ 01015 while (*ptr++) size ++ ; 01016 01017 /* Characters number per line */ 01018 xsize = (BSP_LCD_GetXSize()/DrawProp[ActiveLayer].pFont->Width); 01019 01020 switch (Mode) 01021 { 01022 case CENTER_MODE: 01023 { 01024 refcolumn = Xpos + ((xsize - size)* DrawProp[ActiveLayer].pFont->Width) / 2; 01025 break; 01026 } 01027 case LEFT_MODE: 01028 { 01029 refcolumn = Xpos; 01030 break; 01031 } 01032 case RIGHT_MODE: 01033 { 01034 refcolumn = - Xpos + ((xsize - size)*DrawProp[ActiveLayer].pFont->Width); 01035 break; 01036 } 01037 default: 01038 { 01039 refcolumn = Xpos; 01040 break; 01041 } 01042 } 01043 01044 /* Check that the Start column is located in the screen */ 01045 if ((refcolumn < 1) || (refcolumn >= 0x8000)) 01046 { 01047 refcolumn = 1; 01048 } 01049 01050 /* Send the string character by character on LCD */ 01051 while ((*Text != 0) & (((BSP_LCD_GetXSize() - (i*DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF) >= DrawProp[ActiveLayer].pFont->Width)) 01052 { 01053 /* Display one character on LCD */ 01054 BSP_LCD_DisplayChar(refcolumn, Ypos, *Text); 01055 /* Decrement the column position by 16 */ 01056 refcolumn += DrawProp[ActiveLayer].pFont->Width; 01057 01058 /* Point on the next character */ 01059 Text++; 01060 i++; 01061 } 01062 01063 } 01064 01065 /** 01066 * @brief Displays a maximum of 60 characters on the LCD. 01067 * @param Line: Line where to display the character shape 01068 * @param ptr: Pointer to string to display on LCD 01069 * @retval None 01070 */ 01071 void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr) 01072 { 01073 BSP_LCD_DisplayStringAt(0, LINE(Line), ptr, LEFT_MODE); 01074 } 01075 01076 /** 01077 * @brief Draws an horizontal line in currently active layer. 01078 * @param Xpos: X position 01079 * @param Ypos: Y position 01080 * @param Length: Line length 01081 * @retval None 01082 */ 01083 void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length) 01084 { 01085 uint32_t Xaddress = 0; 01086 01087 /* Get the line address */ 01088 Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos); 01089 01090 /* Write line */ 01091 LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Length, 1, 0, DrawProp[ActiveLayer].TextColor); 01092 } 01093 01094 /** 01095 * @brief Draws a vertical line in currently active layer. 01096 * @param Xpos: X position 01097 * @param Ypos: Y position 01098 * @param Length: Line length 01099 * @retval None 01100 */ 01101 void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length) 01102 { 01103 uint32_t Xaddress = 0; 01104 01105 /* Get the line address */ 01106 Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos); 01107 01108 /* Write line */ 01109 LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, 1, Length, (BSP_LCD_GetXSize() - 1), DrawProp[ActiveLayer].TextColor); 01110 } 01111 01112 /** 01113 * @brief Draws an uni-line (between two points) in currently active layer. 01114 * @param x1: Point 1 X position 01115 * @param y1: Point 1 Y position 01116 * @param x2: Point 2 X position 01117 * @param y2: Point 2 Y position 01118 * @retval None 01119 */ 01120 void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) 01121 { 01122 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 01123 yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 01124 curpixel = 0; 01125 01126 deltax = ABS(x2 - x1); /* The difference between the x's */ 01127 deltay = ABS(y2 - y1); /* The difference between the y's */ 01128 x = x1; /* Start x off at the first pixel */ 01129 y = y1; /* Start y off at the first pixel */ 01130 01131 if (x2 >= x1) /* The x-values are increasing */ 01132 { 01133 xinc1 = 1; 01134 xinc2 = 1; 01135 } 01136 else /* The x-values are decreasing */ 01137 { 01138 xinc1 = -1; 01139 xinc2 = -1; 01140 } 01141 01142 if (y2 >= y1) /* The y-values are increasing */ 01143 { 01144 yinc1 = 1; 01145 yinc2 = 1; 01146 } 01147 else /* The y-values are decreasing */ 01148 { 01149 yinc1 = -1; 01150 yinc2 = -1; 01151 } 01152 01153 if (deltax >= deltay) /* There is at least one x-value for every y-value */ 01154 { 01155 xinc1 = 0; /* Don't change the x when numerator >= denominator */ 01156 yinc2 = 0; /* Don't change the y for every iteration */ 01157 den = deltax; 01158 num = deltax / 2; 01159 numadd = deltay; 01160 numpixels = deltax; /* There are more x-values than y-values */ 01161 } 01162 else /* There is at least one y-value for every x-value */ 01163 { 01164 xinc2 = 0; /* Don't change the x for every iteration */ 01165 yinc1 = 0; /* Don't change the y when numerator >= denominator */ 01166 den = deltay; 01167 num = deltay / 2; 01168 numadd = deltax; 01169 numpixels = deltay; /* There are more y-values than x-values */ 01170 } 01171 01172 for (curpixel = 0; curpixel <= numpixels; curpixel++) 01173 { 01174 BSP_LCD_DrawPixel(x, y, DrawProp[ActiveLayer].TextColor); /* Draw the current pixel */ 01175 num += numadd; /* Increase the numerator by the top of the fraction */ 01176 if (num >= den) /* Check if numerator >= denominator */ 01177 { 01178 num -= den; /* Calculate the new numerator value */ 01179 x += xinc1; /* Change the x as appropriate */ 01180 y += yinc1; /* Change the y as appropriate */ 01181 } 01182 x += xinc2; /* Change the x as appropriate */ 01183 y += yinc2; /* Change the y as appropriate */ 01184 } 01185 } 01186 01187 /** 01188 * @brief Draws a rectangle in currently active layer. 01189 * @param Xpos: X position 01190 * @param Ypos: Y position 01191 * @param Width: Rectangle width 01192 * @param Height: Rectangle height 01193 * @retval None 01194 */ 01195 void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) 01196 { 01197 /* Draw horizontal lines */ 01198 BSP_LCD_DrawHLine(Xpos, Ypos, Width); 01199 BSP_LCD_DrawHLine(Xpos, (Ypos+ Height), Width); 01200 01201 /* Draw vertical lines */ 01202 BSP_LCD_DrawVLine(Xpos, Ypos, Height); 01203 BSP_LCD_DrawVLine((Xpos + Width), Ypos, Height); 01204 } 01205 01206 /** 01207 * @brief Draws a circle in currently active layer. 01208 * @param Xpos: X position 01209 * @param Ypos: Y position 01210 * @param Radius: Circle radius 01211 * @retval None 01212 */ 01213 void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius) 01214 { 01215 int32_t D; /* Decision Variable */ 01216 uint32_t CurX; /* Current X Value */ 01217 uint32_t CurY; /* Current Y Value */ 01218 01219 D = 3 - (Radius << 1); 01220 CurX = 0; 01221 CurY = Radius; 01222 01223 while (CurX <= CurY) 01224 { 01225 BSP_LCD_DrawPixel((Xpos + CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor); 01226 01227 BSP_LCD_DrawPixel((Xpos - CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor); 01228 01229 BSP_LCD_DrawPixel((Xpos + CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor); 01230 01231 BSP_LCD_DrawPixel((Xpos - CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor); 01232 01233 BSP_LCD_DrawPixel((Xpos + CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor); 01234 01235 BSP_LCD_DrawPixel((Xpos - CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor); 01236 01237 BSP_LCD_DrawPixel((Xpos + CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor); 01238 01239 BSP_LCD_DrawPixel((Xpos - CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor); 01240 01241 if (D < 0) 01242 { 01243 D += (CurX << 2) + 6; 01244 } 01245 else 01246 { 01247 D += ((CurX - CurY) << 2) + 10; 01248 CurY--; 01249 } 01250 CurX++; 01251 } 01252 } 01253 01254 /** 01255 * @brief Draws an poly-line (between many points) in currently active layer. 01256 * @param Points: Pointer to the points array 01257 * @param PointCount: Number of points 01258 * @retval None 01259 */ 01260 void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount) 01261 { 01262 int16_t X = 0, Y = 0; 01263 01264 if(PointCount < 2) 01265 { 01266 return; 01267 } 01268 01269 BSP_LCD_DrawLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y); 01270 01271 while(--PointCount) 01272 { 01273 X = Points->X; 01274 Y = Points->Y; 01275 Points++; 01276 BSP_LCD_DrawLine(X, Y, Points->X, Points->Y); 01277 } 01278 } 01279 01280 /** 01281 * @brief Draws an ellipse on LCD in currently active layer. 01282 * @param Xpos: X position 01283 * @param Ypos: Y position 01284 * @param XRadius: Ellipse X radius 01285 * @param YRadius: Ellipse Y radius 01286 * @retval None 01287 */ 01288 void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius) 01289 { 01290 int x = 0, y = -YRadius, err = 2-2*XRadius, e2; 01291 float K = 0, rad1 = 0, rad2 = 0; 01292 01293 rad1 = XRadius; 01294 rad2 = YRadius; 01295 01296 K = (float)(rad2/rad1); 01297 01298 do { 01299 BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos+y), DrawProp[ActiveLayer].TextColor); 01300 BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos+y), DrawProp[ActiveLayer].TextColor); 01301 BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos-y), DrawProp[ActiveLayer].TextColor); 01302 BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos-y), DrawProp[ActiveLayer].TextColor); 01303 01304 e2 = err; 01305 if (e2 <= x) { 01306 err += ++x*2+1; 01307 if (-y == x && e2 <= y) e2 = 0; 01308 } 01309 if (e2 > y) err += ++y*2+1; 01310 } 01311 while (y <= 0); 01312 } 01313 01314 /** 01315 * @brief Draws a bitmap picture loaded in the internal Flash (32 bpp) in currently active layer. 01316 * @param Xpos: Bmp X position in the LCD 01317 * @param Ypos: Bmp Y position in the LCD 01318 * @param pbmp: Pointer to Bmp picture address in the internal Flash 01319 * @retval None 01320 */ 01321 void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp) 01322 { 01323 uint32_t index = 0, width = 0, height = 0, bit_pixel = 0; 01324 uint32_t Address; 01325 uint32_t InputColorMode = 0; 01326 01327 /* Get bitmap data address offset */ 01328 index = *(__IO uint16_t *) (pbmp + 10); 01329 index |= (*(__IO uint16_t *) (pbmp + 12)) << 16; 01330 01331 /* Read bitmap width */ 01332 width = *(uint16_t *) (pbmp + 18); 01333 width |= (*(uint16_t *) (pbmp + 20)) << 16; 01334 01335 /* Read bitmap height */ 01336 height = *(uint16_t *) (pbmp + 22); 01337 height |= (*(uint16_t *) (pbmp + 24)) << 16; 01338 01339 /* Read bit/pixel */ 01340 bit_pixel = *(uint16_t *) (pbmp + 28); 01341 01342 /* Set the address */ 01343 Address = hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (((BSP_LCD_GetXSize()*Ypos) + Xpos)*(4)); 01344 01345 /* Get the layer pixel format */ 01346 if ((bit_pixel/8) == 4) 01347 { 01348 InputColorMode = DMA2D_INPUT_ARGB8888; 01349 } 01350 else if ((bit_pixel/8) == 2) 01351 { 01352 InputColorMode = DMA2D_INPUT_RGB565; 01353 } 01354 else 01355 { 01356 InputColorMode = DMA2D_INPUT_RGB888; 01357 } 01358 01359 /* Bypass the bitmap header */ 01360 pbmp += (index + (width * (height - 1) * (bit_pixel/8))); 01361 01362 /* Convert picture to ARGB8888 pixel format */ 01363 for(index=0; index < height; index++) 01364 { 01365 /* Pixel format conversion */ 01366 LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)Address, width, InputColorMode); 01367 01368 /* Increment the source and destination buffers */ 01369 Address+= (BSP_LCD_GetXSize()*4); 01370 pbmp -= width*(bit_pixel/8); 01371 } 01372 } 01373 01374 /** 01375 * @brief Draws a full rectangle in currently active layer. 01376 * @param Xpos: X position 01377 * @param Ypos: Y position 01378 * @param Width: Rectangle width 01379 * @param Height: Rectangle height 01380 * @retval None 01381 */ 01382 void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) 01383 { 01384 uint32_t Xaddress = 0; 01385 01386 /* Set the text color */ 01387 BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor); 01388 01389 /* Get the rectangle start address */ 01390 Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(BSP_LCD_GetXSize()*Ypos + Xpos); 01391 01392 /* Fill the rectangle */ 01393 LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Width, Height, (BSP_LCD_GetXSize() - Width), DrawProp[ActiveLayer].TextColor); 01394 } 01395 01396 /** 01397 * @brief Draws a full circle in currently active layer. 01398 * @param Xpos: X position 01399 * @param Ypos: Y position 01400 * @param Radius: Circle radius 01401 * @retval None 01402 */ 01403 void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius) 01404 { 01405 int32_t D; /* Decision Variable */ 01406 uint32_t CurX; /* Current X Value */ 01407 uint32_t CurY; /* Current Y Value */ 01408 01409 D = 3 - (Radius << 1); 01410 01411 CurX = 0; 01412 CurY = Radius; 01413 01414 BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor); 01415 01416 while (CurX <= CurY) 01417 { 01418 if(CurY > 0) 01419 { 01420 BSP_LCD_DrawHLine(Xpos - CurY, Ypos + CurX, 2*CurY); 01421 BSP_LCD_DrawHLine(Xpos - CurY, Ypos - CurX, 2*CurY); 01422 } 01423 01424 if(CurX > 0) 01425 { 01426 BSP_LCD_DrawHLine(Xpos - CurX, Ypos - CurY, 2*CurX); 01427 BSP_LCD_DrawHLine(Xpos - CurX, Ypos + CurY, 2*CurX); 01428 } 01429 if (D < 0) 01430 { 01431 D += (CurX << 2) + 6; 01432 } 01433 else 01434 { 01435 D += ((CurX - CurY) << 2) + 10; 01436 CurY--; 01437 } 01438 CurX++; 01439 } 01440 01441 BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor); 01442 BSP_LCD_DrawCircle(Xpos, Ypos, Radius); 01443 } 01444 01445 /** 01446 * @brief Draws a full poly-line (between many points) in currently active layer. 01447 * @param Points: Pointer to the points array 01448 * @param PointCount: Number of points 01449 * @retval None 01450 */ 01451 void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount) 01452 { 01453 int16_t X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0; 01454 uint16_t IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0; 01455 01456 IMAGE_LEFT = IMAGE_RIGHT = Points->X; 01457 IMAGE_TOP= IMAGE_BOTTOM = Points->Y; 01458 01459 for(counter = 1; counter < PointCount; counter++) 01460 { 01461 pixelX = POLY_X(counter); 01462 if(pixelX < IMAGE_LEFT) 01463 { 01464 IMAGE_LEFT = pixelX; 01465 } 01466 if(pixelX > IMAGE_RIGHT) 01467 { 01468 IMAGE_RIGHT = pixelX; 01469 } 01470 01471 pixelY = POLY_Y(counter); 01472 if(pixelY < IMAGE_TOP) 01473 { 01474 IMAGE_TOP = pixelY; 01475 } 01476 if(pixelY > IMAGE_BOTTOM) 01477 { 01478 IMAGE_BOTTOM = pixelY; 01479 } 01480 } 01481 01482 if(PointCount < 2) 01483 { 01484 return; 01485 } 01486 01487 X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2; 01488 Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2; 01489 01490 X_first = Points->X; 01491 Y_first = Points->Y; 01492 01493 while(--PointCount) 01494 { 01495 X = Points->X; 01496 Y = Points->Y; 01497 Points++; 01498 X2 = Points->X; 01499 Y2 = Points->Y; 01500 01501 FillTriangle(X, X2, X_center, Y, Y2, Y_center); 01502 FillTriangle(X, X_center, X2, Y, Y_center, Y2); 01503 FillTriangle(X_center, X2, X, Y_center, Y2, Y); 01504 } 01505 01506 FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center); 01507 FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2); 01508 FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first); 01509 } 01510 01511 /** 01512 * @brief Draws a full ellipse in currently active layer. 01513 * @param Xpos: X position 01514 * @param Ypos: Y position 01515 * @param XRadius: Ellipse X radius 01516 * @param YRadius: Ellipse Y radius 01517 * @retval None 01518 */ 01519 void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius) 01520 { 01521 int x = 0, y = -YRadius, err = 2-2*XRadius, e2; 01522 float K = 0, rad1 = 0, rad2 = 0; 01523 01524 rad1 = XRadius; 01525 rad2 = YRadius; 01526 01527 K = (float)(rad2/rad1); 01528 01529 do 01530 { 01531 BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1)); 01532 BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1)); 01533 01534 e2 = err; 01535 if (e2 <= x) 01536 { 01537 err += ++x*2+1; 01538 if (-y == x && e2 <= y) e2 = 0; 01539 } 01540 if (e2 > y) err += ++y*2+1; 01541 } 01542 while (y <= 0); 01543 } 01544 01545 /** 01546 * @brief Switch back on the display if was switched off by previous call of BSP_LCD_DisplayOff(). 01547 * Exit DSI ULPM mode if was allowed and configured in Dsi Configuration. 01548 * @retval None 01549 */ 01550 void BSP_LCD_DisplayOn(void) 01551 { 01552 #if defined(USE_LCD_HDMI) 01553 if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR)) 01554 { 01555 return ; /* Not supported for HDMI display */ 01556 } 01557 else 01558 #endif /* USE_LCD_HDMI */ 01559 { 01560 01561 /* Send Display on DCS command to display */ 01562 HAL_DSI_ShortWrite(&(hdsi_discovery), 01563 hdsivideo_handle.VirtualChannelID, 01564 DSI_DCS_SHORT_PKT_WRITE_P1, 01565 OTM8009A_CMD_DISPON, 01566 0x00); 01567 } 01568 01569 } 01570 01571 /** 01572 * @brief Switch Off the display. 01573 * Enter DSI ULPM mode if was allowed and configured in Dsi Configuration. 01574 * @retval None 01575 */ 01576 void BSP_LCD_DisplayOff(void) 01577 { 01578 #if defined(USE_LCD_HDMI) 01579 if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR)) 01580 { 01581 return ; /* Not supported for HDMI yet */ 01582 } 01583 else 01584 #endif /* USE_LCD_HDMI */ 01585 { 01586 /* Send Display off DCS Command to display */ 01587 HAL_DSI_ShortWrite(&(hdsi_discovery), 01588 hdsivideo_handle.VirtualChannelID, 01589 DSI_DCS_SHORT_PKT_WRITE_P1, 01590 OTM8009A_CMD_DISPOFF, 01591 0x00); 01592 } 01593 01594 } 01595 01596 /** 01597 * @brief Set the brightness value 01598 * @param BrightnessValue: [00: Min (black), 100 Max] 01599 * @retval None 01600 */ 01601 void BSP_LCD_SetBrightness(uint8_t BrightnessValue) 01602 { 01603 #if defined(USE_LCD_HDMI) 01604 if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR)) 01605 { 01606 return ; /* Not supported for HDMI display */ 01607 } 01608 else 01609 #endif /* USE_LCD_HDMI */ 01610 { 01611 /* Send Display on DCS command to display */ 01612 HAL_DSI_ShortWrite(&hdsi_discovery, 01613 LCD_OTM8009A_ID, 01614 DSI_DCS_SHORT_PKT_WRITE_P1, 01615 OTM8009A_CMD_WRDISBV, (uint16_t)(BrightnessValue * 255)/100); 01616 } 01617 01618 } 01619 01620 /** 01621 * @brief DCS or Generic short/long write command 01622 * @param NbrParams: Number of parameters. It indicates the write command mode: 01623 * If inferior to 2, a long write command is performed else short. 01624 * @param pParams: Pointer to parameter values table. 01625 * @retval None 01626 */ 01627 void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams) 01628 { 01629 if(NbrParams <= 1) 01630 { 01631 HAL_DSI_ShortWrite(&hdsi_discovery, LCD_OTM8009A_ID, DSI_DCS_SHORT_PKT_WRITE_P1, pParams[0], pParams[1]); 01632 } 01633 else 01634 { 01635 HAL_DSI_LongWrite(&hdsi_discovery, LCD_OTM8009A_ID, DSI_DCS_LONG_PKT_WRITE, NbrParams, pParams[NbrParams], pParams); 01636 } 01637 } 01638 01639 /** 01640 * @brief Returns the ID of connected screen by checking the HDMI 01641 * (adv7533 component) ID or LCD DSI (via TS ID) ID. 01642 * @retval LCD ID 01643 */ 01644 static uint16_t LCD_IO_GetID(void) 01645 { 01646 #if defined(USE_LCD_HDMI) 01647 HDMI_IO_Init(); 01648 01649 HDMI_IO_Delay(120); 01650 01651 if(ADV7533_ID == adv7533_drv.ReadID(ADV7533_CEC_DSI_I2C_ADDR)) 01652 { 01653 return ADV7533_ID; 01654 } 01655 else if(((HDMI_IO_Read(LCD_DSI_ADDRESS, LCD_DSI_ID_REG) == LCD_DSI_ID)) || \ 01656 (HDMI_IO_Read(LCD_DSI_ADDRESS_A02, LCD_DSI_ID_REG) == LCD_DSI_ID)) 01657 { 01658 return LCD_DSI_ID; 01659 } 01660 else 01661 { 01662 return 0; 01663 } 01664 #else 01665 return LCD_DSI_ID; 01666 #endif /* USE_LCD_HDMI */ 01667 01668 } 01669 01670 /******************************************************************************* 01671 LTDC, DMA2D and DSI BSP Routines 01672 *******************************************************************************/ 01673 /** 01674 * @brief De-Initializes the BSP LCD Msp 01675 * Application can surcharge if needed this function implementation. 01676 * @retval None 01677 */ 01678 __weak void BSP_LCD_MspDeInit(void) 01679 { 01680 /** @brief Disable IRQ of LTDC IP */ 01681 HAL_NVIC_DisableIRQ(LTDC_IRQn); 01682 01683 /** @brief Disable IRQ of DMA2D IP */ 01684 HAL_NVIC_DisableIRQ(DMA2D_IRQn); 01685 01686 /** @brief Disable IRQ of DSI IP */ 01687 HAL_NVIC_DisableIRQ(DSI_IRQn); 01688 01689 /** @brief Force and let in reset state LTDC, DMA2D and DSI Host + Wrapper IPs */ 01690 __HAL_RCC_LTDC_FORCE_RESET(); 01691 __HAL_RCC_DMA2D_FORCE_RESET(); 01692 __HAL_RCC_DSI_FORCE_RESET(); 01693 01694 /** @brief Disable the LTDC, DMA2D and DSI Host and Wrapper clocks */ 01695 __HAL_RCC_LTDC_CLK_DISABLE(); 01696 __HAL_RCC_DMA2D_CLK_DISABLE(); 01697 __HAL_RCC_DSI_CLK_DISABLE(); 01698 } 01699 01700 /** 01701 * @brief Initialize the BSP LCD Msp. 01702 * Application can surcharge if needed this function implementation 01703 * @retval None 01704 */ 01705 __weak void BSP_LCD_MspInit(void) 01706 { 01707 /** @brief Enable the LTDC clock */ 01708 __HAL_RCC_LTDC_CLK_ENABLE(); 01709 01710 /** @brief Toggle Sw reset of LTDC IP */ 01711 __HAL_RCC_LTDC_FORCE_RESET(); 01712 __HAL_RCC_LTDC_RELEASE_RESET(); 01713 01714 /** @brief Enable the DMA2D clock */ 01715 __HAL_RCC_DMA2D_CLK_ENABLE(); 01716 01717 /** @brief Toggle Sw reset of DMA2D IP */ 01718 __HAL_RCC_DMA2D_FORCE_RESET(); 01719 __HAL_RCC_DMA2D_RELEASE_RESET(); 01720 01721 /** @brief Enable DSI Host and wrapper clocks */ 01722 __HAL_RCC_DSI_CLK_ENABLE(); 01723 01724 /** @brief Soft Reset the DSI Host and wrapper */ 01725 __HAL_RCC_DSI_FORCE_RESET(); 01726 __HAL_RCC_DSI_RELEASE_RESET(); 01727 01728 /** @brief NVIC configuration for LTDC interrupt that is now enabled */ 01729 HAL_NVIC_SetPriority(LTDC_IRQn, 0x0F, 0); 01730 HAL_NVIC_EnableIRQ(LTDC_IRQn); 01731 01732 /** @brief NVIC configuration for DMA2D interrupt that is now enabled */ 01733 HAL_NVIC_SetPriority(DMA2D_IRQn, 0x0F, 0); 01734 HAL_NVIC_EnableIRQ(DMA2D_IRQn); 01735 01736 /** @brief NVIC configuration for DSI interrupt that is now enabled */ 01737 HAL_NVIC_SetPriority(DSI_IRQn, 0x0F, 0); 01738 HAL_NVIC_EnableIRQ(DSI_IRQn); 01739 } 01740 01741 /** 01742 * @brief Draws a pixel on LCD. 01743 * @param Xpos: X position 01744 * @param Ypos: Y position 01745 * @param RGB_Code: Pixel color in ARGB mode (8-8-8-8) 01746 * @retval None 01747 */ 01748 void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code) 01749 { 01750 /* Write data value to all SDRAM memory */ 01751 *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*BSP_LCD_GetXSize() + Xpos))) = RGB_Code; 01752 } 01753 /** 01754 * @} 01755 */ 01756 01757 /** @defgroup STM32H747I_DISCOVERY_LCD_Private_Functions Private Functions 01758 * @{ 01759 */ 01760 01761 /** 01762 * @brief Draws a character on LCD. 01763 * @param Xpos: Line where to display the character shape 01764 * @param Ypos: Start column address 01765 * @param c: Pointer to the character data 01766 * @retval None 01767 */ 01768 static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c) 01769 { 01770 uint32_t i = 0, j = 0; 01771 uint16_t height, width; 01772 uint8_t offset; 01773 uint8_t *pchar; 01774 uint32_t line; 01775 01776 height = DrawProp[ActiveLayer].pFont->Height; 01777 width = DrawProp[ActiveLayer].pFont->Width; 01778 01779 offset = 8 *((width + 7)/8) - width ; 01780 01781 for(i = 0; i < height; i++) 01782 { 01783 pchar = ((uint8_t *)c + (width + 7)/8 * i); 01784 01785 switch(((width + 7)/8)) 01786 { 01787 01788 case 1: 01789 line = pchar[0]; 01790 break; 01791 01792 case 2: 01793 line = (pchar[0]<< 8) | pchar[1]; 01794 break; 01795 01796 case 3: 01797 default: 01798 line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2]; 01799 break; 01800 } 01801 01802 for (j = 0; j < width; j++) 01803 { 01804 if(line & (1 << (width- j + offset- 1))) 01805 { 01806 BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].TextColor); 01807 } 01808 else 01809 { 01810 BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].BackColor); 01811 } 01812 } 01813 Ypos++; 01814 } 01815 } 01816 01817 /** 01818 * @brief Fills a triangle (between 3 points). 01819 * @param x1: Point 1 X position 01820 * @param y1: Point 1 Y position 01821 * @param x2: Point 2 X position 01822 * @param y2: Point 2 Y position 01823 * @param x3: Point 3 X position 01824 * @param y3: Point 3 Y position 01825 * @retval None 01826 */ 01827 static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3) 01828 { 01829 int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, 01830 yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, 01831 curpixel = 0; 01832 01833 deltax = ABS(x2 - x1); /* The difference between the x's */ 01834 deltay = ABS(y2 - y1); /* The difference between the y's */ 01835 x = x1; /* Start x off at the first pixel */ 01836 y = y1; /* Start y off at the first pixel */ 01837 01838 if (x2 >= x1) /* The x-values are increasing */ 01839 { 01840 xinc1 = 1; 01841 xinc2 = 1; 01842 } 01843 else /* The x-values are decreasing */ 01844 { 01845 xinc1 = -1; 01846 xinc2 = -1; 01847 } 01848 01849 if (y2 >= y1) /* The y-values are increasing */ 01850 { 01851 yinc1 = 1; 01852 yinc2 = 1; 01853 } 01854 else /* The y-values are decreasing */ 01855 { 01856 yinc1 = -1; 01857 yinc2 = -1; 01858 } 01859 01860 if (deltax >= deltay) /* There is at least one x-value for every y-value */ 01861 { 01862 xinc1 = 0; /* Don't change the x when numerator >= denominator */ 01863 yinc2 = 0; /* Don't change the y for every iteration */ 01864 den = deltax; 01865 num = deltax / 2; 01866 numadd = deltay; 01867 numpixels = deltax; /* There are more x-values than y-values */ 01868 } 01869 else /* There is at least one y-value for every x-value */ 01870 { 01871 xinc2 = 0; /* Don't change the x for every iteration */ 01872 yinc1 = 0; /* Don't change the y when numerator >= denominator */ 01873 den = deltay; 01874 num = deltay / 2; 01875 numadd = deltax; 01876 numpixels = deltay; /* There are more y-values than x-values */ 01877 } 01878 01879 for (curpixel = 0; curpixel <= numpixels; curpixel++) 01880 { 01881 BSP_LCD_DrawLine(x, y, x3, y3); 01882 01883 num += numadd; /* Increase the numerator by the top of the fraction */ 01884 if (num >= den) /* Check if numerator >= denominator */ 01885 { 01886 num -= den; /* Calculate the new numerator value */ 01887 x += xinc1; /* Change the x as appropriate */ 01888 y += yinc1; /* Change the y as appropriate */ 01889 } 01890 x += xinc2; /* Change the x as appropriate */ 01891 y += yinc2; /* Change the y as appropriate */ 01892 } 01893 } 01894 01895 /** 01896 * @brief Fills a buffer. 01897 * @param LayerIndex: Layer index 01898 * @param pDst: Pointer to destination buffer 01899 * @param xSize: Buffer width 01900 * @param ySize: Buffer height 01901 * @param OffLine: Offset 01902 * @param ColorIndex: Color index 01903 * @retval None 01904 */ 01905 static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex) 01906 { 01907 /* Register to memory mode with ARGB8888 as color Mode */ 01908 hdma2d_discovery.Init.Mode = DMA2D_R2M; 01909 hdma2d_discovery.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; 01910 hdma2d_discovery.Init.OutputOffset = OffLine; 01911 01912 hdma2d_discovery.Instance = DMA2D; 01913 01914 /* DMA2D Initialization */ 01915 if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK) 01916 { 01917 if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, 1) == HAL_OK) 01918 { 01919 if (HAL_DMA2D_Start(&hdma2d_discovery, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK) 01920 { 01921 /* Polling For DMA transfer */ 01922 HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 25); 01923 } 01924 } 01925 } 01926 } 01927 01928 /** 01929 * @brief Converts a line to an ARGB8888 pixel format. 01930 * @param pSrc: Pointer to source buffer 01931 * @param pDst: Output color 01932 * @param xSize: Buffer width 01933 * @param ColorMode: Input color mode 01934 * @retval None 01935 */ 01936 static void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode) 01937 { 01938 /* Configure the DMA2D Mode, Color Mode and output offset */ 01939 hdma2d_discovery.Init.Mode = DMA2D_M2M_PFC; 01940 hdma2d_discovery.Init.ColorMode = DMA2D_OUTPUT_ARGB8888; 01941 hdma2d_discovery.Init.OutputOffset = 0; 01942 01943 /* Foreground Configuration */ 01944 hdma2d_discovery.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA; 01945 hdma2d_discovery.LayerCfg[1].InputAlpha = 0xFF; 01946 hdma2d_discovery.LayerCfg[1].InputColorMode = ColorMode; 01947 hdma2d_discovery.LayerCfg[1].InputOffset = 0; 01948 01949 hdma2d_discovery.Instance = DMA2D; 01950 01951 /* DMA2D Initialization */ 01952 if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK) 01953 { 01954 if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, 1) == HAL_OK) 01955 { 01956 if (HAL_DMA2D_Start(&hdma2d_discovery, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK) 01957 { 01958 /* Polling For DMA transfer */ 01959 HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 25); 01960 } 01961 } 01962 } 01963 } 01964 01965 /** 01966 * @} 01967 */ 01968 01969 /** 01970 * @} 01971 */ 01972 01973 /** 01974 * @} 01975 */ 01976 01977 /** 01978 * @} 01979 */ 01980 01981 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 18:45:41 by 1.7.2