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