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