STM32769I_EVAL BSP User Manual: stm32f769i_eval_lcd.c Source File

STM32769I_EVAL BSP

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