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