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