STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_dcmi.c
Go to the documentation of this file.
1 
161 /* Includes ------------------------------------------------------------------*/
162 #include "stm32l4xx_hal.h"
163 
164 #ifdef HAL_DCMI_MODULE_ENABLED
165 #if defined (DCMI)
166 
175 /* Private typedef -----------------------------------------------------------*/
176 /* Private define ------------------------------------------------------------*/
184 #define DCMI_TIMEOUT_STOP ((uint32_t)1000U)
189 #define NPRIME 16U
190 
194 /* Private macro -------------------------------------------------------------*/
195 /* Private variables ---------------------------------------------------------*/
196 /* Private function prototypes -----------------------------------------------*/
200 static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma);
201 static void DCMI_DMAHalfXferCplt(DMA_HandleTypeDef *hdma);
202 static void DCMI_DMAError(DMA_HandleTypeDef *hdma);
203 static uint32_t DCMI_TransferSize(uint32_t InputSize);
207 /* Exported functions --------------------------------------------------------*/
208 
237 HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
238 {
239  /* Check the DCMI peripheral state */
240  if(hdcmi == NULL)
241  {
242  return HAL_ERROR;
243  }
244 
245  /* Check function parameters */
246  assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance));
247  assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode));
248  assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity));
249  assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity));
250  assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity));
251  assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate));
252  assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode));
253  assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode));
254 
255  assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode));
256  assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart));
257  assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode));
258  assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart));
259 
260  if(hdcmi->State == HAL_DCMI_STATE_RESET)
261  {
262  /* Allocate lock resource and initialize it */
263  hdcmi->Lock = HAL_UNLOCKED;
264 
265  /* Init the DCMI Callback settings */
266 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
267  hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
268  hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
269  hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
270  hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
271 
272  if(hdcmi->MspInitCallback == NULL)
273  {
274  /* Legacy weak MspInit Callback */
276  }
277  /* Initialize the low level hardware (MSP) */
278  hdcmi->MspInitCallback(hdcmi);
279 #else
280  /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
281  HAL_DCMI_MspInit(hdcmi);
282 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
283  }
284 
285  /* Change the DCMI state */
286  hdcmi->State = HAL_DCMI_STATE_BUSY;
287 
288  /* Disable DCMI IP before setting the configuration register */
289  __HAL_DCMI_DISABLE(hdcmi);
290 
291  if (hdcmi->Init.ExtendedDataMode != DCMI_EXTEND_DATA_8B)
292  {
293  /* Byte select mode must be programmed to the reset value if the extended mode
294  is not set to 8-bit data capture on every pixel clock */
295  hdcmi->Init.ByteSelectMode = DCMI_BSM_ALL;
296  }
297 
298  /* Set DCMI parameters */
299  hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 |\
300  DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG |\
301  DCMI_CR_ESS | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS |\
302  DCMI_CR_LSM | DCMI_CR_OELS);
303 
304  hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate |\
305  hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity |\
306  hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode |\
307  hdcmi->Init.JPEGMode | hdcmi->Init.ByteSelectMode |\
308  hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode |\
309  hdcmi->Init.LineSelectStart);
310 
311  if(hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED)
312  {
313  hdcmi->Instance->ESCR = (((uint32_t)hdcmi->Init.SynchroCode.FrameStartCode) |\
314  ((uint32_t)hdcmi->Init.SynchroCode.LineStartCode << DCMI_ESCR_LSC_Pos)|\
315  ((uint32_t)hdcmi->Init.SynchroCode.LineEndCode << DCMI_ESCR_LEC_Pos) |\
316  ((uint32_t)hdcmi->Init.SynchroCode.FrameEndCode << DCMI_ESCR_FEC_Pos));
317  }
318 
319  /* By default, enable all interrupts. The user may disable the unwanted ones
320  in resorting to __HAL_DCMI_DISABLE_IT() macro before invoking HAL_DCMI_Start_DMA().
321  Enabled interruptions are
322  - end of line
323  - end of frame
324  - data reception overrun
325  - frame synchronization signal VSYNC
326  - synchronization error */
327  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME|DCMI_IT_OVR|DCMI_IT_ERR|DCMI_IT_VSYNC|DCMI_IT_LINE);
328 
329  /* Update error code */
330  hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
331 
332  /* Initialize the DCMI state*/
333  hdcmi->State = HAL_DCMI_STATE_READY;
334 
335  return HAL_OK;
336 }
337 
345 HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
346 {
347  /* Before aborting any DCMI transfer, check
348  first whether or not DCMI clock is enabled */
349  if (__HAL_RCC_DCMI_IS_CLK_ENABLED())
350  {
351  if (HAL_DCMI_Stop(hdcmi) != HAL_OK)
352  {
353  /* Issue when stopping DCMI IP */
354  return HAL_ERROR;
355  }
356  }
357 
358  /* Reset DCMI control register */
359  hdcmi->Instance->CR = 0;
360 
361 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
362  if(hdcmi->MspDeInitCallback == NULL)
363  {
365  }
366  /* De-Initialize the low level hardware (MSP) */
367  hdcmi->MspDeInitCallback(hdcmi);
368 #else
369  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
370  HAL_DCMI_MspDeInit(hdcmi);
371 #endif /* (USE_HAL_DCMI_REGISTER_CALLBACKS) */
372 
373  /* Update error code */
374  hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
375 
376  /* Initialize the DCMI state*/
377  hdcmi->State = HAL_DCMI_STATE_RESET;
378 
379  /* Release Lock */
380  __HAL_UNLOCK(hdcmi);
381 
382  return HAL_OK;
383 }
384 
392 {
393  /* Prevent unused argument(s) compilation warning */
394  UNUSED(hdcmi);
395 
396  /* NOTE : This function should not be modified; when the callback is needed,
397  the HAL_DCMI_MspInit() callback can be implemented in the user file
398  */
399 }
400 
408 {
409  /* Prevent unused argument(s) compilation warning */
410  UNUSED(hdcmi);
411 
412  /* NOTE : This function should not be modified; when the callback is needed,
413  the HAL_DCMI_MspDeInit() callback can be implemented in the user file
414  */
415 }
416 
467 HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
468 {
469  uint32_t circular_copy_length;
470 
471  /* Check capture parameter */
472  assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
473 
474  /* Process Locked */
475  __HAL_LOCK(hdcmi);
476 
477  /* Lock the DCMI peripheral state */
478  hdcmi->State = HAL_DCMI_STATE_BUSY;
479 
480  /* Configure the DCMI Mode and enable the DCMI IP at the same time */
481  MODIFY_REG(hdcmi->Instance->CR, (DCMI_CR_CM|DCMI_CR_ENABLE), (DCMI_Mode|DCMI_CR_ENABLE));
482 
483  /* Set the DMA conversion complete callback */
485 
486  /* Set the DMA error callback */
488 
489  /* Set the dma abort callback */
490  hdcmi->DMA_Handle->XferAbortCallback = NULL;
491 
492  if(Length <= 0xFFFFU)
493  {
494  hdcmi->XferCount = 0; /* Mark as direct transfer from DCMI_DR register to final destination buffer */
495 
496  /* Enable the DMA channel */
497  if (HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length) != HAL_OK)
498  {
499  /* Update error code */
500  hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
501 
502  /* Set state back to Ready */
503  hdcmi->State = HAL_DCMI_STATE_READY;
504 
505  /* Process Unlocked */
506  __HAL_UNLOCK(hdcmi);
507 
508  return HAL_ERROR;
509  }
510  }
511  else /* Capture length is longer than DMA maximum transfer size */
512  {
513  /* Set DMA in circular mode */
514  hdcmi->DMA_Handle->Init.Mode = DMA_CIRCULAR;
515 
516  /* Set the DMA half transfer complete callback */
518 
519  /* Initialize transfer parameters */
520  hdcmi->XferSize = Length; /* Store the complete transfer length in DCMI handle */
521  hdcmi->pBuffPtr = pData; /* Final destination buffer pointer */
522 
523  circular_copy_length = DCMI_TransferSize(Length);
524 
525  /* Check if issue in intermediate length computation */
526  if (circular_copy_length == 0U)
527  {
528  /* Set state back to Ready */
529  hdcmi->State = HAL_DCMI_STATE_READY;
530 
531  /* Process Unlocked */
532  __HAL_UNLOCK(hdcmi);
533 
534  return HAL_ERROR;
535  }
536 
537  /* Store the number of half - intermediate buffer copies needed */
538  hdcmi->XferCount = 2U * ((Length / circular_copy_length) - 1U);
539  /* Store the half-buffer copy length */
540  hdcmi->HalfCopyLength = circular_copy_length / 2U;
541 
542  /* DCMI DR samples in circular mode will be copied
543  at the end of the final buffer.
544  Now compute the circular buffer start address. */
545  /* Start by pointing at the final buffer */
546  hdcmi->pCircularBuffer = pData;
547  /* Update pCircularBuffer in "moving" at the end of the final
548  buffer, don't forger to convert in bytes to compute exact address */
549  hdcmi->pCircularBuffer += 4U * (((Length / circular_copy_length) - 1U) * circular_copy_length);
550 
551  /* Initiate the circular DMA transfer from DCMI IP to final buffer end */
552  if ( HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)hdcmi->pCircularBuffer, circular_copy_length) != HAL_OK)
553  {
554  /* Update error code */
555  hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
556 
557  /* Set state back to Ready */
558  hdcmi->State = HAL_DCMI_STATE_READY;
559 
560  /* Process Unlocked */
561  __HAL_UNLOCK(hdcmi);
562 
563  return HAL_ERROR;
564  }
565  }
566 
567  /* Enable Capture */
568  SET_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE);
569 
570  /* Release Lock */
571  __HAL_UNLOCK(hdcmi);
572 
573  /* Return function status */
574  return HAL_OK;
575 }
576 
583 HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef* hdcmi)
584 {
585  uint32_t tickstart;
586  HAL_StatusTypeDef status = HAL_OK;
587 
588  /* Process locked */
589  __HAL_LOCK(hdcmi);
590 
591  /* Lock the DCMI peripheral state */
592  hdcmi->State = HAL_DCMI_STATE_BUSY;
593 
594  /* Disable Capture */
595  CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE);
596 
597  /* Get tick */
598  tickstart = HAL_GetTick();
599 
600  /* Check if the DCMI capture is effectively disabled */
601  while((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U)
602  {
603  if((HAL_GetTick() - tickstart ) > DCMI_TIMEOUT_STOP)
604  {
605  /* Update error code */
606  hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
607 
608  status = HAL_TIMEOUT;
609  break;
610  }
611  }
612 
613  /* Disable the DMA */
614  if (HAL_DMA_Abort(hdcmi->DMA_Handle) != HAL_OK)
615  {
616  DCMI_DMAError(hdcmi->DMA_Handle);
617  }
618 
619  /* Disable DCMI IP */
620  __HAL_DCMI_DISABLE(hdcmi);
621 
622  /* Change DCMI state */
623  hdcmi->State = HAL_DCMI_STATE_READY;
624 
625  /* Process Unlocked */
626  __HAL_UNLOCK(hdcmi);
627 
628  /* Return function status */
629  return status;
630 }
631 
638 HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef* hdcmi)
639 {
640  uint32_t tickstart;
641 
642  /* Process locked */
643  __HAL_LOCK(hdcmi);
644 
645  if(hdcmi->State == HAL_DCMI_STATE_BUSY)
646  {
647  /* Change DCMI state */
649 
650  /* Disable Capture */
651  CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE);
652 
653  /* Get tick */
654  tickstart = HAL_GetTick();
655 
656  /* Check if the DCMI capture is effectively disabled */
657  while((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0U)
658  {
659  if((HAL_GetTick() - tickstart ) > DCMI_TIMEOUT_STOP)
660  {
661  /* Update error code */
662  hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT;
663 
664  /* Change DCMI state */
665  hdcmi->State = HAL_DCMI_STATE_READY;
666 
667  /* Process Unlocked */
668  __HAL_UNLOCK(hdcmi);
669 
670  return HAL_TIMEOUT;
671  }
672  }
673  }
674 
675  /* Process Unlocked */
676  __HAL_UNLOCK(hdcmi);
677 
678  /* Return function status */
679  return HAL_OK;
680 }
681 
688 HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef* hdcmi)
689 {
690  /* Process locked */
691  __HAL_LOCK(hdcmi);
692 
693  if(hdcmi->State == HAL_DCMI_STATE_SUSPENDED)
694  {
695  /* Change DCMI state */
696  hdcmi->State = HAL_DCMI_STATE_BUSY;
697 
698  /* Enable Capture */
699  SET_BIT(hdcmi->Instance->CR, DCMI_CR_CAPTURE);
700  }
701 
702  /* Process Unlocked */
703  __HAL_UNLOCK(hdcmi);
704 
705  return HAL_OK;
706 }
707 
715 {
716  uint32_t misflags = READ_REG(hdcmi->Instance->MISR);
717 
718  /* Synchronization error interrupt management *******************************/
719  if ((misflags & DCMI_MIS_ERR_MIS) != 0x0U)
720  {
721  /* Clear the Synchronization error flag */
722  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);
723 
724  /* Update error code */
725  hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;
726  }
727 
728  /* Overflow interrupt management ********************************************/
729  if ((misflags & DCMI_MIS_OVR_MIS) != 0x0U)
730  {
731  /* Clear the Overflow flag */
732  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);
733 
734  /* Update error code */
735  hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;
736  }
737 
738  if (hdcmi->ErrorCode != HAL_DCMI_ERROR_NONE)
739  {
740  /* Change DCMI state */
741  hdcmi->State = HAL_DCMI_STATE_READY;
742 
743  /* Set the overflow callback */
745 
746  /* Abort the DMA Transfer */
747  if (HAL_DMA_Abort_IT(hdcmi->DMA_Handle) != HAL_OK)
748  {
749  DCMI_DMAError(hdcmi->DMA_Handle);
750  }
751  }
752 
753  /* Line Interrupt management ************************************************/
754  if ((misflags & DCMI_MIS_LINE_MIS) != 0x0U)
755  {
756  /* Clear the Line interrupt flag */
757  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI);
758 
759  /* Line interrupt Event Callback */
760 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
761  /*Call registered DCMI line event callback*/
762  hdcmi->LineEventCallback(hdcmi);
763 #else
765 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
766  }
767 
768  /* VSYNC interrupt management ***********************************************/
769  if ((misflags & DCMI_MIS_VSYNC_MIS) != 0x0U)
770  {
771  /* Clear the VSYNC flag */
772  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI);
773 
774  /* VSYNC Event Callback */
775 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
776  /*Call registered DCMI vsync event callback*/
777  hdcmi->VsyncEventCallback(hdcmi);
778 #else
780 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
781  }
782 
783  /* End of Frame interrupt management ****************************************/
784  if ((misflags & DCMI_MIS_FRAME_MIS) != 0x0U)
785  {
786  /* Disable the Line interrupt when using snapshot mode */
787  if ((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
788  {
789  __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE|DCMI_IT_VSYNC|DCMI_IT_ERR|DCMI_IT_OVR);
790  /* Change the DCMI state */
791  hdcmi->State = HAL_DCMI_STATE_READY;
792  }
793 
794  /* Clear the End of Frame flag */
795  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
796 
797  /* Frame Event Callback */
798 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
799  /*Call registered DCMI frame event callback*/
800  hdcmi->FrameEventCallback(hdcmi);
801 #else
803 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
804  }
805 }
806 
814 {
815  /* Prevent unused argument(s) compilation warning */
816  UNUSED(hdcmi);
817 
818  /* NOTE : This function should not be modified; when the callback is needed,
819  the HAL_DCMI_ErrorCallback() callback can be implemented in the user file.
820  */
821 }
822 
830 {
831  /* Prevent unused argument(s) compilation warning */
832  UNUSED(hdcmi);
833 
834  /* NOTE : This function should not be modified; when the callback is needed,
835  the HAL_DCMI_LineEventCallback() callback can be implemented in the user file.
836  */
837 }
838 
846 {
847  /* Prevent unused argument(s) compilation warning */
848  UNUSED(hdcmi);
849 
850  /* NOTE : This function should not be modified; when the callback is needed,
851  the HAL_DCMI_VsyncEventCallback() callback can be implemented in the user file.
852  */
853 }
854 
862 {
863  /* Prevent unused argument(s) compilation warning */
864  UNUSED(hdcmi);
865 
866  /* NOTE : This function should not be modified; when the callback is needed,
867  the HAL_DCMI_FrameEventCallback() callback can be implemented in the user file.
868  */
869 }
905 HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize)
906 {
907  /* Check the parameters */
908  assert_param(IS_DCMI_WINDOW_COORDINATE(X0));
909  assert_param(IS_DCMI_WINDOW_HEIGHT(Y0));
910  assert_param(IS_DCMI_WINDOW_COORDINATE(XSize));
911  assert_param(IS_DCMI_WINDOW_COORDINATE(YSize));
912 
913  /* Process Locked */
914  __HAL_LOCK(hdcmi);
915 
916  /* Lock the DCMI peripheral state */
917  hdcmi->State = HAL_DCMI_STATE_BUSY;
918 
919  /* Configure CROP */
920  MODIFY_REG(hdcmi->Instance->CWSIZER, (DCMI_CWSIZE_VLINE|DCMI_CWSIZE_CAPCNT), (XSize | (YSize << DCMI_CWSIZE_VLINE_Pos)));
921  MODIFY_REG(hdcmi->Instance->CWSTRTR, (DCMI_CWSTRT_VST|DCMI_CWSTRT_HOFFCNT), (X0 | (Y0 << DCMI_CWSTRT_VST_Pos)));
922 
923  /* Initialize the DCMI state*/
924  hdcmi->State = HAL_DCMI_STATE_READY;
925 
926  /* Process Unlocked */
927  __HAL_UNLOCK(hdcmi);
928 
929  return HAL_OK;
930 }
931 
938 HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
939 {
940  /* Process Locked */
941  __HAL_LOCK(hdcmi);
942 
943  /* Lock the DCMI peripheral state */
944  hdcmi->State = HAL_DCMI_STATE_BUSY;
945 
946  /* Disable DCMI Crop feature */
947  CLEAR_BIT(hdcmi->Instance->CR, DCMI_CR_CROP);
948 
949  /* Change the DCMI state*/
950  hdcmi->State = HAL_DCMI_STATE_READY;
951 
952  /* Process Unlocked */
953  __HAL_UNLOCK(hdcmi);
954 
955  return HAL_OK;
956 }
957 
964 HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
965 {
966  /* Process Locked */
967  __HAL_LOCK(hdcmi);
968 
969  /* Lock the DCMI peripheral state */
970  hdcmi->State = HAL_DCMI_STATE_BUSY;
971 
972  /* Enable DCMI Crop feature */
973  SET_BIT(hdcmi->Instance->CR, DCMI_CR_CROP);
974 
975  /* Change the DCMI state*/
976  hdcmi->State = HAL_DCMI_STATE_READY;
977 
978  /* Process Unlocked */
979  __HAL_UNLOCK(hdcmi);
980 
981  return HAL_OK;
982 }
983 
993 {
994  /* Process Locked */
995  __HAL_LOCK(hdcmi);
996 
997  /* Lock the DCMI peripheral state */
998  hdcmi->State = HAL_DCMI_STATE_BUSY;
999 
1000  /* Write DCMI embedded synchronization unmask register */
1001  hdcmi->Instance->ESUR = (((uint32_t)SyncUnmask->FrameStartUnmask) |\
1002  ((uint32_t)SyncUnmask->LineStartUnmask << DCMI_ESUR_LSU_Pos)|\
1003  ((uint32_t)SyncUnmask->LineEndUnmask << DCMI_ESUR_LEU_Pos)|\
1004  ((uint32_t)SyncUnmask->FrameEndUnmask << DCMI_ESUR_FEU_Pos));
1005 
1006  /* Change the DCMI state*/
1007  hdcmi->State = HAL_DCMI_STATE_READY;
1008 
1009  /* Process Unlocked */
1010  __HAL_UNLOCK(hdcmi);
1011 
1012  return HAL_OK;
1013 }
1014 
1015 
1016 
1017 
1045 {
1046  return hdcmi->State;
1047 }
1048 
1056 {
1057  return hdcmi->ErrorCode;
1058 }
1059 
1064 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1065 
1073 {
1074  HAL_StatusTypeDef status = HAL_OK;
1075 
1076  if(pCallback == NULL)
1077  {
1078  /* update the error code */
1079  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1080  /* update return status */
1081  status = HAL_ERROR;
1082  }
1083  else
1084  {
1085  if(hdcmi->State == HAL_DCMI_STATE_READY)
1086  {
1087  switch (CallbackID)
1088  {
1090  hdcmi->FrameEventCallback = pCallback;
1091  break;
1092 
1094  hdcmi->VsyncEventCallback = pCallback;
1095  break;
1096 
1098  hdcmi->LineEventCallback = pCallback;
1099  break;
1100 
1101  case HAL_DCMI_ERROR_CB_ID :
1102  hdcmi->ErrorCallback = pCallback;
1103  break;
1104 
1105  case HAL_DCMI_MSPINIT_CB_ID :
1106  hdcmi->MspInitCallback = pCallback;
1107  break;
1108 
1110  hdcmi->MspDeInitCallback = pCallback;
1111  break;
1112 
1113  default :
1114  /* Return error status */
1115  status = HAL_ERROR;
1116  break;
1117  }
1118  }
1119  else if(hdcmi->State == HAL_DCMI_STATE_RESET)
1120  {
1121  switch (CallbackID)
1122  {
1123  case HAL_DCMI_MSPINIT_CB_ID :
1124  hdcmi->MspInitCallback = pCallback;
1125  break;
1126 
1128  hdcmi->MspDeInitCallback = pCallback;
1129  break;
1130 
1131  default :
1132  /* update the error code */
1133  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1134  /* update return status */
1135  status = HAL_ERROR;
1136  break;
1137  }
1138  }
1139  else
1140  {
1141  /* update the error code */
1142  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1143  /* update return status */
1144  status = HAL_ERROR;
1145  }
1146  }
1147 
1148  return status;
1149 }
1150 
1158 {
1159  HAL_StatusTypeDef status = HAL_OK;
1160 
1161  if(hdcmi->State == HAL_DCMI_STATE_READY)
1162  {
1163  switch (CallbackID)
1164  {
1166  hdcmi->FrameEventCallback = HAL_DCMI_FrameEventCallback; /* Legacy weak FrameEventCallback */
1167  break;
1168 
1170  hdcmi->VsyncEventCallback = HAL_DCMI_VsyncEventCallback; /* Legacy weak VsyncEventCallback */
1171  break;
1172 
1174  hdcmi->LineEventCallback = HAL_DCMI_LineEventCallback; /* Legacy weak LineEventCallback */
1175  break;
1176 
1177  case HAL_DCMI_ERROR_CB_ID :
1178  hdcmi->ErrorCallback = HAL_DCMI_ErrorCallback; /* Legacy weak ErrorCallback */
1179  break;
1180 
1181  case HAL_DCMI_MSPINIT_CB_ID :
1183  break;
1184 
1187  break;
1188 
1189  default :
1190  /* update the error code */
1191  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1192  /* update return status */
1193  status = HAL_ERROR;
1194  break;
1195  }
1196  }
1197  else if(hdcmi->State == HAL_DCMI_STATE_RESET)
1198  {
1199  switch (CallbackID)
1200  {
1201  case HAL_DCMI_MSPINIT_CB_ID :
1203  break;
1204 
1207  break;
1208 
1209  default :
1210  /* update the error code */
1211  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1212  /* update return status */
1213  status = HAL_ERROR;
1214  break;
1215  }
1216  }
1217  else
1218  {
1219  /* update the error code */
1220  hdcmi->ErrorCode |= HAL_DCMI_ERROR_INVALID_CALLBACK;
1221  /* update return status */
1222  status = HAL_ERROR;
1223  }
1224 
1225  return status;
1226 }
1227 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1228 
1233 /* Private functions ---------------------------------------------------------*/
1249 {
1250  uint32_t loop_length; /* transfer length */
1251  uint32_t * tmpBuffer_Dest;
1252  uint32_t * tmpBuffer_Orig;
1253  uint32_t temp;
1254 
1255  DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1256 
1257 
1258  if(hdcmi->XferCount != 0U)
1259  {
1260  /* Manage second half buffer copy in case of big transfer */
1261 
1262  /* Decrement half-copies counter */
1263  hdcmi->XferCount--;
1264 
1265  /* Point at DCMI final destination */
1266  tmpBuffer_Dest = (uint32_t *)hdcmi->pBuffPtr;
1267 
1268  /* Point at DCMI circular buffer mid-location */
1269  tmpBuffer_Orig = (uint32_t *)hdcmi->pCircularBuffer;
1270  temp = (uint32_t) (tmpBuffer_Orig);
1271  temp += hdcmi->HalfCopyLength;
1272  tmpBuffer_Orig = (uint32_t *) temp;
1273 
1274  /* copy half the buffer size */
1275  loop_length = hdcmi->HalfCopyLength;
1276 
1277  /* Save next entry to write at next half DMA transfer interruption */
1278  hdcmi->pBuffPtr += (uint32_t) loop_length*4U;
1279  hdcmi->XferSize -= hdcmi->HalfCopyLength;
1280 
1281  /* Data copy from work buffer to final destination buffer */
1282  /* Enable the DMA Channel */
1283  if (HAL_DMA_Start_IT(hdcmi->DMAM2M_Handle, (uint32_t) tmpBuffer_Orig, (uint32_t) tmpBuffer_Dest, loop_length) != HAL_OK)
1284  {
1285  /* Update error code */
1286  hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1287 
1288  /* Change DCMI state */
1289  hdcmi->State = HAL_DCMI_STATE_READY;
1290 
1291  /* Process Unlocked */
1292  __HAL_UNLOCK(hdcmi);
1293 
1294  /* DCMI error Callback */
1295 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1296  /*Call registered DCMI error callback*/
1297  hdcmi->ErrorCallback(hdcmi);
1298 #else
1299  HAL_DCMI_ErrorCallback(hdcmi);
1300 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1301  }
1302  }
1303  else
1304  {
1305  /* if End of frame IT is disabled */
1306  if((hdcmi->Instance->IER & DCMI_IT_FRAME) == 0x0U)
1307  {
1308  /* If End of Frame flag is set */
1309  if(__HAL_DCMI_GET_FLAG(hdcmi, (uint32_t)DCMI_FLAG_FRAMERI) != 0x0UL)
1310  {
1311  /* Clear the End of Frame flag */
1312  __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI);
1313 
1314  /* When snapshot mode, disable Vsync, Error and Overrun interrupts */
1315  if((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
1316  {
1317  /* Disable the Vsync, Error and Overrun interrupts */
1318  __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_LINE | DCMI_IT_VSYNC | DCMI_IT_ERR | DCMI_IT_OVR);
1319 
1320  hdcmi->State = HAL_DCMI_STATE_READY;
1321 
1322  /* Process Unlocked */
1323  __HAL_UNLOCK(hdcmi);
1324  }
1325 
1326  /* Frame Event Callback */
1327 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1328  /*Call registered DCMI frame event callback*/
1329  hdcmi->FrameEventCallback(hdcmi);
1330 #else
1332 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1333  }
1334  }
1335  }
1336 }
1337 
1338 
1350 {
1351  uint32_t loop_length; /* transfer length */
1352  uint32_t * tmpBuffer_Dest;
1353  uint32_t * tmpBuffer_Orig;
1354 
1355  DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1356 
1357  if(hdcmi->XferCount != 0U)
1358  {
1359  /* Manage first half buffer copy in case of big transfer */
1360 
1361  /* Decrement half-copies counter */
1362  hdcmi->XferCount--;
1363 
1364  /* Point at DCMI final destination */
1365  tmpBuffer_Dest = (uint32_t *)hdcmi->pBuffPtr;
1366 
1367  /* Point at DCMI circular buffer start */
1368  tmpBuffer_Orig = (uint32_t *)hdcmi->pCircularBuffer;
1369 
1370  /* copy half the buffer size */
1371  loop_length = hdcmi->HalfCopyLength;
1372 
1373  /* Save next entry to write at next DMA transfer interruption */
1374  hdcmi->pBuffPtr += (uint32_t) loop_length*4U;
1375  hdcmi->XferSize -= hdcmi->HalfCopyLength;
1376 
1377  /* Data copy from work buffer to final destination buffer */
1378  /* Enable the DMA Channel */
1379  if (HAL_DMA_Start_IT(hdcmi->DMAM2M_Handle, (uint32_t) tmpBuffer_Orig, (uint32_t) tmpBuffer_Dest, loop_length) != HAL_OK)
1380  {
1381  /* Update error code */
1382  hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1383 
1384  /* Change DCMI state */
1385  hdcmi->State = HAL_DCMI_STATE_READY;
1386 
1387  /* Process Unlocked */
1388  __HAL_UNLOCK(hdcmi);
1389 
1390  /* DCMI error Callback */
1391 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1392  /*Call registered DCMI error callback*/
1393  hdcmi->ErrorCallback(hdcmi);
1394 #else
1395  HAL_DCMI_ErrorCallback(hdcmi);
1396 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1397  }
1398  }
1399 }
1400 
1408 {
1409  DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1410 
1411  /* Update error code */
1412  hdcmi->ErrorCode |= HAL_DCMI_ERROR_DMA;
1413 
1414  /* Change DCMI state */
1415  hdcmi->State = HAL_DCMI_STATE_READY;
1416 
1417  /* DCMI error Callback */
1418 #if (USE_HAL_DCMI_REGISTER_CALLBACKS == 1)
1419  /*Call registered DCMI error callback*/
1420  hdcmi->ErrorCallback(hdcmi);
1421 #else
1422  HAL_DCMI_ErrorCallback(hdcmi);
1423 #endif /* USE_HAL_DCMI_REGISTER_CALLBACKS */
1424 }
1425 
1439 static uint32_t DCMI_TransferSize(uint32_t InputSize)
1440 {
1441  uint32_t j = 1;
1442  uint32_t temp = InputSize;
1443  uint32_t aPrime[NPRIME] = {0};
1444  uint32_t output = 2; /* Want a result which is an even number */
1445  uint32_t PrimeArray[NPRIME] = { 1UL, 2UL, 3UL, 5UL,
1446  7UL, 11UL, 13UL, 17UL,
1447  19UL, 23UL, 29UL, 31UL,
1448  37UL, 41UL, 43UL, 47UL};
1449 
1450 
1451  /* Develop InputSize in product of prime numbers */
1452 
1453  while (j < NPRIME)
1454  {
1455  if (temp < PrimeArray[j])
1456  {
1457  break;
1458  }
1459  while ((temp % PrimeArray[j]) == 0U)
1460  {
1461  aPrime[j]++;
1462  temp /= PrimeArray[j];
1463  }
1464  j++;
1465  }
1466 
1467  /* Search for the biggest even divisor less or equal to 0xFFFE = 65534 */
1468  aPrime[1] -= 1U; /* output is initialized to 2, so don't count dividor 2 twice */
1469 
1470  /* The algorithm below yields a sub-optimal solution
1471  but in an acceptable time. */
1472  j = NPRIME-1U;
1473  while ((j > 0U) && (output <= 0xFFFEU))
1474  {
1475  while (aPrime[j] > 0U)
1476  {
1477  if ((output * PrimeArray[j]) > 0xFFFEU)
1478  {
1479  break;
1480  }
1481  else
1482  {
1483  output *= PrimeArray[j];
1484  aPrime[j]--;
1485  }
1486  }
1487  j--;
1488  }
1489 
1490 
1491 
1492  return output;
1493 }
1494 
1495 
1508 #endif /* DCMI */
1509 #endif /* HAL_DCMI_MODULE_ENABLED */
1510 
1511 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
Frame Event callback.
void(* MspInitCallback)(struct __DCMI_HandleTypeDef *hdcmi)
HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef *hdcmi)
Disable DCMI capture in DMA mode.
HAL_StatusTypeDef HAL_DCMI_ConfigSyncUnmask(DCMI_HandleTypeDef *hdcmi, DCMI_SyncUnmaskTypeDef *SyncUnmask)
Set embedded synchronization delimiters unmasks.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
void(* MspDeInitCallback)(struct __DCMI_HandleTypeDef *hdcmi)
void(* ErrorCallback)(struct __DCMI_HandleTypeDef *hdcmi)
void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
Error DCMI callback.
DCMI Embedded Synchronisation CODE Init structure definition.
void HAL_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
Initialize the DCMI MSP.
HAL_StatusTypeDef HAL_DCMI_RegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID, pDCMI_CallbackTypeDef pCallback)
DCMI Callback registering.
void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
Line Event callback.
void(* FrameEventCallback)(struct __DCMI_HandleTypeDef *hdcmi)
DMA handle Structure definition.
static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
DMA conversion complete callback.
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
__IO HAL_DCMI_StateTypeDef State
This file contains all the functions prototypes for the HAL module driver.
DCMI_CodesInitTypeDef SynchroCode
DMA_HandleTypeDef * DMAM2M_Handle
HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
Enable DCMI capture in DMA mode.
DCMI handle Structure definition.
void(* pDCMI_CallbackTypeDef)(DCMI_HandleTypeDef *hdcmi)
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
__HAL_UNLOCK(hrtc)
HAL_StatusTypeDef HAL_DCMI_ConfigCrop(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize)
Configure the DCMI crop window coordinates.
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi)
Return the DCMI state.
DMA_InitTypeDef Init
void(* LineEventCallback)(struct __DCMI_HandleTypeDef *hdcmi)
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Start the DMA Transfer with interrupt enabled.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
__HAL_LOCK(hrtc)
void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
Handle DCMI interrupt request.
void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
VSYNC Event callback.
return HAL_OK
DMA_HandleTypeDef * DMA_Handle
HAL_StatusTypeDef HAL_DCMI_EnableCrop(DCMI_HandleTypeDef *hdcmi)
Enable the crop feature.
HAL_DCMI_CallbackIDTypeDef
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Abort the DMA Transfer.
HAL_DCMI_StateTypeDef
HAL DCMI State structures definition.
HAL_StatusTypeDef HAL_DCMI_DisableCrop(DCMI_HandleTypeDef *hdcmi)
Disable the crop feature.
static void DCMI_DMAError(DMA_HandleTypeDef *hdma)
DMA error callback.
HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi)
De-initialize the DCMI peripheral, reset control registers to their default values.
HAL_StatusTypeDef HAL_DCMI_Suspend(DCMI_HandleTypeDef *hdcmi)
Suspend DCMI capture.
static uint32_t DCMI_TransferSize(uint32_t InputSize)
Sub-buffers transfer size computation.
static void DCMI_DMAHalfXferCplt(DMA_HandleTypeDef *hdma)
DMA Half Transfer complete callback.
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef *hdcmi)
De-initialize the DCMI MSP.
HAL_StatusTypeDef HAL_DCMI_Resume(DCMI_HandleTypeDef *hdcmi)
Resume DCMI capture.
uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi)
Return the DCMI error code.
HAL_StatusTypeDef HAL_DCMI_UnRegisterCallback(DCMI_HandleTypeDef *hdcmi, HAL_DCMI_CallbackIDTypeDef CallbackID)
DCMI Callback Unregistering.
HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
Initialize the DCMI according to the specified parameters in the DCMI_InitTypeDef and create the asso...
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))
void(* VsyncEventCallback)(struct __DCMI_HandleTypeDef *hdcmi)