BSP_DISCO_L4R9I

Dependents:   DISCO_L4R9I-LCD-demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4r9i_discovery_lcd.c Source File

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