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