BSP files for STM32H747I-Discovery Copy from ST Cube delivery

Dependents:   DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32h747i_discovery_lcd.c Source File

stm32h747i_discovery_lcd.c

Go to the documentation of this file.
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>&copy; 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****/