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