STM32F4xx_HAL_Driver  1.8.3
stm32f4xx_hal_fmpi2c.c
Go to the documentation of this file.
1 
322 /* Includes ------------------------------------------------------------------*/
323 #include "stm32f4xx_hal.h"
324 
334 #ifdef HAL_FMPI2C_MODULE_ENABLED
335 #if defined(FMPI2C_CR1_PE)
336 
337 /* Private typedef -----------------------------------------------------------*/
338 /* Private define ------------------------------------------------------------*/
339 
343 #define TIMING_CLEAR_MASK (0xF0FFFFFFU)
344 #define FMPI2C_TIMEOUT_ADDR (10000U)
345 #define FMPI2C_TIMEOUT_BUSY (25U)
346 #define FMPI2C_TIMEOUT_DIR (25U)
347 #define FMPI2C_TIMEOUT_RXNE (25U)
348 #define FMPI2C_TIMEOUT_STOPF (25U)
349 #define FMPI2C_TIMEOUT_TC (25U)
350 #define FMPI2C_TIMEOUT_TCR (25U)
351 #define FMPI2C_TIMEOUT_TXIS (25U)
352 #define FMPI2C_TIMEOUT_FLAG (25U)
354 #define MAX_NBYTE_SIZE 255U
355 #define SLAVE_ADDR_SHIFT 7U
356 #define SLAVE_ADDR_MSK 0x06U
357 
358 /* Private define for @ref PreviousState usage */
359 #define FMPI2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_FMPI2C_STATE_BUSY_TX | \
360  (uint32_t)HAL_FMPI2C_STATE_BUSY_RX) & \
361  (uint32_t)(~((uint32_t)HAL_FMPI2C_STATE_READY))))
363 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE))
365 #define FMPI2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
366  (uint32_t)HAL_FMPI2C_MODE_MASTER))
368 #define FMPI2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
369  (uint32_t)HAL_FMPI2C_MODE_MASTER))
371 #define FMPI2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
372  (uint32_t)HAL_FMPI2C_MODE_SLAVE))
374 #define FMPI2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
375  (uint32_t)HAL_FMPI2C_MODE_SLAVE))
377 #define FMPI2C_STATE_MEM_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
378  (uint32_t)HAL_FMPI2C_MODE_MEM))
380 #define FMPI2C_STATE_MEM_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
381  (uint32_t)HAL_FMPI2C_MODE_MEM))
385 /* Private define to centralize the enable/disable of Interrupts */
386 #define FMPI2C_XFER_TX_IT (uint16_t)(0x0001U)
388 #define FMPI2C_XFER_RX_IT (uint16_t)(0x0002U)
390 #define FMPI2C_XFER_LISTEN_IT (uint16_t)(0x8000U)
393 #define FMPI2C_XFER_ERROR_IT (uint16_t)(0x0010U)
395 #define FMPI2C_XFER_CPLT_IT (uint16_t)(0x0020U)
396 #define FMPI2C_XFER_RELOAD_IT (uint16_t)(0x0040U)
398 /* Private define Sequential Transfer Options default/reset value */
399 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U)
404 /* Private macros ------------------------------------------------------------*/
408 /* Macro to get remaining data to transfer on DMA side */
409 #define FMPI2C_GET_DMA_REMAIN_DATA(__HANDLE__) __HAL_DMA_GET_COUNTER(__HANDLE__)
414 /* Private variables ---------------------------------------------------------*/
415 /* Private function prototypes -----------------------------------------------*/
416 
420 /* Private functions to handle DMA transfer */
421 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
422 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
423 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
424 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
425 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
426 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma);
427 
428 
429 /* Private functions to handle IT transfer */
430 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
431 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
432 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
433 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
434 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
435 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
436 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode);
437 
438 /* Private functions to handle IT transfer */
439 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
440  uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
441  uint32_t Tickstart);
442 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
443  uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
444  uint32_t Tickstart);
445 
446 /* Private functions for FMPI2C transfer IRQ handler */
447 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
448  uint32_t ITSources);
449 static HAL_StatusTypeDef FMPI2C_Mem_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
450  uint32_t ITSources);
451 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
452  uint32_t ITSources);
453 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
454  uint32_t ITSources);
455 static HAL_StatusTypeDef FMPI2C_Mem_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
456  uint32_t ITSources);
457 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
458  uint32_t ITSources);
459 
460 /* Private functions to handle flags during polling transfer */
461 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
462  uint32_t Timeout, uint32_t Tickstart);
463 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
464  uint32_t Tickstart);
465 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
466  uint32_t Tickstart);
467 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
468  uint32_t Tickstart);
469 static HAL_StatusTypeDef FMPI2C_IsErrorOccurred(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
470  uint32_t Tickstart);
471 
472 /* Private functions to centralize the enable/disable of Interrupts */
473 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
474 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
475 
476 /* Private function to treat different error callback */
477 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c);
478 
479 /* Private function to flush TXDR register */
480 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c);
481 
482 /* Private function to handle start, restart or stop a transfer */
483 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
484  uint32_t Request);
485 
486 /* Private function to Convert Specific options */
487 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c);
492 /* Exported functions --------------------------------------------------------*/
493 
536 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
537 {
538  /* Check the FMPI2C handle allocation */
539  if (hfmpi2c == NULL)
540  {
541  return HAL_ERROR;
542  }
543 
544  /* Check the parameters */
545  assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
546  assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
547  assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
548  assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
549  assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
550  assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
551  assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
552  assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
553 
554  if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
555  {
556  /* Allocate lock resource and initialize it */
557  hfmpi2c->Lock = HAL_UNLOCKED;
558 
559 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
560  /* Init the FMPI2C Callback settings */
561  hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
562  hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
563  hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
564  hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
565  hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
566  hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
567  hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
568  hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */
569  hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
570  hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */
571 
572  if (hfmpi2c->MspInitCallback == NULL)
573  {
574  hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
575  }
576 
577  /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
578  hfmpi2c->MspInitCallback(hfmpi2c);
579 #else
580  /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
581  HAL_FMPI2C_MspInit(hfmpi2c);
582 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
583  }
584 
585  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
586 
587  /* Disable the selected FMPI2C peripheral */
588  __HAL_FMPI2C_DISABLE(hfmpi2c);
589 
590  /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
591  /* Configure FMPI2Cx: Frequency range */
592  hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
593 
594  /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
595  /* Disable Own Address1 before set the Own Address1 configuration */
596  hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
597 
598  /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
599  if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
600  {
601  hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
602  }
603  else /* FMPI2C_ADDRESSINGMODE_10BIT */
604  {
605  hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
606  }
607 
608  /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
609  /* Configure FMPI2Cx: Addressing Master mode */
610  if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
611  {
612  SET_BIT(hfmpi2c->Instance->CR2, FMPI2C_CR2_ADD10);
613  }
614  else
615  {
616  /* Clear the FMPI2C ADD10 bit */
617  CLEAR_BIT(hfmpi2c->Instance->CR2, FMPI2C_CR2_ADD10);
618  }
619  /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
620  hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
621 
622  /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
623  /* Disable Own Address2 before set the Own Address2 configuration */
624  hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE;
625 
626  /* Configure FMPI2Cx: Dual mode and Own Address2 */
627  hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | \
628  (hfmpi2c->Init.OwnAddress2Masks << 8));
629 
630  /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
631  /* Configure FMPI2Cx: Generalcall and NoStretch mode */
632  hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
633 
634  /* Enable the selected FMPI2C peripheral */
635  __HAL_FMPI2C_ENABLE(hfmpi2c);
636 
637  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
638  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
639  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
640  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
641 
642  return HAL_OK;
643 }
644 
651 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
652 {
653  /* Check the FMPI2C handle allocation */
654  if (hfmpi2c == NULL)
655  {
656  return HAL_ERROR;
657  }
658 
659  /* Check the parameters */
660  assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
661 
662  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
663 
664  /* Disable the FMPI2C Peripheral Clock */
665  __HAL_FMPI2C_DISABLE(hfmpi2c);
666 
667 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
668  if (hfmpi2c->MspDeInitCallback == NULL)
669  {
670  hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
671  }
672 
673  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
674  hfmpi2c->MspDeInitCallback(hfmpi2c);
675 #else
676  /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
677  HAL_FMPI2C_MspDeInit(hfmpi2c);
678 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
679 
680  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
681  hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
682  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
683  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
684 
685  /* Release Lock */
686  __HAL_UNLOCK(hfmpi2c);
687 
688  return HAL_OK;
689 }
690 
697 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
698 {
699  /* Prevent unused argument(s) compilation warning */
700  UNUSED(hfmpi2c);
701 
702  /* NOTE : This function should not be modified, when the callback is needed,
703  the HAL_FMPI2C_MspInit could be implemented in the user file
704  */
705 }
706 
713 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
714 {
715  /* Prevent unused argument(s) compilation warning */
716  UNUSED(hfmpi2c);
717 
718  /* NOTE : This function should not be modified, when the callback is needed,
719  the HAL_FMPI2C_MspDeInit could be implemented in the user file
720  */
721 }
722 
723 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
748  pFMPI2C_CallbackTypeDef pCallback)
749 {
750  HAL_StatusTypeDef status = HAL_OK;
751 
752  if (pCallback == NULL)
753  {
754  /* Update the error code */
755  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
756 
757  return HAL_ERROR;
758  }
759 
760  if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
761  {
762  switch (CallbackID)
763  {
765  hfmpi2c->MasterTxCpltCallback = pCallback;
766  break;
767 
769  hfmpi2c->MasterRxCpltCallback = pCallback;
770  break;
771 
773  hfmpi2c->SlaveTxCpltCallback = pCallback;
774  break;
775 
777  hfmpi2c->SlaveRxCpltCallback = pCallback;
778  break;
779 
781  hfmpi2c->ListenCpltCallback = pCallback;
782  break;
783 
785  hfmpi2c->MemTxCpltCallback = pCallback;
786  break;
787 
789  hfmpi2c->MemRxCpltCallback = pCallback;
790  break;
791 
793  hfmpi2c->ErrorCallback = pCallback;
794  break;
795 
797  hfmpi2c->AbortCpltCallback = pCallback;
798  break;
799 
801  hfmpi2c->MspInitCallback = pCallback;
802  break;
803 
805  hfmpi2c->MspDeInitCallback = pCallback;
806  break;
807 
808  default :
809  /* Update the error code */
810  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
811 
812  /* Return error status */
813  status = HAL_ERROR;
814  break;
815  }
816  }
817  else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
818  {
819  switch (CallbackID)
820  {
822  hfmpi2c->MspInitCallback = pCallback;
823  break;
824 
826  hfmpi2c->MspDeInitCallback = pCallback;
827  break;
828 
829  default :
830  /* Update the error code */
831  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
832 
833  /* Return error status */
834  status = HAL_ERROR;
835  break;
836  }
837  }
838  else
839  {
840  /* Update the error code */
841  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
842 
843  /* Return error status */
844  status = HAL_ERROR;
845  }
846 
847  return status;
848 }
849 
874 {
875  HAL_StatusTypeDef status = HAL_OK;
876 
877  if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
878  {
879  switch (CallbackID)
880  {
882  hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
883  break;
884 
886  hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
887  break;
888 
890  hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
891  break;
892 
894  hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
895  break;
896 
898  hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
899  break;
900 
902  hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
903  break;
904 
906  hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
907  break;
908 
910  hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */
911  break;
912 
914  hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
915  break;
916 
918  hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
919  break;
920 
922  hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
923  break;
924 
925  default :
926  /* Update the error code */
927  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
928 
929  /* Return error status */
930  status = HAL_ERROR;
931  break;
932  }
933  }
934  else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
935  {
936  switch (CallbackID)
937  {
939  hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
940  break;
941 
943  hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
944  break;
945 
946  default :
947  /* Update the error code */
948  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
949 
950  /* Return error status */
951  status = HAL_ERROR;
952  break;
953  }
954  }
955  else
956  {
957  /* Update the error code */
958  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
959 
960  /* Return error status */
961  status = HAL_ERROR;
962  }
963 
964  return status;
965 }
966 
976 {
977  HAL_StatusTypeDef status = HAL_OK;
978 
979  if (pCallback == NULL)
980  {
981  /* Update the error code */
982  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
983 
984  return HAL_ERROR;
985  }
986 
987  if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
988  {
989  hfmpi2c->AddrCallback = pCallback;
990  }
991  else
992  {
993  /* Update the error code */
994  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
995 
996  /* Return error status */
997  status = HAL_ERROR;
998  }
999 
1000  return status;
1001 }
1002 
1010 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c)
1011 {
1012  HAL_StatusTypeDef status = HAL_OK;
1013 
1014  if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
1015  {
1016  hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */
1017  }
1018  else
1019  {
1020  /* Update the error code */
1021  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
1022 
1023  /* Return error status */
1024  status = HAL_ERROR;
1025  }
1026 
1027  return status;
1028 }
1029 
1030 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
1031 
1120 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1121  uint16_t Size, uint32_t Timeout)
1122 {
1123  uint32_t tickstart;
1124  uint32_t xfermode;
1125 
1126  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1127  {
1128  /* Process Locked */
1129  __HAL_LOCK(hfmpi2c);
1130 
1131  /* Init tickstart for timeout management*/
1132  tickstart = HAL_GetTick();
1133 
1134  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1135  {
1136  return HAL_ERROR;
1137  }
1138 
1139  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1140  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1141  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1142 
1143  /* Prepare transfer parameters */
1144  hfmpi2c->pBuffPtr = pData;
1145  hfmpi2c->XferCount = Size;
1146  hfmpi2c->XferISR = NULL;
1147 
1148  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1149  {
1150  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1151  xfermode = FMPI2C_RELOAD_MODE;
1152  }
1153  else
1154  {
1155  hfmpi2c->XferSize = hfmpi2c->XferCount;
1156  xfermode = FMPI2C_AUTOEND_MODE;
1157  }
1158 
1159  if (hfmpi2c->XferSize > 0U)
1160  {
1161  /* Preload TX register */
1162  /* Write data to TXDR */
1163  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1164 
1165  /* Increment Buffer pointer */
1166  hfmpi2c->pBuffPtr++;
1167 
1168  hfmpi2c->XferCount--;
1169  hfmpi2c->XferSize--;
1170 
1171  /* Send Slave Address */
1172  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1173  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)(hfmpi2c->XferSize + 1U), xfermode,
1174  FMPI2C_GENERATE_START_WRITE);
1175  }
1176  else
1177  {
1178  /* Send Slave Address */
1179  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1180  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode,
1181  FMPI2C_GENERATE_START_WRITE);
1182  }
1183 
1184  while (hfmpi2c->XferCount > 0U)
1185  {
1186  /* Wait until TXIS flag is set */
1187  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1188  {
1189  return HAL_ERROR;
1190  }
1191  /* Write data to TXDR */
1192  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1193 
1194  /* Increment Buffer pointer */
1195  hfmpi2c->pBuffPtr++;
1196 
1197  hfmpi2c->XferCount--;
1198  hfmpi2c->XferSize--;
1199 
1200  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
1201  {
1202  /* Wait until TCR flag is set */
1203  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1204  {
1205  return HAL_ERROR;
1206  }
1207 
1208  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1209  {
1210  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1211  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1212  FMPI2C_NO_STARTSTOP);
1213  }
1214  else
1215  {
1216  hfmpi2c->XferSize = hfmpi2c->XferCount;
1217  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1218  FMPI2C_NO_STARTSTOP);
1219  }
1220  }
1221  }
1222 
1223  /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1224  /* Wait until STOPF flag is set */
1225  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1226  {
1227  return HAL_ERROR;
1228  }
1229 
1230  /* Clear STOP Flag */
1231  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1232 
1233  /* Clear Configuration Register 2 */
1234  FMPI2C_RESET_CR2(hfmpi2c);
1235 
1236  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1237  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1238 
1239  /* Process Unlocked */
1240  __HAL_UNLOCK(hfmpi2c);
1241 
1242  return HAL_OK;
1243  }
1244  else
1245  {
1246  return HAL_BUSY;
1247  }
1248 }
1249 
1261 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1262  uint16_t Size, uint32_t Timeout)
1263 {
1264  uint32_t tickstart;
1265 
1266  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1267  {
1268  /* Process Locked */
1269  __HAL_LOCK(hfmpi2c);
1270 
1271  /* Init tickstart for timeout management*/
1272  tickstart = HAL_GetTick();
1273 
1274  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1275  {
1276  return HAL_ERROR;
1277  }
1278 
1279  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1280  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1281  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1282 
1283  /* Prepare transfer parameters */
1284  hfmpi2c->pBuffPtr = pData;
1285  hfmpi2c->XferCount = Size;
1286  hfmpi2c->XferISR = NULL;
1287 
1288  /* Send Slave Address */
1289  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1290  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1291  {
1292  hfmpi2c->XferSize = 1U;
1293  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1294  FMPI2C_GENERATE_START_READ);
1295  }
1296  else
1297  {
1298  hfmpi2c->XferSize = hfmpi2c->XferCount;
1299  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1300  FMPI2C_GENERATE_START_READ);
1301  }
1302 
1303  while (hfmpi2c->XferCount > 0U)
1304  {
1305  /* Wait until RXNE flag is set */
1306  if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1307  {
1308  return HAL_ERROR;
1309  }
1310 
1311  /* Read data from RXDR */
1312  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1313 
1314  /* Increment Buffer pointer */
1315  hfmpi2c->pBuffPtr++;
1316 
1317  hfmpi2c->XferSize--;
1318  hfmpi2c->XferCount--;
1319 
1320  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
1321  {
1322  /* Wait until TCR flag is set */
1323  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1324  {
1325  return HAL_ERROR;
1326  }
1327 
1328  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1329  {
1330  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1331  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1332  FMPI2C_NO_STARTSTOP);
1333  }
1334  else
1335  {
1336  hfmpi2c->XferSize = hfmpi2c->XferCount;
1337  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1338  FMPI2C_NO_STARTSTOP);
1339  }
1340  }
1341  }
1342 
1343  /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1344  /* Wait until STOPF flag is set */
1345  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1346  {
1347  return HAL_ERROR;
1348  }
1349 
1350  /* Clear STOP Flag */
1351  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1352 
1353  /* Clear Configuration Register 2 */
1354  FMPI2C_RESET_CR2(hfmpi2c);
1355 
1356  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1357  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1358 
1359  /* Process Unlocked */
1360  __HAL_UNLOCK(hfmpi2c);
1361 
1362  return HAL_OK;
1363  }
1364  else
1365  {
1366  return HAL_BUSY;
1367  }
1368 }
1369 
1379 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
1380  uint32_t Timeout)
1381 {
1382  uint32_t tickstart;
1383  uint16_t tmpXferCount;
1384  HAL_StatusTypeDef error;
1385 
1386  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1387  {
1388  if ((pData == NULL) || (Size == 0U))
1389  {
1390  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
1391  return HAL_ERROR;
1392  }
1393  /* Process Locked */
1394  __HAL_LOCK(hfmpi2c);
1395 
1396  /* Init tickstart for timeout management*/
1397  tickstart = HAL_GetTick();
1398 
1399  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1400  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1401  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1402 
1403  /* Prepare transfer parameters */
1404  hfmpi2c->pBuffPtr = pData;
1405  hfmpi2c->XferCount = Size;
1406  hfmpi2c->XferISR = NULL;
1407 
1408  /* Enable Address Acknowledge */
1409  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1410 
1411  /* Wait until ADDR flag is set */
1412  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1413  {
1414  /* Disable Address Acknowledge */
1415  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1416  return HAL_ERROR;
1417  }
1418 
1419  /* Preload TX data if no stretch enable */
1420  if (hfmpi2c->Init.NoStretchMode == FMPI2C_NOSTRETCH_ENABLE)
1421  {
1422  /* Preload TX register */
1423  /* Write data to TXDR */
1424  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1425 
1426  /* Increment Buffer pointer */
1427  hfmpi2c->pBuffPtr++;
1428 
1429  hfmpi2c->XferCount--;
1430  }
1431 
1432  /* Clear ADDR flag */
1433  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1434 
1435  /* If 10bit addressing mode is selected */
1436  if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
1437  {
1438  /* Wait until ADDR flag is set */
1439  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1440  {
1441  /* Disable Address Acknowledge */
1442  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1443  return HAL_ERROR;
1444  }
1445 
1446  /* Clear ADDR flag */
1447  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1448  }
1449 
1450  /* Wait until DIR flag is set Transmitter mode */
1451  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
1452  {
1453  /* Disable Address Acknowledge */
1454  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1455  return HAL_ERROR;
1456  }
1457 
1458  while (hfmpi2c->XferCount > 0U)
1459  {
1460  /* Wait until TXIS flag is set */
1461  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1462  {
1463  /* Disable Address Acknowledge */
1464  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1465  return HAL_ERROR;
1466  }
1467 
1468  /* Write data to TXDR */
1469  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1470 
1471  /* Increment Buffer pointer */
1472  hfmpi2c->pBuffPtr++;
1473 
1474  hfmpi2c->XferCount--;
1475  }
1476 
1477  /* Wait until AF flag is set */
1478  error = FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_AF, RESET, Timeout, tickstart);
1479 
1480  if (error != HAL_OK)
1481  {
1482  /* Check that FMPI2C transfer finished */
1483  /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
1484  /* Mean XferCount == 0 */
1485 
1486  tmpXferCount = hfmpi2c->XferCount;
1487  if ((hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) && (tmpXferCount == 0U))
1488  {
1489  /* Reset ErrorCode to NONE */
1490  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1491  }
1492  else
1493  {
1494  /* Disable Address Acknowledge */
1495  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1496  return HAL_ERROR;
1497  }
1498  }
1499  else
1500  {
1501  /* Flush TX register */
1502  FMPI2C_Flush_TXDR(hfmpi2c);
1503 
1504  /* Clear AF flag */
1505  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
1506 
1507  /* Wait until STOP flag is set */
1508  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1509  {
1510  /* Disable Address Acknowledge */
1511  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1512 
1513  return HAL_ERROR;
1514  }
1515 
1516  /* Clear STOP flag */
1517  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1518  }
1519 
1520  /* Wait until BUSY flag is reset */
1521  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1522  {
1523  /* Disable Address Acknowledge */
1524  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1525  return HAL_ERROR;
1526  }
1527 
1528  /* Disable Address Acknowledge */
1529  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1530 
1531  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1532  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1533 
1534  /* Process Unlocked */
1535  __HAL_UNLOCK(hfmpi2c);
1536 
1537  return HAL_OK;
1538  }
1539  else
1540  {
1541  return HAL_BUSY;
1542  }
1543 }
1544 
1554 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
1555  uint32_t Timeout)
1556 {
1557  uint32_t tickstart;
1558 
1559  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1560  {
1561  if ((pData == NULL) || (Size == 0U))
1562  {
1563  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
1564  return HAL_ERROR;
1565  }
1566  /* Process Locked */
1567  __HAL_LOCK(hfmpi2c);
1568 
1569  /* Init tickstart for timeout management*/
1570  tickstart = HAL_GetTick();
1571 
1572  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1573  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1574  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1575 
1576  /* Prepare transfer parameters */
1577  hfmpi2c->pBuffPtr = pData;
1578  hfmpi2c->XferCount = Size;
1579  hfmpi2c->XferSize = hfmpi2c->XferCount;
1580  hfmpi2c->XferISR = NULL;
1581 
1582  /* Enable Address Acknowledge */
1583  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1584 
1585  /* Wait until ADDR flag is set */
1586  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1587  {
1588  /* Disable Address Acknowledge */
1589  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1590  return HAL_ERROR;
1591  }
1592 
1593  /* Clear ADDR flag */
1594  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1595 
1596  /* Wait until DIR flag is reset Receiver mode */
1597  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1598  {
1599  /* Disable Address Acknowledge */
1600  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1601  return HAL_ERROR;
1602  }
1603 
1604  while (hfmpi2c->XferCount > 0U)
1605  {
1606  /* Wait until RXNE flag is set */
1607  if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1608  {
1609  /* Disable Address Acknowledge */
1610  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1611 
1612  /* Store Last receive data if any */
1613  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
1614  {
1615  /* Read data from RXDR */
1616  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1617 
1618  /* Increment Buffer pointer */
1619  hfmpi2c->pBuffPtr++;
1620 
1621  hfmpi2c->XferCount--;
1622  hfmpi2c->XferSize--;
1623  }
1624 
1625  return HAL_ERROR;
1626  }
1627 
1628  /* Read data from RXDR */
1629  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1630 
1631  /* Increment Buffer pointer */
1632  hfmpi2c->pBuffPtr++;
1633 
1634  hfmpi2c->XferCount--;
1635  hfmpi2c->XferSize--;
1636  }
1637 
1638  /* Wait until STOP flag is set */
1639  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1640  {
1641  /* Disable Address Acknowledge */
1642  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1643  return HAL_ERROR;
1644  }
1645 
1646  /* Clear STOP flag */
1647  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1648 
1649  /* Wait until BUSY flag is reset */
1650  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1651  {
1652  /* Disable Address Acknowledge */
1653  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1654  return HAL_ERROR;
1655  }
1656 
1657  /* Disable Address Acknowledge */
1658  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1659 
1660  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1661  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1662 
1663  /* Process Unlocked */
1664  __HAL_UNLOCK(hfmpi2c);
1665 
1666  return HAL_OK;
1667  }
1668  else
1669  {
1670  return HAL_BUSY;
1671  }
1672 }
1673 
1684 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1685  uint16_t Size)
1686 {
1687  uint32_t xfermode;
1688 
1689  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1690  {
1691  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1692  {
1693  return HAL_BUSY;
1694  }
1695 
1696  /* Process Locked */
1697  __HAL_LOCK(hfmpi2c);
1698 
1699  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1700  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1701  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1702 
1703  /* Prepare transfer parameters */
1704  hfmpi2c->pBuffPtr = pData;
1705  hfmpi2c->XferCount = Size;
1706  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1707  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1708 
1709  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1710  {
1711  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1712  xfermode = FMPI2C_RELOAD_MODE;
1713  }
1714  else
1715  {
1716  hfmpi2c->XferSize = hfmpi2c->XferCount;
1717  xfermode = FMPI2C_AUTOEND_MODE;
1718  }
1719 
1720  /* Send Slave Address */
1721  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1722  if (hfmpi2c->XferSize > 0U)
1723  {
1724  /* Preload TX register */
1725  /* Write data to TXDR */
1726  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1727 
1728  /* Increment Buffer pointer */
1729  hfmpi2c->pBuffPtr++;
1730 
1731  hfmpi2c->XferCount--;
1732  hfmpi2c->XferSize--;
1733 
1734  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)(hfmpi2c->XferSize + 1U), xfermode,
1735  FMPI2C_GENERATE_START_WRITE);
1736  }
1737  else
1738  {
1739  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode,
1740  FMPI2C_GENERATE_START_WRITE);
1741  }
1742 
1743  /* Process Unlocked */
1744  __HAL_UNLOCK(hfmpi2c);
1745 
1746  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1747  to avoid the risk of FMPI2C interrupt handle execution before current
1748  process unlock */
1749 
1750  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1751  /* possible to enable all of these */
1752  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1753  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1754  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1755 
1756  return HAL_OK;
1757  }
1758  else
1759  {
1760  return HAL_BUSY;
1761  }
1762 }
1763 
1774 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1775  uint16_t Size)
1776 {
1777  uint32_t xfermode;
1778 
1779  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1780  {
1781  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1782  {
1783  return HAL_BUSY;
1784  }
1785 
1786  /* Process Locked */
1787  __HAL_LOCK(hfmpi2c);
1788 
1789  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1790  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1791  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1792 
1793  /* Prepare transfer parameters */
1794  hfmpi2c->pBuffPtr = pData;
1795  hfmpi2c->XferCount = Size;
1796  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1797  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1798 
1799  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1800  {
1801  hfmpi2c->XferSize = 1U;
1802  xfermode = FMPI2C_RELOAD_MODE;
1803  }
1804  else
1805  {
1806  hfmpi2c->XferSize = hfmpi2c->XferCount;
1807  xfermode = FMPI2C_AUTOEND_MODE;
1808  }
1809 
1810  /* Send Slave Address */
1811  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1812  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
1813 
1814  /* Process Unlocked */
1815  __HAL_UNLOCK(hfmpi2c);
1816 
1817  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1818  to avoid the risk of FMPI2C interrupt handle execution before current
1819  process unlock */
1820 
1821  /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1822  /* possible to enable all of these */
1823  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1824  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1825  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
1826 
1827  return HAL_OK;
1828  }
1829  else
1830  {
1831  return HAL_BUSY;
1832  }
1833 }
1834 
1843 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1844 {
1845  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1846  {
1847  /* Process Locked */
1848  __HAL_LOCK(hfmpi2c);
1849 
1850  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1852  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1853 
1854  /* Enable Address Acknowledge */
1855  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1856 
1857  /* Prepare transfer parameters */
1858  hfmpi2c->pBuffPtr = pData;
1859  hfmpi2c->XferCount = Size;
1860  hfmpi2c->XferSize = hfmpi2c->XferCount;
1861  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1862  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1863 
1864  /* Preload TX data if no stretch enable */
1865  if (hfmpi2c->Init.NoStretchMode == FMPI2C_NOSTRETCH_ENABLE)
1866  {
1867  /* Preload TX register */
1868  /* Write data to TXDR */
1869  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1870 
1871  /* Increment Buffer pointer */
1872  hfmpi2c->pBuffPtr++;
1873 
1874  hfmpi2c->XferCount--;
1875  hfmpi2c->XferSize--;
1876  }
1877 
1878  /* Process Unlocked */
1879  __HAL_UNLOCK(hfmpi2c);
1880 
1881  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1882  to avoid the risk of FMPI2C interrupt handle execution before current
1883  process unlock */
1884 
1885  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1886  /* possible to enable all of these */
1887  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1888  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1889  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
1890 
1891  return HAL_OK;
1892  }
1893  else
1894  {
1895  return HAL_BUSY;
1896  }
1897 }
1898 
1907 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1908 {
1909  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1910  {
1911  /* Process Locked */
1912  __HAL_LOCK(hfmpi2c);
1913 
1914  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1916  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1917 
1918  /* Enable Address Acknowledge */
1919  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1920 
1921  /* Prepare transfer parameters */
1922  hfmpi2c->pBuffPtr = pData;
1923  hfmpi2c->XferCount = Size;
1924  hfmpi2c->XferSize = hfmpi2c->XferCount;
1925  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1926  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1927 
1928  /* Process Unlocked */
1929  __HAL_UNLOCK(hfmpi2c);
1930 
1931  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1932  to avoid the risk of FMPI2C interrupt handle execution before current
1933  process unlock */
1934 
1935  /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1936  /* possible to enable all of these */
1937  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1938  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1939  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
1940 
1941  return HAL_OK;
1942  }
1943  else
1944  {
1945  return HAL_BUSY;
1946  }
1947 }
1948 
1959 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1960  uint16_t Size)
1961 {
1962  uint32_t xfermode;
1963  HAL_StatusTypeDef dmaxferstatus;
1964  uint32_t sizetoxfer = 0U;
1965 
1966  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1967  {
1968  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1969  {
1970  return HAL_BUSY;
1971  }
1972 
1973  /* Process Locked */
1974  __HAL_LOCK(hfmpi2c);
1975 
1976  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1977  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1978  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1979 
1980  /* Prepare transfer parameters */
1981  hfmpi2c->pBuffPtr = pData;
1982  hfmpi2c->XferCount = Size;
1983  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1984  hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
1985 
1986  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1987  {
1988  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1989  xfermode = FMPI2C_RELOAD_MODE;
1990  }
1991  else
1992  {
1993  hfmpi2c->XferSize = hfmpi2c->XferCount;
1994  xfermode = FMPI2C_AUTOEND_MODE;
1995  }
1996 
1997  if (hfmpi2c->XferSize > 0U)
1998  {
1999  /* Preload TX register */
2000  /* Write data to TXDR */
2001  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
2002 
2003  /* Increment Buffer pointer */
2004  hfmpi2c->pBuffPtr++;
2005 
2006  sizetoxfer = hfmpi2c->XferSize;
2007  hfmpi2c->XferCount--;
2008  hfmpi2c->XferSize--;
2009  }
2010 
2011  if (hfmpi2c->XferSize > 0U)
2012  {
2013  if (hfmpi2c->hdmatx != NULL)
2014  {
2015  /* Set the FMPI2C DMA transfer complete callback */
2016  hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
2017 
2018  /* Set the DMA error callback */
2019  hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2020 
2021  /* Set the unused DMA callbacks to NULL */
2022  hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
2023  hfmpi2c->hdmatx->XferAbortCallback = NULL;
2024 
2025  /* Enable the DMA stream */
2026  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr,
2027  (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
2028  }
2029  else
2030  {
2031  /* Update FMPI2C state */
2032  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2033  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2034 
2035  /* Update FMPI2C error code */
2036  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2037 
2038  /* Process Unlocked */
2039  __HAL_UNLOCK(hfmpi2c);
2040 
2041  return HAL_ERROR;
2042  }
2043 
2044  if (dmaxferstatus == HAL_OK)
2045  {
2046  /* Send Slave Address */
2047  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2048  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)(hfmpi2c->XferSize + 1U),
2049  xfermode, FMPI2C_GENERATE_START_WRITE);
2050 
2051  /* Update XferCount value */
2052  hfmpi2c->XferCount -= hfmpi2c->XferSize;
2053 
2054  /* Process Unlocked */
2055  __HAL_UNLOCK(hfmpi2c);
2056 
2057  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2058  to avoid the risk of FMPI2C interrupt handle execution before current
2059  process unlock */
2060  /* Enable ERR and NACK interrupts */
2061  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2062 
2063  /* Enable DMA Request */
2064  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2065  }
2066  else
2067  {
2068  /* Update FMPI2C state */
2069  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2070  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2071 
2072  /* Update FMPI2C error code */
2073  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2074 
2075  /* Process Unlocked */
2076  __HAL_UNLOCK(hfmpi2c);
2077 
2078  return HAL_ERROR;
2079  }
2080  }
2081  else
2082  {
2083  /* Update Transfer ISR function pointer */
2084  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2085 
2086  /* Send Slave Address */
2087  /* Set NBYTES to write and generate START condition */
2088  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)sizetoxfer, FMPI2C_AUTOEND_MODE,
2089  FMPI2C_GENERATE_START_WRITE);
2090 
2091  /* Process Unlocked */
2092  __HAL_UNLOCK(hfmpi2c);
2093 
2094  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2095  to avoid the risk of FMPI2C interrupt handle execution before current
2096  process unlock */
2097  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2098  /* possible to enable all of these */
2099  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2100  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2101  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2102  }
2103 
2104  return HAL_OK;
2105  }
2106  else
2107  {
2108  return HAL_BUSY;
2109  }
2110 }
2111 
2122 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
2123  uint16_t Size)
2124 {
2125  uint32_t xfermode;
2126  HAL_StatusTypeDef dmaxferstatus;
2127 
2128  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2129  {
2130  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2131  {
2132  return HAL_BUSY;
2133  }
2134 
2135  /* Process Locked */
2136  __HAL_LOCK(hfmpi2c);
2137 
2138  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2139  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
2140  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2141 
2142  /* Prepare transfer parameters */
2143  hfmpi2c->pBuffPtr = pData;
2144  hfmpi2c->XferCount = Size;
2145  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2146  hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
2147 
2148  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2149  {
2150  hfmpi2c->XferSize = 1U;
2151  xfermode = FMPI2C_RELOAD_MODE;
2152  }
2153  else
2154  {
2155  hfmpi2c->XferSize = hfmpi2c->XferCount;
2156  xfermode = FMPI2C_AUTOEND_MODE;
2157  }
2158 
2159  if (hfmpi2c->XferSize > 0U)
2160  {
2161  if (hfmpi2c->hdmarx != NULL)
2162  {
2163  /* Set the FMPI2C DMA transfer complete callback */
2164  hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
2165 
2166  /* Set the DMA error callback */
2167  hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2168 
2169  /* Set the unused DMA callbacks to NULL */
2170  hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
2171  hfmpi2c->hdmarx->XferAbortCallback = NULL;
2172 
2173  /* Enable the DMA stream */
2174  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
2175  hfmpi2c->XferSize);
2176  }
2177  else
2178  {
2179  /* Update FMPI2C state */
2180  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2181  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2182 
2183  /* Update FMPI2C error code */
2184  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2185 
2186  /* Process Unlocked */
2187  __HAL_UNLOCK(hfmpi2c);
2188 
2189  return HAL_ERROR;
2190  }
2191 
2192  if (dmaxferstatus == HAL_OK)
2193  {
2194  /* Send Slave Address */
2195  /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2196  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
2197 
2198  /* Update XferCount value */
2199  hfmpi2c->XferCount -= hfmpi2c->XferSize;
2200 
2201  /* Process Unlocked */
2202  __HAL_UNLOCK(hfmpi2c);
2203 
2204  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2205  to avoid the risk of FMPI2C interrupt handle execution before current
2206  process unlock */
2207  /* Enable ERR and NACK interrupts */
2208  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2209 
2210  /* Enable DMA Request */
2211  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2212  }
2213  else
2214  {
2215  /* Update FMPI2C state */
2216  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2217  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2218 
2219  /* Update FMPI2C error code */
2220  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2221 
2222  /* Process Unlocked */
2223  __HAL_UNLOCK(hfmpi2c);
2224 
2225  return HAL_ERROR;
2226  }
2227  }
2228  else
2229  {
2230  /* Update Transfer ISR function pointer */
2231  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2232 
2233  /* Send Slave Address */
2234  /* Set NBYTES to read and generate START condition */
2235  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2236  FMPI2C_GENERATE_START_READ);
2237 
2238  /* Process Unlocked */
2239  __HAL_UNLOCK(hfmpi2c);
2240 
2241  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2242  to avoid the risk of FMPI2C interrupt handle execution before current
2243  process unlock */
2244  /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2245  /* possible to enable all of these */
2246  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2247  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2248  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2249  }
2250 
2251  return HAL_OK;
2252  }
2253  else
2254  {
2255  return HAL_BUSY;
2256  }
2257 }
2258 
2267 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
2268 {
2269  HAL_StatusTypeDef dmaxferstatus;
2270 
2271  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2272  {
2273  if ((pData == NULL) || (Size == 0U))
2274  {
2275  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2276  return HAL_ERROR;
2277  }
2278  /* Process Locked */
2279  __HAL_LOCK(hfmpi2c);
2280 
2281  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2282  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2283  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2284 
2285  /* Prepare transfer parameters */
2286  hfmpi2c->pBuffPtr = pData;
2287  hfmpi2c->XferCount = Size;
2288  hfmpi2c->XferSize = hfmpi2c->XferCount;
2289  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2290  hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
2291 
2292  /* Preload TX data if no stretch enable */
2293  if (hfmpi2c->Init.NoStretchMode == FMPI2C_NOSTRETCH_ENABLE)
2294  {
2295  /* Preload TX register */
2296  /* Write data to TXDR */
2297  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
2298 
2299  /* Increment Buffer pointer */
2300  hfmpi2c->pBuffPtr++;
2301 
2302  hfmpi2c->XferCount--;
2303  hfmpi2c->XferSize--;
2304  }
2305 
2306  if (hfmpi2c->XferCount != 0U)
2307  {
2308  if (hfmpi2c->hdmatx != NULL)
2309  {
2310  /* Set the FMPI2C DMA transfer complete callback */
2311  hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
2312 
2313  /* Set the DMA error callback */
2314  hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2315 
2316  /* Set the unused DMA callbacks to NULL */
2317  hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
2318  hfmpi2c->hdmatx->XferAbortCallback = NULL;
2319 
2320  /* Enable the DMA stream */
2321  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx,
2322  (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR,
2323  hfmpi2c->XferSize);
2324  }
2325  else
2326  {
2327  /* Update FMPI2C state */
2328  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2329  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2330 
2331  /* Update FMPI2C error code */
2332  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2333 
2334  /* Process Unlocked */
2335  __HAL_UNLOCK(hfmpi2c);
2336 
2337  return HAL_ERROR;
2338  }
2339 
2340  if (dmaxferstatus == HAL_OK)
2341  {
2342  /* Enable Address Acknowledge */
2343  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2344 
2345  /* Process Unlocked */
2346  __HAL_UNLOCK(hfmpi2c);
2347 
2348  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2349  to avoid the risk of FMPI2C interrupt handle execution before current
2350  process unlock */
2351  /* Enable ERR, STOP, NACK, ADDR interrupts */
2352  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2353 
2354  /* Enable DMA Request */
2355  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2356  }
2357  else
2358  {
2359  /* Update FMPI2C state */
2360  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2361  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2362 
2363  /* Update FMPI2C error code */
2364  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2365 
2366  /* Process Unlocked */
2367  __HAL_UNLOCK(hfmpi2c);
2368 
2369  return HAL_ERROR;
2370  }
2371  }
2372  else
2373  {
2374  /* Enable Address Acknowledge */
2375  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2376 
2377  /* Process Unlocked */
2378  __HAL_UNLOCK(hfmpi2c);
2379 
2380  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2381  to avoid the risk of FMPI2C interrupt handle execution before current
2382  process unlock */
2383  /* Enable ERR, STOP, NACK, ADDR interrupts */
2384  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2385  }
2386 
2387  return HAL_OK;
2388  }
2389  else
2390  {
2391  return HAL_BUSY;
2392  }
2393 }
2394 
2403 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
2404 {
2405  HAL_StatusTypeDef dmaxferstatus;
2406 
2407  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2408  {
2409  if ((pData == NULL) || (Size == 0U))
2410  {
2411  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2412  return HAL_ERROR;
2413  }
2414  /* Process Locked */
2415  __HAL_LOCK(hfmpi2c);
2416 
2417  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2418  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2419  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2420 
2421  /* Prepare transfer parameters */
2422  hfmpi2c->pBuffPtr = pData;
2423  hfmpi2c->XferCount = Size;
2424  hfmpi2c->XferSize = hfmpi2c->XferCount;
2425  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2426  hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
2427 
2428  if (hfmpi2c->hdmarx != NULL)
2429  {
2430  /* Set the FMPI2C DMA transfer complete callback */
2431  hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
2432 
2433  /* Set the DMA error callback */
2434  hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2435 
2436  /* Set the unused DMA callbacks to NULL */
2437  hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
2438  hfmpi2c->hdmarx->XferAbortCallback = NULL;
2439 
2440  /* Enable the DMA stream */
2441  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
2442  hfmpi2c->XferSize);
2443  }
2444  else
2445  {
2446  /* Update FMPI2C state */
2447  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2448  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2449 
2450  /* Update FMPI2C error code */
2451  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2452 
2453  /* Process Unlocked */
2454  __HAL_UNLOCK(hfmpi2c);
2455 
2456  return HAL_ERROR;
2457  }
2458 
2459  if (dmaxferstatus == HAL_OK)
2460  {
2461  /* Enable Address Acknowledge */
2462  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2463 
2464  /* Process Unlocked */
2465  __HAL_UNLOCK(hfmpi2c);
2466 
2467  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2468  to avoid the risk of FMPI2C interrupt handle execution before current
2469  process unlock */
2470  /* Enable ERR, STOP, NACK, ADDR interrupts */
2471  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2472 
2473  /* Enable DMA Request */
2474  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2475  }
2476  else
2477  {
2478  /* Update FMPI2C state */
2479  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2480  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2481 
2482  /* Update FMPI2C error code */
2483  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2484 
2485  /* Process Unlocked */
2486  __HAL_UNLOCK(hfmpi2c);
2487 
2488  return HAL_ERROR;
2489  }
2490 
2491  return HAL_OK;
2492  }
2493  else
2494  {
2495  return HAL_BUSY;
2496  }
2497 }
2498 
2512 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2513  uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2514 {
2515  uint32_t tickstart;
2516 
2517  /* Check the parameters */
2518  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2519 
2521  {
2522  if ((pData == NULL) || (Size == 0U))
2523  {
2524  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2525  return HAL_ERROR;
2526  }
2527 
2528  /* Process Locked */
2529  __HAL_LOCK(hfmpi2c);
2530 
2531  /* Init tickstart for timeout management*/
2532  tickstart = HAL_GetTick();
2533 
2534  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2535  {
2536  return HAL_ERROR;
2537  }
2538 
2539  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2540  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2541  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2542 
2543  /* Prepare transfer parameters */
2544  hfmpi2c->pBuffPtr = pData;
2545  hfmpi2c->XferCount = Size;
2546  hfmpi2c->XferISR = NULL;
2547 
2548  /* Send Slave Address and Memory Address */
2549  if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2550  {
2551  /* Process Unlocked */
2552  __HAL_UNLOCK(hfmpi2c);
2553  return HAL_ERROR;
2554  }
2555 
2556  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
2557  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2558  {
2559  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2560  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
2561  }
2562  else
2563  {
2564  hfmpi2c->XferSize = hfmpi2c->XferCount;
2565  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
2566  }
2567 
2568  do
2569  {
2570  /* Wait until TXIS flag is set */
2571  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2572  {
2573  return HAL_ERROR;
2574  }
2575 
2576  /* Write data to TXDR */
2577  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
2578 
2579  /* Increment Buffer pointer */
2580  hfmpi2c->pBuffPtr++;
2581 
2582  hfmpi2c->XferCount--;
2583  hfmpi2c->XferSize--;
2584 
2585  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
2586  {
2587  /* Wait until TCR flag is set */
2588  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2589  {
2590  return HAL_ERROR;
2591  }
2592 
2593  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2594  {
2595  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2596  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2597  FMPI2C_NO_STARTSTOP);
2598  }
2599  else
2600  {
2601  hfmpi2c->XferSize = hfmpi2c->XferCount;
2602  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2603  FMPI2C_NO_STARTSTOP);
2604  }
2605  }
2606 
2607  } while (hfmpi2c->XferCount > 0U);
2608 
2609  /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2610  /* Wait until STOPF flag is reset */
2611  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2612  {
2613  return HAL_ERROR;
2614  }
2615 
2616  /* Clear STOP Flag */
2617  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2618 
2619  /* Clear Configuration Register 2 */
2620  FMPI2C_RESET_CR2(hfmpi2c);
2621 
2622  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2623  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2624 
2625  /* Process Unlocked */
2626  __HAL_UNLOCK(hfmpi2c);
2627 
2628  return HAL_OK;
2629  }
2630  else
2631  {
2632  return HAL_BUSY;
2633  }
2634 }
2635 
2649 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2650  uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2651 {
2652  uint32_t tickstart;
2653 
2654  /* Check the parameters */
2655  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2656 
2658  {
2659  if ((pData == NULL) || (Size == 0U))
2660  {
2661  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2662  return HAL_ERROR;
2663  }
2664 
2665  /* Process Locked */
2666  __HAL_LOCK(hfmpi2c);
2667 
2668  /* Init tickstart for timeout management*/
2669  tickstart = HAL_GetTick();
2670 
2671  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2672  {
2673  return HAL_ERROR;
2674  }
2675 
2676  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2677  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2678  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2679 
2680  /* Prepare transfer parameters */
2681  hfmpi2c->pBuffPtr = pData;
2682  hfmpi2c->XferCount = Size;
2683  hfmpi2c->XferISR = NULL;
2684 
2685  /* Send Slave Address and Memory Address */
2686  if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2687  {
2688  /* Process Unlocked */
2689  __HAL_UNLOCK(hfmpi2c);
2690  return HAL_ERROR;
2691  }
2692 
2693  /* Send Slave Address */
2694  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2695  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2696  {
2697  hfmpi2c->XferSize = 1U;
2698  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2699  FMPI2C_GENERATE_START_READ);
2700  }
2701  else
2702  {
2703  hfmpi2c->XferSize = hfmpi2c->XferCount;
2704  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2705  FMPI2C_GENERATE_START_READ);
2706  }
2707 
2708  do
2709  {
2710  /* Wait until RXNE flag is set */
2711  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
2712  {
2713  return HAL_ERROR;
2714  }
2715 
2716  /* Read data from RXDR */
2717  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
2718 
2719  /* Increment Buffer pointer */
2720  hfmpi2c->pBuffPtr++;
2721 
2722  hfmpi2c->XferSize--;
2723  hfmpi2c->XferCount--;
2724 
2725  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
2726  {
2727  /* Wait until TCR flag is set */
2728  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2729  {
2730  return HAL_ERROR;
2731  }
2732 
2733  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2734  {
2735  hfmpi2c->XferSize = 1U;
2736  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t) hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2737  FMPI2C_NO_STARTSTOP);
2738  }
2739  else
2740  {
2741  hfmpi2c->XferSize = hfmpi2c->XferCount;
2742  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2743  FMPI2C_NO_STARTSTOP);
2744  }
2745  }
2746  } while (hfmpi2c->XferCount > 0U);
2747 
2748  /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2749  /* Wait until STOPF flag is reset */
2750  if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2751  {
2752  return HAL_ERROR;
2753  }
2754 
2755  /* Clear STOP Flag */
2756  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2757 
2758  /* Clear Configuration Register 2 */
2759  FMPI2C_RESET_CR2(hfmpi2c);
2760 
2761  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2762  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2763 
2764  /* Process Unlocked */
2765  __HAL_UNLOCK(hfmpi2c);
2766 
2767  return HAL_OK;
2768  }
2769  else
2770  {
2771  return HAL_BUSY;
2772  }
2773 }
2786 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2787  uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2788 {
2789  /* Check the parameters */
2790  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2791 
2792  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2793  {
2794  if ((pData == NULL) || (Size == 0U))
2795  {
2796  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2797  return HAL_ERROR;
2798  }
2799 
2800  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2801  {
2802  return HAL_BUSY;
2803  }
2804 
2805  /* Process Locked */
2806  __HAL_LOCK(hfmpi2c);
2807 
2808  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2809  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2810  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2811 
2812  /* Prepare transfer parameters */
2813  hfmpi2c->XferSize = 0U;
2814  hfmpi2c->pBuffPtr = pData;
2815  hfmpi2c->XferCount = Size;
2816  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2817  hfmpi2c->XferISR = FMPI2C_Mem_ISR_IT;
2818  hfmpi2c->Devaddress = DevAddress;
2819 
2820  /* If Memory address size is 8Bit */
2821  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
2822  {
2823  /* Prefetch Memory Address */
2824  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
2825 
2826  /* Reset Memaddress content */
2827  hfmpi2c->Memaddress = 0xFFFFFFFFU;
2828  }
2829  /* If Memory address size is 16Bit */
2830  else
2831  {
2832  /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2833  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
2834 
2835  /* Prepare Memaddress buffer for LSB part */
2836  hfmpi2c->Memaddress = FMPI2C_MEM_ADD_LSB(MemAddress);
2837  }
2838  /* Send Slave Address and Memory Address */
2839  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
2840 
2841  /* Process Unlocked */
2842  __HAL_UNLOCK(hfmpi2c);
2843 
2844  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2845  to avoid the risk of FMPI2C interrupt handle execution before current
2846  process unlock */
2847 
2848  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2849  /* possible to enable all of these */
2850  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2851  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2852  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2853 
2854  return HAL_OK;
2855  }
2856  else
2857  {
2858  return HAL_BUSY;
2859  }
2860 }
2861 
2874 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2875  uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2876 {
2877  /* Check the parameters */
2878  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2879 
2880  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2881  {
2882  if ((pData == NULL) || (Size == 0U))
2883  {
2884  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2885  return HAL_ERROR;
2886  }
2887 
2888  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2889  {
2890  return HAL_BUSY;
2891  }
2892 
2893  /* Process Locked */
2894  __HAL_LOCK(hfmpi2c);
2895 
2896  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2897  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2898  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2899 
2900  /* Prepare transfer parameters */
2901  hfmpi2c->pBuffPtr = pData;
2902  hfmpi2c->XferCount = Size;
2903  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2904  hfmpi2c->XferISR = FMPI2C_Mem_ISR_IT;
2905  hfmpi2c->Devaddress = DevAddress;
2906 
2907  /* If Memory address size is 8Bit */
2908  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
2909  {
2910  /* Prefetch Memory Address */
2911  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
2912 
2913  /* Reset Memaddress content */
2914  hfmpi2c->Memaddress = 0xFFFFFFFFU;
2915  }
2916  /* If Memory address size is 16Bit */
2917  else
2918  {
2919  /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2920  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
2921 
2922  /* Prepare Memaddress buffer for LSB part */
2923  hfmpi2c->Memaddress = FMPI2C_MEM_ADD_LSB(MemAddress);
2924  }
2925  /* Send Slave Address and Memory Address */
2926  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
2927 
2928  /* Process Unlocked */
2929  __HAL_UNLOCK(hfmpi2c);
2930 
2931  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2932  to avoid the risk of FMPI2C interrupt handle execution before current
2933  process unlock */
2934 
2935  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2936  /* possible to enable all of these */
2937  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2938  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2939  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2940 
2941  return HAL_OK;
2942  }
2943  else
2944  {
2945  return HAL_BUSY;
2946  }
2947 }
2948 
2961 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2962  uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2963 {
2964  HAL_StatusTypeDef dmaxferstatus;
2965 
2966  /* Check the parameters */
2967  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2968 
2970  {
2971  if ((pData == NULL) || (Size == 0U))
2972  {
2973  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2974  return HAL_ERROR;
2975  }
2976 
2977  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2978  {
2979  return HAL_BUSY;
2980  }
2981 
2982  /* Process Locked */
2983  __HAL_LOCK(hfmpi2c);
2984 
2985  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2986  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2987  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2988 
2989  /* Prepare transfer parameters */
2990  hfmpi2c->pBuffPtr = pData;
2991  hfmpi2c->XferCount = Size;
2992  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2993  hfmpi2c->XferISR = FMPI2C_Mem_ISR_DMA;
2994  hfmpi2c->Devaddress = DevAddress;
2995 
2996  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2997  {
2998  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2999  }
3000  else
3001  {
3002  hfmpi2c->XferSize = hfmpi2c->XferCount;
3003  }
3004 
3005  /* If Memory address size is 8Bit */
3006  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
3007  {
3008  /* Prefetch Memory Address */
3009  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3010 
3011  /* Reset Memaddress content */
3012  hfmpi2c->Memaddress = 0xFFFFFFFFU;
3013  }
3014  /* If Memory address size is 16Bit */
3015  else
3016  {
3017  /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3018  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
3019 
3020  /* Prepare Memaddress buffer for LSB part */
3021  hfmpi2c->Memaddress = FMPI2C_MEM_ADD_LSB(MemAddress);
3022  }
3023 
3024  if (hfmpi2c->hdmatx != NULL)
3025  {
3026  /* Set the FMPI2C DMA transfer complete callback */
3027  hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
3028 
3029  /* Set the DMA error callback */
3030  hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
3031 
3032  /* Set the unused DMA callbacks to NULL */
3033  hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
3034  hfmpi2c->hdmatx->XferAbortCallback = NULL;
3035 
3036  /* Enable the DMA stream */
3037  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
3038  hfmpi2c->XferSize);
3039  }
3040  else
3041  {
3042  /* Update FMPI2C state */
3043  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3044  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3045 
3046  /* Update FMPI2C error code */
3047  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3048 
3049  /* Process Unlocked */
3050  __HAL_UNLOCK(hfmpi2c);
3051 
3052  return HAL_ERROR;
3053  }
3054 
3055  if (dmaxferstatus == HAL_OK)
3056  {
3057  /* Send Slave Address and Memory Address */
3058  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
3059 
3060  /* Process Unlocked */
3061  __HAL_UNLOCK(hfmpi2c);
3062 
3063  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3064  to avoid the risk of FMPI2C interrupt handle execution before current
3065  process unlock */
3066  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3067  /* possible to enable all of these */
3068  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3069  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3070  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3071  }
3072  else
3073  {
3074  /* Update FMPI2C state */
3075  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3076  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3077 
3078  /* Update FMPI2C error code */
3079  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3080 
3081  /* Process Unlocked */
3082  __HAL_UNLOCK(hfmpi2c);
3083 
3084  return HAL_ERROR;
3085  }
3086 
3087  return HAL_OK;
3088  }
3089  else
3090  {
3091  return HAL_BUSY;
3092  }
3093 }
3094 
3107 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
3108  uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
3109 {
3110  HAL_StatusTypeDef dmaxferstatus;
3111 
3112  /* Check the parameters */
3113  assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
3114 
3116  {
3117  if ((pData == NULL) || (Size == 0U))
3118  {
3119  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
3120  return HAL_ERROR;
3121  }
3122 
3123  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
3124  {
3125  return HAL_BUSY;
3126  }
3127 
3128  /* Process Locked */
3129  __HAL_LOCK(hfmpi2c);
3130 
3131  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3132  hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
3133  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3134 
3135  /* Prepare transfer parameters */
3136  hfmpi2c->pBuffPtr = pData;
3137  hfmpi2c->XferCount = Size;
3138  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
3139  hfmpi2c->XferISR = FMPI2C_Mem_ISR_DMA;
3140  hfmpi2c->Devaddress = DevAddress;
3141 
3142  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3143  {
3144  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3145  }
3146  else
3147  {
3148  hfmpi2c->XferSize = hfmpi2c->XferCount;
3149  }
3150 
3151  /* If Memory address size is 8Bit */
3152  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
3153  {
3154  /* Prefetch Memory Address */
3155  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3156 
3157  /* Reset Memaddress content */
3158  hfmpi2c->Memaddress = 0xFFFFFFFFU;
3159  }
3160  /* If Memory address size is 16Bit */
3161  else
3162  {
3163  /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3164  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
3165 
3166  /* Prepare Memaddress buffer for LSB part */
3167  hfmpi2c->Memaddress = FMPI2C_MEM_ADD_LSB(MemAddress);
3168  }
3169 
3170  if (hfmpi2c->hdmarx != NULL)
3171  {
3172  /* Set the FMPI2C DMA transfer complete callback */
3173  hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
3174 
3175  /* Set the DMA error callback */
3176  hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
3177 
3178  /* Set the unused DMA callbacks to NULL */
3179  hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
3180  hfmpi2c->hdmarx->XferAbortCallback = NULL;
3181 
3182  /* Enable the DMA stream */
3183  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
3184  hfmpi2c->XferSize);
3185  }
3186  else
3187  {
3188  /* Update FMPI2C state */
3189  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3190  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3191 
3192  /* Update FMPI2C error code */
3193  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3194 
3195  /* Process Unlocked */
3196  __HAL_UNLOCK(hfmpi2c);
3197 
3198  return HAL_ERROR;
3199  }
3200 
3201  if (dmaxferstatus == HAL_OK)
3202  {
3203  /* Send Slave Address and Memory Address */
3204  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
3205 
3206  /* Process Unlocked */
3207  __HAL_UNLOCK(hfmpi2c);
3208 
3209  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3210  to avoid the risk of FMPI2C interrupt handle execution before current
3211  process unlock */
3212  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3213  /* possible to enable all of these */
3214  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3215  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3216  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3217  }
3218  else
3219  {
3220  /* Update FMPI2C state */
3221  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3222  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3223 
3224  /* Update FMPI2C error code */
3225  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3226 
3227  /* Process Unlocked */
3228  __HAL_UNLOCK(hfmpi2c);
3229 
3230  return HAL_ERROR;
3231  }
3232 
3233  return HAL_OK;
3234  }
3235  else
3236  {
3237  return HAL_BUSY;
3238  }
3239 }
3240 
3252 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials,
3253  uint32_t Timeout)
3254 {
3255  uint32_t tickstart;
3256 
3257  __IO uint32_t FMPI2C_Trials = 0UL;
3258 
3259  FlagStatus tmp1;
3260  FlagStatus tmp2;
3261 
3262  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3263  {
3264  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
3265  {
3266  return HAL_BUSY;
3267  }
3268 
3269  /* Process Locked */
3270  __HAL_LOCK(hfmpi2c);
3271 
3272  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
3273  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3274 
3275  do
3276  {
3277  /* Generate Start */
3278  hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress);
3279 
3280  /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3281  /* Wait until STOPF flag is set or a NACK flag is set*/
3282  tickstart = HAL_GetTick();
3283 
3284  tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3285  tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3286 
3287  while ((tmp1 == RESET) && (tmp2 == RESET))
3288  {
3289  if (Timeout != HAL_MAX_DELAY)
3290  {
3291  if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3292  {
3293  /* Update FMPI2C state */
3294  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3295 
3296  /* Update FMPI2C error code */
3297  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3298 
3299  /* Process Unlocked */
3300  __HAL_UNLOCK(hfmpi2c);
3301 
3302  return HAL_ERROR;
3303  }
3304  }
3305 
3306  tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3307  tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3308  }
3309 
3310  /* Check if the NACKF flag has not been set */
3311  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
3312  {
3313  /* Wait until STOPF flag is reset */
3314  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3315  {
3316  return HAL_ERROR;
3317  }
3318 
3319  /* Clear STOP Flag */
3320  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3321 
3322  /* Device is ready */
3323  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3324 
3325  /* Process Unlocked */
3326  __HAL_UNLOCK(hfmpi2c);
3327 
3328  return HAL_OK;
3329  }
3330  else
3331  {
3332  /* Wait until STOPF flag is reset */
3333  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3334  {
3335  return HAL_ERROR;
3336  }
3337 
3338  /* Clear NACK Flag */
3339  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3340 
3341  /* Clear STOP Flag, auto generated with autoend*/
3342  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3343  }
3344 
3345  /* Increment Trials */
3346  FMPI2C_Trials++;
3347  } while (FMPI2C_Trials < Trials);
3348 
3349  /* Update FMPI2C state */
3350  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3351 
3352  /* Update FMPI2C error code */
3353  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3354 
3355  /* Process Unlocked */
3356  __HAL_UNLOCK(hfmpi2c);
3357 
3358  return HAL_ERROR;
3359  }
3360  else
3361  {
3362  return HAL_BUSY;
3363  }
3364 }
3365 
3378 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3379  uint16_t Size, uint32_t XferOptions)
3380 {
3381  uint32_t xfermode;
3382  uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
3383  uint32_t sizetoxfer = 0U;
3384 
3385  /* Check the parameters */
3386  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3387 
3388  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3389  {
3390  /* Process Locked */
3391  __HAL_LOCK(hfmpi2c);
3392 
3393  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
3394  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3395  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3396 
3397  /* Prepare transfer parameters */
3398  hfmpi2c->pBuffPtr = pData;
3399  hfmpi2c->XferCount = Size;
3400  hfmpi2c->XferOptions = XferOptions;
3401  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3402 
3403  /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3404  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3405  {
3406  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3407  xfermode = FMPI2C_RELOAD_MODE;
3408  }
3409  else
3410  {
3411  hfmpi2c->XferSize = hfmpi2c->XferCount;
3412  xfermode = hfmpi2c->XferOptions;
3413  }
3414 
3415  if ((hfmpi2c->XferSize > 0U) && ((XferOptions == FMPI2C_FIRST_FRAME) || \
3416  (XferOptions == FMPI2C_FIRST_AND_LAST_FRAME)))
3417  {
3418  /* Preload TX register */
3419  /* Write data to TXDR */
3420  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
3421 
3422  /* Increment Buffer pointer */
3423  hfmpi2c->pBuffPtr++;
3424 
3425  sizetoxfer = hfmpi2c->XferSize;
3426  hfmpi2c->XferCount--;
3427  hfmpi2c->XferSize--;
3428  }
3429 
3430  /* If transfer direction not change and there is no request to start another frame,
3431  do not generate Restart Condition */
3432  /* Mean Previous state is same as current state */
3433  if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
3434  (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3435  {
3436  xferrequest = FMPI2C_NO_STARTSTOP;
3437  }
3438  else
3439  {
3440  /* Convert OTHER_xxx XferOptions if any */
3441  FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3442 
3443  /* Update xfermode accordingly if no reload is necessary */
3444  if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3445  {
3446  xfermode = hfmpi2c->XferOptions;
3447  }
3448  }
3449 
3450  /* Send Slave Address and set NBYTES to write */
3451  if ((XferOptions == FMPI2C_FIRST_FRAME) || (XferOptions == FMPI2C_FIRST_AND_LAST_FRAME))
3452  {
3453  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3454  }
3455  else
3456  {
3457  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3458  }
3459 
3460  /* Process Unlocked */
3461  __HAL_UNLOCK(hfmpi2c);
3462 
3463  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3464  to avoid the risk of FMPI2C interrupt handle execution before current
3465  process unlock */
3466  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3467  /* possible to enable all of these */
3468  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3469  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3470  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3471 
3472  return HAL_OK;
3473  }
3474  else
3475  {
3476  return HAL_BUSY;
3477  }
3478 }
3479 
3492 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3493  uint16_t Size, uint32_t XferOptions)
3494 {
3495  uint32_t xfermode;
3496  uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
3497  HAL_StatusTypeDef dmaxferstatus;
3498  uint32_t sizetoxfer = 0U;
3499 
3500  /* Check the parameters */
3501  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3502 
3503  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3504  {
3505  /* Process Locked */
3506  __HAL_LOCK(hfmpi2c);
3507 
3508  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
3509  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3510  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3511 
3512  /* Prepare transfer parameters */
3513  hfmpi2c->pBuffPtr = pData;
3514  hfmpi2c->XferCount = Size;
3515  hfmpi2c->XferOptions = XferOptions;
3516  hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
3517 
3518  /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3519  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3520  {
3521  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3522  xfermode = FMPI2C_RELOAD_MODE;
3523  }
3524  else
3525  {
3526  hfmpi2c->XferSize = hfmpi2c->XferCount;
3527  xfermode = hfmpi2c->XferOptions;
3528  }
3529 
3530  if ((hfmpi2c->XferSize > 0U) && ((XferOptions == FMPI2C_FIRST_FRAME) || \
3531  (XferOptions == FMPI2C_FIRST_AND_LAST_FRAME)))
3532  {
3533  /* Preload TX register */
3534  /* Write data to TXDR */
3535  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
3536 
3537  /* Increment Buffer pointer */
3538  hfmpi2c->pBuffPtr++;
3539 
3540  sizetoxfer = hfmpi2c->XferSize;
3541  hfmpi2c->XferCount--;
3542  hfmpi2c->XferSize--;
3543  }
3544 
3545  /* If transfer direction not change and there is no request to start another frame,
3546  do not generate Restart Condition */
3547  /* Mean Previous state is same as current state */
3548  if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
3549  (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3550  {
3551  xferrequest = FMPI2C_NO_STARTSTOP;
3552  }
3553  else
3554  {
3555  /* Convert OTHER_xxx XferOptions if any */
3556  FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3557 
3558  /* Update xfermode accordingly if no reload is necessary */
3559  if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3560  {
3561  xfermode = hfmpi2c->XferOptions;
3562  }
3563  }
3564 
3565  if (hfmpi2c->XferSize > 0U)
3566  {
3567  if (hfmpi2c->hdmatx != NULL)
3568  {
3569  /* Set the FMPI2C DMA transfer complete callback */
3570  hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
3571 
3572  /* Set the DMA error callback */
3573  hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
3574 
3575  /* Set the unused DMA callbacks to NULL */
3576  hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
3577  hfmpi2c->hdmatx->XferAbortCallback = NULL;
3578 
3579  /* Enable the DMA stream */
3580  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr,
3581  (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
3582  }
3583  else
3584  {
3585  /* Update FMPI2C state */
3586  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3587  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3588 
3589  /* Update FMPI2C error code */
3590  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3591 
3592  /* Process Unlocked */
3593  __HAL_UNLOCK(hfmpi2c);
3594 
3595  return HAL_ERROR;
3596  }
3597 
3598  if (dmaxferstatus == HAL_OK)
3599  {
3600  /* Send Slave Address and set NBYTES to write */
3601  if ((XferOptions == FMPI2C_FIRST_FRAME) || (XferOptions == FMPI2C_FIRST_AND_LAST_FRAME))
3602  {
3603  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3604  }
3605  else
3606  {
3607  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3608  }
3609 
3610  /* Update XferCount value */
3611  hfmpi2c->XferCount -= hfmpi2c->XferSize;
3612 
3613  /* Process Unlocked */
3614  __HAL_UNLOCK(hfmpi2c);
3615 
3616  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3617  to avoid the risk of FMPI2C interrupt handle execution before current
3618  process unlock */
3619  /* Enable ERR and NACK interrupts */
3620  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
3621 
3622  /* Enable DMA Request */
3623  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
3624  }
3625  else
3626  {
3627  /* Update FMPI2C state */
3628  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3629  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3630 
3631  /* Update FMPI2C error code */
3632  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3633 
3634  /* Process Unlocked */
3635  __HAL_UNLOCK(hfmpi2c);
3636 
3637  return HAL_ERROR;
3638  }
3639  }
3640  else
3641  {
3642  /* Update Transfer ISR function pointer */
3643  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3644 
3645  /* Send Slave Address */
3646  /* Set NBYTES to write and generate START condition */
3647  if ((XferOptions == FMPI2C_FIRST_FRAME) || (XferOptions == FMPI2C_FIRST_AND_LAST_FRAME))
3648  {
3649  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3650  }
3651  else
3652  {
3653  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3654  }
3655 
3656  /* Process Unlocked */
3657  __HAL_UNLOCK(hfmpi2c);
3658 
3659  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3660  to avoid the risk of FMPI2C interrupt handle execution before current
3661  process unlock */
3662  /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3663  /* possible to enable all of these */
3664  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3665  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3666  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3667  }
3668 
3669  return HAL_OK;
3670  }
3671  else
3672  {
3673  return HAL_BUSY;
3674  }
3675 }
3676 
3689 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3690  uint16_t Size, uint32_t XferOptions)
3691 {
3692  uint32_t xfermode;
3693  uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
3694 
3695  /* Check the parameters */
3696  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3698  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3699  {
3700  /* Process Locked */
3701  __HAL_LOCK(hfmpi2c);
3702 
3703  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3704  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3705  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3706 
3707  /* Prepare transfer parameters */
3708  hfmpi2c->pBuffPtr = pData;
3709  hfmpi2c->XferCount = Size;
3710  hfmpi2c->XferOptions = XferOptions;
3711  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3712 
3713  /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3714  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3715  {
3716  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3717  xfermode = FMPI2C_RELOAD_MODE;
3718  }
3719  else
3720  {
3721  hfmpi2c->XferSize = hfmpi2c->XferCount;
3722  xfermode = hfmpi2c->XferOptions;
3723  }
3724 
3725  /* If transfer direction not change and there is no request to start another frame,
3726  do not generate Restart Condition */
3727  /* Mean Previous state is same as current state */
3728  if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
3729  (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3730  {
3731  xferrequest = FMPI2C_NO_STARTSTOP;
3732  }
3733  else
3734  {
3735  /* Convert OTHER_xxx XferOptions if any */
3736  FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3737 
3738  /* Update xfermode accordingly if no reload is necessary */
3739  if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3740  {
3741  xfermode = hfmpi2c->XferOptions;
3742  }
3743  }
3744 
3745  /* Send Slave Address and set NBYTES to read */
3746  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3747 
3748  /* Process Unlocked */
3749  __HAL_UNLOCK(hfmpi2c);
3750 
3751  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3752  to avoid the risk of FMPI2C interrupt handle execution before current
3753  process unlock */
3754  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3755 
3756  return HAL_OK;
3757  }
3758  else
3759  {
3760  return HAL_BUSY;
3761  }
3762 }
3763 
3776 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3777  uint16_t Size, uint32_t XferOptions)
3778 {
3779  uint32_t xfermode;
3780  uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
3781  HAL_StatusTypeDef dmaxferstatus;
3782 
3783  /* Check the parameters */
3784  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3785 
3786  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3787  {
3788  /* Process Locked */
3789  __HAL_LOCK(hfmpi2c);
3790 
3791  hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3792  hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3793  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3794 
3795  /* Prepare transfer parameters */
3796  hfmpi2c->pBuffPtr = pData;
3797  hfmpi2c->XferCount = Size;
3798  hfmpi2c->XferOptions = XferOptions;
3799  hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
3800 
3801  /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3802  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3803  {
3804  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3805  xfermode = FMPI2C_RELOAD_MODE;
3806  }
3807  else
3808  {
3809  hfmpi2c->XferSize = hfmpi2c->XferCount;
3810  xfermode = hfmpi2c->XferOptions;
3811  }
3812 
3813  /* If transfer direction not change and there is no request to start another frame,
3814  do not generate Restart Condition */
3815  /* Mean Previous state is same as current state */
3816  if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
3817  (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3818  {
3819  xferrequest = FMPI2C_NO_STARTSTOP;
3820  }
3821  else
3822  {
3823  /* Convert OTHER_xxx XferOptions if any */
3824  FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3825 
3826  /* Update xfermode accordingly if no reload is necessary */
3827  if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3828  {
3829  xfermode = hfmpi2c->XferOptions;
3830  }
3831  }
3832 
3833  if (hfmpi2c->XferSize > 0U)
3834  {
3835  if (hfmpi2c->hdmarx != NULL)
3836  {
3837  /* Set the FMPI2C DMA transfer complete callback */
3838  hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
3839 
3840  /* Set the DMA error callback */
3841  hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
3842 
3843  /* Set the unused DMA callbacks to NULL */
3844  hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
3845  hfmpi2c->hdmarx->XferAbortCallback = NULL;
3846 
3847  /* Enable the DMA stream */
3848  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
3849  hfmpi2c->XferSize);
3850  }
3851  else
3852  {
3853  /* Update FMPI2C state */
3854  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3855  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3856 
3857  /* Update FMPI2C error code */
3858  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3859 
3860  /* Process Unlocked */
3861  __HAL_UNLOCK(hfmpi2c);
3862 
3863  return HAL_ERROR;
3864  }
3865 
3866  if (dmaxferstatus == HAL_OK)
3867  {
3868  /* Send Slave Address and set NBYTES to read */
3869  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3870 
3871  /* Update XferCount value */
3872  hfmpi2c->XferCount -= hfmpi2c->XferSize;
3873 
3874  /* Process Unlocked */
3875  __HAL_UNLOCK(hfmpi2c);
3876 
3877  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3878  to avoid the risk of FMPI2C interrupt handle execution before current
3879  process unlock */
3880  /* Enable ERR and NACK interrupts */
3881  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
3882 
3883  /* Enable DMA Request */
3884  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3885  }
3886  else
3887  {
3888  /* Update FMPI2C state */
3889  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3890  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3891 
3892  /* Update FMPI2C error code */
3893  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3894 
3895  /* Process Unlocked */
3896  __HAL_UNLOCK(hfmpi2c);
3897 
3898  return HAL_ERROR;
3899  }
3900  }
3901  else
3902  {
3903  /* Update Transfer ISR function pointer */
3904  hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3905 
3906  /* Send Slave Address */
3907  /* Set NBYTES to read and generate START condition */
3908  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
3909  FMPI2C_GENERATE_START_READ);
3910 
3911  /* Process Unlocked */
3912  __HAL_UNLOCK(hfmpi2c);
3913 
3914  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3915  to avoid the risk of FMPI2C interrupt handle execution before current
3916  process unlock */
3917  /* Enable ERR, TC, STOP, NACK, RXI interrupt */
3918  /* possible to enable all of these */
3919  /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3920  FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3921  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3922  }
3923 
3924  return HAL_OK;
3925  }
3926  else
3927  {
3928  return HAL_BUSY;
3929  }
3930 }
3931 
3942 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
3943  uint32_t XferOptions)
3944 {
3945  /* Declaration of tmp to prevent undefined behavior of volatile usage */
3946  FlagStatus tmp;
3947 
3948  /* Check the parameters */
3949  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3951  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
3952  {
3953  if ((pData == NULL) || (Size == 0U))
3954  {
3955  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
3956  return HAL_ERROR;
3957  }
3958 
3959  /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3960  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
3961 
3962  /* Process Locked */
3963  __HAL_LOCK(hfmpi2c);
3964 
3965  /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
3966  /* and then toggle the HAL slave RX state to TX state */
3967  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
3968  {
3969  /* Disable associated Interrupts */
3970  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3971 
3972  /* Abort DMA Xfer if any */
3973  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
3974  {
3975  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3976 
3977  if (hfmpi2c->hdmarx != NULL)
3978  {
3979  /* Set the FMPI2C DMA Abort callback :
3980  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
3981  hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
3982 
3983  /* Abort DMA RX */
3984  if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
3985  {
3986  /* Call Directly XferAbortCallback function in case of error */
3987  hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
3988  }
3989  }
3990  }
3991  }
3992 
3994  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
3995  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3996 
3997  /* Enable Address Acknowledge */
3998  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
3999 
4000  /* Prepare transfer parameters */
4001  hfmpi2c->pBuffPtr = pData;
4002  hfmpi2c->XferCount = Size;
4003  hfmpi2c->XferSize = hfmpi2c->XferCount;
4004  hfmpi2c->XferOptions = XferOptions;
4005  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4006 
4007  tmp = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4008  if ((FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) && (tmp != RESET))
4009  {
4010  /* Clear ADDR flag after prepare the transfer parameters */
4011  /* This action will generate an acknowledge to the Master */
4012  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4013  }
4014 
4015  /* Process Unlocked */
4016  __HAL_UNLOCK(hfmpi2c);
4017 
4018  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4019  to avoid the risk of FMPI2C interrupt handle execution before current
4020  process unlock */
4021  /* REnable ADDR interrupt */
4022  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
4023 
4024  return HAL_OK;
4025  }
4026  else
4027  {
4028  return HAL_ERROR;
4029  }
4030 }
4031 
4042 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
4043  uint32_t XferOptions)
4044 {
4045  /* Declaration of tmp to prevent undefined behavior of volatile usage */
4046  FlagStatus tmp;
4047  HAL_StatusTypeDef dmaxferstatus;
4048 
4049  /* Check the parameters */
4050  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4051 
4052  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
4053  {
4054  if ((pData == NULL) || (Size == 0U))
4055  {
4056  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
4057  return HAL_ERROR;
4058  }
4059 
4060  /* Process Locked */
4061  __HAL_LOCK(hfmpi2c);
4062 
4063  /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4064  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
4065 
4066  /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
4067  /* and then toggle the HAL slave RX state to TX state */
4068  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
4069  {
4070  /* Disable associated Interrupts */
4071  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
4072 
4073  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
4074  {
4075  /* Abort DMA Xfer if any */
4076  if (hfmpi2c->hdmarx != NULL)
4077  {
4078  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
4079 
4080  /* Set the FMPI2C DMA Abort callback :
4081  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4082  hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
4083 
4084  /* Abort DMA RX */
4085  if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
4086  {
4087  /* Call Directly XferAbortCallback function in case of error */
4088  hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
4089  }
4090  }
4091  }
4092  }
4093  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
4094  {
4095  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4096  {
4097  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4098 
4099  /* Abort DMA Xfer if any */
4100  if (hfmpi2c->hdmatx != NULL)
4101  {
4102  /* Set the FMPI2C DMA Abort callback :
4103  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4104  hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4105 
4106  /* Abort DMA TX */
4107  if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4108  {
4109  /* Call Directly XferAbortCallback function in case of error */
4110  hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4111  }
4112  }
4113  }
4114  }
4115  else
4116  {
4117  /* Nothing to do */
4118  }
4119 
4121  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
4122  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4123 
4124  /* Enable Address Acknowledge */
4125  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
4126 
4127  /* Prepare transfer parameters */
4128  hfmpi2c->pBuffPtr = pData;
4129  hfmpi2c->XferCount = Size;
4130  hfmpi2c->XferSize = hfmpi2c->XferCount;
4131  hfmpi2c->XferOptions = XferOptions;
4132  hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
4133 
4134  if (hfmpi2c->hdmatx != NULL)
4135  {
4136  /* Set the FMPI2C DMA transfer complete callback */
4137  hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
4138 
4139  /* Set the DMA error callback */
4140  hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
4141 
4142  /* Set the unused DMA callbacks to NULL */
4143  hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
4144  hfmpi2c->hdmatx->XferAbortCallback = NULL;
4145 
4146  /* Enable the DMA stream */
4147  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
4148  hfmpi2c->XferSize);
4149  }
4150  else
4151  {
4152  /* Update FMPI2C state */
4153  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4154  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4155 
4156  /* Update FMPI2C error code */
4157  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
4158 
4159  /* Process Unlocked */
4160  __HAL_UNLOCK(hfmpi2c);
4161 
4162  return HAL_ERROR;
4163  }
4164 
4165  if (dmaxferstatus == HAL_OK)
4166  {
4167  /* Update XferCount value */
4168  hfmpi2c->XferCount -= hfmpi2c->XferSize;
4169 
4170  /* Reset XferSize */
4171  hfmpi2c->XferSize = 0;
4172  }
4173  else
4174  {
4175  /* Update FMPI2C state */
4176  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4177  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4178 
4179  /* Update FMPI2C error code */
4180  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
4181 
4182  /* Process Unlocked */
4183  __HAL_UNLOCK(hfmpi2c);
4184 
4185  return HAL_ERROR;
4186  }
4187 
4188  tmp = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4189  if ((FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) && (tmp != RESET))
4190  {
4191  /* Clear ADDR flag after prepare the transfer parameters */
4192  /* This action will generate an acknowledge to the Master */
4193  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4194  }
4195 
4196  /* Process Unlocked */
4197  __HAL_UNLOCK(hfmpi2c);
4198 
4199  /* Enable DMA Request */
4200  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
4201 
4202  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4203  to avoid the risk of FMPI2C interrupt handle execution before current
4204  process unlock */
4205  /* Enable ERR, STOP, NACK, ADDR interrupts */
4206  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4207 
4208  return HAL_OK;
4209  }
4210  else
4211  {
4212  return HAL_ERROR;
4213  }
4214 }
4215 
4226 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
4227  uint32_t XferOptions)
4228 {
4229  /* Declaration of tmp to prevent undefined behavior of volatile usage */
4230  FlagStatus tmp;
4231 
4232  /* Check the parameters */
4233  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4235  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
4236  {
4237  if ((pData == NULL) || (Size == 0U))
4238  {
4239  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
4240  return HAL_ERROR;
4241  }
4242 
4243  /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4244  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
4245 
4246  /* Process Locked */
4247  __HAL_LOCK(hfmpi2c);
4248 
4249  /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
4250  /* and then toggle the HAL slave TX state to RX state */
4251  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
4252  {
4253  /* Disable associated Interrupts */
4254  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4255 
4256  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4257  {
4258  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4259 
4260  /* Abort DMA Xfer if any */
4261  if (hfmpi2c->hdmatx != NULL)
4262  {
4263  /* Set the FMPI2C DMA Abort callback :
4264  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4265  hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4266 
4267  /* Abort DMA TX */
4268  if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4269  {
4270  /* Call Directly XferAbortCallback function in case of error */
4271  hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4272  }
4273  }
4274  }
4275  }
4276 
4278  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
4279  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4280 
4281  /* Enable Address Acknowledge */
4282  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
4283 
4284  /* Prepare transfer parameters */
4285  hfmpi2c->pBuffPtr = pData;
4286  hfmpi2c->XferCount = Size;
4287  hfmpi2c->XferSize = hfmpi2c->XferCount;
4288  hfmpi2c->XferOptions = XferOptions;
4289  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4290 
4291  tmp = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4292  if ((FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4293  {
4294  /* Clear ADDR flag after prepare the transfer parameters */
4295  /* This action will generate an acknowledge to the Master */
4296  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4297  }
4298 
4299  /* Process Unlocked */
4300  __HAL_UNLOCK(hfmpi2c);
4301 
4302  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4303  to avoid the risk of FMPI2C interrupt handle execution before current
4304  process unlock */
4305  /* REnable ADDR interrupt */
4306  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
4307 
4308  return HAL_OK;
4309  }
4310  else
4311  {
4312  return HAL_ERROR;
4313  }
4314 }
4315 
4326 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
4327  uint32_t XferOptions)
4328 {
4329  /* Declaration of tmp to prevent undefined behavior of volatile usage */
4330  FlagStatus tmp;
4331  HAL_StatusTypeDef dmaxferstatus;
4332 
4333  /* Check the parameters */
4334  assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4335 
4336  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
4337  {
4338  if ((pData == NULL) || (Size == 0U))
4339  {
4340  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
4341  return HAL_ERROR;
4342  }
4343 
4344  /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4345  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
4346 
4347  /* Process Locked */
4348  __HAL_LOCK(hfmpi2c);
4349 
4350  /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
4351  /* and then toggle the HAL slave TX state to RX state */
4352  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
4353  {
4354  /* Disable associated Interrupts */
4355  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4356 
4357  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4358  {
4359  /* Abort DMA Xfer if any */
4360  if (hfmpi2c->hdmatx != NULL)
4361  {
4362  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4363 
4364  /* Set the FMPI2C DMA Abort callback :
4365  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4366  hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4367 
4368  /* Abort DMA TX */
4369  if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4370  {
4371  /* Call Directly XferAbortCallback function in case of error */
4372  hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4373  }
4374  }
4375  }
4376  }
4377  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
4378  {
4379  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
4380  {
4381  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
4382 
4383  /* Abort DMA Xfer if any */
4384  if (hfmpi2c->hdmarx != NULL)
4385  {
4386  /* Set the FMPI2C DMA Abort callback :
4387  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4388  hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
4389 
4390  /* Abort DMA RX */
4391  if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
4392  {
4393  /* Call Directly XferAbortCallback function in case of error */
4394  hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
4395  }
4396  }
4397  }
4398  }
4399  else
4400  {
4401  /* Nothing to do */
4402  }
4403 
4405  hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
4406  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4407 
4408  /* Enable Address Acknowledge */
4409  hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
4410 
4411  /* Prepare transfer parameters */
4412  hfmpi2c->pBuffPtr = pData;
4413  hfmpi2c->XferCount = Size;
4414  hfmpi2c->XferSize = hfmpi2c->XferCount;
4415  hfmpi2c->XferOptions = XferOptions;
4416  hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
4417 
4418  if (hfmpi2c->hdmarx != NULL)
4419  {
4420  /* Set the FMPI2C DMA transfer complete callback */
4421  hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
4422 
4423  /* Set the DMA error callback */
4424  hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
4425 
4426  /* Set the unused DMA callbacks to NULL */
4427  hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
4428  hfmpi2c->hdmarx->XferAbortCallback = NULL;
4429 
4430  /* Enable the DMA stream */
4431  dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR,
4432  (uint32_t)pData, hfmpi2c->XferSize);
4433  }
4434  else
4435  {
4436  /* Update FMPI2C state */
4437  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4438  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4439 
4440  /* Update FMPI2C error code */
4441  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
4442 
4443  /* Process Unlocked */
4444  __HAL_UNLOCK(hfmpi2c);
4445 
4446  return HAL_ERROR;
4447  }
4448 
4449  if (dmaxferstatus == HAL_OK)
4450  {
4451  /* Update XferCount value */
4452  hfmpi2c->XferCount -= hfmpi2c->XferSize;
4453 
4454  /* Reset XferSize */
4455  hfmpi2c->XferSize = 0;
4456  }
4457  else
4458  {
4459  /* Update FMPI2C state */
4460  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4461  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4462 
4463  /* Update FMPI2C error code */
4464  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
4465 
4466  /* Process Unlocked */
4467  __HAL_UNLOCK(hfmpi2c);
4468 
4469  return HAL_ERROR;
4470  }
4471 
4472  tmp = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4473  if ((FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4474  {
4475  /* Clear ADDR flag after prepare the transfer parameters */
4476  /* This action will generate an acknowledge to the Master */
4477  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4478  }
4479 
4480  /* Process Unlocked */
4481  __HAL_UNLOCK(hfmpi2c);
4482 
4483  /* Enable DMA Request */
4484  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
4485 
4486  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4487  to avoid the risk of FMPI2C interrupt handle execution before current
4488  process unlock */
4489  /* REnable ADDR interrupt */
4490  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
4491 
4492  return HAL_OK;
4493  }
4494  else
4495  {
4496  return HAL_ERROR;
4497  }
4498 }
4499 
4506 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
4507 {
4508  if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
4509  {
4510  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4511  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4512 
4513  /* Enable the Address Match interrupt */
4514  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4515 
4516  return HAL_OK;
4517  }
4518  else
4519  {
4520  return HAL_BUSY;
4521  }
4522 }
4523 
4530 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
4531 {
4532  /* Declaration of tmp to prevent undefined behavior of volatile usage */
4533  uint32_t tmp;
4534 
4535  /* Disable Address listen mode only if a transfer is not ongoing */
4536  if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
4537  {
4538  tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK;
4539  hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode);
4540  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4541  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4542  hfmpi2c->XferISR = NULL;
4543 
4544  /* Disable the Address Match interrupt */
4545  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4546 
4547  return HAL_OK;
4548  }
4549  else
4550  {
4551  return HAL_BUSY;
4552  }
4553 }
4554 
4563 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
4564 {
4565  if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER)
4566  {
4567  /* Process Locked */
4568  __HAL_LOCK(hfmpi2c);
4569 
4570  /* Disable Interrupts and Store Previous state */
4572  {
4573  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4574  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
4575  }
4576  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
4577  {
4578  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
4579  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
4580  }
4581  else
4582  {
4583  /* Do nothing */
4584  }
4585 
4586  /* Set State at HAL_FMPI2C_STATE_ABORT */
4587  hfmpi2c->State = HAL_FMPI2C_STATE_ABORT;
4588 
4589  /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */
4590  /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
4591  FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP);
4592 
4593  /* Process Unlocked */
4594  __HAL_UNLOCK(hfmpi2c);
4595 
4596  /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4597  to avoid the risk of FMPI2C interrupt handle execution before current
4598  process unlock */
4599  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
4600 
4601  return HAL_OK;
4602  }
4603  else
4604  {
4605  /* Wrong usage of abort function */
4606  /* This function should be used only in case of abort monitored by master device */
4607  return HAL_ERROR;
4608  }
4609 }
4610 
4625 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) /* Derogation MISRAC2012-Rule-8.13 */
4626 {
4627  /* Get current IT Flags and IT sources value */
4628  uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
4629  uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
4630 
4631  /* FMPI2C events treatment -------------------------------------*/
4632  if (hfmpi2c->XferISR != NULL)
4633  {
4634  hfmpi2c->XferISR(hfmpi2c, itflags, itsources);
4635  }
4636 }
4637 
4645 {
4646  uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
4647  uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
4648  uint32_t tmperror;
4649 
4650  /* FMPI2C Bus error interrupt occurred ------------------------------------*/
4651  if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_BERR) != RESET) && \
4652  (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4653  {
4654  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
4655 
4656  /* Clear BERR flag */
4657  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
4658  }
4659 
4660  /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
4661  if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_OVR) != RESET) && \
4662  (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4663  {
4664  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
4665 
4666  /* Clear OVR flag */
4667  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
4668  }
4669 
4670  /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
4671  if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_ARLO) != RESET) && \
4672  (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4673  {
4674  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
4675 
4676  /* Clear ARLO flag */
4677  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
4678  }
4679 
4680  /* Store current volatile hfmpi2c->ErrorCode, misra rule */
4681  tmperror = hfmpi2c->ErrorCode;
4682 
4683  /* Call the Error Callback in case of Error detected */
4684  if ((tmperror & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE)
4685  {
4686  FMPI2C_ITError(hfmpi2c, tmperror);
4687  }
4688 }
4689 
4697 {
4698  /* Prevent unused argument(s) compilation warning */
4699  UNUSED(hfmpi2c);
4700 
4701  /* NOTE : This function should not be modified, when the callback is needed,
4702  the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file
4703  */
4705 
4713 {
4714  /* Prevent unused argument(s) compilation warning */
4715  UNUSED(hfmpi2c);
4716 
4717  /* NOTE : This function should not be modified, when the callback is needed,
4718  the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file
4719  */
4721 
4728 {
4729  /* Prevent unused argument(s) compilation warning */
4730  UNUSED(hfmpi2c);
4731 
4732  /* NOTE : This function should not be modified, when the callback is needed,
4733  the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file
4734  */
4736 
4744 {
4745  /* Prevent unused argument(s) compilation warning */
4746  UNUSED(hfmpi2c);
4747 
4748  /* NOTE : This function should not be modified, when the callback is needed,
4749  the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file
4750  */
4752 
4761 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
4762 {
4763  /* Prevent unused argument(s) compilation warning */
4764  UNUSED(hfmpi2c);
4765  UNUSED(TransferDirection);
4766  UNUSED(AddrMatchCode);
4767 
4768  /* NOTE : This function should not be modified, when the callback is needed,
4769  the HAL_FMPI2C_AddrCallback() could be implemented in the user file
4770  */
4771 }
4772 
4780 {
4781  /* Prevent unused argument(s) compilation warning */
4782  UNUSED(hfmpi2c);
4783 
4784  /* NOTE : This function should not be modified, when the callback is needed,
4785  the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file
4786  */
4788 
4796 {
4797  /* Prevent unused argument(s) compilation warning */
4798  UNUSED(hfmpi2c);
4799 
4800  /* NOTE : This function should not be modified, when the callback is needed,
4801  the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file
4802  */
4804 
4812 {
4813  /* Prevent unused argument(s) compilation warning */
4814  UNUSED(hfmpi2c);
4815 
4816  /* NOTE : This function should not be modified, when the callback is needed,
4817  the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file
4818  */
4820 
4827 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4828 {
4829  /* Prevent unused argument(s) compilation warning */
4830  UNUSED(hfmpi2c);
4831 
4832  /* NOTE : This function should not be modified, when the callback is needed,
4833  the HAL_FMPI2C_ErrorCallback could be implemented in the user file
4834  */
4836 
4844 {
4845  /* Prevent unused argument(s) compilation warning */
4846  UNUSED(hfmpi2c);
4847 
4848  /* NOTE : This function should not be modified, when the callback is needed,
4849  the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file
4850  */
4852 
4879 {
4880  /* Return FMPI2C handle state */
4881  return hfmpi2c->State;
4882 }
4883 
4891 {
4892  return hfmpi2c->Mode;
4893 }
4894 
4901 uint32_t HAL_FMPI2C_GetError(const FMPI2C_HandleTypeDef *hfmpi2c)
4902 {
4903  return hfmpi2c->ErrorCode;
4904 }
4905 
4926 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
4927  uint32_t ITSources)
4928 {
4929  uint16_t devaddress;
4930  uint32_t tmpITFlags = ITFlags;
4931 
4932  /* Process Locked */
4933  __HAL_LOCK(hfmpi2c);
4934 
4935  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
4936  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
4937  {
4938  /* Clear NACK Flag */
4939  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4940 
4941  /* Set corresponding Error Code */
4942  /* No need to generate STOP, it is automatically done */
4943  /* Error callback will be send during stop flag treatment */
4944  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4945 
4946  /* Flush TX register */
4947  FMPI2C_Flush_TXDR(hfmpi2c);
4948  }
4949  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
4950  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
4951  {
4952  /* Remove RXNE flag on temporary variable as read done */
4953  tmpITFlags &= ~FMPI2C_FLAG_RXNE;
4954 
4955  /* Read data from RXDR */
4956  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
4957 
4958  /* Increment Buffer pointer */
4959  hfmpi2c->pBuffPtr++;
4960 
4961  hfmpi2c->XferSize--;
4962  hfmpi2c->XferCount--;
4963  }
4964  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) == RESET) && \
4965  ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
4966  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET)))
4967  {
4968  /* Write data to TXDR */
4969  if (hfmpi2c->XferCount != 0U)
4970  {
4971  /* Write data to TXDR */
4972  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
4973 
4974  /* Increment Buffer pointer */
4975  hfmpi2c->pBuffPtr++;
4976 
4977  hfmpi2c->XferSize--;
4978  hfmpi2c->XferCount--;
4979  }
4980  }
4981  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TCR) != RESET) && \
4982  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
4983  {
4984  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
4985  {
4986  devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
4987 
4988  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
4989  {
4990  /* Errata workaround 170323 */
4991  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
4992  {
4993  hfmpi2c->XferSize = 1U;
4994  }
4995  else
4996  {
4997  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
4998  }
4999  FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
5000  }
5001  else
5002  {
5003  hfmpi2c->XferSize = hfmpi2c->XferCount;
5004  if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
5005  {
5006  FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
5007  hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP);
5008  }
5009  else
5010  {
5011  FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
5012  FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
5013  }
5014  }
5015  }
5016  else
5017  {
5018  /* Call TxCpltCallback() if no stop mode is set */
5019  if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5020  {
5021  /* Call FMPI2C Master Sequential complete process */
5022  FMPI2C_ITMasterSeqCplt(hfmpi2c);
5023  }
5024  else
5025  {
5026  /* Wrong size Status regarding TCR flag event */
5027  /* Call the corresponding callback to inform upper layer of End of Transfer */
5028  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5029  }
5030  }
5031  }
5032  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) != RESET) && \
5033  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5034  {
5035  if (hfmpi2c->XferCount == 0U)
5036  {
5037  if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5038  {
5039  /* Generate a stop condition in case of no transfer option */
5040  if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
5041  {
5042  /* Generate Stop */
5043  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
5044  }
5045  else
5046  {
5047  /* Call FMPI2C Master Sequential complete process */
5048  FMPI2C_ITMasterSeqCplt(hfmpi2c);
5049  }
5050  }
5051  }
5052  else
5053  {
5054  /* Wrong size Status regarding TC flag event */
5055  /* Call the corresponding callback to inform upper layer of End of Transfer */
5056  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5057  }
5058  }
5059  else
5060  {
5061  /* Nothing to do */
5062  }
5063 
5064  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5065  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5066  {
5067  /* Call FMPI2C Master complete process */
5068  FMPI2C_ITMasterCplt(hfmpi2c, tmpITFlags);
5069  }
5070 
5071  /* Process Unlocked */
5072  __HAL_UNLOCK(hfmpi2c);
5073 
5074  return HAL_OK;
5075 }
5076 
5085 static HAL_StatusTypeDef FMPI2C_Mem_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5086  uint32_t ITSources)
5087 {
5088  uint32_t direction = FMPI2C_GENERATE_START_WRITE;
5089  uint32_t tmpITFlags = ITFlags;
5090 
5091  /* Process Locked */
5092  __HAL_LOCK(hfmpi2c);
5093 
5094  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
5095  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5096  {
5097  /* Clear NACK Flag */
5098  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5099 
5100  /* Set corresponding Error Code */
5101  /* No need to generate STOP, it is automatically done */
5102  /* Error callback will be send during stop flag treatment */
5103  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5104 
5105  /* Flush TX register */
5106  FMPI2C_Flush_TXDR(hfmpi2c);
5107  }
5108  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
5109  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
5110  {
5111  /* Remove RXNE flag on temporary variable as read done */
5112  tmpITFlags &= ~FMPI2C_FLAG_RXNE;
5113 
5114  /* Read data from RXDR */
5115  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
5116 
5117  /* Increment Buffer pointer */
5118  hfmpi2c->pBuffPtr++;
5119 
5120  hfmpi2c->XferSize--;
5121  hfmpi2c->XferCount--;
5122  }
5123  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
5124  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
5125  {
5126  if (hfmpi2c->Memaddress == 0xFFFFFFFFU)
5127  {
5128  /* Write data to TXDR */
5129  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
5130 
5131  /* Increment Buffer pointer */
5132  hfmpi2c->pBuffPtr++;
5133 
5134  hfmpi2c->XferSize--;
5135  hfmpi2c->XferCount--;
5136  }
5137  else
5138  {
5139  /* Write LSB part of Memory Address */
5140  hfmpi2c->Instance->TXDR = hfmpi2c->Memaddress;
5141 
5142  /* Reset Memaddress content */
5143  hfmpi2c->Memaddress = 0xFFFFFFFFU;
5144  }
5145  }
5146  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TCR) != RESET) && \
5147  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5148  {
5149  if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
5150  {
5151  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5152  {
5153  /* Errata workaround 170323 */
5154  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
5155  {
5156  hfmpi2c->XferSize = 1U;
5157  }
5158  else
5159  {
5160  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5161  }
5162  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5163  FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
5164  }
5165  else
5166  {
5167  hfmpi2c->XferSize = hfmpi2c->XferCount;
5168  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5169  FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
5170  }
5171  }
5172  else
5173  {
5174  /* Wrong size Status regarding TCR flag event */
5175  /* Call the corresponding callback to inform upper layer of End of Transfer */
5176  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5177  }
5178  }
5179  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) != RESET) && \
5180  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5181  {
5182  /* Disable Interrupt related to address step */
5183  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5184 
5185  /* Enable ERR, TC, STOP, NACK and RXI interrupts */
5186  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
5187 
5188  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5189  {
5190  direction = FMPI2C_GENERATE_START_READ;
5191  }
5192 
5193  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5194  {
5195  /* Errata workaround 170323 */
5196  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
5197  {
5198  hfmpi2c->XferSize = 1U;
5199  }
5200  else
5201  {
5202  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5203  }
5204 
5205  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5206  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5207  FMPI2C_RELOAD_MODE, direction);
5208  }
5209  else
5210  {
5211  hfmpi2c->XferSize = hfmpi2c->XferCount;
5212 
5213  /* Set NBYTES to write and generate RESTART */
5214  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5215  FMPI2C_AUTOEND_MODE, direction);
5216  }
5217  }
5218  else
5219  {
5220  /* Nothing to do */
5221  }
5222 
5223  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5224  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5225  {
5226  /* Call FMPI2C Master complete process */
5227  FMPI2C_ITMasterCplt(hfmpi2c, tmpITFlags);
5228  }
5229 
5230  /* Process Unlocked */
5231  __HAL_UNLOCK(hfmpi2c);
5232 
5233  return HAL_OK;
5234 }
5235 
5244 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5245  uint32_t ITSources)
5246 {
5247  uint32_t tmpoptions = hfmpi2c->XferOptions;
5248  uint32_t tmpITFlags = ITFlags;
5249 
5250  /* Process locked */
5251  __HAL_LOCK(hfmpi2c);
5252 
5253  /* Check if STOPF is set */
5254  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5255  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5256  {
5257  /* Call FMPI2C Slave complete process */
5258  FMPI2C_ITSlaveCplt(hfmpi2c, tmpITFlags);
5259  }
5260  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
5261  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5262  {
5263  /* Check that FMPI2C transfer finished */
5264  /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5265  /* Mean XferCount == 0*/
5266  /* So clear Flag NACKF only */
5267  if (hfmpi2c->XferCount == 0U)
5268  {
5269  if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
5270  /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
5271  Warning[Pa134]: left and right operands are identical */
5272  {
5273  /* Call FMPI2C Listen complete process */
5274  FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
5275  }
5276  else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
5277  {
5278  /* Clear NACK Flag */
5279  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5280 
5281  /* Flush TX register */
5282  FMPI2C_Flush_TXDR(hfmpi2c);
5283 
5284  /* Last Byte is Transmitted */
5285  /* Call FMPI2C Slave Sequential complete process */
5286  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5287  }
5288  else
5289  {
5290  /* Clear NACK Flag */
5291  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5292  }
5293  }
5294  else
5295  {
5296  /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5297  /* Clear NACK Flag */
5298  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5299 
5300  /* Set ErrorCode corresponding to a Non-Acknowledge */
5301  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5302 
5303  if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
5304  {
5305  /* Call the corresponding callback to inform upper layer of End of Transfer */
5306  FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
5307  }
5308  }
5309  }
5310  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
5311  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
5312  {
5313  if (hfmpi2c->XferCount > 0U)
5314  {
5315  /* Read data from RXDR */
5316  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
5317 
5318  /* Increment Buffer pointer */
5319  hfmpi2c->pBuffPtr++;
5320 
5321  hfmpi2c->XferSize--;
5322  hfmpi2c->XferCount--;
5323  }
5324 
5325  if ((hfmpi2c->XferCount == 0U) && \
5326  (tmpoptions != FMPI2C_NO_OPTION_FRAME))
5327  {
5328  /* Call FMPI2C Slave Sequential complete process */
5329  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5330  }
5331  }
5332  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
5333  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
5334  {
5335  FMPI2C_ITAddrCplt(hfmpi2c, tmpITFlags);
5336  }
5337  else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
5338  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
5339  {
5340  /* Write data to TXDR only if XferCount not reach "0" */
5341  /* A TXIS flag can be set, during STOP treatment */
5342  /* Check if all Data have already been sent */
5343  /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
5344  if (hfmpi2c->XferCount > 0U)
5345  {
5346  /* Write data to TXDR */
5347  hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
5348 
5349  /* Increment Buffer pointer */
5350  hfmpi2c->pBuffPtr++;
5351 
5352  hfmpi2c->XferCount--;
5353  hfmpi2c->XferSize--;
5354  }
5355  else
5356  {
5357  if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
5358  {
5359  /* Last Byte is Transmitted */
5360  /* Call FMPI2C Slave Sequential complete process */
5361  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5362  }
5363  }
5364  }
5365  else
5366  {
5367  /* Nothing to do */
5368  }
5369 
5370  /* Process Unlocked */
5371  __HAL_UNLOCK(hfmpi2c);
5372 
5373  return HAL_OK;
5374 }
5375 
5384 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5385  uint32_t ITSources)
5386 {
5387  uint16_t devaddress;
5388  uint32_t xfermode;
5389 
5390  /* Process Locked */
5391  __HAL_LOCK(hfmpi2c);
5392 
5393  if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
5394  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5395  {
5396  /* Clear NACK Flag */
5397  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5398 
5399  /* Set corresponding Error Code */
5400  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5401 
5402  /* No need to generate STOP, it is automatically done */
5403  /* But enable STOP interrupt, to treat it */
5404  /* Error callback will be send during stop flag treatment */
5405  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
5406 
5407  /* Flush TX register */
5408  FMPI2C_Flush_TXDR(hfmpi2c);
5409  }
5410  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TCR) != RESET) && \
5411  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5412  {
5413  /* Disable TC interrupt */
5414  __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI);
5415 
5416  if (hfmpi2c->XferCount != 0U)
5417  {
5418  /* Recover Slave address */
5419  devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
5420 
5421  /* Prepare the new XferSize to transfer */
5422  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5423  {
5424  /* Errata workaround 170323 */
5425  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
5426  {
5427  hfmpi2c->XferSize = 1U;
5428  }
5429  else
5430  {
5431  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5432  }
5433  xfermode = FMPI2C_RELOAD_MODE;
5434  }
5435  else
5436  {
5437  hfmpi2c->XferSize = hfmpi2c->XferCount;
5438  if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
5439  {
5440  xfermode = hfmpi2c->XferOptions;
5441  }
5442  else
5443  {
5444  xfermode = FMPI2C_AUTOEND_MODE;
5445  }
5446  }
5447 
5448  /* Set the new XferSize in Nbytes register */
5449  FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
5450 
5451  /* Update XferCount value */
5452  hfmpi2c->XferCount -= hfmpi2c->XferSize;
5453 
5454  /* Enable DMA Request */
5455  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5456  {
5457  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
5458  }
5459  else
5460  {
5461  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
5462  }
5463  }
5464  else
5465  {
5466  /* Call TxCpltCallback() if no stop mode is set */
5467  if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5468  {
5469  /* Call FMPI2C Master Sequential complete process */
5470  FMPI2C_ITMasterSeqCplt(hfmpi2c);
5471  }
5472  else
5473  {
5474  /* Wrong size Status regarding TCR flag event */
5475  /* Call the corresponding callback to inform upper layer of End of Transfer */
5476  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5477  }
5478  }
5479  }
5480  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TC) != RESET) && \
5481  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5482  {
5483  if (hfmpi2c->XferCount == 0U)
5484  {
5485  if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5486  {
5487  /* Generate a stop condition in case of no transfer option */
5488  if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
5489  {
5490  /* Generate Stop */
5491  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
5492  }
5493  else
5494  {
5495  /* Call FMPI2C Master Sequential complete process */
5496  FMPI2C_ITMasterSeqCplt(hfmpi2c);
5497  }
5498  }
5499  }
5500  else
5501  {
5502  /* Wrong size Status regarding TC flag event */
5503  /* Call the corresponding callback to inform upper layer of End of Transfer */
5504  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5505  }
5506  }
5507  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5508  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5509  {
5510  /* Call FMPI2C Master complete process */
5511  FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
5512  }
5513  else
5514  {
5515  /* Nothing to do */
5516  }
5517 
5518  /* Process Unlocked */
5519  __HAL_UNLOCK(hfmpi2c);
5520 
5521  return HAL_OK;
5522 }
5523 
5532 static HAL_StatusTypeDef FMPI2C_Mem_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5533  uint32_t ITSources)
5534 {
5535  uint32_t direction = FMPI2C_GENERATE_START_WRITE;
5536 
5537  /* Process Locked */
5538  __HAL_LOCK(hfmpi2c);
5539 
5540  if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
5541  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5542  {
5543  /* Clear NACK Flag */
5544  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5545 
5546  /* Set corresponding Error Code */
5547  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5548 
5549  /* No need to generate STOP, it is automatically done */
5550  /* But enable STOP interrupt, to treat it */
5551  /* Error callback will be send during stop flag treatment */
5552  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
5553 
5554  /* Flush TX register */
5555  FMPI2C_Flush_TXDR(hfmpi2c);
5556  }
5557  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
5558  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
5559  {
5560  /* Write LSB part of Memory Address */
5561  hfmpi2c->Instance->TXDR = hfmpi2c->Memaddress;
5562 
5563  /* Reset Memaddress content */
5564  hfmpi2c->Memaddress = 0xFFFFFFFFU;
5565  }
5566  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TCR) != RESET) && \
5567  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5568  {
5569  /* Disable Interrupt related to address step */
5570  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5571 
5572  /* Enable only Error interrupt */
5573  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
5574 
5575  if (hfmpi2c->XferCount != 0U)
5576  {
5577  /* Prepare the new XferSize to transfer */
5578  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5579  {
5580  /* Errata workaround 170323 */
5581  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
5582  {
5583  hfmpi2c->XferSize = 1U;
5584  }
5585  else
5586  {
5587  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5588  }
5589  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5590  FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
5591  }
5592  else
5593  {
5594  hfmpi2c->XferSize = hfmpi2c->XferCount;
5595  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5596  FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
5597  }
5598 
5599  /* Update XferCount value */
5600  hfmpi2c->XferCount -= hfmpi2c->XferSize;
5601 
5602  /* Enable DMA Request */
5603  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5604  {
5605  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
5606  }
5607  else
5608  {
5609  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
5610  }
5611  }
5612  else
5613  {
5614  /* Wrong size Status regarding TCR flag event */
5615  /* Call the corresponding callback to inform upper layer of End of Transfer */
5616  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5617  }
5618  }
5619  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TC) != RESET) && \
5620  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5621  {
5622  /* Disable Interrupt related to address step */
5623  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5624 
5625  /* Enable only Error and NACK interrupt for data transfer */
5626  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
5627 
5628  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5629  {
5630  direction = FMPI2C_GENERATE_START_READ;
5631  }
5632 
5633  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5634  {
5635  /* Errata workaround 170323 */
5636  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
5637  {
5638  hfmpi2c->XferSize = 1U;
5639  }
5640  else
5641  {
5642  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5643  }
5644 
5645  /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5646  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5647  FMPI2C_RELOAD_MODE, direction);
5648  }
5649  else
5650  {
5651  hfmpi2c->XferSize = hfmpi2c->XferCount;
5652 
5653  /* Set NBYTES to write and generate RESTART */
5654  FMPI2C_TransferConfig(hfmpi2c, (uint16_t)hfmpi2c->Devaddress, (uint8_t)hfmpi2c->XferSize,
5655  FMPI2C_AUTOEND_MODE, direction);
5656  }
5657 
5658  /* Update XferCount value */
5659  hfmpi2c->XferCount -= hfmpi2c->XferSize;
5660 
5661  /* Enable DMA Request */
5662  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5663  {
5664  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
5665  }
5666  else
5667  {
5668  hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
5669  }
5670  }
5671  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5672  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5673  {
5674  /* Call FMPI2C Master complete process */
5675  FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
5676  }
5677  else
5678  {
5679  /* Nothing to do */
5680  }
5681 
5682  /* Process Unlocked */
5683  __HAL_UNLOCK(hfmpi2c);
5684 
5685  return HAL_OK;
5686 }
5687 
5696 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5697  uint32_t ITSources)
5698 {
5699  uint32_t tmpoptions = hfmpi2c->XferOptions;
5700  uint32_t treatdmanack = 0U;
5701  HAL_FMPI2C_StateTypeDef tmpstate;
5702 
5703  /* Process locked */
5704  __HAL_LOCK(hfmpi2c);
5705 
5706  /* Check if STOPF is set */
5707  if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5708  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5709  {
5710  /* Call FMPI2C Slave complete process */
5711  FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
5712  }
5713  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
5714  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5715  {
5716  /* Check that FMPI2C transfer finished */
5717  /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5718  /* Mean XferCount == 0 */
5719  /* So clear Flag NACKF only */
5720  if ((FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET) ||
5721  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET))
5722  {
5723  /* Split check of hdmarx, for MISRA compliance */
5724  if (hfmpi2c->hdmarx != NULL)
5725  {
5726  if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET)
5727  {
5728  if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmarx) == 0U)
5729  {
5730  treatdmanack = 1U;
5731  }
5732  }
5733  }
5734 
5735  /* Split check of hdmatx, for MISRA compliance */
5736  if (hfmpi2c->hdmatx != NULL)
5737  {
5738  if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET)
5739  {
5740  if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmatx) == 0U)
5741  {
5742  treatdmanack = 1U;
5743  }
5744  }
5745  }
5746 
5747  if (treatdmanack == 1U)
5748  {
5749  if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
5750  /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
5751  Warning[Pa134]: left and right operands are identical */
5752  {
5753  /* Call FMPI2C Listen complete process */
5754  FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
5755  }
5756  else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
5757  {
5758  /* Clear NACK Flag */
5759  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5760 
5761  /* Flush TX register */
5762  FMPI2C_Flush_TXDR(hfmpi2c);
5763 
5764  /* Last Byte is Transmitted */
5765  /* Call FMPI2C Slave Sequential complete process */
5766  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5767  }
5768  else
5769  {
5770  /* Clear NACK Flag */
5771  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5772  }
5773  }
5774  else
5775  {
5776  /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5777  /* Clear NACK Flag */
5778  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5779 
5780  /* Set ErrorCode corresponding to a Non-Acknowledge */
5781  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5782 
5783  /* Store current hfmpi2c->State, solve MISRA2012-Rule-13.5 */
5784  tmpstate = hfmpi2c->State;
5785 
5786  if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
5787  {
5788  if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
5789  {
5790  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
5791  }
5792  else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
5793  {
5794  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
5795  }
5796  else
5797  {
5798  /* Do nothing */
5799  }
5800 
5801  /* Call the corresponding callback to inform upper layer of End of Transfer */
5802  FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
5803  }
5804  }
5805  }
5806  else
5807  {
5808  /* Only Clear NACK Flag, no DMA treatment is pending */
5809  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5810  }
5811  }
5812  else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
5813  (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
5814  {
5815  FMPI2C_ITAddrCplt(hfmpi2c, ITFlags);
5816  }
5817  else
5818  {
5819  /* Nothing to do */
5820  }
5821 
5822  /* Process Unlocked */
5823  __HAL_UNLOCK(hfmpi2c);
5824 
5825  return HAL_OK;
5826 }
5827 
5840 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
5841  uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5842  uint32_t Tickstart)
5843 {
5844  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
5845 
5846  /* Wait until TXIS flag is set */
5847  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5848  {
5849  return HAL_ERROR;
5850  }
5851 
5852  /* If Memory address size is 8Bit */
5853  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
5854  {
5855  /* Send Memory Address */
5856  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5857  }
5858  /* If Memory address size is 16Bit */
5859  else
5860  {
5861  /* Send MSB of Memory Address */
5862  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
5863 
5864  /* Wait until TXIS flag is set */
5865  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5866  {
5867  return HAL_ERROR;
5868  }
5869 
5870  /* Send LSB of Memory Address */
5871  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5872  }
5873 
5874  /* Wait until TCR flag is set */
5875  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
5876  {
5877  return HAL_ERROR;
5878  }
5879 
5880  return HAL_OK;
5881 }
5882 
5895 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
5896  uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5897  uint32_t Tickstart)
5898 {
5899  FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
5900 
5901  /* Wait until TXIS flag is set */
5902  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5903  {
5904  return HAL_ERROR;
5905  }
5906 
5907  /* If Memory address size is 8Bit */
5908  if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
5909  {
5910  /* Send Memory Address */
5911  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5912  }
5913  /* If Memory address size is 16Bit */
5914  else
5915  {
5916  /* Send MSB of Memory Address */
5917  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
5918 
5919  /* Wait until TXIS flag is set */
5920  if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5921  {
5922  return HAL_ERROR;
5923  }
5924 
5925  /* Send LSB of Memory Address */
5926  hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5927  }
5928 
5929  /* Wait until TC flag is set */
5930  if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
5931  {
5932  return HAL_ERROR;
5933  }
5934 
5935  return HAL_OK;
5936 }
5937 
5944 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
5945 {
5946  uint8_t transferdirection;
5947  uint16_t slaveaddrcode;
5948  uint16_t ownadd1code;
5949  uint16_t ownadd2code;
5950 
5951  /* Prevent unused argument(s) compilation warning */
5952  UNUSED(ITFlags);
5953 
5954  /* In case of Listen state, need to inform upper layer of address match code event */
5955  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
5956  {
5957  transferdirection = FMPI2C_GET_DIR(hfmpi2c);
5958  slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c);
5959  ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c);
5960  ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c);
5961 
5962  /* If 10bits addressing mode is selected */
5963  if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
5964  {
5965  if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
5966  {
5967  slaveaddrcode = ownadd1code;
5968  hfmpi2c->AddrEventCount++;
5969  if (hfmpi2c->AddrEventCount == 2U)
5970  {
5971  /* Reset Address Event counter */
5972  hfmpi2c->AddrEventCount = 0U;
5973 
5974  /* Clear ADDR flag */
5975  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
5976 
5977  /* Process Unlocked */
5978  __HAL_UNLOCK(hfmpi2c);
5979 
5980  /* Call Slave Addr callback */
5981 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5982  hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5983 #else
5984  HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5985 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5986  }
5987  }
5988  else
5989  {
5990  slaveaddrcode = ownadd2code;
5991 
5992  /* Disable ADDR Interrupts */
5993  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
5994 
5995  /* Process Unlocked */
5996  __HAL_UNLOCK(hfmpi2c);
5997 
5998  /* Call Slave Addr callback */
5999 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6000  hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
6001 #else
6002  HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
6003 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6004  }
6005  }
6006  /* else 7 bits addressing mode is selected */
6007  else
6008  {
6009  /* Disable ADDR Interrupts */
6010  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
6011 
6012  /* Process Unlocked */
6013  __HAL_UNLOCK(hfmpi2c);
6014 
6015  /* Call Slave Addr callback */
6016 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6017  hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
6018 #else
6019  HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
6020 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6021  }
6022  }
6023  /* Else clear address flag only */
6024  else
6025  {
6026  /* Clear ADDR flag */
6027  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
6028 
6029  /* Process Unlocked */
6030  __HAL_UNLOCK(hfmpi2c);
6031  }
6032 }
6033 
6039 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
6040 {
6041  /* Reset FMPI2C handle mode */
6042  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6043 
6044  /* No Generate Stop, to permit restart mode */
6045  /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */
6046  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
6047  {
6048  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6049  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
6050  hfmpi2c->XferISR = NULL;
6051 
6052  /* Disable Interrupts */
6053  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
6054 
6055  /* Process Unlocked */
6056  __HAL_UNLOCK(hfmpi2c);
6057 
6058  /* Call the corresponding callback to inform upper layer of End of Transfer */
6059 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6060  hfmpi2c->MasterTxCpltCallback(hfmpi2c);
6061 #else
6063 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6064  }
6065  /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
6066  else
6067  {
6068  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6069  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
6070  hfmpi2c->XferISR = NULL;
6071 
6072  /* Disable Interrupts */
6073  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
6074 
6075  /* Process Unlocked */
6076  __HAL_UNLOCK(hfmpi2c);
6077 
6078  /* Call the corresponding callback to inform upper layer of End of Transfer */
6079 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6080  hfmpi2c->MasterRxCpltCallback(hfmpi2c);
6081 #else
6083 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6084  }
6085 }
6086 
6092 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
6093 {
6094  uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
6095 
6096  /* Reset FMPI2C handle mode */
6097  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6098 
6099  /* If a DMA is ongoing, Update handle size context */
6100  if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
6101  {
6102  /* Disable DMA Request */
6103  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6104  }
6105  else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
6106  {
6107  /* Disable DMA Request */
6108  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6109  }
6110  else
6111  {
6112  /* Do nothing */
6113  }
6114 
6115  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
6116  {
6117  /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */
6118  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
6119  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
6120 
6121  /* Disable Interrupts */
6122  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
6123 
6124  /* Process Unlocked */
6125  __HAL_UNLOCK(hfmpi2c);
6126 
6127  /* Call the corresponding callback to inform upper layer of End of Transfer */
6128 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6129  hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
6130 #else
6132 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6133  }
6134 
6135  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
6136  {
6137  /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */
6138  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
6139  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
6140 
6141  /* Disable Interrupts */
6142  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
6143 
6144  /* Process Unlocked */
6145  __HAL_UNLOCK(hfmpi2c);
6146 
6147  /* Call the corresponding callback to inform upper layer of End of Transfer */
6148 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6149  hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
6150 #else
6152 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6153  }
6154  else
6155  {
6156  /* Nothing to do */
6157  }
6158 }
6159 
6166 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
6167 {
6168  uint32_t tmperror;
6169  uint32_t tmpITFlags = ITFlags;
6170  __IO uint32_t tmpreg;
6171 
6172  /* Clear STOP Flag */
6173  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
6174 
6175  /* Disable Interrupts and Store Previous state */
6176  if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
6177  {
6178  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
6179  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
6180  }
6181  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
6182  {
6183  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
6184  hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
6185  }
6186  else
6187  {
6188  /* Do nothing */
6189  }
6190 
6191  /* Clear Configuration Register 2 */
6192  FMPI2C_RESET_CR2(hfmpi2c);
6193 
6194  /* Reset handle parameters */
6195  hfmpi2c->XferISR = NULL;
6196  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
6197 
6198  if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET)
6199  {
6200  /* Clear NACK Flag */
6201  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6202 
6203  /* Set acknowledge error code */
6204  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
6205  }
6206 
6207  /* Fetch Last receive data if any */
6208  if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) && (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET))
6209  {
6210  /* Read data from RXDR */
6211  tmpreg = (uint8_t)hfmpi2c->Instance->RXDR;
6212  UNUSED(tmpreg);
6213  }
6214 
6215  /* Flush TX register */
6216  FMPI2C_Flush_TXDR(hfmpi2c);
6217 
6218  /* Store current volatile hfmpi2c->ErrorCode, misra rule */
6219  tmperror = hfmpi2c->ErrorCode;
6220 
6221  /* Call the corresponding callback to inform upper layer of End of Transfer */
6222  if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) || (tmperror != HAL_FMPI2C_ERROR_NONE))
6223  {
6224  /* Call the corresponding callback to inform upper layer of End of Transfer */
6225  FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
6226  }
6227  /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */
6228  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
6229  {
6230  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6231  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6232 
6233  if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
6234  {
6235  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6236 
6237  /* Process Unlocked */
6238  __HAL_UNLOCK(hfmpi2c);
6239 
6240  /* Call the corresponding callback to inform upper layer of End of Transfer */
6241 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6242  hfmpi2c->MemTxCpltCallback(hfmpi2c);
6243 #else
6245 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6246  }
6247  else
6248  {
6249  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6250 
6251  /* Process Unlocked */
6252  __HAL_UNLOCK(hfmpi2c);
6253 
6254  /* Call the corresponding callback to inform upper layer of End of Transfer */
6255 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6256  hfmpi2c->MasterTxCpltCallback(hfmpi2c);
6257 #else
6259 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6260  }
6261  }
6262  /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
6263  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
6264  {
6265  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6266  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6267 
6268  if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
6269  {
6270  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6271 
6272  /* Process Unlocked */
6273  __HAL_UNLOCK(hfmpi2c);
6274 
6275  /* Call the corresponding callback to inform upper layer of End of Transfer */
6276 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6277  hfmpi2c->MemRxCpltCallback(hfmpi2c);
6278 #else
6280 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6281  }
6282  else
6283  {
6284  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6285 
6286  /* Process Unlocked */
6287  __HAL_UNLOCK(hfmpi2c);
6288 
6289  /* Call the corresponding callback to inform upper layer of End of Transfer */
6290 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6291  hfmpi2c->MasterRxCpltCallback(hfmpi2c);
6292 #else
6294 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6295  }
6296  }
6297  else
6298  {
6299  /* Nothing to do */
6300  }
6301 }
6302 
6309 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
6310 {
6311  uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
6312  uint32_t tmpITFlags = ITFlags;
6313  uint32_t tmpoptions = hfmpi2c->XferOptions;
6314  HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
6315 
6316  /* Clear STOP Flag */
6317  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
6318 
6319  /* Disable Interrupts and Store Previous state */
6320  if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
6321  {
6322  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
6323  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
6324  }
6325  else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
6326  {
6327  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
6328  hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
6329  }
6330  else if (tmpstate == HAL_FMPI2C_STATE_LISTEN)
6331  {
6332  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT);
6333  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6334  }
6335  else
6336  {
6337  /* Do nothing */
6338  }
6339 
6340  /* Disable Address Acknowledge */
6341  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
6342 
6343  /* Clear Configuration Register 2 */
6344  FMPI2C_RESET_CR2(hfmpi2c);
6345 
6346  /* Flush TX register */
6347  FMPI2C_Flush_TXDR(hfmpi2c);
6348 
6349  /* If a DMA is ongoing, Update handle size context */
6350  if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
6351  {
6352  /* Disable DMA Request */
6353  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6354 
6355  if (hfmpi2c->hdmatx != NULL)
6356  {
6357  hfmpi2c->XferCount = (uint16_t)FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmatx);
6358  }
6359  }
6360  else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
6361  {
6362  /* Disable DMA Request */
6363  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6364 
6365  if (hfmpi2c->hdmarx != NULL)
6366  {
6367  hfmpi2c->XferCount = (uint16_t)FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmarx);
6368  }
6369  }
6370  else
6371  {
6372  /* Do nothing */
6373  }
6374 
6375  /* Store Last receive data if any */
6376  if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET)
6377  {
6378  /* Remove RXNE flag on temporary variable as read done */
6379  tmpITFlags &= ~FMPI2C_FLAG_RXNE;
6380 
6381  /* Read data from RXDR */
6382  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
6383 
6384  /* Increment Buffer pointer */
6385  hfmpi2c->pBuffPtr++;
6386 
6387  if ((hfmpi2c->XferSize > 0U))
6388  {
6389  hfmpi2c->XferSize--;
6390  hfmpi2c->XferCount--;
6391  }
6392  }
6393 
6394  /* All data are not transferred, so set error code accordingly */
6395  if (hfmpi2c->XferCount != 0U)
6396  {
6397  /* Set ErrorCode corresponding to a Non-Acknowledge */
6398  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
6399  }
6400 
6401  if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
6402  (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_IT_NACKI) != RESET))
6403  {
6404  /* Check that FMPI2C transfer finished */
6405  /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
6406  /* Mean XferCount == 0*/
6407  /* So clear Flag NACKF only */
6408  if (hfmpi2c->XferCount == 0U)
6409  {
6410  if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
6411  /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
6412  Warning[Pa134]: left and right operands are identical */
6413  {
6414  /* Call FMPI2C Listen complete process */
6415  FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
6416  }
6417  else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
6418  {
6419  /* Clear NACK Flag */
6420  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6421 
6422  /* Flush TX register */
6423  FMPI2C_Flush_TXDR(hfmpi2c);
6424 
6425  /* Last Byte is Transmitted */
6426  /* Call FMPI2C Slave Sequential complete process */
6427  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6428  }
6429  else
6430  {
6431  /* Clear NACK Flag */
6432  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6433  }
6434  }
6435  else
6436  {
6437  /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
6438  /* Clear NACK Flag */
6439  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6440 
6441  /* Set ErrorCode corresponding to a Non-Acknowledge */
6442  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
6443 
6444  if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
6445  {
6446  /* Call the corresponding callback to inform upper layer of End of Transfer */
6447  FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
6448  }
6449  }
6450  }
6451 
6452  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6453  hfmpi2c->XferISR = NULL;
6454 
6455  if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
6456  {
6457  /* Call the corresponding callback to inform upper layer of End of Transfer */
6458  FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
6459 
6460  /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6461  if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
6462  {
6463  /* Call FMPI2C Listen complete process */
6464  FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
6465  }
6466  }
6467  else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
6468  {
6469  /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
6470  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6471 
6472  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
6473  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6474  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6475 
6476  /* Process Unlocked */
6477  __HAL_UNLOCK(hfmpi2c);
6478 
6479  /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6480 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6481  hfmpi2c->ListenCpltCallback(hfmpi2c);
6482 #else
6484 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6485  }
6486  /* Call the corresponding callback to inform upper layer of End of Transfer */
6487  else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
6488  {
6489  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6490  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6491 
6492  /* Process Unlocked */
6493  __HAL_UNLOCK(hfmpi2c);
6494 
6495  /* Call the corresponding callback to inform upper layer of End of Transfer */
6496 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6497  hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
6498 #else
6500 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6501  }
6502  else
6503  {
6504  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6505  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6506 
6507  /* Process Unlocked */
6508  __HAL_UNLOCK(hfmpi2c);
6509 
6510  /* Call the corresponding callback to inform upper layer of End of Transfer */
6511 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6512  hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
6513 #else
6515 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6516  }
6517 }
6518 
6525 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
6526 {
6527  /* Reset handle parameters */
6528  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
6529  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6530  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6531  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6532  hfmpi2c->XferISR = NULL;
6533 
6534  /* Store Last receive data if any */
6535  if (FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_RXNE) != RESET)
6536  {
6537  /* Read data from RXDR */
6538  *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
6539 
6540  /* Increment Buffer pointer */
6541  hfmpi2c->pBuffPtr++;
6542 
6543  if ((hfmpi2c->XferSize > 0U))
6544  {
6545  hfmpi2c->XferSize--;
6546  hfmpi2c->XferCount--;
6547 
6548  /* Set ErrorCode corresponding to a Non-Acknowledge */
6549  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
6550  }
6551  }
6552 
6553  /* Disable all Interrupts*/
6554  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
6555 
6556  /* Clear NACK Flag */
6557  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6558 
6559  /* Process Unlocked */
6560  __HAL_UNLOCK(hfmpi2c);
6561 
6562  /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6563 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6564  hfmpi2c->ListenCpltCallback(hfmpi2c);
6565 #else
6567 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6568 }
6569 
6576 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode)
6577 {
6578  HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
6579 
6580  uint32_t tmppreviousstate;
6581 
6582  /* Reset handle parameters */
6583  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6584  hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
6585  hfmpi2c->XferCount = 0U;
6586 
6587  /* Set new error code */
6588  hfmpi2c->ErrorCode |= ErrorCode;
6589 
6590  /* Disable Interrupts */
6591  if ((tmpstate == HAL_FMPI2C_STATE_LISTEN) ||
6592  (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) ||
6593  (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
6594  {
6595  /* Disable all interrupts, except interrupts related to LISTEN state */
6596  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
6597 
6598  /* keep HAL_FMPI2C_STATE_LISTEN if set */
6599  hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
6600  hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
6601  }
6602  else
6603  {
6604  /* Disable all interrupts */
6605  FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
6606 
6607  /* Flush TX register */
6608  FMPI2C_Flush_TXDR(hfmpi2c);
6609 
6610  /* If state is an abort treatment on going, don't change state */
6611  /* This change will be do later */
6612  if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT)
6613  {
6614  /* Set HAL_FMPI2C_STATE_READY */
6615  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6616 
6617  /* Check if a STOPF is detected */
6618  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
6619  {
6620  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
6621  {
6622  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6623  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
6624  }
6625 
6626  /* Clear STOP Flag */
6627  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
6628  }
6629 
6630  }
6631  hfmpi2c->XferISR = NULL;
6632  }
6633 
6634  /* Abort DMA TX transfer if any */
6635  tmppreviousstate = hfmpi2c->PreviousState;
6636 
6637  if ((hfmpi2c->hdmatx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_TX) || \
6638  (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_TX)))
6639  {
6640  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
6641  {
6642  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6643  }
6644 
6645  if (HAL_DMA_GetState(hfmpi2c->hdmatx) != HAL_DMA_STATE_READY)
6646  {
6647  /* Set the FMPI2C DMA Abort callback :
6648  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
6649  hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
6650 
6651  /* Process Unlocked */
6652  __HAL_UNLOCK(hfmpi2c);
6653 
6654  /* Abort DMA TX */
6655  if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
6656  {
6657  /* Call Directly XferAbortCallback function in case of error */
6658  hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
6659  }
6660  }
6661  else
6662  {
6663  FMPI2C_TreatErrorCallback(hfmpi2c);
6664  }
6665  }
6666  /* Abort DMA RX transfer if any */
6667  else if ((hfmpi2c->hdmarx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_RX) || \
6668  (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_RX)))
6669  {
6670  if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
6671  {
6672  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6673  }
6674 
6675  if (HAL_DMA_GetState(hfmpi2c->hdmarx) != HAL_DMA_STATE_READY)
6676  {
6677  /* Set the FMPI2C DMA Abort callback :
6678  will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
6679  hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
6680 
6681  /* Process Unlocked */
6682  __HAL_UNLOCK(hfmpi2c);
6683 
6684  /* Abort DMA RX */
6685  if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
6686  {
6687  /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */
6688  hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
6689  }
6690  }
6691  else
6692  {
6693  FMPI2C_TreatErrorCallback(hfmpi2c);
6694  }
6695  }
6696  else
6697  {
6698  FMPI2C_TreatErrorCallback(hfmpi2c);
6699  }
6700 }
6701 
6707 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
6708 {
6709  if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
6710  {
6711  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6712  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6713 
6714  /* Process Unlocked */
6715  __HAL_UNLOCK(hfmpi2c);
6716 
6717  /* Call the corresponding callback to inform upper layer of End of Transfer */
6718 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6719  hfmpi2c->AbortCpltCallback(hfmpi2c);
6720 #else
6722 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6723  }
6724  else
6725  {
6726  hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6727 
6728  /* Process Unlocked */
6729  __HAL_UNLOCK(hfmpi2c);
6730 
6731  /* Call the corresponding callback to inform upper layer of End of Transfer */
6732 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6733  hfmpi2c->ErrorCallback(hfmpi2c);
6734 #else
6735  HAL_FMPI2C_ErrorCallback(hfmpi2c);
6736 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6737  }
6738 }
6739 
6745 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c)
6746 {
6747  /* If a pending TXIS flag is set */
6748  /* Write a dummy data in TXDR to clear it */
6749  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET)
6750  {
6751  hfmpi2c->Instance->TXDR = 0x00U;
6752  }
6753 
6754  /* Flush TX register if not empty */
6755  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET)
6756  {
6757  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE);
6758  }
6759 }
6760 
6766 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
6767 {
6768  /* Derogation MISRAC2012-Rule-11.5 */
6769  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6770 
6771  /* Disable DMA Request */
6772  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6773 
6774  /* If last transfer, enable STOP interrupt */
6775  if (hfmpi2c->XferCount == 0U)
6776  {
6777  /* Enable STOP interrupt */
6778  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
6779  }
6780  /* else prepare a new DMA transfer and enable TCReload interrupt */
6781  else
6782  {
6783  /* Update Buffer pointer */
6784  hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
6785 
6786  /* Set the XferSize to transfer */
6787  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
6788  {
6789  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
6790  }
6791  else
6792  {
6793  hfmpi2c->XferSize = hfmpi2c->XferCount;
6794  }
6795 
6796  /* Enable the DMA stream */
6797  if (HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR,
6798  hfmpi2c->XferSize) != HAL_OK)
6799  {
6800  /* Call the corresponding callback to inform upper layer of End of Transfer */
6801  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6802  }
6803  else
6804  {
6805  /* Enable TC interrupts */
6806  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
6807  }
6808  }
6809 }
6810 
6811 
6817 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
6818 {
6819  /* Derogation MISRAC2012-Rule-11.5 */
6820  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6821  uint32_t tmpoptions = hfmpi2c->XferOptions;
6822 
6823  if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
6824  {
6825  /* Disable DMA Request */
6826  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6827 
6828  /* Last Byte is Transmitted */
6829  /* Call FMPI2C Slave Sequential complete process */
6830  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6831  }
6832  else
6833  {
6834  /* No specific action, Master fully manage the generation of STOP condition */
6835  /* Mean that this generation can arrive at any time, at the end or during DMA process */
6836  /* So STOP condition should be manage through Interrupt treatment */
6837  }
6838 }
6839 
6840 
6846 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
6847 {
6848  /* Derogation MISRAC2012-Rule-11.5 */
6849  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6850 
6851  /* Disable DMA Request */
6852  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6853 
6854  /* If last transfer, enable STOP interrupt */
6855  if (hfmpi2c->XferCount == 0U)
6856  {
6857  /* Enable STOP interrupt */
6858  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
6859  }
6860  /* else prepare a new DMA transfer and enable TCReload interrupt */
6861  else
6862  {
6863  /* Update Buffer pointer */
6864  hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
6865 
6866  /* Set the XferSize to transfer */
6867  if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
6868  {
6869  /* Errata workaround 170323 */
6870  if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
6871  {
6872  hfmpi2c->XferSize = 1U;
6873  }
6874  else
6875  {
6876  hfmpi2c->XferSize = MAX_NBYTE_SIZE;
6877  }
6878  }
6879  else
6880  {
6881  hfmpi2c->XferSize = hfmpi2c->XferCount;
6882  }
6883 
6884  /* Enable the DMA stream */
6885  if (HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr,
6886  hfmpi2c->XferSize) != HAL_OK)
6887  {
6888  /* Call the corresponding callback to inform upper layer of End of Transfer */
6889  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6890  }
6891  else
6892  {
6893  /* Enable TC interrupts */
6894  FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
6895  }
6896  }
6897 }
6898 
6899 
6905 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
6906 {
6907  /* Derogation MISRAC2012-Rule-11.5 */
6908  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6909  uint32_t tmpoptions = hfmpi2c->XferOptions;
6910 
6911  if ((FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmarx) == 0U) && \
6912  (tmpoptions != FMPI2C_NO_OPTION_FRAME))
6913  {
6914  /* Disable DMA Request */
6915  hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6916 
6917  /* Call FMPI2C Slave Sequential complete process */
6918  FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6919  }
6920  else
6921  {
6922  /* No specific action, Master fully manage the generation of STOP condition */
6923  /* Mean that this generation can arrive at any time, at the end or during DMA process */
6924  /* So STOP condition should be manage through Interrupt treatment */
6925  }
6926 }
6927 
6928 
6934 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
6935 {
6936  uint32_t treatdmaerror = 0U;
6937  /* Derogation MISRAC2012-Rule-11.5 */
6938  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6939 
6940  if (hfmpi2c->hdmatx != NULL)
6941  {
6942  if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmatx) == 0U)
6943  {
6944  treatdmaerror = 1U;
6945  }
6946  }
6947 
6948  if (hfmpi2c->hdmarx != NULL)
6949  {
6950  if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c->hdmarx) == 0U)
6951  {
6952  treatdmaerror = 1U;
6953  }
6954  }
6955 
6956  /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */
6957  if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U))
6958  {
6959  /* Disable Acknowledge */
6960  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
6961 
6962  /* Call the corresponding callback to inform upper layer of End of Transfer */
6963  FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6964  }
6965 }
6966 
6967 
6974 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma)
6975 {
6976  /* Derogation MISRAC2012-Rule-11.5 */
6977  FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6978 
6979  /* Reset AbortCpltCallback */
6980  if (hfmpi2c->hdmatx != NULL)
6981  {
6982  hfmpi2c->hdmatx->XferAbortCallback = NULL;
6983  }
6984  if (hfmpi2c->hdmarx != NULL)
6985  {
6986  hfmpi2c->hdmarx->XferAbortCallback = NULL;
6987  }
6988 
6989  FMPI2C_TreatErrorCallback(hfmpi2c);
6990 }
6991 
6992 
7004 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
7005  uint32_t Timeout, uint32_t Tickstart)
7006 {
7007  while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status)
7008  {
7009  /* Check if an error is detected */
7010  if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
7011  {
7012  return HAL_ERROR;
7013  }
7014 
7015  /* Check for the Timeout */
7016  if (Timeout != HAL_MAX_DELAY)
7017  {
7018  if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7019  {
7020  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status))
7021  {
7022  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
7023  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7024  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
7025 
7026  /* Process Unlocked */
7027  __HAL_UNLOCK(hfmpi2c);
7028  return HAL_ERROR;
7029  }
7030  }
7031  }
7032  }
7033  return HAL_OK;
7034 }
7035 
7044 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
7045  uint32_t Tickstart)
7046 {
7047  while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
7048  {
7049  /* Check if an error is detected */
7050  if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
7051  {
7052  return HAL_ERROR;
7053  }
7054 
7055  /* Check for the Timeout */
7056  if (Timeout != HAL_MAX_DELAY)
7057  {
7058  if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7059  {
7060  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET))
7061  {
7062  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
7063  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7064  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
7065 
7066  /* Process Unlocked */
7067  __HAL_UNLOCK(hfmpi2c);
7068 
7069  return HAL_ERROR;
7070  }
7071  }
7072  }
7073  }
7074  return HAL_OK;
7075 }
7076 
7085 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
7086  uint32_t Tickstart)
7087 {
7088  while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
7089  {
7090  /* Check if an error is detected */
7091  if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
7092  {
7093  return HAL_ERROR;
7094  }
7095 
7096  /* Check for the Timeout */
7097  if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7098  {
7099  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET))
7100  {
7101  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
7102  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7103  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
7104 
7105  /* Process Unlocked */
7106  __HAL_UNLOCK(hfmpi2c);
7107 
7108  return HAL_ERROR;
7109  }
7110  }
7111  }
7112  return HAL_OK;
7113 }
7114 
7123 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
7124  uint32_t Tickstart)
7125 {
7126  HAL_StatusTypeDef status = HAL_OK;
7127 
7128  while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET) && (status == HAL_OK))
7129  {
7130  /* Check if an error is detected */
7131  if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
7132  {
7133  status = HAL_ERROR;
7134  }
7135 
7136  /* Check if a STOPF is detected */
7137  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) && (status == HAL_OK))
7138  {
7139  /* Check if an RXNE is pending */
7140  /* Store Last receive data if any */
7141  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U))
7142  {
7143  /* Return HAL_OK */
7144  /* The Reading of data from RXDR will be done in caller function */
7145  status = HAL_OK;
7146  }
7147 
7148  /* Check a no-acknowledge have been detected */
7149  if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
7150  {
7151  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
7152  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF;
7153 
7154  /* Clear STOP Flag */
7155  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
7156 
7157  /* Clear Configuration Register 2 */
7158  FMPI2C_RESET_CR2(hfmpi2c);
7159 
7160  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7161  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
7162 
7163  /* Process Unlocked */
7164  __HAL_UNLOCK(hfmpi2c);
7165 
7166  status = HAL_ERROR;
7167  }
7168  else
7169  {
7170  hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
7171  }
7172  }
7173 
7174  /* Check for the Timeout */
7175  if ((((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) && (status == HAL_OK))
7176  {
7177  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET))
7178  {
7179  hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
7180  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7181 
7182  /* Process Unlocked */
7183  __HAL_UNLOCK(hfmpi2c);
7184 
7185  status = HAL_ERROR;
7186  }
7187  }
7188  }
7189  return status;
7190 }
7191 
7200 static HAL_StatusTypeDef FMPI2C_IsErrorOccurred(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
7201 {
7202  HAL_StatusTypeDef status = HAL_OK;
7203  uint32_t itflag = hfmpi2c->Instance->ISR;
7204  uint32_t error_code = 0;
7205  uint32_t tickstart = Tickstart;
7206  uint32_t tmp1;
7208 
7209  if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_AF))
7210  {
7211  /* Clear NACKF Flag */
7212  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
7213 
7214  /* Wait until STOP Flag is set or timeout occurred */
7215  /* AutoEnd should be initiate after AF */
7216  while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (status == HAL_OK))
7217  {
7218  /* Check for the Timeout */
7219  if (Timeout != HAL_MAX_DELAY)
7220  {
7221  if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
7222  {
7223  tmp1 = (uint32_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_STOP);
7224  tmp2 = hfmpi2c->Mode;
7225 
7226  /* In case of FMPI2C still busy, try to regenerate a STOP manually */
7227  if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) != RESET) && \
7228  (tmp1 != FMPI2C_CR2_STOP) && \
7229  (tmp2 != HAL_FMPI2C_MODE_SLAVE))
7230  {
7231  /* Generate Stop */
7232  hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
7233 
7234  /* Update Tick with new reference */
7235  tickstart = HAL_GetTick();
7236  }
7237 
7238  while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
7239  {
7240  /* Check for the Timeout */
7241  if ((HAL_GetTick() - tickstart) > FMPI2C_TIMEOUT_STOPF)
7242  {
7243  error_code |= HAL_FMPI2C_ERROR_TIMEOUT;
7244 
7245  status = HAL_ERROR;
7246 
7247  break;
7248  }
7249  }
7250  }
7251  }
7252  }
7253 
7254  /* In case STOP Flag is detected, clear it */
7255  if (status == HAL_OK)
7256  {
7257  /* Clear STOP Flag */
7258  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
7259  }
7260 
7261  error_code |= HAL_FMPI2C_ERROR_AF;
7262 
7263  status = HAL_ERROR;
7264  }
7265 
7266  /* Refresh Content of Status register */
7267  itflag = hfmpi2c->Instance->ISR;
7268 
7269  /* Then verify if an additional errors occurs */
7270  /* Check if a Bus error occurred */
7271  if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_BERR))
7272  {
7273  error_code |= HAL_FMPI2C_ERROR_BERR;
7274 
7275  /* Clear BERR flag */
7276  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
7277 
7278  status = HAL_ERROR;
7279  }
7280 
7281  /* Check if an Over-Run/Under-Run error occurred */
7282  if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_OVR))
7283  {
7284  error_code |= HAL_FMPI2C_ERROR_OVR;
7285 
7286  /* Clear OVR flag */
7287  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
7288 
7289  status = HAL_ERROR;
7290  }
7291 
7292  /* Check if an Arbitration Loss error occurred */
7293  if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_ARLO))
7294  {
7295  error_code |= HAL_FMPI2C_ERROR_ARLO;
7296 
7297  /* Clear ARLO flag */
7298  __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
7299 
7300  status = HAL_ERROR;
7301  }
7302 
7303  if (status != HAL_OK)
7304  {
7305  /* Flush TX register */
7306  FMPI2C_Flush_TXDR(hfmpi2c);
7307 
7308  /* Clear Configuration Register 2 */
7309  FMPI2C_RESET_CR2(hfmpi2c);
7310 
7311  hfmpi2c->ErrorCode |= error_code;
7312  hfmpi2c->State = HAL_FMPI2C_STATE_READY;
7313  hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
7314 
7315  /* Process Unlocked */
7316  __HAL_UNLOCK(hfmpi2c);
7317  }
7318 
7319  return status;
7320 }
7321 
7341 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
7342  uint32_t Request)
7343 {
7344  /* Check the parameters */
7345  assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
7346  assert_param(IS_TRANSFER_MODE(Mode));
7347  assert_param(IS_TRANSFER_REQUEST(Request));
7348 
7349  /* Declaration of tmp to prevent undefined behavior of volatile usage */
7350  uint32_t tmp = ((uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
7351  (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
7352  (uint32_t)Mode | (uint32_t)Request) & (~0x80000000U));
7353 
7354  /* update CR2 register */
7355  MODIFY_REG(hfmpi2c->Instance->CR2, \
7356  ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
7357  (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | \
7358  FMPI2C_CR2_START | FMPI2C_CR2_STOP)), tmp);
7359 }
7360 
7368 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
7369 {
7370  uint32_t tmpisr = 0U;
7371 
7372  if ((hfmpi2c->XferISR != FMPI2C_Master_ISR_DMA) && \
7373  (hfmpi2c->XferISR != FMPI2C_Slave_ISR_DMA) && \
7374  (hfmpi2c->XferISR != FMPI2C_Mem_ISR_DMA))
7375  {
7376  if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
7377  {
7378  /* Enable ERR, STOP, NACK and ADDR interrupts */
7379  tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
7380  }
7381 
7382  if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
7383  {
7384  /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7385  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
7386  }
7387 
7388  if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
7389  {
7390  /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7391  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
7392  }
7393 
7394  if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
7395  {
7396  /* Enable ERR and NACK interrupts */
7397  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
7398  }
7399 
7400  if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
7401  {
7402  /* Enable STOP interrupts */
7403  tmpisr |= FMPI2C_IT_STOPI;
7404  }
7405  }
7406 
7407  else
7408  {
7409  if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
7410  {
7411  /* Enable ERR, STOP, NACK and ADDR interrupts */
7412  tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
7413  }
7414 
7415  if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
7416  {
7417  /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7418  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
7419  }
7420 
7421  if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
7422  {
7423  /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7424  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
7425  }
7426 
7427  if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
7428  {
7429  /* Enable ERR and NACK interrupts */
7430  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
7431  }
7432 
7433  if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
7434  {
7435  /* Enable STOP interrupts */
7436  tmpisr |= (FMPI2C_IT_STOPI | FMPI2C_IT_TCI);
7437  }
7438 
7439  if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
7440  {
7441  /* Enable TC interrupts */
7442  tmpisr |= FMPI2C_IT_TCI;
7443  }
7444  }
7445 
7446  /* Enable interrupts only at the end */
7447  /* to avoid the risk of FMPI2C interrupt handle execution before */
7448  /* all interrupts requested done */
7449  __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr);
7450 }
7451 
7459 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
7460 {
7461  uint32_t tmpisr = 0U;
7462 
7463  if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
7464  {
7465  /* Disable TC and TXI interrupts */
7466  tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI;
7467 
7468  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
7469  {
7470  /* Disable NACK and STOP interrupts */
7471  tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
7472  }
7473  }
7474 
7475  if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
7476  {
7477  /* Disable TC and RXI interrupts */
7478  tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI;
7479 
7480  if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
7481  {
7482  /* Disable NACK and STOP interrupts */
7483  tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
7484  }
7485  }
7486 
7487  if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
7488  {
7489  /* Disable ADDR, NACK and STOP interrupts */
7490  tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
7491  }
7492 
7493  if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
7494  {
7495  /* Enable ERR and NACK interrupts */
7496  tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
7497  }
7498 
7499  if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
7500  {
7501  /* Enable STOP interrupts */
7502  tmpisr |= FMPI2C_IT_STOPI;
7503  }
7504 
7505  if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
7506  {
7507  /* Enable TC interrupts */
7508  tmpisr |= FMPI2C_IT_TCI;
7509  }
7510 
7511  /* Disable interrupts only at the end */
7512  /* to avoid a breaking situation like at "t" time */
7513  /* all disable interrupts request are not done */
7514  __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr);
7515 }
7516 
7522 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c)
7523 {
7524  /* if user set XferOptions to FMPI2C_OTHER_FRAME */
7525  /* it request implicitly to generate a restart condition */
7526  /* set XferOptions to FMPI2C_FIRST_FRAME */
7527  if (hfmpi2c->XferOptions == FMPI2C_OTHER_FRAME)
7528  {
7529  hfmpi2c->XferOptions = FMPI2C_FIRST_FRAME;
7530  }
7531  /* else if user set XferOptions to FMPI2C_OTHER_AND_LAST_FRAME */
7532  /* it request implicitly to generate a restart condition */
7533  /* then generate a stop condition at the end of transfer */
7534  /* set XferOptions to FMPI2C_FIRST_AND_LAST_FRAME */
7535  else if (hfmpi2c->XferOptions == FMPI2C_OTHER_AND_LAST_FRAME)
7536  {
7537  hfmpi2c->XferOptions = FMPI2C_FIRST_AND_LAST_FRAME;
7538  }
7539  else
7540  {
7541  /* Nothing to do */
7542  }
7543 }
7544 
7549 #endif /* FMPI2C_CR1_PE */
7550 #endif /* HAL_FMPI2C_MODULE_ENABLED */
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
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.
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
Return the DMA error code.
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
Returns the DMA state.
HAL_StatusTypeDef HAL_FMPI2C_RegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID, pFMPI2C_CallbackTypeDef pCallback)
Register a User FMPI2C Callback To be used instead of the weak predefined callback.
HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
DeInitialize the FMPI2C peripheral.
HAL_StatusTypeDef HAL_FMPI2C_RegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, pFMPI2C_AddrCallbackTypeDef pCallback)
Register the Slave Address Match FMPI2C Callback To be used instead of the weak HAL_FMPI2C_AddrCallba...
void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
DeInitialize the FMPI2C MSP.
void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
Initialize the FMPI2C MSP.
HAL_StatusTypeDef HAL_FMPI2C_UnRegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID)
Unregister an FMPI2C Callback FMPI2C callback is redirected to the weak predefined callback.
HAL_StatusTypeDef HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c)
UnRegister the Slave Address Match FMPI2C Callback Info Ready FMPI2C Callback is redirected to the we...
HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
Initializes the FMPI2C according to the specified parameters in the FMPI2C_InitTypeDef and initialize...
HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
Receive in slave mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Receive in slave mode an amount of data in blocking mode.
HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
Checks if target device is ready for communication.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Read an amount of data in blocking mode from a specific memory address.
HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
Transmit in master mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
Write an amount of data in non-blocking mode with DMA to a specific memory address.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
Receive in slave mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
Enable the Address listen mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
Transmit in master mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
Reads an amount of data in non-blocking mode with DMA from a specific memory address.
HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
Receive in master mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
Read an amount of data in non-blocking mode with Interrupt from a specific memory address.
HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
Disable the Address listen mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Receives in master mode an amount of data in blocking mode.
HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Transmits in master mode an amount of data in blocking mode.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Transmits in slave mode an amount of data in blocking mode.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt...
HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
Transmit in slave mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
Transmit in slave mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
Write an amount of data in non-blocking mode with Interrupt to a specific memory address.
HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
Abort a master FMPI2C IT or DMA process communication with Interrupt.
HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
Receive in master mode an amount of data in non-blocking mode with DMA.
HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Write an amount of data in blocking mode to a specific memory address.
HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(const FMPI2C_HandleTypeDef *hfmpi2c)
Return the FMPI2C handle state.
uint32_t HAL_FMPI2C_GetError(const FMPI2C_HandleTypeDef *hfmpi2c)
Return the FMPI2C error code.
HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(const FMPI2C_HandleTypeDef *hfmpi2c)
Returns the FMPI2C Master, Slave, Memory or no mode.
void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
This function handles FMPI2C error interrupt request.
void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Master Tx Transfer completed callback.
void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Listen Complete callback.
void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
FMPI2C abort callback.
void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Memory Tx Transfer completed callback.
void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
FMPI2C error callback.
void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
This function handles FMPI2C event interrupt request.
void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Slave Tx Transfer completed callback.
void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
Slave Address Match callback.
void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Master Rx Transfer completed callback.
void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Slave Rx Transfer completed callback.
void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
Memory Rx Transfer completed callback.
void(* MasterRxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* MemTxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* MspInitCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* AbortCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* SlaveRxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* AddrCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
void(* SlaveTxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
__IO HAL_FMPI2C_ModeTypeDef Mode
void(* ErrorCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
__IO HAL_FMPI2C_StateTypeDef State
void(* MasterTxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
DMA_HandleTypeDef * hdmarx
HAL_StatusTypeDef(* XferISR)(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
DMA_HandleTypeDef * hdmatx
void(* ListenCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* MemRxCpltCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* MspDeInitCallback)(struct __FMPI2C_HandleTypeDef *hfmpi2c)
void(* pFMPI2C_CallbackTypeDef)(FMPI2C_HandleTypeDef *hfmpi2c)
HAL FMPI2C Callback pointer definition.
void(* pFMPI2C_AddrCallbackTypeDef)(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
HAL_FMPI2C_CallbackIDTypeDef
HAL FMPI2C Callback ID enumeration definition.
@ HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID
@ HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID
@ HAL_FMPI2C_LISTEN_COMPLETE_CB_ID
@ HAL_FMPI2C_MSPDEINIT_CB_ID
@ HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID
@ HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID
@ HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID
@ HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID
@ HAL_FMPI2C_ABORT_CB_ID
@ HAL_FMPI2C_MSPINIT_CB_ID
@ HAL_FMPI2C_ERROR_CB_ID
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
HAL_FMPI2C_ModeTypeDef
@ HAL_FMPI2C_MODE_MASTER
@ HAL_FMPI2C_MODE_NONE
@ HAL_FMPI2C_MODE_SLAVE
@ HAL_FMPI2C_MODE_MEM
HAL_FMPI2C_StateTypeDef
@ HAL_FMPI2C_STATE_RESET
@ HAL_FMPI2C_STATE_LISTEN
@ HAL_FMPI2C_STATE_BUSY_RX
@ HAL_FMPI2C_STATE_BUSY_RX_LISTEN
@ HAL_FMPI2C_STATE_BUSY_TX_LISTEN
@ HAL_FMPI2C_STATE_READY
@ HAL_FMPI2C_STATE_BUSY_TX
@ HAL_FMPI2C_STATE_ABORT
@ HAL_FMPI2C_STATE_BUSY
This file contains all the functions prototypes for the HAL module driver.
@ HAL_DMA_STATE_READY
DMA handle Structure definition.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)