STM32F769I-Discovery BSP User Manual: stm32f769i_discovery_lcd.c Source File

STM32F769I-Discovery BSP Drivers

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