1 /**
2 ******************************************************************************
3 * @file stm32u5xx_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) 2021 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 "stm32u5xx_hal.h"
127 #ifdef HAL_DCMI_MODULE_ENABLED
128 #if defined (DCMI)
129
130 /** @addtogroup STM32U5xx_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 assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode));
214 assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart));
215 assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode));
216 assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart));
217
218 if (hdcmi->State == HAL_DCMI_STATE_RESET)
219 {
220 /* Init the DCMI Callback settings */
221 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
222 /* Reset callback pointers to the weak predefined callbacks */
223 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
224 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
225 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
226 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
227
228 if (hdcmi->MspInitCallback == NULL)
229 {
230 /* Legacy weak MspInit Callback */
231 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
232 }
233 /* Initialize the low level hardware (MSP) */
234 hdcmi->MspInitCallback(hdcmi);
235 #else
236 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
237 HAL_DCMI_MspInit(hdcmi);
238 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
239 }
240
241 /* Change the DCMI state */
242 hdcmi->State = HAL_DCMI_STATE_BUSY;
243
244 if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B)
245 {
246 /* Byte select mode must be programmed to the reset value if the extended mode
247 is not set to 8-bit data capture on every pixel clock */
248 hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL;
249 }
250 /* Configures the HS, VS, DE and PC polarity */
251 hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 | \
252 DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG | \
253 DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS | \
254 DCMI_CR_LSM | DCMI_CR_OELS);
255
256 hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \
257 hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity | \
258 hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \
259 hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode | \
260 hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode | \
261 hdcmi->Init.LineSelectStart);
262
263 if (hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED)
264 {
265 hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode) | \
266 ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << DCMI_ESCR_LSC_Pos) | \
267 ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << DCMI_ESCR_LEC_Pos) | \
268 ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << DCMI_ESCR_FEC_Pos));
269
270 }
271
272 /* Enable the Line, Vsync, Error and Overrun interrupts */
273 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
274
275 /* Update error code */
276 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
277
278 /* Initialize the DCMI state*/
279 hdcmi->State = HAL_DCMI_STATE_READY;
280
281 return HAL_OK;
282 }
283
284 /**
285 * @brief Deinitializes the DCMI peripheral registers to their default reset
286 * values.
287 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
288 * the configuration information for DCMI.
289 * @retval HAL status
290 */
291
HAL_DCMI_DeInit(DCMI_HandleTypeDef * hdcmi)292 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
293 {
294 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
295 if (hdcmi->MspDeInitCallback == NULL)
296 {
297 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
298 }
299 /* De-Initialize the low level hardware (MSP) */
300 hdcmi->MspDeInitCallback(hdcmi);
301 #else
302 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
303 HAL_DCMI_MspDeInit(hdcmi);
304 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
305
306 /* Update error code */
307 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
308
309 /* Initialize the DCMI state*/
310 hdcmi->State = HAL_DCMI_STATE_RESET;
311
312 /* Release Lock */
313 __HAL_UNLOCK(hdcmi);
314
315 return HAL_OK;
316 }
317
318 /**
319 * @brief Initializes the DCMI MSP.
320 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
321 * the configuration information for DCMI.
322 * @retval None
323 */
HAL_DCMI_MspInit(DCMI_HandleTypeDef * hdcmi)324 __weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
325 {
326 /* Prevent unused argument(s) compilation warning */
327 UNUSED(hdcmi);
328
329 /* NOTE : This function Should not be modified, when the callback is needed,
330 the HAL_DCMI_MspInit could be implemented in the user file
331 */
332 }
333
334 /**
335 * @brief DeInitializes the DCMI MSP.
336 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
337 * the configuration information for DCMI.
338 * @retval None
339 */
HAL_DCMI_MspDeInit(DCMI_HandleTypeDef * hdcmi)340 __weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi)
341 {
342 /* Prevent unused argument(s) compilation warning */
343 UNUSED(hdcmi);
344
345 /* NOTE : This function Should not be modified, when the callback is needed,
346 the HAL_DCMI_MspDeInit could be implemented in the user file
347 */
348 }
349
350 /**
351 * @}
352 */
353 /** @defgroup DCMI_Exported_Functions_Group2 IO operation functions
354 * @brief IO operation functions
355 *
356 @verbatim
357 ===============================================================================
358 ##### IO operation functions #####
359 ===============================================================================
360 [..] This section provides functions allowing to:
361 (+) Configure destination address and data length and
362 Enables DCMI DMA request and enables DCMI capture
363 (+) Stop the DCMI capture.
364 (+) Handles DCMI interrupt request.
365
366 @endverbatim
367 * @{
368 */
369
370 /**
371 * @brief Enables DCMI DMA request and enables DCMI capture
372 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
373 * the configuration information for DCMI.
374 * @param DCMI_Mode DCMI capture mode snapshot or continuous grab.
375 * @param pData The destination memory Buffer address (LCD Frame buffer).
376 * @param Length The length of capture to be transferred.
377 * @retval HAL status
378 */
HAL_DCMI_Start_DMA(DCMI_HandleTypeDef * hdcmi,uint32_t DCMI_Mode,uint32_t pData,uint32_t Length)379 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
380 {
381 uint32_t tmp_length = Length;
382 HAL_StatusTypeDef status = HAL_OK;
383 uint32_t cllr_offset;
384 uint32_t tmp1;
385 uint32_t tmp2;
386
387 /* Check function parameters */
388 assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
389
390 /* Process Locked */
391 __HAL_LOCK(hdcmi);
392
393 /* Lock the DCMI peripheral state */
394 hdcmi->State = HAL_DCMI_STATE_BUSY;
395
396 /* Enable DCMI by setting DCMIEN bit */
397 __HAL_DCMI_ENABLE(hdcmi);
398
399 /* Configure the DCMI Mode */
400 hdcmi->Instance->CR &= ~(DCMI_CR_CM);
401 hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode);
402
403 /* Set the DMA memory0 conversion complete callback */
404 hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt;
405
406 /* Set the DMA error callback */
407 hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;
408
409 /* Set the dma abort callback */
410 hdcmi->DMA_Handle->XferAbortCallback = NULL;
411
412 /* Reset transfer counters value */
413 hdcmi->XferCount = 0;
414 hdcmi->XferTransferNumber = 0;
415 hdcmi->XferSize = 0;
416 hdcmi->pBuffPtr = 0;
417
418 /* Length should be converted to number of bytes */
419 tmp_length = tmp_length * 4U;
420
421 if (tmp_length <= 0xFFFFU)
422 {
423 /* Continuoues Mode */
424 /* Enable the DMA Stream */
425 if ((hdcmi->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
426 {
427 if ((hdcmi->DMA_Handle->LinkedListQueue != 0U) && (hdcmi->DMA_Handle->LinkedListQueue->Head != 0U))
428 {
429 /* Set Source , Destination , Length for DMA Xfer */
430
431 /* Set DMA data size */
432 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = tmp_length;
433 /* Set DMA source address */
434 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \
435 (uint32_t)&hdcmi->Instance->DR;
436 /* Set DMA destination address */
437 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
438
439 status = HAL_DMAEx_List_Start_IT(hdcmi->DMA_Handle);
440 }
441 else
442 {
443 /* Set Error Code */
444 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
445 /* Change DCMI state */
446 hdcmi->State = HAL_DCMI_STATE_READY;
447 /* Release Lock */
448 __HAL_UNLOCK(hdcmi);
449 /* Return function status */
450 status = HAL_ERROR;
451 }
452 }
453 else
454 {
455 status = HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, tmp_length);
456 }
457 }
458 else /* DCMI_DOUBLE_BUFFER Mode */
459 {
460 /* Double buffering is used through 2 Nodes
461 Calculate the elementary size to be transferred by each node */
462
463 /* Initialize transfer parameters */
464 hdcmi->XferCount = 1;
465 hdcmi->XferSize = tmp_length;
466 hdcmi->pBuffPtr = pData;
467
468 /* Get the number of buffer */
469 while (hdcmi->XferSize > 0xFFFFU)
470 {
471 hdcmi->XferSize = (hdcmi->XferSize / 2U);
472 hdcmi->XferCount = hdcmi->XferCount * 2U;
473 }
474
475 /* Update DCMI counter and transfer number*/
476 hdcmi->XferCount = (hdcmi->XferCount - 1U);
477 hdcmi->XferTransferNumber = hdcmi->XferCount;
478
479 if ((hdcmi->DMA_Handle->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
480 {
481 if ((hdcmi->DMA_Handle->LinkedListQueue != 0U) && (hdcmi->DMA_Handle->LinkedListQueue->Head != 0U))
482 {
483 /* Update first node */
484
485 /* Set DMA Data size */
486 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hdcmi->XferSize ;
487
488 /* Set DMA Source address */
489 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \
490 (uint32_t)&hdcmi->Instance->DR;
491
492 /* Set DMA Destination address */
493 hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pData;
494
495 /* Get CLLR offset */
496 cllr_offset = (hdcmi->DMA_Handle->LinkedListQueue->Head->NodeInfo & NODE_CLLR_IDX) >> 8U;
497
498 /* Update second node */
499 if (hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[cllr_offset] != 0U)
500 {
501 tmp1 = (uint32_t)hdcmi->DMA_Handle->LinkedListQueue->Head ;
502 tmp2 = hdcmi->DMA_Handle->LinkedListQueue->Head->LinkRegisters[cllr_offset];
503 /* Update second node */
504
505 /* Set DMA Data size */
506 ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \
507 (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = hdcmi->XferSize;
508
509 /* Set DMA Source address */
510 ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \
511 (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = \
512 (uint32_t)&hdcmi->Instance->DR;
513
514 /* Set DMA Destination address */
515 ((DMA_NodeTypeDef *)((tmp1 & DMA_CLBAR_LBA) + \
516 (tmp2 & DMA_CLLR_LA)))->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = \
517 (uint32_t)pData + hdcmi->XferSize;
518
519 if (HAL_DMAEx_List_Start_IT(hdcmi->DMA_Handle) != HAL_OK)
520 {
521 /* Set Error Code */
522 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
523 /* Change DCMI state */
524 hdcmi->State = HAL_DCMI_STATE_READY;
525 /* Release Lock */
526 __HAL_UNLOCK(hdcmi);
527 /* Return function status */
528 status = HAL_ERROR;
529 }
530 }
531 else
532 {
533 /* Set Error Code */
534 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
535 /* Change DCMI state */
536 hdcmi->State = HAL_DCMI_STATE_READY;
537 /* Release Lock */
538 __HAL_UNLOCK(hdcmi);
539 /* Return function status */
540 status = HAL_ERROR;
541 }
542 }
543 else
544 {
545 /* Set Error Code */
546 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
547 /* Change DCMI state */
548 hdcmi->State = HAL_DCMI_STATE_READY;
549 /* Release Lock */
550 __HAL_UNLOCK(hdcmi);
551 /* Return function status */
552 status = HAL_ERROR;
553 }
554 }
555 else
556 {
557 /* Set Error Code */
558 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
559 /* Change DCMI state */
560 hdcmi->State = HAL_DCMI_STATE_READY;
561 /* Release Lock */
562 __HAL_UNLOCK(hdcmi);
563 /* Return function status */
564 status = HAL_ERROR;
565 }
566 }
567 if (status == HAL_OK)
568 {
569 /* Enable Capture */
570 hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
571
572 /* Release Lock */
573 __HAL_UNLOCK(hdcmi);
574 }
575 else
576 {
577 /* Set Error Code */
578 hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
579 /* Change DCMI state */
580 hdcmi->State = HAL_DCMI_STATE_READY;
581 /* Release Lock */
582 __HAL_UNLOCK(hdcmi);
583 /* Return function status */
584 status = HAL_ERROR;
585 }
586
587 /* Return function status */
588 return status;
589 }
590
591 /**
592 * @brief Disable DCMI DMA request and Disable DCMI capture
593 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
594 * the configuration information for DCMI.
595 * @retval HAL status
596 */
HAL_DCMI_Stop(DCMI_HandleTypeDef * hdcmi)597 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi)
598 {
599 uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
600 HAL_StatusTypeDef status = HAL_OK;
601
602 /* Process locked */
603 __HAL_LOCK(hdcmi);
604
605 /* Lock the DCMI peripheral state */
606 hdcmi->State = HAL_DCMI_STATE_BUSY;
607
608 /* Disable Capture */
609 hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
610
611 /* Check if the DCMI capture effectively disabled */
612 do
613 {
614 count-- ;
615 if (count == 0U)
616 {
617 /* Update error code */
618 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
619
620 status = HAL_TIMEOUT;
621 break;
622 }
623 } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
624
625 /* Disable the DCMI */
626 __HAL_DCMI_DISABLE(hdcmi);
627
628 /* Disable the DMA */
629 (void)HAL_DMA_Abort(hdcmi->DMA_Handle);
630
631 /* Update error code */
632 hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE;
633
634 /* Change DCMI state */
635 hdcmi->State = HAL_DCMI_STATE_READY;
636
637 /* Process Unlocked */
638 __HAL_UNLOCK(hdcmi);
639
640 /* Return function status */
641 return status;
642 }
643
644 /**
645 * @brief Suspend DCMI capture
646 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
647 * the configuration information for DCMI.
648 * @retval HAL status
649 */
HAL_DCMI_Suspend(DCMI_HandleTypeDef * hdcmi)650 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi)
651 {
652 uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
653 HAL_StatusTypeDef status = HAL_OK;
654
655 /* Process locked */
656 __HAL_LOCK(hdcmi);
657
658 if (hdcmi->State == HAL_DCMI_STATE_BUSY)
659 {
660 /* Change DCMI state */
661 hdcmi->State = HAL_DCMI_STATE_SUSPENDED;
662
663 /* Disable Capture */
664 hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
665
666 /* Check if the DCMI capture effectively disabled */
667 do
668 {
669 count-- ;
670 if (count == 0U)
671 {
672 /* Update error code */
673 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
674
675 /* Change DCMI state */
676 hdcmi->State = HAL_DCMI_STATE_READY;
677
678 status = HAL_TIMEOUT;
679 break;
680 }
681 } while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
682 }
683 /* Process Unlocked */
684 __HAL_UNLOCK(hdcmi);
685
686 /* Return function status */
687 return status;
688 }
689
690 /**
691 * @brief Resume DCMI capture
692 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
693 * the configuration information for DCMI.
694 * @retval HAL status
695 */
HAL_DCMI_Resume(DCMI_HandleTypeDef * hdcmi)696 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi)
697 {
698 /* Process locked */
699 __HAL_LOCK(hdcmi);
700
701 if (hdcmi->State == HAL_DCMI_STATE_SUSPENDED)
702 {
703 /* Change DCMI state */
704 hdcmi->State = HAL_DCMI_STATE_BUSY;
705
706 /* Enable Capture */
707 hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
708 }
709 /* Process Unlocked */
710 __HAL_UNLOCK(hdcmi);
711
712 /* Return function status */
713 return HAL_OK;
714 }
715
716 /**
717 * @brief Handles DCMI interrupt request.
718 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
719 * the configuration information for the DCMI.
720 * @retval None
721 */
HAL_DCMI_IRQHandler(DCMI_HandleTypeDef * hdcmi)722 void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
723 {
724 uint32_t isr_value = READ_REG(hdcmi->Instance->MISR);
725
726 /* Synchronization error interrupt management *******************************/
727 if ((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI)
728 {
729 /* Clear the Synchronization error flag */
730 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);
731
732 /* Update error code */
733 hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;
734
735 /* Change DCMI state */
736 hdcmi->State = HAL_DCMI_STATE_ERROR;
737
738 /* Set the synchronization error callback */
739 hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
740
741 /* Abort the DMA Transfer */
742 if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK)
743 {
744 DCMI_DMAError(hdcmi->DMA_Handle);
745 }
746 }
747 /* Overflow interrupt management ********************************************/
748 if ((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI)
749 {
750 /* Clear the Overflow flag */
751 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);
752
753 /* Update error code */
754 hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;
755
756 /* Change DCMI state */
757 hdcmi->State = HAL_DCMI_STATE_ERROR;
758
759 /* Set the overflow callback */
760 hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
761
762 /* Abort the DMA Transfer */
763 if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK)
764 {
765 DCMI_DMAError(hdcmi->DMA_Handle);
766 }
767 }
768 /* Line Interrupt management ************************************************/
769 if ((isr_value & DCMI_FLAG_LINERI) == DCMI_FLAG_LINERI)
770 {
771 /* Clear the Line interrupt flag */
772 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI);
773
774 /* Line interrupt Callback */
775 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
776 /*Call registered DCMI line event callback*/
777 hdcmi->LineEventCallback(hdcmi);
778 #else
779 HAL_DCMI_LineEventCallback(hdcmi);
780 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
781 }
782 /* VSYNC interrupt management ***********************************************/
783 if ((isr_value & DCMI_FLAG_VSYNCRI) == DCMI_FLAG_VSYNCRI)
784 {
785 /* Clear the VSYNC flag */
786 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI);
787
788 /* VSYNC Callback */
789 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
790 /*Call registered DCMI vsync event callback*/
791 hdcmi->VsyncEventCallback(hdcmi);
792 #else
793 HAL_DCMI_VsyncEventCallback(hdcmi);
794 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
795 }
796 /* FRAME interrupt management ***********************************************/
797 if ((isr_value & DCMI_FLAG_FRAMERI) == DCMI_FLAG_FRAMERI)
798 {
799 /* When snapshot mode, disable Vsync, Error and Overrun interrupts */
800 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
801 {
802 /* Disable the Line, Vsync, Error and Overrun interrupts */
803 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
804 }
805
806 /* Disable the Frame interrupt */
807 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME);
808
809 /* Clear the End of Frame flag */
810 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
811
812 /* Frame Callback */
813 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
814 /*Call registered DCMI frame event callback*/
815 hdcmi->FrameEventCallback(hdcmi);
816 #else
817 HAL_DCMI_FrameEventCallback(hdcmi);
818 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
819 }
820 }
821
822 /**
823 * @brief Error DCMI callback.
824 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
825 * the configuration information for DCMI.
826 * @retval None
827 */
HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef * hdcmi)828 __weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
829 {
830 /* Prevent unused argument(s) compilation warning */
831 UNUSED(hdcmi);
832
833 /* NOTE : This function Should not be modified, when the callback is needed,
834 the HAL_DCMI_ErrorCallback could be implemented in the user file
835 */
836 }
837
838 /**
839 * @brief Line Event callback.
840 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
841 * the configuration information for DCMI.
842 * @retval None
843 */
HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef * hdcmi)844 __weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
845 {
846 /* Prevent unused argument(s) compilation warning */
847 UNUSED(hdcmi);
848 /* NOTE : This function Should not be modified, when the callback is needed,
849 the HAL_DCMI_LineEventCallback could be implemented in the user file
850 */
851 }
852
853 /**
854 * @brief VSYNC Event callback.
855 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
856 * the configuration information for DCMI.
857 * @retval None
858 */
HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef * hdcmi)859 __weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
860 {
861 /* Prevent unused argument(s) compilation warning */
862 UNUSED(hdcmi);
863
864 /* NOTE : This function Should not be modified, when the callback is needed,
865 the HAL_DCMI_VsyncEventCallback could be implemented in the user file
866 */
867 }
868
869 /**
870 * @brief Frame Event callback.
871 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
872 * the configuration information for DCMI.
873 * @retval None
874 */
HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef * hdcmi)875 __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
876 {
877 /* Prevent unused argument(s) compilation warning */
878 UNUSED(hdcmi);
879
880 /* NOTE : This function Should not be modified, when the callback is needed,
881 the HAL_DCMI_FrameEventCallback could be implemented in the user file
882 */
883 }
884
885 /**
886 * @}
887 */
888
889 /** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions
890 * @brief Peripheral Control functions
891 *
892 @verbatim
893 ===============================================================================
894 ##### Peripheral Control functions #####
895 ===============================================================================
896 [..] This section provides functions allowing to:
897 (+) Configure the CROP feature.
898 (+) Enable/Disable the CROP feature.
899 (+) Set embedded synchronization delimiters unmasks.
900
901 @endverbatim
902 * @{
903 */
904
905 /**
906 * @brief Configure the DCMI CROP coordinate.
907 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
908 * the configuration information for DCMI.
909 * @param YSize DCMI Line number
910 * @param XSize DCMI Pixel per line
911 * @param X0 DCMI window X offset
912 * @param Y0 DCMI window Y offset
913 * @retval HAL status
914 */
HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef * hdcmi,uint32_t X0,uint32_t Y0,uint32_t XSize,uint32_t YSize)915 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize,
916 uint32_t YSize)
917 {
918 /* Process Locked */
919 __HAL_LOCK(hdcmi);
920
921 /* Lock the DCMI peripheral state */
922 hdcmi->State = HAL_DCMI_STATE_BUSY;
923
924 /* Check the parameters */
925 assert_param(IS_DCMI_WINDOW_COORDINATE(X0));
926 assert_param(IS_DCMI_WINDOW_HEIGHT(Y0));
927 assert_param(IS_DCMI_WINDOW_COORDINATE(XSize));
928 assert_param(IS_DCMI_WINDOW_COORDINATE(YSize));
929
930 /* Configure CROP */
931 hdcmi->Instance->CWSIZER = (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos));
932 hdcmi->Instance->CWSTRTR = (X0 | (Y0 << DCMI_CWSTRT_VST_Pos));
933
934 /* Initialize the DCMI state*/
935 hdcmi->State = HAL_DCMI_STATE_READY;
936
937 /* Process Unlocked */
938 __HAL_UNLOCK(hdcmi);
939
940 return HAL_OK;
941 }
942
943 /**
944 * @brief Disable the Crop feature.
945 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
946 * the configuration information for DCMI.
947 * @retval HAL status
948 */
HAL_DCMI_DisableCrop(DCMI_HandleTypeDef * hdcmi)949 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
950 {
951 /* Process Locked */
952 __HAL_LOCK(hdcmi);
953
954 /* Lock the DCMI peripheral state */
955 hdcmi->State = HAL_DCMI_STATE_BUSY;
956
957 /* Disable DCMI Crop feature */
958 hdcmi->Instance->CR &= ~(uint32_t)DCMI_CR_CROP;
959
960 /* Change the DCMI state*/
961 hdcmi->State = HAL_DCMI_STATE_READY;
962
963 /* Process Unlocked */
964 __HAL_UNLOCK(hdcmi);
965
966 return HAL_OK;
967 }
968
969 /**
970 * @brief Enable the Crop feature.
971 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
972 * the configuration information for DCMI.
973 * @retval HAL status
974 */
HAL_DCMI_EnableCrop(DCMI_HandleTypeDef * hdcmi)975 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
976 {
977 /* Process Locked */
978 __HAL_LOCK(hdcmi);
979
980 /* Lock the DCMI peripheral state */
981 hdcmi->State = HAL_DCMI_STATE_BUSY;
982
983 /* Enable DCMI Crop feature */
984 hdcmi->Instance->CR |= (uint32_t)DCMI_CR_CROP;
985
986 /* Change the DCMI state*/
987 hdcmi->State = HAL_DCMI_STATE_READY;
988
989 /* Process Unlocked */
990 __HAL_UNLOCK(hdcmi);
991
992 return HAL_OK;
993 }
994
995 /**
996 * @brief Set embedded synchronization delimiters unmasks.
997 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
998 * the configuration information for DCMI.
999 * @param SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains
1000 * the embedded synchronization delimiters unmasks.
1001 * @retval HAL status
1002 */
HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef * hdcmi,DCMI_SyncUnmaskTypeDef * SyncUnmask)1003 HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask)
1004 {
1005 /* Process Locked */
1006 __HAL_LOCK(hdcmi);
1007
1008 /* Lock the DCMI peripheral state */
1009 hdcmi->State = HAL_DCMI_STATE_BUSY;
1010
1011 /* Write DCMI embedded synchronization unmask register */
1012 hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) | \
1013 ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos) | \
1014 ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos) | \
1015 ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos));
1016
1017 /* Change the DCMI state*/
1018 hdcmi->State = HAL_DCMI_STATE_READY;
1019
1020 /* Process Unlocked */
1021 __HAL_UNLOCK(hdcmi);
1022
1023 return HAL_OK;
1024 }
1025
1026 /**
1027 * @}
1028 */
1029
1030 /** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions
1031 * @brief Peripheral State functions
1032 *
1033 @verbatim
1034 ===============================================================================
1035 ##### Peripheral State and Errors functions #####
1036 ===============================================================================
1037 [..]
1038 This subsection provides functions allowing to
1039 (+) Check the DCMI state.
1040 (+) Get the specific DCMI error flag.
1041
1042 @endverbatim
1043 * @{
1044 */
1045
1046 /**
1047 * @brief Return the DCMI state
1048 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
1049 * the configuration information for DCMI.
1050 * @retval HAL state
1051 */
HAL_DCMI_GetState(const DCMI_HandleTypeDef * hdcmi)1052 HAL_DCMI_StateTypeDef HAL_DCMI_GetState(const DCMI_HandleTypeDef *hdcmi)
1053 {
1054 return hdcmi->State;
1055 }
1056
1057 /**
1058 * @brief Return the DCMI error code
1059 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
1060 * the configuration information for DCMI.
1061 * @retval DCMI Error Code
1062 */
HAL_DCMI_GetError(const DCMI_HandleTypeDef * hdcmi)1063 uint32_t HAL_DCMI_GetError(const DCMI_HandleTypeDef *hdcmi)
1064 {
1065 return hdcmi->ErrorCode;
1066 }
1067
1068 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1069 /**
1070 * @brief Register a User DCMI Callback
1071 * To be used instead of the weak predefined callback
1072 * @param hdcmi DCMI handle
1073 * @param CallbackID ID of the callback to be registered
1074 * This parameter can be one of the following values:
1075 * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
1076 * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
1077 * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
1078 * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
1079 * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
1080 * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
1081 * @param pCallback pointer to the Callback function
1082 * @retval HAL status
1083 */
HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef * hdcmi,HAL_DCMI_CallbackIDTypeDef CallbackID,pDCMI_CallbackTypeDef pCallback)1084 HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID,
1085 pDCMI_CallbackTypeDef pCallback)
1086 {
1087 HAL_StatusTypeDef status = HAL_OK;
1088
1089 if (pCallback == NULL)
1090 {
1091 /* update the error code */
1092 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1093 /* update return status */
1094 status = HAL_ERROR;
1095 }
1096 else
1097 {
1098 if (hdcmi->State == HAL_DCMI_STATE_READY)
1099 {
1100 switch (CallbackID)
1101 {
1102 case HAL_DCMI_FRAME_EVENT_CB_ID :
1103 hdcmi->FrameEventCallback = pCallback;
1104 break;
1105
1106 case HAL_DCMI_VSYNC_EVENT_CB_ID :
1107 hdcmi->VsyncEventCallback = pCallback;
1108 break;
1109
1110 case HAL_DCMI_LINE_EVENT_CB_ID :
1111 hdcmi->LineEventCallback = pCallback;
1112 break;
1113
1114 case HAL_DCMI_ERROR_CB_ID :
1115 hdcmi->ErrorCallback = pCallback;
1116 break;
1117
1118 case HAL_DCMI_MSPINIT_CB_ID :
1119 hdcmi->MspInitCallback = pCallback;
1120 break;
1121
1122 case HAL_DCMI_MSPDEINIT_CB_ID :
1123 hdcmi->MspDeInitCallback = pCallback;
1124 break;
1125
1126 default :
1127 /* Return error status */
1128 status = HAL_ERROR;
1129 break;
1130 }
1131 }
1132 else if (hdcmi->State == HAL_DCMI_STATE_RESET)
1133 {
1134 switch (CallbackID)
1135 {
1136 case HAL_DCMI_MSPINIT_CB_ID :
1137 hdcmi->MspInitCallback = pCallback;
1138 break;
1139
1140 case HAL_DCMI_MSPDEINIT_CB_ID :
1141 hdcmi->MspDeInitCallback = pCallback;
1142 break;
1143
1144 default :
1145 /* update the error code */
1146 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1147 /* update return status */
1148 status = HAL_ERROR;
1149 break;
1150 }
1151 }
1152 else
1153 {
1154 /* update the error code */
1155 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1156 /* update return status */
1157 status = HAL_ERROR;
1158 }
1159 }
1160
1161 return status;
1162 }
1163
1164 /**
1165 * @brief Unregister a DCMI Callback
1166 * DCMI callback is redirected to the weak predefined callback
1167 * @param hdcmi DCMI handle
1168 * @param CallbackID ID of the callback to be registered
1169 * This parameter can be one of the following values:
1170 * @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
1171 * @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
1172 * @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
1173 * @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
1174 * @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
1175 * @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
1176 * @retval HAL status
1177 */
HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef * hdcmi,HAL_DCMI_CallbackIDTypeDef CallbackID)1178 HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID)
1179 {
1180 HAL_StatusTypeDef status = HAL_OK;
1181
1182 if (hdcmi->State == HAL_DCMI_STATE_READY)
1183 {
1184 switch (CallbackID)
1185 {
1186 case HAL_DCMI_FRAME_EVENT_CB_ID :
1187 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
1188 break;
1189
1190 case HAL_DCMI_VSYNC_EVENT_CB_ID :
1191 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
1192 break;
1193
1194 case HAL_DCMI_LINE_EVENT_CB_ID :
1195 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
1196 break;
1197
1198 case HAL_DCMI_ERROR_CB_ID :
1199 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
1200 break;
1201
1202 case HAL_DCMI_MSPINIT_CB_ID :
1203 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1204 break;
1205
1206 case HAL_DCMI_MSPDEINIT_CB_ID :
1207 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1208 break;
1209
1210 default :
1211 /* update the error code */
1212 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1213 /* update return status */
1214 status = HAL_ERROR;
1215 break;
1216 }
1217 }
1218 else if (hdcmi->State == HAL_DCMI_STATE_RESET)
1219 {
1220 switch (CallbackID)
1221 {
1222 case HAL_DCMI_MSPINIT_CB_ID :
1223 hdcmi->MspInitCallback = HAL_DCMI_MspInit;
1224 break;
1225
1226 case HAL_DCMI_MSPDEINIT_CB_ID :
1227 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
1228 break;
1229
1230 default :
1231 /* update the error code */
1232 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1233 /* update return status */
1234 status = HAL_ERROR;
1235 break;
1236 }
1237 }
1238 else
1239 {
1240 /* update the error code */
1241 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1242 /* update return status */
1243 status = HAL_ERROR;
1244 }
1245
1246 return status;
1247 }
1248 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1249
1250 /**
1251 * @}
1252 */
1253
1254 /**
1255 * @}
1256 */
1257
1258 /* Private functions ---------------------------------------------------------*/
1259 /** @defgroup DCMI_Private_Functions DCMI Private Functions
1260 * @{
1261 */
1262 /**
1263 * @brief DMA conversion complete callback.
1264 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1265 * the configuration information for the specified DMA module.
1266 * @retval None
1267 */
DCMI_DMAXferCplt(DMA_HandleTypeDef * hdma)1268 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
1269 {
1270
1271 DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1272 uint32_t tmp1;
1273 uint32_t tmp2;
1274 DMA_NodeTypeDef *pnode;
1275 uint32_t pbuff;
1276 uint32_t transfernumber;
1277 uint32_t transfercount;
1278 uint32_t transfersize ;
1279
1280 /* Update Nodes destinations */
1281 if (hdcmi->XferSize != 0U)
1282 {
1283 pbuff = hdcmi->pBuffPtr;
1284 transfernumber = hdcmi->XferTransferNumber;
1285 transfercount = hdcmi->XferCount;
1286 transfersize = hdcmi->XferSize;
1287
1288 tmp1 = hdcmi->DMA_Handle->Instance->CLLR & DMA_CLLR_LA;
1289 tmp2 = hdcmi->DMA_Handle->Instance->CLBAR & DMA_CLBAR_LBA;
1290 pnode = (DMA_NodeTypeDef *)(uint32_t)(tmp1 | tmp2);
1291
1292 if (hdcmi->XferCount > 1U)
1293 {
1294 pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pbuff + ((transfernumber - transfercount + 2U) * transfersize);
1295 hdcmi->XferCount--;
1296 }
1297
1298 else if (hdcmi->XferCount == 1U)
1299 {
1300 pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = hdcmi->pBuffPtr;
1301 hdcmi->XferCount--;
1302 }
1303 else
1304 {
1305 pnode->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = hdcmi->pBuffPtr + hdcmi->XferSize;
1306
1307 /* When Continuous mode, re-set dcmi XferCount */
1308 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_CONTINUOUS)
1309 {
1310 hdcmi->XferCount = hdcmi->XferTransferNumber ;
1311 }
1312 /* When snapshot mode, set dcmi state to ready */
1313 else
1314 {
1315 hdcmi->State = HAL_DCMI_STATE_READY;
1316 }
1317
1318 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
1319 }
1320 }
1321 else /* Snapshot Mode */
1322 {
1323 /* Enable the Frame interrupt */
1324 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
1325
1326 /* When snapshot mode, set dcmi state to ready */
1327 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
1328 {
1329 hdcmi->State = HAL_DCMI_STATE_READY;
1330 }
1331 }
1332 }
1333
1334 /**
1335 * @brief DMA error callback
1336 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1337 * the configuration information for the specified DMA module.
1338 * @retval None
1339 */
DCMI_DMAError(DMA_HandleTypeDef * hdma)1340 static void DCMI_DMAError(DMA_HandleTypeDef *hdma)
1341 {
1342 DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1343
1344 if (hdcmi->DMA_Handle->ErrorCode != HAL_DMA_ERROR_ULE)
1345 {
1346 /* Initialize the DCMI state*/
1347 hdcmi->State = HAL_DCMI_STATE_READY;
1348
1349 /* Set DCMI Error Code */
1350 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1351 }
1352
1353 /* DCMI error Callback */
1354 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1355 /*Call registered DCMI error callback*/
1356 hdcmi->ErrorCallback(hdcmi);
1357 #else
1358 HAL_DCMI_ErrorCallback(hdcmi);
1359 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1360
1361 }
1362
1363 /**
1364 * @}
1365 */
1366 #endif /* DCMI */
1367 #endif /* HAL_DCMI_MODULE_ENABLED */
1368 /**
1369 * @}
1370 */
1371
1372 /**
1373 * @}
1374 */
1375