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