BSP_DISCO_L4R9I
Dependents: DISCO_L4R9I-LCD-demo
stm32l4r9i_discovery_lcd.c
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. 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****/
Generated on Wed Jul 13 2022 19:15:17 by 1.7.2