1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_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) 2017 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 (overridden) 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 (overridden) 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 (overridden) 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 (overridden) 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 (overridden) 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 "stm32h7xx_hal.h"
165 
166 #ifdef HAL_DMA2D_MODULE_ENABLED
167 #if defined (DMA2D)
168 
169 /** @addtogroup STM32H7xx_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() == 1U)
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 (overridden) 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 (overridden) 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 (overridden) Msp Init */
575         break;
576 
577       case HAL_DMA2D_MSPDEINIT_CB_ID :
578         hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit; /* Legacy weak (overridden) 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 (overridden) Msp Init */
595         break;
596 
597       case HAL_DMA2D_MSPDEINIT_CB_ID :
598         hdma2d->MspDeInitCallback = HAL_DMA2D_MspDeInit;  /* Legacy weak (overridden) 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,const DMA2D_CLUTCfgTypeDef * CLUTCfg,uint32_t LayerIdx)1016 HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg,
1017                                           uint32_t LayerIdx)
1018 {
1019   /* Check the parameters */
1020   assert_param(IS_DMA2D_LAYER(LayerIdx));
1021   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode));
1022   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size));
1023 
1024   /* Process locked */
1025   __HAL_LOCK(hdma2d);
1026 
1027   /* Change DMA2D peripheral state */
1028   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1029 
1030   /* Configure the CLUT of the background DMA2D layer */
1031   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1032   {
1033     /* Write background CLUT memory address */
1034     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT);
1035 
1036     /* Write background CLUT size and CLUT color mode */
1037     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1038                ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1039 
1040     /* Enable the CLUT loading for the background */
1041     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1042   }
1043   /* Configure the CLUT of the foreground DMA2D layer */
1044   else
1045   {
1046     /* Write foreground CLUT memory address */
1047     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT);
1048 
1049     /* Write foreground CLUT size and CLUT color mode */
1050     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1051                ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1052 
1053     /* Enable the CLUT loading for the foreground */
1054     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1055   }
1056 
1057   return HAL_OK;
1058 }
1059 
1060 /**
1061   * @brief  Start DMA2D CLUT Loading with interrupt enabled.
1062   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1063   *                   the configuration information for the DMA2D.
1064   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1065   *                   the configuration information for the color look up table.
1066   * @param  LayerIdx DMA2D Layer index.
1067   *                   This parameter can be one of the following values:
1068   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1069   * @retval HAL status
1070   */
HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef * hdma2d,const DMA2D_CLUTCfgTypeDef * CLUTCfg,uint32_t LayerIdx)1071 HAL_StatusTypeDef HAL_DMA2D_CLUTStartLoad_IT(DMA2D_HandleTypeDef *hdma2d, const DMA2D_CLUTCfgTypeDef *CLUTCfg,
1072                                              uint32_t LayerIdx)
1073 {
1074   /* Check the parameters */
1075   assert_param(IS_DMA2D_LAYER(LayerIdx));
1076   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg->CLUTColorMode));
1077   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg->Size));
1078 
1079   /* Process locked */
1080   __HAL_LOCK(hdma2d);
1081 
1082   /* Change DMA2D peripheral state */
1083   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1084 
1085   /* Configure the CLUT of the background DMA2D layer */
1086   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1087   {
1088     /* Write background CLUT memory address */
1089     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg->pCLUT);
1090 
1091     /* Write background CLUT size and CLUT color mode */
1092     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1093                ((CLUTCfg->Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1094 
1095     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1096     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1097 
1098     /* Enable the CLUT loading for the background */
1099     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1100   }
1101   /* Configure the CLUT of the foreground DMA2D layer */
1102   else
1103   {
1104     /* Write foreground CLUT memory address */
1105     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg->pCLUT);
1106 
1107     /* Write foreground CLUT size and CLUT color mode */
1108     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1109                ((CLUTCfg->Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg->CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1110 
1111     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1112     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1113 
1114     /* Enable the CLUT loading for the foreground */
1115     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1116   }
1117 
1118   return HAL_OK;
1119 }
1120 
1121 /**
1122   * @brief  Start DMA2D CLUT Loading.
1123   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1124   *                   the configuration information for the DMA2D.
1125   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1126   *                   the configuration information for the color look up table.
1127   * @param  LayerIdx DMA2D Layer index.
1128   *                   This parameter can be one of the following values:
1129   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1130   * @note API obsolete and maintained for compatibility with legacy. User is
1131   *      invited to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from
1132   *      code compactness, code size and improved heap usage.
1133   * @retval HAL status
1134   */
HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1135 HAL_StatusTypeDef HAL_DMA2D_CLUTLoad(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1136 {
1137   /* Check the parameters */
1138   assert_param(IS_DMA2D_LAYER(LayerIdx));
1139   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1140   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1141 
1142   /* Process locked */
1143   __HAL_LOCK(hdma2d);
1144 
1145   /* Change DMA2D peripheral state */
1146   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1147 
1148   /* Configure the CLUT of the background DMA2D layer */
1149   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1150   {
1151     /* Write background CLUT memory address */
1152     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1153 
1154     /* Write background CLUT size and CLUT color mode */
1155     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1156                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1157 
1158     /* Enable the CLUT loading for the background */
1159     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1160   }
1161   /* Configure the CLUT of the foreground DMA2D layer */
1162   else
1163   {
1164     /* Write foreground CLUT memory address */
1165     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1166 
1167     /* Write foreground CLUT size and CLUT color mode */
1168     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1169                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1170 
1171     /* Enable the CLUT loading for the foreground */
1172     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1173   }
1174 
1175   return HAL_OK;
1176 }
1177 
1178 /**
1179   * @brief  Start DMA2D CLUT Loading with interrupt enabled.
1180   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1181   *                   the configuration information for the DMA2D.
1182   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1183   *                   the configuration information for the color look up table.
1184   * @param  LayerIdx DMA2D Layer index.
1185   *                   This parameter can be one of the following values:
1186   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1187   * @note API obsolete and maintained for compatibility with legacy. User is
1188   *      invited to resort to HAL_DMA2D_CLUTStartLoad_IT() instead to benefit
1189   *      from code compactness, code size and improved heap usage.
1190   * @retval HAL status
1191   */
HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1192 HAL_StatusTypeDef HAL_DMA2D_CLUTLoad_IT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1193 {
1194   /* Check the parameters */
1195   assert_param(IS_DMA2D_LAYER(LayerIdx));
1196   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1197   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1198 
1199   /* Process locked */
1200   __HAL_LOCK(hdma2d);
1201 
1202   /* Change DMA2D peripheral state */
1203   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1204 
1205   /* Configure the CLUT of the background DMA2D layer */
1206   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1207   {
1208     /* Write background CLUT memory address */
1209     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1210 
1211     /* Write background CLUT size and CLUT color mode */
1212     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1213                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1214 
1215     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1216     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1217 
1218     /* Enable the CLUT loading for the background */
1219     SET_BIT(hdma2d->Instance->BGPFCCR, DMA2D_BGPFCCR_START);
1220   }
1221   /* Configure the CLUT of the foreground DMA2D layer */
1222   else
1223   {
1224     /* Write foreground CLUT memory address */
1225     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1226 
1227     /* Write foreground CLUT size and CLUT color mode */
1228     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1229                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1230 
1231     /* Enable the CLUT Transfer Complete, transfer Error, configuration Error and CLUT Access Error interrupts */
1232     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1233 
1234     /* Enable the CLUT loading for the foreground */
1235     SET_BIT(hdma2d->Instance->FGPFCCR, DMA2D_FGPFCCR_START);
1236   }
1237 
1238   return HAL_OK;
1239 }
1240 
1241 /**
1242   * @brief  Abort the DMA2D CLUT loading.
1243   * @param  hdma2d  Pointer to a DMA2D_HandleTypeDef structure that contains
1244   *                  the configuration information for the DMA2D.
1245   * @param  LayerIdx DMA2D Layer index.
1246   *                   This parameter can be one of the following values:
1247   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1248   * @retval HAL status
1249   */
HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1250 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Abort(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1251 {
1252   uint32_t tickstart;
1253   const __IO uint32_t *reg =  &(hdma2d->Instance->BGPFCCR);  /* by default, point at background register */
1254 
1255   /* Abort the CLUT loading */
1256   SET_BIT(hdma2d->Instance->CR, DMA2D_CR_ABORT);
1257 
1258   /* If foreground CLUT loading is considered, update local variables */
1259   if (LayerIdx == DMA2D_FOREGROUND_LAYER)
1260   {
1261     reg  = &(hdma2d->Instance->FGPFCCR);
1262   }
1263 
1264 
1265   /* Get tick */
1266   tickstart = HAL_GetTick();
1267 
1268   /* Check if the CLUT loading is aborted */
1269   while ((*reg & DMA2D_BGPFCCR_START) != 0U)
1270   {
1271     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_ABORT)
1272     {
1273       /* Update error code */
1274       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1275 
1276       /* Change the DMA2D state */
1277       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1278 
1279       /* Process Unlocked */
1280       __HAL_UNLOCK(hdma2d);
1281 
1282       return HAL_TIMEOUT;
1283     }
1284   }
1285 
1286   /* Disable the CLUT Transfer Complete, Transfer Error, Configuration Error and CLUT Access Error interrupts */
1287   __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC | DMA2D_IT_TE | DMA2D_IT_CE | DMA2D_IT_CAE);
1288 
1289   /* Change the DMA2D state*/
1290   hdma2d->State = HAL_DMA2D_STATE_READY;
1291 
1292   /* Process Unlocked */
1293   __HAL_UNLOCK(hdma2d);
1294 
1295   return HAL_OK;
1296 }
1297 
1298 /**
1299   * @brief  Suspend the DMA2D CLUT loading.
1300   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1301   *                 the configuration information for the DMA2D.
1302   * @param  LayerIdx DMA2D Layer index.
1303   *                   This parameter can be one of the following values:
1304   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1305   * @retval HAL status
1306   */
HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1307 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Suspend(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1308 {
1309   uint32_t tickstart;
1310   uint32_t loadsuspended;
1311   const __IO uint32_t *reg =  &(hdma2d->Instance->BGPFCCR);  /* by default, point at background register */
1312 
1313   /* Suspend the CLUT loading */
1314   SET_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1315 
1316   /* If foreground CLUT loading is considered, update local variables */
1317   if (LayerIdx == DMA2D_FOREGROUND_LAYER)
1318   {
1319     reg  = &(hdma2d->Instance->FGPFCCR);
1320   }
1321 
1322   /* Get tick */
1323   tickstart = HAL_GetTick();
1324 
1325   /* Check if the CLUT loading is suspended */
1326   /* 1st condition: Suspend Check */
1327   loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL;
1328   /* 2nd condition: Not Start Check */
1329   loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL;
1330   while (loadsuspended == 0UL)
1331   {
1332     if ((HAL_GetTick() - tickstart) > DMA2D_TIMEOUT_SUSPEND)
1333     {
1334       /* Update error code */
1335       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1336 
1337       /* Change the DMA2D state */
1338       hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1339 
1340       return HAL_TIMEOUT;
1341     }
1342     /* 1st condition: Suspend Check */
1343     loadsuspended = ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP) ? 1UL : 0UL;
1344     /* 2nd condition: Not Start Check */
1345     loadsuspended |= ((*reg & DMA2D_BGPFCCR_START) != DMA2D_BGPFCCR_START) ? 1UL : 0UL;
1346   }
1347 
1348   /* Check whether or not a transfer is actually suspended and change the DMA2D state accordingly */
1349   if ((*reg & DMA2D_BGPFCCR_START) != 0U)
1350   {
1351     hdma2d->State = HAL_DMA2D_STATE_SUSPEND;
1352   }
1353   else
1354   {
1355     /* Make sure SUSP bit is cleared since it is meaningless
1356        when no transfer is on-going */
1357     CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1358   }
1359 
1360   return HAL_OK;
1361 }
1362 
1363 /**
1364   * @brief  Resume the DMA2D CLUT loading.
1365   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1366   *                 the configuration information for the DMA2D.
1367   * @param  LayerIdx DMA2D Layer index.
1368   *                   This parameter can be one of the following values:
1369   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1370   * @retval HAL status
1371   */
HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1372 HAL_StatusTypeDef HAL_DMA2D_CLUTLoading_Resume(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1373 {
1374   /* Check the SUSP and START bits for background or foreground CLUT loading */
1375   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1376   {
1377     /* Background CLUT loading suspension check */
1378     if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP)
1379     {
1380       if ((hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START) == DMA2D_BGPFCCR_START)
1381       {
1382         /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */
1383         hdma2d->State = HAL_DMA2D_STATE_BUSY;
1384       }
1385     }
1386   }
1387   else
1388   {
1389     /* Foreground CLUT loading suspension check */
1390     if ((hdma2d->Instance->CR & DMA2D_CR_SUSP) == DMA2D_CR_SUSP)
1391     {
1392       if ((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) == DMA2D_FGPFCCR_START)
1393       {
1394         /* Ongoing CLUT loading is suspended: change the DMA2D state before resuming */
1395         hdma2d->State = HAL_DMA2D_STATE_BUSY;
1396       }
1397     }
1398   }
1399 
1400   /* Resume the CLUT loading */
1401   CLEAR_BIT(hdma2d->Instance->CR, DMA2D_CR_SUSP);
1402 
1403   return HAL_OK;
1404 }
1405 
1406 
1407 /**
1408 
1409   * @brief  Polling for transfer complete or CLUT loading.
1410   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1411   *                 the configuration information for the DMA2D.
1412   * @param  Timeout Timeout duration
1413   * @retval HAL status
1414   */
HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef * hdma2d,uint32_t Timeout)1415 HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout)
1416 {
1417   uint32_t tickstart;
1418   uint32_t layer_start;
1419   __IO uint32_t isrflags = 0x0U;
1420 
1421   /* Polling for DMA2D transfer */
1422   if ((hdma2d->Instance->CR & DMA2D_CR_START) != 0U)
1423   {
1424     /* Get tick */
1425     tickstart = HAL_GetTick();
1426 
1427     while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) == 0U)
1428     {
1429       isrflags = READ_REG(hdma2d->Instance->ISR);
1430       if ((isrflags & (DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U)
1431       {
1432         if ((isrflags & DMA2D_FLAG_CE) != 0U)
1433         {
1434           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1435         }
1436         if ((isrflags & DMA2D_FLAG_TE) != 0U)
1437         {
1438           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1439         }
1440         /* Clear the transfer and configuration error flags */
1441         __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE | DMA2D_FLAG_TE);
1442 
1443         /* Change DMA2D state */
1444         hdma2d->State = HAL_DMA2D_STATE_ERROR;
1445 
1446         /* Process unlocked */
1447         __HAL_UNLOCK(hdma2d);
1448 
1449         return HAL_ERROR;
1450       }
1451       /* Check for the Timeout */
1452       if (Timeout != HAL_MAX_DELAY)
1453       {
1454         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1455         {
1456           /* Update error code */
1457           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1458 
1459           /* Change the DMA2D state */
1460           hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1461 
1462           /* Process unlocked */
1463           __HAL_UNLOCK(hdma2d);
1464 
1465           return HAL_TIMEOUT;
1466         }
1467       }
1468     }
1469   }
1470   /* Polling for CLUT loading (foreground or background) */
1471   layer_start = hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START;
1472   layer_start |= hdma2d->Instance->BGPFCCR & DMA2D_BGPFCCR_START;
1473   if (layer_start != 0U)
1474   {
1475     /* Get tick */
1476     tickstart = HAL_GetTick();
1477 
1478     while (__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CTC) == 0U)
1479     {
1480       isrflags = READ_REG(hdma2d->Instance->ISR);
1481       if ((isrflags & (DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE)) != 0U)
1482       {
1483         if ((isrflags & DMA2D_FLAG_CAE) != 0U)
1484         {
1485           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE;
1486         }
1487         if ((isrflags & DMA2D_FLAG_CE) != 0U)
1488         {
1489           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1490         }
1491         if ((isrflags & DMA2D_FLAG_TE) != 0U)
1492         {
1493           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1494         }
1495         /* Clear the CLUT Access Error, Configuration Error and Transfer Error flags */
1496         __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE | DMA2D_FLAG_CE | DMA2D_FLAG_TE);
1497 
1498         /* Change DMA2D state */
1499         hdma2d->State = HAL_DMA2D_STATE_ERROR;
1500 
1501         /* Process unlocked */
1502         __HAL_UNLOCK(hdma2d);
1503 
1504         return HAL_ERROR;
1505       }
1506       /* Check for the Timeout */
1507       if (Timeout != HAL_MAX_DELAY)
1508       {
1509         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1510         {
1511           /* Update error code */
1512           hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT;
1513 
1514           /* Change the DMA2D state */
1515           hdma2d->State = HAL_DMA2D_STATE_TIMEOUT;
1516 
1517           /* Process unlocked */
1518           __HAL_UNLOCK(hdma2d);
1519 
1520           return HAL_TIMEOUT;
1521         }
1522       }
1523     }
1524   }
1525 
1526   /* Clear the transfer complete and CLUT loading flags */
1527   __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC | DMA2D_FLAG_CTC);
1528 
1529   /* Change DMA2D state */
1530   hdma2d->State = HAL_DMA2D_STATE_READY;
1531 
1532   /* Process unlocked */
1533   __HAL_UNLOCK(hdma2d);
1534 
1535   return HAL_OK;
1536 }
1537 /**
1538   * @brief  Handle DMA2D interrupt request.
1539   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1540   *                 the configuration information for the DMA2D.
1541   * @retval HAL status
1542   */
HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef * hdma2d)1543 void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d)
1544 {
1545   uint32_t isrflags = READ_REG(hdma2d->Instance->ISR);
1546   uint32_t crflags = READ_REG(hdma2d->Instance->CR);
1547 
1548   /* Transfer Error Interrupt management ***************************************/
1549   if ((isrflags & DMA2D_FLAG_TE) != 0U)
1550   {
1551     if ((crflags & DMA2D_IT_TE) != 0U)
1552     {
1553       /* Disable the transfer Error interrupt */
1554       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TE);
1555 
1556       /* Update error code */
1557       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE;
1558 
1559       /* Clear the transfer error flag */
1560       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TE);
1561 
1562       /* Change DMA2D state */
1563       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1564 
1565       /* Process Unlocked */
1566       __HAL_UNLOCK(hdma2d);
1567 
1568       if (hdma2d->XferErrorCallback != NULL)
1569       {
1570         /* Transfer error Callback */
1571         hdma2d->XferErrorCallback(hdma2d);
1572       }
1573     }
1574   }
1575   /* Configuration Error Interrupt management **********************************/
1576   if ((isrflags & DMA2D_FLAG_CE) != 0U)
1577   {
1578     if ((crflags & DMA2D_IT_CE) != 0U)
1579     {
1580       /* Disable the Configuration Error interrupt */
1581       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CE);
1582 
1583       /* Clear the Configuration error flag */
1584       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE);
1585 
1586       /* Update error code */
1587       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE;
1588 
1589       /* Change DMA2D state */
1590       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1591 
1592       /* Process Unlocked */
1593       __HAL_UNLOCK(hdma2d);
1594 
1595       if (hdma2d->XferErrorCallback != NULL)
1596       {
1597         /* Transfer error Callback */
1598         hdma2d->XferErrorCallback(hdma2d);
1599       }
1600     }
1601   }
1602   /* CLUT access Error Interrupt management ***********************************/
1603   if ((isrflags & DMA2D_FLAG_CAE) != 0U)
1604   {
1605     if ((crflags & DMA2D_IT_CAE) != 0U)
1606     {
1607       /* Disable the CLUT access error interrupt */
1608       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CAE);
1609 
1610       /* Clear the CLUT access error flag */
1611       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE);
1612 
1613       /* Update error code */
1614       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CAE;
1615 
1616       /* Change DMA2D state */
1617       hdma2d->State = HAL_DMA2D_STATE_ERROR;
1618 
1619       /* Process Unlocked */
1620       __HAL_UNLOCK(hdma2d);
1621 
1622       if (hdma2d->XferErrorCallback != NULL)
1623       {
1624         /* Transfer error Callback */
1625         hdma2d->XferErrorCallback(hdma2d);
1626       }
1627     }
1628   }
1629   /* Transfer watermark Interrupt management **********************************/
1630   if ((isrflags & DMA2D_FLAG_TW) != 0U)
1631   {
1632     if ((crflags & DMA2D_IT_TW) != 0U)
1633     {
1634       /* Disable the transfer watermark interrupt */
1635       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TW);
1636 
1637       /* Clear the transfer watermark flag */
1638       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TW);
1639 
1640       /* Transfer watermark Callback */
1641 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
1642       hdma2d->LineEventCallback(hdma2d);
1643 #else
1644       HAL_DMA2D_LineEventCallback(hdma2d);
1645 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
1646 
1647     }
1648   }
1649   /* Transfer Complete Interrupt management ************************************/
1650   if ((isrflags & DMA2D_FLAG_TC) != 0U)
1651   {
1652     if ((crflags & DMA2D_IT_TC) != 0U)
1653     {
1654       /* Disable the transfer complete interrupt */
1655       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC);
1656 
1657       /* Clear the transfer complete flag */
1658       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC);
1659 
1660       /* Update error code */
1661       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE;
1662 
1663       /* Change DMA2D state */
1664       hdma2d->State = HAL_DMA2D_STATE_READY;
1665 
1666       /* Process Unlocked */
1667       __HAL_UNLOCK(hdma2d);
1668 
1669       if (hdma2d->XferCpltCallback != NULL)
1670       {
1671         /* Transfer complete Callback */
1672         hdma2d->XferCpltCallback(hdma2d);
1673       }
1674     }
1675   }
1676   /* CLUT Transfer Complete Interrupt management ******************************/
1677   if ((isrflags & DMA2D_FLAG_CTC) != 0U)
1678   {
1679     if ((crflags & DMA2D_IT_CTC) != 0U)
1680     {
1681       /* Disable the CLUT transfer complete interrupt */
1682       __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CTC);
1683 
1684       /* Clear the CLUT transfer complete flag */
1685       __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CTC);
1686 
1687       /* Update error code */
1688       hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE;
1689 
1690       /* Change DMA2D state */
1691       hdma2d->State = HAL_DMA2D_STATE_READY;
1692 
1693       /* Process Unlocked */
1694       __HAL_UNLOCK(hdma2d);
1695 
1696       /* CLUT Transfer complete Callback */
1697 #if (USE_HAL_DMA2D_REGISTER_CALLBACKS == 1)
1698       hdma2d->CLUTLoadingCpltCallback(hdma2d);
1699 #else
1700       HAL_DMA2D_CLUTLoadingCpltCallback(hdma2d);
1701 #endif /* USE_HAL_DMA2D_REGISTER_CALLBACKS */
1702     }
1703   }
1704 
1705 }
1706 
1707 /**
1708   * @brief  Transfer watermark callback.
1709   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1710   *                 the configuration information for the DMA2D.
1711   * @retval None
1712   */
HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef * hdma2d)1713 __weak void HAL_DMA2D_LineEventCallback(DMA2D_HandleTypeDef *hdma2d)
1714 {
1715   /* Prevent unused argument(s) compilation warning */
1716   UNUSED(hdma2d);
1717 
1718   /* NOTE : This function should not be modified; when the callback is needed,
1719             the HAL_DMA2D_LineEventCallback can be implemented in the user file.
1720    */
1721 }
1722 
1723 /**
1724   * @brief  CLUT Transfer Complete callback.
1725   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
1726   *                 the configuration information for the DMA2D.
1727   * @retval None
1728   */
HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef * hdma2d)1729 __weak void HAL_DMA2D_CLUTLoadingCpltCallback(DMA2D_HandleTypeDef *hdma2d)
1730 {
1731   /* Prevent unused argument(s) compilation warning */
1732   UNUSED(hdma2d);
1733 
1734   /* NOTE : This function should not be modified; when the callback is needed,
1735             the HAL_DMA2D_CLUTLoadingCpltCallback can be implemented in the user file.
1736    */
1737 }
1738 
1739 /**
1740   * @}
1741   */
1742 
1743 /** @defgroup DMA2D_Exported_Functions_Group3 Peripheral Control functions
1744   *  @brief    Peripheral Control functions
1745   *
1746 @verbatim
1747  ===============================================================================
1748                     ##### Peripheral Control functions #####
1749  ===============================================================================
1750     [..]  This section provides functions allowing to:
1751       (+) Configure the DMA2D foreground or background layer parameters.
1752       (+) Configure the DMA2D CLUT transfer.
1753       (+) Configure the line watermark
1754       (+) Configure the dead time value.
1755       (+) Enable or disable the dead time value functionality.
1756 
1757 
1758 @endverbatim
1759   * @{
1760   */
1761 
1762 /**
1763   * @brief  Configure the DMA2D Layer according to the specified
1764   *         parameters in the DMA2D_HandleTypeDef.
1765   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1766   *                 the configuration information for the DMA2D.
1767   * @param  LayerIdx DMA2D Layer index.
1768   *                   This parameter can be one of the following values:
1769   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1770   * @retval HAL status
1771   */
HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef * hdma2d,uint32_t LayerIdx)1772 HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx)
1773 {
1774   const DMA2D_LayerCfgTypeDef *pLayerCfg;
1775   uint32_t regMask;
1776   uint32_t regValue;
1777 
1778   /* Check the parameters */
1779   assert_param(IS_DMA2D_LAYER(LayerIdx));
1780   assert_param(IS_DMA2D_OFFSET(hdma2d->LayerCfg[LayerIdx].InputOffset));
1781   if (hdma2d->Init.Mode != DMA2D_R2M)
1782   {
1783     assert_param(IS_DMA2D_INPUT_COLOR_MODE(hdma2d->LayerCfg[LayerIdx].InputColorMode));
1784     if (hdma2d->Init.Mode != DMA2D_M2M)
1785     {
1786       assert_param(IS_DMA2D_ALPHA_MODE(hdma2d->LayerCfg[LayerIdx].AlphaMode));
1787     }
1788   }
1789   assert_param(IS_DMA2D_ALPHA_INVERTED(hdma2d->LayerCfg[LayerIdx].AlphaInverted));
1790   assert_param(IS_DMA2D_RB_SWAP(hdma2d->LayerCfg[LayerIdx].RedBlueSwap));
1791 
1792   if ((LayerIdx == DMA2D_FOREGROUND_LAYER) && (hdma2d->LayerCfg[LayerIdx].InputColorMode == DMA2D_INPUT_YCBCR))
1793   {
1794     assert_param(IS_DMA2D_CHROMA_SUB_SAMPLING(hdma2d->LayerCfg[LayerIdx].ChromaSubSampling));
1795   }
1796 
1797   /* Process locked */
1798   __HAL_LOCK(hdma2d);
1799 
1800   /* Change DMA2D peripheral state */
1801   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1802 
1803   pLayerCfg = &hdma2d->LayerCfg[LayerIdx];
1804 
1805   /* Prepare the value to be written to the BGPFCCR or FGPFCCR register */
1806   regValue = pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << DMA2D_BGPFCCR_AM_Pos) | \
1807              (pLayerCfg->AlphaInverted << DMA2D_BGPFCCR_AI_Pos) | (pLayerCfg->RedBlueSwap << DMA2D_BGPFCCR_RBS_Pos);
1808   regMask  = (DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA | DMA2D_BGPFCCR_AI | DMA2D_BGPFCCR_RBS);
1809 
1810 
1811   if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1812   {
1813     regValue |= (pLayerCfg->InputAlpha & DMA2D_BGPFCCR_ALPHA);
1814   }
1815   else
1816   {
1817     regValue |= (pLayerCfg->InputAlpha << DMA2D_BGPFCCR_ALPHA_Pos);
1818   }
1819 
1820   /* Configure the background DMA2D layer */
1821   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1822   {
1823     /* Write DMA2D BGPFCCR register */
1824     MODIFY_REG(hdma2d->Instance->BGPFCCR, regMask, regValue);
1825 
1826     /* DMA2D BGOR register configuration -------------------------------------*/
1827     WRITE_REG(hdma2d->Instance->BGOR, pLayerCfg->InputOffset);
1828 
1829     /* DMA2D BGCOLR register configuration -------------------------------------*/
1830     if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1831     {
1832       WRITE_REG(hdma2d->Instance->BGCOLR, pLayerCfg->InputAlpha & (DMA2D_BGCOLR_BLUE | DMA2D_BGCOLR_GREEN | \
1833                                                                    DMA2D_BGCOLR_RED));
1834     }
1835   }
1836   /* Configure the foreground DMA2D layer */
1837   else
1838   {
1839 
1840     if (pLayerCfg->InputColorMode == DMA2D_INPUT_YCBCR)
1841     {
1842       regValue |= (pLayerCfg->ChromaSubSampling << DMA2D_FGPFCCR_CSS_Pos);
1843       regMask  |= DMA2D_FGPFCCR_CSS;
1844     }
1845 
1846     /* Write DMA2D FGPFCCR register */
1847     MODIFY_REG(hdma2d->Instance->FGPFCCR, regMask, regValue);
1848 
1849     /* DMA2D FGOR register configuration -------------------------------------*/
1850     WRITE_REG(hdma2d->Instance->FGOR, pLayerCfg->InputOffset);
1851 
1852     /* DMA2D FGCOLR register configuration -------------------------------------*/
1853     if ((pLayerCfg->InputColorMode == DMA2D_INPUT_A4) || (pLayerCfg->InputColorMode == DMA2D_INPUT_A8))
1854     {
1855       WRITE_REG(hdma2d->Instance->FGCOLR, pLayerCfg->InputAlpha & (DMA2D_FGCOLR_BLUE | DMA2D_FGCOLR_GREEN | \
1856                                                                    DMA2D_FGCOLR_RED));
1857     }
1858   }
1859   /* Initialize the DMA2D state*/
1860   hdma2d->State = HAL_DMA2D_STATE_READY;
1861 
1862   /* Process unlocked */
1863   __HAL_UNLOCK(hdma2d);
1864 
1865   return HAL_OK;
1866 }
1867 
1868 /**
1869   * @brief  Configure the DMA2D CLUT Transfer.
1870   * @param  hdma2d   Pointer to a DMA2D_HandleTypeDef structure that contains
1871   *                   the configuration information for the DMA2D.
1872   * @param  CLUTCfg  Pointer to a DMA2D_CLUTCfgTypeDef structure that contains
1873   *                   the configuration information for the color look up table.
1874   * @param  LayerIdx DMA2D Layer index.
1875   *                   This parameter can be one of the following values:
1876   *                   DMA2D_BACKGROUND_LAYER(0) / DMA2D_FOREGROUND_LAYER(1)
1877   * @note API obsolete and maintained for compatibility with legacy. User is invited
1878   *      to resort to HAL_DMA2D_CLUTStartLoad() instead to benefit from code compactness,
1879   *      code size and improved heap usage.
1880   * @retval HAL status
1881   */
HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef * hdma2d,DMA2D_CLUTCfgTypeDef CLUTCfg,uint32_t LayerIdx)1882 HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx)
1883 {
1884   /* Check the parameters */
1885   assert_param(IS_DMA2D_LAYER(LayerIdx));
1886   assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode));
1887   assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size));
1888 
1889   /* Process locked */
1890   __HAL_LOCK(hdma2d);
1891 
1892   /* Change DMA2D peripheral state */
1893   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1894 
1895   /* Configure the CLUT of the background DMA2D layer */
1896   if (LayerIdx == DMA2D_BACKGROUND_LAYER)
1897   {
1898     /* Write background CLUT memory address */
1899     WRITE_REG(hdma2d->Instance->BGCMAR, (uint32_t)CLUTCfg.pCLUT);
1900 
1901     /* Write background CLUT size and CLUT color mode */
1902     MODIFY_REG(hdma2d->Instance->BGPFCCR, (DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM),
1903                ((CLUTCfg.Size << DMA2D_BGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_BGPFCCR_CCM_Pos)));
1904   }
1905   /* Configure the CLUT of the foreground DMA2D layer */
1906   else
1907   {
1908     /* Write foreground CLUT memory address */
1909     WRITE_REG(hdma2d->Instance->FGCMAR, (uint32_t)CLUTCfg.pCLUT);
1910 
1911     /* Write foreground CLUT size and CLUT color mode */
1912     MODIFY_REG(hdma2d->Instance->FGPFCCR, (DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM),
1913                ((CLUTCfg.Size << DMA2D_FGPFCCR_CS_Pos) | (CLUTCfg.CLUTColorMode << DMA2D_FGPFCCR_CCM_Pos)));
1914   }
1915 
1916   /* Set the DMA2D state to Ready*/
1917   hdma2d->State = HAL_DMA2D_STATE_READY;
1918 
1919   /* Process unlocked */
1920   __HAL_UNLOCK(hdma2d);
1921 
1922   return HAL_OK;
1923 }
1924 
1925 
1926 /**
1927   * @brief  Configure the line watermark.
1928   * @param  hdma2d Pointer to a DMA2D_HandleTypeDef structure that contains
1929   *                 the configuration information for the DMA2D.
1930   * @param  Line   Line Watermark configuration (maximum 16-bit long value expected).
1931   * @note   HAL_DMA2D_ProgramLineEvent() API enables the transfer watermark interrupt.
1932   * @note   The transfer watermark interrupt is disabled once it has occurred.
1933   * @retval HAL status
1934   */
1935 
HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef * hdma2d,uint32_t Line)1936 HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line)
1937 {
1938   /* Check the parameters */
1939   if (Line > DMA2D_LWR_LW)
1940   {
1941     return HAL_ERROR;
1942   }
1943   else
1944   {
1945     /* Process locked */
1946     __HAL_LOCK(hdma2d);
1947 
1948     /* Change DMA2D peripheral state */
1949     hdma2d->State = HAL_DMA2D_STATE_BUSY;
1950 
1951     /* Sets the Line watermark configuration */
1952     WRITE_REG(hdma2d->Instance->LWR, Line);
1953 
1954     /* Enable the Line interrupt */
1955     __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TW);
1956 
1957     /* Initialize the DMA2D state*/
1958     hdma2d->State = HAL_DMA2D_STATE_READY;
1959 
1960     /* Process unlocked */
1961     __HAL_UNLOCK(hdma2d);
1962 
1963     return HAL_OK;
1964   }
1965 }
1966 
1967 /**
1968   * @brief Enable DMA2D dead time feature.
1969   * @param hdma2d DMA2D handle.
1970   * @retval HAL status
1971   */
HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef * hdma2d)1972 HAL_StatusTypeDef HAL_DMA2D_EnableDeadTime(DMA2D_HandleTypeDef *hdma2d)
1973 {
1974   /* Process Locked */
1975   __HAL_LOCK(hdma2d);
1976 
1977   hdma2d->State = HAL_DMA2D_STATE_BUSY;
1978 
1979   /* Set DMA2D_AMTCR EN bit */
1980   SET_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN);
1981 
1982   hdma2d->State = HAL_DMA2D_STATE_READY;
1983 
1984   /* Process Unlocked */
1985   __HAL_UNLOCK(hdma2d);
1986 
1987   return HAL_OK;
1988 }
1989 
1990 /**
1991   * @brief Disable DMA2D dead time feature.
1992   * @param hdma2d DMA2D handle.
1993   * @retval HAL status
1994   */
HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef * hdma2d)1995 HAL_StatusTypeDef HAL_DMA2D_DisableDeadTime(DMA2D_HandleTypeDef *hdma2d)
1996 {
1997   /* Process Locked */
1998   __HAL_LOCK(hdma2d);
1999 
2000   hdma2d->State = HAL_DMA2D_STATE_BUSY;
2001 
2002   /* Clear DMA2D_AMTCR EN bit */
2003   CLEAR_BIT(hdma2d->Instance->AMTCR, DMA2D_AMTCR_EN);
2004 
2005   hdma2d->State = HAL_DMA2D_STATE_READY;
2006 
2007   /* Process Unlocked */
2008   __HAL_UNLOCK(hdma2d);
2009 
2010   return HAL_OK;
2011 }
2012 
2013 /**
2014   * @brief Configure dead time.
2015   * @note The dead time value represents the guaranteed minimum number of cycles between
2016   *       two consecutive transactions on the AHB bus.
2017   * @param hdma2d DMA2D handle.
2018   * @param DeadTime dead time value.
2019   * @retval HAL status
2020   */
HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef * hdma2d,uint8_t DeadTime)2021 HAL_StatusTypeDef HAL_DMA2D_ConfigDeadTime(DMA2D_HandleTypeDef *hdma2d, uint8_t DeadTime)
2022 {
2023   /* Process Locked */
2024   __HAL_LOCK(hdma2d);
2025 
2026   hdma2d->State = HAL_DMA2D_STATE_BUSY;
2027 
2028   /* Set DMA2D_AMTCR DT field */
2029   MODIFY_REG(hdma2d->Instance->AMTCR, DMA2D_AMTCR_DT, (((uint32_t) DeadTime) << DMA2D_AMTCR_DT_Pos));
2030 
2031   hdma2d->State = HAL_DMA2D_STATE_READY;
2032 
2033   /* Process Unlocked */
2034   __HAL_UNLOCK(hdma2d);
2035 
2036   return HAL_OK;
2037 }
2038 
2039 /**
2040   * @}
2041   */
2042 
2043 
2044 /** @defgroup DMA2D_Exported_Functions_Group4 Peripheral State and Error functions
2045   *  @brief    Peripheral State functions
2046   *
2047 @verbatim
2048  ===============================================================================
2049                   ##### Peripheral State and Errors functions #####
2050  ===============================================================================
2051     [..]
2052     This subsection provides functions allowing to:
2053       (+) Get the DMA2D state
2054       (+) Get the DMA2D error code
2055 
2056 @endverbatim
2057   * @{
2058   */
2059 
2060 /**
2061   * @brief  Return the DMA2D state
2062   * @param  hdma2d pointer to a DMA2D_HandleTypeDef structure that contains
2063   *                 the configuration information for the DMA2D.
2064   * @retval HAL state
2065   */
HAL_DMA2D_GetState(const DMA2D_HandleTypeDef * hdma2d)2066 HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(const DMA2D_HandleTypeDef *hdma2d)
2067 {
2068   return hdma2d->State;
2069 }
2070 
2071 /**
2072   * @brief  Return the DMA2D error code
2073   * @param  hdma2d  pointer to a DMA2D_HandleTypeDef structure that contains
2074   *               the configuration information for DMA2D.
2075   * @retval DMA2D Error Code
2076   */
HAL_DMA2D_GetError(const DMA2D_HandleTypeDef * hdma2d)2077 uint32_t HAL_DMA2D_GetError(const DMA2D_HandleTypeDef *hdma2d)
2078 {
2079   return hdma2d->ErrorCode;
2080 }
2081 
2082 /**
2083   * @}
2084   */
2085 
2086 /**
2087   * @}
2088   */
2089 
2090 
2091 /** @defgroup DMA2D_Private_Functions DMA2D Private Functions
2092   * @{
2093   */
2094 
2095 /**
2096   * @brief  Set the DMA2D transfer parameters.
2097   * @param  hdma2d     Pointer to a DMA2D_HandleTypeDef structure that contains
2098   *                     the configuration information for the specified DMA2D.
2099   * @param  pdata      The source memory Buffer address
2100   * @param  DstAddress The destination memory Buffer address
2101   * @param  Width      The width of data to be transferred from source to destination.
2102   * @param  Height     The height of data to be transferred from source to destination.
2103   * @retval HAL status
2104   */
DMA2D_SetConfig(DMA2D_HandleTypeDef * hdma2d,uint32_t pdata,uint32_t DstAddress,uint32_t Width,uint32_t Height)2105 static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width,
2106                             uint32_t Height)
2107 {
2108   uint32_t tmp;
2109   uint32_t tmp1;
2110   uint32_t tmp2;
2111   uint32_t tmp3;
2112   uint32_t tmp4;
2113 
2114   /* Configure DMA2D data size */
2115   MODIFY_REG(hdma2d->Instance->NLR, (DMA2D_NLR_NL | DMA2D_NLR_PL), (Height | (Width << DMA2D_NLR_PL_Pos)));
2116 
2117   /* Configure DMA2D destination address */
2118   WRITE_REG(hdma2d->Instance->OMAR, DstAddress);
2119 
2120   /* Register to memory DMA2D mode selected */
2121   if (hdma2d->Init.Mode == DMA2D_R2M)
2122   {
2123     tmp1 = pdata & DMA2D_OCOLR_ALPHA_1;
2124     tmp2 = pdata & DMA2D_OCOLR_RED_1;
2125     tmp3 = pdata & DMA2D_OCOLR_GREEN_1;
2126     tmp4 = pdata & DMA2D_OCOLR_BLUE_1;
2127 
2128     /* Prepare the value to be written to the OCOLR register according to the color mode */
2129     if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB8888)
2130     {
2131       tmp = (tmp3 | tmp2 | tmp1 | tmp4);
2132     }
2133     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB888)
2134     {
2135       tmp = (tmp3 | tmp2 | tmp4);
2136     }
2137     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_RGB565)
2138     {
2139       tmp2 = (tmp2 >> 19U);
2140       tmp3 = (tmp3 >> 10U);
2141       tmp4 = (tmp4 >> 3U);
2142       tmp  = ((tmp3 << 5U) | (tmp2 << 11U) | tmp4);
2143     }
2144     else if (hdma2d->Init.ColorMode == DMA2D_OUTPUT_ARGB1555)
2145     {
2146       tmp1 = (tmp1 >> 31U);
2147       tmp2 = (tmp2 >> 19U);
2148       tmp3 = (tmp3 >> 11U);
2149       tmp4 = (tmp4 >> 3U);
2150       tmp  = ((tmp3 << 5U) | (tmp2 << 10U) | (tmp1 << 15U) | tmp4);
2151     }
2152     else /* Dhdma2d->Init.ColorMode = DMA2D_OUTPUT_ARGB4444 */
2153     {
2154       tmp1 = (tmp1 >> 28U);
2155       tmp2 = (tmp2 >> 20U);
2156       tmp3 = (tmp3 >> 12U);
2157       tmp4 = (tmp4 >> 4U);
2158       tmp  = ((tmp3 << 4U) | (tmp2 << 8U) | (tmp1 << 12U) | tmp4);
2159     }
2160     /* Write to DMA2D OCOLR register */
2161     WRITE_REG(hdma2d->Instance->OCOLR, tmp);
2162   }
2163   else if (hdma2d->Init.Mode == DMA2D_M2M_BLEND_FG) /*M2M_blending with fixed color FG DMA2D Mode selected*/
2164   {
2165     WRITE_REG(hdma2d->Instance->BGMAR, pdata);
2166   }
2167   else /* M2M, M2M_PFC,M2M_Blending or M2M_blending with fixed color BG DMA2D Mode */
2168   {
2169     /* Configure DMA2D source address */
2170     WRITE_REG(hdma2d->Instance->FGMAR, pdata);
2171   }
2172 }
2173 
2174 /**
2175   * @}
2176   */
2177 
2178 /**
2179   * @}
2180   */
2181 
2182 /**
2183   * @}
2184   */
2185 #endif /* DMA2D */
2186 #endif /* HAL_DMA2D_MODULE_ENABLED */
2187