STM32F479xx HAL User Manual
stm32f4xx_hal_fmpi2c.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_fmpi2c.c
00004   * @author  MCD Application Team
00005   * @brief   FMPI2C HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Inter Integrated Circuit (FMPI2C) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral State and Errors functions
00011   *
00012   @verbatim
00013   ==============================================================================
00014                         ##### How to use this driver #####
00015   ==============================================================================
00016     [..]
00017     The FMPI2C HAL driver can be used as follows:
00018 
00019     (#) Declare a FMPI2C_HandleTypeDef handle structure, for example:
00020         FMPI2C_HandleTypeDef  hfmpi2c;
00021 
00022     (#)Initialize the FMPI2C low level resources by implementing the HAL_FMPI2C_MspInit() API:
00023         (##) Enable the FMPI2Cx interface clock
00024         (##) FMPI2C pins configuration
00025             (+++) Enable the clock for the FMPI2C GPIOs
00026             (+++) Configure FMPI2C pins as alternate function open-drain
00027         (##) NVIC configuration if you need to use interrupt process
00028             (+++) Configure the FMPI2Cx interrupt priority
00029             (+++) Enable the NVIC FMPI2C IRQ Channel
00030         (##) DMA Configuration if you need to use DMA process
00031             (+++) Declare a DMA_HandleTypeDef handle structure for
00032                   the transmit or receive stream
00033             (+++) Enable the DMAx interface clock using
00034             (+++) Configure the DMA handle parameters
00035             (+++) Configure the DMA Tx or Rx stream
00036             (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle
00037             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
00038                   the DMA Tx or Rx stream
00039 
00040     (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
00041         Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure.
00042 
00043     (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware
00044         (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API.
00045 
00046     (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady()
00047 
00048     (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver :
00049 
00050     *** Polling mode IO operation ***
00051     =================================
00052     [..]
00053       (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit()
00054       (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive()
00055       (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit()
00056       (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive()
00057 
00058     *** Polling mode IO MEM operation ***
00059     =====================================
00060     [..]
00061       (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write()
00062       (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read()
00063 
00064 
00065     *** Interrupt mode IO operation ***
00066     ===================================
00067     [..]
00068       (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT()
00069       (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00070            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00071       (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT()
00072       (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00073            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00074       (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT()
00075       (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00076            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00077       (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT()
00078       (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00079            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00080       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00081            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00082       (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00083       (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00084            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00085       (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00086            This action will inform Master to generate a Stop condition to discard the communication.
00087 
00088 
00089     *** Interrupt mode or DMA mode IO sequential operation ***
00090     ==========================================================
00091     [..]
00092       (@) These interfaces allow to manage a sequential transfer with a repeated start condition
00093           when a direction change during transfer
00094     [..]
00095       (+) A specific option field manage the different steps of a sequential transfer
00096       (+) Option field values are defined through FMPI2C_XFEROPTIONS and are listed below:
00097       (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in no sequential mode
00098       (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
00099                             and data to transfer without a final stop condition
00100       (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
00101                             and data to transfer without a final stop condition, an then permit a call the same master sequential interface
00102                             several times (like HAL_FMPI2C_Master_Seq_Transmit_IT() then HAL_FMPI2C_Master_Seq_Transmit_IT()
00103                             or HAL_FMPI2C_Master_Seq_Transmit_DMA() then HAL_FMPI2C_Master_Seq_Transmit_DMA())
00104       (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
00105                             and with new data to transfer if the direction change or manage only the new data to
00106                             transfer
00107                             if no direction change and without a final stop condition in both cases
00108       (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
00109                             and with new data to transfer if the direction change or manage only the new data to
00110                             transfer
00111                             if no direction change and with a final stop condition in both cases
00112       (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition
00113                             after several call of the same master sequential interface several times
00114                             (link with option FMPI2C_FIRST_AND_NEXT_FRAME).
00115                             Usage can, transfer several bytes one by one using
00116                               HAL_FMPI2C_Master_Seq_Transmit_IT
00117                               or HAL_FMPI2C_Master_Seq_Receive_IT
00118                               or HAL_FMPI2C_Master_Seq_Transmit_DMA
00119                               or HAL_FMPI2C_Master_Seq_Receive_DMA
00120                               with option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME.
00121                              Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or
00122                               Receive sequence permit to call the opposite interface Receive or Transmit
00123                               without stopping the communication and so generate a restart condition.
00124       (++) FMPI2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after
00125                             each call of the same master sequential
00126                             interface.
00127                             Usage can, transfer several bytes one by one with a restart with slave address between
00128                             each bytes using
00129                               HAL_FMPI2C_Master_Seq_Transmit_IT
00130                               or HAL_FMPI2C_Master_Seq_Receive_IT
00131                               or HAL_FMPI2C_Master_Seq_Transmit_DMA
00132                               or HAL_FMPI2C_Master_Seq_Receive_DMA
00133                               with option FMPI2C_FIRST_FRAME then FMPI2C_OTHER_FRAME.
00134                             Then usage of this option FMPI2C_OTHER_AND_LAST_FRAME at the last frame to help automatic
00135                             generation of STOP condition.
00136 
00137       (+) Different sequential FMPI2C interfaces are listed below:
00138       (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Seq_Transmit_IT()
00139             or using HAL_FMPI2C_Master_Seq_Transmit_DMA()
00140       (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00141            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00142       (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Seq_Receive_IT()
00143             or using HAL_FMPI2C_Master_Seq_Receive_DMA()
00144       (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00145            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00146       (++) Abort a master IT or DMA FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00147       (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00148            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00149       (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT()
00150       (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can
00151            add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
00152       (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can
00153            add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback()
00154       (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Seq_Transmit_IT()
00155             or using HAL_FMPI2C_Slave_Seq_Transmit_DMA()
00156       (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00157            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00158       (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Seq_Receive_IT()
00159             or using HAL_FMPI2C_Slave_Seq_Receive_DMA()
00160       (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00161            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00162       (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00163            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00164       (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00165            This action will inform Master to generate a Stop condition to discard the communication.
00166 
00167     *** Interrupt mode IO MEM operation ***
00168     =======================================
00169     [..]
00170       (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
00171           HAL_FMPI2C_Mem_Write_IT()
00172       (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
00173            add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
00174       (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
00175           HAL_FMPI2C_Mem_Read_IT()
00176       (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
00177            add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
00178       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00179            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00180 
00181     *** DMA mode IO operation ***
00182     ==============================
00183     [..]
00184       (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
00185           HAL_FMPI2C_Master_Transmit_DMA()
00186       (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00187            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00188       (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
00189           HAL_FMPI2C_Master_Receive_DMA()
00190       (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00191            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00192       (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
00193           HAL_FMPI2C_Slave_Transmit_DMA()
00194       (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00195            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00196       (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
00197           HAL_FMPI2C_Slave_Receive_DMA()
00198       (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00199            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00200       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00201            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00202       (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00203       (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00204            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00205       (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00206            This action will inform Master to generate a Stop condition to discard the communication.
00207 
00208     *** DMA mode IO MEM operation ***
00209     =================================
00210     [..]
00211       (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
00212           HAL_FMPI2C_Mem_Write_DMA()
00213       (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
00214            add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
00215       (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
00216           HAL_FMPI2C_Mem_Read_DMA()
00217       (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
00218            add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
00219       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00220            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00221 
00222 
00223      *** FMPI2C HAL driver macros list ***
00224      ==================================
00225      [..]
00226        Below the list of most used macros in FMPI2C HAL driver.
00227 
00228       (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral
00229       (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral
00230       (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode
00231       (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not
00232       (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag
00233       (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt
00234       (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt
00235 
00236      *** Callback registration ***
00237      =============================================
00238     [..]
00239      The compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS when set to 1
00240      allows the user to configure dynamically the driver callbacks.
00241      Use Functions HAL_FMPI2C_RegisterCallback() or HAL_FMPI2C_RegisterAddrCallback()
00242      to register an interrupt callback.
00243     [..]
00244      Function HAL_FMPI2C_RegisterCallback() allows to register following callbacks:
00245        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00246        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00247        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00248        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00249        (+) ListenCpltCallback   : callback for end of listen mode.
00250        (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
00251        (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
00252        (+) ErrorCallback        : callback for error detection.
00253        (+) AbortCpltCallback    : callback for abort completion process.
00254        (+) MspInitCallback      : callback for Msp Init.
00255        (+) MspDeInitCallback    : callback for Msp DeInit.
00256      This function takes as parameters the HAL peripheral handle, the Callback ID
00257      and a pointer to the user callback function.
00258     [..]
00259      For specific callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_RegisterAddrCallback().
00260     [..]
00261      Use function HAL_FMPI2C_UnRegisterCallback to reset a callback to the default
00262      weak function.
00263      HAL_FMPI2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
00264      and the Callback ID.
00265      This function allows to reset following callbacks:
00266        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00267        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00268        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00269        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00270        (+) ListenCpltCallback   : callback for end of listen mode.
00271        (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
00272        (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
00273        (+) ErrorCallback        : callback for error detection.
00274        (+) AbortCpltCallback    : callback for abort completion process.
00275        (+) MspInitCallback      : callback for Msp Init.
00276        (+) MspDeInitCallback    : callback for Msp DeInit.
00277     [..]
00278      For callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_UnRegisterAddrCallback().
00279     [..]
00280      By default, after the HAL_FMPI2C_Init() and when the state is HAL_FMPI2C_STATE_RESET
00281      all callbacks are set to the corresponding weak functions:
00282      examples HAL_FMPI2C_MasterTxCpltCallback(), HAL_FMPI2C_MasterRxCpltCallback().
00283      Exception done for MspInit and MspDeInit functions that are
00284      reset to the legacy weak functions in the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit() only when
00285      these callbacks are null (not registered beforehand).
00286      If MspInit or MspDeInit are not null, the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit()
00287      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00288     [..]
00289      Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only.
00290      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00291      in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state,
00292      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00293      Then, the user first registers the MspInit/MspDeInit user callbacks
00294      using HAL_FMPI2C_RegisterCallback() before calling HAL_FMPI2C_DeInit()
00295      or HAL_FMPI2C_Init() function.
00296     [..]
00297      When the compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS is set to 0 or
00298      not defined, the callback registration feature is not available and all callbacks
00299      are set to the corresponding weak functions.
00300 
00301      [..]
00302        (@) You can refer to the FMPI2C HAL driver header file for more useful macros
00303 
00304   @endverbatim
00305   ******************************************************************************
00306   * @attention
00307   *
00308   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00309   * All rights reserved.</center></h2>
00310   *
00311   * This software component is licensed by ST under BSD 3-Clause license,
00312   * the "License"; You may not use this file except in compliance with the
00313   * License. You may obtain a copy of the License at:
00314   *                        opensource.org/licenses/BSD-3-Clause
00315   *
00316   ******************************************************************************
00317   */
00318 
00319 /* Includes ------------------------------------------------------------------*/
00320 #include "stm32f4xx_hal.h"
00321 
00322 /** @addtogroup STM32F4xx_HAL_Driver
00323   * @{
00324   */
00325 
00326 /** @defgroup FMPI2C FMPI2C
00327   * @brief FMPI2C HAL module driver
00328   * @{
00329   */
00330 
00331 #ifdef HAL_FMPI2C_MODULE_ENABLED
00332 #if defined(FMPI2C_CR1_PE)
00333 
00334 /* Private typedef -----------------------------------------------------------*/
00335 /* Private define ------------------------------------------------------------*/
00336 
00337 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define
00338   * @{
00339   */
00340 #define TIMING_CLEAR_MASK   (0xF0FFFFFFU)  /*!< FMPI2C TIMING clear register Mask */
00341 #define FMPI2C_TIMEOUT_ADDR    (10000U)       /*!< 10 s  */
00342 #define FMPI2C_TIMEOUT_BUSY    (25U)          /*!< 25 ms */
00343 #define FMPI2C_TIMEOUT_DIR     (25U)          /*!< 25 ms */
00344 #define FMPI2C_TIMEOUT_RXNE    (25U)          /*!< 25 ms */
00345 #define FMPI2C_TIMEOUT_STOPF   (25U)          /*!< 25 ms */
00346 #define FMPI2C_TIMEOUT_TC      (25U)          /*!< 25 ms */
00347 #define FMPI2C_TIMEOUT_TCR     (25U)          /*!< 25 ms */
00348 #define FMPI2C_TIMEOUT_TXIS    (25U)          /*!< 25 ms */
00349 #define FMPI2C_TIMEOUT_FLAG    (25U)          /*!< 25 ms */
00350 
00351 #define MAX_NBYTE_SIZE      255U
00352 #define SLAVE_ADDR_SHIFT     7U
00353 #define SLAVE_ADDR_MSK       0x06U
00354 
00355 /* Private define for @ref PreviousState usage */
00356 #define FMPI2C_STATE_MSK             ((uint32_t)((uint32_t)((uint32_t)HAL_FMPI2C_STATE_BUSY_TX | \
00357                                                          (uint32_t)HAL_FMPI2C_STATE_BUSY_RX) & \
00358                                               (uint32_t)(~((uint32_t)HAL_FMPI2C_STATE_READY))))
00359 /*!< Mask State define, keep only RX and TX bits */
00360 #define FMPI2C_STATE_NONE            ((uint32_t)(HAL_FMPI2C_MODE_NONE))
00361 /*!< Default Value */
00362 #define FMPI2C_STATE_MASTER_BUSY_TX  ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
00363                                               (uint32_t)HAL_FMPI2C_MODE_MASTER))
00364 /*!< Master Busy TX, combinaison of State LSB and Mode enum */
00365 #define FMPI2C_STATE_MASTER_BUSY_RX  ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
00366                                               (uint32_t)HAL_FMPI2C_MODE_MASTER))
00367 /*!< Master Busy RX, combinaison of State LSB and Mode enum */
00368 #define FMPI2C_STATE_SLAVE_BUSY_TX   ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
00369                                               (uint32_t)HAL_FMPI2C_MODE_SLAVE))
00370 /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
00371 #define FMPI2C_STATE_SLAVE_BUSY_RX   ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
00372                                               (uint32_t)HAL_FMPI2C_MODE_SLAVE))
00373 /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
00374 #define FMPI2C_STATE_MEM_BUSY_TX     ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
00375                                               (uint32_t)HAL_FMPI2C_MODE_MEM))
00376 /*!< Memory Busy TX, combinaison of State LSB and Mode enum */
00377 #define FMPI2C_STATE_MEM_BUSY_RX     ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
00378                                               (uint32_t)HAL_FMPI2C_MODE_MEM))
00379 /*!< Memory Busy RX, combinaison of State LSB and Mode enum */
00380 
00381 
00382 /* Private define to centralize the enable/disable of Interrupts */
00383 #define FMPI2C_XFER_TX_IT          (uint16_t)(0x0001U)   /*!< Bit field can be combinated with
00384                                                          @ref FMPI2C_XFER_LISTEN_IT */
00385 #define FMPI2C_XFER_RX_IT          (uint16_t)(0x0002U)   /*!< Bit field can be combinated with
00386                                                          @ref FMPI2C_XFER_LISTEN_IT */
00387 #define FMPI2C_XFER_LISTEN_IT      (uint16_t)(0x8000U)   /*!< Bit field can be combinated with @ref FMPI2C_XFER_TX_IT
00388                                                          and @ref FMPI2C_XFER_RX_IT */
00389 
00390 #define FMPI2C_XFER_ERROR_IT       (uint16_t)(0x0010U)   /*!< Bit definition to manage addition of global Error
00391                                                          and NACK treatment */
00392 #define FMPI2C_XFER_CPLT_IT        (uint16_t)(0x0020U)   /*!< Bit definition to manage only STOP evenement */
00393 #define FMPI2C_XFER_RELOAD_IT      (uint16_t)(0x0040U)   /*!< Bit definition to manage only Reload of NBYTE */
00394 
00395 /* Private define Sequential Transfer Options default/reset value */
00396 #define FMPI2C_NO_OPTION_FRAME     (0xFFFF0000U)
00397 /**
00398   * @}
00399   */
00400 
00401 /* Private macro -------------------------------------------------------------*/
00402 /* Private variables ---------------------------------------------------------*/
00403 /* Private function prototypes -----------------------------------------------*/
00404 
00405 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions
00406   * @{
00407   */
00408 /* Private functions to handle DMA transfer */
00409 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
00410 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
00411 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
00412 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
00413 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
00414 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma);
00415 
00416 /* Private functions to handle IT transfer */
00417 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00418 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
00419 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
00420 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00421 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00422 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00423 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode);
00424 
00425 /* Private functions to handle IT transfer */
00426 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
00427                                                    uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
00428                                                    uint32_t Tickstart);
00429 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
00430                                                   uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
00431                                                   uint32_t Tickstart);
00432 
00433 /* Private functions for FMPI2C transfer IRQ handler */
00434 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
00435                                               uint32_t ITSources);
00436 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
00437                                              uint32_t ITSources);
00438 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
00439                                                uint32_t ITSources);
00440 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
00441                                               uint32_t ITSources);
00442 
00443 /* Private functions to handle flags during polling transfer */
00444 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
00445                                                     uint32_t Timeout, uint32_t Tickstart);
00446 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
00447                                                            uint32_t Tickstart);
00448 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
00449                                                            uint32_t Tickstart);
00450 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
00451                                                            uint32_t Tickstart);
00452 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
00453                                                     uint32_t Tickstart);
00454 
00455 /* Private functions to centralize the enable/disable of Interrupts */
00456 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
00457 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
00458 
00459 /* Private function to treat different error callback */
00460 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c);
00461 
00462 /* Private function to flush TXDR register */
00463 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c);
00464 
00465 /* Private function to handle  start, restart or stop a transfer */
00466 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, 
00467                                   uint32_t Request);
00468 
00469 /* Private function to Convert Specific options */
00470 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c);
00471 /**
00472   * @}
00473   */
00474 
00475 /* Exported functions --------------------------------------------------------*/
00476 
00477 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions
00478   * @{
00479   */
00480 
00481 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions
00482   *  @brief    Initialization and Configuration functions
00483   *
00484 @verbatim
00485  ===============================================================================
00486               ##### Initialization and de-initialization functions #####
00487  ===============================================================================
00488     [..]  This subsection provides a set of functions allowing to initialize and
00489           deinitialize the FMPI2Cx peripheral:
00490 
00491       (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures
00492           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
00493 
00494       (+) Call the function HAL_FMPI2C_Init() to configure the selected device with
00495           the selected configuration:
00496         (++) Clock Timing
00497         (++) Own Address 1
00498         (++) Addressing mode (Master, Slave)
00499         (++) Dual Addressing mode
00500         (++) Own Address 2
00501         (++) Own Address 2 Mask
00502         (++) General call mode
00503         (++) Nostretch mode
00504 
00505       (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration
00506           of the selected FMPI2Cx peripheral.
00507 
00508 @endverbatim
00509   * @{
00510   */
00511 
00512 /**
00513   * @brief  Initializes the FMPI2C according to the specified parameters
00514   *         in the FMPI2C_InitTypeDef and initialize the associated handle.
00515   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00516   *                the configuration information for the specified FMPI2C.
00517   * @retval HAL status
00518   */
00519 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
00520 {
00521   /* Check the FMPI2C handle allocation */
00522   if (hfmpi2c == NULL)
00523   {
00524     return HAL_ERROR;
00525   }
00526 
00527   /* Check the parameters */
00528   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
00529   assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
00530   assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
00531   assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
00532   assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
00533   assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
00534   assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
00535   assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
00536 
00537   if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
00538   {
00539     /* Allocate lock resource and initialize it */
00540     hfmpi2c->Lock = HAL_UNLOCKED;
00541 
00542 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
00543     /* Init the FMPI2C Callback settings */
00544     hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00545     hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00546     hfmpi2c->SlaveTxCpltCallback  = HAL_FMPI2C_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
00547     hfmpi2c->SlaveRxCpltCallback  = HAL_FMPI2C_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
00548     hfmpi2c->ListenCpltCallback   = HAL_FMPI2C_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
00549     hfmpi2c->MemTxCpltCallback    = HAL_FMPI2C_MemTxCpltCallback;    /* Legacy weak MemTxCpltCallback    */
00550     hfmpi2c->MemRxCpltCallback    = HAL_FMPI2C_MemRxCpltCallback;    /* Legacy weak MemRxCpltCallback    */
00551     hfmpi2c->ErrorCallback        = HAL_FMPI2C_ErrorCallback;        /* Legacy weak ErrorCallback        */
00552     hfmpi2c->AbortCpltCallback    = HAL_FMPI2C_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
00553     hfmpi2c->AddrCallback         = HAL_FMPI2C_AddrCallback;         /* Legacy weak AddrCallback         */
00554 
00555     if (hfmpi2c->MspInitCallback == NULL)
00556     {
00557       hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit  */
00558     }
00559 
00560     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00561     hfmpi2c->MspInitCallback(hfmpi2c);
00562 #else
00563     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00564     HAL_FMPI2C_MspInit(hfmpi2c);
00565 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
00566   }
00567 
00568   hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
00569 
00570   /* Disable the selected FMPI2C peripheral */
00571   __HAL_FMPI2C_DISABLE(hfmpi2c);
00572 
00573   /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
00574   /* Configure FMPI2Cx: Frequency range */
00575   hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
00576 
00577   /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
00578   /* Disable Own Address1 before set the Own Address1 configuration */
00579   hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
00580 
00581   /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
00582   if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
00583   {
00584     hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
00585   }
00586   else /* FMPI2C_ADDRESSINGMODE_10BIT */
00587   {
00588     hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
00589   }
00590 
00591   /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
00592   /* Configure FMPI2Cx: Addressing Master mode */
00593   if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
00594   {
00595     hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10);
00596   }
00597   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
00598   hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
00599 
00600   /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
00601   /* Disable Own Address2 before set the Own Address2 configuration */
00602   hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE;
00603 
00604   /* Configure FMPI2Cx: Dual mode and Own Address2 */
00605   hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | \
00606                              (hfmpi2c->Init.OwnAddress2Masks << 8));
00607 
00608   /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
00609   /* Configure FMPI2Cx: Generalcall and NoStretch mode */
00610   hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
00611 
00612   /* Enable the selected FMPI2C peripheral */
00613   __HAL_FMPI2C_ENABLE(hfmpi2c);
00614 
00615   hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00616   hfmpi2c->State = HAL_FMPI2C_STATE_READY;
00617   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
00618   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
00619 
00620   return HAL_OK;
00621 }
00622 
00623 /**
00624   * @brief  DeInitialize the FMPI2C peripheral.
00625   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00626   *                the configuration information for the specified FMPI2C.
00627   * @retval HAL status
00628   */
00629 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
00630 {
00631   /* Check the FMPI2C handle allocation */
00632   if (hfmpi2c == NULL)
00633   {
00634     return HAL_ERROR;
00635   }
00636 
00637   /* Check the parameters */
00638   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
00639 
00640   hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
00641 
00642   /* Disable the FMPI2C Peripheral Clock */
00643   __HAL_FMPI2C_DISABLE(hfmpi2c);
00644 
00645 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
00646   if (hfmpi2c->MspDeInitCallback == NULL)
00647   {
00648     hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit  */
00649   }
00650 
00651   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00652   hfmpi2c->MspDeInitCallback(hfmpi2c);
00653 #else
00654   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00655   HAL_FMPI2C_MspDeInit(hfmpi2c);
00656 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
00657 
00658   hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00659   hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
00660   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
00661   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
00662 
00663   /* Release Lock */
00664   __HAL_UNLOCK(hfmpi2c);
00665 
00666   return HAL_OK;
00667 }
00668 
00669 /**
00670   * @brief Initialize the FMPI2C MSP.
00671   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00672   *                the configuration information for the specified FMPI2C.
00673   * @retval None
00674   */
00675 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
00676 {
00677   /* Prevent unused argument(s) compilation warning */
00678   UNUSED(hfmpi2c);
00679 
00680   /* NOTE : This function should not be modified, when the callback is needed,
00681             the HAL_FMPI2C_MspInit could be implemented in the user file
00682    */
00683 }
00684 
00685 /**
00686   * @brief DeInitialize the FMPI2C MSP.
00687   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00688   *                the configuration information for the specified FMPI2C.
00689   * @retval None
00690   */
00691 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
00692 {
00693   /* Prevent unused argument(s) compilation warning */
00694   UNUSED(hfmpi2c);
00695 
00696   /* NOTE : This function should not be modified, when the callback is needed,
00697             the HAL_FMPI2C_MspDeInit could be implemented in the user file
00698    */
00699 }
00700 
00701 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
00702 /**
00703   * @brief  Register a User FMPI2C Callback
00704   *         To be used instead of the weak predefined callback
00705   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00706   *                the configuration information for the specified FMPI2C.
00707   * @param  CallbackID ID of the callback to be registered
00708   *         This parameter can be one of the following values:
00709   *          @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00710   *          @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00711   *          @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00712   *          @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00713   *          @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00714   *          @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
00715   *          @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
00716   *          @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID
00717   *          @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID
00718   *          @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID
00719   *          @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID
00720   * @param  pCallback pointer to the Callback function
00721   * @retval HAL status
00722   */
00723 HAL_StatusTypeDef HAL_FMPI2C_RegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID,
00724                                            pFMPI2C_CallbackTypeDef pCallback)
00725 {
00726   HAL_StatusTypeDef status = HAL_OK;
00727 
00728   if (pCallback == NULL)
00729   {
00730     /* Update the error code */
00731     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00732 
00733     return HAL_ERROR;
00734   }
00735   /* Process locked */
00736   __HAL_LOCK(hfmpi2c);
00737 
00738   if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
00739   {
00740     switch (CallbackID)
00741     {
00742       case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID :
00743         hfmpi2c->MasterTxCpltCallback = pCallback;
00744         break;
00745 
00746       case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID :
00747         hfmpi2c->MasterRxCpltCallback = pCallback;
00748         break;
00749 
00750       case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID :
00751         hfmpi2c->SlaveTxCpltCallback = pCallback;
00752         break;
00753 
00754       case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID :
00755         hfmpi2c->SlaveRxCpltCallback = pCallback;
00756         break;
00757 
00758       case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID :
00759         hfmpi2c->ListenCpltCallback = pCallback;
00760         break;
00761 
00762       case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID :
00763         hfmpi2c->MemTxCpltCallback = pCallback;
00764         break;
00765 
00766       case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID :
00767         hfmpi2c->MemRxCpltCallback = pCallback;
00768         break;
00769 
00770       case HAL_FMPI2C_ERROR_CB_ID :
00771         hfmpi2c->ErrorCallback = pCallback;
00772         break;
00773 
00774       case HAL_FMPI2C_ABORT_CB_ID :
00775         hfmpi2c->AbortCpltCallback = pCallback;
00776         break;
00777 
00778       case HAL_FMPI2C_MSPINIT_CB_ID :
00779         hfmpi2c->MspInitCallback = pCallback;
00780         break;
00781 
00782       case HAL_FMPI2C_MSPDEINIT_CB_ID :
00783         hfmpi2c->MspDeInitCallback = pCallback;
00784         break;
00785 
00786       default :
00787         /* Update the error code */
00788         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00789 
00790         /* Return error status */
00791         status =  HAL_ERROR;
00792         break;
00793     }
00794   }
00795   else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
00796   {
00797     switch (CallbackID)
00798     {
00799       case HAL_FMPI2C_MSPINIT_CB_ID :
00800         hfmpi2c->MspInitCallback = pCallback;
00801         break;
00802 
00803       case HAL_FMPI2C_MSPDEINIT_CB_ID :
00804         hfmpi2c->MspDeInitCallback = pCallback;
00805         break;
00806 
00807       default :
00808         /* Update the error code */
00809         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00810 
00811         /* Return error status */
00812         status =  HAL_ERROR;
00813         break;
00814     }
00815   }
00816   else
00817   {
00818     /* Update the error code */
00819     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00820 
00821     /* Return error status */
00822     status =  HAL_ERROR;
00823   }
00824 
00825   /* Release Lock */
00826   __HAL_UNLOCK(hfmpi2c);
00827   return status;
00828 }
00829 
00830 /**
00831   * @brief  Unregister an FMPI2C Callback
00832   *         FMPI2C callback is redirected to the weak predefined callback
00833   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00834   *                the configuration information for the specified FMPI2C.
00835   * @param  CallbackID ID of the callback to be unregistered
00836   *         This parameter can be one of the following values:
00837   *         This parameter can be one of the following values:
00838   *          @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00839   *          @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00840   *          @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00841   *          @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00842   *          @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00843   *          @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
00844   *          @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
00845   *          @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID
00846   *          @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID
00847   *          @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID
00848   *          @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID
00849   * @retval HAL status
00850   */
00851 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID)
00852 {
00853   HAL_StatusTypeDef status = HAL_OK;
00854 
00855   /* Process locked */
00856   __HAL_LOCK(hfmpi2c);
00857 
00858   if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
00859   {
00860     switch (CallbackID)
00861     {
00862       case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID :
00863         hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00864         break;
00865 
00866       case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID :
00867         hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00868         break;
00869 
00870       case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID :
00871         hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
00872         break;
00873 
00874       case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID :
00875         hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
00876         break;
00877 
00878       case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID :
00879         hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
00880         break;
00881 
00882       case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID :
00883         hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback;       /* Legacy weak MemTxCpltCallback    */
00884         break;
00885 
00886       case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID :
00887         hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback;       /* Legacy weak MemRxCpltCallback    */
00888         break;
00889 
00890       case HAL_FMPI2C_ERROR_CB_ID :
00891         hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback;               /* Legacy weak ErrorCallback        */
00892         break;
00893 
00894       case HAL_FMPI2C_ABORT_CB_ID :
00895         hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
00896         break;
00897 
00898       case HAL_FMPI2C_MSPINIT_CB_ID :
00899         hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit;                   /* Legacy weak MspInit              */
00900         break;
00901 
00902       case HAL_FMPI2C_MSPDEINIT_CB_ID :
00903         hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit;               /* Legacy weak MspDeInit            */
00904         break;
00905 
00906       default :
00907         /* Update the error code */
00908         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00909 
00910         /* Return error status */
00911         status =  HAL_ERROR;
00912         break;
00913     }
00914   }
00915   else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
00916   {
00917     switch (CallbackID)
00918     {
00919       case HAL_FMPI2C_MSPINIT_CB_ID :
00920         hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit;                   /* Legacy weak MspInit              */
00921         break;
00922 
00923       case HAL_FMPI2C_MSPDEINIT_CB_ID :
00924         hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit;               /* Legacy weak MspDeInit            */
00925         break;
00926 
00927       default :
00928         /* Update the error code */
00929         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00930 
00931         /* Return error status */
00932         status =  HAL_ERROR;
00933         break;
00934     }
00935   }
00936   else
00937   {
00938     /* Update the error code */
00939     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00940 
00941     /* Return error status */
00942     status =  HAL_ERROR;
00943   }
00944 
00945   /* Release Lock */
00946   __HAL_UNLOCK(hfmpi2c);
00947   return status;
00948 }
00949 
00950 /**
00951   * @brief  Register the Slave Address Match FMPI2C Callback
00952   *         To be used instead of the weak HAL_FMPI2C_AddrCallback() predefined callback
00953   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00954   *                the configuration information for the specified FMPI2C.
00955   * @param  pCallback pointer to the Address Match Callback function
00956   * @retval HAL status
00957   */
00958 HAL_StatusTypeDef HAL_FMPI2C_RegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, pFMPI2C_AddrCallbackTypeDef pCallback)
00959 {
00960   HAL_StatusTypeDef status = HAL_OK;
00961 
00962   if (pCallback == NULL)
00963   {
00964     /* Update the error code */
00965     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00966 
00967     return HAL_ERROR;
00968   }
00969   /* Process locked */
00970   __HAL_LOCK(hfmpi2c);
00971 
00972   if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
00973   {
00974     hfmpi2c->AddrCallback = pCallback;
00975   }
00976   else
00977   {
00978     /* Update the error code */
00979     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
00980 
00981     /* Return error status */
00982     status =  HAL_ERROR;
00983   }
00984 
00985   /* Release Lock */
00986   __HAL_UNLOCK(hfmpi2c);
00987   return status;
00988 }
00989 
00990 /**
00991   * @brief  UnRegister the Slave Address Match FMPI2C Callback
00992   *         Info Ready FMPI2C Callback is redirected to the weak HAL_FMPI2C_AddrCallback() predefined callback
00993   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00994   *                the configuration information for the specified FMPI2C.
00995   * @retval HAL status
00996   */
00997 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c)
00998 {
00999   HAL_StatusTypeDef status = HAL_OK;
01000 
01001   /* Process locked */
01002   __HAL_LOCK(hfmpi2c);
01003 
01004   if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
01005   {
01006     hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback  */
01007   }
01008   else
01009   {
01010     /* Update the error code */
01011     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
01012 
01013     /* Return error status */
01014     status =  HAL_ERROR;
01015   }
01016 
01017   /* Release Lock */
01018   __HAL_UNLOCK(hfmpi2c);
01019   return status;
01020 }
01021 
01022 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
01023 
01024 /**
01025   * @}
01026   */
01027 
01028 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions
01029   *  @brief   Data transfers functions
01030   *
01031 @verbatim
01032  ===============================================================================
01033                       ##### IO operation functions #####
01034  ===============================================================================
01035     [..]
01036     This subsection provides a set of functions allowing to manage the FMPI2C data
01037     transfers.
01038 
01039     (#) There are two modes of transfer:
01040        (++) Blocking mode : The communication is performed in the polling mode.
01041             The status of all data processing is returned by the same function
01042             after finishing transfer.
01043        (++) No-Blocking mode : The communication is performed using Interrupts
01044             or DMA. These functions return the status of the transfer startup.
01045             The end of the data processing will be indicated through the
01046             dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when
01047             using DMA mode.
01048 
01049     (#) Blocking mode functions are :
01050         (++) HAL_FMPI2C_Master_Transmit()
01051         (++) HAL_FMPI2C_Master_Receive()
01052         (++) HAL_FMPI2C_Slave_Transmit()
01053         (++) HAL_FMPI2C_Slave_Receive()
01054         (++) HAL_FMPI2C_Mem_Write()
01055         (++) HAL_FMPI2C_Mem_Read()
01056         (++) HAL_FMPI2C_IsDeviceReady()
01057 
01058     (#) No-Blocking mode functions with Interrupt are :
01059         (++) HAL_FMPI2C_Master_Transmit_IT()
01060         (++) HAL_FMPI2C_Master_Receive_IT()
01061         (++) HAL_FMPI2C_Slave_Transmit_IT()
01062         (++) HAL_FMPI2C_Slave_Receive_IT()
01063         (++) HAL_FMPI2C_Mem_Write_IT()
01064         (++) HAL_FMPI2C_Mem_Read_IT()
01065         (++) HAL_FMPI2C_Master_Seq_Transmit_IT()
01066         (++) HAL_FMPI2C_Master_Seq_Receive_IT()
01067         (++) HAL_FMPI2C_Slave_Seq_Transmit_IT()
01068         (++) HAL_FMPI2C_Slave_Seq_Receive_IT()
01069         (++) HAL_FMPI2C_EnableListen_IT()
01070         (++) HAL_FMPI2C_DisableListen_IT()
01071         (++) HAL_FMPI2C_Master_Abort_IT()
01072 
01073     (#) No-Blocking mode functions with DMA are :
01074         (++) HAL_FMPI2C_Master_Transmit_DMA()
01075         (++) HAL_FMPI2C_Master_Receive_DMA()
01076         (++) HAL_FMPI2C_Slave_Transmit_DMA()
01077         (++) HAL_FMPI2C_Slave_Receive_DMA()
01078         (++) HAL_FMPI2C_Mem_Write_DMA()
01079         (++) HAL_FMPI2C_Mem_Read_DMA()
01080         (++) HAL_FMPI2C_Master_Seq_Transmit_DMA()
01081         (++) HAL_FMPI2C_Master_Seq_Receive_DMA()
01082         (++) HAL_FMPI2C_Slave_Seq_Transmit_DMA()
01083         (++) HAL_FMPI2C_Slave_Seq_Receive_DMA()
01084 
01085     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
01086         (++) HAL_FMPI2C_MasterTxCpltCallback()
01087         (++) HAL_FMPI2C_MasterRxCpltCallback()
01088         (++) HAL_FMPI2C_SlaveTxCpltCallback()
01089         (++) HAL_FMPI2C_SlaveRxCpltCallback()
01090         (++) HAL_FMPI2C_MemTxCpltCallback()
01091         (++) HAL_FMPI2C_MemRxCpltCallback()
01092         (++) HAL_FMPI2C_AddrCallback()
01093         (++) HAL_FMPI2C_ListenCpltCallback()
01094         (++) HAL_FMPI2C_ErrorCallback()
01095         (++) HAL_FMPI2C_AbortCpltCallback()
01096 
01097 @endverbatim
01098   * @{
01099   */
01100 
01101 /**
01102   * @brief  Transmits in master mode an amount of data in blocking mode.
01103   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01104   *                the configuration information for the specified FMPI2C.
01105   * @param  DevAddress Target device address: The device 7 bits address value
01106   *         in datasheet must be shifted to the left before calling the interface
01107   * @param  pData Pointer to data buffer
01108   * @param  Size Amount of data to be sent
01109   * @param  Timeout Timeout duration
01110   * @retval HAL status
01111   */
01112 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
01113                                              uint16_t Size, uint32_t Timeout)
01114 {
01115   uint32_t tickstart;
01116 
01117   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01118   {
01119     /* Process Locked */
01120     __HAL_LOCK(hfmpi2c);
01121 
01122     /* Init tickstart for timeout management*/
01123     tickstart = HAL_GetTick();
01124 
01125     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
01126     {
01127       return HAL_ERROR;
01128     }
01129 
01130     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
01131     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
01132     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01133 
01134     /* Prepare transfer parameters */
01135     hfmpi2c->pBuffPtr  = pData;
01136     hfmpi2c->XferCount = Size;
01137     hfmpi2c->XferISR   = NULL;
01138 
01139     /* Send Slave Address */
01140     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01141     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01142     {
01143       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01144       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
01145                             FMPI2C_GENERATE_START_WRITE);
01146     }
01147     else
01148     {
01149       hfmpi2c->XferSize = hfmpi2c->XferCount;
01150       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
01151                             FMPI2C_GENERATE_START_WRITE);
01152     }
01153 
01154     while (hfmpi2c->XferCount > 0U)
01155     {
01156       /* Wait until TXIS flag is set */
01157       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01158       {
01159         return HAL_ERROR;
01160       }
01161       /* Write data to TXDR */
01162       hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
01163 
01164       /* Increment Buffer pointer */
01165       hfmpi2c->pBuffPtr++;
01166 
01167       hfmpi2c->XferCount--;
01168       hfmpi2c->XferSize--;
01169 
01170       if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
01171       {
01172         /* Wait until TCR flag is set */
01173         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
01174         {
01175           return HAL_ERROR;
01176         }
01177 
01178         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01179         {
01180           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01181           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
01182                                 FMPI2C_NO_STARTSTOP);
01183         }
01184         else
01185         {
01186           hfmpi2c->XferSize = hfmpi2c->XferCount;
01187           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
01188                                 FMPI2C_NO_STARTSTOP);
01189         }
01190       }
01191     }
01192 
01193     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01194     /* Wait until STOPF flag is set */
01195     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01196     {
01197       return HAL_ERROR;
01198     }
01199 
01200     /* Clear STOP Flag */
01201     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01202 
01203     /* Clear Configuration Register 2 */
01204     FMPI2C_RESET_CR2(hfmpi2c);
01205 
01206     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01207     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01208 
01209     /* Process Unlocked */
01210     __HAL_UNLOCK(hfmpi2c);
01211 
01212     return HAL_OK;
01213   }
01214   else
01215   {
01216     return HAL_BUSY;
01217   }
01218 }
01219 
01220 /**
01221   * @brief  Receives in master mode an amount of data in blocking mode.
01222   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01223   *                the configuration information for the specified FMPI2C.
01224   * @param  DevAddress Target device address: The device 7 bits address value
01225   *         in datasheet must be shifted to the left before calling the interface
01226   * @param  pData Pointer to data buffer
01227   * @param  Size Amount of data to be sent
01228   * @param  Timeout Timeout duration
01229   * @retval HAL status
01230   */
01231 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
01232                                             uint16_t Size, uint32_t Timeout)
01233 {
01234   uint32_t tickstart;
01235 
01236   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01237   {
01238     /* Process Locked */
01239     __HAL_LOCK(hfmpi2c);
01240 
01241     /* Init tickstart for timeout management*/
01242     tickstart = HAL_GetTick();
01243 
01244     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
01245     {
01246       return HAL_ERROR;
01247     }
01248 
01249     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
01250     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
01251     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01252 
01253     /* Prepare transfer parameters */
01254     hfmpi2c->pBuffPtr  = pData;
01255     hfmpi2c->XferCount = Size;
01256     hfmpi2c->XferISR   = NULL;
01257 
01258     /* Send Slave Address */
01259     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01260     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01261     {
01262       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01263       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
01264                             FMPI2C_GENERATE_START_READ);
01265     }
01266     else
01267     {
01268       hfmpi2c->XferSize = hfmpi2c->XferCount;
01269       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
01270                             FMPI2C_GENERATE_START_READ);
01271     }
01272 
01273     while (hfmpi2c->XferCount > 0U)
01274     {
01275       /* Wait until RXNE flag is set */
01276       if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01277       {
01278         return HAL_ERROR;
01279       }
01280 
01281       /* Read data from RXDR */
01282       *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
01283 
01284       /* Increment Buffer pointer */
01285       hfmpi2c->pBuffPtr++;
01286 
01287       hfmpi2c->XferSize--;
01288       hfmpi2c->XferCount--;
01289 
01290       if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
01291       {
01292         /* Wait until TCR flag is set */
01293         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
01294         {
01295           return HAL_ERROR;
01296         }
01297 
01298         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01299         {
01300           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01301           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
01302                                 FMPI2C_NO_STARTSTOP);
01303         }
01304         else
01305         {
01306           hfmpi2c->XferSize = hfmpi2c->XferCount;
01307           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
01308                                 FMPI2C_NO_STARTSTOP);
01309         }
01310       }
01311     }
01312 
01313     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01314     /* Wait until STOPF flag is set */
01315     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01316     {
01317       return HAL_ERROR;
01318     }
01319 
01320     /* Clear STOP Flag */
01321     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01322 
01323     /* Clear Configuration Register 2 */
01324     FMPI2C_RESET_CR2(hfmpi2c);
01325 
01326     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01327     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01328 
01329     /* Process Unlocked */
01330     __HAL_UNLOCK(hfmpi2c);
01331 
01332     return HAL_OK;
01333   }
01334   else
01335   {
01336     return HAL_BUSY;
01337   }
01338 }
01339 
01340 /**
01341   * @brief  Transmits in slave mode an amount of data in blocking mode.
01342   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01343   *                the configuration information for the specified FMPI2C.
01344   * @param  pData Pointer to data buffer
01345   * @param  Size Amount of data to be sent
01346   * @param  Timeout Timeout duration
01347   * @retval HAL status
01348   */
01349 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
01350                                             uint32_t Timeout)
01351 {
01352   uint32_t tickstart;
01353 
01354   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01355   {
01356     if ((pData == NULL) || (Size == 0U))
01357     {
01358       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
01359       return  HAL_ERROR;
01360     }
01361     /* Process Locked */
01362     __HAL_LOCK(hfmpi2c);
01363 
01364     /* Init tickstart for timeout management*/
01365     tickstart = HAL_GetTick();
01366 
01367     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
01368     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
01369     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01370 
01371     /* Prepare transfer parameters */
01372     hfmpi2c->pBuffPtr  = pData;
01373     hfmpi2c->XferCount = Size;
01374     hfmpi2c->XferISR   = NULL;
01375 
01376     /* Enable Address Acknowledge */
01377     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01378 
01379     /* Wait until ADDR flag is set */
01380     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
01381     {
01382       /* Disable Address Acknowledge */
01383       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01384       return HAL_ERROR;
01385     }
01386 
01387     /* Clear ADDR flag */
01388     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
01389 
01390     /* If 10bit addressing mode is selected */
01391     if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
01392     {
01393       /* Wait until ADDR flag is set */
01394       if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
01395       {
01396         /* Disable Address Acknowledge */
01397         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01398         return HAL_ERROR;
01399       }
01400 
01401       /* Clear ADDR flag */
01402       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
01403     }
01404 
01405     /* Wait until DIR flag is set Transmitter mode */
01406     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
01407     {
01408       /* Disable Address Acknowledge */
01409       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01410       return HAL_ERROR;
01411     }
01412 
01413     while (hfmpi2c->XferCount > 0U)
01414     {
01415       /* Wait until TXIS flag is set */
01416       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01417       {
01418         /* Disable Address Acknowledge */
01419         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01420         return HAL_ERROR;
01421       }
01422 
01423       /* Write data to TXDR */
01424       hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
01425 
01426       /* Increment Buffer pointer */
01427       hfmpi2c->pBuffPtr++;
01428 
01429       hfmpi2c->XferCount--;
01430     }
01431 
01432     /* Wait until STOP flag is set */
01433     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01434     {
01435       /* Disable Address Acknowledge */
01436       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01437 
01438       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01439       {
01440         /* Normal use case for Transmitter mode */
01441         /* A NACK is generated to confirm the end of transfer */
01442         hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01443       }
01444       else
01445       {
01446         return HAL_ERROR;
01447       }
01448     }
01449 
01450     /* Clear STOP flag */
01451     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01452 
01453     /* Wait until BUSY flag is reset */
01454     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
01455     {
01456       /* Disable Address Acknowledge */
01457       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01458       return HAL_ERROR;
01459     }
01460 
01461     /* Disable Address Acknowledge */
01462     hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01463 
01464     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01465     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01466 
01467     /* Process Unlocked */
01468     __HAL_UNLOCK(hfmpi2c);
01469 
01470     return HAL_OK;
01471   }
01472   else
01473   {
01474     return HAL_BUSY;
01475   }
01476 }
01477 
01478 /**
01479   * @brief  Receive in slave mode an amount of data in blocking mode
01480   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01481   *                the configuration information for the specified FMPI2C.
01482   * @param  pData Pointer to data buffer
01483   * @param  Size Amount of data to be sent
01484   * @param  Timeout Timeout duration
01485   * @retval HAL status
01486   */
01487 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
01488                                            uint32_t Timeout)
01489 {
01490   uint32_t tickstart;
01491 
01492   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01493   {
01494     if ((pData == NULL) || (Size == 0U))
01495     {
01496       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
01497       return  HAL_ERROR;
01498     }
01499     /* Process Locked */
01500     __HAL_LOCK(hfmpi2c);
01501 
01502     /* Init tickstart for timeout management*/
01503     tickstart = HAL_GetTick();
01504 
01505     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
01506     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
01507     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01508 
01509     /* Prepare transfer parameters */
01510     hfmpi2c->pBuffPtr  = pData;
01511     hfmpi2c->XferCount = Size;
01512     hfmpi2c->XferISR   = NULL;
01513 
01514     /* Enable Address Acknowledge */
01515     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01516 
01517     /* Wait until ADDR flag is set */
01518     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
01519     {
01520       /* Disable Address Acknowledge */
01521       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01522       return HAL_ERROR;
01523     }
01524 
01525     /* Clear ADDR flag */
01526     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
01527 
01528     /* Wait until DIR flag is reset Receiver mode */
01529     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
01530     {
01531       /* Disable Address Acknowledge */
01532       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01533       return HAL_ERROR;
01534     }
01535 
01536     while (hfmpi2c->XferCount > 0U)
01537     {
01538       /* Wait until RXNE flag is set */
01539       if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01540       {
01541         /* Disable Address Acknowledge */
01542         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01543 
01544         /* Store Last receive data if any */
01545         if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
01546         {
01547           /* Read data from RXDR */
01548           *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
01549 
01550           /* Increment Buffer pointer */
01551           hfmpi2c->pBuffPtr++;
01552 
01553           hfmpi2c->XferCount--;
01554         }
01555 
01556         return HAL_ERROR;
01557       }
01558 
01559       /* Read data from RXDR */
01560       *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
01561 
01562       /* Increment Buffer pointer */
01563       hfmpi2c->pBuffPtr++;
01564 
01565       hfmpi2c->XferCount--;
01566     }
01567 
01568     /* Wait until STOP flag is set */
01569     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01570     {
01571       /* Disable Address Acknowledge */
01572       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01573       return HAL_ERROR;
01574     }
01575 
01576     /* Clear STOP flag */
01577     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01578 
01579     /* Wait until BUSY flag is reset */
01580     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
01581     {
01582       /* Disable Address Acknowledge */
01583       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01584       return HAL_ERROR;
01585     }
01586 
01587     /* Disable Address Acknowledge */
01588     hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01589 
01590     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01591     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01592 
01593     /* Process Unlocked */
01594     __HAL_UNLOCK(hfmpi2c);
01595 
01596     return HAL_OK;
01597   }
01598   else
01599   {
01600     return HAL_BUSY;
01601   }
01602 }
01603 
01604 /**
01605   * @brief  Transmit in master mode an amount of data in non-blocking mode with Interrupt
01606   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01607   *                the configuration information for the specified FMPI2C.
01608   * @param  DevAddress Target device address: The device 7 bits address value
01609   *         in datasheet must be shifted to the left before calling the interface
01610   * @param  pData Pointer to data buffer
01611   * @param  Size Amount of data to be sent
01612   * @retval HAL status
01613   */
01614 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
01615                                              uint16_t Size)
01616 {
01617   uint32_t xfermode;
01618 
01619   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01620   {
01621     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01622     {
01623       return HAL_BUSY;
01624     }
01625 
01626     /* Process Locked */
01627     __HAL_LOCK(hfmpi2c);
01628 
01629     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01630     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01631     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01632 
01633     /* Prepare transfer parameters */
01634     hfmpi2c->pBuffPtr    = pData;
01635     hfmpi2c->XferCount   = Size;
01636     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01637     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
01638 
01639     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01640     {
01641       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01642       xfermode = FMPI2C_RELOAD_MODE;
01643     }
01644     else
01645     {
01646       hfmpi2c->XferSize = hfmpi2c->XferCount;
01647       xfermode = FMPI2C_AUTOEND_MODE;
01648     }
01649 
01650     /* Send Slave Address */
01651     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
01652     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
01653 
01654     /* Process Unlocked */
01655     __HAL_UNLOCK(hfmpi2c);
01656 
01657     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01658               to avoid the risk of FMPI2C interrupt handle execution before current
01659               process unlock */
01660 
01661     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01662     /* possible to enable all of these */
01663     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
01664       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01665     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
01666 
01667     return HAL_OK;
01668   }
01669   else
01670   {
01671     return HAL_BUSY;
01672   }
01673 }
01674 
01675 /**
01676   * @brief  Receive in master mode an amount of data in non-blocking mode with Interrupt
01677   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01678   *                the configuration information for the specified FMPI2C.
01679   * @param  DevAddress Target device address: The device 7 bits address value
01680   *         in datasheet must be shifted to the left before calling the interface
01681   * @param  pData Pointer to data buffer
01682   * @param  Size Amount of data to be sent
01683   * @retval HAL status
01684   */
01685 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
01686                                             uint16_t Size)
01687 {
01688   uint32_t xfermode;
01689 
01690   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01691   {
01692     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01693     {
01694       return HAL_BUSY;
01695     }
01696 
01697     /* Process Locked */
01698     __HAL_LOCK(hfmpi2c);
01699 
01700     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01701     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01702     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01703 
01704     /* Prepare transfer parameters */
01705     hfmpi2c->pBuffPtr    = pData;
01706     hfmpi2c->XferCount   = Size;
01707     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01708     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
01709 
01710     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01711     {
01712       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01713       xfermode = FMPI2C_RELOAD_MODE;
01714     }
01715     else
01716     {
01717       hfmpi2c->XferSize = hfmpi2c->XferCount;
01718       xfermode = FMPI2C_AUTOEND_MODE;
01719     }
01720 
01721     /* Send Slave Address */
01722     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
01723     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
01724 
01725     /* Process Unlocked */
01726     __HAL_UNLOCK(hfmpi2c);
01727 
01728     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01729               to avoid the risk of FMPI2C interrupt handle execution before current
01730               process unlock */
01731 
01732     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
01733     /* possible to enable all of these */
01734     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
01735       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01736     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
01737 
01738     return HAL_OK;
01739   }
01740   else
01741   {
01742     return HAL_BUSY;
01743   }
01744 }
01745 
01746 /**
01747   * @brief  Transmit in slave mode an amount of data in non-blocking mode with Interrupt
01748   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01749   *                the configuration information for the specified FMPI2C.
01750   * @param  pData Pointer to data buffer
01751   * @param  Size Amount of data to be sent
01752   * @retval HAL status
01753   */
01754 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01755 {
01756   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01757   {
01758     /* Process Locked */
01759     __HAL_LOCK(hfmpi2c);
01760 
01761     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01762     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01763     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01764 
01765     /* Enable Address Acknowledge */
01766     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01767 
01768     /* Prepare transfer parameters */
01769     hfmpi2c->pBuffPtr    = pData;
01770     hfmpi2c->XferCount   = Size;
01771     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01772     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01773     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
01774 
01775     /* Process Unlocked */
01776     __HAL_UNLOCK(hfmpi2c);
01777 
01778     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01779               to avoid the risk of FMPI2C interrupt handle execution before current
01780               process unlock */
01781 
01782     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01783     /* possible to enable all of these */
01784     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
01785       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01786     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
01787 
01788     return HAL_OK;
01789   }
01790   else
01791   {
01792     return HAL_BUSY;
01793   }
01794 }
01795 
01796 /**
01797   * @brief  Receive in slave mode an amount of data in non-blocking mode with Interrupt
01798   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01799   *                the configuration information for the specified FMPI2C.
01800   * @param  pData Pointer to data buffer
01801   * @param  Size Amount of data to be sent
01802   * @retval HAL status
01803   */
01804 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01805 {
01806   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01807   {
01808     /* Process Locked */
01809     __HAL_LOCK(hfmpi2c);
01810 
01811     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01812     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01813     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01814 
01815     /* Enable Address Acknowledge */
01816     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01817 
01818     /* Prepare transfer parameters */
01819     hfmpi2c->pBuffPtr    = pData;
01820     hfmpi2c->XferCount   = Size;
01821     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01822     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01823     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
01824 
01825     /* Process Unlocked */
01826     __HAL_UNLOCK(hfmpi2c);
01827 
01828     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01829               to avoid the risk of FMPI2C interrupt handle execution before current
01830               process unlock */
01831 
01832     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
01833     /* possible to enable all of these */
01834     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
01835       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01836     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
01837 
01838     return HAL_OK;
01839   }
01840   else
01841   {
01842     return HAL_BUSY;
01843   }
01844 }
01845 
01846 /**
01847   * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
01848   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01849   *                the configuration information for the specified FMPI2C.
01850   * @param  DevAddress Target device address: The device 7 bits address value
01851   *         in datasheet must be shifted to the left before calling the interface
01852   * @param  pData Pointer to data buffer
01853   * @param  Size Amount of data to be sent
01854   * @retval HAL status
01855   */
01856 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
01857                                               uint16_t Size)
01858 {
01859   uint32_t xfermode;
01860   HAL_StatusTypeDef dmaxferstatus;
01861 
01862   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01863   {
01864     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01865     {
01866       return HAL_BUSY;
01867     }
01868 
01869     /* Process Locked */
01870     __HAL_LOCK(hfmpi2c);
01871 
01872     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01873     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01874     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01875 
01876     /* Prepare transfer parameters */
01877     hfmpi2c->pBuffPtr    = pData;
01878     hfmpi2c->XferCount   = Size;
01879     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01880     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
01881 
01882     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01883     {
01884       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01885       xfermode = FMPI2C_RELOAD_MODE;
01886     }
01887     else
01888     {
01889       hfmpi2c->XferSize = hfmpi2c->XferCount;
01890       xfermode = FMPI2C_AUTOEND_MODE;
01891     }
01892 
01893     if (hfmpi2c->XferSize > 0U)
01894     {
01895       if (hfmpi2c->hdmatx != NULL)
01896       {
01897         /* Set the FMPI2C DMA transfer complete callback */
01898         hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
01899 
01900         /* Set the DMA error callback */
01901         hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
01902 
01903         /* Set the unused DMA callbacks to NULL */
01904         hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
01905         hfmpi2c->hdmatx->XferAbortCallback = NULL;
01906 
01907         /* Enable the DMA stream */
01908         dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
01909                                          hfmpi2c->XferSize);
01910       }
01911       else
01912       {
01913         /* Update FMPI2C state */
01914         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
01915         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
01916 
01917         /* Update FMPI2C error code */
01918         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
01919 
01920         /* Process Unlocked */
01921         __HAL_UNLOCK(hfmpi2c);
01922 
01923         return HAL_ERROR;
01924       }
01925 
01926       if (dmaxferstatus == HAL_OK)
01927       {
01928         /* Send Slave Address */
01929         /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01930         FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
01931 
01932         /* Update XferCount value */
01933         hfmpi2c->XferCount -= hfmpi2c->XferSize;
01934 
01935         /* Process Unlocked */
01936         __HAL_UNLOCK(hfmpi2c);
01937 
01938         /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01939                   to avoid the risk of FMPI2C interrupt handle execution before current
01940                   process unlock */
01941         /* Enable ERR and NACK interrupts */
01942         FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
01943 
01944         /* Enable DMA Request */
01945         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
01946       }
01947       else
01948       {
01949         /* Update FMPI2C state */
01950         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
01951         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
01952 
01953         /* Update FMPI2C error code */
01954         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
01955 
01956         /* Process Unlocked */
01957         __HAL_UNLOCK(hfmpi2c);
01958 
01959         return HAL_ERROR;
01960       }
01961     }
01962     else
01963     {
01964       /* Update Transfer ISR function pointer */
01965       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
01966 
01967       /* Send Slave Address */
01968       /* Set NBYTES to write and generate START condition */
01969       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
01970                             FMPI2C_GENERATE_START_WRITE);
01971 
01972       /* Process Unlocked */
01973       __HAL_UNLOCK(hfmpi2c);
01974 
01975       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01976                 to avoid the risk of FMPI2C interrupt handle execution before current
01977                 process unlock */
01978       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01979       /* possible to enable all of these */
01980       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
01981         FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01982       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
01983     }
01984 
01985     return HAL_OK;
01986   }
01987   else
01988   {
01989     return HAL_BUSY;
01990   }
01991 }
01992 
01993 /**
01994   * @brief  Receive in master mode an amount of data in non-blocking mode with DMA
01995   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01996   *                the configuration information for the specified FMPI2C.
01997   * @param  DevAddress Target device address: The device 7 bits address value
01998   *         in datasheet must be shifted to the left before calling the interface
01999   * @param  pData Pointer to data buffer
02000   * @param  Size Amount of data to be sent
02001   * @retval HAL status
02002   */
02003 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
02004                                              uint16_t Size)
02005 {
02006   uint32_t xfermode;
02007   HAL_StatusTypeDef dmaxferstatus;
02008 
02009   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02010   {
02011     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02012     {
02013       return HAL_BUSY;
02014     }
02015 
02016     /* Process Locked */
02017     __HAL_LOCK(hfmpi2c);
02018 
02019     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02020     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
02021     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02022 
02023     /* Prepare transfer parameters */
02024     hfmpi2c->pBuffPtr    = pData;
02025     hfmpi2c->XferCount   = Size;
02026     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02027     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
02028 
02029     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02030     {
02031       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02032       xfermode = FMPI2C_RELOAD_MODE;
02033     }
02034     else
02035     {
02036       hfmpi2c->XferSize = hfmpi2c->XferCount;
02037       xfermode = FMPI2C_AUTOEND_MODE;
02038     }
02039 
02040     if (hfmpi2c->XferSize > 0U)
02041     {
02042       if (hfmpi2c->hdmarx != NULL)
02043       {
02044         /* Set the FMPI2C DMA transfer complete callback */
02045         hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
02046 
02047         /* Set the DMA error callback */
02048         hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
02049 
02050         /* Set the unused DMA callbacks to NULL */
02051         hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
02052         hfmpi2c->hdmarx->XferAbortCallback = NULL;
02053 
02054         /* Enable the DMA stream */
02055         dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
02056                                          hfmpi2c->XferSize);
02057       }
02058       else
02059       {
02060         /* Update FMPI2C state */
02061         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
02062         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02063 
02064         /* Update FMPI2C error code */
02065         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
02066 
02067         /* Process Unlocked */
02068         __HAL_UNLOCK(hfmpi2c);
02069 
02070         return HAL_ERROR;
02071       }
02072 
02073       if (dmaxferstatus == HAL_OK)
02074       {
02075         /* Send Slave Address */
02076         /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02077         FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
02078 
02079         /* Update XferCount value */
02080         hfmpi2c->XferCount -= hfmpi2c->XferSize;
02081 
02082         /* Process Unlocked */
02083         __HAL_UNLOCK(hfmpi2c);
02084 
02085         /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02086                   to avoid the risk of FMPI2C interrupt handle execution before current
02087                   process unlock */
02088         /* Enable ERR and NACK interrupts */
02089         FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
02090 
02091         /* Enable DMA Request */
02092         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
02093       }
02094       else
02095       {
02096         /* Update FMPI2C state */
02097         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
02098         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02099 
02100         /* Update FMPI2C error code */
02101         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
02102 
02103         /* Process Unlocked */
02104         __HAL_UNLOCK(hfmpi2c);
02105 
02106         return HAL_ERROR;
02107       }
02108     }
02109     else
02110     {
02111       /* Update Transfer ISR function pointer */
02112       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
02113 
02114       /* Send Slave Address */
02115       /* Set NBYTES to read and generate START condition */
02116       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
02117                             FMPI2C_GENERATE_START_READ);
02118 
02119       /* Process Unlocked */
02120       __HAL_UNLOCK(hfmpi2c);
02121 
02122       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02123                 to avoid the risk of FMPI2C interrupt handle execution before current
02124                 process unlock */
02125       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
02126       /* possible to enable all of these */
02127       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
02128         FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
02129       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02130     }
02131 
02132     return HAL_OK;
02133   }
02134   else
02135   {
02136     return HAL_BUSY;
02137   }
02138 }
02139 
02140 /**
02141   * @brief  Transmit in slave mode an amount of data in non-blocking mode with DMA
02142   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02143   *                the configuration information for the specified FMPI2C.
02144   * @param  pData Pointer to data buffer
02145   * @param  Size Amount of data to be sent
02146   * @retval HAL status
02147   */
02148 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
02149 {
02150   HAL_StatusTypeDef dmaxferstatus;
02151 
02152   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02153   {
02154     if ((pData == NULL) || (Size == 0U))
02155     {
02156       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02157       return  HAL_ERROR;
02158     }
02159     /* Process Locked */
02160     __HAL_LOCK(hfmpi2c);
02161 
02162     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
02163     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
02164     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02165 
02166     /* Prepare transfer parameters */
02167     hfmpi2c->pBuffPtr    = pData;
02168     hfmpi2c->XferCount   = Size;
02169     hfmpi2c->XferSize    = hfmpi2c->XferCount;
02170     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02171     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
02172 
02173     if (hfmpi2c->hdmatx != NULL)
02174     {
02175       /* Set the FMPI2C DMA transfer complete callback */
02176       hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
02177 
02178       /* Set the DMA error callback */
02179       hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
02180 
02181       /* Set the unused DMA callbacks to NULL */
02182       hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
02183       hfmpi2c->hdmatx->XferAbortCallback = NULL;
02184 
02185       /* Enable the DMA stream */
02186       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
02187                                        hfmpi2c->XferSize);
02188     }
02189     else
02190     {
02191       /* Update FMPI2C state */
02192       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
02193       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02194 
02195       /* Update FMPI2C error code */
02196       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
02197 
02198       /* Process Unlocked */
02199       __HAL_UNLOCK(hfmpi2c);
02200 
02201       return HAL_ERROR;
02202     }
02203 
02204     if (dmaxferstatus == HAL_OK)
02205     {
02206       /* Enable Address Acknowledge */
02207       hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
02208 
02209       /* Process Unlocked */
02210       __HAL_UNLOCK(hfmpi2c);
02211 
02212       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02213                 to avoid the risk of FMPI2C interrupt handle execution before current
02214                 process unlock */
02215       /* Enable ERR, STOP, NACK, ADDR interrupts */
02216       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
02217 
02218       /* Enable DMA Request */
02219       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
02220     }
02221     else
02222     {
02223       /* Update FMPI2C state */
02224       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
02225       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02226 
02227       /* Update FMPI2C error code */
02228       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
02229 
02230       /* Process Unlocked */
02231       __HAL_UNLOCK(hfmpi2c);
02232 
02233       return HAL_ERROR;
02234     }
02235 
02236     return HAL_OK;
02237   }
02238   else
02239   {
02240     return HAL_BUSY;
02241   }
02242 }
02243 
02244 /**
02245   * @brief  Receive in slave mode an amount of data in non-blocking mode with DMA
02246   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02247   *                the configuration information for the specified FMPI2C.
02248   * @param  pData Pointer to data buffer
02249   * @param  Size Amount of data to be sent
02250   * @retval HAL status
02251   */
02252 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
02253 {
02254   HAL_StatusTypeDef dmaxferstatus;
02255 
02256   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02257   {
02258     if ((pData == NULL) || (Size == 0U))
02259     {
02260       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02261       return  HAL_ERROR;
02262     }
02263     /* Process Locked */
02264     __HAL_LOCK(hfmpi2c);
02265 
02266     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02267     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
02268     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02269 
02270     /* Prepare transfer parameters */
02271     hfmpi2c->pBuffPtr    = pData;
02272     hfmpi2c->XferCount   = Size;
02273     hfmpi2c->XferSize    = hfmpi2c->XferCount;
02274     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02275     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
02276 
02277     if (hfmpi2c->hdmarx != NULL)
02278     {
02279       /* Set the FMPI2C DMA transfer complete callback */
02280       hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
02281 
02282       /* Set the DMA error callback */
02283       hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
02284 
02285       /* Set the unused DMA callbacks to NULL */
02286       hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
02287       hfmpi2c->hdmarx->XferAbortCallback = NULL;
02288 
02289       /* Enable the DMA stream */
02290       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
02291                                        hfmpi2c->XferSize);
02292     }
02293     else
02294     {
02295       /* Update FMPI2C state */
02296       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
02297       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02298 
02299       /* Update FMPI2C error code */
02300       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
02301 
02302       /* Process Unlocked */
02303       __HAL_UNLOCK(hfmpi2c);
02304 
02305       return HAL_ERROR;
02306     }
02307 
02308     if (dmaxferstatus == HAL_OK)
02309     {
02310       /* Enable Address Acknowledge */
02311       hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
02312 
02313       /* Process Unlocked */
02314       __HAL_UNLOCK(hfmpi2c);
02315 
02316       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02317                 to avoid the risk of FMPI2C interrupt handle execution before current
02318                 process unlock */
02319       /* Enable ERR, STOP, NACK, ADDR interrupts */
02320       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
02321 
02322       /* Enable DMA Request */
02323       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
02324     }
02325     else
02326     {
02327       /* Update FMPI2C state */
02328       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
02329       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02330 
02331       /* Update FMPI2C error code */
02332       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
02333 
02334       /* Process Unlocked */
02335       __HAL_UNLOCK(hfmpi2c);
02336 
02337       return HAL_ERROR;
02338     }
02339 
02340     return HAL_OK;
02341   }
02342   else
02343   {
02344     return HAL_BUSY;
02345   }
02346 }
02347 /**
02348   * @brief  Write an amount of data in blocking mode to a specific memory address
02349   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02350   *                the configuration information for the specified FMPI2C.
02351   * @param  DevAddress Target device address: The device 7 bits address value
02352   *         in datasheet must be shifted to the left before calling the interface
02353   * @param  MemAddress Internal memory address
02354   * @param  MemAddSize Size of internal memory address
02355   * @param  pData Pointer to data buffer
02356   * @param  Size Amount of data to be sent
02357   * @param  Timeout Timeout duration
02358   * @retval HAL status
02359   */
02360 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02361                                     uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
02362 {
02363   uint32_t tickstart;
02364 
02365   /* Check the parameters */
02366   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02367 
02368   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02369   {
02370     if ((pData == NULL) || (Size == 0U))
02371     {
02372       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02373       return  HAL_ERROR;
02374     }
02375 
02376     /* Process Locked */
02377     __HAL_LOCK(hfmpi2c);
02378 
02379     /* Init tickstart for timeout management*/
02380     tickstart = HAL_GetTick();
02381 
02382     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
02383     {
02384       return HAL_ERROR;
02385     }
02386 
02387     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
02388     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MEM;
02389     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02390 
02391     /* Prepare transfer parameters */
02392     hfmpi2c->pBuffPtr  = pData;
02393     hfmpi2c->XferCount = Size;
02394     hfmpi2c->XferISR   = NULL;
02395 
02396     /* Send Slave Address and Memory Address */
02397     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
02398     {
02399       /* Process Unlocked */
02400       __HAL_UNLOCK(hfmpi2c);
02401       return HAL_ERROR;
02402     }
02403 
02404     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
02405     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02406     {
02407       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02408       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
02409     }
02410     else
02411     {
02412       hfmpi2c->XferSize = hfmpi2c->XferCount;
02413       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
02414     }
02415 
02416     do
02417     {
02418       /* Wait until TXIS flag is set */
02419       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
02420       {
02421         return HAL_ERROR;
02422       }
02423 
02424       /* Write data to TXDR */
02425       hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
02426 
02427       /* Increment Buffer pointer */
02428       hfmpi2c->pBuffPtr++;
02429 
02430       hfmpi2c->XferCount--;
02431       hfmpi2c->XferSize--;
02432 
02433       if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
02434       {
02435         /* Wait until TCR flag is set */
02436         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
02437         {
02438           return HAL_ERROR;
02439         }
02440 
02441         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02442         {
02443           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02444           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
02445                                 FMPI2C_NO_STARTSTOP);
02446         }
02447         else
02448         {
02449           hfmpi2c->XferSize = hfmpi2c->XferCount;
02450           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
02451                                 FMPI2C_NO_STARTSTOP);
02452         }
02453       }
02454 
02455     } while (hfmpi2c->XferCount > 0U);
02456 
02457     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
02458     /* Wait until STOPF flag is reset */
02459     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
02460     {
02461       return HAL_ERROR;
02462     }
02463 
02464     /* Clear STOP Flag */
02465     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02466 
02467     /* Clear Configuration Register 2 */
02468     FMPI2C_RESET_CR2(hfmpi2c);
02469 
02470     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02471     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
02472 
02473     /* Process Unlocked */
02474     __HAL_UNLOCK(hfmpi2c);
02475 
02476     return HAL_OK;
02477   }
02478   else
02479   {
02480     return HAL_BUSY;
02481   }
02482 }
02483 
02484 /**
02485   * @brief  Read an amount of data in blocking mode from a specific memory address
02486   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02487   *                the configuration information for the specified FMPI2C.
02488   * @param  DevAddress Target device address: The device 7 bits address value
02489   *         in datasheet must be shifted to the left before calling the interface
02490   * @param  MemAddress Internal memory address
02491   * @param  MemAddSize Size of internal memory address
02492   * @param  pData Pointer to data buffer
02493   * @param  Size Amount of data to be sent
02494   * @param  Timeout Timeout duration
02495   * @retval HAL status
02496   */
02497 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02498                                    uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
02499 {
02500   uint32_t tickstart;
02501 
02502   /* Check the parameters */
02503   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02504 
02505   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02506   {
02507     if ((pData == NULL) || (Size == 0U))
02508     {
02509       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02510       return  HAL_ERROR;
02511     }
02512 
02513     /* Process Locked */
02514     __HAL_LOCK(hfmpi2c);
02515 
02516     /* Init tickstart for timeout management*/
02517     tickstart = HAL_GetTick();
02518 
02519     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
02520     {
02521       return HAL_ERROR;
02522     }
02523 
02524     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
02525     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MEM;
02526     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02527 
02528     /* Prepare transfer parameters */
02529     hfmpi2c->pBuffPtr  = pData;
02530     hfmpi2c->XferCount = Size;
02531     hfmpi2c->XferISR   = NULL;
02532 
02533     /* Send Slave Address and Memory Address */
02534     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
02535     {
02536       /* Process Unlocked */
02537       __HAL_UNLOCK(hfmpi2c);
02538       return HAL_ERROR;
02539     }
02540 
02541     /* Send Slave Address */
02542     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02543     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02544     {
02545       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02546       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
02547                             FMPI2C_GENERATE_START_READ);
02548     }
02549     else
02550     {
02551       hfmpi2c->XferSize = hfmpi2c->XferCount;
02552       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
02553                             FMPI2C_GENERATE_START_READ);
02554     }
02555 
02556     do
02557     {
02558       /* Wait until RXNE flag is set */
02559       if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
02560       {
02561         return HAL_ERROR;
02562       }
02563 
02564       /* Read data from RXDR */
02565       *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
02566 
02567       /* Increment Buffer pointer */
02568       hfmpi2c->pBuffPtr++;
02569 
02570       hfmpi2c->XferSize--;
02571       hfmpi2c->XferCount--;
02572 
02573       if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
02574       {
02575         /* Wait until TCR flag is set */
02576         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
02577         {
02578           return HAL_ERROR;
02579         }
02580 
02581         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02582         {
02583           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02584           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t) hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
02585                                 FMPI2C_NO_STARTSTOP);
02586         }
02587         else
02588         {
02589           hfmpi2c->XferSize = hfmpi2c->XferCount;
02590           FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
02591                                 FMPI2C_NO_STARTSTOP);
02592         }
02593       }
02594     } while (hfmpi2c->XferCount > 0U);
02595 
02596     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
02597     /* Wait until STOPF flag is reset */
02598     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
02599     {
02600       return HAL_ERROR;
02601     }
02602 
02603     /* Clear STOP Flag */
02604     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02605 
02606     /* Clear Configuration Register 2 */
02607     FMPI2C_RESET_CR2(hfmpi2c);
02608 
02609     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02610     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
02611 
02612     /* Process Unlocked */
02613     __HAL_UNLOCK(hfmpi2c);
02614 
02615     return HAL_OK;
02616   }
02617   else
02618   {
02619     return HAL_BUSY;
02620   }
02621 }
02622 /**
02623   * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
02624   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02625   *                the configuration information for the specified FMPI2C.
02626   * @param  DevAddress Target device address: The device 7 bits address value
02627   *         in datasheet must be shifted to the left before calling the interface
02628   * @param  MemAddress Internal memory address
02629   * @param  MemAddSize Size of internal memory address
02630   * @param  pData Pointer to data buffer
02631   * @param  Size Amount of data to be sent
02632   * @retval HAL status
02633   */
02634 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02635                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02636 {
02637   uint32_t tickstart;
02638   uint32_t xfermode;
02639 
02640   /* Check the parameters */
02641   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02642 
02643   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02644   {
02645     if ((pData == NULL) || (Size == 0U))
02646     {
02647       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02648       return  HAL_ERROR;
02649     }
02650 
02651     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02652     {
02653       return HAL_BUSY;
02654     }
02655 
02656     /* Process Locked */
02657     __HAL_LOCK(hfmpi2c);
02658 
02659     /* Init tickstart for timeout management*/
02660     tickstart = HAL_GetTick();
02661 
02662     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
02663     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02664     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02665 
02666     /* Prepare transfer parameters */
02667     hfmpi2c->pBuffPtr    = pData;
02668     hfmpi2c->XferCount   = Size;
02669     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02670     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02671 
02672     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02673     {
02674       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02675       xfermode = FMPI2C_RELOAD_MODE;
02676     }
02677     else
02678     {
02679       hfmpi2c->XferSize = hfmpi2c->XferCount;
02680       xfermode = FMPI2C_AUTOEND_MODE;
02681     }
02682 
02683     /* Send Slave Address and Memory Address */
02684     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart)
02685         != HAL_OK)
02686     {
02687       /* Process Unlocked */
02688       __HAL_UNLOCK(hfmpi2c);
02689       return HAL_ERROR;
02690     }
02691 
02692     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02693     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
02694 
02695     /* Process Unlocked */
02696     __HAL_UNLOCK(hfmpi2c);
02697 
02698     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02699               to avoid the risk of FMPI2C interrupt handle execution before current
02700               process unlock */
02701 
02702     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
02703     /* possible to enable all of these */
02704     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
02705       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
02706     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02707 
02708     return HAL_OK;
02709   }
02710   else
02711   {
02712     return HAL_BUSY;
02713   }
02714 }
02715 
02716 /**
02717   * @brief  Read an amount of data in non-blocking mode with Interrupt from a specific memory address
02718   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02719   *                the configuration information for the specified FMPI2C.
02720   * @param  DevAddress Target device address: The device 7 bits address value
02721   *         in datasheet must be shifted to the left before calling the interface
02722   * @param  MemAddress Internal memory address
02723   * @param  MemAddSize Size of internal memory address
02724   * @param  pData Pointer to data buffer
02725   * @param  Size Amount of data to be sent
02726   * @retval HAL status
02727   */
02728 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02729                                       uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02730 {
02731   uint32_t tickstart;
02732   uint32_t xfermode;
02733 
02734   /* Check the parameters */
02735   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02736 
02737   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02738   {
02739     if ((pData == NULL) || (Size == 0U))
02740     {
02741       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02742       return  HAL_ERROR;
02743     }
02744 
02745     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02746     {
02747       return HAL_BUSY;
02748     }
02749 
02750     /* Process Locked */
02751     __HAL_LOCK(hfmpi2c);
02752 
02753     /* Init tickstart for timeout management*/
02754     tickstart = HAL_GetTick();
02755 
02756     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02757     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02758     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02759 
02760     /* Prepare transfer parameters */
02761     hfmpi2c->pBuffPtr    = pData;
02762     hfmpi2c->XferCount   = Size;
02763     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02764     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02765 
02766     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02767     {
02768       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02769       xfermode = FMPI2C_RELOAD_MODE;
02770     }
02771     else
02772     {
02773       hfmpi2c->XferSize = hfmpi2c->XferCount;
02774       xfermode = FMPI2C_AUTOEND_MODE;
02775     }
02776 
02777     /* Send Slave Address and Memory Address */
02778     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
02779     {
02780       /* Process Unlocked */
02781       __HAL_UNLOCK(hfmpi2c);
02782       return HAL_ERROR;
02783     }
02784 
02785     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02786     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
02787 
02788     /* Process Unlocked */
02789     __HAL_UNLOCK(hfmpi2c);
02790 
02791     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02792               to avoid the risk of FMPI2C interrupt handle execution before current
02793               process unlock */
02794 
02795     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
02796     /* possible to enable all of these */
02797     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
02798       FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
02799     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
02800 
02801     return HAL_OK;
02802   }
02803   else
02804   {
02805     return HAL_BUSY;
02806   }
02807 }
02808 /**
02809   * @brief  Write an amount of data in non-blocking mode with DMA to a specific memory address
02810   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02811   *                the configuration information for the specified FMPI2C.
02812   * @param  DevAddress Target device address: The device 7 bits address value
02813   *         in datasheet must be shifted to the left before calling the interface
02814   * @param  MemAddress Internal memory address
02815   * @param  MemAddSize Size of internal memory address
02816   * @param  pData Pointer to data buffer
02817   * @param  Size Amount of data to be sent
02818   * @retval HAL status
02819   */
02820 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02821                                         uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02822 {
02823   uint32_t tickstart;
02824   uint32_t xfermode;
02825   HAL_StatusTypeDef dmaxferstatus;
02826 
02827   /* Check the parameters */
02828   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02829 
02830   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02831   {
02832     if ((pData == NULL) || (Size == 0U))
02833     {
02834       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02835       return  HAL_ERROR;
02836     }
02837 
02838     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02839     {
02840       return HAL_BUSY;
02841     }
02842 
02843     /* Process Locked */
02844     __HAL_LOCK(hfmpi2c);
02845 
02846     /* Init tickstart for timeout management*/
02847     tickstart = HAL_GetTick();
02848 
02849     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
02850     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02851     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02852 
02853     /* Prepare transfer parameters */
02854     hfmpi2c->pBuffPtr    = pData;
02855     hfmpi2c->XferCount   = Size;
02856     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02857     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
02858 
02859     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02860     {
02861       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02862       xfermode = FMPI2C_RELOAD_MODE;
02863     }
02864     else
02865     {
02866       hfmpi2c->XferSize = hfmpi2c->XferCount;
02867       xfermode = FMPI2C_AUTOEND_MODE;
02868     }
02869 
02870     /* Send Slave Address and Memory Address */
02871     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart)
02872         != HAL_OK)
02873     {
02874       /* Process Unlocked */
02875       __HAL_UNLOCK(hfmpi2c);
02876       return HAL_ERROR;
02877     }
02878 
02879 
02880     if (hfmpi2c->hdmatx != NULL)
02881     {
02882       /* Set the FMPI2C DMA transfer complete callback */
02883       hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
02884 
02885       /* Set the DMA error callback */
02886       hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
02887 
02888       /* Set the unused DMA callbacks to NULL */
02889       hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
02890       hfmpi2c->hdmatx->XferAbortCallback = NULL;
02891 
02892       /* Enable the DMA stream */
02893       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
02894                                        hfmpi2c->XferSize);
02895     }
02896     else
02897     {
02898       /* Update FMPI2C state */
02899       hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
02900       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02901 
02902       /* Update FMPI2C error code */
02903       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
02904 
02905       /* Process Unlocked */
02906       __HAL_UNLOCK(hfmpi2c);
02907 
02908       return HAL_ERROR;
02909     }
02910 
02911     if (dmaxferstatus == HAL_OK)
02912     {
02913       /* Send Slave Address */
02914       /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02915       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
02916 
02917       /* Update XferCount value */
02918       hfmpi2c->XferCount -= hfmpi2c->XferSize;
02919 
02920       /* Process Unlocked */
02921       __HAL_UNLOCK(hfmpi2c);
02922 
02923       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02924                 to avoid the risk of FMPI2C interrupt handle execution before current
02925                 process unlock */
02926       /* Enable ERR and NACK interrupts */
02927       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
02928 
02929       /* Enable DMA Request */
02930       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
02931     }
02932     else
02933     {
02934       /* Update FMPI2C state */
02935       hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
02936       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
02937 
02938       /* Update FMPI2C error code */
02939       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
02940 
02941       /* Process Unlocked */
02942       __HAL_UNLOCK(hfmpi2c);
02943 
02944       return HAL_ERROR;
02945     }
02946 
02947     return HAL_OK;
02948   }
02949   else
02950   {
02951     return HAL_BUSY;
02952   }
02953 }
02954 
02955 /**
02956   * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
02957   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02958   *                the configuration information for the specified FMPI2C.
02959   * @param  DevAddress Target device address: The device 7 bits address value
02960   *         in datasheet must be shifted to the left before calling the interface
02961   * @param  MemAddress Internal memory address
02962   * @param  MemAddSize Size of internal memory address
02963   * @param  pData Pointer to data buffer
02964   * @param  Size Amount of data to be read
02965   * @retval HAL status
02966   */
02967 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
02968                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02969 {
02970   uint32_t tickstart;
02971   uint32_t xfermode;
02972   HAL_StatusTypeDef dmaxferstatus;
02973 
02974   /* Check the parameters */
02975   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02976 
02977   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02978   {
02979     if ((pData == NULL) || (Size == 0U))
02980     {
02981       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
02982       return  HAL_ERROR;
02983     }
02984 
02985     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02986     {
02987       return HAL_BUSY;
02988     }
02989 
02990     /* Process Locked */
02991     __HAL_LOCK(hfmpi2c);
02992 
02993     /* Init tickstart for timeout management*/
02994     tickstart = HAL_GetTick();
02995 
02996     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02997     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02998     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02999 
03000     /* Prepare transfer parameters */
03001     hfmpi2c->pBuffPtr    = pData;
03002     hfmpi2c->XferCount   = Size;
03003     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
03004     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
03005 
03006     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03007     {
03008       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03009       xfermode = FMPI2C_RELOAD_MODE;
03010     }
03011     else
03012     {
03013       hfmpi2c->XferSize = hfmpi2c->XferCount;
03014       xfermode = FMPI2C_AUTOEND_MODE;
03015     }
03016 
03017     /* Send Slave Address and Memory Address */
03018     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
03019     {
03020       /* Process Unlocked */
03021       __HAL_UNLOCK(hfmpi2c);
03022       return HAL_ERROR;
03023     }
03024 
03025     if (hfmpi2c->hdmarx != NULL)
03026     {
03027       /* Set the FMPI2C DMA transfer complete callback */
03028       hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
03029 
03030       /* Set the DMA error callback */
03031       hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
03032 
03033       /* Set the unused DMA callbacks to NULL */
03034       hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
03035       hfmpi2c->hdmarx->XferAbortCallback = NULL;
03036 
03037       /* Enable the DMA stream */
03038       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
03039                                        hfmpi2c->XferSize);
03040     }
03041     else
03042     {
03043       /* Update FMPI2C state */
03044       hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03045       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03046 
03047       /* Update FMPI2C error code */
03048       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
03049 
03050       /* Process Unlocked */
03051       __HAL_UNLOCK(hfmpi2c);
03052 
03053       return HAL_ERROR;
03054     }
03055 
03056     if (dmaxferstatus == HAL_OK)
03057     {
03058       /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
03059       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
03060 
03061       /* Update XferCount value */
03062       hfmpi2c->XferCount -= hfmpi2c->XferSize;
03063 
03064       /* Process Unlocked */
03065       __HAL_UNLOCK(hfmpi2c);
03066 
03067       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03068                 to avoid the risk of FMPI2C interrupt handle execution before current
03069                 process unlock */
03070       /* Enable ERR and NACK interrupts */
03071       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
03072 
03073       /* Enable DMA Request */
03074       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
03075     }
03076     else
03077     {
03078       /* Update FMPI2C state */
03079       hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03080       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03081 
03082       /* Update FMPI2C error code */
03083       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
03084 
03085       /* Process Unlocked */
03086       __HAL_UNLOCK(hfmpi2c);
03087 
03088       return HAL_ERROR;
03089     }
03090 
03091     return HAL_OK;
03092   }
03093   else
03094   {
03095     return HAL_BUSY;
03096   }
03097 }
03098 
03099 /**
03100   * @brief  Checks if target device is ready for communication.
03101   * @note   This function is used with Memory devices
03102   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03103   *                the configuration information for the specified FMPI2C.
03104   * @param  DevAddress Target device address: The device 7 bits address value
03105   *         in datasheet must be shifted to the left before calling the interface
03106   * @param  Trials Number of trials
03107   * @param  Timeout Timeout duration
03108   * @retval HAL status
03109   */
03110 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials,
03111                                            uint32_t Timeout)
03112 {
03113   uint32_t tickstart;
03114 
03115   __IO uint32_t FMPI2C_Trials = 0UL;
03116 
03117   FlagStatus tmp1;
03118   FlagStatus tmp2;
03119 
03120   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
03121   {
03122     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
03123     {
03124       return HAL_BUSY;
03125     }
03126 
03127     /* Process Locked */
03128     __HAL_LOCK(hfmpi2c);
03129 
03130     hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
03131     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03132 
03133     do
03134     {
03135       /* Generate Start */
03136       hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress);
03137 
03138       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
03139       /* Wait until STOPF flag is set or a NACK flag is set*/
03140       tickstart = HAL_GetTick();
03141 
03142       tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03143       tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03144 
03145       while ((tmp1 == RESET) && (tmp2 == RESET))
03146       {
03147         if (Timeout != HAL_MAX_DELAY)
03148         {
03149           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
03150           {
03151             /* Update FMPI2C state */
03152             hfmpi2c->State = HAL_FMPI2C_STATE_READY;
03153 
03154             /* Update FMPI2C error code */
03155             hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
03156 
03157             /* Process Unlocked */
03158             __HAL_UNLOCK(hfmpi2c);
03159 
03160             return HAL_ERROR;
03161           }
03162         }
03163 
03164         tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03165         tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03166       }
03167 
03168       /* Check if the NACKF flag has not been set */
03169       if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
03170       {
03171         /* Wait until STOPF flag is reset */
03172         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
03173         {
03174           return HAL_ERROR;
03175         }
03176 
03177         /* Clear STOP Flag */
03178         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03179 
03180         /* Device is ready */
03181         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
03182 
03183         /* Process Unlocked */
03184         __HAL_UNLOCK(hfmpi2c);
03185 
03186         return HAL_OK;
03187       }
03188       else
03189       {
03190         /* Wait until STOPF flag is reset */
03191         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
03192         {
03193           return HAL_ERROR;
03194         }
03195 
03196         /* Clear NACK Flag */
03197         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03198 
03199         /* Clear STOP Flag, auto generated with autoend*/
03200         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03201       }
03202 
03203       /* Check if the maximum allowed number of trials has been reached */
03204       if (FMPI2C_Trials == Trials)
03205       {
03206         /* Generate Stop */
03207         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
03208 
03209         /* Wait until STOPF flag is reset */
03210         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
03211         {
03212           return HAL_ERROR;
03213         }
03214 
03215         /* Clear STOP Flag */
03216         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03217       }
03218 
03219       /* Increment Trials */
03220       FMPI2C_Trials++;
03221     } while (FMPI2C_Trials < Trials);
03222 
03223     /* Update FMPI2C state */
03224     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
03225 
03226     /* Update FMPI2C error code */
03227     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
03228 
03229     /* Process Unlocked */
03230     __HAL_UNLOCK(hfmpi2c);
03231 
03232     return HAL_ERROR;
03233   }
03234   else
03235   {
03236     return HAL_BUSY;
03237   }
03238 }
03239 
03240 /**
03241   * @brief  Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
03242   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03243   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03244   *                the configuration information for the specified FMPI2C.
03245   * @param  DevAddress Target device address: The device 7 bits address value
03246   *         in datasheet must be shifted to the left before calling the interface
03247   * @param  pData Pointer to data buffer
03248   * @param  Size Amount of data to be sent
03249   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03250   * @retval HAL status
03251   */
03252 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
03253                                                  uint16_t Size, uint32_t XferOptions)
03254 {
03255   uint32_t xfermode;
03256   uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
03257 
03258   /* Check the parameters */
03259   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03260 
03261   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
03262   {
03263     /* Process Locked */
03264     __HAL_LOCK(hfmpi2c);
03265 
03266     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
03267     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
03268     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03269 
03270     /* Prepare transfer parameters */
03271     hfmpi2c->pBuffPtr    = pData;
03272     hfmpi2c->XferCount   = Size;
03273     hfmpi2c->XferOptions = XferOptions;
03274     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
03275 
03276     /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
03277     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03278     {
03279       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03280       xfermode = FMPI2C_RELOAD_MODE;
03281     }
03282     else
03283     {
03284       hfmpi2c->XferSize = hfmpi2c->XferCount;
03285       xfermode = hfmpi2c->XferOptions;
03286     }
03287 
03288     /* If transfer direction not change and there is no request to start another frame,
03289        do not generate Restart Condition */
03290     /* Mean Previous state is same as current state */
03291     if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
03292       (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
03293     {
03294       xferrequest = FMPI2C_NO_STARTSTOP;
03295     }
03296     else
03297     {
03298       /* Convert OTHER_xxx XferOptions if any */
03299       FMPI2C_ConvertOtherXferOptions(hfmpi2c);
03300 
03301       /* Update xfermode accordingly if no reload is necessary */
03302       if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
03303       {
03304         xfermode = hfmpi2c->XferOptions;
03305       }
03306     }
03307 
03308     /* Send Slave Address and set NBYTES to write */
03309     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
03310 
03311     /* Process Unlocked */
03312     __HAL_UNLOCK(hfmpi2c);
03313 
03314     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03315               to avoid the risk of FMPI2C interrupt handle execution before current
03316               process unlock */
03317     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
03318 
03319     return HAL_OK;
03320   }
03321   else
03322   {
03323     return HAL_BUSY;
03324   }
03325 }
03326 
03327 /**
03328   * @brief  Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with DMA.
03329   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03330   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03331   *                the configuration information for the specified FMPI2C.
03332   * @param  DevAddress Target device address: The device 7 bits address value
03333   *         in datasheet must be shifted to the left before calling the interface
03334   * @param  pData Pointer to data buffer
03335   * @param  Size Amount of data to be sent
03336   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03337   * @retval HAL status
03338   */
03339 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
03340                                                   uint16_t Size, uint32_t XferOptions)
03341 {
03342   uint32_t xfermode;
03343   uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
03344   HAL_StatusTypeDef dmaxferstatus;
03345 
03346   /* Check the parameters */
03347   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03348 
03349   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
03350   {
03351     /* Process Locked */
03352     __HAL_LOCK(hfmpi2c);
03353 
03354     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
03355     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
03356     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03357 
03358     /* Prepare transfer parameters */
03359     hfmpi2c->pBuffPtr    = pData;
03360     hfmpi2c->XferCount   = Size;
03361     hfmpi2c->XferOptions = XferOptions;
03362     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
03363 
03364     /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
03365     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03366     {
03367       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03368       xfermode = FMPI2C_RELOAD_MODE;
03369     }
03370     else
03371     {
03372       hfmpi2c->XferSize = hfmpi2c->XferCount;
03373       xfermode = hfmpi2c->XferOptions;
03374     }
03375 
03376     /* If transfer direction not change and there is no request to start another frame,
03377        do not generate Restart Condition */
03378     /* Mean Previous state is same as current state */
03379     if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
03380       (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
03381     {
03382       xferrequest = FMPI2C_NO_STARTSTOP;
03383     }
03384     else
03385     {
03386       /* Convert OTHER_xxx XferOptions if any */
03387       FMPI2C_ConvertOtherXferOptions(hfmpi2c);
03388 
03389       /* Update xfermode accordingly if no reload is necessary */
03390       if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
03391       {
03392         xfermode = hfmpi2c->XferOptions;
03393       }
03394     }
03395 
03396     if (hfmpi2c->XferSize > 0U)
03397     {
03398       if (hfmpi2c->hdmatx != NULL)
03399       {
03400         /* Set the FMPI2C DMA transfer complete callback */
03401         hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
03402 
03403         /* Set the DMA error callback */
03404         hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
03405 
03406         /* Set the unused DMA callbacks to NULL */
03407         hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
03408         hfmpi2c->hdmatx->XferAbortCallback = NULL;
03409 
03410         /* Enable the DMA stream */
03411         dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
03412                                          hfmpi2c->XferSize);
03413       }
03414       else
03415       {
03416         /* Update FMPI2C state */
03417         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03418         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03419 
03420         /* Update FMPI2C error code */
03421         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
03422 
03423         /* Process Unlocked */
03424         __HAL_UNLOCK(hfmpi2c);
03425 
03426         return HAL_ERROR;
03427       }
03428 
03429       if (dmaxferstatus == HAL_OK)
03430       {
03431         /* Send Slave Address and set NBYTES to write */
03432         FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
03433 
03434         /* Update XferCount value */
03435         hfmpi2c->XferCount -= hfmpi2c->XferSize;
03436 
03437         /* Process Unlocked */
03438         __HAL_UNLOCK(hfmpi2c);
03439 
03440         /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03441                   to avoid the risk of FMPI2C interrupt handle execution before current
03442                   process unlock */
03443         /* Enable ERR and NACK interrupts */
03444         FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
03445 
03446         /* Enable DMA Request */
03447         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
03448       }
03449       else
03450       {
03451         /* Update FMPI2C state */
03452         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03453         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03454 
03455         /* Update FMPI2C error code */
03456         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
03457 
03458         /* Process Unlocked */
03459         __HAL_UNLOCK(hfmpi2c);
03460 
03461         return HAL_ERROR;
03462       }
03463     }
03464     else
03465     {
03466       /* Update Transfer ISR function pointer */
03467       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
03468 
03469       /* Send Slave Address */
03470       /* Set NBYTES to write and generate START condition */
03471       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
03472                             FMPI2C_GENERATE_START_WRITE);
03473 
03474       /* Process Unlocked */
03475       __HAL_UNLOCK(hfmpi2c);
03476 
03477       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03478                 to avoid the risk of FMPI2C interrupt handle execution before current
03479                 process unlock */
03480       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
03481       /* possible to enable all of these */
03482       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
03483         FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
03484       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
03485     }
03486 
03487     return HAL_OK;
03488   }
03489   else
03490   {
03491     return HAL_BUSY;
03492   }
03493 }
03494 
03495 /**
03496   * @brief  Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt
03497   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03498   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03499   *                the configuration information for the specified FMPI2C.
03500   * @param  DevAddress Target device address: The device 7 bits address value
03501   *         in datasheet must be shifted to the left before calling the interface
03502   * @param  pData Pointer to data buffer
03503   * @param  Size Amount of data to be sent
03504   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03505   * @retval HAL status
03506   */
03507 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
03508                                                 uint16_t Size, uint32_t XferOptions)
03509 {
03510   uint32_t xfermode;
03511   uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
03512 
03513   /* Check the parameters */
03514   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03515 
03516   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
03517   {
03518     /* Process Locked */
03519     __HAL_LOCK(hfmpi2c);
03520 
03521     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
03522     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
03523     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03524 
03525     /* Prepare transfer parameters */
03526     hfmpi2c->pBuffPtr    = pData;
03527     hfmpi2c->XferCount   = Size;
03528     hfmpi2c->XferOptions = XferOptions;
03529     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
03530 
03531     /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
03532     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03533     {
03534       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03535       xfermode = FMPI2C_RELOAD_MODE;
03536     }
03537     else
03538     {
03539       hfmpi2c->XferSize = hfmpi2c->XferCount;
03540       xfermode = hfmpi2c->XferOptions;
03541     }
03542 
03543     /* If transfer direction not change and there is no request to start another frame,
03544        do not generate Restart Condition */
03545     /* Mean Previous state is same as current state */
03546     if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
03547       (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
03548     {
03549       xferrequest = FMPI2C_NO_STARTSTOP;
03550     }
03551     else
03552     {
03553       /* Convert OTHER_xxx XferOptions if any */
03554       FMPI2C_ConvertOtherXferOptions(hfmpi2c);
03555 
03556       /* Update xfermode accordingly if no reload is necessary */
03557       if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
03558       {
03559         xfermode = hfmpi2c->XferOptions;
03560       }
03561     }
03562 
03563     /* Send Slave Address and set NBYTES to read */
03564     FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
03565 
03566     /* Process Unlocked */
03567     __HAL_UNLOCK(hfmpi2c);
03568 
03569     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03570               to avoid the risk of FMPI2C interrupt handle execution before current
03571               process unlock */
03572     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
03573 
03574     return HAL_OK;
03575   }
03576   else
03577   {
03578     return HAL_BUSY;
03579   }
03580 }
03581 
03582 /**
03583   * @brief  Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with DMA
03584   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03585   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03586   *                the configuration information for the specified FMPI2C.
03587   * @param  DevAddress Target device address: The device 7 bits address value
03588   *         in datasheet must be shifted to the left before calling the interface
03589   * @param  pData Pointer to data buffer
03590   * @param  Size Amount of data to be sent
03591   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03592   * @retval HAL status
03593   */
03594 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
03595                                                  uint16_t Size, uint32_t XferOptions)
03596 {
03597   uint32_t xfermode;
03598   uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
03599   HAL_StatusTypeDef dmaxferstatus;
03600 
03601   /* Check the parameters */
03602   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03603 
03604   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
03605   {
03606     /* Process Locked */
03607     __HAL_LOCK(hfmpi2c);
03608 
03609     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
03610     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
03611     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03612 
03613     /* Prepare transfer parameters */
03614     hfmpi2c->pBuffPtr    = pData;
03615     hfmpi2c->XferCount   = Size;
03616     hfmpi2c->XferOptions = XferOptions;
03617     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
03618 
03619     /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
03620     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03621     {
03622       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03623       xfermode = FMPI2C_RELOAD_MODE;
03624     }
03625     else
03626     {
03627       hfmpi2c->XferSize = hfmpi2c->XferCount;
03628       xfermode = hfmpi2c->XferOptions;
03629     }
03630 
03631     /* If transfer direction not change and there is no request to start another frame,
03632        do not generate Restart Condition */
03633     /* Mean Previous state is same as current state */
03634     if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
03635       (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
03636     {
03637       xferrequest = FMPI2C_NO_STARTSTOP;
03638     }
03639     else
03640     {
03641       /* Convert OTHER_xxx XferOptions if any */
03642       FMPI2C_ConvertOtherXferOptions(hfmpi2c);
03643 
03644       /* Update xfermode accordingly if no reload is necessary */
03645       if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
03646       {
03647         xfermode = hfmpi2c->XferOptions;
03648       }
03649     }
03650 
03651     if (hfmpi2c->XferSize > 0U)
03652     {
03653       if (hfmpi2c->hdmarx != NULL)
03654       {
03655         /* Set the FMPI2C DMA transfer complete callback */
03656         hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
03657 
03658         /* Set the DMA error callback */
03659         hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
03660 
03661         /* Set the unused DMA callbacks to NULL */
03662         hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
03663         hfmpi2c->hdmarx->XferAbortCallback = NULL;
03664 
03665         /* Enable the DMA stream */
03666         dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
03667                                          hfmpi2c->XferSize);
03668       }
03669       else
03670       {
03671         /* Update FMPI2C state */
03672         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03673         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03674 
03675         /* Update FMPI2C error code */
03676         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
03677 
03678         /* Process Unlocked */
03679         __HAL_UNLOCK(hfmpi2c);
03680 
03681         return HAL_ERROR;
03682       }
03683 
03684       if (dmaxferstatus == HAL_OK)
03685       {
03686         /* Send Slave Address and set NBYTES to read */
03687         FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
03688 
03689         /* Update XferCount value */
03690         hfmpi2c->XferCount -= hfmpi2c->XferSize;
03691 
03692         /* Process Unlocked */
03693         __HAL_UNLOCK(hfmpi2c);
03694 
03695         /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03696                   to avoid the risk of FMPI2C interrupt handle execution before current
03697                   process unlock */
03698         /* Enable ERR and NACK interrupts */
03699         FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
03700 
03701         /* Enable DMA Request */
03702         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
03703       }
03704       else
03705       {
03706         /* Update FMPI2C state */
03707         hfmpi2c->State     = HAL_FMPI2C_STATE_READY;
03708         hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03709 
03710         /* Update FMPI2C error code */
03711         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
03712 
03713         /* Process Unlocked */
03714         __HAL_UNLOCK(hfmpi2c);
03715 
03716         return HAL_ERROR;
03717       }
03718     }
03719     else
03720     {
03721       /* Update Transfer ISR function pointer */
03722       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
03723 
03724       /* Send Slave Address */
03725       /* Set NBYTES to read and generate START condition */
03726       FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
03727                             FMPI2C_GENERATE_START_READ);
03728 
03729       /* Process Unlocked */
03730       __HAL_UNLOCK(hfmpi2c);
03731 
03732       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03733                 to avoid the risk of FMPI2C interrupt handle execution before current
03734                 process unlock */
03735       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
03736       /* possible to enable all of these */
03737       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
03738         FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
03739       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
03740     }
03741 
03742     return HAL_OK;
03743   }
03744   else
03745   {
03746     return HAL_BUSY;
03747   }
03748 }
03749 
03750 /**
03751   * @brief  Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
03752   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03753   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03754   *                the configuration information for the specified FMPI2C.
03755   * @param  pData Pointer to data buffer
03756   * @param  Size Amount of data to be sent
03757   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03758   * @retval HAL status
03759   */
03760 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
03761                                                 uint32_t XferOptions)
03762 {
03763   /* Check the parameters */
03764   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03765 
03766   if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
03767   {
03768     if ((pData == NULL) || (Size == 0U))
03769     {
03770       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
03771       return  HAL_ERROR;
03772     }
03773 
03774     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
03775     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
03776 
03777     /* Process Locked */
03778     __HAL_LOCK(hfmpi2c);
03779 
03780     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
03781     /* and then toggle the HAL slave RX state to TX state */
03782     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
03783     {
03784       /* Disable associated Interrupts */
03785       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
03786 
03787       /* Abort DMA Xfer if any */
03788       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
03789       {
03790         hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
03791 
03792         if (hfmpi2c->hdmarx != NULL)
03793         {
03794           /* Set the FMPI2C DMA Abort callback :
03795            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
03796           hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
03797 
03798           /* Abort DMA RX */
03799           if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
03800           {
03801             /* Call Directly XferAbortCallback function in case of error */
03802             hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
03803           }
03804         }
03805       }
03806     }
03807 
03808     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
03809     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
03810     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03811 
03812     /* Enable Address Acknowledge */
03813     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
03814 
03815     /* Prepare transfer parameters */
03816     hfmpi2c->pBuffPtr    = pData;
03817     hfmpi2c->XferCount   = Size;
03818     hfmpi2c->XferSize    = hfmpi2c->XferCount;
03819     hfmpi2c->XferOptions = XferOptions;
03820     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
03821 
03822     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
03823     {
03824       /* Clear ADDR flag after prepare the transfer parameters */
03825       /* This action will generate an acknowledge to the Master */
03826       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
03827     }
03828 
03829     /* Process Unlocked */
03830     __HAL_UNLOCK(hfmpi2c);
03831 
03832     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
03833     to avoid the risk of FMPI2C interrupt handle execution before current
03834     process unlock */
03835     /* REnable ADDR interrupt */
03836     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
03837 
03838     return HAL_OK;
03839   }
03840   else
03841   {
03842     return HAL_ERROR;
03843   }
03844 }
03845 
03846 /**
03847   * @brief  Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA
03848   * @note   This interface allow to manage repeated start condition when a direction change during transfer
03849   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03850   *                the configuration information for the specified FMPI2C.
03851   * @param  pData Pointer to data buffer
03852   * @param  Size Amount of data to be sent
03853   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
03854   * @retval HAL status
03855   */
03856 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
03857                                                  uint32_t XferOptions)
03858 {
03859   HAL_StatusTypeDef dmaxferstatus;
03860 
03861   /* Check the parameters */
03862   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
03863 
03864   if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
03865   {
03866     if ((pData == NULL) || (Size == 0U))
03867     {
03868       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
03869       return  HAL_ERROR;
03870     }
03871 
03872     /* Process Locked */
03873     __HAL_LOCK(hfmpi2c);
03874 
03875     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
03876     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
03877 
03878     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
03879     /* and then toggle the HAL slave RX state to TX state */
03880     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
03881     {
03882       /* Disable associated Interrupts */
03883       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
03884 
03885       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
03886       {
03887         /* Abort DMA Xfer if any */
03888         if (hfmpi2c->hdmarx != NULL)
03889         {
03890           hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
03891 
03892           /* Set the FMPI2C DMA Abort callback :
03893            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
03894           hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
03895 
03896           /* Abort DMA RX */
03897           if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
03898           {
03899             /* Call Directly XferAbortCallback function in case of error */
03900             hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
03901           }
03902         }
03903       }
03904     }
03905     else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
03906     {
03907       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
03908       {
03909         hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
03910 
03911         /* Abort DMA Xfer if any */
03912         if (hfmpi2c->hdmatx != NULL)
03913         {
03914           /* Set the FMPI2C DMA Abort callback :
03915            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
03916           hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
03917 
03918           /* Abort DMA TX */
03919           if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
03920           {
03921             /* Call Directly XferAbortCallback function in case of error */
03922             hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
03923           }
03924         }
03925       }
03926     }
03927     else
03928     {
03929       /* Nothing to do */
03930     }
03931 
03932     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
03933     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
03934     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
03935 
03936     /* Enable Address Acknowledge */
03937     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
03938 
03939     /* Prepare transfer parameters */
03940     hfmpi2c->pBuffPtr    = pData;
03941     hfmpi2c->XferCount   = Size;
03942     hfmpi2c->XferSize    = hfmpi2c->XferCount;
03943     hfmpi2c->XferOptions = XferOptions;
03944     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
03945 
03946     if (hfmpi2c->hdmatx != NULL)
03947     {
03948       /* Set the FMPI2C DMA transfer complete callback */
03949       hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
03950 
03951       /* Set the DMA error callback */
03952       hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
03953 
03954       /* Set the unused DMA callbacks to NULL */
03955       hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
03956       hfmpi2c->hdmatx->XferAbortCallback = NULL;
03957 
03958       /* Enable the DMA stream */
03959       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
03960                                        hfmpi2c->XferSize);
03961     }
03962     else
03963     {
03964       /* Update FMPI2C state */
03965       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
03966       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03967 
03968       /* Update FMPI2C error code */
03969       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
03970 
03971       /* Process Unlocked */
03972       __HAL_UNLOCK(hfmpi2c);
03973 
03974       return HAL_ERROR;
03975     }
03976 
03977     if (dmaxferstatus == HAL_OK)
03978     {
03979       /* Update XferCount value */
03980       hfmpi2c->XferCount -= hfmpi2c->XferSize;
03981 
03982       /* Reset XferSize */
03983       hfmpi2c->XferSize = 0;
03984     }
03985     else
03986     {
03987       /* Update FMPI2C state */
03988       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
03989       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
03990 
03991       /* Update FMPI2C error code */
03992       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
03993 
03994       /* Process Unlocked */
03995       __HAL_UNLOCK(hfmpi2c);
03996 
03997       return HAL_ERROR;
03998     }
03999 
04000     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
04001     {
04002       /* Clear ADDR flag after prepare the transfer parameters */
04003       /* This action will generate an acknowledge to the Master */
04004       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
04005     }
04006 
04007     /* Process Unlocked */
04008     __HAL_UNLOCK(hfmpi2c);
04009 
04010     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
04011     to avoid the risk of FMPI2C interrupt handle execution before current
04012     process unlock */
04013     /* Enable ERR, STOP, NACK, ADDR interrupts */
04014     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
04015 
04016     /* Enable DMA Request */
04017     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
04018 
04019     return HAL_OK;
04020   }
04021   else
04022   {
04023     return HAL_ERROR;
04024   }
04025 }
04026 
04027 /**
04028   * @brief  Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
04029   * @note   This interface allow to manage repeated start condition when a direction change during transfer
04030   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04031   *                the configuration information for the specified FMPI2C.
04032   * @param  pData Pointer to data buffer
04033   * @param  Size Amount of data to be sent
04034   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
04035   * @retval HAL status
04036   */
04037 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
04038                                                uint32_t XferOptions)
04039 {
04040   /* Check the parameters */
04041   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
04042 
04043   if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
04044   {
04045     if ((pData == NULL) || (Size == 0U))
04046     {
04047       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
04048       return  HAL_ERROR;
04049     }
04050 
04051     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
04052     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
04053 
04054     /* Process Locked */
04055     __HAL_LOCK(hfmpi2c);
04056 
04057     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
04058     /* and then toggle the HAL slave TX state to RX state */
04059     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
04060     {
04061       /* Disable associated Interrupts */
04062       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
04063 
04064       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
04065       {
04066         hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
04067 
04068         /* Abort DMA Xfer if any */
04069         if (hfmpi2c->hdmatx != NULL)
04070         {
04071           /* Set the FMPI2C DMA Abort callback :
04072            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
04073           hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
04074 
04075           /* Abort DMA TX */
04076           if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
04077           {
04078             /* Call Directly XferAbortCallback function in case of error */
04079             hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
04080           }
04081         }
04082       }
04083     }
04084 
04085     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
04086     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
04087     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
04088 
04089     /* Enable Address Acknowledge */
04090     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
04091 
04092     /* Prepare transfer parameters */
04093     hfmpi2c->pBuffPtr    = pData;
04094     hfmpi2c->XferCount   = Size;
04095     hfmpi2c->XferSize    = hfmpi2c->XferCount;
04096     hfmpi2c->XferOptions = XferOptions;
04097     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
04098 
04099     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
04100     {
04101       /* Clear ADDR flag after prepare the transfer parameters */
04102       /* This action will generate an acknowledge to the Master */
04103       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
04104     }
04105 
04106     /* Process Unlocked */
04107     __HAL_UNLOCK(hfmpi2c);
04108 
04109     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
04110     to avoid the risk of FMPI2C interrupt handle execution before current
04111     process unlock */
04112     /* REnable ADDR interrupt */
04113     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
04114 
04115     return HAL_OK;
04116   }
04117   else
04118   {
04119     return HAL_ERROR;
04120   }
04121 }
04122 
04123 /**
04124   * @brief  Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA
04125   * @note   This interface allow to manage repeated start condition when a direction change during transfer
04126   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04127   *                the configuration information for the specified FMPI2C.
04128   * @param  pData Pointer to data buffer
04129   * @param  Size Amount of data to be sent
04130   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
04131   * @retval HAL status
04132   */
04133 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
04134                                                 uint32_t XferOptions)
04135 {
04136   HAL_StatusTypeDef dmaxferstatus;
04137 
04138   /* Check the parameters */
04139   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
04140 
04141   if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
04142   {
04143     if ((pData == NULL) || (Size == 0U))
04144     {
04145       hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
04146       return  HAL_ERROR;
04147     }
04148 
04149     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
04150     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
04151 
04152     /* Process Locked */
04153     __HAL_LOCK(hfmpi2c);
04154 
04155     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
04156     /* and then toggle the HAL slave TX state to RX state */
04157     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
04158     {
04159       /* Disable associated Interrupts */
04160       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
04161 
04162       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
04163       {
04164         /* Abort DMA Xfer if any */
04165         if (hfmpi2c->hdmatx != NULL)
04166         {
04167           hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
04168 
04169           /* Set the FMPI2C DMA Abort callback :
04170            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
04171           hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
04172 
04173           /* Abort DMA TX */
04174           if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
04175           {
04176             /* Call Directly XferAbortCallback function in case of error */
04177             hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
04178           }
04179         }
04180       }
04181     }
04182     else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
04183     {
04184       if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
04185       {
04186         hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
04187 
04188         /* Abort DMA Xfer if any */
04189         if (hfmpi2c->hdmarx != NULL)
04190         {
04191           /* Set the FMPI2C DMA Abort callback :
04192            will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
04193           hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
04194 
04195           /* Abort DMA RX */
04196           if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
04197           {
04198             /* Call Directly XferAbortCallback function in case of error */
04199             hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
04200           }
04201         }
04202       }
04203     }
04204     else
04205     {
04206       /* Nothing to do */
04207     }
04208 
04209     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
04210     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
04211     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
04212 
04213     /* Enable Address Acknowledge */
04214     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
04215 
04216     /* Prepare transfer parameters */
04217     hfmpi2c->pBuffPtr    = pData;
04218     hfmpi2c->XferCount   = Size;
04219     hfmpi2c->XferSize    = hfmpi2c->XferCount;
04220     hfmpi2c->XferOptions = XferOptions;
04221     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
04222 
04223     if (hfmpi2c->hdmarx != NULL)
04224     {
04225       /* Set the FMPI2C DMA transfer complete callback */
04226       hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
04227 
04228       /* Set the DMA error callback */
04229       hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
04230 
04231       /* Set the unused DMA callbacks to NULL */
04232       hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
04233       hfmpi2c->hdmarx->XferAbortCallback = NULL;
04234 
04235       /* Enable the DMA stream */
04236       dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR,
04237                                        (uint32_t)pData, hfmpi2c->XferSize);
04238     }
04239     else
04240     {
04241       /* Update FMPI2C state */
04242       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
04243       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
04244 
04245       /* Update FMPI2C error code */
04246       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
04247 
04248       /* Process Unlocked */
04249       __HAL_UNLOCK(hfmpi2c);
04250 
04251       return HAL_ERROR;
04252     }
04253 
04254     if (dmaxferstatus == HAL_OK)
04255     {
04256       /* Update XferCount value */
04257       hfmpi2c->XferCount -= hfmpi2c->XferSize;
04258 
04259       /* Reset XferSize */
04260       hfmpi2c->XferSize = 0;
04261     }
04262     else
04263     {
04264       /* Update FMPI2C state */
04265       hfmpi2c->State     = HAL_FMPI2C_STATE_LISTEN;
04266       hfmpi2c->Mode      = HAL_FMPI2C_MODE_NONE;
04267 
04268       /* Update FMPI2C error code */
04269       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
04270 
04271       /* Process Unlocked */
04272       __HAL_UNLOCK(hfmpi2c);
04273 
04274       return HAL_ERROR;
04275     }
04276 
04277     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
04278     {
04279       /* Clear ADDR flag after prepare the transfer parameters */
04280       /* This action will generate an acknowledge to the Master */
04281       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
04282     }
04283 
04284     /* Process Unlocked */
04285     __HAL_UNLOCK(hfmpi2c);
04286 
04287     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
04288     to avoid the risk of FMPI2C interrupt handle execution before current
04289     process unlock */
04290     /* REnable ADDR interrupt */
04291     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
04292 
04293     /* Enable DMA Request */
04294     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
04295 
04296     return HAL_OK;
04297   }
04298   else
04299   {
04300     return HAL_ERROR;
04301   }
04302 }
04303 
04304 /**
04305   * @brief  Enable the Address listen mode with Interrupt.
04306   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04307   *                the configuration information for the specified FMPI2C.
04308   * @retval HAL status
04309   */
04310 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
04311 {
04312   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
04313   {
04314     hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
04315     hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
04316 
04317     /* Enable the Address Match interrupt */
04318     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
04319 
04320     return HAL_OK;
04321   }
04322   else
04323   {
04324     return HAL_BUSY;
04325   }
04326 }
04327 
04328 /**
04329   * @brief  Disable the Address listen mode with Interrupt.
04330   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04331   *                the configuration information for the specified FMPI2C
04332   * @retval HAL status
04333   */
04334 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
04335 {
04336   /* Declaration of tmp to prevent undefined behavior of volatile usage */
04337   uint32_t tmp;
04338 
04339   /* Disable Address listen mode only if a transfer is not ongoing */
04340   if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
04341   {
04342     tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK;
04343     hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode);
04344     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04345     hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04346     hfmpi2c->XferISR = NULL;
04347 
04348     /* Disable the Address Match interrupt */
04349     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
04350 
04351     return HAL_OK;
04352   }
04353   else
04354   {
04355     return HAL_BUSY;
04356   }
04357 }
04358 
04359 /**
04360   * @brief  Abort a master FMPI2C IT or DMA process communication with Interrupt.
04361   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04362   *                the configuration information for the specified FMPI2C.
04363   * @param  DevAddress Target device address: The device 7 bits address value
04364   *         in datasheet must be shifted to the left before calling the interface
04365   * @retval HAL status
04366   */
04367 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
04368 {
04369   if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER)
04370   {
04371     /* Process Locked */
04372     __HAL_LOCK(hfmpi2c);
04373 
04374     /* Disable Interrupts and Store Previous state */
04375     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
04376     {
04377       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
04378       hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
04379     }
04380     else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
04381     {
04382       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
04383       hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
04384     }
04385     else
04386     {
04387       /* Do nothing */
04388     }
04389 
04390     /* Set State at HAL_FMPI2C_STATE_ABORT */
04391     hfmpi2c->State = HAL_FMPI2C_STATE_ABORT;
04392 
04393     /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */
04394     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
04395     FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP);
04396 
04397     /* Process Unlocked */
04398     __HAL_UNLOCK(hfmpi2c);
04399 
04400     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
04401               to avoid the risk of FMPI2C interrupt handle execution before current
04402               process unlock */
04403     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
04404 
04405     return HAL_OK;
04406   }
04407   else
04408   {
04409     /* Wrong usage of abort function */
04410     /* This function should be used only in case of abort monitored by master device */
04411     return HAL_ERROR;
04412   }
04413 }
04414 
04415 /**
04416   * @}
04417   */
04418 
04419 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
04420   * @{
04421   */
04422 
04423 /**
04424   * @brief  This function handles FMPI2C event interrupt request.
04425   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04426   *                the configuration information for the specified FMPI2C.
04427   * @retval None
04428   */
04429 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
04430 {
04431   /* Get current IT Flags and IT sources value */
04432   uint32_t itflags   = READ_REG(hfmpi2c->Instance->ISR);
04433   uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
04434 
04435   /* FMPI2C events treatment -------------------------------------*/
04436   if (hfmpi2c->XferISR != NULL)
04437   {
04438     hfmpi2c->XferISR(hfmpi2c, itflags, itsources);
04439   }
04440 }
04441 
04442 /**
04443   * @brief  This function handles FMPI2C error interrupt request.
04444   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04445   *                the configuration information for the specified FMPI2C.
04446   * @retval None
04447   */
04448 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
04449 {
04450   uint32_t itflags   = READ_REG(hfmpi2c->Instance->ISR);
04451   uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
04452   uint32_t tmperror;
04453 
04454   /* FMPI2C Bus error interrupt occurred ------------------------------------*/
04455   if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_BERR) != RESET) && \
04456     (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
04457   {
04458     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
04459 
04460     /* Clear BERR flag */
04461     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
04462   }
04463 
04464   /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
04465   if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_OVR) != RESET) && \
04466     (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
04467   {
04468     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
04469 
04470     /* Clear OVR flag */
04471     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
04472   }
04473 
04474   /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
04475   if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_ARLO) != RESET) && \
04476     (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
04477   {
04478     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
04479 
04480     /* Clear ARLO flag */
04481     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
04482   }
04483 
04484   /* Store current volatile hfmpi2c->ErrorCode, misra rule */
04485   tmperror = hfmpi2c->ErrorCode;
04486 
04487   /* Call the Error Callback in case of Error detected */
04488   if ((tmperror & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) !=  HAL_FMPI2C_ERROR_NONE)
04489   {
04490     FMPI2C_ITError(hfmpi2c, tmperror);
04491   }
04492 }
04493 
04494 /**
04495   * @brief  Master Tx Transfer completed callback.
04496   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04497   *                the configuration information for the specified FMPI2C.
04498   * @retval None
04499   */
04500 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04501 {
04502   /* Prevent unused argument(s) compilation warning */
04503   UNUSED(hfmpi2c);
04504 
04505   /* NOTE : This function should not be modified, when the callback is needed,
04506             the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file
04507    */
04508 }
04509 
04510 /**
04511   * @brief  Master Rx Transfer completed callback.
04512   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04513   *                the configuration information for the specified FMPI2C.
04514   * @retval None
04515   */
04516 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04517 {
04518   /* Prevent unused argument(s) compilation warning */
04519   UNUSED(hfmpi2c);
04520 
04521   /* NOTE : This function should not be modified, when the callback is needed,
04522             the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file
04523    */
04524 }
04525 
04526 /** @brief  Slave Tx Transfer completed callback.
04527   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04528   *                the configuration information for the specified FMPI2C.
04529   * @retval None
04530   */
04531 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04532 {
04533   /* Prevent unused argument(s) compilation warning */
04534   UNUSED(hfmpi2c);
04535 
04536   /* NOTE : This function should not be modified, when the callback is needed,
04537             the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file
04538    */
04539 }
04540 
04541 /**
04542   * @brief  Slave Rx Transfer completed callback.
04543   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04544   *                the configuration information for the specified FMPI2C.
04545   * @retval None
04546   */
04547 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04548 {
04549   /* Prevent unused argument(s) compilation warning */
04550   UNUSED(hfmpi2c);
04551 
04552   /* NOTE : This function should not be modified, when the callback is needed,
04553             the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file
04554    */
04555 }
04556 
04557 /**
04558   * @brief  Slave Address Match callback.
04559   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04560   *                the configuration information for the specified FMPI2C.
04561   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION
04562   * @param  AddrMatchCode Address Match Code
04563   * @retval None
04564   */
04565 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
04566 {
04567   /* Prevent unused argument(s) compilation warning */
04568   UNUSED(hfmpi2c);
04569   UNUSED(TransferDirection);
04570   UNUSED(AddrMatchCode);
04571 
04572   /* NOTE : This function should not be modified, when the callback is needed,
04573             the HAL_FMPI2C_AddrCallback() could be implemented in the user file
04574    */
04575 }
04576 
04577 /**
04578   * @brief  Listen Complete callback.
04579   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04580   *                the configuration information for the specified FMPI2C.
04581   * @retval None
04582   */
04583 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04584 {
04585   /* Prevent unused argument(s) compilation warning */
04586   UNUSED(hfmpi2c);
04587 
04588   /* NOTE : This function should not be modified, when the callback is needed,
04589             the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file
04590    */
04591 }
04592 
04593 /**
04594   * @brief  Memory Tx Transfer completed callback.
04595   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04596   *                the configuration information for the specified FMPI2C.
04597   * @retval None
04598   */
04599 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04600 {
04601   /* Prevent unused argument(s) compilation warning */
04602   UNUSED(hfmpi2c);
04603 
04604   /* NOTE : This function should not be modified, when the callback is needed,
04605             the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file
04606    */
04607 }
04608 
04609 /**
04610   * @brief  Memory Rx Transfer completed callback.
04611   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04612   *                the configuration information for the specified FMPI2C.
04613   * @retval None
04614   */
04615 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04616 {
04617   /* Prevent unused argument(s) compilation warning */
04618   UNUSED(hfmpi2c);
04619 
04620   /* NOTE : This function should not be modified, when the callback is needed,
04621             the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file
04622    */
04623 }
04624 
04625 /**
04626   * @brief  FMPI2C error callback.
04627   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04628   *                the configuration information for the specified FMPI2C.
04629   * @retval None
04630   */
04631 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04632 {
04633   /* Prevent unused argument(s) compilation warning */
04634   UNUSED(hfmpi2c);
04635 
04636   /* NOTE : This function should not be modified, when the callback is needed,
04637             the HAL_FMPI2C_ErrorCallback could be implemented in the user file
04638    */
04639 }
04640 
04641 /**
04642   * @brief  FMPI2C abort callback.
04643   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04644   *                the configuration information for the specified FMPI2C.
04645   * @retval None
04646   */
04647 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
04648 {
04649   /* Prevent unused argument(s) compilation warning */
04650   UNUSED(hfmpi2c);
04651 
04652   /* NOTE : This function should not be modified, when the callback is needed,
04653             the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file
04654    */
04655 }
04656 
04657 /**
04658   * @}
04659   */
04660 
04661 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
04662   *  @brief   Peripheral State, Mode and Error functions
04663   *
04664 @verbatim
04665  ===============================================================================
04666             ##### Peripheral State, Mode and Error functions #####
04667  ===============================================================================
04668     [..]
04669     This subsection permit to get in run-time the status of the peripheral
04670     and the data flow.
04671 
04672 @endverbatim
04673   * @{
04674   */
04675 
04676 /**
04677   * @brief  Return the FMPI2C handle state.
04678   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04679   *                the configuration information for the specified FMPI2C.
04680   * @retval HAL state
04681   */
04682 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c)
04683 {
04684   /* Return FMPI2C handle state */
04685   return hfmpi2c->State;
04686 }
04687 
04688 /**
04689   * @brief  Returns the FMPI2C Master, Slave, Memory or no mode.
04690   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04691   *         the configuration information for FMPI2C module
04692   * @retval HAL mode
04693   */
04694 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c)
04695 {
04696   return hfmpi2c->Mode;
04697 }
04698 
04699 /**
04700   * @brief  Return the FMPI2C error code.
04701   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04702   *              the configuration information for the specified FMPI2C.
04703   * @retval FMPI2C Error Code
04704   */
04705 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c)
04706 {
04707   return hfmpi2c->ErrorCode;
04708 }
04709 
04710 /**
04711   * @}
04712   */
04713 
04714 /**
04715   * @}
04716   */
04717 
04718 /** @addtogroup FMPI2C_Private_Functions
04719   * @{
04720   */
04721 
04722 /**
04723   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
04724   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04725   *                the configuration information for the specified FMPI2C.
04726   * @param  ITFlags Interrupt flags to handle.
04727   * @param  ITSources Interrupt sources enabled.
04728   * @retval HAL status
04729   */
04730 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
04731                                               uint32_t ITSources)
04732 {
04733   uint16_t devaddress;
04734   uint32_t tmpITFlags = ITFlags;
04735 
04736   /* Process Locked */
04737   __HAL_LOCK(hfmpi2c);
04738 
04739   if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
04740     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
04741   {
04742     /* Clear NACK Flag */
04743     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04744 
04745     /* Set corresponding Error Code */
04746     /* No need to generate STOP, it is automatically done */
04747     /* Error callback will be send during stop flag treatment */
04748     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
04749 
04750     /* Flush TX register */
04751     FMPI2C_Flush_TXDR(hfmpi2c);
04752   }
04753   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
04754            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
04755   {
04756     /* Remove RXNE flag on temporary variable as read done */
04757     tmpITFlags &= ~FMPI2C_FLAG_RXNE;
04758 
04759     /* Read data from RXDR */
04760     *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
04761 
04762     /* Increment Buffer pointer */
04763     hfmpi2c->pBuffPtr++;
04764 
04765     hfmpi2c->XferSize--;
04766     hfmpi2c->XferCount--;
04767   }
04768   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
04769            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
04770   {
04771     /* Write data to TXDR */
04772     hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
04773 
04774     /* Increment Buffer pointer */
04775     hfmpi2c->pBuffPtr++;
04776 
04777     hfmpi2c->XferSize--;
04778     hfmpi2c->XferCount--;
04779   }
04780   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TCR) != RESET) && \
04781            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
04782   {
04783     if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
04784     {
04785       devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
04786 
04787       if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
04788       {
04789         hfmpi2c->XferSize = MAX_NBYTE_SIZE;
04790         FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
04791       }
04792       else
04793       {
04794         hfmpi2c->XferSize = hfmpi2c->XferCount;
04795         if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
04796         {
04797           FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
04798                                 hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP);
04799         }
04800         else
04801         {
04802           FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
04803                                 FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
04804         }
04805       }
04806     }
04807     else
04808     {
04809       /* Call TxCpltCallback() if no stop mode is set */
04810       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
04811       {
04812         /* Call FMPI2C Master Sequential complete process */
04813         FMPI2C_ITMasterSeqCplt(hfmpi2c);
04814       }
04815       else
04816       {
04817         /* Wrong size Status regarding TCR flag event */
04818         /* Call the corresponding callback to inform upper layer of End of Transfer */
04819         FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
04820       }
04821     }
04822   }
04823   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) != RESET) && \
04824            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
04825   {
04826     if (hfmpi2c->XferCount == 0U)
04827     {
04828       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
04829       {
04830         /* Generate a stop condition in case of no transfer option */
04831         if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
04832         {
04833           /* Generate Stop */
04834           hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
04835         }
04836         else
04837         {
04838           /* Call FMPI2C Master Sequential complete process */
04839           FMPI2C_ITMasterSeqCplt(hfmpi2c);
04840         }
04841       }
04842     }
04843     else
04844     {
04845       /* Wrong size Status regarding TC flag event */
04846       /* Call the corresponding callback to inform upper layer of End of Transfer */
04847       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
04848     }
04849   }
04850   else
04851   {
04852     /* Nothing to do */
04853   }
04854 
04855   if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
04856     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
04857   {
04858     /* Call FMPI2C Master complete process */
04859     FMPI2C_ITMasterCplt(hfmpi2c, tmpITFlags);
04860   }
04861 
04862   /* Process Unlocked */
04863   __HAL_UNLOCK(hfmpi2c);
04864 
04865   return HAL_OK;
04866 }
04867 
04868 /**
04869   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
04870   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04871   *                the configuration information for the specified FMPI2C.
04872   * @param  ITFlags Interrupt flags to handle.
04873   * @param  ITSources Interrupt sources enabled.
04874   * @retval HAL status
04875   */
04876 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
04877                                              uint32_t ITSources)
04878 {
04879   uint32_t tmpoptions = hfmpi2c->XferOptions;
04880   uint32_t tmpITFlags = ITFlags;
04881 
04882   /* Process locked */
04883   __HAL_LOCK(hfmpi2c);
04884 
04885   /* Check if STOPF is set */
04886   if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
04887     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
04888   {
04889     /* Call FMPI2C Slave complete process */
04890     FMPI2C_ITSlaveCplt(hfmpi2c, tmpITFlags);
04891   }
04892 
04893   if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
04894     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
04895   {
04896     /* Check that FMPI2C transfer finished */
04897     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
04898     /* Mean XferCount == 0*/
04899     /* So clear Flag NACKF only */
04900     if (hfmpi2c->XferCount == 0U)
04901     {
04902       if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
04903         /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
04904            Warning[Pa134]: left and right operands are identical */
04905       {
04906         /* Call FMPI2C Listen complete process */
04907         FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
04908       }
04909       else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
04910       {
04911         /* Clear NACK Flag */
04912         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04913 
04914         /* Flush TX register */
04915         FMPI2C_Flush_TXDR(hfmpi2c);
04916 
04917         /* Last Byte is Transmitted */
04918         /* Call FMPI2C Slave Sequential complete process */
04919         FMPI2C_ITSlaveSeqCplt(hfmpi2c);
04920       }
04921       else
04922       {
04923         /* Clear NACK Flag */
04924         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04925       }
04926     }
04927     else
04928     {
04929       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
04930       /* Clear NACK Flag */
04931       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04932 
04933       /* Set ErrorCode corresponding to a Non-Acknowledge */
04934       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
04935 
04936       if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
04937       {
04938         /* Call the corresponding callback to inform upper layer of End of Transfer */
04939         FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
04940       }
04941     }
04942   }
04943   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
04944            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
04945   {
04946     if (hfmpi2c->XferCount > 0U)
04947     {
04948       /* Read data from RXDR */
04949       *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
04950 
04951       /* Increment Buffer pointer */
04952       hfmpi2c->pBuffPtr++;
04953 
04954       hfmpi2c->XferSize--;
04955       hfmpi2c->XferCount--;
04956     }
04957 
04958     if ((hfmpi2c->XferCount == 0U) && \
04959         (tmpoptions != FMPI2C_NO_OPTION_FRAME))
04960     {
04961       /* Call FMPI2C Slave Sequential complete process */
04962       FMPI2C_ITSlaveSeqCplt(hfmpi2c);
04963     }
04964   }
04965   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
04966            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
04967   {
04968     FMPI2C_ITAddrCplt(hfmpi2c, tmpITFlags);
04969   }
04970   else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
04971            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
04972   {
04973     /* Write data to TXDR only if XferCount not reach "0" */
04974     /* A TXIS flag can be set, during STOP treatment      */
04975     /* Check if all Data have already been sent */
04976     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
04977     if (hfmpi2c->XferCount > 0U)
04978     {
04979       /* Write data to TXDR */
04980       hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
04981 
04982       /* Increment Buffer pointer */
04983       hfmpi2c->pBuffPtr++;
04984 
04985       hfmpi2c->XferCount--;
04986       hfmpi2c->XferSize--;
04987     }
04988     else
04989     {
04990       if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
04991       {
04992         /* Last Byte is Transmitted */
04993         /* Call FMPI2C Slave Sequential complete process */
04994         FMPI2C_ITSlaveSeqCplt(hfmpi2c);
04995       }
04996     }
04997   }
04998   else
04999   {
05000     /* Nothing to do */
05001   }
05002 
05003   /* Process Unlocked */
05004   __HAL_UNLOCK(hfmpi2c);
05005 
05006   return HAL_OK;
05007 }
05008 
05009 /**
05010   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
05011   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
05012   *                the configuration information for the specified FMPI2C.
05013   * @param  ITFlags Interrupt flags to handle.
05014   * @param  ITSources Interrupt sources enabled.
05015   * @retval HAL status
05016   */
05017 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
05018                                                uint32_t ITSources)
05019 {
05020   uint16_t devaddress;
05021   uint32_t xfermode;
05022 
05023   /* Process Locked */
05024   __HAL_LOCK(hfmpi2c);
05025 
05026   if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
05027     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
05028   {
05029     /* Clear NACK Flag */
05030     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05031 
05032     /* Set corresponding Error Code */
05033     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
05034 
05035     /* No need to generate STOP, it is automatically done */
05036     /* But enable STOP interrupt, to treat it */
05037     /* Error callback will be send during stop flag treatment */
05038     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
05039 
05040     /* Flush TX register */
05041     FMPI2C_Flush_TXDR(hfmpi2c);
05042   }
05043   else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TCR) != RESET) && \
05044     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
05045   {
05046     /* Disable TC interrupt */
05047     __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI);
05048 
05049     if (hfmpi2c->XferCount != 0U)
05050     {
05051       /* Recover Slave address */
05052       devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
05053 
05054       /* Prepare the new XferSize to transfer */
05055       if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
05056       {
05057         hfmpi2c->XferSize = MAX_NBYTE_SIZE;
05058         xfermode = FMPI2C_RELOAD_MODE;
05059       }
05060       else
05061       {
05062         hfmpi2c->XferSize = hfmpi2c->XferCount;
05063         if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
05064         {
05065           xfermode = hfmpi2c->XferOptions;
05066         }
05067         else
05068         {
05069           xfermode = FMPI2C_AUTOEND_MODE;
05070         }
05071       }
05072 
05073       /* Set the new XferSize in Nbytes register */
05074       FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
05075 
05076       /* Update XferCount value */
05077       hfmpi2c->XferCount -= hfmpi2c->XferSize;
05078 
05079       /* Enable DMA Request */
05080       if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
05081       {
05082         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
05083       }
05084       else
05085       {
05086         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
05087       }
05088     }
05089     else
05090     {
05091       /* Call TxCpltCallback() if no stop mode is set */
05092       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
05093       {
05094         /* Call FMPI2C Master Sequential complete process */
05095         FMPI2C_ITMasterSeqCplt(hfmpi2c);
05096       }
05097       else
05098       {
05099         /* Wrong size Status regarding TCR flag event */
05100         /* Call the corresponding callback to inform upper layer of End of Transfer */
05101         FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
05102       }
05103     }
05104   }
05105   else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TC) != RESET) && \
05106     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
05107   {
05108     if (hfmpi2c->XferCount == 0U)
05109     {
05110       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
05111       {
05112         /* Generate a stop condition in case of no transfer option */
05113         if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
05114         {
05115           /* Generate Stop */
05116           hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
05117         }
05118         else
05119         {
05120           /* Call FMPI2C Master Sequential complete process */
05121           FMPI2C_ITMasterSeqCplt(hfmpi2c);
05122         }
05123       }
05124     }
05125     else
05126     {
05127       /* Wrong size Status regarding TC flag event */
05128       /* Call the corresponding callback to inform upper layer of End of Transfer */
05129       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
05130     }
05131   }
05132   else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
05133            (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
05134   {
05135     /* Call FMPI2C Master complete process */
05136     FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
05137   }
05138   else
05139   {
05140     /* Nothing to do */
05141   }
05142 
05143   /* Process Unlocked */
05144   __HAL_UNLOCK(hfmpi2c);
05145 
05146   return HAL_OK;
05147 }
05148 
05149 /**
05150   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
05151   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
05152   *                the configuration information for the specified FMPI2C.
05153   * @param  ITFlags Interrupt flags to handle.
05154   * @param  ITSources Interrupt sources enabled.
05155   * @retval HAL status
05156   */
05157 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
05158                                               uint32_t ITSources)
05159 {
05160   uint32_t tmpoptions = hfmpi2c->XferOptions;
05161   uint32_t treatdmanack = 0U;
05162   HAL_FMPI2C_StateTypeDef tmpstate;
05163 
05164   /* Process locked */
05165   __HAL_LOCK(hfmpi2c);
05166 
05167   /* Check if STOPF is set */
05168   if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
05169     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
05170   {
05171     /* Call FMPI2C Slave complete process */
05172     FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
05173   }
05174 
05175   if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
05176     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
05177   {
05178     /* Check that FMPI2C transfer finished */
05179     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
05180     /* Mean XferCount == 0 */
05181     /* So clear Flag NACKF only */
05182     if ((FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET) ||
05183         (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET))
05184     {
05185       /* Split check of hdmarx, for MISRA compliance */
05186       if (hfmpi2c->hdmarx != NULL)
05187       {
05188         if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET)
05189         {
05190           if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U)
05191           {
05192             treatdmanack = 1U;
05193           }
05194         }
05195       }
05196 
05197       /* Split check of hdmatx, for MISRA compliance  */
05198       if (hfmpi2c->hdmatx != NULL)
05199       {
05200         if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET)
05201         {
05202           if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U)
05203           {
05204             treatdmanack = 1U;
05205           }
05206         }
05207       }
05208 
05209       if (treatdmanack == 1U)
05210       {
05211         if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
05212           /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
05213              Warning[Pa134]: left and right operands are identical */
05214         {
05215           /* Call FMPI2C Listen complete process */
05216           FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
05217         }
05218         else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
05219         {
05220           /* Clear NACK Flag */
05221           __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05222 
05223           /* Flush TX register */
05224           FMPI2C_Flush_TXDR(hfmpi2c);
05225 
05226           /* Last Byte is Transmitted */
05227           /* Call FMPI2C Slave Sequential complete process */
05228           FMPI2C_ITSlaveSeqCplt(hfmpi2c);
05229         }
05230         else
05231         {
05232           /* Clear NACK Flag */
05233           __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05234         }
05235       }
05236       else
05237       {
05238         /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
05239         /* Clear NACK Flag */
05240         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05241 
05242         /* Set ErrorCode corresponding to a Non-Acknowledge */
05243         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
05244 
05245         /* Store current hfmpi2c->State, solve MISRA2012-Rule-13.5 */
05246         tmpstate = hfmpi2c->State;
05247 
05248         if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
05249         {
05250           if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
05251           {
05252             hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
05253           }
05254           else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
05255           {
05256             hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
05257           }
05258           else
05259           {
05260             /* Do nothing */
05261           }
05262 
05263           /* Call the corresponding callback to inform upper layer of End of Transfer */
05264           FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
05265         }
05266       }
05267     }
05268     else
05269     {
05270       /* Only Clear NACK Flag, no DMA treatment is pending */
05271       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05272     }
05273   }
05274   else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
05275     (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
05276   {
05277     FMPI2C_ITAddrCplt(hfmpi2c, ITFlags);
05278   }
05279   else
05280   {
05281     /* Nothing to do */
05282   }
05283 
05284   /* Process Unlocked */
05285   __HAL_UNLOCK(hfmpi2c);
05286 
05287   return HAL_OK;
05288 }
05289 
05290 /**
05291   * @brief  Master sends target device address followed by internal memory address for write request.
05292   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
05293   *                the configuration information for the specified FMPI2C.
05294   * @param  DevAddress Target device address: The device 7 bits address value
05295   *         in datasheet must be shifted to the left before calling the interface
05296   * @param  MemAddress Internal memory address
05297   * @param  MemAddSize Size of internal memory address
05298   * @param  Timeout Timeout duration
05299   * @param  Tickstart Tick start value
05300   * @retval HAL status
05301   */
05302 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
05303                                                    uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
05304                                                    uint32_t Tickstart)
05305 {
05306   FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
05307 
05308   /* Wait until TXIS flag is set */
05309   if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
05310   {
05311     return HAL_ERROR;
05312   }
05313 
05314   /* If Memory address size is 8Bit */
05315   if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
05316   {
05317     /* Send Memory Address */
05318     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
05319   }
05320   /* If Memory address size is 16Bit */
05321   else
05322   {
05323     /* Send MSB of Memory Address */
05324     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
05325 
05326     /* Wait until TXIS flag is set */
05327     if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
05328     {
05329       return HAL_ERROR;
05330     }
05331 
05332     /* Send LSB of Memory Address */
05333     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
05334   }
05335 
05336   /* Wait until TCR flag is set */
05337   if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
05338   {
05339     return HAL_ERROR;
05340   }
05341 
05342   return HAL_OK;
05343 }
05344 
05345 /**
05346   * @brief  Master sends target device address followed by internal memory address for read request.
05347   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
05348   *                the configuration information for the specified FMPI2C.
05349   * @param  DevAddress Target device address: The device 7 bits address value
05350   *         in datasheet must be shifted to the left before calling the interface
05351   * @param  MemAddress Internal memory address
05352   * @param  MemAddSize Size of internal memory address
05353   * @param  Timeout Timeout duration
05354   * @param  Tickstart Tick start value
05355   * @retval HAL status
05356   */
05357 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
05358                                                   uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
05359                                                   uint32_t Tickstart)
05360 {
05361   FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
05362 
05363   /* Wait until TXIS flag is set */
05364   if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
05365   {
05366     return HAL_ERROR;
05367   }
05368 
05369   /* If Memory address size is 8Bit */
05370   if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
05371   {
05372     /* Send Memory Address */
05373     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
05374   }
05375   /* If Memory address size is 16Bit */
05376   else
05377   {
05378     /* Send MSB of Memory Address */
05379     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
05380 
05381     /* Wait until TXIS flag is set */
05382     if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
05383     {
05384       return HAL_ERROR;
05385     }
05386 
05387     /* Send LSB of Memory Address */
05388     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
05389   }
05390 
05391   /* Wait until TC flag is set */
05392   if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
05393   {
05394     return HAL_ERROR;
05395   }
05396 
05397   return HAL_OK;
05398 }
05399 
05400 /**
05401   * @brief  FMPI2C Address complete process callback.
05402   * @param  hfmpi2c FMPI2C handle.
05403   * @param  ITFlags Interrupt flags to handle.
05404   * @retval None
05405   */
05406 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
05407 {
05408   uint8_t transferdirection;
05409   uint16_t slaveaddrcode;
05410   uint16_t ownadd1code;
05411   uint16_t ownadd2code;
05412 
05413   /* Prevent unused argument(s) compilation warning */
05414   UNUSED(ITFlags);
05415 
05416   /* In case of Listen state, need to inform upper layer of address match code event */
05417   if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
05418   {
05419     transferdirection = FMPI2C_GET_DIR(hfmpi2c);
05420     slaveaddrcode     = FMPI2C_GET_ADDR_MATCH(hfmpi2c);
05421     ownadd1code       = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c);
05422     ownadd2code       = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c);
05423 
05424     /* If 10bits addressing mode is selected */
05425     if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
05426     {
05427       if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
05428       {
05429         slaveaddrcode = ownadd1code;
05430         hfmpi2c->AddrEventCount++;
05431         if (hfmpi2c->AddrEventCount == 2U)
05432         {
05433           /* Reset Address Event counter */
05434           hfmpi2c->AddrEventCount = 0U;
05435 
05436           /* Clear ADDR flag */
05437           __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
05438 
05439           /* Process Unlocked */
05440           __HAL_UNLOCK(hfmpi2c);
05441 
05442           /* Call Slave Addr callback */
05443 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05444           hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05445 #else
05446           HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05447 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05448         }
05449       }
05450       else
05451       {
05452         slaveaddrcode = ownadd2code;
05453 
05454         /* Disable ADDR Interrupts */
05455         FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
05456 
05457         /* Process Unlocked */
05458         __HAL_UNLOCK(hfmpi2c);
05459 
05460         /* Call Slave Addr callback */
05461 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05462         hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05463 #else
05464         HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05465 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05466       }
05467     }
05468     /* else 7 bits addressing mode is selected */
05469     else
05470     {
05471       /* Disable ADDR Interrupts */
05472       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
05473 
05474       /* Process Unlocked */
05475       __HAL_UNLOCK(hfmpi2c);
05476 
05477       /* Call Slave Addr callback */
05478 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05479       hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05480 #else
05481       HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
05482 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05483     }
05484   }
05485   /* Else clear address flag only */
05486   else
05487   {
05488     /* Clear ADDR flag */
05489     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
05490 
05491     /* Process Unlocked */
05492     __HAL_UNLOCK(hfmpi2c);
05493   }
05494 }
05495 
05496 /**
05497   * @brief  FMPI2C Master sequential complete process.
05498   * @param  hfmpi2c FMPI2C handle.
05499   * @retval None
05500   */
05501 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
05502 {
05503   /* Reset FMPI2C handle mode */
05504   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05505 
05506   /* No Generate Stop, to permit restart mode */
05507   /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */
05508   if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
05509   {
05510     hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
05511     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
05512     hfmpi2c->XferISR       = NULL;
05513 
05514     /* Disable Interrupts */
05515     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
05516 
05517     /* Process Unlocked */
05518     __HAL_UNLOCK(hfmpi2c);
05519 
05520     /* Call the corresponding callback to inform upper layer of End of Transfer */
05521 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05522     hfmpi2c->MasterTxCpltCallback(hfmpi2c);
05523 #else
05524     HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
05525 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05526   }
05527   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
05528   else
05529   {
05530     hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
05531     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
05532     hfmpi2c->XferISR       = NULL;
05533 
05534     /* Disable Interrupts */
05535     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
05536 
05537     /* Process Unlocked */
05538     __HAL_UNLOCK(hfmpi2c);
05539 
05540     /* Call the corresponding callback to inform upper layer of End of Transfer */
05541 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05542     hfmpi2c->MasterRxCpltCallback(hfmpi2c);
05543 #else
05544     HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
05545 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05546   }
05547 }
05548 
05549 /**
05550   * @brief  FMPI2C Slave sequential complete process.
05551   * @param  hfmpi2c FMPI2C handle.
05552   * @retval None
05553   */
05554 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
05555 {
05556   uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
05557 
05558   /* Reset FMPI2C handle mode */
05559   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05560 
05561   /* If a DMA is ongoing, Update handle size context */
05562   if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
05563   {
05564     /* Disable DMA Request */
05565     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
05566   }
05567   else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
05568   {
05569     /* Disable DMA Request */
05570     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
05571   }
05572   else
05573   {
05574     /* Do nothing */
05575   }
05576 
05577   if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
05578   {
05579     /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */
05580     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
05581     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
05582 
05583     /* Disable Interrupts */
05584     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
05585 
05586     /* Process Unlocked */
05587     __HAL_UNLOCK(hfmpi2c);
05588 
05589     /* Call the corresponding callback to inform upper layer of End of Transfer */
05590 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05591     hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
05592 #else
05593     HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
05594 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05595   }
05596 
05597   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
05598   {
05599     /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */
05600     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
05601     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
05602 
05603     /* Disable Interrupts */
05604     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
05605 
05606     /* Process Unlocked */
05607     __HAL_UNLOCK(hfmpi2c);
05608 
05609     /* Call the corresponding callback to inform upper layer of End of Transfer */
05610 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05611     hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
05612 #else
05613     HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
05614 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05615   }
05616   else
05617   {
05618     /* Nothing to do */
05619   }
05620 }
05621 
05622 /**
05623   * @brief  FMPI2C Master complete process.
05624   * @param  hfmpi2c FMPI2C handle.
05625   * @param  ITFlags Interrupt flags to handle.
05626   * @retval None
05627   */
05628 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
05629 {
05630   uint32_t tmperror;
05631   uint32_t tmpITFlags = ITFlags;
05632   __IO uint32_t tmpreg;
05633 
05634   /* Clear STOP Flag */
05635   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
05636 
05637   /* Disable Interrupts and Store Previous state */
05638   if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
05639   {
05640     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
05641     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
05642   }
05643   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
05644   {
05645     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
05646     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
05647   }
05648   else
05649   {
05650     /* Do nothing */
05651   }
05652 
05653   /* Clear Configuration Register 2 */
05654   FMPI2C_RESET_CR2(hfmpi2c);
05655 
05656   /* Reset handle parameters */
05657   hfmpi2c->XferISR       = NULL;
05658   hfmpi2c->XferOptions   = FMPI2C_NO_OPTION_FRAME;
05659 
05660   if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET)
05661   {
05662     /* Clear NACK Flag */
05663     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05664 
05665     /* Set acknowledge error code */
05666     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
05667   }
05668 
05669   /* Fetch Last receive data if any */
05670   if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) && (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET))
05671   {
05672     /* Read data from RXDR */
05673     tmpreg = (uint8_t)hfmpi2c->Instance->RXDR;
05674     UNUSED(tmpreg);
05675   }
05676 
05677   /* Flush TX register */
05678   FMPI2C_Flush_TXDR(hfmpi2c);
05679 
05680   /* Store current volatile hfmpi2c->ErrorCode, misra rule */
05681   tmperror = hfmpi2c->ErrorCode;
05682 
05683   /* Call the corresponding callback to inform upper layer of End of Transfer */
05684   if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) || (tmperror != HAL_FMPI2C_ERROR_NONE))
05685   {
05686     /* Call the corresponding callback to inform upper layer of End of Transfer */
05687     FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
05688   }
05689   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */
05690   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
05691   {
05692     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05693     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05694 
05695     if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
05696     {
05697       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05698 
05699       /* Process Unlocked */
05700       __HAL_UNLOCK(hfmpi2c);
05701 
05702       /* Call the corresponding callback to inform upper layer of End of Transfer */
05703 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05704       hfmpi2c->MemTxCpltCallback(hfmpi2c);
05705 #else
05706       HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
05707 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05708     }
05709     else
05710     {
05711       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05712 
05713       /* Process Unlocked */
05714       __HAL_UNLOCK(hfmpi2c);
05715 
05716       /* Call the corresponding callback to inform upper layer of End of Transfer */
05717 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05718       hfmpi2c->MasterTxCpltCallback(hfmpi2c);
05719 #else
05720       HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
05721 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05722     }
05723   }
05724   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
05725   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
05726   {
05727     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05728     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05729 
05730     if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
05731     {
05732       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05733 
05734       /* Process Unlocked */
05735       __HAL_UNLOCK(hfmpi2c);
05736 
05737       /* Call the corresponding callback to inform upper layer of End of Transfer */
05738 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05739       hfmpi2c->MemRxCpltCallback(hfmpi2c);
05740 #else
05741       HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
05742 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05743     }
05744     else
05745     {
05746       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05747 
05748       /* Process Unlocked */
05749       __HAL_UNLOCK(hfmpi2c);
05750 
05751       /* Call the corresponding callback to inform upper layer of End of Transfer */
05752 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05753       hfmpi2c->MasterRxCpltCallback(hfmpi2c);
05754 #else
05755       HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
05756 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05757     }
05758   }
05759   else
05760   {
05761     /* Nothing to do */
05762   }
05763 }
05764 
05765 /**
05766   * @brief  FMPI2C Slave complete process.
05767   * @param  hfmpi2c FMPI2C handle.
05768   * @param  ITFlags Interrupt flags to handle.
05769   * @retval None
05770   */
05771 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
05772 {
05773   uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
05774   uint32_t tmpITFlags = ITFlags;
05775   HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
05776 
05777   /* Clear STOP Flag */
05778   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
05779 
05780   /* Disable Interrupts and Store Previous state */
05781   if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
05782   {
05783     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
05784     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
05785   }
05786   else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
05787   {
05788     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
05789     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
05790   }
05791   else
05792   {
05793     /* Do nothing */
05794   }
05795 
05796   /* Disable Address Acknowledge */
05797   hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
05798 
05799   /* Clear Configuration Register 2 */
05800   FMPI2C_RESET_CR2(hfmpi2c);
05801 
05802   /* Flush TX register */
05803   FMPI2C_Flush_TXDR(hfmpi2c);
05804 
05805   /* If a DMA is ongoing, Update handle size context */
05806   if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
05807   {
05808     /* Disable DMA Request */
05809     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
05810 
05811     if (hfmpi2c->hdmatx != NULL)
05812     {
05813       hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx);
05814     }
05815   }
05816   else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
05817   {
05818     /* Disable DMA Request */
05819     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
05820 
05821     if (hfmpi2c->hdmarx != NULL)
05822     {
05823       hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx);
05824     }
05825   }
05826   else
05827   {
05828     /* Do nothing */
05829   }
05830 
05831   /* Store Last receive data if any */
05832   if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET)
05833   {
05834     /* Remove RXNE flag on temporary variable as read done */
05835     tmpITFlags &= ~FMPI2C_FLAG_RXNE;
05836 
05837     /* Read data from RXDR */
05838     *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
05839 
05840     /* Increment Buffer pointer */
05841     hfmpi2c->pBuffPtr++;
05842 
05843     if ((hfmpi2c->XferSize > 0U))
05844     {
05845       hfmpi2c->XferSize--;
05846       hfmpi2c->XferCount--;
05847     }
05848   }
05849 
05850   /* All data are not transferred, so set error code accordingly */
05851   if (hfmpi2c->XferCount != 0U)
05852   {
05853     /* Set ErrorCode corresponding to a Non-Acknowledge */
05854     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
05855   }
05856 
05857   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05858   hfmpi2c->XferISR = NULL;
05859 
05860   if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
05861   {
05862     /* Call the corresponding callback to inform upper layer of End of Transfer */
05863     FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
05864 
05865     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
05866     if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
05867     {
05868       /* Call FMPI2C Listen complete process */
05869       FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
05870     }
05871   }
05872   else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
05873   {
05874     /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
05875     FMPI2C_ITSlaveSeqCplt(hfmpi2c);
05876 
05877     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
05878     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05879     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05880 
05881     /* Process Unlocked */
05882     __HAL_UNLOCK(hfmpi2c);
05883 
05884     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
05885 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05886     hfmpi2c->ListenCpltCallback(hfmpi2c);
05887 #else
05888     HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
05889 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05890   }
05891   /* Call the corresponding callback to inform upper layer of End of Transfer */
05892   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
05893   {
05894     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05895     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05896 
05897     /* Process Unlocked */
05898     __HAL_UNLOCK(hfmpi2c);
05899 
05900     /* Call the corresponding callback to inform upper layer of End of Transfer */
05901 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05902     hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
05903 #else
05904     HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
05905 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05906   }
05907   else
05908   {
05909     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05910     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05911 
05912     /* Process Unlocked */
05913     __HAL_UNLOCK(hfmpi2c);
05914 
05915     /* Call the corresponding callback to inform upper layer of End of Transfer */
05916 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05917     hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
05918 #else
05919     HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
05920 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05921   }
05922 }
05923 
05924 /**
05925   * @brief  FMPI2C Listen complete process.
05926   * @param  hfmpi2c FMPI2C handle.
05927   * @param  ITFlags Interrupt flags to handle.
05928   * @retval None
05929   */
05930 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
05931 {
05932   /* Reset handle parameters */
05933   hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
05934   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
05935   hfmpi2c->State = HAL_FMPI2C_STATE_READY;
05936   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
05937   hfmpi2c->XferISR = NULL;
05938 
05939   /* Store Last receive data if any */
05940   if (FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_RXNE) != RESET)
05941   {
05942     /* Read data from RXDR */
05943     *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
05944 
05945     /* Increment Buffer pointer */
05946     hfmpi2c->pBuffPtr++;
05947 
05948     if ((hfmpi2c->XferSize > 0U))
05949     {
05950       hfmpi2c->XferSize--;
05951       hfmpi2c->XferCount--;
05952 
05953       /* Set ErrorCode corresponding to a Non-Acknowledge */
05954       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
05955     }
05956   }
05957 
05958   /* Disable all Interrupts*/
05959   FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
05960 
05961   /* Clear NACK Flag */
05962   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
05963 
05964   /* Process Unlocked */
05965   __HAL_UNLOCK(hfmpi2c);
05966 
05967   /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
05968 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
05969   hfmpi2c->ListenCpltCallback(hfmpi2c);
05970 #else
05971   HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
05972 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
05973 }
05974 
05975 /**
05976   * @brief  FMPI2C interrupts error process.
05977   * @param  hfmpi2c FMPI2C handle.
05978   * @param  ErrorCode Error code to handle.
05979   * @retval None
05980   */
05981 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode)
05982 {
05983   HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
05984   uint32_t tmppreviousstate;
05985 
05986   /* Reset handle parameters */
05987   hfmpi2c->Mode          = HAL_FMPI2C_MODE_NONE;
05988   hfmpi2c->XferOptions   = FMPI2C_NO_OPTION_FRAME;
05989   hfmpi2c->XferCount     = 0U;
05990 
05991   /* Set new error code */
05992   hfmpi2c->ErrorCode |= ErrorCode;
05993 
05994   /* Disable Interrupts */
05995   if ((tmpstate == HAL_FMPI2C_STATE_LISTEN)         ||
05996       (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) ||
05997       (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
05998   {
05999     /* Disable all interrupts, except interrupts related to LISTEN state */
06000     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
06001 
06002     /* keep HAL_FMPI2C_STATE_LISTEN if set */
06003     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
06004     hfmpi2c->XferISR       = FMPI2C_Slave_ISR_IT;
06005   }
06006   else
06007   {
06008     /* Disable all interrupts */
06009     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
06010 
06011     /* If state is an abort treatment on going, don't change state */
06012     /* This change will be do later */
06013     if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT)
06014     {
06015       /* Set HAL_FMPI2C_STATE_READY */
06016       hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
06017     }
06018     hfmpi2c->XferISR       = NULL;
06019   }
06020 
06021   /* Abort DMA TX transfer if any */
06022   tmppreviousstate = hfmpi2c->PreviousState;
06023   if ((hfmpi2c->hdmatx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_TX) || \
06024                                  (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_TX)))
06025   {
06026     if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
06027     {
06028       hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
06029     }
06030 
06031     if (HAL_DMA_GetState(hfmpi2c->hdmatx) != HAL_DMA_STATE_READY)
06032     {
06033       /* Set the FMPI2C DMA Abort callback :
06034        will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
06035       hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
06036 
06037       /* Process Unlocked */
06038       __HAL_UNLOCK(hfmpi2c);
06039 
06040       /* Abort DMA TX */
06041       if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
06042       {
06043         /* Call Directly XferAbortCallback function in case of error */
06044         hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
06045       }
06046     }
06047     else
06048     {
06049       FMPI2C_TreatErrorCallback(hfmpi2c);
06050     }
06051   }
06052   /* Abort DMA RX transfer if any */
06053   else if ((hfmpi2c->hdmarx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_RX) || \
06054                                       (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_RX)))
06055   {
06056     if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
06057     {
06058       hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
06059     }
06060 
06061     if (HAL_DMA_GetState(hfmpi2c->hdmarx) != HAL_DMA_STATE_READY)
06062     {
06063       /* Set the FMPI2C DMA Abort callback :
06064         will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
06065       hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
06066 
06067       /* Process Unlocked */
06068       __HAL_UNLOCK(hfmpi2c);
06069 
06070       /* Abort DMA RX */
06071       if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
06072       {
06073         /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */
06074         hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
06075       }
06076     }
06077     else
06078     {
06079       FMPI2C_TreatErrorCallback(hfmpi2c);
06080     }
06081   }
06082   else
06083   {
06084     FMPI2C_TreatErrorCallback(hfmpi2c);
06085   }
06086 }
06087 
06088 /**
06089   * @brief  FMPI2C Error callback treatment.
06090   * @param  hfmpi2c FMPI2C handle.
06091   * @retval None
06092   */
06093 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
06094 {
06095   if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
06096   {
06097     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06098     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
06099 
06100     /* Process Unlocked */
06101     __HAL_UNLOCK(hfmpi2c);
06102 
06103     /* Call the corresponding callback to inform upper layer of End of Transfer */
06104 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
06105     hfmpi2c->AbortCpltCallback(hfmpi2c);
06106 #else
06107     HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
06108 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
06109   }
06110   else
06111   {
06112     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
06113 
06114     /* Process Unlocked */
06115     __HAL_UNLOCK(hfmpi2c);
06116 
06117     /* Call the corresponding callback to inform upper layer of End of Transfer */
06118 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
06119     hfmpi2c->ErrorCallback(hfmpi2c);
06120 #else
06121     HAL_FMPI2C_ErrorCallback(hfmpi2c);
06122 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
06123   }
06124 }
06125 
06126 /**
06127   * @brief  FMPI2C Tx data register flush process.
06128   * @param  hfmpi2c FMPI2C handle.
06129   * @retval None
06130   */
06131 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c)
06132 {
06133   /* If a pending TXIS flag is set */
06134   /* Write a dummy data in TXDR to clear it */
06135   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET)
06136   {
06137     hfmpi2c->Instance->TXDR = 0x00U;
06138   }
06139 
06140   /* Flush TX register if not empty */
06141   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET)
06142   {
06143     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE);
06144   }
06145 }
06146 
06147 /**
06148   * @brief  DMA FMPI2C master transmit process complete callback.
06149   * @param  hdma DMA handle
06150   * @retval None
06151   */
06152 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
06153 {
06154   /* Derogation MISRAC2012-Rule-11.5 */
06155   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06156 
06157   /* Disable DMA Request */
06158   hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
06159 
06160   /* If last transfer, enable STOP interrupt */
06161   if (hfmpi2c->XferCount == 0U)
06162   {
06163     /* Enable STOP interrupt */
06164     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
06165   }
06166   /* else prepare a new DMA transfer and enable TCReload interrupt */
06167   else
06168   {
06169     /* Update Buffer pointer */
06170     hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
06171 
06172     /* Set the XferSize to transfer */
06173     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
06174     {
06175       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
06176     }
06177     else
06178     {
06179       hfmpi2c->XferSize = hfmpi2c->XferCount;
06180     }
06181 
06182     /* Enable the DMA stream */
06183     if (HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR,
06184                          hfmpi2c->XferSize) != HAL_OK)
06185     {
06186       /* Call the corresponding callback to inform upper layer of End of Transfer */
06187       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
06188     }
06189     else
06190     {
06191       /* Enable TC interrupts */
06192       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
06193     }
06194   }
06195 }
06196 
06197 /**
06198   * @brief  DMA FMPI2C slave transmit process complete callback.
06199   * @param  hdma DMA handle
06200   * @retval None
06201   */
06202 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
06203 {
06204   /* Derogation MISRAC2012-Rule-11.5 */
06205   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06206   uint32_t tmpoptions = hfmpi2c->XferOptions;
06207 
06208   if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
06209   {
06210     /* Disable DMA Request */
06211     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
06212 
06213     /* Last Byte is Transmitted */
06214     /* Call FMPI2C Slave Sequential complete process */
06215     FMPI2C_ITSlaveSeqCplt(hfmpi2c);
06216   }
06217   else
06218   {
06219     /* No specific action, Master fully manage the generation of STOP condition */
06220     /* Mean that this generation can arrive at any time, at the end or during DMA process */
06221     /* So STOP condition should be manage through Interrupt treatment */
06222   }
06223 }
06224 
06225 /**
06226   * @brief DMA FMPI2C master receive process complete callback.
06227   * @param  hdma DMA handle
06228   * @retval None
06229   */
06230 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
06231 {
06232   /* Derogation MISRAC2012-Rule-11.5 */
06233   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06234 
06235   /* Disable DMA Request */
06236   hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
06237 
06238   /* If last transfer, enable STOP interrupt */
06239   if (hfmpi2c->XferCount == 0U)
06240   {
06241     /* Enable STOP interrupt */
06242     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
06243   }
06244   /* else prepare a new DMA transfer and enable TCReload interrupt */
06245   else
06246   {
06247     /* Update Buffer pointer */
06248     hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
06249 
06250     /* Set the XferSize to transfer */
06251     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
06252     {
06253       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
06254     }
06255     else
06256     {
06257       hfmpi2c->XferSize = hfmpi2c->XferCount;
06258     }
06259 
06260     /* Enable the DMA stream */
06261     if (HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr,
06262                          hfmpi2c->XferSize) != HAL_OK)
06263     {
06264       /* Call the corresponding callback to inform upper layer of End of Transfer */
06265       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
06266     }
06267     else
06268     {
06269       /* Enable TC interrupts */
06270       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
06271     }
06272   }
06273 }
06274 
06275 /**
06276   * @brief  DMA FMPI2C slave receive process complete callback.
06277   * @param  hdma DMA handle
06278   * @retval None
06279   */
06280 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
06281 {
06282   /* Derogation MISRAC2012-Rule-11.5 */
06283   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06284   uint32_t tmpoptions = hfmpi2c->XferOptions;
06285 
06286   if ((__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U) && \
06287       (tmpoptions != FMPI2C_NO_OPTION_FRAME))
06288   {
06289     /* Disable DMA Request */
06290     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
06291 
06292     /* Call FMPI2C Slave Sequential complete process */
06293     FMPI2C_ITSlaveSeqCplt(hfmpi2c);
06294   }
06295   else
06296   {
06297     /* No specific action, Master fully manage the generation of STOP condition */
06298     /* Mean that this generation can arrive at any time, at the end or during DMA process */
06299     /* So STOP condition should be manage through Interrupt treatment */
06300   }
06301 }
06302 
06303 /**
06304   * @brief  DMA FMPI2C communication error callback.
06305   * @param hdma DMA handle
06306   * @retval None
06307   */
06308 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
06309 {
06310   uint32_t treatdmaerror = 0U;
06311   /* Derogation MISRAC2012-Rule-11.5 */
06312   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06313 
06314   if (hfmpi2c->hdmatx != NULL)
06315   {
06316     if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U)
06317     {
06318       treatdmaerror = 1U;
06319     }
06320   }
06321 
06322   if (hfmpi2c->hdmarx != NULL)
06323   {
06324     if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U)
06325     {
06326       treatdmaerror = 1U;
06327     }
06328   }
06329 
06330   /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */
06331   if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U))
06332   {
06333     /* Disable Acknowledge */
06334     hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
06335 
06336     /* Call the corresponding callback to inform upper layer of End of Transfer */
06337     FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
06338   }
06339 }
06340 
06341 /**
06342   * @brief DMA FMPI2C communication abort callback
06343   *        (To be called at end of DMA Abort procedure).
06344   * @param hdma DMA handle.
06345   * @retval None
06346   */
06347 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma)
06348 {
06349   /* Derogation MISRAC2012-Rule-11.5 */
06350   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
06351 
06352   /* Reset AbortCpltCallback */
06353   if (hfmpi2c->hdmatx != NULL)
06354   {
06355     hfmpi2c->hdmatx->XferAbortCallback = NULL;
06356   }
06357   if (hfmpi2c->hdmarx != NULL)
06358   {
06359     hfmpi2c->hdmarx->XferAbortCallback = NULL;
06360   }
06361 
06362   FMPI2C_TreatErrorCallback(hfmpi2c);
06363 }
06364 
06365 /**
06366   * @brief  This function handles FMPI2C Communication Timeout.
06367   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06368   *                the configuration information for the specified FMPI2C.
06369   * @param  Flag Specifies the FMPI2C flag to check.
06370   * @param  Status The new Flag status (SET or RESET).
06371   * @param  Timeout Timeout duration
06372   * @param  Tickstart Tick start value
06373   * @retval HAL status
06374   */
06375 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
06376                                                     uint32_t Timeout, uint32_t Tickstart)
06377 {
06378   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status)
06379   {
06380     /* Check for the Timeout */
06381     if (Timeout != HAL_MAX_DELAY)
06382     {
06383       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
06384       {
06385         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
06386         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06387         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06388 
06389         /* Process Unlocked */
06390         __HAL_UNLOCK(hfmpi2c);
06391         return HAL_ERROR;
06392       }
06393     }
06394   }
06395   return HAL_OK;
06396 }
06397 
06398 /**
06399   * @brief  This function handles FMPI2C Communication Timeout for specific usage of TXIS flag.
06400   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06401   *                the configuration information for the specified FMPI2C.
06402   * @param  Timeout Timeout duration
06403   * @param  Tickstart Tick start value
06404   * @retval HAL status
06405   */
06406 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
06407                                                            uint32_t Tickstart)
06408 {
06409   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
06410   {
06411     /* Check if a NACK is detected */
06412     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
06413     {
06414       return HAL_ERROR;
06415     }
06416 
06417     /* Check for the Timeout */
06418     if (Timeout != HAL_MAX_DELAY)
06419     {
06420       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
06421       {
06422         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
06423         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06424         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06425 
06426         /* Process Unlocked */
06427         __HAL_UNLOCK(hfmpi2c);
06428 
06429         return HAL_ERROR;
06430       }
06431     }
06432   }
06433   return HAL_OK;
06434 }
06435 
06436 /**
06437   * @brief  This function handles FMPI2C Communication Timeout for specific usage of STOP flag.
06438   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06439   *                the configuration information for the specified FMPI2C.
06440   * @param  Timeout Timeout duration
06441   * @param  Tickstart Tick start value
06442   * @retval HAL status
06443   */
06444 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
06445                                                            uint32_t Tickstart)
06446 {
06447   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
06448   {
06449     /* Check if a NACK is detected */
06450     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
06451     {
06452       return HAL_ERROR;
06453     }
06454 
06455     /* Check for the Timeout */
06456     if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
06457     {
06458       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
06459       hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06460       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06461 
06462       /* Process Unlocked */
06463       __HAL_UNLOCK(hfmpi2c);
06464 
06465       return HAL_ERROR;
06466     }
06467   }
06468   return HAL_OK;
06469 }
06470 
06471 /**
06472   * @brief  This function handles FMPI2C Communication Timeout for specific usage of RXNE flag.
06473   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06474   *                the configuration information for the specified FMPI2C.
06475   * @param  Timeout Timeout duration
06476   * @param  Tickstart Tick start value
06477   * @retval HAL status
06478   */
06479 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
06480                                                            uint32_t Tickstart)
06481 {
06482   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET)
06483   {
06484     /* Check if a NACK is detected */
06485     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
06486     {
06487       return HAL_ERROR;
06488     }
06489 
06490     /* Check if a STOPF is detected */
06491     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
06492     {
06493       /* Check if an RXNE is pending */
06494       /* Store Last receive data if any */
06495       if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U))
06496       {
06497         /* Return HAL_OK */
06498         /* The Reading of data from RXDR will be done in caller function */
06499         return HAL_OK;
06500       }
06501       else
06502       {
06503         /* Clear STOP Flag */
06504         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
06505 
06506         /* Clear Configuration Register 2 */
06507         FMPI2C_RESET_CR2(hfmpi2c);
06508 
06509         hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
06510         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06511         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06512 
06513         /* Process Unlocked */
06514         __HAL_UNLOCK(hfmpi2c);
06515 
06516         return HAL_ERROR;
06517       }
06518     }
06519 
06520     /* Check for the Timeout */
06521     if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
06522     {
06523       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
06524       hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06525 
06526       /* Process Unlocked */
06527       __HAL_UNLOCK(hfmpi2c);
06528 
06529       return HAL_ERROR;
06530     }
06531   }
06532   return HAL_OK;
06533 }
06534 
06535 /**
06536   * @brief  This function handles Acknowledge failed detection during an FMPI2C Communication.
06537   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06538   *                the configuration information for the specified FMPI2C.
06539   * @param  Timeout Timeout duration
06540   * @param  Tickstart Tick start value
06541   * @retval HAL status
06542   */
06543 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
06544 {
06545   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
06546   {
06547     /* In case of Soft End condition, generate the STOP condition */
06548     if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
06549     {
06550       /* Generate Stop */
06551       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
06552     }
06553     /* Wait until STOP Flag is reset */
06554     /* AutoEnd should be initiate after AF */
06555     while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
06556     {
06557       /* Check for the Timeout */
06558       if (Timeout != HAL_MAX_DELAY)
06559       {
06560         if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
06561         {
06562           hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
06563           hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06564           hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06565 
06566           /* Process Unlocked */
06567           __HAL_UNLOCK(hfmpi2c);
06568 
06569           return HAL_ERROR;
06570         }
06571       }
06572     }
06573 
06574     /* Clear NACKF Flag */
06575     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
06576 
06577     /* Clear STOP Flag */
06578     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
06579 
06580     /* Flush TX register */
06581     FMPI2C_Flush_TXDR(hfmpi2c);
06582 
06583     /* Clear Configuration Register 2 */
06584     FMPI2C_RESET_CR2(hfmpi2c);
06585 
06586     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
06587     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
06588     hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
06589 
06590     /* Process Unlocked */
06591     __HAL_UNLOCK(hfmpi2c);
06592 
06593     return HAL_ERROR;
06594   }
06595   return HAL_OK;
06596 }
06597 
06598 /**
06599   * @brief  Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
06600   * @param  hfmpi2c FMPI2C handle.
06601   * @param  DevAddress Specifies the slave address to be programmed.
06602   * @param  Size Specifies the number of bytes to be programmed.
06603   *   This parameter must be a value between 0 and 255.
06604   * @param  Mode New state of the FMPI2C START condition generation.
06605   *   This parameter can be one of the following values:
06606   *     @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode .
06607   *     @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode.
06608   *     @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode.
06609   * @param  Request New state of the FMPI2C START condition generation.
06610   *   This parameter can be one of the following values:
06611   *     @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition.
06612   *     @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
06613   *     @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request.
06614   *     @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request.
06615   * @retval None
06616   */
06617 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
06618                                uint32_t Request)
06619 {
06620   /* Check the parameters */
06621   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
06622   assert_param(IS_TRANSFER_MODE(Mode));
06623   assert_param(IS_TRANSFER_REQUEST(Request));
06624 
06625   /* update CR2 register */
06626   MODIFY_REG(hfmpi2c->Instance->CR2,
06627              ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
06628                (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | \
06629                  FMPI2C_CR2_START | FMPI2C_CR2_STOP)), \
06630              (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
06631                         (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
06632                         (uint32_t)Mode | (uint32_t)Request));
06633 }
06634 
06635 /**
06636   * @brief  Manage the enabling of Interrupts.
06637   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06638   *                the configuration information for the specified FMPI2C.
06639   * @param  InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
06640   * @retval None
06641   */
06642 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
06643 {
06644   uint32_t tmpisr = 0U;
06645 
06646   if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \
06647       (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA))
06648   {
06649     if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
06650     {
06651       /* Enable ERR, STOP, NACK and ADDR interrupts */
06652       tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
06653     }
06654 
06655     if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
06656     {
06657       /* Enable ERR and NACK interrupts */
06658       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
06659     }
06660 
06661     if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
06662     {
06663       /* Enable STOP interrupts */
06664       tmpisr |= (FMPI2C_IT_STOPI | FMPI2C_IT_TCI);
06665     }
06666 
06667     if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
06668     {
06669       /* Enable TC interrupts */
06670       tmpisr |= FMPI2C_IT_TCI;
06671     }
06672   }
06673   else
06674   {
06675     if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
06676     {
06677       /* Enable ERR, STOP, NACK, and ADDR interrupts */
06678       tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
06679     }
06680 
06681     if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
06682     {
06683       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
06684       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
06685     }
06686 
06687     if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
06688     {
06689       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
06690       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
06691     }
06692 
06693     if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
06694     {
06695       /* Enable STOP interrupts */
06696       tmpisr |= FMPI2C_IT_STOPI;
06697     }
06698   }
06699 
06700   /* Enable interrupts only at the end */
06701   /* to avoid the risk of FMPI2C interrupt handle execution before */
06702   /* all interrupts requested done */
06703   __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr);
06704 }
06705 
06706 /**
06707   * @brief  Manage the disabling of Interrupts.
06708   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
06709   *                the configuration information for the specified FMPI2C.
06710   * @param  InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
06711   * @retval None
06712   */
06713 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
06714 {
06715   uint32_t tmpisr = 0U;
06716 
06717   if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
06718   {
06719     /* Disable TC and TXI interrupts */
06720     tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI;
06721 
06722     if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
06723     {
06724       /* Disable NACK and STOP interrupts */
06725       tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
06726     }
06727   }
06728 
06729   if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
06730   {
06731     /* Disable TC and RXI interrupts */
06732     tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI;
06733 
06734     if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
06735     {
06736       /* Disable NACK and STOP interrupts */
06737       tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
06738     }
06739   }
06740 
06741   if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
06742   {
06743     /* Disable ADDR, NACK and STOP interrupts */
06744     tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
06745   }
06746 
06747   if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
06748   {
06749     /* Enable ERR and NACK interrupts */
06750     tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
06751   }
06752 
06753   if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
06754   {
06755     /* Enable STOP interrupts */
06756     tmpisr |= FMPI2C_IT_STOPI;
06757   }
06758 
06759   if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
06760   {
06761     /* Enable TC interrupts */
06762     tmpisr |= FMPI2C_IT_TCI;
06763   }
06764 
06765   /* Disable interrupts only at the end */
06766   /* to avoid a breaking situation like at "t" time */
06767   /* all disable interrupts request are not done */
06768   __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr);
06769 }
06770 
06771 /**
06772   * @brief  Convert FMPI2Cx OTHER_xxx XferOptions to functional XferOptions.
06773   * @param  hfmpi2c FMPI2C handle.
06774   * @retval None
06775   */
06776 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c)
06777 {
06778   /* if user set XferOptions to FMPI2C_OTHER_FRAME            */
06779   /* it request implicitly to generate a restart condition */
06780   /* set XferOptions to FMPI2C_FIRST_FRAME                    */
06781   if (hfmpi2c->XferOptions == FMPI2C_OTHER_FRAME)
06782   {
06783     hfmpi2c->XferOptions = FMPI2C_FIRST_FRAME;
06784   }
06785   /* else if user set XferOptions to FMPI2C_OTHER_AND_LAST_FRAME */
06786   /* it request implicitly to generate a restart condition    */
06787   /* then generate a stop condition at the end of transfer    */
06788   /* set XferOptions to FMPI2C_FIRST_AND_LAST_FRAME              */
06789   else if (hfmpi2c->XferOptions == FMPI2C_OTHER_AND_LAST_FRAME)
06790   {
06791     hfmpi2c->XferOptions = FMPI2C_FIRST_AND_LAST_FRAME;
06792   }
06793   else
06794   {
06795     /* Nothing to do */
06796   }
06797 }
06798 
06799 /**
06800   * @}
06801   */
06802 
06803 #endif /* FMPI2C_CR1_PE */
06804 #endif /* HAL_FMPI2C_MODULE_ENABLED */
06805 /**
06806   * @}
06807   */
06808 
06809 /**
06810   * @}
06811   */
06812 
06813 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/