Files
inav/lib/main/STM32H7/Drivers/BSP/STM32H7B3I-DK/stm32h7b3i_discovery_lcd.c
T
admin dac37fd077
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Sync inav to Gitea
2026-08-03 16:37:40 +08:00

1595 lines
45 KiB
C

/**
******************************************************************************
* @file stm32h7b3i_discovery_lcd.c
* @author MCD Application Team
* @brief This file includes the driver for Liquid Crystal Display (LCD) module
* mounted on STM32H7B3I_DK board.
******************************************************************************
@verbatim
How To use this driver:
--------------------------
- This driver is used to drive directly a LCD TFT using the LTDC controller.
- This driver uses the adequate timing and setting for the RK043FN48H LCD component
Driver description:
---------------------
+ Initialization steps:
o Initialize the LCD in default mode using the BSP_LCD_Init() function with the
following settings:
- Pixelformat : LCD_PIXEL_FORMAT_RGB888
- Orientation : LCD_ORIENTATION_LANDSCAPE.
- Width : LCD_DEFAULT_WIDTH (480)
- Height : LCD_DEFAULT_HEIGHT(272)
The default LTDC layer configured is layer 0.
BSP_LCD_Init() includes LTDC, LTDC Layer and clock configurations by calling:
- MX_LTDC_ClockConfig()
- MX_LTDC_Init()
- MX_LTDC_ConfigLayer()
o Initialize the LCD with required parameters using the BSP_LCD_InitEx() function.
o Select the LCD layer to be activated using the BSP_LCD_SetActiveLayer() function.
o Enable the LCD display using the BSP_LCD_DisplayOn() function.
o Disable the LCD display using the BSP_LCD_DisplayOff() function.
o Set the display brightness using the BSP_LCD_SetBrightness() function. Not that
by default the brightness is set to 50%
o Get the display brightness using the BSP_LCD_GetBrightness() function.
o Write a pixel to the LCD memory using the BSP_LCD_WritePixel() function.
o Read a pixel from the LCD memory using the BSP_LCD_ReadPixel() function.
o Draw an horizontal line using the BSP_LCD_DrawHLine() function.
o Draw a vertical line using the BSP_LCD_DrawVLine() function.
o Draw a bitmap image using the BSP_LCD_DrawBitmap() function.
+ Options
o Configure the LTDC reload mode by calling BSP_LCD_Relaod(). By default, the
reload mode is set to BSP_LCD_RELOAD_IMMEDIATE then LTDC is reloaded immediately.
To control the reload mode:
- Call BSP_LCD_Relaod() with ReloadType parameter set to BSP_LCD_RELOAD_NONE
- Configure LTDC (color keying, transparency ..)
- Call BSP_LCD_Relaod() with ReloadType parameter set to BSP_LCD_RELOAD_IMMEDIATE
for immediate reload or BSP_LCD_RELOAD_VERTICAL_BLANKING for LTDC reload
in the next vertical blanking
o Configure LTDC layers using BSP_LCD_ConfigLayer()
o Control layer visibility using BSP_LCD_SetLayerVisible()
o Configure and enable the color keying functionality using the
BSP_LCD_SetColorKeying() function.
o Disable the color keying functionality using the BSP_LCD_ResetColorKeying() function.
o Modify on the fly the transparency and/or the frame buffer address
using the following functions:
- BSP_LCD_SetTransparency()
- BSP_LCD_SetLayerAddress()
+ Display on LCD
o To draw and fill a basic shapes (dot, line, rectangle, circle, ellipse, .. bitmap)
on LCD and display text, utility basic_gui.c/.h must be called. Once the LCD is initialized,
user should call GUI_SetFuncDriver() API to link board LCD drivers to BASIC GUI LCD drivers.
The basic gui services, defined in basic_gui utility, are ready for use.
Note:
--------
Regarding the "Instance" parameter, needed for all functions, it is used to select
an LCD instance. On the STM32H7B3I-DK board, there's one instance. Then, this
parameter should be 0.
@endverbatim
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32h7b3i_discovery_lcd.h"
#include "stm32h7b3i_discovery_bus.h"
#include "stm32h7b3i_discovery_ts.h"
#include "stm32h7b3i_discovery_sdram.h"
/** @addtogroup BSP
* @{
*/
/** @addtogroup STM32H7B3I_DK
* @{
*/
/** @defgroup STM32H7B3I_DK_LCD LCD
* @{
*/
/** @defgroup STM32H7B3I_DK_LCD_Private_Variables Private Variables
* @{
*/
/* Timer handler declaration */
static TIM_HandleTypeDef hlcd_tim;
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Private_TypesDefinitions Private TypesDefinitions
* @{
*/
const LCD_UTILS_Drv_t LCD_Driver =
{
BSP_LCD_DrawBitmap,
BSP_LCD_FillRGBRect,
BSP_LCD_DrawHLine,
BSP_LCD_DrawVLine,
BSP_LCD_FillRect,
BSP_LCD_ReadPixel,
BSP_LCD_WritePixel,
BSP_LCD_GetXSize,
BSP_LCD_GetYSize,
BSP_LCD_SetActiveLayer,
BSP_LCD_GetPixelFormat
};
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Exported_Variables Exported Variables
* @{
*/
DMA2D_HandleTypeDef hlcd_dma2d;
LTDC_HandleTypeDef hlcd_ltdc;
BSP_LCD_Ctx_t Lcd_Ctx[LCD_INSTANCES_NBR];
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Private_FunctionPrototypes Private Functions Prototypes
* @{
*/
static void LTDC_MspInit(LTDC_HandleTypeDef *hltdc);
static void LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc);
static void DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d);
static void DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d);
static void LL_FillBuffer(uint32_t Instance, uint32_t *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine,
uint32_t Color);
static void LL_ConvertLineToRGB(uint32_t Instance, uint32_t *pSrc, uint32_t *pDst, uint32_t xSize, uint32_t ColorMode);
static void TIMx_PWM_MspInit(TIM_HandleTypeDef *htim);
static void TIMx_PWM_MspDeInit(TIM_HandleTypeDef *htim);
static void TIMx_PWM_DeInit(TIM_HandleTypeDef *htim);
static void TIMx_PWM_Init(TIM_HandleTypeDef *htim);
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Private_Macros Private Macros
* @{
*/
#define CONVERTRGB5652ARGB8888(Color)((((((((Color) >> (11U)) & 0x1FU) * 527U) + 23U) >> (6U)) << (16U)) |\
(((((((Color) >> (5U)) & 0x3FU) * 259U) + 33U) >> (6U)) << (8U)) |\
(((((Color) & 0x1FU) * 527U) + 23U) >> (6U)) | (0xFF000000U))
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Exported_Functions Exported Functions
* @{
*/
/**
* @brief Initializes the LCD in default mode.
* @param Instance LCD Instance
* @param Orientation LCD_ORIENTATION_LANDSCAPE
* @retval BSP status
*/
int32_t BSP_LCD_Init(uint32_t Instance, uint32_t Orientation)
{
return BSP_LCD_InitEx(Instance, Orientation, LCD_PIXEL_FORMAT_RGB888, LCD_DEFAULT_WIDTH, LCD_DEFAULT_HEIGHT);
}
/**
* @brief Initializes the LCD.
* @param Instance LCD Instance
* @param Orientation LCD_ORIENTATION_LANDSCAPE
* @param PixelFormat LCD_PIXEL_FORMAT_RGB565 or LCD_PIXEL_FORMAT_RGB888
* @param Width Display width
* @param Height Display height
* @retval BSP status
*/
int32_t BSP_LCD_InitEx(uint32_t Instance, uint32_t Orientation, uint32_t PixelFormat, uint32_t Width, uint32_t Height)
{
int32_t ret = BSP_ERROR_NONE;
uint32_t ltdc_pixel_format;
uint32_t ft5336_id = 0;
FT5336_Object_t ts_comp_obj;
FT5336_IO_t io_comp_ctx;
MX_LTDC_LayerConfig_t config;
if ((Orientation > LCD_ORIENTATION_LANDSCAPE) || (Instance >= LCD_INSTANCES_NBR) || \
((PixelFormat != LCD_PIXEL_FORMAT_RGB565) && (PixelFormat != LTDC_PIXEL_FORMAT_RGB888)))
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (PixelFormat == LCD_PIXEL_FORMAT_RGB565)
{
ltdc_pixel_format = LTDC_PIXEL_FORMAT_RGB565;
Lcd_Ctx[Instance].BppFactor = 2U;
}
else /* LCD_PIXEL_FORMAT_RGB888 */
{
ltdc_pixel_format = LTDC_PIXEL_FORMAT_ARGB8888;
Lcd_Ctx[Instance].BppFactor = 4U;
}
/* Store pixel format, xsize and ysize information */
Lcd_Ctx[Instance].PixelFormat = PixelFormat;
Lcd_Ctx[Instance].XSize = Width;
Lcd_Ctx[Instance].YSize = Height;
/* Initializes peripherals instance value */
hlcd_ltdc.Instance = LTDC;
hlcd_dma2d.Instance = DMA2D;
/* MSP initialization */
#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
/* Register the LTDC MSP Callbacks */
if (Lcd_Ctx[Instance].IsMspCallbacksValid == 0U)
{
if (BSP_LCD_RegisterDefaultMspCallbacks(0) != BSP_ERROR_NONE)
{
return BSP_ERROR_PERIPH_FAILURE;
}
}
#else
LTDC_MspInit(&hlcd_ltdc);
#endif
/* De-assert display enable LCD_DISP_EN pin */
HAL_GPIO_WritePin(LCD_DISP_EN_GPIO_PORT, LCD_DISP_EN_PIN, GPIO_PIN_RESET);
/* Assert display enable LCD_DISP_CTRL pin */
HAL_GPIO_WritePin(LCD_DISP_CTRL_GPIO_PORT, LCD_DISP_CTRL_PIN, GPIO_PIN_SET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET);
DMA2D_MspInit(&hlcd_dma2d);
io_comp_ctx.Init = BSP_I2C4_Init;
io_comp_ctx.ReadReg = BSP_I2C4_ReadReg;
io_comp_ctx.Address = TS_I2C_ADDRESS;
if (FT5336_RegisterBusIO(&ts_comp_obj, &io_comp_ctx) < 0)
{
ret = BSP_ERROR_COMPONENT_FAILURE;
}
else if (FT5336_ReadID(&ts_comp_obj, &ft5336_id) < 0)
{
ret = BSP_ERROR_COMPONENT_FAILURE;
}
else if (ft5336_id != FT5336_ID)
{
ret = BSP_ERROR_UNKNOWN_COMPONENT;
}
else if (MX_LTDC_ClockConfig(&hlcd_ltdc) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
if (MX_LTDC_Init(&hlcd_ltdc, Width, Height) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
}
if (ret == BSP_ERROR_NONE)
{
/* Before configuring LTDC layer, ensure SDRAM is initialized */
#if !defined(DATA_IN_ExtSDRAM)
/* Initialize the SDRAM */
if (BSP_SDRAM_Init(0) != BSP_ERROR_NONE)
{
return BSP_ERROR_PERIPH_FAILURE;
}
#endif /* DATA_IN_ExtSDRAM */
/* Configure default LTDC Layer 0. This configuration can be override by calling
BSP_LCD_ConfigLayer() at application level */
config.X0 = 0;
config.X1 = Width;
config.Y0 = 0;
config.Y1 = Height;
config.PixelFormat = ltdc_pixel_format;
config.Address = LCD_LAYER_0_ADDRESS;
if (MX_LTDC_ConfigLayer(&hlcd_ltdc, 0, &config) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
/* Initialize TIM in PWM mode to control brightness */
TIMx_PWM_Init(&hlcd_tim);
/* By default the reload is activated and executed immediately */
Lcd_Ctx[Instance].ReloadEnable = 1U;
}
}
return ret;
}
/**
* @brief De-Initializes the LCD resources.
* @param Instance LCD Instance
* @retval BSP status
*/
int32_t BSP_LCD_DeInit(uint32_t Instance)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
/* Assert display enable LCD_DISP pin */
HAL_GPIO_WritePin(LCD_DISP_CTRL_GPIO_PORT, LCD_DISP_CTRL_PIN, GPIO_PIN_RESET);
/* Assert backlight LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_RESET);
#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 0)
LTDC_MspDeInit(&hlcd_ltdc);
#endif /* (USE_HAL_LTDC_REGISTER_CALLBACKS == 0) */
DMA2D_MspDeInit(&hlcd_dma2d);
(void)HAL_LTDC_DeInit(&hlcd_ltdc);
if (HAL_DMA2D_DeInit(&hlcd_dma2d) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
/* DeInit TIM PWM */
TIMx_PWM_DeInit(&hlcd_tim);
Lcd_Ctx[Instance].IsMspCallbacksValid = 0;
}
}
return ret;
}
/**
* @brief Initializes the LTDC.
* @param hltdc LTDC handle
* @param Width LTDC width
* @param Height LTDC height
* @retval HAL status
*/
__weak HAL_StatusTypeDef MX_LTDC_Init(LTDC_HandleTypeDef *hltdc, uint32_t Width, uint32_t Height)
{
hltdc->Instance = LTDC;
hltdc->Init.HSPolarity = LTDC_HSPOLARITY_AL;
hltdc->Init.VSPolarity = LTDC_VSPOLARITY_AL;
hltdc->Init.DEPolarity = LTDC_DEPOLARITY_AL;
hltdc->Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hltdc->Init.HorizontalSync = RK043FN48H_HSYNC - 1U;
hltdc->Init.AccumulatedHBP = (RK043FN48H_HSYNC + (RK043FN48H_HBP - 11U) - 1U);
hltdc->Init.AccumulatedActiveW = RK043FN48H_HSYNC + Width + RK043FN48H_HBP - 1U;
hltdc->Init.TotalWidth = RK043FN48H_HSYNC + Width + (RK043FN48H_HBP - 11U) + RK043FN48H_HFP - 1U;
hltdc->Init.VerticalSync = RK043FN48H_VSYNC - 1U;
hltdc->Init.AccumulatedVBP = RK043FN48H_VSYNC + RK043FN48H_VBP - 1U;
hltdc->Init.AccumulatedActiveH = RK043FN48H_VSYNC + Height + RK043FN48H_VBP - 1U;
hltdc->Init.TotalHeigh = RK043FN48H_VSYNC + Height + RK043FN48H_VBP + RK043FN48H_VFP - 1U;
hltdc->Init.Backcolor.Blue = 0xFF;
hltdc->Init.Backcolor.Green = 0xFF;
hltdc->Init.Backcolor.Red = 0xFF;
return HAL_LTDC_Init(hltdc);
}
/**
* @brief MX LTDC layer configuration.
* @param hltdc LTDC handle
* @param LayerIndex Layer 0 or 1
* @param Config Layer configuration
* @retval HAL status
*/
__weak HAL_StatusTypeDef MX_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, uint32_t LayerIndex,
MX_LTDC_LayerConfig_t *Config)
{
LTDC_LayerCfgTypeDef pLayerCfg;
pLayerCfg.WindowX0 = Config->X0;
pLayerCfg.WindowX1 = Config->X1;
pLayerCfg.WindowY0 = Config->Y0;
pLayerCfg.WindowY1 = Config->Y1;
pLayerCfg.PixelFormat = Config->PixelFormat;
pLayerCfg.Alpha = 255;
pLayerCfg.Alpha0 = 0;
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
pLayerCfg.FBStartAdress = Config->Address;
pLayerCfg.ImageWidth = (Config->X1 - Config->X0);
pLayerCfg.ImageHeight = (Config->Y1 - Config->Y0);
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
return HAL_LTDC_ConfigLayer(hltdc, &pLayerCfg, LayerIndex);
}
/**
* @brief LTDC Clock Config for LCD DPI display.
* @param hltdc LTDC Handle
* Being __weak it can be overwritten by the application
* @retval HAL_status
*/
__weak HAL_StatusTypeDef MX_LTDC_ClockConfig(LTDC_HandleTypeDef *hltdc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hltdc);
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
/* RK043FN48H LCD clock configuration */
/* LCD clock configuration */
/* PLL3_VCO Input = HSE_VALUE/PLL3M = 4 Mhz */
/* PLL3_VCO Output = PLL3_VCO Input * PLL3N = 800 Mhz */
/* PLLLCDCLK = PLL3_VCO Output/PLL3R = 800/83 = 9.63 Mhz */
/* LTDC clock frequency = PLLLCDCLK = 9.63 Mhz */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLL3.PLL3M = 6;
PeriphClkInitStruct.PLL3.PLL3N = 200;
PeriphClkInitStruct.PLL3.PLL3P = 10;
PeriphClkInitStruct.PLL3.PLL3Q = 10;
PeriphClkInitStruct.PLL3.PLL3R = 83;
PeriphClkInitStruct.PLL3.PLL3VCOSEL = 0;
PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
return HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
}
#if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
/**
* @brief Default BSP LCD Msp Callbacks
* @param Instance BSP LCD Instance
* @retval BSP status
*/
int32_t BSP_LCD_RegisterDefaultMspCallbacks(uint32_t Instance)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPINIT_CB_ID, LTDC_MspInit) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPDEINIT_CB_ID, LTDC_MspDeInit) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
}
Lcd_Ctx[Instance].IsMspCallbacksValid = 1;
}
return ret;
}
/**
* @brief BSP LCD Msp Callback registering
* @param Instance LCD Instance
* @param CallBacks pointer to LCD MspInit/MspDeInit functions
* @retval BSP status
*/
int32_t BSP_LCD_RegisterMspCallbacks(uint32_t Instance, BSP_LCD_Cb_t *CallBacks)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPINIT_CB_ID, CallBacks->pMspLtdcInitCb) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
if (HAL_LTDC_RegisterCallback(&hlcd_ltdc, HAL_LTDC_MSPDEINIT_CB_ID, CallBacks->pMspLtdcDeInitCb) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
}
Lcd_Ctx[Instance].IsMspCallbacksValid = 1;
}
return ret;
}
#endif /*(USE_HAL_LTDC_REGISTER_CALLBACKS == 1) */
/**
* @brief LTDC layer configuration.
* @param Instance LCD instance
* @param LayerIndex Layer 0 or 1
* @param Config Layer configuration
* @retval HAL status
*/
int32_t BSP_LCD_ConfigLayer(uint32_t Instance, uint32_t LayerIndex, BSP_LCD_LayerConfig_t *Config)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (MX_LTDC_ConfigLayer(&hlcd_ltdc, LayerIndex, Config) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
}
return ret;
}
/**
* @brief Gets the LCD Active LCD Pixel Format.
* @param Instance LCD Instance
* @param PixelFormat Active LCD Pixel Format
* @retval BSP status
*/
int32_t BSP_LCD_GetPixelFormat(uint32_t Instance, uint32_t *PixelFormat)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
/* Only RGB565 format is supported */
*PixelFormat = Lcd_Ctx[Instance].PixelFormat;
}
return ret;
}
/**
* @brief Set the LCD Active Layer.
* @param Instance LCD Instance
* @param LayerIndex LCD layer index
* @retval BSP status
*/
int32_t BSP_LCD_SetActiveLayer(uint32_t Instance, uint32_t LayerIndex)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
Lcd_Ctx[Instance].ActiveLayer = LayerIndex;
}
return ret;
}
/**
* @brief Control the LTDC reload
* @param Instance LCD Instance
* @param ReloadType can be one of the following values
* - BSP_LCD_RELOAD_NONE
* - BSP_LCD_RELOAD_IMMEDIATE
* - BSP_LCD_RELOAD_VERTICAL_BLANKING
* @retval BSP status
*/
int32_t BSP_LCD_Relaod(uint32_t Instance, uint32_t ReloadType)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else if (ReloadType == BSP_LCD_RELOAD_NONE)
{
Lcd_Ctx[Instance].ReloadEnable = 0U;
}
else if (HAL_LTDC_Reload(&hlcd_ltdc, ReloadType) != HAL_OK)
{
ret = BSP_ERROR_PERIPH_FAILURE;
}
else
{
Lcd_Ctx[Instance].ReloadEnable = 1U;
}
return ret;
}
/**
* @brief Sets an LCD Layer visible
* @param Instance LCD Instance
* @param LayerIndex Visible Layer
* @param State New state of the specified layer
* This parameter can be one of the following values:
* @arg ENABLE
* @arg DISABLE
* @retval BSP status
*/
int32_t BSP_LCD_SetLayerVisible(uint32_t Instance, uint32_t LayerIndex, FunctionalState State)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (State == ENABLE)
{
__HAL_LTDC_LAYER_ENABLE(&hlcd_ltdc, LayerIndex);
}
else
{
__HAL_LTDC_LAYER_DISABLE(&hlcd_ltdc, LayerIndex);
}
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
__HAL_LTDC_RELOAD_IMMEDIATE_CONFIG(&hlcd_ltdc);
}
}
return ret;
}
/**
* @brief Configures the transparency.
* @param Instance LCD Instance
* @param LayerIndex Layer foreground or background.
* @param Transparency Transparency
* This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF
* @retval BSP status
*/
int32_t BSP_LCD_SetTransparency(uint32_t Instance, uint32_t LayerIndex, uint8_t Transparency)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
(void)HAL_LTDC_SetAlpha(&hlcd_ltdc, Transparency, LayerIndex);
}
else
{
(void)HAL_LTDC_SetAlpha_NoReload(&hlcd_ltdc, Transparency, LayerIndex);
}
}
return ret;
}
/**
* @brief Sets an LCD layer frame buffer address.
* @param Instance LCD Instance
* @param LayerIndex Layer foreground or background
* @param Address New LCD frame buffer value
* @retval BSP status
*/
int32_t BSP_LCD_SetLayerAddress(uint32_t Instance, uint32_t LayerIndex, uint32_t Address)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
(void)HAL_LTDC_SetAddress(&hlcd_ltdc, Address, LayerIndex);
}
else
{
(void)HAL_LTDC_SetAddress_NoReload(&hlcd_ltdc, Address, LayerIndex);
}
}
return ret;
}
/**
* @brief Sets display window.
* @param Instance LCD Instance
* @param LayerIndex Layer index
* @param Xpos LCD X position
* @param Ypos LCD Y position
* @param Width LCD window width
* @param Height LCD window height
* @retval BSP status
*/
int32_t BSP_LCD_SetLayerWindow(uint32_t Instance, uint16_t LayerIndex, uint16_t Xpos, uint16_t Ypos, uint16_t Width,
uint16_t Height)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
/* Reconfigure the layer size and position */
(void)HAL_LTDC_SetWindowSize(&hlcd_ltdc, Width, Height, LayerIndex);
(void)HAL_LTDC_SetWindowPosition(&hlcd_ltdc, Xpos, Ypos, LayerIndex);
}
else
{
/* Reconfigure the layer size and position */
(void)HAL_LTDC_SetWindowSize_NoReload(&hlcd_ltdc, Width, Height, LayerIndex);
(void)HAL_LTDC_SetWindowPosition_NoReload(&hlcd_ltdc, Xpos, Ypos, LayerIndex);
}
Lcd_Ctx[Instance].XSize = Width;
Lcd_Ctx[Instance].YSize = Height;
}
return ret;
}
/**
* @brief Configures and sets the color keying.
* @param Instance LCD Instance
* @param LayerIndex Layer foreground or background
* @param Color Color reference
* @retval BSP status
*/
int32_t BSP_LCD_SetColorKeying(uint32_t Instance, uint32_t LayerIndex, uint32_t Color)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
/* Configure and Enable the color Keying for LCD Layer */
(void)HAL_LTDC_ConfigColorKeying(&hlcd_ltdc, Color, LayerIndex);
(void)HAL_LTDC_EnableColorKeying(&hlcd_ltdc, LayerIndex);
}
else
{
/* Configure and Enable the color Keying for LCD Layer */
(void)HAL_LTDC_ConfigColorKeying_NoReload(&hlcd_ltdc, Color, LayerIndex);
(void)HAL_LTDC_EnableColorKeying_NoReload(&hlcd_ltdc, LayerIndex);
}
}
return ret;
}
/**
* @brief Disables the color keying.
* @param Instance LCD Instance
* @param LayerIndex Layer foreground or background
* @retval BSP status
*/
int32_t BSP_LCD_ResetColorKeying(uint32_t Instance, uint32_t LayerIndex)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
if (Lcd_Ctx[Instance].ReloadEnable == 1U)
{
/* Disable the color Keying for LCD Layer */
(void)HAL_LTDC_DisableColorKeying(&hlcd_ltdc, LayerIndex);
}
else
{
/* Disable the color Keying for LCD Layer */
(void)HAL_LTDC_DisableColorKeying_NoReload(&hlcd_ltdc, LayerIndex);
}
}
return ret;
}
/**
* @brief Gets the LCD X size.
* @param Instance LCD Instance
* @param XSize LCD width
* @retval BSP status
*/
int32_t BSP_LCD_GetXSize(uint32_t Instance, uint32_t *XSize)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
*XSize = Lcd_Ctx[Instance].XSize;
}
return ret;
}
/**
* @brief Gets the LCD Y size.
* @param Instance LCD Instance
* @param YSize LCD Height
* @retval BSP status
*/
int32_t BSP_LCD_GetYSize(uint32_t Instance, uint32_t *YSize)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
*YSize = Lcd_Ctx[Instance].YSize;
}
return ret;
}
/**
* @brief Switch On the display.
* @param Instance LCD Instance
* @retval BSP status
*/
int32_t BSP_LCD_DisplayOn(uint32_t Instance)
{
int32_t ret = BSP_ERROR_NONE;
GPIO_InitTypeDef gpio_init_structure;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
__HAL_LTDC_ENABLE(&hlcd_ltdc);
/* Assert LCD_DISP_EN pin */
HAL_GPIO_WritePin(LCD_DISP_CTRL_GPIO_PORT, LCD_DISP_CTRL_PIN, GPIO_PIN_SET);
/* Assert LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_SET);
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
gpio_init_structure.Alternate = LCD_TIMx_CHANNEL_AF;
gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */
HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure);
}
return ret;
}
/**
* @brief Switch Off the display.
* @param Instance LCD Instance
* @retval BSP status
*/
int32_t BSP_LCD_DisplayOff(uint32_t Instance)
{
int32_t ret = BSP_ERROR_NONE;
GPIO_InitTypeDef gpio_init_structure;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
__HAL_LTDC_DISABLE(&hlcd_ltdc);
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */
HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure);
/* Assert LCD_DISP_EN pin */
HAL_GPIO_WritePin(LCD_DISP_CTRL_GPIO_PORT, LCD_DISP_CTRL_PIN, GPIO_PIN_RESET);
/* Assert LCD_BL_CTRL pin */
HAL_GPIO_WritePin(LCD_BL_CTRL_GPIO_PORT, LCD_BL_CTRL_PIN, GPIO_PIN_RESET);
}
return ret;
}
/**
* @brief Set the brightness value
* @param Instance LCD Instance
* @param Brightness [00: Min (black), 100 Max]
* @retval BSP status
*/
int32_t BSP_LCD_SetBrightness(uint32_t Instance, uint32_t Brightness)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
__HAL_TIM_SET_COMPARE(&hlcd_tim, LCD_TIMx_CHANNEL, 2U * Brightness);
Lcd_Ctx[Instance].Brightness = Brightness;
}
return ret;
}
/**
* @brief Set the brightness value
* @param Instance LCD Instance
* @param Brightness [00: Min (black), 100 Max]
* @retval BSP status
*/
int32_t BSP_LCD_GetBrightness(uint32_t Instance, uint32_t *Brightness)
{
int32_t ret = BSP_ERROR_NONE;
if (Instance >= LCD_INSTANCES_NBR)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
*Brightness = Lcd_Ctx[Instance].Brightness;
}
return ret;
}
/**
* @brief Draws a bitmap picture loaded in the internal Flash in currently active layer.
* @param Instance LCD Instance
* @param Xpos Bmp X position in the LCD
* @param Ypos Bmp Y position in the LCD
* @param pBmp Pointer to Bmp picture address in the internal Flash.
* @retval BSP status
*/
int32_t BSP_LCD_DrawBitmap(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pBmp)
{
int32_t ret = BSP_ERROR_NONE;
uint32_t index, width, height, bit_pixel;
uint32_t Address;
uint32_t input_color_mode;
uint8_t *pbmp;
/* Get bitmap data address offset */
index = (uint32_t)pBmp[10] + ((uint32_t)pBmp[11] << 8) + ((uint32_t)pBmp[12] << 16) + ((uint32_t)pBmp[13] << 24);
/* Read bitmap width */
width = (uint32_t)pBmp[18] + ((uint32_t)pBmp[19] << 8) + ((uint32_t)pBmp[20] << 16) + ((uint32_t)pBmp[21] << 24);
/* Read bitmap height */
height = (uint32_t)pBmp[22] + ((uint32_t)pBmp[23] << 8) + ((uint32_t)pBmp[24] << 16) + ((uint32_t)pBmp[25] << 24);
/* Read bit/pixel */
bit_pixel = (uint32_t)pBmp[28] + ((uint32_t)pBmp[29] << 8);
/* Set the address */
Address = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (((Lcd_Ctx[Instance].XSize * Ypos) + Xpos) * Lcd_Ctx[Instance].BppFactor);
/* Get the layer pixel format */
if ((bit_pixel / 8U) == 4U)
{
input_color_mode = DMA2D_INPUT_ARGB8888;
}
else if ((bit_pixel / 8U) == 2U)
{
input_color_mode = DMA2D_INPUT_RGB565;
}
else
{
input_color_mode = DMA2D_INPUT_RGB888;
}
/* Bypass the bitmap header */
pbmp = pBmp + (index + (width * (height - 1U) * (bit_pixel / 8U)));
/* Convert picture to ARGB8888 pixel format */
for (index = 0; index < height; index++)
{
/* Pixel format conversion */
LL_ConvertLineToRGB(Instance, (uint32_t *)pbmp, (uint32_t *)Address, width, input_color_mode);
/* Increment the source and destination buffers */
Address += (Lcd_Ctx[Instance].XSize * Lcd_Ctx[Instance].BppFactor);
pbmp -= width * (bit_pixel / 8U);
}
return ret;
}
/**
* @brief Draw a horizontal line on LCD.
* @param Instance LCD Instance.
* @param Xpos X position.
* @param Ypos Y position.
* @param pData Pointer to RGB line data
* @param Width Rectangle width.
* @param Height Rectangle Height.
* @retval BSP status.
*/
int32_t BSP_LCD_FillRGBRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint8_t *pData, uint32_t Width,
uint32_t Height)
{
uint32_t i;
uint8_t *pdata = pData;
#if (USE_DMA2D_TO_FILL_RGB_RECT == 1)
uint32_t Xaddress;
for (i = 0; i < Height; i++)
{
/* Get the line address */
Xaddress = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (Lcd_Ctx[Instance].BppFactor * ((Lcd_Ctx[Instance].XSize * (Ypos + i)) + Xpos));
#if (USE_BSP_CPU_CACHE_MAINTENANCE == 1)
SCB_CleanDCache_by_Addr((uint32_t *)pdata, Lcd_Ctx[Instance].BppFactor * Lcd_Ctx[Instance].XSize);
#endif /* USE_BSP_CPU_CACHE_MAINTENANCE */
/* Write line */
if (Lcd_Ctx[Instance].PixelFormat == LCD_PIXEL_FORMAT_RGB565)
{
LL_ConvertLineToRGB(Instance, (uint32_t *)pdata, (uint32_t *)Xaddress, Width, DMA2D_INPUT_RGB565);
}
else
{
LL_ConvertLineToRGB(Instance, (uint32_t *)pdata, (uint32_t *)Xaddress, Width, DMA2D_INPUT_ARGB8888);
}
pdata += Lcd_Ctx[Instance].BppFactor * Width;
}
#else
uint32_t color, j;
for (i = 0; i < Height; i++)
{
for (j = 0; j < Width; j++)
{
color = (uint32_t)((uint32_t) * pdata | ((uint32_t)(*(pdata + 1U)) << 8U) | ((uint32_t)(*(pdata + 2U)) << 16U) | ((uint32_t)(*(pdata + 3U)) << 24U));
(void)BSP_LCD_WritePixel(Instance, Xpos + j, Ypos + i, color);
pdata += Lcd_Ctx[Instance].BppFactor;
}
}
#endif
return BSP_ERROR_NONE;
}
/**
* @brief Draws an horizontal line in currently active layer.
* @param Instance LCD Instance
* @param Xpos X position
* @param Ypos Y position
* @param Length Line length
* @param Color RGB color
* @retval BSP status
*/
int32_t BSP_LCD_DrawHLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
{
uint32_t Xaddress;
uint32_t tmp_length = Length;
/* Get the line address */
Xaddress = hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (Lcd_Ctx[Instance].BppFactor * ((Lcd_Ctx[Instance].XSize * Ypos) + Xpos));
/* Write line */
if ((Xpos + Length) > Lcd_Ctx[Instance].XSize)
{
tmp_length = Lcd_Ctx[Instance].XSize - Xpos;
}
LL_FillBuffer(Instance, (uint32_t *)Xaddress, tmp_length, 1, 0, Color);
return BSP_ERROR_NONE;
}
/**
* @brief Draws a vertical line in currently active layer.
* @param Instance LCD Instance
* @param Xpos X position
* @param Ypos Y position
* @param Length Line length
* @param Color RGB color
* @retval BSP status
*/
int32_t BSP_LCD_DrawVLine(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Length, uint32_t Color)
{
uint32_t Xaddress;
uint32_t tmp_length = Length;
/* Get the line address */
Xaddress = (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress) + (Lcd_Ctx[Instance].BppFactor * ((Lcd_Ctx[Instance].XSize * Ypos) + Xpos));
/* Write line */
if ((Ypos + Length) > Lcd_Ctx[Instance].YSize)
{
tmp_length = Lcd_Ctx[Instance].YSize - Ypos;
}
LL_FillBuffer(Instance, (uint32_t *)Xaddress, 1, tmp_length, (Lcd_Ctx[Instance].XSize - 1U), Color);
return BSP_ERROR_NONE;
}
/**
* @brief Draws a full rectangle in currently active layer.
* @param Instance LCD Instance
* @param Xpos X position
* @param Ypos Y position
* @param Width Rectangle width
* @param Height Rectangle height
* @param Color RGB color
* @retval BSP status
*/
int32_t BSP_LCD_FillRect(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Width, uint32_t Height,
uint32_t Color)
{
uint32_t Xaddress;
/* Get the rectangle start address */
Xaddress = (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress) + (Lcd_Ctx[Instance].BppFactor * ((Lcd_Ctx[Instance].XSize * Ypos) + Xpos));
/* Fill the rectangle */
LL_FillBuffer(Instance, (uint32_t *)Xaddress, Width, Height, (Lcd_Ctx[Instance].XSize - Width), Color);
return BSP_ERROR_NONE;
}
/**
* @brief Reads a LCD pixel.
* @param Instance LCD Instance
* @param Xpos X position
* @param Ypos Y position
* @param Color RGB pixel color
* @retval BSP status
*/
int32_t BSP_LCD_ReadPixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t *Color)
{
if (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
{
/* Read data value from SDRAM memory */
*Color = *(__IO uint32_t *)(hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (4U * ((Ypos * Lcd_Ctx[Instance].XSize) + Xpos)));
}
else /* if((hlcd_ltdc.LayerCfg[layer].PixelFormat == LTDC_PIXEL_FORMAT_RGB565) */
{
/* Read data value from SDRAM memory */
*Color = *(__IO uint16_t *)(hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (2U * ((Ypos * Lcd_Ctx[Instance].XSize) + Xpos)));
}
return BSP_ERROR_NONE;
}
/**
* @brief Draws a pixel on LCD.
* @param Instance LCD Instance
* @param Xpos X position
* @param Ypos Y position
* @param Color Pixel color
* @retval BSP status
*/
int32_t BSP_LCD_WritePixel(uint32_t Instance, uint32_t Xpos, uint32_t Ypos, uint32_t Color)
{
if (hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
{
/* Write data value to SDRAM memory */
*(__IO uint32_t *)(hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (4U * ((
Ypos * Lcd_Ctx[Instance].XSize) + Xpos))) = Color;
}
else
{
/* Write data value to SDRAM memory */
*(__IO uint16_t *)(hlcd_ltdc.LayerCfg[Lcd_Ctx[Instance].ActiveLayer].FBStartAdress + (2U * ((
Ypos * Lcd_Ctx[Instance].XSize) + Xpos))) = (uint16_t)Color;
}
return BSP_ERROR_NONE;
}
/**
* @}
*/
/** @defgroup STM32H7B3I_DK_LCD_Private_Functions Private Functions
* @{
*/
/**
* @brief Fills a buffer.
* @param Instance LCD Instance
* @param pDst Pointer to destination buffer
* @param xSize Buffer width
* @param ySize Buffer height
* @param OffLine Offset
* @param Color Color index
*/
static void LL_FillBuffer(uint32_t Instance, uint32_t *pDst, uint32_t xSize, uint32_t ySize, uint32_t OffLine,
uint32_t Color)
{
uint32_t output_color_mode, input_color = Color;
switch (Lcd_Ctx[Instance].PixelFormat)
{
case LCD_PIXEL_FORMAT_RGB565:
output_color_mode = DMA2D_OUTPUT_RGB565; /* RGB565 */
input_color = CONVERTRGB5652ARGB8888(Color);
break;
case LCD_PIXEL_FORMAT_RGB888:
default:
output_color_mode = DMA2D_OUTPUT_ARGB8888; /* ARGB8888 */
break;
}
/* Register to memory mode with ARGB8888 as color Mode */
hlcd_dma2d.Init.Mode = DMA2D_R2M;
hlcd_dma2d.Init.ColorMode = output_color_mode;
hlcd_dma2d.Init.OutputOffset = OffLine;
hlcd_dma2d.Instance = DMA2D;
/* DMA2D Initialization */
if (HAL_DMA2D_Init(&hlcd_dma2d) == HAL_OK)
{
if (HAL_DMA2D_Start(&hlcd_dma2d, input_color, (uint32_t)pDst, xSize, ySize) == HAL_OK)
{
/* Polling For DMA transfer */
(void)HAL_DMA2D_PollForTransfer(&hlcd_dma2d, 50);
}
}
}
/**
* @brief Converts a line to an RGB pixel format.
* @param Instance LCD Instance
* @param pSrc Pointer to source buffer
* @param pDst Output color
* @param xSize Buffer width
* @param ColorMode Input color mode
*/
static void LL_ConvertLineToRGB(uint32_t Instance, uint32_t *pSrc, uint32_t *pDst, uint32_t xSize, uint32_t ColorMode)
{
uint32_t output_color_mode;
switch (Lcd_Ctx[Instance].PixelFormat)
{
case LCD_PIXEL_FORMAT_RGB565:
output_color_mode = DMA2D_OUTPUT_RGB565; /* RGB565 */
break;
case LCD_PIXEL_FORMAT_RGB888:
default:
output_color_mode = DMA2D_OUTPUT_ARGB8888; /* ARGB8888 */
break;
}
/* Configure the DMA2D Mode, Color Mode and output offset */
hlcd_dma2d.Init.Mode = DMA2D_M2M_PFC;
hlcd_dma2d.Init.ColorMode = output_color_mode;
hlcd_dma2d.Init.OutputOffset = 0;
/* Foreground Configuration */
hlcd_dma2d.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
hlcd_dma2d.LayerCfg[1].InputAlpha = 0xFF;
hlcd_dma2d.LayerCfg[1].InputColorMode = ColorMode;
hlcd_dma2d.LayerCfg[1].InputOffset = 0;
hlcd_dma2d.Instance = DMA2D;
/* DMA2D Initialization */
if (HAL_DMA2D_Init(&hlcd_dma2d) == HAL_OK)
{
if (HAL_DMA2D_ConfigLayer(&hlcd_dma2d, 1) == HAL_OK)
{
if (HAL_DMA2D_Start(&hlcd_dma2d, (uint32_t)pSrc, (uint32_t)pDst, xSize, 1) == HAL_OK)
{
/* Polling For DMA transfer */
(void)HAL_DMA2D_PollForTransfer(&hlcd_dma2d, 50);
}
}
}
}
/*******************************************************************************
BSP Routines:
LTDC
DMA2D
*******************************************************************************/
/**
* @brief Initialize the BSP LTDC Msp.
* @param hltdc LTDC handle
* @retval None
*/
static void LTDC_MspInit(LTDC_HandleTypeDef *hltdc)
{
GPIO_InitTypeDef gpio_init_structure;
if (hltdc->Instance == LTDC)
{
/** Enable the LTDC clock */
__HAL_RCC_LTDC_CLK_ENABLE();
/* Enable GPIOs clock */
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOJ_CLK_ENABLE();
__HAL_RCC_GPIOK_CLK_ENABLE();
/*** LTDC Pins configuration ***/
/* GPIOI configuration */
gpio_init_structure.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
gpio_init_structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOI, &gpio_init_structure);
/* GPIOJ configuration */
gpio_init_structure.Pin = GPIO_PIN_All;
gpio_init_structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOJ, &gpio_init_structure);
/* GPIOK configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
gpio_init_structure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOK, &gpio_init_structure);
/** Toggle Sw reset of LTDC IP */
__HAL_RCC_LTDC_FORCE_RESET();
__HAL_RCC_LTDC_RELEASE_RESET();
}
LCD_DISP_CTRL_GPIO_CLK_ENABLE();
LCD_BL_CTRL_GPIO_CLK_ENABLE();
LCD_DISP_EN_GPIO_CLK_ENABLE();
/* LCD_DISP_EN GPIO configuration */
gpio_init_structure.Pin = LCD_DISP_EN_PIN; /* LCD_DISP pin has to be manually controlled */
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(LCD_DISP_EN_GPIO_PORT, &gpio_init_structure);
/* LCD_DISP_CTRL GPIO configuration */
gpio_init_structure.Pin = LCD_DISP_CTRL_PIN; /* LCD_DISP pin has to be manually controlled */
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(LCD_DISP_CTRL_GPIO_PORT, &gpio_init_structure);
/* LCD_BL_CTRL GPIO configuration */
gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* LCD_BL_CTRL pin has to be manually controlled */
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure);
HAL_Delay(30);
}
/**
* @brief De-Initializes the BSP LTDC Msp
* @param hltdc LTDC handle
* @retval None
*/
static void LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc)
{
GPIO_InitTypeDef gpio_init_structure;
if (hltdc->Instance == LTDC)
{
/* LTDC Pins deactivation */
/* GPIOI deactivation */
gpio_init_structure.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_DeInit(GPIOI, gpio_init_structure.Pin);
/* GPIOJ deactivation */
gpio_init_structure.Pin = GPIO_PIN_All;
HAL_GPIO_DeInit(GPIOJ, gpio_init_structure.Pin);
/* GPIOK deactivation */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | \
GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_DeInit(GPIOK, gpio_init_structure.Pin);
/** Force and let in reset state LTDC */
__HAL_RCC_LTDC_FORCE_RESET();
/** Disable the LTDC */
__HAL_RCC_LTDC_CLK_DISABLE();
}
}
/**
* @brief Initialize the BSP DMA2D Msp.
* @param hdma2d DMA2D handle
* @retval None
*/
static void DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d)
{
if (hdma2d->Instance == DMA2D)
{
/** Enable the DMA2D clock */
__HAL_RCC_DMA2D_CLK_ENABLE();
/** Toggle Sw reset of DMA2D IP */
__HAL_RCC_DMA2D_FORCE_RESET();
__HAL_RCC_DMA2D_RELEASE_RESET();
}
}
/**
* @brief De-Initializes the BSP DMA2D Msp
* @param hdma2d DMA2D handle
* @retval None
*/
static void DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d)
{
if (hdma2d->Instance == DMA2D)
{
/** Disable IRQ of DMA2D IP */
HAL_NVIC_DisableIRQ(DMA2D_IRQn);
/** Force and let in reset state DMA2D */
__HAL_RCC_DMA2D_FORCE_RESET();
/** Disable the DMA2D */
__HAL_RCC_DMA2D_CLK_DISABLE();
}
}
/**
* @brief Initializes TIM MSP.
* @param htim TIM handle
* @retval None
*/
static void TIMx_PWM_MspInit(TIM_HandleTypeDef *htim)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(htim);
GPIO_InitTypeDef gpio_init_structure;
LCD_BL_CTRL_GPIO_CLK_ENABLE();
/* TIMx Peripheral clock enable */
LCD_TIMx_CLK_ENABLE();
/* Timer channel configuration */
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_NOPULL;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
gpio_init_structure.Alternate = LCD_TIMx_CHANNEL_AF;
gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */
HAL_GPIO_Init(LCD_BL_CTRL_GPIO_PORT, &gpio_init_structure);
}
/**
* @brief De-Initializes TIM MSP.
* @param htim TIM handle
* @retval None
*/
static void TIMx_PWM_MspDeInit(TIM_HandleTypeDef *htim)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(htim);
GPIO_InitTypeDef gpio_init_structure;
/* TIMx Peripheral clock enable */
LCD_BL_CTRL_GPIO_CLK_DISABLE();
/* Timer channel configuration */
gpio_init_structure.Pin = LCD_BL_CTRL_PIN; /* BL_CTRL */
HAL_GPIO_DeInit(LCD_BL_CTRL_GPIO_PORT, gpio_init_structure.Pin);
}
/**
* @brief Initializes TIM in PWM mode
* @param htim TIM handle
* @retval None
*/
static void TIMx_PWM_Init(TIM_HandleTypeDef *htim)
{
TIM_OC_InitTypeDef LCD_TIM_Config;
/* Timer_Clock = 2 x APB1_clock = 280 MHz */
/* PWM_freq = Timer_Clock /(Period x (Prescaler + 1))*/
/* PWM_freq = 280 MHz /(200 x (27 + 1)) = 50000 Hz*/
htim->Instance = LCD_TIMx;
(void)HAL_TIM_PWM_DeInit(htim);
TIMx_PWM_MspInit(htim);
htim->Init.Prescaler = LCD_TIMX_PRESCALER_VALUE;
htim->Init.Period = LCD_TIMX_PERIOD_VALUE - 1U;
htim->Init.ClockDivision = 0;
htim->Init.CounterMode = TIM_COUNTERMODE_UP;
htim->Init.RepetitionCounter = 0;
htim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
(void)HAL_TIM_PWM_Init(htim);
/* Common configuration for all channels */
LCD_TIM_Config.OCMode = TIM_OCMODE_PWM1;
LCD_TIM_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
LCD_TIM_Config.OCFastMode = TIM_OCFAST_DISABLE;
LCD_TIM_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
LCD_TIM_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
LCD_TIM_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
/* Set the default pulse value for channel: 50% duty cycle */
LCD_TIM_Config.Pulse = 100;
(void)HAL_TIM_PWM_ConfigChannel(&hlcd_tim, &LCD_TIM_Config, LCD_TIMx_CHANNEL);
/* Start PWM Timer channel */
(void)HAL_TIM_PWM_Start(&hlcd_tim, LCD_TIMx_CHANNEL);
}
/**
* @brief De-Initializes TIM in PWM mode
* @param htim TIM handle
* @retval None
*/
static void TIMx_PWM_DeInit(TIM_HandleTypeDef *htim)
{
htim->Instance = LCD_TIMx;
/* Timer de-intialization */
(void)HAL_TIM_PWM_DeInit(htim);
/* Timer Msp de-intialization */
TIMx_PWM_MspDeInit(htim);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/