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