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