STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_dcmi.c 00004 * @author MCD Application Team 00005 * @brief DCMI HAL module driver 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Digital Camera Interface (DCMI) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + Peripheral State and Error functions 00012 * 00013 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2017 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 ============================================================================== 00026 ##### How to use this driver ##### 00027 ============================================================================== 00028 [..] 00029 The sequence below describes how to use this driver to capture images 00030 from a camera module connected to the DCMI Interface. 00031 This sequence does not take into account the configuration of the 00032 camera module, which should be made before configuring and enabling 00033 the DCMI to capture images. 00034 00035 (#) Program the required configuration through the following parameters: 00036 horizontal and vertical polarity, pixel clock polarity, capture rate, 00037 synchronization mode, frame delimiter codes, data width, byte and line 00038 selection using HAL_DCMI_Init() function. 00039 00040 (#) Optionally select JPEG mode; in that case, only the polarity 00041 and the capture mode parameters need to be set. 00042 00043 (#) Capture mode can be either snapshot or continuous mode. 00044 00045 (#) Configure the DMA_Handle to transfer data from DCMI DR 00046 register to the destination memory buffer. 00047 00048 -@- In snapshot mode, the interface transfers a single frame through DMA. In 00049 continuous mode, the DMA must be set in circular mode to ensure a continuous 00050 flow of images data samples. 00051 00052 (#) Program the transfer configuration through the following parameters: 00053 DCMI mode, destination memory buffer address and data length then 00054 enable capture using HAL_DCMI_Start_DMA() function. 00055 00056 (#) Whether in continuous or snapshot mode, data length parameter must be 00057 equal to the frame size. 00058 00059 (#) When the frame size is unknown beforehand (e.g. JPEG case), data length must 00060 be large enough to ensure the capture of a frame. 00061 00062 (#) If the frame size is larger than the maximum DMA transfer length (i.e. 65535), 00063 (++) the DMA must be configured in circular mode, either for snapshot or continuous 00064 capture mode, 00065 (++) during capture, the driver copies the image data samples from DCMI DR register 00066 at the end of the final destination buffer used as a work buffer, 00067 (++) at each DMA half (respectively complete) transfer interrupt, the first 00068 (resp. second) half of the work buffer is copied to the final destination thru 00069 a second DMA channel. 00070 (++) Parameters of this second DMA channel are contained in the memory to memory DMA 00071 handle "DMAM2M_Handle", itself field of the DCMI handle structure. 00072 (++) This memory to memory transfer has length half that of the work buffer and is 00073 carried out in normal mode (not in circular mode). 00074 00075 (#) Optionally, configure and enable the CROP feature to select a 00076 rectangular window from the received image using HAL_DCMI_ConfigCrop() 00077 and HAL_DCMI_EnableCrop() functions. Use HAL_DCMI_DisableCrop() to 00078 disable this feature. 00079 00080 (#) The capture can be stopped with HAL_DCMI_Stop() function. 00081 00082 (#) To control the DCMI state, use the function HAL_DCMI_GetState(). 00083 00084 (#) To read the DCMI error code, use the function HAL_DCMI_GetError(). 00085 00086 [..] 00087 (@) When the frame size is less than the maximum DMA transfer length (i.e. 65535) 00088 and when in snapshot mode, user must make sure the FRAME interrupt is disabled. 00089 This allows to avoid corner cases where the FRAME interrupt might be triggered 00090 before the DMA transfer completion interrupt. In this specific configuration, 00091 the driver checks the FRAME capture flag after the DMA transfer end and calls 00092 HAL_DCMI_FrameEventCallback() if the flag is set. 00093 00094 *** DCMI HAL driver macros list *** 00095 ============================================= 00096 [..] 00097 Below the list of most used macros in DCMI HAL driver. 00098 00099 (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral. 00100 (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral. 00101 (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags. 00102 (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags. 00103 (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts. 00104 (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts. 00105 (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not. 00106 00107 *** Callback registration *** 00108 ============================= 00109 00110 The compilation define USE_HAL_DCMI_REGISTER_CALLBACKS when set to 1 00111 allows the user to configure dynamically the driver callbacks. 00112 Use functions @ref HAL_DCMI_RegisterCallback() to register a user callback. 00113 00114 Function @ref HAL_DCMI_RegisterCallback() allows to register following callbacks: 00115 (+) FrameEventCallback : DCMI Frame Event. 00116 (+) VsyncEventCallback : DCMI Vsync Event. 00117 (+) LineEventCallback : DCMI Line Event. 00118 (+) ErrorCallback : DCMI error. 00119 (+) MspInitCallback : DCMI MspInit. 00120 (+) MspDeInitCallback : DCMI MspDeInit. 00121 This function takes as parameters the HAL peripheral handle, the callback ID 00122 and a pointer to the user callback function. 00123 00124 Use function @ref HAL_DCMI_UnRegisterCallback() to reset a callback to the default 00125 weak (surcharged) function. 00126 @ref HAL_DCMI_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00127 and the callback ID. 00128 This function allows to reset following callbacks: 00129 (+) FrameEventCallback : DCMI Frame Event. 00130 (+) VsyncEventCallback : DCMI Vsync Event. 00131 (+) LineEventCallback : DCMI Line Event. 00132 (+) ErrorCallback : DCMI error. 00133 (+) MspInitCallback : DCMI MspInit. 00134 (+) MspDeInitCallback : DCMI MspDeInit. 00135 00136 By default, after the @ref HAL_DCMI_Init and if the state is HAL_DCMI_STATE_RESET 00137 all callbacks are reset to the corresponding legacy weak (surcharged) functions: 00138 examples @ref FrameEventCallback(), @ref HAL_DCMI_ErrorCallback(). 00139 Exception done for MspInit and MspDeInit callbacks that are respectively 00140 reset to the legacy weak (surcharged) functions in the @ref HAL_DCMI_Init 00141 and @ref HAL_DCMI_DeInit only when these callbacks are null (not registered beforehand). 00142 If not, MspInit or MspDeInit are not null, the @ref HAL_DCMI_Init and @ref HAL_DCMI_DeInit 00143 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00144 00145 Callbacks can be registered/unregistered in READY state only. 00146 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00147 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00148 during the Init/DeInit. 00149 In that case first register the MspInit/MspDeInit user callbacks 00150 using @ref HAL_DCMI_RegisterCallback before calling @ref HAL_DCMI_DeInit 00151 or @ref HAL_DCMI_Init function. 00152 00153 When the compilation define USE_HAL_DCMI_REGISTER_CALLBACKS is set to 0 or 00154 not defined, the callback registering feature is not available 00155 and weak (surcharged) callbacks are used. 00156 00157 @endverbatim 00158 ****************************************************************************** 00159 */ 00160 00161 /* Includes ------------------------------------------------------------------*/ 00162 #include "stm32l4xx_hal.h" 00163 00164 #ifdef HAL_DCMI_MODULE_ENABLED 00165 #if defined (DCMI) 00166 00167 /** @addtogroup STM32L4xx_HAL_Driver 00168 * @{ 00169 */ 00170 /** @defgroup DCMI DCMI 00171 * @brief DCMI HAL module driver 00172 * @{ 00173 */ 00174 00175 /* Private typedef -----------------------------------------------------------*/ 00176 /* Private define ------------------------------------------------------------*/ 00177 /** @defgroup DCMI_Private_Constants DCMI Private Constants 00178 * @{ 00179 */ 00180 00181 /** @defgroup DCMI_Stop_TimeOut DCMI Stop TimeOut 00182 * @{ 00183 */ 00184 #define DCMI_TIMEOUT_STOP ((uint32_t)1000U) /*!< 1s */ 00185 /** 00186 * @} 00187 */ 00188 00189 #define NPRIME 16U 00190 00191 /** 00192 * @} 00193 */ 00194 /* Private macro -------------------------------------------------------------*/ 00195 /* Private variables ---------------------------------------------------------*/ 00196 /* Private function prototypes -----------------------------------------------*/ 00197 /** @addtogroup DCMI_Private_Functions DCMI Private Functions 00198 * @{ 00199 */ 00200 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma); 00201 static void DCMI_DMAHalfXferCplt(DMA_HandleTypeDef *hdma); 00202 static void DCMI_DMAError(DMA_HandleTypeDef *hdma); 00203 static uint32_t DCMI_TransferSize(uint32_t InputSize); 00204 /** 00205 * @} 00206 */ 00207 /* Exported functions --------------------------------------------------------*/ 00208 00209 /** @defgroup DCMI_Exported_Functions DCMI Exported Functions 00210 * @{ 00211 */ 00212 00213 /** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions 00214 * @brief Initialization and Configuration functions 00215 * 00216 @verbatim 00217 =============================================================================== 00218 ##### Initialization and Configuration functions ##### 00219 =============================================================================== 00220 [..] This section provides functions allowing to: 00221 (+) Initialize and configure the DCMI 00222 (+) De-initialize the DCMI 00223 00224 @endverbatim 00225 * @{ 00226 */ 00227 00228 /** 00229 * @brief Initialize the DCMI according to the specified 00230 * parameters in the DCMI_InitTypeDef and create the associated handle. 00231 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00232 * the configuration information for DCMI. 00233 * @note By default, all interruptions are enabled (line end, frame end, overrun, 00234 * VSYNC and embedded synchronization error interrupts). 00235 * @retval HAL status 00236 */ 00237 HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi) 00238 { 00239 /* Check the DCMI peripheral state */ 00240 if(hdcmi == NULL) 00241 { 00242 return HAL_ERROR; 00243 } 00244 00245 /* Check function parameters */ 00246 assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance)); 00247 assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode)); 00248 assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity)); 00249 assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity)); 00250 assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity)); 00251 assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate)); 00252 assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode)); 00253 assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode)); 00254 00255 assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode)); 00256 assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart)); 00257 assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode)); 00258 assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart)); 00259 00260 if(hdcmi->State == HAL_DCMI_STATE_RESET) 00261 { 00262 /* Allocate lock resource and initialize it */ 00263 hdcmi->Lock = HAL_UNLOCKED; 00264 00265 /* Init the DCMI Callback settings */ 00266 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 00267 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */ 00268 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */ 00269 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */ 00270 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */ 00271 00272 if(hdcmi->MspInitCallback == NULL) 00273 { 00274 /* Legacy weak MspInit Callback */ 00275 hdcmi->MspInitCallback = HAL_DCMI_MspInit; 00276 } 00277 /* Initialize the low level hardware (MSP) */ 00278 hdcmi->MspInitCallback(hdcmi); 00279 #else 00280 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ 00281 HAL_DCMI_MspInit(hdcmi); 00282 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */ 00283 } 00284 00285 /* Change the DCMI state */ 00286 hdcmi->State = HAL_DCMI_STATE_BUSY; 00287 00288 /* Disable DCMI IP before setting the configuration register */ 00289 __HAL_DCMI_DISABLE(hdcmi); 00290 00291 if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B) 00292 { 00293 /* Byte select mode must be programmed to the reset value if the extended mode 00294 is not set to 8-bit data capture on every pixel clock */ 00295 hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL; 00296 } 00297 00298 /* Set DCMI parameters */ 00299 hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 |\ 00300 DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG |\ 00301 DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS |\ 00302 DCMI_CR_LSM | DCMI_CR_OELS); 00303 00304 hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate |\ 00305 hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity |\ 00306 hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode |\ 00307 hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode |\ 00308 hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode |\ 00309 hdcmi->Init.LineSelectStart); 00310 00311 if(hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED) 00312 { 00313 hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SynchroCode.FrameStartCode) |\ 00314 ((uint32_t)hdcmi->Init.SynchroCode.LineStartCode << DCMI_ESCR_LSC_Pos)|\ 00315 ((uint32_t)hdcmi->Init.SynchroCode.LineEndCode << DCMI_ESCR_LEC_Pos) |\ 00316 ((uint32_t)hdcmi->Init.SynchroCode.FrameEndCode << DCMI_ESCR_FEC_Pos)); 00317 } 00318 00319 /* By default, enable all interrupts. The user may disable the unwanted ones 00320 in resorting to __HAL_DCMI_DISABLE_IT() macro before invoking HAL_DCMI_Start_DMA(). 00321 Enabled interruptions are 00322 - end of line 00323 - end of frame 00324 - data reception overrun 00325 - frame synchronization signal VSYNC 00326 - synchronization error */ 00327 __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME|DCMI_IT_OVR|DCMI_IT_ERR|DCMI_IT_VSYNC|DCMI_IT_LINE); 00328 00329 /* Update error code */ 00330 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; 00331 00332 /* Initialize the DCMI state*/ 00333 hdcmi->State = HAL_DCMI_STATE_READY; 00334 00335 return HAL_OK; 00336 } 00337 00338 /** 00339 * @brief De-initialize the DCMI peripheral, reset control registers to 00340 * their default values. 00341 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00342 * the configuration information for DCMI. 00343 * @retval HAL status 00344 */ 00345 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi) 00346 { 00347 /* Before aborting any DCMI transfer, check 00348 first whether or not DCMI clock is enabled */ 00349 if (__HAL_RCC_DCMI_IS_CLK_ENABLED()) 00350 { 00351 if (HAL_DCMI_Stop(hdcmi) != HAL_OK) 00352 { 00353 /* Issue when stopping DCMI IP */ 00354 return HAL_ERROR; 00355 } 00356 } 00357 00358 /* Reset DCMI control register */ 00359 hdcmi->Instance->CR = 0; 00360 00361 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 00362 if(hdcmi->MspDeInitCallback == NULL) 00363 { 00364 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; 00365 } 00366 /* De-Initialize the low level hardware (MSP) */ 00367 hdcmi->MspDeInitCallback(hdcmi); 00368 #else 00369 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ 00370 HAL_DCMI_MspDeInit(hdcmi); 00371 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */ 00372 00373 /* Update error code */ 00374 hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; 00375 00376 /* Initialize the DCMI state*/ 00377 hdcmi->State = HAL_DCMI_STATE_RESET; 00378 00379 /* Release Lock */ 00380 __HAL_UNLOCK(hdcmi); 00381 00382 return HAL_OK; 00383 } 00384 00385 /** 00386 * @brief Initialize the DCMI MSP. 00387 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00388 * the configuration information for DCMI. 00389 * @retval None 00390 */ 00391 __weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi) 00392 { 00393 /* Prevent unused argument(s) compilation warning */ 00394 UNUSED(hdcmi); 00395 00396 /* NOTE : This function should not be modified; when the callback is needed, 00397 the HAL_DCMI_MspInit() callback can be implemented in the user file 00398 */ 00399 } 00400 00401 /** 00402 * @brief De-initialize the DCMI MSP. 00403 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00404 * the configuration information for DCMI. 00405 * @retval None 00406 */ 00407 __weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi) 00408 { 00409 /* Prevent unused argument(s) compilation warning */ 00410 UNUSED(hdcmi); 00411 00412 /* NOTE : This function should not be modified; when the callback is needed, 00413 the HAL_DCMI_MspDeInit() callback can be implemented in the user file 00414 */ 00415 } 00416 00417 /** 00418 * @} 00419 */ 00420 00421 /** @defgroup DCMI_Exported_Functions_Group2 IO operation functions 00422 * @brief IO operation functions 00423 * 00424 @verbatim 00425 =============================================================================== 00426 ##### IO operation functions ##### 00427 =============================================================================== 00428 [..] This section provides functions allowing to: 00429 (+) Configure destination address and data length, 00430 enable DCMI DMA request and DCMI capture. 00431 (+) Stop DCMI capture. 00432 (+) Handle DCMI interrupt request. 00433 00434 [..] A set of callbacks is provided: 00435 (+) HAL_DCMI_ErrorCallback() 00436 (+) HAL_DCMI_LineEventCallback() 00437 (+) HAL_DCMI_VsyncEventCallback() 00438 (+) HAL_DCMI_FrameEventCallback() 00439 00440 00441 @endverbatim 00442 * @{ 00443 */ 00444 00445 /** 00446 * @brief Enable DCMI capture in DMA mode. 00447 * @param hdcmi Pointer to a DCMI_HandleTypeDef structure that contains 00448 * the configuration information for DCMI. 00449 * @param DCMI_Mode DCMI capture mode snapshot or continuous grab. 00450 * @param pData The destination memory buffer address. 00451 * @param Length The length of capture to be transferred (in 32-bit words). 00452 * @note In case of length larger than 65535 (0xFFFF is the DMA maximum transfer length), 00453 * the API uses the end of the destination buffer as a work area: HAL_DCMI_Start_DMA() 00454 * initiates a circular DMA transfer from DCMI DR to the ad-hoc work buffer and each 00455 * half and complete transfer interrupt triggers a copy from the work buffer to 00456 * the final destination pData thru a second DMA channel. 00457 * @note Following HAL_DCMI_Init() call, all interruptions are enabled (line end, 00458 * frame end, overrun, VSYNC and embedded synchronization error interrupts). 00459 * User can disable unwanted interrupts thru __HAL_DCMI_DISABLE_IT() macro 00460 * before invoking HAL_DCMI_Start_DMA(). 00461 * @note For length less than 0xFFFF (DMA maximum transfer length) and in snapshot mode, 00462 * frame interrupt is disabled before DMA transfer. FRAME capture flag is checked 00463 * in DCMI_DMAXferCplt callback at the end of the DMA transfer. If flag is set, 00464 * HAL_DCMI_FrameEventCallback() API is called. 00465 * @retval HAL status 00466 */ 00467 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length) 00468 { 00469 uint32_t circular_copy_length; 00470 00471 /* Check capture parameter */ 00472 assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode)); 00473 00474 /* Process Locked */ 00475 __HAL_LOCK(hdcmi); 00476 00477 /* Lock the DCMI peripheral state */ 00478 hdcmi->State = HAL_DCMI_STATE_BUSY; 00479 00480 /* Configure the DCMI Mode and enable the DCMI IP at the same time */ 00481 MODIFY_REG(hdcmi->Instance->CR, (DCMI_CR_CM|DCMI_CR_ENABLE), (DCMI_Mode|DCMI_CR_ENABLE)); 00482 00483 /* Set the DMA conversion complete callback */ 00484 hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt; 00485 00486 /* Set the DMA error callback */ 00487 hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError; 00488 00489 /* Set the dma abort callback */ 00490 hdcmi->DMA_Handle->XferAbortCallback = NULL; 00491 00492 if(Length <= 0xFFFFU) 00493 { 00494 hdcmi->XferCount = 0; /* Mark as direct transfer from DCMI_DR register to final destination buffer */ 00495 00496 /* Enable the DMA channel */ 00497 if (HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length) != HAL_OK) 00498 { 00499 /* Update error code */ 00500 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; 00501 00502 /* Set state back to Ready */ 00503 hdcmi->State = HAL_DCMI_STATE_READY; 00504 00505 /* Process Unlocked */ 00506 __HAL_UNLOCK(hdcmi); 00507 00508 return HAL_ERROR; 00509 } 00510 } 00511 else /* Capture length is longer than DMA maximum transfer size */ 00512 { 00513 /* Set DMA in circular mode */ 00514 hdcmi->DMA_Handle->Init.Mode = DMA_CIRCULAR; 00515 00516 /* Set the DMA half transfer complete callback */ 00517 hdcmi->DMA_Handle->XferHalfCpltCallback = DCMI_DMAHalfXferCplt; 00518 00519 /* Initialize transfer parameters */ 00520 hdcmi->XferSize = Length; /* Store the complete transfer length in DCMI handle */ 00521 hdcmi->pBuffPtr = pData; /* Final destination buffer pointer */ 00522 00523 circular_copy_length = DCMI_TransferSize(Length); 00524 00525 /* Check if issue in intermediate length computation */ 00526 if (circular_copy_length == 0U) 00527 { 00528 /* Set state back to Ready */ 00529 hdcmi->State = HAL_DCMI_STATE_READY; 00530 00531 /* Process Unlocked */ 00532 __HAL_UNLOCK(hdcmi); 00533 00534 return HAL_ERROR; 00535 } 00536 00537 /* Store the number of half - intermediate buffer copies needed */ 00538 hdcmi->XferCount = 2U * ((Length / circular_copy_length) - 1U); 00539 /* Store the half-buffer copy length */ 00540 hdcmi->HalfCopyLength = circular_copy_length / 2U; 00541 00542 /* Save initial values for continuous mode case */ 00543 hdcmi->XferCount_0 = hdcmi->XferCount; 00544 hdcmi->XferSize_0 = hdcmi->XferSize; 00545 hdcmi->pBuffPtr_0 = hdcmi->pBuffPtr; 00546 00547 /* DCMI DR samples in circular mode will be copied 00548 at the end of the final buffer. 00549 Now compute the circular buffer start address. */ 00550 /* Start by pointing at the final buffer */ 00551 hdcmi->pCircularBuffer = pData; 00552 /* Update pCircularBuffer in "moving" at the end of the final 00553 buffer, don't forger to convert in bytes to compute exact address */ 00554 hdcmi->pCircularBuffer += 4U * (((Length / circular_copy_length) - 1U) * circular_copy_length); 00555 00556 /* Initiate the circular DMA transfer from DCMI IP to final buffer end */ 00557 if ( HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)hdcmi->pCircularBuffer, circular_copy_length) != HAL_OK) 00558 { 00559 /* Update error code */ 00560 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; 00561 00562 /* Set state back to Ready */ 00563 hdcmi->State = HAL_DCMI_STATE_READY; 00564 00565 /* Process Unlocked */ 00566 __HAL_UNLOCK(hdcmi); 00567 00568 return HAL_ERROR; 00569 } 00570 } 00571 00572 /* Enable Capture */ 00573 SET_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE); 00574 00575 /* Release Lock */ 00576 __HAL_UNLOCK(hdcmi); 00577 00578 /* Return function status */ 00579 return HAL_OK; 00580 } 00581 00582 /** 00583 * @brief Disable DCMI capture in DMA mode. 00584 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00585 * the configuration information for DCMI. 00586 * @retval HAL status 00587 */ 00588 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef* hdcmi) 00589 { 00590 uint32_t tickstart; 00591 HAL_StatusTypeDef status = HAL_OK; 00592 00593 /* Process locked */ 00594 __HAL_LOCK(hdcmi); 00595 00596 /* Lock the DCMI peripheral state */ 00597 hdcmi->State = HAL_DCMI_STATE_BUSY; 00598 00599 /* Disable Capture */ 00600 CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE); 00601 00602 /* Get tick */ 00603 tickstart = HAL_GetTick(); 00604 00605 /* Check if the DCMI capture is effectively disabled */ 00606 while((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U) 00607 { 00608 if((HAL_GetTick() - tickstart ) > DCMI_TIMEOUT_STOP) 00609 { 00610 /* Update error code */ 00611 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT; 00612 00613 status = HAL_TIMEOUT; 00614 break; 00615 } 00616 } 00617 00618 /* Disable the DMA */ 00619 if (HAL_DMA_Abort(hdcmi->DMA_Handle) != HAL_OK) 00620 { 00621 DCMI_DMAError(hdcmi->DMA_Handle); 00622 } 00623 00624 /* Disable DCMI IP */ 00625 __HAL_DCMI_DISABLE(hdcmi); 00626 00627 /* Change DCMI state */ 00628 hdcmi->State = HAL_DCMI_STATE_READY; 00629 00630 /* Process Unlocked */ 00631 __HAL_UNLOCK(hdcmi); 00632 00633 /* Return function status */ 00634 return status; 00635 } 00636 00637 /** 00638 * @brief Suspend DCMI capture. 00639 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00640 * the configuration information for DCMI. 00641 * @retval HAL status 00642 */ 00643 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef* hdcmi) 00644 { 00645 uint32_t tickstart; 00646 00647 /* Process locked */ 00648 __HAL_LOCK(hdcmi); 00649 00650 if(hdcmi->State == HAL_DCMI_STATE_BUSY) 00651 { 00652 /* Change DCMI state */ 00653 hdcmi->State = HAL_DCMI_STATE_SUSPENDED; 00654 00655 /* Disable Capture */ 00656 CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE); 00657 00658 /* Get tick */ 00659 tickstart = HAL_GetTick(); 00660 00661 /* Check if the DCMI capture is effectively disabled */ 00662 while((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U) 00663 { 00664 if((HAL_GetTick() - tickstart ) > DCMI_TIMEOUT_STOP) 00665 { 00666 /* Update error code */ 00667 hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT; 00668 00669 /* Change DCMI state */ 00670 hdcmi->State = HAL_DCMI_STATE_READY; 00671 00672 /* Process Unlocked */ 00673 __HAL_UNLOCK(hdcmi); 00674 00675 return HAL_TIMEOUT; 00676 } 00677 } 00678 } 00679 00680 /* Process Unlocked */ 00681 __HAL_UNLOCK(hdcmi); 00682 00683 /* Return function status */ 00684 return HAL_OK; 00685 } 00686 00687 /** 00688 * @brief Resume DCMI capture. 00689 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00690 * the configuration information for DCMI. 00691 * @retval HAL status 00692 */ 00693 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef* hdcmi) 00694 { 00695 /* Process locked */ 00696 __HAL_LOCK(hdcmi); 00697 00698 if(hdcmi->State == HAL_DCMI_STATE_SUSPENDED) 00699 { 00700 /* Change DCMI state */ 00701 hdcmi->State = HAL_DCMI_STATE_BUSY; 00702 00703 /* Enable Capture */ 00704 SET_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE); 00705 } 00706 00707 /* Process Unlocked */ 00708 __HAL_UNLOCK(hdcmi); 00709 00710 return HAL_OK; 00711 } 00712 00713 /** 00714 * @brief Handle DCMI interrupt request. 00715 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00716 * the configuration information for the DCMI. 00717 * @retval None 00718 */ 00719 void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi) 00720 { 00721 uint32_t misflags = READ_REG(hdcmi->Instance->MISR); 00722 00723 /* Synchronization error interrupt management *******************************/ 00724 if ((misflags & DCMI_MIS_ERR_MIS) != 0x0U) 00725 { 00726 /* Clear the Synchronization error flag */ 00727 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI); 00728 00729 /* Update error code */ 00730 hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC; 00731 } 00732 00733 /* Overflow interrupt management ********************************************/ 00734 if ((misflags & DCMI_MIS_OVR_MIS) != 0x0U) 00735 { 00736 /* Clear the Overflow flag */ 00737 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI); 00738 00739 /* Update error code */ 00740 hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR; 00741 } 00742 00743 if (hdcmi->ErrorCode != HAL_DCMI_ERROR_NONE) 00744 { 00745 /* Change DCMI state */ 00746 hdcmi->State = HAL_DCMI_STATE_READY; 00747 00748 /* Set the overflow callback */ 00749 hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError; 00750 00751 /* Abort the DMA Transfer */ 00752 if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK) 00753 { 00754 DCMI_DMAError(hdcmi->DMA_Handle); 00755 } 00756 } 00757 00758 /* Line Interrupt management ************************************************/ 00759 if ((misflags & DCMI_MIS_LINE_MIS) != 0x0U) 00760 { 00761 /* Clear the Line interrupt flag */ 00762 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI); 00763 00764 /* Line interrupt Event Callback */ 00765 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 00766 /*Call registered DCMI line event callback*/ 00767 hdcmi->LineEventCallback(hdcmi); 00768 #else 00769 HAL_DCMI_LineEventCallback(hdcmi); 00770 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 00771 } 00772 00773 /* VSYNC interrupt management ***********************************************/ 00774 if ((misflags & DCMI_MIS_VSYNC_MIS) != 0x0U) 00775 { 00776 /* Clear the VSYNC flag */ 00777 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI); 00778 00779 /* VSYNC Event Callback */ 00780 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 00781 /*Call registered DCMI vsync event callback*/ 00782 hdcmi->VsyncEventCallback(hdcmi); 00783 #else 00784 HAL_DCMI_VsyncEventCallback(hdcmi); 00785 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 00786 } 00787 00788 /* End of Frame interrupt management ****************************************/ 00789 if ((misflags & DCMI_MIS_FRAME_MIS) != 0x0U) 00790 { 00791 /* Disable the Line interrupt when using snapshot mode */ 00792 if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT) 00793 { 00794 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE|DCMI_IT_VSYNC|DCMI_IT_ERR|DCMI_IT_OVR); 00795 /* Change the DCMI state */ 00796 hdcmi->State = HAL_DCMI_STATE_READY; 00797 } 00798 00799 /* Clear the End of Frame flag */ 00800 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI); 00801 00802 /* Frame Event Callback */ 00803 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 00804 /*Call registered DCMI frame event callback*/ 00805 hdcmi->FrameEventCallback(hdcmi); 00806 #else 00807 HAL_DCMI_FrameEventCallback(hdcmi); 00808 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 00809 } 00810 } 00811 00812 /** 00813 * @brief Error DCMI callback. 00814 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00815 * the configuration information for DCMI. 00816 * @retval None 00817 */ 00818 __weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi) 00819 { 00820 /* Prevent unused argument(s) compilation warning */ 00821 UNUSED(hdcmi); 00822 00823 /* NOTE : This function should not be modified; when the callback is needed, 00824 the HAL_DCMI_ErrorCallback() callback can be implemented in the user file. 00825 */ 00826 } 00827 00828 /** 00829 * @brief Line Event callback. 00830 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00831 * the configuration information for DCMI. 00832 * @retval None 00833 */ 00834 __weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi) 00835 { 00836 /* Prevent unused argument(s) compilation warning */ 00837 UNUSED(hdcmi); 00838 00839 /* NOTE : This function should not be modified; when the callback is needed, 00840 the HAL_DCMI_LineEventCallback() callback can be implemented in the user file. 00841 */ 00842 } 00843 00844 /** 00845 * @brief VSYNC Event callback. 00846 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00847 * the configuration information for DCMI. 00848 * @retval None 00849 */ 00850 __weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi) 00851 { 00852 /* Prevent unused argument(s) compilation warning */ 00853 UNUSED(hdcmi); 00854 00855 /* NOTE : This function should not be modified; when the callback is needed, 00856 the HAL_DCMI_VsyncEventCallback() callback can be implemented in the user file. 00857 */ 00858 } 00859 00860 /** 00861 * @brief Frame Event callback. 00862 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00863 * the configuration information for DCMI. 00864 * @retval None 00865 */ 00866 __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) 00867 { 00868 /* Prevent unused argument(s) compilation warning */ 00869 UNUSED(hdcmi); 00870 00871 /* NOTE : This function should not be modified; when the callback is needed, 00872 the HAL_DCMI_FrameEventCallback() callback can be implemented in the user file. 00873 */ 00874 } 00875 /** 00876 * @} 00877 */ 00878 00879 00880 /** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions 00881 * @brief Peripheral Control functions 00882 * 00883 @verbatim 00884 =============================================================================== 00885 ##### Peripheral Control functions ##### 00886 =============================================================================== 00887 [..] This section provides functions allowing to: 00888 (+) Configure the crop feature. 00889 (+) Enable/Disable the crop feature. 00890 (+) Configure the synchronization delimiters unmasks. 00891 (+) Enable/Disable user-specified DCMI interrupts. 00892 00893 @endverbatim 00894 * @{ 00895 */ 00896 00897 /** 00898 * @brief Configure the DCMI crop window coordinates. 00899 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00900 * the configuration information for DCMI. 00901 * @param X0 DCMI window crop window X offset (number of pixels clocks to count before the capture). 00902 * @param Y0 DCMI window crop window Y offset (image capture starts with this line number, previous 00903 * line data are ignored). 00904 * @param XSize DCMI crop window horizontal size (in number of pixels per line). 00905 * @param YSize DCMI crop window vertical size (in lines count). 00906 * @note For all the parameters, the actual value is the input data + 1 (e.g. YSize = 0x0 means 1 line, 00907 * YSize = 0x1 means 2 lines, ...) 00908 * @retval HAL status 00909 */ 00910 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize) 00911 { 00912 /* Check the parameters */ 00913 assert_param(IS_DCMI_WINDOW_COORDINATE(X0)); 00914 assert_param(IS_DCMI_WINDOW_HEIGHT(Y0)); 00915 assert_param(IS_DCMI_WINDOW_COORDINATE(XSize)); 00916 assert_param(IS_DCMI_WINDOW_COORDINATE(YSize)); 00917 00918 /* Process Locked */ 00919 __HAL_LOCK(hdcmi); 00920 00921 /* Lock the DCMI peripheral state */ 00922 hdcmi->State = HAL_DCMI_STATE_BUSY; 00923 00924 /* Configure CROP */ 00925 MODIFY_REG(hdcmi->Instance->CWSIZER, (DCMI_CWSIZE_VLINE|DCMI_CWSIZE_CAPCNT), (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos))); 00926 MODIFY_REG(hdcmi->Instance->CWSTRTR, (DCMI_CWSTRT_VST|DCMI_CWSTRT_HOFFCNT), (X0 | (Y0 << DCMI_CWSTRT_VST_Pos))); 00927 00928 /* Initialize the DCMI state*/ 00929 hdcmi->State = HAL_DCMI_STATE_READY; 00930 00931 /* Process Unlocked */ 00932 __HAL_UNLOCK(hdcmi); 00933 00934 return HAL_OK; 00935 } 00936 00937 /** 00938 * @brief Disable the crop feature. 00939 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00940 * the configuration information for DCMI. 00941 * @retval HAL status 00942 */ 00943 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi) 00944 { 00945 /* Process Locked */ 00946 __HAL_LOCK(hdcmi); 00947 00948 /* Lock the DCMI peripheral state */ 00949 hdcmi->State = HAL_DCMI_STATE_BUSY; 00950 00951 /* Disable DCMI Crop feature */ 00952 CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CROP); 00953 00954 /* Change the DCMI state*/ 00955 hdcmi->State = HAL_DCMI_STATE_READY; 00956 00957 /* Process Unlocked */ 00958 __HAL_UNLOCK(hdcmi); 00959 00960 return HAL_OK; 00961 } 00962 00963 /** 00964 * @brief Enable the crop feature. 00965 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00966 * the configuration information for DCMI. 00967 * @retval HAL status 00968 */ 00969 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi) 00970 { 00971 /* Process Locked */ 00972 __HAL_LOCK(hdcmi); 00973 00974 /* Lock the DCMI peripheral state */ 00975 hdcmi->State = HAL_DCMI_STATE_BUSY; 00976 00977 /* Enable DCMI Crop feature */ 00978 SET_BIT(hdcmi->Instance->CR, DCMI_CR_CROP); 00979 00980 /* Change the DCMI state*/ 00981 hdcmi->State = HAL_DCMI_STATE_READY; 00982 00983 /* Process Unlocked */ 00984 __HAL_UNLOCK(hdcmi); 00985 00986 return HAL_OK; 00987 } 00988 00989 /** 00990 * @brief Set embedded synchronization delimiters unmasks. 00991 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 00992 * the configuration information for DCMI. 00993 * @param SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains 00994 * the embedded synchronization delimiters unmasks. 00995 * @retval HAL status 00996 */ 00997 HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask) 00998 { 00999 /* Process Locked */ 01000 __HAL_LOCK(hdcmi); 01001 01002 /* Lock the DCMI peripheral state */ 01003 hdcmi->State = HAL_DCMI_STATE_BUSY; 01004 01005 /* Write DCMI embedded synchronization unmask register */ 01006 hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) |\ 01007 ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos)|\ 01008 ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos)|\ 01009 ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos)); 01010 01011 /* Change the DCMI state*/ 01012 hdcmi->State = HAL_DCMI_STATE_READY; 01013 01014 /* Process Unlocked */ 01015 __HAL_UNLOCK(hdcmi); 01016 01017 return HAL_OK; 01018 } 01019 01020 01021 01022 01023 /** 01024 * @} 01025 */ 01026 01027 /** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions 01028 * @brief Peripheral State functions 01029 * 01030 @verbatim 01031 =============================================================================== 01032 ##### Peripheral State and Errors functions ##### 01033 =============================================================================== 01034 [..] 01035 This subsection provides functions allowing to 01036 (+) Check the DCMI state. 01037 (+) Get the specific DCMI error flag. 01038 01039 @endverbatim 01040 * @{ 01041 */ 01042 01043 /** 01044 * @brief Return the DCMI state. 01045 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 01046 * the configuration information for DCMI. 01047 * @retval HAL state 01048 */ 01049 HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi) 01050 { 01051 return hdcmi->State; 01052 } 01053 01054 /** 01055 * @brief Return the DCMI error code. 01056 * @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains 01057 * the configuration information for DCMI. 01058 * @retval DCMI Error Code 01059 */ 01060 uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi) 01061 { 01062 return hdcmi->ErrorCode; 01063 } 01064 01065 /** 01066 * @} 01067 */ 01068 01069 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 01070 /** 01071 * @brief DCMI Callback registering 01072 * @param hdcmi dcmi handle 01073 * @param CallbackID dcmi Callback ID 01074 * @param pCallback pointer to dcmi Callback function 01075 * @retval status 01076 */ 01077 HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, pDCMI_CallbackTypeDef pCallback) 01078 { 01079 HAL_StatusTypeDef status = HAL_OK; 01080 01081 if(pCallback == NULL) 01082 { 01083 /* update the error code */ 01084 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01085 /* update return status */ 01086 status = HAL_ERROR; 01087 } 01088 else 01089 { 01090 if(hdcmi->State == HAL_DCMI_STATE_READY) 01091 { 01092 switch (CallbackID) 01093 { 01094 case HAL_DCMI_FRAME_EVENT_CB_ID : 01095 hdcmi->FrameEventCallback = pCallback; 01096 break; 01097 01098 case HAL_DCMI_VSYNC_EVENT_CB_ID : 01099 hdcmi->VsyncEventCallback = pCallback; 01100 break; 01101 01102 case HAL_DCMI_LINE_EVENT_CB_ID : 01103 hdcmi->LineEventCallback = pCallback; 01104 break; 01105 01106 case HAL_DCMI_ERROR_CB_ID : 01107 hdcmi->ErrorCallback = pCallback; 01108 break; 01109 01110 case HAL_DCMI_MSPINIT_CB_ID : 01111 hdcmi->MspInitCallback = pCallback; 01112 break; 01113 01114 case HAL_DCMI_MSPDEINIT_CB_ID : 01115 hdcmi->MspDeInitCallback = pCallback; 01116 break; 01117 01118 default : 01119 /* Return error status */ 01120 status = HAL_ERROR; 01121 break; 01122 } 01123 } 01124 else if(hdcmi->State == HAL_DCMI_STATE_RESET) 01125 { 01126 switch (CallbackID) 01127 { 01128 case HAL_DCMI_MSPINIT_CB_ID : 01129 hdcmi->MspInitCallback = pCallback; 01130 break; 01131 01132 case HAL_DCMI_MSPDEINIT_CB_ID : 01133 hdcmi->MspDeInitCallback = pCallback; 01134 break; 01135 01136 default : 01137 /* update the error code */ 01138 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01139 /* update return status */ 01140 status = HAL_ERROR; 01141 break; 01142 } 01143 } 01144 else 01145 { 01146 /* update the error code */ 01147 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01148 /* update return status */ 01149 status = HAL_ERROR; 01150 } 01151 } 01152 01153 return status; 01154 } 01155 01156 /** 01157 * @brief DCMI Callback Unregistering 01158 * @param hdcmi dcmi handle 01159 * @param CallbackID dcmi Callback ID 01160 * @retval status 01161 */ 01162 HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID) 01163 { 01164 HAL_StatusTypeDef status = HAL_OK; 01165 01166 if(hdcmi->State == HAL_DCMI_STATE_READY) 01167 { 01168 switch (CallbackID) 01169 { 01170 case HAL_DCMI_FRAME_EVENT_CB_ID : 01171 hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */ 01172 break; 01173 01174 case HAL_DCMI_VSYNC_EVENT_CB_ID : 01175 hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */ 01176 break; 01177 01178 case HAL_DCMI_LINE_EVENT_CB_ID : 01179 hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */ 01180 break; 01181 01182 case HAL_DCMI_ERROR_CB_ID : 01183 hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */ 01184 break; 01185 01186 case HAL_DCMI_MSPINIT_CB_ID : 01187 hdcmi->MspInitCallback = HAL_DCMI_MspInit; 01188 break; 01189 01190 case HAL_DCMI_MSPDEINIT_CB_ID : 01191 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; 01192 break; 01193 01194 default : 01195 /* update the error code */ 01196 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01197 /* update return status */ 01198 status = HAL_ERROR; 01199 break; 01200 } 01201 } 01202 else if(hdcmi->State == HAL_DCMI_STATE_RESET) 01203 { 01204 switch (CallbackID) 01205 { 01206 case HAL_DCMI_MSPINIT_CB_ID : 01207 hdcmi->MspInitCallback = HAL_DCMI_MspInit; 01208 break; 01209 01210 case HAL_DCMI_MSPDEINIT_CB_ID : 01211 hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit; 01212 break; 01213 01214 default : 01215 /* update the error code */ 01216 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01217 /* update return status */ 01218 status = HAL_ERROR; 01219 break; 01220 } 01221 } 01222 else 01223 { 01224 /* update the error code */ 01225 hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK; 01226 /* update return status */ 01227 status = HAL_ERROR; 01228 } 01229 01230 return status; 01231 } 01232 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 01233 01234 /** 01235 * @} 01236 */ 01237 01238 /* Private functions ---------------------------------------------------------*/ 01239 /** @defgroup DCMI_Private_Functions DCMI Private Functions 01240 * @{ 01241 */ 01242 01243 /** 01244 * @brief DMA conversion complete callback. 01245 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01246 * the configuration information for the specified DMA module. 01247 * @note When the size of the frame being captured by the DCMI peripheral is 01248 * larger than 0xFFFF (DMA maximum transfer length), this API initiates 01249 * another DMA transfer to copy the second half of the work buffer 01250 * associated to the DCMI handle to the final destination buffer. 01251 * @retval None 01252 */ 01253 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma) 01254 { 01255 uint32_t loop_length; /* transfer length */ 01256 uint32_t * tmpBuffer_Dest; 01257 uint32_t * tmpBuffer_Orig; 01258 uint32_t temp; 01259 01260 DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01261 01262 01263 if(hdcmi->XferCount != 0U) 01264 { 01265 if (hdcmi->XferCount == 0xBEBE) 01266 { 01267 hdcmi->XferCount = hdcmi->XferCount_0; 01268 hdcmi->XferSize = hdcmi->XferSize_0; 01269 hdcmi->pBuffPtr = hdcmi->pBuffPtr_0; 01270 } 01271 else 01272 { 01273 /* Manage second half buffer copy in case of big transfer */ 01274 01275 /* Decrement half-copies counter */ 01276 hdcmi->XferCount--; 01277 01278 /* Point at DCMI final destination */ 01279 tmpBuffer_Dest = (uint32_t *)hdcmi->pBuffPtr; 01280 01281 /* Point at DCMI circular buffer mid-location */ 01282 tmpBuffer_Orig = (uint32_t *)hdcmi->pCircularBuffer; 01283 temp = (uint32_t) (tmpBuffer_Orig); 01284 temp += hdcmi->HalfCopyLength * 4U; 01285 tmpBuffer_Orig = (uint32_t *) temp; 01286 01287 /* copy half the buffer size */ 01288 loop_length = hdcmi->HalfCopyLength; 01289 01290 /* Save next entry to write at next half DMA transfer interruption */ 01291 hdcmi->pBuffPtr += (uint32_t) loop_length*4U; 01292 hdcmi->XferSize -= hdcmi->HalfCopyLength; 01293 01294 if (hdcmi->XferCount == 0) 01295 { 01296 hdcmi->XferCount = 0xBEBE; 01297 } 01298 01299 01300 /* Data copy from work buffer to final destination buffer */ 01301 /* Enable the DMA Channel */ 01302 if (HAL_DMA_Start_IT(hdcmi->DMAM2M_Handle, (uint32_t) tmpBuffer_Orig, (uint32_t) tmpBuffer_Dest, loop_length) != HAL_OK) 01303 { 01304 /* Update error code */ 01305 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; 01306 01307 /* Change DCMI state */ 01308 hdcmi->State = HAL_DCMI_STATE_READY; 01309 01310 /* Process Unlocked */ 01311 __HAL_UNLOCK(hdcmi); 01312 01313 /* DCMI error Callback */ 01314 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 01315 /*Call registered DCMI error callback*/ 01316 hdcmi->ErrorCallback(hdcmi); 01317 #else 01318 HAL_DCMI_ErrorCallback(hdcmi); 01319 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 01320 } 01321 } 01322 } 01323 else 01324 { 01325 /* if End of frame IT is disabled */ 01326 if((hdcmi->Instance->IER & DCMI_IT_FRAME) == 0x0U) 01327 { 01328 /* If End of Frame flag is set */ 01329 if(__HAL_DCMI_GET_FLAG(hdcmi, (uint32_t)DCMI_FLAG_FRAMERI) != 0x0UL) 01330 { 01331 /* Clear the End of Frame flag */ 01332 __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI); 01333 01334 /* When snapshot mode, disable Vsync, Error and Overrun interrupts */ 01335 if((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT) 01336 { 01337 /* Disable the Vsync, Error and Overrun interrupts */ 01338 __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR); 01339 01340 hdcmi->State = HAL_DCMI_STATE_READY; 01341 01342 /* Process Unlocked */ 01343 __HAL_UNLOCK(hdcmi); 01344 } 01345 01346 /* Frame Event Callback */ 01347 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 01348 /*Call registered DCMI frame event callback*/ 01349 hdcmi->FrameEventCallback(hdcmi); 01350 #else 01351 HAL_DCMI_FrameEventCallback(hdcmi); 01352 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 01353 } 01354 } 01355 } 01356 } 01357 01358 01359 /** 01360 * @brief DMA Half Transfer complete callback. 01361 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01362 * the configuration information for the specified DMA module. 01363 * @note When the size of the frame being captured by the DCMI peripheral is 01364 * larger than 0xFFFF (DMA maximum transfer length), this API initiates 01365 * another DMA transfer to copy the first half of the work buffer 01366 * associated to the DCMI handle to the final destination buffer. 01367 * @retval None 01368 */ 01369 static void DCMI_DMAHalfXferCplt(DMA_HandleTypeDef *hdma) 01370 { 01371 uint32_t loop_length; /* transfer length */ 01372 uint32_t * tmpBuffer_Dest; 01373 uint32_t * tmpBuffer_Orig; 01374 01375 DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01376 01377 if(hdcmi->XferCount != 0U) 01378 { 01379 if (hdcmi->XferCount != 0xBEBE) 01380 { 01381 /* Manage first half buffer copy in case of big transfer */ 01382 01383 /* Decrement half-copies counter */ 01384 hdcmi->XferCount--; 01385 01386 /* Point at DCMI final destination */ 01387 tmpBuffer_Dest = (uint32_t *)hdcmi->pBuffPtr; 01388 01389 /* Point at DCMI circular buffer start */ 01390 tmpBuffer_Orig = (uint32_t *)hdcmi->pCircularBuffer; 01391 01392 /* copy half the buffer size */ 01393 loop_length = hdcmi->HalfCopyLength; 01394 01395 /* Save next entry to write at next DMA transfer interruption */ 01396 hdcmi->pBuffPtr += (uint32_t) loop_length*4U; 01397 hdcmi->XferSize -= hdcmi->HalfCopyLength; 01398 01399 /* Data copy from work buffer to final destination buffer */ 01400 /* Enable the DMA Channel */ 01401 if (HAL_DMA_Start_IT(hdcmi->DMAM2M_Handle, (uint32_t) tmpBuffer_Orig, (uint32_t) tmpBuffer_Dest, loop_length) != HAL_OK) 01402 { 01403 /* Update error code */ 01404 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; 01405 01406 /* Change DCMI state */ 01407 hdcmi->State = HAL_DCMI_STATE_READY; 01408 01409 /* Process Unlocked */ 01410 __HAL_UNLOCK(hdcmi); 01411 01412 /* DCMI error Callback */ 01413 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 01414 /*Call registered DCMI error callback*/ 01415 hdcmi->ErrorCallback(hdcmi); 01416 #else 01417 HAL_DCMI_ErrorCallback(hdcmi); 01418 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 01419 } 01420 } 01421 } 01422 } 01423 01424 /** 01425 * @brief DMA error callback 01426 * @param hdma pointer to a DMA_HandleTypeDef structure that contains 01427 * the configuration information for the specified DMA module. 01428 * @retval None 01429 */ 01430 static void DCMI_DMAError(DMA_HandleTypeDef *hdma) 01431 { 01432 DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01433 01434 /* Update error code */ 01435 hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA; 01436 01437 /* Change DCMI state */ 01438 hdcmi->State = HAL_DCMI_STATE_READY; 01439 01440 /* DCMI error Callback */ 01441 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1) 01442 /*Call registered DCMI error callback*/ 01443 hdcmi->ErrorCallback(hdcmi); 01444 #else 01445 HAL_DCMI_ErrorCallback(hdcmi); 01446 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */ 01447 } 01448 01449 /** 01450 * @brief Sub-buffers transfer size computation. 01451 * @note In the case of a frame size larger than the maximum DMA transfer length (0xFFFF), 01452 * the tranfer from DCMI DR register to the final output buffer is carried out by a sequence 01453 * of intermediate sub-copies to temporary buffers of size less than 0xFFFF. 01454 * To optimize the number of DMA transfers, the API computes the temporary buffer 01455 * size so that the latter is an even number less than 0xFFFF, that divides the final 01456 * buffer size and is as high as possible. The API implements a sub-optimum solution for 01457 * complexity's sake. 01458 * @note InputSize MUST be even. 01459 * @param InputSize full buffer size (in 32-bit words) 01460 * @retval Transfer size (in 32-bit words) 01461 */ 01462 static uint32_t DCMI_TransferSize(uint32_t InputSize) 01463 { 01464 uint32_t j = 1; 01465 uint32_t temp = InputSize; 01466 uint32_t aPrime[NPRIME] = {0}; 01467 uint32_t output = 2; /* Want a result which is an even number */ 01468 static const uint32_t PrimeArray[NPRIME] = { 1UL, 2UL, 3UL, 5UL, 01469 7UL, 11UL, 13UL, 17UL, 01470 19UL, 23UL, 29UL, 31UL, 01471 37UL, 41UL, 43UL, 47UL}; 01472 01473 01474 /* Develop InputSize in product of prime numbers */ 01475 01476 while (j < NPRIME) 01477 { 01478 if (temp < PrimeArray[j]) 01479 { 01480 break; 01481 } 01482 while ((temp % PrimeArray[j]) == 0U) 01483 { 01484 aPrime[j]++; 01485 temp /= PrimeArray[j]; 01486 } 01487 j++; 01488 } 01489 01490 /* Search for the biggest even divisor less or equal to 0xFFFE = 65534 */ 01491 aPrime[1] -= 1U; /* output is initialized to 2, so don't count dividor 2 twice */ 01492 01493 /* The algorithm below yields a sub-optimal solution 01494 but in an acceptable time. */ 01495 j = NPRIME-1U; 01496 while ((j > 0U) && (output <= 0xFFFEU)) 01497 { 01498 while (aPrime[j] > 0U) 01499 { 01500 if ((output * PrimeArray[j]) > 0xFFFEU) 01501 { 01502 break; 01503 } 01504 else 01505 { 01506 output *= PrimeArray[j]; 01507 aPrime[j]--; 01508 } 01509 } 01510 j--; 01511 } 01512 01513 01514 01515 return output; 01516 } 01517 01518 01519 /** 01520 * @} 01521 */ 01522 01523 /** 01524 * @} 01525 */ 01526 01527 /** 01528 * @} 01529 */ 01530 01531 #endif /* DCMI */ 01532 #endif /* HAL_DCMI_MODULE_ENABLED */