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