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