/** * @brief LCD Configuration. * @note This function Configure tha LTDC peripheral : * 1) Configure the Pixel Clock for the LCD * 2) Configure the LTDC Timing and Polarity * 3) Configure the LTDC Layer 1 : * - indirect color (L8) as pixel format * - The frame buffer is located at FLASH memory * - The Layer size configuration : 320x240 * 4) Configure the LTDC Layer 2 : * - The frame buffer is located at FLASH memory * - The Layer size configuration : 320x240 * 5) Load 256 colors in CLUT address for Layer 1 * @retval * None */ static void LCD_Config(void) { LTDC_InitTypeDef LTDC_InitStruct; LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct; LTDC_CLUT_InitTypeDef LTDC_CLUT_InitStruct; uint32_t uwCounter = 0; /* Enable Pixel Clock --------------------------------------------------------*/ /* Configure PLLSAI prescalers for LCD */ /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz */ /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/3 = 64 Mhz */ /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/8 = 8 Mhz */ RCC_PLLSAIConfig(192, 7, 3); RCC_LTDCCLKDivConfig(RCC_PLLSAIDivR_Div8); /* Enable PLLSAI Clock */ RCC_PLLSAICmd(ENABLE); /* Wait for PLLSAI activation */ while(RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET) { } /* Enable the LTDC Clock -----------------------------------------------------*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_LTDC, ENABLE); /* Configure the LCD Control pins --------------------------------------------*/ LCD_AF_GPIOConfig(); /* Sets LCD backlight and display On -----------------------------------------*/ GPIO_SetBits(GPIOA, GPIO_Pin_8); GPIO_SetBits(GPIOC, GPIO_Pin_6); /* Initialize the LCD --------------------------------------------------------*/ /* Polarity configuration */ /* Initialize the horizontal synchronization polarity as active low*/ LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL; /* Initialize the vertical synchronization polarity as active low */ LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL; /* Initialize the data enable polarity as active low */ LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL; /* Initialize the pixel clock polarity as input pixel clock */ LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC; /* Timing configuration */ /* Horizontal synchronization width = Hsync - 1 */ LTDC_InitStruct.LTDC_HorizontalSync = 40; /* Vertical synchronization height = Vsync - 1 */ LTDC_InitStruct.LTDC_VerticalSync = 9; /* Accumulated horizontal back porch = Hsync + HBP - 1 */ LTDC_InitStruct.LTDC_AccumulatedHBP = 42; /* Accumulated vertical back porch = Vsync + VBP - 1 */ LTDC_InitStruct.LTDC_AccumulatedVBP = 11; /* Accumulated active width = Hsync + HBP + Active Width - 1 */ LTDC_InitStruct.LTDC_AccumulatedActiveW = 522; /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */ LTDC_InitStruct.LTDC_AccumulatedActiveH = 283; /* Total width = Hsync + HBP + Active Width + HFP - 1 */ LTDC_InitStruct.LTDC_TotalWidth = 524; /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */ LTDC_InitStruct.LTDC_TotalHeigh = 285; /* Configure R,G,B component values for LCD background color */ LTDC_InitStruct.LTDC_BackgroundRedValue = 0; LTDC_InitStruct.LTDC_BackgroundGreenValue = 0; LTDC_InitStruct.LTDC_BackgroundBlueValue = 0; /* Initialize LTDC */ LTDC_Init(<DC_InitStruct); /* LCD initializing end ------------------------------------------------------*/ /* Layer1 Configuration ------------------------------------------------------*/ /* Windowing configuration */ /* In this case only 320x240 window of the active display area is used to display a picture then : Horizontal start = horizontal synchronization + Horizontal back porch = 43 Vertical start = vertical synchronization + vertical back porch = 12 Horizontal stop = Horizontal start + window width -1 = 43 + 320 -1 Vertical stop = Vertical start + window height -1 = 12 + 240 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = 43; LTDC_Layer_InitStruct.LTDC_HorizontalStop = (320 + 43 - 1); LTDC_Layer_InitStruct.LTDC_VerticalStart = 12; LTDC_Layer_InitStruct.LTDC_VerticalStop = (240 + 12 - 1); /* Pixel Format configuration : indirect color (L8) */ LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_L8; /* Alpha constant configuration */ LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255; /* Default Color configuration (configure A,R,G,B component values) */ LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0; /* Blending Factors */ LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA; LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA; /* Start Address configuration : frame buffer is located at FLASH memory */ LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)&L8_320x240; /* the length of one line of pixels in bytes + 3 then : Line Lenth = Active high width x number of bytes per pixel + 3 Active high width = 320 number of bytes per pixel = 1 (pixel_format : L8) */ LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((320 * 1) + 3); /* the pitch is the increment from the start of one line of pixels to the start of the next line in bytes, then : Pitch = Active high width x number of bytes per pixel */ LTDC_Layer_InitStruct.LTDC_CFBPitch = (320 * 1); /* Configure the number of lines */ LTDC_Layer_InitStruct.LTDC_CFBLineNumber = 240; /* Initialize the Layer1 */ LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct); /* Layer1 Configuration end --------------------------------------------------*/ /* Layer2 Configuration ------------------------------------------------------*/ /* Windowing configuration */ /* In this case only 320x240 window of the active display area is used to display a picture then : Horizontal start = horizontal synchronization + offset_x + Horizontal back porch = 43 Vertical start = vertical synchronization + offset_y + vertical back porch = 12 Horizontal stop = Horizontal start + offset_x + window width -1 = 43 + 320 -1 Vertical stop = Vertical start + offset_y + window height -1 = 12 + 240 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = 160 + 43; LTDC_Layer_InitStruct.LTDC_HorizontalStop = (320 + 160 + 43 - 1); LTDC_Layer_InitStruct.LTDC_VerticalStart = 32 + 12; LTDC_Layer_InitStruct.LTDC_VerticalStop = (32 + 240 + 12 - 1); /* Pixel Format configuration */ LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_RGB565; /* Alpha constant configuration : The constant alpha for layer 2 is decreased to see the layer 1 in the intersection zone*/ LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 200; /* Default Color configuration (configure A,R,G,B component values) */ LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0; /* blending Factors */ LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA; LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA; /* Configure Input Address : frame buffer is located at FLASH memory */ LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)&RGB565_320x240; /* the length of one line of pixels in bytes + 3 then : Line Lenth = Active high width x number of bytes per pixel + 3 Active high width = 320 number of bytes per pixel = 2 (pixel_format : RGB565) */ LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((320 * 2) + 3); LTDC_Layer_InitStruct.LTDC_CFBPitch = (320 * 2); /* the pitch is the increment from the start of one line of pixels to the start of the next line in bytes, then : Pitch = Active high width x number of bytes per pixel */ LTDC_Layer_InitStruct.LTDC_CFBLineNumber = 240; /* Initialize the Layer 2 */ LTDC_LayerInit(LTDC_Layer2, <DC_Layer_InitStruct); /* Layer2 Configuration end --------------------------------------------------*/ /* CLUT loading --------------------------------------------------------------*/ /* Load 256 colors in CLUT address for Layer 1 */ for(uwCounter = 0; (uwCounter < 256); uwCounter++) { LTDC_CLUT_InitStruct.LTDC_CLUTAdress = uwCounter; LTDC_CLUT_InitStruct.LTDC_BlueValue = (L8_320x240_CLUT[uwCounter] & 0xFF); LTDC_CLUT_InitStruct.LTDC_GreenValue = (L8_320x240_CLUT[uwCounter] & 0xFF00) >> 8; LTDC_CLUT_InitStruct.LTDC_RedValue = (L8_320x240_CLUT[uwCounter] & 0xFF0000) >> 16; LTDC_CLUTInit(LTDC_Layer1, <DC_CLUT_InitStruct); } /* CLUT loading end ----------------------------------------------------------*/ }
static void LCD_DithCLUTLayerInit(void) { uint32_t uwCounter; LTDC_CLUT_InitTypeDef LTDC_CLUT_InitStruct; LTDC_LayerCmd(LTDC_Layer1, DISABLE); /* Windowing configuration */ /* In this case all the active display area is used to display a picture then : Horizontal start = horizontal synchronization + Horizontal back porch = 30 Horizontal stop = Horizontal start + window width -1 = 30 + 240 -1 Vertical start = vertical synchronization + vertical back porch = 4 Vertical stop = Vertical start + window height -1 = 4 + 320 -1 */ LTDC_Layer_InitStruct.LTDC_HorizontalStart = 30; LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_PIXEL_WIDTH + 30 - 1); LTDC_Layer_InitStruct.LTDC_VerticalStart = 4; LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_PIXEL_HEIGHT + 4 - 1); /* Pixel Format configuration*/ LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_L8; /* Alpha constant (255 totally opaque) */ LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255; /* Default Color configuration (configure A,R,G,B component values) */ LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0; LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0; /* Configure blending factors */ LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA; LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA; /* the length of one line of pixels in bytes + 3 then : Line Lenth = Active width x number of bytes per pixel + 3 Active width = LCD_PIXEL_WIDTH number of bytes per pixel = 1 (pixel_format : L8) */ LTDC_Layer_InitStruct.LTDC_CFBLineLength = ((LCD_PIXEL_WIDTH * 1) + 3); /* the pitch is the increment from the start of one line of pixels to the start of the next line in bytes, then : Pitch = Active high width x number of bytes per pixel */ LTDC_Layer_InitStruct.LTDC_CFBPitch = (ImageDithCLUT_width * 1); /* Configure the number of lines */ LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_PIXEL_HEIGHT; /* Start Address configuration : the LCD Frame buffer is defined in Flash memory*/ LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t)ImageDithCLUT; /* Initialize LTDC layer 1 */ LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct); /* CLUT loading --------------------------------------------------------------*/ /* Load 256 colors in CLUT address for Layer 1 */ for(uwCounter = 0; (uwCounter < 256); uwCounter++) { LTDC_CLUT_InitStruct.LTDC_CLUTAdress = uwCounter; LTDC_CLUT_InitStruct.LTDC_BlueValue = (ImageDithCLUT_CLUT[uwCounter] & 0xFF); LTDC_CLUT_InitStruct.LTDC_GreenValue = (ImageDithCLUT_CLUT[uwCounter] & 0xFF00) >> 8; LTDC_CLUT_InitStruct.LTDC_RedValue = (ImageDithCLUT_CLUT[uwCounter] & 0xFF0000) >> 16; LTDC_CLUTInit(LTDC_Layer1, <DC_CLUT_InitStruct); } /* CLUT loading end ----------------------------------------------------------*/ /* Enable CLUT for Layer 1 */ LTDC_CLUTCmd(LTDC_Layer1, ENABLE); /* LTDC configuration reload */ LTDC_ReloadConfig(LTDC_SRCR_VBR); /* Enable backgrounf layers */ LTDC_LayerCmd(LTDC_Layer1, ENABLE); /* LTDC configuration reload */ LTDC_ReloadConfig(LTDC_SRCR_VBR); }