STM32F439xx 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 the transmit or receive stream
00032             (+++) Enable the DMAx interface clock using
00033             (+++) Configure the DMA handle parameters
00034             (+++) Configure the DMA Tx or Rx stream
00035             (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle
00036             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
00037                   the DMA Tx or Rx stream
00038 
00039     (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
00040         Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure.
00041 
00042     (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware
00043         (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API.
00044 
00045     (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady()
00046 
00047     (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver :
00048 
00049     *** Polling mode IO operation ***
00050     =================================
00051     [..]
00052       (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit()
00053       (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive()
00054       (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit()
00055       (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive()
00056 
00057     *** Polling mode IO MEM operation ***
00058     =====================================
00059     [..]
00060       (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write()
00061       (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read()
00062 
00063 
00064     *** Interrupt mode IO operation ***
00065     ===================================
00066     [..]
00067       (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT()
00068       (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00069            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00070       (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT()
00071       (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00072            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00073       (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT()
00074       (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00075            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00076       (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT()
00077       (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00078            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00079       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00080            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00081       (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00082       (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00083            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00084       (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00085            This action will inform Master to generate a Stop condition to discard the communication.
00086 
00087 
00088     *** Interrupt mode IO sequential operation ***
00089     ==============================================
00090     [..]
00091       (@) These interfaces allow to manage a sequential transfer with a repeated start condition
00092           when a direction change during transfer
00093     [..]
00094       (+) A specific option field manage the different steps of a sequential transfer
00095       (+) Option field values are defined through @ref FMPI2C_XFEROPTIONS and are listed below:
00096       (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode
00097       (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
00098                             and data to transfer without a final stop condition
00099       (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
00100                             and data to transfer without a final stop condition, an then permit a call the same master sequential interface
00101                             several times (like HAL_FMPI2C_Master_Sequential_Transmit_IT() then HAL_FMPI2C_Master_Sequential_Transmit_IT())
00102       (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
00103                             and with new data to transfer if the direction change or manage only the new data to transfer
00104                             if no direction change and without a final stop condition in both cases
00105       (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
00106                             and with new data to transfer if the direction change or manage only the new data to transfer
00107                             if no direction change and with a final stop condition in both cases
00108       (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential
00109                             interface several times (link with option FMPI2C_FIRST_AND_NEXT_FRAME).
00110                             Usage can, transfer several bytes one by one using HAL_FMPI2C_Master_Sequential_Transmit_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME)
00111                             or HAL_FMPI2C_Master_Sequential_Receive_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME).
00112                             Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the oposite interface Receive or Transmit
00113                             without stopping the communication and so generate a restart condition.
00114 
00115       (+) Differents sequential FMPI2C interfaces are listed below:
00116       (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Transmit_IT()
00117       (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00118            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00119       (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Receive_IT()
00120       (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00121            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00122       (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00123       (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00124            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00125       (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT()
00126       (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can
00127            add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
00128       (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can
00129            add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback()
00130       (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Transmit_IT()
00131       (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00132            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00133       (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Receive_IT()
00134       (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00135            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00136       (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00137            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00138       (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00139       (++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00140            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00141       (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00142            This action will inform Master to generate a Stop condition to discard the communication.
00143 
00144     *** Interrupt mode IO MEM operation ***
00145     =======================================
00146     [..]
00147       (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
00148           HAL_FMPI2C_Mem_Write_IT()
00149       (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
00150            add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
00151       (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
00152           HAL_FMPI2C_Mem_Read_IT()
00153       (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
00154            add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
00155       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00156            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00157 
00158     *** DMA mode IO operation ***
00159     ==============================
00160     [..]
00161       (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
00162           HAL_FMPI2C_Master_Transmit_DMA()
00163       (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
00164            add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
00165       (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
00166           HAL_FMPI2C_Master_Receive_DMA()
00167       (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
00168            add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
00169       (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
00170           HAL_FMPI2C_Slave_Transmit_DMA()
00171       (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
00172            add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
00173       (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
00174           HAL_FMPI2C_Slave_Receive_DMA()
00175       (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
00176            add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
00177       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00178            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00179       (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
00180       (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
00181            add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
00182       (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
00183            This action will inform Master to generate a Stop condition to discard the communication.
00184 
00185     *** DMA mode IO MEM operation ***
00186     =================================
00187     [..]
00188       (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
00189           HAL_FMPI2C_Mem_Write_DMA()
00190       (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
00191            add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
00192       (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
00193           HAL_FMPI2C_Mem_Read_DMA()
00194       (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
00195            add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
00196       (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
00197            add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
00198 
00199 
00200      *** FMPI2C HAL driver macros list ***
00201      ==================================
00202      [..]
00203        Below the list of most used macros in FMPI2C HAL driver.
00204 
00205       (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral
00206       (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral
00207       (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode
00208       (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not
00209       (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag
00210       (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt
00211       (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt
00212 
00213      [..]
00214        (@) You can refer to the FMPI2C HAL driver header file for more useful macros
00215 
00216   @endverbatim
00217   ******************************************************************************
00218   * @attention
00219   *
00220   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00221   *
00222   * Redistribution and use in source and binary forms, with or without modification,
00223   * are permitted provided that the following conditions are met:
00224   *   1. Redistributions of source code must retain the above copyright notice,
00225   *      this list of conditions and the following disclaimer.
00226   *   2. Redistributions in binary form must reproduce the above copyright notice,
00227   *      this list of conditions and the following disclaimer in the documentation
00228   *      and/or other materials provided with the distribution.
00229   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00230   *      may be used to endorse or promote products derived from this software
00231   *      without specific prior written permission.
00232   *
00233   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00234   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00235   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00236   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00237   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00238   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00239   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00240   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00241   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00242   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00243   *
00244   ******************************************************************************
00245   */
00246 
00247 /* Includes ------------------------------------------------------------------*/
00248 #include "stm32f4xx_hal.h"
00249 
00250 /** @addtogroup STM32F4xx_HAL_Driver
00251   * @{
00252   */
00253 
00254 /** @defgroup FMPI2C FMPI2C
00255   * @brief FMPI2C HAL module driver
00256   * @{
00257   */
00258 
00259 #ifdef HAL_FMPI2C_MODULE_ENABLED
00260 
00261 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F412Zx) ||\
00262     defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00263 
00264 /* Private typedef -----------------------------------------------------------*/
00265 /* Private define ------------------------------------------------------------*/
00266 
00267 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define
00268   * @{
00269   */
00270 #define TIMING_CLEAR_MASK      (0xF0FFFFFFU)  /*!< FMPI2C TIMING clear register Mask */
00271 #define FMPI2C_TIMEOUT_ADDR    (10000U)       /*!< 10 s  */
00272 #define FMPI2C_TIMEOUT_BUSY    (25U)          /*!< 25 ms */
00273 #define FMPI2C_TIMEOUT_DIR     (25U)          /*!< 25 ms */
00274 #define FMPI2C_TIMEOUT_RXNE    (25U)          /*!< 25 ms */
00275 #define FMPI2C_TIMEOUT_STOPF   (25U)          /*!< 25 ms */
00276 #define FMPI2C_TIMEOUT_TC      (25U)          /*!< 25 ms */
00277 #define FMPI2C_TIMEOUT_TCR     (25U)          /*!< 25 ms */
00278 #define FMPI2C_TIMEOUT_TXIS    (25U)          /*!< 25 ms */
00279 #define FMPI2C_TIMEOUT_FLAG    (25U)          /*!< 25 ms */
00280 
00281 #define MAX_NBYTE_SIZE      255U
00282 #define SlaveAddr_SHIFT     7U
00283 #define SlaveAddr_MSK       0x06U
00284 
00285 /* Private define for @ref PreviousState usage */
00286 #define FMPI2C_STATE_MSK             ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX | HAL_FMPI2C_STATE_BUSY_RX) & (~((uint32_t)HAL_FMPI2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits            */
00287 #define FMPI2C_STATE_NONE            ((uint32_t)(HAL_FMPI2C_MODE_NONE))                                                        /*!< Default Value                                          */
00288 #define FMPI2C_STATE_MASTER_BUSY_TX  ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER))            /*!< Master Busy TX, combinaison of State LSB and Mode enum */
00289 #define FMPI2C_STATE_MASTER_BUSY_RX  ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER))            /*!< Master Busy RX, combinaison of State LSB and Mode enum */
00290 #define FMPI2C_STATE_SLAVE_BUSY_TX   ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE))             /*!< Slave Busy TX, combinaison of State LSB and Mode enum  */
00291 #define FMPI2C_STATE_SLAVE_BUSY_RX   ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE))             /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
00292 #define FMPI2C_STATE_MEM_BUSY_TX     ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM))               /*!< Memory Busy TX, combinaison of State LSB and Mode enum */
00293 #define FMPI2C_STATE_MEM_BUSY_RX     ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM))               /*!< Memory Busy RX, combinaison of State LSB and Mode enum */
00294 
00295 
00296 /* Private define to centralize the enable/disable of Interrupts */
00297 #define FMPI2C_XFER_TX_IT          (0x00000001U)
00298 #define FMPI2C_XFER_RX_IT          (0x00000002U)
00299 #define FMPI2C_XFER_LISTEN_IT      (0x00000004U)
00300 
00301 #define FMPI2C_XFER_ERROR_IT       (0x00000011U)
00302 #define FMPI2C_XFER_CPLT_IT        (0x00000012U)
00303 #define FMPI2C_XFER_RELOAD_IT      (0x00000012U)
00304 
00305 /* Private define Sequential Transfer Options default/reset value */
00306 #define FMPI2C_NO_OPTION_FRAME     (0xFFFF0000U)
00307 /**
00308   * @}
00309   */
00310 
00311 /* Private macro -------------------------------------------------------------*/
00312 #define FMPI2C_GET_DMA_REMAIN_DATA(__HANDLE__) ((((__HANDLE__)->State) == HAL_FMPI2C_STATE_BUSY_TX)   ? \
00313                                               ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmatx->Instance)->NDTR)) :  \
00314                                               ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmarx->Instance)->NDTR)))
00315 
00316 /* Private variables ---------------------------------------------------------*/
00317 /* Private function prototypes -----------------------------------------------*/
00318 
00319 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions
00320   * @{
00321   */
00322 /* Private functions to handle DMA transfer */
00323 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
00324 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
00325 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
00326 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
00327 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
00328 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma);
00329 
00330 /* Private functions to handle IT transfer */
00331 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00332 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c);
00333 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c);
00334 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00335 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00336 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
00337 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode);
00338 
00339 /* Private functions to handle IT transfer */
00340 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
00341 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
00342 
00343 /* Private functions for FMPI2C transfer IRQ handler */
00344 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
00345 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
00346 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
00347 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
00348 
00349 /* Private functions to handle flags during polling transfer */
00350 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
00351 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
00352 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
00353 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
00354 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
00355 
00356 /* Private functions to centralize the enable/disable of Interrupts */
00357 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
00358 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
00359 
00360 /* Private functions to flush TXDR register */
00361 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c);
00362 
00363 /* Private functions to handle  start, restart or stop a transfer */
00364 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
00365 /**
00366   * @}
00367   */
00368 
00369 /* Exported functions --------------------------------------------------------*/
00370 
00371 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions
00372   * @{
00373   */
00374 
00375 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions
00376  *  @brief    Initialization and Configuration functions
00377  *
00378 @verbatim
00379  ===============================================================================
00380               ##### Initialization and de-initialization functions #####
00381  ===============================================================================
00382     [..]  This subsection provides a set of functions allowing to initialize and
00383           deinitialize the FMPI2Cx peripheral:
00384 
00385       (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures
00386           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
00387 
00388       (+) Call the function HAL_FMPI2C_Init() to configure the selected device with
00389           the selected configuration:
00390         (++) Clock Timing
00391         (++) Own Address 1
00392         (++) Addressing mode (Master, Slave)
00393         (++) Dual Addressing mode
00394         (++) Own Address 2
00395         (++) Own Address 2 Mask
00396         (++) General call mode
00397         (++) Nostretch mode
00398 
00399       (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration
00400           of the selected FMPI2Cx peripheral.
00401 
00402 @endverbatim
00403   * @{
00404   */
00405 
00406 /**
00407   * @brief  Initializes the FMPI2C according to the specified parameters
00408   *         in the FMPI2C_InitTypeDef and initialize the associated handle.
00409   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00410   *                the configuration information for the specified FMPI2C.
00411   * @retval HAL status
00412   */
00413 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
00414 {
00415   /* Check the FMPI2C handle allocation */
00416   if (hfmpi2c == NULL)
00417   {
00418     return HAL_ERROR;
00419   }
00420 
00421   /* Check the parameters */
00422   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
00423   assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
00424   assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
00425   assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
00426   assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
00427   assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
00428   assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
00429   assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
00430 
00431   if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
00432   {
00433     /* Allocate lock resource and initialize it */
00434     hfmpi2c->Lock = HAL_UNLOCKED;
00435 
00436     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00437     HAL_FMPI2C_MspInit(hfmpi2c);
00438   }
00439 
00440   hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
00441 
00442   /* Disable the selected FMPI2C peripheral */
00443   __HAL_FMPI2C_DISABLE(hfmpi2c);
00444 
00445   /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
00446   /* Configure FMPI2Cx: Frequency range */
00447   hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
00448 
00449   /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
00450   /* Disable Own Address1 before set the Own Address1 configuration */
00451   hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
00452 
00453   /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
00454   if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
00455   {
00456     hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
00457   }
00458   else /* FMPI2C_ADDRESSINGMODE_10BIT */
00459   {
00460     hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
00461   }
00462 
00463   /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
00464   /* Configure FMPI2Cx: Addressing Master mode */
00465   if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
00466   {
00467     hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10);
00468   }
00469   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
00470   hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
00471 
00472   /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
00473   /* Disable Own Address2 before set the Own Address2 configuration */
00474   hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE;
00475 
00476   /* Configure FMPI2Cx: Dual mode and Own Address2 */
00477   hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8));
00478 
00479   /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
00480   /* Configure FMPI2Cx: Generalcall and NoStretch mode */
00481   hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
00482 
00483   /* Enable the selected FMPI2C peripheral */
00484   __HAL_FMPI2C_ENABLE(hfmpi2c);
00485 
00486   hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00487   hfmpi2c->State = HAL_FMPI2C_STATE_READY;
00488   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
00489   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
00490 
00491   return HAL_OK;
00492 }
00493 
00494 /**
00495   * @brief  DeInitialize the FMPI2C peripheral.
00496   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00497   *                the configuration information for the specified FMPI2C.
00498   * @retval HAL status
00499   */
00500 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
00501 {
00502   /* Check the FMPI2C handle allocation */
00503   if (hfmpi2c == NULL)
00504   {
00505     return HAL_ERROR;
00506   }
00507 
00508   /* Check the parameters */
00509   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
00510 
00511   hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
00512 
00513   /* Disable the FMPI2C Peripheral Clock */
00514   __HAL_FMPI2C_DISABLE(hfmpi2c);
00515 
00516   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00517   HAL_FMPI2C_MspDeInit(hfmpi2c);
00518 
00519   hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00520   hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
00521   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
00522   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
00523 
00524   /* Release Lock */
00525   __HAL_UNLOCK(hfmpi2c);
00526 
00527   return HAL_OK;
00528 }
00529 
00530 /**
00531   * @brief Initialize the FMPI2C MSP.
00532   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00533   *                the configuration information for the specified FMPI2C.
00534   * @retval None
00535   */
00536 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
00537 {
00538   /* Prevent unused argument(s) compilation warning */
00539   UNUSED(hfmpi2c);
00540 
00541   /* NOTE : This function should not be modified, when the callback is needed,
00542             the HAL_FMPI2C_MspInit could be implemented in the user file
00543    */
00544 }
00545 
00546 /**
00547   * @brief DeInitialize the FMPI2C MSP.
00548   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00549   *                the configuration information for the specified FMPI2C.
00550   * @retval None
00551   */
00552 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
00553 {
00554   /* Prevent unused argument(s) compilation warning */
00555   UNUSED(hfmpi2c);
00556 
00557   /* NOTE : This function should not be modified, when the callback is needed,
00558             the HAL_FMPI2C_MspDeInit could be implemented in the user file
00559    */
00560 }
00561 
00562 /**
00563   * @}
00564   */
00565 
00566 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions
00567  *  @brief   Data transfers functions
00568  *
00569 @verbatim
00570  ===============================================================================
00571                       ##### IO operation functions #####
00572  ===============================================================================
00573     [..]
00574     This subsection provides a set of functions allowing to manage the FMPI2C data
00575     transfers.
00576 
00577     (#) There are two modes of transfer:
00578        (++) Blocking mode : The communication is performed in the polling mode.
00579             The status of all data processing is returned by the same function
00580             after finishing transfer.
00581        (++) No-Blocking mode : The communication is performed using Interrupts
00582             or DMA. These functions return the status of the transfer startup.
00583             The end of the data processing will be indicated through the
00584             dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when
00585             using DMA mode.
00586 
00587     (#) Blocking mode functions are :
00588         (++) HAL_FMPI2C_Master_Transmit()
00589         (++) HAL_FMPI2C_Master_Receive()
00590         (++) HAL_FMPI2C_Slave_Transmit()
00591         (++) HAL_FMPI2C_Slave_Receive()
00592         (++) HAL_FMPI2C_Mem_Write()
00593         (++) HAL_FMPI2C_Mem_Read()
00594         (++) HAL_FMPI2C_IsDeviceReady()
00595 
00596     (#) No-Blocking mode functions with Interrupt are :
00597         (++) HAL_FMPI2C_Master_Transmit_IT()
00598         (++) HAL_FMPI2C_Master_Receive_IT()
00599         (++) HAL_FMPI2C_Slave_Transmit_IT()
00600         (++) HAL_FMPI2C_Slave_Receive_IT()
00601         (++) HAL_FMPI2C_Master_Sequential_Transmit_IT()
00602         (++) HAL_FMPI2C_Master_Sequential_Receive_IT()
00603         (++) HAL_FMPI2C_Slave_Sequential_Transmit_IT()
00604         (++) HAL_FMPI2C_Slave_Sequential_Receive_IT()
00605         (++) HAL_FMPI2C_Mem_Write_IT()
00606         (++) HAL_FMPI2C_Mem_Read_IT()
00607 
00608     (#) No-Blocking mode functions with DMA are :
00609         (++) HAL_FMPI2C_Master_Transmit_DMA()
00610         (++) HAL_FMPI2C_Master_Receive_DMA()
00611         (++) HAL_FMPI2C_Slave_Transmit_DMA()
00612         (++) HAL_FMPI2C_Slave_Receive_DMA()
00613         (++) HAL_FMPI2C_Mem_Write_DMA()
00614         (++) HAL_FMPI2C_Mem_Read_DMA()
00615 
00616     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
00617         (++) HAL_FMPI2C_MemTxCpltCallback()
00618         (++) HAL_FMPI2C_MemRxCpltCallback()
00619         (++) HAL_FMPI2C_MasterTxCpltCallback()
00620         (++) HAL_FMPI2C_MasterRxCpltCallback()
00621         (++) HAL_FMPI2C_SlaveTxCpltCallback()
00622         (++) HAL_FMPI2C_SlaveRxCpltCallback()
00623         (++) HAL_FMPI2C_ErrorCallback()
00624 
00625 @endverbatim
00626   * @{
00627   */
00628 
00629 /**
00630   * @brief  Transmits in master mode an amount of data in blocking mode.
00631   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00632   *                the configuration information for the specified FMPI2C.
00633   * @param  DevAddress Target device address The device 7 bits address value
00634   *         in datasheet must be shifted to the left before calling the interface
00635   * @param  pData Pointer to data buffer
00636   * @param  Size Amount of data to be sent
00637   * @param  Timeout Timeout duration
00638   * @retval HAL status
00639   */
00640 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00641 {
00642   uint32_t tickstart = 0U;
00643 
00644   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
00645   {
00646     /* Process Locked */
00647     __HAL_LOCK(hfmpi2c);
00648 
00649     /* Init tickstart for timeout management*/
00650     tickstart = HAL_GetTick();
00651 
00652     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
00653     {
00654       return HAL_TIMEOUT;
00655     }
00656 
00657     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
00658     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
00659     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00660 
00661     /* Prepare transfer parameters */
00662     hfmpi2c->pBuffPtr  = pData;
00663     hfmpi2c->XferCount = Size;
00664     hfmpi2c->XferISR   = NULL;
00665 
00666     /* Send Slave Address */
00667     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
00668     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
00669     {
00670       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
00671       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
00672     }
00673     else
00674     {
00675       hfmpi2c->XferSize = hfmpi2c->XferCount;
00676       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
00677     }
00678 
00679     while (hfmpi2c->XferCount > 0U)
00680     {
00681       /* Wait until TXIS flag is set */
00682       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00683       {
00684         if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00685         {
00686           return HAL_ERROR;
00687         }
00688         else
00689         {
00690           return HAL_TIMEOUT;
00691         }
00692       }
00693       /* Write data to TXDR */
00694       hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
00695       hfmpi2c->XferCount--;
00696       hfmpi2c->XferSize--;
00697 
00698       if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
00699       {
00700         /* Wait until TCR flag is set */
00701         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
00702         {
00703           return HAL_TIMEOUT;
00704         }
00705 
00706         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
00707         {
00708           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
00709           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
00710         }
00711         else
00712         {
00713           hfmpi2c->XferSize = hfmpi2c->XferCount;
00714           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
00715         }
00716       }
00717     }
00718 
00719     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
00720     /* Wait until STOPF flag is set */
00721     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00722     {
00723       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00724       {
00725         return HAL_ERROR;
00726       }
00727       else
00728       {
00729         return HAL_TIMEOUT;
00730       }
00731     }
00732 
00733     /* Clear STOP Flag */
00734     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
00735 
00736     /* Clear Configuration Register 2 */
00737     FMPI2C_RESET_CR2(hfmpi2c);
00738 
00739     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
00740     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
00741 
00742     /* Process Unlocked */
00743     __HAL_UNLOCK(hfmpi2c);
00744 
00745     return HAL_OK;
00746   }
00747   else
00748   {
00749     return HAL_BUSY;
00750   }
00751 }
00752 
00753 /**
00754   * @brief  Receives in master mode an amount of data in blocking mode.
00755   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00756   *                the configuration information for the specified FMPI2C.
00757   * @param  DevAddress Target device address The device 7 bits address value
00758   *         in datasheet must be shifted to the left before calling the interface
00759   * @param  pData Pointer to data buffer
00760   * @param  Size Amount of data to be sent
00761   * @param  Timeout Timeout duration
00762   * @retval HAL status
00763   */
00764 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00765 {
00766   uint32_t tickstart = 0U;
00767 
00768   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
00769   {
00770     /* Process Locked */
00771     __HAL_LOCK(hfmpi2c);
00772 
00773     /* Init tickstart for timeout management*/
00774     tickstart = HAL_GetTick();
00775 
00776     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
00777     {
00778       return HAL_TIMEOUT;
00779     }
00780 
00781     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
00782     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
00783     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00784 
00785     /* Prepare transfer parameters */
00786     hfmpi2c->pBuffPtr  = pData;
00787     hfmpi2c->XferCount = Size;
00788     hfmpi2c->XferISR   = NULL;
00789 
00790     /* Send Slave Address */
00791     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
00792     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
00793     {
00794       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
00795       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
00796     }
00797     else
00798     {
00799       hfmpi2c->XferSize = hfmpi2c->XferCount;
00800       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
00801     }
00802 
00803     while (hfmpi2c->XferCount > 0U)
00804     {
00805       /* Wait until RXNE flag is set */
00806       if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00807       {
00808         if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00809         {
00810           return HAL_ERROR;
00811         }
00812         else
00813         {
00814           return HAL_TIMEOUT;
00815         }
00816       }
00817 
00818       /* Read data from RXDR */
00819       (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
00820       hfmpi2c->XferSize--;
00821       hfmpi2c->XferCount--;
00822 
00823       if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
00824       {
00825         /* Wait until TCR flag is set */
00826         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
00827         {
00828           return HAL_TIMEOUT;
00829         }
00830 
00831         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
00832         {
00833           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
00834           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
00835         }
00836         else
00837         {
00838           hfmpi2c->XferSize = hfmpi2c->XferCount;
00839           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
00840         }
00841       }
00842     }
00843 
00844     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
00845     /* Wait until STOPF flag is set */
00846     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00847     {
00848       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00849       {
00850         return HAL_ERROR;
00851       }
00852       else
00853       {
00854         return HAL_TIMEOUT;
00855       }
00856     }
00857 
00858     /* Clear STOP Flag */
00859     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
00860 
00861     /* Clear Configuration Register 2 */
00862     FMPI2C_RESET_CR2(hfmpi2c);
00863 
00864     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
00865     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
00866 
00867     /* Process Unlocked */
00868     __HAL_UNLOCK(hfmpi2c);
00869 
00870     return HAL_OK;
00871   }
00872   else
00873   {
00874     return HAL_BUSY;
00875   }
00876 }
00877 
00878 /**
00879   * @brief  Transmits in slave mode an amount of data in blocking mode.
00880   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
00881   *                the configuration information for the specified FMPI2C.
00882   * @param  pData Pointer to data buffer
00883   * @param  Size Amount of data to be sent
00884   * @param  Timeout Timeout duration
00885   * @retval HAL status
00886   */
00887 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00888 {
00889   uint32_t tickstart = 0U;
00890 
00891   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
00892   {
00893     if ((pData == NULL) || (Size == 0U))
00894     {
00895       return  HAL_ERROR;
00896     }
00897     /* Process Locked */
00898     __HAL_LOCK(hfmpi2c);
00899 
00900     /* Init tickstart for timeout management*/
00901     tickstart = HAL_GetTick();
00902 
00903     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
00904     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
00905     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00906 
00907     /* Prepare transfer parameters */
00908     hfmpi2c->pBuffPtr  = pData;
00909     hfmpi2c->XferCount = Size;
00910     hfmpi2c->XferISR   = NULL;
00911 
00912     /* Enable Address Acknowledge */
00913     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
00914 
00915     /* Wait until ADDR flag is set */
00916     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
00917     {
00918       /* Disable Address Acknowledge */
00919       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00920       return HAL_TIMEOUT;
00921     }
00922 
00923     /* Clear ADDR flag */
00924     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
00925 
00926     /* If 10bit addressing mode is selected */
00927     if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
00928     {
00929       /* Wait until ADDR flag is set */
00930       if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
00931       {
00932         /* Disable Address Acknowledge */
00933         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00934         return HAL_TIMEOUT;
00935       }
00936 
00937       /* Clear ADDR flag */
00938       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
00939     }
00940 
00941     /* Wait until DIR flag is set Transmitter mode */
00942     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
00943     {
00944       /* Disable Address Acknowledge */
00945       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00946       return HAL_TIMEOUT;
00947     }
00948 
00949     while (hfmpi2c->XferCount > 0U)
00950     {
00951       /* Wait until TXIS flag is set */
00952       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00953       {
00954         /* Disable Address Acknowledge */
00955         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00956 
00957         if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00958         {
00959           return HAL_ERROR;
00960         }
00961         else
00962         {
00963           return HAL_TIMEOUT;
00964         }
00965       }
00966 
00967       /* Write data to TXDR */
00968       hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
00969       hfmpi2c->XferCount--;
00970     }
00971 
00972     /* Wait until STOP flag is set */
00973     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
00974     {
00975       /* Disable Address Acknowledge */
00976       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00977 
00978       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
00979       {
00980         /* Normal use case for Transmitter mode */
00981         /* A NACK is generated to confirm the end of transfer */
00982         hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
00983       }
00984       else
00985       {
00986         return HAL_TIMEOUT;
00987       }
00988     }
00989 
00990     /* Clear STOP flag */
00991     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
00992 
00993     /* Wait until BUSY flag is reset */
00994     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
00995     {
00996       /* Disable Address Acknowledge */
00997       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
00998       return HAL_TIMEOUT;
00999     }
01000 
01001     /* Disable Address Acknowledge */
01002     hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01003 
01004     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01005     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01006 
01007     /* Process Unlocked */
01008     __HAL_UNLOCK(hfmpi2c);
01009 
01010     return HAL_OK;
01011   }
01012   else
01013   {
01014     return HAL_BUSY;
01015   }
01016 }
01017 
01018 /**
01019   * @brief  Receive in slave mode an amount of data in blocking mode
01020   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01021   *                the configuration information for the specified FMPI2C.
01022   * @param  pData Pointer to data buffer
01023   * @param  Size Amount of data to be sent
01024   * @param  Timeout Timeout duration
01025   * @retval HAL status
01026   */
01027 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
01028 {
01029   uint32_t tickstart = 0U;
01030 
01031   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01032   {
01033     if ((pData == NULL) || (Size == 0U))
01034     {
01035       return  HAL_ERROR;
01036     }
01037     /* Process Locked */
01038     __HAL_LOCK(hfmpi2c);
01039 
01040     /* Init tickstart for timeout management*/
01041     tickstart = HAL_GetTick();
01042 
01043     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
01044     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
01045     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01046 
01047     /* Prepare transfer parameters */
01048     hfmpi2c->pBuffPtr  = pData;
01049     hfmpi2c->XferCount = Size;
01050     hfmpi2c->XferISR   = NULL;
01051 
01052     /* Enable Address Acknowledge */
01053     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01054 
01055     /* Wait until ADDR flag is set */
01056     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
01057     {
01058       /* Disable Address Acknowledge */
01059       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01060       return HAL_TIMEOUT;
01061     }
01062 
01063     /* Clear ADDR flag */
01064     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
01065 
01066     /* Wait until DIR flag is reset Receiver mode */
01067     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
01068     {
01069       /* Disable Address Acknowledge */
01070       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01071       return HAL_TIMEOUT;
01072     }
01073 
01074     while (hfmpi2c->XferCount > 0U)
01075     {
01076       /* Wait until RXNE flag is set */
01077       if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01078       {
01079         /* Disable Address Acknowledge */
01080         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01081 
01082         /* Store Last receive data if any */
01083         if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
01084         {
01085           /* Read data from RXDR */
01086           (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
01087           hfmpi2c->XferCount--;
01088         }
01089 
01090         if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT)
01091         {
01092           return HAL_TIMEOUT;
01093         }
01094         else
01095         {
01096           return HAL_ERROR;
01097         }
01098       }
01099 
01100       /* Read data from RXDR */
01101       (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
01102       hfmpi2c->XferCount--;
01103     }
01104 
01105     /* Wait until STOP flag is set */
01106     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01107     {
01108       /* Disable Address Acknowledge */
01109       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01110 
01111       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01112       {
01113         return HAL_ERROR;
01114       }
01115       else
01116       {
01117         return HAL_TIMEOUT;
01118       }
01119     }
01120 
01121     /* Clear STOP flag */
01122     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01123 
01124     /* Wait until BUSY flag is reset */
01125     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
01126     {
01127       /* Disable Address Acknowledge */
01128       hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01129       return HAL_TIMEOUT;
01130     }
01131 
01132     /* Disable Address Acknowledge */
01133     hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
01134 
01135     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01136     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01137 
01138     /* Process Unlocked */
01139     __HAL_UNLOCK(hfmpi2c);
01140 
01141     return HAL_OK;
01142   }
01143   else
01144   {
01145     return HAL_BUSY;
01146   }
01147 }
01148 
01149 /**
01150   * @brief  Transmit in master mode an amount of data in non-blocking mode with Interrupt
01151   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01152   *                the configuration information for the specified FMPI2C.
01153   * @param  DevAddress Target device address The device 7 bits address value
01154   *         in datasheet must be shifted to the left before calling the interface
01155   * @param  pData Pointer to data buffer
01156   * @param  Size Amount of data to be sent
01157   * @retval HAL status
01158   */
01159 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
01160 {
01161   uint32_t xfermode = 0U;
01162 
01163   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01164   {
01165     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01166     {
01167       return HAL_BUSY;
01168     }
01169 
01170     /* Process Locked */
01171     __HAL_LOCK(hfmpi2c);
01172 
01173     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01174     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01175     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01176 
01177     /* Prepare transfer parameters */
01178     hfmpi2c->pBuffPtr    = pData;
01179     hfmpi2c->XferCount   = Size;
01180     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01181     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
01182 
01183     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01184     {
01185       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01186       xfermode = FMPI2C_RELOAD_MODE;
01187     }
01188     else
01189     {
01190       hfmpi2c->XferSize = hfmpi2c->XferCount;
01191       xfermode = FMPI2C_AUTOEND_MODE;
01192     }
01193 
01194     /* Send Slave Address */
01195     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
01196     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
01197 
01198     /* Process Unlocked */
01199     __HAL_UNLOCK(hfmpi2c);
01200 
01201     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01202               to avoid the risk of FMPI2C interrupt handle execution before current
01203               process unlock */
01204 
01205     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01206     /* possible to enable all of these */
01207     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01208     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
01209 
01210     return HAL_OK;
01211   }
01212   else
01213   {
01214     return HAL_BUSY;
01215   }
01216 }
01217 
01218 /**
01219   * @brief  Receive in master mode an amount of data in non-blocking mode with Interrupt
01220   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01221   *                the configuration information for the specified FMPI2C.
01222   * @param  DevAddress Target device address The device 7 bits address value
01223   *         in datasheet must be shifted to the left before calling the interface
01224   * @param  pData Pointer to data buffer
01225   * @param  Size Amount of data to be sent
01226   * @retval HAL status
01227   */
01228 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
01229 {
01230   uint32_t xfermode = 0U;
01231 
01232   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01233   {
01234     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01235     {
01236       return HAL_BUSY;
01237     }
01238 
01239     /* Process Locked */
01240     __HAL_LOCK(hfmpi2c);
01241 
01242     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01243     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01244     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01245 
01246     /* Prepare transfer parameters */
01247     hfmpi2c->pBuffPtr    = pData;
01248     hfmpi2c->XferCount   = Size;
01249     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01250     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
01251 
01252     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01253     {
01254       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01255       xfermode = FMPI2C_RELOAD_MODE;
01256     }
01257     else
01258     {
01259       hfmpi2c->XferSize = hfmpi2c->XferCount;
01260       xfermode = FMPI2C_AUTOEND_MODE;
01261     }
01262 
01263     /* Send Slave Address */
01264     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
01265     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
01266 
01267     /* Process Unlocked */
01268     __HAL_UNLOCK(hfmpi2c);
01269 
01270     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01271               to avoid the risk of FMPI2C interrupt handle execution before current
01272               process unlock */
01273 
01274     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
01275     /* possible to enable all of these */
01276     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01277     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
01278 
01279     return HAL_OK;
01280   }
01281   else
01282   {
01283     return HAL_BUSY;
01284   }
01285 }
01286 
01287 /**
01288   * @brief  Transmit in slave mode an amount of data in non-blocking mode with Interrupt
01289   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01290   *                the configuration information for the specified FMPI2C.
01291   * @param  pData Pointer to data buffer
01292   * @param  Size Amount of data to be sent
01293   * @retval HAL status
01294   */
01295 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01296 {
01297   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01298   {
01299     /* Process Locked */
01300     __HAL_LOCK(hfmpi2c);
01301 
01302     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01303     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01304     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01305 
01306     /* Enable Address Acknowledge */
01307     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01308 
01309     /* Prepare transfer parameters */
01310     hfmpi2c->pBuffPtr    = pData;
01311     hfmpi2c->XferCount   = Size;
01312     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01313     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01314     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
01315 
01316     /* Process Unlocked */
01317     __HAL_UNLOCK(hfmpi2c);
01318 
01319     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01320               to avoid the risk of FMPI2C interrupt handle execution before current
01321               process unlock */
01322 
01323     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01324     /* possible to enable all of these */
01325     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01326     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
01327 
01328     return HAL_OK;
01329   }
01330   else
01331   {
01332     return HAL_BUSY;
01333   }
01334 }
01335 
01336 /**
01337   * @brief  Receive in slave mode an amount of data in non-blocking mode with Interrupt
01338   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01339   *                the configuration information for the specified FMPI2C.
01340   * @param  pData Pointer to data buffer
01341   * @param  Size Amount of data to be sent
01342   * @retval HAL status
01343   */
01344 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01345 {
01346   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01347   {
01348     /* Process Locked */
01349     __HAL_LOCK(hfmpi2c);
01350 
01351     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01352     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01353     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01354 
01355     /* Enable Address Acknowledge */
01356     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01357 
01358     /* Prepare transfer parameters */
01359     hfmpi2c->pBuffPtr    = pData;
01360     hfmpi2c->XferCount   = Size;
01361     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01362     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01363     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
01364 
01365     /* Process Unlocked */
01366     __HAL_UNLOCK(hfmpi2c);
01367 
01368     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01369               to avoid the risk of FMPI2C interrupt handle execution before current
01370               process unlock */
01371 
01372     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
01373     /* possible to enable all of these */
01374     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01375     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
01376 
01377     return HAL_OK;
01378   }
01379   else
01380   {
01381     return HAL_BUSY;
01382   }
01383 }
01384 
01385 /**
01386   * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
01387   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01388   *                the configuration information for the specified FMPI2C.
01389   * @param  DevAddress Target device address The device 7 bits address value
01390   *         in datasheet must be shifted to the left before calling the interface
01391   * @param  pData Pointer to data buffer
01392   * @param  Size Amount of data to be sent
01393   * @retval HAL status
01394   */
01395 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
01396 {
01397   uint32_t xfermode = 0U;
01398 
01399   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01400   {
01401     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01402     {
01403       return HAL_BUSY;
01404     }
01405 
01406     /* Process Locked */
01407     __HAL_LOCK(hfmpi2c);
01408 
01409     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01410     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01411     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01412 
01413     /* Prepare transfer parameters */
01414     hfmpi2c->pBuffPtr    = pData;
01415     hfmpi2c->XferCount   = Size;
01416     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01417     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
01418 
01419     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01420     {
01421       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01422       xfermode = FMPI2C_RELOAD_MODE;
01423     }
01424     else
01425     {
01426       hfmpi2c->XferSize = hfmpi2c->XferCount;
01427       xfermode = FMPI2C_AUTOEND_MODE;
01428     }
01429 
01430     if (hfmpi2c->XferSize > 0U)
01431     {
01432       /* Set the FMPI2C DMA transfer complete callback */
01433       hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
01434 
01435       /* Set the DMA error callback */
01436       hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
01437 
01438       /* Set the unused DMA callbacks to NULL */
01439       hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
01440       hfmpi2c->hdmatx->XferAbortCallback = NULL;
01441 
01442       /* Enable the DMA stream */
01443       HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
01444 
01445       /* Send Slave Address */
01446       /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01447       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
01448 
01449       /* Update XferCount value */
01450       hfmpi2c->XferCount -= hfmpi2c->XferSize;
01451 
01452       /* Process Unlocked */
01453       __HAL_UNLOCK(hfmpi2c);
01454 
01455       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01456                 to avoid the risk of FMPI2C interrupt handle execution before current
01457                 process unlock */
01458       /* Enable ERR and NACK interrupts */
01459       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
01460 
01461       /* Enable DMA Request */
01462       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
01463     }
01464     else
01465     {
01466       /* Update Transfer ISR function pointer */
01467       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
01468 
01469       /* Send Slave Address */
01470       /* Set NBYTES to write and generate START condition */
01471       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
01472 
01473       /* Process Unlocked */
01474       __HAL_UNLOCK(hfmpi2c);
01475 
01476       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01477                 to avoid the risk of FMPI2C interrupt handle execution before current
01478                 process unlock */
01479       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01480       /* possible to enable all of these */
01481       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01482       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
01483     }
01484 
01485     return HAL_OK;
01486   }
01487   else
01488   {
01489     return HAL_BUSY;
01490   }
01491 }
01492 
01493 /**
01494   * @brief  Receive in master mode an amount of data in non-blocking mode with DMA
01495   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01496   *                the configuration information for the specified FMPI2C.
01497   * @param  DevAddress Target device address The device 7 bits address value
01498   *         in datasheet must be shifted to the left before calling the interface
01499   * @param  pData Pointer to data buffer
01500   * @param  Size Amount of data to be sent
01501   * @retval HAL status
01502   */
01503 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
01504 {
01505   uint32_t xfermode = 0U;
01506 
01507   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01508   {
01509     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
01510     {
01511       return HAL_BUSY;
01512     }
01513 
01514     /* Process Locked */
01515     __HAL_LOCK(hfmpi2c);
01516 
01517     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01518     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MASTER;
01519     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01520 
01521     /* Prepare transfer parameters */
01522     hfmpi2c->pBuffPtr    = pData;
01523     hfmpi2c->XferCount   = Size;
01524     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01525     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
01526 
01527     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01528     {
01529       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01530       xfermode = FMPI2C_RELOAD_MODE;
01531     }
01532     else
01533     {
01534       hfmpi2c->XferSize = hfmpi2c->XferCount;
01535       xfermode = FMPI2C_AUTOEND_MODE;
01536     }
01537 
01538     if (hfmpi2c->XferSize > 0U)
01539     {
01540       /* Set the FMPI2C DMA transfer complete callback */
01541       hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
01542 
01543       /* Set the DMA error callback */
01544       hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
01545 
01546       /* Set the unused DMA callbacks to NULL */
01547       hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
01548       hfmpi2c->hdmarx->XferAbortCallback = NULL;
01549 
01550       /* Enable the DMA stream */
01551       HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
01552 
01553       /* Send Slave Address */
01554       /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01555       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
01556 
01557       /* Update XferCount value */
01558       hfmpi2c->XferCount -= hfmpi2c->XferSize;
01559 
01560       /* Process Unlocked */
01561       __HAL_UNLOCK(hfmpi2c);
01562 
01563       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01564                 to avoid the risk of FMPI2C interrupt handle execution before current
01565                 process unlock */
01566       /* Enable ERR and NACK interrupts */
01567       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
01568 
01569       /* Enable DMA Request */
01570       hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
01571     }
01572     else
01573     {
01574       /* Update Transfer ISR function pointer */
01575       hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
01576 
01577       /* Send Slave Address */
01578       /* Set NBYTES to read and generate START condition */
01579       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
01580 
01581       /* Process Unlocked */
01582       __HAL_UNLOCK(hfmpi2c);
01583 
01584       /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01585                 to avoid the risk of FMPI2C interrupt handle execution before current
01586                 process unlock */
01587       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
01588       /* possible to enable all of these */
01589       /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
01590       FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
01591     }
01592     return HAL_OK;
01593   }
01594   else
01595   {
01596     return HAL_BUSY;
01597   }
01598 }
01599 
01600 /**
01601   * @brief  Transmit in slave mode an amount of data in non-blocking mode with DMA
01602   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01603   *                the configuration information for the specified FMPI2C.
01604   * @param  pData Pointer to data buffer
01605   * @param  Size Amount of data to be sent
01606   * @retval HAL status
01607   */
01608 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01609 {
01610   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01611   {
01612     if ((pData == NULL) || (Size == 0U))
01613     {
01614       return  HAL_ERROR;
01615     }
01616     /* Process Locked */
01617     __HAL_LOCK(hfmpi2c);
01618 
01619     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
01620     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01621     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01622 
01623     /* Prepare transfer parameters */
01624     hfmpi2c->pBuffPtr    = pData;
01625     hfmpi2c->XferCount   = Size;
01626     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01627     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01628     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
01629 
01630     /* Set the FMPI2C DMA transfer complete callback */
01631     hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
01632 
01633     /* Set the DMA error callback */
01634     hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
01635 
01636     /* Set the unused DMA callbacks to NULL */
01637     hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
01638     hfmpi2c->hdmatx->XferAbortCallback = NULL;
01639 
01640     /* Enable the DMA stream */
01641     HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
01642 
01643     /* Enable Address Acknowledge */
01644     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01645 
01646     /* Process Unlocked */
01647     __HAL_UNLOCK(hfmpi2c);
01648 
01649     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01650               to avoid the risk of FMPI2C interrupt handle execution before current
01651               process unlock */
01652     /* Enable ERR, STOP, NACK, ADDR interrupts */
01653     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
01654 
01655     /* Enable DMA Request */
01656     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
01657 
01658     return HAL_OK;
01659   }
01660   else
01661   {
01662     return HAL_BUSY;
01663   }
01664 }
01665 
01666 /**
01667   * @brief  Receive in slave mode an amount of data in non-blocking mode with DMA
01668   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01669   *                the configuration information for the specified FMPI2C.
01670   * @param  pData Pointer to data buffer
01671   * @param  Size Amount of data to be sent
01672   * @retval HAL status
01673   */
01674 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
01675 {
01676   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01677   {
01678     if ((pData == NULL) || (Size == 0U))
01679     {
01680       return  HAL_ERROR;
01681     }
01682     /* Process Locked */
01683     __HAL_LOCK(hfmpi2c);
01684 
01685     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
01686     hfmpi2c->Mode        = HAL_FMPI2C_MODE_SLAVE;
01687     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
01688 
01689     /* Prepare transfer parameters */
01690     hfmpi2c->pBuffPtr    = pData;
01691     hfmpi2c->XferCount   = Size;
01692     hfmpi2c->XferSize    = hfmpi2c->XferCount;
01693     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
01694     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_DMA;
01695 
01696     /* Set the FMPI2C DMA transfer complete callback */
01697     hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
01698 
01699     /* Set the DMA error callback */
01700     hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
01701 
01702     /* Set the unused DMA callbacks to NULL */
01703     hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
01704     hfmpi2c->hdmarx->XferAbortCallback = NULL;
01705 
01706     /* Enable the DMA stream */
01707     HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
01708 
01709     /* Enable Address Acknowledge */
01710     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01711 
01712     /* Process Unlocked */
01713     __HAL_UNLOCK(hfmpi2c);
01714 
01715     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
01716               to avoid the risk of FMPI2C interrupt handle execution before current
01717               process unlock */
01718     /* Enable ERR, STOP, NACK, ADDR interrupts */
01719     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
01720 
01721     /* Enable DMA Request */
01722     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
01723 
01724     return HAL_OK;
01725   }
01726   else
01727   {
01728     return HAL_BUSY;
01729   }
01730 }
01731 /**
01732   * @brief  Write an amount of data in blocking mode to a specific memory address
01733   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01734   *                the configuration information for the specified FMPI2C.
01735   * @param  DevAddress Target device address The device 7 bits address value
01736   *         in datasheet must be shifted to the left before calling the interface
01737   * @param  MemAddress Internal memory address
01738   * @param  MemAddSize Size of internal memory address
01739   * @param  pData Pointer to data buffer
01740   * @param  Size Amount of data to be sent
01741   * @param  Timeout Timeout duration
01742   * @retval HAL status
01743   */
01744 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
01745 {
01746   uint32_t tickstart = 0U;
01747 
01748   /* Check the parameters */
01749   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
01750 
01751   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01752   {
01753     if ((pData == NULL) || (Size == 0U))
01754     {
01755       return  HAL_ERROR;
01756     }
01757 
01758     /* Process Locked */
01759     __HAL_LOCK(hfmpi2c);
01760 
01761     /* Init tickstart for timeout management*/
01762     tickstart = HAL_GetTick();
01763 
01764     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
01765     {
01766       return HAL_TIMEOUT;
01767     }
01768 
01769     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
01770     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MEM;
01771     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01772 
01773     /* Prepare transfer parameters */
01774     hfmpi2c->pBuffPtr  = pData;
01775     hfmpi2c->XferCount = Size;
01776     hfmpi2c->XferISR   = NULL;
01777 
01778     /* Send Slave Address and Memory Address */
01779     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
01780     {
01781       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01782       {
01783         /* Process Unlocked */
01784         __HAL_UNLOCK(hfmpi2c);
01785         return HAL_ERROR;
01786       }
01787       else
01788       {
01789         /* Process Unlocked */
01790         __HAL_UNLOCK(hfmpi2c);
01791         return HAL_TIMEOUT;
01792       }
01793     }
01794 
01795     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
01796     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01797     {
01798       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01799       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
01800     }
01801     else
01802     {
01803       hfmpi2c->XferSize = hfmpi2c->XferCount;
01804       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
01805     }
01806 
01807     do
01808     {
01809       /* Wait until TXIS flag is set */
01810       if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01811       {
01812         if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01813         {
01814           return HAL_ERROR;
01815         }
01816         else
01817         {
01818           return HAL_TIMEOUT;
01819         }
01820       }
01821 
01822       /* Write data to TXDR */
01823       hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
01824       hfmpi2c->XferCount--;
01825       hfmpi2c->XferSize--;
01826 
01827       if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
01828       {
01829         /* Wait until TCR flag is set */
01830         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
01831         {
01832           return HAL_TIMEOUT;
01833         }
01834 
01835         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01836         {
01837           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01838           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
01839         }
01840         else
01841         {
01842           hfmpi2c->XferSize = hfmpi2c->XferCount;
01843           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
01844         }
01845       }
01846 
01847     }
01848     while (hfmpi2c->XferCount > 0U);
01849 
01850     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01851     /* Wait until STOPF flag is reset */
01852     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01853     {
01854       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01855       {
01856         return HAL_ERROR;
01857       }
01858       else
01859       {
01860         return HAL_TIMEOUT;
01861       }
01862     }
01863 
01864     /* Clear STOP Flag */
01865     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
01866 
01867     /* Clear Configuration Register 2 */
01868     FMPI2C_RESET_CR2(hfmpi2c);
01869 
01870     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
01871     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
01872 
01873     /* Process Unlocked */
01874     __HAL_UNLOCK(hfmpi2c);
01875 
01876     return HAL_OK;
01877   }
01878   else
01879   {
01880     return HAL_BUSY;
01881   }
01882 }
01883 
01884 /**
01885   * @brief  Read an amount of data in blocking mode from a specific memory address
01886   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
01887   *                the configuration information for the specified FMPI2C.
01888   * @param  DevAddress Target device address The device 7 bits address value
01889   *         in datasheet must be shifted to the left before calling the interface
01890   * @param  MemAddress Internal memory address
01891   * @param  MemAddSize Size of internal memory address
01892   * @param  pData Pointer to data buffer
01893   * @param  Size Amount of data to be sent
01894   * @param  Timeout Timeout duration
01895   * @retval HAL status
01896   */
01897 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
01898 {
01899   uint32_t tickstart = 0U;
01900 
01901   /* Check the parameters */
01902   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
01903 
01904   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
01905   {
01906     if ((pData == NULL) || (Size == 0U))
01907     {
01908       return  HAL_ERROR;
01909     }
01910 
01911     /* Process Locked */
01912     __HAL_LOCK(hfmpi2c);
01913 
01914     /* Init tickstart for timeout management*/
01915     tickstart = HAL_GetTick();
01916 
01917     if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
01918     {
01919       return HAL_TIMEOUT;
01920     }
01921 
01922     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
01923     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MEM;
01924     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
01925 
01926     /* Prepare transfer parameters */
01927     hfmpi2c->pBuffPtr  = pData;
01928     hfmpi2c->XferCount = Size;
01929     hfmpi2c->XferISR   = NULL;
01930 
01931     /* Send Slave Address and Memory Address */
01932     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
01933     {
01934       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
01935       {
01936         /* Process Unlocked */
01937         __HAL_UNLOCK(hfmpi2c);
01938         return HAL_ERROR;
01939       }
01940       else
01941       {
01942         /* Process Unlocked */
01943         __HAL_UNLOCK(hfmpi2c);
01944         return HAL_TIMEOUT;
01945       }
01946     }
01947 
01948     /* Send Slave Address */
01949     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
01950     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01951     {
01952       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01953       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
01954     }
01955     else
01956     {
01957       hfmpi2c->XferSize = hfmpi2c->XferCount;
01958       FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
01959     }
01960 
01961     do
01962     {
01963       /* Wait until RXNE flag is set */
01964       if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
01965       {
01966         return HAL_TIMEOUT;
01967       }
01968 
01969       /* Read data from RXDR */
01970       (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
01971       hfmpi2c->XferSize--;
01972       hfmpi2c->XferCount--;
01973 
01974       if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
01975       {
01976         /* Wait until TCR flag is set */
01977         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
01978         {
01979           return HAL_TIMEOUT;
01980         }
01981 
01982         if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
01983         {
01984           hfmpi2c->XferSize = MAX_NBYTE_SIZE;
01985           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
01986         }
01987         else
01988         {
01989           hfmpi2c->XferSize = hfmpi2c->XferCount;
01990           FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
01991         }
01992       }
01993     }
01994     while (hfmpi2c->XferCount > 0U);
01995 
01996     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01997     /* Wait until STOPF flag is reset */
01998     if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
01999     {
02000       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
02001       {
02002         return HAL_ERROR;
02003       }
02004       else
02005       {
02006         return HAL_TIMEOUT;
02007       }
02008     }
02009 
02010     /* Clear STOP Flag */
02011     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02012 
02013     /* Clear Configuration Register 2 */
02014     FMPI2C_RESET_CR2(hfmpi2c);
02015 
02016     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02017     hfmpi2c->Mode  = HAL_FMPI2C_MODE_NONE;
02018 
02019     /* Process Unlocked */
02020     __HAL_UNLOCK(hfmpi2c);
02021 
02022     return HAL_OK;
02023   }
02024   else
02025   {
02026     return HAL_BUSY;
02027   }
02028 }
02029 /**
02030   * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
02031   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02032   *                the configuration information for the specified FMPI2C.
02033   * @param  DevAddress Target device address The device 7 bits address value
02034   *         in datasheet must be shifted to the left before calling the interface
02035   * @param  MemAddress Internal memory address
02036   * @param  MemAddSize Size of internal memory address
02037   * @param  pData Pointer to data buffer
02038   * @param  Size Amount of data to be sent
02039   * @retval HAL status
02040   */
02041 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02042 {
02043   uint32_t tickstart = 0U;
02044   uint32_t xfermode = 0U;
02045 
02046   /* Check the parameters */
02047   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02048 
02049   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02050   {
02051     if ((pData == NULL) || (Size == 0U))
02052     {
02053       return  HAL_ERROR;
02054     }
02055 
02056     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02057     {
02058       return HAL_BUSY;
02059     }
02060 
02061     /* Process Locked */
02062     __HAL_LOCK(hfmpi2c);
02063 
02064     /* Init tickstart for timeout management*/
02065     tickstart = HAL_GetTick();
02066 
02067     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
02068     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02069     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02070 
02071     /* Prepare transfer parameters */
02072     hfmpi2c->pBuffPtr    = pData;
02073     hfmpi2c->XferCount   = Size;
02074     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02075     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02076 
02077     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02078     {
02079       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02080       xfermode = FMPI2C_RELOAD_MODE;
02081     }
02082     else
02083     {
02084       hfmpi2c->XferSize = hfmpi2c->XferCount;
02085       xfermode = FMPI2C_AUTOEND_MODE;
02086     }
02087 
02088     /* Send Slave Address and Memory Address */
02089     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
02090     {
02091       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
02092       {
02093         /* Process Unlocked */
02094         __HAL_UNLOCK(hfmpi2c);
02095         return HAL_ERROR;
02096       }
02097       else
02098       {
02099         /* Process Unlocked */
02100         __HAL_UNLOCK(hfmpi2c);
02101         return HAL_TIMEOUT;
02102       }
02103     }
02104 
02105     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02106     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
02107 
02108     /* Process Unlocked */
02109     __HAL_UNLOCK(hfmpi2c);
02110 
02111     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02112               to avoid the risk of FMPI2C interrupt handle execution before current
02113               process unlock */
02114 
02115     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
02116     /* possible to enable all of these */
02117     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
02118     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02119 
02120     return HAL_OK;
02121   }
02122   else
02123   {
02124     return HAL_BUSY;
02125   }
02126 }
02127 
02128 /**
02129   * @brief  Read an amount of data in non-blocking mode with Interrupt from a specific memory address
02130   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02131   *                the configuration information for the specified FMPI2C.
02132   * @param  DevAddress Target device address The device 7 bits address value
02133   *         in datasheet must be shifted to the left before calling the interface
02134   * @param  MemAddress Internal memory address
02135   * @param  MemAddSize Size of internal memory address
02136   * @param  pData Pointer to data buffer
02137   * @param  Size Amount of data to be sent
02138   * @retval HAL status
02139   */
02140 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02141 {
02142   uint32_t tickstart = 0U;
02143   uint32_t xfermode = 0U;
02144 
02145   /* Check the parameters */
02146   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02147 
02148   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02149   {
02150     if ((pData == NULL) || (Size == 0U))
02151     {
02152       return  HAL_ERROR;
02153     }
02154 
02155     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02156     {
02157       return HAL_BUSY;
02158     }
02159 
02160     /* Process Locked */
02161     __HAL_LOCK(hfmpi2c);
02162 
02163     /* Init tickstart for timeout management*/
02164     tickstart = HAL_GetTick();
02165 
02166     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02167     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02168     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02169 
02170     /* Prepare transfer parameters */
02171     hfmpi2c->pBuffPtr    = pData;
02172     hfmpi2c->XferCount   = Size;
02173     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02174     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02175 
02176     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02177     {
02178       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02179       xfermode = FMPI2C_RELOAD_MODE;
02180     }
02181     else
02182     {
02183       hfmpi2c->XferSize = hfmpi2c->XferCount;
02184       xfermode = FMPI2C_AUTOEND_MODE;
02185     }
02186 
02187     /* Send Slave Address and Memory Address */
02188     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
02189     {
02190       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
02191       {
02192         /* Process Unlocked */
02193         __HAL_UNLOCK(hfmpi2c);
02194         return HAL_ERROR;
02195       }
02196       else
02197       {
02198         /* Process Unlocked */
02199         __HAL_UNLOCK(hfmpi2c);
02200         return HAL_TIMEOUT;
02201       }
02202     }
02203 
02204     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02205     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
02206 
02207     /* Process Unlocked */
02208     __HAL_UNLOCK(hfmpi2c);
02209 
02210     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02211               to avoid the risk of FMPI2C interrupt handle execution before current
02212               process unlock */
02213 
02214     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
02215     /* possible to enable all of these */
02216     /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
02217     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
02218 
02219     return HAL_OK;
02220   }
02221   else
02222   {
02223     return HAL_BUSY;
02224   }
02225 }
02226 /**
02227   * @brief  Write an amount of data in non-blocking mode with DMA to a specific memory address
02228   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02229   *                the configuration information for the specified FMPI2C.
02230   * @param  DevAddress Target device address The device 7 bits address value
02231   *         in datasheet must be shifted to the left before calling the interface
02232   * @param  MemAddress Internal memory address
02233   * @param  MemAddSize Size of internal memory address
02234   * @param  pData Pointer to data buffer
02235   * @param  Size Amount of data to be sent
02236   * @retval HAL status
02237   */
02238 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02239 {
02240   uint32_t tickstart = 0U;
02241   uint32_t xfermode = 0U;
02242 
02243   /* Check the parameters */
02244   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02245 
02246   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02247   {
02248     if ((pData == NULL) || (Size == 0U))
02249     {
02250       return  HAL_ERROR;
02251     }
02252 
02253     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02254     {
02255       return HAL_BUSY;
02256     }
02257 
02258     /* Process Locked */
02259     __HAL_LOCK(hfmpi2c);
02260 
02261     /* Init tickstart for timeout management*/
02262     tickstart = HAL_GetTick();
02263 
02264     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_TX;
02265     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02266     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02267 
02268     /* Prepare transfer parameters */
02269     hfmpi2c->pBuffPtr    = pData;
02270     hfmpi2c->XferCount   = Size;
02271     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02272     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
02273 
02274     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02275     {
02276       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02277       xfermode = FMPI2C_RELOAD_MODE;
02278     }
02279     else
02280     {
02281       hfmpi2c->XferSize = hfmpi2c->XferCount;
02282       xfermode = FMPI2C_AUTOEND_MODE;
02283     }
02284 
02285     /* Send Slave Address and Memory Address */
02286     if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
02287     {
02288       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
02289       {
02290         /* Process Unlocked */
02291         __HAL_UNLOCK(hfmpi2c);
02292         return HAL_ERROR;
02293       }
02294       else
02295       {
02296         /* Process Unlocked */
02297         __HAL_UNLOCK(hfmpi2c);
02298         return HAL_TIMEOUT;
02299       }
02300     }
02301 
02302     /* Set the FMPI2C DMA transfer complete callback */
02303     hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
02304 
02305     /* Set the DMA error callback */
02306     hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
02307 
02308     /* Set the unused DMA callbacks to NULL */
02309     hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
02310     hfmpi2c->hdmatx->XferAbortCallback = NULL;
02311 
02312     /* Enable the DMA stream */
02313     HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
02314 
02315     /* Send Slave Address */
02316     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02317     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
02318 
02319     /* Update XferCount value */
02320     hfmpi2c->XferCount -= hfmpi2c->XferSize;
02321 
02322     /* Process Unlocked */
02323     __HAL_UNLOCK(hfmpi2c);
02324 
02325     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02326               to avoid the risk of FMPI2C interrupt handle execution before current
02327               process unlock */
02328     /* Enable ERR and NACK interrupts */
02329     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
02330 
02331     /* Enable DMA Request */
02332     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
02333 
02334     return HAL_OK;
02335   }
02336   else
02337   {
02338     return HAL_BUSY;
02339   }
02340 }
02341 
02342 /**
02343   * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
02344   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02345   *                the configuration information for the specified FMPI2C.
02346   * @param  DevAddress Target device address The device 7 bits address value
02347   *         in datasheet must be shifted to the left before calling the interface
02348   * @param  MemAddress Internal memory address
02349   * @param  MemAddSize Size of internal memory address
02350   * @param  pData Pointer to data buffer
02351   * @param  Size Amount of data to be read
02352   * @retval HAL status
02353   */
02354 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
02355 {
02356   uint32_t tickstart = 0U;
02357   uint32_t xfermode = 0U;
02358 
02359   /* Check the parameters */
02360   assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
02361 
02362   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02363   {
02364     if ((pData == NULL) || (Size == 0U))
02365     {
02366       return  HAL_ERROR;
02367     }
02368 
02369     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02370     {
02371       return HAL_BUSY;
02372     }
02373 
02374     /* Process Locked */
02375     __HAL_LOCK(hfmpi2c);
02376 
02377     /* Init tickstart for timeout management*/
02378     tickstart = HAL_GetTick();
02379 
02380     hfmpi2c->State       = HAL_FMPI2C_STATE_BUSY_RX;
02381     hfmpi2c->Mode        = HAL_FMPI2C_MODE_MEM;
02382     hfmpi2c->ErrorCode   = HAL_FMPI2C_ERROR_NONE;
02383 
02384     /* Prepare transfer parameters */
02385     hfmpi2c->pBuffPtr    = pData;
02386     hfmpi2c->XferCount   = Size;
02387     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
02388     hfmpi2c->XferISR     = FMPI2C_Master_ISR_DMA;
02389 
02390     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02391     {
02392       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02393       xfermode = FMPI2C_RELOAD_MODE;
02394     }
02395     else
02396     {
02397       hfmpi2c->XferSize = hfmpi2c->XferCount;
02398       xfermode = FMPI2C_AUTOEND_MODE;
02399     }
02400 
02401     /* Send Slave Address and Memory Address */
02402     if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
02403     {
02404       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
02405       {
02406         /* Process Unlocked */
02407         __HAL_UNLOCK(hfmpi2c);
02408         return HAL_ERROR;
02409       }
02410       else
02411       {
02412         /* Process Unlocked */
02413         __HAL_UNLOCK(hfmpi2c);
02414         return HAL_TIMEOUT;
02415       }
02416     }
02417 
02418     /* Set the FMPI2C DMA transfer complete callback */
02419     hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
02420 
02421     /* Set the DMA error callback */
02422     hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
02423 
02424     /* Set the unused DMA callbacks to NULL */
02425     hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
02426     hfmpi2c->hdmarx->XferAbortCallback = NULL;
02427 
02428     /* Enable the DMA stream */
02429     HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
02430 
02431     /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
02432     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
02433 
02434     /* Update XferCount value */
02435     hfmpi2c->XferCount -= hfmpi2c->XferSize;
02436 
02437     /* Process Unlocked */
02438     __HAL_UNLOCK(hfmpi2c);
02439 
02440     /* Enable DMA Request */
02441     hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
02442 
02443     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02444               to avoid the risk of FMPI2C interrupt handle execution before current
02445               process unlock */
02446     /* Enable ERR and NACK interrupts */
02447     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
02448 
02449     return HAL_OK;
02450   }
02451   else
02452   {
02453     return HAL_BUSY;
02454   }
02455 }
02456 
02457 /**
02458   * @brief  Checks if target device is ready for communication.
02459   * @note   This function is used with Memory devices
02460   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02461   *                the configuration information for the specified FMPI2C.
02462   * @param  DevAddress Target device address The device 7 bits address value
02463   *         in datasheet must be shifted to the left before calling the interface
02464   * @param  Trials Number of trials
02465   * @param  Timeout Timeout duration
02466   * @retval HAL status
02467   */
02468 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
02469 {
02470   uint32_t tickstart = 0U;
02471 
02472   __IO uint32_t FMPI2C_Trials = 0U;
02473 
02474   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02475   {
02476     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
02477     {
02478       return HAL_BUSY;
02479     }
02480 
02481     /* Process Locked */
02482     __HAL_LOCK(hfmpi2c);
02483 
02484     hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
02485     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02486 
02487     do
02488     {
02489       /* Generate Start */
02490       hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress);
02491 
02492       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
02493       /* Wait until STOPF flag is set or a NACK flag is set*/
02494       tickstart = HAL_GetTick();
02495       while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) && (hfmpi2c->State != HAL_FMPI2C_STATE_TIMEOUT))
02496       {
02497         if (Timeout != HAL_MAX_DELAY)
02498         {
02499           if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
02500           {
02501             /* Device is ready */
02502             hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02503             /* Process Unlocked */
02504             __HAL_UNLOCK(hfmpi2c);
02505             return HAL_TIMEOUT;
02506           }
02507         }
02508       }
02509 
02510       /* Check if the NACKF flag has not been set */
02511       if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
02512       {
02513         /* Wait until STOPF flag is reset */
02514         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
02515         {
02516           return HAL_TIMEOUT;
02517         }
02518 
02519         /* Clear STOP Flag */
02520         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02521 
02522         /* Device is ready */
02523         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02524 
02525         /* Process Unlocked */
02526         __HAL_UNLOCK(hfmpi2c);
02527 
02528         return HAL_OK;
02529       }
02530       else
02531       {
02532         /* Wait until STOPF flag is reset */
02533         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
02534         {
02535           return HAL_TIMEOUT;
02536         }
02537 
02538         /* Clear NACK Flag */
02539         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
02540 
02541         /* Clear STOP Flag, auto generated with autoend*/
02542         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02543       }
02544 
02545       /* Check if the maximum allowed number of trials has been reached */
02546       if (FMPI2C_Trials++ == Trials)
02547       {
02548         /* Generate Stop */
02549         hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
02550 
02551         /* Wait until STOPF flag is reset */
02552         if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
02553         {
02554           return HAL_TIMEOUT;
02555         }
02556 
02557         /* Clear STOP Flag */
02558         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
02559       }
02560     }
02561     while (FMPI2C_Trials < Trials);
02562 
02563     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02564 
02565     /* Process Unlocked */
02566     __HAL_UNLOCK(hfmpi2c);
02567 
02568     return HAL_TIMEOUT;
02569   }
02570   else
02571   {
02572     return HAL_BUSY;
02573   }
02574 }
02575 
02576 /**
02577   * @brief  Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
02578   * @note   This interface allow to manage repeated start condition when a direction change during transfer
02579   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02580   *                the configuration information for the specified FMPI2C.
02581   * @param  DevAddress Target device address The device 7 bits address value
02582   *         in datasheet must be shifted to the left before calling the interface
02583   * @param  pData Pointer to data buffer
02584   * @param  Size Amount of data to be sent
02585   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
02586   * @retval HAL status
02587   */
02588 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
02589 {
02590   uint32_t xfermode = 0U;
02591   uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
02592 
02593   /* Check the parameters */
02594   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
02595 
02596   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02597   {
02598     /* Process Locked */
02599     __HAL_LOCK(hfmpi2c);
02600 
02601     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX;
02602     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
02603     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02604 
02605     /* Prepare transfer parameters */
02606     hfmpi2c->pBuffPtr    = pData;
02607     hfmpi2c->XferCount   = Size;
02608     hfmpi2c->XferOptions = XferOptions;
02609     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02610 
02611     /* If size > MAX_NBYTE_SIZE, use reload mode */
02612     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02613     {
02614       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02615       xfermode = FMPI2C_RELOAD_MODE;
02616     }
02617     else
02618     {
02619       hfmpi2c->XferSize = hfmpi2c->XferCount;
02620       xfermode = hfmpi2c->XferOptions;
02621     }
02622 
02623     /* If transfer direction not change, do not generate Restart Condition */
02624     /* Mean Previous state is same as current state */
02625     if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX)
02626     {
02627       xferrequest = FMPI2C_NO_STARTSTOP;
02628     }
02629 
02630     /* Send Slave Address and set NBYTES to write */
02631     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest);
02632 
02633     /* Process Unlocked */
02634     __HAL_UNLOCK(hfmpi2c);
02635 
02636     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02637               to avoid the risk of FMPI2C interrupt handle execution before current
02638               process unlock */
02639     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02640 
02641     return HAL_OK;
02642   }
02643   else
02644   {
02645     return HAL_BUSY;
02646   }
02647 }
02648 
02649 /**
02650   * @brief  Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt
02651   * @note   This interface allow to manage repeated start condition when a direction change during transfer
02652   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02653   *                the configuration information for the specified FMPI2C.
02654   * @param  DevAddress Target device address The device 7 bits address value
02655   *         in datasheet must be shifted to the left before calling the interface
02656   * @param  pData Pointer to data buffer
02657   * @param  Size Amount of data to be sent
02658   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
02659   * @retval HAL status
02660   */
02661 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
02662 {
02663   uint32_t xfermode = 0U;
02664   uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
02665 
02666   /* Check the parameters */
02667   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
02668 
02669   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02670   {
02671     /* Process Locked */
02672     __HAL_LOCK(hfmpi2c);
02673 
02674     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX;
02675     hfmpi2c->Mode      = HAL_FMPI2C_MODE_MASTER;
02676     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02677 
02678     /* Prepare transfer parameters */
02679     hfmpi2c->pBuffPtr    = pData;
02680     hfmpi2c->XferCount   = Size;
02681     hfmpi2c->XferOptions = XferOptions;
02682     hfmpi2c->XferISR     = FMPI2C_Master_ISR_IT;
02683 
02684     /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
02685     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
02686     {
02687       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
02688       xfermode = FMPI2C_RELOAD_MODE;
02689     }
02690     else
02691     {
02692       hfmpi2c->XferSize = hfmpi2c->XferCount;
02693       xfermode = hfmpi2c->XferOptions;
02694     }
02695 
02696     /* If transfer direction not change, do not generate Restart Condition */
02697     /* Mean Previous state is same as current state */
02698     if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX)
02699     {
02700       xferrequest = FMPI2C_NO_STARTSTOP;
02701     }
02702 
02703     /* Send Slave Address and set NBYTES to read */
02704     FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest);
02705 
02706     /* Process Unlocked */
02707     __HAL_UNLOCK(hfmpi2c);
02708 
02709     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02710               to avoid the risk of FMPI2C interrupt handle execution before current
02711               process unlock */
02712     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
02713 
02714     return HAL_OK;
02715   }
02716   else
02717   {
02718     return HAL_BUSY;
02719   }
02720 }
02721 
02722 /**
02723   * @brief  Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
02724   * @note   This interface allow to manage repeated start condition when a direction change during transfer
02725   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02726   *                the configuration information for the specified FMPI2C.
02727   * @param  pData Pointer to data buffer
02728   * @param  Size Amount of data to be sent
02729   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
02730   * @retval HAL status
02731   */
02732 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
02733 {
02734   /* Check the parameters */
02735   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
02736 
02737   if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
02738   {
02739     if ((pData == NULL) || (Size == 0U))
02740     {
02741       return  HAL_ERROR;
02742     }
02743 
02744     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
02745     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
02746 
02747     /* Process Locked */
02748     __HAL_LOCK(hfmpi2c);
02749 
02750     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
02751     /* and then toggle the HAL slave RX state to TX state */
02752     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
02753     {
02754       /* Disable associated Interrupts */
02755       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
02756     }
02757 
02758     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
02759     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
02760     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02761 
02762     /* Enable Address Acknowledge */
02763     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
02764 
02765     /* Prepare transfer parameters */
02766     hfmpi2c->pBuffPtr    = pData;
02767     hfmpi2c->XferCount   = Size;
02768     hfmpi2c->XferSize    = hfmpi2c->XferCount;
02769     hfmpi2c->XferOptions = XferOptions;
02770     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
02771 
02772     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
02773     {
02774       /* Clear ADDR flag after prepare the transfer parameters */
02775       /* This action will generate an acknowledge to the Master */
02776       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
02777     }
02778 
02779     /* Process Unlocked */
02780     __HAL_UNLOCK(hfmpi2c);
02781 
02782     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02783     to avoid the risk of FMPI2C interrupt handle execution before current
02784     process unlock */
02785     /* REnable ADDR interrupt */
02786     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
02787 
02788     return HAL_OK;
02789   }
02790   else
02791   {
02792     return HAL_ERROR;
02793   }
02794 }
02795 
02796 /**
02797   * @brief  Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
02798   * @note   This interface allow to manage repeated start condition when a direction change during transfer
02799   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02800   *                the configuration information for the specified FMPI2C.
02801   * @param  pData Pointer to data buffer
02802   * @param  Size Amount of data to be sent
02803   * @param  XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
02804   * @retval HAL status
02805   */
02806 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
02807 {
02808   /* Check the parameters */
02809   assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
02810 
02811   if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
02812   {
02813     if ((pData == NULL) || (Size == 0U))
02814     {
02815       return  HAL_ERROR;
02816     }
02817 
02818     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
02819     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
02820 
02821     /* Process Locked */
02822     __HAL_LOCK(hfmpi2c);
02823 
02824     /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
02825     /* and then toggle the HAL slave TX state to RX state */
02826     if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
02827     {
02828       /* Disable associated Interrupts */
02829       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02830     }
02831 
02832     hfmpi2c->State     = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
02833     hfmpi2c->Mode      = HAL_FMPI2C_MODE_SLAVE;
02834     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
02835 
02836     /* Enable Address Acknowledge */
02837     hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
02838 
02839     /* Prepare transfer parameters */
02840     hfmpi2c->pBuffPtr    = pData;
02841     hfmpi2c->XferCount   = Size;
02842     hfmpi2c->XferSize    = hfmpi2c->XferCount;
02843     hfmpi2c->XferOptions = XferOptions;
02844     hfmpi2c->XferISR     = FMPI2C_Slave_ISR_IT;
02845 
02846     if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
02847     {
02848       /* Clear ADDR flag after prepare the transfer parameters */
02849       /* This action will generate an acknowledge to the Master */
02850       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
02851     }
02852 
02853     /* Process Unlocked */
02854     __HAL_UNLOCK(hfmpi2c);
02855 
02856     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02857     to avoid the risk of FMPI2C interrupt handle execution before current
02858     process unlock */
02859     /* REnable ADDR interrupt */
02860     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
02861 
02862     return HAL_OK;
02863   }
02864   else
02865   {
02866     return HAL_ERROR;
02867   }
02868 }
02869 
02870 /**
02871   * @brief  Enable the Address listen mode with Interrupt.
02872   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02873   *                the configuration information for the specified FMPI2C.
02874   * @retval HAL status
02875   */
02876 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
02877 {
02878   if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
02879   {
02880     hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
02881     hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
02882 
02883     /* Enable the Address Match interrupt */
02884     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
02885 
02886     return HAL_OK;
02887   }
02888   else
02889   {
02890     return HAL_BUSY;
02891   }
02892 }
02893 
02894 /**
02895   * @brief  Disable the Address listen mode with Interrupt.
02896   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02897   *                the configuration information for the specified FMPI2C
02898   * @retval HAL status
02899   */
02900 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
02901 {
02902   /* Declaration of tmp to prevent undefined behavior of volatile usage */
02903   uint32_t tmp;
02904 
02905   /* Disable Address listen mode only if a transfer is not ongoing */
02906   if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
02907   {
02908     tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK;
02909     hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode);
02910     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
02911     hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
02912     hfmpi2c->XferISR = NULL;
02913 
02914     /* Disable the Address Match interrupt */
02915     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
02916 
02917     return HAL_OK;
02918   }
02919   else
02920   {
02921     return HAL_BUSY;
02922   }
02923 }
02924 
02925 /**
02926   * @brief  Abort a master FMPI2C IT or DMA process communication with Interrupt.
02927   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02928   *                the configuration information for the specified FMPI2C.
02929   * @param  DevAddress Target device address The device 7 bits address value
02930   *         in datasheet must be shifted to the left before calling the interface
02931   * @retval HAL status
02932   */
02933 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
02934 {
02935   if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER)
02936   {
02937     /* Process Locked */
02938     __HAL_LOCK(hfmpi2c);
02939 
02940     /* Disable Interrupts */
02941     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
02942     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
02943 
02944     /* Set State at HAL_FMPI2C_STATE_ABORT */
02945     hfmpi2c->State = HAL_FMPI2C_STATE_ABORT;
02946 
02947     /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */
02948     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
02949     FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP);
02950 
02951     /* Process Unlocked */
02952     __HAL_UNLOCK(hfmpi2c);
02953 
02954     /* Note : The FMPI2C interrupts must be enabled after unlocking current process
02955               to avoid the risk of FMPI2C interrupt handle execution before current
02956               process unlock */
02957     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
02958 
02959     return HAL_OK;
02960   }
02961   else
02962   {
02963     /* Wrong usage of abort function */
02964     /* This function should be used only in case of abort monitored by master device */
02965     return HAL_ERROR;
02966   }
02967 }
02968 
02969 /**
02970   * @}
02971   */
02972 
02973 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
02974  * @{
02975  */
02976 
02977 /**
02978   * @brief  This function handles FMPI2C event interrupt request.
02979   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02980   *                the configuration information for the specified FMPI2C.
02981   * @retval None
02982   */
02983 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
02984 {
02985   /* Get current IT Flags and IT sources value */
02986   uint32_t itflags   = READ_REG(hfmpi2c->Instance->ISR);
02987   uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
02988 
02989   /* FMPI2C events treatment -------------------------------------*/
02990   if (hfmpi2c->XferISR != NULL)
02991   {
02992     hfmpi2c->XferISR(hfmpi2c, itflags, itsources);
02993   }
02994 }
02995 
02996 /**
02997   * @brief  This function handles FMPI2C error interrupt request.
02998   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
02999   *                the configuration information for the specified FMPI2C.
03000   * @retval None
03001   */
03002 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
03003 {
03004   uint32_t itflags   = READ_REG(hfmpi2c->Instance->ISR);
03005   uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
03006 
03007   /* FMPI2C Bus error interrupt occurred ------------------------------------*/
03008   if (((itflags & FMPI2C_FLAG_BERR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
03009   {
03010     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
03011 
03012     /* Clear BERR flag */
03013     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
03014   }
03015 
03016   /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
03017   if (((itflags & FMPI2C_FLAG_OVR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
03018   {
03019     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
03020 
03021     /* Clear OVR flag */
03022     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
03023   }
03024 
03025   /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
03026   if (((itflags & FMPI2C_FLAG_ARLO) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
03027   {
03028     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
03029 
03030     /* Clear ARLO flag */
03031     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
03032   }
03033 
03034   /* Call the Error Callback in case of Error detected */
03035   if ((hfmpi2c->ErrorCode & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) !=  HAL_FMPI2C_ERROR_NONE)
03036   {
03037     FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
03038   }
03039 }
03040 
03041 /**
03042   * @brief  Master Tx Transfer completed callback.
03043   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03044   *                the configuration information for the specified FMPI2C.
03045   * @retval None
03046   */
03047 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03048 {
03049   /* Prevent unused argument(s) compilation warning */
03050   UNUSED(hfmpi2c);
03051 
03052   /* NOTE : This function should not be modified, when the callback is needed,
03053             the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file
03054    */
03055 }
03056 
03057 /**
03058   * @brief  Master Rx Transfer completed callback.
03059   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03060   *                the configuration information for the specified FMPI2C.
03061   * @retval None
03062   */
03063 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03064 {
03065   /* Prevent unused argument(s) compilation warning */
03066   UNUSED(hfmpi2c);
03067 
03068   /* NOTE : This function should not be modified, when the callback is needed,
03069             the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file
03070    */
03071 }
03072 
03073 /** @brief  Slave Tx Transfer completed callback.
03074   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03075   *                the configuration information for the specified FMPI2C.
03076   * @retval None
03077   */
03078 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03079 {
03080   /* Prevent unused argument(s) compilation warning */
03081   UNUSED(hfmpi2c);
03082 
03083   /* NOTE : This function should not be modified, when the callback is needed,
03084             the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file
03085    */
03086 }
03087 
03088 /**
03089   * @brief  Slave Rx Transfer completed callback.
03090   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03091   *                the configuration information for the specified FMPI2C.
03092   * @retval None
03093   */
03094 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03095 {
03096   /* Prevent unused argument(s) compilation warning */
03097   UNUSED(hfmpi2c);
03098 
03099   /* NOTE : This function should not be modified, when the callback is needed,
03100             the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file
03101    */
03102 }
03103 
03104 /**
03105   * @brief  Slave Address Match callback.
03106   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03107   *                the configuration information for the specified FMPI2C.
03108   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION
03109   * @param  AddrMatchCode Address Match Code
03110   * @retval None
03111   */
03112 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
03113 {
03114   /* Prevent unused argument(s) compilation warning */
03115   UNUSED(hfmpi2c);
03116   UNUSED(TransferDirection);
03117   UNUSED(AddrMatchCode);
03118 
03119   /* NOTE : This function should not be modified, when the callback is needed,
03120             the HAL_FMPI2C_AddrCallback() could be implemented in the user file
03121    */
03122 }
03123 
03124 /**
03125   * @brief  Listen Complete callback.
03126   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03127   *                the configuration information for the specified FMPI2C.
03128   * @retval None
03129   */
03130 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03131 {
03132   /* Prevent unused argument(s) compilation warning */
03133   UNUSED(hfmpi2c);
03134 
03135   /* NOTE : This function should not be modified, when the callback is needed,
03136             the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file
03137    */
03138 }
03139 
03140 /**
03141   * @brief  Memory Tx Transfer completed callback.
03142   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03143   *                the configuration information for the specified FMPI2C.
03144   * @retval None
03145   */
03146 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03147 {
03148   /* Prevent unused argument(s) compilation warning */
03149   UNUSED(hfmpi2c);
03150 
03151   /* NOTE : This function should not be modified, when the callback is needed,
03152             the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file
03153    */
03154 }
03155 
03156 /**
03157   * @brief  Memory Rx Transfer completed callback.
03158   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03159   *                the configuration information for the specified FMPI2C.
03160   * @retval None
03161   */
03162 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03163 {
03164   /* Prevent unused argument(s) compilation warning */
03165   UNUSED(hfmpi2c);
03166 
03167   /* NOTE : This function should not be modified, when the callback is needed,
03168             the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file
03169    */
03170 }
03171 
03172 /**
03173   * @brief  FMPI2C error callback.
03174   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03175   *                the configuration information for the specified FMPI2C.
03176   * @retval None
03177   */
03178 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03179 {
03180   /* Prevent unused argument(s) compilation warning */
03181   UNUSED(hfmpi2c);
03182 
03183   /* NOTE : This function should not be modified, when the callback is needed,
03184             the HAL_FMPI2C_ErrorCallback could be implemented in the user file
03185    */
03186 }
03187 
03188 /**
03189   * @brief  FMPI2C abort callback.
03190   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03191   *                the configuration information for the specified FMPI2C.
03192   * @retval None
03193   */
03194 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
03195 {
03196   /* Prevent unused argument(s) compilation warning */
03197   UNUSED(hfmpi2c);
03198 
03199   /* NOTE : This function should not be modified, when the callback is needed,
03200             the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file
03201    */
03202 }
03203 
03204 /**
03205   * @}
03206   */
03207 
03208 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
03209  *  @brief   Peripheral State, Mode and Error functions
03210  *
03211 @verbatim
03212  ===============================================================================
03213             ##### Peripheral State, Mode and Error functions #####
03214  ===============================================================================
03215     [..]
03216     This subsection permit to get in run-time the status of the peripheral
03217     and the data flow.
03218 
03219 @endverbatim
03220   * @{
03221   */
03222 
03223 /**
03224   * @brief  Return the FMPI2C handle state.
03225   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03226   *                the configuration information for the specified FMPI2C.
03227   * @retval HAL state
03228   */
03229 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c)
03230 {
03231   /* Return FMPI2C handle state */
03232   return hfmpi2c->State;
03233 }
03234 
03235 /**
03236   * @brief  Returns the FMPI2C Master, Slave, Memory or no mode.
03237   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03238   *         the configuration information for FMPI2C module
03239   * @retval HAL mode
03240   */
03241 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c)
03242 {
03243   return hfmpi2c->Mode;
03244 }
03245 
03246 /**
03247 * @brief  Return the FMPI2C error code.
03248   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03249   *              the configuration information for the specified FMPI2C.
03250 * @retval FMPI2C Error Code
03251 */
03252 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c)
03253 {
03254   return hfmpi2c->ErrorCode;
03255 }
03256 
03257 /**
03258   * @}
03259   */
03260 
03261 /**
03262   * @}
03263   */
03264 
03265 /** @addtogroup FMPI2C_Private_Functions
03266   * @{
03267   */
03268 
03269 /**
03270   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
03271   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03272   *                the configuration information for the specified FMPI2C.
03273   * @param  ITFlags Interrupt flags to handle.
03274   * @param  ITSources Interrupt sources enabled.
03275   * @retval HAL status
03276   */
03277 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
03278 {
03279   uint16_t devaddress = 0U;
03280 
03281   /* Process Locked */
03282   __HAL_LOCK(hfmpi2c);
03283 
03284   if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
03285   {
03286     /* Clear NACK Flag */
03287     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03288 
03289     /* Set corresponding Error Code */
03290     /* No need to generate STOP, it is automatically done */
03291     /* Error callback will be send during stop flag treatment */
03292     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
03293 
03294     /* Flush TX register */
03295     FMPI2C_Flush_TXDR(hfmpi2c);
03296   }
03297   else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET))
03298   {
03299     /* Read data from RXDR */
03300     (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
03301     hfmpi2c->XferSize--;
03302     hfmpi2c->XferCount--;
03303   }
03304   else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET))
03305   {
03306     /* Write data to TXDR */
03307     hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
03308     hfmpi2c->XferSize--;
03309     hfmpi2c->XferCount--;
03310   }
03311   else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
03312   {
03313     if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
03314     {
03315       devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
03316 
03317       if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03318       {
03319         hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03320         FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
03321       }
03322       else
03323       {
03324         hfmpi2c->XferSize = hfmpi2c->XferCount;
03325         if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
03326         {
03327           FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP);
03328         }
03329         else
03330         {
03331           FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
03332         }
03333       }
03334     }
03335     else
03336     {
03337       /* Call TxCpltCallback() if no stop mode is set */
03338       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
03339       {
03340         /* Call FMPI2C Master Sequential complete process */
03341         FMPI2C_ITMasterSequentialCplt(hfmpi2c);
03342       }
03343       else
03344       {
03345         /* Wrong size Status regarding TCR flag event */
03346         /* Call the corresponding callback to inform upper layer of End of Transfer */
03347         FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
03348       }
03349     }
03350   }
03351   else if (((ITFlags & FMPI2C_FLAG_TC) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
03352   {
03353     if (hfmpi2c->XferCount == 0U)
03354     {
03355       if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
03356       {
03357         /* Generate a stop condition in case of no transfer option */
03358         if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
03359         {
03360           /* Generate Stop */
03361           hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
03362         }
03363         else
03364         {
03365           /* Call FMPI2C Master Sequential complete process */
03366           FMPI2C_ITMasterSequentialCplt(hfmpi2c);
03367         }
03368       }
03369     }
03370     else
03371     {
03372       /* Wrong size Status regarding TC flag event */
03373       /* Call the corresponding callback to inform upper layer of End of Transfer */
03374       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
03375     }
03376   }
03377 
03378   if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
03379   {
03380     /* Call FMPI2C Master complete process */
03381     FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
03382   }
03383 
03384   /* Process Unlocked */
03385   __HAL_UNLOCK(hfmpi2c);
03386 
03387   return HAL_OK;
03388 }
03389 
03390 /**
03391   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
03392   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03393   *                the configuration information for the specified FMPI2C.
03394   * @param  ITFlags Interrupt flags to handle.
03395   * @param  ITSources Interrupt sources enabled.
03396   * @retval HAL status
03397   */
03398 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
03399 {
03400   /* Process locked */
03401   __HAL_LOCK(hfmpi2c);
03402 
03403   if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
03404   {
03405     /* Check that FMPI2C transfer finished */
03406     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
03407     /* Mean XferCount == 0*/
03408     /* So clear Flag NACKF only */
03409     if (hfmpi2c->XferCount == 0U)
03410     {
03411       if (((hfmpi2c->XferOptions == FMPI2C_FIRST_AND_LAST_FRAME) || (hfmpi2c->XferOptions == FMPI2C_LAST_FRAME)) && \
03412           (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN))
03413       {
03414         /* Call FMPI2C Listen complete process */
03415         FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
03416       }
03417       else if ((hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) && (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
03418       {
03419         /* Clear NACK Flag */
03420         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03421 
03422         /* Flush TX register */
03423         FMPI2C_Flush_TXDR(hfmpi2c);
03424 
03425         /* Last Byte is Transmitted */
03426         /* Call FMPI2C Slave Sequential complete process */
03427         FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
03428       }
03429       else
03430       {
03431         /* Clear NACK Flag */
03432         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03433       }
03434     }
03435     else
03436     {
03437       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
03438       /* Clear NACK Flag */
03439       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03440 
03441       /* Set ErrorCode corresponding to a Non-Acknowledge */
03442       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
03443     }
03444   }
03445   else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET))
03446   {
03447     if (hfmpi2c->XferCount > 0U)
03448     {
03449       /* Read data from RXDR */
03450       (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
03451       hfmpi2c->XferSize--;
03452       hfmpi2c->XferCount--;
03453     }
03454 
03455     if ((hfmpi2c->XferCount == 0U) && \
03456         (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME))
03457     {
03458       /* Call FMPI2C Slave Sequential complete process */
03459       FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
03460     }
03461   }
03462   else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET))
03463   {
03464     FMPI2C_ITAddrCplt(hfmpi2c, ITFlags);
03465   }
03466   else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET))
03467   {
03468     /* Write data to TXDR only if XferCount not reach "0" */
03469     /* A TXIS flag can be set, during STOP treatment      */
03470     /* Check if all Datas have already been sent */
03471     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
03472     if (hfmpi2c->XferCount > 0U)
03473     {
03474       /* Write data to TXDR */
03475       hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
03476       hfmpi2c->XferCount--;
03477       hfmpi2c->XferSize--;
03478     }
03479     else
03480     {
03481       if ((hfmpi2c->XferOptions == FMPI2C_NEXT_FRAME) || (hfmpi2c->XferOptions == FMPI2C_FIRST_FRAME))
03482       {
03483         /* Last Byte is Transmitted */
03484         /* Call FMPI2C Slave Sequential complete process */
03485         FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
03486       }
03487     }
03488   }
03489 
03490   /* Check if STOPF is set */
03491   if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
03492   {
03493     /* Call FMPI2C Slave complete process */
03494     FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
03495   }
03496 
03497   /* Process Unlocked */
03498   __HAL_UNLOCK(hfmpi2c);
03499 
03500   return HAL_OK;
03501 }
03502 
03503 /**
03504   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
03505   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03506   *                the configuration information for the specified FMPI2C.
03507   * @param  ITFlags Interrupt flags to handle.
03508   * @param  ITSources Interrupt sources enabled.
03509   * @retval HAL status
03510   */
03511 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
03512 {
03513   uint16_t devaddress = 0U;
03514   uint32_t xfermode = 0U;
03515 
03516   /* Process Locked */
03517   __HAL_LOCK(hfmpi2c);
03518 
03519   if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
03520   {
03521     /* Clear NACK Flag */
03522     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03523 
03524     /* Set corresponding Error Code */
03525     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
03526 
03527     /* No need to generate STOP, it is automatically done */
03528     /* But enable STOP interrupt, to treat it */
03529     /* Error callback will be send during stop flag treatment */
03530     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
03531 
03532     /* Flush TX register */
03533     FMPI2C_Flush_TXDR(hfmpi2c);
03534   }
03535   else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
03536   {
03537     /* Disable TC interrupt */
03538     __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI);
03539 
03540     if (hfmpi2c->XferCount != 0U)
03541     {
03542       /* Recover Slave address */
03543       devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
03544 
03545       /* Prepare the new XferSize to transfer */
03546       if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
03547       {
03548         hfmpi2c->XferSize = MAX_NBYTE_SIZE;
03549         xfermode = FMPI2C_RELOAD_MODE;
03550       }
03551       else
03552       {
03553         hfmpi2c->XferSize = hfmpi2c->XferCount;
03554         xfermode = FMPI2C_AUTOEND_MODE;
03555       }
03556 
03557       /* Set the new XferSize in Nbytes register */
03558       FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
03559 
03560       /* Update XferCount value */
03561       hfmpi2c->XferCount -= hfmpi2c->XferSize;
03562 
03563       /* Enable DMA Request */
03564       if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
03565       {
03566         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
03567       }
03568       else
03569       {
03570         hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
03571       }
03572     }
03573     else
03574     {
03575       /* Wrong size Status regarding TCR flag event */
03576       /* Call the corresponding callback to inform upper layer of End of Transfer */
03577       FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
03578     }
03579   }
03580   else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
03581   {
03582     /* Call FMPI2C Master complete process */
03583     FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
03584   }
03585 
03586   /* Process Unlocked */
03587   __HAL_UNLOCK(hfmpi2c);
03588 
03589   return HAL_OK;
03590 }
03591 
03592 /**
03593   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
03594   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03595   *                the configuration information for the specified FMPI2C.
03596   * @param  ITFlags Interrupt flags to handle.
03597   * @param  ITSources Interrupt sources enabled.
03598   * @retval HAL status
03599   */
03600 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
03601 {
03602   /* Process locked */
03603   __HAL_LOCK(hfmpi2c);
03604 
03605   if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
03606   {
03607     /* Check that FMPI2C transfer finished */
03608     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
03609     /* Mean XferCount == 0 */
03610     /* So clear Flag NACKF only */
03611     if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c) == 0U)
03612     {
03613       /* Clear NACK Flag */
03614       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03615     }
03616     else
03617     {
03618       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
03619       /* Clear NACK Flag */
03620       __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03621 
03622       /* Set ErrorCode corresponding to a Non-Acknowledge */
03623       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
03624     }
03625   }
03626   else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET))
03627   {
03628     /* Clear ADDR flag */
03629     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
03630   }
03631   else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
03632   {
03633     /* Call FMPI2C Slave complete process */
03634     FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
03635   }
03636 
03637   /* Process Unlocked */
03638   __HAL_UNLOCK(hfmpi2c);
03639 
03640   return HAL_OK;
03641 }
03642 
03643 /**
03644   * @brief  Master sends target device address followed by internal memory address for write request.
03645   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03646   *                the configuration information for the specified FMPI2C.
03647   * @param  DevAddress Target device address The device 7 bits address value
03648   *         in datasheet must be shifted to the left before calling the interface
03649   * @param  MemAddress Internal memory address
03650   * @param  MemAddSize Size of internal memory address
03651   * @param  Timeout Timeout duration
03652   * @param  Tickstart Tick start value
03653   * @retval HAL status
03654   */
03655 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
03656 {
03657   FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
03658 
03659   /* Wait until TXIS flag is set */
03660   if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
03661   {
03662     if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
03663     {
03664       return HAL_ERROR;
03665     }
03666     else
03667     {
03668       return HAL_TIMEOUT;
03669     }
03670   }
03671 
03672   /* If Memory address size is 8Bit */
03673   if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
03674   {
03675     /* Send Memory Address */
03676     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
03677   }
03678   /* If Memory address size is 16Bit */
03679   else
03680   {
03681     /* Send MSB of Memory Address */
03682     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
03683 
03684     /* Wait until TXIS flag is set */
03685     if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
03686     {
03687       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
03688       {
03689         return HAL_ERROR;
03690       }
03691       else
03692       {
03693         return HAL_TIMEOUT;
03694       }
03695     }
03696 
03697     /* Send LSB of Memory Address */
03698     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
03699   }
03700 
03701   /* Wait until TCR flag is set */
03702   if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
03703   {
03704     return HAL_TIMEOUT;
03705   }
03706 
03707   return HAL_OK;
03708 }
03709 
03710 /**
03711   * @brief  Master sends target device address followed by internal memory address for read request.
03712   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
03713   *                the configuration information for the specified FMPI2C.
03714   * @param  DevAddress Target device address The device 7 bits address value
03715   *         in datasheet must be shifted to the left before calling the interface
03716   * @param  MemAddress Internal memory address
03717   * @param  MemAddSize Size of internal memory address
03718   * @param  Timeout Timeout duration
03719   * @param  Tickstart Tick start value
03720   * @retval HAL status
03721   */
03722 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
03723 {
03724   FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
03725 
03726   /* Wait until TXIS flag is set */
03727   if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
03728   {
03729     if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
03730     {
03731       return HAL_ERROR;
03732     }
03733     else
03734     {
03735       return HAL_TIMEOUT;
03736     }
03737   }
03738 
03739   /* If Memory address size is 8Bit */
03740   if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
03741   {
03742     /* Send Memory Address */
03743     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
03744   }
03745   /* If Memory address size is 16Bit */
03746   else
03747   {
03748     /* Send MSB of Memory Address */
03749     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
03750 
03751     /* Wait until TXIS flag is set */
03752     if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
03753     {
03754       if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
03755       {
03756         return HAL_ERROR;
03757       }
03758       else
03759       {
03760         return HAL_TIMEOUT;
03761       }
03762     }
03763 
03764     /* Send LSB of Memory Address */
03765     hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
03766   }
03767 
03768   /* Wait until TC flag is set */
03769   if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
03770   {
03771     return HAL_TIMEOUT;
03772   }
03773 
03774   return HAL_OK;
03775 }
03776 
03777 /**
03778   * @brief  FMPI2C Address complete process callback.
03779   * @param  hfmpi2c FMPI2C handle.
03780   * @param  ITFlags Interrupt flags to handle.
03781   * @retval None
03782   */
03783 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
03784 {
03785   uint8_t transferdirection = 0;
03786   uint16_t slaveaddrcode = 0;
03787   uint16_t ownadd1code = 0;
03788   uint16_t ownadd2code = 0;
03789 
03790   /* Prevent unused argument(s) compilation warning */
03791   UNUSED(ITFlags);
03792 
03793   /* In case of Listen state, need to inform upper layer of address match code event */
03794   if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
03795   {
03796     transferdirection = FMPI2C_GET_DIR(hfmpi2c);
03797     slaveaddrcode     = FMPI2C_GET_ADDR_MATCH(hfmpi2c);
03798     ownadd1code       = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c);
03799     ownadd2code       = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c);
03800 
03801     /* If 10bits addressing mode is selected */
03802     if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
03803     {
03804       if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK))
03805       {
03806         slaveaddrcode = ownadd1code;
03807         hfmpi2c->AddrEventCount++;
03808         if (hfmpi2c->AddrEventCount == 2U)
03809         {
03810           /* Reset Address Event counter */
03811           hfmpi2c->AddrEventCount = 0U;
03812 
03813           /* Clear ADDR flag */
03814           __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
03815 
03816           /* Process Unlocked */
03817           __HAL_UNLOCK(hfmpi2c);
03818 
03819           /* Call Slave Addr callback */
03820           HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
03821         }
03822       }
03823       else
03824       {
03825         slaveaddrcode = ownadd2code;
03826 
03827         /* Disable ADDR Interrupts */
03828         FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
03829 
03830         /* Process Unlocked */
03831         __HAL_UNLOCK(hfmpi2c);
03832 
03833         /* Call Slave Addr callback */
03834         HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
03835       }
03836     }
03837     /* else 7 bits addressing mode is selected */
03838     else
03839     {
03840       /* Disable ADDR Interrupts */
03841       FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
03842 
03843       /* Process Unlocked */
03844       __HAL_UNLOCK(hfmpi2c);
03845 
03846       /* Call Slave Addr callback */
03847       HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
03848     }
03849   }
03850   /* Else clear address flag only */
03851   else
03852   {
03853     /* Clear ADDR flag */
03854     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
03855 
03856     /* Process Unlocked */
03857     __HAL_UNLOCK(hfmpi2c);
03858   }
03859 }
03860 
03861 /**
03862   * @brief  FMPI2C Master sequential complete process.
03863   * @param  hfmpi2c FMPI2C handle.
03864   * @retval None
03865   */
03866 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c)
03867 {
03868   /* Reset FMPI2C handle mode */
03869   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
03870 
03871   /* No Generate Stop, to permit restart mode */
03872   /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */
03873   if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
03874   {
03875     hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
03876     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
03877     hfmpi2c->XferISR       = NULL;
03878 
03879     /* Disable Interrupts */
03880     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
03881 
03882     /* Process Unlocked */
03883     __HAL_UNLOCK(hfmpi2c);
03884 
03885     /* Call the corresponding callback to inform upper layer of End of Transfer */
03886     HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
03887   }
03888   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
03889   else
03890   {
03891     hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
03892     hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
03893     hfmpi2c->XferISR       = NULL;
03894 
03895     /* Disable Interrupts */
03896     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
03897 
03898     /* Process Unlocked */
03899     __HAL_UNLOCK(hfmpi2c);
03900 
03901     /* Call the corresponding callback to inform upper layer of End of Transfer */
03902     HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
03903   }
03904 }
03905 
03906 /**
03907   * @brief  FMPI2C Slave sequential complete process.
03908   * @param  hfmpi2c FMPI2C handle.
03909   * @retval None
03910   */
03911 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c)
03912 {
03913   /* Reset FMPI2C handle mode */
03914   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
03915 
03916   if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
03917   {
03918     /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */
03919     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
03920     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
03921 
03922     /* Disable Interrupts */
03923     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
03924 
03925     /* Process Unlocked */
03926     __HAL_UNLOCK(hfmpi2c);
03927 
03928     /* Call the Tx complete callback to inform upper layer of the end of transmit process */
03929     HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
03930   }
03931 
03932   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
03933   {
03934     /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */
03935     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
03936     hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
03937 
03938     /* Disable Interrupts */
03939     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
03940 
03941     /* Process Unlocked */
03942     __HAL_UNLOCK(hfmpi2c);
03943 
03944     /* Call the Rx complete callback to inform upper layer of the end of receive process */
03945     HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
03946   }
03947 }
03948 
03949 /**
03950   * @brief  FMPI2C Master complete process.
03951   * @param  hfmpi2c FMPI2C handle.
03952   * @param  ITFlags Interrupt flags to handle.
03953   * @retval None
03954   */
03955 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
03956 {
03957   /* Clear STOP Flag */
03958   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
03959 
03960   /* Clear Configuration Register 2 */
03961   FMPI2C_RESET_CR2(hfmpi2c);
03962 
03963   /* Reset handle parameters */
03964   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
03965   hfmpi2c->XferISR       = NULL;
03966   hfmpi2c->XferOptions   = FMPI2C_NO_OPTION_FRAME;
03967 
03968   if ((ITFlags & FMPI2C_FLAG_AF) != RESET)
03969   {
03970     /* Clear NACK Flag */
03971     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
03972 
03973     /* Set acknowledge error code */
03974     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
03975   }
03976 
03977   /* Flush TX register */
03978   FMPI2C_Flush_TXDR(hfmpi2c);
03979 
03980   /* Disable Interrupts */
03981   FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT);
03982 
03983   /* Call the corresponding callback to inform upper layer of End of Transfer */
03984   if ((hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) || (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT))
03985   {
03986     /* Call the corresponding callback to inform upper layer of End of Transfer */
03987     FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
03988   }
03989   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */
03990   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
03991   {
03992     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
03993 
03994     if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
03995     {
03996       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
03997 
03998       /* Process Unlocked */
03999       __HAL_UNLOCK(hfmpi2c);
04000 
04001       /* Call the corresponding callback to inform upper layer of End of Transfer */
04002       HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
04003     }
04004     else
04005     {
04006       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04007 
04008       /* Process Unlocked */
04009       __HAL_UNLOCK(hfmpi2c);
04010 
04011       /* Call the corresponding callback to inform upper layer of End of Transfer */
04012       HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
04013     }
04014   }
04015   /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
04016   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
04017   {
04018     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04019 
04020     if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
04021     {
04022       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04023 
04024       /* Process Unlocked */
04025       __HAL_UNLOCK(hfmpi2c);
04026 
04027       HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
04028     }
04029     else
04030     {
04031       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04032 
04033       /* Process Unlocked */
04034       __HAL_UNLOCK(hfmpi2c);
04035 
04036       HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
04037     }
04038   }
04039 }
04040 
04041 /**
04042   * @brief  FMPI2C Slave complete process.
04043   * @param  hfmpi2c FMPI2C handle.
04044   * @param  ITFlags Interrupt flags to handle.
04045   * @retval None
04046   */
04047 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
04048 {
04049   /* Clear STOP Flag */
04050   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
04051 
04052   /* Clear ADDR flag */
04053   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
04054 
04055   /* Disable all interrupts */
04056   FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT);
04057 
04058   /* Disable Address Acknowledge */
04059   hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
04060 
04061   /* Clear Configuration Register 2 */
04062   FMPI2C_RESET_CR2(hfmpi2c);
04063 
04064   /* Flush TX register */
04065   FMPI2C_Flush_TXDR(hfmpi2c);
04066 
04067   /* If a DMA is ongoing, Update handle size context */
04068   if (((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) ||
04069       ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN))
04070   {
04071     hfmpi2c->XferCount = FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c);
04072   }
04073 
04074   /* All data are not transferred, so set error code accordingly */
04075   if (hfmpi2c->XferCount != 0U)
04076   {
04077     /* Set ErrorCode corresponding to a Non-Acknowledge */
04078     hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
04079   }
04080 
04081   /* Store Last receive data if any */
04082   if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET))
04083   {
04084     /* Read data from RXDR */
04085     (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
04086 
04087     if ((hfmpi2c->XferSize > 0U))
04088     {
04089       hfmpi2c->XferSize--;
04090       hfmpi2c->XferCount--;
04091 
04092       /* Set ErrorCode corresponding to a Non-Acknowledge */
04093       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
04094     }
04095   }
04096 
04097   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
04098   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04099   hfmpi2c->XferISR = NULL;
04100 
04101   if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
04102   {
04103     /* Call the corresponding callback to inform upper layer of End of Transfer */
04104     FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
04105 
04106     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
04107     if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
04108     {
04109       /* Call FMPI2C Listen complete process */
04110       FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
04111     }
04112   }
04113   else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
04114   {
04115     hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
04116     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04117 
04118     /* Process Unlocked */
04119     __HAL_UNLOCK(hfmpi2c);
04120 
04121     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
04122     HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
04123   }
04124   /* Call the corresponding callback to inform upper layer of End of Transfer */
04125   else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
04126   {
04127     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04128 
04129     /* Process Unlocked */
04130     __HAL_UNLOCK(hfmpi2c);
04131 
04132     /* Call the Slave Rx Complete callback */
04133     HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
04134   }
04135   else
04136   {
04137     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04138 
04139     /* Process Unlocked */
04140     __HAL_UNLOCK(hfmpi2c);
04141 
04142     /* Call the Slave Tx Complete callback */
04143     HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
04144   }
04145 }
04146 
04147 /**
04148   * @brief  FMPI2C Listen complete process.
04149   * @param  hfmpi2c FMPI2C handle.
04150   * @param  ITFlags Interrupt flags to handle.
04151   * @retval None
04152   */
04153 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
04154 {
04155   /* Reset handle parameters */
04156   hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
04157   hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
04158   hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04159   hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04160   hfmpi2c->XferISR = NULL;
04161 
04162   /* Store Last receive data if any */
04163   if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET))
04164   {
04165     /* Read data from RXDR */
04166     (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
04167 
04168     if ((hfmpi2c->XferSize > 0U))
04169     {
04170       hfmpi2c->XferSize--;
04171       hfmpi2c->XferCount--;
04172 
04173       /* Set ErrorCode corresponding to a Non-Acknowledge */
04174       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
04175     }
04176   }
04177 
04178   /* Disable all Interrupts*/
04179   FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
04180 
04181   /* Clear NACK Flag */
04182   __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04183 
04184   /* Process Unlocked */
04185   __HAL_UNLOCK(hfmpi2c);
04186 
04187   /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
04188   HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
04189 }
04190 
04191 /**
04192   * @brief  FMPI2C interrupts error process.
04193   * @param  hfmpi2c FMPI2C handle.
04194   * @param  ErrorCode Error code to handle.
04195   * @retval None
04196   */
04197 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode)
04198 {
04199   /* Reset handle parameters */
04200   hfmpi2c->Mode          = HAL_FMPI2C_MODE_NONE;
04201   hfmpi2c->XferOptions   = FMPI2C_NO_OPTION_FRAME;
04202   hfmpi2c->XferCount     = 0U;
04203 
04204   /* Set new error code */
04205   hfmpi2c->ErrorCode |= ErrorCode;
04206 
04207   /* Disable Interrupts */
04208   if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)         ||
04209       (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) ||
04210       (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
04211   {
04212     /* Disable all interrupts, except interrupts related to LISTEN state */
04213     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
04214 
04215     /* keep HAL_FMPI2C_STATE_LISTEN if set */
04216     hfmpi2c->State         = HAL_FMPI2C_STATE_LISTEN;
04217     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
04218     hfmpi2c->XferISR       = FMPI2C_Slave_ISR_IT;
04219   }
04220   else
04221   {
04222     /* Disable all interrupts */
04223     FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
04224 
04225     /* If state is an abort treatment on goind, don't change state */
04226     /* This change will be do later */
04227     if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT)
04228     {
04229       /* Set HAL_FMPI2C_STATE_READY */
04230       hfmpi2c->State         = HAL_FMPI2C_STATE_READY;
04231     }
04232     hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
04233     hfmpi2c->XferISR       = NULL;
04234   }
04235 
04236   /* Abort DMA TX transfer if any */
04237   if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
04238   {
04239     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
04240 
04241     /* Set the FMPI2C DMA Abort callback :
04242        will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
04243     hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
04244 
04245     /* Process Unlocked */
04246     __HAL_UNLOCK(hfmpi2c);
04247 
04248     /* Abort DMA TX */
04249     if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
04250     {
04251       /* Call Directly XferAbortCallback function in case of error */
04252       hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
04253     }
04254   }
04255   /* Abort DMA RX transfer if any */
04256   else if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
04257   {
04258     hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
04259 
04260     /* Set the FMPI2C DMA Abort callback :
04261        will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
04262     hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
04263 
04264     /* Process Unlocked */
04265     __HAL_UNLOCK(hfmpi2c);
04266 
04267     /* Abort DMA RX */
04268     if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
04269     {
04270       /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */
04271       hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
04272     }
04273   }
04274   else if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
04275   {
04276     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04277 
04278     /* Process Unlocked */
04279     __HAL_UNLOCK(hfmpi2c);
04280 
04281     /* Call the corresponding callback to inform upper layer of End of Transfer */
04282     HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
04283   }
04284   else
04285   {
04286     /* Process Unlocked */
04287     __HAL_UNLOCK(hfmpi2c);
04288 
04289     /* Call the corresponding callback to inform upper layer of End of Transfer */
04290     HAL_FMPI2C_ErrorCallback(hfmpi2c);
04291   }
04292 }
04293 
04294 /**
04295   * @brief  FMPI2C Tx data register flush process.
04296   * @param  hfmpi2c FMPI2C handle.
04297   * @retval None
04298   */
04299 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c)
04300 {
04301   /* If a pending TXIS flag is set */
04302   /* Write a dummy data in TXDR to clear it */
04303   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET)
04304   {
04305     hfmpi2c->Instance->TXDR = 0x00U;
04306   }
04307 
04308   /* Flush TX register if not empty */
04309   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET)
04310   {
04311     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE);
04312   }
04313 }
04314 
04315 /**
04316   * @brief  DMA FMPI2C master transmit process complete callback.
04317   * @param  hdma DMA handle
04318   * @retval None
04319   */
04320 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
04321 {
04322   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
04323 
04324   /* Disable DMA Request */
04325   hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
04326 
04327   /* If last transfer, enable STOP interrupt */
04328   if (hfmpi2c->XferCount == 0U)
04329   {
04330     /* Enable STOP interrupt */
04331     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
04332   }
04333   /* else prepare a new DMA transfer and enable TCReload interrupt */
04334   else
04335   {
04336     /* Update Buffer pointer */
04337     hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
04338 
04339     /* Set the XferSize to transfer */
04340     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
04341     {
04342       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
04343     }
04344     else
04345     {
04346       hfmpi2c->XferSize = hfmpi2c->XferCount;
04347     }
04348 
04349     /* Enable the DMA stream */
04350     HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
04351 
04352     /* Enable TC interrupts */
04353     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
04354   }
04355 }
04356 
04357 /**
04358   * @brief  DMA FMPI2C slave transmit process complete callback.
04359   * @param  hdma DMA handle
04360   * @retval None
04361   */
04362 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
04363 {
04364   /* Prevent unused argument(s) compilation warning */
04365   UNUSED(hdma);
04366 
04367   /* No specific action, Master fully manage the generation of STOP condition */
04368   /* Mean that this generation can arrive at any time, at the end or during DMA process */
04369   /* So STOP condition should be manage through Interrupt treatment */
04370 }
04371 
04372 /**
04373   * @brief DMA FMPI2C master receive process complete callback.
04374   * @param  hdma DMA handle
04375   * @retval None
04376   */
04377 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
04378 {
04379   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
04380 
04381   /* Disable DMA Request */
04382   hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
04383 
04384   /* If last transfer, enable STOP interrupt */
04385   if (hfmpi2c->XferCount == 0U)
04386   {
04387     /* Enable STOP interrupt */
04388     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
04389   }
04390   /* else prepare a new DMA transfer and enable TCReload interrupt */
04391   else
04392   {
04393     /* Update Buffer pointer */
04394     hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
04395 
04396     /* Set the XferSize to transfer */
04397     if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
04398     {
04399       hfmpi2c->XferSize = MAX_NBYTE_SIZE;
04400     }
04401     else
04402     {
04403       hfmpi2c->XferSize = hfmpi2c->XferCount;
04404     }
04405 
04406     /* Enable the DMA stream */
04407     HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize);
04408 
04409     /* Enable TC interrupts */
04410     FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
04411   }
04412 }
04413 
04414 /**
04415   * @brief  DMA FMPI2C slave receive process complete callback.
04416   * @param  hdma DMA handle
04417   * @retval None
04418   */
04419 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
04420 {
04421   /* Prevent unused argument(s) compilation warning */
04422   UNUSED(hdma);
04423 
04424   /* No specific action, Master fully manage the generation of STOP condition */
04425   /* Mean that this generation can arrive at any time, at the end or during DMA process */
04426   /* So STOP condition should be manage through Interrupt treatment */
04427 }
04428 
04429 /**
04430   * @brief  DMA FMPI2C communication error callback.
04431   * @param hdma DMA handle
04432   * @retval None
04433   */
04434 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
04435 {
04436   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
04437 
04438   /* Disable Acknowledge */
04439   hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
04440 
04441   /* Call the corresponding callback to inform upper layer of End of Transfer */
04442   FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
04443 }
04444 
04445 /**
04446   * @brief DMA FMPI2C communication abort callback
04447   *        (To be called at end of DMA Abort procedure).
04448   * @param hdma DMA handle.
04449   * @retval None
04450   */
04451 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma)
04452 {
04453   FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
04454 
04455   /* Disable Acknowledge */
04456   hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
04457 
04458   /* Reset AbortCpltCallback */
04459   hfmpi2c->hdmatx->XferAbortCallback = NULL;
04460   hfmpi2c->hdmarx->XferAbortCallback = NULL;
04461 
04462   /* Check if come from abort from user */
04463   if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
04464   {
04465     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04466 
04467     /* Call the corresponding callback to inform upper layer of End of Transfer */
04468     HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
04469   }
04470   else
04471   {
04472     /* Call the corresponding callback to inform upper layer of End of Transfer */
04473     HAL_FMPI2C_ErrorCallback(hfmpi2c);
04474   }
04475 }
04476 
04477 /**
04478   * @brief  This function handles FMPI2C Communication Timeout.
04479   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04480   *                the configuration information for the specified FMPI2C.
04481   * @param  Flag Specifies the FMPI2C flag to check.
04482   * @param  Status The new Flag status (SET or RESET).
04483   * @param  Timeout Timeout duration
04484   * @param  Tickstart Tick start value
04485   * @retval HAL status
04486   */
04487 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
04488 {
04489   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status)
04490   {
04491     /* Check for the Timeout */
04492     if (Timeout != HAL_MAX_DELAY)
04493     {
04494       if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
04495       {
04496         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04497         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04498 
04499         /* Process Unlocked */
04500         __HAL_UNLOCK(hfmpi2c);
04501         return HAL_TIMEOUT;
04502       }
04503     }
04504   }
04505   return HAL_OK;
04506 }
04507 
04508 /**
04509   * @brief  This function handles FMPI2C Communication Timeout for specific usage of TXIS flag.
04510   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04511   *                the configuration information for the specified FMPI2C.
04512   * @param  Timeout Timeout duration
04513   * @param  Tickstart Tick start value
04514   * @retval HAL status
04515   */
04516 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
04517 {
04518   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
04519   {
04520     /* Check if a NACK is detected */
04521     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
04522     {
04523       return HAL_ERROR;
04524     }
04525 
04526     /* Check for the Timeout */
04527     if (Timeout != HAL_MAX_DELAY)
04528     {
04529       if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
04530       {
04531         hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
04532         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04533         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04534 
04535         /* Process Unlocked */
04536         __HAL_UNLOCK(hfmpi2c);
04537 
04538         return HAL_TIMEOUT;
04539       }
04540     }
04541   }
04542   return HAL_OK;
04543 }
04544 
04545 /**
04546   * @brief  This function handles FMPI2C Communication Timeout for specific usage of STOP flag.
04547   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04548   *                the configuration information for the specified FMPI2C.
04549   * @param  Timeout Timeout duration
04550   * @param  Tickstart Tick start value
04551   * @retval HAL status
04552   */
04553 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
04554 {
04555   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
04556   {
04557     /* Check if a NACK is detected */
04558     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
04559     {
04560       return HAL_ERROR;
04561     }
04562 
04563     /* Check for the Timeout */
04564     if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
04565     {
04566       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
04567       hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04568       hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04569 
04570       /* Process Unlocked */
04571       __HAL_UNLOCK(hfmpi2c);
04572 
04573       return HAL_TIMEOUT;
04574     }
04575   }
04576   return HAL_OK;
04577 }
04578 
04579 /**
04580   * @brief  This function handles FMPI2C Communication Timeout for specific usage of RXNE flag.
04581   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04582   *                the configuration information for the specified FMPI2C.
04583   * @param  Timeout Timeout duration
04584   * @param  Tickstart Tick start value
04585   * @retval HAL status
04586   */
04587 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
04588 {
04589   while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET)
04590   {
04591     /* Check if a NACK is detected */
04592     if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
04593     {
04594       return HAL_ERROR;
04595     }
04596 
04597     /* Check if a STOPF is detected */
04598     if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
04599     {
04600       /* Check if an RXNE is pending */
04601       /* Store Last receive data if any */
04602       if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U))
04603       {
04604         /* Return HAL_OK */
04605         /* The Reading of data from RXDR will be done in caller function */
04606         return HAL_OK;
04607       }
04608       else
04609       {
04610         /* Clear STOP Flag */
04611         __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
04612 
04613         /* Clear Configuration Register 2 */
04614         FMPI2C_RESET_CR2(hfmpi2c);
04615 
04616         hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
04617         hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04618         hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04619 
04620         /* Process Unlocked */
04621         __HAL_UNLOCK(hfmpi2c);
04622 
04623         return HAL_ERROR;
04624       }
04625     }
04626 
04627     /* Check for the Timeout */
04628     if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
04629     {
04630       hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
04631       hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04632 
04633       /* Process Unlocked */
04634       __HAL_UNLOCK(hfmpi2c);
04635 
04636       return HAL_TIMEOUT;
04637     }
04638   }
04639   return HAL_OK;
04640 }
04641 
04642 /**
04643   * @brief  This function handles Acknowledge failed detection during an FMPI2C Communication.
04644   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04645   *                the configuration information for the specified FMPI2C.
04646   * @param  Timeout Timeout duration
04647   * @param  Tickstart Tick start value
04648   * @retval HAL status
04649   */
04650 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
04651 {
04652   if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
04653   {
04654     /* Wait until STOP Flag is reset */
04655     /* AutoEnd should be initiate after AF */
04656     while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
04657     {
04658       /* Check for the Timeout */
04659       if (Timeout != HAL_MAX_DELAY)
04660       {
04661         if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
04662         {
04663           hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04664           hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04665 
04666           /* Process Unlocked */
04667           __HAL_UNLOCK(hfmpi2c);
04668           return HAL_TIMEOUT;
04669         }
04670       }
04671     }
04672 
04673     /* Clear NACKF Flag */
04674     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
04675 
04676     /* Clear STOP Flag */
04677     __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
04678 
04679     /* Flush TX register */
04680     FMPI2C_Flush_TXDR(hfmpi2c);
04681 
04682     /* Clear Configuration Register 2 */
04683     FMPI2C_RESET_CR2(hfmpi2c);
04684 
04685     hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF;
04686     hfmpi2c->State = HAL_FMPI2C_STATE_READY;
04687     hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
04688 
04689     /* Process Unlocked */
04690     __HAL_UNLOCK(hfmpi2c);
04691 
04692     return HAL_ERROR;
04693   }
04694   return HAL_OK;
04695 }
04696 
04697 /**
04698   * @brief  Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
04699   * @param  hfmpi2c FMPI2C handle.
04700   * @param  DevAddress Specifies the slave address to be programmed.
04701   * @param  Size Specifies the number of bytes to be programmed.
04702   *   This parameter must be a value between 0 and 255.
04703   * @param  Mode New state of the FMPI2C START condition generation.
04704   *   This parameter can be one of the following values:
04705   *     @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode .
04706   *     @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode.
04707   *     @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode.
04708   * @param  Request New state of the FMPI2C START condition generation.
04709   *   This parameter can be one of the following values:
04710   *     @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition.
04711   *     @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
04712   *     @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request.
04713   *     @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request.
04714   * @retval None
04715   */
04716 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
04717 {
04718   /* Check the parameters */
04719   assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
04720   assert_param(IS_TRANSFER_MODE(Mode));
04721   assert_param(IS_TRANSFER_REQUEST(Request));
04722 
04723   /* update CR2 register */
04724   MODIFY_REG(hfmpi2c->Instance->CR2, ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | FMPI2C_CR2_START | FMPI2C_CR2_STOP)), \
04725              (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
04726 }
04727 
04728 /**
04729   * @brief  Manage the enabling of Interrupts.
04730   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04731   *                the configuration information for the specified FMPI2C.
04732   * @param  InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
04733   * @retval HAL status
04734   */
04735 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
04736 {
04737   uint32_t tmpisr = 0U;
04738 
04739   if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \
04740       (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA))
04741   {
04742     if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
04743     {
04744       /* Enable ERR, STOP, NACK and ADDR interrupts */
04745       tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
04746     }
04747 
04748     if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT)
04749     {
04750       /* Enable ERR and NACK interrupts */
04751       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
04752     }
04753 
04754     if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
04755     {
04756       /* Enable STOP interrupts */
04757       tmpisr |= FMPI2C_IT_STOPI;
04758     }
04759 
04760     if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT)
04761     {
04762       /* Enable TC interrupts */
04763       tmpisr |= FMPI2C_IT_TCI;
04764     }
04765   }
04766   else
04767   {
04768     if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
04769     {
04770       /* Enable ERR, STOP, NACK, and ADDR interrupts */
04771       tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
04772     }
04773 
04774     if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
04775     {
04776       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
04777       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
04778     }
04779 
04780     if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
04781     {
04782       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
04783       tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
04784     }
04785 
04786     if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
04787     {
04788       /* Enable STOP interrupts */
04789       tmpisr |= FMPI2C_IT_STOPI;
04790     }
04791   }
04792 
04793   /* Enable interrupts only at the end */
04794   /* to avoid the risk of FMPI2C interrupt handle execution before */
04795   /* all interrupts requested done */
04796   __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr);
04797 
04798   return HAL_OK;
04799 }
04800 
04801 /**
04802   * @brief  Manage the disabling of Interrupts.
04803   * @param  hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
04804   *                the configuration information for the specified FMPI2C.
04805   * @param  InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
04806   * @retval HAL status
04807   */
04808 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
04809 {
04810   uint32_t tmpisr = 0U;
04811 
04812   if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
04813   {
04814     /* Disable TC and TXI interrupts */
04815     tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI;
04816 
04817     if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN)
04818     {
04819       /* Disable NACK and STOP interrupts */
04820       tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
04821     }
04822   }
04823 
04824   if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
04825   {
04826     /* Disable TC and RXI interrupts */
04827     tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI;
04828 
04829     if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN)
04830     {
04831       /* Disable NACK and STOP interrupts */
04832       tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
04833     }
04834   }
04835 
04836   if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
04837   {
04838     /* Disable ADDR, NACK and STOP interrupts */
04839     tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
04840   }
04841 
04842   if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT)
04843   {
04844     /* Enable ERR and NACK interrupts */
04845     tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
04846   }
04847 
04848   if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
04849   {
04850     /* Enable STOP interrupts */
04851     tmpisr |= FMPI2C_IT_STOPI;
04852   }
04853 
04854   if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT)
04855   {
04856     /* Enable TC interrupts */
04857     tmpisr |= FMPI2C_IT_TCI;
04858   }
04859 
04860   /* Disable interrupts only at the end */
04861   /* to avoid a breaking situation like at "t" time */
04862   /* all disable interrupts request are not done */
04863   __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr);
04864 
04865   return HAL_OK;
04866 }
04867 
04868 /**
04869   * @}
04870   */
04871 #endif /* STM32F410xx || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
04872 #endif /* HAL_FMPI2C_MODULE_ENABLED */
04873 /**
04874   * @}
04875   */
04876 
04877 /**
04878   * @}
04879   */
04880 
04881 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/