Create release.yml
[betaflight.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_dcmi.c
blob46906e09b77abb1c77a02c7a0510547d4aea4284
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
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 The sequence below describes how to use this driver to capture image
19 from a camera module connected to the DCMI Interface.
20 This sequence does not take into account the configuration of the
21 camera module, which should be made before to configure and enable
22 the DCMI to capture images.
24 (#) Program the required configuration through following parameters:
25 horizontal and vertical polarity, pixel clock polarity, Capture Rate,
26 Synchronization Mode, code of the frame delimiter and data width
27 using HAL_DCMI_Init() function.
29 (#) Configure the selected DMA stream to transfer Data from DCMI DR
30 register to the destination memory buffer.
32 (#) Program the required configuration through following parameters:
33 DCMI mode, destination memory Buffer address and the data length
34 and enable capture using HAL_DCMI_Start_DMA() function.
36 (#) Optionally, configure and Enable the CROP feature to select a rectangular
37 window from the received image using HAL_DCMI_ConfigCrop()
38 and HAL_DCMI_EnableCrop() functions
40 (#) The capture can be stopped using HAL_DCMI_Stop() function.
42 (#) To control DCMI state you can use the function HAL_DCMI_GetState().
44 *** Callback registration ***
45 =============================================
47 The compilation flag USE_HAL_DCMI_REGISTER_CALLBACKS when set to 1
48 allows the user to configure dynamically the driver callbacks.
49 Use Functions HAL_DCMI_RegisterCallback() to register an interrupt callback.
51 Function HAL_DCMI_RegisterCallback() allows to register following callbacks:
52 (+) LineEventCallback : callback for DCMI line event.
53 (+) FrameEventCallback : callback for DCMI Frame event.
54 (+) VsyncEventCallback : callback for DCMI Vsync event.
55 (+) ErrorCallback : callback for error detection.
56 (+) MspInitCallback : callback for Msp Init.
57 (+) MspDeInitCallback : callback for Msp DeInit.
58 This function takes as parameters the HAL peripheral handle, the Callback ID
59 and a pointer to the user callback function.
61 Use function HAL_DCMI_UnRegisterCallback to reset a callback to the default weak function.
62 HAL_DCMI_UnRegisterCallback takes as parameters the HAL peripheral handle and the Callback ID.
63 This function allows to reset following callbacks:
64 (+) LineEventCallback : callback for DCMI line event.
65 (+) FrameEventCallback : callback for DCMI Frame event.
66 (+) VsyncEventCallback : callback for DCMI Vsync event.
67 (+) ErrorCallback : callback for error detection.
68 (+) MspInitCallback : callback for Msp Init.
69 (+) MspDeInitCallback : callback for Msp DeInit.
71 By default, after the HAL_DCMI_Init() and when the state is HAL_DCMI_STATE_RESET
72 all callbacks are set to the corresponding weak functions:
73 examples HAL_DCMI_LineEventCallback(), HAL_DCMI_FrameEventCallback().
74 Exception done for MspInit and MspDeInit functions that are
75 reset to the legacy weak functions in the HAL_DCMI_Init()/ HAL_DCMI_DeInit() only when
76 these callbacks are null (not registered beforehand).
77 If MspInit or MspDeInit are not null, the HAL_DCMI_Init()/ HAL_DCMI_DeInit()
78 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
80 Callbacks can be registered/unregistered in HAL_DCMI_STATE_READY state only.
81 Exception done MspInit/MspDeInit functions that can be registered/unregistered
82 in HAL_DCMI_STATE_READY or HAL_DCMI_STATE_RESET state,
83 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
84 In that case first register the MspInit/MspDeInit user callbacks
85 using HAL_DCMI_RegisterCallback() before calling HAL_DCMI_DeInit() or HAL_DCMI_Init() function.
87 When the compilation flag USE_HAL_DCMI_REGISTER_CALLBACKS is set to 0 or
88 not defined, the callback registration feature is not available and all callbacks
89 are set to the corresponding weak functions.
91 *** DCMI HAL driver macros list ***
92 =============================================
93 [..]
94 Below the list of most used macros in DCMI HAL driver.
96 (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral.
97 (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral.
98 (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags.
99 (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags.
100 (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts.
101 (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts.
102 (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not.
104 [..]
105 (@) You can refer to the DCMI HAL driver header file for more useful macros
107 @endverbatim
108 ******************************************************************************
109 * @attention
111 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
112 * All rights reserved.</center></h2>
114 * This software component is licensed by ST under BSD 3-Clause license,
115 * the "License"; You may not use this file except in compliance with the
116 * License. You may obtain a copy of the License at:
117 * opensource.org/licenses/BSD-3-Clause
119 ******************************************************************************
122 /* Includes ------------------------------------------------------------------*/
123 #include "stm32h7xx_hal.h"
125 /** @addtogroup STM32H7xx_HAL_Driver
126 * @{
128 /** @defgroup DCMI DCMI
129 * @brief DCMI HAL module driver
130 * @{
133 #ifdef HAL_DCMI_MODULE_ENABLED
134 #if defined (DCMI)
136 /* Private typedef -----------------------------------------------------------*/
137 /* Private define ------------------------------------------------------------*/
138 #define HAL_TIMEOUT_DCMI_STOP ((uint32_t)1000) /* Set timeout to 1s */
140 /* Private macro -------------------------------------------------------------*/
141 /* Private variables ---------------------------------------------------------*/
142 /* Private function prototypes -----------------------------------------------*/
143 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma);
144 static void DCMI_DMAError(DMA_HandleTypeDef *hdma);
146 /* Exported functions --------------------------------------------------------*/
148 /** @defgroup DCMI_Exported_Functions DCMI Exported Functions
149 * @{
152 /** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions
153 * @brief Initialization and Configuration functions
155 @verbatim
156 ===============================================================================
157 ##### Initialization and Configuration functions #####
158 ===============================================================================
159 [..] This section provides functions allowing to:
160 (+) Initialize and configure the DCMI
161 (+) De-initialize the DCMI
163 @endverbatim
164 * @{
168 * @brief Initializes the DCMI according to the specified
169 * parameters in the DCMI_InitTypeDef and create the associated handle.
170 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
171 * the configuration information for DCMI.
172 * @retval HAL status
174 HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
176 /* Check the DCMI peripheral state */
177 if (hdcmi == NULL)
179 return HAL_ERROR;
182 /* Check function parameters */
183 assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance));
184 assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity));
185 assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity));
186 assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity));
187 assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode));
188 assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate));
189 assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode));
190 assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode));
192 assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode));
193 assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart));
194 assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode));
195 assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart));
197 if (hdcmi->State == HAL_DCMI_STATE_RESET)
199 /* Init the DCMI Callback settings */
200 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
201 /* Reset callback pointers to the weak predefined callbacks */
202 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
203 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
204 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
205 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
207 if (hdcmi->MspInitCallback == NULL)
209 /* Legacy weak MspInit Callback */
210 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
212 /* Initialize the low level hardware (MSP) */
213 hdcmi->MspInitCallback(hdcmi);
214 #else
215 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
216 HAL_DCMI_MspInit(hdcmi);
217 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
220 /* Change the DCMI state */
221 hdcmi->State = HAL_DCMI_STATE_BUSY;
223 if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B)
225 /* Byte select mode must be programmed to the reset value if the extended mode
226 is not set to 8-bit data capture on every pixel clock */
227 hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL;
229 /* Configures the HS, VS, DE and PC polarity */
230 hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 | \
231 DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG | \
232 DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS | \
233 DCMI_CR_LSM | DCMI_CR_OELS);
235 hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \
236 hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity | \
237 hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \
238 hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode | \
239 hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode | \
240 hdcmi->Init.LineSelectStart);
242 if (hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED)
244 hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode) | \
245 ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << DCMI_ESCR_LSC_Pos) | \
246 ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << DCMI_ESCR_LEC_Pos) | \
247 ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << DCMI_ESCR_FEC_Pos));
251 /* Enable the Line, Vsync, Error and Overrun interrupts */
252 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
254 /* Update error code */
255 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
257 /* Initialize the DCMI state*/
258 hdcmi->State = HAL_DCMI_STATE_READY;
260 return HAL_OK;
264 * @brief Deinitializes the DCMI peripheral registers to their default reset
265 * values.
266 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
267 * the configuration information for DCMI.
268 * @retval HAL status
271 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
273 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
274 if (hdcmi->MspDeInitCallback == NULL)
276 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
278 /* De-Initialize the low level hardware (MSP) */
279 hdcmi->MspDeInitCallback(hdcmi);
280 #else
281 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
282 HAL_DCMI_MspDeInit(hdcmi);
283 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
285 /* Update error code */
286 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
288 /* Initialize the DCMI state*/
289 hdcmi->State = HAL_DCMI_STATE_RESET;
291 /* Release Lock */
292 __HAL_UNLOCK(hdcmi);
294 return HAL_OK;
298 * @brief Initializes the DCMI MSP.
299 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
300 * the configuration information for DCMI.
301 * @retval None
303 __weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
305 /* Prevent unused argument(s) compilation warning */
306 UNUSED(hdcmi);
308 /* NOTE : This function Should not be modified, when the callback is needed,
309 the HAL_DCMI_MspInit could be implemented in the user file
314 * @brief DeInitializes the DCMI MSP.
315 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
316 * the configuration information for DCMI.
317 * @retval None
319 __weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi)
321 /* Prevent unused argument(s) compilation warning */
322 UNUSED(hdcmi);
324 /* NOTE : This function Should not be modified, when the callback is needed,
325 the HAL_DCMI_MspDeInit could be implemented in the user file
330 * @}
332 /** @defgroup DCMI_Exported_Functions_Group2 IO operation functions
333 * @brief IO operation functions
335 @verbatim
336 ===============================================================================
337 ##### IO operation functions #####
338 ===============================================================================
339 [..] This section provides functions allowing to:
340 (+) Configure destination address and data length and
341 Enables DCMI DMA request and enables DCMI capture
342 (+) Stop the DCMI capture.
343 (+) Handles DCMI interrupt request.
345 @endverbatim
346 * @{
350 * @brief Enables DCMI DMA request and enables DCMI capture
351 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
352 * the configuration information for DCMI.
353 * @param DCMI_Mode DCMI capture mode snapshot or continuous grab.
354 * @param pData The destination memory Buffer address (LCD Frame buffer).
355 * @param Length The length of capture to be transferred.
356 * @retval HAL status
358 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
360 /* Initialize the second memory address */
361 uint32_t SecondMemAddress;
363 /* Check function parameters */
364 assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
366 /* Process Locked */
367 __HAL_LOCK(hdcmi);
369 /* Lock the DCMI peripheral state */
370 hdcmi->State = HAL_DCMI_STATE_BUSY;
372 /* Enable DCMI by setting DCMIEN bit */
373 __HAL_DCMI_ENABLE(hdcmi);
375 /* Configure the DCMI Mode */
376 hdcmi->Instance->CR &= ~(DCMI_CR_CM);
377 hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode);
379 /* Set the DMA memory0 conversion complete callback */
380 hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt;
382 /* Set the DMA error callback */
383 hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;
385 /* Set the dma abort callback */
386 hdcmi->DMA_Handle->XferAbortCallback = NULL;
388 /* Reset transfer counters value */
389 hdcmi->XferCount = 0;
390 hdcmi->XferTransferNumber = 0;
391 hdcmi->XferSize = 0;
392 hdcmi->pBuffPtr = 0;
394 if (Length <= 0xFFFFU)
396 /* Enable the DMA Stream */
397 if (HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length) != HAL_OK)
399 /* Set Error Code */
400 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
401 /* Change DCMI state */
402 hdcmi->State = HAL_DCMI_STATE_READY;
403 /* Release Lock */
404 __HAL_UNLOCK(hdcmi);
405 /* Return function status */
406 return HAL_ERROR;
409 else /* DCMI_DOUBLE_BUFFER Mode */
411 /* Set the DMA memory1 conversion complete callback */
412 hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAXferCplt;
414 /* Initialize transfer parameters */
415 hdcmi->XferCount = 1;
416 hdcmi->XferSize = Length;
417 hdcmi->pBuffPtr = pData;
419 /* Get the number of buffer */
420 while (hdcmi->XferSize > 0xFFFFU)
422 hdcmi->XferSize = (hdcmi->XferSize / 2U);
423 hdcmi->XferCount = hdcmi->XferCount * 2U;
426 /* Update DCMI counter and transfer number*/
427 hdcmi->XferCount = (hdcmi->XferCount - 2U);
428 hdcmi->XferTransferNumber = hdcmi->XferCount;
430 /* Update second memory address */
431 SecondMemAddress = (uint32_t)(pData + (4U * hdcmi->XferSize));
433 /* Start DMA multi buffer transfer */
434 if (HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize) != HAL_OK)
436 /* Set Error Code */
437 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
438 /* Change DCMI state */
439 hdcmi->State = HAL_DCMI_STATE_READY;
440 /* Release Lock */
441 __HAL_UNLOCK(hdcmi);
442 /* Return function status */
443 return HAL_ERROR;
447 /* Enable Capture */
448 hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
450 /* Release Lock */
451 __HAL_UNLOCK(hdcmi);
453 /* Return function status */
454 return HAL_OK;
458 * @brief Disable DCMI DMA request and Disable DCMI capture
459 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
460 * the configuration information for DCMI.
461 * @retval HAL status
463 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi)
465 uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
466 HAL_StatusTypeDef status = HAL_OK;
468 /* Process locked */
469 __HAL_LOCK(hdcmi);
471 /* Lock the DCMI peripheral state */
472 hdcmi->State = HAL_DCMI_STATE_BUSY;
474 /* Disable Capture */
475 hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
477 /* Check if the DCMI capture effectively disabled */
480 count-- ;
481 if (count == 0U)
483 /* Update error code */
484 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
486 status = HAL_TIMEOUT;
487 break;
490 while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
492 /* Disable the DCMI */
493 __HAL_DCMI_DISABLE(hdcmi);
495 /* Disable the DMA */
496 (void)HAL_DMA_Abort(hdcmi->DMA_Handle);
498 /* Update error code */
499 hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE;
501 /* Change DCMI state */
502 hdcmi->State = HAL_DCMI_STATE_READY;
504 /* Process Unlocked */
505 __HAL_UNLOCK(hdcmi);
507 /* Return function status */
508 return status;
512 * @brief Suspend DCMI capture
513 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
514 * the configuration information for DCMI.
515 * @retval HAL status
517 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi)
519 uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
520 HAL_StatusTypeDef status = HAL_OK;
522 /* Process locked */
523 __HAL_LOCK(hdcmi);
525 if (hdcmi->State == HAL_DCMI_STATE_BUSY)
527 /* Change DCMI state */
528 hdcmi->State = HAL_DCMI_STATE_SUSPENDED;
530 /* Disable Capture */
531 hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
533 /* Check if the DCMI capture effectively disabled */
536 count-- ;
537 if (count == 0U)
539 /* Update error code */
540 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
542 /* Change DCMI state */
543 hdcmi->State = HAL_DCMI_STATE_READY;
545 status = HAL_TIMEOUT;
546 break;
549 while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
551 /* Process Unlocked */
552 __HAL_UNLOCK(hdcmi);
554 /* Return function status */
555 return status;
559 * @brief Resume DCMI capture
560 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
561 * the configuration information for DCMI.
562 * @retval HAL status
564 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi)
566 /* Process locked */
567 __HAL_LOCK(hdcmi);
569 if (hdcmi->State == HAL_DCMI_STATE_SUSPENDED)
571 /* Change DCMI state */
572 hdcmi->State = HAL_DCMI_STATE_BUSY;
574 /* Disable Capture */
575 hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
577 /* Process Unlocked */
578 __HAL_UNLOCK(hdcmi);
580 /* Return function status */
581 return HAL_OK;
585 * @brief Handles DCMI interrupt request.
586 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
587 * the configuration information for the DCMI.
588 * @retval None
590 void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
592 uint32_t isr_value = READ_REG(hdcmi->Instance->MISR);
594 /* Synchronization error interrupt management *******************************/
595 if ((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI)
597 /* Clear the Synchronization error flag */
598 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);
600 /* Update error code */
601 hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;
603 /* Change DCMI state */
604 hdcmi->State = HAL_DCMI_STATE_ERROR;
606 /* Set the synchronization error callback */
607 hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
609 /* Abort the DMA Transfer */
610 (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
612 /* Overflow interrupt management ********************************************/
613 if ((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI)
615 /* Clear the Overflow flag */
616 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);
618 /* Update error code */
619 hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;
621 /* Change DCMI state */
622 hdcmi->State = HAL_DCMI_STATE_ERROR;
624 /* Set the overflow callback */
625 hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
627 /* Abort the DMA Transfer */
628 (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
630 /* Line Interrupt management ************************************************/
631 if ((isr_value & DCMI_FLAG_LINERI) == DCMI_FLAG_LINERI)
633 /* Clear the Line interrupt flag */
634 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI);
636 /* Line interrupt Callback */
637 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
638 /*Call registered DCMI line event callback*/
639 hdcmi->LineEventCallback(hdcmi);
640 #else
641 HAL_DCMI_LineEventCallback(hdcmi);
642 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
644 /* VSYNC interrupt management ***********************************************/
645 if ((isr_value & DCMI_FLAG_VSYNCRI) == DCMI_FLAG_VSYNCRI)
647 /* Clear the VSYNC flag */
648 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI);
650 /* VSYNC Callback */
651 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
652 /*Call registered DCMI vsync event callback*/
653 hdcmi->VsyncEventCallback(hdcmi);
654 #else
655 HAL_DCMI_VsyncEventCallback(hdcmi);
656 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
658 /* FRAME interrupt management ***********************************************/
659 if ((isr_value & DCMI_FLAG_FRAMERI) == DCMI_FLAG_FRAMERI)
661 /* When snapshot mode, disable Vsync, Error and Overrun interrupts */
662 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
664 /* Disable the Line, Vsync, Error and Overrun interrupts */
665 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
668 /* Disable the Frame interrupt */
669 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME);
671 /* Clear the End of Frame flag */
672 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
674 /* Frame Callback */
675 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
676 /*Call registered DCMI frame event callback*/
677 hdcmi->FrameEventCallback(hdcmi);
678 #else
679 HAL_DCMI_FrameEventCallback(hdcmi);
680 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
685 * @brief Error DCMI callback.
686 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
687 * the configuration information for DCMI.
688 * @retval None
690 __weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
692 /* Prevent unused argument(s) compilation warning */
693 UNUSED(hdcmi);
695 /* NOTE : This function Should not be modified, when the callback is needed,
696 the HAL_DCMI_ErrorCallback could be implemented in the user file
701 * @brief Line Event callback.
702 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
703 * the configuration information for DCMI.
704 * @retval None
706 __weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
708 /* Prevent unused argument(s) compilation warning */
709 UNUSED(hdcmi);
710 /* NOTE : This function Should not be modified, when the callback is needed,
711 the HAL_DCMI_LineEventCallback could be implemented in the user file
716 * @brief VSYNC Event callback.
717 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
718 * the configuration information for DCMI.
719 * @retval None
721 __weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
723 /* Prevent unused argument(s) compilation warning */
724 UNUSED(hdcmi);
726 /* NOTE : This function Should not be modified, when the callback is needed,
727 the HAL_DCMI_VsyncEventCallback could be implemented in the user file
732 * @brief Frame Event callback.
733 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
734 * the configuration information for DCMI.
735 * @retval None
737 __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
739 /* Prevent unused argument(s) compilation warning */
740 UNUSED(hdcmi);
742 /* NOTE : This function Should not be modified, when the callback is needed,
743 the HAL_DCMI_FrameEventCallback could be implemented in the user file
748 * @}
751 /** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions
752 * @brief Peripheral Control functions
754 @verbatim
755 ===============================================================================
756 ##### Peripheral Control functions #####
757 ===============================================================================
758 [..] This section provides functions allowing to:
759 (+) Configure the CROP feature.
760 (+) Enable/Disable the CROP feature.
761 (+) Set embedded synchronization delimiters unmasks.
763 @endverbatim
764 * @{
768 * @brief Configure the DCMI CROP coordinate.
769 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
770 * the configuration information for DCMI.
771 * @param YSize DCMI Line number
772 * @param XSize DCMI Pixel per line
773 * @param X0 DCMI window X offset
774 * @param Y0 DCMI window Y offset
775 * @retval HAL status
777 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize)
779 /* Process Locked */
780 __HAL_LOCK(hdcmi);
782 /* Lock the DCMI peripheral state */
783 hdcmi->State = HAL_DCMI_STATE_BUSY;
785 /* Check the parameters */
786 assert_param(IS_DCMI_WINDOW_COORDINATE(X0));
787 assert_param(IS_DCMI_WINDOW_HEIGHT(Y0));
788 assert_param(IS_DCMI_WINDOW_COORDINATE(XSize));
789 assert_param(IS_DCMI_WINDOW_COORDINATE(YSize));
791 /* Configure CROP */
792 hdcmi->Instance->CWSIZER = (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos));
793 hdcmi->Instance->CWSTRTR = (X0 | (Y0 << DCMI_CWSTRT_VST_Pos));
795 /* Initialize the DCMI state*/
796 hdcmi->State = HAL_DCMI_STATE_READY;
798 /* Process Unlocked */
799 __HAL_UNLOCK(hdcmi);
801 return HAL_OK;
805 * @brief Disable the Crop feature.
806 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
807 * the configuration information for DCMI.
808 * @retval HAL status
810 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
812 /* Process Locked */
813 __HAL_LOCK(hdcmi);
815 /* Lock the DCMI peripheral state */
816 hdcmi->State = HAL_DCMI_STATE_BUSY;
818 /* Disable DCMI Crop feature */
819 hdcmi->Instance->CR &= ~(uint32_t)DCMI_CR_CROP;
821 /* Change the DCMI state*/
822 hdcmi->State = HAL_DCMI_STATE_READY;
824 /* Process Unlocked */
825 __HAL_UNLOCK(hdcmi);
827 return HAL_OK;
831 * @brief Enable the Crop feature.
832 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
833 * the configuration information for DCMI.
834 * @retval HAL status
836 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
838 /* Process Locked */
839 __HAL_LOCK(hdcmi);
841 /* Lock the DCMI peripheral state */
842 hdcmi->State = HAL_DCMI_STATE_BUSY;
844 /* Enable DCMI Crop feature */
845 hdcmi->Instance->CR |= (uint32_t)DCMI_CR_CROP;
847 /* Change the DCMI state*/
848 hdcmi->State = HAL_DCMI_STATE_READY;
850 /* Process Unlocked */
851 __HAL_UNLOCK(hdcmi);
853 return HAL_OK;
857 * @brief Set embedded synchronization delimiters unmasks.
858 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
859 * the configuration information for DCMI.
860 * @param SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains
861 * the embedded synchronization delimiters unmasks.
862 * @retval HAL status
864 HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask)
866 /* Process Locked */
867 __HAL_LOCK(hdcmi);
869 /* Lock the DCMI peripheral state */
870 hdcmi->State = HAL_DCMI_STATE_BUSY;
872 /* Write DCMI embedded synchronization unmask register */
873 hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) | \
874 ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos) | \
875 ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos) | \
876 ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos));
878 /* Change the DCMI state*/
879 hdcmi->State = HAL_DCMI_STATE_READY;
881 /* Process Unlocked */
882 __HAL_UNLOCK(hdcmi);
884 return HAL_OK;
888 * @}
891 /** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions
892 * @brief Peripheral State functions
894 @verbatim
895 ===============================================================================
896 ##### Peripheral State and Errors functions #####
897 ===============================================================================
898 [..]
899 This subsection provides functions allowing to
900 (+) Check the DCMI state.
901 (+) Get the specific DCMI error flag.
903 @endverbatim
904 * @{
908 * @brief Return the DCMI state
909 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
910 * the configuration information for DCMI.
911 * @retval HAL state
913 HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi)
915 return hdcmi->State;
919 * @brief Return the DCMI error code
920 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
921 * the configuration information for DCMI.
922 * @retval DCMI Error Code
924 uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi)
926 return hdcmi->ErrorCode;
929 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
931 * @brief Register a User DCMI Callback
932 * To be used instead of the weak predefined callback
933 * @param hdcmi DCMI handle
934 * @param CallbackID ID of the callback to be registered
935 * This parameter can be one of the following values:
936 * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
937 * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
938 * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
939 * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
940 * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
941 * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
942 * @param pCallback pointer to the Callback function
943 * @retval HAL status
945 HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, pDCMI_CallbackTypeDef pCallback)
947 HAL_StatusTypeDef status = HAL_OK;
949 if (pCallback == NULL)
951 /* update the error code */
952 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
953 /* update return status */
954 status = HAL_ERROR;
956 else
958 if (hdcmi->State == HAL_DCMI_STATE_READY)
960 switch (CallbackID)
962 case HAL_DCMI_FRAME_EVENT_CB_ID :
963 hdcmi->FrameEventCallback = pCallback;
964 break;
966 case HAL_DCMI_VSYNC_EVENT_CB_ID :
967 hdcmi->VsyncEventCallback = pCallback;
968 break;
970 case HAL_DCMI_LINE_EVENT_CB_ID :
971 hdcmi->LineEventCallback = pCallback;
972 break;
974 case HAL_DCMI_ERROR_CB_ID :
975 hdcmi->ErrorCallback = pCallback;
976 break;
978 case HAL_DCMI_MSPINIT_CB_ID :
979 hdcmi->MspInitCallback = pCallback;
980 break;
982 case HAL_DCMI_MSPDEINIT_CB_ID :
983 hdcmi->MspDeInitCallback = pCallback;
984 break;
986 default :
987 /* Return error status */
988 status = HAL_ERROR;
989 break;
992 else if (hdcmi->State == HAL_DCMI_STATE_RESET)
994 switch (CallbackID)
996 case HAL_DCMI_MSPINIT_CB_ID :
997 hdcmi->MspInitCallback = pCallback;
998 break;
1000 case HAL_DCMI_MSPDEINIT_CB_ID :
1001 hdcmi->MspDeInitCallback = pCallback;
1002 break;
1004 default :
1005 /* update the error code */
1006 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1007 /* update return status */
1008 status = HAL_ERROR;
1009 break;
1012 else
1014 /* update the error code */
1015 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1016 /* update return status */
1017 status = HAL_ERROR;
1021 return status;
1025 * @brief Unregister a DCMI Callback
1026 * DCMI callabck is redirected to the weak predefined callback
1027 * @param hdcmi DCMI handle
1028 * @param CallbackID ID of the callback to be registered
1029 * This parameter can be one of the following values:
1030 * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
1031 * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
1032 * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
1033 * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
1034 * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
1035 * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
1036 * @retval HAL status
1038 HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID)
1040 HAL_StatusTypeDef status = HAL_OK;
1042 if (hdcmi->State == HAL_DCMI_STATE_READY)
1044 switch (CallbackID)
1046 case HAL_DCMI_FRAME_EVENT_CB_ID :
1047 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
1048 break;
1050 case HAL_DCMI_VSYNC_EVENT_CB_ID :
1051 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
1052 break;
1054 case HAL_DCMI_LINE_EVENT_CB_ID :
1055 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
1056 break;
1058 case HAL_DCMI_ERROR_CB_ID :
1059 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
1060 break;
1062 case HAL_DCMI_MSPINIT_CB_ID :
1063 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1064 break;
1066 case HAL_DCMI_MSPDEINIT_CB_ID :
1067 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1068 break;
1070 default :
1071 /* update the error code */
1072 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1073 /* update return status */
1074 status = HAL_ERROR;
1075 break;
1078 else if (hdcmi->State == HAL_DCMI_STATE_RESET)
1080 switch (CallbackID)
1082 case HAL_DCMI_MSPINIT_CB_ID :
1083 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1084 break;
1086 case HAL_DCMI_MSPDEINIT_CB_ID :
1087 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1088 break;
1090 default :
1091 /* update the error code */
1092 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1093 /* update return status */
1094 status = HAL_ERROR;
1095 break;
1098 else
1100 /* update the error code */
1101 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1102 /* update return status */
1103 status = HAL_ERROR;
1106 return status;
1108 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1111 * @}
1113 /* Private functions ---------------------------------------------------------*/
1114 /** @defgroup DCMI_Private_Functions DCMI Private Functions
1115 * @{
1118 * @brief DMA conversion complete callback.
1119 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1120 * the configuration information for the specified DMA module.
1121 * @retval None
1123 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
1125 uint32_t tmp ;
1127 DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1129 if (hdcmi->XferCount != 0U)
1131 /* Update memory 0 address location */
1132 tmp = ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR) & DMA_SxCR_CT);
1133 if (((hdcmi->XferCount % 2U) == 0U) && (tmp != 0U))
1135 tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR;
1136 (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY0);
1137 hdcmi->XferCount--;
1139 /* Update memory 1 address location */
1140 else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
1142 tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR;
1143 (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY1);
1144 hdcmi->XferCount--;
1146 else
1148 /* Nothing to do */
1151 /* Update memory 0 address location */
1152 else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) != 0U)
1154 ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR = hdcmi->pBuffPtr;
1156 /* Update memory 1 address location */
1157 else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
1159 tmp = hdcmi->pBuffPtr;
1160 ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR = (tmp + (4U * hdcmi->XferSize));
1161 hdcmi->XferCount = hdcmi->XferTransferNumber;
1163 else
1165 /* Nothing to do */
1168 /* Check if the frame is transferred */
1169 if (hdcmi->XferCount == hdcmi->XferTransferNumber)
1171 /* Enable the Frame interrupt */
1172 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
1174 /* When snapshot mode, set dcmi state to ready */
1175 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
1177 hdcmi->State = HAL_DCMI_STATE_READY;
1183 * @brief DMA error callback
1184 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1185 * the configuration information for the specified DMA module.
1186 * @retval None
1188 static void DCMI_DMAError(DMA_HandleTypeDef *hdma)
1190 DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1192 if (hdcmi->DMA_Handle->ErrorCode != HAL_DMA_ERROR_FE)
1194 /* Initialize the DCMI state*/
1195 hdcmi->State = HAL_DCMI_STATE_READY;
1197 /* Set DCMI Error Code */
1198 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1201 /* DCMI error Callback */
1202 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1203 /*Call registered DCMI error callback*/
1204 hdcmi->ErrorCallback(hdcmi);
1205 #else
1206 HAL_DCMI_ErrorCallback(hdcmi);
1207 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1211 * @}
1215 * @}
1217 #endif /* DCMI */
1218 #endif /* HAL_DCMI_MODULE_ENABLED */
1220 * @}
1224 * @}
1227 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/