Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_i2c.c
0004   * @author  MCD Application Team
0005   * @brief   I2C HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Inter Integrated Circuit (I2C) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral State and Errors functions
0011   *
0012   ******************************************************************************
0013   * @attention
0014   *
0015   * Copyright (c) 2017 STMicroelectronics.
0016   * All rights reserved.
0017   *
0018   * This software is licensed under terms that can be found in the LICENSE file
0019   * in the root directory of this software component.
0020   * If no LICENSE file comes with this software, it is provided AS-IS.
0021   *
0022   ******************************************************************************
0023   @verbatim
0024   ==============================================================================
0025                         ##### How to use this driver #####
0026   ==============================================================================
0027     [..]
0028     The I2C HAL driver can be used as follows:
0029 
0030     (#) Declare a I2C_HandleTypeDef handle structure, for example:
0031         I2C_HandleTypeDef  hi2c;
0032 
0033     (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API:
0034         (##) Enable the I2Cx interface clock
0035         (##) I2C pins configuration
0036             (+++) Enable the clock for the I2C GPIOs
0037             (+++) Configure I2C pins as alternate function open-drain
0038         (##) NVIC configuration if you need to use interrupt process
0039             (+++) Configure the I2Cx interrupt priority
0040             (+++) Enable the NVIC I2C IRQ Channel
0041         (##) DMA Configuration if you need to use DMA process
0042             (+++) Declare a DMA_HandleTypeDef handle structure for
0043                   the transmit or receive stream or channel depends on Instance
0044             (+++) Enable the DMAx interface clock using
0045             (+++) Configure the DMA handle parameters
0046             (+++) Configure the DMA Tx or Rx stream or channel depends on Instance
0047             (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle
0048             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
0049                   the DMA Tx or Rx stream or channel depends on Instance
0050 
0051     (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
0052         Own Address2, Own Address2 Mask, General call and Nostretch mode in the hi2c Init structure.
0053 
0054     (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware
0055         (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API.
0056 
0057     (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()
0058 
0059     (#) For I2C IO and IO MEM operations, three operation modes are available within this driver :
0060 
0061     *** Polling mode IO operation ***
0062     =================================
0063     [..]
0064       (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit()
0065       (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive()
0066       (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit()
0067       (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive()
0068 
0069     *** Polling mode IO MEM operation ***
0070     =====================================
0071     [..]
0072       (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write()
0073       (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read()
0074 
0075 
0076     *** Interrupt mode IO operation ***
0077     ===================================
0078     [..]
0079       (+) Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Transmit_IT()
0080       (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can
0081            add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
0082       (+) Receive in master mode an amount of data in non-blocking mode using HAL_I2C_Master_Receive_IT()
0083       (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
0084            add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
0085       (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Transmit_IT()
0086       (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can
0087            add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
0088       (+) Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_Slave_Receive_IT()
0089       (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
0090            add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
0091       (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
0092            add their own code by customization of function pointer HAL_I2C_ErrorCallback()
0093       (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
0094       (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
0095            add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
0096       (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
0097            This action will inform Master to generate a Stop condition to discard the communication.
0098 
0099 
0100     *** Interrupt mode or DMA mode IO sequential operation ***
0101     ==========================================================
0102     [..]
0103       (@) These interfaces allow to manage a sequential transfer with a repeated start condition
0104           when a direction change during transfer
0105     [..]
0106       (+) A specific option field manage the different steps of a sequential transfer
0107       (+) Option field values are defined through I2C_XFEROPTIONS and are listed below:
0108       (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in
0109            no sequential mode
0110       (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
0111                             and data to transfer without a final stop condition
0112       (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with
0113                             start condition, address and data to transfer without a final stop condition,
0114                             an then permit a call the same master sequential interface several times
0115                             (like HAL_I2C_Master_Seq_Transmit_IT() then HAL_I2C_Master_Seq_Transmit_IT()
0116                             or HAL_I2C_Master_Seq_Transmit_DMA() then HAL_I2C_Master_Seq_Transmit_DMA())
0117       (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
0118                             and with new data to transfer if the direction change or manage only the new data to
0119                             transfer
0120                             if no direction change and without a final stop condition in both cases
0121       (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
0122                             and with new data to transfer if the direction change or manage only the new data to
0123                             transfer
0124                             if no direction change and with a final stop condition in both cases
0125       (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition
0126                             after several call of the same master sequential interface several times
0127                             (link with option I2C_FIRST_AND_NEXT_FRAME).
0128                             Usage can, transfer several bytes one by one using
0129                               HAL_I2C_Master_Seq_Transmit_IT
0130                               or HAL_I2C_Master_Seq_Receive_IT
0131                               or HAL_I2C_Master_Seq_Transmit_DMA
0132                               or HAL_I2C_Master_Seq_Receive_DMA
0133                               with option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME.
0134                              Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or
0135                               Receive sequence permit to call the opposite interface Receive or Transmit
0136                               without stopping the communication and so generate a restart condition.
0137       (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after
0138                             each call of the same master sequential
0139                             interface.
0140                             Usage can, transfer several bytes one by one with a restart with slave address between
0141                             each bytes using
0142                               HAL_I2C_Master_Seq_Transmit_IT
0143                               or HAL_I2C_Master_Seq_Receive_IT
0144                               or HAL_I2C_Master_Seq_Transmit_DMA
0145                               or HAL_I2C_Master_Seq_Receive_DMA
0146                               with option I2C_FIRST_FRAME then I2C_OTHER_FRAME.
0147                             Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic
0148                             generation of STOP condition.
0149 
0150       (+) Different sequential I2C interfaces are listed below:
0151       (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using
0152             HAL_I2C_Master_Seq_Transmit_IT() or using HAL_I2C_Master_Seq_Transmit_DMA()
0153       (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and
0154             users can add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
0155       (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using
0156             HAL_I2C_Master_Seq_Receive_IT() or using HAL_I2C_Master_Seq_Receive_DMA()
0157       (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
0158            add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
0159       (++) Abort a master IT or DMA I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
0160       (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
0161            add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
0162       (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT()
0163             HAL_I2C_DisableListen_IT()
0164       (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and users can
0165            add their own code to check the Address Match Code and the transmission direction request by master
0166            (Write/Read).
0167       (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and users can
0168           add their own code by customization of function pointer HAL_I2C_ListenCpltCallback()
0169       (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using
0170             HAL_I2C_Slave_Seq_Transmit_IT() or using HAL_I2C_Slave_Seq_Transmit_DMA()
0171       (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and
0172             users can add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
0173       (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using
0174             HAL_I2C_Slave_Seq_Receive_IT() or using HAL_I2C_Slave_Seq_Receive_DMA()
0175       (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
0176            add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
0177       (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
0178            add their own code by customization of function pointer HAL_I2C_ErrorCallback()
0179       (++) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
0180            This action will inform Master to generate a Stop condition to discard the communication.
0181 
0182     *** Interrupt mode IO MEM operation ***
0183     =======================================
0184     [..]
0185       (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
0186           HAL_I2C_Mem_Write_IT()
0187       (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can
0188            add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
0189       (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
0190           HAL_I2C_Mem_Read_IT()
0191       (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can
0192            add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
0193       (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
0194            add their own code by customization of function pointer HAL_I2C_ErrorCallback()
0195 
0196     *** DMA mode IO operation ***
0197     ==============================
0198     [..]
0199       (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
0200           HAL_I2C_Master_Transmit_DMA()
0201       (+) At transmission end of transfer, HAL_I2C_MasterTxCpltCallback() is executed and users can
0202            add their own code by customization of function pointer HAL_I2C_MasterTxCpltCallback()
0203       (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
0204           HAL_I2C_Master_Receive_DMA()
0205       (+) At reception end of transfer, HAL_I2C_MasterRxCpltCallback() is executed and users can
0206            add their own code by customization of function pointer HAL_I2C_MasterRxCpltCallback()
0207       (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
0208           HAL_I2C_Slave_Transmit_DMA()
0209       (+) At transmission end of transfer, HAL_I2C_SlaveTxCpltCallback() is executed and users can
0210            add their own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback()
0211       (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
0212           HAL_I2C_Slave_Receive_DMA()
0213       (+) At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and users can
0214            add their own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()
0215       (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
0216            add their own code by customization of function pointer HAL_I2C_ErrorCallback()
0217       (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT()
0218       (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and users can
0219            add their own code by customization of function pointer HAL_I2C_AbortCpltCallback()
0220       (+) Discard a slave I2C process communication using __HAL_I2C_GENERATE_NACK() macro.
0221            This action will inform Master to generate a Stop condition to discard the communication.
0222 
0223     *** DMA mode IO MEM operation ***
0224     =================================
0225     [..]
0226       (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
0227           HAL_I2C_Mem_Write_DMA()
0228       (+) At Memory end of write transfer, HAL_I2C_MemTxCpltCallback() is executed and users can
0229            add their own code by customization of function pointer HAL_I2C_MemTxCpltCallback()
0230       (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
0231           HAL_I2C_Mem_Read_DMA()
0232       (+) At Memory end of read transfer, HAL_I2C_MemRxCpltCallback() is executed and users can
0233            add their own code by customization of function pointer HAL_I2C_MemRxCpltCallback()
0234       (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and users can
0235            add their own code by customization of function pointer HAL_I2C_ErrorCallback()
0236 
0237 
0238      *** I2C HAL driver macros list ***
0239      ==================================
0240      [..]
0241        Below the list of most used macros in I2C HAL driver.
0242 
0243       (+) __HAL_I2C_ENABLE: Enable the I2C peripheral
0244       (+) __HAL_I2C_DISABLE: Disable the I2C peripheral
0245       (+) __HAL_I2C_GENERATE_NACK: Generate a Non-Acknowledge I2C peripheral in Slave mode
0246       (+) __HAL_I2C_GET_FLAG: Check whether the specified I2C flag is set or not
0247       (+) __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag
0248       (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt
0249       (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt
0250 
0251      *** Callback registration ***
0252      =============================================
0253     [..]
0254      The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1
0255      allows the user to configure dynamically the driver callbacks.
0256      Use Functions HAL_I2C_RegisterCallback() or HAL_I2C_RegisterAddrCallback()
0257      to register an interrupt callback.
0258     [..]
0259      Function HAL_I2C_RegisterCallback() allows to register following callbacks:
0260        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
0261        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
0262        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
0263        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
0264        (+) ListenCpltCallback   : callback for end of listen mode.
0265        (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
0266        (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
0267        (+) ErrorCallback        : callback for error detection.
0268        (+) AbortCpltCallback    : callback for abort completion process.
0269        (+) MspInitCallback      : callback for Msp Init.
0270        (+) MspDeInitCallback    : callback for Msp DeInit.
0271      This function takes as parameters the HAL peripheral handle, the Callback ID
0272      and a pointer to the user callback function.
0273     [..]
0274      For specific callback AddrCallback use dedicated register callbacks : HAL_I2C_RegisterAddrCallback().
0275     [..]
0276      Use function HAL_I2C_UnRegisterCallback to reset a callback to the default
0277      weak function.
0278      HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
0279      and the Callback ID.
0280      This function allows to reset following callbacks:
0281        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
0282        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
0283        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
0284        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
0285        (+) ListenCpltCallback   : callback for end of listen mode.
0286        (+) MemTxCpltCallback    : callback for Memory transmission end of transfer.
0287        (+) MemRxCpltCallback    : callback for Memory reception end of transfer.
0288        (+) ErrorCallback        : callback for error detection.
0289        (+) AbortCpltCallback    : callback for abort completion process.
0290        (+) MspInitCallback      : callback for Msp Init.
0291        (+) MspDeInitCallback    : callback for Msp DeInit.
0292     [..]
0293      For callback AddrCallback use dedicated register callbacks : HAL_I2C_UnRegisterAddrCallback().
0294     [..]
0295      By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_RESET
0296      all callbacks are set to the corresponding weak functions:
0297      examples HAL_I2C_MasterTxCpltCallback(), HAL_I2C_MasterRxCpltCallback().
0298      Exception done for MspInit and MspDeInit functions that are
0299      reset to the legacy weak functions in the HAL_I2C_Init()/ HAL_I2C_DeInit() only when
0300      these callbacks are null (not registered beforehand).
0301      If MspInit or MspDeInit are not null, the HAL_I2C_Init()/ HAL_I2C_DeInit()
0302      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
0303     [..]
0304      Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
0305      Exception done MspInit/MspDeInit functions that can be registered/unregistered
0306      in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state,
0307      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0308      Then, the user first registers the MspInit/MspDeInit user callbacks
0309      using HAL_I2C_RegisterCallback() before calling HAL_I2C_DeInit()
0310      or HAL_I2C_Init() function.
0311     [..]
0312      When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 0 or
0313      not defined, the callback registration feature is not available and all callbacks
0314      are set to the corresponding weak functions.
0315 
0316      [..]
0317        (@) You can refer to the I2C HAL driver header file for more useful macros
0318 
0319   @endverbatim
0320   */
0321 
0322 /* Includes ------------------------------------------------------------------*/
0323 #include "stm32h7xx_hal.h"
0324 
0325 /** @addtogroup STM32H7xx_HAL_Driver
0326   * @{
0327   */
0328 
0329 /** @defgroup I2C I2C
0330   * @ingroup RTEMSBSPsARMSTM32H7
0331   * @brief I2C HAL module driver
0332   * @{
0333   */
0334 
0335 #ifdef HAL_I2C_MODULE_ENABLED
0336 
0337 /* Private typedef -----------------------------------------------------------*/
0338 /* Private define ------------------------------------------------------------*/
0339 
0340 /** @defgroup I2C_Private_Define I2C Private Define
0341   * @ingroup RTEMSBSPsARMSTM32H7
0342   * @{
0343   */
0344 #define TIMING_CLEAR_MASK   (0xF0FFFFFFU)  /*!< I2C TIMING clear register Mask */
0345 #define I2C_TIMEOUT_ADDR    (10000U)       /*!< 10 s  */
0346 #define I2C_TIMEOUT_BUSY    (25U)          /*!< 25 ms */
0347 #define I2C_TIMEOUT_DIR     (25U)          /*!< 25 ms */
0348 #define I2C_TIMEOUT_RXNE    (25U)          /*!< 25 ms */
0349 #define I2C_TIMEOUT_STOPF   (25U)          /*!< 25 ms */
0350 #define I2C_TIMEOUT_TC      (25U)          /*!< 25 ms */
0351 #define I2C_TIMEOUT_TCR     (25U)          /*!< 25 ms */
0352 #define I2C_TIMEOUT_TXIS    (25U)          /*!< 25 ms */
0353 #define I2C_TIMEOUT_FLAG    (25U)          /*!< 25 ms */
0354 
0355 #define MAX_NBYTE_SIZE      255U
0356 #define SLAVE_ADDR_SHIFT     7U
0357 #define SLAVE_ADDR_MSK       0x06U
0358 
0359 /* Private define for @ref PreviousState usage */
0360 #define I2C_STATE_MSK             ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | \
0361                                                          (uint32_t)HAL_I2C_STATE_BUSY_RX) & \
0362                                               (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY))))
0363 /*!< Mask State define, keep only RX and TX bits */
0364 #define I2C_STATE_NONE            ((uint32_t)(HAL_I2C_MODE_NONE))
0365 /*!< Default Value */
0366 #define I2C_STATE_MASTER_BUSY_TX  ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
0367                                               (uint32_t)HAL_I2C_MODE_MASTER))
0368 /*!< Master Busy TX, combinaison of State LSB and Mode enum */
0369 #define I2C_STATE_MASTER_BUSY_RX  ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
0370                                               (uint32_t)HAL_I2C_MODE_MASTER))
0371 /*!< Master Busy RX, combinaison of State LSB and Mode enum */
0372 #define I2C_STATE_SLAVE_BUSY_TX   ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
0373                                               (uint32_t)HAL_I2C_MODE_SLAVE))
0374 /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
0375 #define I2C_STATE_SLAVE_BUSY_RX   ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
0376                                               (uint32_t)HAL_I2C_MODE_SLAVE))
0377 /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
0378 #define I2C_STATE_MEM_BUSY_TX     ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | \
0379                                               (uint32_t)HAL_I2C_MODE_MEM))
0380 /*!< Memory Busy TX, combinaison of State LSB and Mode enum */
0381 #define I2C_STATE_MEM_BUSY_RX     ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | \
0382                                               (uint32_t)HAL_I2C_MODE_MEM))
0383 /*!< Memory Busy RX, combinaison of State LSB and Mode enum */
0384 
0385 
0386 /* Private define to centralize the enable/disable of Interrupts */
0387 #define I2C_XFER_TX_IT          (uint16_t)(0x0001U)   /*!< Bit field can be combinated with
0388                                                          @ref I2C_XFER_LISTEN_IT */
0389 #define I2C_XFER_RX_IT          (uint16_t)(0x0002U)   /*!< Bit field can be combinated with
0390                                                          @ref I2C_XFER_LISTEN_IT */
0391 #define I2C_XFER_LISTEN_IT      (uint16_t)(0x8000U)   /*!< Bit field can be combinated with @ref I2C_XFER_TX_IT
0392                                                          and @ref I2C_XFER_RX_IT */
0393 
0394 #define I2C_XFER_ERROR_IT       (uint16_t)(0x0010U)   /*!< Bit definition to manage addition of global Error
0395                                                          and NACK treatment */
0396 #define I2C_XFER_CPLT_IT        (uint16_t)(0x0020U)   /*!< Bit definition to manage only STOP evenement */
0397 #define I2C_XFER_RELOAD_IT      (uint16_t)(0x0040U)   /*!< Bit definition to manage only Reload of NBYTE */
0398 
0399 /* Private define Sequential Transfer Options default/reset value */
0400 #define I2C_NO_OPTION_FRAME     (0xFFFF0000U)
0401 /**
0402   * @}
0403   */
0404 
0405 /* Private macros ------------------------------------------------------------*/
0406 /** @addtogroup I2C_Private_Macro
0407   * @{
0408   */
0409 /* Macro to get remaining data to transfer on DMA side */
0410 #define I2C_GET_DMA_REMAIN_DATA(__HANDLE__)     __HAL_DMA_GET_COUNTER(__HANDLE__)
0411 /**
0412   * @}
0413   */
0414 
0415 /* Private variables ---------------------------------------------------------*/
0416 /* Private function prototypes -----------------------------------------------*/
0417 
0418 /** @defgroup I2C_Private_Functions I2C Private Functions
0419   * @ingroup RTEMSBSPsARMSTM32H7
0420   * @{
0421   */
0422 /* Private functions to handle DMA transfer */
0423 static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
0424 static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
0425 static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
0426 static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
0427 static void I2C_DMAError(DMA_HandleTypeDef *hdma);
0428 static void I2C_DMAAbort(DMA_HandleTypeDef *hdma);
0429 
0430 
0431 /* Private functions to handle IT transfer */
0432 static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
0433 static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c);
0434 static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c);
0435 static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
0436 static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
0437 static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags);
0438 static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode);
0439 
0440 /* Private functions to handle IT transfer */
0441 static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
0442                                                 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
0443                                                 uint32_t Tickstart);
0444 static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
0445                                                uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
0446                                                uint32_t Tickstart);
0447 
0448 /* Private functions for I2C transfer IRQ handler */
0449 static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0450                                            uint32_t ITSources);
0451 static HAL_StatusTypeDef I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0452                                         uint32_t ITSources);
0453 static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0454                                           uint32_t ITSources);
0455 static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0456                                             uint32_t ITSources);
0457 static HAL_StatusTypeDef I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0458                                          uint32_t ITSources);
0459 static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
0460                                            uint32_t ITSources);
0461 
0462 /* Private functions to handle flags during polling transfer */
0463 static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
0464                                                     uint32_t Timeout, uint32_t Tickstart);
0465 static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
0466                                                         uint32_t Tickstart);
0467 static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
0468                                                         uint32_t Tickstart);
0469 static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
0470                                                         uint32_t Tickstart);
0471 static HAL_StatusTypeDef I2C_IsErrorOccurred(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
0472                                              uint32_t Tickstart);
0473 
0474 /* Private functions to centralize the enable/disable of Interrupts */
0475 static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
0476 static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest);
0477 
0478 /* Private function to treat different error callback */
0479 static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c);
0480 
0481 /* Private function to flush TXDR register */
0482 static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c);
0483 
0484 /* Private function to handle  start, restart or stop a transfer */
0485 static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
0486                                uint32_t Request);
0487 
0488 /* Private function to Convert Specific options */
0489 static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c);
0490 /**
0491   * @}
0492   */
0493 
0494 /* Exported functions --------------------------------------------------------*/
0495 
0496 /** @defgroup I2C_Exported_Functions I2C Exported Functions
0497   * @ingroup RTEMSBSPsARMSTM32H7
0498   * @{
0499   */
0500 
0501 /** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
0502   * @ingroup RTEMSBSPsARMSTM32H7
0503   *  @brief    Initialization and Configuration functions
0504   *
0505 @verbatim
0506  ===============================================================================
0507               ##### Initialization and de-initialization functions #####
0508  ===============================================================================
0509     [..]  This subsection provides a set of functions allowing to initialize and
0510           deinitialize the I2Cx peripheral:
0511 
0512       (+) User must Implement HAL_I2C_MspInit() function in which he configures
0513           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
0514 
0515       (+) Call the function HAL_I2C_Init() to configure the selected device with
0516           the selected configuration:
0517         (++) Clock Timing
0518         (++) Own Address 1
0519         (++) Addressing mode (Master, Slave)
0520         (++) Dual Addressing mode
0521         (++) Own Address 2
0522         (++) Own Address 2 Mask
0523         (++) General call mode
0524         (++) Nostretch mode
0525 
0526       (+) Call the function HAL_I2C_DeInit() to restore the default configuration
0527           of the selected I2Cx peripheral.
0528 
0529 @endverbatim
0530   * @{
0531   */
0532 
0533 /**
0534   * @brief  Initializes the I2C according to the specified parameters
0535   *         in the I2C_InitTypeDef and initialize the associated handle.
0536   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0537   *                the configuration information for the specified I2C.
0538   * @retval HAL status
0539   */
0540 HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
0541 {
0542   /* Check the I2C handle allocation */
0543   if (hi2c == NULL)
0544   {
0545     return HAL_ERROR;
0546   }
0547 
0548   /* Check the parameters */
0549   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
0550   assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));
0551   assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));
0552   assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));
0553   assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));
0554   assert_param(IS_I2C_OWN_ADDRESS2_MASK(hi2c->Init.OwnAddress2Masks));
0555   assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));
0556   assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));
0557 
0558   if (hi2c->State == HAL_I2C_STATE_RESET)
0559   {
0560     /* Allocate lock resource and initialize it */
0561     hi2c->Lock = HAL_UNLOCKED;
0562 
0563 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
0564     /* Init the I2C Callback settings */
0565     hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
0566     hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
0567     hi2c->SlaveTxCpltCallback  = HAL_I2C_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
0568     hi2c->SlaveRxCpltCallback  = HAL_I2C_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
0569     hi2c->ListenCpltCallback   = HAL_I2C_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
0570     hi2c->MemTxCpltCallback    = HAL_I2C_MemTxCpltCallback;    /* Legacy weak MemTxCpltCallback    */
0571     hi2c->MemRxCpltCallback    = HAL_I2C_MemRxCpltCallback;    /* Legacy weak MemRxCpltCallback    */
0572     hi2c->ErrorCallback        = HAL_I2C_ErrorCallback;        /* Legacy weak ErrorCallback        */
0573     hi2c->AbortCpltCallback    = HAL_I2C_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
0574     hi2c->AddrCallback         = HAL_I2C_AddrCallback;         /* Legacy weak AddrCallback         */
0575 
0576     if (hi2c->MspInitCallback == NULL)
0577     {
0578       hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit  */
0579     }
0580 
0581     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
0582     hi2c->MspInitCallback(hi2c);
0583 #else
0584     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
0585     HAL_I2C_MspInit(hi2c);
0586 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
0587   }
0588 
0589   hi2c->State = HAL_I2C_STATE_BUSY;
0590 
0591   /* Disable the selected I2C peripheral */
0592   __HAL_I2C_DISABLE(hi2c);
0593 
0594   /*---------------------------- I2Cx TIMINGR Configuration ------------------*/
0595   /* Configure I2Cx: Frequency range */
0596   hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK;
0597 
0598   /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
0599   /* Disable Own Address1 before set the Own Address1 configuration */
0600   hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
0601 
0602   /* Configure I2Cx: Own Address1 and ack own address1 mode */
0603   if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
0604   {
0605     hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1);
0606   }
0607   else /* I2C_ADDRESSINGMODE_10BIT */
0608   {
0609     hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1);
0610   }
0611 
0612   /*---------------------------- I2Cx CR2 Configuration ----------------------*/
0613   /* Configure I2Cx: Addressing Master mode */
0614   if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
0615   {
0616     SET_BIT(hi2c->Instance->CR2, I2C_CR2_ADD10);
0617   }
0618   else
0619   {
0620     /* Clear the I2C ADD10 bit */
0621     CLEAR_BIT(hi2c->Instance->CR2, I2C_CR2_ADD10);
0622   }
0623   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
0624   hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
0625 
0626   /*---------------------------- I2Cx OAR2 Configuration ---------------------*/
0627   /* Disable Own Address2 before set the Own Address2 configuration */
0628   hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE;
0629 
0630   /* Configure I2Cx: Dual mode and Own Address2 */
0631   hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | \
0632                           (hi2c->Init.OwnAddress2Masks << 8));
0633 
0634   /*---------------------------- I2Cx CR1 Configuration ----------------------*/
0635   /* Configure I2Cx: Generalcall and NoStretch mode */
0636   hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode);
0637 
0638   /* Enable the selected I2C peripheral */
0639   __HAL_I2C_ENABLE(hi2c);
0640 
0641   hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
0642   hi2c->State = HAL_I2C_STATE_READY;
0643   hi2c->PreviousState = I2C_STATE_NONE;
0644   hi2c->Mode = HAL_I2C_MODE_NONE;
0645 
0646   return HAL_OK;
0647 }
0648 
0649 /**
0650   * @brief  DeInitialize the I2C peripheral.
0651   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0652   *                the configuration information for the specified I2C.
0653   * @retval HAL status
0654   */
0655 HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
0656 {
0657   /* Check the I2C handle allocation */
0658   if (hi2c == NULL)
0659   {
0660     return HAL_ERROR;
0661   }
0662 
0663   /* Check the parameters */
0664   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
0665 
0666   hi2c->State = HAL_I2C_STATE_BUSY;
0667 
0668   /* Disable the I2C Peripheral Clock */
0669   __HAL_I2C_DISABLE(hi2c);
0670 
0671 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
0672   if (hi2c->MspDeInitCallback == NULL)
0673   {
0674     hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit  */
0675   }
0676 
0677   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
0678   hi2c->MspDeInitCallback(hi2c);
0679 #else
0680   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
0681   HAL_I2C_MspDeInit(hi2c);
0682 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
0683 
0684   hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
0685   hi2c->State = HAL_I2C_STATE_RESET;
0686   hi2c->PreviousState = I2C_STATE_NONE;
0687   hi2c->Mode = HAL_I2C_MODE_NONE;
0688 
0689   /* Release Lock */
0690   __HAL_UNLOCK(hi2c);
0691 
0692   return HAL_OK;
0693 }
0694 
0695 /**
0696   * @brief Initialize the I2C MSP.
0697   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0698   *                the configuration information for the specified I2C.
0699   * @retval None
0700   */
0701 __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
0702 {
0703   /* Prevent unused argument(s) compilation warning */
0704   UNUSED(hi2c);
0705 
0706   /* NOTE : This function should not be modified, when the callback is needed,
0707             the HAL_I2C_MspInit could be implemented in the user file
0708    */
0709 }
0710 
0711 /**
0712   * @brief DeInitialize the I2C MSP.
0713   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0714   *                the configuration information for the specified I2C.
0715   * @retval None
0716   */
0717 __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
0718 {
0719   /* Prevent unused argument(s) compilation warning */
0720   UNUSED(hi2c);
0721 
0722   /* NOTE : This function should not be modified, when the callback is needed,
0723             the HAL_I2C_MspDeInit could be implemented in the user file
0724    */
0725 }
0726 
0727 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
0728 /**
0729   * @brief  Register a User I2C Callback
0730   *         To be used instead of the weak predefined callback
0731   * @note   The HAL_I2C_RegisterCallback() may be called before HAL_I2C_Init() in HAL_I2C_STATE_RESET
0732   *         to register callbacks for HAL_I2C_MSPINIT_CB_ID and HAL_I2C_MSPDEINIT_CB_ID.
0733   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0734   *                the configuration information for the specified I2C.
0735   * @param  CallbackID ID of the callback to be registered
0736   *         This parameter can be one of the following values:
0737   *          @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
0738   *          @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
0739   *          @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
0740   *          @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
0741   *          @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
0742   *          @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
0743   *          @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
0744   *          @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
0745   *          @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
0746   *          @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
0747   *          @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
0748   * @param  pCallback pointer to the Callback function
0749   * @retval HAL status
0750   */
0751 HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID,
0752                                            pI2C_CallbackTypeDef pCallback)
0753 {
0754   HAL_StatusTypeDef status = HAL_OK;
0755 
0756   if (pCallback == NULL)
0757   {
0758     /* Update the error code */
0759     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0760 
0761     return HAL_ERROR;
0762   }
0763 
0764   if (HAL_I2C_STATE_READY == hi2c->State)
0765   {
0766     switch (CallbackID)
0767     {
0768       case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
0769         hi2c->MasterTxCpltCallback = pCallback;
0770         break;
0771 
0772       case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
0773         hi2c->MasterRxCpltCallback = pCallback;
0774         break;
0775 
0776       case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
0777         hi2c->SlaveTxCpltCallback = pCallback;
0778         break;
0779 
0780       case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
0781         hi2c->SlaveRxCpltCallback = pCallback;
0782         break;
0783 
0784       case HAL_I2C_LISTEN_COMPLETE_CB_ID :
0785         hi2c->ListenCpltCallback = pCallback;
0786         break;
0787 
0788       case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
0789         hi2c->MemTxCpltCallback = pCallback;
0790         break;
0791 
0792       case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
0793         hi2c->MemRxCpltCallback = pCallback;
0794         break;
0795 
0796       case HAL_I2C_ERROR_CB_ID :
0797         hi2c->ErrorCallback = pCallback;
0798         break;
0799 
0800       case HAL_I2C_ABORT_CB_ID :
0801         hi2c->AbortCpltCallback = pCallback;
0802         break;
0803 
0804       case HAL_I2C_MSPINIT_CB_ID :
0805         hi2c->MspInitCallback = pCallback;
0806         break;
0807 
0808       case HAL_I2C_MSPDEINIT_CB_ID :
0809         hi2c->MspDeInitCallback = pCallback;
0810         break;
0811 
0812       default :
0813         /* Update the error code */
0814         hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0815 
0816         /* Return error status */
0817         status =  HAL_ERROR;
0818         break;
0819     }
0820   }
0821   else if (HAL_I2C_STATE_RESET == hi2c->State)
0822   {
0823     switch (CallbackID)
0824     {
0825       case HAL_I2C_MSPINIT_CB_ID :
0826         hi2c->MspInitCallback = pCallback;
0827         break;
0828 
0829       case HAL_I2C_MSPDEINIT_CB_ID :
0830         hi2c->MspDeInitCallback = pCallback;
0831         break;
0832 
0833       default :
0834         /* Update the error code */
0835         hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0836 
0837         /* Return error status */
0838         status =  HAL_ERROR;
0839         break;
0840     }
0841   }
0842   else
0843   {
0844     /* Update the error code */
0845     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0846 
0847     /* Return error status */
0848     status =  HAL_ERROR;
0849   }
0850 
0851   return status;
0852 }
0853 
0854 /**
0855   * @brief  Unregister an I2C Callback
0856   *         I2C callback is redirected to the weak predefined callback
0857   * @note   The HAL_I2C_UnRegisterCallback() may be called before HAL_I2C_Init() in HAL_I2C_STATE_RESET
0858   *         to un-register callbacks for HAL_I2C_MSPINIT_CB_ID and HAL_I2C_MSPDEINIT_CB_ID.
0859   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0860   *                the configuration information for the specified I2C.
0861   * @param  CallbackID ID of the callback to be unregistered
0862   *         This parameter can be one of the following values:
0863   *         This parameter can be one of the following values:
0864   *          @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
0865   *          @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
0866   *          @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
0867   *          @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
0868   *          @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
0869   *          @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
0870   *          @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
0871   *          @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID
0872   *          @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID
0873   *          @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID
0874   *          @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID
0875   * @retval HAL status
0876   */
0877 HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID)
0878 {
0879   HAL_StatusTypeDef status = HAL_OK;
0880 
0881   if (HAL_I2C_STATE_READY == hi2c->State)
0882   {
0883     switch (CallbackID)
0884     {
0885       case HAL_I2C_MASTER_TX_COMPLETE_CB_ID :
0886         hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
0887         break;
0888 
0889       case HAL_I2C_MASTER_RX_COMPLETE_CB_ID :
0890         hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
0891         break;
0892 
0893       case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID :
0894         hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
0895         break;
0896 
0897       case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID :
0898         hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
0899         break;
0900 
0901       case HAL_I2C_LISTEN_COMPLETE_CB_ID :
0902         hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
0903         break;
0904 
0905       case HAL_I2C_MEM_TX_COMPLETE_CB_ID :
0906         hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback;       /* Legacy weak MemTxCpltCallback    */
0907         break;
0908 
0909       case HAL_I2C_MEM_RX_COMPLETE_CB_ID :
0910         hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback;       /* Legacy weak MemRxCpltCallback    */
0911         break;
0912 
0913       case HAL_I2C_ERROR_CB_ID :
0914         hi2c->ErrorCallback = HAL_I2C_ErrorCallback;               /* Legacy weak ErrorCallback        */
0915         break;
0916 
0917       case HAL_I2C_ABORT_CB_ID :
0918         hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
0919         break;
0920 
0921       case HAL_I2C_MSPINIT_CB_ID :
0922         hi2c->MspInitCallback = HAL_I2C_MspInit;                   /* Legacy weak MspInit              */
0923         break;
0924 
0925       case HAL_I2C_MSPDEINIT_CB_ID :
0926         hi2c->MspDeInitCallback = HAL_I2C_MspDeInit;               /* Legacy weak MspDeInit            */
0927         break;
0928 
0929       default :
0930         /* Update the error code */
0931         hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0932 
0933         /* Return error status */
0934         status =  HAL_ERROR;
0935         break;
0936     }
0937   }
0938   else if (HAL_I2C_STATE_RESET == hi2c->State)
0939   {
0940     switch (CallbackID)
0941     {
0942       case HAL_I2C_MSPINIT_CB_ID :
0943         hi2c->MspInitCallback = HAL_I2C_MspInit;                   /* Legacy weak MspInit              */
0944         break;
0945 
0946       case HAL_I2C_MSPDEINIT_CB_ID :
0947         hi2c->MspDeInitCallback = HAL_I2C_MspDeInit;               /* Legacy weak MspDeInit            */
0948         break;
0949 
0950       default :
0951         /* Update the error code */
0952         hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0953 
0954         /* Return error status */
0955         status =  HAL_ERROR;
0956         break;
0957     }
0958   }
0959   else
0960   {
0961     /* Update the error code */
0962     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0963 
0964     /* Return error status */
0965     status =  HAL_ERROR;
0966   }
0967 
0968   return status;
0969 }
0970 
0971 /**
0972   * @brief  Register the Slave Address Match I2C Callback
0973   *         To be used instead of the weak HAL_I2C_AddrCallback() predefined callback
0974   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
0975   *                the configuration information for the specified I2C.
0976   * @param  pCallback pointer to the Address Match Callback function
0977   * @retval HAL status
0978   */
0979 HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback)
0980 {
0981   HAL_StatusTypeDef status = HAL_OK;
0982 
0983   if (pCallback == NULL)
0984   {
0985     /* Update the error code */
0986     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0987 
0988     return HAL_ERROR;
0989   }
0990 
0991   if (HAL_I2C_STATE_READY == hi2c->State)
0992   {
0993     hi2c->AddrCallback = pCallback;
0994   }
0995   else
0996   {
0997     /* Update the error code */
0998     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
0999 
1000     /* Return error status */
1001     status =  HAL_ERROR;
1002   }
1003 
1004   return status;
1005 }
1006 
1007 /**
1008   * @brief  UnRegister the Slave Address Match I2C Callback
1009   *         Info Ready I2C Callback is redirected to the weak HAL_I2C_AddrCallback() predefined callback
1010   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1011   *                the configuration information for the specified I2C.
1012   * @retval HAL status
1013   */
1014 HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c)
1015 {
1016   HAL_StatusTypeDef status = HAL_OK;
1017 
1018   if (HAL_I2C_STATE_READY == hi2c->State)
1019   {
1020     hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback  */
1021   }
1022   else
1023   {
1024     /* Update the error code */
1025     hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK;
1026 
1027     /* Return error status */
1028     status =  HAL_ERROR;
1029   }
1030 
1031   return status;
1032 }
1033 
1034 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
1035 
1036 /**
1037   * @}
1038   */
1039 
1040 /** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions
1041   * @ingroup RTEMSBSPsARMSTM32H7
1042   *  @brief   Data transfers functions
1043   *
1044 @verbatim
1045  ===============================================================================
1046                       ##### IO operation functions #####
1047  ===============================================================================
1048     [..]
1049     This subsection provides a set of functions allowing to manage the I2C data
1050     transfers.
1051 
1052     (#) There are two modes of transfer:
1053        (++) Blocking mode : The communication is performed in the polling mode.
1054             The status of all data processing is returned by the same function
1055             after finishing transfer.
1056        (++) No-Blocking mode : The communication is performed using Interrupts
1057             or DMA. These functions return the status of the transfer startup.
1058             The end of the data processing will be indicated through the
1059             dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when
1060             using DMA mode.
1061 
1062     (#) Blocking mode functions are :
1063         (++) HAL_I2C_Master_Transmit()
1064         (++) HAL_I2C_Master_Receive()
1065         (++) HAL_I2C_Slave_Transmit()
1066         (++) HAL_I2C_Slave_Receive()
1067         (++) HAL_I2C_Mem_Write()
1068         (++) HAL_I2C_Mem_Read()
1069         (++) HAL_I2C_IsDeviceReady()
1070 
1071     (#) No-Blocking mode functions with Interrupt are :
1072         (++) HAL_I2C_Master_Transmit_IT()
1073         (++) HAL_I2C_Master_Receive_IT()
1074         (++) HAL_I2C_Slave_Transmit_IT()
1075         (++) HAL_I2C_Slave_Receive_IT()
1076         (++) HAL_I2C_Mem_Write_IT()
1077         (++) HAL_I2C_Mem_Read_IT()
1078         (++) HAL_I2C_Master_Seq_Transmit_IT()
1079         (++) HAL_I2C_Master_Seq_Receive_IT()
1080         (++) HAL_I2C_Slave_Seq_Transmit_IT()
1081         (++) HAL_I2C_Slave_Seq_Receive_IT()
1082         (++) HAL_I2C_EnableListen_IT()
1083         (++) HAL_I2C_DisableListen_IT()
1084         (++) HAL_I2C_Master_Abort_IT()
1085 
1086     (#) No-Blocking mode functions with DMA are :
1087         (++) HAL_I2C_Master_Transmit_DMA()
1088         (++) HAL_I2C_Master_Receive_DMA()
1089         (++) HAL_I2C_Slave_Transmit_DMA()
1090         (++) HAL_I2C_Slave_Receive_DMA()
1091         (++) HAL_I2C_Mem_Write_DMA()
1092         (++) HAL_I2C_Mem_Read_DMA()
1093         (++) HAL_I2C_Master_Seq_Transmit_DMA()
1094         (++) HAL_I2C_Master_Seq_Receive_DMA()
1095         (++) HAL_I2C_Slave_Seq_Transmit_DMA()
1096         (++) HAL_I2C_Slave_Seq_Receive_DMA()
1097 
1098     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
1099         (++) HAL_I2C_MasterTxCpltCallback()
1100         (++) HAL_I2C_MasterRxCpltCallback()
1101         (++) HAL_I2C_SlaveTxCpltCallback()
1102         (++) HAL_I2C_SlaveRxCpltCallback()
1103         (++) HAL_I2C_MemTxCpltCallback()
1104         (++) HAL_I2C_MemRxCpltCallback()
1105         (++) HAL_I2C_AddrCallback()
1106         (++) HAL_I2C_ListenCpltCallback()
1107         (++) HAL_I2C_ErrorCallback()
1108         (++) HAL_I2C_AbortCpltCallback()
1109 
1110 @endverbatim
1111   * @{
1112   */
1113 
1114 /**
1115   * @brief  Transmits in master mode an amount of data in blocking mode.
1116   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1117   *                the configuration information for the specified I2C.
1118   * @param  DevAddress Target device address: The device 7 bits address value
1119   *         in datasheet must be shifted to the left before calling the interface
1120   * @param  pData Pointer to data buffer
1121   * @param  Size Amount of data to be sent
1122   * @param  Timeout Timeout duration
1123   * @retval HAL status
1124   */
1125 HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1126                                           uint16_t Size, uint32_t Timeout)
1127 {
1128   uint32_t tickstart;
1129   uint32_t xfermode;
1130 
1131   if (hi2c->State == HAL_I2C_STATE_READY)
1132   {
1133     /* Process Locked */
1134     __HAL_LOCK(hi2c);
1135 
1136     /* Init tickstart for timeout management*/
1137     tickstart = HAL_GetTick();
1138 
1139     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1140     {
1141       return HAL_ERROR;
1142     }
1143 
1144     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
1145     hi2c->Mode      = HAL_I2C_MODE_MASTER;
1146     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1147 
1148     /* Prepare transfer parameters */
1149     hi2c->pBuffPtr  = pData;
1150     hi2c->XferCount = Size;
1151     hi2c->XferISR   = NULL;
1152 
1153     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1154     {
1155       hi2c->XferSize = MAX_NBYTE_SIZE;
1156       xfermode = I2C_RELOAD_MODE;
1157     }
1158     else
1159     {
1160       hi2c->XferSize = hi2c->XferCount;
1161       xfermode = I2C_AUTOEND_MODE;
1162     }
1163 
1164     if (hi2c->XferSize > 0U)
1165     {
1166       /* Preload TX register */
1167       /* Write data to TXDR */
1168       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1169 
1170       /* Increment Buffer pointer */
1171       hi2c->pBuffPtr++;
1172 
1173       hi2c->XferCount--;
1174       hi2c->XferSize--;
1175 
1176       /* Send Slave Address */
1177       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1178       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)(hi2c->XferSize + 1U), xfermode,
1179                          I2C_GENERATE_START_WRITE);
1180     }
1181     else
1182     {
1183       /* Send Slave Address */
1184       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1185       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode,
1186                          I2C_GENERATE_START_WRITE);
1187     }
1188 
1189     while (hi2c->XferCount > 0U)
1190     {
1191       /* Wait until TXIS flag is set */
1192       if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1193       {
1194         return HAL_ERROR;
1195       }
1196       /* Write data to TXDR */
1197       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1198 
1199       /* Increment Buffer pointer */
1200       hi2c->pBuffPtr++;
1201 
1202       hi2c->XferCount--;
1203       hi2c->XferSize--;
1204 
1205       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
1206       {
1207         /* Wait until TCR flag is set */
1208         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1209         {
1210           return HAL_ERROR;
1211         }
1212 
1213         if (hi2c->XferCount > MAX_NBYTE_SIZE)
1214         {
1215           hi2c->XferSize = MAX_NBYTE_SIZE;
1216           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1217                              I2C_NO_STARTSTOP);
1218         }
1219         else
1220         {
1221           hi2c->XferSize = hi2c->XferCount;
1222           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1223                              I2C_NO_STARTSTOP);
1224         }
1225       }
1226     }
1227 
1228     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1229     /* Wait until STOPF flag is set */
1230     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1231     {
1232       return HAL_ERROR;
1233     }
1234 
1235     /* Clear STOP Flag */
1236     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1237 
1238     /* Clear Configuration Register 2 */
1239     I2C_RESET_CR2(hi2c);
1240 
1241     hi2c->State = HAL_I2C_STATE_READY;
1242     hi2c->Mode  = HAL_I2C_MODE_NONE;
1243 
1244     /* Process Unlocked */
1245     __HAL_UNLOCK(hi2c);
1246 
1247     return HAL_OK;
1248   }
1249   else
1250   {
1251     return HAL_BUSY;
1252   }
1253 }
1254 
1255 /**
1256   * @brief  Receives in master mode an amount of data in blocking mode.
1257   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1258   *                the configuration information for the specified I2C.
1259   * @param  DevAddress Target device address: The device 7 bits address value
1260   *         in datasheet must be shifted to the left before calling the interface
1261   * @param  pData Pointer to data buffer
1262   * @param  Size Amount of data to be sent
1263   * @param  Timeout Timeout duration
1264   * @retval HAL status
1265   */
1266 HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1267                                          uint16_t Size, uint32_t Timeout)
1268 {
1269   uint32_t tickstart;
1270 
1271   if (hi2c->State == HAL_I2C_STATE_READY)
1272   {
1273     /* Process Locked */
1274     __HAL_LOCK(hi2c);
1275 
1276     /* Init tickstart for timeout management*/
1277     tickstart = HAL_GetTick();
1278 
1279     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1280     {
1281       return HAL_ERROR;
1282     }
1283 
1284     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
1285     hi2c->Mode      = HAL_I2C_MODE_MASTER;
1286     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1287 
1288     /* Prepare transfer parameters */
1289     hi2c->pBuffPtr  = pData;
1290     hi2c->XferCount = Size;
1291     hi2c->XferISR   = NULL;
1292 
1293     /* Send Slave Address */
1294     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1295     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1296     {
1297       hi2c->XferSize = MAX_NBYTE_SIZE;
1298       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1299                          I2C_GENERATE_START_READ);
1300     }
1301     else
1302     {
1303       hi2c->XferSize = hi2c->XferCount;
1304       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1305                          I2C_GENERATE_START_READ);
1306     }
1307 
1308     while (hi2c->XferCount > 0U)
1309     {
1310       /* Wait until RXNE flag is set */
1311       if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1312       {
1313         return HAL_ERROR;
1314       }
1315 
1316       /* Read data from RXDR */
1317       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1318 
1319       /* Increment Buffer pointer */
1320       hi2c->pBuffPtr++;
1321 
1322       hi2c->XferSize--;
1323       hi2c->XferCount--;
1324 
1325       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
1326       {
1327         /* Wait until TCR flag is set */
1328         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1329         {
1330           return HAL_ERROR;
1331         }
1332 
1333         if (hi2c->XferCount > MAX_NBYTE_SIZE)
1334         {
1335           hi2c->XferSize = MAX_NBYTE_SIZE;
1336           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
1337                              I2C_NO_STARTSTOP);
1338         }
1339         else
1340         {
1341           hi2c->XferSize = hi2c->XferCount;
1342           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
1343                              I2C_NO_STARTSTOP);
1344         }
1345       }
1346     }
1347 
1348     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1349     /* Wait until STOPF flag is set */
1350     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1351     {
1352       return HAL_ERROR;
1353     }
1354 
1355     /* Clear STOP Flag */
1356     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1357 
1358     /* Clear Configuration Register 2 */
1359     I2C_RESET_CR2(hi2c);
1360 
1361     hi2c->State = HAL_I2C_STATE_READY;
1362     hi2c->Mode  = HAL_I2C_MODE_NONE;
1363 
1364     /* Process Unlocked */
1365     __HAL_UNLOCK(hi2c);
1366 
1367     return HAL_OK;
1368   }
1369   else
1370   {
1371     return HAL_BUSY;
1372   }
1373 }
1374 
1375 /**
1376   * @brief  Transmits in slave mode an amount of data in blocking mode.
1377   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1378   *                the configuration information for the specified I2C.
1379   * @param  pData Pointer to data buffer
1380   * @param  Size Amount of data to be sent
1381   * @param  Timeout Timeout duration
1382   * @retval HAL status
1383   */
1384 HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
1385                                          uint32_t Timeout)
1386 {
1387   uint32_t tickstart;
1388   uint16_t tmpXferCount;
1389   HAL_StatusTypeDef error;
1390 
1391   if (hi2c->State == HAL_I2C_STATE_READY)
1392   {
1393     if ((pData == NULL) || (Size == 0U))
1394     {
1395       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1396       return  HAL_ERROR;
1397     }
1398     /* Process Locked */
1399     __HAL_LOCK(hi2c);
1400 
1401     /* Init tickstart for timeout management*/
1402     tickstart = HAL_GetTick();
1403 
1404     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
1405     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1406     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1407 
1408     /* Prepare transfer parameters */
1409     hi2c->pBuffPtr  = pData;
1410     hi2c->XferCount = Size;
1411     hi2c->XferISR   = NULL;
1412 
1413     /* Enable Address Acknowledge */
1414     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1415 
1416     /* Wait until ADDR flag is set */
1417     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1418     {
1419       /* Disable Address Acknowledge */
1420       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1421       return HAL_ERROR;
1422     }
1423 
1424     /* Preload TX data if no stretch enable */
1425     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
1426     {
1427       /* Preload TX register */
1428       /* Write data to TXDR */
1429       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1430 
1431       /* Increment Buffer pointer */
1432       hi2c->pBuffPtr++;
1433 
1434       hi2c->XferCount--;
1435     }
1436 
1437     /* Clear ADDR flag */
1438     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1439 
1440     /* If 10bit addressing mode is selected */
1441     if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
1442     {
1443       /* Wait until ADDR flag is set */
1444       if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1445       {
1446         /* Disable Address Acknowledge */
1447         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1448         return HAL_ERROR;
1449       }
1450 
1451       /* Clear ADDR flag */
1452       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1453     }
1454 
1455     /* Wait until DIR flag is set Transmitter mode */
1456     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
1457     {
1458       /* Disable Address Acknowledge */
1459       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1460       return HAL_ERROR;
1461     }
1462 
1463     while (hi2c->XferCount > 0U)
1464     {
1465       /* Wait until TXIS flag is set */
1466       if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1467       {
1468         /* Disable Address Acknowledge */
1469         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1470         return HAL_ERROR;
1471       }
1472 
1473       /* Write data to TXDR */
1474       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1475 
1476       /* Increment Buffer pointer */
1477       hi2c->pBuffPtr++;
1478 
1479       hi2c->XferCount--;
1480     }
1481 
1482     /* Wait until AF flag is set */
1483     error = I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart);
1484 
1485     if (error != HAL_OK)
1486     {
1487       /* Check that I2C transfer finished */
1488       /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
1489       /* Mean XferCount == 0 */
1490 
1491       tmpXferCount = hi2c->XferCount;
1492       if ((hi2c->ErrorCode == HAL_I2C_ERROR_AF) && (tmpXferCount == 0U))
1493       {
1494         /* Reset ErrorCode to NONE */
1495         hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1496       }
1497       else
1498       {
1499         /* Disable Address Acknowledge */
1500         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1501         return HAL_ERROR;
1502       }
1503     }
1504     else
1505     {
1506       /* Flush TX register */
1507       I2C_Flush_TXDR(hi2c);
1508 
1509       /* Clear AF flag */
1510       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
1511 
1512       /* Wait until STOP flag is set */
1513       if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1514       {
1515         /* Disable Address Acknowledge */
1516         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1517 
1518         return HAL_ERROR;
1519       }
1520 
1521       /* Clear STOP flag */
1522       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1523     }
1524 
1525     /* Wait until BUSY flag is reset */
1526     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1527     {
1528       /* Disable Address Acknowledge */
1529       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1530       return HAL_ERROR;
1531     }
1532 
1533     /* Disable Address Acknowledge */
1534     hi2c->Instance->CR2 |= I2C_CR2_NACK;
1535 
1536     hi2c->State = HAL_I2C_STATE_READY;
1537     hi2c->Mode  = HAL_I2C_MODE_NONE;
1538 
1539     /* Process Unlocked */
1540     __HAL_UNLOCK(hi2c);
1541 
1542     return HAL_OK;
1543   }
1544   else
1545   {
1546     return HAL_BUSY;
1547   }
1548 }
1549 
1550 /**
1551   * @brief  Receive in slave mode an amount of data in blocking mode
1552   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1553   *                the configuration information for the specified I2C.
1554   * @param  pData Pointer to data buffer
1555   * @param  Size Amount of data to be sent
1556   * @param  Timeout Timeout duration
1557   * @retval HAL status
1558   */
1559 HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
1560                                         uint32_t Timeout)
1561 {
1562   uint32_t tickstart;
1563 
1564   if (hi2c->State == HAL_I2C_STATE_READY)
1565   {
1566     if ((pData == NULL) || (Size == 0U))
1567     {
1568       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1569       return  HAL_ERROR;
1570     }
1571     /* Process Locked */
1572     __HAL_LOCK(hi2c);
1573 
1574     /* Init tickstart for timeout management*/
1575     tickstart = HAL_GetTick();
1576 
1577     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
1578     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1579     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1580 
1581     /* Prepare transfer parameters */
1582     hi2c->pBuffPtr  = pData;
1583     hi2c->XferCount = Size;
1584     hi2c->XferSize = hi2c->XferCount;
1585     hi2c->XferISR   = NULL;
1586 
1587     /* Enable Address Acknowledge */
1588     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1589 
1590     /* Wait until ADDR flag is set */
1591     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1592     {
1593       /* Disable Address Acknowledge */
1594       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1595       return HAL_ERROR;
1596     }
1597 
1598     /* Clear ADDR flag */
1599     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1600 
1601     /* Wait until DIR flag is reset Receiver mode */
1602     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1603     {
1604       /* Disable Address Acknowledge */
1605       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1606       return HAL_ERROR;
1607     }
1608 
1609     while (hi2c->XferCount > 0U)
1610     {
1611       /* Wait until RXNE flag is set */
1612       if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1613       {
1614         /* Disable Address Acknowledge */
1615         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1616 
1617         /* Store Last receive data if any */
1618         if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
1619         {
1620           /* Read data from RXDR */
1621           *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1622 
1623           /* Increment Buffer pointer */
1624           hi2c->pBuffPtr++;
1625 
1626           hi2c->XferCount--;
1627           hi2c->XferSize--;
1628         }
1629 
1630         return HAL_ERROR;
1631       }
1632 
1633       /* Read data from RXDR */
1634       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1635 
1636       /* Increment Buffer pointer */
1637       hi2c->pBuffPtr++;
1638 
1639       hi2c->XferCount--;
1640       hi2c->XferSize--;
1641     }
1642 
1643     /* Wait until STOP flag is set */
1644     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1645     {
1646       /* Disable Address Acknowledge */
1647       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1648       return HAL_ERROR;
1649     }
1650 
1651     /* Clear STOP flag */
1652     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1653 
1654     /* Wait until BUSY flag is reset */
1655     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1656     {
1657       /* Disable Address Acknowledge */
1658       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1659       return HAL_ERROR;
1660     }
1661 
1662     /* Disable Address Acknowledge */
1663     hi2c->Instance->CR2 |= I2C_CR2_NACK;
1664 
1665     hi2c->State = HAL_I2C_STATE_READY;
1666     hi2c->Mode  = HAL_I2C_MODE_NONE;
1667 
1668     /* Process Unlocked */
1669     __HAL_UNLOCK(hi2c);
1670 
1671     return HAL_OK;
1672   }
1673   else
1674   {
1675     return HAL_BUSY;
1676   }
1677 }
1678 
1679 /**
1680   * @brief  Transmit in master mode an amount of data in non-blocking mode with Interrupt
1681   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1682   *                the configuration information for the specified I2C.
1683   * @param  DevAddress Target device address: The device 7 bits address value
1684   *         in datasheet must be shifted to the left before calling the interface
1685   * @param  pData Pointer to data buffer
1686   * @param  Size Amount of data to be sent
1687   * @retval HAL status
1688   */
1689 HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1690                                              uint16_t Size)
1691 {
1692   uint32_t xfermode;
1693 
1694   if (hi2c->State == HAL_I2C_STATE_READY)
1695   {
1696     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1697     {
1698       return HAL_BUSY;
1699     }
1700 
1701     /* Process Locked */
1702     __HAL_LOCK(hi2c);
1703 
1704     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1705     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1706     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1707 
1708     /* Prepare transfer parameters */
1709     hi2c->pBuffPtr    = pData;
1710     hi2c->XferCount   = Size;
1711     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1712     hi2c->XferISR     = I2C_Master_ISR_IT;
1713 
1714     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1715     {
1716       hi2c->XferSize = MAX_NBYTE_SIZE;
1717       xfermode = I2C_RELOAD_MODE;
1718     }
1719     else
1720     {
1721       hi2c->XferSize = hi2c->XferCount;
1722       xfermode = I2C_AUTOEND_MODE;
1723     }
1724 
1725     /* Send Slave Address */
1726     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1727     if (hi2c->XferSize > 0U)
1728     {
1729       /* Preload TX register */
1730       /* Write data to TXDR */
1731       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1732 
1733       /* Increment Buffer pointer */
1734       hi2c->pBuffPtr++;
1735 
1736       hi2c->XferCount--;
1737       hi2c->XferSize--;
1738 
1739       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)(hi2c->XferSize + 1U), xfermode,
1740                          I2C_GENERATE_START_WRITE);
1741     }
1742     else
1743     {
1744       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode,
1745                          I2C_GENERATE_START_WRITE);
1746     }
1747 
1748     /* Process Unlocked */
1749     __HAL_UNLOCK(hi2c);
1750 
1751     /* Note : The I2C interrupts must be enabled after unlocking current process
1752               to avoid the risk of I2C interrupt handle execution before current
1753               process unlock */
1754 
1755     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1756     /* possible to enable all of these */
1757     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1758       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1759     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
1760 
1761     return HAL_OK;
1762   }
1763   else
1764   {
1765     return HAL_BUSY;
1766   }
1767 }
1768 
1769 /**
1770   * @brief  Receive in master mode an amount of data in non-blocking mode with Interrupt
1771   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1772   *                the configuration information for the specified I2C.
1773   * @param  DevAddress Target device address: The device 7 bits address value
1774   *         in datasheet must be shifted to the left before calling the interface
1775   * @param  pData Pointer to data buffer
1776   * @param  Size Amount of data to be sent
1777   * @retval HAL status
1778   */
1779 HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1780                                             uint16_t Size)
1781 {
1782   uint32_t xfermode;
1783 
1784   if (hi2c->State == HAL_I2C_STATE_READY)
1785   {
1786     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1787     {
1788       return HAL_BUSY;
1789     }
1790 
1791     /* Process Locked */
1792     __HAL_LOCK(hi2c);
1793 
1794     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1795     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1796     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1797 
1798     /* Prepare transfer parameters */
1799     hi2c->pBuffPtr    = pData;
1800     hi2c->XferCount   = Size;
1801     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1802     hi2c->XferISR     = I2C_Master_ISR_IT;
1803 
1804     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1805     {
1806       hi2c->XferSize = MAX_NBYTE_SIZE;
1807       xfermode = I2C_RELOAD_MODE;
1808     }
1809     else
1810     {
1811       hi2c->XferSize = hi2c->XferCount;
1812       xfermode = I2C_AUTOEND_MODE;
1813     }
1814 
1815     /* Send Slave Address */
1816     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1817     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
1818 
1819     /* Process Unlocked */
1820     __HAL_UNLOCK(hi2c);
1821 
1822     /* Note : The I2C interrupts must be enabled after unlocking current process
1823               to avoid the risk of I2C interrupt handle execution before current
1824               process unlock */
1825 
1826     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1827     /* possible to enable all of these */
1828     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1829       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1830     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
1831 
1832     return HAL_OK;
1833   }
1834   else
1835   {
1836     return HAL_BUSY;
1837   }
1838 }
1839 
1840 /**
1841   * @brief  Transmit in slave mode an amount of data in non-blocking mode with Interrupt
1842   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1843   *                the configuration information for the specified I2C.
1844   * @param  pData Pointer to data buffer
1845   * @param  Size Amount of data to be sent
1846   * @retval HAL status
1847   */
1848 HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1849 {
1850   if (hi2c->State == HAL_I2C_STATE_READY)
1851   {
1852     /* Process Locked */
1853     __HAL_LOCK(hi2c);
1854 
1855     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1856     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1857     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1858 
1859     /* Enable Address Acknowledge */
1860     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1861 
1862     /* Prepare transfer parameters */
1863     hi2c->pBuffPtr    = pData;
1864     hi2c->XferCount   = Size;
1865     hi2c->XferSize    = hi2c->XferCount;
1866     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1867     hi2c->XferISR     = I2C_Slave_ISR_IT;
1868 
1869     /* Preload TX data if no stretch enable */
1870     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
1871     {
1872       /* Preload TX register */
1873       /* Write data to TXDR */
1874       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1875 
1876       /* Increment Buffer pointer */
1877       hi2c->pBuffPtr++;
1878 
1879       hi2c->XferCount--;
1880       hi2c->XferSize--;
1881     }
1882 
1883     /* Process Unlocked */
1884     __HAL_UNLOCK(hi2c);
1885 
1886     /* Note : The I2C interrupts must be enabled after unlocking current process
1887               to avoid the risk of I2C interrupt handle execution before current
1888               process unlock */
1889 
1890     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1891     /* possible to enable all of these */
1892     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1893       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1894     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
1895 
1896     return HAL_OK;
1897   }
1898   else
1899   {
1900     return HAL_BUSY;
1901   }
1902 }
1903 
1904 /**
1905   * @brief  Receive in slave mode an amount of data in non-blocking mode with Interrupt
1906   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1907   *                the configuration information for the specified I2C.
1908   * @param  pData Pointer to data buffer
1909   * @param  Size Amount of data to be sent
1910   * @retval HAL status
1911   */
1912 HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1913 {
1914   if (hi2c->State == HAL_I2C_STATE_READY)
1915   {
1916     /* Process Locked */
1917     __HAL_LOCK(hi2c);
1918 
1919     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1920     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1921     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1922 
1923     /* Enable Address Acknowledge */
1924     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1925 
1926     /* Prepare transfer parameters */
1927     hi2c->pBuffPtr    = pData;
1928     hi2c->XferCount   = Size;
1929     hi2c->XferSize    = hi2c->XferCount;
1930     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1931     hi2c->XferISR     = I2C_Slave_ISR_IT;
1932 
1933     /* Process Unlocked */
1934     __HAL_UNLOCK(hi2c);
1935 
1936     /* Note : The I2C interrupts must be enabled after unlocking current process
1937               to avoid the risk of I2C interrupt handle execution before current
1938               process unlock */
1939 
1940     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1941     /* possible to enable all of these */
1942     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1943       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1944     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
1945 
1946     return HAL_OK;
1947   }
1948   else
1949   {
1950     return HAL_BUSY;
1951   }
1952 }
1953 
1954 /**
1955   * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
1956   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1957   *                the configuration information for the specified I2C.
1958   * @param  DevAddress Target device address: The device 7 bits address value
1959   *         in datasheet must be shifted to the left before calling the interface
1960   * @param  pData Pointer to data buffer
1961   * @param  Size Amount of data to be sent
1962   * @retval HAL status
1963   */
1964 HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1965                                               uint16_t Size)
1966 {
1967   uint32_t xfermode;
1968   HAL_StatusTypeDef dmaxferstatus;
1969   uint32_t sizetoxfer = 0U;
1970 
1971   if (hi2c->State == HAL_I2C_STATE_READY)
1972   {
1973     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1974     {
1975       return HAL_BUSY;
1976     }
1977 
1978     /* Process Locked */
1979     __HAL_LOCK(hi2c);
1980 
1981     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1982     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1983     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1984 
1985     /* Prepare transfer parameters */
1986     hi2c->pBuffPtr    = pData;
1987     hi2c->XferCount   = Size;
1988     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1989     hi2c->XferISR     = I2C_Master_ISR_DMA;
1990 
1991     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1992     {
1993       hi2c->XferSize = MAX_NBYTE_SIZE;
1994       xfermode = I2C_RELOAD_MODE;
1995     }
1996     else
1997     {
1998       hi2c->XferSize = hi2c->XferCount;
1999       xfermode = I2C_AUTOEND_MODE;
2000     }
2001 
2002     if (hi2c->XferSize > 0U)
2003     {
2004       /* Preload TX register */
2005       /* Write data to TXDR */
2006       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2007 
2008       /* Increment Buffer pointer */
2009       hi2c->pBuffPtr++;
2010 
2011       sizetoxfer = hi2c->XferSize;
2012       hi2c->XferCount--;
2013       hi2c->XferSize--;
2014     }
2015 
2016     if (hi2c->XferSize > 0U)
2017     {
2018       if (hi2c->hdmatx != NULL)
2019       {
2020         /* Set the I2C DMA transfer complete callback */
2021         hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
2022 
2023         /* Set the DMA error callback */
2024         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2025 
2026         /* Set the unused DMA callbacks to NULL */
2027         hi2c->hdmatx->XferHalfCpltCallback = NULL;
2028         hi2c->hdmatx->XferAbortCallback = NULL;
2029 
2030         /* Enable the DMA stream or channel depends on Instance */
2031         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr,
2032                                          (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
2033       }
2034       else
2035       {
2036         /* Update I2C state */
2037         hi2c->State     = HAL_I2C_STATE_READY;
2038         hi2c->Mode      = HAL_I2C_MODE_NONE;
2039 
2040         /* Update I2C error code */
2041         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2042 
2043         /* Process Unlocked */
2044         __HAL_UNLOCK(hi2c);
2045 
2046         return HAL_ERROR;
2047       }
2048 
2049       if (dmaxferstatus == HAL_OK)
2050       {
2051         /* Send Slave Address */
2052         /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2053         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)(hi2c->XferSize + 1U),
2054                            xfermode, I2C_GENERATE_START_WRITE);
2055 
2056         /* Update XferCount value */
2057         hi2c->XferCount -= hi2c->XferSize;
2058 
2059         /* Process Unlocked */
2060         __HAL_UNLOCK(hi2c);
2061 
2062         /* Note : The I2C interrupts must be enabled after unlocking current process
2063                   to avoid the risk of I2C interrupt handle execution before current
2064                   process unlock */
2065         /* Enable ERR and NACK interrupts */
2066         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2067 
2068         /* Enable DMA Request */
2069         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2070       }
2071       else
2072       {
2073         /* Update I2C state */
2074         hi2c->State     = HAL_I2C_STATE_READY;
2075         hi2c->Mode      = HAL_I2C_MODE_NONE;
2076 
2077         /* Update I2C error code */
2078         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2079 
2080         /* Process Unlocked */
2081         __HAL_UNLOCK(hi2c);
2082 
2083         return HAL_ERROR;
2084       }
2085     }
2086     else
2087     {
2088       /* Update Transfer ISR function pointer */
2089       hi2c->XferISR = I2C_Master_ISR_IT;
2090 
2091       /* Send Slave Address */
2092       /* Set NBYTES to write and generate START condition */
2093       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, I2C_AUTOEND_MODE,
2094                          I2C_GENERATE_START_WRITE);
2095 
2096       /* Process Unlocked */
2097       __HAL_UNLOCK(hi2c);
2098 
2099       /* Note : The I2C interrupts must be enabled after unlocking current process
2100                 to avoid the risk of I2C interrupt handle execution before current
2101                 process unlock */
2102       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2103       /* possible to enable all of these */
2104       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2105         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2106       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2107     }
2108 
2109     return HAL_OK;
2110   }
2111   else
2112   {
2113     return HAL_BUSY;
2114   }
2115 }
2116 
2117 /**
2118   * @brief  Receive in master mode an amount of data in non-blocking mode with DMA
2119   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2120   *                the configuration information for the specified I2C.
2121   * @param  DevAddress Target device address: The device 7 bits address value
2122   *         in datasheet must be shifted to the left before calling the interface
2123   * @param  pData Pointer to data buffer
2124   * @param  Size Amount of data to be sent
2125   * @retval HAL status
2126   */
2127 HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
2128                                              uint16_t Size)
2129 {
2130   uint32_t xfermode;
2131   HAL_StatusTypeDef dmaxferstatus;
2132 
2133   if (hi2c->State == HAL_I2C_STATE_READY)
2134   {
2135     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2136     {
2137       return HAL_BUSY;
2138     }
2139 
2140     /* Process Locked */
2141     __HAL_LOCK(hi2c);
2142 
2143     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2144     hi2c->Mode        = HAL_I2C_MODE_MASTER;
2145     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2146 
2147     /* Prepare transfer parameters */
2148     hi2c->pBuffPtr    = pData;
2149     hi2c->XferCount   = Size;
2150     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2151     hi2c->XferISR     = I2C_Master_ISR_DMA;
2152 
2153     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2154     {
2155       hi2c->XferSize = MAX_NBYTE_SIZE;
2156       xfermode = I2C_RELOAD_MODE;
2157     }
2158     else
2159     {
2160       hi2c->XferSize = hi2c->XferCount;
2161       xfermode = I2C_AUTOEND_MODE;
2162     }
2163 
2164     if (hi2c->XferSize > 0U)
2165     {
2166       if (hi2c->hdmarx != NULL)
2167       {
2168         /* Set the I2C DMA transfer complete callback */
2169         hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
2170 
2171         /* Set the DMA error callback */
2172         hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2173 
2174         /* Set the unused DMA callbacks to NULL */
2175         hi2c->hdmarx->XferHalfCpltCallback = NULL;
2176         hi2c->hdmarx->XferAbortCallback = NULL;
2177 
2178         /* Enable the DMA stream or channel depends on Instance */
2179         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2180                                          hi2c->XferSize);
2181       }
2182       else
2183       {
2184         /* Update I2C state */
2185         hi2c->State     = HAL_I2C_STATE_READY;
2186         hi2c->Mode      = HAL_I2C_MODE_NONE;
2187 
2188         /* Update I2C error code */
2189         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2190 
2191         /* Process Unlocked */
2192         __HAL_UNLOCK(hi2c);
2193 
2194         return HAL_ERROR;
2195       }
2196 
2197       if (dmaxferstatus == HAL_OK)
2198       {
2199         /* Send Slave Address */
2200         /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2201         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
2202 
2203         /* Update XferCount value */
2204         hi2c->XferCount -= hi2c->XferSize;
2205 
2206         /* Process Unlocked */
2207         __HAL_UNLOCK(hi2c);
2208 
2209         /* Note : The I2C interrupts must be enabled after unlocking current process
2210                   to avoid the risk of I2C interrupt handle execution before current
2211                   process unlock */
2212         /* Enable ERR and NACK interrupts */
2213         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2214 
2215         /* Enable DMA Request */
2216         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2217       }
2218       else
2219       {
2220         /* Update I2C state */
2221         hi2c->State     = HAL_I2C_STATE_READY;
2222         hi2c->Mode      = HAL_I2C_MODE_NONE;
2223 
2224         /* Update I2C error code */
2225         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2226 
2227         /* Process Unlocked */
2228         __HAL_UNLOCK(hi2c);
2229 
2230         return HAL_ERROR;
2231       }
2232     }
2233     else
2234     {
2235       /* Update Transfer ISR function pointer */
2236       hi2c->XferISR = I2C_Master_ISR_IT;
2237 
2238       /* Send Slave Address */
2239       /* Set NBYTES to read and generate START condition */
2240       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2241                          I2C_GENERATE_START_READ);
2242 
2243       /* Process Unlocked */
2244       __HAL_UNLOCK(hi2c);
2245 
2246       /* Note : The I2C interrupts must be enabled after unlocking current process
2247                 to avoid the risk of I2C interrupt handle execution before current
2248                 process unlock */
2249       /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2250       /* possible to enable all of these */
2251       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2252         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2253       I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
2254     }
2255 
2256     return HAL_OK;
2257   }
2258   else
2259   {
2260     return HAL_BUSY;
2261   }
2262 }
2263 
2264 /**
2265   * @brief  Transmit in slave mode an amount of data in non-blocking mode with DMA
2266   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2267   *                the configuration information for the specified I2C.
2268   * @param  pData Pointer to data buffer
2269   * @param  Size Amount of data to be sent
2270   * @retval HAL status
2271   */
2272 HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2273 {
2274   HAL_StatusTypeDef dmaxferstatus;
2275 
2276   if (hi2c->State == HAL_I2C_STATE_READY)
2277   {
2278     if ((pData == NULL) || (Size == 0U))
2279     {
2280       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2281       return  HAL_ERROR;
2282     }
2283     /* Process Locked */
2284     __HAL_LOCK(hi2c);
2285 
2286     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2287     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2288     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2289 
2290     /* Prepare transfer parameters */
2291     hi2c->pBuffPtr    = pData;
2292     hi2c->XferCount   = Size;
2293     hi2c->XferSize    = hi2c->XferCount;
2294     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2295     hi2c->XferISR     = I2C_Slave_ISR_DMA;
2296 
2297     /* Preload TX data if no stretch enable */
2298     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
2299     {
2300       /* Preload TX register */
2301       /* Write data to TXDR */
2302       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2303 
2304       /* Increment Buffer pointer */
2305       hi2c->pBuffPtr++;
2306 
2307       hi2c->XferCount--;
2308       hi2c->XferSize--;
2309     }
2310 
2311     if (hi2c->XferCount != 0U)
2312     {
2313       if (hi2c->hdmatx != NULL)
2314       {
2315         /* Set the I2C DMA transfer complete callback */
2316         hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
2317 
2318         /* Set the DMA error callback */
2319         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2320 
2321         /* Set the unused DMA callbacks to NULL */
2322         hi2c->hdmatx->XferHalfCpltCallback = NULL;
2323         hi2c->hdmatx->XferAbortCallback = NULL;
2324 
2325         /* Enable the DMA stream or channel depends on Instance */
2326         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx,
2327                                          (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR,
2328                                          hi2c->XferSize);
2329       }
2330       else
2331       {
2332         /* Update I2C state */
2333         hi2c->State     = HAL_I2C_STATE_LISTEN;
2334         hi2c->Mode      = HAL_I2C_MODE_NONE;
2335 
2336         /* Update I2C error code */
2337         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2338 
2339         /* Process Unlocked */
2340         __HAL_UNLOCK(hi2c);
2341 
2342         return HAL_ERROR;
2343       }
2344 
2345       if (dmaxferstatus == HAL_OK)
2346       {
2347         /* Enable Address Acknowledge */
2348         hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2349 
2350         /* Process Unlocked */
2351         __HAL_UNLOCK(hi2c);
2352 
2353         /* Note : The I2C interrupts must be enabled after unlocking current process
2354                   to avoid the risk of I2C interrupt handle execution before current
2355                   process unlock */
2356         /* Enable ERR, STOP, NACK, ADDR interrupts */
2357         I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2358 
2359         /* Enable DMA Request */
2360         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2361       }
2362       else
2363       {
2364         /* Update I2C state */
2365         hi2c->State     = HAL_I2C_STATE_LISTEN;
2366         hi2c->Mode      = HAL_I2C_MODE_NONE;
2367 
2368         /* Update I2C error code */
2369         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2370 
2371         /* Process Unlocked */
2372         __HAL_UNLOCK(hi2c);
2373 
2374         return HAL_ERROR;
2375       }
2376     }
2377     else
2378     {
2379       /* Enable Address Acknowledge */
2380       hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2381 
2382       /* Process Unlocked */
2383       __HAL_UNLOCK(hi2c);
2384 
2385       /* Note : The I2C interrupts must be enabled after unlocking current process
2386       to avoid the risk of I2C interrupt handle execution before current
2387       process unlock */
2388       /* Enable ERR, STOP, NACK, ADDR interrupts */
2389       I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2390     }
2391 
2392     return HAL_OK;
2393   }
2394   else
2395   {
2396     return HAL_BUSY;
2397   }
2398 }
2399 
2400 /**
2401   * @brief  Receive in slave mode an amount of data in non-blocking mode with DMA
2402   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2403   *                the configuration information for the specified I2C.
2404   * @param  pData Pointer to data buffer
2405   * @param  Size Amount of data to be sent
2406   * @retval HAL status
2407   */
2408 HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2409 {
2410   HAL_StatusTypeDef dmaxferstatus;
2411 
2412   if (hi2c->State == HAL_I2C_STATE_READY)
2413   {
2414     if ((pData == NULL) || (Size == 0U))
2415     {
2416       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2417       return  HAL_ERROR;
2418     }
2419     /* Process Locked */
2420     __HAL_LOCK(hi2c);
2421 
2422     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2423     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2424     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2425 
2426     /* Prepare transfer parameters */
2427     hi2c->pBuffPtr    = pData;
2428     hi2c->XferCount   = Size;
2429     hi2c->XferSize    = hi2c->XferCount;
2430     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2431     hi2c->XferISR     = I2C_Slave_ISR_DMA;
2432 
2433     if (hi2c->hdmarx != NULL)
2434     {
2435       /* Set the I2C DMA transfer complete callback */
2436       hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
2437 
2438       /* Set the DMA error callback */
2439       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2440 
2441       /* Set the unused DMA callbacks to NULL */
2442       hi2c->hdmarx->XferHalfCpltCallback = NULL;
2443       hi2c->hdmarx->XferAbortCallback = NULL;
2444 
2445       /* Enable the DMA stream or channel depends on Instance */
2446       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2447                                        hi2c->XferSize);
2448     }
2449     else
2450     {
2451       /* Update I2C state */
2452       hi2c->State     = HAL_I2C_STATE_LISTEN;
2453       hi2c->Mode      = HAL_I2C_MODE_NONE;
2454 
2455       /* Update I2C error code */
2456       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2457 
2458       /* Process Unlocked */
2459       __HAL_UNLOCK(hi2c);
2460 
2461       return HAL_ERROR;
2462     }
2463 
2464     if (dmaxferstatus == HAL_OK)
2465     {
2466       /* Enable Address Acknowledge */
2467       hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2468 
2469       /* Process Unlocked */
2470       __HAL_UNLOCK(hi2c);
2471 
2472       /* Note : The I2C interrupts must be enabled after unlocking current process
2473                 to avoid the risk of I2C interrupt handle execution before current
2474                 process unlock */
2475       /* Enable ERR, STOP, NACK, ADDR interrupts */
2476       I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2477 
2478       /* Enable DMA Request */
2479       hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2480     }
2481     else
2482     {
2483       /* Update I2C state */
2484       hi2c->State     = HAL_I2C_STATE_LISTEN;
2485       hi2c->Mode      = HAL_I2C_MODE_NONE;
2486 
2487       /* Update I2C error code */
2488       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2489 
2490       /* Process Unlocked */
2491       __HAL_UNLOCK(hi2c);
2492 
2493       return HAL_ERROR;
2494     }
2495 
2496     return HAL_OK;
2497   }
2498   else
2499   {
2500     return HAL_BUSY;
2501   }
2502 }
2503 
2504 /**
2505   * @brief  Write an amount of data in blocking mode to a specific memory address
2506   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2507   *                the configuration information for the specified I2C.
2508   * @param  DevAddress Target device address: The device 7 bits address value
2509   *         in datasheet must be shifted to the left before calling the interface
2510   * @param  MemAddress Internal memory address
2511   * @param  MemAddSize Size of internal memory address
2512   * @param  pData Pointer to data buffer
2513   * @param  Size Amount of data to be sent
2514   * @param  Timeout Timeout duration
2515   * @retval HAL status
2516   */
2517 HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2518                                     uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2519 {
2520   uint32_t tickstart;
2521 
2522   /* Check the parameters */
2523   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2524 
2525   if (hi2c->State == HAL_I2C_STATE_READY)
2526   {
2527     if ((pData == NULL) || (Size == 0U))
2528     {
2529       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2530       return  HAL_ERROR;
2531     }
2532 
2533     /* Process Locked */
2534     __HAL_LOCK(hi2c);
2535 
2536     /* Init tickstart for timeout management*/
2537     tickstart = HAL_GetTick();
2538 
2539     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2540     {
2541       return HAL_ERROR;
2542     }
2543 
2544     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
2545     hi2c->Mode      = HAL_I2C_MODE_MEM;
2546     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2547 
2548     /* Prepare transfer parameters */
2549     hi2c->pBuffPtr  = pData;
2550     hi2c->XferCount = Size;
2551     hi2c->XferISR   = NULL;
2552 
2553     /* Send Slave Address and Memory Address */
2554     if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2555     {
2556       /* Process Unlocked */
2557       __HAL_UNLOCK(hi2c);
2558       return HAL_ERROR;
2559     }
2560 
2561     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
2562     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2563     {
2564       hi2c->XferSize = MAX_NBYTE_SIZE;
2565       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
2566     }
2567     else
2568     {
2569       hi2c->XferSize = hi2c->XferCount;
2570       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
2571     }
2572 
2573     do
2574     {
2575       /* Wait until TXIS flag is set */
2576       if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2577       {
2578         return HAL_ERROR;
2579       }
2580 
2581       /* Write data to TXDR */
2582       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2583 
2584       /* Increment Buffer pointer */
2585       hi2c->pBuffPtr++;
2586 
2587       hi2c->XferCount--;
2588       hi2c->XferSize--;
2589 
2590       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2591       {
2592         /* Wait until TCR flag is set */
2593         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2594         {
2595           return HAL_ERROR;
2596         }
2597 
2598         if (hi2c->XferCount > MAX_NBYTE_SIZE)
2599         {
2600           hi2c->XferSize = MAX_NBYTE_SIZE;
2601           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2602                              I2C_NO_STARTSTOP);
2603         }
2604         else
2605         {
2606           hi2c->XferSize = hi2c->XferCount;
2607           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2608                              I2C_NO_STARTSTOP);
2609         }
2610       }
2611 
2612     } while (hi2c->XferCount > 0U);
2613 
2614     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2615     /* Wait until STOPF flag is reset */
2616     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2617     {
2618       return HAL_ERROR;
2619     }
2620 
2621     /* Clear STOP Flag */
2622     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2623 
2624     /* Clear Configuration Register 2 */
2625     I2C_RESET_CR2(hi2c);
2626 
2627     hi2c->State = HAL_I2C_STATE_READY;
2628     hi2c->Mode  = HAL_I2C_MODE_NONE;
2629 
2630     /* Process Unlocked */
2631     __HAL_UNLOCK(hi2c);
2632 
2633     return HAL_OK;
2634   }
2635   else
2636   {
2637     return HAL_BUSY;
2638   }
2639 }
2640 
2641 /**
2642   * @brief  Read an amount of data in blocking mode from a specific memory address
2643   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2644   *                the configuration information for the specified I2C.
2645   * @param  DevAddress Target device address: The device 7 bits address value
2646   *         in datasheet must be shifted to the left before calling the interface
2647   * @param  MemAddress Internal memory address
2648   * @param  MemAddSize Size of internal memory address
2649   * @param  pData Pointer to data buffer
2650   * @param  Size Amount of data to be sent
2651   * @param  Timeout Timeout duration
2652   * @retval HAL status
2653   */
2654 HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2655                                    uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2656 {
2657   uint32_t tickstart;
2658 
2659   /* Check the parameters */
2660   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2661 
2662   if (hi2c->State == HAL_I2C_STATE_READY)
2663   {
2664     if ((pData == NULL) || (Size == 0U))
2665     {
2666       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2667       return  HAL_ERROR;
2668     }
2669 
2670     /* Process Locked */
2671     __HAL_LOCK(hi2c);
2672 
2673     /* Init tickstart for timeout management*/
2674     tickstart = HAL_GetTick();
2675 
2676     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2677     {
2678       return HAL_ERROR;
2679     }
2680 
2681     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
2682     hi2c->Mode      = HAL_I2C_MODE_MEM;
2683     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2684 
2685     /* Prepare transfer parameters */
2686     hi2c->pBuffPtr  = pData;
2687     hi2c->XferCount = Size;
2688     hi2c->XferISR   = NULL;
2689 
2690     /* Send Slave Address and Memory Address */
2691     if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2692     {
2693       /* Process Unlocked */
2694       __HAL_UNLOCK(hi2c);
2695       return HAL_ERROR;
2696     }
2697 
2698     /* Send Slave Address */
2699     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2700     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2701     {
2702       hi2c->XferSize = MAX_NBYTE_SIZE;
2703       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2704                          I2C_GENERATE_START_READ);
2705     }
2706     else
2707     {
2708       hi2c->XferSize = hi2c->XferCount;
2709       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2710                          I2C_GENERATE_START_READ);
2711     }
2712 
2713     do
2714     {
2715       /* Wait until RXNE flag is set */
2716       if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
2717       {
2718         return HAL_ERROR;
2719       }
2720 
2721       /* Read data from RXDR */
2722       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
2723 
2724       /* Increment Buffer pointer */
2725       hi2c->pBuffPtr++;
2726 
2727       hi2c->XferSize--;
2728       hi2c->XferCount--;
2729 
2730       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2731       {
2732         /* Wait until TCR flag is set */
2733         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2734         {
2735           return HAL_ERROR;
2736         }
2737 
2738         if (hi2c->XferCount > MAX_NBYTE_SIZE)
2739         {
2740           hi2c->XferSize = MAX_NBYTE_SIZE;
2741           I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE,
2742                              I2C_NO_STARTSTOP);
2743         }
2744         else
2745         {
2746           hi2c->XferSize = hi2c->XferCount;
2747           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2748                              I2C_NO_STARTSTOP);
2749         }
2750       }
2751     } while (hi2c->XferCount > 0U);
2752 
2753     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2754     /* Wait until STOPF flag is reset */
2755     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2756     {
2757       return HAL_ERROR;
2758     }
2759 
2760     /* Clear STOP Flag */
2761     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2762 
2763     /* Clear Configuration Register 2 */
2764     I2C_RESET_CR2(hi2c);
2765 
2766     hi2c->State = HAL_I2C_STATE_READY;
2767     hi2c->Mode  = HAL_I2C_MODE_NONE;
2768 
2769     /* Process Unlocked */
2770     __HAL_UNLOCK(hi2c);
2771 
2772     return HAL_OK;
2773   }
2774   else
2775   {
2776     return HAL_BUSY;
2777   }
2778 }
2779 /**
2780   * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
2781   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2782   *                the configuration information for the specified I2C.
2783   * @param  DevAddress Target device address: The device 7 bits address value
2784   *         in datasheet must be shifted to the left before calling the interface
2785   * @param  MemAddress Internal memory address
2786   * @param  MemAddSize Size of internal memory address
2787   * @param  pData Pointer to data buffer
2788   * @param  Size Amount of data to be sent
2789   * @retval HAL status
2790   */
2791 HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2792                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2793 {
2794   /* Check the parameters */
2795   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2796 
2797   if (hi2c->State == HAL_I2C_STATE_READY)
2798   {
2799     if ((pData == NULL) || (Size == 0U))
2800     {
2801       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2802       return  HAL_ERROR;
2803     }
2804 
2805     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2806     {
2807       return HAL_BUSY;
2808     }
2809 
2810     /* Process Locked */
2811     __HAL_LOCK(hi2c);
2812 
2813     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2814     hi2c->Mode        = HAL_I2C_MODE_MEM;
2815     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2816 
2817     /* Prepare transfer parameters */
2818     hi2c->XferSize    = 0U;
2819     hi2c->pBuffPtr    = pData;
2820     hi2c->XferCount   = Size;
2821     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2822     hi2c->XferISR     = I2C_Mem_ISR_IT;
2823     hi2c->Devaddress  = DevAddress;
2824 
2825     /* If Memory address size is 8Bit */
2826     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
2827     {
2828       /* Prefetch Memory Address */
2829       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
2830 
2831       /* Reset Memaddress content */
2832       hi2c->Memaddress = 0xFFFFFFFFU;
2833     }
2834     /* If Memory address size is 16Bit */
2835     else
2836     {
2837       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2838       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
2839 
2840       /* Prepare Memaddress buffer for LSB part */
2841       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
2842     }
2843     /* Send Slave Address and Memory Address */
2844     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
2845 
2846     /* Process Unlocked */
2847     __HAL_UNLOCK(hi2c);
2848 
2849     /* Note : The I2C interrupts must be enabled after unlocking current process
2850               to avoid the risk of I2C interrupt handle execution before current
2851               process unlock */
2852 
2853     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2854     /* possible to enable all of these */
2855     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2856       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2857     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2858 
2859     return HAL_OK;
2860   }
2861   else
2862   {
2863     return HAL_BUSY;
2864   }
2865 }
2866 
2867 /**
2868   * @brief  Read an amount of data in non-blocking mode with Interrupt from a specific memory address
2869   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2870   *                the configuration information for the specified I2C.
2871   * @param  DevAddress Target device address: The device 7 bits address value
2872   *         in datasheet must be shifted to the left before calling the interface
2873   * @param  MemAddress Internal memory address
2874   * @param  MemAddSize Size of internal memory address
2875   * @param  pData Pointer to data buffer
2876   * @param  Size Amount of data to be sent
2877   * @retval HAL status
2878   */
2879 HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2880                                       uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2881 {
2882   /* Check the parameters */
2883   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2884 
2885   if (hi2c->State == HAL_I2C_STATE_READY)
2886   {
2887     if ((pData == NULL) || (Size == 0U))
2888     {
2889       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2890       return  HAL_ERROR;
2891     }
2892 
2893     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2894     {
2895       return HAL_BUSY;
2896     }
2897 
2898     /* Process Locked */
2899     __HAL_LOCK(hi2c);
2900 
2901     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2902     hi2c->Mode        = HAL_I2C_MODE_MEM;
2903     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2904 
2905     /* Prepare transfer parameters */
2906     hi2c->pBuffPtr    = pData;
2907     hi2c->XferCount   = Size;
2908     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2909     hi2c->XferISR     = I2C_Mem_ISR_IT;
2910     hi2c->Devaddress  = DevAddress;
2911 
2912     /* If Memory address size is 8Bit */
2913     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
2914     {
2915       /* Prefetch Memory Address */
2916       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
2917 
2918       /* Reset Memaddress content */
2919       hi2c->Memaddress = 0xFFFFFFFFU;
2920     }
2921     /* If Memory address size is 16Bit */
2922     else
2923     {
2924       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2925       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
2926 
2927       /* Prepare Memaddress buffer for LSB part */
2928       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
2929     }
2930     /* Send Slave Address and Memory Address */
2931     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
2932 
2933     /* Process Unlocked */
2934     __HAL_UNLOCK(hi2c);
2935 
2936     /* Note : The I2C interrupts must be enabled after unlocking current process
2937               to avoid the risk of I2C interrupt handle execution before current
2938               process unlock */
2939 
2940     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2941     /* possible to enable all of these */
2942     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2943       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2944     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2945 
2946     return HAL_OK;
2947   }
2948   else
2949   {
2950     return HAL_BUSY;
2951   }
2952 }
2953 
2954 /**
2955   * @brief  Write an amount of data in non-blocking mode with DMA to a specific memory address
2956   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2957   *                the configuration information for the specified I2C.
2958   * @param  DevAddress Target device address: The device 7 bits address value
2959   *         in datasheet must be shifted to the left before calling the interface
2960   * @param  MemAddress Internal memory address
2961   * @param  MemAddSize Size of internal memory address
2962   * @param  pData Pointer to data buffer
2963   * @param  Size Amount of data to be sent
2964   * @retval HAL status
2965   */
2966 HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2967                                         uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2968 {
2969   HAL_StatusTypeDef dmaxferstatus;
2970 
2971   /* Check the parameters */
2972   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2973 
2974   if (hi2c->State == HAL_I2C_STATE_READY)
2975   {
2976     if ((pData == NULL) || (Size == 0U))
2977     {
2978       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2979       return  HAL_ERROR;
2980     }
2981 
2982     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2983     {
2984       return HAL_BUSY;
2985     }
2986 
2987     /* Process Locked */
2988     __HAL_LOCK(hi2c);
2989 
2990     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2991     hi2c->Mode        = HAL_I2C_MODE_MEM;
2992     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2993 
2994     /* Prepare transfer parameters */
2995     hi2c->pBuffPtr    = pData;
2996     hi2c->XferCount   = Size;
2997     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2998     hi2c->XferISR     = I2C_Mem_ISR_DMA;
2999     hi2c->Devaddress  = DevAddress;
3000 
3001     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3002     {
3003       hi2c->XferSize = MAX_NBYTE_SIZE;
3004     }
3005     else
3006     {
3007       hi2c->XferSize = hi2c->XferCount;
3008     }
3009 
3010     /* If Memory address size is 8Bit */
3011     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
3012     {
3013       /* Prefetch Memory Address */
3014       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
3015 
3016       /* Reset Memaddress content */
3017       hi2c->Memaddress = 0xFFFFFFFFU;
3018     }
3019     /* If Memory address size is 16Bit */
3020     else
3021     {
3022       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3023       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
3024 
3025       /* Prepare Memaddress buffer for LSB part */
3026       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
3027     }
3028 
3029     if (hi2c->hdmatx != NULL)
3030     {
3031       /* Set the I2C DMA transfer complete callback */
3032       hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
3033 
3034       /* Set the DMA error callback */
3035       hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3036 
3037       /* Set the unused DMA callbacks to NULL */
3038       hi2c->hdmatx->XferHalfCpltCallback = NULL;
3039       hi2c->hdmatx->XferAbortCallback = NULL;
3040 
3041       /* Enable the DMA stream or channel depends on Instance */
3042       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
3043                                        hi2c->XferSize);
3044     }
3045     else
3046     {
3047       /* Update I2C state */
3048       hi2c->State     = HAL_I2C_STATE_READY;
3049       hi2c->Mode      = HAL_I2C_MODE_NONE;
3050 
3051       /* Update I2C error code */
3052       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3053 
3054       /* Process Unlocked */
3055       __HAL_UNLOCK(hi2c);
3056 
3057       return HAL_ERROR;
3058     }
3059 
3060     if (dmaxferstatus == HAL_OK)
3061     {
3062       /* Send Slave Address and Memory Address */
3063       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
3064 
3065       /* Process Unlocked */
3066       __HAL_UNLOCK(hi2c);
3067 
3068       /* Note : The I2C interrupts must be enabled after unlocking current process
3069                 to avoid the risk of I2C interrupt handle execution before current
3070                 process unlock */
3071       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3072       /* possible to enable all of these */
3073       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3074         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3075       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3076     }
3077     else
3078     {
3079       /* Update I2C state */
3080       hi2c->State     = HAL_I2C_STATE_READY;
3081       hi2c->Mode      = HAL_I2C_MODE_NONE;
3082 
3083       /* Update I2C error code */
3084       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3085 
3086       /* Process Unlocked */
3087       __HAL_UNLOCK(hi2c);
3088 
3089       return HAL_ERROR;
3090     }
3091 
3092     return HAL_OK;
3093   }
3094   else
3095   {
3096     return HAL_BUSY;
3097   }
3098 }
3099 
3100 /**
3101   * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
3102   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3103   *                the configuration information for the specified I2C.
3104   * @param  DevAddress Target device address: The device 7 bits address value
3105   *         in datasheet must be shifted to the left before calling the interface
3106   * @param  MemAddress Internal memory address
3107   * @param  MemAddSize Size of internal memory address
3108   * @param  pData Pointer to data buffer
3109   * @param  Size Amount of data to be read
3110   * @retval HAL status
3111   */
3112 HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
3113                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
3114 {
3115   HAL_StatusTypeDef dmaxferstatus;
3116 
3117   /* Check the parameters */
3118   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
3119 
3120   if (hi2c->State == HAL_I2C_STATE_READY)
3121   {
3122     if ((pData == NULL) || (Size == 0U))
3123     {
3124       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3125       return  HAL_ERROR;
3126     }
3127 
3128     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
3129     {
3130       return HAL_BUSY;
3131     }
3132 
3133     /* Process Locked */
3134     __HAL_LOCK(hi2c);
3135 
3136     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
3137     hi2c->Mode        = HAL_I2C_MODE_MEM;
3138     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
3139 
3140     /* Prepare transfer parameters */
3141     hi2c->pBuffPtr    = pData;
3142     hi2c->XferCount   = Size;
3143     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
3144     hi2c->XferISR     = I2C_Mem_ISR_DMA;
3145     hi2c->Devaddress  = DevAddress;
3146 
3147     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3148     {
3149       hi2c->XferSize = MAX_NBYTE_SIZE;
3150     }
3151     else
3152     {
3153       hi2c->XferSize = hi2c->XferCount;
3154     }
3155 
3156     /* If Memory address size is 8Bit */
3157     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
3158     {
3159       /* Prefetch Memory Address */
3160       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
3161 
3162       /* Reset Memaddress content */
3163       hi2c->Memaddress = 0xFFFFFFFFU;
3164     }
3165     /* If Memory address size is 16Bit */
3166     else
3167     {
3168       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3169       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
3170 
3171       /* Prepare Memaddress buffer for LSB part */
3172       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
3173     }
3174 
3175     if (hi2c->hdmarx != NULL)
3176     {
3177       /* Set the I2C DMA transfer complete callback */
3178       hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3179 
3180       /* Set the DMA error callback */
3181       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3182 
3183       /* Set the unused DMA callbacks to NULL */
3184       hi2c->hdmarx->XferHalfCpltCallback = NULL;
3185       hi2c->hdmarx->XferAbortCallback = NULL;
3186 
3187       /* Enable the DMA stream or channel depends on Instance */
3188       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3189                                        hi2c->XferSize);
3190     }
3191     else
3192     {
3193       /* Update I2C state */
3194       hi2c->State     = HAL_I2C_STATE_READY;
3195       hi2c->Mode      = HAL_I2C_MODE_NONE;
3196 
3197       /* Update I2C error code */
3198       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3199 
3200       /* Process Unlocked */
3201       __HAL_UNLOCK(hi2c);
3202 
3203       return HAL_ERROR;
3204     }
3205 
3206     if (dmaxferstatus == HAL_OK)
3207     {
3208       /* Send Slave Address and Memory Address */
3209       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
3210 
3211       /* Process Unlocked */
3212       __HAL_UNLOCK(hi2c);
3213 
3214       /* Note : The I2C interrupts must be enabled after unlocking current process
3215                 to avoid the risk of I2C interrupt handle execution before current
3216                 process unlock */
3217       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3218       /* possible to enable all of these */
3219       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3220         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3221       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3222     }
3223     else
3224     {
3225       /* Update I2C state */
3226       hi2c->State     = HAL_I2C_STATE_READY;
3227       hi2c->Mode      = HAL_I2C_MODE_NONE;
3228 
3229       /* Update I2C error code */
3230       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3231 
3232       /* Process Unlocked */
3233       __HAL_UNLOCK(hi2c);
3234 
3235       return HAL_ERROR;
3236     }
3237 
3238     return HAL_OK;
3239   }
3240   else
3241   {
3242     return HAL_BUSY;
3243   }
3244 }
3245 
3246 /**
3247   * @brief  Checks if target device is ready for communication.
3248   * @note   This function is used with Memory devices
3249   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3250   *                the configuration information for the specified I2C.
3251   * @param  DevAddress Target device address: The device 7 bits address value
3252   *         in datasheet must be shifted to the left before calling the interface
3253   * @param  Trials Number of trials
3254   * @param  Timeout Timeout duration
3255   * @retval HAL status
3256   */
3257 HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials,
3258                                         uint32_t Timeout)
3259 {
3260   uint32_t tickstart;
3261 
3262   __IO uint32_t I2C_Trials = 0UL;
3263 
3264   FlagStatus tmp1;
3265   FlagStatus tmp2;
3266 
3267   if (hi2c->State == HAL_I2C_STATE_READY)
3268   {
3269     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
3270     {
3271       return HAL_BUSY;
3272     }
3273 
3274     /* Process Locked */
3275     __HAL_LOCK(hi2c);
3276 
3277     hi2c->State = HAL_I2C_STATE_BUSY;
3278     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3279 
3280     do
3281     {
3282       /* Generate Start */
3283       hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);
3284 
3285       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3286       /* Wait until STOPF flag is set or a NACK flag is set*/
3287       tickstart = HAL_GetTick();
3288 
3289       tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3290       tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3291 
3292       while ((tmp1 == RESET) && (tmp2 == RESET))
3293       {
3294         if (Timeout != HAL_MAX_DELAY)
3295         {
3296           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3297           {
3298             /* Update I2C state */
3299             hi2c->State = HAL_I2C_STATE_READY;
3300 
3301             /* Update I2C error code */
3302             hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3303 
3304             /* Process Unlocked */
3305             __HAL_UNLOCK(hi2c);
3306 
3307             return HAL_ERROR;
3308           }
3309         }
3310 
3311         tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3312         tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3313       }
3314 
3315       /* Check if the NACKF flag has not been set */
3316       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET)
3317       {
3318         /* Wait until STOPF flag is reset */
3319         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3320         {
3321           return HAL_ERROR;
3322         }
3323 
3324         /* Clear STOP Flag */
3325         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3326 
3327         /* Device is ready */
3328         hi2c->State = HAL_I2C_STATE_READY;
3329 
3330         /* Process Unlocked */
3331         __HAL_UNLOCK(hi2c);
3332 
3333         return HAL_OK;
3334       }
3335       else
3336       {
3337         /* Wait until STOPF flag is reset */
3338         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3339         {
3340           return HAL_ERROR;
3341         }
3342 
3343         /* Clear NACK Flag */
3344         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
3345 
3346         /* Clear STOP Flag, auto generated with autoend*/
3347         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3348       }
3349 
3350       /* Increment Trials */
3351       I2C_Trials++;
3352     } while (I2C_Trials < Trials);
3353 
3354     /* Update I2C state */
3355     hi2c->State = HAL_I2C_STATE_READY;
3356 
3357     /* Update I2C error code */
3358     hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3359 
3360     /* Process Unlocked */
3361     __HAL_UNLOCK(hi2c);
3362 
3363     return HAL_ERROR;
3364   }
3365   else
3366   {
3367     return HAL_BUSY;
3368   }
3369 }
3370 
3371 /**
3372   * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt.
3373   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3374   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3375   *                the configuration information for the specified I2C.
3376   * @param  DevAddress Target device address: The device 7 bits address value
3377   *         in datasheet must be shifted to the left before calling the interface
3378   * @param  pData Pointer to data buffer
3379   * @param  Size Amount of data to be sent
3380   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3381   * @retval HAL status
3382   */
3383 HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3384                                                  uint16_t Size, uint32_t XferOptions)
3385 {
3386   uint32_t xfermode;
3387   uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3388   uint32_t sizetoxfer = 0U;
3389 
3390   /* Check the parameters */
3391   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3392 
3393   if (hi2c->State == HAL_I2C_STATE_READY)
3394   {
3395     /* Process Locked */
3396     __HAL_LOCK(hi2c);
3397 
3398     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3399     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3400     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3401 
3402     /* Prepare transfer parameters */
3403     hi2c->pBuffPtr    = pData;
3404     hi2c->XferCount   = Size;
3405     hi2c->XferOptions = XferOptions;
3406     hi2c->XferISR     = I2C_Master_ISR_IT;
3407 
3408     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3409     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3410     {
3411       hi2c->XferSize = MAX_NBYTE_SIZE;
3412       xfermode = I2C_RELOAD_MODE;
3413     }
3414     else
3415     {
3416       hi2c->XferSize = hi2c->XferCount;
3417       xfermode = hi2c->XferOptions;
3418     }
3419 
3420     if ((hi2c->XferSize > 0U) && ((XferOptions == I2C_FIRST_FRAME) || \
3421                                   (XferOptions == I2C_FIRST_AND_LAST_FRAME)))
3422     {
3423       /* Preload TX register */
3424       /* Write data to TXDR */
3425       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
3426 
3427       /* Increment Buffer pointer */
3428       hi2c->pBuffPtr++;
3429 
3430       sizetoxfer = hi2c->XferSize;
3431       hi2c->XferCount--;
3432       hi2c->XferSize--;
3433     }
3434 
3435     /* If transfer direction not change and there is no request to start another frame,
3436        do not generate Restart Condition */
3437     /* Mean Previous state is same as current state */
3438     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3439         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3440     {
3441       xferrequest = I2C_NO_STARTSTOP;
3442     }
3443     else
3444     {
3445       /* Convert OTHER_xxx XferOptions if any */
3446       I2C_ConvertOtherXferOptions(hi2c);
3447 
3448       /* Update xfermode accordingly if no reload is necessary */
3449       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3450       {
3451         xfermode = hi2c->XferOptions;
3452       }
3453     }
3454 
3455     /* Send Slave Address and set NBYTES to write */
3456     if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3457     {
3458       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3459     }
3460     else
3461     {
3462       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3463     }
3464 
3465     /* Process Unlocked */
3466     __HAL_UNLOCK(hi2c);
3467 
3468     /* Note : The I2C interrupts must be enabled after unlocking current process
3469               to avoid the risk of I2C interrupt handle execution before current
3470               process unlock */
3471     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3472     /* possible to enable all of these */
3473     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3474        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3475     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3476 
3477     return HAL_OK;
3478   }
3479   else
3480   {
3481     return HAL_BUSY;
3482   }
3483 }
3484 
3485 /**
3486   * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA.
3487   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3488   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3489   *                the configuration information for the specified I2C.
3490   * @param  DevAddress Target device address: The device 7 bits address value
3491   *         in datasheet must be shifted to the left before calling the interface
3492   * @param  pData Pointer to data buffer
3493   * @param  Size Amount of data to be sent
3494   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3495   * @retval HAL status
3496   */
3497 HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3498                                                   uint16_t Size, uint32_t XferOptions)
3499 {
3500   uint32_t xfermode;
3501   uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3502   HAL_StatusTypeDef dmaxferstatus;
3503   uint32_t sizetoxfer = 0U;
3504 
3505   /* Check the parameters */
3506   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3507 
3508   if (hi2c->State == HAL_I2C_STATE_READY)
3509   {
3510     /* Process Locked */
3511     __HAL_LOCK(hi2c);
3512 
3513     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3514     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3515     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3516 
3517     /* Prepare transfer parameters */
3518     hi2c->pBuffPtr    = pData;
3519     hi2c->XferCount   = Size;
3520     hi2c->XferOptions = XferOptions;
3521     hi2c->XferISR     = I2C_Master_ISR_DMA;
3522 
3523     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3524     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3525     {
3526       hi2c->XferSize = MAX_NBYTE_SIZE;
3527       xfermode = I2C_RELOAD_MODE;
3528     }
3529     else
3530     {
3531       hi2c->XferSize = hi2c->XferCount;
3532       xfermode = hi2c->XferOptions;
3533     }
3534 
3535     if ((hi2c->XferSize > 0U) && ((XferOptions == I2C_FIRST_FRAME) || \
3536                                   (XferOptions == I2C_FIRST_AND_LAST_FRAME)))
3537     {
3538       /* Preload TX register */
3539       /* Write data to TXDR */
3540       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
3541 
3542       /* Increment Buffer pointer */
3543       hi2c->pBuffPtr++;
3544 
3545       sizetoxfer = hi2c->XferSize;
3546       hi2c->XferCount--;
3547       hi2c->XferSize--;
3548     }
3549 
3550     /* If transfer direction not change and there is no request to start another frame,
3551        do not generate Restart Condition */
3552     /* Mean Previous state is same as current state */
3553     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3554         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3555     {
3556       xferrequest = I2C_NO_STARTSTOP;
3557     }
3558     else
3559     {
3560       /* Convert OTHER_xxx XferOptions if any */
3561       I2C_ConvertOtherXferOptions(hi2c);
3562 
3563       /* Update xfermode accordingly if no reload is necessary */
3564       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3565       {
3566         xfermode = hi2c->XferOptions;
3567       }
3568     }
3569 
3570     if (hi2c->XferSize > 0U)
3571     {
3572       if (hi2c->hdmatx != NULL)
3573       {
3574         /* Set the I2C DMA transfer complete callback */
3575         hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
3576 
3577         /* Set the DMA error callback */
3578         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3579 
3580         /* Set the unused DMA callbacks to NULL */
3581         hi2c->hdmatx->XferHalfCpltCallback = NULL;
3582         hi2c->hdmatx->XferAbortCallback = NULL;
3583 
3584         /* Enable the DMA stream or channel depends on Instance */
3585         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr,
3586                                          (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
3587       }
3588       else
3589       {
3590         /* Update I2C state */
3591         hi2c->State     = HAL_I2C_STATE_READY;
3592         hi2c->Mode      = HAL_I2C_MODE_NONE;
3593 
3594         /* Update I2C error code */
3595         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3596 
3597         /* Process Unlocked */
3598         __HAL_UNLOCK(hi2c);
3599 
3600         return HAL_ERROR;
3601       }
3602 
3603       if (dmaxferstatus == HAL_OK)
3604       {
3605         /* Send Slave Address and set NBYTES to write */
3606         if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3607         {
3608           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3609         }
3610         else
3611         {
3612           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3613         }
3614 
3615         /* Update XferCount value */
3616         hi2c->XferCount -= hi2c->XferSize;
3617 
3618         /* Process Unlocked */
3619         __HAL_UNLOCK(hi2c);
3620 
3621         /* Note : The I2C interrupts must be enabled after unlocking current process
3622                   to avoid the risk of I2C interrupt handle execution before current
3623                   process unlock */
3624         /* Enable ERR and NACK interrupts */
3625         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3626 
3627         /* Enable DMA Request */
3628         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
3629       }
3630       else
3631       {
3632         /* Update I2C state */
3633         hi2c->State     = HAL_I2C_STATE_READY;
3634         hi2c->Mode      = HAL_I2C_MODE_NONE;
3635 
3636         /* Update I2C error code */
3637         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3638 
3639         /* Process Unlocked */
3640         __HAL_UNLOCK(hi2c);
3641 
3642         return HAL_ERROR;
3643       }
3644     }
3645     else
3646     {
3647       /* Update Transfer ISR function pointer */
3648       hi2c->XferISR = I2C_Master_ISR_IT;
3649 
3650       /* Send Slave Address */
3651       /* Set NBYTES to write and generate START condition */
3652       if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3653       {
3654         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3655       }
3656       else
3657       {
3658         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3659       }
3660 
3661       /* Process Unlocked */
3662       __HAL_UNLOCK(hi2c);
3663 
3664       /* Note : The I2C interrupts must be enabled after unlocking current process
3665                 to avoid the risk of I2C interrupt handle execution before current
3666                 process unlock */
3667       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3668       /* possible to enable all of these */
3669       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3670         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3671       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3672     }
3673 
3674     return HAL_OK;
3675   }
3676   else
3677   {
3678     return HAL_BUSY;
3679   }
3680 }
3681 
3682 /**
3683   * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt
3684   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3685   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3686   *                the configuration information for the specified I2C.
3687   * @param  DevAddress Target device address: The device 7 bits address value
3688   *         in datasheet must be shifted to the left before calling the interface
3689   * @param  pData Pointer to data buffer
3690   * @param  Size Amount of data to be sent
3691   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3692   * @retval HAL status
3693   */
3694 HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3695                                                 uint16_t Size, uint32_t XferOptions)
3696 {
3697   uint32_t xfermode;
3698   uint32_t xferrequest = I2C_GENERATE_START_READ;
3699 
3700   /* Check the parameters */
3701   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3702 
3703   if (hi2c->State == HAL_I2C_STATE_READY)
3704   {
3705     /* Process Locked */
3706     __HAL_LOCK(hi2c);
3707 
3708     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3709     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3710     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3711 
3712     /* Prepare transfer parameters */
3713     hi2c->pBuffPtr    = pData;
3714     hi2c->XferCount   = Size;
3715     hi2c->XferOptions = XferOptions;
3716     hi2c->XferISR     = I2C_Master_ISR_IT;
3717 
3718     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3719     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3720     {
3721       hi2c->XferSize = MAX_NBYTE_SIZE;
3722       xfermode = I2C_RELOAD_MODE;
3723     }
3724     else
3725     {
3726       hi2c->XferSize = hi2c->XferCount;
3727       xfermode = hi2c->XferOptions;
3728     }
3729 
3730     /* If transfer direction not change and there is no request to start another frame,
3731        do not generate Restart Condition */
3732     /* Mean Previous state is same as current state */
3733     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3734         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3735     {
3736       xferrequest = I2C_NO_STARTSTOP;
3737     }
3738     else
3739     {
3740       /* Convert OTHER_xxx XferOptions if any */
3741       I2C_ConvertOtherXferOptions(hi2c);
3742 
3743       /* Update xfermode accordingly if no reload is necessary */
3744       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3745       {
3746         xfermode = hi2c->XferOptions;
3747       }
3748     }
3749 
3750     /* Send Slave Address and set NBYTES to read */
3751     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3752 
3753     /* Process Unlocked */
3754     __HAL_UNLOCK(hi2c);
3755 
3756     /* Note : The I2C interrupts must be enabled after unlocking current process
3757               to avoid the risk of I2C interrupt handle execution before current
3758               process unlock */
3759     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
3760 
3761     return HAL_OK;
3762   }
3763   else
3764   {
3765     return HAL_BUSY;
3766   }
3767 }
3768 
3769 /**
3770   * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with DMA
3771   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3772   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3773   *                the configuration information for the specified I2C.
3774   * @param  DevAddress Target device address: The device 7 bits address value
3775   *         in datasheet must be shifted to the left before calling the interface
3776   * @param  pData Pointer to data buffer
3777   * @param  Size Amount of data to be sent
3778   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3779   * @retval HAL status
3780   */
3781 HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3782                                                  uint16_t Size, uint32_t XferOptions)
3783 {
3784   uint32_t xfermode;
3785   uint32_t xferrequest = I2C_GENERATE_START_READ;
3786   HAL_StatusTypeDef dmaxferstatus;
3787 
3788   /* Check the parameters */
3789   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3790 
3791   if (hi2c->State == HAL_I2C_STATE_READY)
3792   {
3793     /* Process Locked */
3794     __HAL_LOCK(hi2c);
3795 
3796     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3797     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3798     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3799 
3800     /* Prepare transfer parameters */
3801     hi2c->pBuffPtr    = pData;
3802     hi2c->XferCount   = Size;
3803     hi2c->XferOptions = XferOptions;
3804     hi2c->XferISR     = I2C_Master_ISR_DMA;
3805 
3806     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3807     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3808     {
3809       hi2c->XferSize = MAX_NBYTE_SIZE;
3810       xfermode = I2C_RELOAD_MODE;
3811     }
3812     else
3813     {
3814       hi2c->XferSize = hi2c->XferCount;
3815       xfermode = hi2c->XferOptions;
3816     }
3817 
3818     /* If transfer direction not change and there is no request to start another frame,
3819        do not generate Restart Condition */
3820     /* Mean Previous state is same as current state */
3821     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3822         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3823     {
3824       xferrequest = I2C_NO_STARTSTOP;
3825     }
3826     else
3827     {
3828       /* Convert OTHER_xxx XferOptions if any */
3829       I2C_ConvertOtherXferOptions(hi2c);
3830 
3831       /* Update xfermode accordingly if no reload is necessary */
3832       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3833       {
3834         xfermode = hi2c->XferOptions;
3835       }
3836     }
3837 
3838     if (hi2c->XferSize > 0U)
3839     {
3840       if (hi2c->hdmarx != NULL)
3841       {
3842         /* Set the I2C DMA transfer complete callback */
3843         hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3844 
3845         /* Set the DMA error callback */
3846         hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3847 
3848         /* Set the unused DMA callbacks to NULL */
3849         hi2c->hdmarx->XferHalfCpltCallback = NULL;
3850         hi2c->hdmarx->XferAbortCallback = NULL;
3851 
3852         /* Enable the DMA stream or channel depends on Instance */
3853         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3854                                          hi2c->XferSize);
3855       }
3856       else
3857       {
3858         /* Update I2C state */
3859         hi2c->State     = HAL_I2C_STATE_READY;
3860         hi2c->Mode      = HAL_I2C_MODE_NONE;
3861 
3862         /* Update I2C error code */
3863         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3864 
3865         /* Process Unlocked */
3866         __HAL_UNLOCK(hi2c);
3867 
3868         return HAL_ERROR;
3869       }
3870 
3871       if (dmaxferstatus == HAL_OK)
3872       {
3873         /* Send Slave Address and set NBYTES to read */
3874         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3875 
3876         /* Update XferCount value */
3877         hi2c->XferCount -= hi2c->XferSize;
3878 
3879         /* Process Unlocked */
3880         __HAL_UNLOCK(hi2c);
3881 
3882         /* Note : The I2C interrupts must be enabled after unlocking current process
3883                   to avoid the risk of I2C interrupt handle execution before current
3884                   process unlock */
3885         /* Enable ERR and NACK interrupts */
3886         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3887 
3888         /* Enable DMA Request */
3889         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
3890       }
3891       else
3892       {
3893         /* Update I2C state */
3894         hi2c->State     = HAL_I2C_STATE_READY;
3895         hi2c->Mode      = HAL_I2C_MODE_NONE;
3896 
3897         /* Update I2C error code */
3898         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3899 
3900         /* Process Unlocked */
3901         __HAL_UNLOCK(hi2c);
3902 
3903         return HAL_ERROR;
3904       }
3905     }
3906     else
3907     {
3908       /* Update Transfer ISR function pointer */
3909       hi2c->XferISR = I2C_Master_ISR_IT;
3910 
3911       /* Send Slave Address */
3912       /* Set NBYTES to read and generate START condition */
3913       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
3914                          I2C_GENERATE_START_READ);
3915 
3916       /* Process Unlocked */
3917       __HAL_UNLOCK(hi2c);
3918 
3919       /* Note : The I2C interrupts must be enabled after unlocking current process
3920                 to avoid the risk of I2C interrupt handle execution before current
3921                 process unlock */
3922       /* Enable ERR, TC, STOP, NACK, RXI interrupt */
3923       /* possible to enable all of these */
3924       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3925         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3926       I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
3927     }
3928 
3929     return HAL_OK;
3930   }
3931   else
3932   {
3933     return HAL_BUSY;
3934   }
3935 }
3936 
3937 /**
3938   * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
3939   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3940   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3941   *                the configuration information for the specified I2C.
3942   * @param  pData Pointer to data buffer
3943   * @param  Size Amount of data to be sent
3944   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3945   * @retval HAL status
3946   */
3947 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
3948                                                 uint32_t XferOptions)
3949 {
3950   /* Declaration of tmp to prevent undefined behavior of volatile usage */
3951   FlagStatus tmp;
3952 
3953   /* Check the parameters */
3954   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3955 
3956   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
3957   {
3958     if ((pData == NULL) || (Size == 0U))
3959     {
3960       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3961       return  HAL_ERROR;
3962     }
3963 
3964     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3965     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
3966 
3967     /* Process Locked */
3968     __HAL_LOCK(hi2c);
3969 
3970     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
3971     /* and then toggle the HAL slave RX state to TX state */
3972     if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
3973     {
3974       /* Disable associated Interrupts */
3975       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
3976 
3977       /* Abort DMA Xfer if any */
3978       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
3979       {
3980         hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
3981 
3982         if (hi2c->hdmarx != NULL)
3983         {
3984           /* Set the I2C DMA Abort callback :
3985            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
3986           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
3987 
3988           /* Abort DMA RX */
3989           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
3990           {
3991             /* Call Directly XferAbortCallback function in case of error */
3992             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
3993           }
3994         }
3995       }
3996     }
3997 
3998     hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
3999     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4000     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4001 
4002     /* Enable Address Acknowledge */
4003     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4004 
4005     /* Prepare transfer parameters */
4006     hi2c->pBuffPtr    = pData;
4007     hi2c->XferCount   = Size;
4008     hi2c->XferSize    = hi2c->XferCount;
4009     hi2c->XferOptions = XferOptions;
4010     hi2c->XferISR     = I2C_Slave_ISR_IT;
4011 
4012     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4013     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET))
4014     {
4015       /* Clear ADDR flag after prepare the transfer parameters */
4016       /* This action will generate an acknowledge to the Master */
4017       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4018     }
4019 
4020     /* Process Unlocked */
4021     __HAL_UNLOCK(hi2c);
4022 
4023     /* Note : The I2C interrupts must be enabled after unlocking current process
4024     to avoid the risk of I2C interrupt handle execution before current
4025     process unlock */
4026     /* REnable ADDR interrupt */
4027     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
4028 
4029     return HAL_OK;
4030   }
4031   else
4032   {
4033     return HAL_ERROR;
4034   }
4035 }
4036 
4037 /**
4038   * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with DMA
4039   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4040   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4041   *                the configuration information for the specified I2C.
4042   * @param  pData Pointer to data buffer
4043   * @param  Size Amount of data to be sent
4044   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4045   * @retval HAL status
4046   */
4047 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4048                                                  uint32_t XferOptions)
4049 {
4050   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4051   FlagStatus tmp;
4052   HAL_StatusTypeDef dmaxferstatus;
4053 
4054   /* Check the parameters */
4055   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4056 
4057   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4058   {
4059     if ((pData == NULL) || (Size == 0U))
4060     {
4061       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4062       return  HAL_ERROR;
4063     }
4064 
4065     /* Process Locked */
4066     __HAL_LOCK(hi2c);
4067 
4068     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4069     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
4070 
4071     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4072     /* and then toggle the HAL slave RX state to TX state */
4073     if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
4074     {
4075       /* Disable associated Interrupts */
4076       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
4077 
4078       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
4079       {
4080         /* Abort DMA Xfer if any */
4081         if (hi2c->hdmarx != NULL)
4082         {
4083           hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
4084 
4085           /* Set the I2C DMA Abort callback :
4086           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4087           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
4088 
4089           /* Abort DMA RX */
4090           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
4091           {
4092             /* Call Directly XferAbortCallback function in case of error */
4093             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
4094           }
4095         }
4096       }
4097     }
4098     else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4099     {
4100       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4101       {
4102         hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4103 
4104         /* Abort DMA Xfer if any */
4105         if (hi2c->hdmatx != NULL)
4106         {
4107           /* Set the I2C DMA Abort callback :
4108           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4109           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4110 
4111           /* Abort DMA TX */
4112           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4113           {
4114             /* Call Directly XferAbortCallback function in case of error */
4115             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4116           }
4117         }
4118       }
4119     }
4120     else
4121     {
4122       /* Nothing to do */
4123     }
4124 
4125     hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
4126     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4127     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4128 
4129     /* Enable Address Acknowledge */
4130     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4131 
4132     /* Prepare transfer parameters */
4133     hi2c->pBuffPtr    = pData;
4134     hi2c->XferCount   = Size;
4135     hi2c->XferSize    = hi2c->XferCount;
4136     hi2c->XferOptions = XferOptions;
4137     hi2c->XferISR     = I2C_Slave_ISR_DMA;
4138 
4139     if (hi2c->hdmatx != NULL)
4140     {
4141       /* Set the I2C DMA transfer complete callback */
4142       hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
4143 
4144       /* Set the DMA error callback */
4145       hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
4146 
4147       /* Set the unused DMA callbacks to NULL */
4148       hi2c->hdmatx->XferHalfCpltCallback = NULL;
4149       hi2c->hdmatx->XferAbortCallback = NULL;
4150 
4151       /* Enable the DMA stream or channel depends on Instance */
4152       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
4153                                        hi2c->XferSize);
4154     }
4155     else
4156     {
4157       /* Update I2C state */
4158       hi2c->State     = HAL_I2C_STATE_LISTEN;
4159       hi2c->Mode      = HAL_I2C_MODE_NONE;
4160 
4161       /* Update I2C error code */
4162       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
4163 
4164       /* Process Unlocked */
4165       __HAL_UNLOCK(hi2c);
4166 
4167       return HAL_ERROR;
4168     }
4169 
4170     if (dmaxferstatus == HAL_OK)
4171     {
4172       /* Update XferCount value */
4173       hi2c->XferCount -= hi2c->XferSize;
4174 
4175       /* Reset XferSize */
4176       hi2c->XferSize = 0;
4177     }
4178     else
4179     {
4180       /* Update I2C state */
4181       hi2c->State     = HAL_I2C_STATE_LISTEN;
4182       hi2c->Mode      = HAL_I2C_MODE_NONE;
4183 
4184       /* Update I2C error code */
4185       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
4186 
4187       /* Process Unlocked */
4188       __HAL_UNLOCK(hi2c);
4189 
4190       return HAL_ERROR;
4191     }
4192 
4193     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4194     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET))
4195     {
4196       /* Clear ADDR flag after prepare the transfer parameters */
4197       /* This action will generate an acknowledge to the Master */
4198       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4199     }
4200 
4201     /* Process Unlocked */
4202     __HAL_UNLOCK(hi2c);
4203 
4204     /* Enable DMA Request */
4205     hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
4206 
4207     /* Note : The I2C interrupts must be enabled after unlocking current process
4208     to avoid the risk of I2C interrupt handle execution before current
4209     process unlock */
4210     /* Enable ERR, STOP, NACK, ADDR interrupts */
4211     I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4212 
4213     return HAL_OK;
4214   }
4215   else
4216   {
4217     return HAL_ERROR;
4218   }
4219 }
4220 
4221 /**
4222   * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
4223   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4224   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4225   *                the configuration information for the specified I2C.
4226   * @param  pData Pointer to data buffer
4227   * @param  Size Amount of data to be sent
4228   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4229   * @retval HAL status
4230   */
4231 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4232                                                uint32_t XferOptions)
4233 {
4234   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4235   FlagStatus tmp;
4236 
4237   /* Check the parameters */
4238   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4239 
4240   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4241   {
4242     if ((pData == NULL) || (Size == 0U))
4243     {
4244       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4245       return  HAL_ERROR;
4246     }
4247 
4248     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4249     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4250 
4251     /* Process Locked */
4252     __HAL_LOCK(hi2c);
4253 
4254     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4255     /* and then toggle the HAL slave TX state to RX state */
4256     if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4257     {
4258       /* Disable associated Interrupts */
4259       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4260 
4261       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4262       {
4263         hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4264 
4265         /* Abort DMA Xfer if any */
4266         if (hi2c->hdmatx != NULL)
4267         {
4268           /* Set the I2C DMA Abort callback :
4269            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4270           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4271 
4272           /* Abort DMA TX */
4273           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4274           {
4275             /* Call Directly XferAbortCallback function in case of error */
4276             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4277           }
4278         }
4279       }
4280     }
4281 
4282     hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4283     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4284     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4285 
4286     /* Enable Address Acknowledge */
4287     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4288 
4289     /* Prepare transfer parameters */
4290     hi2c->pBuffPtr    = pData;
4291     hi2c->XferCount   = Size;
4292     hi2c->XferSize    = hi2c->XferCount;
4293     hi2c->XferOptions = XferOptions;
4294     hi2c->XferISR     = I2C_Slave_ISR_IT;
4295 
4296     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4297     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4298     {
4299       /* Clear ADDR flag after prepare the transfer parameters */
4300       /* This action will generate an acknowledge to the Master */
4301       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4302     }
4303 
4304     /* Process Unlocked */
4305     __HAL_UNLOCK(hi2c);
4306 
4307     /* Note : The I2C interrupts must be enabled after unlocking current process
4308     to avoid the risk of I2C interrupt handle execution before current
4309     process unlock */
4310     /* REnable ADDR interrupt */
4311     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4312 
4313     return HAL_OK;
4314   }
4315   else
4316   {
4317     return HAL_ERROR;
4318   }
4319 }
4320 
4321 /**
4322   * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with DMA
4323   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4324   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4325   *                the configuration information for the specified I2C.
4326   * @param  pData Pointer to data buffer
4327   * @param  Size Amount of data to be sent
4328   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4329   * @retval HAL status
4330   */
4331 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4332                                                 uint32_t XferOptions)
4333 {
4334   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4335   FlagStatus tmp;
4336   HAL_StatusTypeDef dmaxferstatus;
4337 
4338   /* Check the parameters */
4339   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4340 
4341   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4342   {
4343     if ((pData == NULL) || (Size == 0U))
4344     {
4345       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4346       return  HAL_ERROR;
4347     }
4348 
4349     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4350     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4351 
4352     /* Process Locked */
4353     __HAL_LOCK(hi2c);
4354 
4355     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4356     /* and then toggle the HAL slave TX state to RX state */
4357     if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4358     {
4359       /* Disable associated Interrupts */
4360       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4361 
4362       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4363       {
4364         /* Abort DMA Xfer if any */
4365         if (hi2c->hdmatx != NULL)
4366         {
4367           hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4368 
4369           /* Set the I2C DMA Abort callback :
4370            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4371           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4372 
4373           /* Abort DMA TX */
4374           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4375           {
4376             /* Call Directly XferAbortCallback function in case of error */
4377             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4378           }
4379         }
4380       }
4381     }
4382     else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
4383     {
4384       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
4385       {
4386         hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
4387 
4388         /* Abort DMA Xfer if any */
4389         if (hi2c->hdmarx != NULL)
4390         {
4391           /* Set the I2C DMA Abort callback :
4392            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4393           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
4394 
4395           /* Abort DMA RX */
4396           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
4397           {
4398             /* Call Directly XferAbortCallback function in case of error */
4399             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
4400           }
4401         }
4402       }
4403     }
4404     else
4405     {
4406       /* Nothing to do */
4407     }
4408 
4409     hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4410     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4411     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4412 
4413     /* Enable Address Acknowledge */
4414     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4415 
4416     /* Prepare transfer parameters */
4417     hi2c->pBuffPtr    = pData;
4418     hi2c->XferCount   = Size;
4419     hi2c->XferSize    = hi2c->XferCount;
4420     hi2c->XferOptions = XferOptions;
4421     hi2c->XferISR     = I2C_Slave_ISR_DMA;
4422 
4423     if (hi2c->hdmarx != NULL)
4424     {
4425       /* Set the I2C DMA transfer complete callback */
4426       hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
4427 
4428       /* Set the DMA error callback */
4429       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
4430 
4431       /* Set the unused DMA callbacks to NULL */
4432       hi2c->hdmarx->XferHalfCpltCallback = NULL;
4433       hi2c->hdmarx->XferAbortCallback = NULL;
4434 
4435       /* Enable the DMA stream or channel depends on Instance */
4436       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR,
4437                                        (uint32_t)pData, hi2c->XferSize);
4438     }
4439     else
4440     {
4441       /* Update I2C state */
4442       hi2c->State     = HAL_I2C_STATE_LISTEN;
4443       hi2c->Mode      = HAL_I2C_MODE_NONE;
4444 
4445       /* Update I2C error code */
4446       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
4447 
4448       /* Process Unlocked */
4449       __HAL_UNLOCK(hi2c);
4450 
4451       return HAL_ERROR;
4452     }
4453 
4454     if (dmaxferstatus == HAL_OK)
4455     {
4456       /* Update XferCount value */
4457       hi2c->XferCount -= hi2c->XferSize;
4458 
4459       /* Reset XferSize */
4460       hi2c->XferSize = 0;
4461     }
4462     else
4463     {
4464       /* Update I2C state */
4465       hi2c->State     = HAL_I2C_STATE_LISTEN;
4466       hi2c->Mode      = HAL_I2C_MODE_NONE;
4467 
4468       /* Update I2C error code */
4469       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
4470 
4471       /* Process Unlocked */
4472       __HAL_UNLOCK(hi2c);
4473 
4474       return HAL_ERROR;
4475     }
4476 
4477     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4478     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4479     {
4480       /* Clear ADDR flag after prepare the transfer parameters */
4481       /* This action will generate an acknowledge to the Master */
4482       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4483     }
4484 
4485     /* Process Unlocked */
4486     __HAL_UNLOCK(hi2c);
4487 
4488     /* Enable DMA Request */
4489     hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
4490 
4491     /* Note : The I2C interrupts must be enabled after unlocking current process
4492     to avoid the risk of I2C interrupt handle execution before current
4493     process unlock */
4494     /* REnable ADDR interrupt */
4495     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4496 
4497     return HAL_OK;
4498   }
4499   else
4500   {
4501     return HAL_ERROR;
4502   }
4503 }
4504 
4505 /**
4506   * @brief  Enable the Address listen mode with Interrupt.
4507   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4508   *                the configuration information for the specified I2C.
4509   * @retval HAL status
4510   */
4511 HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c)
4512 {
4513   if (hi2c->State == HAL_I2C_STATE_READY)
4514   {
4515     hi2c->State = HAL_I2C_STATE_LISTEN;
4516     hi2c->XferISR = I2C_Slave_ISR_IT;
4517 
4518     /* Enable the Address Match interrupt */
4519     I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4520 
4521     return HAL_OK;
4522   }
4523   else
4524   {
4525     return HAL_BUSY;
4526   }
4527 }
4528 
4529 /**
4530   * @brief  Disable the Address listen mode with Interrupt.
4531   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4532   *                the configuration information for the specified I2C
4533   * @retval HAL status
4534   */
4535 HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
4536 {
4537   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4538   uint32_t tmp;
4539 
4540   /* Disable Address listen mode only if a transfer is not ongoing */
4541   if (hi2c->State == HAL_I2C_STATE_LISTEN)
4542   {
4543     tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
4544     hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
4545     hi2c->State = HAL_I2C_STATE_READY;
4546     hi2c->Mode = HAL_I2C_MODE_NONE;
4547     hi2c->XferISR = NULL;
4548 
4549     /* Disable the Address Match interrupt */
4550     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4551 
4552     return HAL_OK;
4553   }
4554   else
4555   {
4556     return HAL_BUSY;
4557   }
4558 }
4559 
4560 /**
4561   * @brief  Abort a master I2C IT or DMA process communication with Interrupt.
4562   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4563   *                the configuration information for the specified I2C.
4564   * @param  DevAddress Target device address: The device 7 bits address value
4565   *         in datasheet must be shifted to the left before calling the interface
4566   * @retval HAL status
4567   */
4568 HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
4569 {
4570   if (hi2c->Mode == HAL_I2C_MODE_MASTER)
4571   {
4572     /* Process Locked */
4573     __HAL_LOCK(hi2c);
4574 
4575     /* Disable Interrupts and Store Previous state */
4576     if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
4577     {
4578       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4579       hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
4580     }
4581     else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
4582     {
4583       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
4584       hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
4585     }
4586     else
4587     {
4588       /* Do nothing */
4589     }
4590 
4591     /* Set State at HAL_I2C_STATE_ABORT */
4592     hi2c->State = HAL_I2C_STATE_ABORT;
4593 
4594     /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */
4595     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
4596     I2C_TransferConfig(hi2c, DevAddress, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP);
4597 
4598     /* Process Unlocked */
4599     __HAL_UNLOCK(hi2c);
4600 
4601     /* Note : The I2C interrupts must be enabled after unlocking current process
4602               to avoid the risk of I2C interrupt handle execution before current
4603               process unlock */
4604     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
4605 
4606     return HAL_OK;
4607   }
4608   else
4609   {
4610     /* Wrong usage of abort function */
4611     /* This function should be used only in case of abort monitored by master device */
4612     return HAL_ERROR;
4613   }
4614 }
4615 
4616 /**
4617   * @}
4618   */
4619 
4620 /** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
4621   * @ingroup RTEMSBSPsARMSTM32H7
4622   * @{
4623   */
4624 
4625 /**
4626   * @brief  This function handles I2C event interrupt request.
4627   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4628   *                the configuration information for the specified I2C.
4629   * @retval None
4630   */
4631 void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) /* Derogation MISRAC2012-Rule-8.13 */
4632 {
4633   /* Get current IT Flags and IT sources value */
4634   uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4635   uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4636 
4637   /* I2C events treatment -------------------------------------*/
4638   if (hi2c->XferISR != NULL)
4639   {
4640     hi2c->XferISR(hi2c, itflags, itsources);
4641   }
4642 }
4643 
4644 /**
4645   * @brief  This function handles I2C error interrupt request.
4646   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4647   *                the configuration information for the specified I2C.
4648   * @retval None
4649   */
4650 void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
4651 {
4652   uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4653   uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4654   uint32_t tmperror;
4655 
4656   /* I2C Bus error interrupt occurred ------------------------------------*/
4657   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_BERR) != RESET) && \
4658       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4659   {
4660     hi2c->ErrorCode |= HAL_I2C_ERROR_BERR;
4661 
4662     /* Clear BERR flag */
4663     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
4664   }
4665 
4666   /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
4667   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_OVR) != RESET) && \
4668       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4669   {
4670     hi2c->ErrorCode |= HAL_I2C_ERROR_OVR;
4671 
4672     /* Clear OVR flag */
4673     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
4674   }
4675 
4676   /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/
4677   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_ARLO) != RESET) && \
4678       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4679   {
4680     hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO;
4681 
4682     /* Clear ARLO flag */
4683     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
4684   }
4685 
4686   /* Store current volatile hi2c->ErrorCode, misra rule */
4687   tmperror = hi2c->ErrorCode;
4688 
4689   /* Call the Error Callback in case of Error detected */
4690   if ((tmperror & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) !=  HAL_I2C_ERROR_NONE)
4691   {
4692     I2C_ITError(hi2c, tmperror);
4693   }
4694 }
4695 
4696 /**
4697   * @brief  Master Tx Transfer completed callback.
4698   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4699   *                the configuration information for the specified I2C.
4700   * @retval None
4701   */
4702 __weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
4703 {
4704   /* Prevent unused argument(s) compilation warning */
4705   UNUSED(hi2c);
4706 
4707   /* NOTE : This function should not be modified, when the callback is needed,
4708             the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
4709    */
4710 }
4711 
4712 /**
4713   * @brief  Master Rx Transfer completed callback.
4714   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4715   *                the configuration information for the specified I2C.
4716   * @retval None
4717   */
4718 __weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
4719 {
4720   /* Prevent unused argument(s) compilation warning */
4721   UNUSED(hi2c);
4722 
4723   /* NOTE : This function should not be modified, when the callback is needed,
4724             the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
4725    */
4726 }
4727 
4728 /** @brief  Slave Tx Transfer completed callback.
4729   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4730   *                the configuration information for the specified I2C.
4731   * @retval None
4732   */
4733 __weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
4734 {
4735   /* Prevent unused argument(s) compilation warning */
4736   UNUSED(hi2c);
4737 
4738   /* NOTE : This function should not be modified, when the callback is needed,
4739             the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
4740    */
4741 }
4742 
4743 /**
4744   * @brief  Slave Rx Transfer completed callback.
4745   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4746   *                the configuration information for the specified I2C.
4747   * @retval None
4748   */
4749 __weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
4750 {
4751   /* Prevent unused argument(s) compilation warning */
4752   UNUSED(hi2c);
4753 
4754   /* NOTE : This function should not be modified, when the callback is needed,
4755             the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
4756    */
4757 }
4758 
4759 /**
4760   * @brief  Slave Address Match callback.
4761   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4762   *                the configuration information for the specified I2C.
4763   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION
4764   * @param  AddrMatchCode Address Match Code
4765   * @retval None
4766   */
4767 __weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
4768 {
4769   /* Prevent unused argument(s) compilation warning */
4770   UNUSED(hi2c);
4771   UNUSED(TransferDirection);
4772   UNUSED(AddrMatchCode);
4773 
4774   /* NOTE : This function should not be modified, when the callback is needed,
4775             the HAL_I2C_AddrCallback() could be implemented in the user file
4776    */
4777 }
4778 
4779 /**
4780   * @brief  Listen Complete callback.
4781   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4782   *                the configuration information for the specified I2C.
4783   * @retval None
4784   */
4785 __weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
4786 {
4787   /* Prevent unused argument(s) compilation warning */
4788   UNUSED(hi2c);
4789 
4790   /* NOTE : This function should not be modified, when the callback is needed,
4791             the HAL_I2C_ListenCpltCallback() could be implemented in the user file
4792    */
4793 }
4794 
4795 /**
4796   * @brief  Memory Tx Transfer completed callback.
4797   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4798   *                the configuration information for the specified I2C.
4799   * @retval None
4800   */
4801 __weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
4802 {
4803   /* Prevent unused argument(s) compilation warning */
4804   UNUSED(hi2c);
4805 
4806   /* NOTE : This function should not be modified, when the callback is needed,
4807             the HAL_I2C_MemTxCpltCallback could be implemented in the user file
4808    */
4809 }
4810 
4811 /**
4812   * @brief  Memory Rx Transfer completed callback.
4813   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4814   *                the configuration information for the specified I2C.
4815   * @retval None
4816   */
4817 __weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
4818 {
4819   /* Prevent unused argument(s) compilation warning */
4820   UNUSED(hi2c);
4821 
4822   /* NOTE : This function should not be modified, when the callback is needed,
4823             the HAL_I2C_MemRxCpltCallback could be implemented in the user file
4824    */
4825 }
4826 
4827 /**
4828   * @brief  I2C error callback.
4829   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4830   *                the configuration information for the specified I2C.
4831   * @retval None
4832   */
4833 __weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
4834 {
4835   /* Prevent unused argument(s) compilation warning */
4836   UNUSED(hi2c);
4837 
4838   /* NOTE : This function should not be modified, when the callback is needed,
4839             the HAL_I2C_ErrorCallback could be implemented in the user file
4840    */
4841 }
4842 
4843 /**
4844   * @brief  I2C abort callback.
4845   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4846   *                the configuration information for the specified I2C.
4847   * @retval None
4848   */
4849 __weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
4850 {
4851   /* Prevent unused argument(s) compilation warning */
4852   UNUSED(hi2c);
4853 
4854   /* NOTE : This function should not be modified, when the callback is needed,
4855             the HAL_I2C_AbortCpltCallback could be implemented in the user file
4856    */
4857 }
4858 
4859 /**
4860   * @}
4861   */
4862 
4863 /** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
4864   * @ingroup RTEMSBSPsARMSTM32H7
4865   *  @brief   Peripheral State, Mode and Error functions
4866   *
4867 @verbatim
4868  ===============================================================================
4869             ##### Peripheral State, Mode and Error functions #####
4870  ===============================================================================
4871     [..]
4872     This subsection permit to get in run-time the status of the peripheral
4873     and the data flow.
4874 
4875 @endverbatim
4876   * @{
4877   */
4878 
4879 /**
4880   * @brief  Return the I2C handle state.
4881   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4882   *                the configuration information for the specified I2C.
4883   * @retval HAL state
4884   */
4885 HAL_I2C_StateTypeDef HAL_I2C_GetState(const I2C_HandleTypeDef *hi2c)
4886 {
4887   /* Return I2C handle state */
4888   return hi2c->State;
4889 }
4890 
4891 /**
4892   * @brief  Returns the I2C Master, Slave, Memory or no mode.
4893   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4894   *         the configuration information for I2C module
4895   * @retval HAL mode
4896   */
4897 HAL_I2C_ModeTypeDef HAL_I2C_GetMode(const I2C_HandleTypeDef *hi2c)
4898 {
4899   return hi2c->Mode;
4900 }
4901 
4902 /**
4903   * @brief  Return the I2C error code.
4904   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4905   *              the configuration information for the specified I2C.
4906   * @retval I2C Error Code
4907   */
4908 uint32_t HAL_I2C_GetError(const I2C_HandleTypeDef *hi2c)
4909 {
4910   return hi2c->ErrorCode;
4911 }
4912 
4913 /**
4914   * @}
4915   */
4916 
4917 /**
4918   * @}
4919   */
4920 
4921 /** @addtogroup I2C_Private_Functions
4922   * @{
4923   */
4924 
4925 /**
4926   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
4927   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4928   *                the configuration information for the specified I2C.
4929   * @param  ITFlags Interrupt flags to handle.
4930   * @param  ITSources Interrupt sources enabled.
4931   * @retval HAL status
4932   */
4933 static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
4934                                            uint32_t ITSources)
4935 {
4936   uint16_t devaddress;
4937   uint32_t tmpITFlags = ITFlags;
4938 
4939   /* Process Locked */
4940   __HAL_LOCK(hi2c);
4941 
4942   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
4943       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
4944   {
4945     /* Clear NACK Flag */
4946     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4947 
4948     /* Set corresponding Error Code */
4949     /* No need to generate STOP, it is automatically done */
4950     /* Error callback will be send during stop flag treatment */
4951     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
4952 
4953     /* Flush TX register */
4954     I2C_Flush_TXDR(hi2c);
4955   }
4956   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
4957            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
4958   {
4959     /* Remove RXNE flag on temporary variable as read done */
4960     tmpITFlags &= ~I2C_FLAG_RXNE;
4961 
4962     /* Read data from RXDR */
4963     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
4964 
4965     /* Increment Buffer pointer */
4966     hi2c->pBuffPtr++;
4967 
4968     hi2c->XferSize--;
4969     hi2c->XferCount--;
4970   }
4971   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) == RESET) && \
4972            ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
4973             (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)))
4974   {
4975     /* Write data to TXDR */
4976     if (hi2c->XferCount != 0U)
4977     {
4978       /* Write data to TXDR */
4979       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
4980 
4981       /* Increment Buffer pointer */
4982       hi2c->pBuffPtr++;
4983 
4984       hi2c->XferSize--;
4985       hi2c->XferCount--;
4986     }
4987   }
4988   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \
4989            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
4990   {
4991     if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
4992     {
4993       devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
4994 
4995       if (hi2c->XferCount > MAX_NBYTE_SIZE)
4996       {
4997         hi2c->XferSize = MAX_NBYTE_SIZE;
4998         I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
4999       }
5000       else
5001       {
5002         hi2c->XferSize = hi2c->XferCount;
5003         if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5004         {
5005           I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
5006                              hi2c->XferOptions, I2C_NO_STARTSTOP);
5007         }
5008         else
5009         {
5010           I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
5011                              I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5012         }
5013       }
5014     }
5015     else
5016     {
5017       /* Call TxCpltCallback() if no stop mode is set */
5018       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5019       {
5020         /* Call I2C Master Sequential complete process */
5021         I2C_ITMasterSeqCplt(hi2c);
5022       }
5023       else
5024       {
5025         /* Wrong size Status regarding TCR flag event */
5026         /* Call the corresponding callback to inform upper layer of End of Transfer */
5027         I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5028       }
5029     }
5030   }
5031   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \
5032            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5033   {
5034     if (hi2c->XferCount == 0U)
5035     {
5036       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5037       {
5038         /* Generate a stop condition in case of no transfer option */
5039         if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
5040         {
5041           /* Generate Stop */
5042           hi2c->Instance->CR2 |= I2C_CR2_STOP;
5043         }
5044         else
5045         {
5046           /* Call I2C Master Sequential complete process */
5047           I2C_ITMasterSeqCplt(hi2c);
5048         }
5049       }
5050     }
5051     else
5052     {
5053       /* Wrong size Status regarding TC flag event */
5054       /* Call the corresponding callback to inform upper layer of End of Transfer */
5055       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5056     }
5057   }
5058   else
5059   {
5060     /* Nothing to do */
5061   }
5062 
5063   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5064       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5065   {
5066     /* Call I2C Master complete process */
5067     I2C_ITMasterCplt(hi2c, tmpITFlags);
5068   }
5069 
5070   /* Process Unlocked */
5071   __HAL_UNLOCK(hi2c);
5072 
5073   return HAL_OK;
5074 }
5075 
5076 /**
5077   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with Interrupt.
5078   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5079   *                the configuration information for the specified I2C.
5080   * @param  ITFlags Interrupt flags to handle.
5081   * @param  ITSources Interrupt sources enabled.
5082   * @retval HAL status
5083   */
5084 static HAL_StatusTypeDef I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5085                                         uint32_t ITSources)
5086 {
5087   uint32_t direction = I2C_GENERATE_START_WRITE;
5088   uint32_t tmpITFlags = ITFlags;
5089 
5090   /* Process Locked */
5091   __HAL_LOCK(hi2c);
5092 
5093   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
5094       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5095   {
5096     /* Clear NACK Flag */
5097     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5098 
5099     /* Set corresponding Error Code */
5100     /* No need to generate STOP, it is automatically done */
5101     /* Error callback will be send during stop flag treatment */
5102     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5103 
5104     /* Flush TX register */
5105     I2C_Flush_TXDR(hi2c);
5106   }
5107   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
5108            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
5109   {
5110     /* Remove RXNE flag on temporary variable as read done */
5111     tmpITFlags &= ~I2C_FLAG_RXNE;
5112 
5113     /* Read data from RXDR */
5114     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5115 
5116     /* Increment Buffer pointer */
5117     hi2c->pBuffPtr++;
5118 
5119     hi2c->XferSize--;
5120     hi2c->XferCount--;
5121   }
5122   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
5123            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5124   {
5125     if (hi2c->Memaddress == 0xFFFFFFFFU)
5126     {
5127       /* Write data to TXDR */
5128       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
5129 
5130       /* Increment Buffer pointer */
5131       hi2c->pBuffPtr++;
5132 
5133       hi2c->XferSize--;
5134       hi2c->XferCount--;
5135     }
5136     else
5137     {
5138       /* Write LSB part of Memory Address */
5139       hi2c->Instance->TXDR = hi2c->Memaddress;
5140 
5141       /* Reset Memaddress content */
5142       hi2c->Memaddress = 0xFFFFFFFFU;
5143     }
5144   }
5145   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \
5146            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5147   {
5148     if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
5149     {
5150       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5151       {
5152         hi2c->XferSize = MAX_NBYTE_SIZE;
5153         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5154                            I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
5155       }
5156       else
5157       {
5158         hi2c->XferSize = hi2c->XferCount;
5159         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5160                            I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5161       }
5162     }
5163     else
5164     {
5165       /* Wrong size Status regarding TCR flag event */
5166       /* Call the corresponding callback to inform upper layer of End of Transfer */
5167       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5168     }
5169   }
5170   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \
5171            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5172   {
5173     /* Disable Interrupt related to address step */
5174     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5175 
5176     /* Enable ERR, TC, STOP, NACK and RXI interrupts */
5177     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
5178 
5179     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5180     {
5181       direction = I2C_GENERATE_START_READ;
5182     }
5183 
5184     if (hi2c->XferCount > MAX_NBYTE_SIZE)
5185     {
5186       hi2c->XferSize = MAX_NBYTE_SIZE;
5187 
5188       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5189       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5190                          I2C_RELOAD_MODE, direction);
5191     }
5192     else
5193     {
5194       hi2c->XferSize = hi2c->XferCount;
5195 
5196       /* Set NBYTES to write and generate RESTART */
5197       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5198                          I2C_AUTOEND_MODE, direction);
5199     }
5200   }
5201   else
5202   {
5203     /* Nothing to do */
5204   }
5205 
5206   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5207       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5208   {
5209     /* Call I2C Master complete process */
5210     I2C_ITMasterCplt(hi2c, tmpITFlags);
5211   }
5212 
5213   /* Process Unlocked */
5214   __HAL_UNLOCK(hi2c);
5215 
5216   return HAL_OK;
5217 }
5218 
5219 /**
5220   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
5221   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5222   *                the configuration information for the specified I2C.
5223   * @param  ITFlags Interrupt flags to handle.
5224   * @param  ITSources Interrupt sources enabled.
5225   * @retval HAL status
5226   */
5227 static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5228                                           uint32_t ITSources)
5229 {
5230   uint32_t tmpoptions = hi2c->XferOptions;
5231   uint32_t tmpITFlags = ITFlags;
5232 
5233   /* Process locked */
5234   __HAL_LOCK(hi2c);
5235 
5236   /* Check if STOPF is set */
5237   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5238       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5239   {
5240     /* Call I2C Slave complete process */
5241     I2C_ITSlaveCplt(hi2c, tmpITFlags);
5242   }
5243   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
5244            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5245   {
5246     /* Check that I2C transfer finished */
5247     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5248     /* Mean XferCount == 0*/
5249     /* So clear Flag NACKF only */
5250     if (hi2c->XferCount == 0U)
5251     {
5252       if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
5253         /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
5254            Warning[Pa134]: left and right operands are identical */
5255       {
5256         /* Call I2C Listen complete process */
5257         I2C_ITListenCplt(hi2c, tmpITFlags);
5258       }
5259       else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
5260       {
5261         /* Clear NACK Flag */
5262         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5263 
5264         /* Flush TX register */
5265         I2C_Flush_TXDR(hi2c);
5266 
5267         /* Last Byte is Transmitted */
5268         /* Call I2C Slave Sequential complete process */
5269         I2C_ITSlaveSeqCplt(hi2c);
5270       }
5271       else
5272       {
5273         /* Clear NACK Flag */
5274         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5275       }
5276     }
5277     else
5278     {
5279       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5280       /* Clear NACK Flag */
5281       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5282 
5283       /* Set ErrorCode corresponding to a Non-Acknowledge */
5284       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5285 
5286       if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
5287       {
5288         /* Call the corresponding callback to inform upper layer of End of Transfer */
5289         I2C_ITError(hi2c, hi2c->ErrorCode);
5290       }
5291     }
5292   }
5293   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
5294            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
5295   {
5296     if (hi2c->XferCount > 0U)
5297     {
5298       /* Read data from RXDR */
5299       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5300 
5301       /* Increment Buffer pointer */
5302       hi2c->pBuffPtr++;
5303 
5304       hi2c->XferSize--;
5305       hi2c->XferCount--;
5306     }
5307 
5308     if ((hi2c->XferCount == 0U) && \
5309         (tmpoptions != I2C_NO_OPTION_FRAME))
5310     {
5311       /* Call I2C Slave Sequential complete process */
5312       I2C_ITSlaveSeqCplt(hi2c);
5313     }
5314   }
5315   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_ADDR) != RESET) && \
5316            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
5317   {
5318     I2C_ITAddrCplt(hi2c, tmpITFlags);
5319   }
5320   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
5321            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5322   {
5323     /* Write data to TXDR only if XferCount not reach "0" */
5324     /* A TXIS flag can be set, during STOP treatment      */
5325     /* Check if all Data have already been sent */
5326     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
5327     if (hi2c->XferCount > 0U)
5328     {
5329       /* Write data to TXDR */
5330       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
5331 
5332       /* Increment Buffer pointer */
5333       hi2c->pBuffPtr++;
5334 
5335       hi2c->XferCount--;
5336       hi2c->XferSize--;
5337     }
5338     else
5339     {
5340       if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
5341       {
5342         /* Last Byte is Transmitted */
5343         /* Call I2C Slave Sequential complete process */
5344         I2C_ITSlaveSeqCplt(hi2c);
5345       }
5346     }
5347   }
5348   else
5349   {
5350     /* Nothing to do */
5351   }
5352 
5353   /* Process Unlocked */
5354   __HAL_UNLOCK(hi2c);
5355 
5356   return HAL_OK;
5357 }
5358 
5359 /**
5360   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
5361   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5362   *                the configuration information for the specified I2C.
5363   * @param  ITFlags Interrupt flags to handle.
5364   * @param  ITSources Interrupt sources enabled.
5365   * @retval HAL status
5366   */
5367 static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5368                                             uint32_t ITSources)
5369 {
5370   uint16_t devaddress;
5371   uint32_t xfermode;
5372 
5373   /* Process Locked */
5374   __HAL_LOCK(hi2c);
5375 
5376   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5377       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5378   {
5379     /* Clear NACK Flag */
5380     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5381 
5382     /* Set corresponding Error Code */
5383     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5384 
5385     /* No need to generate STOP, it is automatically done */
5386     /* But enable STOP interrupt, to treat it */
5387     /* Error callback will be send during stop flag treatment */
5388     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
5389 
5390     /* Flush TX register */
5391     I2C_Flush_TXDR(hi2c);
5392   }
5393   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \
5394            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5395   {
5396     /* Disable TC interrupt */
5397     __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI);
5398 
5399     if (hi2c->XferCount != 0U)
5400     {
5401       /* Recover Slave address */
5402       devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
5403 
5404       /* Prepare the new XferSize to transfer */
5405       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5406       {
5407         hi2c->XferSize = MAX_NBYTE_SIZE;
5408         xfermode = I2C_RELOAD_MODE;
5409       }
5410       else
5411       {
5412         hi2c->XferSize = hi2c->XferCount;
5413         if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5414         {
5415           xfermode = hi2c->XferOptions;
5416         }
5417         else
5418         {
5419           xfermode = I2C_AUTOEND_MODE;
5420         }
5421       }
5422 
5423       /* Set the new XferSize in Nbytes register */
5424       I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
5425 
5426       /* Update XferCount value */
5427       hi2c->XferCount -= hi2c->XferSize;
5428 
5429       /* Enable DMA Request */
5430       if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5431       {
5432         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5433       }
5434       else
5435       {
5436         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5437       }
5438     }
5439     else
5440     {
5441       /* Call TxCpltCallback() if no stop mode is set */
5442       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5443       {
5444         /* Call I2C Master Sequential complete process */
5445         I2C_ITMasterSeqCplt(hi2c);
5446       }
5447       else
5448       {
5449         /* Wrong size Status regarding TCR flag event */
5450         /* Call the corresponding callback to inform upper layer of End of Transfer */
5451         I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5452       }
5453     }
5454   }
5455   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \
5456            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5457   {
5458     if (hi2c->XferCount == 0U)
5459     {
5460       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5461       {
5462         /* Generate a stop condition in case of no transfer option */
5463         if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
5464         {
5465           /* Generate Stop */
5466           hi2c->Instance->CR2 |= I2C_CR2_STOP;
5467         }
5468         else
5469         {
5470           /* Call I2C Master Sequential complete process */
5471           I2C_ITMasterSeqCplt(hi2c);
5472         }
5473       }
5474     }
5475     else
5476     {
5477       /* Wrong size Status regarding TC flag event */
5478       /* Call the corresponding callback to inform upper layer of End of Transfer */
5479       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5480     }
5481   }
5482   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5483            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5484   {
5485     /* Call I2C Master complete process */
5486     I2C_ITMasterCplt(hi2c, ITFlags);
5487   }
5488   else
5489   {
5490     /* Nothing to do */
5491   }
5492 
5493   /* Process Unlocked */
5494   __HAL_UNLOCK(hi2c);
5495 
5496   return HAL_OK;
5497 }
5498 
5499 /**
5500   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with DMA.
5501   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5502   *                the configuration information for the specified I2C.
5503   * @param  ITFlags Interrupt flags to handle.
5504   * @param  ITSources Interrupt sources enabled.
5505   * @retval HAL status
5506   */
5507 static HAL_StatusTypeDef I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5508                                          uint32_t ITSources)
5509 {
5510   uint32_t direction = I2C_GENERATE_START_WRITE;
5511 
5512   /* Process Locked */
5513   __HAL_LOCK(hi2c);
5514 
5515   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5516       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5517   {
5518     /* Clear NACK Flag */
5519     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5520 
5521     /* Set corresponding Error Code */
5522     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5523 
5524     /* No need to generate STOP, it is automatically done */
5525     /* But enable STOP interrupt, to treat it */
5526     /* Error callback will be send during stop flag treatment */
5527     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
5528 
5529     /* Flush TX register */
5530     I2C_Flush_TXDR(hi2c);
5531   }
5532   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TXIS) != RESET) && \
5533            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5534   {
5535     /* Write LSB part of Memory Address */
5536     hi2c->Instance->TXDR = hi2c->Memaddress;
5537 
5538     /* Reset Memaddress content */
5539     hi2c->Memaddress = 0xFFFFFFFFU;
5540   }
5541   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \
5542            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5543   {
5544     /* Disable Interrupt related to address step */
5545     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5546 
5547     /* Enable only Error interrupt */
5548     I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
5549 
5550     if (hi2c->XferCount != 0U)
5551     {
5552       /* Prepare the new XferSize to transfer */
5553       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5554       {
5555         hi2c->XferSize = MAX_NBYTE_SIZE;
5556         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5557                            I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
5558       }
5559       else
5560       {
5561         hi2c->XferSize = hi2c->XferCount;
5562         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5563                            I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5564       }
5565 
5566       /* Update XferCount value */
5567       hi2c->XferCount -= hi2c->XferSize;
5568 
5569       /* Enable DMA Request */
5570       if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5571       {
5572         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5573       }
5574       else
5575       {
5576         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5577       }
5578     }
5579     else
5580     {
5581       /* Wrong size Status regarding TCR flag event */
5582       /* Call the corresponding callback to inform upper layer of End of Transfer */
5583       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5584     }
5585   }
5586   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \
5587            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5588   {
5589     /* Disable Interrupt related to address step */
5590     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5591 
5592     /* Enable only Error and NACK interrupt for data transfer */
5593     I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
5594 
5595     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5596     {
5597       direction = I2C_GENERATE_START_READ;
5598     }
5599 
5600     if (hi2c->XferCount > MAX_NBYTE_SIZE)
5601     {
5602       hi2c->XferSize = MAX_NBYTE_SIZE;
5603 
5604       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5605       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5606                          I2C_RELOAD_MODE, direction);
5607     }
5608     else
5609     {
5610       hi2c->XferSize = hi2c->XferCount;
5611 
5612       /* Set NBYTES to write and generate RESTART */
5613       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5614                          I2C_AUTOEND_MODE, direction);
5615     }
5616 
5617     /* Update XferCount value */
5618     hi2c->XferCount -= hi2c->XferSize;
5619 
5620     /* Enable DMA Request */
5621     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5622     {
5623       hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5624     }
5625     else
5626     {
5627       hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5628     }
5629   }
5630   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5631            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5632   {
5633     /* Call I2C Master complete process */
5634     I2C_ITMasterCplt(hi2c, ITFlags);
5635   }
5636   else
5637   {
5638     /* Nothing to do */
5639   }
5640 
5641   /* Process Unlocked */
5642   __HAL_UNLOCK(hi2c);
5643 
5644   return HAL_OK;
5645 }
5646 
5647 /**
5648   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
5649   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5650   *                the configuration information for the specified I2C.
5651   * @param  ITFlags Interrupt flags to handle.
5652   * @param  ITSources Interrupt sources enabled.
5653   * @retval HAL status
5654   */
5655 static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5656                                            uint32_t ITSources)
5657 {
5658   uint32_t tmpoptions = hi2c->XferOptions;
5659   uint32_t treatdmanack = 0U;
5660   HAL_I2C_StateTypeDef tmpstate;
5661 
5662   /* Process locked */
5663   __HAL_LOCK(hi2c);
5664 
5665   /* Check if STOPF is set */
5666   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5667       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5668   {
5669     /* Call I2C Slave complete process */
5670     I2C_ITSlaveCplt(hi2c, ITFlags);
5671   }
5672   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5673            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5674   {
5675     /* Check that I2C transfer finished */
5676     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5677     /* Mean XferCount == 0 */
5678     /* So clear Flag NACKF only */
5679     if ((I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) ||
5680         (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET))
5681     {
5682       /* Split check of hdmarx, for MISRA compliance */
5683       if (hi2c->hdmarx != NULL)
5684       {
5685         if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET)
5686         {
5687           if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U)
5688           {
5689             treatdmanack = 1U;
5690           }
5691         }
5692       }
5693 
5694       /* Split check of hdmatx, for MISRA compliance  */
5695       if (hi2c->hdmatx != NULL)
5696       {
5697         if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET)
5698         {
5699           if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx) == 0U)
5700           {
5701             treatdmanack = 1U;
5702           }
5703         }
5704       }
5705 
5706       if (treatdmanack == 1U)
5707       {
5708         if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
5709           /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
5710              Warning[Pa134]: left and right operands are identical */
5711         {
5712           /* Call I2C Listen complete process */
5713           I2C_ITListenCplt(hi2c, ITFlags);
5714         }
5715         else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
5716         {
5717           /* Clear NACK Flag */
5718           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5719 
5720           /* Flush TX register */
5721           I2C_Flush_TXDR(hi2c);
5722 
5723           /* Last Byte is Transmitted */
5724           /* Call I2C Slave Sequential complete process */
5725           I2C_ITSlaveSeqCplt(hi2c);
5726         }
5727         else
5728         {
5729           /* Clear NACK Flag */
5730           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5731         }
5732       }
5733       else
5734       {
5735         /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5736         /* Clear NACK Flag */
5737         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5738 
5739         /* Set ErrorCode corresponding to a Non-Acknowledge */
5740         hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5741 
5742         /* Store current hi2c->State, solve MISRA2012-Rule-13.5 */
5743         tmpstate = hi2c->State;
5744 
5745         if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
5746         {
5747           if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
5748           {
5749             hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
5750           }
5751           else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
5752           {
5753             hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
5754           }
5755           else
5756           {
5757             /* Do nothing */
5758           }
5759 
5760           /* Call the corresponding callback to inform upper layer of End of Transfer */
5761           I2C_ITError(hi2c, hi2c->ErrorCode);
5762         }
5763       }
5764     }
5765     else
5766     {
5767       /* Only Clear NACK Flag, no DMA treatment is pending */
5768       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5769     }
5770   }
5771   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_ADDR) != RESET) && \
5772            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
5773   {
5774     I2C_ITAddrCplt(hi2c, ITFlags);
5775   }
5776   else
5777   {
5778     /* Nothing to do */
5779   }
5780 
5781   /* Process Unlocked */
5782   __HAL_UNLOCK(hi2c);
5783 
5784   return HAL_OK;
5785 }
5786 
5787 /**
5788   * @brief  Master sends target device address followed by internal memory address for write request.
5789   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5790   *                the configuration information for the specified I2C.
5791   * @param  DevAddress Target device address: The device 7 bits address value
5792   *         in datasheet must be shifted to the left before calling the interface
5793   * @param  MemAddress Internal memory address
5794   * @param  MemAddSize Size of internal memory address
5795   * @param  Timeout Timeout duration
5796   * @param  Tickstart Tick start value
5797   * @retval HAL status
5798   */
5799 static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5800                                                 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5801                                                 uint32_t Tickstart)
5802 {
5803   I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
5804 
5805   /* Wait until TXIS flag is set */
5806   if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5807   {
5808     return HAL_ERROR;
5809   }
5810 
5811   /* If Memory address size is 8Bit */
5812   if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5813   {
5814     /* Send Memory Address */
5815     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5816   }
5817   /* If Memory address size is 16Bit */
5818   else
5819   {
5820     /* Send MSB of Memory Address */
5821     hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5822 
5823     /* Wait until TXIS flag is set */
5824     if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5825     {
5826       return HAL_ERROR;
5827     }
5828 
5829     /* Send LSB of Memory Address */
5830     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5831   }
5832 
5833   /* Wait until TCR flag is set */
5834   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
5835   {
5836     return HAL_ERROR;
5837   }
5838 
5839   return HAL_OK;
5840 }
5841 
5842 /**
5843   * @brief  Master sends target device address followed by internal memory address for read request.
5844   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5845   *                the configuration information for the specified I2C.
5846   * @param  DevAddress Target device address: The device 7 bits address value
5847   *         in datasheet must be shifted to the left before calling the interface
5848   * @param  MemAddress Internal memory address
5849   * @param  MemAddSize Size of internal memory address
5850   * @param  Timeout Timeout duration
5851   * @param  Tickstart Tick start value
5852   * @retval HAL status
5853   */
5854 static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5855                                                uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5856                                                uint32_t Tickstart)
5857 {
5858   I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
5859 
5860   /* Wait until TXIS flag is set */
5861   if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5862   {
5863     return HAL_ERROR;
5864   }
5865 
5866   /* If Memory address size is 8Bit */
5867   if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5868   {
5869     /* Send Memory Address */
5870     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5871   }
5872   /* If Memory address size is 16Bit */
5873   else
5874   {
5875     /* Send MSB of Memory Address */
5876     hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5877 
5878     /* Wait until TXIS flag is set */
5879     if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5880     {
5881       return HAL_ERROR;
5882     }
5883 
5884     /* Send LSB of Memory Address */
5885     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5886   }
5887 
5888   /* Wait until TC flag is set */
5889   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
5890   {
5891     return HAL_ERROR;
5892   }
5893 
5894   return HAL_OK;
5895 }
5896 
5897 /**
5898   * @brief  I2C Address complete process callback.
5899   * @param  hi2c I2C handle.
5900   * @param  ITFlags Interrupt flags to handle.
5901   * @retval None
5902   */
5903 static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5904 {
5905   uint8_t transferdirection;
5906   uint16_t slaveaddrcode;
5907   uint16_t ownadd1code;
5908   uint16_t ownadd2code;
5909 
5910   /* Prevent unused argument(s) compilation warning */
5911   UNUSED(ITFlags);
5912 
5913   /* In case of Listen state, need to inform upper layer of address match code event */
5914   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
5915   {
5916     transferdirection = I2C_GET_DIR(hi2c);
5917     slaveaddrcode     = I2C_GET_ADDR_MATCH(hi2c);
5918     ownadd1code       = I2C_GET_OWN_ADDRESS1(hi2c);
5919     ownadd2code       = I2C_GET_OWN_ADDRESS2(hi2c);
5920 
5921     /* If 10bits addressing mode is selected */
5922     if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
5923     {
5924       if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
5925       {
5926         slaveaddrcode = ownadd1code;
5927         hi2c->AddrEventCount++;
5928         if (hi2c->AddrEventCount == 2U)
5929         {
5930           /* Reset Address Event counter */
5931           hi2c->AddrEventCount = 0U;
5932 
5933           /* Clear ADDR flag */
5934           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
5935 
5936           /* Process Unlocked */
5937           __HAL_UNLOCK(hi2c);
5938 
5939           /* Call Slave Addr callback */
5940 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5941           hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5942 #else
5943           HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5944 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5945         }
5946       }
5947       else
5948       {
5949         slaveaddrcode = ownadd2code;
5950 
5951         /* Disable ADDR Interrupts */
5952         I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
5953 
5954         /* Process Unlocked */
5955         __HAL_UNLOCK(hi2c);
5956 
5957         /* Call Slave Addr callback */
5958 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5959         hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5960 #else
5961         HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5962 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5963       }
5964     }
5965     /* else 7 bits addressing mode is selected */
5966     else
5967     {
5968       /* Disable ADDR Interrupts */
5969       I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
5970 
5971       /* Process Unlocked */
5972       __HAL_UNLOCK(hi2c);
5973 
5974       /* Call Slave Addr callback */
5975 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5976       hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5977 #else
5978       HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5979 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5980     }
5981   }
5982   /* Else clear address flag only */
5983   else
5984   {
5985     /* Clear ADDR flag */
5986     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
5987 
5988     /* Process Unlocked */
5989     __HAL_UNLOCK(hi2c);
5990   }
5991 }
5992 
5993 /**
5994   * @brief  I2C Master sequential complete process.
5995   * @param  hi2c I2C handle.
5996   * @retval None
5997   */
5998 static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c)
5999 {
6000   /* Reset I2C handle mode */
6001   hi2c->Mode = HAL_I2C_MODE_NONE;
6002 
6003   /* No Generate Stop, to permit restart mode */
6004   /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */
6005   if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6006   {
6007     hi2c->State         = HAL_I2C_STATE_READY;
6008     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
6009     hi2c->XferISR       = NULL;
6010 
6011     /* Disable Interrupts */
6012     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6013 
6014     /* Process Unlocked */
6015     __HAL_UNLOCK(hi2c);
6016 
6017     /* Call the corresponding callback to inform upper layer of End of Transfer */
6018 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6019     hi2c->MasterTxCpltCallback(hi2c);
6020 #else
6021     HAL_I2C_MasterTxCpltCallback(hi2c);
6022 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6023   }
6024   /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
6025   else
6026   {
6027     hi2c->State         = HAL_I2C_STATE_READY;
6028     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
6029     hi2c->XferISR       = NULL;
6030 
6031     /* Disable Interrupts */
6032     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6033 
6034     /* Process Unlocked */
6035     __HAL_UNLOCK(hi2c);
6036 
6037     /* Call the corresponding callback to inform upper layer of End of Transfer */
6038 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6039     hi2c->MasterRxCpltCallback(hi2c);
6040 #else
6041     HAL_I2C_MasterRxCpltCallback(hi2c);
6042 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6043   }
6044 }
6045 
6046 /**
6047   * @brief  I2C Slave sequential complete process.
6048   * @param  hi2c I2C handle.
6049   * @retval None
6050   */
6051 static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c)
6052 {
6053   uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
6054 
6055   /* Reset I2C handle mode */
6056   hi2c->Mode = HAL_I2C_MODE_NONE;
6057 
6058   /* If a DMA is ongoing, Update handle size context */
6059   if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
6060   {
6061     /* Disable DMA Request */
6062     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6063   }
6064   else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
6065   {
6066     /* Disable DMA Request */
6067     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6068   }
6069   else
6070   {
6071     /* Do nothing */
6072   }
6073 
6074   if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
6075   {
6076     /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */
6077     hi2c->State         = HAL_I2C_STATE_LISTEN;
6078     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
6079 
6080     /* Disable Interrupts */
6081     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6082 
6083     /* Process Unlocked */
6084     __HAL_UNLOCK(hi2c);
6085 
6086     /* Call the corresponding callback to inform upper layer of End of Transfer */
6087 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6088     hi2c->SlaveTxCpltCallback(hi2c);
6089 #else
6090     HAL_I2C_SlaveTxCpltCallback(hi2c);
6091 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6092   }
6093 
6094   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
6095   {
6096     /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */
6097     hi2c->State         = HAL_I2C_STATE_LISTEN;
6098     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
6099 
6100     /* Disable Interrupts */
6101     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6102 
6103     /* Process Unlocked */
6104     __HAL_UNLOCK(hi2c);
6105 
6106     /* Call the corresponding callback to inform upper layer of End of Transfer */
6107 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6108     hi2c->SlaveRxCpltCallback(hi2c);
6109 #else
6110     HAL_I2C_SlaveRxCpltCallback(hi2c);
6111 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6112   }
6113   else
6114   {
6115     /* Nothing to do */
6116   }
6117 }
6118 
6119 /**
6120   * @brief  I2C Master complete process.
6121   * @param  hi2c I2C handle.
6122   * @param  ITFlags Interrupt flags to handle.
6123   * @retval None
6124   */
6125 static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6126 {
6127   uint32_t tmperror;
6128   uint32_t tmpITFlags = ITFlags;
6129   __IO uint32_t tmpreg;
6130 
6131   /* Clear STOP Flag */
6132   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6133 
6134   /* Disable Interrupts and Store Previous state */
6135   if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6136   {
6137     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6138     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
6139   }
6140   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6141   {
6142     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6143     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
6144   }
6145   else
6146   {
6147     /* Do nothing */
6148   }
6149 
6150   /* Clear Configuration Register 2 */
6151   I2C_RESET_CR2(hi2c);
6152 
6153   /* Reset handle parameters */
6154   hi2c->XferISR       = NULL;
6155   hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
6156 
6157   if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET)
6158   {
6159     /* Clear NACK Flag */
6160     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6161 
6162     /* Set acknowledge error code */
6163     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6164   }
6165 
6166   /* Fetch Last receive data if any */
6167   if ((hi2c->State == HAL_I2C_STATE_ABORT) && (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET))
6168   {
6169     /* Read data from RXDR */
6170     tmpreg = (uint8_t)hi2c->Instance->RXDR;
6171     UNUSED(tmpreg);
6172   }
6173 
6174   /* Flush TX register */
6175   I2C_Flush_TXDR(hi2c);
6176 
6177   /* Store current volatile hi2c->ErrorCode, misra rule */
6178   tmperror = hi2c->ErrorCode;
6179 
6180   /* Call the corresponding callback to inform upper layer of End of Transfer */
6181   if ((hi2c->State == HAL_I2C_STATE_ABORT) || (tmperror != HAL_I2C_ERROR_NONE))
6182   {
6183     /* Call the corresponding callback to inform upper layer of End of Transfer */
6184     I2C_ITError(hi2c, hi2c->ErrorCode);
6185   }
6186   /* hi2c->State == HAL_I2C_STATE_BUSY_TX */
6187   else if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6188   {
6189     hi2c->State = HAL_I2C_STATE_READY;
6190     hi2c->PreviousState = I2C_STATE_NONE;
6191 
6192     if (hi2c->Mode == HAL_I2C_MODE_MEM)
6193     {
6194       hi2c->Mode = HAL_I2C_MODE_NONE;
6195 
6196       /* Process Unlocked */
6197       __HAL_UNLOCK(hi2c);
6198 
6199       /* Call the corresponding callback to inform upper layer of End of Transfer */
6200 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6201       hi2c->MemTxCpltCallback(hi2c);
6202 #else
6203       HAL_I2C_MemTxCpltCallback(hi2c);
6204 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6205     }
6206     else
6207     {
6208       hi2c->Mode = HAL_I2C_MODE_NONE;
6209 
6210       /* Process Unlocked */
6211       __HAL_UNLOCK(hi2c);
6212 
6213       /* Call the corresponding callback to inform upper layer of End of Transfer */
6214 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6215       hi2c->MasterTxCpltCallback(hi2c);
6216 #else
6217       HAL_I2C_MasterTxCpltCallback(hi2c);
6218 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6219     }
6220   }
6221   /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
6222   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6223   {
6224     hi2c->State = HAL_I2C_STATE_READY;
6225     hi2c->PreviousState = I2C_STATE_NONE;
6226 
6227     if (hi2c->Mode == HAL_I2C_MODE_MEM)
6228     {
6229       hi2c->Mode = HAL_I2C_MODE_NONE;
6230 
6231       /* Process Unlocked */
6232       __HAL_UNLOCK(hi2c);
6233 
6234       /* Call the corresponding callback to inform upper layer of End of Transfer */
6235 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6236       hi2c->MemRxCpltCallback(hi2c);
6237 #else
6238       HAL_I2C_MemRxCpltCallback(hi2c);
6239 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6240     }
6241     else
6242     {
6243       hi2c->Mode = HAL_I2C_MODE_NONE;
6244 
6245       /* Process Unlocked */
6246       __HAL_UNLOCK(hi2c);
6247 
6248       /* Call the corresponding callback to inform upper layer of End of Transfer */
6249 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6250       hi2c->MasterRxCpltCallback(hi2c);
6251 #else
6252       HAL_I2C_MasterRxCpltCallback(hi2c);
6253 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6254     }
6255   }
6256   else
6257   {
6258     /* Nothing to do */
6259   }
6260 }
6261 
6262 /**
6263   * @brief  I2C Slave complete process.
6264   * @param  hi2c I2C handle.
6265   * @param  ITFlags Interrupt flags to handle.
6266   * @retval None
6267   */
6268 static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6269 {
6270   uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
6271   uint32_t tmpITFlags = ITFlags;
6272   uint32_t tmpoptions = hi2c->XferOptions;
6273   HAL_I2C_StateTypeDef tmpstate = hi2c->State;
6274 
6275   /* Clear STOP Flag */
6276   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6277 
6278   /* Disable Interrupts and Store Previous state */
6279   if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
6280   {
6281     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
6282     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
6283   }
6284   else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
6285   {
6286     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
6287     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
6288   }
6289   else if (tmpstate == HAL_I2C_STATE_LISTEN)
6290   {
6291     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT);
6292     hi2c->PreviousState = I2C_STATE_NONE;
6293   }
6294   else
6295   {
6296     /* Do nothing */
6297   }
6298 
6299   /* Disable Address Acknowledge */
6300   hi2c->Instance->CR2 |= I2C_CR2_NACK;
6301 
6302   /* Clear Configuration Register 2 */
6303   I2C_RESET_CR2(hi2c);
6304 
6305   /* Flush TX register */
6306   I2C_Flush_TXDR(hi2c);
6307 
6308   /* If a DMA is ongoing, Update handle size context */
6309   if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
6310   {
6311     /* Disable DMA Request */
6312     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6313 
6314     if (hi2c->hdmatx != NULL)
6315     {
6316       hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx);
6317     }
6318   }
6319   else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
6320   {
6321     /* Disable DMA Request */
6322     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6323 
6324     if (hi2c->hdmarx != NULL)
6325     {
6326       hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx);
6327     }
6328   }
6329   else
6330   {
6331     /* Do nothing */
6332   }
6333 
6334   /* Store Last receive data if any */
6335   if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET)
6336   {
6337     /* Remove RXNE flag on temporary variable as read done */
6338     tmpITFlags &= ~I2C_FLAG_RXNE;
6339 
6340     /* Read data from RXDR */
6341     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
6342 
6343     /* Increment Buffer pointer */
6344     hi2c->pBuffPtr++;
6345 
6346     if ((hi2c->XferSize > 0U))
6347     {
6348       hi2c->XferSize--;
6349       hi2c->XferCount--;
6350     }
6351   }
6352 
6353   /* All data are not transferred, so set error code accordingly */
6354   if (hi2c->XferCount != 0U)
6355   {
6356     /* Set ErrorCode corresponding to a Non-Acknowledge */
6357     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6358   }
6359 
6360   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
6361       (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_IT_NACKI) != RESET))
6362   {
6363     /* Check that I2C transfer finished */
6364     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
6365     /* Mean XferCount == 0*/
6366     /* So clear Flag NACKF only */
6367     if (hi2c->XferCount == 0U)
6368     {
6369       if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
6370         /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
6371            Warning[Pa134]: left and right operands are identical */
6372       {
6373         /* Call I2C Listen complete process */
6374         I2C_ITListenCplt(hi2c, tmpITFlags);
6375       }
6376       else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
6377       {
6378         /* Clear NACK Flag */
6379         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6380 
6381         /* Flush TX register */
6382         I2C_Flush_TXDR(hi2c);
6383 
6384         /* Last Byte is Transmitted */
6385         /* Call I2C Slave Sequential complete process */
6386         I2C_ITSlaveSeqCplt(hi2c);
6387       }
6388       else
6389       {
6390         /* Clear NACK Flag */
6391         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6392       }
6393     }
6394     else
6395     {
6396       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
6397       /* Clear NACK Flag */
6398       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6399 
6400       /* Set ErrorCode corresponding to a Non-Acknowledge */
6401       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6402 
6403       if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
6404       {
6405         /* Call the corresponding callback to inform upper layer of End of Transfer */
6406         I2C_ITError(hi2c, hi2c->ErrorCode);
6407       }
6408     }
6409   }
6410 
6411   hi2c->Mode = HAL_I2C_MODE_NONE;
6412   hi2c->XferISR = NULL;
6413 
6414   if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
6415   {
6416     /* Call the corresponding callback to inform upper layer of End of Transfer */
6417     I2C_ITError(hi2c, hi2c->ErrorCode);
6418 
6419     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6420     if (hi2c->State == HAL_I2C_STATE_LISTEN)
6421     {
6422       /* Call I2C Listen complete process */
6423       I2C_ITListenCplt(hi2c, tmpITFlags);
6424     }
6425   }
6426   else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
6427   {
6428     /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
6429     I2C_ITSlaveSeqCplt(hi2c);
6430 
6431     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
6432     hi2c->State = HAL_I2C_STATE_READY;
6433     hi2c->PreviousState = I2C_STATE_NONE;
6434 
6435     /* Process Unlocked */
6436     __HAL_UNLOCK(hi2c);
6437 
6438     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6439 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6440     hi2c->ListenCpltCallback(hi2c);
6441 #else
6442     HAL_I2C_ListenCpltCallback(hi2c);
6443 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6444   }
6445   /* Call the corresponding callback to inform upper layer of End of Transfer */
6446   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6447   {
6448     hi2c->State = HAL_I2C_STATE_READY;
6449     hi2c->PreviousState = I2C_STATE_NONE;
6450 
6451     /* Process Unlocked */
6452     __HAL_UNLOCK(hi2c);
6453 
6454     /* Call the corresponding callback to inform upper layer of End of Transfer */
6455 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6456     hi2c->SlaveRxCpltCallback(hi2c);
6457 #else
6458     HAL_I2C_SlaveRxCpltCallback(hi2c);
6459 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6460   }
6461   else
6462   {
6463     hi2c->State = HAL_I2C_STATE_READY;
6464     hi2c->PreviousState = I2C_STATE_NONE;
6465 
6466     /* Process Unlocked */
6467     __HAL_UNLOCK(hi2c);
6468 
6469     /* Call the corresponding callback to inform upper layer of End of Transfer */
6470 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6471     hi2c->SlaveTxCpltCallback(hi2c);
6472 #else
6473     HAL_I2C_SlaveTxCpltCallback(hi2c);
6474 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6475   }
6476 }
6477 
6478 /**
6479   * @brief  I2C Listen complete process.
6480   * @param  hi2c I2C handle.
6481   * @param  ITFlags Interrupt flags to handle.
6482   * @retval None
6483   */
6484 static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6485 {
6486   /* Reset handle parameters */
6487   hi2c->XferOptions = I2C_NO_OPTION_FRAME;
6488   hi2c->PreviousState = I2C_STATE_NONE;
6489   hi2c->State = HAL_I2C_STATE_READY;
6490   hi2c->Mode = HAL_I2C_MODE_NONE;
6491   hi2c->XferISR = NULL;
6492 
6493   /* Store Last receive data if any */
6494   if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_RXNE) != RESET)
6495   {
6496     /* Read data from RXDR */
6497     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
6498 
6499     /* Increment Buffer pointer */
6500     hi2c->pBuffPtr++;
6501 
6502     if ((hi2c->XferSize > 0U))
6503     {
6504       hi2c->XferSize--;
6505       hi2c->XferCount--;
6506 
6507       /* Set ErrorCode corresponding to a Non-Acknowledge */
6508       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6509     }
6510   }
6511 
6512   /* Disable all Interrupts*/
6513   I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6514 
6515   /* Clear NACK Flag */
6516   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6517 
6518   /* Process Unlocked */
6519   __HAL_UNLOCK(hi2c);
6520 
6521   /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6522 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6523   hi2c->ListenCpltCallback(hi2c);
6524 #else
6525   HAL_I2C_ListenCpltCallback(hi2c);
6526 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6527 }
6528 
6529 /**
6530   * @brief  I2C interrupts error process.
6531   * @param  hi2c I2C handle.
6532   * @param  ErrorCode Error code to handle.
6533   * @retval None
6534   */
6535 static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode)
6536 {
6537   HAL_I2C_StateTypeDef tmpstate = hi2c->State;
6538 
6539   uint32_t tmppreviousstate;
6540 
6541   /* Reset handle parameters */
6542   hi2c->Mode          = HAL_I2C_MODE_NONE;
6543   hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
6544   hi2c->XferCount     = 0U;
6545 
6546   /* Set new error code */
6547   hi2c->ErrorCode |= ErrorCode;
6548 
6549   /* Disable Interrupts */
6550   if ((tmpstate == HAL_I2C_STATE_LISTEN)         ||
6551       (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN) ||
6552       (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
6553   {
6554     /* Disable all interrupts, except interrupts related to LISTEN state */
6555     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6556 
6557     /* keep HAL_I2C_STATE_LISTEN if set */
6558     hi2c->State         = HAL_I2C_STATE_LISTEN;
6559     hi2c->XferISR       = I2C_Slave_ISR_IT;
6560   }
6561   else
6562   {
6563     /* Disable all interrupts */
6564     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6565 
6566     /* Flush TX register */
6567     I2C_Flush_TXDR(hi2c);
6568 
6569     /* If state is an abort treatment on going, don't change state */
6570     /* This change will be do later */
6571     if (hi2c->State != HAL_I2C_STATE_ABORT)
6572     {
6573       /* Set HAL_I2C_STATE_READY */
6574       hi2c->State         = HAL_I2C_STATE_READY;
6575 
6576       /* Check if a STOPF is detected */
6577       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
6578       {
6579         if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
6580         {
6581           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6582           hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6583         }
6584 
6585         /* Clear STOP Flag */
6586         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6587       }
6588 
6589     }
6590     hi2c->XferISR       = NULL;
6591   }
6592 
6593   /* Abort DMA TX transfer if any */
6594   tmppreviousstate = hi2c->PreviousState;
6595 
6596   if ((hi2c->hdmatx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_TX) || \
6597                                  (tmppreviousstate == I2C_STATE_SLAVE_BUSY_TX)))
6598   {
6599     if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
6600     {
6601       hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6602     }
6603 
6604     if (HAL_DMA_GetState(hi2c->hdmatx) != HAL_DMA_STATE_READY)
6605     {
6606       /* Set the I2C DMA Abort callback :
6607        will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6608       hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
6609 
6610       /* Process Unlocked */
6611       __HAL_UNLOCK(hi2c);
6612 
6613       /* Abort DMA TX */
6614       if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
6615       {
6616         /* Call Directly XferAbortCallback function in case of error */
6617         hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
6618       }
6619     }
6620     else
6621     {
6622       I2C_TreatErrorCallback(hi2c);
6623     }
6624   }
6625   /* Abort DMA RX transfer if any */
6626   else if ((hi2c->hdmarx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_RX) || \
6627                                       (tmppreviousstate == I2C_STATE_SLAVE_BUSY_RX)))
6628   {
6629     if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
6630     {
6631       hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6632     }
6633 
6634     if (HAL_DMA_GetState(hi2c->hdmarx) != HAL_DMA_STATE_READY)
6635     {
6636       /* Set the I2C DMA Abort callback :
6637         will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6638       hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
6639 
6640       /* Process Unlocked */
6641       __HAL_UNLOCK(hi2c);
6642 
6643       /* Abort DMA RX */
6644       if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
6645       {
6646         /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
6647         hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
6648       }
6649     }
6650     else
6651     {
6652       I2C_TreatErrorCallback(hi2c);
6653     }
6654   }
6655   else
6656   {
6657     I2C_TreatErrorCallback(hi2c);
6658   }
6659 }
6660 
6661 /**
6662   * @brief  I2C Error callback treatment.
6663   * @param  hi2c I2C handle.
6664   * @retval None
6665   */
6666 static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c)
6667 {
6668   if (hi2c->State == HAL_I2C_STATE_ABORT)
6669   {
6670     hi2c->State = HAL_I2C_STATE_READY;
6671     hi2c->PreviousState = I2C_STATE_NONE;
6672 
6673     /* Process Unlocked */
6674     __HAL_UNLOCK(hi2c);
6675 
6676     /* Call the corresponding callback to inform upper layer of End of Transfer */
6677 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6678     hi2c->AbortCpltCallback(hi2c);
6679 #else
6680     HAL_I2C_AbortCpltCallback(hi2c);
6681 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6682   }
6683   else
6684   {
6685     hi2c->PreviousState = I2C_STATE_NONE;
6686 
6687     /* Process Unlocked */
6688     __HAL_UNLOCK(hi2c);
6689 
6690     /* Call the corresponding callback to inform upper layer of End of Transfer */
6691 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6692     hi2c->ErrorCallback(hi2c);
6693 #else
6694     HAL_I2C_ErrorCallback(hi2c);
6695 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6696   }
6697 }
6698 
6699 /**
6700   * @brief  I2C Tx data register flush process.
6701   * @param  hi2c I2C handle.
6702   * @retval None
6703   */
6704 static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c)
6705 {
6706   /* If a pending TXIS flag is set */
6707   /* Write a dummy data in TXDR to clear it */
6708   if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET)
6709   {
6710     hi2c->Instance->TXDR = 0x00U;
6711   }
6712 
6713   /* Flush TX register if not empty */
6714   if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
6715   {
6716     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE);
6717   }
6718 }
6719 
6720 /**
6721   * @brief  DMA I2C master transmit process complete callback.
6722   * @param  hdma DMA handle
6723   * @retval None
6724   */
6725 static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
6726 {
6727   /* Derogation MISRAC2012-Rule-11.5 */
6728   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6729 
6730   /* Disable DMA Request */
6731   hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6732 
6733   /* If last transfer, enable STOP interrupt */
6734   if (hi2c->XferCount == 0U)
6735   {
6736     /* Enable STOP interrupt */
6737     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6738   }
6739   /* else prepare a new DMA transfer and enable TCReload interrupt */
6740   else
6741   {
6742     /* Update Buffer pointer */
6743     hi2c->pBuffPtr += hi2c->XferSize;
6744 
6745     /* Set the XferSize to transfer */
6746     if (hi2c->XferCount > MAX_NBYTE_SIZE)
6747     {
6748       hi2c->XferSize = MAX_NBYTE_SIZE;
6749     }
6750     else
6751     {
6752       hi2c->XferSize = hi2c->XferCount;
6753     }
6754 
6755     /* Enable the DMA stream or channel depends on Instance */
6756     if (HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR,
6757                          hi2c->XferSize) != HAL_OK)
6758     {
6759       /* Call the corresponding callback to inform upper layer of End of Transfer */
6760       I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6761     }
6762     else
6763     {
6764       /* Enable TC interrupts */
6765       I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6766     }
6767   }
6768 }
6769 
6770 
6771 /**
6772   * @brief  DMA I2C slave transmit process complete callback.
6773   * @param  hdma DMA handle
6774   * @retval None
6775   */
6776 static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
6777 {
6778   /* Derogation MISRAC2012-Rule-11.5 */
6779   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6780   uint32_t tmpoptions = hi2c->XferOptions;
6781 
6782   if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
6783   {
6784     /* Disable DMA Request */
6785     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6786 
6787     /* Last Byte is Transmitted */
6788     /* Call I2C Slave Sequential complete process */
6789     I2C_ITSlaveSeqCplt(hi2c);
6790   }
6791   else
6792   {
6793     /* No specific action, Master fully manage the generation of STOP condition */
6794     /* Mean that this generation can arrive at any time, at the end or during DMA process */
6795     /* So STOP condition should be manage through Interrupt treatment */
6796   }
6797 }
6798 
6799 
6800 /**
6801   * @brief DMA I2C master receive process complete callback.
6802   * @param  hdma DMA handle
6803   * @retval None
6804   */
6805 static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
6806 {
6807   /* Derogation MISRAC2012-Rule-11.5 */
6808   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6809 
6810   /* Disable DMA Request */
6811   hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6812 
6813   /* If last transfer, enable STOP interrupt */
6814   if (hi2c->XferCount == 0U)
6815   {
6816     /* Enable STOP interrupt */
6817     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6818   }
6819   /* else prepare a new DMA transfer and enable TCReload interrupt */
6820   else
6821   {
6822     /* Update Buffer pointer */
6823     hi2c->pBuffPtr += hi2c->XferSize;
6824 
6825     /* Set the XferSize to transfer */
6826     if (hi2c->XferCount > MAX_NBYTE_SIZE)
6827     {
6828       hi2c->XferSize = MAX_NBYTE_SIZE;
6829     }
6830     else
6831     {
6832       hi2c->XferSize = hi2c->XferCount;
6833     }
6834 
6835     /* Enable the DMA stream or channel depends on Instance */
6836     if (HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr,
6837                          hi2c->XferSize) != HAL_OK)
6838     {
6839       /* Call the corresponding callback to inform upper layer of End of Transfer */
6840       I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6841     }
6842     else
6843     {
6844       /* Enable TC interrupts */
6845       I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6846     }
6847   }
6848 }
6849 
6850 
6851 /**
6852   * @brief  DMA I2C slave receive process complete callback.
6853   * @param  hdma DMA handle
6854   * @retval None
6855   */
6856 static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
6857 {
6858   /* Derogation MISRAC2012-Rule-11.5 */
6859   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6860   uint32_t tmpoptions = hi2c->XferOptions;
6861 
6862   if ((I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U) && \
6863       (tmpoptions != I2C_NO_OPTION_FRAME))
6864   {
6865     /* Disable DMA Request */
6866     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6867 
6868     /* Call I2C Slave Sequential complete process */
6869     I2C_ITSlaveSeqCplt(hi2c);
6870   }
6871   else
6872   {
6873     /* No specific action, Master fully manage the generation of STOP condition */
6874     /* Mean that this generation can arrive at any time, at the end or during DMA process */
6875     /* So STOP condition should be manage through Interrupt treatment */
6876   }
6877 }
6878 
6879 
6880 /**
6881   * @brief  DMA I2C communication error callback.
6882   * @param hdma DMA handle
6883   * @retval None
6884   */
6885 static void I2C_DMAError(DMA_HandleTypeDef *hdma)
6886 {
6887   uint32_t treatdmaerror = 0U;
6888   /* Derogation MISRAC2012-Rule-11.5 */
6889   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6890 
6891   if (hi2c->hdmatx != NULL)
6892   {
6893     if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx) == 0U)
6894     {
6895       treatdmaerror = 1U;
6896     }
6897   }
6898 
6899   if (hi2c->hdmarx != NULL)
6900   {
6901     if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U)
6902     {
6903       treatdmaerror = 1U;
6904     }
6905   }
6906 
6907   /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */
6908   if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U))
6909   {
6910     /* Disable Acknowledge */
6911     hi2c->Instance->CR2 |= I2C_CR2_NACK;
6912 
6913     /* Call the corresponding callback to inform upper layer of End of Transfer */
6914     I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6915   }
6916 }
6917 
6918 
6919 /**
6920   * @brief DMA I2C communication abort callback
6921   *        (To be called at end of DMA Abort procedure).
6922   * @param hdma DMA handle.
6923   * @retval None
6924   */
6925 static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
6926 {
6927   /* Derogation MISRAC2012-Rule-11.5 */
6928   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6929 
6930   /* Reset AbortCpltCallback */
6931   if (hi2c->hdmatx != NULL)
6932   {
6933     hi2c->hdmatx->XferAbortCallback = NULL;
6934   }
6935   if (hi2c->hdmarx != NULL)
6936   {
6937     hi2c->hdmarx->XferAbortCallback = NULL;
6938   }
6939 
6940   I2C_TreatErrorCallback(hi2c);
6941 }
6942 
6943 
6944 /**
6945   * @brief  This function handles I2C Communication Timeout. It waits
6946   *                until a flag is no longer in the specified status.
6947   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6948   *                the configuration information for the specified I2C.
6949   * @param  Flag Specifies the I2C flag to check.
6950   * @param  Status The actual Flag status (SET or RESET).
6951   * @param  Timeout Timeout duration
6952   * @param  Tickstart Tick start value
6953   * @retval HAL status
6954   */
6955 static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
6956                                                     uint32_t Timeout, uint32_t Tickstart)
6957 {
6958   while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
6959   {
6960     /* Check if an error is detected */
6961     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
6962     {
6963       return HAL_ERROR;
6964     }
6965 
6966     /* Check for the Timeout */
6967     if (Timeout != HAL_MAX_DELAY)
6968     {
6969       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6970       {
6971         if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == Status))
6972         {
6973           hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
6974           hi2c->State = HAL_I2C_STATE_READY;
6975           hi2c->Mode = HAL_I2C_MODE_NONE;
6976 
6977           /* Process Unlocked */
6978           __HAL_UNLOCK(hi2c);
6979           return HAL_ERROR;
6980         }
6981       }
6982     }
6983   }
6984   return HAL_OK;
6985 }
6986 
6987 /**
6988   * @brief  This function handles I2C Communication Timeout for specific usage of TXIS flag.
6989   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
6990   *                the configuration information for the specified I2C.
6991   * @param  Timeout Timeout duration
6992   * @param  Tickstart Tick start value
6993   * @retval HAL status
6994   */
6995 static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
6996                                                         uint32_t Tickstart)
6997 {
6998   while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)
6999   {
7000     /* Check if an error is detected */
7001     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7002     {
7003       return HAL_ERROR;
7004     }
7005 
7006     /* Check for the Timeout */
7007     if (Timeout != HAL_MAX_DELAY)
7008     {
7009       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7010       {
7011         if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET))
7012         {
7013           hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7014           hi2c->State = HAL_I2C_STATE_READY;
7015           hi2c->Mode = HAL_I2C_MODE_NONE;
7016 
7017           /* Process Unlocked */
7018           __HAL_UNLOCK(hi2c);
7019 
7020           return HAL_ERROR;
7021         }
7022       }
7023     }
7024   }
7025   return HAL_OK;
7026 }
7027 
7028 /**
7029   * @brief  This function handles I2C Communication Timeout for specific usage of STOP flag.
7030   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7031   *                the configuration information for the specified I2C.
7032   * @param  Timeout Timeout duration
7033   * @param  Tickstart Tick start value
7034   * @retval HAL status
7035   */
7036 static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
7037                                                         uint32_t Tickstart)
7038 {
7039   while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
7040   {
7041     /* Check if an error is detected */
7042     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7043     {
7044       return HAL_ERROR;
7045     }
7046 
7047     /* Check for the Timeout */
7048     if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7049     {
7050       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET))
7051       {
7052         hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7053         hi2c->State = HAL_I2C_STATE_READY;
7054         hi2c->Mode = HAL_I2C_MODE_NONE;
7055 
7056         /* Process Unlocked */
7057         __HAL_UNLOCK(hi2c);
7058 
7059         return HAL_ERROR;
7060       }
7061     }
7062   }
7063   return HAL_OK;
7064 }
7065 
7066 /**
7067   * @brief  This function handles I2C Communication Timeout for specific usage of RXNE flag.
7068   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7069   *                the configuration information for the specified I2C.
7070   * @param  Timeout Timeout duration
7071   * @param  Tickstart Tick start value
7072   * @retval HAL status
7073   */
7074 static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
7075                                                         uint32_t Tickstart)
7076 {
7077   HAL_StatusTypeDef status = HAL_OK;
7078 
7079   while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) && (status == HAL_OK))
7080   {
7081     /* Check if an error is detected */
7082     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7083     {
7084       status = HAL_ERROR;
7085     }
7086 
7087     /* Check if a STOPF is detected */
7088     if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) && (status == HAL_OK))
7089     {
7090       /* Check if an RXNE is pending */
7091       /* Store Last receive data if any */
7092       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U))
7093       {
7094         /* Return HAL_OK */
7095         /* The Reading of data from RXDR will be done in caller function */
7096         status = HAL_OK;
7097       }
7098 
7099       /* Check a no-acknowledge have been detected */
7100       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
7101       {
7102         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
7103         hi2c->ErrorCode = HAL_I2C_ERROR_AF;
7104 
7105         /* Clear STOP Flag */
7106         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
7107 
7108         /* Clear Configuration Register 2 */
7109         I2C_RESET_CR2(hi2c);
7110 
7111         hi2c->State = HAL_I2C_STATE_READY;
7112         hi2c->Mode = HAL_I2C_MODE_NONE;
7113 
7114         /* Process Unlocked */
7115         __HAL_UNLOCK(hi2c);
7116 
7117         status = HAL_ERROR;
7118       }
7119       else
7120       {
7121         hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
7122       }
7123     }
7124 
7125     /* Check for the Timeout */
7126     if ((((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) && (status == HAL_OK))
7127     {
7128       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET))
7129       {
7130         hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7131         hi2c->State = HAL_I2C_STATE_READY;
7132 
7133         /* Process Unlocked */
7134         __HAL_UNLOCK(hi2c);
7135 
7136         status = HAL_ERROR;
7137       }
7138     }
7139   }
7140   return status;
7141 }
7142 
7143 /**
7144   * @brief  This function handles errors detection during an I2C Communication.
7145   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7146   *                the configuration information for the specified I2C.
7147   * @param  Timeout Timeout duration
7148   * @param  Tickstart Tick start value
7149   * @retval HAL status
7150   */
7151 static HAL_StatusTypeDef I2C_IsErrorOccurred(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
7152 {
7153   HAL_StatusTypeDef status = HAL_OK;
7154   uint32_t itflag   = hi2c->Instance->ISR;
7155   uint32_t error_code = 0;
7156   uint32_t tickstart = Tickstart;
7157   uint32_t tmp1;
7158   HAL_I2C_ModeTypeDef tmp2;
7159 
7160   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_AF))
7161   {
7162     /* Clear NACKF Flag */
7163     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
7164 
7165     /* Wait until STOP Flag is set or timeout occurred */
7166     /* AutoEnd should be initiate after AF */
7167     while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (status == HAL_OK))
7168     {
7169       /* Check for the Timeout */
7170       if (Timeout != HAL_MAX_DELAY)
7171       {
7172         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
7173         {
7174           tmp1 = (uint32_t)(hi2c->Instance->CR2 & I2C_CR2_STOP);
7175           tmp2 = hi2c->Mode;
7176 
7177           /* In case of I2C still busy, try to regenerate a STOP manually */
7178           if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && \
7179               (tmp1 != I2C_CR2_STOP) && \
7180               (tmp2 != HAL_I2C_MODE_SLAVE))
7181           {
7182             /* Generate Stop */
7183             hi2c->Instance->CR2 |= I2C_CR2_STOP;
7184 
7185             /* Update Tick with new reference */
7186             tickstart = HAL_GetTick();
7187           }
7188 
7189           while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
7190           {
7191             /* Check for the Timeout */
7192             if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_STOPF)
7193             {
7194               error_code |= HAL_I2C_ERROR_TIMEOUT;
7195 
7196               status = HAL_ERROR;
7197 
7198               break;
7199             }
7200           }
7201         }
7202       }
7203     }
7204 
7205     /* In case STOP Flag is detected, clear it */
7206     if (status == HAL_OK)
7207     {
7208       /* Clear STOP Flag */
7209       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
7210     }
7211 
7212     error_code |= HAL_I2C_ERROR_AF;
7213 
7214     status = HAL_ERROR;
7215   }
7216 
7217   /* Refresh Content of Status register */
7218   itflag = hi2c->Instance->ISR;
7219 
7220   /* Then verify if an additional errors occurs */
7221   /* Check if a Bus error occurred */
7222   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_BERR))
7223   {
7224     error_code |= HAL_I2C_ERROR_BERR;
7225 
7226     /* Clear BERR flag */
7227     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
7228 
7229     status = HAL_ERROR;
7230   }
7231 
7232   /* Check if an Over-Run/Under-Run error occurred */
7233   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_OVR))
7234   {
7235     error_code |= HAL_I2C_ERROR_OVR;
7236 
7237     /* Clear OVR flag */
7238     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
7239 
7240     status = HAL_ERROR;
7241   }
7242 
7243   /* Check if an Arbitration Loss error occurred */
7244   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_ARLO))
7245   {
7246     error_code |= HAL_I2C_ERROR_ARLO;
7247 
7248     /* Clear ARLO flag */
7249     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
7250 
7251     status = HAL_ERROR;
7252   }
7253 
7254   if (status != HAL_OK)
7255   {
7256     /* Flush TX register */
7257     I2C_Flush_TXDR(hi2c);
7258 
7259     /* Clear Configuration Register 2 */
7260     I2C_RESET_CR2(hi2c);
7261 
7262     hi2c->ErrorCode |= error_code;
7263     hi2c->State = HAL_I2C_STATE_READY;
7264     hi2c->Mode = HAL_I2C_MODE_NONE;
7265 
7266     /* Process Unlocked */
7267     __HAL_UNLOCK(hi2c);
7268   }
7269 
7270   return status;
7271 }
7272 
7273 /**
7274   * @brief  Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
7275   * @param  hi2c I2C handle.
7276   * @param  DevAddress Specifies the slave address to be programmed.
7277   * @param  Size Specifies the number of bytes to be programmed.
7278   *   This parameter must be a value between 0 and 255.
7279   * @param  Mode New state of the I2C START condition generation.
7280   *   This parameter can be one of the following values:
7281   *     @arg @ref I2C_RELOAD_MODE Enable Reload mode .
7282   *     @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode.
7283   *     @arg @ref I2C_SOFTEND_MODE Enable Software end mode.
7284   * @param  Request New state of the I2C START condition generation.
7285   *   This parameter can be one of the following values:
7286   *     @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition.
7287   *     @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
7288   *     @arg @ref I2C_GENERATE_START_READ Generate Restart for read request.
7289   *     @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request.
7290   * @retval None
7291   */
7292 static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
7293                                uint32_t Request)
7294 {
7295   /* Check the parameters */
7296   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
7297   assert_param(IS_TRANSFER_MODE(Mode));
7298   assert_param(IS_TRANSFER_REQUEST(Request));
7299 
7300   /* Declaration of tmp to prevent undefined behavior of volatile usage */
7301   uint32_t tmp = ((uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \
7302                              (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \
7303                              (uint32_t)Mode | (uint32_t)Request) & (~0x80000000U));
7304 
7305   /* update CR2 register */
7306   MODIFY_REG(hi2c->Instance->CR2, \
7307              ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
7308                (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | \
7309                I2C_CR2_START | I2C_CR2_STOP)), tmp);
7310 }
7311 
7312 /**
7313   * @brief  Manage the enabling of Interrupts.
7314   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7315   *                the configuration information for the specified I2C.
7316   * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
7317   * @retval None
7318   */
7319 static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
7320 {
7321   uint32_t tmpisr = 0U;
7322 
7323   if ((hi2c->XferISR != I2C_Master_ISR_DMA) && \
7324       (hi2c->XferISR != I2C_Slave_ISR_DMA) && \
7325       (hi2c->XferISR != I2C_Mem_ISR_DMA))
7326   {
7327     if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7328     {
7329       /* Enable ERR, STOP, NACK and ADDR interrupts */
7330       tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7331     }
7332 
7333     if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7334     {
7335       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7336       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
7337     }
7338 
7339     if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7340     {
7341       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7342       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
7343     }
7344 
7345     if (InterruptRequest == I2C_XFER_ERROR_IT)
7346     {
7347       /* Enable ERR and NACK interrupts */
7348       tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7349     }
7350 
7351     if (InterruptRequest == I2C_XFER_CPLT_IT)
7352     {
7353       /* Enable STOP interrupts */
7354       tmpisr |= I2C_IT_STOPI;
7355     }
7356   }
7357 
7358   else
7359   {
7360     if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7361     {
7362       /* Enable ERR, STOP, NACK and ADDR interrupts */
7363       tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7364     }
7365 
7366     if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7367     {
7368       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7369       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
7370     }
7371 
7372     if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7373     {
7374       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7375       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
7376     }
7377 
7378     if (InterruptRequest == I2C_XFER_ERROR_IT)
7379     {
7380       /* Enable ERR and NACK interrupts */
7381       tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7382     }
7383 
7384     if (InterruptRequest == I2C_XFER_CPLT_IT)
7385     {
7386       /* Enable STOP interrupts */
7387       tmpisr |= (I2C_IT_STOPI | I2C_IT_TCI);
7388     }
7389 
7390     if (InterruptRequest == I2C_XFER_RELOAD_IT)
7391     {
7392       /* Enable TC interrupts */
7393       tmpisr |= I2C_IT_TCI;
7394     }
7395   }
7396 
7397   /* Enable interrupts only at the end */
7398   /* to avoid the risk of I2C interrupt handle execution before */
7399   /* all interrupts requested done */
7400   __HAL_I2C_ENABLE_IT(hi2c, tmpisr);
7401 }
7402 
7403 /**
7404   * @brief  Manage the disabling of Interrupts.
7405   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7406   *                the configuration information for the specified I2C.
7407   * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
7408   * @retval None
7409   */
7410 static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
7411 {
7412   uint32_t tmpisr = 0U;
7413 
7414   if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7415   {
7416     /* Disable TC and TXI interrupts */
7417     tmpisr |= I2C_IT_TCI | I2C_IT_TXI;
7418 
7419     if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
7420     {
7421       /* Disable NACK and STOP interrupts */
7422       tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7423     }
7424   }
7425 
7426   if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7427   {
7428     /* Disable TC and RXI interrupts */
7429     tmpisr |= I2C_IT_TCI | I2C_IT_RXI;
7430 
7431     if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
7432     {
7433       /* Disable NACK and STOP interrupts */
7434       tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7435     }
7436   }
7437 
7438   if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7439   {
7440     /* Disable ADDR, NACK and STOP interrupts */
7441     tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7442   }
7443 
7444   if (InterruptRequest == I2C_XFER_ERROR_IT)
7445   {
7446     /* Enable ERR and NACK interrupts */
7447     tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7448   }
7449 
7450   if (InterruptRequest == I2C_XFER_CPLT_IT)
7451   {
7452     /* Enable STOP interrupts */
7453     tmpisr |= I2C_IT_STOPI;
7454   }
7455 
7456   if (InterruptRequest == I2C_XFER_RELOAD_IT)
7457   {
7458     /* Enable TC interrupts */
7459     tmpisr |= I2C_IT_TCI;
7460   }
7461 
7462   /* Disable interrupts only at the end */
7463   /* to avoid a breaking situation like at "t" time */
7464   /* all disable interrupts request are not done */
7465   __HAL_I2C_DISABLE_IT(hi2c, tmpisr);
7466 }
7467 
7468 /**
7469   * @brief  Convert I2Cx OTHER_xxx XferOptions to functional XferOptions.
7470   * @param  hi2c I2C handle.
7471   * @retval None
7472   */
7473 static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c)
7474 {
7475   /* if user set XferOptions to I2C_OTHER_FRAME            */
7476   /* it request implicitly to generate a restart condition */
7477   /* set XferOptions to I2C_FIRST_FRAME                    */
7478   if (hi2c->XferOptions == I2C_OTHER_FRAME)
7479   {
7480     hi2c->XferOptions = I2C_FIRST_FRAME;
7481   }
7482   /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */
7483   /* it request implicitly to generate a restart condition    */
7484   /* then generate a stop condition at the end of transfer    */
7485   /* set XferOptions to I2C_FIRST_AND_LAST_FRAME              */
7486   else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME)
7487   {
7488     hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME;
7489   }
7490   else
7491   {
7492     /* Nothing to do */
7493   }
7494 }
7495 
7496 /**
7497   * @}
7498   */
7499 
7500 #endif /* HAL_I2C_MODULE_ENABLED */
7501 /**
7502   * @}
7503   */
7504 
7505 /**
7506   * @}
7507   */