1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_hal_dcmi.c
4   * @author  MCD Application Team
5   * @brief   DCMI HAL module driver
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Digital Camera Interface (DCMI) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Error functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29       The sequence below describes how to use this driver to capture image
30       from a camera module connected to the DCMI Interface.
31       This sequence does not take into account the configuration of the
32       camera module, which should be made before to configure and enable
33       the DCMI to capture images.
34 
35     (#) Program the required configuration through following parameters:
36         horizontal and vertical polarity, pixel clock polarity, Capture Rate,
37         Synchronization Mode, code of the frame delimiter and data width
38         using HAL_DCMI_Init() function.
39 
40     (#) Configure the selected DMA stream to transfer Data from DCMI DR
41         register to the destination memory buffer.
42 
43     (#) Program the required configuration through following parameters:
44         DCMI mode, destination memory Buffer address and the data length
45         and enable capture using HAL_DCMI_Start_DMA() function.
46 
47     (#) Optionally, configure and Enable the CROP feature to select a rectangular
48         window from the received image using HAL_DCMI_ConfigCrop()
49         and HAL_DCMI_EnableCrop() functions
50 
51     (#) The capture can be stopped using HAL_DCMI_Stop() function.
52 
53     (#) To control DCMI state you can use the function HAL_DCMI_GetState().
54 
55      *** DCMI HAL driver macros list ***
56      =============================================
57      [..]
58        Below the list of most used macros in DCMI HAL driver.
59 
60       (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral.
61       (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral.
62       (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags.
63       (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags.
64       (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts.
65       (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts.
66       (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not.
67 
68      [..]
69        (@) You can refer to the DCMI HAL driver header file for more useful macros
70 
71     *** Callback registration ***
72     =============================
73 
74     The compilation define USE_HAL_DCMI_REGISTER_CALLBACKS when set to 1
75     allows the user to configure dynamically the driver callbacks.
76     Use functions HAL_DCMI_RegisterCallback() to register a user callback.
77 
78     Function HAL_DCMI_RegisterCallback() allows to register following callbacks:
79       (+) FrameEventCallback : callback for DCMI Frame Event.
80       (+) VsyncEventCallback : callback for DCMI Vsync Event.
81       (+) LineEventCallback  : callback for DCMI Line Event.
82       (+) ErrorCallback      : callback for DCMI error detection.
83       (+) MspInitCallback    : callback for DCMI MspInit.
84       (+) MspDeInitCallback  : callback for DCMI MspDeInit.
85     This function takes as parameters the HAL peripheral handle, the Callback ID
86     and a pointer to the user callback function.
87 
88     Use function HAL_DCMI_UnRegisterCallback() to reset a callback to the default
89     weak (overridden) function.
90     HAL_DCMI_UnRegisterCallback() takes as parameters the HAL peripheral handle,
91     and the callback ID.
92     This function allows to reset following callbacks:
93       (+) FrameEventCallback : callback for DCMI Frame Event.
94       (+) VsyncEventCallback : callback for DCMI Vsync Event.
95       (+) LineEventCallback  : callback for DCMI Line Event.
96       (+) ErrorCallback      : callback for DCMI error.
97       (+) MspInitCallback    : callback for DCMI MspInit.
98       (+) MspDeInitCallback  : callback for DCMI MspDeInit.
99 
100     By default, after the HAL_DCMI_Init and if the state is HAL_DCMI_STATE_RESET
101     all callbacks are reset to the corresponding legacy weak (overridden) functions:
102     examples FrameEventCallback(), HAL_DCMI_ErrorCallback().
103     Exception done for MspInit and MspDeInit callbacks that are respectively
104     reset to the legacy weak (overridden) functions in the HAL_DCMI_Init
105     and HAL_DCMI_DeInit only when these callbacks are null (not registered beforehand).
106     If not, MspInit or MspDeInit are not null, the HAL_DCMI_Init and HAL_DCMI_DeInit
107     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
108 
109     Callbacks can be registered/unregistered in READY state only.
110     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
111     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
112     during the Init/DeInit.
113     In that case first register the MspInit/MspDeInit user callbacks
114     using HAL_DCMI_RegisterCallback before calling HAL_DCMI_DeInit
115     or HAL_DCMI_Init function.
116 
117     When the compilation define USE_HAL_DCMI_REGISTER_CALLBACKS is set to 0 or
118     not defined, the callback registering feature is not available
119     and weak (overridden) callbacks are used.
120 
121   @endverbatim
122   ******************************************************************************
123   */
124 
125 /* Includes ------------------------------------------------------------------*/
126 #include "stm32f2xx_hal.h"
127 #ifdef HAL_DCMI_MODULE_ENABLED
128 #if defined (DCMI)
129 
130 /** @addtogroup STM32F2xx_HAL_Driver
131   * @{
132   */
133 /** @defgroup DCMI DCMI
134   * @brief DCMI HAL module driver
135   * @{
136   */
137 
138 /* Private typedef -----------------------------------------------------------*/
139 /* Private define ------------------------------------------------------------*/
140 /** @defgroup DCMI_Private_Constants DCMI Private Constants
141   * @{
142   */
143 
144 /** @defgroup DCMI_Stop_TimeOut DCMI Stop Time Out
145   * @{
146   */
147 #define HAL_TIMEOUT_DCMI_STOP    ((uint32_t)1000) /* Set timeout to 1s  */
148 /**
149   * @}
150   */
151 
152 /**
153   * @}
154   */
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 /** @addtogroup DCMI_Private_Functions DCMI Private Functions
159   * @{
160   */
161 static void       DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma);
162 static void       DCMI_DMAError(DMA_HandleTypeDef *hdma);
163 
164 /**
165   * @}
166   */
167 /* Exported functions --------------------------------------------------------*/
168 
169 /** @defgroup DCMI_Exported_Functions DCMI Exported Functions
170   * @{
171   */
172 
173 /** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions
174   *  @brief   Initialization and Configuration functions
175   *
176 @verbatim
177  ===============================================================================
178                 ##### Initialization and Configuration functions #####
179  ===============================================================================
180     [..]  This section provides functions allowing to:
181       (+) Initialize and configure the DCMI
182       (+) De-initialize the DCMI
183 
184 @endverbatim
185   * @{
186   */
187 
188 /**
189   * @brief  Initializes the DCMI according to the specified
190   *         parameters in the DCMI_InitTypeDef and create the associated handle.
191   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
192   *                the configuration information for DCMI.
193   * @retval HAL status
194   */
HAL_DCMI_Init(DCMI_HandleTypeDef * hdcmi)195 HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
196 {
197   /* Check the DCMI peripheral state */
198   if (hdcmi == NULL)
199   {
200     return HAL_ERROR;
201   }
202 
203   /* Check function parameters */
204   assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance));
205   assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity));
206   assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity));
207   assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity));
208   assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode));
209   assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate));
210   assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode));
211   assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode));
212 
213   if (hdcmi->State == HAL_DCMI_STATE_RESET)
214   {
215     /* Init the DCMI Callback settings */
216 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
217     /* Reset callback pointers to the weak predefined callbacks */
218     hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback  */
219     hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback  */
220     hdcmi->LineEventCallback  = HAL_DCMI_LineEventCallback;  /* Legacy weak LineEventCallback   */
221     hdcmi->ErrorCallback      = HAL_DCMI_ErrorCallback;      /* Legacy weak ErrorCallback       */
222 
223     if (hdcmi->MspInitCallback == NULL)
224     {
225       /* Legacy weak MspInit Callback        */
226       hdcmi->MspInitCallback = HAL_DCMI_MspInit;
227     }
228     /* Initialize the low level hardware (MSP) */
229     hdcmi->MspInitCallback(hdcmi);
230 #else
231     /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
232     HAL_DCMI_MspInit(hdcmi);
233 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
234   }
235 
236   /* Change the DCMI state */
237   hdcmi->State = HAL_DCMI_STATE_BUSY;
238 
239   /* Configures the HS, VS, DE and PC polarity */
240   hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL  | DCMI_CR_VSPOL  | DCMI_CR_EDM_0 | \
241                            DCMI_CR_EDM_1  | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG  | \
242                            DCMI_CR_ESS);
243 
244   hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \
245                                     hdcmi->Init.VSPolarity  | hdcmi->Init.HSPolarity  | \
246                                     hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \
247                                     hdcmi->Init.JPEGMode);
248 
249   if (hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED)
250   {
251     hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode)    | \
252                              ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << DCMI_ESCR_LSC_Pos) | \
253                              ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << DCMI_ESCR_LEC_Pos) | \
254                              ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << DCMI_ESCR_FEC_Pos));
255 
256   }
257 
258   /* Enable the Line, Vsync, Error and Overrun interrupts */
259   __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
260 
261   /* Update error code */
262   hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
263 
264   /* Initialize the DCMI state*/
265   hdcmi->State  = HAL_DCMI_STATE_READY;
266 
267   return HAL_OK;
268 }
269 
270 /**
271   * @brief  Deinitializes the DCMI peripheral registers to their default reset
272   *         values.
273   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
274   *                the configuration information for DCMI.
275   * @retval HAL status
276   */
277 
HAL_DCMI_DeInit(DCMI_HandleTypeDef * hdcmi)278 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
279 {
280 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
281   if (hdcmi->MspDeInitCallback == NULL)
282   {
283     hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
284   }
285   /* De-Initialize the low level hardware (MSP) */
286   hdcmi->MspDeInitCallback(hdcmi);
287 #else
288   /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
289   HAL_DCMI_MspDeInit(hdcmi);
290 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
291 
292   /* Update error code */
293   hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
294 
295   /* Initialize the DCMI state*/
296   hdcmi->State = HAL_DCMI_STATE_RESET;
297 
298   /* Release Lock */
299   __HAL_UNLOCK(hdcmi);
300 
301   return HAL_OK;
302 }
303 
304 /**
305   * @brief  Initializes the DCMI MSP.
306   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
307   *                the configuration information for DCMI.
308   * @retval None
309   */
HAL_DCMI_MspInit(DCMI_HandleTypeDef * hdcmi)310 __weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
311 {
312   /* Prevent unused argument(s) compilation warning */
313   UNUSED(hdcmi);
314 
315   /* NOTE : This function Should not be modified, when the callback is needed,
316             the HAL_DCMI_MspInit could be implemented in the user file
317    */
318 }
319 
320 /**
321   * @brief  DeInitializes the DCMI MSP.
322   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
323   *                the configuration information for DCMI.
324   * @retval None
325   */
HAL_DCMI_MspDeInit(DCMI_HandleTypeDef * hdcmi)326 __weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi)
327 {
328   /* Prevent unused argument(s) compilation warning */
329   UNUSED(hdcmi);
330 
331   /* NOTE : This function Should not be modified, when the callback is needed,
332             the HAL_DCMI_MspDeInit could be implemented in the user file
333    */
334 }
335 
336 /**
337   * @}
338   */
339 /** @defgroup DCMI_Exported_Functions_Group2 IO operation functions
340   *  @brief   IO operation functions
341   *
342 @verbatim
343  ===============================================================================
344                       #####  IO operation functions  #####
345  ===============================================================================
346     [..]  This section provides functions allowing to:
347       (+) Configure destination address and data length and
348           Enables DCMI DMA request and enables DCMI capture
349       (+) Stop the DCMI capture.
350       (+) Handles DCMI interrupt request.
351 
352 @endverbatim
353   * @{
354   */
355 
356 /**
357   * @brief  Enables DCMI DMA request and enables DCMI capture
358   * @param  hdcmi     pointer to a DCMI_HandleTypeDef structure that contains
359   *                    the configuration information for DCMI.
360   * @param  DCMI_Mode DCMI capture mode snapshot or continuous grab.
361   * @param  pData     The destination memory Buffer address (LCD Frame buffer).
362   * @param  Length    The length of capture to be transferred.
363   * @retval HAL status
364   */
HAL_DCMI_Start_DMA(DCMI_HandleTypeDef * hdcmi,uint32_t DCMI_Mode,uint32_t pData,uint32_t Length)365 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
366 {
367   uint32_t tmp_length = Length;
368   /* Initialize the second memory address */
369   uint32_t SecondMemAddress;
370 
371   /* Check function parameters */
372   assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
373 
374   /* Process Locked */
375   __HAL_LOCK(hdcmi);
376 
377   /* Lock the DCMI peripheral state */
378   hdcmi->State = HAL_DCMI_STATE_BUSY;
379 
380   /* Enable DCMI by setting DCMIEN bit */
381   __HAL_DCMI_ENABLE(hdcmi);
382 
383   /* Configure the DCMI Mode */
384   hdcmi->Instance->CR &= ~(DCMI_CR_CM);
385   hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode);
386 
387   /* Set the DMA memory0 conversion complete callback */
388   hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt;
389 
390   /* Set the DMA error callback */
391   hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;
392 
393   /* Set the dma abort callback */
394   hdcmi->DMA_Handle->XferAbortCallback = NULL;
395 
396   /* Reset transfer counters value */
397   hdcmi->XferCount = 0;
398   hdcmi->XferTransferNumber = 0;
399   hdcmi->XferSize = 0;
400   hdcmi->pBuffPtr = 0;
401 
402   if (tmp_length <= 0xFFFFU)
403   {
404     /* Enable the DMA Stream */
405     if (HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, tmp_length) != HAL_OK)
406     {
407       /* Set Error Code */
408       hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
409       /* Change DCMI state */
410       hdcmi->State = HAL_DCMI_STATE_READY;
411       /* Release Lock */
412       __HAL_UNLOCK(hdcmi);
413       /* Return function status */
414       return HAL_ERROR;
415     }
416   }
417   else /* DCMI_DOUBLE_BUFFER Mode */
418   {
419     /* Set the DMA memory1 conversion complete callback */
420     hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAXferCplt;
421 
422     /* Initialize transfer parameters */
423     hdcmi->XferCount = 1;
424     hdcmi->XferSize = tmp_length;
425     hdcmi->pBuffPtr = pData;
426 
427     /* Get the number of buffer */
428     while (hdcmi->XferSize > 0xFFFFU)
429     {
430       hdcmi->XferSize = (hdcmi->XferSize / 2U);
431       hdcmi->XferCount = hdcmi->XferCount * 2U;
432     }
433 
434     /* Update DCMI counter  and transfer number*/
435     hdcmi->XferCount = (hdcmi->XferCount - 2U);
436     hdcmi->XferTransferNumber = hdcmi->XferCount;
437 
438     /* Update second memory address */
439     SecondMemAddress = (uint32_t)(pData + (4U * hdcmi->XferSize));
440 
441     /* Start DMA multi buffer transfer */
442     if (HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize) != HAL_OK)
443     {
444       /* Set Error Code */
445       hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
446       /* Change DCMI state */
447       hdcmi->State = HAL_DCMI_STATE_READY;
448       /* Release Lock */
449       __HAL_UNLOCK(hdcmi);
450       /* Return function status */
451       return HAL_ERROR;
452     }
453   }
454 
455   /* Enable Capture */
456   hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
457 
458   /* Release Lock */
459   __HAL_UNLOCK(hdcmi);
460 
461   /* Return function status */
462   return HAL_OK;
463 }
464 
465 /**
466   * @brief  Disable DCMI DMA request and Disable DCMI capture
467   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
468   *                the configuration information for DCMI.
469   * @retval HAL status
470   */
HAL_DCMI_Stop(DCMI_HandleTypeDef * hdcmi)471 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi)
472 {
473   uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
474   HAL_StatusTypeDef status = HAL_OK;
475 
476   /* Process locked */
477   __HAL_LOCK(hdcmi);
478 
479   /* Lock the DCMI peripheral state */
480   hdcmi->State = HAL_DCMI_STATE_BUSY;
481 
482   /* Disable Capture */
483   hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
484 
485   /* Check if the DCMI capture effectively disabled */
486   do
487   {
488     count-- ;
489     if (count == 0U)
490     {
491       /* Update error code */
492       hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
493 
494       status = HAL_TIMEOUT;
495       break;
496     }
497   } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
498 
499   /* Disable the DCMI */
500   __HAL_DCMI_DISABLE(hdcmi);
501 
502   /* Disable the DMA */
503   (void)HAL_DMA_Abort(hdcmi->DMA_Handle);
504 
505   /* Update error code */
506   hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE;
507 
508   /* Change DCMI state */
509   hdcmi->State = HAL_DCMI_STATE_READY;
510 
511   /* Process Unlocked */
512   __HAL_UNLOCK(hdcmi);
513 
514   /* Return function status */
515   return status;
516 }
517 
518 /**
519   * @brief  Suspend DCMI capture
520   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
521   *                the configuration information for DCMI.
522   * @retval HAL status
523   */
HAL_DCMI_Suspend(DCMI_HandleTypeDef * hdcmi)524 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi)
525 {
526   uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
527   HAL_StatusTypeDef status = HAL_OK;
528 
529   /* Process locked */
530   __HAL_LOCK(hdcmi);
531 
532   if (hdcmi->State == HAL_DCMI_STATE_BUSY)
533   {
534     /* Change DCMI state */
535     hdcmi->State = HAL_DCMI_STATE_SUSPENDED;
536 
537     /* Disable Capture */
538     hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
539 
540     /* Check if the DCMI capture effectively disabled */
541     do
542     {
543       count-- ;
544       if (count == 0U)
545       {
546         /* Update error code */
547         hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
548 
549         /* Change DCMI state */
550         hdcmi->State = HAL_DCMI_STATE_READY;
551 
552         status = HAL_TIMEOUT;
553         break;
554       }
555     } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
556   }
557   /* Process Unlocked */
558   __HAL_UNLOCK(hdcmi);
559 
560   /* Return function status */
561   return status;
562 }
563 
564 /**
565   * @brief  Resume DCMI capture
566   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
567   *                the configuration information for DCMI.
568   * @retval HAL status
569   */
HAL_DCMI_Resume(DCMI_HandleTypeDef * hdcmi)570 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi)
571 {
572   /* Process locked */
573   __HAL_LOCK(hdcmi);
574 
575   if (hdcmi->State == HAL_DCMI_STATE_SUSPENDED)
576   {
577     /* Change DCMI state */
578     hdcmi->State = HAL_DCMI_STATE_BUSY;
579 
580     /* Enable Capture */
581     hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
582   }
583   /* Process Unlocked */
584   __HAL_UNLOCK(hdcmi);
585 
586   /* Return function status */
587   return HAL_OK;
588 }
589 
590 /**
591   * @brief  Handles DCMI interrupt request.
592   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
593   *                the configuration information for the DCMI.
594   * @retval None
595   */
HAL_DCMI_IRQHandler(DCMI_HandleTypeDef * hdcmi)596 void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
597 {
598   uint32_t isr_value = READ_REG(hdcmi->Instance->MISR);
599 
600   /* Synchronization error interrupt management *******************************/
601   if ((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI)
602   {
603     /* Clear the Synchronization error flag */
604     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);
605 
606     /* Update error code */
607     hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;
608 
609     /* Change DCMI state */
610     hdcmi->State = HAL_DCMI_STATE_ERROR;
611 
612     /* Set the synchronization error callback */
613     hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
614 
615     /* Abort the DMA Transfer */
616     if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK)
617     {
618       DCMI_DMAError(hdcmi->DMA_Handle);
619     }
620   }
621   /* Overflow interrupt management ********************************************/
622   if ((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI)
623   {
624     /* Clear the Overflow flag */
625     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);
626 
627     /* Update error code */
628     hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;
629 
630     /* Change DCMI state */
631     hdcmi->State = HAL_DCMI_STATE_ERROR;
632 
633     /* Set the overflow callback */
634     hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
635 
636     /* Abort the DMA Transfer */
637     if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK)
638     {
639       DCMI_DMAError(hdcmi->DMA_Handle);
640     }
641   }
642   /* Line Interrupt management ************************************************/
643   if ((isr_value & DCMI_FLAG_LINERI) == DCMI_FLAG_LINERI)
644   {
645     /* Clear the Line interrupt flag */
646     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI);
647 
648     /* Line interrupt Callback */
649 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
650     /*Call registered DCMI line event callback*/
651     hdcmi->LineEventCallback(hdcmi);
652 #else
653     HAL_DCMI_LineEventCallback(hdcmi);
654 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
655   }
656   /* VSYNC interrupt management ***********************************************/
657   if ((isr_value & DCMI_FLAG_VSYNCRI) == DCMI_FLAG_VSYNCRI)
658   {
659     /* Clear the VSYNC flag */
660     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI);
661 
662     /* VSYNC Callback */
663 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
664     /*Call registered DCMI vsync event callback*/
665     hdcmi->VsyncEventCallback(hdcmi);
666 #else
667     HAL_DCMI_VsyncEventCallback(hdcmi);
668 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
669   }
670   /* FRAME interrupt management ***********************************************/
671   if ((isr_value & DCMI_FLAG_FRAMERI) == DCMI_FLAG_FRAMERI)
672   {
673     /* When snapshot mode, disable Vsync, Error and Overrun interrupts */
674     if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
675     {
676       /* Disable the Line, Vsync, Error and Overrun interrupts */
677       __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
678     }
679 
680     /* Disable the Frame interrupt */
681     __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME);
682 
683     /* Clear the End of Frame flag */
684     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
685 
686     /* Frame Callback */
687 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
688     /*Call registered DCMI frame event callback*/
689     hdcmi->FrameEventCallback(hdcmi);
690 #else
691     HAL_DCMI_FrameEventCallback(hdcmi);
692 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
693   }
694 }
695 
696 /**
697   * @brief  Error DCMI callback.
698   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
699   *                the configuration information for DCMI.
700   * @retval None
701   */
HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef * hdcmi)702 __weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
703 {
704   /* Prevent unused argument(s) compilation warning */
705   UNUSED(hdcmi);
706 
707   /* NOTE : This function Should not be modified, when the callback is needed,
708             the HAL_DCMI_ErrorCallback could be implemented in the user file
709    */
710 }
711 
712 /**
713   * @brief  Line Event callback.
714   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
715   *                the configuration information for DCMI.
716   * @retval None
717   */
HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef * hdcmi)718 __weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
719 {
720   /* Prevent unused argument(s) compilation warning */
721   UNUSED(hdcmi);
722   /* NOTE : This function Should not be modified, when the callback is needed,
723             the HAL_DCMI_LineEventCallback could be implemented in the user file
724    */
725 }
726 
727 /**
728   * @brief  VSYNC Event callback.
729   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
730   *                the configuration information for DCMI.
731   * @retval None
732   */
HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef * hdcmi)733 __weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
734 {
735   /* Prevent unused argument(s) compilation warning */
736   UNUSED(hdcmi);
737 
738   /* NOTE : This function Should not be modified, when the callback is needed,
739             the HAL_DCMI_VsyncEventCallback could be implemented in the user file
740    */
741 }
742 
743 /**
744   * @brief  Frame Event callback.
745   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
746   *                the configuration information for DCMI.
747   * @retval None
748   */
HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef * hdcmi)749 __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
750 {
751   /* Prevent unused argument(s) compilation warning */
752   UNUSED(hdcmi);
753 
754   /* NOTE : This function Should not be modified, when the callback is needed,
755             the HAL_DCMI_FrameEventCallback could be implemented in the user file
756    */
757 }
758 
759 /**
760   * @}
761   */
762 
763 /** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions
764   *  @brief    Peripheral Control functions
765   *
766 @verbatim
767  ===============================================================================
768                     ##### Peripheral Control functions #####
769  ===============================================================================
770 [..]  This section provides functions allowing to:
771       (+) Configure the CROP feature.
772       (+) Enable/Disable the CROP feature.
773       (+) Set embedded synchronization delimiters unmasks.
774 
775 @endverbatim
776   * @{
777   */
778 
779 /**
780   * @brief  Configure the DCMI CROP coordinate.
781   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
782   *                the configuration information for DCMI.
783   * @param  YSize DCMI Line number
784   * @param  XSize DCMI Pixel per line
785   * @param  X0    DCMI window X offset
786   * @param  Y0    DCMI window Y offset
787   * @retval HAL status
788   */
HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef * hdcmi,uint32_t X0,uint32_t Y0,uint32_t XSize,uint32_t YSize)789 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize,
790                                       uint32_t YSize)
791 {
792   /* Process Locked */
793   __HAL_LOCK(hdcmi);
794 
795   /* Lock the DCMI peripheral state */
796   hdcmi->State = HAL_DCMI_STATE_BUSY;
797 
798   /* Check the parameters */
799   assert_param(IS_DCMI_WINDOW_COORDINATE(X0));
800   assert_param(IS_DCMI_WINDOW_HEIGHT(Y0));
801   assert_param(IS_DCMI_WINDOW_COORDINATE(XSize));
802   assert_param(IS_DCMI_WINDOW_COORDINATE(YSize));
803 
804   /* Configure CROP */
805   hdcmi->Instance->CWSIZER = (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos));
806   hdcmi->Instance->CWSTRTR = (X0 | (Y0 << DCMI_CWSTRT_VST_Pos));
807 
808   /* Initialize the DCMI state*/
809   hdcmi->State  = HAL_DCMI_STATE_READY;
810 
811   /* Process Unlocked */
812   __HAL_UNLOCK(hdcmi);
813 
814   return HAL_OK;
815 }
816 
817 /**
818   * @brief  Disable the Crop feature.
819   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
820   *                the configuration information for DCMI.
821   * @retval HAL status
822   */
HAL_DCMI_DisableCrop(DCMI_HandleTypeDef * hdcmi)823 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
824 {
825   /* Process Locked */
826   __HAL_LOCK(hdcmi);
827 
828   /* Lock the DCMI peripheral state */
829   hdcmi->State = HAL_DCMI_STATE_BUSY;
830 
831   /* Disable DCMI Crop feature */
832   hdcmi->Instance->CR &= ~(uint32_t)DCMI_CR_CROP;
833 
834   /* Change the DCMI state*/
835   hdcmi->State = HAL_DCMI_STATE_READY;
836 
837   /* Process Unlocked */
838   __HAL_UNLOCK(hdcmi);
839 
840   return HAL_OK;
841 }
842 
843 /**
844   * @brief  Enable the Crop feature.
845   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
846   *                the configuration information for DCMI.
847   * @retval HAL status
848   */
HAL_DCMI_EnableCrop(DCMI_HandleTypeDef * hdcmi)849 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
850 {
851   /* Process Locked */
852   __HAL_LOCK(hdcmi);
853 
854   /* Lock the DCMI peripheral state */
855   hdcmi->State = HAL_DCMI_STATE_BUSY;
856 
857   /* Enable DCMI Crop feature */
858   hdcmi->Instance->CR |= (uint32_t)DCMI_CR_CROP;
859 
860   /* Change the DCMI state*/
861   hdcmi->State = HAL_DCMI_STATE_READY;
862 
863   /* Process Unlocked */
864   __HAL_UNLOCK(hdcmi);
865 
866   return HAL_OK;
867 }
868 
869 /**
870   * @brief  Set embedded synchronization delimiters unmasks.
871   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
872   *               the configuration information for DCMI.
873   * @param  SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains
874   *                    the embedded synchronization delimiters unmasks.
875   * @retval HAL status
876   */
HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef * hdcmi,const DCMI_SyncUnmaskTypeDef * SyncUnmask)877 HAL_StatusTypeDef  HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, const DCMI_SyncUnmaskTypeDef *SyncUnmask)
878 {
879   /* Process Locked */
880   __HAL_LOCK(hdcmi);
881 
882   /* Lock the DCMI peripheral state */
883   hdcmi->State = HAL_DCMI_STATE_BUSY;
884 
885   /* Write DCMI embedded synchronization unmask register */
886   hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) | \
887                            ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos) | \
888                            ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos) | \
889                            ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos));
890 
891   /* Change the DCMI state*/
892   hdcmi->State = HAL_DCMI_STATE_READY;
893 
894   /* Process Unlocked */
895   __HAL_UNLOCK(hdcmi);
896 
897   return HAL_OK;
898 }
899 
900 /**
901   * @}
902   */
903 
904 /** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions
905   *  @brief    Peripheral State functions
906   *
907 @verbatim
908  ===============================================================================
909                ##### Peripheral State and Errors functions #####
910  ===============================================================================
911     [..]
912     This subsection provides functions allowing to
913       (+) Check the DCMI state.
914       (+) Get the specific DCMI error flag.
915 
916 @endverbatim
917   * @{
918   */
919 
920 /**
921   * @brief  Return the DCMI state
922   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
923   *                the configuration information for DCMI.
924   * @retval HAL state
925   */
HAL_DCMI_GetState(const DCMI_HandleTypeDef * hdcmi)926 HAL_DCMI_StateTypeDef HAL_DCMI_GetState(const DCMI_HandleTypeDef *hdcmi)
927 {
928   return hdcmi->State;
929 }
930 
931 /**
932   * @brief  Return the DCMI error code
933   * @param  hdcmi  pointer to a DCMI_HandleTypeDef structure that contains
934   *               the configuration information for DCMI.
935   * @retval DCMI Error Code
936   */
HAL_DCMI_GetError(const DCMI_HandleTypeDef * hdcmi)937 uint32_t HAL_DCMI_GetError(const DCMI_HandleTypeDef *hdcmi)
938 {
939   return hdcmi->ErrorCode;
940 }
941 
942 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
943 /**
944   * @brief  Register a User DCMI Callback
945   *         To be used instead of the weak predefined callback
946   * @param  hdcmi DCMI handle
947   * @param  CallbackID ID of the callback to be registered
948   *         This parameter can be one of the following values:
949   *          @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
950   *          @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
951   *          @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
952   *          @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
953   *          @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
954   *          @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
955   * @param  pCallback pointer to the Callback function
956   * @retval HAL status
957   */
HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef * hdcmi,HAL_DCMI_CallbackIDTypeDef CallbackID,pDCMI_CallbackTypeDef pCallback)958 HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID,
959                                             pDCMI_CallbackTypeDef pCallback)
960 {
961   HAL_StatusTypeDef status = HAL_OK;
962 
963   if (pCallback == NULL)
964   {
965     /* update the error code */
966     hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
967     /* update return status */
968     status = HAL_ERROR;
969   }
970   else
971   {
972     if (hdcmi->State == HAL_DCMI_STATE_READY)
973     {
974       switch (CallbackID)
975       {
976         case HAL_DCMI_FRAME_EVENT_CB_ID :
977           hdcmi->FrameEventCallback = pCallback;
978           break;
979 
980         case HAL_DCMI_VSYNC_EVENT_CB_ID :
981           hdcmi->VsyncEventCallback = pCallback;
982           break;
983 
984         case HAL_DCMI_LINE_EVENT_CB_ID :
985           hdcmi->LineEventCallback = pCallback;
986           break;
987 
988         case HAL_DCMI_ERROR_CB_ID :
989           hdcmi->ErrorCallback = pCallback;
990           break;
991 
992         case HAL_DCMI_MSPINIT_CB_ID :
993           hdcmi->MspInitCallback = pCallback;
994           break;
995 
996         case HAL_DCMI_MSPDEINIT_CB_ID :
997           hdcmi->MspDeInitCallback = pCallback;
998           break;
999 
1000         default :
1001           /* Return error status */
1002           status =  HAL_ERROR;
1003           break;
1004       }
1005     }
1006     else if (hdcmi->State == HAL_DCMI_STATE_RESET)
1007     {
1008       switch (CallbackID)
1009       {
1010         case HAL_DCMI_MSPINIT_CB_ID :
1011           hdcmi->MspInitCallback = pCallback;
1012           break;
1013 
1014         case HAL_DCMI_MSPDEINIT_CB_ID :
1015           hdcmi->MspDeInitCallback = pCallback;
1016           break;
1017 
1018         default :
1019           /* update the error code */
1020           hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1021           /* update return status */
1022           status = HAL_ERROR;
1023           break;
1024       }
1025     }
1026     else
1027     {
1028       /* update the error code */
1029       hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1030       /* update return status */
1031       status = HAL_ERROR;
1032     }
1033   }
1034 
1035   return status;
1036 }
1037 
1038 /**
1039   * @brief  Unregister a DCMI Callback
1040   *         DCMI callback is redirected to the weak predefined callback
1041   * @param  hdcmi DCMI handle
1042   * @param  CallbackID ID of the callback to be registered
1043   *         This parameter can be one of the following values:
1044   *          @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
1045   *          @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
1046   *          @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
1047   *          @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
1048   *          @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
1049   *          @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
1050   * @retval HAL status
1051   */
HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef * hdcmi,HAL_DCMI_CallbackIDTypeDef CallbackID)1052 HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID)
1053 {
1054   HAL_StatusTypeDef status = HAL_OK;
1055 
1056   if (hdcmi->State == HAL_DCMI_STATE_READY)
1057   {
1058     switch (CallbackID)
1059     {
1060       case HAL_DCMI_FRAME_EVENT_CB_ID :
1061         hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback;  /* Legacy weak  FrameEventCallback  */
1062         break;
1063 
1064       case HAL_DCMI_VSYNC_EVENT_CB_ID :
1065         hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback;  /* Legacy weak VsyncEventCallback   */
1066         break;
1067 
1068       case HAL_DCMI_LINE_EVENT_CB_ID :
1069         hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback;    /* Legacy weak LineEventCallback    */
1070         break;
1071 
1072       case HAL_DCMI_ERROR_CB_ID :
1073         hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback;           /* Legacy weak ErrorCallback         */
1074         break;
1075 
1076       case HAL_DCMI_MSPINIT_CB_ID :
1077         hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1078         break;
1079 
1080       case HAL_DCMI_MSPDEINIT_CB_ID :
1081         hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1082         break;
1083 
1084       default :
1085         /* update the error code */
1086         hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1087         /* update return status */
1088         status = HAL_ERROR;
1089         break;
1090     }
1091   }
1092   else if (hdcmi->State == HAL_DCMI_STATE_RESET)
1093   {
1094     switch (CallbackID)
1095     {
1096       case HAL_DCMI_MSPINIT_CB_ID :
1097         hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1098         break;
1099 
1100       case HAL_DCMI_MSPDEINIT_CB_ID :
1101         hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1102         break;
1103 
1104       default :
1105         /* update the error code */
1106         hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1107         /* update return status */
1108         status = HAL_ERROR;
1109         break;
1110     }
1111   }
1112   else
1113   {
1114     /* update the error code */
1115     hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1116     /* update return status */
1117     status = HAL_ERROR;
1118   }
1119 
1120   return status;
1121 }
1122 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1123 
1124 /**
1125   * @}
1126   */
1127 
1128 /**
1129   * @}
1130   */
1131 
1132 /* Private functions ---------------------------------------------------------*/
1133 /** @defgroup DCMI_Private_Functions DCMI Private Functions
1134   * @{
1135   */
1136 /**
1137   * @brief  DMA conversion complete callback.
1138   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1139   *                the configuration information for the specified DMA module.
1140   * @retval None
1141   */
DCMI_DMAXferCplt(DMA_HandleTypeDef * hdma)1142 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
1143 {
1144   uint32_t tmp ;
1145 
1146   DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1147 
1148   if (hdcmi->XferCount != 0U)
1149   {
1150     /* Update memory 0 address location */
1151     tmp = ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR) & DMA_SxCR_CT);
1152     if (((hdcmi->XferCount % 2U) == 0U) && (tmp != 0U))
1153     {
1154       tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR;
1155       (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY0);
1156       hdcmi->XferCount--;
1157     }
1158     /* Update memory 1 address location */
1159     else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
1160     {
1161       tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR;
1162       (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY1);
1163       hdcmi->XferCount--;
1164     }
1165     else
1166     {
1167       /* Nothing to do */
1168     }
1169   }
1170   /* Update memory 0 address location */
1171   else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) != 0U)
1172   {
1173     ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR = hdcmi->pBuffPtr;
1174   }
1175   /* Update memory 1 address location */
1176   else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
1177   {
1178     tmp = hdcmi->pBuffPtr;
1179     ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR = (tmp + (4U * hdcmi->XferSize));
1180     hdcmi->XferCount = hdcmi->XferTransferNumber;
1181   }
1182   else
1183   {
1184     /* Nothing to do */
1185   }
1186 
1187   /* Check if the frame is transferred */
1188   if (hdcmi->XferCount == hdcmi->XferTransferNumber)
1189   {
1190     /* Enable the Frame interrupt */
1191     __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
1192 
1193     /* When snapshot mode, set dcmi state to ready */
1194     if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
1195     {
1196       hdcmi->State = HAL_DCMI_STATE_READY;
1197     }
1198   }
1199 }
1200 
1201 /**
1202   * @brief  DMA error callback
1203   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1204   *                the configuration information for the specified DMA module.
1205   * @retval None
1206   */
DCMI_DMAError(DMA_HandleTypeDef * hdma)1207 static void DCMI_DMAError(DMA_HandleTypeDef *hdma)
1208 {
1209   DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1210 
1211   if (hdcmi->DMA_Handle->ErrorCode != HAL_DMA_ERROR_FE)
1212   {
1213     /* Initialize the DCMI state*/
1214     hdcmi->State = HAL_DCMI_STATE_READY;
1215 
1216     /* Set DCMI Error Code */
1217     hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1218   }
1219 
1220   /* DCMI error Callback */
1221 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1222   /*Call registered DCMI error callback*/
1223   hdcmi->ErrorCallback(hdcmi);
1224 #else
1225   HAL_DCMI_ErrorCallback(hdcmi);
1226 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1227 
1228 }
1229 
1230 /**
1231   * @}
1232   */
1233 #endif /* DCMI */
1234 #endif /* HAL_DCMI_MODULE_ENABLED */
1235 /**
1236   * @}
1237   */
1238 
1239 /**
1240   * @}
1241   */
1242