STM32L4R9I-Discovery BSP User Manual
|
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>© 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 1.7.6.1