1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_ltdc.c
4   * @author  MCD Application Team
5   * @brief   LTDC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the LTDC peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2023 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28      [..]
29      The LTDC HAL driver can be used as follows:
30 
31      (#) Declare a LTDC_HandleTypeDef handle structure, for example: LTDC_HandleTypeDef  hltdc;
32 
33      (#) Initialize the LTDC low level resources by implementing the HAL_LTDC_MspInit() API:
34          (##) Enable the LTDC interface clock
35          (##) NVIC configuration if you need to use interrupt process
36              (+++) Configure the LTDC interrupt priority
37              (+++) Enable the NVIC LTDC IRQ Channel
38 
39      (#) Initialize the required configuration through the following parameters:
40          the LTDC timing, the horizontal and vertical polarity, the pixel clock polarity,
41          Data Enable polarity and the LTDC background color value using HAL_LTDC_Init() function
42 
43      *** Configuration ***
44      =========================
45      [..]
46      (#) Program the required configuration through the following parameters:
47          the pixel format, the blending factors, input alpha value, the window size
48          and the image size using HAL_LTDC_ConfigLayer() function for foreground
49          or/and background layer.
50 
51      (#) Optionally, configure and enable the CLUT using HAL_LTDC_ConfigCLUT() and
52          HAL_LTDC_EnableCLUT functions.
53 
54      (#) Optionally, enable the Dither using HAL_LTDC_EnableDither().
55 
56      (#) Optionally, configure and enable the Color keying using HAL_LTDC_ConfigColorKeying()
57          and HAL_LTDC_EnableColorKeying functions.
58 
59      (#) Optionally, configure LineInterrupt using HAL_LTDC_ProgramLineEvent()
60          function
61 
62      (#) If needed, reconfigure and change the pixel format value, the alpha value
63          value, the window size, the window position and the layer start address
64          for foreground or/and background layer using respectively the following
65          functions: HAL_LTDC_SetPixelFormat(), HAL_LTDC_SetAlpha(), HAL_LTDC_SetWindowSize(),
66          HAL_LTDC_SetWindowPosition() and HAL_LTDC_SetAddress().
67 
68      (#) Variant functions with _NoReload suffix allows to set the LTDC configuration/settings without immediate reload.
69          This is useful in case when the program requires to modify serval LTDC settings (on one or both layers)
70          then applying(reload) these settings in one shot by calling the function HAL_LTDC_Reload().
71 
72          After calling the _NoReload functions to set different color/format/layer settings,
73          the program shall call the function HAL_LTDC_Reload() to apply(reload) these settings.
74          Function HAL_LTDC_Reload() can be called with the parameter ReloadType set to LTDC_RELOAD_IMMEDIATE if
75          an immediate reload is required.
76          Function HAL_LTDC_Reload() can be called with the parameter ReloadType set to LTDC_RELOAD_VERTICAL_BLANKING if
77          the reload should be done in the next vertical blanking period,
78          this option allows to avoid display flicker by applying the new settings during the vertical blanking period.
79 
80 
81      (#) To control LTDC state you can use the following function: HAL_LTDC_GetState()
82 
83      *** LTDC HAL driver macros list ***
84      =============================================
85      [..]
86        Below the list of most used macros in LTDC HAL driver.
87 
88       (+) __HAL_LTDC_ENABLE: Enable the LTDC.
89       (+) __HAL_LTDC_DISABLE: Disable the LTDC.
90       (+) __HAL_LTDC_LAYER_ENABLE: Enable an LTDC Layer.
91       (+) __HAL_LTDC_LAYER_DISABLE: Disable an LTDC Layer.
92       (+) __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG: Reload  Layer Configuration.
93       (+) __HAL_LTDC_GET_FLAG: Get the LTDC pending flags.
94       (+) __HAL_LTDC_CLEAR_FLAG: Clear the LTDC pending flags.
95       (+) __HAL_LTDC_ENABLE_IT: Enable the specified LTDC interrupts.
96       (+) __HAL_LTDC_DISABLE_IT: Disable the specified LTDC interrupts.
97       (+) __HAL_LTDC_GET_IT_SOURCE: Check whether the specified LTDC interrupt has occurred or not.
98 
99      [..]
100        (@) You can refer to the LTDC HAL driver header file for more useful macros
101 
102 
103      *** Callback registration ***
104      =============================================
105      [..]
106      The compilation define  USE_HAL_LTDC_REGISTER_CALLBACKS when set to 1
107      allows the user to configure dynamically the driver callbacks.
108      Use function HAL_LTDC_RegisterCallback() to register a callback.
109 
110     [..]
111     Function HAL_LTDC_RegisterCallback() allows to register following callbacks:
112       (+) LineEventCallback   : LTDC Line Event Callback.
113       (+) ReloadEventCallback : LTDC Reload Event Callback.
114       (+) ErrorCallback       : LTDC Error Callback
115       (+) MspInitCallback     : LTDC MspInit.
116       (+) MspDeInitCallback   : LTDC MspDeInit.
117     [..]
118     This function takes as parameters the HAL peripheral handle, the callback ID
119     and a pointer to the user callback function.
120 
121     [..]
122     Use function HAL_LTDC_UnRegisterCallback() to reset a callback to the default
123     weak function.
124     HAL_LTDC_UnRegisterCallback() takes as parameters the HAL peripheral handle
125     and the callback ID.
126     [..]
127     This function allows to reset following callbacks:
128       (+) LineEventCallback   : LTDC Line Event Callback
129       (+) ReloadEventCallback : LTDC Reload Event Callback
130       (+) ErrorCallback       : LTDC Error Callback
131       (+) MspInitCallback     : LTDC MspInit
132       (+) MspDeInitCallback   : LTDC MspDeInit.
133 
134     [..]
135     By default, after the HAL_LTDC_Init and when the state is HAL_LTDC_STATE_RESET
136     all callbacks are set to the corresponding weak functions:
137     examples HAL_LTDC_LineEventCallback(), HAL_LTDC_ErrorCallback().
138     Exception done for MspInit and MspDeInit functions that are
139     reset to the legacy weak (surcharged) functions in the HAL_LTDC_Init() and HAL_LTDC_DeInit()
140     only when these callbacks are null (not registered beforehand).
141     If not, MspInit or MspDeInit are not null, the HAL_LTDC_Init() and HAL_LTDC_DeInit()
142     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
143 
144     [..]
145     Callbacks can be registered/unregistered in HAL_LTDC_STATE_READY state only.
146     Exception done MspInit/MspDeInit that can be registered/unregistered
147     in HAL_LTDC_STATE_READY or HAL_LTDC_STATE_RESET state,
148     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
149     In that case first register the MspInit/MspDeInit user callbacks
150     using HAL_LTDC_RegisterCallback() before calling HAL_LTDC_DeInit()
151     or HAL_LTDC_Init() function.
152 
153     [..]
154     When the compilation define USE_HAL_LTDC_REGISTER_CALLBACKS is set to 0 or
155     not defined, the callback registration feature is not available and all callbacks
156     are set to the corresponding weak functions.
157 
158   @endverbatim
159   ******************************************************************************
160   */
161 
162 /* Includes ------------------------------------------------------------------*/
163 #include "stm32n6xx_hal.h"
164 
165 /** @addtogroup STM32N6xx_HAL_Driver
166   * @{
167   */
168 
169 #ifdef HAL_LTDC_MODULE_ENABLED
170 
171 #if defined (LTDC)
172 
173 /** @defgroup LTDC LTDC
174   * @brief LTDC HAL module driver
175   * @{
176   */
177 
178 
179 /* Private typedef -----------------------------------------------------------*/
180 /* Private define ------------------------------------------------------------*/
181 /** @defgroup LTDC_Private_Define LTDC Private Define
182   * @{
183   */
184 #define LTDC_TIMEOUT_VALUE ((uint32_t)100U)  /* 100ms */
185 #define LTDC_PIXEL_FORMAT_FLEX_ARGB               0x00CU       /*!< Flexible ARGB format LTDC pixel format*/
186 #define LTDC_PIXEL_FORMAT_FLEX_YUV_COPLANAR       0x00DU       /*!< Flexible Co-planar format*/
187 #define LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR     0x10DU       /*!< Flexible Semi planar format*/
188 #define LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR     0x20DU       /*!< Flexible Full planar format*/
189 #define LTDC_FLEXIBLE_PIXEL_FORMAT                0x007U       /*!< Flexible pixel format selection */
190 #define LTDC_PITCH_SIGN_MSK                       0x40000000U  /*!< Mask to check Pitch sign  */
191 /**
192   * @}
193   */
194 /* Private macro -------------------------------------------------------------*/
195 /* Private variables ---------------------------------------------------------*/
196 /* YUV to RGB conversion coefficients for BT601/709 Full/Reduced Luminance */
197 static const uint32_t V2R[4] = {403, 459, 359, 409};
198 static const uint32_t U2G[4] = {48, 55, 88, 100};
199 static const uint32_t V2G[4] = {120, 136, 183, 208};
200 static const uint32_t U2B[4] = {475, 541, 454, 516};
201 
202 /* Private function prototypes -----------------------------------------------*/
203 static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc,  uint32_t Aux0Addr, uint32_t Aux1Addr, uint32_t Mirror,
204                            uint32_t LayerIdx);
205 static void LTDC_SetCompositionConfig(LTDC_HandleTypeDef *hltdc,  uint32_t LayerIdx);
206 static void LTDC_SetPredefFormat(LTDC_HandleTypeDef *hltdc,  uint32_t LayerIdx);
207 static void LTDC_RetrieveUserConfig(LTDC_HandleTypeDef *hltdc, uint32_t *Mirror, uint32_t *Aux0Addr,
208                                     uint32_t *Aux1Addr, uint32_t LayerIdx);
209 /* Private functions ---------------------------------------------------------*/
210 
211 /** @defgroup LTDC_Exported_Functions LTDC Exported Functions
212   * @{
213   */
214 
215 /** @defgroup LTDC_Exported_Functions_Group1 Initialization and Configuration functions
216   *  @brief   Initialization and Configuration functions
217   *
218 @verbatim
219  ===============================================================================
220                 ##### Initialization and Configuration functions #####
221  ===============================================================================
222     [..]  This section provides functions allowing to:
223       (+) Initialize and configure the LTDC
224       (+) De-initialize the LTDC
225 
226 @endverbatim
227   * @{
228   */
229 
230 /**
231   * @brief  Initialize the LTDC according to the specified parameters in the LTDC_InitTypeDef.
232   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
233   *                the configuration information for the LTDC.
234   * @retval HAL status
235   */
HAL_LTDC_Init(LTDC_HandleTypeDef * hltdc)236 HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc)
237 {
238   uint32_t tmp;
239   uint32_t tmp1;
240 
241   /* Check the LTDC peripheral state */
242   if (hltdc == NULL)
243   {
244     return HAL_ERROR;
245   }
246 
247   /* Check function parameters */
248   assert_param(IS_LTDC_ALL_INSTANCE(hltdc->Instance));
249   assert_param(IS_LTDC_HSYNC(hltdc->Init.HorizontalSync));
250   assert_param(IS_LTDC_VSYNC(hltdc->Init.VerticalSync));
251   assert_param(IS_LTDC_AHBP(hltdc->Init.AccumulatedHBP));
252   assert_param(IS_LTDC_AVBP(hltdc->Init.AccumulatedVBP));
253   assert_param(IS_LTDC_AAH(hltdc->Init.AccumulatedActiveH));
254   assert_param(IS_LTDC_AAW(hltdc->Init.AccumulatedActiveW));
255   assert_param(IS_LTDC_TOTALH(hltdc->Init.TotalHeigh));
256   assert_param(IS_LTDC_TOTALW(hltdc->Init.TotalWidth));
257   assert_param(IS_LTDC_HSPOL(hltdc->Init.HSPolarity));
258   assert_param(IS_LTDC_VSPOL(hltdc->Init.VSPolarity));
259   assert_param(IS_LTDC_DEPOL(hltdc->Init.DEPolarity));
260   assert_param(IS_LTDC_PCPOL(hltdc->Init.PCPolarity));
261 
262 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
263   if (hltdc->State == HAL_LTDC_STATE_RESET)
264   {
265     /* Allocate lock resource and initialize it */
266     hltdc->Lock = HAL_UNLOCKED;
267 
268     /* Reset the LTDC callback to the legacy weak callbacks */
269     hltdc->LineEventCallback   = HAL_LTDC_LineEventCallback;    /* Legacy weak LineEventCallback    */
270     hltdc->ReloadEventCallback = HAL_LTDC_ReloadEventCallback;  /* Legacy weak ReloadEventCallback  */
271     hltdc->ErrorCallback       = HAL_LTDC_ErrorCallback;        /* Legacy weak ErrorCallback        */
272 
273     if (hltdc->MspInitCallback == NULL)
274     {
275       hltdc->MspInitCallback = HAL_LTDC_MspInit;
276     }
277     /* Init the low level hardware */
278     hltdc->MspInitCallback(hltdc);
279   }
280 #else
281   if (hltdc->State == HAL_LTDC_STATE_RESET)
282   {
283     /* Allocate lock resource and initialize it */
284     hltdc->Lock = HAL_UNLOCKED;
285     /* Init the low level hardware */
286     HAL_LTDC_MspInit(hltdc);
287   }
288 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
289 
290   /* Change LTDC peripheral state */
291   hltdc->State = HAL_LTDC_STATE_BUSY;
292 
293   /* Configure the HS, VS, DE and PC polarity */
294   hltdc->Instance->GCR &= ~(LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL);
295   hltdc->Instance->GCR |= (uint32_t)(hltdc->Init.HSPolarity | hltdc->Init.VSPolarity | \
296                                      hltdc->Init.DEPolarity | hltdc->Init.PCPolarity);
297 
298   /* Set Synchronization size */
299   tmp = (hltdc->Init.HorizontalSync << 16U);
300   WRITE_REG(hltdc->Instance->SSCR, (tmp | hltdc->Init.VerticalSync));
301 
302   /* Set Accumulated Back porch */
303   tmp = (hltdc->Init.AccumulatedHBP << 16U);
304   WRITE_REG(hltdc->Instance->BPCR, (tmp | hltdc->Init.AccumulatedVBP));
305 
306   /* Set Accumulated Active Width */
307   tmp = (hltdc->Init.AccumulatedActiveW << 16U);
308   WRITE_REG(hltdc->Instance->AWCR, (tmp | hltdc->Init.AccumulatedActiveH));
309 
310   /* Set Total Width */
311   tmp = (hltdc->Init.TotalWidth << 16U);
312   WRITE_REG(hltdc->Instance->TWCR, (tmp | hltdc->Init.TotalHeigh));
313 
314   /* Set the background color value */
315   tmp = ((uint32_t)(hltdc->Init.Backcolor.Green) << 8U);
316   tmp1 = ((uint32_t)(hltdc->Init.Backcolor.Red) << 16U);
317   hltdc->Instance->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED);
318   hltdc->Instance->BCCR |= (tmp1 | tmp | hltdc->Init.Backcolor.Blue);
319 
320   /* Activate Global Reload for Layer 1 and Layer 2 */
321   WRITE_REG(LTDC_LAYER(hltdc, LTDC_LAYER_1)->RCR, LTDC_LxRCR_GRMSK);
322   WRITE_REG(LTDC_LAYER(hltdc, LTDC_LAYER_2)->RCR, LTDC_LxRCR_GRMSK);
323 
324   /* Enable the Transfer Error and FIFO underrun interrupts */
325   __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_TE | LTDC_IT_FU);
326 
327   /* Enable LTDC by setting LTDCEN bit */
328   __HAL_LTDC_ENABLE(hltdc);
329 
330   /* Initialize the error code */
331   hltdc->ErrorCode = HAL_LTDC_ERROR_NONE;
332 
333   /* Initialize the LTDC state*/
334   hltdc->State = HAL_LTDC_STATE_READY;
335 
336   return HAL_OK;
337 }
338 
339 /**
340   * @brief  De-initialize the LTDC peripheral.
341   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
342   *                the configuration information for the LTDC.
343   * @retval None
344   */
345 
HAL_LTDC_DeInit(LTDC_HandleTypeDef * hltdc)346 HAL_StatusTypeDef HAL_LTDC_DeInit(LTDC_HandleTypeDef *hltdc)
347 {
348   uint32_t tickstart;
349 
350   /* Check the LTDC peripheral state */
351   if (hltdc == NULL)
352   {
353     return HAL_ERROR;
354   }
355 
356   /* Check function parameters */
357   assert_param(IS_LTDC_ALL_INSTANCE(hltdc->Instance));
358 
359   /* Disable LTDC Layer 1 */
360   __HAL_LTDC_LAYER_DISABLE(hltdc, LTDC_LAYER_1);
361 
362 #if defined(LTDC_Layer2_BASE)
363   /* Disable LTDC Layer 2 */
364   __HAL_LTDC_LAYER_DISABLE(hltdc, LTDC_LAYER_2);
365 #endif /* LTDC_Layer2_BASE */
366 
367   /* Reload during vertical blanking period */
368   __HAL_LTDC_VERTICAL_BLANKING_RELOAD_CONFIG(hltdc);
369 
370   /* Get tick */
371   tickstart = HAL_GetTick();
372 
373   /* Wait for VSYNC Interrupt */
374   while (READ_BIT(hltdc->Instance->CDSR, LTDC_CDSR_VSYNCS) == 0U)
375   {
376     /* Check for the Timeout */
377     if ((HAL_GetTick() - tickstart) > LTDC_TIMEOUT_VALUE)
378     {
379       break;
380     }
381   }
382 
383   /* Disable LTDC  */
384   __HAL_LTDC_DISABLE(hltdc);
385 
386 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
387   if (hltdc->MspDeInitCallback == NULL)
388   {
389     hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit;
390   }
391   /* DeInit the low level hardware */
392   hltdc->MspDeInitCallback(hltdc);
393 #else
394   /* DeInit the low level hardware */
395   HAL_LTDC_MspDeInit(hltdc);
396 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
397 
398   /* Initialize the error code */
399   hltdc->ErrorCode = HAL_LTDC_ERROR_NONE;
400 
401   /* Initialize the LTDC state*/
402   hltdc->State = HAL_LTDC_STATE_RESET;
403 
404   /* Release Lock */
405   __HAL_UNLOCK(hltdc);
406 
407   return HAL_OK;
408 }
409 
410 /**
411   * @brief  Initialize the LTDC MSP.
412   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
413   *                the configuration information for the LTDC.
414   * @retval None
415   */
HAL_LTDC_MspInit(LTDC_HandleTypeDef * hltdc)416 __weak void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc)
417 {
418   /* Prevent unused argument(s) compilation warning */
419   UNUSED(hltdc);
420 
421   /* NOTE : This function should not be modified, when the callback is needed,
422             the HAL_LTDC_MspInit could be implemented in the user file
423    */
424 }
425 
426 /**
427   * @brief  De-initialize the LTDC MSP.
428   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
429   *                the configuration information for the LTDC.
430   * @retval None
431   */
HAL_LTDC_MspDeInit(LTDC_HandleTypeDef * hltdc)432 __weak void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef *hltdc)
433 {
434   /* Prevent unused argument(s) compilation warning */
435   UNUSED(hltdc);
436 
437   /* NOTE : This function should not be modified, when the callback is needed,
438             the HAL_LTDC_MspDeInit could be implemented in the user file
439    */
440 }
441 
442 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
443 /**
444   * @brief  Register a User LTDC Callback
445   *         To be used instead of the weak predefined callback
446   * @param hltdc ltdc handle
447   * @param CallbackID ID of the callback to be registered
448   *        This parameter can be one of the following values:
449   *          @arg @ref HAL_LTDC_LINE_EVENT_CB_ID Line Event Callback ID
450   *          @arg @ref HAL_LTDC_RELOAD_EVENT_CB_ID Reload Event Callback ID
451   *          @arg @ref HAL_LTDC_ERROR_CB_ID Error Callback ID
452   *          @ref @ref HAL_LTDC_WARNING_EVENT_CB_ID Warning Event Callback ID
453   *          @arg @ref HAL_LTDC_MSPINIT_CB_ID MspInit callback ID
454   *          @arg @ref HAL_LTDC_MSPDEINIT_CB_ID MspDeInit callback ID
455   * @param pCallback pointer to the Callback function
456   * @retval status
457   */
HAL_LTDC_RegisterCallback(LTDC_HandleTypeDef * hltdc,HAL_LTDC_CallbackIDTypeDef CallbackID,pLTDC_CallbackTypeDef pCallback)458 HAL_StatusTypeDef HAL_LTDC_RegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID,
459                                             pLTDC_CallbackTypeDef pCallback)
460 {
461   HAL_StatusTypeDef status = HAL_OK;
462 
463   if (pCallback == NULL)
464   {
465     /* Update the error code */
466     hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
467 
468     return HAL_ERROR;
469   }
470   /* Process locked */
471   __HAL_LOCK(hltdc);
472 
473   if (hltdc->State == HAL_LTDC_STATE_READY)
474   {
475     switch (CallbackID)
476     {
477       case HAL_LTDC_LINE_EVENT_CB_ID :
478         hltdc->LineEventCallback = pCallback;
479         break;
480 
481       case HAL_LTDC_RELOAD_EVENT_CB_ID :
482         hltdc->ReloadEventCallback = pCallback;
483         break;
484 
485       case HAL_LTDC_ERROR_CB_ID :
486         hltdc->ErrorCallback = pCallback;
487         break;
488 
489       case HAL_LTDC_WARNING_EVENT_CB_ID:
490         hltdc->WarningEventCallback = pCallback;
491         break;
492 
493       case HAL_LTDC_MSPINIT_CB_ID :
494         hltdc->MspInitCallback = pCallback;
495         break;
496 
497       case HAL_LTDC_MSPDEINIT_CB_ID :
498         hltdc->MspDeInitCallback = pCallback;
499         break;
500 
501       default :
502         /* Update the error code */
503         hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
504         /* Return error status */
505         status =  HAL_ERROR;
506         break;
507     }
508   }
509   else if (hltdc->State == HAL_LTDC_STATE_RESET)
510   {
511     switch (CallbackID)
512     {
513       case HAL_LTDC_MSPINIT_CB_ID :
514         hltdc->MspInitCallback = pCallback;
515         break;
516 
517       case HAL_LTDC_MSPDEINIT_CB_ID :
518         hltdc->MspDeInitCallback = pCallback;
519         break;
520 
521       default :
522         /* Update the error code */
523         hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
524         /* Return error status */
525         status =  HAL_ERROR;
526         break;
527     }
528   }
529   else
530   {
531     /* Update the error code */
532     hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
533     /* Return error status */
534     status =  HAL_ERROR;
535   }
536 
537   /* Release Lock */
538   __HAL_UNLOCK(hltdc);
539 
540   return status;
541 }
542 
543 /**
544   * @brief  Unregister an LTDC Callback
545   *         LTDC callback is redirected to the weak predefined callback
546   * @param hltdc ltdc handle
547   * @param CallbackID ID of the callback to be unregistered
548   *        This parameter can be one of the following values:
549   *          @arg @ref HAL_LTDC_LINE_EVENT_CB_ID Line Event Callback ID
550   *          @arg @ref HAL_LTDC_RELOAD_EVENT_CB_ID Reload Event Callback ID
551   *          @arg @ref HAL_LTDC_ERROR_CB_ID Error Callback ID
552   *          @arg @ref HAL_LTDC_WARNING_EVENT_CB_ID Warning Event Callback ID
553   *          @arg @ref HAL_LTDC_MSPINIT_CB_ID MspInit callback ID
554   *          @arg @ref HAL_LTDC_MSPDEINIT_CB_ID MspDeInit callback ID
555   * @retval status
556   */
HAL_LTDC_UnRegisterCallback(LTDC_HandleTypeDef * hltdc,HAL_LTDC_CallbackIDTypeDef CallbackID)557 HAL_StatusTypeDef HAL_LTDC_UnRegisterCallback(LTDC_HandleTypeDef *hltdc, HAL_LTDC_CallbackIDTypeDef CallbackID)
558 {
559   HAL_StatusTypeDef status = HAL_OK;
560 
561   /* Process locked */
562   __HAL_LOCK(hltdc);
563 
564   if (hltdc->State == HAL_LTDC_STATE_READY)
565   {
566     switch (CallbackID)
567     {
568       case HAL_LTDC_LINE_EVENT_CB_ID :
569         hltdc->LineEventCallback = HAL_LTDC_LineEventCallback;      /* Legacy weak LineEventCallback    */
570         break;
571 
572       case HAL_LTDC_RELOAD_EVENT_CB_ID :
573         hltdc->ReloadEventCallback = HAL_LTDC_ReloadEventCallback;  /* Legacy weak ReloadEventCallback  */
574         break;
575 
576       case HAL_LTDC_ERROR_CB_ID :
577         hltdc->ErrorCallback       = HAL_LTDC_ErrorCallback;        /* Legacy weak ErrorCallback        */
578         break;
579 
580       case HAL_LTDC_WARNING_EVENT_CB_ID :
581         hltdc->WarningEventCallback = HAL_LTDC_WarningEventCallback;
582         break;
583 
584       case HAL_LTDC_MSPINIT_CB_ID :
585         hltdc->MspInitCallback = HAL_LTDC_MspInit;                  /* Legcay weak MspInit Callback  */
586         break;
587 
588       case HAL_LTDC_MSPDEINIT_CB_ID :
589         hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit;              /* Legcay weak MspDeInit Callback     */
590         break;
591 
592       default :
593         /* Update the error code */
594         hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
595         /* Return error status */
596         status =  HAL_ERROR;
597         break;
598     }
599   }
600   else if (hltdc->State == HAL_LTDC_STATE_RESET)
601   {
602     switch (CallbackID)
603     {
604       case HAL_LTDC_MSPINIT_CB_ID :
605         hltdc->MspInitCallback = HAL_LTDC_MspInit;                  /* Legcay weak MspInit Callback     */
606         break;
607 
608       case HAL_LTDC_MSPDEINIT_CB_ID :
609         hltdc->MspDeInitCallback = HAL_LTDC_MspDeInit;              /* Legcay weak MspDeInit Callback     */
610         break;
611 
612       default :
613         /* Update the error code */
614         hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
615         /* Return error status */
616         status =  HAL_ERROR;
617         break;
618     }
619   }
620   else
621   {
622     /* Update the error code */
623     hltdc->ErrorCode |= HAL_LTDC_ERROR_INVALID_CALLBACK;
624     /* Return error status */
625     status =  HAL_ERROR;
626   }
627 
628   /* Release Lock */
629   __HAL_UNLOCK(hltdc);
630 
631   return status;
632 }
633 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
634 
635 /**
636   * @brief  Configure the LTDC Layer burst length
637   * @param  hltdc        Pointer to a LTDC_HandleTypeDef structure that contains
638   *                       the configuration information for the LTDC.
639   * @param  BurstLength  Burst length.
640   *                       This parameter can be a value between 1-16
641   * @param  LayerIdx     LTDC Layer index.
642   *                       This parameter can be one of the following values:
643   *                       LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
644   * @retval HAL status
645   */
HAL_LTDC_ConfigBurstLength(LTDC_HandleTypeDef * hltdc,uint32_t BurstLength,uint32_t LayerIdx)646 HAL_StatusTypeDef HAL_LTDC_ConfigBurstLength(LTDC_HandleTypeDef *hltdc, uint32_t BurstLength, uint32_t LayerIdx)
647 {
648   /* Check the parameters */
649   assert_param(IS_LTDC_LAYER(LayerIdx));
650   assert_param(IS_LTDC_BURST_LENGTH(BurstLength));
651 
652   /* Process locked */
653   __HAL_LOCK(hltdc);
654 
655   /* Change LTDC peripheral state */
656   hltdc->State = HAL_LTDC_STATE_BUSY;
657 
658   /* Configure the layer burst length configuration register */
659   LTDC_LAYER(hltdc, LayerIdx)->BLCR  &= ~(LTDC_LxBLCR_BL);
660   LTDC_LAYER(hltdc, LayerIdx)->BLCR  = BurstLength;
661 
662   /* Initialize the LTDC state*/
663   hltdc->State  = HAL_LTDC_STATE_READY;
664 
665   /* Process unlocked */
666   __HAL_UNLOCK(hltdc);
667 
668   return HAL_OK;
669 }
670 
671 
672 /**
673   * @brief               Configure the LTDC Underrun Threshold.
674   * @param  hltdc        Pointer to a LTDC_HandleTypeDef structure that contains
675   *                       the configuration information for the LTDC.
676   * @param  Threshold    Threshold above which
677   *                       a FIFO underrun warning becomes a FIFO underrun error.
678   *                       This parameter can be a value between 0 - 0XFFFF
679   * @retval HAL status
680   */
HAL_LTDC_ConfigUnderrunThreshold(LTDC_HandleTypeDef * hltdc,uint16_t Threshold)681 HAL_StatusTypeDef HAL_LTDC_ConfigUnderrunThreshold(LTDC_HandleTypeDef *hltdc, uint16_t Threshold)
682 {
683   /* Process locked */
684   __HAL_LOCK(hltdc);
685 
686   /* Change LTDC peripheral state */
687   hltdc->State = HAL_LTDC_STATE_BUSY;
688 
689   /* Configure the Fifo Underrun Threshold register */
690   hltdc->Instance->FUTR &= ~(LTDC_FUTR_THRE);
691   hltdc->Instance->FUTR = (uint32_t) Threshold;
692 
693   /* Initialize the LTDC state*/
694   hltdc->State  = HAL_LTDC_STATE_READY;
695 
696   /* Process unlocked */
697   __HAL_UNLOCK(hltdc);
698 
699   return HAL_OK;
700 }
701 
702 /**
703   * @}
704   */
705 
706 /** @defgroup LTDC_Exported_Functions_Group2 IO operation functions
707   *  @brief   IO operation functions
708   *
709 @verbatim
710  ===============================================================================
711                       #####  IO operation functions  #####
712  ===============================================================================
713     [..]  This section provides function allowing to:
714       (+) Handle LTDC interrupt request
715 
716 @endverbatim
717   * @{
718   */
719 /**
720   * @brief  Handle LTDC interrupt request.
721   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
722   *                the configuration information for the LTDC.
723   * @retval HAL status
724   */
HAL_LTDC_IRQHandler(LTDC_HandleTypeDef * hltdc)725 void HAL_LTDC_IRQHandler(LTDC_HandleTypeDef *hltdc)
726 {
727 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
728   uint32_t isrflags = READ_REG(hltdc->Instance->ISR2);
729   uint32_t itsources = READ_REG(hltdc->Instance->IER2);
730 #else
731   uint32_t isrflags = READ_REG(hltdc->Instance->ISR);
732   uint32_t itsources = READ_REG(hltdc->Instance->IER);
733 #endif /* __ARM_FEATURE_CMSE & __ARM_FEATURE_CMSE == 3U */
734 
735 
736   /* CRC Interrupt management ***************************************/
737   if (((isrflags & LTDC_ISR_CRCIF) != 0U) && ((itsources & LTDC_IER_CRCIE) != 0U))
738   {
739     /* Disable the transfer Error interrupt */
740     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_CRC);
741 
742     /* Clear the crc flag */
743     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_CRC);
744 
745     /* Update error code */
746     hltdc->ErrorCode |= HAL_LTDC_ERROR_CRC;
747 
748     /* Change LTDC state */
749     hltdc->State = HAL_LTDC_STATE_ERROR;
750 
751     /* Process unlocked */
752     __HAL_UNLOCK(hltdc);
753 
754     /* Transfer error Callback */
755 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
756     /*Call registered error callback*/
757     hltdc->ErrorCallback(hltdc);
758 #else
759     /* Call legacy error callback*/
760     HAL_LTDC_ErrorCallback(hltdc);
761 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
762   }
763 
764   /* Fifo Underrun Interrupt management ***************************************/
765   if (((isrflags & LTDC_ISR_FUIF) != 0U) && ((itsources & LTDC_IER_FUIE) != 0U))
766   {
767     /* Disable the transfer Error interrupt */
768     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_FU);
769 
770     /* Clear the UK flag */
771     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_FU);
772 
773     /* Update error code */
774     hltdc->ErrorCode |= HAL_LTDC_ERROR_FU;
775 
776     /* Change LTDC state */
777     hltdc->State = HAL_LTDC_STATE_ERROR;
778 
779     /* Process unlocked */
780     __HAL_UNLOCK(hltdc);
781 
782     /* Transfer error Callback */
783 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
784     /*Call registered error callback*/
785     hltdc->ErrorCallback(hltdc);
786 #else
787     /* Call legacy error callback*/
788     HAL_LTDC_ErrorCallback(hltdc);
789 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
790   }
791 
792   /* Transfer Error Interrupt management ***************************************/
793   if (((isrflags & LTDC_ISR_TERRIF) != 0U) && ((itsources & LTDC_IER_TERRIE) != 0U))
794   {
795     /* Disable the transfer Error interrupt */
796     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_TE);
797 
798     /* Clear the transfer error flag */
799     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_TE);
800 
801     /* Update error code */
802     hltdc->ErrorCode |= HAL_LTDC_ERROR_TE;
803 
804     /* Change LTDC state */
805     hltdc->State = HAL_LTDC_STATE_ERROR;
806 
807     /* Process unlocked */
808     __HAL_UNLOCK(hltdc);
809 
810     /* Transfer error Callback */
811 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
812     /*Call registered error callback*/
813     hltdc->ErrorCallback(hltdc);
814 #else
815     /* Call legacy error callback*/
816     HAL_LTDC_ErrorCallback(hltdc);
817 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
818   }
819 
820   /* FIFO underrun Interrupt management ***************************************/
821   if (((isrflags & LTDC_ISR_FUIF) != 0U) && ((itsources & LTDC_IER_FUIE) != 0U))
822   {
823     /* Disable the FIFO underrun interrupt */
824     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_FU);
825 
826     /* Clear the FIFO underrun flag */
827     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_FU);
828 
829     /* Update error code */
830     hltdc->ErrorCode |= HAL_LTDC_ERROR_FU;
831 
832     /* Change LTDC state */
833     hltdc->State = HAL_LTDC_STATE_ERROR;
834 
835     /* Process unlocked */
836     __HAL_UNLOCK(hltdc);
837 
838     /* Transfer error Callback */
839 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
840     /*Call registered error callback*/
841     hltdc->ErrorCallback(hltdc);
842 #else
843     /* Call legacy error callback*/
844     HAL_LTDC_ErrorCallback(hltdc);
845 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
846   }
847 
848   /* FIFO underrun Warning Interrupt management ***************************************/
849   if (((isrflags & LTDC_ISR_FUWIF) != 0U) && ((itsources & LTDC_IER_FUWIE) != 0U))
850   {
851     /* Disable the FIFO underrun interrupt */
852     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_FUW);
853 
854     /* Clear the FIFO underrun flag */
855     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_FUW);
856 
857     /* Process unlocked */
858     __HAL_UNLOCK(hltdc);
859 
860     /* Transfer error Callback */
861 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
862     /*Call registered error callback*/
863     hltdc->WarningEventCallback(hltdc);
864 #else
865     /* Call legacy error callback*/
866     HAL_LTDC_WarningEventCallback(hltdc);
867 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
868   }
869 
870   /* Line Interrupt management ************************************************/
871   if (((isrflags & LTDC_ISR_LIF) != 0U) && ((itsources & LTDC_IER_LIE) != 0U))
872   {
873     /* Disable the Line interrupt */
874     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_LI);
875 
876     /* Clear the Line interrupt flag */
877     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_LI);
878 
879     /* Change LTDC state */
880     hltdc->State = HAL_LTDC_STATE_READY;
881 
882     /* Process unlocked */
883     __HAL_UNLOCK(hltdc);
884 
885     /* Line interrupt Callback */
886 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
887     /*Call registered Line Event callback */
888     hltdc->LineEventCallback(hltdc);
889 #else
890     /*Call Legacy Line Event callback */
891     HAL_LTDC_LineEventCallback(hltdc);
892 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
893   }
894 
895   /* Register reload Interrupt management ***************************************/
896   if (((isrflags & LTDC_ISR_RRIF) != 0U) && ((itsources & LTDC_IER_RRIE) != 0U))
897   {
898     /* Disable the register reload interrupt */
899     __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_RR);
900 
901     /* Clear the register reload flag */
902     __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_RR);
903 
904     /* Change LTDC state */
905     hltdc->State = HAL_LTDC_STATE_READY;
906 
907     /* Process unlocked */
908     __HAL_UNLOCK(hltdc);
909 
910     /* Reload interrupt Callback */
911 #if (USE_HAL_LTDC_REGISTER_CALLBACKS == 1)
912     /*Call registered reload Event callback */
913     hltdc->ReloadEventCallback(hltdc);
914 #else
915     /*Call Legacy Reload Event callback */
916     HAL_LTDC_ReloadEventCallback(hltdc);
917 #endif /* USE_HAL_LTDC_REGISTER_CALLBACKS */
918   }
919 }
920 
921 /**
922   * @brief  Error LTDC callback.
923   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
924   *                the configuration information for the LTDC.
925   * @retval None
926   */
HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef * hltdc)927 __weak void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc)
928 {
929   /* Prevent unused argument(s) compilation warning */
930   UNUSED(hltdc);
931 
932   /* NOTE : This function should not be modified, when the callback is needed,
933             the HAL_LTDC_ErrorCallback could be implemented in the user file
934    */
935 }
936 
937 /**
938   * @brief  Line Event callback.
939   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
940   *                the configuration information for the LTDC.
941   * @retval None
942   */
HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef * hltdc)943 __weak void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc)
944 {
945   /* Prevent unused argument(s) compilation warning */
946   UNUSED(hltdc);
947 
948   /* NOTE : This function should not be modified, when the callback is needed,
949             the HAL_LTDC_LineEventCallback could be implemented in the user file
950    */
951 }
952 
953 /**
954   * @brief  Reload Event callback.
955   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
956   *                the configuration information for the LTDC.
957   * @retval None
958   */
HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef * hltdc)959 __weak void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
960 {
961   /* Prevent unused argument(s) compilation warning */
962   UNUSED(hltdc);
963 
964   /* NOTE : This function should not be modified, when the callback is needed,
965             the HAL_LTDC_ReloadEvenCallback could be implemented in the user file
966    */
967 }
968 
969 /**
970   * @brief  LTDC FIFO Uderrun Warning callback.
971   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
972   *                the configuration information for the LTDC.
973   * @retval None
974   */
HAL_LTDC_WarningEventCallback(LTDC_HandleTypeDef * hltdc)975 __weak void HAL_LTDC_WarningEventCallback(LTDC_HandleTypeDef *hltdc)
976 {
977   /* Prevent unused argument(s) compilation warning */
978   UNUSED(hltdc);
979 
980   /* NOTE : This function should not be modified, when the callback is needed,
981             the HAL_LTDC_SErrorCallback could be implemented in the user file
982    */
983 }
984 
985 /**
986   * @}
987   */
988 
989 /** @defgroup LTDC_Exported_Functions_Group3 Peripheral Control functions
990   *  @brief    Peripheral Control functions
991   *
992 @verbatim
993  ===============================================================================
994                     ##### Peripheral Control functions #####
995  ===============================================================================
996     [..]  This section provides functions allowing to:
997       (+) Configure the LTDC foreground or/and background parameters.
998       (+) Set the active layer.
999       (+) Configure the color keying.
1000       (+) Configure the C-LUT.
1001       (+) Enable / Disable the color keying.
1002       (+) Enable / Disable the C-LUT.
1003       (+) Update the layer position.
1004       (+) Update the layer size.
1005       (+) Update pixel format on the fly.
1006       (+) Update transparency on the fly.
1007       (+) Update address on the fly.
1008 
1009 @endverbatim
1010   * @{
1011   */
1012 
1013 /**
1014   * @brief  Configure the LTDC Layer according to the specified
1015   *         parameters in the LTDC_InitTypeDef and create the associated handle.
1016   * @param  hltdc      pointer to a LTDC_HandleTypeDef structure that contains
1017   *                    the configuration information for the LTDC.
1018   * @param  pLayerCfg  pointer to a LTDC_LayerCfgTypeDef structure that contains
1019   *                    the configuration information for the Layer.
1020   * @param  LayerIdx  LTDC Layer index.
1021   *                    This parameter can be one of the following values:
1022   *                    LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1023   * @retval HAL status
1024   */
HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef * hltdc,LTDC_LayerCfgTypeDef * pLayerCfg,uint32_t LayerIdx)1025 HAL_StatusTypeDef HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx)
1026 {
1027   /* Check the parameters */
1028   assert_param(IS_LTDC_LAYER(LayerIdx));
1029   assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0));
1030   assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1));
1031   assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0));
1032   assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1));
1033   assert_param(IS_LTDC_PIXEL_FORMAT(pLayerCfg->PixelFormat));
1034   assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha));
1035   assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha0));
1036   assert_param(IS_LTDC_BLENDING_FACTOR1(pLayerCfg->BlendingFactor1));
1037   assert_param(IS_LTDC_BLENDING_FACTOR2(pLayerCfg->BlendingFactor2));
1038   assert_param(IS_LTDC_CFBLL(pLayerCfg->ImageWidth));
1039   assert_param(IS_LTDC_CFBLNBR(pLayerCfg->ImageHeight));
1040 
1041   /* Process locked */
1042   __HAL_LOCK(hltdc);
1043 
1044   /* Change LTDC peripheral state */
1045   hltdc->State = HAL_LTDC_STATE_BUSY;
1046 
1047   /* Copy new layer configuration into handle structure */
1048   hltdc->LayerCfg[LayerIdx] = *pLayerCfg;
1049 
1050   /* Configure Predefined format */
1051   LTDC_SetPredefFormat(hltdc, LayerIdx);
1052 
1053   /* Configure composition and blending*/
1054   LTDC_SetCompositionConfig(hltdc, LayerIdx);
1055 
1056   /* Disable YUV format */
1057   CLEAR_BIT(LTDC_LAYER(hltdc, LayerIdx)->PCR, LTDC_LxPCR_YCEN);
1058 
1059   /* Configure the LTDC Layer */
1060   LTDC_SetConfig(hltdc, 0U, 0U, LTDC_MIRROR_NONE, LayerIdx);
1061 
1062   /* Set the Immediate Reload type */
1063   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1064 
1065   /* Initialize the LTDC state*/
1066   hltdc->State  = HAL_LTDC_STATE_READY;
1067 
1068   /* Process unlocked */
1069   __HAL_UNLOCK(hltdc);
1070 
1071   return HAL_OK;
1072 }
1073 
1074 /**
1075   * @brief  Configure the color keying.
1076   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1077   *                   the configuration information for the LTDC.
1078   * @param  RGBValue  the color key value
1079   * @param  LayerIdx  LTDC Layer index.
1080   *                   This parameter can be one of the following values:
1081   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1082   * @retval HAL status
1083   */
HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef * hltdc,uint32_t RGBValue,uint32_t LayerIdx)1084 HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx)
1085 {
1086   /* Check the parameters */
1087   assert_param(IS_LTDC_LAYER(LayerIdx));
1088 
1089   /* Process locked */
1090   __HAL_LOCK(hltdc);
1091 
1092   /* Change LTDC peripheral state */
1093   hltdc->State = HAL_LTDC_STATE_BUSY;
1094 
1095   /* Configure the default color values */
1096   LTDC_LAYER(hltdc, LayerIdx)->CKCR &=  ~(LTDC_LxCKCR_CKBLUE | LTDC_LxCKCR_CKGREEN | LTDC_LxCKCR_CKRED);
1097   LTDC_LAYER(hltdc, LayerIdx)->CKCR  = RGBValue;
1098 
1099   /* Set the Immediate Reload type */
1100   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1101 
1102   /* Change the LTDC state*/
1103   hltdc->State = HAL_LTDC_STATE_READY;
1104 
1105   /* Process unlocked */
1106   __HAL_UNLOCK(hltdc);
1107 
1108   return HAL_OK;
1109 }
1110 
1111 /**
1112   * @brief  Load the color lookup table.
1113   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1114   *                   the configuration information for the LTDC.
1115   * @param  pCLUT     pointer to the color lookup table address.
1116   * @param  CLUTSize  the color lookup table size.
1117   * @param  LayerIdx  LTDC Layer index.
1118   *                   This parameter can be one of the following values:
1119   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1120   * @retval HAL status
1121   */
HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef * hltdc,const uint32_t * pCLUT,uint32_t CLUTSize,uint32_t LayerIdx)1122 HAL_StatusTypeDef HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef *hltdc, const uint32_t *pCLUT, uint32_t CLUTSize,
1123                                       uint32_t LayerIdx)
1124 {
1125   uint32_t tmp;
1126   uint32_t counter;
1127   const uint32_t *pcolorlut = pCLUT;
1128   /* Check the parameters */
1129   assert_param(IS_LTDC_LAYER(LayerIdx));
1130 
1131   /* Process locked */
1132   __HAL_LOCK(hltdc);
1133 
1134   /* Change LTDC peripheral state */
1135   hltdc->State = HAL_LTDC_STATE_BUSY;
1136 
1137   for (counter = 0U; (counter < CLUTSize); counter++)
1138   {
1139     if (hltdc->LayerCfg[LayerIdx].PixelFormat == LTDC_PIXEL_FORMAT_AL44)
1140     {
1141       tmp  = (((counter + (16U * counter)) << 24U) | ((uint32_t)(*pcolorlut) & 0xFFU) | \
1142               ((uint32_t)(*pcolorlut) & 0xFF00U) | ((uint32_t)(*pcolorlut) & 0xFF0000U));
1143     }
1144     else
1145     {
1146       tmp  = ((counter << 24U) | ((uint32_t)(*pcolorlut) & 0xFFU) | \
1147               ((uint32_t)(*pcolorlut) & 0xFF00U) | ((uint32_t)(*pcolorlut) & 0xFF0000U));
1148     }
1149 
1150     pcolorlut++;
1151 
1152     /* Specifies the C-LUT address and RGB value */
1153     LTDC_LAYER(hltdc, LayerIdx)->CLUTWR  = tmp;
1154   }
1155 
1156   /* Change the LTDC state*/
1157   hltdc->State = HAL_LTDC_STATE_READY;
1158 
1159   /* Process unlocked */
1160   __HAL_UNLOCK(hltdc);
1161 
1162   return HAL_OK;
1163 }
1164 
1165 /**
1166   * @brief Configures the gamma correction for the LTDC peripheral.
1167   *
1168   * This function sets up the gamma correction feature of the LTDC (Liquid Crystal Display Controller)
1169   * peripheral. Gamma correction helps in adjusting the brightness of the output image. This function
1170   * allows the configuration of the gamma curve by setting the values for ones, tenths, and the specific
1171   * RGB component to be adjusted.
1172   *
1173   * @param  hltdc      pointer to a LTDC_HandleTypeDef structure that contains
1174   *                    the configuration information for the LTDC.
1175   * @param GammaOnes Specifies the value for the ones place in the gamma correction factor.
1176   *                  This parameter can be a value between 0 and 2.
1177   * @param GammaTenths Specifies the value for the tenths place in the gamma correction factor.
1178   *                    This parameter can be a value between 0 and 9 if GammaOnes > 0 else between 4 and 9.
1179   * @param RGBComponent Specifies the RGB component to which the gamma correction is applied.
1180   *                     This parameter can be one of the following values:
1181   *                     @arg LTDC_RGB_COMPONENT_RED  : Gamma correction for the red component.
1182   *                     @arg LTDC_RGB_COMPONENT_GREEN: Gamma correction for the green component.
1183   *                     @arg LTDC_RGB_COMPONENT_BLUE : Gamma correction for the blue component.
1184   *                     @arg LTDC_RGB_COMPONENT_ALL  : Gamma correction for all components.
1185   * @retval HAL status
1186   */
HAL_LTDC_ConfigGammaCorrection(LTDC_HandleTypeDef * hltdc,uint32_t GammaOnes,uint32_t GammaTenths,uint32_t RGBComponent)1187 HAL_StatusTypeDef HAL_LTDC_ConfigGammaCorrection(LTDC_HandleTypeDef *hltdc, uint32_t GammaOnes,
1188                                                  uint32_t GammaTenths, uint32_t RGBComponent)
1189 {
1190   const uint32_t gammaindex = (GammaOnes * 70U) + (GammaTenths  * 7U) - 28U;
1191   uint8_t gammasegment;
1192   const uint8_t GammaAdress[7] = {32, 64, 96, 128, 160, 192, 224};
1193   /* Gamma Mapped coefficients for segments 1 to 7 */
1194   const uint8_t GammaLUT[182] =
1195   {
1196     111, 147, 173, 194, 212, 228, 242,  /* Gamma = 0.4 */
1197     90, 128, 156, 181, 202, 221, 239,   /* Gamma = 0.5 */
1198     73, 111, 142, 169, 193, 215, 236,   /* Gamma = 0.6 */
1199     60, 97, 129, 157, 184, 209, 233,    /* Gamma = 0.7 */
1200     48, 84, 117, 147, 176, 203, 230,    /* Gamma = 0.8 */
1201     39, 73, 106, 137, 168, 198, 227,    /* Gamma = 0.9 */
1202     32, 64, 96, 128, 160, 192, 224,     /* Gamma = 1.0 */
1203     26, 56, 87, 119, 153, 187, 221,     /* Gamma = 1.1 */
1204     21, 49, 79, 112, 146, 181, 218,     /* Gamma = 1.2 */
1205     17, 42, 72, 104, 139, 176, 215,     /* Gamma = 1.3 */
1206     14, 37, 65, 97, 133, 171, 213,      /* Gamma = 1.4 */
1207     11, 32, 59, 91, 127, 167, 210,      /* Gamma = 1.5 */
1208     9, 28, 53, 85, 121, 162, 207,       /* Gamma = 1.6 */
1209     7, 24, 48, 79, 115, 157, 205,       /* Gamma = 1.7 */
1210     6, 21, 44, 74, 110, 153, 202,       /* Gamma = 1.8 */
1211     5, 18, 40, 69, 105, 149, 199,       /* Gamma = 1.9 */
1212     4, 16, 36, 64, 100, 145, 197,       /* Gamma = 2.0 */
1213     3, 14, 33, 60, 96, 141, 194,        /* Gamma = 2.1 */
1214     3, 12, 30, 56, 91, 137, 192,        /* Gamma = 2.2 */
1215     2, 11, 27, 52, 87, 133, 189,        /* Gamma = 2.3 */
1216     2, 9, 24, 49, 83, 129, 187,         /* Gamma = 2.4 */
1217     1, 8, 22, 46, 80, 125, 184,         /* Gamma = 2.5 */
1218     1, 7, 20, 42, 76, 122, 182,         /* Gamma = 2.6 */
1219     1, 6, 18, 40, 72, 119, 180,         /* Gamma = 2.7 */
1220     1, 5, 17, 37, 69, 115, 177,         /* Gamma = 2.8 */
1221     1, 5, 15, 35, 66, 112, 175,         /* Gamma = 2.9 */
1222   };
1223 
1224   /* Check the parameters */
1225   assert_param(IS_LTDC_RGB_COMPONENT(RGBComponent));
1226   assert_param(IS_LTDC_GAMMA_VALUE(GammaOnes, GammaTenths));
1227 
1228   /* Process locked */
1229   __HAL_LOCK(hltdc);
1230 
1231   /* Change LTDC peripheral state */
1232   hltdc->State = HAL_LTDC_STATE_BUSY;
1233 
1234   /* Set Gamma interpolated segments*/
1235   hltdc->Instance->GCCR = RGBComponent ;
1236   for (gammasegment = 0U; (gammasegment < 7U); gammasegment++)
1237   {
1238     hltdc->Instance->GCCR = RGBComponent | ((uint32_t) GammaAdress[gammasegment] << LTDC_GCCR_ADDR_Pos) |
1239                             ((uint32_t) GammaLUT[gammasegment + gammaindex] << LTDC_GCCR_COMP_Pos);
1240   }
1241   hltdc->Instance->GCCR = RGBComponent | (0xFFU << LTDC_GCCR_COMP_Pos) | LTDC_GCCR_ADDR;
1242 
1243   /* Change the LTDC state*/
1244   hltdc->State = HAL_LTDC_STATE_READY;
1245 
1246   /* Process unlocked */
1247   __HAL_UNLOCK(hltdc);
1248 
1249   return HAL_OK;
1250 }
1251 
1252 /**
1253   * @brief  Enable the color keying.
1254   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1255   *                   the configuration information for the LTDC.
1256   * @param  LayerIdx  LTDC Layer index.
1257   *                   This parameter can be one of the following values:
1258   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1259   * @retval  HAL status
1260   */
HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)1261 HAL_StatusTypeDef HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
1262 {
1263   /* Check the parameters */
1264   assert_param(IS_LTDC_LAYER(LayerIdx));
1265 
1266   /* Process locked */
1267   __HAL_LOCK(hltdc);
1268 
1269   /* Change LTDC peripheral state */
1270   hltdc->State = HAL_LTDC_STATE_BUSY;
1271 
1272   /* Enable LTDC color keying by setting COLKEN bit */
1273   LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CKEN;
1274 
1275   /* Set the Immediate Reload type */
1276   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1277 
1278   /* Change the LTDC state*/
1279   hltdc->State = HAL_LTDC_STATE_READY;
1280 
1281   /* Process unlocked */
1282   __HAL_UNLOCK(hltdc);
1283 
1284   return HAL_OK;
1285 }
1286 
1287 /**
1288   * @brief  Disable the color keying.
1289   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1290   *                   the configuration information for the LTDC.
1291   * @param  LayerIdx  LTDC Layer index.
1292   *                   This parameter can be one of the following values:
1293   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1294   * @retval  HAL status
1295   */
HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)1296 HAL_StatusTypeDef HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
1297 {
1298   /* Check the parameters */
1299   assert_param(IS_LTDC_LAYER(LayerIdx));
1300 
1301   /* Process locked */
1302   __HAL_LOCK(hltdc);
1303 
1304   /* Change LTDC peripheral state */
1305   hltdc->State = HAL_LTDC_STATE_BUSY;
1306 
1307   /* Disable LTDC color keying by setting COLKEN bit */
1308   LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CKEN;
1309 
1310   /* Set the Immediate Reload type */
1311   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1312 
1313   /* Change the LTDC state*/
1314   hltdc->State = HAL_LTDC_STATE_READY;
1315 
1316   /* Process unlocked */
1317   __HAL_UNLOCK(hltdc);
1318 
1319   return HAL_OK;
1320 }
1321 
1322 /**
1323   * @brief  Enable the color lookup table.
1324   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1325   *                   the configuration information for the LTDC.
1326   * @param  LayerIdx  LTDC Layer index.
1327   *                   This parameter can be one of the following values:
1328   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1329   * @retval  HAL status
1330   */
HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)1331 HAL_StatusTypeDef HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
1332 {
1333   /* Check the parameters */
1334   assert_param(IS_LTDC_LAYER(LayerIdx));
1335 
1336   /* Process locked */
1337   __HAL_LOCK(hltdc);
1338 
1339   /* Change LTDC peripheral state */
1340   hltdc->State = HAL_LTDC_STATE_BUSY;
1341 
1342   /* Enable LTDC color lookup table by setting CLUTEN bit */
1343   LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CLUTEN;
1344 
1345   /* Set the Immediate Reload type */
1346   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1347 
1348   /* Change the LTDC state*/
1349   hltdc->State = HAL_LTDC_STATE_READY;
1350 
1351   /* Process unlocked */
1352   __HAL_UNLOCK(hltdc);
1353 
1354   return HAL_OK;
1355 }
1356 
1357 /**
1358   * @brief  Disable the color lookup table.
1359   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1360   *                   the configuration information for the LTDC.
1361   * @param  LayerIdx  LTDC Layer index.
1362   *                   This parameter can be one of the following values:
1363   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1364   * @retval  HAL status
1365   */
HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)1366 HAL_StatusTypeDef HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
1367 {
1368   /* Check the parameters */
1369   assert_param(IS_LTDC_LAYER(LayerIdx));
1370 
1371   /* Process locked */
1372   __HAL_LOCK(hltdc);
1373 
1374   /* Change LTDC peripheral state */
1375   hltdc->State = HAL_LTDC_STATE_BUSY;
1376 
1377   /* Disable LTDC color lookup table by setting CLUTEN bit */
1378   LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CLUTEN;
1379 
1380   /* Set the Immediate Reload type */
1381   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1382 
1383   /* Change the LTDC state*/
1384   hltdc->State = HAL_LTDC_STATE_READY;
1385 
1386   /* Process unlocked */
1387   __HAL_UNLOCK(hltdc);
1388 
1389   return HAL_OK;
1390 }
1391 
1392 /**
1393   * @brief  Enable Dither.
1394   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1395   *                the configuration information for the LTDC.
1396   * @retval  HAL status
1397   */
1398 
HAL_LTDC_EnableDither(LTDC_HandleTypeDef * hltdc)1399 HAL_StatusTypeDef HAL_LTDC_EnableDither(LTDC_HandleTypeDef *hltdc)
1400 {
1401   /* Process locked */
1402   __HAL_LOCK(hltdc);
1403 
1404   /* Change LTDC peripheral state */
1405   hltdc->State = HAL_LTDC_STATE_BUSY;
1406 
1407   /* Enable Dither by setting DTEN bit */
1408   LTDC->GCR |= (uint32_t)LTDC_GCR_DEN;
1409 
1410   /* Change the LTDC state*/
1411   hltdc->State = HAL_LTDC_STATE_READY;
1412 
1413   /* Process unlocked */
1414   __HAL_UNLOCK(hltdc);
1415 
1416   return HAL_OK;
1417 }
1418 
1419 /**
1420   * @brief  Disable Dither.
1421   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1422   *                the configuration information for the LTDC.
1423   * @retval  HAL status
1424   */
1425 
HAL_LTDC_DisableDither(LTDC_HandleTypeDef * hltdc)1426 HAL_StatusTypeDef HAL_LTDC_DisableDither(LTDC_HandleTypeDef *hltdc)
1427 {
1428   /* Process locked */
1429   __HAL_LOCK(hltdc);
1430 
1431   /* Change LTDC peripheral state */
1432   hltdc->State = HAL_LTDC_STATE_BUSY;
1433 
1434   /* Disable Dither by setting DTEN bit */
1435   LTDC->GCR &= ~(uint32_t)LTDC_GCR_DEN;
1436 
1437   /* Change the LTDC state*/
1438   hltdc->State = HAL_LTDC_STATE_READY;
1439 
1440   /* Process unlocked */
1441   __HAL_UNLOCK(hltdc);
1442 
1443   return HAL_OK;
1444 }
1445 
1446 
1447 /**
1448   * @brief Enables the CRC generator on the LTDC peripheral.
1449   *
1450   * Activates the Cyclic Redundancy Check (CRC) generator for the LTDC peripheral. The CRC can be used
1451   * to verify the integrity of the data processed by the LTDC. Once enabled, the CRC generator computes
1452   * a CRC value on the configured frame and can be used for error checking purposes.
1453   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1454   *                the configuration information for the LTDC.
1455   * @retval  HAL status
1456   */
1457 
HAL_LTDC_EnableCRC(LTDC_HandleTypeDef * hltdc)1458 HAL_StatusTypeDef HAL_LTDC_EnableCRC(LTDC_HandleTypeDef *hltdc)
1459 {
1460   uint32_t tickstart;
1461 
1462   /* Process locked */
1463   __HAL_LOCK(hltdc);
1464 
1465   /* Change LTDC peripheral state */
1466   hltdc->State = HAL_LTDC_STATE_BUSY;
1467 
1468   /* Enable crc by setting CRCEN bit */
1469   LTDC->GCR |= (uint32_t)LTDC_GCR_CRCEN;
1470 
1471   /* Get tick */
1472   tickstart = HAL_GetTick();
1473 
1474   /* Wait for CRC computing */
1475   while (READ_REG(hltdc->Instance->CCRCR) == 0U)
1476   {
1477     /* Check for the Timeout */
1478     if ((HAL_GetTick() - tickstart) > LTDC_TIMEOUT_VALUE)
1479     {
1480       break;
1481     }
1482   }
1483 
1484   __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_CRC);
1485 
1486   /* Change the LTDC state*/
1487   hltdc->State = HAL_LTDC_STATE_READY;
1488 
1489   /* Process unlocked */
1490   __HAL_UNLOCK(hltdc);
1491 
1492   return HAL_OK;
1493 }
1494 
1495 /**
1496   * @brief Disables the CRC generator on the LTDC peripheral.
1497   *
1498   * Deactivates the Cyclic Redundancy Check (CRC) generator for the LTDC peripheral. This function
1499   * stops the CRC computation on the data processed by the LTDC, which may be required when CRC
1500   * validation is no longer needed.
1501   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1502   *                the configuration information for the LTDC.
1503   * @retval  HAL status
1504   */
1505 
HAL_LTDC_DisableCRC(LTDC_HandleTypeDef * hltdc)1506 HAL_StatusTypeDef HAL_LTDC_DisableCRC(LTDC_HandleTypeDef *hltdc)
1507 {
1508   /* Process locked */
1509   __HAL_LOCK(hltdc);
1510 
1511   /* Change LTDC peripheral state */
1512   hltdc->State = HAL_LTDC_STATE_BUSY;
1513 
1514   __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_CRC);
1515 
1516   /* Disable crc by clearing CRCEN bit */
1517   LTDC->GCR &= ~(uint32_t)LTDC_GCR_CRCEN;
1518 
1519   /* Change the LTDC state*/
1520   hltdc->State = HAL_LTDC_STATE_READY;
1521 
1522   /* Process unlocked */
1523   __HAL_UNLOCK(hltdc);
1524 
1525   return HAL_OK;
1526 }
1527 
1528 /**
1529   * @brief Enables gamma correction on the LTDC peripheral.
1530   *
1531   * This function enables the gamma correction feature of the LTDC peripheral, which adjusts the
1532   * luminance of the output image to improve visual quality. Gamma correction is applied according to
1533   * the previously configured parameters.
1534   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1535   *                the configuration information for the LTDC.
1536   * @retval  HAL status
1537   */
1538 
HAL_LTDC_EnableGammaCorrection(LTDC_HandleTypeDef * hltdc)1539 HAL_StatusTypeDef HAL_LTDC_EnableGammaCorrection(LTDC_HandleTypeDef *hltdc)
1540 {
1541   /* Process locked */
1542   __HAL_LOCK(hltdc);
1543 
1544   /* Change LTDC peripheral state */
1545   hltdc->State = HAL_LTDC_STATE_BUSY;
1546 
1547   /* Enable gamma correction by setting GAMEN bit */
1548   LTDC->GCR |= (uint32_t)LTDC_GCR_GAMEN;
1549 
1550   /* Change the LTDC state*/
1551   hltdc->State = HAL_LTDC_STATE_READY;
1552 
1553   /* Process unlocked */
1554   __HAL_UNLOCK(hltdc);
1555 
1556   return HAL_OK;
1557 }
1558 
1559 /**
1560   * @brief  Disable gamma correction.
1561   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
1562   *                the configuration information for the LTDC.
1563   * @retval  HAL status
1564   */
1565 
HAL_LTDC_DisableGammaCorrection(LTDC_HandleTypeDef * hltdc)1566 HAL_StatusTypeDef HAL_LTDC_DisableGammaCorrection(LTDC_HandleTypeDef *hltdc)
1567 {
1568   /* Process locked */
1569   __HAL_LOCK(hltdc);
1570 
1571   /* Change LTDC peripheral state */
1572   hltdc->State = HAL_LTDC_STATE_BUSY;
1573 
1574   /* Disable gamma correction by clearing GAMEN bit */
1575   LTDC->GCR &= ~(uint32_t)LTDC_GCR_GAMEN;
1576 
1577   /* Change the LTDC state*/
1578   hltdc->State = HAL_LTDC_STATE_READY;
1579 
1580   /* Process unlocked */
1581   __HAL_UNLOCK(hltdc);
1582 
1583   return HAL_OK;
1584 }
1585 /**
1586   * @brief  Set the LTDC window size.
1587   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1588   *                   the configuration information for the LTDC.
1589   * @param  XSize     LTDC Pixel per line
1590   * @param  YSize     LTDC Line number
1591   * @param  LayerIdx  LTDC Layer index.
1592   *                   This parameter can be one of the following values:
1593   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1594   * @retval  HAL status
1595   */
HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef * hltdc,uint32_t XSize,uint32_t YSize,uint32_t LayerIdx)1596 HAL_StatusTypeDef HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx)
1597 {
1598   uint32_t mirror = 0U;
1599   uint32_t aux0Addr = 0U;
1600   uint32_t aux1Addr = 0U;
1601 
1602   /* Check the parameters (Layers parameters)*/
1603   assert_param(IS_LTDC_LAYER(LayerIdx));
1604   assert_param(IS_LTDC_CFBLL(XSize));
1605   assert_param(IS_LTDC_CFBLNBR(YSize));
1606 
1607   /* Process locked */
1608   __HAL_LOCK(hltdc);
1609 
1610   /* Change LTDC peripheral state */
1611   hltdc->State = HAL_LTDC_STATE_BUSY;
1612 
1613   /* Get previous user configuration */
1614   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
1615 
1616   /* update horizontal stop */
1617   hltdc->LayerCfg[LayerIdx].WindowX1 = XSize + hltdc->LayerCfg[LayerIdx].WindowX0;
1618 
1619   /* update vertical stop */
1620   hltdc->LayerCfg[LayerIdx].WindowY1 = YSize + hltdc->LayerCfg[LayerIdx].WindowY0;
1621 
1622   /* Reconfigures the color frame buffer pitch in byte */
1623   hltdc->LayerCfg[LayerIdx].ImageWidth = XSize;
1624 
1625   /* Reconfigures the frame buffer line number */
1626   hltdc->LayerCfg[LayerIdx].ImageHeight = YSize;
1627 
1628   /* Set LTDC parameters */
1629   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
1630 
1631   /* Set the Immediate Reload type */
1632   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1633 
1634   /* Change the LTDC state*/
1635   hltdc->State = HAL_LTDC_STATE_READY;
1636 
1637   /* Process unlocked */
1638   __HAL_UNLOCK(hltdc);
1639 
1640   return HAL_OK;
1641 }
1642 
1643 /**
1644   * @brief  Set the LTDC window position.
1645   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1646   *                   the configuration information for the LTDC.
1647   * @param  X0        LTDC window X offset
1648   * @param  Y0        LTDC window Y offset
1649   * @param  LayerIdx  LTDC Layer index.
1650   *                         This parameter can be one of the following values:
1651   *                         LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1652   * @retval  HAL status
1653   */
HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef * hltdc,uint32_t X0,uint32_t Y0,uint32_t LayerIdx)1654 HAL_StatusTypeDef HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx)
1655 {
1656   uint32_t aux0Addr = 0U;
1657   uint32_t aux1Addr = 0U;
1658   uint32_t mirror = 0U;
1659 
1660   /* Check the parameters */
1661   assert_param(IS_LTDC_LAYER(LayerIdx));
1662   assert_param(IS_LTDC_CFBLL(X0));
1663   assert_param(IS_LTDC_CFBLNBR(Y0));
1664 
1665   /* Process locked */
1666   __HAL_LOCK(hltdc);
1667 
1668   /* Change LTDC peripheral state */
1669   hltdc->State = HAL_LTDC_STATE_BUSY;
1670 
1671   /* Get previous user configuration */
1672   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
1673 
1674   /* update horizontal start/stop */
1675   hltdc->LayerCfg[LayerIdx].WindowX0 = X0;
1676   hltdc->LayerCfg[LayerIdx].WindowX1 = X0 + hltdc->LayerCfg[LayerIdx].ImageWidth;
1677 
1678   /* update vertical start/stop */
1679   hltdc->LayerCfg[LayerIdx].WindowY0 = Y0;
1680   hltdc->LayerCfg[LayerIdx].WindowY1 = Y0 + hltdc->LayerCfg[LayerIdx].ImageHeight;
1681 
1682   /* Set LTDC parameters */
1683   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
1684 
1685   /* Set the Immediate Reload type */
1686   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1687 
1688   /* Change the LTDC state*/
1689   hltdc->State = HAL_LTDC_STATE_READY;
1690 
1691   /* Process unlocked */
1692   __HAL_UNLOCK(hltdc);
1693 
1694   return HAL_OK;
1695 }
1696 
1697 /**
1698   * @brief  Reconfigure the pixel format.
1699   * @param  hltdc        pointer to a LTDC_HandleTypeDef structure that contains
1700   *                      the configuration information for the LTDC.
1701   * @param  Pixelformat  new pixel format value.
1702   * @param  LayerIdx     LTDC Layer index.
1703   *                      This parameter can be one of the following values:
1704   *                      LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
1705   * @retval  HAL status
1706   */
HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef * hltdc,uint32_t Pixelformat,uint32_t LayerIdx)1707 HAL_StatusTypeDef HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx)
1708 {
1709   uint32_t aux0Addr = 0U;
1710   uint32_t aux1Addr = 0U;
1711   uint32_t mirror = 0U;
1712 
1713   /* Check the parameters */
1714   assert_param(IS_LTDC_PIXEL_FORMAT(Pixelformat));
1715   assert_param(IS_LTDC_LAYER(LayerIdx));
1716 
1717   /* Process locked */
1718   __HAL_LOCK(hltdc);
1719 
1720   /* Change LTDC peripheral state */
1721   hltdc->State = HAL_LTDC_STATE_BUSY;
1722 
1723   /* Get previous user configuration */
1724   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
1725 
1726   /* Reconfigure the pixel format */
1727   hltdc->LayerCfg[LayerIdx].PixelFormat = Pixelformat;
1728 
1729   /* Set LTDC parameters */
1730   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
1731 
1732   /* Set LTDC format */
1733   LTDC_SetPredefFormat(hltdc, LayerIdx);
1734 
1735   /* Set the Immediate Reload type */
1736   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1737 
1738   /* Change the LTDC state*/
1739   hltdc->State = HAL_LTDC_STATE_READY;
1740 
1741   /* Process unlocked */
1742   __HAL_UNLOCK(hltdc);
1743 
1744   return HAL_OK;
1745 }
1746 
1747 /**
1748   * @brief  Reconfigure the layer alpha value.
1749   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1750   *                   the configuration information for the LTDC.
1751   * @param  Alpha     new alpha value.
1752   * @param  LayerIdx  LTDC Layer index.
1753   *                   This parameter can be one of the following values:
1754   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
1755   * @retval  HAL status
1756   */
HAL_LTDC_SetAlpha(LTDC_HandleTypeDef * hltdc,uint32_t Alpha,uint32_t LayerIdx)1757 HAL_StatusTypeDef HAL_LTDC_SetAlpha(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx)
1758 {
1759   /* Check the parameters */
1760   assert_param(IS_LTDC_ALPHA(Alpha));
1761   assert_param(IS_LTDC_LAYER(LayerIdx));
1762 
1763   /* Process locked */
1764   __HAL_LOCK(hltdc);
1765 
1766   /* Change LTDC peripheral state */
1767   hltdc->State = HAL_LTDC_STATE_BUSY;
1768 
1769   /* Specifies the constant alpha value */
1770   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CACR, Alpha);
1771 
1772   /* Set the Immediate Reload type */
1773   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1774 
1775   /* Change the LTDC state*/
1776   hltdc->State = HAL_LTDC_STATE_READY;
1777 
1778   /* Process unlocked */
1779   __HAL_UNLOCK(hltdc);
1780 
1781   return HAL_OK;
1782 }
1783 /**
1784   *
1785   * @brief Reconfigure the memory address for a layer buffer in the LTDC peripheral.
1786   *
1787   * This function configures the memory address for a layer buffer that can contain either ARGB data or
1788   * YUV co-planar data.
1789   * This allows dynamic updating of the frame buffer address for the specified layer.
1790   *
1791   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1792   *                   the configuration information for the LTDC.
1793   * @param  Address   The memory address where the layer data (ARGB or YUV co-planar) is stored.
1794   * @param  LayerIdx  LTDC Layer index.
1795   *                   This parameter can be one of the following values:
1796   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
1797   * @retval  HAL status
1798   */
HAL_LTDC_SetAddress(LTDC_HandleTypeDef * hltdc,uint32_t Address,uint32_t LayerIdx)1799 HAL_StatusTypeDef HAL_LTDC_SetAddress(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx)
1800 {
1801   uint32_t aux0Addr = 0U;
1802   uint32_t aux1Addr = 0U;
1803   uint32_t mirror = 0U;
1804 
1805   /* Check the parameters */
1806   assert_param(IS_LTDC_LAYER(LayerIdx));
1807 
1808   /* Process locked */
1809   __HAL_LOCK(hltdc);
1810 
1811   /* Change LTDC peripheral state */
1812   hltdc->State = HAL_LTDC_STATE_BUSY;
1813 
1814   /* Get previous user configuration */
1815   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
1816 
1817   /* Reconfigure the Address */
1818   hltdc->LayerCfg[LayerIdx].FBStartAdress = Address;
1819 
1820   /* Set LTDC parameters */
1821   LTDC_SetConfig(hltdc, 0U, 0U, mirror, LayerIdx);
1822 
1823   /* Set the Immediate Reload type */
1824   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1825 
1826   /* Change the LTDC state*/
1827   hltdc->State = HAL_LTDC_STATE_READY;
1828 
1829   /* Process unlocked */
1830   __HAL_UNLOCK(hltdc);
1831 
1832   return HAL_OK;
1833 }
1834 
1835 /**
1836   * @brief  Function used to reconfigure the pitch for specific cases where the attached LayerIdx buffer have a width
1837   *         that is larger than the one intended to be displayed on screen. Example of a buffer 800x480 attached to
1838   *         layer for which we want to read and display on screen only a portion 320x240 taken in the center
1839   *         of the buffer.
1840   *         The pitch in pixels will be in that case 800 pixels and not 320 pixels as initially configured by previous
1841   *         call to HAL_LTDC_ConfigLayer().
1842   * @note   This function should be called only after a previous call to HAL_LTDC_ConfigLayer() to modify the default
1843   *         pitch configured by HAL_LTDC_ConfigLayer() when required (refer to example described just above).
1844   * @param  hltdc              pointer to a LTDC_HandleTypeDef structure that contains
1845   *                            the configuration information for the LTDC.
1846   * @param  LinePitchInPixels  New line pitch in pixels to configure for LTDC layer 'LayerIdx'.
1847   * @param  LayerIdx           LTDC layer index concerned by the modification of line pitch.
1848   * @retval HAL status
1849   */
HAL_LTDC_SetPitch(LTDC_HandleTypeDef * hltdc,uint32_t LinePitchInPixels,uint32_t LayerIdx)1850 HAL_StatusTypeDef HAL_LTDC_SetPitch(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx)
1851 {
1852   uint32_t tmp;
1853   uint32_t pitchUpdate;
1854   uint32_t pixelFormat;
1855 
1856   /* Check the parameters */
1857   assert_param(IS_LTDC_LAYER(LayerIdx));
1858 
1859   /* Process locked */
1860   __HAL_LOCK(hltdc);
1861 
1862   /* Change LTDC peripheral state */
1863   hltdc->State = HAL_LTDC_STATE_BUSY;
1864 
1865   /* get LayerIdx used pixel format */
1866   pixelFormat = hltdc->LayerCfg[LayerIdx].PixelFormat;
1867 
1868   if (pixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
1869   {
1870     tmp = 4U;
1871   }
1872   else if (pixelFormat == LTDC_PIXEL_FORMAT_RGB888)
1873   {
1874     tmp = 3U;
1875   }
1876   else if ((pixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
1877            (pixelFormat == LTDC_PIXEL_FORMAT_RGB565)   || \
1878            (pixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \
1879            (pixelFormat == LTDC_PIXEL_FORMAT_AL88))
1880   {
1881     tmp = 2U;
1882   }
1883   else
1884   {
1885     tmp = 1U;
1886   }
1887 
1888   pitchUpdate = ((LinePitchInPixels * tmp) << 16U);
1889 
1890   /* Clear previously set standard pitch */
1891   LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~LTDC_LxCFBLR_CFBP;
1892 
1893   /* Set the Reload type as immediate update of LTDC pitch configured above */
1894   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1895 
1896   /* Set new line pitch value */
1897   LTDC_LAYER(hltdc, LayerIdx)->CFBLR |= pitchUpdate;
1898 
1899   /* Set the Reload type as immediate update of LTDC pitch configured above */
1900   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
1901 
1902   /* Change the LTDC state*/
1903   hltdc->State = HAL_LTDC_STATE_READY;
1904 
1905   /* Process unlocked */
1906   __HAL_UNLOCK(hltdc);
1907 
1908   return HAL_OK;
1909 }
1910 
1911 /**
1912   * @brief Sets the expected CRC value for the LTDC peripheral.
1913   *
1914   * Programs the expected Cyclic Redundancy Check (CRC) value for comparison against the CRC
1915   * generated by the LTDC peripheral. This can be used for data integrity verification during
1916   * runtime.
1917   *
1918   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
1919   *                   the configuration information for the LTDC.
1920   * @param ExpectedCRC The expected CRC value to be set for comparison. This is a 16-bit value.
1921   * @retval  HAL status
1922   */
HAL_LTDC_SetExpectedCRC(LTDC_HandleTypeDef * hltdc,uint16_t ExpectedCRC)1923 HAL_StatusTypeDef HAL_LTDC_SetExpectedCRC(LTDC_HandleTypeDef *hltdc, uint16_t ExpectedCRC)
1924 {
1925   /* Process locked */
1926   __HAL_LOCK(hltdc);
1927 
1928   /* Change LTDC peripheral state */
1929   hltdc->State = HAL_LTDC_STATE_BUSY;
1930 
1931   /* Set the expected crc value */
1932   hltdc->Instance->ECRCR = ExpectedCRC;
1933 
1934   /* Change the LTDC state*/
1935   hltdc->State = HAL_LTDC_STATE_READY;
1936 
1937   /* Process unlocked */
1938   __HAL_UNLOCK(hltdc);
1939 
1940   return HAL_OK;
1941 }
1942 
1943 /**
1944   * @brief Retrieves the computed CRC value from the LTDC peripheral.
1945   *
1946   * Obtains the CRC value computed by the LTDC peripheral for the current frame. This value can be
1947   * used to verify the integrity of the data processed by the LTDC against a known CRC value.
1948   *
1949   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration
1950   *              information for the LTDC module.
1951   * @param ComputedCRC Pointer to a uint16_t variable where the computed CRC value will be stored.
1952   * @note  To get the computed CRC for the current frame (N), this function should be called at the start
1953   *        of the first line of the next frame (N+1).
1954   *        The CRC value will remain stable until frame (N+1) is fully displayed.
1955   * @retval  HAL status
1956   */
HAL_LTDC_GetComputedCRC(LTDC_HandleTypeDef * hltdc,uint16_t * pComputedCRC)1957 HAL_StatusTypeDef HAL_LTDC_GetComputedCRC(LTDC_HandleTypeDef *hltdc, uint16_t *pComputedCRC)
1958 {
1959   /* Process locked */
1960   __HAL_LOCK(hltdc);
1961 
1962   /* Change LTDC peripheral state */
1963   hltdc->State = HAL_LTDC_STATE_BUSY;
1964 
1965   /* Get the computed crc value */
1966   *pComputedCRC = (uint16_t) hltdc->Instance->CCRCR;
1967 
1968   /* Change the LTDC state*/
1969   hltdc->State = HAL_LTDC_STATE_READY;
1970 
1971   /* Process unlocked */
1972   __HAL_UNLOCK(hltdc);
1973 
1974   return HAL_OK;
1975 }
1976 
1977 /**
1978   * @brief  Define the position of the line interrupt.
1979   * @param  hltdc   pointer to a LTDC_HandleTypeDef structure that contains
1980   *                 the configuration information for the LTDC.
1981   * @param  Line    Line Interrupt Position.
1982   * @note   User application may resort to HAL_LTDC_LineEventCallback() at line interrupt generation.
1983   * @retval  HAL status
1984   */
HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef * hltdc,uint32_t Line)1985 HAL_StatusTypeDef HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef *hltdc, uint32_t Line)
1986 {
1987   /* Check the parameters */
1988   assert_param(IS_LTDC_LIPOS(Line));
1989 
1990   /* Process locked */
1991   __HAL_LOCK(hltdc);
1992 
1993   /* Change LTDC peripheral state */
1994   hltdc->State = HAL_LTDC_STATE_BUSY;
1995 
1996   /* Disable the Line interrupt */
1997   __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_LI);
1998 
1999   /* Set the Line Interrupt position */
2000   LTDC->LIPCR = (uint32_t)Line;
2001 
2002   /* Enable the Line interrupt */
2003   __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_LI);
2004 
2005   /* Change the LTDC state*/
2006   hltdc->State = HAL_LTDC_STATE_READY;
2007 
2008   /* Process unlocked */
2009   __HAL_UNLOCK(hltdc);
2010 
2011   return HAL_OK;
2012 }
2013 
2014 /**
2015   * @brief  Reload LTDC Layers configuration.
2016   * @param  hltdc      pointer to a LTDC_HandleTypeDef structure that contains
2017   *                    the configuration information for the LTDC.
2018   * @param  ReloadType This parameter can be one of the following values :
2019   *                      LTDC_RELOAD_IMMEDIATE : Immediate Reload
2020   *                      LTDC_RELOAD_VERTICAL_BLANKING  : Reload in the next Vertical Blanking
2021   * @note   User application may resort to HAL_LTDC_ReloadEventCallback() at reload interrupt generation.
2022   * @retval  HAL status
2023   */
HAL_LTDC_Reload(LTDC_HandleTypeDef * hltdc,uint32_t ReloadType)2024 HAL_StatusTypeDef  HAL_LTDC_Reload(LTDC_HandleTypeDef *hltdc, uint32_t ReloadType)
2025 {
2026   /* Check the parameters */
2027   assert_param(IS_LTDC_RELOAD(ReloadType));
2028 
2029   /* Process locked */
2030   __HAL_LOCK(hltdc);
2031 
2032   /* Change LTDC peripheral state */
2033   hltdc->State = HAL_LTDC_STATE_BUSY;
2034 
2035   /* Enable the Reload interrupt */
2036   __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_RR);
2037 
2038   /* Apply Reload type */
2039   hltdc->Instance->SRCR = ReloadType;
2040 
2041   /* Change the LTDC state*/
2042   hltdc->State = HAL_LTDC_STATE_READY;
2043 
2044   /* Process unlocked */
2045   __HAL_UNLOCK(hltdc);
2046 
2047   return HAL_OK;
2048 }
2049 
2050 /**
2051   * @brief Reloads configuration for a specific layer of the LTDC peripheral.
2052   *
2053   * This function triggers a reload of the layer configuration for the LTDC peripheral. The type of
2054   * reload operation can be immediate or vertical blanking, as specified by the ReloadType parameter.
2055   *
2056   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration
2057   *              information for the LTDC module.
2058   * @param ReloadType Specifies the type of reload operation. This parameter can be one of the
2059   *                   following values:
2060   *                   - LTDC_RELOAD_IMMEDIATE: Perform an immediate reload.
2061   *                   - LTDC_RELOAD_VERTICAL_BLANKING: Perform the reload during the vertical blanking
2062   *                     period.
2063   * @param LayerIdx Specifies the index of the layer to be reloaded. This parameter can be one of the
2064   *                 following values:
2065   *                 - LTDC_LAYER_1: Reload configuration for layer 1.
2066   *                 - LTDC_LAYER_2: Reload configuration for layer 2.
2067   * @note   User application may resort to HAL_LTDC_ReloadEventCallback() at reload interrupt generation.
2068   * @retval  HAL status
2069   */
HAL_LTDC_ReloadLayer(LTDC_HandleTypeDef * hltdc,uint32_t ReloadType,uint32_t LayerIdx)2070 HAL_StatusTypeDef HAL_LTDC_ReloadLayer(LTDC_HandleTypeDef *hltdc, uint32_t ReloadType, uint32_t LayerIdx)
2071 {
2072   /* Check the parameters */
2073   assert_param(IS_LTDC_RELOAD(ReloadType));
2074 
2075   /* Process locked */
2076   __HAL_LOCK(hltdc);
2077 
2078   /* Change LTDC peripheral state */
2079   hltdc->State = HAL_LTDC_STATE_BUSY;
2080 
2081   /* Enable the Reload interrupt */
2082   __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_RR);
2083 
2084   /* Apply Reload type */
2085   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, ReloadType | LTDC_LxRCR_GRMSK);
2086 
2087   /* Change the LTDC state*/
2088   hltdc->State = HAL_LTDC_STATE_READY;
2089 
2090   /* Process unlocked */
2091   __HAL_UNLOCK(hltdc);
2092 
2093   return HAL_OK;
2094 }
2095 
2096 /**
2097   * @brief Sets the display output format for the LTDC peripheral.
2098   *
2099   * Configures the LTDC peripheral to output in a specified format. This function allows for the
2100   * selection of different color encoding formats, including RGB and YUV/YVU with specific conversion
2101   * standards.
2102   *
2103   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration
2104   *              information for the LTDC module.
2105   * @param Display Specifies the display output format to be selected. This parameter can be one of
2106   *                the following values:
2107   *                - LTDC_OUT_RGB: Output in RGB format.
2108   *                - LTDC_OUT_YUV_HDTV: Output in YUV format using BT.709 conversion (HDTV standard).
2109   *                - LTDC_OUT_YUV_SDTV: Output in YUV format using BT.601 conversion (SDTV standard).
2110   *                - LTDC_OUT_YVU_HDTV: Output in YVU format using BT.709 conversion (HDTV standard).
2111   *                - LTDC_OUT_YVU_SDTV: Output in YVU format using BT.601 conversion (SDTV standard).
2112   * @retval  HAL status
2113   */
HAL_LTDC_SetOutputDisplay(LTDC_HandleTypeDef * hltdc,uint32_t Display)2114 HAL_StatusTypeDef HAL_LTDC_SetOutputDisplay(LTDC_HandleTypeDef *hltdc, uint32_t Display)
2115 {
2116   /* Check the parameters */
2117   assert_param(IS_LTDC_DISPLAY(Display));
2118 
2119   /* Process locked */
2120   __HAL_LOCK(hltdc);
2121 
2122   /* Change LTDC peripheral state */
2123   hltdc->State = HAL_LTDC_STATE_BUSY;
2124 
2125   /* Configure the output format */
2126   hltdc->Instance->EDCR = Display;
2127 
2128   /* Change the LTDC state*/
2129   hltdc->State = HAL_LTDC_STATE_READY;
2130 
2131   /* Process unlocked */
2132   __HAL_UNLOCK(hltdc);
2133 
2134   return HAL_OK;
2135 }
2136 
2137 /**
2138   * @brief  Configure the LTDC Layer according to the specified without reloading
2139   *         parameters in the LTDC_InitTypeDef and create the associated handle.
2140   *         Variant of the function HAL_LTDC_ConfigLayer without immediate reload.
2141   * @param  hltdc      pointer to a LTDC_HandleTypeDef structure that contains
2142   *                    the configuration information for the LTDC.
2143   * @param  pLayerCfg  pointer to a LTDC_LayerCfgTypeDef structure that contains
2144   *                    the configuration information for the Layer.
2145   * @param  LayerIdx   LTDC Layer index.
2146   *                    This parameter can be one of the following values:
2147   *                    LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2148   * @retval HAL status
2149   */
HAL_LTDC_ConfigLayer_NoReload(LTDC_HandleTypeDef * hltdc,LTDC_LayerCfgTypeDef * pLayerCfg,uint32_t LayerIdx)2150 HAL_StatusTypeDef HAL_LTDC_ConfigLayer_NoReload(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg,
2151                                                 uint32_t LayerIdx)
2152 {
2153   /* Check the parameters */
2154   assert_param(IS_LTDC_LAYER(LayerIdx));
2155   assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0));
2156   assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1));
2157   assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0));
2158   assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1));
2159   assert_param(IS_LTDC_PIXEL_FORMAT(pLayerCfg->PixelFormat));
2160   assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha));
2161   assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha0));
2162   assert_param(IS_LTDC_BLENDING_FACTOR1(pLayerCfg->BlendingFactor1));
2163   assert_param(IS_LTDC_BLENDING_FACTOR2(pLayerCfg->BlendingFactor2));
2164   assert_param(IS_LTDC_CFBLL(pLayerCfg->ImageWidth));
2165   assert_param(IS_LTDC_CFBLNBR(pLayerCfg->ImageHeight));
2166 
2167   /* Process locked */
2168   __HAL_LOCK(hltdc);
2169 
2170   /* Change LTDC peripheral state */
2171   hltdc->State = HAL_LTDC_STATE_BUSY;
2172 
2173   /* Copy new layer configuration into handle structure */
2174   hltdc->LayerCfg[LayerIdx] = *pLayerCfg;
2175 
2176   /* Configure Predefined format */
2177   LTDC_SetPredefFormat(hltdc, LayerIdx);
2178 
2179   /* Configure composition and blending*/
2180   LTDC_SetCompositionConfig(hltdc, LayerIdx);
2181 
2182   /* Configure the LTDC Layer */
2183   LTDC_SetConfig(hltdc, 0U, 0U, LTDC_MIRROR_NONE, LayerIdx);
2184 
2185   /* Initialize the LTDC state*/
2186   hltdc->State  = HAL_LTDC_STATE_READY;
2187 
2188   /* Process unlocked */
2189   __HAL_UNLOCK(hltdc);
2190 
2191   return HAL_OK;
2192 }
2193 
2194 /**
2195   * @brief  Set the LTDC window size without reloading.
2196   *         Variant of the function HAL_LTDC_SetWindowSize without immediate reload.
2197   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2198   *                   the configuration information for the LTDC.
2199   * @param  XSize     LTDC Pixel per line
2200   * @param  YSize     LTDC Line number
2201   * @param  LayerIdx  LTDC Layer index.
2202   *                   This parameter can be one of the following values:
2203   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2204   * @retval  HAL status
2205   */
HAL_LTDC_SetWindowSize_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t XSize,uint32_t YSize,uint32_t LayerIdx)2206 HAL_StatusTypeDef HAL_LTDC_SetWindowSize_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize,
2207                                                   uint32_t LayerIdx)
2208 {
2209   uint32_t aux0Addr = 0U;
2210   uint32_t aux1Addr = 0U;
2211   uint32_t mirror = 0U;
2212 
2213   /* Check the parameters (Layers parameters)*/
2214   assert_param(IS_LTDC_LAYER(LayerIdx));
2215   assert_param(IS_LTDC_CFBLL(XSize));
2216   assert_param(IS_LTDC_CFBLNBR(YSize));
2217 
2218   /* Process locked */
2219   __HAL_LOCK(hltdc);
2220 
2221   /* Change LTDC peripheral state */
2222   hltdc->State = HAL_LTDC_STATE_BUSY;
2223 
2224   /* Get previous user configuration */
2225   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2226 
2227   /* update horizontal stop */
2228   hltdc->LayerCfg[LayerIdx].WindowX1 = XSize + hltdc->LayerCfg[LayerIdx].WindowX0;
2229 
2230   /* update vertical stop */
2231   hltdc->LayerCfg[LayerIdx].WindowY1 = YSize + hltdc->LayerCfg[LayerIdx].WindowY0;
2232 
2233   /* Reconfigures the color frame buffer pitch in byte */
2234   hltdc->LayerCfg[LayerIdx].ImageWidth = XSize;
2235 
2236   /* Reconfigures the frame buffer line number */
2237   hltdc->LayerCfg[LayerIdx].ImageHeight = YSize;
2238 
2239   /* Set LTDC parameters */
2240   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
2241 
2242   /* Change the LTDC state*/
2243   hltdc->State = HAL_LTDC_STATE_READY;
2244 
2245   /* Process unlocked */
2246   __HAL_UNLOCK(hltdc);
2247 
2248   return HAL_OK;
2249 }
2250 
2251 /**
2252   * @brief  Set the LTDC window position without reloading.
2253   *         Variant of the function HAL_LTDC_SetWindowPosition without immediate reload.
2254   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2255   *                   the configuration information for the LTDC.
2256   * @param  X0        LTDC window X offset
2257   * @param  Y0        LTDC window Y offset
2258   * @param  LayerIdx  LTDC Layer index.
2259   *                         This parameter can be one of the following values:
2260   *                         LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2261   * @retval  HAL status
2262   */
HAL_LTDC_SetWindowPosition_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t X0,uint32_t Y0,uint32_t LayerIdx)2263 HAL_StatusTypeDef HAL_LTDC_SetWindowPosition_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0,
2264                                                       uint32_t LayerIdx)
2265 {
2266   uint32_t aux0Addr = 0U;
2267   uint32_t aux1Addr = 0U;
2268   uint32_t mirror = 0U;
2269 
2270   /* Check the parameters */
2271   assert_param(IS_LTDC_LAYER(LayerIdx));
2272   assert_param(IS_LTDC_CFBLL(X0));
2273   assert_param(IS_LTDC_CFBLNBR(Y0));
2274 
2275   /* Process locked */
2276   __HAL_LOCK(hltdc);
2277 
2278   /* Change LTDC peripheral state */
2279   hltdc->State = HAL_LTDC_STATE_BUSY;
2280 
2281   /* Get previous user configuration */
2282   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2283 
2284   /* update horizontal start/stop */
2285   hltdc->LayerCfg[LayerIdx].WindowX0 = X0;
2286   hltdc->LayerCfg[LayerIdx].WindowX1 = X0 + hltdc->LayerCfg[LayerIdx].ImageWidth;
2287 
2288   /* update vertical start/stop */
2289   hltdc->LayerCfg[LayerIdx].WindowY0 = Y0;
2290   hltdc->LayerCfg[LayerIdx].WindowY1 = Y0 + hltdc->LayerCfg[LayerIdx].ImageHeight;
2291 
2292   /* Set LTDC parameters */
2293   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
2294 
2295   /* Change the LTDC state*/
2296   hltdc->State = HAL_LTDC_STATE_READY;
2297 
2298   /* Process unlocked */
2299   __HAL_UNLOCK(hltdc);
2300 
2301   return HAL_OK;
2302 }
2303 
2304 /**
2305   * @brief  Reconfigure the pixel format without reloading.
2306   *         Variant of the function HAL_LTDC_SetPixelFormat without immediate reload.
2307   * @param  hltdc        pointer to a LTDC_HandleTypeDfef structure that contains
2308   *                      the configuration information for the LTDC.
2309   * @param  Pixelformat  new pixel format value.
2310   * @param  LayerIdx     LTDC Layer index.
2311   *                      This parameter can be one of the following values:
2312   *                      LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
2313   * @retval  HAL status
2314   */
HAL_LTDC_SetPixelFormat_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t Pixelformat,uint32_t LayerIdx)2315 HAL_StatusTypeDef HAL_LTDC_SetPixelFormat_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx)
2316 {
2317   uint32_t aux0Addr = 0U;
2318   uint32_t aux1Addr = 0U;
2319   uint32_t mirror = 0U;
2320 
2321   /* Check the parameters */
2322   assert_param(IS_LTDC_PIXEL_FORMAT(Pixelformat));
2323   assert_param(IS_LTDC_LAYER(LayerIdx));
2324 
2325   /* Process locked */
2326   __HAL_LOCK(hltdc);
2327 
2328   /* Change LTDC peripheral state */
2329   hltdc->State = HAL_LTDC_STATE_BUSY;
2330 
2331   /* Get previous user configuration */
2332   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2333 
2334   /* Reconfigure the pixel format */
2335   hltdc->LayerCfg[LayerIdx].PixelFormat = Pixelformat;
2336 
2337   /* Set LTDC parameters */
2338   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, mirror, LayerIdx);
2339 
2340   /* Set LTDC format */
2341   LTDC_SetPredefFormat(hltdc, LayerIdx);
2342 
2343   /* Change the LTDC state*/
2344   hltdc->State = HAL_LTDC_STATE_READY;
2345 
2346   /* Process unlocked */
2347   __HAL_UNLOCK(hltdc);
2348 
2349   return HAL_OK;
2350 }
2351 
2352 /**
2353   * @brief  Reconfigure the layer alpha value without reloading.
2354   *         Variant of the function HAL_LTDC_SetAlpha without immediate reload.
2355   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2356   *                   the configuration information for the LTDC.
2357   * @param  Alpha     new alpha value.
2358   * @param  LayerIdx  LTDC Layer index.
2359   *                   This parameter can be one of the following values:
2360   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2361   * @retval  HAL status
2362   */
HAL_LTDC_SetAlpha_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t Alpha,uint32_t LayerIdx)2363 HAL_StatusTypeDef HAL_LTDC_SetAlpha_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx)
2364 {
2365   /* Check the parameters */
2366   assert_param(IS_LTDC_ALPHA(Alpha));
2367   assert_param(IS_LTDC_LAYER(LayerIdx));
2368 
2369   /* Process locked */
2370   __HAL_LOCK(hltdc);
2371 
2372   /* Change LTDC peripheral state */
2373   hltdc->State = HAL_LTDC_STATE_BUSY;
2374 
2375   /* Specifies the constant alpha value */
2376   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CACR, Alpha);
2377 
2378   /* Change the LTDC state*/
2379   hltdc->State = HAL_LTDC_STATE_READY;
2380 
2381   /* Process unlocked */
2382   __HAL_UNLOCK(hltdc);
2383 
2384   return HAL_OK;
2385 }
2386 
2387 /**
2388   * @brief  Reconfigure the frame buffer Address without reloading.
2389   *         Variant of the function HAL_LTDC_SetAddress without immediate reload.
2390   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2391   *                   the configuration information for the LTDC.
2392   * @param  Address   new address value.
2393   * @param  LayerIdx  LTDC Layer index.
2394   *                   This parameter can be one of the following values:
2395   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
2396   * @retval  HAL status
2397   */
HAL_LTDC_SetAddress_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t Address,uint32_t LayerIdx)2398 HAL_StatusTypeDef HAL_LTDC_SetAddress_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx)
2399 {
2400   uint32_t aux0Addr = 0U;
2401   uint32_t aux1Addr = 0U;
2402   uint32_t mirror = 0U;
2403 
2404   /* Check the parameters */
2405   assert_param(IS_LTDC_LAYER(LayerIdx));
2406 
2407   /* Process locked */
2408   __HAL_LOCK(hltdc);
2409 
2410   /* Change LTDC peripheral state */
2411   hltdc->State = HAL_LTDC_STATE_BUSY;
2412 
2413   /* Get previous user configuration */
2414   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2415 
2416   /* Reconfigure the Address */
2417   hltdc->LayerCfg[LayerIdx].FBStartAdress = Address;
2418 
2419   /* Set LTDC parameters */
2420   LTDC_SetConfig(hltdc, 0, 0, mirror, LayerIdx);
2421 
2422   /* Change the LTDC state*/
2423   hltdc->State = HAL_LTDC_STATE_READY;
2424 
2425   /* Process unlocked */
2426   __HAL_UNLOCK(hltdc);
2427 
2428   return HAL_OK;
2429 }
2430 
2431 /**
2432   * @brief  Function used to reconfigure the pitch for specific cases where the attached LayerIdx buffer have a width
2433   *         that is larger than the one intended to be displayed on screen. Example of a buffer 800x480 attached to
2434   *         layer for which we want to read and display on screen only a portion 320x240 taken in the center
2435   *         of the buffer.
2436   *         The pitch in pixels will be in that case 800 pixels and not 320 pixels as initially configured by
2437   *         previous call to HAL_LTDC_ConfigLayer().
2438   * @note   This function should be called only after a previous call to HAL_LTDC_ConfigLayer() to modify the default
2439   *         pitch configured by HAL_LTDC_ConfigLayer() when required (refer to example described just above).
2440   *         Variant of the function HAL_LTDC_SetPitch without immediate reload.
2441   * @param  hltdc              pointer to a LTDC_HandleTypeDef structure that contains
2442   *                            the configuration information for the LTDC.
2443   * @param  LinePitchInPixels  New line pitch in pixels to configure for LTDC layer 'LayerIdx'.
2444   * @param  LayerIdx           LTDC layer index concerned by the modification of line pitch.
2445   * @retval HAL status
2446   */
HAL_LTDC_SetPitch_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t LinePitchInPixels,uint32_t LayerIdx)2447 HAL_StatusTypeDef HAL_LTDC_SetPitch_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LinePitchInPixels, uint32_t LayerIdx)
2448 {
2449   uint32_t tmp;
2450   uint32_t pitchUpdate;
2451   uint32_t pixelFormat;
2452 
2453   /* Check the parameters */
2454   assert_param(IS_LTDC_LAYER(LayerIdx));
2455 
2456   /* Process locked */
2457   __HAL_LOCK(hltdc);
2458 
2459   /* Change LTDC peripheral state */
2460   hltdc->State = HAL_LTDC_STATE_BUSY;
2461 
2462   /* get LayerIdx used pixel format */
2463   pixelFormat = hltdc->LayerCfg[LayerIdx].PixelFormat;
2464 
2465   if (pixelFormat == LTDC_PIXEL_FORMAT_ARGB8888)
2466   {
2467     tmp = 4U;
2468   }
2469   else if (pixelFormat == LTDC_PIXEL_FORMAT_RGB888)
2470   {
2471     tmp = 3U;
2472   }
2473   else if ((pixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \
2474            (pixelFormat == LTDC_PIXEL_FORMAT_RGB565)   || \
2475            (pixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \
2476            (pixelFormat == LTDC_PIXEL_FORMAT_AL88))
2477   {
2478     tmp = 2U;
2479   }
2480   else
2481   {
2482     tmp = 1U;
2483   }
2484 
2485   pitchUpdate = ((LinePitchInPixels * tmp) << 16U);
2486 
2487   /* Clear previously set standard pitch */
2488   LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~LTDC_LxCFBLR_CFBP;
2489 
2490   /* Set new line pitch value */
2491   LTDC_LAYER(hltdc, LayerIdx)->CFBLR |= pitchUpdate;
2492 
2493   /* Change the LTDC state*/
2494   hltdc->State = HAL_LTDC_STATE_READY;
2495 
2496   /* Process unlocked */
2497   __HAL_UNLOCK(hltdc);
2498 
2499   return HAL_OK;
2500 }
2501 
2502 /**
2503   * @brief  Enable the color keying without reloading.
2504   *         Variant of the function HAL_LTDC_EnableColorKeying without immediate reload.
2505   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2506   *                   the configuration information for the LTDC.
2507   * @param  LayerIdx  LTDC Layer index.
2508   *                   This parameter can be one of the following values:
2509   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2510   * @retval  HAL status
2511   */
HAL_LTDC_EnableColorKeying_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)2512 HAL_StatusTypeDef HAL_LTDC_EnableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
2513 {
2514   /* Check the parameters */
2515   assert_param(IS_LTDC_LAYER(LayerIdx));
2516 
2517   /* Process locked */
2518   __HAL_LOCK(hltdc);
2519 
2520   /* Change LTDC peripheral state */
2521   hltdc->State = HAL_LTDC_STATE_BUSY;
2522 
2523   /* Enable LTDC color keying by setting COLKEN bit */
2524   LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CKEN;
2525 
2526   /* Change the LTDC state*/
2527   hltdc->State = HAL_LTDC_STATE_READY;
2528 
2529   /* Process unlocked */
2530   __HAL_UNLOCK(hltdc);
2531 
2532   return HAL_OK;
2533 }
2534 
2535 /**
2536   * @brief  Disable the color keying without reloading.
2537   *         Variant of the function HAL_LTDC_DisableColorKeying without immediate reload.
2538   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2539   *                   the configuration information for the LTDC.
2540   * @param  LayerIdx  LTDC Layer index.
2541   *                   This parameter can be one of the following values:
2542   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2543   * @retval  HAL status
2544   */
HAL_LTDC_DisableColorKeying_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)2545 HAL_StatusTypeDef HAL_LTDC_DisableColorKeying_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
2546 {
2547   /* Check the parameters */
2548   assert_param(IS_LTDC_LAYER(LayerIdx));
2549 
2550   /* Process locked */
2551   __HAL_LOCK(hltdc);
2552 
2553   /* Change LTDC peripheral state */
2554   hltdc->State = HAL_LTDC_STATE_BUSY;
2555 
2556   /* Disable LTDC color keying by setting COLKEN bit */
2557   LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CKEN;
2558 
2559   /* Change the LTDC state*/
2560   hltdc->State = HAL_LTDC_STATE_READY;
2561 
2562   /* Process unlocked */
2563   __HAL_UNLOCK(hltdc);
2564 
2565   return HAL_OK;
2566 }
2567 
2568 /**
2569   * @brief  Enable the color lookup table without reloading.
2570   *         Variant of the function HAL_LTDC_EnableCLUT without immediate reload.
2571   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2572   *                   the configuration information for the LTDC.
2573   * @param  LayerIdx  LTDC Layer index.
2574   *                   This parameter can be one of the following values:
2575   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2576   * @retval  HAL status
2577   */
HAL_LTDC_EnableCLUT_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)2578 HAL_StatusTypeDef HAL_LTDC_EnableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
2579 {
2580   /* Check the parameters */
2581   assert_param(IS_LTDC_LAYER(LayerIdx));
2582 
2583   /* Process locked */
2584   __HAL_LOCK(hltdc);
2585 
2586   /* Change LTDC peripheral state */
2587   hltdc->State = HAL_LTDC_STATE_BUSY;
2588 
2589   /* Disable LTDC color lookup table by setting CLUTEN bit */
2590   LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CLUTEN;
2591 
2592   /* Change the LTDC state*/
2593   hltdc->State = HAL_LTDC_STATE_READY;
2594 
2595   /* Process unlocked */
2596   __HAL_UNLOCK(hltdc);
2597 
2598   return HAL_OK;
2599 }
2600 
2601 /**
2602   * @brief  Disable the color lookup table without reloading.
2603   *         Variant of the function HAL_LTDC_DisableCLUT without immediate reload.
2604   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
2605   *                   the configuration information for the LTDC.
2606   * @param  LayerIdx  LTDC Layer index.
2607   *                   This parameter can be one of the following values:
2608   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
2609   * @retval  HAL status
2610   */
HAL_LTDC_DisableCLUT_NoReload(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)2611 HAL_StatusTypeDef HAL_LTDC_DisableCLUT_NoReload(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
2612 {
2613   /* Check the parameters */
2614   assert_param(IS_LTDC_LAYER(LayerIdx));
2615 
2616   /* Process locked */
2617   __HAL_LOCK(hltdc);
2618 
2619   /* Change LTDC peripheral state */
2620   hltdc->State = HAL_LTDC_STATE_BUSY;
2621 
2622   /* Disable LTDC color lookup table by setting CLUTEN bit */
2623   LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CLUTEN;
2624 
2625   /* Change the LTDC state*/
2626   hltdc->State = HAL_LTDC_STATE_READY;
2627 
2628   /* Process unlocked */
2629   __HAL_UNLOCK(hltdc);
2630 
2631   return HAL_OK;
2632 }
2633 
2634 /**
2635   * @}
2636   */
2637 
2638 /** @defgroup LTDC_Exported_Functions_Group4 Peripheral State and Errors functions
2639   *  @brief    Peripheral State and Errors functions
2640   *
2641 @verbatim
2642  ===============================================================================
2643                   ##### Peripheral State and Errors functions #####
2644  ===============================================================================
2645     [..]
2646     This subsection provides functions allowing to
2647       (+) Check the LTDC handle state.
2648       (+) Get the LTDC handle error code.
2649 
2650 @endverbatim
2651   * @{
2652   */
2653 
2654 /**
2655   * @brief  Return the LTDC handle state.
2656   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
2657   *                the configuration information for the LTDC.
2658   * @retval HAL state
2659   */
HAL_LTDC_GetState(const LTDC_HandleTypeDef * hltdc)2660 HAL_LTDC_StateTypeDef HAL_LTDC_GetState(const LTDC_HandleTypeDef *hltdc)
2661 {
2662   return hltdc->State;
2663 }
2664 
2665 /**
2666   * @brief  Return the LTDC handle error code.
2667   * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
2668   *               the configuration information for the LTDC.
2669   * @retval LTDC Error Code
2670   */
HAL_LTDC_GetError(const LTDC_HandleTypeDef * hltdc)2671 uint32_t HAL_LTDC_GetError(const LTDC_HandleTypeDef *hltdc)
2672 {
2673   return hltdc->ErrorCode;
2674 }
2675 
2676 /**
2677   * @}
2678   */
2679 
2680 /**
2681   * @}
2682   */
2683 
2684 /** @defgroup LTDC_Private_Functions LTDC Private Functions
2685   * @{
2686   */
2687 
2688 
2689 /**
2690   * @brief Reconfigure the full planar memory addresses for a YUV layer in the LTDC peripheral.
2691   *
2692   * Configures the memory addresses for the Y, U, and V planes of a full planar YUV layer. This function
2693   * is used when the Layer is operating in a full planar mode, where the Y, U, and V components are stored in
2694   * separate memory areas. It allows for dynamic updating of the frame buffer addresses.
2695   *
2696   * @note This function is applicable only to LTDC_LAYER_1.
2697   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2698   *              for the LTDC module.
2699   * @param pYUVFullPlanarAddress Pointer to a LTDC_LayerFlexYUVFullPlanarTypeDef structure that holds
2700   *                              the memory addresses for the Y, U, and V planes.
2701   * @param  LayerIdx  Specifies the index of the layer being configured. For this function, the only
2702   *                 valid value is LTDC_LAYER_1.
2703   * @retval  HAL status
2704   */
HAL_LTDC_SetFullPlanarAddress(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVFullPlanarTypeDef * pYUVFullPlanarAddress,uint32_t LayerIdx)2705 HAL_StatusTypeDef HAL_LTDC_SetFullPlanarAddress(LTDC_HandleTypeDef *hltdc,
2706                                                 LTDC_LayerFlexYUVFullPlanarTypeDef *pYUVFullPlanarAddress,
2707                                                 uint32_t LayerIdx)
2708 {
2709   uint32_t aux0Addr = 0U;
2710   uint32_t aux1Addr = 0U;
2711   uint32_t mirror = 0U;
2712 
2713   /* Check the parameters */
2714   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
2715 
2716   /* Process locked */
2717   __HAL_LOCK(hltdc);
2718 
2719   /* Change LTDC peripheral state */
2720   hltdc->State = HAL_LTDC_STATE_BUSY;
2721 
2722   /* Get previous user configuration */
2723   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2724 
2725   /* Update LayerCfg structure with required parameters */
2726   hltdc->LayerCfg[LayerIdx].FBStartAdress = pYUVFullPlanarAddress->YUVFullPlanarAddress.YAddress;
2727 
2728   /* Set LTDC parameters */
2729   LTDC_SetConfig(hltdc, pYUVFullPlanarAddress->YUVFullPlanarAddress.UAddress,
2730                  pYUVFullPlanarAddress->YUVFullPlanarAddress.VAddress, mirror, LayerIdx);
2731 
2732   /* Set the Immediate Reload type */
2733   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
2734 
2735   /* Change the LTDC state*/
2736   hltdc->State = HAL_LTDC_STATE_READY;
2737 
2738   /* Process unlocked */
2739   __HAL_UNLOCK(hltdc);
2740 
2741   return HAL_OK;
2742 }
2743 
2744 /**
2745   * @brief Reconfigure the semi-planar memory addresses for a YUV layer in the LTDC peripheral.
2746   *
2747   * Configures the memory addresses for the Y plane and the combined U/V plane of a semi-planar YUV layer.
2748   * This function is used when the Layer is operating in a semi-planar mode, where the Y component and the
2749   * U/V components are stored in separate memory areas, allowing dynamic updates of the frame buffer addresses.
2750   *
2751   * @note This function is applicable only to LTDC_LAYER_1.
2752   *
2753   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2754   *              for the LTDC module.
2755   * @param pYUVSemiPlanarAddress Pointer to an LTDC_LayerFlexYUVSemiPlanarTypeDef structure that holds
2756   *                              the memory addresses for the Y plane and the combined U/V plane.
2757   * @param LayerIdx Specifies the index of the layer being configured. For this function, the only
2758   *                 valid value is LTDC_LAYER_1.
2759   * @retval  HAL status
2760   */
HAL_LTDC_SetSemiPlanarAddress(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVSemiPlanarTypeDef * pYUVSemiPlanarAddress,uint32_t LayerIdx)2761 HAL_StatusTypeDef HAL_LTDC_SetSemiPlanarAddress(LTDC_HandleTypeDef *hltdc,
2762                                                 LTDC_LayerFlexYUVSemiPlanarTypeDef *pYUVSemiPlanarAddress,
2763                                                 uint32_t LayerIdx)
2764 {
2765   uint32_t aux0Addr = 0U;
2766   uint32_t aux1Addr = 0U;
2767   uint32_t mirror = 0U;
2768 
2769   /* Check the parameters */
2770   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
2771 
2772   /* Process locked */
2773   __HAL_LOCK(hltdc);
2774 
2775   /* Change LTDC peripheral state */
2776   hltdc->State = HAL_LTDC_STATE_BUSY;
2777 
2778   /* Get previous user configuration */
2779   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2780 
2781   /* Update handle */
2782   hltdc->LayerCfg[LayerIdx].FBStartAdress = pYUVSemiPlanarAddress->YUVSemiPlanarAddress.YAddress;
2783 
2784   /* Set LTDC parameters */
2785   LTDC_SetConfig(hltdc, pYUVSemiPlanarAddress->YUVSemiPlanarAddress.UVAddress, 0, mirror, LayerIdx);
2786 
2787   /* Set the Immediate Reload type */
2788   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
2789 
2790   /* Change the LTDC state*/
2791   hltdc->State = HAL_LTDC_STATE_READY;
2792 
2793   /* Process unlocked */
2794   __HAL_UNLOCK(hltdc);
2795 
2796   return HAL_OK;
2797 }
2798 
2799 /**
2800   * @brief Reconfigure the full planar memory addresses for a YUV layer in the LTDC peripheral with no reload.
2801   *
2802   * Configures the memory addresses for the Y, U, and V planes of a full planar YUV layer. This function
2803   * is used when the Layer is operating in a full planar mode, where the Y, U, and V components are stored in
2804   * separate memory areas. It allows for dynamic updating of the frame buffer addresses.
2805   *
2806   * @note This function is applicable only to LTDC_LAYER_1.
2807   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2808   *              for the LTDC module.
2809   * @param pYUVFullPlanarAddress Pointer to a LTDC_LayerFlexYUVFullPlanarTypeDef structure that holds
2810   *                              the memory addresses for the Y, U, and V planes.
2811   * @param  LayerIdx  Specifies the index of the layer being configured. For this function, the only
2812   *                 valid value is LTDC_LAYER_1.
2813   * @retval  HAL status
2814   */
HAL_LTDC_SetFullPlanarAddress_NoReload(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVFullPlanarTypeDef * pYUVFullPlanarAddress,uint32_t LayerIdx)2815 HAL_StatusTypeDef HAL_LTDC_SetFullPlanarAddress_NoReload(LTDC_HandleTypeDef *hltdc,
2816                                                          LTDC_LayerFlexYUVFullPlanarTypeDef *pYUVFullPlanarAddress,
2817                                                          uint32_t LayerIdx)
2818 {
2819   uint32_t mirror = 0U;
2820   uint32_t aux0Addr = 0U;
2821   uint32_t aux1Addr = 0U;
2822 
2823   /* Check the parameters */
2824   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
2825 
2826   /* Process locked */
2827   __HAL_LOCK(hltdc);
2828 
2829   /* Change LTDC peripheral state */
2830   hltdc->State = HAL_LTDC_STATE_BUSY;
2831 
2832   /* Get previous user configuration */
2833   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2834 
2835   /* Update LayerCfg structure with required parameters */
2836   hltdc->LayerCfg[LayerIdx].FBStartAdress = pYUVFullPlanarAddress->YUVFullPlanarAddress.YAddress;
2837 
2838   /* Set LTDC parameters */
2839   LTDC_SetConfig(hltdc, pYUVFullPlanarAddress->YUVFullPlanarAddress.UAddress,
2840                  pYUVFullPlanarAddress->YUVFullPlanarAddress.VAddress, mirror, LayerIdx);
2841 
2842   /* Change the LTDC state*/
2843   hltdc->State = HAL_LTDC_STATE_READY;
2844 
2845   /* Process unlocked */
2846   __HAL_UNLOCK(hltdc);
2847 
2848   return HAL_OK;
2849 }
2850 
2851 /**
2852   * @brief Reconfigure the semi-planar memory addresses for a YUV layer in the LTDC peripheral without reload.
2853   *
2854   * Configures the memory addresses for the Y plane and the combined U/V plane of a semi-planar YUV layer.
2855   * This function is used when the Layer is operating in a semi-planar mode, where the Y component and the
2856   * U/V components are stored in separate memory areas, allowing dynamic updates of the frame buffer addresses.
2857   *
2858   * @note This function is applicable only to LTDC_LAYER_1.
2859   *
2860   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2861   *              for the LTDC module.
2862   * @param pYUVSemiPlanarAddress Pointer to an LTDC_LayerFlexYUVSemiPlanarTypeDef structure that holds
2863   *                              the memory addresses for the Y plane and the combined U/V plane.
2864   * @param LayerIdx Specifies the index of the layer being configured. For this function, the only
2865   *                 valid value is LTDC_LAYER_1.
2866   * @retval  HAL status
2867   */
HAL_LTDC_SetSemiPlanarAddress_NoReload(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVSemiPlanarTypeDef * pYUVSemiPlanarAddress,uint32_t LayerIdx)2868 HAL_StatusTypeDef HAL_LTDC_SetSemiPlanarAddress_NoReload(LTDC_HandleTypeDef *hltdc,
2869                                                          LTDC_LayerFlexYUVSemiPlanarTypeDef *pYUVSemiPlanarAddress,
2870                                                          uint32_t LayerIdx)
2871 {
2872   uint32_t aux0Addr = 0U;
2873   uint32_t aux1Addr = 0U;
2874   uint32_t mirror = 0U;
2875 
2876   /* Check the parameters */
2877   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
2878 
2879   /* Process locked */
2880   __HAL_LOCK(hltdc);
2881 
2882   /* Change LTDC peripheral state */
2883   hltdc->State = HAL_LTDC_STATE_BUSY;
2884 
2885   /* Get previous user configuration */
2886   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2887 
2888   /* Update handle */
2889   hltdc->LayerCfg[LayerIdx].FBStartAdress = pYUVSemiPlanarAddress->YUVSemiPlanarAddress.YAddress;
2890 
2891   /* Set LTDC parameters */
2892   LTDC_SetConfig(hltdc, pYUVSemiPlanarAddress->YUVSemiPlanarAddress.UVAddress, 0, mirror, LayerIdx);
2893 
2894   /* Change the LTDC state*/
2895   hltdc->State = HAL_LTDC_STATE_READY;
2896 
2897   /* Process unlocked */
2898   __HAL_UNLOCK(hltdc);
2899 
2900   return HAL_OK;
2901 }
2902 
2903 /**
2904   * @brief Configures the mirroring effect for a specific layer in the LTDC peripheral.
2905   *
2906   * This function sets the mirroring effect for the specified layer of the LTDC. It can configure the
2907   * layer to mirror the image horizontally, vertically, both horizontally and vertically, or not at all.
2908   *
2909   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2910   *              for the LTDC module.
2911   * @param Mirror Specifies the mirroring effect to be applied. This parameter can be one of the
2912   *               following values:
2913   *               - LTDC_MIRROR_HORIZONTAL: Apply horizontal mirroring to the layer.
2914   *               - LTDC_MIRROR_VERTICAL: Apply vertical mirroring to the layer.
2915   *               - LTDC_MIRROR_HORIZONTAL_VERTICAL: Apply both horizontal and vertical mirroring to
2916   *                 the layer.
2917   *               - LTDC_MIRROR_NONE: No mirroring is applied to the layer.
2918   * @param  LayerIdx  LTDC Layer index.
2919   *                   This parameter can be one of the following values:
2920   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
2921   * @retval  HAL status
2922   */
HAL_LTDC_ConfigMirror(LTDC_HandleTypeDef * hltdc,uint32_t Mirror,uint32_t LayerIdx)2923 HAL_StatusTypeDef HAL_LTDC_ConfigMirror(LTDC_HandleTypeDef *hltdc, uint32_t Mirror, uint32_t LayerIdx)
2924 {
2925   uint32_t aux0Addr = 0U;
2926   uint32_t aux1Addr = 0U;
2927   uint32_t mirror = 0U;
2928 
2929   /* Check the parameters */
2930   assert_param(IS_LTDC_LAYER(LayerIdx));
2931 
2932   /* Process locked */
2933   __HAL_LOCK(hltdc);
2934 
2935   /* Change LTDC peripheral state */
2936   hltdc->State = HAL_LTDC_STATE_BUSY;
2937 
2938   /* Get previous user configuration */
2939   LTDC_RetrieveUserConfig(hltdc, &mirror, &aux0Addr, &aux1Addr, LayerIdx);
2940 
2941   /* Set LTDC parameters */
2942   LTDC_SetConfig(hltdc, aux0Addr, aux1Addr, Mirror, LayerIdx);
2943 
2944   /* Set the Immediate Reload type */
2945   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
2946 
2947   /* Change the LTDC state*/
2948   hltdc->State = HAL_LTDC_STATE_READY;
2949 
2950   /* Process unlocked */
2951   __HAL_UNLOCK(hltdc);
2952 
2953   return HAL_OK;
2954 }
2955 
2956 /**
2957   * @brief Configures the layer parameters for ARGB format in the LTDC peripheral.
2958   *
2959   * This function sets up the layer-specific parameters for a layer that will handle ARGB pixel data.
2960   * It configures various aspects such as pixel format, blending factors, color frame buffer address,
2961   * color keying, and more, according to the LTDC_LayerFlexARGBTypeDef structure.
2962   *
2963   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
2964   *              for the LTDC module.
2965   * @param pLayerFlexARGB Pointer to an LTDC_LayerFlexARGBTypeDef structure that specifies the layer
2966   *                       configuration parameters for the ARGB format.
2967   * @param LayerIdx Specifies the index of the layer being configured. This parameter can be one of the
2968   *                 following values:
2969   *                 - LTDC_LAYER_1: Configuration for layer 1.
2970   *                 - LTDC_LAYER_2: Configuration for layer 2.
2971   * @retval  HAL status
2972   */
HAL_LTDC_ConfigLayerFlexARGB(LTDC_HandleTypeDef * hltdc,const LTDC_LayerFlexARGBTypeDef * pLayerFlexARGB,uint32_t LayerIdx)2973 HAL_StatusTypeDef HAL_LTDC_ConfigLayerFlexARGB(LTDC_HandleTypeDef *hltdc,
2974                                                const LTDC_LayerFlexARGBTypeDef *pLayerFlexARGB, uint32_t LayerIdx)
2975 {
2976   /* Check the parameters */
2977   assert_param(IS_LTDC_LAYER(LayerIdx));
2978   assert_param(IS_LTDC_ARGB_COMPONENT_WIDTH(pLayerFlexARGB->FlexARGB.RedWidth));
2979   assert_param(IS_LTDC_ARGB_COMPONENT_WIDTH(pLayerFlexARGB->FlexARGB.GreenWidth));
2980   assert_param(IS_LTDC_ARGB_COMPONENT_WIDTH(pLayerFlexARGB->FlexARGB.BlueWidth));
2981   assert_param(IS_LTDC_ARGB_COMPONENT_POSITION(pLayerFlexARGB->FlexARGB.RedPos));
2982   assert_param(IS_LTDC_ARGB_COMPONENT_POSITION(pLayerFlexARGB->FlexARGB.GreenPos));
2983   assert_param(IS_LTDC_ARGB_COMPONENT_POSITION(pLayerFlexARGB->FlexARGB.BluePos));
2984 
2985   /* Process locked */
2986   __HAL_LOCK(hltdc);
2987 
2988   /* Change LTDC peripheral state */
2989   hltdc->State = HAL_LTDC_STATE_BUSY;
2990 
2991   /* update in the handler */
2992   hltdc->LayerCfg[LayerIdx].WindowX0 = pLayerFlexARGB->Layer.WindowX0;
2993   hltdc->LayerCfg[LayerIdx].WindowX1 = pLayerFlexARGB->Layer.WindowX1;
2994   hltdc->LayerCfg[LayerIdx].WindowY0 = pLayerFlexARGB->Layer.WindowY0;
2995   hltdc->LayerCfg[LayerIdx].WindowY1 = pLayerFlexARGB->Layer.WindowY1;
2996   hltdc->LayerCfg[LayerIdx].PixelFormat = LTDC_PIXEL_FORMAT_FLEX_ARGB;
2997   hltdc->LayerCfg[LayerIdx].Alpha = pLayerFlexARGB->Layer.Alpha;
2998   hltdc->LayerCfg[LayerIdx].Alpha0 = pLayerFlexARGB->Layer.Alpha0;
2999   hltdc->LayerCfg[LayerIdx].BlendingFactor1 = pLayerFlexARGB->Layer.BlendingFactor1;
3000   hltdc->LayerCfg[LayerIdx].BlendingFactor2 = pLayerFlexARGB->Layer.BlendingFactor2;
3001   hltdc->LayerCfg[LayerIdx].FBStartAdress = pLayerFlexARGB->ARGBAddress;
3002   hltdc->LayerCfg[LayerIdx].ImageWidth = pLayerFlexARGB->Layer.ImageWidth;
3003   hltdc->LayerCfg[LayerIdx].ImageHeight = pLayerFlexARGB->Layer.ImageHeight;
3004 
3005   /* Configure Flexible ARGB */
3006   LTDC_LAYER(hltdc, LayerIdx)->PFCR = 0x7U;
3007   LTDC_LAYER(hltdc, LayerIdx)->FPF0R = (pLayerFlexARGB->FlexARGB.RedWidth << LTDC_LxFPF0R_RLEN_Pos) |
3008                                        (pLayerFlexARGB->FlexARGB.RedPos << LTDC_LxFPF0R_RPOS_Pos) |
3009                                        (pLayerFlexARGB->FlexARGB.AlphaWidth << LTDC_LxFPF0R_ALEN_Pos) |
3010                                        pLayerFlexARGB->FlexARGB.AlphaPos;
3011   LTDC_LAYER(hltdc, LayerIdx)->FPF1R = (pLayerFlexARGB->FlexARGB.PixelSize << LTDC_LxFPF1R_PSIZE_Pos) |
3012                                        (pLayerFlexARGB->FlexARGB.BlueWidth << LTDC_LxFPF1R_BLEN_Pos) |
3013                                        (pLayerFlexARGB->FlexARGB.BluePos << LTDC_LxFPF1R_BPOS_Pos) |
3014                                        (pLayerFlexARGB->FlexARGB.GreenWidth << LTDC_LxFPF1R_GLEN_Pos) |
3015                                        (pLayerFlexARGB->FlexARGB.GreenPos);
3016 
3017   /* Set composition parameters */
3018   LTDC_SetCompositionConfig(hltdc, LayerIdx);
3019 
3020 
3021   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3022   /* Disable YUV mode */
3023   MODIFY_REG(LTDC_LAYER(hltdc, LayerIdx)->PCR, LTDC_LxPCR_YCEN, 0U);
3024 
3025   LTDC_SetConfig(hltdc, 0, 0, LTDC_MIRROR_NONE, LayerIdx);
3026 
3027   /* Set the Immediate Reload type */
3028   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3029 
3030   /* Change the LTDC state*/
3031   hltdc->State = HAL_LTDC_STATE_READY;
3032 
3033   /* Process unlocked */
3034   __HAL_UNLOCK(hltdc);
3035 
3036   return HAL_OK;
3037 }
3038 
3039 /**
3040   * @brief Configures the layer parameters for YUV co-planar format in the LTDC peripheral.
3041   *
3042   * This function sets up the layer-specific parameters for a layer that will handle YUV co-planar pixel
3043   * data. It allows configuration of the layer to handle pixel data where the Y component is stored
3044   * separately from the UV components, which are stored together. The configuration parameters include
3045   * pixel format, blending factors, color frame buffer addresses, and more, as defined in the
3046   * LTDC_LayerFlexYUVCoPlanarTypeDef structure.
3047   *
3048   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
3049   *              for the LTDC module.
3050   * @param pLayerFlexYUVCoPlanar Pointer to an LTDC_LayerFlexYUVCoPlanarTypeDef structure that
3051   *                              specifies the layer configuration parameters for the YUV co-planar format.
3052   * @param LayerIdx Specifies the index of the layer being configured. This parameter can be one of the
3053   *                 following values:
3054   *                 - LTDC_LAYER_1: Configuration for layer 1.
3055   *                 - LTDC_LAYER_2: Configuration for layer 2.
3056   * @retval  HAL status
3057   */
HAL_LTDC_ConfigLayerFlexYUVCoPlanar(LTDC_HandleTypeDef * hltdc,const LTDC_LayerFlexYUVCoPlanarTypeDef * pLayerFlexYUVCoPlanar,uint32_t LayerIdx)3058 HAL_StatusTypeDef HAL_LTDC_ConfigLayerFlexYUVCoPlanar(LTDC_HandleTypeDef *hltdc,
3059                                                       const LTDC_LayerFlexYUVCoPlanarTypeDef *pLayerFlexYUVCoPlanar,
3060                                                       uint32_t LayerIdx)
3061 {
3062   /* Check the parameters */
3063   assert_param(IS_LTDC_LAYER(LayerIdx));
3064   assert_param(IS_LTDC_Y_RANHGE(pLayerFlexYUVCoPlanar->FlexYUV.LuminanceRescale));
3065   assert_param(IS_LTDC_Y_ORDER(pLayerFlexYUVCoPlanar->FlexYUV.LuminanceOrder));
3066   assert_param(IS_LTDC_YUV_ORDER(pLayerFlexYUVCoPlanar->FlexYUV.YUVOrder));
3067   assert_param(IS_LTDC_UV_ORDER(pLayerFlexYUVCoPlanar->FlexYUV.ChrominanceOrder));
3068   assert_param(IS_LTDC_YUV2RGBCONVERTOR(pLayerFlexYUVCoPlanar->ColorConverter));
3069 
3070   /* Process locked */
3071   __HAL_LOCK(hltdc);
3072 
3073   /* Change LTDC peripheral state */
3074   hltdc->State = HAL_LTDC_STATE_BUSY;
3075 
3076   /* update the handler */
3077   hltdc->LayerCfg[LayerIdx].WindowX0 = pLayerFlexYUVCoPlanar->Layer.WindowX0;
3078   hltdc->LayerCfg[LayerIdx].WindowX1 = pLayerFlexYUVCoPlanar->Layer.WindowX1;
3079   hltdc->LayerCfg[LayerIdx].WindowY0 = pLayerFlexYUVCoPlanar->Layer.WindowY0;
3080   hltdc->LayerCfg[LayerIdx].WindowY1 = pLayerFlexYUVCoPlanar->Layer.WindowY1;
3081   hltdc->LayerCfg[LayerIdx].PixelFormat = LTDC_PIXEL_FORMAT_FLEX_YUV_COPLANAR;
3082   hltdc->LayerCfg[LayerIdx].Alpha = pLayerFlexYUVCoPlanar->Layer.Alpha;
3083   hltdc->LayerCfg[LayerIdx].Alpha0 = pLayerFlexYUVCoPlanar->Layer.Alpha0;
3084   hltdc->LayerCfg[LayerIdx].BlendingFactor1 = pLayerFlexYUVCoPlanar->Layer.BlendingFactor1;
3085   hltdc->LayerCfg[LayerIdx].BlendingFactor2 = pLayerFlexYUVCoPlanar->Layer.BlendingFactor2;
3086   hltdc->LayerCfg[LayerIdx].FBStartAdress = pLayerFlexYUVCoPlanar->YUVAddress;
3087   hltdc->LayerCfg[LayerIdx].ImageWidth = pLayerFlexYUVCoPlanar->Layer.ImageWidth;
3088   hltdc->LayerCfg[LayerIdx].ImageHeight = pLayerFlexYUVCoPlanar->Layer.ImageHeight;
3089 
3090   /* Set composition parameters */
3091   LTDC_SetCompositionConfig(hltdc, LayerIdx);
3092 
3093   /* Set flexible YUV format */
3094   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->PCR, LTDC_LxPCR_YCEN | (pLayerFlexYUVCoPlanar->FlexYUV.ChrominanceOrder) |
3095             (LTDC_PIXEL_FORMAT_FLEX_YUV_COPLANAR >> LTDC_LxPCR_YCM_Pos) |
3096             (pLayerFlexYUVCoPlanar->FlexYUV.YUVOrder) |
3097             (pLayerFlexYUVCoPlanar->FlexYUV.LuminanceOrder) | pLayerFlexYUVCoPlanar->FlexYUV.LuminanceRescale);
3098 
3099   /* Set YUV to RGB conversion */
3100   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR0R, \
3101             (U2B[pLayerFlexYUVCoPlanar->ColorConverter] << LTDC_LxCYR0R_CB2B_Pos) |
3102             V2R[pLayerFlexYUVCoPlanar->ColorConverter]);
3103   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR1R, (V2G[pLayerFlexYUVCoPlanar->ColorConverter]) |
3104             (U2G[pLayerFlexYUVCoPlanar->ColorConverter] << LTDC_LxCYR1R_CB2G_Pos));
3105 
3106   /* Set LTDC parameters */
3107   LTDC_SetConfig(hltdc, 0, 0, LTDC_MIRROR_NONE, LayerIdx);
3108 
3109   /* Set the Immediate Reload type */
3110   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3111 
3112   /* Change the LTDC state*/
3113   hltdc->State = HAL_LTDC_STATE_READY;
3114 
3115   /* Process unlocked */
3116   __HAL_UNLOCK(hltdc);
3117 
3118   return HAL_OK;
3119 }
3120 
3121 /**
3122   * @brief Configures the layer parameters for YUV semi-planar format in the LTDC peripheral.
3123   *
3124   * This function sets up the layer-specific parameters for a layer that will handle YUV semi-planar pixel
3125   * data. It configures the layer to process pixel data where the Y component is stored separately from
3126   * the UV components, which are stored together in a semi-planar format. The configuration parameters
3127   * include pixel format, blending factors, color frame buffer addresses, and more, as defined in the
3128   * LTDC_LayerFlexYUVSemiPlanarTypeDef structure.
3129   *
3130   * @note This function is applicable only to LTDC_LAYER_1.
3131   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
3132   *              for the LTDC module.
3133   * @param pLayerFlexYUVSemiPlanar Pointer to an LTDC_LayerFlexYUVSemiPlanarTypeDef structure that
3134   *                                specifies the layer configuration parameters for the YUV semi-planar
3135   *                                format.
3136   * @param LayerIdx Specifies the index of the layer being configured. For this function, the only
3137   *                 valid value is LTDC_LAYER_1.
3138   * @retval  HAL status
3139   */
HAL_LTDC_ConfigLayerFlexYUVSemiPlanar(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVSemiPlanarTypeDef * pLayerFlexYUVSemiPlanar,uint32_t LayerIdx)3140 HAL_StatusTypeDef HAL_LTDC_ConfigLayerFlexYUVSemiPlanar(LTDC_HandleTypeDef *hltdc,
3141                                                         LTDC_LayerFlexYUVSemiPlanarTypeDef *pLayerFlexYUVSemiPlanar,
3142                                                         uint32_t LayerIdx)
3143 {
3144   /* Check the parameters */
3145   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
3146   assert_param(IS_LTDC_Y_RANHGE(pLayerFlexYUVSemiPlanar->FlexYUV.LuminanceRescale));
3147   assert_param(IS_LTDC_Y_ORDER(pLayerFlexYUVSemiPlanar->FlexYUV.LuminanceOrder));
3148   assert_param(IS_LTDC_YUV_ORDER(pLayerFlexYUVSemiPlanar->FlexYUV.YUVOrder));
3149   assert_param(IS_LTDC_UV_ORDER(pLayerFlexYUVSemiPlanar->FlexYUV.ChrominanceOrder));
3150   assert_param(IS_LTDC_YUV2RGBCONVERTOR(pLayerFlexYUVSemiPlanar->ColorConverter));
3151 
3152   /* Process locked */
3153   __HAL_LOCK(hltdc);
3154 
3155   /* Change LTDC peripheral state */
3156   hltdc->State = HAL_LTDC_STATE_BUSY;
3157 
3158   /* update the handler */
3159   hltdc->LayerCfg[LayerIdx].WindowX0 = pLayerFlexYUVSemiPlanar->Layer.WindowX0;
3160   hltdc->LayerCfg[LayerIdx].WindowX1 = pLayerFlexYUVSemiPlanar->Layer.WindowX1;
3161   hltdc->LayerCfg[LayerIdx].WindowY0 = pLayerFlexYUVSemiPlanar->Layer.WindowY0;
3162   hltdc->LayerCfg[LayerIdx].WindowY1 = pLayerFlexYUVSemiPlanar->Layer.WindowY1;
3163   hltdc->LayerCfg[LayerIdx].PixelFormat = LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR;
3164   hltdc->LayerCfg[LayerIdx].Alpha = pLayerFlexYUVSemiPlanar->Layer.Alpha;
3165   hltdc->LayerCfg[LayerIdx].Alpha0 = pLayerFlexYUVSemiPlanar->Layer.Alpha0;
3166   hltdc->LayerCfg[LayerIdx].BlendingFactor1 = pLayerFlexYUVSemiPlanar->Layer.BlendingFactor1;
3167   hltdc->LayerCfg[LayerIdx].BlendingFactor2 = pLayerFlexYUVSemiPlanar->Layer.BlendingFactor2;
3168   hltdc->LayerCfg[LayerIdx].FBStartAdress = pLayerFlexYUVSemiPlanar->YUVSemiPlanarAddress.YAddress;
3169   hltdc->LayerCfg[LayerIdx].ImageWidth = pLayerFlexYUVSemiPlanar->Layer.ImageWidth;
3170   hltdc->LayerCfg[LayerIdx].ImageHeight = pLayerFlexYUVSemiPlanar->Layer.ImageHeight;
3171 
3172   /* Set composition parameters */
3173   LTDC_SetCompositionConfig(hltdc, LayerIdx);
3174 
3175   /* Set flexible YUV format */
3176   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->PCR, LTDC_LxPCR_YCEN | pLayerFlexYUVSemiPlanar->FlexYUV.ChrominanceOrder |
3177             (LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR >> LTDC_LxPCR_YCM_Pos) |
3178             pLayerFlexYUVSemiPlanar->FlexYUV.YUVOrder |
3179             pLayerFlexYUVSemiPlanar->FlexYUV.LuminanceOrder | pLayerFlexYUVSemiPlanar->FlexYUV.LuminanceRescale);
3180 
3181   /* Set YUV to RGB conversion */
3182   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR0R, \
3183             (U2B[pLayerFlexYUVSemiPlanar->ColorConverter] << LTDC_LxCYR0R_CB2B_Pos) |
3184             V2R[pLayerFlexYUVSemiPlanar->ColorConverter]);
3185   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR1R, (V2G[pLayerFlexYUVSemiPlanar->ColorConverter]) |
3186             (U2G[pLayerFlexYUVSemiPlanar->ColorConverter] << LTDC_LxCYR1R_CB2G_Pos));
3187 
3188   /* Set LTDC parameters */
3189   LTDC_SetConfig(hltdc, pLayerFlexYUVSemiPlanar->YUVSemiPlanarAddress.UVAddress, 0, LTDC_MIRROR_NONE, LayerIdx);
3190 
3191   /* Set the Immediate Reload type */
3192   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3193 
3194   /* Change the LTDC state*/
3195   hltdc->State = HAL_LTDC_STATE_READY;
3196 
3197   /* Process unlocked */
3198   __HAL_UNLOCK(hltdc);
3199 
3200   return HAL_OK;
3201 }
3202 
3203 /**
3204   * @brief Configures the layer parameters for YUV full-planar format in the LTDC peripheral.
3205   *
3206   * This function sets up the layer-specific parameters for a layer that will handle YUV full-planar pixel
3207   * data. It configures the layer to process pixel data where the Y component is stored separately from
3208   * the UV components, which are stored together in a full-planar format. The configuration parameters
3209   * include pixel format, blending factors, color frame buffer addresses, and more, as defined in the
3210   * LTDC_LayerFlexYUVfullPlanarTypeDef structure.
3211   *
3212   *  @note This function is applicable only to LTDC_LAYER_1.
3213   *
3214   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
3215   *              for the LTDC module.
3216   * @param pLayerFlexYUVfullPlanar Pointer to an LTDC_LayerFlexYUVfullPlanarTypeDef structure that
3217   *                                specifies the layer configuration parameters for the YUV full-planar
3218   *                                format.
3219   * @param LayerIdx Specifies the index of the layer being configured. For this function, the only
3220   *                 valid value is LTDC_LAYER_1.
3221   * @retval  HAL status
3222   */
HAL_LTDC_ConfigLayerFlexYUVFullPlanar(LTDC_HandleTypeDef * hltdc,LTDC_LayerFlexYUVFullPlanarTypeDef * pLayerFlexYUVFullPlanar,uint32_t LayerIdx)3223 HAL_StatusTypeDef HAL_LTDC_ConfigLayerFlexYUVFullPlanar(LTDC_HandleTypeDef *hltdc,
3224                                                         LTDC_LayerFlexYUVFullPlanarTypeDef *pLayerFlexYUVFullPlanar,
3225                                                         uint32_t LayerIdx)
3226 {
3227   /* Check the parameters */
3228   assert_param(IS_LTDC_PLANAR_LAYER(LayerIdx));
3229   assert_param(IS_LTDC_Y_RANHGE(pLayerFlexYUVFullPlanar->FlexYUV.LuminanceRescale));
3230   assert_param(IS_LTDC_Y_ORDER(pLayerFlexYUVFullPlanar->FlexYUV.LuminanceOrder));
3231   assert_param(IS_LTDC_YUV_ORDER(pLayerFlexYUVFullPlanar->FlexYUV.YUVOrder));
3232   assert_param(IS_LTDC_UV_ORDER(pLayerFlexYUVFullPlanar->FlexYUV.ChrominanceOrder));
3233   assert_param(IS_LTDC_YUV2RGBCONVERTOR(pLayerFlexYUVFullPlanar->ColorConverter));
3234 
3235   /* Process locked */
3236   __HAL_LOCK(hltdc);
3237 
3238   /* Change LTDC peripheral state */
3239   hltdc->State = HAL_LTDC_STATE_BUSY;
3240 
3241   /* update the handler */
3242   hltdc->LayerCfg[LayerIdx].WindowX0 = pLayerFlexYUVFullPlanar->Layer.WindowX0;
3243   hltdc->LayerCfg[LayerIdx].WindowX1 = pLayerFlexYUVFullPlanar->Layer.WindowX1;
3244   hltdc->LayerCfg[LayerIdx].WindowY0 = pLayerFlexYUVFullPlanar->Layer.WindowY0;
3245   hltdc->LayerCfg[LayerIdx].WindowY1 = pLayerFlexYUVFullPlanar->Layer.WindowY1;
3246   hltdc->LayerCfg[LayerIdx].PixelFormat = LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR;
3247   hltdc->LayerCfg[LayerIdx].Alpha = pLayerFlexYUVFullPlanar->Layer.Alpha;
3248   hltdc->LayerCfg[LayerIdx].Alpha0 = pLayerFlexYUVFullPlanar->Layer.Alpha0;
3249   hltdc->LayerCfg[LayerIdx].BlendingFactor1 = pLayerFlexYUVFullPlanar->Layer.BlendingFactor1;
3250   hltdc->LayerCfg[LayerIdx].BlendingFactor2 = pLayerFlexYUVFullPlanar->Layer.BlendingFactor2;
3251   hltdc->LayerCfg[LayerIdx].FBStartAdress = pLayerFlexYUVFullPlanar->YUVFullPlanarAddress.YAddress;
3252   hltdc->LayerCfg[LayerIdx].ImageWidth = pLayerFlexYUVFullPlanar->Layer.ImageWidth;
3253   hltdc->LayerCfg[LayerIdx].ImageHeight = pLayerFlexYUVFullPlanar->Layer.ImageHeight;
3254 
3255   /* Set composition parameters */
3256   LTDC_SetCompositionConfig(hltdc, LayerIdx);
3257 
3258   /* Set flexible YUV format */
3259   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->PCR, LTDC_LxPCR_YCEN |
3260             pLayerFlexYUVFullPlanar->FlexYUV.ChrominanceOrder |
3261             (LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR >> LTDC_LxPCR_YCM_Pos) |
3262             pLayerFlexYUVFullPlanar->FlexYUV.YUVOrder |
3263             pLayerFlexYUVFullPlanar->FlexYUV.LuminanceOrder | pLayerFlexYUVFullPlanar->FlexYUV.LuminanceRescale);
3264 
3265   /* Set YUV to RGB conversion */
3266   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR0R, \
3267             (U2B[pLayerFlexYUVFullPlanar->ColorConverter] << LTDC_LxCYR0R_CB2B_Pos) |
3268             V2R[pLayerFlexYUVFullPlanar->ColorConverter]);
3269   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->CYR1R, V2G[pLayerFlexYUVFullPlanar->ColorConverter] |
3270             (U2G[pLayerFlexYUVFullPlanar->ColorConverter] << LTDC_LxCYR1R_CB2G_Pos));
3271 
3272   /* Set LTDC parameters */
3273   LTDC_SetConfig(hltdc, pLayerFlexYUVFullPlanar->YUVFullPlanarAddress.UAddress,
3274                  pLayerFlexYUVFullPlanar->YUVFullPlanarAddress.VAddress, LTDC_MIRROR_NONE,
3275                  LayerIdx);
3276 
3277   /* Set the Immediate Reload type */
3278   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3279 
3280   /* Change the LTDC state*/
3281   hltdc->State = HAL_LTDC_STATE_READY;
3282 
3283   /* Process unlocked */
3284   __HAL_UNLOCK(hltdc);
3285 
3286   return HAL_OK;
3287 }
3288 
3289 /**
3290   * @brief  Enable the default ARGB8888 color for a specific LTDC layer.
3291   *
3292   * Each layer within the LTDC module has a default color in the ARGB8888 format, which is
3293   * displayed outside the defined layer window or when the layer itself is disabled.
3294   * This function enable the display of default color for a given layer.
3295   * @param  LayerIdx  LTDC Layer index.
3296   *                   This parameter can be one of the following values:
3297   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
3298   * @retval  HAL status
3299   */
HAL_LTDC_EnableDefaultColor(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)3300 HAL_StatusTypeDef HAL_LTDC_EnableDefaultColor(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
3301 {
3302   /* Check the parameters */
3303   assert_param(IS_LTDC_LAYER(LayerIdx));
3304 
3305   /* Process locked */
3306   __HAL_LOCK(hltdc);
3307 
3308   /* Change LTDC peripheral state */
3309   hltdc->State = HAL_LTDC_STATE_BUSY;
3310 
3311   /* Enable Default Color Blending */
3312   SET_BIT(LTDC_LAYER(hltdc, LayerIdx)->CR, LTDC_LxCR_DCBEN);
3313 
3314   /* Set the Immediate Reload type */
3315   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3316 
3317   /* Change the LTDC state*/
3318   hltdc->State = HAL_LTDC_STATE_READY;
3319 
3320   /* Process unlocked */
3321   __HAL_UNLOCK(hltdc);
3322 
3323   return HAL_OK;
3324 }
3325 
3326 /**
3327   * @brief  Disable the default ARGB8888 color for a specific LTDC layer.
3328   *
3329   * Each layer within the LTDC module has a default color in the ARGB8888 format, which is
3330   * displayed outside the defined layer window or when the layer itself is disabled.
3331   * This function prevents the default color from being displayed when a  layer is disabled.
3332   *
3333   * @param  hltdc     pointer to a LTDC_HandleTypeDef structure that contains
3334   *                   the configuration information for the LTDC.
3335   * @param  LayerIdx  LTDC Layer index.
3336   *                   This parameter can be one of the following values:
3337   *                   LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1).
3338   * @retval  HAL status
3339   */
HAL_LTDC_DisableDefaultColor(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)3340 HAL_StatusTypeDef HAL_LTDC_DisableDefaultColor(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
3341 {
3342   /* Check the parameters */
3343   assert_param(IS_LTDC_LAYER(LayerIdx));
3344 
3345   /* Process locked */
3346   __HAL_LOCK(hltdc);
3347 
3348   /* Change LTDC peripheral state */
3349   hltdc->State = HAL_LTDC_STATE_BUSY;
3350 
3351   /* Enable Default Color Blending */
3352   CLEAR_BIT(LTDC_LAYER(hltdc, LayerIdx)->CR, LTDC_LxCR_DCBEN);
3353 
3354   /* Set the Immediate Reload type */
3355   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3356 
3357   /* Change the LTDC state*/
3358   hltdc->State = HAL_LTDC_STATE_READY;
3359 
3360   /* Process unlocked */
3361   __HAL_UNLOCK(hltdc);
3362 
3363   return HAL_OK;
3364 }
3365 
3366 /**
3367   * @brief Configure the blending order for a given layer.
3368   *
3369   * This function sets the blending order of the layers managed by the LTDC module.
3370   * The blending order determines how the layers are superimposed on each other.
3371   *
3372   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains
3373   *              the configuration information for the LTDC module.
3374   * @param Order The blending order value. This parameter can be one of the following values:
3375   *              @arg LTDC_BLENDING_ORDER_FOREGROUND: Layer set in the foreground.
3376   *              @arg LTDC_BLENDING_ORDER_BACKGROUND: Layer set in the background.
3377   * @param LayerIdx Index of the layer being configured. This parameter can be one of the following:
3378   *                 @arg LTDC_LAYER_1: Layer 1 of the LTDC.
3379   *                 @arg LTDC_LAYER_2: Layer 2 of the LTDC.
3380   * @retval  HAL status
3381   */
HAL_LTDC_ConfigBlendingOrder(LTDC_HandleTypeDef * hltdc,uint32_t Order,uint32_t LayerIdx)3382 HAL_StatusTypeDef HAL_LTDC_ConfigBlendingOrder(LTDC_HandleTypeDef *hltdc, uint32_t Order, uint32_t LayerIdx)
3383 {
3384   /* Check the parameters */
3385   assert_param(IS_LTDC_LAYER(LayerIdx));
3386   assert_param(IS_LTDC_BLEND_ORDER(Order));
3387 
3388   /* Process locked */
3389   __HAL_LOCK(hltdc);
3390 
3391   /* Change LTDC peripheral state */
3392   hltdc->State = HAL_LTDC_STATE_BUSY;
3393 
3394   /* Set the blending order */
3395   MODIFY_REG(LTDC_LAYER(hltdc, LayerIdx)->BFCR, LTDC_LxBFCR_BOR, Order);
3396 
3397   /* Set the Immediate Reload type */
3398   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->RCR, LTDC_LxRCR_IMR | LTDC_LxRCR_GRMSK);
3399 
3400   /* Change the LTDC state*/
3401   hltdc->State = HAL_LTDC_STATE_READY;
3402 
3403   /* Process unlocked */
3404   __HAL_UNLOCK(hltdc);
3405 
3406   return HAL_OK;
3407 }
3408 /**
3409   * @brief Retrieves the user configuration for a specific layer in the LTDC peripheral.
3410   *
3411   * This static function retrieves the current configuration for the specified layer, including the
3412   * mirroring setup and auxiliary buffer addresses.  It extracts the stride based on the pixel format
3413   * and calculates the buffer addresses accordingly. The retrieved configuration includes the mirror
3414   * orientation and the starting addresses of the color frame buffer and auxiliary buffers.
3415   *
3416   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
3417   *              for the LTDC module.
3418   * @param Mirror Pointer to a uint32_t variable where the mirror configuration will be stored. The
3419   *               value will be one of the following:
3420   *               - LTDC_MIRROR_NONE: No mirroring.
3421   *               - LTDC_MIRROR_HORIZONTAL: Horizontal mirroring.
3422   *               - LTDC_MIRROR_VERTICAL: Vertical mirroring.
3423   *               - LTDC_MIRROR_HORIZONTAL_VERTICAL: Horizontal and vertical mirroring.
3424   * @param Aux0Addr Pointer to a uint32_t variable where the address of the first auxiliary buffer will
3425   *                 be stored, if applicable.
3426   * @param Aux1Addr Pointer to a uint32_t variable where the address of the second auxiliary buffer will
3427   *                 be stored, if applicable.
3428   * @param LayerIdx Specifies the index of the layer being queried. This parameter can be one of the
3429   *                 following values:
3430   *                 - LTDC_LAYER_1: Retrieve configuration for layer 1.
3431   *                 - LTDC_LAYER_2: Retrieve configuration for layer 2.
3432   *                 - Other layer indices as defined by the hardware and used within the driver.
3433   *
3434   * @note This function is intended for internal use within the LTDC driver and does not return a value.
3435   */
LTDC_RetrieveUserConfig(LTDC_HandleTypeDef * hltdc,uint32_t * Mirror,uint32_t * Aux0Addr,uint32_t * Aux1Addr,uint32_t LayerIdx)3436 static void LTDC_RetrieveUserConfig(LTDC_HandleTypeDef *hltdc, uint32_t *Mirror, uint32_t *Aux0Addr,
3437                                     uint32_t *Aux1Addr, uint32_t LayerIdx)
3438 {
3439   uint32_t stride;
3440   const uint32_t hmirror = ((LTDC_LAYER(hltdc, LayerIdx)->CR) & LTDC_LxCR_HMEN_Msk);
3441   const uint32_t pitchSign = (LTDC_LAYER(hltdc, LayerIdx)->CFBLR & LTDC_LxCFBLR_CFBP) & LTDC_PITCH_SIGN_MSK;
3442 
3443   switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3444   {
3445     case LTDC_PIXEL_FORMAT_ARGB8888:
3446     case LTDC_PIXEL_FORMAT_BGRA8888:
3447     case LTDC_PIXEL_FORMAT_ABGR8888:
3448     case LTDC_PIXEL_FORMAT_RGBA8888:
3449       stride = 4U;
3450       break;
3451     case LTDC_PIXEL_FORMAT_RGB888:
3452       stride = 3U;
3453       break;
3454     case LTDC_PIXEL_FORMAT_RGB565:
3455     case LTDC_PIXEL_FORMAT_BGR565:
3456     case LTDC_PIXEL_FORMAT_ARGB1555:
3457     case LTDC_PIXEL_FORMAT_ARGB4444:
3458     case LTDC_PIXEL_FORMAT_AL88:
3459     case LTDC_PIXEL_FORMAT_FLEX_YUV_COPLANAR:
3460       stride = 2U;
3461       break;
3462     case LTDC_PIXEL_FORMAT_FLEX_ARGB:
3463       stride = ((LTDC_LAYER(hltdc, LayerIdx)->FPF1R) & LTDC_LxFPF1R_PSIZE_Msk) >> LTDC_LxFPF1R_PSIZE_Pos;
3464       break;
3465     case LTDC_PIXEL_FORMAT_L8:
3466     case LTDC_PIXEL_FORMAT_AL44:
3467     case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3468     default:
3469       stride = 1U;
3470       break;
3471   }
3472 
3473   if ((pitchSign == 0U) && (hmirror == 0U))
3474   {
3475     *Mirror = LTDC_MIRROR_NONE;
3476     hltdc->LayerCfg[LayerIdx].FBStartAdress = LTDC_LAYER(hltdc, LayerIdx)->CFBAR;
3477     *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R;
3478     *Aux1Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA1R;
3479   }
3480   else if ((pitchSign == 0U) && (hmirror == LTDC_LxCR_HMEN))
3481   {
3482     *Mirror = LTDC_MIRROR_HORIZONTAL;
3483     hltdc->LayerCfg[LayerIdx].FBStartAdress = LTDC_LAYER(hltdc, LayerIdx)->CFBAR - \
3484                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3485                                                          hltdc->LayerCfg[LayerIdx].WindowX0)) + 1U;
3486     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3487     {
3488       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3489         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - \
3490                     (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3491                                hltdc->LayerCfg[LayerIdx].WindowX0)) + 1U;
3492         break;
3493       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3494         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - \
3495                     (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3496                                 hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U)) + 1U;
3497         *Aux1Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA1R - \
3498                     (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3499                                 hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U)) + 1U;
3500         break;
3501       default:
3502         /* Nothing to do */
3503         break;
3504     }
3505 
3506   }
3507   else if ((pitchSign != 0U) && (hmirror == 0U))
3508   {
3509     *Mirror = LTDC_MIRROR_VERTICAL;
3510     hltdc->LayerCfg[LayerIdx].FBStartAdress = LTDC_LAYER(hltdc, LayerIdx)->CFBAR - \
3511                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3512                                                          hltdc->LayerCfg[LayerIdx].WindowX0) * \
3513                                                ((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3514                                                  hltdc->LayerCfg[LayerIdx].WindowY0) - 1U));
3515     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3516     {
3517       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3518         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - (stride * \
3519                                                            (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3520                                                             hltdc->LayerCfg[LayerIdx].WindowX0) * \
3521                                                            (((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3522                                                               hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3523         break;
3524       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3525         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - (stride * \
3526                                                            ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3527                                                              hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * \
3528                                                            (((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3529                                                               hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3530         *Aux1Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA1R - (stride * \
3531                                                            ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3532                                                              hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * \
3533                                                            (((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3534                                                               hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3535         break;
3536       default:
3537         /* Nothing to do */
3538         break;
3539     }
3540   }
3541 
3542   else
3543   {
3544     *Mirror = LTDC_MIRROR_HORIZONTAL_VERTICAL;
3545     hltdc->LayerCfg[LayerIdx].FBStartAdress = LTDC_LAYER(hltdc, LayerIdx)->CFBAR - \
3546                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3547                                                          hltdc->LayerCfg[LayerIdx].WindowX0) * \
3548                                                (hltdc->LayerCfg[LayerIdx].WindowY1 - \
3549                                                 hltdc->LayerCfg[LayerIdx].WindowY0)) + 1U;
3550     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3551     {
3552       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3553         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - (stride * \
3554                                                            (hltdc->LayerCfg[LayerIdx].WindowX1 - \
3555                                                             hltdc->LayerCfg[LayerIdx].WindowX0) * \
3556                                                            ((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3557                                                              hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) + 1U;
3558         break;
3559       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3560         *Aux0Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA0R - (stride * \
3561                                                            ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3562                                                              hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * \
3563                                                            ((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3564                                                              hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) + 1U;
3565         *Aux1Addr = LTDC_LAYER(hltdc, LayerIdx)->AFBA1R - (stride * \
3566                                                            ((hltdc->LayerCfg[LayerIdx].WindowX1 - \
3567                                                              hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * \
3568                                                            ((hltdc->LayerCfg[LayerIdx].WindowY1 - \
3569                                                              hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) + 1U;
3570         break;
3571       default:
3572         /* Nothing to do */
3573         break;
3574     }
3575   }
3576 }
3577 
3578 /**
3579   * @brief Set the configuration for a specific layer of the LTDC controller.
3580   *
3581   * This function configures a layer of the LTDC controller with the specified parameters.
3582   * It sets the pixel format stride, window positioning, color frame buffer address, auxiliary
3583   * frame buffer addresses, buffer length, and line number based on the layer configuration.
3584   * It also handles the mirroring configuration for the layer if specified.
3585   *
3586   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains
3587   *              the configuration information for the specified LTDC.
3588   * @param Aux0Addr Auxiliary frame buffer address 0 used for certain pixel formats.
3589   * @param Aux1Addr Auxiliary frame buffer address 1 used for certain pixel formats.
3590   * @param Mirror Specifies the mirroring configuration for the layer. This parameter
3591   *               can be one of the following values:
3592   *               @arg LTDC_MIRROR_NONE: No mirroring.
3593   *               @arg LTDC_MIRROR_HORIZONTAL: Horizontal mirroring.
3594   *               @arg LTDC_MIRROR_VERTICAL: Vertical mirroring.
3595   *               @arg LTDC_MIRROR_HORIZONTAL_VERTICAL: Horizontal and vertical mirroring.
3596   * @param LayerIdx Index of the layer being configured. This parameter can be one of the following:
3597   *                 @arg LTDC_LAYER_1: Layer 1 of the LTDC.
3598   *                 @arg LTDC_LAYER_2: Layer 2 of the LTDC.
3599   *                 Depending on the LTDC hardware, additional layers may be supported.
3600   *
3601   * @note The stride is calculated based on the pixel format of the layer. The pixel format
3602   *       defines the number of bytes per pixel and hence the stride (the increment from one
3603   *       pixel to the next in a row of pixels). The function configures the layer window size
3604   *       and position, as well as the color and auxiliary frame buffer addresses, which are
3605   *       dependent on the mirroring configuration and pixel format. The buffer length and
3606   *       frame buffer line number are also set according to the pixel format and layer size.
3607   *       Mirroring settings are applied by adjusting the frame buffer start address and
3608   *       enabling the corresponding mirroring bits in the control register.
3609   *
3610   *       This function does not return a value as it is a static function used internally within the
3611   *        driver.
3612   */
LTDC_SetConfig(LTDC_HandleTypeDef * hltdc,uint32_t Aux0Addr,uint32_t Aux1Addr,uint32_t Mirror,uint32_t LayerIdx)3613 static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc, uint32_t Aux0Addr, uint32_t Aux1Addr, uint32_t Mirror,
3614                            uint32_t LayerIdx)
3615 {
3616   uint32_t stride;
3617   uint32_t tmp;
3618 
3619   /* Configure the frame buffer line number */
3620   LTDC_LAYER(hltdc, LayerIdx)->CFBLNR  = (hltdc->LayerCfg[LayerIdx].ImageHeight);
3621 
3622   switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3623   {
3624     case LTDC_PIXEL_FORMAT_ARGB8888:
3625     case LTDC_PIXEL_FORMAT_BGRA8888:
3626     case LTDC_PIXEL_FORMAT_ABGR8888:
3627     case LTDC_PIXEL_FORMAT_RGBA8888:
3628       stride = 4U;
3629       break;
3630     case LTDC_PIXEL_FORMAT_RGB888:
3631       stride = 3U;
3632       break;
3633     case LTDC_PIXEL_FORMAT_RGB565:
3634     case LTDC_PIXEL_FORMAT_BGR565:
3635     case LTDC_PIXEL_FORMAT_ARGB1555:
3636     case LTDC_PIXEL_FORMAT_ARGB4444:
3637     case LTDC_PIXEL_FORMAT_AL88:
3638     case LTDC_PIXEL_FORMAT_FLEX_YUV_COPLANAR:
3639       stride = 2U;
3640       break;
3641     case LTDC_PIXEL_FORMAT_FLEX_ARGB:
3642       stride = (((LTDC_LAYER(hltdc, LayerIdx)->FPF1R) & LTDC_LxFPF1R_PSIZE_Msk) >> LTDC_LxFPF1R_PSIZE_Pos);
3643       break;
3644     case LTDC_PIXEL_FORMAT_L8:
3645     case LTDC_PIXEL_FORMAT_AL44:
3646     case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3647     default:
3648       stride = 1U;
3649       break;
3650   }
3651 
3652   /* Configure the horizontal start and stop position */
3653   tmp = ((hltdc->LayerCfg[LayerIdx].WindowX1 + ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16U)) << 16U);
3654   LTDC_LAYER(hltdc, LayerIdx)->WHPCR = ((hltdc->LayerCfg[LayerIdx].WindowX0 +
3655                                          ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16U) + 1U) | tmp);
3656 
3657   /* Configure the vertical start and stop position */
3658   tmp = ((hltdc->LayerCfg[LayerIdx].WindowY1 + (hltdc->Instance->BPCR & LTDC_BPCR_AVBP)) << 16U);
3659   LTDC_LAYER(hltdc, LayerIdx)->WVPCR = ((hltdc->LayerCfg[LayerIdx].WindowY0 +
3660                                          (hltdc->Instance->BPCR & LTDC_BPCR_AVBP) + 1U) | tmp);
3661 
3662   if (Mirror == LTDC_MIRROR_NONE)
3663   {
3664     LTDC_LAYER(hltdc, LayerIdx)->CFBAR = (hltdc->LayerCfg[LayerIdx].FBStartAdress);
3665 
3666     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3667     {
3668       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3669         /* Configure the auxiliary frame buffer address 0 */
3670         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr;
3671 
3672         /* Configure the buffer length */
3673         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = (hltdc->LayerCfg[LayerIdx].ImageWidth << 16U) |
3674                                              (hltdc->LayerCfg[LayerIdx].WindowX1 -
3675                                               hltdc->LayerCfg[LayerIdx].WindowX0 + 7U);
3676         /* Configure the frame buffer line number */
3677         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = (hltdc->LayerCfg[LayerIdx].ImageHeight) >> 1U;
3678         break;
3679       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3680         /* Configure the auxiliary frame buffer address 0 */
3681         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr;
3682 
3683         /* Configure the auxiliary frame buffer address 1 */
3684         LTDC_LAYER(hltdc, LayerIdx)->AFBA1R = Aux1Addr;
3685 
3686         /* Configure the buffer length */
3687         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = ((hltdc->LayerCfg[LayerIdx].ImageWidth >> 1U) << 16U) |
3688                                              (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3689                                                 hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) + 7U);
3690 
3691         /* Configure the frame buffer line number */
3692         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = (hltdc->LayerCfg[LayerIdx].ImageHeight) >> 1U;
3693         break;
3694       default:
3695         /* Nothing to do */
3696         break;
3697     }
3698 
3699     /* Configure the color frame buffer pitch in byte */
3700     LTDC_LAYER(hltdc, LayerIdx)->CFBLR = (((hltdc->LayerCfg[LayerIdx].ImageWidth * stride) << 16U) |
3701                                           (((hltdc->LayerCfg[LayerIdx].WindowX1 - hltdc->LayerCfg[LayerIdx].WindowX0) *
3702                                             stride)  + 7U));
3703 
3704     /* Enable LTDC_Layer by setting LEN bit */
3705     MODIFY_REG(LTDC_LAYER(hltdc, LayerIdx)->CR,LTDC_LxCR_HMEN, LTDC_LxCR_LEN);
3706   }
3707 
3708   else if (Mirror == LTDC_MIRROR_HORIZONTAL)
3709   {
3710     /* Configure the color frame buffer start address */
3711     LTDC_LAYER(hltdc, LayerIdx)->CFBAR = hltdc->LayerCfg[LayerIdx].FBStartAdress +
3712                                          (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3713                                                     hltdc->LayerCfg[LayerIdx].WindowX0)) - 1U;
3714 
3715     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3716     {
3717       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3718         /* Configure the auxiliary frame buffer address 0 */
3719         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3720                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3721                                                          hltdc->LayerCfg[LayerIdx].WindowX0)) - 1U;
3722 
3723         /* Configure the buffer length */
3724         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = (hltdc->LayerCfg[LayerIdx].ImageWidth << 16U) |
3725                                              (hltdc->LayerCfg[LayerIdx].WindowX1 - hltdc->LayerCfg[LayerIdx].WindowX0 +
3726                                               7U);
3727 
3728         /* Configure the frame buffer line number */
3729         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U ;
3730         break;
3731       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3732         /* Configure the auxiliary frame buffer address 0 */
3733         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3734                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3735                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U)) - 1U;
3736 
3737         /* Configure the auxiliary frame buffer address 1 */
3738         LTDC_LAYER(hltdc, LayerIdx)->AFBA1R = Aux1Addr +
3739                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3740                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U)) - 1U;
3741 
3742         /* Configure the buffer length */
3743         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = ((hltdc->LayerCfg[LayerIdx].ImageWidth >> 1U) << 16U) |
3744                                              (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3745                                                 hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) + 7U);
3746 
3747         /* Configure the frame buffer line number */
3748         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U;
3749         break;
3750       default:
3751         /* Nothing to do */
3752         break;
3753     }
3754 
3755     /* Configure the color frame buffer pitch in byte */
3756     LTDC_LAYER(hltdc, LayerIdx)->CFBLR = (((hltdc->LayerCfg[LayerIdx].ImageWidth * stride) << 16U) |
3757                                           (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3758                                              hltdc->LayerCfg[LayerIdx].WindowX0) * stride)  + 7U));
3759 
3760     /* Enable horizontal mirroring bit & LTDC_Layer by setting LEN bit */
3761     SET_BIT(LTDC_LAYER(hltdc, LayerIdx)->CR, LTDC_LxCR_HMEN | LTDC_LxCR_LEN);
3762   }
3763 
3764   else if (Mirror == LTDC_MIRROR_VERTICAL)
3765   {
3766     /* Configure the color frame buffer start address */
3767     LTDC_LAYER(hltdc, LayerIdx)->CFBAR = hltdc->LayerCfg[LayerIdx].FBStartAdress +
3768                                          (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3769                                                     hltdc->LayerCfg[LayerIdx].WindowX0) *
3770                                           ((hltdc->LayerCfg[LayerIdx].WindowY1 -
3771                                             hltdc->LayerCfg[LayerIdx].WindowY0) - 1U));
3772 
3773     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3774     {
3775       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3776         /* Configure the auxiliary frame buffer address 0 */
3777         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3778                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3779                                                          hltdc->LayerCfg[LayerIdx].WindowX0) *
3780                                                (((hltdc->LayerCfg[LayerIdx].WindowY1 -
3781                                                   hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3782 
3783         /* Configure the buffer length */
3784         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = ((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth * stride)) << 16U) |
3785                                              (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3786                                                 hltdc->LayerCfg[LayerIdx].WindowX0) * stride)  + 7U);
3787 
3788         /* Configure the frame buffer line number */
3789         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U;
3790         break;
3791       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3792         /* Configure the auxiliary frame buffer address 0 */
3793         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3794                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3795                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) *
3796                                                (((hltdc->LayerCfg[LayerIdx].WindowY1 -
3797                                                   hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3798 
3799         /* Configure the auxiliary frame buffer address 1 */
3800         LTDC_LAYER(hltdc, LayerIdx)->AFBA1R = Aux1Addr +
3801                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3802                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) *
3803                                                (((hltdc->LayerCfg[LayerIdx].WindowY1 -
3804                                                   hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U) - 1U));
3805 
3806         /* Configure the buffer length */
3807         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = (((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth >> 1U)) *
3808                                                stride) << 16U) |
3809                                              ((((hltdc->LayerCfg[LayerIdx].WindowX1 -
3810                                                  hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * stride) + 7U);
3811 
3812         /* Configure the frame buffer line number */
3813         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U;
3814         break;
3815       default:
3816         /* Nothing to do */
3817         break;
3818     }
3819 
3820     /* set the pitch */
3821     LTDC_LAYER(hltdc, LayerIdx)->CFBLR  = ((((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth * stride))) << 16U) |
3822                                            (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3823                                               hltdc->LayerCfg[LayerIdx].WindowX0) * stride) + 7U));
3824 
3825     /* Enable LTDC_Layer by setting LEN bit */
3826     MODIFY_REG(LTDC_LAYER(hltdc, LayerIdx)->CR, LTDC_LxCR_HMEN, LTDC_LxCR_LEN);
3827   }
3828 
3829   else
3830     /*  Mirror = LTDC_MIRROR_HORIZONTAL_VERTICAL */
3831   {
3832     /* Configure the color frame buffer start address */
3833     LTDC_LAYER(hltdc, LayerIdx)->CFBAR = hltdc->LayerCfg[LayerIdx].FBStartAdress +
3834                                          (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3835                                                     hltdc->LayerCfg[LayerIdx].WindowX0) *
3836                                           (hltdc->LayerCfg[LayerIdx].WindowY1 - \
3837                                            hltdc->LayerCfg[LayerIdx].WindowY0)) - 1U;
3838 
3839     switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3840     {
3841       case LTDC_PIXEL_FORMAT_FLEX_YUV_SEMIPLANAR:
3842         /* Configure the auxiliary frame buffer address 0 */
3843         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3844                                               (stride * (hltdc->LayerCfg[LayerIdx].WindowX1 -
3845                                                          hltdc->LayerCfg[LayerIdx].WindowX0) *
3846                                                ((hltdc->LayerCfg[LayerIdx].WindowY1 -
3847                                                  hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) - 1U;
3848 
3849         /* Configure the buffer length */
3850         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = ((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth * stride)) << 16U) |
3851                                              (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3852                                                 hltdc->LayerCfg[LayerIdx].WindowX0) * stride) + 7U);
3853 
3854         /* Configure the frame buffer line number */
3855         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U;
3856         break;
3857       case LTDC_PIXEL_FORMAT_FLEX_YUV_FULLPLANAR:
3858         /* Configure the auxiliary frame buffer address 0 */
3859         LTDC_LAYER(hltdc, LayerIdx)->AFBA0R = Aux0Addr +
3860                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3861                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) *
3862                                                ((hltdc->LayerCfg[LayerIdx].WindowY1 -
3863                                                  hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) - 1U;
3864 
3865         /* Configure the auxiliary frame buffer address 1 */
3866         LTDC_LAYER(hltdc, LayerIdx)->AFBA1R = Aux1Addr +
3867                                               (stride * ((hltdc->LayerCfg[LayerIdx].WindowX1 -
3868                                                           hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) *
3869                                                ((hltdc->LayerCfg[LayerIdx].WindowY1 -
3870                                                  hltdc->LayerCfg[LayerIdx].WindowY0) >> 1U)) - 1U;
3871 
3872         /* Configure the buffer length */
3873         LTDC_LAYER(hltdc, LayerIdx)->AFBLR = (((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth >> 1U)) * stride)
3874                                               << 16U) |
3875                                              ((((hltdc->LayerCfg[LayerIdx].WindowX1 -
3876                                                  hltdc->LayerCfg[LayerIdx].WindowX0) >> 1U) * stride) + 7U);
3877 
3878         /* Configure the frame buffer line number */
3879         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR &= ~(LTDC_L1AFBLNR_AFBLNBR);
3880         LTDC_LAYER(hltdc, LayerIdx)->AFBLNR = hltdc->LayerCfg[LayerIdx].ImageHeight >> 1U;
3881         break;
3882       default:
3883         /* Nothing to do */
3884         break;
3885     }
3886 
3887     LTDC_LAYER(hltdc, LayerIdx)->CFBLR  = ((((0x8000U - (hltdc->LayerCfg[LayerIdx].ImageWidth * stride))) << 16U) |
3888                                            (((hltdc->LayerCfg[LayerIdx].WindowX1 -
3889                                               hltdc->LayerCfg[LayerIdx].WindowX0) * stride) + 7U));
3890 
3891     /* Enable horizontal mirroring bit & LTDC_Layer by setting LEN bit */
3892     SET_BIT(LTDC_LAYER(hltdc, LayerIdx)->CR, LTDC_LxCR_HMEN | LTDC_LxCR_LEN);
3893   }
3894 }
3895 
3896 /**
3897   * @brief Configures the composition parameters for the specified layer in the LTDC peripheral.
3898   *
3899   * This static function sets the default color values, constant alpha value, and blending factors for
3900   * the specified layer of the LTDC. The configuration is based on the LayerCfg structure within the
3901   * LTDC handle, which includes the background color, alpha values, and blending factors.
3902   *
3903   * @param hltdc Pointer to a LTDC_HandleTypeDef structure that contains the configuration information
3904   *              for the LTDC module.
3905   * @param LayerIdx Specifies the index of the layer being configured. This parameter can be one of the
3906   *                 following values:
3907   *                 - LTDC_LAYER_1: Configuration for layer 1.
3908   *                 - LTDC_LAYER_2: Configuration for layer 2.
3909   *                 - Other layer indices as defined by the hardware and used within the driver.
3910   *
3911   * @note This function is intended for internal use within the LTDC driver and does not return a value.
3912  */
LTDC_SetCompositionConfig(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)3913 static void LTDC_SetCompositionConfig(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
3914 {
3915   uint32_t tmp;
3916   uint32_t tmp1;
3917   uint32_t tmp2;
3918 
3919   /* Configure the default color values */
3920   tmp = ((uint32_t)(hltdc->LayerCfg[LayerIdx].Backcolor.Green) << 8U);
3921   tmp1 = ((uint32_t)(hltdc->LayerCfg[LayerIdx].Backcolor.Red) << 16U);
3922   tmp2 = (hltdc->LayerCfg[LayerIdx].Alpha0 << 24U);
3923   WRITE_REG(LTDC_LAYER(hltdc, LayerIdx)->DCCR, (hltdc->LayerCfg[LayerIdx].Backcolor.Blue | tmp | tmp1 | tmp2));
3924 
3925   /* Specifies the constant alpha value */
3926   LTDC_LAYER(hltdc, LayerIdx)->CACR &= ~(LTDC_LxCACR_CONSTA);
3927   LTDC_LAYER(hltdc, LayerIdx)->CACR = (hltdc->LayerCfg[LayerIdx].Alpha);
3928 
3929   /* Specifies the blending factors */
3930   LTDC_LAYER(hltdc, LayerIdx)->BFCR &= ~(LTDC_LxBFCR_BOR | LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1);
3931   tmp = ((uint32_t)(LTDC_LAYER(hltdc, LayerIdx)->BFCR & LTDC_LxBFCR_BOR_Msk) >> LTDC_LxBFCR_BOR_Pos) << 16U;
3932   LTDC_LAYER(hltdc, LayerIdx)->BFCR = (hltdc->LayerCfg[LayerIdx].BlendingFactor1 |
3933                                        hltdc->LayerCfg[LayerIdx].BlendingFactor2 | tmp);
3934 }
3935 
3936 /**
3937   * @brief Sets a software predefined ARGB pixel format using flexible ARGB parameters for the specified layer.
3938   *
3939   * This function configures the specified layer of the LTDC to use a software predefined ARGB pixel
3940   * format. The desired format is specified by the PixelFormat parameter within the LTDC handle.
3941   * @param  hltdc     Pointer to a LTDC_HandleTypeDef structure that contains
3942   *                   the configuration information for the LTDC.
3943   * @param  LayerIdx  LTDC Layer index.
3944   *                   This parameter can be one of the following values: LTDC_LAYER_1 (0) or LTDC_LAYER_2 (1)
3945   * @retval None
3946   *
3947   *  @note This function does not return a value as it is a static function used internally within the
3948   *        driver.
3949   */
LTDC_SetPredefFormat(LTDC_HandleTypeDef * hltdc,uint32_t LayerIdx)3950 static void LTDC_SetPredefFormat(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx)
3951 {
3952   uint32_t PSIZE = 0U;
3953   uint32_t ALEN = 0U;
3954   uint32_t APOS = 0U;
3955   uint32_t RLEN = 0U;
3956   uint32_t RPOS = 0U;
3957   uint32_t BLEN = 0U;
3958   uint32_t BPOS = 0U;
3959   uint32_t GLEN = 0U;
3960   uint32_t GPOS = 0U;
3961 
3962   /* Specify Flex ARGB parameters according to pixel format */
3963   switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
3964   {
3965     case LTDC_PIXEL_FORMAT_ARGB1555:
3966       PSIZE = 2U;
3967       ALEN = 1U;
3968       APOS = 15U;
3969       RLEN = 5U;
3970       RPOS = 10U;
3971       GLEN = 5U;
3972       GPOS = 5U;
3973       BLEN = 5U;
3974       BPOS = 0U;
3975       break;
3976     case LTDC_PIXEL_FORMAT_ARGB4444:
3977       PSIZE = 2U;
3978       ALEN = 4U;
3979       APOS = 12U;
3980       RLEN = 4U;
3981       RPOS = 8U;
3982       GLEN = 4U;
3983       GPOS = 4U;
3984       BLEN = 4U;
3985       BPOS = 0U;
3986       break;
3987     case LTDC_PIXEL_FORMAT_L8:
3988       PSIZE = 1U;
3989       ALEN = 0U;
3990       APOS = 0U;
3991       RLEN = 8U;
3992       RPOS = 0U;
3993       GLEN = 8U;
3994       GPOS = 0U;
3995       BLEN = 8U;
3996       BPOS = 0U;
3997       break;
3998     case LTDC_PIXEL_FORMAT_AL44:
3999       PSIZE = 1U;
4000       ALEN = 4U;
4001       APOS = 4U;
4002       RLEN = 4U;
4003       RPOS = 0U;
4004       GLEN = 4U;
4005       GPOS = 0U;
4006       BLEN = 4U;
4007       BPOS = 0U;
4008       break;
4009     case LTDC_PIXEL_FORMAT_AL88:
4010       PSIZE = 2U;
4011       ALEN = 8U;
4012       APOS = 8U;
4013       RLEN = 8U;
4014       RPOS = 0U;
4015       GLEN = 8U;
4016       GPOS = 0U;
4017       BLEN = 8U;
4018       BPOS = 0U;
4019       break;
4020     default:
4021       break;
4022   }
4023 
4024   switch (hltdc->LayerCfg[LayerIdx].PixelFormat)
4025   {
4026     case LTDC_PIXEL_FORMAT_ARGB8888:
4027     case LTDC_PIXEL_FORMAT_ABGR8888:
4028     case LTDC_PIXEL_FORMAT_RGBA8888:
4029     case LTDC_PIXEL_FORMAT_BGRA8888:
4030     case LTDC_PIXEL_FORMAT_RGB565:
4031     case LTDC_PIXEL_FORMAT_BGR565:
4032     case LTDC_PIXEL_FORMAT_RGB888:
4033       LTDC_LAYER(hltdc, LayerIdx)->PFCR = (hltdc->LayerCfg[LayerIdx].PixelFormat);
4034       LTDC_LAYER(hltdc, LayerIdx)->FPF0R = 0U;
4035       LTDC_LAYER(hltdc, LayerIdx)->FPF1R = 0U;
4036       break;
4037     case LTDC_PIXEL_FORMAT_ARGB1555:
4038     case LTDC_PIXEL_FORMAT_ARGB4444:
4039     case LTDC_PIXEL_FORMAT_L8:
4040     case LTDC_PIXEL_FORMAT_AL44:
4041     case LTDC_PIXEL_FORMAT_AL88:
4042       LTDC_LAYER(hltdc, LayerIdx)->PFCR = LTDC_LxPFCR_PF;
4043       LTDC_LAYER(hltdc, LayerIdx)->FPF0R = (RLEN << LTDC_LxFPF0R_RLEN_Pos) +
4044                                            (RPOS << LTDC_LxFPF0R_RPOS_Pos) +
4045                                            (ALEN << LTDC_LxFPF0R_ALEN_Pos) +
4046                                            APOS;
4047       LTDC_LAYER(hltdc, LayerIdx)->FPF1R = (PSIZE << LTDC_LxFPF1R_PSIZE_Pos) +
4048                                            (BLEN << LTDC_LxFPF1R_BLEN_Pos)  +
4049                                            (BPOS << LTDC_LxFPF1R_BPOS_Pos) +
4050                                            (GLEN << LTDC_LxFPF1R_GLEN_Pos) +
4051                                            GPOS;
4052       break;
4053     default:
4054       break;
4055   }
4056 }
4057 /**
4058   * @}
4059   */
4060 
4061 
4062 /**
4063   * @}
4064   */
4065 
4066 #endif /* LTDC */
4067 
4068 #endif /* HAL_LTDC_MODULE_ENABLED */
4069 
4070 /**
4071   * @}
4072   */
4073 
4074