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