STM32H735xx HAL User Manual
stm32h7xx_hal_dcmi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_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 image
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 to configure and enable
00033       the DCMI to capture images.
00034 
00035     (#) Program the required configuration through following parameters:
00036         horizontal and vertical polarity, pixel clock polarity, Capture Rate,
00037         Synchronization Mode, code of the frame delimiter and data width
00038         using HAL_DCMI_Init() function.
00039 
00040     (#) Configure the selected DMA stream to transfer Data from DCMI DR
00041         register to the destination memory buffer.
00042 
00043     (#) Program the required configuration through following parameters:
00044         DCMI mode, destination memory Buffer address and the data length
00045         and enable capture using HAL_DCMI_Start_DMA() function.
00046 
00047     (#) Optionally, configure and Enable the CROP feature to select a rectangular
00048         window from the received image using HAL_DCMI_ConfigCrop()
00049         and HAL_DCMI_EnableCrop() functions
00050 
00051     (#) The capture can be stopped using HAL_DCMI_Stop() function.
00052 
00053     (#) To control DCMI state you can use the function HAL_DCMI_GetState().
00054 
00055      *** Callback registration ***
00056      =============================================
00057 
00058      The compilation flag USE_HAL_DCMI_REGISTER_CALLBACKS when set to 1
00059      allows the user to configure dynamically the driver callbacks.
00060      Use Functions HAL_DCMI_RegisterCallback() to register an interrupt callback.
00061 
00062      Function HAL_DCMI_RegisterCallback() allows to register following callbacks:
00063        (+) LineEventCallback    : callback for DCMI line event.
00064        (+) FrameEventCallback   : callback for DCMI Frame event.
00065        (+) VsyncEventCallback   : callback for DCMI Vsync event.
00066        (+) ErrorCallback        : callback for error detection.
00067        (+) MspInitCallback      : callback for Msp Init.
00068        (+) MspDeInitCallback    : callback for Msp DeInit.
00069      This function takes as parameters the HAL peripheral handle, the Callback ID
00070      and a pointer to the user callback function.
00071 
00072      Use function HAL_DCMI_UnRegisterCallback to reset a callback to the default weak function.
00073      HAL_DCMI_UnRegisterCallback takes as parameters the HAL peripheral handle and the Callback ID.
00074      This function allows to reset following callbacks:
00075        (+) LineEventCallback    : callback for DCMI line event.
00076        (+) FrameEventCallback   : callback for DCMI Frame event.
00077        (+) VsyncEventCallback   : callback for DCMI Vsync event.
00078        (+) ErrorCallback        : callback for error detection.
00079        (+) MspInitCallback      : callback for Msp Init.
00080        (+) MspDeInitCallback    : callback for Msp DeInit.
00081 
00082      By default, after the HAL_DCMI_Init() and when the state is HAL_DCMI_STATE_RESET
00083      all callbacks are set to the corresponding weak functions:
00084      examples HAL_DCMI_LineEventCallback(), HAL_DCMI_FrameEventCallback().
00085      Exception done for MspInit and MspDeInit functions that are
00086      reset to the legacy weak functions in the HAL_DCMI_Init()/ HAL_DCMI_DeInit() only when
00087      these callbacks are null (not registered beforehand).
00088      If MspInit or MspDeInit are not null, the HAL_DCMI_Init()/ HAL_DCMI_DeInit()
00089      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00090 
00091      Callbacks can be registered/unregistered in HAL_DCMI_STATE_READY state only.
00092      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00093      in HAL_DCMI_STATE_READY or HAL_DCMI_STATE_RESET state,
00094      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00095      In that case first register the MspInit/MspDeInit user callbacks
00096      using HAL_DCMI_RegisterCallback() before calling HAL_DCMI_DeInit() or HAL_DCMI_Init() function.
00097 
00098      When the compilation flag USE_HAL_DCMI_REGISTER_CALLBACKS is set to 0 or
00099      not defined, the callback registration feature is not available and all callbacks
00100      are set to the corresponding weak functions.
00101 
00102      *** DCMI HAL driver macros list ***
00103      =============================================
00104      [..]
00105        Below the list of most used macros in DCMI HAL driver.
00106 
00107       (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral.
00108       (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral.
00109       (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags.
00110       (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags.
00111       (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts.
00112       (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts.
00113       (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not.
00114 
00115      [..]
00116        (@) You can refer to the DCMI HAL driver header file for more useful macros
00117 
00118   @endverbatim
00119   */
00120 
00121 /* Includes ------------------------------------------------------------------*/
00122 #include "stm32h7xx_hal.h"
00123 
00124 /** @addtogroup STM32H7xx_HAL_Driver
00125   * @{
00126   */
00127 /** @defgroup DCMI DCMI
00128   * @brief DCMI HAL module driver
00129   * @{
00130   */
00131 
00132 #ifdef HAL_DCMI_MODULE_ENABLED
00133 #if defined (DCMI)
00134 
00135 /* Private typedef -----------------------------------------------------------*/
00136 /* Private define ------------------------------------------------------------*/
00137 #define HAL_TIMEOUT_DCMI_STOP    ((uint32_t)1000) /* Set timeout to 1s  */
00138 
00139 /* Private macro -------------------------------------------------------------*/
00140 /* Private variables ---------------------------------------------------------*/
00141 /* Private function prototypes -----------------------------------------------*/
00142 static void       DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma);
00143 static void       DCMI_DMAError(DMA_HandleTypeDef *hdma);
00144 
00145 /* Exported functions --------------------------------------------------------*/
00146 
00147 /** @defgroup DCMI_Exported_Functions DCMI Exported Functions
00148   * @{
00149   */
00150 
00151 /** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions
00152  *  @brief   Initialization and Configuration functions
00153  *
00154 @verbatim
00155  ===============================================================================
00156                 ##### Initialization and Configuration functions #####
00157  ===============================================================================
00158     [..]  This section provides functions allowing to:
00159       (+) Initialize and configure the DCMI
00160       (+) De-initialize the DCMI
00161 
00162 @endverbatim
00163   * @{
00164   */
00165 
00166 /**
00167   * @brief  Initializes the DCMI according to the specified
00168   *         parameters in the DCMI_InitTypeDef and create the associated handle.
00169   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00170   *                the configuration information for DCMI.
00171   * @retval HAL status
00172   */
00173 HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
00174 {
00175   /* Check the DCMI peripheral state */
00176   if (hdcmi == NULL)
00177   {
00178     return HAL_ERROR;
00179   }
00180 
00181   /* Check function parameters */
00182   assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance));
00183   assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity));
00184   assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity));
00185   assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity));
00186   assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode));
00187   assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate));
00188   assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode));
00189   assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode));
00190 
00191   assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode));
00192   assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart));
00193   assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode));
00194   assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart));
00195 
00196   if (hdcmi->State == HAL_DCMI_STATE_RESET)
00197   {
00198     /* Init the DCMI Callback settings */
00199 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00200     /* Reset callback pointers to the weak predefined callbacks */
00201     hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback  */
00202     hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback  */
00203     hdcmi->LineEventCallback  = HAL_DCMI_LineEventCallback;  /* Legacy weak LineEventCallback   */
00204     hdcmi->ErrorCallback      = HAL_DCMI_ErrorCallback;      /* Legacy weak ErrorCallback       */
00205 
00206     if (hdcmi->MspInitCallback == NULL)
00207     {
00208       /* Legacy weak MspInit Callback        */
00209       hdcmi->MspInitCallback = HAL_DCMI_MspInit;
00210     }
00211     /* Initialize the low level hardware (MSP) */
00212     hdcmi->MspInitCallback(hdcmi);
00213 #else
00214     /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
00215     HAL_DCMI_MspInit(hdcmi);
00216 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
00217   }
00218 
00219   /* Change the DCMI state */
00220   hdcmi->State = HAL_DCMI_STATE_BUSY;
00221 
00222   if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B)
00223   {
00224     /* Byte select mode must be programmed to the reset value if the extended mode
00225     is not set to 8-bit data capture on every pixel clock */
00226     hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL;
00227   }
00228   /* Configures the HS, VS, DE and PC polarity */
00229   hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL  | DCMI_CR_VSPOL  | DCMI_CR_EDM_0 | \
00230                            DCMI_CR_EDM_1  | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG  | \
00231                            DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS | \
00232                            DCMI_CR_LSM | DCMI_CR_OELS);
00233 
00234   hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \
00235                                     hdcmi->Init.VSPolarity  | hdcmi->Init.HSPolarity  | \
00236                                     hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \
00237                                     hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode | \
00238                                     hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode | \
00239                                     hdcmi->Init.LineSelectStart);
00240 
00241   if (hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED)
00242   {
00243     hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode)    | \
00244                              ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << DCMI_ESCR_LSC_Pos) | \
00245                              ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << DCMI_ESCR_LEC_Pos) | \
00246                              ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << DCMI_ESCR_FEC_Pos));
00247 
00248   }
00249 
00250   /* Enable the Line, Vsync, Error and Overrun interrupts */
00251   __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
00252 
00253   /* Update error code */
00254   hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
00255 
00256   /* Initialize the DCMI state*/
00257   hdcmi->State  = HAL_DCMI_STATE_READY;
00258 
00259   return HAL_OK;
00260 }
00261 
00262 /**
00263   * @brief  Deinitializes the DCMI peripheral registers to their default reset
00264   *         values.
00265   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00266   *                the configuration information for DCMI.
00267   * @retval HAL status
00268   */
00269 
00270 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
00271 {
00272 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00273   if (hdcmi->MspDeInitCallback == NULL)
00274   {
00275     hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
00276   }
00277   /* De-Initialize the low level hardware (MSP) */
00278   hdcmi->MspDeInitCallback(hdcmi);
00279 #else
00280   /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
00281   HAL_DCMI_MspDeInit(hdcmi);
00282 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
00283 
00284   /* Update error code */
00285   hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
00286 
00287   /* Initialize the DCMI state*/
00288   hdcmi->State = HAL_DCMI_STATE_RESET;
00289 
00290   /* Release Lock */
00291   __HAL_UNLOCK(hdcmi);
00292 
00293   return HAL_OK;
00294 }
00295 
00296 /**
00297   * @brief  Initializes the DCMI MSP.
00298   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00299   *                the configuration information for DCMI.
00300   * @retval None
00301   */
00302 __weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
00303 {
00304   /* Prevent unused argument(s) compilation warning */
00305   UNUSED(hdcmi);
00306 
00307   /* NOTE : This function Should not be modified, when the callback is needed,
00308             the HAL_DCMI_MspInit could be implemented in the user file
00309    */
00310 }
00311 
00312 /**
00313   * @brief  DeInitializes the DCMI MSP.
00314   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00315   *                the configuration information for DCMI.
00316   * @retval None
00317   */
00318 __weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi)
00319 {
00320   /* Prevent unused argument(s) compilation warning */
00321   UNUSED(hdcmi);
00322 
00323   /* NOTE : This function Should not be modified, when the callback is needed,
00324             the HAL_DCMI_MspDeInit could be implemented in the user file
00325    */
00326 }
00327 
00328 /**
00329   * @}
00330   */
00331 /** @defgroup DCMI_Exported_Functions_Group2 IO operation functions
00332  *  @brief   IO operation functions
00333  *
00334 @verbatim
00335  ===============================================================================
00336                       #####  IO operation functions  #####
00337  ===============================================================================
00338     [..]  This section provides functions allowing to:
00339       (+) Configure destination address and data length and
00340           Enables DCMI DMA request and enables DCMI capture
00341       (+) Stop the DCMI capture.
00342       (+) Handles DCMI interrupt request.
00343 
00344 @endverbatim
00345   * @{
00346   */
00347 
00348 /**
00349   * @brief  Enables DCMI DMA request and enables DCMI capture
00350   * @param  hdcmi     pointer to a DCMI_HandleTypeDef structure that contains
00351   *                    the configuration information for DCMI.
00352   * @param  DCMI_Mode DCMI capture mode snapshot or continuous grab.
00353   * @param  pData     The destination memory Buffer address (LCD Frame buffer).
00354   * @param  Length    The length of capture to be transferred.
00355   * @retval HAL status
00356   */
00357 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
00358 {
00359   /* Initialize the second memory address */
00360   uint32_t SecondMemAddress;
00361 
00362   /* Check function parameters */
00363   assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
00364 
00365   /* Process Locked */
00366   __HAL_LOCK(hdcmi);
00367 
00368   /* Lock the DCMI peripheral state */
00369   hdcmi->State = HAL_DCMI_STATE_BUSY;
00370 
00371   /* Enable DCMI by setting DCMIEN bit */
00372   __HAL_DCMI_ENABLE(hdcmi);
00373 
00374   /* Configure the DCMI Mode */
00375   hdcmi->Instance->CR &= ~(DCMI_CR_CM);
00376   hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode);
00377 
00378   /* Set the DMA memory0 conversion complete callback */
00379   hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt;
00380 
00381   /* Set the DMA error callback */
00382   hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;
00383 
00384   /* Set the dma abort callback */
00385   hdcmi->DMA_Handle->XferAbortCallback = NULL;
00386 
00387   /* Reset transfer counters value */
00388   hdcmi->XferCount = 0;
00389   hdcmi->XferTransferNumber = 0;
00390   hdcmi->XferSize = 0;
00391   hdcmi->pBuffPtr = 0;
00392 
00393   if (Length <= 0xFFFFU)
00394   {
00395     /* Enable the DMA Stream */
00396     if (HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length) != HAL_OK)
00397     {
00398       /* Set Error Code */
00399       hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
00400       /* Change DCMI state */
00401       hdcmi->State = HAL_DCMI_STATE_READY;
00402       /* Release Lock */
00403       __HAL_UNLOCK(hdcmi);
00404       /* Return function status */
00405       return HAL_ERROR;
00406     }
00407   }
00408   else /* DCMI_DOUBLE_BUFFER Mode */
00409   {
00410     /* Set the DMA memory1 conversion complete callback */
00411     hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAXferCplt;
00412 
00413     /* Initialize transfer parameters */
00414     hdcmi->XferCount = 1;
00415     hdcmi->XferSize = Length;
00416     hdcmi->pBuffPtr = pData;
00417 
00418     /* Get the number of buffer */
00419     while (hdcmi->XferSize > 0xFFFFU)
00420     {
00421       hdcmi->XferSize = (hdcmi->XferSize / 2U);
00422       hdcmi->XferCount = hdcmi->XferCount * 2U;
00423     }
00424 
00425     /* Update DCMI counter  and transfer number*/
00426     hdcmi->XferCount = (hdcmi->XferCount - 2U);
00427     hdcmi->XferTransferNumber = hdcmi->XferCount;
00428 
00429     /* Update second memory address */
00430     SecondMemAddress = (uint32_t)(pData + (4U * hdcmi->XferSize));
00431 
00432     /* Start DMA multi buffer transfer */
00433     if (HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize) != HAL_OK)
00434     {
00435       /* Set Error Code */
00436       hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
00437       /* Change DCMI state */
00438       hdcmi->State = HAL_DCMI_STATE_READY;
00439       /* Release Lock */
00440       __HAL_UNLOCK(hdcmi);
00441       /* Return function status */
00442       return HAL_ERROR;
00443     }
00444   }
00445 
00446   /* Enable Capture */
00447   hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
00448 
00449   /* Release Lock */
00450   __HAL_UNLOCK(hdcmi);
00451 
00452   /* Return function status */
00453   return HAL_OK;
00454 }
00455 
00456 /**
00457   * @brief  Disable DCMI DMA request and Disable DCMI capture
00458   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00459   *                the configuration information for DCMI.
00460   * @retval HAL status
00461   */
00462 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi)
00463 {
00464   uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
00465   HAL_StatusTypeDef status = HAL_OK;
00466 
00467   /* Process locked */
00468   __HAL_LOCK(hdcmi);
00469 
00470   /* Lock the DCMI peripheral state */
00471   hdcmi->State = HAL_DCMI_STATE_BUSY;
00472 
00473   /* Disable Capture */
00474   hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
00475 
00476   /* Check if the DCMI capture effectively disabled */
00477   do
00478   {
00479     count-- ;
00480     if (count == 0U)
00481     {
00482       /* Update error code */
00483       hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
00484 
00485       status = HAL_TIMEOUT;
00486       break;
00487     }
00488   }
00489   while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
00490 
00491   /* Disable the DCMI */
00492   __HAL_DCMI_DISABLE(hdcmi);
00493 
00494   /* Disable the DMA */
00495   (void)HAL_DMA_Abort(hdcmi->DMA_Handle);
00496 
00497   /* Update error code */
00498   hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE;
00499 
00500   /* Change DCMI state */
00501   hdcmi->State = HAL_DCMI_STATE_READY;
00502 
00503   /* Process Unlocked */
00504   __HAL_UNLOCK(hdcmi);
00505 
00506   /* Return function status */
00507   return status;
00508 }
00509 
00510 /**
00511   * @brief  Suspend DCMI capture
00512   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00513   *                the configuration information for DCMI.
00514   * @retval HAL status
00515   */
00516 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi)
00517 {
00518   uint32_t count = HAL_TIMEOUT_DCMI_STOP * (SystemCoreClock / 8U / 1000U);
00519   HAL_StatusTypeDef status = HAL_OK;
00520 
00521   /* Process locked */
00522   __HAL_LOCK(hdcmi);
00523 
00524   if (hdcmi->State == HAL_DCMI_STATE_BUSY)
00525   {
00526     /* Change DCMI state */
00527     hdcmi->State = HAL_DCMI_STATE_SUSPENDED;
00528 
00529     /* Disable Capture */
00530     hdcmi->Instance->CR &= ~(DCMI_CR_CAPTURE);
00531 
00532     /* Check if the DCMI capture effectively disabled */
00533     do
00534     {
00535       count-- ;
00536       if (count == 0U)
00537       {
00538         /* Update error code */
00539         hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
00540 
00541         /* Change DCMI state */
00542         hdcmi->State = HAL_DCMI_STATE_READY;
00543 
00544         status = HAL_TIMEOUT;
00545         break;
00546       }
00547     }
00548     while ((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U);
00549   }
00550   /* Process Unlocked */
00551   __HAL_UNLOCK(hdcmi);
00552 
00553   /* Return function status */
00554   return status;
00555 }
00556 
00557 /**
00558   * @brief  Resume DCMI capture
00559   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00560   *                the configuration information for DCMI.
00561   * @retval HAL status
00562   */
00563 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi)
00564 {
00565   /* Process locked */
00566   __HAL_LOCK(hdcmi);
00567 
00568   if (hdcmi->State == HAL_DCMI_STATE_SUSPENDED)
00569   {
00570     /* Change DCMI state */
00571     hdcmi->State = HAL_DCMI_STATE_BUSY;
00572 
00573     /* Enable Capture */
00574     hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
00575   }
00576   /* Process Unlocked */
00577   __HAL_UNLOCK(hdcmi);
00578 
00579   /* Return function status */
00580   return HAL_OK;
00581 }
00582 
00583 /**
00584   * @brief  Handles DCMI interrupt request.
00585   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00586   *                the configuration information for the DCMI.
00587   * @retval None
00588   */
00589 void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
00590 {
00591   uint32_t isr_value = READ_REG(hdcmi->Instance->MISR);
00592 
00593   /* Synchronization error interrupt management *******************************/
00594   if ((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI)
00595   {
00596     /* Clear the Synchronization error flag */
00597     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);
00598 
00599     /* Update error code */
00600     hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;
00601 
00602     /* Change DCMI state */
00603     hdcmi->State = HAL_DCMI_STATE_ERROR;
00604 
00605     /* Set the synchronization error callback */
00606     hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
00607 
00608     /* Abort the DMA Transfer */
00609     (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
00610   }
00611   /* Overflow interrupt management ********************************************/
00612   if ((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI)
00613   {
00614     /* Clear the Overflow flag */
00615     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);
00616 
00617     /* Update error code */
00618     hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;
00619 
00620     /* Change DCMI state */
00621     hdcmi->State = HAL_DCMI_STATE_ERROR;
00622 
00623     /* Set the overflow callback */
00624     hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;
00625 
00626     /* Abort the DMA Transfer */
00627     (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
00628   }
00629   /* Line Interrupt management ************************************************/
00630   if ((isr_value & DCMI_FLAG_LINERI) == DCMI_FLAG_LINERI)
00631   {
00632     /* Clear the Line interrupt flag */
00633     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI);
00634 
00635     /* Line interrupt Callback */
00636 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00637     /*Call registered DCMI line event callback*/
00638     hdcmi->LineEventCallback(hdcmi);
00639 #else
00640     HAL_DCMI_LineEventCallback(hdcmi);
00641 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
00642   }
00643   /* VSYNC interrupt management ***********************************************/
00644   if ((isr_value & DCMI_FLAG_VSYNCRI) == DCMI_FLAG_VSYNCRI)
00645   {
00646     /* Clear the VSYNC flag */
00647     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI);
00648 
00649     /* VSYNC Callback */
00650 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00651     /*Call registered DCMI vsync event callback*/
00652     hdcmi->VsyncEventCallback(hdcmi);
00653 #else
00654     HAL_DCMI_VsyncEventCallback(hdcmi);
00655 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
00656   }
00657   /* FRAME interrupt management ***********************************************/
00658   if ((isr_value & DCMI_FLAG_FRAMERI) == DCMI_FLAG_FRAMERI)
00659   {
00660     /* When snapshot mode, disable Vsync, Error and Overrun interrupts */
00661     if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
00662     {
00663       /* Disable the Line, Vsync, Error and Overrun interrupts */
00664       __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
00665     }
00666 
00667     /* Disable the Frame interrupt */
00668     __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME);
00669 
00670     /* Clear the End of Frame flag */
00671     __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
00672 
00673     /* Frame Callback */
00674 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00675     /*Call registered DCMI frame event callback*/
00676     hdcmi->FrameEventCallback(hdcmi);
00677 #else
00678     HAL_DCMI_FrameEventCallback(hdcmi);
00679 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
00680   }
00681 }
00682 
00683 /**
00684   * @brief  Error DCMI callback.
00685   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00686   *                the configuration information for DCMI.
00687   * @retval None
00688   */
00689 __weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
00690 {
00691   /* Prevent unused argument(s) compilation warning */
00692   UNUSED(hdcmi);
00693 
00694   /* NOTE : This function Should not be modified, when the callback is needed,
00695             the HAL_DCMI_ErrorCallback could be implemented in the user file
00696    */
00697 }
00698 
00699 /**
00700   * @brief  Line Event callback.
00701   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00702   *                the configuration information for DCMI.
00703   * @retval None
00704   */
00705 __weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
00706 {
00707   /* Prevent unused argument(s) compilation warning */
00708   UNUSED(hdcmi);
00709   /* NOTE : This function Should not be modified, when the callback is needed,
00710             the HAL_DCMI_LineEventCallback could be implemented in the user file
00711    */
00712 }
00713 
00714 /**
00715   * @brief  VSYNC Event callback.
00716   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00717   *                the configuration information for DCMI.
00718   * @retval None
00719   */
00720 __weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
00721 {
00722   /* Prevent unused argument(s) compilation warning */
00723   UNUSED(hdcmi);
00724 
00725   /* NOTE : This function Should not be modified, when the callback is needed,
00726             the HAL_DCMI_VsyncEventCallback could be implemented in the user file
00727    */
00728 }
00729 
00730 /**
00731   * @brief  Frame Event callback.
00732   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00733   *                the configuration information for DCMI.
00734   * @retval None
00735   */
00736 __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
00737 {
00738   /* Prevent unused argument(s) compilation warning */
00739   UNUSED(hdcmi);
00740 
00741   /* NOTE : This function Should not be modified, when the callback is needed,
00742             the HAL_DCMI_FrameEventCallback could be implemented in the user file
00743    */
00744 }
00745 
00746 /**
00747   * @}
00748   */
00749 
00750 /** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions
00751  *  @brief    Peripheral Control functions
00752  *
00753 @verbatim
00754  ===============================================================================
00755                     ##### Peripheral Control functions #####
00756  ===============================================================================
00757 [..]  This section provides functions allowing to:
00758       (+) Configure the CROP feature.
00759       (+) Enable/Disable the CROP feature.
00760       (+) Set embedded synchronization delimiters unmasks.
00761 
00762 @endverbatim
00763   * @{
00764   */
00765 
00766 /**
00767   * @brief  Configure the DCMI CROP coordinate.
00768   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00769   *                the configuration information for DCMI.
00770   * @param  YSize DCMI Line number
00771   * @param  XSize DCMI Pixel per line
00772   * @param  X0    DCMI window X offset
00773   * @param  Y0    DCMI window Y offset
00774   * @retval HAL status
00775   */
00776 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize)
00777 {
00778   /* Process Locked */
00779   __HAL_LOCK(hdcmi);
00780 
00781   /* Lock the DCMI peripheral state */
00782   hdcmi->State = HAL_DCMI_STATE_BUSY;
00783 
00784   /* Check the parameters */
00785   assert_param(IS_DCMI_WINDOW_COORDINATE(X0));
00786   assert_param(IS_DCMI_WINDOW_HEIGHT(Y0));
00787   assert_param(IS_DCMI_WINDOW_COORDINATE(XSize));
00788   assert_param(IS_DCMI_WINDOW_COORDINATE(YSize));
00789 
00790   /* Configure CROP */
00791   hdcmi->Instance->CWSIZER = (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos));
00792   hdcmi->Instance->CWSTRTR = (X0 | (Y0 << DCMI_CWSTRT_VST_Pos));
00793 
00794   /* Initialize the DCMI state*/
00795   hdcmi->State  = HAL_DCMI_STATE_READY;
00796 
00797   /* Process Unlocked */
00798   __HAL_UNLOCK(hdcmi);
00799 
00800   return HAL_OK;
00801 }
00802 
00803 /**
00804   * @brief  Disable the Crop feature.
00805   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00806   *                the configuration information for DCMI.
00807   * @retval HAL status
00808   */
00809 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
00810 {
00811   /* Process Locked */
00812   __HAL_LOCK(hdcmi);
00813 
00814   /* Lock the DCMI peripheral state */
00815   hdcmi->State = HAL_DCMI_STATE_BUSY;
00816 
00817   /* Disable DCMI Crop feature */
00818   hdcmi->Instance->CR &= ~(uint32_t)DCMI_CR_CROP;
00819 
00820   /* Change the DCMI state*/
00821   hdcmi->State = HAL_DCMI_STATE_READY;
00822 
00823   /* Process Unlocked */
00824   __HAL_UNLOCK(hdcmi);
00825 
00826   return HAL_OK;
00827 }
00828 
00829 /**
00830   * @brief  Enable the Crop feature.
00831   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00832   *                the configuration information for DCMI.
00833   * @retval HAL status
00834   */
00835 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
00836 {
00837   /* Process Locked */
00838   __HAL_LOCK(hdcmi);
00839 
00840   /* Lock the DCMI peripheral state */
00841   hdcmi->State = HAL_DCMI_STATE_BUSY;
00842 
00843   /* Enable DCMI Crop feature */
00844   hdcmi->Instance->CR |= (uint32_t)DCMI_CR_CROP;
00845 
00846   /* Change the DCMI state*/
00847   hdcmi->State = HAL_DCMI_STATE_READY;
00848 
00849   /* Process Unlocked */
00850   __HAL_UNLOCK(hdcmi);
00851 
00852   return HAL_OK;
00853 }
00854 
00855 /**
00856   * @brief  Set embedded synchronization delimiters unmasks.
00857   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00858   *               the configuration information for DCMI.
00859   * @param  SyncUnmask pointer to a DCMI_SyncUnmaskTypeDef structure that contains
00860   *                    the embedded synchronization delimiters unmasks.
00861   * @retval HAL status
00862   */
00863 HAL_StatusTypeDef  HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask)
00864 {
00865   /* Process Locked */
00866   __HAL_LOCK(hdcmi);
00867 
00868   /* Lock the DCMI peripheral state */
00869   hdcmi->State = HAL_DCMI_STATE_BUSY;
00870 
00871   /* Write DCMI embedded synchronization unmask register */
00872   hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) | \
00873                            ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos) | \
00874                            ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos) | \
00875                            ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos));
00876 
00877   /* Change the DCMI state*/
00878   hdcmi->State = HAL_DCMI_STATE_READY;
00879 
00880   /* Process Unlocked */
00881   __HAL_UNLOCK(hdcmi);
00882 
00883   return HAL_OK;
00884 }
00885 
00886 /**
00887   * @}
00888   */
00889 
00890 /** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions
00891  *  @brief    Peripheral State functions
00892  *
00893 @verbatim
00894  ===============================================================================
00895                ##### Peripheral State and Errors functions #####
00896  ===============================================================================
00897     [..]
00898     This subsection provides functions allowing to
00899       (+) Check the DCMI state.
00900       (+) Get the specific DCMI error flag.
00901 
00902 @endverbatim
00903   * @{
00904   */
00905 
00906 /**
00907   * @brief  Return the DCMI state
00908   * @param  hdcmi pointer to a DCMI_HandleTypeDef structure that contains
00909   *                the configuration information for DCMI.
00910   * @retval HAL state
00911   */
00912 HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi)
00913 {
00914   return hdcmi->State;
00915 }
00916 
00917 /**
00918 * @brief  Return the DCMI error code
00919 * @param  hdcmi  pointer to a DCMI_HandleTypeDef structure that contains
00920   *               the configuration information for DCMI.
00921 * @retval DCMI Error Code
00922 */
00923 uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi)
00924 {
00925   return hdcmi->ErrorCode;
00926 }
00927 
00928 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
00929 /**
00930   * @brief  Register a User DCMI Callback
00931   *         To be used instead of the weak predefined callback
00932   * @param  hdcmi DCMI handle
00933   * @param  CallbackID ID of the callback to be registered
00934   *         This parameter can be one of the following values:
00935   *          @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
00936   *          @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
00937   *          @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
00938   *          @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
00939   *          @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
00940   *          @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
00941   * @param  pCallback pointer to the Callback function
00942   * @retval HAL status
00943   */
00944 HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, pDCMI_CallbackTypeDef pCallback)
00945 {
00946   HAL_StatusTypeDef status = HAL_OK;
00947 
00948   if (pCallback == NULL)
00949   {
00950     /* update the error code */
00951     hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
00952     /* update return status */
00953     status = HAL_ERROR;
00954   }
00955   else
00956   {
00957     if (hdcmi->State == HAL_DCMI_STATE_READY)
00958     {
00959       switch (CallbackID)
00960       {
00961         case HAL_DCMI_FRAME_EVENT_CB_ID :
00962           hdcmi->FrameEventCallback = pCallback;
00963           break;
00964 
00965         case HAL_DCMI_VSYNC_EVENT_CB_ID :
00966           hdcmi->VsyncEventCallback = pCallback;
00967           break;
00968 
00969         case HAL_DCMI_LINE_EVENT_CB_ID :
00970           hdcmi->LineEventCallback = pCallback;
00971           break;
00972 
00973         case HAL_DCMI_ERROR_CB_ID :
00974           hdcmi->ErrorCallback = pCallback;
00975           break;
00976 
00977         case HAL_DCMI_MSPINIT_CB_ID :
00978           hdcmi->MspInitCallback = pCallback;
00979           break;
00980 
00981         case HAL_DCMI_MSPDEINIT_CB_ID :
00982           hdcmi->MspDeInitCallback = pCallback;
00983           break;
00984 
00985         default :
00986           /* Return error status */
00987           status =  HAL_ERROR;
00988           break;
00989       }
00990     }
00991     else if (hdcmi->State == HAL_DCMI_STATE_RESET)
00992     {
00993       switch (CallbackID)
00994       {
00995         case HAL_DCMI_MSPINIT_CB_ID :
00996           hdcmi->MspInitCallback = pCallback;
00997           break;
00998 
00999         case HAL_DCMI_MSPDEINIT_CB_ID :
01000           hdcmi->MspDeInitCallback = pCallback;
01001           break;
01002 
01003         default :
01004           /* update the error code */
01005           hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
01006           /* update return status */
01007           status = HAL_ERROR;
01008           break;
01009       }
01010     }
01011     else
01012     {
01013       /* update the error code */
01014       hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
01015       /* update return status */
01016       status = HAL_ERROR;
01017     }
01018   }
01019 
01020   return status;
01021 }
01022 
01023 /**
01024   * @brief  Unregister a DCMI Callback
01025   *         DCMI callabck is redirected to the weak predefined callback
01026   * @param  hdcmi DCMI handle
01027   * @param  CallbackID ID of the callback to be registered
01028   *         This parameter can be one of the following values:
01029   *          @arg @ref HAL_DCMI_LINE_EVENT_CB_ID Line Event callback ID
01030   *          @arg @ref HAL_DCMI_FRAME_EVENT_CB_ID Frame Event callback ID
01031   *          @arg @ref HAL_DCMI_VSYNC_EVENT_CB_ID Vsync Event callback ID
01032   *          @arg @ref HAL_DCMI_ERROR_CB_ID Error callback ID
01033   *          @arg @ref HAL_DCMI_MSPINIT_CB_ID MspInit callback ID
01034   *          @arg @ref HAL_DCMI_MSPDEINIT_CB_ID MspDeInit callback ID
01035   * @retval HAL status
01036   */
01037 HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID)
01038 {
01039   HAL_StatusTypeDef status = HAL_OK;
01040 
01041   if (hdcmi->State == HAL_DCMI_STATE_READY)
01042   {
01043     switch (CallbackID)
01044     {
01045       case HAL_DCMI_FRAME_EVENT_CB_ID :
01046         hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback;  /* Legacy weak  FrameEventCallback  */
01047         break;
01048 
01049       case HAL_DCMI_VSYNC_EVENT_CB_ID :
01050         hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback;  /* Legacy weak VsyncEventCallback       */
01051         break;
01052 
01053       case HAL_DCMI_LINE_EVENT_CB_ID :
01054         hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback;    /* Legacy weak LineEventCallback   */
01055         break;
01056 
01057       case HAL_DCMI_ERROR_CB_ID :
01058         hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback;           /* Legacy weak ErrorCallback        */
01059         break;
01060 
01061       case HAL_DCMI_MSPINIT_CB_ID :
01062         hdcmi->MspInitCallback = HAL_DCMI_MspInit;
01063         break;
01064 
01065       case HAL_DCMI_MSPDEINIT_CB_ID :
01066         hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
01067         break;
01068 
01069       default :
01070         /* update the error code */
01071         hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
01072         /* update return status */
01073         status = HAL_ERROR;
01074         break;
01075     }
01076   }
01077   else if (hdcmi->State == HAL_DCMI_STATE_RESET)
01078   {
01079     switch (CallbackID)
01080     {
01081       case HAL_DCMI_MSPINIT_CB_ID :
01082         hdcmi->MspInitCallback = HAL_DCMI_MspInit;
01083         break;
01084 
01085       case HAL_DCMI_MSPDEINIT_CB_ID :
01086         hdcmi->MspDeInitCallback = HAL_DCMI_MspDeInit;
01087         break;
01088 
01089       default :
01090         /* update the error code */
01091         hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
01092         /* update return status */
01093         status = HAL_ERROR;
01094         break;
01095     }
01096   }
01097   else
01098   {
01099     /* update the error code */
01100     hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
01101     /* update return status */
01102     status = HAL_ERROR;
01103   }
01104 
01105   return status;
01106 }
01107 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
01108 
01109 /**
01110   * @}
01111   */
01112 /* Private functions ---------------------------------------------------------*/
01113 /** @defgroup DCMI_Private_Functions DCMI Private Functions
01114   * @{
01115   */
01116 /**
01117   * @brief  DMA conversion complete callback.
01118   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
01119   *                the configuration information for the specified DMA module.
01120   * @retval None
01121   */
01122 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
01123 {
01124   uint32_t tmp ;
01125 
01126   DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
01127 
01128   if (hdcmi->XferCount != 0U)
01129   {
01130     /* Update memory 0 address location */
01131     tmp = ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR) & DMA_SxCR_CT);
01132     if (((hdcmi->XferCount % 2U) == 0U) && (tmp != 0U))
01133     {
01134       tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR;
01135       (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY0);
01136       hdcmi->XferCount--;
01137     }
01138     /* Update memory 1 address location */
01139     else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
01140     {
01141       tmp = ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR;
01142       (void)HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8U * hdcmi->XferSize)), MEMORY1);
01143       hdcmi->XferCount--;
01144     }
01145     else
01146     {
01147       /* Nothing to do */
01148     }
01149   }
01150   /* Update memory 0 address location */
01151   else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) != 0U)
01152   {
01153     ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M0AR = hdcmi->pBuffPtr;
01154   }
01155   /* Update memory 1 address location */
01156   else if ((((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->CR & DMA_SxCR_CT) == 0U)
01157   {
01158     tmp = hdcmi->pBuffPtr;
01159     ((DMA_Stream_TypeDef *)(hdcmi->DMA_Handle->Instance))->M1AR = (tmp + (4U * hdcmi->XferSize));
01160     hdcmi->XferCount = hdcmi->XferTransferNumber;
01161   }
01162   else
01163   {
01164     /* Nothing to do */
01165   }
01166 
01167   /* Check if the frame is transferred */
01168   if (hdcmi->XferCount == hdcmi->XferTransferNumber)
01169   {
01170     /* Enable the Frame interrupt */
01171     __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
01172 
01173     /* When snapshot mode, set dcmi state to ready */
01174     if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
01175     {
01176       hdcmi->State = HAL_DCMI_STATE_READY;
01177     }
01178   }
01179 }
01180 
01181 /**
01182   * @brief  DMA error callback
01183   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
01184   *                the configuration information for the specified DMA module.
01185   * @retval None
01186   */
01187 static void DCMI_DMAError(DMA_HandleTypeDef *hdma)
01188 {
01189   DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
01190 
01191   if (hdcmi->DMA_Handle->ErrorCode != HAL_DMA_ERROR_FE)
01192   {
01193     /* Initialize the DCMI state*/
01194     hdcmi->State = HAL_DCMI_STATE_READY;
01195 
01196     /* Set DCMI Error Code */
01197     hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
01198   }
01199 
01200   /* DCMI error Callback */
01201 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
01202   /*Call registered DCMI error callback*/
01203   hdcmi->ErrorCallback(hdcmi);
01204 #else
01205   HAL_DCMI_ErrorCallback(hdcmi);
01206 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
01207 }
01208 
01209 /**
01210   * @}
01211   */
01212 
01213 /**
01214   * @}
01215   */
01216 #endif /* DCMI */
01217 #endif /* HAL_DCMI_MODULE_ENABLED */
01218 /**
01219   * @}
01220   */
01221 
01222 /**
01223   * @}
01224   */
01225