STM32L4R9I-Discovery BSP User Manual: stm32l4r9i_discovery_lcd.c Source File

STM32L4R9I-Discovery BSP

stm32l4r9i_discovery_lcd.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4r9i_discovery_lcd.c
00004   * @author  MCD Application Team
00005   * @brief   This file includes the driver for DSI Liquid Crystal Display (LCD)
00006   *          module mounted on STM32L4R9I_DISCOVERY board.
00007   ******************************************************************************
00008   * @attention
00009   *
00010   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00011   *
00012   * Redistribution and use in source and binary forms, with or without modification,
00013   * are permitted provided that the following conditions are met:
00014   *   1. Redistributions of source code must retain the above copyright notice,
00015   *      this list of conditions and the following disclaimer.
00016   *   2. Redistributions in binary form must reproduce the above copyright notice,
00017   *      this list of conditions and the following disclaimer in the documentation
00018   *      and/or other materials provided with the distribution.
00019   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00020   *      may be used to endorse or promote products derived from this software
00021   *      without specific prior written permission.
00022   *
00023   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00027   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00028   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00031   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00032   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033   *
00034   ******************************************************************************
00035   */
00036 
00037 /* File Info: ------------------------------------------------------------------
00038                                    User NOTES
00039 1. How To use this driver:
00040 --------------------------
00041    - This driver is used to drive directly in command mode a LCD TFT using the
00042      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.
00046 
00047 2. Driver description:
00048 ----------------------
00049   + Initialization steps:
00050      o Initialize the LCD using the BSP_LCD_Init() function.
00051        Please note that LCD display will be turned on at the end of this function.
00052      o De-inietialize the LCD using BSP_LCD_DeInit() function.
00053 
00054   + Options
00055      o Modify in the fly the display properties using the following functions:
00056        - BSP_LCD_SetTransparency().
00057        - BSP_LCD_SetColorKeying().
00058        - BSP_LCD_ResetColorKeying().
00059        - BSP_LCD_SetFont().
00060        - BSP_LCD_SetBackColor().
00061        - BSP_LCD_SetTextColor().
00062        - BSP_LCD_SetBrightness().
00063      o You can set display on/off using following functions:
00064        - BSP_LCD_DisplayOn().
00065        - BSP_LCD_DisplayOff().
00066 
00067   + Display on LCD
00068      o First, check that frame buffer is available using BSP_LCD_IsFrameBufferAvailable().
00069      o When frame buffer is available, modify it using following functions:
00070        - BSP_LCD_Clear().
00071        - BSP_LCD_ClearStringLine().
00072        - BSP_LCD_DisplayChar().
00073        - BSP_LCD_DisplayStringAt().
00074        - BSP_LCD_DisplayStringAtLine().
00075        - BSP_LCD_DrawBitmap().
00076        - BSP_LCD_DrawCircle().
00077        - BSP_LCD_DrawEllipse().
00078        - ....
00079 
00080      o Call BSP_LCD_Refresh() to refresh LCD display.
00081 
00082 ------------------------------------------------------------------------------*/
00083 
00084 /* Includes ------------------------------------------------------------------*/
00085 #include "stm32l4r9i_discovery_lcd.h"
00086 #include "stm32l4r9i_discovery_gfxmmu_lut.h"
00087 #include "stm32l4r9i_discovery_io.h"
00088 #include "../../../Utilities/Fonts/fonts.h"
00089 #include "../../../Utilities/Fonts/font24.c"
00090 #include "../../../Utilities/Fonts/font20.c"
00091 #include "../../../Utilities/Fonts/font16.c"
00092 #include "../../../Utilities/Fonts/font12.c"
00093 #include "../../../Utilities/Fonts/font8.c"
00094 
00095 /** @addtogroup BSP
00096   * @{
00097   */
00098 
00099 /** @addtogroup STM32L4R9I_DISCOVERY
00100   * @{
00101   */
00102 
00103 /** @defgroup STM32L4R9I_DISCOVERY_LCD STM32L4R9I_DISCOVERY LCD
00104   * @{
00105   */
00106 
00107 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Private_Macros Private Macros
00108   * @{
00109   */
00110 #define ABS(X)                 ((X) > 0 ? (X) : -(X))
00111 
00112 #define POLY_X(Z)              ((int32_t)((Points + (Z))->X))
00113 #define POLY_Y(Z)              ((int32_t)((Points + (Z))->Y))
00114 /**
00115   * @}
00116   */
00117 
00118 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Exported_Variables Exported Variables
00119   * @{
00120   */
00121 /* DMA2D handle */
00122 DMA2D_HandleTypeDef  hdma2d_discovery;
00123 
00124 /**
00125   * @}
00126   */
00127 
00128 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Private_Variables Private Variables
00129   * @{
00130   */
00131 /* LCD/PSRAM initialization status sharing the same power source */
00132 extern uint32_t bsp_lcd_initialized;
00133 extern uint32_t bsp_psram_initialized;
00134 
00135 /* Flag to indicate if HSE has to be disabled during de-initialization */
00136 static uint32_t bsp_lcd_hse_to_disable = 0;
00137 /* Default Active LTDC Layer in which drawing is made is LTDC Layer Background */
00138 static uint32_t  ActiveLayer = LTDC_ACTIVE_LAYER_BACKGROUND;
00139 /* Current Drawing Layer properties variable */
00140 static LCD_DrawPropTypeDef DrawProp[LTDC_MAX_LAYER_NUMBER];
00141 
00142 /* Physical frame buffer for background and foreground layers */
00143 /* 390*390 pixels with 32bpp - 20% */
00144 #if defined ( __ICCARM__ )  /* IAR Compiler */
00145   #pragma data_alignment = 16
00146 uint32_t              PhysFrameBuffer[121680];
00147 #elif defined (__GNUC__)    /* GNU Compiler */
00148 uint32_t              PhysFrameBuffer[121680] __attribute__ ((aligned (16)));
00149 #else                       /* ARM Compiler */
00150 __align(16) uint32_t  PhysFrameBuffer[121680];
00151 #endif
00152 
00153 /* Global variable used to know if frame buffer is available (1) or not because refresh is on going (0) */
00154 __IO uint32_t FrameBufferAvailable = 1;
00155 /* LCD size */
00156 uint32_t lcd_x_size = 390;
00157 uint32_t lcd_y_size = 390;
00158 /* GFXMMU, LTDC and DSI handles */
00159 GFXMMU_HandleTypeDef hgfxmmu_discovery;
00160 LTDC_HandleTypeDef   hltdc_discovery;
00161 DSI_HandleTypeDef    hdsi_discovery;
00162 /**
00163   * @}
00164   */
00165 
00166 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Private_FunctionPrototypes Private FunctionPrototypes
00167   * @{
00168   */
00169 static void LCD_PowerOn(void);
00170 static void LCD_PowerOff(void);
00171 static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c);
00172 static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3);
00173 static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex);
00174 static void LL_ConvertLineToARGB8888(void * pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode);
00175 /**
00176   * @}
00177   */
00178 
00179 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Exported_Functions Exported Functions
00180   * @{
00181   */
00182 
00183 /**
00184   * @brief  Initialize the DSI LCD.
00185   * @note   The initialization is done as below:
00186   *     - GFXMMU initialization
00187   *     - DSI PLL initialization
00188   *     - DSI initialization
00189   *     - LTDC initialization
00190   *     - RM67162 LCD Display IC Driver initialization
00191   * @retval LCD state
00192   */
00193 uint8_t BSP_LCD_Init(void)
00194 {
00195   if(bsp_lcd_initialized == 0)
00196   {
00197     LTDC_LayerCfgTypeDef    LayerCfg;
00198     DSI_PLLInitTypeDef      dsiPllInit;
00199     DSI_PHY_TimerTypeDef    PhyTimings;
00200     DSI_HOST_TimeoutTypeDef HostTimeouts;
00201     DSI_LPCmdTypeDef        LPCmd;
00202     DSI_CmdCfgTypeDef       CmdCfg;
00203 
00204     /* Power on LCD */
00205     LCD_PowerOn();
00206 
00207     /* Call first MSP Initialize
00208      * This will set IP blocks LTDC, DSI and DMA2D
00209      * - out of reset
00210      * - clocked
00211      * - NVIC IRQ related to IP blocks enabled
00212     */
00213     BSP_LCD_MspInit();
00214 
00215     /************************/
00216     /* GFXMMU CONFIGURATION */
00217     /************************/
00218     hgfxmmu_discovery.Instance = GFXMMU;
00219     __HAL_GFXMMU_RESET_HANDLE_STATE(&hgfxmmu_discovery);
00220     hgfxmmu_discovery.Init.BlocksPerLine                     = GFXMMU_192BLOCKS;
00221     hgfxmmu_discovery.Init.DefaultValue                      = 0xFFFFFFFF;
00222     hgfxmmu_discovery.Init.Buffers.Buf0Address               = (uint32_t) PhysFrameBuffer;
00223     hgfxmmu_discovery.Init.Buffers.Buf1Address               = 0; /* NU */
00224     hgfxmmu_discovery.Init.Buffers.Buf2Address               = 0; /* NU */
00225     hgfxmmu_discovery.Init.Buffers.Buf3Address               = 0; /* NU */
00226     hgfxmmu_discovery.Init.Interrupts.Activation             = DISABLE;
00227     hgfxmmu_discovery.Init.Interrupts.UsedInterrupts         = GFXMMU_AHB_MASTER_ERROR_IT; /* NU */
00228     if(HAL_OK != HAL_GFXMMU_Init(&hgfxmmu_discovery))
00229     {
00230       return(LCD_ERROR);
00231     }
00232 
00233     /* Initialize LUT */
00234     if(HAL_OK != HAL_GFXMMU_ConfigLut(&hgfxmmu_discovery, 0, 390, (uint32_t) gfxmmu_lut_config_argb8888))
00235     {
00236       return(LCD_ERROR);
00237     }
00238     /* Disable non visible lines : from line 390 to 1023 */
00239     if(HAL_OK != HAL_GFXMMU_DisableLutLines(&hgfxmmu_discovery, 390, 634))
00240     {
00241       return(LCD_ERROR);
00242     }
00243 
00244     /**********************/
00245     /* LTDC CONFIGURATION */
00246     /**********************/
00247 
00248     /* LTDC initialization */
00249     hltdc_discovery.Instance = LTDC;
00250     __HAL_LTDC_RESET_HANDLE_STATE(&hltdc_discovery);
00251     hltdc_discovery.Init.HSPolarity         = LTDC_HSPOLARITY_AL;
00252     hltdc_discovery.Init.VSPolarity         = LTDC_VSPOLARITY_AL;
00253     hltdc_discovery.Init.DEPolarity         = LTDC_DEPOLARITY_AL;
00254     hltdc_discovery.Init.PCPolarity         = LTDC_PCPOLARITY_IPC;
00255     hltdc_discovery.Init.HorizontalSync     = 0;   /* HSYNC width - 1 */
00256     hltdc_discovery.Init.VerticalSync       = 0;   /* VSYNC width - 1 */
00257     hltdc_discovery.Init.AccumulatedHBP     = 1;   /* HSYNC width + HBP - 1 */
00258     hltdc_discovery.Init.AccumulatedVBP     = 1;   /* VSYNC width + VBP - 1 */
00259     hltdc_discovery.Init.AccumulatedActiveW = 391; /* HSYNC width + HBP + Active width - 1 */
00260     hltdc_discovery.Init.AccumulatedActiveH = 391; /* VSYNC width + VBP + Active height - 1 */
00261     hltdc_discovery.Init.TotalWidth         = 392; /* HSYNC width + HBP + Active width + HFP - 1 */
00262     hltdc_discovery.Init.TotalHeigh         = 392; /* VSYNC width + VBP + Active height + VFP - 1 */
00263     hltdc_discovery.Init.Backcolor.Red      = 255;
00264     hltdc_discovery.Init.Backcolor.Green    = 255;
00265     hltdc_discovery.Init.Backcolor.Blue     = 0;
00266     hltdc_discovery.Init.Backcolor.Reserved = 0xFF;
00267     if(HAL_LTDC_Init(&hltdc_discovery) != HAL_OK)
00268     {
00269       return(LCD_ERROR);
00270     }
00271 
00272     /* LTDC layers configuration */
00273     LayerCfg.WindowX0        = 0;
00274     LayerCfg.WindowX1        = 390;
00275     LayerCfg.WindowY0        = 0;
00276     LayerCfg.WindowY1        = 390;
00277     LayerCfg.PixelFormat     = LTDC_PIXEL_FORMAT_ARGB8888;
00278     LayerCfg.Alpha           = 0xFF; /* NU default value */
00279     LayerCfg.Alpha0          = 0; /* NU default value */
00280     LayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA; /* NU default value */
00281     LayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA; /* NU default value */
00282     LayerCfg.FBStartAdress   = GFXMMU_VIRTUAL_BUFFER0_BASE;
00283     LayerCfg.ImageWidth      = 768; /* virtual frame buffer contains 768 pixels per line for 32bpp */
00284     LayerCfg.ImageHeight     = 390;
00285     LayerCfg.Backcolor.Red   = 0; /* NU default value */
00286     LayerCfg.Backcolor.Green = 0; /* NU default value */
00287     LayerCfg.Backcolor.Blue  = 0; /* NU default value */
00288     LayerCfg.Backcolor.Reserved = 0xFF;
00289     if(HAL_LTDC_ConfigLayer(&hltdc_discovery, &LayerCfg, 0) != HAL_OK)
00290     {
00291       return(LCD_ERROR);
00292     }
00293 
00294     DrawProp[0].BackColor = LCD_COLOR_WHITE;
00295     DrawProp[0].pFont     = &Font24;
00296     DrawProp[0].TextColor = LCD_COLOR_BLACK;
00297 
00298     /*********************/
00299     /* DSI CONFIGURATION */
00300     /*********************/
00301 
00302     /* DSI initialization */
00303     hdsi_discovery.Instance = DSI;
00304     __HAL_DSI_RESET_HANDLE_STATE(&hdsi_discovery);
00305     hdsi_discovery.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_DISABLE;
00306     /* We have 1 data lane at 500Mbps => lane byte clock at 500/8 = 62,5 MHZ */
00307     /* We want TX escape clock at arround 20MHz and under 20MHz so clock division is set to 4 */
00308     hdsi_discovery.Init.TXEscapeCkdiv             = 4;
00309     hdsi_discovery.Init.NumberOfLanes             = DSI_ONE_DATA_LANE;
00310     /* We have HSE value at 16 Mhz and we want data lane at 500Mbps */
00311     dsiPllInit.PLLNDIV = 125;
00312     dsiPllInit.PLLIDF  = DSI_PLL_IN_DIV4;
00313     dsiPllInit.PLLODF  = DSI_PLL_OUT_DIV1;
00314     if(HAL_DSI_Init(&hdsi_discovery, &dsiPllInit) != HAL_OK)
00315     {
00316       return(LCD_ERROR);
00317     }
00318 
00319     PhyTimings.ClockLaneHS2LPTime  = 33; /* Tclk-post + Tclk-trail + Ths-exit = [(60ns + 52xUI) + (60ns) + (300ns)]/16ns */
00320     PhyTimings.ClockLaneLP2HSTime  = 30; /* Tlpx + (Tclk-prepare + Tclk-zero) + Tclk-pre = [150ns + 300ns + 8xUI]/16ns */
00321     PhyTimings.DataLaneHS2LPTime   = 11; /* Ths-trail + Ths-exit = [(60ns + 4xUI) + 100ns]/16ns */
00322     PhyTimings.DataLaneLP2HSTime   = 21; /* Tlpx + (Ths-prepare + Ths-zero) + Ths-sync = [150ns + (145ns + 10xUI) + 8xUI]/16ns */
00323     PhyTimings.DataLaneMaxReadTime = 0;
00324     PhyTimings.StopWaitTime        = 7;
00325     if(HAL_DSI_ConfigPhyTimer(&hdsi_discovery, &PhyTimings) != HAL_OK)
00326     {
00327       return(LCD_ERROR);
00328     }
00329 
00330     HostTimeouts.TimeoutCkdiv                 = 1;
00331     HostTimeouts.HighSpeedTransmissionTimeout = 0;
00332     HostTimeouts.LowPowerReceptionTimeout     = 0;
00333     HostTimeouts.HighSpeedReadTimeout         = 0;
00334     HostTimeouts.LowPowerReadTimeout          = 0;
00335     HostTimeouts.HighSpeedWriteTimeout        = 0;
00336     HostTimeouts.HighSpeedWritePrespMode      = 0;
00337     HostTimeouts.LowPowerWriteTimeout         = 0;
00338     HostTimeouts.BTATimeout                   = 0;
00339     if(HAL_DSI_ConfigHostTimeouts(&hdsi_discovery, &HostTimeouts) != HAL_OK)
00340     {
00341       return(LCD_ERROR);
00342     }
00343 
00344     LPCmd.LPGenShortWriteNoP  = DSI_LP_GSW0P_ENABLE;
00345     LPCmd.LPGenShortWriteOneP = DSI_LP_GSW1P_ENABLE;
00346     LPCmd.LPGenShortWriteTwoP = DSI_LP_GSW2P_ENABLE;
00347     LPCmd.LPGenShortReadNoP   = DSI_LP_GSR0P_ENABLE;
00348     LPCmd.LPGenShortReadOneP  = DSI_LP_GSR1P_ENABLE;
00349     LPCmd.LPGenShortReadTwoP  = DSI_LP_GSR2P_ENABLE;
00350     LPCmd.LPGenLongWrite      = DSI_LP_GLW_DISABLE;
00351     LPCmd.LPDcsShortWriteNoP  = DSI_LP_DSW0P_ENABLE;
00352     LPCmd.LPDcsShortWriteOneP = DSI_LP_DSW1P_ENABLE;
00353     LPCmd.LPDcsShortReadNoP   = DSI_LP_DSR0P_ENABLE;
00354     LPCmd.LPDcsLongWrite      = DSI_LP_DLW_DISABLE;
00355     LPCmd.LPMaxReadPacket     = DSI_LP_MRDP_DISABLE;
00356     LPCmd.AcknowledgeRequest  = DSI_ACKNOWLEDGE_DISABLE;
00357     if(HAL_DSI_ConfigCommand(&hdsi_discovery, &LPCmd) != HAL_OK)
00358     {
00359       return(LCD_ERROR);
00360     }
00361 
00362     CmdCfg.VirtualChannelID      = 0;
00363     CmdCfg.ColorCoding           = DSI_RGB888;
00364     CmdCfg.CommandSize           = 390;
00365     CmdCfg.TearingEffectSource   = DSI_TE_DSILINK;
00366     CmdCfg.TearingEffectPolarity = DSI_TE_FALLING_EDGE;
00367     CmdCfg.HSPolarity            = DSI_HSYNC_ACTIVE_LOW;
00368     CmdCfg.VSPolarity            = DSI_VSYNC_ACTIVE_LOW;
00369     CmdCfg.DEPolarity            = DSI_DATA_ENABLE_ACTIVE_HIGH;
00370     CmdCfg.VSyncPol              = DSI_VSYNC_FALLING;
00371     CmdCfg.AutomaticRefresh      = DSI_AR_ENABLE;
00372     CmdCfg.TEAcknowledgeRequest  = DSI_TE_ACKNOWLEDGE_ENABLE;
00373     if(HAL_DSI_ConfigAdaptedCommandMode(&hdsi_discovery, &CmdCfg) != HAL_OK)
00374     {
00375       return(LCD_ERROR);
00376     }
00377 
00378     /* Disable the Tearing Effect interrupt activated by default on previous function */
00379     __HAL_DSI_DISABLE_IT(&hdsi_discovery, DSI_IT_TE);
00380 
00381     if(HAL_DSI_ConfigFlowControl(&hdsi_discovery, DSI_FLOW_CONTROL_BTA) != HAL_OK)
00382     {
00383       return(LCD_ERROR);
00384     }
00385 
00386     /* Enable DSI */
00387     __HAL_DSI_ENABLE(&hdsi_discovery);
00388 
00389     /*************************/
00390     /* LCD POWER ON SEQUENCE */
00391     /*************************/
00392     /* Step 1 */
00393     /* Go to command 2 */
00394     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x01);
00395     /* IC Frame rate control, set power, sw mapping, mux swithc timing command */
00396     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x06, 0x62);
00397     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0E, 0x80);
00398     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0F, 0x80);
00399     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x10, 0x71);
00400     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x13, 0x81);
00401     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x14, 0x81);
00402     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x15, 0x82);
00403     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x16, 0x82);
00404     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x18, 0x88);
00405     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x19, 0x55);
00406     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1A, 0x10);
00407     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1C, 0x99);
00408     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1D, 0x03);
00409     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1E, 0x03);
00410     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1F, 0x03);
00411     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x20, 0x03);
00412     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x25, 0x03);
00413     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x26, 0x8D);
00414     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2A, 0x03);
00415     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2B, 0x8D);
00416     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x36, 0x00);
00417     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x37, 0x10);
00418     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3A, 0x00);
00419     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3B, 0x00);
00420     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3D, 0x20);
00421     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x3F, 0x3A);
00422     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x40, 0x30);
00423     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x41, 0x1A);
00424     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x42, 0x33);
00425     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x43, 0x22);
00426     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x44, 0x11);
00427     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x45, 0x66);
00428     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x46, 0x55);
00429     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x47, 0x44);
00430     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x4C, 0x33);
00431     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x4D, 0x22);
00432     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x4E, 0x11);
00433     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x4F, 0x66);
00434     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x50, 0x55);
00435     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x51, 0x44);
00436     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x57, 0x33);
00437     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x6B, 0x1B);
00438     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x70, 0x55);
00439     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x74, 0x0C);
00440 
00441     /* Go to command 3 */
00442     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x02);
00443     /* Set the VGMP/VGSP coltage control */
00444     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9B, 0x40);
00445     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9C, 0x00);
00446     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9D, 0x20);
00447 
00448     /* Go to command 4 */
00449     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x03);
00450     /* Set the VGMP/VGSP coltage control */
00451     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9B, 0x40);
00452     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9C, 0x00);
00453     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x9D, 0x20);
00454 
00455 
00456     /* Go to command 5 */
00457     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x04);
00458     /* VSR command */
00459     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x5D, 0x10);
00460     /* VSR1 timing set */
00461     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x00, 0x8D);
00462     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x01, 0x00);
00463     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x02, 0x01);
00464     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x03, 0x01);
00465     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x04, 0x10);
00466     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x05, 0x01);
00467     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x06, 0xA7);
00468     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x07, 0x20);
00469     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x08, 0x00);
00470     /* VSR2 timing set */
00471     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x09, 0xC2);
00472     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0A, 0x00);
00473     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0B, 0x02);
00474     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0C, 0x01);
00475     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0D, 0x40);
00476     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0E, 0x06);
00477     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x0F, 0x01);
00478     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x10, 0xA7);
00479     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x11, 0x00);
00480     /* VSR3 timing set */
00481     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x12, 0xC2);
00482     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x13, 0x00);
00483     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x14, 0x02);
00484     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x15, 0x01);
00485     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x16, 0x40);
00486     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x17, 0x07);
00487     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x18, 0x01);
00488     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x19, 0xA7);
00489     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1A, 0x00);
00490     /* VSR4 timing set */
00491     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1B, 0x82);
00492     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1C, 0x00);
00493     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1D, 0xFF);
00494     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1E, 0x05);
00495     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x1F, 0x60);
00496     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x20, 0x02);
00497     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x21, 0x01);
00498     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x22, 0x7C);
00499     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x23, 0x00);
00500     /* VSR5 timing set */
00501     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x24, 0xC2);
00502     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x25, 0x00);
00503     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x26, 0x04);
00504     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x27, 0x02);
00505     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x28, 0x70);
00506     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x29, 0x05);
00507     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2A, 0x74);
00508     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2B, 0x8D);
00509     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2D, 0x00);
00510     /* VSR6 timing set */
00511     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2F, 0xC2);
00512     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x30, 0x00);
00513     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x31, 0x04);
00514     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x32, 0x02);
00515     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x33, 0x70);
00516     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x34, 0x07);
00517     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x35, 0x74);
00518     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x36, 0x8D);
00519     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x37, 0x00);
00520     /* VSR marping command */
00521     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x5E, 0x20);
00522     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x5F, 0x31);
00523     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x60, 0x54);
00524     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x61, 0x76);
00525     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x62, 0x98);
00526 
00527     /* Go to command 6 */
00528     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x05);
00529     /* Set the ELVSS voltage */
00530     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x05, 0x17);
00531     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x2A, 0x04);
00532     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0x91, 0x00);
00533 
00534     /* Go back in standard commands */
00535     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xFE, 0x00);
00536 
00537     /* Set tear off */
00538     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, DSI_SET_TEAR_OFF, 0x0);
00539 
00540     /* Set DSI mode to internal timing added vs ORIGINAL for Command mode */
00541     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, 0xC2, 0x0);
00542 
00543     /* Set memory address MODIFIED vs ORIGINAL */
00544     uint8_t InitParam1[4]= {0x00, 0x04, 0x01, 0x89}; // MODIF OFe: adjusted w/ real image
00545     HAL_DSI_LongWrite(&hdsi_discovery, 0, DSI_DCS_LONG_PKT_WRITE, 4, DSI_SET_COLUMN_ADDRESS, InitParam1);
00546     uint8_t InitParam2[4]= {0x00, 0x00, 0x01, 0x85};
00547     HAL_DSI_LongWrite(&hdsi_discovery, 0, DSI_DCS_LONG_PKT_WRITE, 4, DSI_SET_PAGE_ADDRESS, InitParam2);
00548 
00549     /* Sleep out */
00550     HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P0, DSI_EXIT_SLEEP_MODE, 0x0);
00551 
00552     HAL_Delay(120);
00553 
00554     /* Set display on */
00555     if(HAL_DSI_ShortWrite(&hdsi_discovery,
00556                           0,
00557                           DSI_DCS_SHORT_PKT_WRITE_P0,
00558                           DSI_SET_DISPLAY_ON,
00559                           0x0) != HAL_OK)
00560     {
00561       return(LCD_ERROR);
00562     }
00563 
00564 
00565     /* Enable DSI Wrapper */
00566     __HAL_DSI_WRAPPER_ENABLE(&hdsi_discovery);
00567 
00568     /* Initialize the font */
00569     BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
00570 
00571     bsp_lcd_initialized = 1;
00572   }
00573 
00574   return(LCD_OK);
00575 }
00576 
00577 /**
00578   * @brief  De-initialize the DSI LCD.
00579   * @retval LCD state
00580   */
00581 uint8_t BSP_LCD_DeInit(void)
00582 {
00583   if(bsp_lcd_initialized == 1)
00584   {
00585     /* Disable DSI wrapper */
00586     __HAL_DSI_WRAPPER_DISABLE(&hdsi_discovery);
00587 
00588     /* Set display off */
00589     if(HAL_DSI_ShortWrite(&hdsi_discovery,
00590                           0,
00591                           DSI_DCS_SHORT_PKT_WRITE_P0,
00592                           DSI_SET_DISPLAY_OFF,
00593                           0x0) != HAL_OK)
00594     {
00595       return(LCD_ERROR);
00596     }
00597 
00598     /* Wait before entering in sleep mode */
00599     HAL_Delay(2000);
00600 
00601     /* Put LCD in sleep mode */
00602     if(HAL_DSI_ShortWrite(&hdsi_discovery,
00603                           0,
00604                           DSI_DCS_SHORT_PKT_WRITE_P0,
00605                           DSI_ENTER_SLEEP_MODE,
00606                           0x0) != HAL_OK)
00607     {
00608       return(LCD_ERROR);
00609     }
00610 
00611     HAL_Delay(120);
00612 
00613     /* Power off LCD */
00614     LCD_PowerOff();
00615 
00616     /* De-initialize DSI */
00617     if(HAL_DSI_DeInit(&hdsi_discovery) != HAL_OK)
00618     {
00619       return(LCD_ERROR);
00620     }
00621 
00622     /* De-initialize LTDC */
00623     if(HAL_LTDC_DeInit(&hltdc_discovery) != HAL_OK)
00624     {
00625       return(LCD_ERROR);
00626     }
00627 
00628     /* De-initialize GFXMMU */
00629     if(HAL_GFXMMU_DeInit(&hgfxmmu_discovery) != HAL_OK)
00630     {
00631       return(LCD_ERROR);
00632     }
00633 
00634     /* Call MSP de-initialize function */
00635     BSP_LCD_MspDeInit();
00636 
00637     bsp_lcd_initialized = 0;
00638   }
00639 
00640   return(LCD_OK);
00641 }
00642 
00643 /**
00644   * @brief  Gets the LCD X size.
00645   * @retval Used LCD X size
00646   */
00647 uint32_t BSP_LCD_GetXSize(void)
00648 {
00649   return (lcd_x_size);
00650 }
00651 
00652 /**
00653   * @brief  Gets the LCD Y size.
00654   * @retval Used LCD Y size
00655   */
00656 uint32_t BSP_LCD_GetYSize(void)
00657 {
00658   return (lcd_y_size);
00659 }
00660 
00661 /**
00662   * @brief  Selects the LCD Layer.
00663   * @param  LayerIndex: Layer foreground (1) or background (0)
00664   * @note : Only backgroung layer can be used.
00665   * @retval LCD state
00666   */
00667 uint8_t BSP_LCD_SelectLayer(uint32_t LayerIndex)
00668 {
00669   uint8_t status = LCD_OK;
00670 
00671   if(LayerIndex == LTDC_ACTIVE_LAYER_BACKGROUND)
00672   {
00673     ActiveLayer = LayerIndex;
00674   }
00675   else
00676   {
00677     status = LCD_ERROR;
00678   }
00679   return(status);
00680 }
00681 
00682 /**
00683   * @brief  Sets an LCD Layer visible
00684   * @param  LayerIndex: Visible Layer
00685   * @param  State: New state of the specified layer
00686   *          This parameter can be one of the following values:
00687   *            @arg  ENABLE
00688   *            @arg  DISABLE
00689   * @note : Only backgroung layer can be used.
00690   * @retval LCD state
00691   */
00692 uint8_t BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState State)
00693 {
00694   uint8_t status = LCD_OK;
00695 
00696   if(LayerIndex == LTDC_ACTIVE_LAYER_BACKGROUND)
00697   {
00698     if(State == ENABLE)
00699     {
00700       __HAL_LTDC_LAYER_ENABLE(&(hltdc_discovery), LayerIndex);
00701     }
00702     else
00703     {
00704       __HAL_LTDC_LAYER_DISABLE(&(hltdc_discovery), LayerIndex);
00705     }
00706     __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&(hltdc_discovery));
00707   }
00708   else
00709   {
00710     status = LCD_ERROR;
00711   }
00712   return(status);
00713 }
00714 
00715 /**
00716   * @brief  Configures the transparency.
00717   * @param  LayerIndex: Layer foreground or background.
00718   * @param  Transparency: Transparency
00719   *           This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF
00720   * @note : Only backgroung layer can be used.
00721   * @retval LCD state
00722   */
00723 uint8_t BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency)
00724 {
00725   uint8_t status = LCD_OK;
00726 
00727   if(LayerIndex == LTDC_ACTIVE_LAYER_BACKGROUND)
00728   {
00729     HAL_LTDC_SetAlpha(&(hltdc_discovery), Transparency, LayerIndex);
00730   }
00731   else
00732   {
00733     status = LCD_ERROR;
00734   }
00735   return(status);
00736 }
00737 
00738 /**
00739   * @brief  Configures and sets the color keying.
00740   * @param  LayerIndex: Layer foreground (1) or background (0)
00741   * @param  RGBValue: Color reference
00742   * @note : Only backgroung layer can be used.
00743   * @retval LCD state
00744   */
00745 uint8_t BSP_LCD_SetColorKeying(uint32_t LayerIndex, uint32_t RGBValue)
00746 {
00747   uint8_t status = LCD_OK;
00748 
00749   if(LayerIndex == LTDC_ACTIVE_LAYER_BACKGROUND)
00750   {
00751     /* Configure and Enable the color Keying for LCD Layer */
00752     HAL_LTDC_ConfigColorKeying(&(hltdc_discovery), RGBValue, LayerIndex);
00753     HAL_LTDC_EnableColorKeying(&(hltdc_discovery), LayerIndex);
00754   }
00755   else
00756   {
00757     status = LCD_ERROR;
00758   }
00759   return(status);
00760 }
00761 
00762 /**
00763   * @brief  Disables the color keying.
00764   * @param  LayerIndex: Layer foreground (1) or background (0)
00765   * @note : Only backgroung layer can be used.
00766   * @retval LCD state
00767   */
00768 uint8_t BSP_LCD_ResetColorKeying(uint32_t LayerIndex)
00769 {
00770   uint8_t status = LCD_OK;
00771 
00772   if(LayerIndex == LTDC_ACTIVE_LAYER_BACKGROUND)
00773   {
00774     /* Disable the color Keying for LCD Layer */
00775     HAL_LTDC_DisableColorKeying(&(hltdc_discovery), LayerIndex);
00776   }
00777   else
00778   {
00779     status = LCD_ERROR;
00780   }
00781   return(status);
00782 }
00783 
00784 /**
00785   * @brief  Sets the LCD text color.
00786   * @param  Color: Text color code ARGB8888
00787   */
00788 void BSP_LCD_SetTextColor(uint32_t Color)
00789 {
00790   DrawProp[ActiveLayer].TextColor = Color;
00791 }
00792 
00793 /**
00794   * @brief  Gets the LCD text color.
00795   * @retval Used text color.
00796   */
00797 uint32_t BSP_LCD_GetTextColor(void)
00798 {
00799   return DrawProp[ActiveLayer].TextColor;
00800 }
00801 
00802 /**
00803   * @brief  Sets the LCD background color.
00804   * @param  Color: Layer background color code ARGB8888
00805   */
00806 void BSP_LCD_SetBackColor(uint32_t Color)
00807 {
00808   DrawProp[ActiveLayer].BackColor = Color;
00809 }
00810 
00811 /**
00812   * @brief  Gets the LCD background color.
00813   * @retval Used background color
00814   */
00815 uint32_t BSP_LCD_GetBackColor(void)
00816 {
00817   return DrawProp[ActiveLayer].BackColor;
00818 }
00819 
00820 /**
00821   * @brief  Sets the LCD text font.
00822   * @param  fonts: Layer font to be used
00823   */
00824 void BSP_LCD_SetFont(sFONT *fonts)
00825 {
00826   DrawProp[ActiveLayer].pFont = fonts;
00827 }
00828 
00829 /**
00830   * @brief  Gets the LCD text font.
00831   * @retval Used layer font
00832   */
00833 sFONT *BSP_LCD_GetFont(void)
00834 {
00835   return DrawProp[ActiveLayer].pFont;
00836 }
00837 
00838 /**
00839   * @brief  Reads an LCD pixel.
00840   * @param  Xpos: X position
00841   * @param  Ypos: Y position
00842   * @retval ARGB8888 pixel color
00843   */
00844 uint32_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos)
00845 {
00846   uint32_t ret = 0;
00847 
00848   /* Read value of corresponding pixel */
00849   /* We have 768 pixels per line and 4 bytes per pixel so 3072 bytes per line */
00850   ret = *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*768 + Xpos)));
00851 
00852   /* Return pixel value */
00853   return ret;
00854 }
00855 
00856 /**
00857   * @brief  Clears the whole currently active layer of LTDC.
00858   * @param  Color: Color of the background (in ARGB8888 format)
00859   */
00860 void BSP_LCD_Clear(uint32_t Color)
00861 {
00862   /* Clear the LCD */
00863   /* Offset line is 768 - 390 = 378 */
00864   LL_FillBuffer(ActiveLayer, (uint32_t *)(hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress), 390, 390, 378, Color);
00865 }
00866 
00867 /**
00868   * @brief  Clears the selected line in currently active layer.
00869   * @param  Line: Line to be cleared
00870   */
00871 void BSP_LCD_ClearStringLine(uint32_t Line)
00872 {
00873   uint32_t color_backup = DrawProp[ActiveLayer].TextColor;
00874   DrawProp[ActiveLayer].TextColor = DrawProp[ActiveLayer].BackColor;
00875 
00876   /* Draw rectangle with background color */
00877   BSP_LCD_FillRect(0, (Line * DrawProp[ActiveLayer].pFont->Height), 390, DrawProp[ActiveLayer].pFont->Height);
00878 
00879   DrawProp[ActiveLayer].TextColor = color_backup;
00880   BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
00881 }
00882 
00883 /**
00884   * @brief  Displays one character in currently active layer.
00885   * @param  Xpos: Start column address
00886   * @param  Ypos: Line where to display the character shape.
00887   * @param  Ascii: Character ascii code
00888   *           This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E
00889   */
00890 void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii)
00891 {
00892   DrawChar(Xpos, Ypos, &DrawProp[ActiveLayer].pFont->table[(Ascii-' ') * DrawProp[ActiveLayer].pFont->Height * ((DrawProp[ActiveLayer].pFont->Width + 7) / 8)]);
00893 }
00894 
00895 /**
00896   * @brief  Displays characters in currently active layer.
00897   * @param  Xpos: X position (in pixel)
00898   * @param  Ypos: Y position (in pixel)
00899   * @param  Text: Pointer to string to display on LCD
00900   * @param  Mode: Display mode
00901   *          This parameter can be one of the following values:
00902   *            @arg  CENTER_MODE
00903   *            @arg  RIGHT_MODE
00904   *            @arg  LEFT_MODE
00905   */
00906 void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Text_AlignModeTypdef Mode)
00907 {
00908   uint16_t refcolumn = 1, i = 0;
00909   uint32_t size = 0, xsize = 0;
00910   uint8_t  *ptr = Text;
00911 
00912   /* Get the text size */
00913   while (*ptr++) size ++ ;
00914 
00915   /* Characters number per line */
00916   xsize = (390/DrawProp[ActiveLayer].pFont->Width);
00917 
00918   switch (Mode)
00919   {
00920   case CENTER_MODE:
00921     {
00922       refcolumn = Xpos + ((xsize - size)* DrawProp[ActiveLayer].pFont->Width) / 2;
00923       break;
00924     }
00925   case LEFT_MODE:
00926     {
00927       refcolumn = Xpos;
00928       break;
00929     }
00930   case RIGHT_MODE:
00931     {
00932       refcolumn = - Xpos + ((xsize - size)*DrawProp[ActiveLayer].pFont->Width);
00933       break;
00934     }
00935   default:
00936     {
00937       refcolumn = Xpos;
00938       break;
00939     }
00940   }
00941 
00942   /* Check that the Start column is located in the screen */
00943   if ((refcolumn < 1) || (refcolumn >= 0x8000))
00944   {
00945     refcolumn = 1;
00946   }
00947 
00948   /* Send the string character by character on LCD */
00949   while ((*Text != 0) & (((390 - (i*DrawProp[ActiveLayer].pFont->Width)) & 0xFFFF) >= DrawProp[ActiveLayer].pFont->Width))
00950   {
00951     /* Display one character on LCD */
00952     BSP_LCD_DisplayChar(refcolumn, Ypos, *Text);
00953     /* Decrement the column position by 16 */
00954     refcolumn += DrawProp[ActiveLayer].pFont->Width;
00955 
00956     /* Point on the next character */
00957     Text++;
00958     i++;
00959   }
00960 
00961 }
00962 
00963 /**
00964   * @brief  Displays string on specified line of the LCD.
00965   * @param  Line: Line where to display the character shape
00966   * @param  ptr: Pointer to string to display on LCD
00967   */
00968 void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr)
00969 {
00970   BSP_LCD_DisplayStringAt(0, Line * (((sFONT *)BSP_LCD_GetFont())->Height), ptr, CENTER_MODE);
00971 }
00972 
00973 /**
00974   * @brief  Draws an horizontal line in currently active layer.
00975   * @param  Xpos: X position
00976   * @param  Ypos: Y position
00977   * @param  Length: Line length
00978   */
00979 void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
00980 {
00981   uint32_t  Xaddress = 0;
00982 
00983   /* Get the line address */
00984   Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(768*Ypos + Xpos);
00985 
00986   /* Write line */
00987   LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Length, 1, (768 - Length), DrawProp[ActiveLayer].TextColor);
00988 }
00989 
00990 /**
00991   * @brief  Draws a vertical line in currently active layer.
00992   * @param  Xpos: X position
00993   * @param  Ypos: Y position
00994   * @param  Length: Line length
00995   */
00996 void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length)
00997 {
00998   uint32_t  Xaddress = 0;
00999 
01000   /* Get the line address */
01001   Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(768*Ypos + Xpos);
01002 
01003   /* Write line */
01004   LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, 1, Length, (768 - 1), DrawProp[ActiveLayer].TextColor);
01005 }
01006 
01007 /**
01008   * @brief  Draws an uni-line (between two points) in currently active layer.
01009   * @param  x1: Point 1 X position
01010   * @param  y1: Point 1 Y position
01011   * @param  x2: Point 2 X position
01012   * @param  y2: Point 2 Y position
01013   */
01014 void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
01015 {
01016   int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
01017   yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
01018   curpixel = 0;
01019 
01020   deltax = ABS(x2 - x1);        /* The difference between the x's */
01021   deltay = ABS(y2 - y1);        /* The difference between the y's */
01022   x = x1;                       /* Start x off at the first pixel */
01023   y = y1;                       /* Start y off at the first pixel */
01024 
01025   if (x2 >= x1)                 /* The x-values are increasing */
01026   {
01027     xinc1 = 1;
01028     xinc2 = 1;
01029   }
01030   else                          /* The x-values are decreasing */
01031   {
01032     xinc1 = -1;
01033     xinc2 = -1;
01034   }
01035 
01036   if (y2 >= y1)                 /* The y-values are increasing */
01037   {
01038     yinc1 = 1;
01039     yinc2 = 1;
01040   }
01041   else                          /* The y-values are decreasing */
01042   {
01043     yinc1 = -1;
01044     yinc2 = -1;
01045   }
01046 
01047   if (deltax >= deltay)         /* There is at least one x-value for every y-value */
01048   {
01049     xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
01050     yinc2 = 0;                  /* Don't change the y for every iteration */
01051     den = deltax;
01052     num = deltax / 2;
01053     numadd = deltay;
01054     numpixels = deltax;         /* There are more x-values than y-values */
01055   }
01056   else                          /* There is at least one y-value for every x-value */
01057   {
01058     xinc2 = 0;                  /* Don't change the x for every iteration */
01059     yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
01060     den = deltay;
01061     num = deltay / 2;
01062     numadd = deltax;
01063     numpixels = deltay;         /* There are more y-values than x-values */
01064   }
01065 
01066   for (curpixel = 0; curpixel <= numpixels; curpixel++)
01067   {
01068     BSP_LCD_DrawPixel(x, y, DrawProp[ActiveLayer].TextColor);   /* Draw the current pixel */
01069     num += numadd;                            /* Increase the numerator by the top of the fraction */
01070     if (num >= den)                           /* Check if numerator >= denominator */
01071     {
01072       num -= den;                             /* Calculate the new numerator value */
01073       x += xinc1;                             /* Change the x as appropriate */
01074       y += yinc1;                             /* Change the y as appropriate */
01075     }
01076     x += xinc2;                               /* Change the x as appropriate */
01077     y += yinc2;                               /* Change the y as appropriate */
01078   }
01079 }
01080 
01081 /**
01082   * @brief  Draws a rectangle in currently active layer.
01083   * @param  Xpos: X position
01084   * @param  Ypos: Y position
01085   * @param  Width: Rectangle width
01086   * @param  Height: Rectangle height
01087   */
01088 void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
01089 {
01090   /* Draw horizontal lines */
01091   BSP_LCD_DrawHLine(Xpos, Ypos, Width);
01092   BSP_LCD_DrawHLine(Xpos, (Ypos+ Height), Width);
01093 
01094   /* Draw vertical lines */
01095   BSP_LCD_DrawVLine(Xpos, Ypos, Height);
01096   BSP_LCD_DrawVLine((Xpos + Width), Ypos, Height);
01097 }
01098 
01099 /**
01100   * @brief  Draws a circle in currently active layer.
01101   * @param  Xpos: X position
01102   * @param  Ypos: Y position
01103   * @param  Radius: Circle radius
01104   */
01105 void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
01106 {
01107   int32_t   D;    /* Decision Variable */
01108   uint32_t  CurX; /* Current X Value */
01109   uint32_t  CurY; /* Current Y Value */
01110 
01111   D = 3 - (Radius << 1);
01112   CurX = 0;
01113   CurY = Radius;
01114 
01115   while (CurX <= CurY)
01116   {
01117     BSP_LCD_DrawPixel((Xpos + CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor);
01118 
01119     BSP_LCD_DrawPixel((Xpos - CurX), (Ypos - CurY), DrawProp[ActiveLayer].TextColor);
01120 
01121     BSP_LCD_DrawPixel((Xpos + CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor);
01122 
01123     BSP_LCD_DrawPixel((Xpos - CurY), (Ypos - CurX), DrawProp[ActiveLayer].TextColor);
01124 
01125     BSP_LCD_DrawPixel((Xpos + CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor);
01126 
01127     BSP_LCD_DrawPixel((Xpos - CurX), (Ypos + CurY), DrawProp[ActiveLayer].TextColor);
01128 
01129     BSP_LCD_DrawPixel((Xpos + CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor);
01130 
01131     BSP_LCD_DrawPixel((Xpos - CurY), (Ypos + CurX), DrawProp[ActiveLayer].TextColor);
01132 
01133     if (D < 0)
01134     {
01135       D += (CurX << 2) + 6;
01136     }
01137     else
01138     {
01139       D += ((CurX - CurY) << 2) + 10;
01140       CurY--;
01141     }
01142     CurX++;
01143   }
01144 }
01145 
01146 /**
01147   * @brief  Draws an poly-line (between many points) in currently active layer.
01148   * @param  Points: Pointer to the points array
01149   * @param  PointCount: Number of points
01150   */
01151 void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount)
01152 {
01153   int16_t X = 0, Y = 0;
01154 
01155   if(PointCount < 2)
01156   {
01157     return;
01158   }
01159 
01160   BSP_LCD_DrawLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);
01161 
01162   while(--PointCount)
01163   {
01164     X = Points->X;
01165     Y = Points->Y;
01166     Points++;
01167     BSP_LCD_DrawLine(X, Y, Points->X, Points->Y);
01168   }
01169 }
01170 
01171 /**
01172   * @brief  Draws an ellipse on LCD in currently active layer.
01173   * @param  Xpos: X position
01174   * @param  Ypos: Y position
01175   * @param  XRadius: Ellipse X radius
01176   * @param  YRadius: Ellipse Y radius
01177   */
01178 void BSP_LCD_DrawEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
01179 {
01180   int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
01181   float K = 0, rad1 = 0, rad2 = 0;
01182 
01183   rad1 = XRadius;
01184   rad2 = YRadius;
01185 
01186   K = (float)(rad2/rad1);
01187 
01188   do {
01189     BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos+y), DrawProp[ActiveLayer].TextColor);
01190     BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos+y), DrawProp[ActiveLayer].TextColor);
01191     BSP_LCD_DrawPixel((Xpos+(uint16_t)(x/K)), (Ypos-y), DrawProp[ActiveLayer].TextColor);
01192     BSP_LCD_DrawPixel((Xpos-(uint16_t)(x/K)), (Ypos-y), DrawProp[ActiveLayer].TextColor);
01193 
01194     e2 = err;
01195     if (e2 <= x) {
01196       err += ++x*2+1;
01197       if (-y == x && e2 <= y) e2 = 0;
01198     }
01199     if (e2 > y) err += ++y*2+1;
01200   }
01201   while (y <= 0);
01202 }
01203 
01204 /**
01205   * @brief  Draws a bitmap picture loaded in the internal Flash (32 bpp) in currently active layer.
01206   * @param  Xpos: Bmp X position in the LCD
01207   * @param  Ypos: Bmp Y position in the LCD
01208   * @param  pbmp: Pointer to Bmp picture address in the internal Flash
01209   */
01210 void BSP_LCD_DrawBitmap(uint32_t Xpos, uint32_t Ypos, uint8_t *pbmp)
01211 {
01212   uint32_t index = 0, width = 0, height = 0, bit_pixel = 0;
01213   uint32_t Address;
01214   uint32_t InputColorMode = 0;
01215 
01216   /* Get bitmap data address offset */
01217   index = *(__IO uint16_t *) (pbmp + 10);
01218   index |= (*(__IO uint16_t *) (pbmp + 12)) << 16;
01219 
01220   /* Read bitmap width */
01221   width = *(uint16_t *) (pbmp + 18);
01222   width |= (*(uint16_t *) (pbmp + 20)) << 16;
01223 
01224   /* Read bitmap height */
01225   height = *(uint16_t *) (pbmp + 22);
01226   height |= (*(uint16_t *) (pbmp + 24)) << 16;
01227 
01228   /* Read bit/pixel */
01229   bit_pixel = *(uint16_t *) (pbmp + 28);
01230 
01231   /* Set the address */
01232   Address = hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (((768*Ypos) + Xpos)*(4));
01233 
01234   /* Get the layer pixel format */
01235   if ((bit_pixel/8) == 4)
01236   {
01237     InputColorMode = DMA2D_INPUT_ARGB8888;
01238   }
01239   else if ((bit_pixel/8) == 2)
01240   {
01241     InputColorMode = DMA2D_INPUT_RGB565;
01242   }
01243   else
01244   {
01245     InputColorMode = DMA2D_INPUT_RGB888;
01246   }
01247 
01248   /* Bypass the bitmap header */
01249   pbmp += (index + (width * (height - 1) * (bit_pixel/8)));
01250 
01251   /* Convert picture to ARGB8888 pixel format */
01252   for(index=0; index < height; index++)
01253   {
01254     /* Pixel format conversion */
01255     LL_ConvertLineToARGB8888((uint32_t *)pbmp, (uint32_t *)Address, width, InputColorMode);
01256 
01257     /* Increment the source and destination buffers */
01258     Address+=  (768*4);
01259     pbmp -= width*(bit_pixel/8);
01260   }
01261 }
01262 
01263 /**
01264   * @brief  Draws a full rectangle in currently active layer.
01265   * @param  Xpos: X position
01266   * @param  Ypos: Y position
01267   * @param  Width: Rectangle width
01268   * @param  Height: Rectangle height
01269   */
01270 void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
01271 {
01272   uint32_t  Xaddress = 0;
01273 
01274   /* Set the text color */
01275   BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
01276 
01277   /* Get the rectangle start address */
01278   Xaddress = (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress) + 4*(768*Ypos + Xpos);
01279 
01280   /* Fill the rectangle */
01281   LL_FillBuffer(ActiveLayer, (uint32_t *)Xaddress, Width, Height, (768 - Width), DrawProp[ActiveLayer].TextColor);
01282 }
01283 
01284 /**
01285   * @brief  Draws a full circle in currently active layer.
01286   * @param  Xpos: X position
01287   * @param  Ypos: Y position
01288   * @param  Radius: Circle radius
01289   */
01290 void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)
01291 {
01292   int32_t  D;     /* Decision Variable */
01293   uint32_t  CurX; /* Current X Value */
01294   uint32_t  CurY; /* Current Y Value */
01295 
01296   D = 3 - (Radius << 1);
01297 
01298   CurX = 0;
01299   CurY = Radius;
01300 
01301   BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
01302 
01303   while (CurX <= CurY)
01304   {
01305     if(CurY > 0)
01306     {
01307       BSP_LCD_DrawHLine(Xpos - CurY, Ypos + CurX, 2*CurY);
01308       BSP_LCD_DrawHLine(Xpos - CurY, Ypos - CurX, 2*CurY);
01309     }
01310 
01311     if(CurX > 0)
01312     {
01313       BSP_LCD_DrawHLine(Xpos - CurX, Ypos - CurY, 2*CurX);
01314       BSP_LCD_DrawHLine(Xpos - CurX, Ypos + CurY, 2*CurX);
01315     }
01316     if (D < 0)
01317     {
01318       D += (CurX << 2) + 6;
01319     }
01320     else
01321     {
01322       D += ((CurX - CurY) << 2) + 10;
01323       CurY--;
01324     }
01325     CurX++;
01326   }
01327 
01328   BSP_LCD_SetTextColor(DrawProp[ActiveLayer].TextColor);
01329   BSP_LCD_DrawCircle(Xpos, Ypos, Radius);
01330 }
01331 
01332 /**
01333   * @brief  Draws a full poly-line (between many points) in currently active layer.
01334   * @param  Points: Pointer to the points array
01335   * @param  PointCount: Number of points
01336   */
01337 void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount)
01338 {
01339   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;
01340   uint16_t  IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;
01341 
01342   IMAGE_LEFT = IMAGE_RIGHT = Points->X;
01343   IMAGE_TOP= IMAGE_BOTTOM = Points->Y;
01344 
01345   for(counter = 1; counter < PointCount; counter++)
01346   {
01347     pixelX = POLY_X(counter);
01348     if(pixelX < IMAGE_LEFT)
01349     {
01350       IMAGE_LEFT = pixelX;
01351     }
01352     if(pixelX > IMAGE_RIGHT)
01353     {
01354       IMAGE_RIGHT = pixelX;
01355     }
01356 
01357     pixelY = POLY_Y(counter);
01358     if(pixelY < IMAGE_TOP)
01359     {
01360       IMAGE_TOP = pixelY;
01361     }
01362     if(pixelY > IMAGE_BOTTOM)
01363     {
01364       IMAGE_BOTTOM = pixelY;
01365     }
01366   }
01367 
01368   if(PointCount < 2)
01369   {
01370     return;
01371   }
01372 
01373   X_center = (IMAGE_LEFT + IMAGE_RIGHT)/2;
01374   Y_center = (IMAGE_BOTTOM + IMAGE_TOP)/2;
01375 
01376   X_first = Points->X;
01377   Y_first = Points->Y;
01378 
01379   while(--PointCount)
01380   {
01381     X = Points->X;
01382     Y = Points->Y;
01383     Points++;
01384     X2 = Points->X;
01385     Y2 = Points->Y;
01386 
01387     FillTriangle(X, X2, X_center, Y, Y2, Y_center);
01388     FillTriangle(X, X_center, X2, Y, Y_center, Y2);
01389     FillTriangle(X_center, X2, X, Y_center, Y2, Y);
01390   }
01391 
01392   FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center);
01393   FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2);
01394   FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first);
01395 }
01396 
01397 /**
01398   * @brief  Draws a full ellipse in currently active layer.
01399   * @param  Xpos: X position
01400   * @param  Ypos: Y position
01401   * @param  XRadius: Ellipse X radius
01402   * @param  YRadius: Ellipse Y radius
01403   */
01404 void BSP_LCD_FillEllipse(int Xpos, int Ypos, int XRadius, int YRadius)
01405 {
01406   int x = 0, y = -YRadius, err = 2-2*XRadius, e2;
01407   float K = 0, rad1 = 0, rad2 = 0;
01408 
01409   rad1 = XRadius;
01410   rad2 = YRadius;
01411 
01412   K = (float)(rad2/rad1);
01413 
01414   do
01415   {
01416     BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos+y), (2*(uint16_t)(x/K) + 1));
01417     BSP_LCD_DrawHLine((Xpos-(uint16_t)(x/K)), (Ypos-y), (2*(uint16_t)(x/K) + 1));
01418 
01419     e2 = err;
01420     if (e2 <= x)
01421     {
01422       err += ++x*2+1;
01423       if (-y == x && e2 <= y) e2 = 0;
01424     }
01425     if (e2 > y) err += ++y*2+1;
01426   }
01427   while (y <= 0);
01428 }
01429 
01430 /**
01431   * @brief  Draws a pixel on LCD.
01432   * @param  Xpos: X position
01433   * @param  Ypos: Y position
01434   * @param  RGB_Code: Pixel color in ARGB mode (8-8-8-8)
01435   */
01436 void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint32_t RGB_Code)
01437 {
01438   /* Write pixel */
01439   *(__IO uint32_t*) (hltdc_discovery.LayerCfg[ActiveLayer].FBStartAdress + (4*(Ypos*768 + Xpos))) = RGB_Code;
01440 }
01441 
01442 /**
01443   * @brief  Switch back on the display if was switched off by previous call of BSP_LCD_DisplayOff().
01444   */
01445 void BSP_LCD_DisplayOn(void)
01446 {
01447   /* Send Display on DCS command to display */
01448   HAL_DSI_ShortWrite(&hdsi_discovery,
01449                      0,
01450                      DSI_DCS_SHORT_PKT_WRITE_P0,
01451                      DSI_SET_DISPLAY_ON,
01452                      0x0);
01453 }
01454 
01455 /**
01456   * @brief  Switch Off the display.
01457   */
01458 void BSP_LCD_DisplayOff(void)
01459 {
01460   /* Send Display off DCS Command to display */
01461   HAL_DSI_ShortWrite(&hdsi_discovery,
01462                      0,
01463                      DSI_DCS_SHORT_PKT_WRITE_P0,
01464                      DSI_SET_DISPLAY_OFF,
01465                      0x0);
01466 }
01467 
01468 /**
01469   * @brief  Refresh the display.
01470   */
01471 void BSP_LCD_Refresh(void)
01472 {
01473   /* Set frame buffer busy */
01474   FrameBufferAvailable = 0;
01475 
01476   /* Set tear on */
01477   HAL_DSI_ShortWrite(&hdsi_discovery, 0, DSI_DCS_SHORT_PKT_WRITE_P1, DSI_SET_TEAR_ON, 0x0);
01478 }
01479 
01480 /**
01481   * @brief  Check if frame buffer is available.
01482   * @retval LCD_OK if frame buffer is available else LCD_ERROR (frame buffer busy)
01483   */
01484 uint8_t BSP_LCD_IsFrameBufferAvailable(void)
01485 {
01486   uint8_t status;
01487   /* Check frame buffer status */
01488   status = (FrameBufferAvailable == 1) ? LCD_OK : LCD_ERROR;
01489 
01490   return(status);
01491 }
01492 
01493 /**
01494   * @brief  Set the brightness value
01495   * @param  BrightnessValue: [0% Min (black), 100% Max]
01496   */
01497 void BSP_LCD_SetBrightness(uint8_t BrightnessValue)
01498 {
01499   /* Send Display on DCS command to display */
01500   HAL_DSI_ShortWrite(&hdsi_discovery,
01501                      0,
01502                      DSI_DCS_SHORT_PKT_WRITE_P1,
01503                      0x51, (uint16_t)(BrightnessValue * 255)/100);
01504 }
01505 
01506 /*******************************************************************************
01507                        LTDC, DMA2D and DSI BSP Routines
01508 *******************************************************************************/
01509 /**
01510   * @brief  Handles DMA2D interrupt request.
01511   * @note   Application can surcharge if needed this function implementation.
01512   */
01513 __weak void BSP_LCD_DMA2D_IRQHandler(void)
01514 {
01515   HAL_DMA2D_IRQHandler(&hdma2d_discovery);
01516 }
01517 
01518 /**
01519   * @brief  Handles DSI interrupt request.
01520   * @note   Application can surcharge if needed this function implementation.
01521   */
01522 __weak void BSP_LCD_DSI_IRQHandler(void)
01523 {
01524   HAL_DSI_IRQHandler(&(hdsi_discovery));
01525 }
01526 
01527 /**
01528   * @brief  Handles LTDC interrupt request.
01529   * @note   Application can surcharge if needed this function implementation.
01530   */
01531 __weak void BSP_LCD_LTDC_IRQHandler(void)
01532 {
01533   HAL_LTDC_IRQHandler(&(hltdc_discovery));
01534 }
01535 
01536 /**
01537   * @brief  This function handles LTDC Error interrupt Handler.
01538   * @note   Application can surcharge if needed this function implementation.
01539   */
01540 
01541 __weak void BSP_LCD_LTDC_ER_IRQHandler(void)
01542 {
01543   HAL_LTDC_IRQHandler(&(hltdc_discovery));
01544 }
01545 
01546 /**
01547   * @brief  De-Initializes the BSP LCD Msp.
01548   * @note   Application can surcharge if needed this function implementation.
01549   */
01550 __weak void BSP_LCD_MspDeInit(void)
01551 {
01552   /* Disable IRQ of LTDC IP */
01553   HAL_NVIC_DisableIRQ(LTDC_IRQn);
01554   HAL_NVIC_DisableIRQ(LTDC_ER_IRQn);
01555 
01556   /* Disable IRQ of DMA2D IP */
01557   HAL_NVIC_DisableIRQ(DMA2D_IRQn);
01558 
01559   /* Disable IRQ of DSI IP */
01560   HAL_NVIC_DisableIRQ(DSI_IRQn);
01561 
01562   /* Disable HSE used for DSI PLL */
01563   if(bsp_lcd_hse_to_disable == 1)
01564   {
01565     RCC_OscInitTypeDef RCC_OscInitStruct;
01566     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
01567     RCC_OscInitStruct.HSEState       = RCC_HSE_OFF;
01568     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
01569     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
01570     {
01571       while(1);
01572     }
01573     /* Workaround for long HSE startup time (deinit PH0) */
01574     HAL_GPIO_DeInit(GPIOH, GPIO_PIN_0);
01575 
01576     bsp_lcd_hse_to_disable = 0;
01577   }
01578 
01579   /* Force and let in reset state GFXMMU, LTDC, DMA2D and DSI Host + Wrapper IPs */
01580   __HAL_RCC_GFXMMU_FORCE_RESET();
01581   __HAL_RCC_LTDC_FORCE_RESET();
01582   __HAL_RCC_DMA2D_FORCE_RESET();
01583   __HAL_RCC_DSI_FORCE_RESET();
01584 
01585   /* Disable the GFXMMU, LTDC, DMA2D and DSI Host and Wrapper clocks */
01586   __HAL_RCC_GFXMMU_CLK_DISABLE();
01587   __HAL_RCC_LTDC_CLK_DISABLE();
01588   __HAL_RCC_DMA2D_CLK_DISABLE();
01589   __HAL_RCC_DSI_CLK_DISABLE();
01590 }
01591 
01592 /**
01593   * @brief  Initialize the BSP LCD Msp.
01594   * @note   Application can surcharge if needed this function implementation.
01595   */
01596 __weak void BSP_LCD_MspInit(void)
01597 {
01598   /* Enable the GFXMMU clock */
01599   __HAL_RCC_GFXMMU_CLK_ENABLE();
01600 
01601   /* Reset of GFXMMU IP */
01602   __HAL_RCC_GFXMMU_FORCE_RESET();
01603   __HAL_RCC_GFXMMU_RELEASE_RESET();
01604 
01605   /* Enable the LTDC clock */
01606   __HAL_RCC_LTDC_CLK_ENABLE();
01607 
01608   /* Reset of LTDC IP */
01609   __HAL_RCC_LTDC_FORCE_RESET();
01610   __HAL_RCC_LTDC_RELEASE_RESET();
01611 
01612   /* Enable the DMA2D clock */
01613   __HAL_RCC_DMA2D_CLK_ENABLE();
01614 
01615   /* Reset of DMA2D IP */
01616   __HAL_RCC_DMA2D_FORCE_RESET();
01617   __HAL_RCC_DMA2D_RELEASE_RESET();
01618 
01619   /* Enable DSI Host and wrapper clocks */
01620   __HAL_RCC_DSI_CLK_ENABLE();
01621 
01622   /* Reset the DSI Host and wrapper */
01623   __HAL_RCC_DSI_FORCE_RESET();
01624   __HAL_RCC_DSI_RELEASE_RESET();
01625 
01626   /* Configure the clock for the LTDC */
01627   /* We want DSI PHI at 500MHz */
01628   /* We have only one line => 500Mbps */
01629   /* With 24bits per pixel, equivalent PCLK is 500/24 = 20.8MHz */
01630   /* We will set PCLK at 15MHz */
01631   /* Following values are OK with MSI = 4MHz */
01632   /* (4*60)/(1*4*4) = 15MHz */
01633   RCC_PeriphCLKInitTypeDef  PeriphClkInit;
01634   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
01635   PeriphClkInit.PLLSAI2.PLLSAI2Source = RCC_PLLSOURCE_MSI;
01636   PeriphClkInit.PLLSAI2.PLLSAI2M = 1;
01637   PeriphClkInit.PLLSAI2.PLLSAI2N = 60;
01638   PeriphClkInit.PLLSAI2.PLLSAI2R = RCC_PLLR_DIV4;
01639   PeriphClkInit.LtdcClockSelection = RCC_LTDCCLKSOURCE_PLLSAI2_DIV4;
01640   PeriphClkInit.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_LTDCCLK;
01641   if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
01642   {
01643     while(1);
01644   }
01645 
01646   /* Enable HSE used for DSI PLL */
01647   RCC_OscInitTypeDef RCC_OscInitStruct;
01648   HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
01649   if(RCC_OscInitStruct.HSEState == RCC_HSE_OFF)
01650   {
01651     /* Workaround for long HSE startup time (set PH0 to ouput PP low) */
01652     GPIO_InitTypeDef  GPIO_InitStruct;
01653     __HAL_RCC_GPIOH_CLK_ENABLE();
01654     GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;
01655     GPIO_InitStruct.Pull      = GPIO_NOPULL;
01656     GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
01657     GPIO_InitStruct.Pin       = GPIO_PIN_0;
01658     HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
01659     HAL_GPIO_WritePin(GPIOH, GPIO_PIN_0, GPIO_PIN_RESET);
01660 
01661     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
01662     RCC_OscInitStruct.HSEState       = RCC_HSE_ON;
01663     RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
01664     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
01665     {
01666       while(1);
01667     }
01668     bsp_lcd_hse_to_disable = 1;
01669   }
01670 
01671   /* NVIC configuration for LTDC interrupts that are now enabled */
01672   HAL_NVIC_SetPriority(LTDC_IRQn, 3, 0);
01673   HAL_NVIC_EnableIRQ(LTDC_IRQn);
01674   HAL_NVIC_SetPriority(LTDC_ER_IRQn, 3, 0);
01675   HAL_NVIC_EnableIRQ(LTDC_ER_IRQn);
01676 
01677   /* NVIC configuration for DMA2D interrupt that is now enabled */
01678   HAL_NVIC_SetPriority(DMA2D_IRQn, 3, 0);
01679   HAL_NVIC_EnableIRQ(DMA2D_IRQn);
01680 
01681   /* NVIC configuration for DSI interrupt that is now enabled */
01682   HAL_NVIC_SetPriority(DSI_IRQn, 3, 0);
01683   HAL_NVIC_EnableIRQ(DSI_IRQn);
01684 }
01685 
01686 /**
01687   * @}
01688   */
01689 
01690 /** @defgroup STM32L4R9I_DISCOVERY_LCD_Private_Functions LCD Private Functions
01691   * @{
01692   */
01693 
01694 /**
01695   * @brief  End of Refresh DSI callback.
01696   * @param  hdsi: pointer to a DSI_HandleTypeDef structure that contains
01697   *               the configuration information for the DSI.
01698   * @retval None
01699   */
01700 void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
01701 {
01702   /* Clear pending tearing effect flag */
01703   __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
01704 
01705   /* Set frame buffer available */
01706   FrameBufferAvailable = 1;
01707 }
01708 
01709 /**
01710   * @brief  LCD power on
01711   *         Power on LCD.
01712   */
01713 static void LCD_PowerOn(void)
01714 {
01715   /* Configure DSI_RESET and DSI_POWER_ON only if psram is not currently used */
01716   if(bsp_psram_initialized == 0)
01717   {
01718     BSP_IO_Init();
01719 
01720 #if defined(USE_STM32L4R9I_DISCO_REVA) || defined(USE_STM32L4R9I_DISCO_REVB)
01721     /* Set DSI_POWER_ON to input floating to avoid I2C issue during input PD configuration */
01722     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_INPUT);
01723 
01724     /* Configure the GPIO connected to DSI_RESET signal */
01725     BSP_IO_ConfigPin(IO_PIN_10, IO_MODE_OUTPUT);
01726 
01727     /* Activate DSI_RESET (active low) */
01728     BSP_IO_WritePin(IO_PIN_10, GPIO_PIN_RESET);
01729 
01730     /* Configure the GPIO connected to DSI_POWER_ON signal as input pull down */
01731     /* to activate 3V3_LCD. VDD_LCD is also activated if VDD = 3,3V */
01732     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_INPUT_PD);
01733 
01734     /* Wait at least 1ms before enabling 1V8_LCD */
01735     HAL_Delay(1);
01736 
01737     /* Configure the GPIO connected to DSI_POWER_ON signal as output low */
01738     /* to activate 1V8_LCD. VDD_LCD is also activated if VDD = 1,8V */
01739     BSP_IO_WritePin(IO_PIN_8, GPIO_PIN_RESET);
01740     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_OUTPUT);
01741 #else /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01742     /* Configure the GPIO connected to DSI_3V3_POWERON signal as output low */
01743     /* to activate 3V3_LCD. VDD_LCD is also activated if VDD = 3,3V */
01744     BSP_IO_WritePin(IO_PIN_8, GPIO_PIN_RESET);
01745     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_OUTPUT);
01746 
01747     /* Wait at least 1ms before enabling 1V8_LCD */
01748     HAL_Delay(1);
01749 
01750     /* Configure the GPIO connected to DSI_1V8_POWERON signal as output low */
01751     /* to activate 1V8_LCD. VDD_LCD is also activated if VDD = 1,8V */
01752     BSP_IO_WritePin(AGPIO_PIN_2, GPIO_PIN_RESET);
01753     BSP_IO_ConfigPin(AGPIO_PIN_2, IO_MODE_OUTPUT);
01754 #endif /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01755 
01756     /* Wait at least 15 ms (minimum reset low width is 10ms and add margin for 1V8_LCD ramp-up) */
01757     HAL_Delay(15);
01758   }
01759 
01760 #if defined(USE_STM32L4R9I_DISCO_REVA) || defined(USE_STM32L4R9I_DISCO_REVB)
01761   /* Desactivate DSI_RESET */
01762   BSP_IO_WritePin(IO_PIN_10, GPIO_PIN_SET);
01763 #else /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01764   /* Configure the GPIO connected to DSI_RESET signal */
01765   BSP_IO_ConfigPin(IO_PIN_10, IO_MODE_OUTPUT);
01766 
01767   /* Desactivate DSI_RESET */
01768   BSP_IO_WritePin(IO_PIN_10, GPIO_PIN_SET);
01769 #endif /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01770 
01771   /* Wait reset complete time (maximum time is 5ms when LCD in sleep mode and 120ms when LCD is not in sleep mode) */
01772   HAL_Delay(120);
01773 }
01774 
01775 /**
01776   * @brief  LCD power off
01777   *         Power off LCD.
01778   */
01779 static void LCD_PowerOff(void)
01780 {
01781   /* Activate DSI_RESET */
01782   BSP_IO_WritePin(IO_PIN_10, GPIO_PIN_RESET);
01783 
01784   /* Wait at least 5 ms */
01785   HAL_Delay(5);
01786 
01787   /* Set DSI_POWER_ON to analog mode only if psram is not currently used */
01788   if(bsp_psram_initialized == 0)
01789   {
01790 #if defined(USE_STM32L4R9I_DISCO_REVA) || defined(USE_STM32L4R9I_DISCO_REVB)
01791     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_ANALOG);
01792 #else /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01793     /* Disable first DSI_1V8_PWRON then DSI_3V3_PWRON */
01794     BSP_IO_ConfigPin(AGPIO_PIN_2, IO_MODE_ANALOG);
01795     BSP_IO_ConfigPin(IO_PIN_8, IO_MODE_ANALOG);
01796 #endif /* USE_STM32L4R9I_DISCO_REVA || USE_STM32L4R9I_DISCO_REVB */
01797   }
01798 }
01799 
01800 /**
01801   * @brief  Draws a character on LCD.
01802   * @param  Xpos: Line where to display the character shape
01803   * @param  Ypos: Start column address
01804   * @param  c: Pointer to the character data
01805   */
01806 static void DrawChar(uint16_t Xpos, uint16_t Ypos, const uint8_t *c)
01807 {
01808   uint32_t i = 0, j = 0;
01809   uint16_t height, width;
01810   uint8_t  offset;
01811   uint8_t  *pchar;
01812   uint32_t line;
01813 
01814   height = DrawProp[ActiveLayer].pFont->Height;
01815   width  = DrawProp[ActiveLayer].pFont->Width;
01816 
01817   offset =  8 *((width + 7)/8) -  width ;
01818 
01819   for(i = 0; i < height; i++)
01820   {
01821     pchar = ((uint8_t *)c + (width + 7)/8 * i);
01822 
01823     switch(((width + 7)/8))
01824     {
01825 
01826     case 1:
01827       line =  pchar[0];
01828       break;
01829 
01830     case 2:
01831       line =  (pchar[0]<< 8) | pchar[1];
01832       break;
01833 
01834     case 3:
01835     default:
01836       line =  (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2];
01837       break;
01838     }
01839 
01840     for (j = 0; j < width; j++)
01841     {
01842       if(line & (1 << (width- j + offset- 1)))
01843       {
01844         BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].TextColor);
01845       }
01846       else
01847       {
01848         BSP_LCD_DrawPixel((Xpos + j), Ypos, DrawProp[ActiveLayer].BackColor);
01849       }
01850     }
01851     Ypos++;
01852   }
01853 }
01854 
01855 /**
01856   * @brief  Fills a triangle (between 3 points).
01857   * @param  x1: Point 1 X position
01858   * @param  y1: Point 1 Y position
01859   * @param  x2: Point 2 X position
01860   * @param  y2: Point 2 Y position
01861   * @param  x3: Point 3 X position
01862   * @param  y3: Point 3 Y position
01863   */
01864 static void FillTriangle(uint16_t x1, uint16_t x2, uint16_t x3, uint16_t y1, uint16_t y2, uint16_t y3)
01865 {
01866   int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,
01867   yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,
01868   curpixel = 0;
01869 
01870   deltax = ABS(x2 - x1);        /* The difference between the x's */
01871   deltay = ABS(y2 - y1);        /* The difference between the y's */
01872   x = x1;                       /* Start x off at the first pixel */
01873   y = y1;                       /* Start y off at the first pixel */
01874 
01875   if (x2 >= x1)                 /* The x-values are increasing */
01876   {
01877     xinc1 = 1;
01878     xinc2 = 1;
01879   }
01880   else                          /* The x-values are decreasing */
01881   {
01882     xinc1 = -1;
01883     xinc2 = -1;
01884   }
01885 
01886   if (y2 >= y1)                 /* The y-values are increasing */
01887   {
01888     yinc1 = 1;
01889     yinc2 = 1;
01890   }
01891   else                          /* The y-values are decreasing */
01892   {
01893     yinc1 = -1;
01894     yinc2 = -1;
01895   }
01896 
01897   if (deltax >= deltay)         /* There is at least one x-value for every y-value */
01898   {
01899     xinc1 = 0;                  /* Don't change the x when numerator >= denominator */
01900     yinc2 = 0;                  /* Don't change the y for every iteration */
01901     den = deltax;
01902     num = deltax / 2;
01903     numadd = deltay;
01904     numpixels = deltax;         /* There are more x-values than y-values */
01905   }
01906   else                          /* There is at least one y-value for every x-value */
01907   {
01908     xinc2 = 0;                  /* Don't change the x for every iteration */
01909     yinc1 = 0;                  /* Don't change the y when numerator >= denominator */
01910     den = deltay;
01911     num = deltay / 2;
01912     numadd = deltax;
01913     numpixels = deltay;         /* There are more y-values than x-values */
01914   }
01915 
01916   for (curpixel = 0; curpixel <= numpixels; curpixel++)
01917   {
01918     BSP_LCD_DrawLine(x, y, x3, y3);
01919 
01920     num += numadd;              /* Increase the numerator by the top of the fraction */
01921     if (num >= den)             /* Check if numerator >= denominator */
01922     {
01923       num -= den;               /* Calculate the new numerator value */
01924       x += xinc1;               /* Change the x as appropriate */
01925       y += yinc1;               /* Change the y as appropriate */
01926     }
01927     x += xinc2;                 /* Change the x as appropriate */
01928     y += yinc2;                 /* Change the y as appropriate */
01929   }
01930 }
01931 
01932 /**
01933   * @brief  Fills a buffer.
01934   * @param  LayerIndex: Layer index
01935   * @param  pDst: Pointer to destination buffer
01936   * @param  xSize: Buffer width
01937   * @param  ySize: Buffer height
01938   * @param  OffLine: Offset
01939   * @param  ColorIndex: Color index
01940   */
01941 static void LL_FillBuffer(uint32_t LayerIndex, void *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine, uint32_t ColorIndex)
01942 {
01943   /* Register to memory mode with ARGB8888 as color Mode */
01944   hdma2d_discovery.Init.Mode          = DMA2D_R2M;
01945   hdma2d_discovery.Init.ColorMode     = DMA2D_OUTPUT_ARGB8888;
01946   hdma2d_discovery.Init.OutputOffset  = OffLine;
01947   hdma2d_discovery.Init.AlphaInverted = DMA2D_REGULAR_ALPHA;
01948   hdma2d_discovery.Init.RedBlueSwap   = DMA2D_RB_REGULAR;
01949 
01950   hdma2d_discovery.Instance = DMA2D;
01951 
01952   /* DMA2D Initialization */
01953   if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK)
01954   {
01955     if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, LayerIndex) == HAL_OK)
01956     {
01957       if (HAL_DMA2D_Start(&hdma2d_discovery, ColorIndex, (uint32_t)pDst, xSize, ySize) == HAL_OK)
01958       {
01959         /* Polling For DMA transfer */
01960         HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 10);
01961       }
01962     }
01963   }
01964 }
01965 
01966 /**
01967   * @brief  Converts a line to an ARGB8888 pixel format.
01968   * @param  pSrc: Pointer to source buffer
01969   * @param  pDst: Output color
01970   * @param  xSize: Buffer width
01971   * @param  ColorMode: Input color mode
01972   */
01973 static void LL_ConvertLineToARGB8888(void *pSrc, void *pDst, uint32_t xSize, uint32_t ColorMode)
01974 {
01975   /* Configure the DMA2D Mode, Color Mode and output offset */
01976   hdma2d_discovery.Init.Mode           = DMA2D_M2M_PFC;
01977   hdma2d_discovery.Init.ColorMode      = DMA2D_OUTPUT_ARGB8888;
01978   hdma2d_discovery.Init.OutputOffset   = 0;
01979   hdma2d_discovery.Init.LineOffsetMode = DMA2D_LOM_PIXELS;
01980   hdma2d_discovery.Init.BytesSwap      = DMA2D_BYTES_REGULAR;
01981   hdma2d_discovery.Init.AlphaInverted  = DMA2D_REGULAR_ALPHA;
01982   hdma2d_discovery.Init.RedBlueSwap    = DMA2D_RB_REGULAR;
01983 
01984   /* Foreground Configuration */
01985   hdma2d_discovery.LayerCfg[1].AlphaMode      = DMA2D_NO_MODIF_ALPHA;
01986   hdma2d_discovery.LayerCfg[1].InputAlpha     = 0xFF;
01987   hdma2d_discovery.LayerCfg[1].InputColorMode = ColorMode;
01988   hdma2d_discovery.LayerCfg[1].InputOffset    = 0;
01989   hdma2d_discovery.LayerCfg[1].AlphaInverted  = DMA2D_REGULAR_ALPHA;
01990   hdma2d_discovery.LayerCfg[1].RedBlueSwap    = DMA2D_RB_REGULAR;
01991 
01992   hdma2d_discovery.Instance = DMA2D;
01993 
01994   /* DMA2D Initialization */
01995   if(HAL_DMA2D_Init(&hdma2d_discovery) == HAL_OK)
01996   {
01997     if(HAL_DMA2D_ConfigLayer(&hdma2d_discovery, 1) == HAL_OK)
01998     {
01999       if (HAL_DMA2D_Start(&hdma2d_discovery, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK)
02000       {
02001         /* Polling For DMA transfer */
02002         HAL_DMA2D_PollForTransfer(&hdma2d_discovery, 10);
02003       }
02004     }
02005   }
02006 }
02007 
02008 /**
02009   * @}
02010   */
02011 
02012 /**
02013   * @}
02014   */
02015 
02016 /**
02017   * @}
02018   */
02019 
02020 /**
02021   * @}
02022   */
02023 
02024 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Oct 13 2017 02:37:42 for STM32L4R9I-Discovery BSP User Manual by   doxygen 1.7.6.1