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