1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_dma2d.c
4   * @author  MCD Application Team
5   * @brief   DMA2D HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the DMA2D 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) 2021 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       (#) Program the required configuration through the following parameters:
30           the transfer mode, the output color mode and the output offset using
31           HAL_DMA2D_Init() function.
32 
33       (#) Program the required configuration through the following parameters:
34           the input color mode, the input color, the input alpha value, the alpha mode,
35           the red/blue swap mode, the inverted alpha mode and the input offset using
36           HAL_DMA2D_ConfigLayer() function for foreground or/and background layer.
37 
38      *** Polling mode IO operation ***
39      =================================
40     [..]
41        (#) Configure pdata parameter (explained hereafter), destination and data length
42            and enable the transfer using HAL_DMA2D_Start().
43        (#) Wait for end of transfer using HAL_DMA2D_PollForTransfer(), at this stage
44            user can specify the value of timeout according to his end application.
45 
46      *** Interrupt mode IO operation ***
47      ===================================
48      [..]
49        (#) Configure pdata parameter, destination and data length and enable
50            the transfer using HAL_DMA2D_Start_IT().
51        (#) Use HAL_DMA2D_IRQHandler() called under DMA2D_IRQHandler() interrupt subroutine.
52        (#) At the end of data transfer HAL_DMA2D_IRQHandler() function is executed and user can
53            add his own function by customization of function pointer XferCpltCallback (member
54            of DMA2D handle structure).
55        (#) In case of error, the HAL_DMA2D_IRQHandler() function calls the callback
56            XferErrorCallback.
57 
58          -@-   In Register-to-Memory transfer mode, pdata parameter is the register
59                color, in Memory-to-memory or Memory-to-Memory with pixel format
60                conversion pdata is the source address.
61 
62          -@-   Configure the foreground source address, the background source address,
63                the destination and data length then Enable the transfer using
64                HAL_DMA2D_BlendingStart() in polling mode and HAL_DMA2D_BlendingStart_IT()
65                in interrupt mode.
66 
67          -@-   HAL_DMA2D_BlendingStart() and HAL_DMA2D_BlendingStart_IT() functions
68                are used if the memory to memory with blending transfer mode is selected.
69 
70       (#) Optionally, configure and enable the CLUT using HAL_DMA2D_CLUTLoad() in polling
71           mode or HAL_DMA2D_CLUTLoad_IT() in interrupt mode.
72 
73       (#) Optionally, configure the line watermark in using the API HAL_DMA2D_ProgramLineEvent().
74 
75       (#) Optionally, configure the dead time value in the AHB clock cycle inserted between two
76           consecutive accesses on the AHB master port in using the API HAL_DMA2D_ConfigDeadTime()
77           and enable/disable the functionality  with the APIs HAL_DMA2D_EnableDeadTime() or
78           HAL_DMA2D_DisableDeadTime().
79 
80       (#) The transfer can be suspended, resumed and aborted using the following
81           functions: HAL_DMA2D_Suspend(), HAL_DMA2D_Resume(), HAL_DMA2D_Abort().
82 
83       (#) The CLUT loading can be suspended, resumed and aborted using the following
84           functions: HAL_DMA2D_CLUTLoading_Suspend(), HAL_DMA2D_CLUTLoading_Resume(),
85           HAL_DMA2D_CLUTLoading_Abort().
86 
87       (#) To control the DMA2D state, use the following function: HAL_DMA2D_GetState().
88 
89       (#) To read the DMA2D error code, use the following function: HAL_DMA2D_GetError().
90 
91      *** DMA2D HAL driver macros list ***
92      =============================================
93      [..]
94        Below the list of most used macros in DMA2D HAL driver :
95 
96       (+) __HAL_DMA2D_ENABLE: Enable the DMA2D peripheral.
97       (+) __HAL_DMA2D_GET_FLAG: Get the DMA2D pending flags.
98       (+) __HAL_DMA2D_CLEAR_FLAG: Clear the DMA2D pending flags.
99       (+) __HAL_DMA2D_ENABLE_IT: Enable the specified DMA2D interrupts.
100       (+) __HAL_DMA2D_DISABLE_IT: Disable the specified DMA2D interrupts.
101       (+) __HAL_DMA2D_GET_IT_SOURCE: Check whether the specified DMA2D interrupt is enabled or not.
102 
103      *** Callback registration ***
104      ===================================
105      [..]
106       (#) The compilation define  USE_HAL_DMA2D_REGISTER_CALLBACKS when set to 1
107           allows the user to configure dynamically the driver callbacks.
108           Use function @ref HAL_DMA2D_RegisterCallback() to register a user callback.
109 
110       (#) Function @ref HAL_DMA2D_RegisterCallback() allows to register following callbacks:
111             (+) XferCpltCallback : callback for transfer complete.
112             (+) XferErrorCallback : callback for transfer error.
113             (+) LineEventCallback : callback for line event.
114             (+) CLUTLoadingCpltCallback : callback for CLUT loading completion.
115             (+) MspInitCallback    : DMA2D MspInit.
116             (+) MspDeInitCallback  : DMA2D MspDeInit.
117           This function takes as parameters the HAL peripheral handle, the Callback ID
118           and a pointer to the user callback function.
119 
120       (#) Use function @ref HAL_DMA2D_UnRegisterCallback() to reset a callback to the default
121           weak (surcharged) function.
122           @ref HAL_DMA2D_UnRegisterCallback() takes as parameters the HAL peripheral handle,
123           and the Callback ID.
124           This function allows to reset following callbacks:
125             (+) XferCpltCallback : callback for transfer complete.
126             (+) XferErrorCallback : callback for transfer error.
127             (+) LineEventCallback : callback for line event.
128             (+) CLUTLoadingCpltCallback : callback for CLUT loading completion.
129             (+) MspInitCallback    : DMA2D MspInit.
130             (+) MspDeInitCallback  : DMA2D MspDeInit.
131 
132       (#) By default, after the @ref HAL_DMA2D_Init and if the state is HAL_DMA2D_STATE_RESET
133           all callbacks are reset to the corresponding legacy weak (surcharged) functions:
134           examples @ref HAL_DMA2D_LineEventCallback(), @ref HAL_DMA2D_CLUTLoadingCpltCallback()
135           Exception done for MspInit and MspDeInit callbacks that are respectively
136           reset to the legacy weak (surcharged) functions in the @ref HAL_DMA2D_Init
137           and @ref HAL_DMA2D_DeInit only when these callbacks are null (not registered beforehand)
138           If not, MspInit or MspDeInit are not null, the @ref HAL_DMA2D_Init and @ref HAL_DMA2D_DeInit
139           keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
140 
141           Exception as well for Transfer Completion and Transfer Error callbacks that are not defined
142           as weak (surcharged) functions. They must be defined by the user to be resorted to.
143 
144           Callbacks can be registered/unregistered in READY state only.
145           Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
146           in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
147           during the Init/DeInit.
148           In that case first register the MspInit/MspDeInit user callbacks
149           using @ref HAL_DMA2D_RegisterCallback before calling @ref HAL_DMA2D_DeInit
150           or @ref HAL_DMA2D_Init function.
151 
152           When The compilation define USE_HAL_DMA2D_REGISTER_CALLBACKS is set to 0 or
153           not defined, the callback registering feature is not available
154           and weak (surcharged) callbacks are used.
155 
156      [..]
157       (@) You can refer to the DMA2D HAL driver header file for more useful macros
158 
159   @endverbatim
160   ******************************************************************************
161   */
162 
163 /* Includes ------------------------------------------------------------------*/
164 #include "stm32u5xx_hal.h"
165 
166 #ifdef HAL_DMA2D_MODULE_ENABLED
167 #if defined (DMA2D)
168 
169 /** @addtogroup STM32U5xx_HAL_Driver
170   * @{
171   */
172 
173 /** @defgroup DMA2D  DMA2D
174   * @brief DMA2D HAL module driver
175   * @{
176   */
177 
178 /* Private types -------------------------------------------------------------*/
179 /* Private define ------------------------------------------------------------*/
180 /** @defgroup DMA2D_Private_Constants DMA2D Private Constants
181   * @{
182   */
183 
184 /** @defgroup DMA2D_TimeOut DMA2D Time Out
185   * @{
186   */
187 #define DMA2D_TIMEOUT_ABORT           (1000U)  /*!<  1s  */
188 #define DMA2D_TIMEOUT_SUSPEND         (1000U)  /*!<  1s  */
189 /**
190   * @}
191   */
192 
193 /**
194   * @}
195   */
196 
197 /* Private variables ---------------------------------------------------------*/
198 /* Private constants ---------------------------------------------------------*/
199 /* Private macro -------------------------------------------------------------*/
200 /* Private function prototypes -----------------------------------------------*/
201 /** @addtogroup DMA2D_Private_Functions DMA2D Private Functions
202   * @{
203   */
204 static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,
205                             uint32_t Height);
206 /**
207   * @}
208   */
209 
210 /* Private functions ---------------------------------------------------------*/
211 /* Exported functions --------------------------------------------------------*/
212 /** @defgroup DMA2D_Exported_Functions DMA2D Exported Functions
213   * @{
214   */
215 
216 /** @defgroup DMA2D_Exported_Functions_Group1 Initialization and de-initialization functions
217   *  @brief   Initialization and Configuration functions
218   *
219 @verbatim
220  ===============================================================================
221                 ##### Initialization and Configuration functions #####
222  ===============================================================================
223     [..]  This section provides functions allowing to:
224       (+) Initialize and configure the DMA2D
225       (+) De-initialize the DMA2D
226 
227 @endverbatim
228   * @{
229   */
230 
231 /**
232   * @brief  Initialize the DMA2D according to the specified
233   *         parameters in the DMA2D_InitTypeDef and create the associated handle.
234   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
235   *                 the configuration information for the DMA2D.
236   * @retval HAL status
237   */
HAL_DMA2D_Init(DMA2D_HandleTypeDef * hdma2d)238 HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d)
239 {
240   /* Check the DMA2D peripheral state */
241   if (hdma2d == NULL)
242   {
243     return HAL_ERROR;
244   }
245 
246   /* Check the parameters */
247   assert_param(IS_DMA2D_ALL_INSTANCE(hdma2d->Instance));
248   assert_param(IS_DMA2D_MODE(hdma2d->Init.Mode));
249   assert_param(IS_DMA2D_CMODE(hdma2d->Init.ColorMode));
250   assert_param(IS_DMA2D_OFFSET(hdma2d->Init.OutputOffset));
251   assert_param(IS_DMA2D_ALPHA_INVERTED(hdma2d->Init.AlphaInverted));
252   assert_param(IS_DMA2D_RB_SWAP(hdma2d->Init.RedBlueSwap));
253   assert_param(IS_DMA2D_LOM_MODE(hdma2d->Init.LineOffsetMode));
254   assert_param(IS_DMA2D_BYTES_SWAP(hdma2d->Init.BytesSwap));
255 
256 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
257   if (hdma2d->State == HAL_DMA2D_STATE_RESET)
258   {
259     /* Reset Callback pointers in HAL_DMA2D_STATE_RESET only */
260     hdma2d->LineEventCallback       = HAL_DMA2D_LineEventCallback;
261     hdma2d->CLUTLoadingCpltCallback = HAL_DMA2D_CLUTLoadingCpltCallback;
262     if (hdma2d->MspInitCallback == NULL)
263     {
264       hdma2d->MspInitCallback = HAL_DMA2D_MspInit;
265     }
266 
267     /* Init the low level hardware */
268     hdma2d->MspInitCallback(hdma2d);
269   }
270 #else
271   if (hdma2d->State == HAL_DMA2D_STATE_RESET)
272   {
273     /* Allocate lock resource and initialize it */
274     hdma2d->Lock = HAL_UNLOCKED;
275     /* Init the low level hardware */
276     HAL_DMA2D_MspInit(hdma2d);
277   }
278 #endif /* (USE_HAL_DMA2D_REGISTER_CALLBACKS) */
279 
280   /* Change DMA2D peripheral state */
281   hdma2d->State = HAL_DMA2D_STATE_BUSY;
282 
283   /* DMA2D CR register configuration -------------------------------------------*/
284   MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_MODE | DMA2D_CR_LOM, hdma2d->Init.Mode | hdma2d->Init.LineOffsetMode);
285 
286   /* DMA2D OPFCCR register configuration ---------------------------------------*/
287   MODIFY_REG(hdma2d->Instance->OPFCCR, DMA2D_OPFCCR_CM | DMA2D_OPFCCR_SB,
288              hdma2d->Init.ColorMode | hdma2d->Init.BytesSwap);
289 
290   /* DMA2D OOR register configuration ------------------------------------------*/
291   MODIFY_REG(hdma2d->Instance->OOR, DMA2D_OOR_LO, hdma2d->Init.OutputOffset);
292   /* DMA2D OPFCCR AI and RBS fields setting (Output Alpha Inversion)*/
293   MODIFY_REG(hdma2d->Instance->OPFCCR, (DMA2D_OPFCCR_AI | DMA2D_OPFCCR_RBS),
294              ((hdma2d->Init.AlphaInverted << DMA2D_OPFCCR_AI_Pos) | \
295               (hdma2d->Init.RedBlueSwap << DMA2D_OPFCCR_RBS_Pos)));
296 
297 
298   /* Update error code */
299   hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE;
300 
301   /* Initialize the DMA2D state*/
302   hdma2d->State  = HAL_DMA2D_STATE_READY;
303 
304   return HAL_OK;
305 }
306 
307 /**
308   * @brief  Deinitializes the DMA2D peripheral registers to their default reset
309   *         values.
310   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
311   *                 the configuration information for the DMA2D.
312   * @retval None
313   */
314 
HAL_DMA2D_DeInit(DMA2D_HandleTypeDef * hdma2d)315 HAL_StatusTypeDef HAL_DMA2D_DeInit(DMA2D_HandleTypeDef *hdma2d)
316 {
317 
318   /* Check the DMA2D peripheral state */
319   if (hdma2d == NULL)
320   {
321     return HAL_ERROR;
322   }
323 
324   /* Before aborting any DMA2D transfer or CLUT loading, check
325      first whether or not DMA2D clock is enabled */
326   if (__HAL_RCC_DMA2D_IS_CLK_ENABLED())
327   {
328     /* Abort DMA2D transfer if any */
329     if ((hdma2d->Instance->CR & DMA2D_CR_START) == DMA2D_CR_START)
330     {
331       if (HAL_DMA2D_Abort(hdma2d) != HAL_OK)
332       {
333         /* Issue when aborting DMA2D transfer */
334         return HAL_ERROR;
335       }
336     }
337     else
338     {
339       /* Abort background CLUT loading if any */
340       if ((hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START) == DMA2D_BGPFCCR_START)
341       {
342         if (HAL_DMA2D_CLUTLoading_Abort(hdma2d, 0U) != HAL_OK)
343         {
344           /* Issue when aborting background CLUT loading */
345           return HAL_ERROR;
346         }
347       }
348       else
349       {
350         /* Abort foreground CLUT loading if any */
351         if ((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) == DMA2D_FGPFCCR_START)
352         {
353           if (HAL_DMA2D_CLUTLoading_Abort(hdma2d, 1U) != HAL_OK)
354           {
355             /* Issue when aborting foreground CLUT loading */
356             return HAL_ERROR;
357           }
358         }
359       }
360     }
361   }
362 
363   /* Reset DMA2D control registers*/
364   hdma2d->Instance->CR       =    0U;
365   hdma2d->Instance->IFCR     = 0x3FU;
366   hdma2d->Instance->FGOR     =    0U;
367   hdma2d->Instance->BGOR     =    0U;
368   hdma2d->Instance->FGPFCCR  =    0U;
369   hdma2d->Instance->BGPFCCR  =    0U;
370   hdma2d->Instance->OPFCCR   =    0U;
371 
372 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
373 
374   if (hdma2d->MspDeInitCallback == NULL)
375   {
376     hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit;
377   }
378 
379   /* DeInit the low level hardware */
380   hdma2d->MspDeInitCallback(hdma2d);
381 
382 #else
383   /* Carry on with de-initialization of low level hardware */
384   HAL_DMA2D_MspDeInit(hdma2d);
385 #endif /* (USE_HAL_DMA2D_REGISTER_CALLBACKS) */
386 
387   /* Update error code */
388   hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE;
389 
390   /* Initialize the DMA2D state*/
391   hdma2d->State  = HAL_DMA2D_STATE_RESET;
392 
393   /* Release Lock */
394   __HAL_UNLOCK(hdma2d);
395 
396   return HAL_OK;
397 }
398 
399 /**
400   * @brief  Initializes the DMA2D MSP.
401   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
402   *                 the configuration information for the DMA2D.
403   * @retval None
404   */
HAL_DMA2D_MspInit(DMA2D_HandleTypeDef * hdma2d)405 __weak void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef *hdma2d)
406 {
407   /* Prevent unused argument(s) compilation warning */
408   UNUSED(hdma2d);
409 
410   /* NOTE : This function should not be modified; when the callback is needed,
411             the HAL_DMA2D_MspInit can be implemented in the user file.
412    */
413 }
414 
415 /**
416   * @brief  DeInitializes the DMA2D MSP.
417   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
418   *                 the configuration information for the DMA2D.
419   * @retval None
420   */
HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef * hdma2d)421 __weak void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef *hdma2d)
422 {
423   /* Prevent unused argument(s) compilation warning */
424   UNUSED(hdma2d);
425 
426   /* NOTE : This function should not be modified; when the callback is needed,
427             the HAL_DMA2D_MspDeInit can be implemented in the user file.
428    */
429 }
430 
431 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
432 /**
433   * @brief  Register a User DMA2D Callback
434   *         To be used instead of the weak (surcharged) predefined callback
435   * @param hdma2d DMA2D handle
436   * @param CallbackID ID of the callback to be registered
437   *        This parameter can be one of the following values:
438   *          @arg @ref HAL_DMA2D_TRANSFERCOMPLETE_CB_ID DMA2D transfer complete Callback ID
439   *          @arg @ref HAL_DMA2D_TRANSFERERROR_CB_ID DMA2D transfer error Callback ID
440   *          @arg @ref HAL_DMA2D_LINEEVENT_CB_ID DMA2D line event Callback ID
441   *          @arg @ref HAL_DMA2D_CLUTLOADINGCPLT_CB_ID DMA2D CLUT loading completion Callback ID
442   *          @arg @ref HAL_DMA2D_MSPINIT_CB_ID DMA2D MspInit callback ID
443   *          @arg @ref HAL_DMA2D_MSPDEINIT_CB_ID DMA2D MspDeInit callback ID
444   * @param pCallback pointer to the Callback function
445   * @note No weak predefined callbacks are defined for HAL_DMA2D_TRANSFERCOMPLETE_CB_ID or HAL_DMA2D_TRANSFERERROR_CB_ID
446   * @retval status
447   */
HAL_DMA2D_RegisterCallback(DMA2D_HandleTypeDef * hdma2d,HAL_DMA2D_CallbackIDTypeDef CallbackID,pDMA2D_CallbackTypeDef pCallback)448 HAL_StatusTypeDef HAL_DMA2D_RegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID,
449                                              pDMA2D_CallbackTypeDef pCallback)
450 {
451   HAL_StatusTypeDef status = HAL_OK;
452 
453   if (pCallback == NULL)
454   {
455     /* Update the error code */
456     hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
457     return HAL_ERROR;
458   }
459   /* Process locked */
460   __HAL_LOCK(hdma2d);
461 
462   if (HAL_DMA2D_STATE_READY == hdma2d->State)
463   {
464     switch (CallbackID)
465     {
466       case HAL_DMA2D_TRANSFERCOMPLETE_CB_ID :
467         hdma2d->XferCpltCallback = pCallback;
468         break;
469 
470       case HAL_DMA2D_TRANSFERERROR_CB_ID :
471         hdma2d->XferErrorCallback = pCallback;
472         break;
473 
474       case HAL_DMA2D_LINEEVENT_CB_ID :
475         hdma2d->LineEventCallback = pCallback;
476         break;
477 
478       case HAL_DMA2D_CLUTLOADINGCPLT_CB_ID :
479         hdma2d->CLUTLoadingCpltCallback = pCallback;
480         break;
481 
482       case HAL_DMA2D_MSPINIT_CB_ID :
483         hdma2d->MspInitCallback = pCallback;
484         break;
485 
486       case HAL_DMA2D_MSPDEINIT_CB_ID :
487         hdma2d->MspDeInitCallback = pCallback;
488         break;
489 
490       default :
491         /* Update the error code */
492         hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
493         /* update return status */
494         status =  HAL_ERROR;
495         break;
496     }
497   }
498   else if (HAL_DMA2D_STATE_RESET == hdma2d->State)
499   {
500     switch (CallbackID)
501     {
502       case HAL_DMA2D_MSPINIT_CB_ID :
503         hdma2d->MspInitCallback = pCallback;
504         break;
505 
506       case HAL_DMA2D_MSPDEINIT_CB_ID :
507         hdma2d->MspDeInitCallback = pCallback;
508         break;
509 
510       default :
511         /* Update the error code */
512         hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
513         /* update return status */
514         status =  HAL_ERROR;
515         break;
516     }
517   }
518   else
519   {
520     /* Update the error code */
521     hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
522     /* update return status */
523     status =  HAL_ERROR;
524   }
525 
526   /* Release Lock */
527   __HAL_UNLOCK(hdma2d);
528   return status;
529 }
530 
531 /**
532   * @brief  Unregister a DMA2D Callback
533   *         DMA2D Callback is redirected to the weak (surcharged) predefined callback
534   * @param hdma2d DMA2D handle
535   * @param CallbackID ID of the callback to be unregistered
536   *        This parameter can be one of the following values:
537   *          @arg @ref HAL_DMA2D_TRANSFERCOMPLETE_CB_ID DMA2D transfer complete Callback ID
538   *          @arg @ref HAL_DMA2D_TRANSFERERROR_CB_ID DMA2D transfer error Callback ID
539   *          @arg @ref HAL_DMA2D_LINEEVENT_CB_ID DMA2D line event Callback ID
540   *          @arg @ref HAL_DMA2D_CLUTLOADINGCPLT_CB_ID DMA2D CLUT loading completion Callback ID
541   *          @arg @ref HAL_DMA2D_MSPINIT_CB_ID DMA2D MspInit callback ID
542   *          @arg @ref HAL_DMA2D_MSPDEINIT_CB_ID DMA2D MspDeInit callback ID
543   * @note No weak predefined callbacks are defined for HAL_DMA2D_TRANSFERCOMPLETE_CB_ID or HAL_DMA2D_TRANSFERERROR_CB_ID
544   * @retval status
545   */
HAL_DMA2D_UnRegisterCallback(DMA2D_HandleTypeDef * hdma2d,HAL_DMA2D_CallbackIDTypeDef CallbackID)546 HAL_StatusTypeDef HAL_DMA2D_UnRegisterCallback(DMA2D_HandleTypeDef *hdma2d, HAL_DMA2D_CallbackIDTypeDef CallbackID)
547 {
548   HAL_StatusTypeDef status = HAL_OK;
549 
550   /* Process locked */
551   __HAL_LOCK(hdma2d);
552 
553   if (HAL_DMA2D_STATE_READY == hdma2d->State)
554   {
555     switch (CallbackID)
556     {
557       case HAL_DMA2D_TRANSFERCOMPLETE_CB_ID :
558         hdma2d->XferCpltCallback = NULL;
559         break;
560 
561       case HAL_DMA2D_TRANSFERERROR_CB_ID :
562         hdma2d->XferErrorCallback = NULL;
563         break;
564 
565       case HAL_DMA2D_LINEEVENT_CB_ID :
566         hdma2d->LineEventCallback = HAL_DMA2D_LineEventCallback;
567         break;
568 
569       case HAL_DMA2D_CLUTLOADINGCPLT_CB_ID :
570         hdma2d->CLUTLoadingCpltCallback = HAL_DMA2D_CLUTLoadingCpltCallback;
571         break;
572 
573       case HAL_DMA2D_MSPINIT_CB_ID :
574         hdma2d->MspInitCallback = HAL_DMA2D_MspInit; /* Legacy weak (surcharged) Msp Init */
575         break;
576 
577       case HAL_DMA2D_MSPDEINIT_CB_ID :
578         hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit; /* Legacy weak (surcharged) Msp DeInit */
579         break;
580 
581       default :
582         /* Update the error code */
583         hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
584         /* update return status */
585         status =  HAL_ERROR;
586         break;
587     }
588   }
589   else if (HAL_DMA2D_STATE_RESET == hdma2d->State)
590   {
591     switch (CallbackID)
592     {
593       case HAL_DMA2D_MSPINIT_CB_ID :
594         hdma2d->MspInitCallback = HAL_DMA2D_MspInit;   /* Legacy weak (surcharged) Msp Init */
595         break;
596 
597       case HAL_DMA2D_MSPDEINIT_CB_ID :
598         hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit;  /* Legacy weak (surcharged) Msp DeInit */
599         break;
600 
601       default :
602         /* Update the error code */
603         hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
604         /* update return status */
605         status =  HAL_ERROR;
606         break;
607     }
608   }
609   else
610   {
611     /* Update the error code */
612     hdma2d->ErrorCode |= HAL_DMA2D_ERROR_INVALID_CALLBACK;
613     /* update return status */
614     status =  HAL_ERROR;
615   }
616 
617   /* Release Lock */
618   __HAL_UNLOCK(hdma2d);
619   return status;
620 }
621 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
622 
623 /**
624   * @}
625   */
626 
627 
628 /** @defgroup DMA2D_Exported_Functions_Group2 IO operation functions
629   *  @brief   IO operation functions
630   *
631 @verbatim
632  ===============================================================================
633                       #####  IO operation functions  #####
634  ===============================================================================
635     [..]  This section provides functions allowing to:
636       (+) Configure the pdata, destination address and data size then
637           start the DMA2D transfer.
638       (+) Configure the source for foreground and background, destination address
639           and data size then start a MultiBuffer DMA2D transfer.
640       (+) Configure the pdata, destination address and data size then
641           start the DMA2D transfer with interrupt.
642       (+) Configure the source for foreground and background, destination address
643           and data size then start a MultiBuffer DMA2D transfer with interrupt.
644       (+) Abort DMA2D transfer.
645       (+) Suspend DMA2D transfer.
646       (+) Resume DMA2D transfer.
647       (+) Enable CLUT transfer.
648       (+) Configure CLUT loading then start transfer in polling mode.
649       (+) Configure CLUT loading then start transfer in interrupt mode.
650       (+) Abort DMA2D CLUT loading.
651       (+) Suspend DMA2D CLUT loading.
652       (+) Resume DMA2D CLUT loading.
653       (+) Poll for transfer complete.
654       (+) handle DMA2D interrupt request.
655       (+) Transfer watermark callback.
656       (+) CLUT Transfer Complete callback.
657 
658 
659 @endverbatim
660   * @{
661   */
662 
663 /**
664   * @brief  Start the DMA2D Transfer.
665   * @param  hdma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
666   *                     the configuration information for the DMA2D.
667   * @param  pdata      Configure the source memory Buffer address if
668   *                     Memory-to-Memory or Memory-to-Memory with pixel format
669   *                     conversion mode is selected, or configure
670   *                     the color value if Register-to-Memory mode is selected.
671   * @param  DstAddress The destination memory Buffer address.
672   * @param  Width      The width of data to be transferred from source
673   *                    to destination (expressed in number of pixels per line).
674   * @param  Height     The height of data to be transferred from source to destination (expressed in number of lines).
675   * @retval HAL status
676   */
HAL_DMA2D_Start(DMA2D_HandleTypeDef * hdma2d,uint32_t pdata,uint32_t DstAddress,uint32_t Width,uint32_t Height)677 HAL_StatusTypeDef HAL_DMA2D_Start(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,
678                                   uint32_t Height)
679 {
680   /* Check the parameters */
681   assert_param(IS_DMA2D_LINE(Height));
682   assert_param(IS_DMA2D_PIXEL(Width));
683 
684   /* Process locked */
685   __HAL_LOCK(hdma2d);
686 
687   /* Change DMA2D peripheral state */
688   hdma2d->State = HAL_DMA2D_STATE_BUSY;
689 
690   /* Configure the source, destination address and the data size */
691   DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height);
692 
693   /* Enable the Peripheral */
694   __HAL_DMA2D_ENABLE(hdma2d);
695 
696   return HAL_OK;
697 }
698 
699 /**
700   * @brief  Start the DMA2D Transfer with interrupt enabled.
701   * @param  hdma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
702   *                     the configuration information for the DMA2D.
703   * @param  pdata      Configure the source memory Buffer address if
704   *                     the Memory-to-Memory or Memory-to-Memory with pixel format
705   *                     conversion mode is selected, or configure
706   *                     the color value if Register-to-Memory mode is selected.
707   * @param  DstAddress The destination memory Buffer address.
708   * @param  Width      The width of data to be transferred from source
709   *                    to destination (expressed in number of pixels per line).
710   * @param  Height     The height of data to be transferred from source to destination (expressed in number of lines).
711   * @retval HAL status
712   */
HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef * hdma2d,uint32_t pdata,uint32_t DstAddress,uint32_t Width,uint32_t Height)713 HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,
714                                      uint32_t Height)
715 {
716   /* Check the parameters */
717   assert_param(IS_DMA2D_LINE(Height));
718   assert_param(IS_DMA2D_PIXEL(Width));
719 
720   /* Process locked */
721   __HAL_LOCK(hdma2d);
722 
723   /* Change DMA2D peripheral state */
724   hdma2d->State = HAL_DMA2D_STATE_BUSY;
725 
726   /* Configure the source, destination address and the data size */
727   DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height);
728 
729   /* Enable the transfer complete, transfer error and configuration error interrupts */
730   __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE);
731 
732   /* Enable the Peripheral */
733   __HAL_DMA2D_ENABLE(hdma2d);
734 
735   return HAL_OK;
736 }
737 
738 /**
739   * @brief  Start the multi-source DMA2D Transfer.
740   * @param  hdma2d      Pointer to a DMA2D_HandleTypeDef structure that contains
741   *                      the configuration information for the DMA2D.
742   * @param  SrcAddress1 The source memory Buffer address for the foreground layer.
743   * @param  SrcAddress2 The source memory Buffer address for the background layer.
744   * @param  DstAddress  The destination memory Buffer address.
745   * @param  Width       The width of data to be transferred from source
746   *                     to destination (expressed in number of pixels per line).
747   * @param  Height      The height of data to be transferred from source to destination (expressed in number of lines).
748   * @retval HAL status
749   */
HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef * hdma2d,uint32_t SrcAddress1,uint32_t SrcAddress2,uint32_t DstAddress,uint32_t Width,uint32_t Height)750 HAL_StatusTypeDef HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t  SrcAddress2,
751                                           uint32_t DstAddress, uint32_t Width,  uint32_t Height)
752 {
753   /* Check the parameters */
754   assert_param(IS_DMA2D_LINE(Height));
755   assert_param(IS_DMA2D_PIXEL(Width));
756 
757   /* Process locked */
758   __HAL_LOCK(hdma2d);
759 
760   /* Change DMA2D peripheral state */
761   hdma2d->State = HAL_DMA2D_STATE_BUSY;
762 
763   if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG)
764   {
765     /*blending & fixed FG*/
766     WRITE_REG(hdma2d->Instance->FGCOLR, SrcAddress1);
767     /* Configure the source, destination address and the data size */
768     DMA2D_SetConfig(hdma2d, SrcAddress2, DstAddress, Width, Height);
769   }
770   else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_BG)
771   {
772     /*blending & fixed BG*/
773     WRITE_REG(hdma2d->Instance->BGCOLR, SrcAddress2);
774     /* Configure the source, destination address and the data size */
775     DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height);
776   }
777   else
778   {
779     /* Configure DMA2D Stream source2 address */
780     WRITE_REG(hdma2d->Instance->BGMAR, SrcAddress2);
781 
782     /* Configure the source, destination address and the data size */
783     DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height);
784   }
785 
786   /* Enable the Peripheral */
787   __HAL_DMA2D_ENABLE(hdma2d);
788 
789   return HAL_OK;
790 }
791 
792 /**
793   * @brief  Start the multi-source DMA2D Transfer with interrupt enabled.
794   * @param  hdma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
795   *                     the configuration information for the DMA2D.
796   * @param  SrcAddress1 The source memory Buffer address for the foreground layer.
797   * @param  SrcAddress2 The source memory Buffer address for the background layer.
798   * @param  DstAddress  The destination memory Buffer address.
799   * @param  Width       The width of data to be transferred from source
800   *                     to destination (expressed in number of pixels per line).
801   * @param  Height      The height of data to be transferred from source to destination (expressed in number of lines).
802   * @retval HAL status
803   */
HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef * hdma2d,uint32_t SrcAddress1,uint32_t SrcAddress2,uint32_t DstAddress,uint32_t Width,uint32_t Height)804 HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t  SrcAddress2,
805                                              uint32_t DstAddress, uint32_t Width,  uint32_t Height)
806 {
807   /* Check the parameters */
808   assert_param(IS_DMA2D_LINE(Height));
809   assert_param(IS_DMA2D_PIXEL(Width));
810 
811   /* Process locked */
812   __HAL_LOCK(hdma2d);
813 
814   /* Change DMA2D peripheral state */
815   hdma2d->State = HAL_DMA2D_STATE_BUSY;
816 
817   if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG)
818   {
819     /*blending & fixed FG*/
820     WRITE_REG(hdma2d->Instance->FGCOLR, SrcAddress1);
821     /* Configure the source, destination address and the data size */
822     DMA2D_SetConfig(hdma2d, SrcAddress2, DstAddress, Width, Height);
823   }
824   else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_BG)
825   {
826     /*blending & fixed BG*/
827     WRITE_REG(hdma2d->Instance->BGCOLR, SrcAddress2);
828     /* Configure the source, destination address and the data size */
829     DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height);
830   }
831   else
832   {
833     WRITE_REG(hdma2d->Instance->BGMAR, SrcAddress2);
834 
835     /* Configure the source, destination address and the data size */
836     DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height);
837   }
838 
839   /* Enable the transfer complete, transfer error and configuration error interrupts */
840   __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE);
841 
842   /* Enable the Peripheral */
843   __HAL_DMA2D_ENABLE(hdma2d);
844 
845   return HAL_OK;
846 }
847 
848 /**
849   * @brief  Abort the DMA2D Transfer.
850   * @param  hdma2d  pointer to a DMA2D_HandleTypeDef structure that contains
851   *                  the configuration information for the DMA2D.
852   * @retval HAL status
853   */
HAL_DMA2D_Abort(DMA2D_HandleTypeDef * hdma2d)854 HAL_StatusTypeDef HAL_DMA2D_Abort(DMA2D_HandleTypeDef *hdma2d)
855 {
856   uint32_t tickstart;
857 
858   /* Abort the DMA2D transfer */
859   /* START bit is reset to make sure not to set it again, in the event the HW clears it
860      between the register read and the register write by the CPU (writing 0 has no
861      effect on START bitvalue) */
862   MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_ABORT | DMA2D_CR_START, DMA2D_CR_ABORT);
863 
864   /* Get tick */
865   tickstart = HAL_GetTick();
866 
867   /* Check if the DMA2D is effectively disabled */
868   while ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U)
869   {
870     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_ABORT)
871     {
872       /* Update error code */
873       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
874 
875       /* Change the DMA2D state */
876       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
877 
878       /* Process Unlocked */
879       __HAL_UNLOCK(hdma2d);
880 
881       return HAL_TIMEOUT;
882     }
883   }
884 
885   /* Disable the Transfer Complete, Transfer Error and Configuration Error interrupts */
886   __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC | DMA2D_IT_TE | DMA2D_IT_CE);
887 
888   /* Change the DMA2D state*/
889   hdma2d->State = HAL_DMA2D_STATE_READY;
890 
891   /* Process Unlocked */
892   __HAL_UNLOCK(hdma2d);
893 
894   return HAL_OK;
895 }
896 
897 /**
898   * @brief  Suspend the DMA2D Transfer.
899   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
900   *                 the configuration information for the DMA2D.
901   * @retval HAL status
902   */
HAL_DMA2D_Suspend(DMA2D_HandleTypeDef * hdma2d)903 HAL_StatusTypeDef HAL_DMA2D_Suspend(DMA2D_HandleTypeDef *hdma2d)
904 {
905   uint32_t tickstart;
906 
907   /* Suspend the DMA2D transfer */
908   /* START bit is reset to make sure not to set it again, in the event the HW clears it
909      between the register read and the register write by the CPU (writing 0 has no
910      effect on START bitvalue). */
911   MODIFY_REG(hdma2d->Instance->CR, DMA2D_CR_SUSP | DMA2D_CR_START, DMA2D_CR_SUSP);
912 
913   /* Get tick */
914   tickstart = HAL_GetTick();
915 
916   /* Check if the DMA2D is effectively suspended */
917   while ((hdma2d->Instance->CR & (DMA2D_CR_SUSP | DMA2D_CR_START)) == DMA2D_CR_START)
918   {
919     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_SUSPEND)
920     {
921       /* Update error code */
922       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
923 
924       /* Change the DMA2D state */
925       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
926 
927       return HAL_TIMEOUT;
928     }
929   }
930 
931   /* Check whether or not a transfer is actually suspended and change the DMA2D state accordingly */
932   if ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U)
933   {
934     hdma2d->State = HAL_DMA2D_STATE_SUSPEND;
935   }
936   else
937   {
938     /* Make sure SUSP bit is cleared since it is meaningless
939        when no transfer is on-going */
940     CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
941   }
942 
943   return HAL_OK;
944 }
945 
946 /**
947   * @brief  Resume the DMA2D Transfer.
948   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
949   *                 the configuration information for the DMA2D.
950   * @retval HAL status
951   */
HAL_DMA2D_Resume(DMA2D_HandleTypeDef * hdma2d)952 HAL_StatusTypeDef HAL_DMA2D_Resume(DMA2D_HandleTypeDef *hdma2d)
953 {
954   /* Check the SUSP and START bits */
955   if ((hdma2d->Instance->CR & (DMA2D_CR_SUSP | DMA2D_CR_START)) == (DMA2D_CR_SUSP | DMA2D_CR_START))
956   {
957     /* Ongoing transfer is suspended: change the DMA2D state before resuming */
958     hdma2d->State = HAL_DMA2D_STATE_BUSY;
959   }
960 
961   /* Resume the DMA2D transfer */
962   /* START bit is reset to make sure not to set it again, in the event the HW clears it
963      between the register read and the register write by the CPU (writing 0 has no
964      effect on START bitvalue). */
965   CLEAR_BIT(hdma2d->Instance->CR, (DMA2D_CR_SUSP | DMA2D_CR_START));
966 
967   return HAL_OK;
968 }
969 
970 
971 /**
972   * @brief  Enable the DMA2D CLUT Transfer.
973   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
974   *                   the configuration information for the DMA2D.
975   * @param  LayerIdx DMA2D Layer index.
976   *                   This parameter can be one of the following values:
977   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
978   * @retval HAL status
979   */
HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)980 HAL_StatusTypeDef HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
981 {
982   /* Check the parameters */
983   assert_param(IS_DMA2D_LAYER(LayerIdx));
984 
985   /* Process locked */
986   __HAL_LOCK(hdma2d);
987 
988   /* Change DMA2D peripheral state */
989   hdma2d->State = HAL_DMA2D_STATE_BUSY;
990 
991   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
992   {
993     /* Enable the background CLUT loading */
994     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
995   }
996   else
997   {
998     /* Enable the foreground CLUT loading */
999     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1000   }
1001 
1002   return HAL_OK;
1003 }
1004 
1005 /**
1006   * @brief  Start DMA2D CLUT Loading.
1007   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1008   *                   the configuration information for the DMA2D.
1009   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1010   *                   the configuration information for the color look up table.
1011   * @param  LayerIdx DMA2D Layer index.
1012   *                   This parameter can be one of the following values:
1013   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1014   * @retval HAL status
1015   */
HAL_DMA2D_CLUTStartLoad(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef * CLUTCfg,uint32_t LayerIdx)1016 HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef *CLUTCfg, uint32_t LayerIdx)
1017 {
1018   /* Check the parameters */
1019   assert_param(IS_DMA2D_LAYER(LayerIdx));
1020   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode));
1021   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size));
1022 
1023   /* Process locked */
1024   __HAL_LOCK(hdma2d);
1025 
1026   /* Change DMA2D peripheral state */
1027   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1028 
1029   /* Configure the CLUT of the background DMA2D layer */
1030   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1031   {
1032     /* Write background CLUT memory address */
1033     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT);
1034 
1035     /* Write background CLUT size and CLUT color mode */
1036     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1037                ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1038 
1039     /* Enable the CLUT loading for the background */
1040     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1041   }
1042   /* Configure the CLUT of the foreground DMA2D layer */
1043   else
1044   {
1045     /* Write foreground CLUT memory address */
1046     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT);
1047 
1048     /* Write foreground CLUT size and CLUT color mode */
1049     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1050                ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1051 
1052     /* Enable the CLUT loading for the foreground */
1053     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1054   }
1055 
1056   return HAL_OK;
1057 }
1058 
1059 /**
1060   * @brief  Start DMA2D CLUT Loading with interrupt enabled.
1061   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1062   *                   the configuration information for the DMA2D.
1063   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1064   *                   the configuration information for the color look up table.
1065   * @param  LayerIdx DMA2D Layer index.
1066   *                   This parameter can be one of the following values:
1067   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1068   * @retval HAL status
1069   */
HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef * CLUTCfg,uint32_t LayerIdx)1070 HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef *CLUTCfg,
1071                                              uint32_t LayerIdx)
1072 {
1073   /* Check the parameters */
1074   assert_param(IS_DMA2D_LAYER(LayerIdx));
1075   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode));
1076   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size));
1077 
1078   /* Process locked */
1079   __HAL_LOCK(hdma2d);
1080 
1081   /* Change DMA2D peripheral state */
1082   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1083 
1084   /* Configure the CLUT of the background DMA2D layer */
1085   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1086   {
1087     /* Write background CLUT memory address */
1088     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT);
1089 
1090     /* Write background CLUT size and CLUT color mode */
1091     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1092                ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1093 
1094     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1095     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1096 
1097     /* Enable the CLUT loading for the background */
1098     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1099   }
1100   /* Configure the CLUT of the foreground DMA2D layer */
1101   else
1102   {
1103     /* Write foreground CLUT memory address */
1104     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT);
1105 
1106     /* Write foreground CLUT size and CLUT color mode */
1107     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1108                ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1109 
1110     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1111     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1112 
1113     /* Enable the CLUT loading for the foreground */
1114     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1115   }
1116 
1117   return HAL_OK;
1118 }
1119 
1120 /**
1121   * @brief  Start DMA2D CLUT Loading.
1122   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1123   *                   the configuration information for the DMA2D.
1124   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1125   *                   the configuration information for the color look up table.
1126   * @param  LayerIdx DMA2D Layer index.
1127   *                   This parameter can be one of the following values:
1128   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1129   * @note API obsolete and maintained for compatibility with legacy. User is
1130   *      invited to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from
1131   *      code compactness, code size and improved heap usage.
1132   * @retval HAL status
1133   */
HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1134 HAL_StatusTypeDef HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1135 {
1136   /* Check the parameters */
1137   assert_param(IS_DMA2D_LAYER(LayerIdx));
1138   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1139   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1140 
1141   /* Process locked */
1142   __HAL_LOCK(hdma2d);
1143 
1144   /* Change DMA2D peripheral state */
1145   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1146 
1147   /* Configure the CLUT of the background DMA2D layer */
1148   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1149   {
1150     /* Write background CLUT memory address */
1151     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1152 
1153     /* Write background CLUT size and CLUT color mode */
1154     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1155                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1156 
1157     /* Enable the CLUT loading for the background */
1158     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1159   }
1160   /* Configure the CLUT of the foreground DMA2D layer */
1161   else
1162   {
1163     /* Write foreground CLUT memory address */
1164     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1165 
1166     /* Write foreground CLUT size and CLUT color mode */
1167     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1168                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1169 
1170     /* Enable the CLUT loading for the foreground */
1171     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1172   }
1173 
1174   return HAL_OK;
1175 }
1176 
1177 /**
1178   * @brief  Start DMA2D CLUT Loading with interrupt enabled.
1179   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1180   *                   the configuration information for the DMA2D.
1181   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1182   *                   the configuration information for the color look up table.
1183   * @param  LayerIdx DMA2D Layer index.
1184   *                   This parameter can be one of the following values:
1185   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1186   * @note API obsolete and maintained for compatibility with legacy. User is
1187   *      invited to resort to HAL_DMA2D_CLUTStartLoad_IT() instead to benefit
1188   *      from code compactness, code size and improved heap usage.
1189   * @retval HAL status
1190   */
HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1191 HAL_StatusTypeDef HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1192 {
1193   /* Check the parameters */
1194   assert_param(IS_DMA2D_LAYER(LayerIdx));
1195   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1196   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1197 
1198   /* Process locked */
1199   __HAL_LOCK(hdma2d);
1200 
1201   /* Change DMA2D peripheral state */
1202   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1203 
1204   /* Configure the CLUT of the background DMA2D layer */
1205   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1206   {
1207     /* Write background CLUT memory address */
1208     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1209 
1210     /* Write background CLUT size and CLUT color mode */
1211     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1212                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1213 
1214     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1215     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1216 
1217     /* Enable the CLUT loading for the background */
1218     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1219   }
1220   /* Configure the CLUT of the foreground DMA2D layer */
1221   else
1222   {
1223     /* Write foreground CLUT memory address */
1224     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1225 
1226     /* Write foreground CLUT size and CLUT color mode */
1227     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1228                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1229 
1230     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1231     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1232 
1233     /* Enable the CLUT loading for the foreground */
1234     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1235   }
1236 
1237   return HAL_OK;
1238 }
1239 
1240 /**
1241   * @brief  Abort the DMA2D CLUT loading.
1242   * @param  hdma2d  Pointer to a DMA2D_HandleTypeDef structure that contains
1243   *                  the configuration information for the DMA2D.
1244   * @param  LayerIdx DMA2D Layer index.
1245   *                   This parameter can be one of the following values:
1246   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1247   * @retval HAL status
1248   */
HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1249 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1250 {
1251   uint32_t tickstart;
1252   const __IO uint32_t *reg =  &(hdma2d->Instance->BGPFCCR);  /* by default, point at background register */
1253 
1254   /* Abort the CLUT loading */
1255   SET_BIT(hdma2d->Instance->CR, DMA2D_CR_ABORT);
1256 
1257   /* If foreground CLUT loading is considered, update local variables */
1258   if (LayerIdx == DMA2D_FOREGROUND_LAYER)
1259   {
1260     reg  = &(hdma2d->Instance->FGPFCCR);
1261   }
1262 
1263 
1264   /* Get tick */
1265   tickstart = HAL_GetTick();
1266 
1267   /* Check if the CLUT loading is aborted */
1268   while ((*reg & DMA2D_BGPFCCR_START) != 0U)
1269   {
1270     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_ABORT)
1271     {
1272       /* Update error code */
1273       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1274 
1275       /* Change the DMA2D state */
1276       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1277 
1278       /* Process Unlocked */
1279       __HAL_UNLOCK(hdma2d);
1280 
1281       return HAL_TIMEOUT;
1282     }
1283   }
1284 
1285   /* Disable the CLUT Transfer Complete, Transfer Error, Configuration Error and CLUT Access Error interrupts */
1286   __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1287 
1288   /* Change the DMA2D state*/
1289   hdma2d->State = HAL_DMA2D_STATE_READY;
1290 
1291   /* Process Unlocked */
1292   __HAL_UNLOCK(hdma2d);
1293 
1294   return HAL_OK;
1295 }
1296 
1297 /**
1298   * @brief  Suspend the DMA2D CLUT loading.
1299   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1300   *                 the configuration information for the DMA2D.
1301   * @param  LayerIdx DMA2D Layer index.
1302   *                   This parameter can be one of the following values:
1303   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1304   * @retval HAL status
1305   */
HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1306 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1307 {
1308   uint32_t tickstart;
1309   uint32_t loadsuspended;
1310   const __IO uint32_t *reg =  &(hdma2d->Instance->BGPFCCR);  /* by default, point at background register */
1311 
1312   /* Suspend the CLUT loading */
1313   SET_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1314 
1315   /* If foreground CLUT loading is considered, update local variables */
1316   if (LayerIdx == DMA2D_FOREGROUND_LAYER)
1317   {
1318     reg  = &(hdma2d->Instance->FGPFCCR);
1319   }
1320 
1321   /* Get tick */
1322   tickstart = HAL_GetTick();
1323 
1324   /* Check if the CLUT loading is suspended */
1325   /* 1st condition: Suspend Check */
1326   loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL;
1327   /* 2nd condition: Not Start Check */
1328   loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL;
1329   while (loadsuspended == 0UL)
1330   {
1331     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_SUSPEND)
1332     {
1333       /* Update error code */
1334       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1335 
1336       /* Change the DMA2D state */
1337       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1338 
1339       return HAL_TIMEOUT;
1340     }
1341     /* 1st condition: Suspend Check */
1342     loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL;
1343     /* 2nd condition: Not Start Check */
1344     loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL;
1345   }
1346 
1347   /* Check whether or not a transfer is actually suspended and change the DMA2D state accordingly */
1348   if ((*reg & DMA2D_BGPFCCR_START) != 0U)
1349   {
1350     hdma2d->State = HAL_DMA2D_STATE_SUSPEND;
1351   }
1352   else
1353   {
1354     /* Make sure SUSP bit is cleared since it is meaningless
1355        when no transfer is on-going */
1356     CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1357   }
1358 
1359   return HAL_OK;
1360 }
1361 
1362 /**
1363   * @brief  Resume the DMA2D CLUT loading.
1364   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1365   *                 the configuration information for the DMA2D.
1366   * @param  LayerIdx DMA2D Layer index.
1367   *                   This parameter can be one of the following values:
1368   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1369   * @retval HAL status
1370   */
HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1371 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1372 {
1373   /* Check the SUSP and START bits for background or foreground CLUT loading */
1374   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1375   {
1376     /* Background CLUT loading suspension check */
1377     if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP)
1378     {
1379       if ((hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START) == DMA2D_BGPFCCR_START)
1380       {
1381         /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */
1382         hdma2d->State = HAL_DMA2D_STATE_BUSY;
1383       }
1384     }
1385   }
1386   else
1387   {
1388     /* Foreground CLUT loading suspension check */
1389     if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP)
1390     {
1391       if ((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) == DMA2D_FGPFCCR_START)
1392       {
1393         /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */
1394         hdma2d->State = HAL_DMA2D_STATE_BUSY;
1395       }
1396     }
1397   }
1398 
1399   /* Resume the CLUT loading */
1400   CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1401 
1402   return HAL_OK;
1403 }
1404 
1405 
1406 /**
1407 
1408   * @brief  Polling for transfer complete or CLUT loading.
1409   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1410   *                 the configuration information for the DMA2D.
1411   * @param  Timeout Timeout duration
1412   * @retval HAL status
1413   */
HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef * hdma2d,uint32_t Timeout)1414 HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout)
1415 {
1416   uint32_t tickstart;
1417   uint32_t layer_start;
1418   __IO uint32_t isrflags = 0x0U;
1419 
1420   /* Polling for DMA2D transfer */
1421   if ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U)
1422   {
1423     /* Get tick */
1424     tickstart = HAL_GetTick();
1425 
1426     while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) == 0U)
1427     {
1428       isrflags = READ_REG(hdma2d->Instance->ISR);
1429       if ((isrflags & (DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U)
1430       {
1431         if ((isrflags & DMA2D_FLAG_CE) != 0U)
1432         {
1433           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1434         }
1435         if ((isrflags & DMA2D_FLAG_TE) != 0U)
1436         {
1437           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1438         }
1439         /* Clear the transfer and configuration error flags */
1440         __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE | DMA2D_FLAG_TE);
1441 
1442         /* Change DMA2D state */
1443         hdma2d->State = HAL_DMA2D_STATE_ERROR;
1444 
1445         /* Process unlocked */
1446         __HAL_UNLOCK(hdma2d);
1447 
1448         return HAL_ERROR;
1449       }
1450       /* Check for the Timeout */
1451       if (Timeout != HAL_MAX_DELAY)
1452       {
1453         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1454         {
1455           /* Update error code */
1456           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1457 
1458           /* Change the DMA2D state */
1459           hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1460 
1461           /* Process unlocked */
1462           __HAL_UNLOCK(hdma2d);
1463 
1464           return HAL_TIMEOUT;
1465         }
1466       }
1467     }
1468   }
1469   /* Polling for CLUT loading (foreground or background) */
1470   layer_start = hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START;
1471   layer_start |= hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START;
1472   if (layer_start != 0U)
1473   {
1474     /* Get tick */
1475     tickstart = HAL_GetTick();
1476 
1477     while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CTC) == 0U)
1478     {
1479       isrflags = READ_REG(hdma2d->Instance->ISR);
1480       if ((isrflags & (DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U)
1481       {
1482         if ((isrflags & DMA2D_FLAG_CAE) != 0U)
1483         {
1484           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE;
1485         }
1486         if ((isrflags & DMA2D_FLAG_CE) != 0U)
1487         {
1488           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1489         }
1490         if ((isrflags & DMA2D_FLAG_TE) != 0U)
1491         {
1492           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1493         }
1494         /* Clear the CLUT Access Error, Configuration Error and Transfer Error flags */
1495         __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
1496 
1497         /* Change DMA2D state */
1498         hdma2d->State = HAL_DMA2D_STATE_ERROR;
1499 
1500         /* Process unlocked */
1501         __HAL_UNLOCK(hdma2d);
1502 
1503         return HAL_ERROR;
1504       }
1505       /* Check for the Timeout */
1506       if (Timeout != HAL_MAX_DELAY)
1507       {
1508         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1509         {
1510           /* Update error code */
1511           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1512 
1513           /* Change the DMA2D state */
1514           hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1515 
1516           /* Process unlocked */
1517           __HAL_UNLOCK(hdma2d);
1518 
1519           return HAL_TIMEOUT;
1520         }
1521       }
1522     }
1523   }
1524 
1525   /* Clear the transfer complete and CLUT loading flags */
1526   __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC | DMA2D_FLAG_CTC);
1527 
1528   /* Change DMA2D state */
1529   hdma2d->State = HAL_DMA2D_STATE_READY;
1530 
1531   /* Process unlocked */
1532   __HAL_UNLOCK(hdma2d);
1533 
1534   return HAL_OK;
1535 }
1536 /**
1537   * @brief  Handle DMA2D interrupt request.
1538   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1539   *                 the configuration information for the DMA2D.
1540   * @retval HAL status
1541   */
HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef * hdma2d)1542 void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d)
1543 {
1544   uint32_t isrflags = READ_REG(hdma2d->Instance->ISR);
1545   uint32_t crflags = READ_REG(hdma2d->Instance->CR);
1546 
1547   /* Transfer Error Interrupt management ***************************************/
1548   if ((isrflags & DMA2D_FLAG_TE) != 0U)
1549   {
1550     if ((crflags & DMA2D_IT_TE) != 0U)
1551     {
1552       /* Disable the transfer Error interrupt */
1553       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TE);
1554 
1555       /* Update error code */
1556       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1557 
1558       /* Clear the transfer error flag */
1559       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TE);
1560 
1561       /* Change DMA2D state */
1562       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1563 
1564       /* Process Unlocked */
1565       __HAL_UNLOCK(hdma2d);
1566 
1567       if (hdma2d->XferErrorCallback != NULL)
1568       {
1569         /* Transfer error Callback */
1570         hdma2d->XferErrorCallback(hdma2d);
1571       }
1572     }
1573   }
1574   /* Configuration Error Interrupt management **********************************/
1575   if ((isrflags & DMA2D_FLAG_CE) != 0U)
1576   {
1577     if ((crflags & DMA2D_IT_CE) != 0U)
1578     {
1579       /* Disable the Configuration Error interrupt */
1580       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CE);
1581 
1582       /* Clear the Configuration error flag */
1583       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE);
1584 
1585       /* Update error code */
1586       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1587 
1588       /* Change DMA2D state */
1589       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1590 
1591       /* Process Unlocked */
1592       __HAL_UNLOCK(hdma2d);
1593 
1594       if (hdma2d->XferErrorCallback != NULL)
1595       {
1596         /* Transfer error Callback */
1597         hdma2d->XferErrorCallback(hdma2d);
1598       }
1599     }
1600   }
1601   /* CLUT access Error Interrupt management ***********************************/
1602   if ((isrflags & DMA2D_FLAG_CAE) != 0U)
1603   {
1604     if ((crflags & DMA2D_IT_CAE) != 0U)
1605     {
1606       /* Disable the CLUT access error interrupt */
1607       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CAE);
1608 
1609       /* Clear the CLUT access error flag */
1610       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE);
1611 
1612       /* Update error code */
1613       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE;
1614 
1615       /* Change DMA2D state */
1616       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1617 
1618       /* Process Unlocked */
1619       __HAL_UNLOCK(hdma2d);
1620 
1621       if (hdma2d->XferErrorCallback != NULL)
1622       {
1623         /* Transfer error Callback */
1624         hdma2d->XferErrorCallback(hdma2d);
1625       }
1626     }
1627   }
1628   /* Transfer watermark Interrupt management **********************************/
1629   if ((isrflags & DMA2D_FLAG_TW) != 0U)
1630   {
1631     if ((crflags & DMA2D_IT_TW) != 0U)
1632     {
1633       /* Disable the transfer watermark interrupt */
1634       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TW);
1635 
1636       /* Clear the transfer watermark flag */
1637       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TW);
1638 
1639       /* Transfer watermark Callback */
1640 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
1641       hdma2d->LineEventCallback(hdma2d);
1642 #else
1643       HAL_DMA2D_LineEventCallback(hdma2d);
1644 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
1645 
1646     }
1647   }
1648   /* Transfer Complete Interrupt management ************************************/
1649   if ((isrflags & DMA2D_FLAG_TC) != 0U)
1650   {
1651     if ((crflags & DMA2D_IT_TC) != 0U)
1652     {
1653       /* Disable the transfer complete interrupt */
1654       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC);
1655 
1656       /* Clear the transfer complete flag */
1657       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC);
1658 
1659       /* Update error code */
1660       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE;
1661 
1662       /* Change DMA2D state */
1663       hdma2d->State = HAL_DMA2D_STATE_READY;
1664 
1665       /* Process Unlocked */
1666       __HAL_UNLOCK(hdma2d);
1667 
1668       if (hdma2d->XferCpltCallback != NULL)
1669       {
1670         /* Transfer complete Callback */
1671         hdma2d->XferCpltCallback(hdma2d);
1672       }
1673     }
1674   }
1675   /* CLUT Transfer Complete Interrupt management ******************************/
1676   if ((isrflags & DMA2D_FLAG_CTC) != 0U)
1677   {
1678     if ((crflags & DMA2D_IT_CTC) != 0U)
1679     {
1680       /* Disable the CLUT transfer complete interrupt */
1681       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC);
1682 
1683       /* Clear the CLUT transfer complete flag */
1684       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CTC);
1685 
1686       /* Update error code */
1687       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE;
1688 
1689       /* Change DMA2D state */
1690       hdma2d->State = HAL_DMA2D_STATE_READY;
1691 
1692       /* Process Unlocked */
1693       __HAL_UNLOCK(hdma2d);
1694 
1695       /* CLUT Transfer complete Callback */
1696 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
1697       hdma2d->CLUTLoadingCpltCallback(hdma2d);
1698 #else
1699       HAL_DMA2D_CLUTLoadingCpltCallback(hdma2d);
1700 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
1701     }
1702   }
1703 
1704 }
1705 
1706 /**
1707   * @brief  Transfer watermark callback.
1708   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1709   *                 the configuration information for the DMA2D.
1710   * @retval None
1711   */
HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef * hdma2d)1712 __weak void HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef *hdma2d)
1713 {
1714   /* Prevent unused argument(s) compilation warning */
1715   UNUSED(hdma2d);
1716 
1717   /* NOTE : This function should not be modified; when the callback is needed,
1718             the HAL_DMA2D_LineEventCallback can be implemented in the user file.
1719    */
1720 }
1721 
1722 /**
1723   * @brief  CLUT Transfer Complete callback.
1724   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1725   *                 the configuration information for the DMA2D.
1726   * @retval None
1727   */
HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef * hdma2d)1728 __weak void HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef *hdma2d)
1729 {
1730   /* Prevent unused argument(s) compilation warning */
1731   UNUSED(hdma2d);
1732 
1733   /* NOTE : This function should not be modified; when the callback is needed,
1734             the HAL_DMA2D_CLUTLoadingCpltCallback can be implemented in the user file.
1735    */
1736 }
1737 
1738 /**
1739   * @}
1740   */
1741 
1742 /** @defgroup DMA2D_Exported_Functions_Group3 Peripheral Control functions
1743   *  @brief    Peripheral Control functions
1744   *
1745 @verbatim
1746  ===============================================================================
1747                     ##### Peripheral Control functions #####
1748  ===============================================================================
1749     [..]  This section provides functions allowing to:
1750       (+) Configure the DMA2D foreground or background layer parameters.
1751       (+) Configure the DMA2D CLUT transfer.
1752       (+) Configure the line watermark
1753       (+) Configure the dead time value.
1754       (+) Enable or disable the dead time value functionality.
1755 
1756 
1757 @endverbatim
1758   * @{
1759   */
1760 
1761 /**
1762   * @brief  Configure the DMA2D Layer according to the specified
1763   *         parameters in the DMA2D_HandleTypeDef.
1764   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1765   *                 the configuration information for the DMA2D.
1766   * @param  LayerIdx DMA2D Layer index.
1767   *                   This parameter can be one of the following values:
1768   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1769   * @retval HAL status
1770   */
HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1771 HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1772 {
1773   DMA2D_LayerCfgTypeDef *pLayerCfg;
1774   uint32_t regMask;
1775   uint32_t regValue;
1776 
1777   /* Check the parameters */
1778   assert_param(IS_DMA2D_LAYER(LayerIdx));
1779   assert_param(IS_DMA2D_OFFSET(hdma2d->LayerCfg[LayerIdx].InputOffset));
1780   if (hdma2d->Init.Mode != DMA2D_R2M)
1781   {
1782     assert_param(IS_DMA2D_INPUT_COLOR_MODE(hdma2d->LayerCfg[LayerIdx].InputColorMode));
1783     if (hdma2d->Init.Mode != DMA2D_M2M)
1784     {
1785       assert_param(IS_DMA2D_ALPHA_MODE(hdma2d->LayerCfg[LayerIdx].AlphaMode));
1786     }
1787   }
1788   assert_param(IS_DMA2D_ALPHA_INVERTED(hdma2d->LayerCfg[LayerIdx].AlphaInverted));
1789   assert_param(IS_DMA2D_RB_SWAP(hdma2d->LayerCfg[LayerIdx].RedBlueSwap));
1790 
1791   /* Process locked */
1792   __HAL_LOCK(hdma2d);
1793 
1794   /* Change DMA2D peripheral state */
1795   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1796 
1797   pLayerCfg = &hdma2d->LayerCfg[LayerIdx];
1798 
1799   /* Prepare the value to be written to the BGPFCCR or FGPFCCR register */
1800   regValue = pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << DMA2D_BGPFCCR_AM_Pos) | \
1801              (pLayerCfg->AlphaInverted << DMA2D_BGPFCCR_AI_Pos) | (pLayerCfg->RedBlueSwap << DMA2D_BGPFCCR_RBS_Pos);
1802   regMask  = (DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA | DMA2D_BGPFCCR_AI | DMA2D_BGPFCCR_RBS);
1803 
1804 
1805   if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1806   {
1807     regValue |= (pLayerCfg->InputAlpha & DMA2D_BGPFCCR_ALPHA);
1808   }
1809   else
1810   {
1811     regValue |= (pLayerCfg->InputAlpha << DMA2D_BGPFCCR_ALPHA_Pos);
1812   }
1813 
1814   /* Configure the background DMA2D layer */
1815   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1816   {
1817     /* Write DMA2D BGPFCCR register */
1818     MODIFY_REG(hdma2d->Instance->BGPFCCR, regMask, regValue);
1819 
1820     /* DMA2D BGOR register configuration -------------------------------------*/
1821     WRITE_REG(hdma2d->Instance->BGOR, pLayerCfg->InputOffset);
1822 
1823     /* DMA2D BGCOLR register configuration -------------------------------------*/
1824     if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1825     {
1826       WRITE_REG(hdma2d->Instance->BGCOLR, pLayerCfg->InputAlpha & (DMA2D_BGCOLR_BLUE | DMA2D_BGCOLR_GREEN | \
1827                                                                    DMA2D_BGCOLR_RED));
1828     }
1829   }
1830   /* Configure the foreground DMA2D layer */
1831   else
1832   {
1833 
1834 
1835     /* Write DMA2D FGPFCCR register */
1836     MODIFY_REG(hdma2d->Instance->FGPFCCR, regMask, regValue);
1837 
1838     /* DMA2D FGOR register configuration -------------------------------------*/
1839     WRITE_REG(hdma2d->Instance->FGOR, pLayerCfg->InputOffset);
1840 
1841     /* DMA2D FGCOLR register configuration -------------------------------------*/
1842     if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1843     {
1844       WRITE_REG(hdma2d->Instance->FGCOLR, pLayerCfg->InputAlpha & (DMA2D_FGCOLR_BLUE | DMA2D_FGCOLR_GREEN | \
1845                                                                    DMA2D_FGCOLR_RED));
1846     }
1847   }
1848   /* Initialize the DMA2D state*/
1849   hdma2d->State = HAL_DMA2D_STATE_READY;
1850 
1851   /* Process unlocked */
1852   __HAL_UNLOCK(hdma2d);
1853 
1854   return HAL_OK;
1855 }
1856 
1857 /**
1858   * @brief  Configure the DMA2D CLUT Transfer.
1859   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1860   *                   the configuration information for the DMA2D.
1861   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1862   *                   the configuration information for the color look up table.
1863   * @param  LayerIdx DMA2D Layer index.
1864   *                   This parameter can be one of the following values:
1865   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1866   * @note API obsolete and maintained for compatibility with legacy. User is invited
1867   *      to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from code compactness,
1868   *      code size and improved heap usage.
1869   * @retval HAL status
1870   */
HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1871 HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1872 {
1873   /* Check the parameters */
1874   assert_param(IS_DMA2D_LAYER(LayerIdx));
1875   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1876   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1877 
1878   /* Process locked */
1879   __HAL_LOCK(hdma2d);
1880 
1881   /* Change DMA2D peripheral state */
1882   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1883 
1884   /* Configure the CLUT of the background DMA2D layer */
1885   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1886   {
1887     /* Write background CLUT memory address */
1888     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1889 
1890     /* Write background CLUT size and CLUT color mode */
1891     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1892                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1893   }
1894   /* Configure the CLUT of the foreground DMA2D layer */
1895   else
1896   {
1897     /* Write foreground CLUT memory address */
1898     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1899 
1900     /* Write foreground CLUT size and CLUT color mode */
1901     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1902                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1903   }
1904 
1905   /* Set the DMA2D state to Ready*/
1906   hdma2d->State = HAL_DMA2D_STATE_READY;
1907 
1908   /* Process unlocked */
1909   __HAL_UNLOCK(hdma2d);
1910 
1911   return HAL_OK;
1912 }
1913 
1914 
1915 /**
1916   * @brief  Configure the line watermark.
1917   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1918   *                 the configuration information for the DMA2D.
1919   * @param  Line   Line Watermark configuration (maximum 16-bit long value expected).
1920   * @note   HAL_DMA2D_ProgramLineEvent() API enables the transfer watermark interrupt.
1921   * @note   The transfer watermark interrupt is disabled once it has occurred.
1922   * @retval HAL status
1923   */
1924 
HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef * hdma2d,uint32_t Line)1925 HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line)
1926 {
1927   /* Check the parameters */
1928   if (Line > DMA2D_LWR_LW)
1929   {
1930     return HAL_ERROR;
1931   }
1932   else
1933   {
1934     /* Process locked */
1935     __HAL_LOCK(hdma2d);
1936 
1937     /* Change DMA2D peripheral state */
1938     hdma2d->State = HAL_DMA2D_STATE_BUSY;
1939 
1940     /* Sets the Line watermark configuration */
1941     WRITE_REG(hdma2d->Instance->LWR, Line);
1942 
1943     /* Enable the Line interrupt */
1944     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TW);
1945 
1946     /* Initialize the DMA2D state*/
1947     hdma2d->State = HAL_DMA2D_STATE_READY;
1948 
1949     /* Process unlocked */
1950     __HAL_UNLOCK(hdma2d);
1951 
1952     return HAL_OK;
1953   }
1954 }
1955 
1956 /**
1957   * @brief Enable DMA2D dead time feature.
1958   * @param hdma2d DMA2D handle.
1959   * @retval HAL status
1960   */
HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef * hdma2d)1961 HAL_StatusTypeDef HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef *hdma2d)
1962 {
1963   /* Process Locked */
1964   __HAL_LOCK(hdma2d);
1965 
1966   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1967 
1968   /* Set DMA2D_AMTCR EN bit */
1969   SET_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN);
1970 
1971   hdma2d->State = HAL_DMA2D_STATE_READY;
1972 
1973   /* Process Unlocked */
1974   __HAL_UNLOCK(hdma2d);
1975 
1976   return HAL_OK;
1977 }
1978 
1979 /**
1980   * @brief Disable DMA2D dead time feature.
1981   * @param hdma2d DMA2D handle.
1982   * @retval HAL status
1983   */
HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef * hdma2d)1984 HAL_StatusTypeDef HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef *hdma2d)
1985 {
1986   /* Process Locked */
1987   __HAL_LOCK(hdma2d);
1988 
1989   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1990 
1991   /* Clear DMA2D_AMTCR EN bit */
1992   CLEAR_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN);
1993 
1994   hdma2d->State = HAL_DMA2D_STATE_READY;
1995 
1996   /* Process Unlocked */
1997   __HAL_UNLOCK(hdma2d);
1998 
1999   return HAL_OK;
2000 }
2001 
2002 /**
2003   * @brief Configure dead time.
2004   * @note The dead time value represents the guaranteed minimum number of cycles between
2005   *       two consecutive transactions on the AHB bus.
2006   * @param hdma2d DMA2D handle.
2007   * @param DeadTime dead time value.
2008   * @retval HAL status
2009   */
HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef * hdma2d,uint8_t DeadTime)2010 HAL_StatusTypeDef HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef *hdma2d, uint8_t DeadTime)
2011 {
2012   /* Process Locked */
2013   __HAL_LOCK(hdma2d);
2014 
2015   hdma2d->State = HAL_DMA2D_STATE_BUSY;
2016 
2017   /* Set DMA2D_AMTCR DT field */
2018   MODIFY_REG(hdma2d->Instance->AMTCR, DMA2D_AMTCR_DT, (((uint32_t) DeadTime) << DMA2D_AMTCR_DT_Pos));
2019 
2020   hdma2d->State = HAL_DMA2D_STATE_READY;
2021 
2022   /* Process Unlocked */
2023   __HAL_UNLOCK(hdma2d);
2024 
2025   return HAL_OK;
2026 }
2027 
2028 /**
2029   * @}
2030   */
2031 
2032 
2033 /** @defgroup DMA2D_Exported_Functions_Group4 Peripheral State and Error functions
2034   *  @brief    Peripheral State functions
2035   *
2036 @verbatim
2037  ===============================================================================
2038                   ##### Peripheral State and Errors functions #####
2039  ===============================================================================
2040     [..]
2041     This subsection provides functions allowing to:
2042       (+) Get the DMA2D state
2043       (+) Get the DMA2D error code
2044 
2045 @endverbatim
2046   * @{
2047   */
2048 
2049 /**
2050   * @brief  Return the DMA2D state
2051   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
2052   *                 the configuration information for the DMA2D.
2053   * @retval HAL state
2054   */
HAL_DMA2D_GetState(DMA2D_HandleTypeDef * hdma2d)2055 HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(DMA2D_HandleTypeDef *hdma2d)
2056 {
2057   return hdma2d->State;
2058 }
2059 
2060 /**
2061   * @brief  Return the DMA2D error code
2062   * @param  hdma2d  pointer to a DMA2D_HandleTypeDef structure that contains
2063   *               the configuration information for DMA2D.
2064   * @retval DMA2D Error Code
2065   */
HAL_DMA2D_GetError(DMA2D_HandleTypeDef * hdma2d)2066 uint32_t HAL_DMA2D_GetError(DMA2D_HandleTypeDef *hdma2d)
2067 {
2068   return hdma2d->ErrorCode;
2069 }
2070 
2071 /**
2072   * @}
2073   */
2074 
2075 /**
2076   * @}
2077   */
2078 
2079 
2080 /** @defgroup DMA2D_Private_Functions DMA2D Private Functions
2081   * @{
2082   */
2083 
2084 /**
2085   * @brief  Set the DMA2D transfer parameters.
2086   * @param  hdma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
2087   *                     the configuration information for the specified DMA2D.
2088   * @param  pdata      The source memory Buffer address
2089   * @param  DstAddress The destination memory Buffer address
2090   * @param  Width      The width of data to be transferred from source to destination.
2091   * @param  Height     The height of data to be transferred from source to destination.
2092   * @retval HAL status
2093   */
DMA2D_SetConfig(DMA2D_HandleTypeDef * hdma2d,uint32_t pdata,uint32_t DstAddress,uint32_t Width,uint32_t Height)2094 static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,
2095                             uint32_t Height)
2096 {
2097   uint32_t tmp;
2098   uint32_t tmp1;
2099   uint32_t tmp2;
2100   uint32_t tmp3;
2101   uint32_t tmp4;
2102 
2103   /* Configure DMA2D data size */
2104   MODIFY_REG(hdma2d->Instance->NLR, (DMA2D_NLR_NL | DMA2D_NLR_PL), (Height | (Width << DMA2D_NLR_PL_Pos)));
2105 
2106   /* Configure DMA2D destination address */
2107   WRITE_REG(hdma2d->Instance->OMAR, DstAddress);
2108 
2109   /* Register to memory DMA2D mode selected */
2110   if (hdma2d->Init.Mode == DMA2D_R2M)
2111   {
2112     tmp1 = pdata & DMA2D_OCOLR_ALPHA_1;
2113     tmp2 = pdata & DMA2D_OCOLR_RED_1;
2114     tmp3 = pdata & DMA2D_OCOLR_GREEN_1;
2115     tmp4 = pdata & DMA2D_OCOLR_BLUE_1;
2116 
2117     /* Prepare the value to be written to the OCOLR register according to the color mode */
2118     if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB8888)
2119     {
2120       tmp = (tmp3 | tmp2 | tmp1 | tmp4);
2121     }
2122     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB888)
2123     {
2124       tmp = (tmp3 | tmp2 | tmp4);
2125     }
2126     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB565)
2127     {
2128       tmp2 = (tmp2 >> 19U);
2129       tmp3 = (tmp3 >> 10U);
2130       tmp4 = (tmp4 >> 3U);
2131       tmp  = ((tmp3 << 5U) | (tmp2 << 11U) | tmp4);
2132     }
2133     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB1555)
2134     {
2135       tmp1 = (tmp1 >> 31U);
2136       tmp2 = (tmp2 >> 19U);
2137       tmp3 = (tmp3 >> 11U);
2138       tmp4 = (tmp4 >> 3U);
2139       tmp  = ((tmp3 << 5U) | (tmp2 << 10U) | (tmp1 << 15U) | tmp4);
2140     }
2141     else /* Dhdma2d->Init.ColorMode = DMA2D_OUTPUT_ARGB4444 */
2142     {
2143       tmp1 = (tmp1 >> 28U);
2144       tmp2 = (tmp2 >> 20U);
2145       tmp3 = (tmp3 >> 12U);
2146       tmp4 = (tmp4 >> 4U);
2147       tmp  = ((tmp3 << 4U) | (tmp2 << 8U) | (tmp1 << 12U) | tmp4);
2148     }
2149     /* Write to DMA2D OCOLR register */
2150     WRITE_REG(hdma2d->Instance->OCOLR, tmp);
2151   }
2152   else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG) /*M2M_blending with fixed color FG DMA2D Mode selected*/
2153   {
2154     WRITE_REG(hdma2d->Instance->BGMAR, pdata);
2155   }
2156   else /* M2M, M2M_PFC,M2M_Blending or M2M_blending with fixed color BG DMA2D Mode */
2157   {
2158     /* Configure DMA2D source address */
2159     WRITE_REG(hdma2d->Instance->FGMAR, pdata);
2160   }
2161 }
2162 
2163 /**
2164   * @}
2165   */
2166 
2167 /**
2168   * @}
2169   */
2170 
2171 /**
2172   * @}
2173   */
2174 #endif /* DMA2D */
2175 #endif /* HAL_DMA2D_MODULE_ENABLED */
2176 
2177