STM32F479xx HAL User Manual
stm32f4xx_hal_smbus.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_smbus.c
00004   * @author  MCD Application Team
00005   * @brief   SMBUS HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the System Management Bus (SMBus) peripheral,
00008   *          based on SMBUS principals of operation :
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State, Mode and Error functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017   [..]
00018     The SMBUS HAL driver can be used as follows:
00019 
00020     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
00021         SMBUS_HandleTypeDef  hsmbus;
00022 
00023     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
00024         (##) Enable the SMBUSx interface clock
00025         (##) SMBUS pins configuration
00026             (+++) Enable the clock for the SMBUS GPIOs
00027             (+++) Configure SMBUS pins as alternate function open-drain
00028         (##) NVIC configuration if you need to use interrupt process
00029             (+++) Configure the SMBUSx interrupt priority
00030             (+++) Enable the NVIC SMBUS IRQ Channel
00031 
00032     (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
00033         Dual Addressing mode, Own Address2, General call and Nostretch mode in the hsmbus Init structure.
00034 
00035     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init(), configures also the low level Hardware
00036         (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
00037 
00038     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
00039 
00040     (#) For SMBUS IO operations, only one mode of operations is available within this driver :
00041 
00042 
00043     *** Interrupt mode IO operation ***
00044     ===================================
00045 
00046   [..]
00047       (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Transmit_IT()
00048       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
00049            add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
00050       (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Receive_IT()
00051       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
00052            add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
00053       (+) Abort a master/Host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
00054       (++) End of abort process, HAL_SMBUS_AbortCpltCallback() is executed and user can
00055            add his own code by customization of function pointer HAL_SMBUS_AbortCpltCallback()
00056       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
00057            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
00058       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
00059            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
00060       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
00061            add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
00062       (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Transmit_IT()
00063       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
00064            add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
00065       (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Receive_IT()
00066       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
00067            add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
00068       (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() and HAL_SMBUS_DisableAlert_IT()
00069       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
00070            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00071            to check the Alert Error Code using function HAL_SMBUS_GetError()
00072       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
00073       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
00074            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00075            to check the Error Code using function HAL_SMBUS_GetError()
00076 
00077 
00078      *** SMBUS HAL driver macros list ***
00079      ==================================
00080      [..]
00081        Below the list of most used macros in SMBUS HAL driver.
00082 
00083       (+) __HAL_SMBUS_ENABLE    : Enable the SMBUS peripheral
00084       (+) __HAL_SMBUS_DISABLE   : Disable the SMBUS peripheral
00085       (+) __HAL_SMBUS_GET_FLAG  : Checks whether the specified SMBUS flag is set or not
00086       (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag
00087       (+) __HAL_SMBUS_ENABLE_IT : Enable the specified SMBUS interrupt
00088       (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt
00089 
00090      [..]
00091        (@) You can refer to the SMBUS HAL driver header file for more useful macros
00092 
00093      *** Callback registration ***
00094      =============================================
00095     [..]
00096      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
00097      allows the user to configure dynamically the driver callbacks.
00098      Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterXXXCallback()
00099      to register an interrupt callback.
00100 
00101      Function HAL_SMBUS_RegisterCallback() allows to register following callbacks:
00102        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00103        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00104        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00105        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00106        (+) ListenCpltCallback   : callback for end of listen mode.
00107        (+) ErrorCallback        : callback for error detection.
00108        (+) AbortCpltCallback    : callback for abort completion process.
00109        (+) MspInitCallback      : callback for Msp Init.
00110        (+) MspDeInitCallback    : callback for Msp DeInit.
00111      This function takes as parameters the HAL peripheral handle, the Callback ID
00112      and a pointer to the user callback function.
00113     [..]
00114      For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback().
00115     [..]
00116      Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default
00117      weak function.
00118      HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
00119      and the Callback ID.
00120      This function allows to reset following callbacks:
00121        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00122        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00123        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00124        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00125        (+) ListenCpltCallback   : callback for end of listen mode.
00126        (+) ErrorCallback        : callback for error detection.
00127        (+) AbortCpltCallback    : callback for abort completion process.
00128        (+) MspInitCallback      : callback for Msp Init.
00129        (+) MspDeInitCallback    : callback for Msp DeInit.
00130     [..]
00131      For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback().
00132     [..]
00133      By default, after the HAL_SMBUS_Init() and when the state is HAL_SMBUS_STATE_RESET
00134      all callbacks are set to the corresponding weak functions:
00135      examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback().
00136      Exception done for MspInit and MspDeInit functions that are
00137      reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when
00138      these callbacks are null (not registered beforehand).
00139      If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit()
00140      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00141     [..]
00142      Callbacks can be registered/unregistered in HAL_SMBUS_STATE_READY state only.
00143      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00144      in HAL_SMBUS_STATE_READY or HAL_SMBUS_STATE_RESET state,
00145      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00146      Then, the user first registers the MspInit/MspDeInit user callbacks
00147      using HAL_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit()
00148      or HAL_SMBUS_Init() function.
00149     [..]
00150      When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
00151      not defined, the callback registration feature is not available and all callbacks
00152      are set to the corresponding weak functions.
00153 
00154   @endverbatim
00155   ******************************************************************************
00156   * @attention
00157   *
00158   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00159   * All rights reserved.</center></h2>
00160   *
00161   * This software component is licensed by ST under BSD 3-Clause license,
00162   * the "License"; You may not use this file except in compliance with the
00163   * License. You may obtain a copy of the License at:
00164   *                        opensource.org/licenses/BSD-3-Clause
00165   *
00166   ******************************************************************************
00167   */
00168 
00169 /* Includes ------------------------------------------------------------------*/
00170 #include "stm32f4xx_hal.h"
00171 
00172 /** @addtogroup STM32F4xx_HAL_Driver
00173   * @{
00174   */
00175 
00176 /** @defgroup SMBUS SMBUS
00177   * @brief SMBUS HAL module driver
00178   * @{
00179   */
00180 
00181 #ifdef HAL_SMBUS_MODULE_ENABLED
00182 
00183 /* Private typedef -----------------------------------------------------------*/
00184 /* Private define ------------------------------------------------------------*/
00185 /** @addtogroup SMBUS_Private_Define
00186   * @{
00187   */
00188 #define SMBUS_TIMEOUT_FLAG          35U         /*!< Timeout 35 ms             */
00189 #define SMBUS_TIMEOUT_BUSY_FLAG     25U         /*!< Timeout 25 ms             */
00190 #define SMBUS_NO_OPTION_FRAME       0xFFFF0000U /*!< XferOptions default value */
00191 
00192 #define SMBUS_SENDPEC_MODE          I2C_CR1_PEC
00193 #define SMBUS_GET_PEC(__HANDLE__)             (((__HANDLE__)->Instance->SR2 & I2C_SR2_PEC) >> 8)
00194 
00195 /* Private define for @ref PreviousState usage */
00196 #define SMBUS_STATE_MSK             ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX | HAL_SMBUS_STATE_BUSY_RX) & (~(uint32_t)HAL_SMBUS_STATE_READY))) /*!< Mask State define, keep only RX and TX bits            */
00197 #define SMBUS_STATE_NONE            ((uint32_t)(HAL_SMBUS_MODE_NONE))                                                                      /*!< Default Value                                          */
00198 #define SMBUS_STATE_MASTER_BUSY_TX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy TX, combinaison of State LSB and Mode enum */
00199 #define SMBUS_STATE_MASTER_BUSY_RX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy RX, combinaison of State LSB and Mode enum */
00200 #define SMBUS_STATE_SLAVE_BUSY_TX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy TX, combinaison of State LSB and Mode enum  */
00201 #define SMBUS_STATE_SLAVE_BUSY_RX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
00202 
00203 /**
00204   * @}
00205   */
00206 
00207 /* Private macro -------------------------------------------------------------*/
00208 /* Private variables ---------------------------------------------------------*/
00209 /* Private function prototypes -----------------------------------------------*/
00210 
00211 /** @addtogroup SMBUS_Private_Functions
00212   * @{
00213   */
00214 
00215 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
00216 static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus);
00217 
00218 /* Private functions for SMBUS transfer IRQ handler */
00219 static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
00220 static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
00221 static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
00222 static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
00223 static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus);
00224 static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus);
00225 static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus);
00226 
00227 static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
00228 static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
00229 static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
00230 static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
00231 static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus);
00232 static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus);
00233 static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus);
00234 /**
00235   * @}
00236   */
00237 
00238 /* Exported functions --------------------------------------------------------*/
00239 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
00240   * @{
00241   */
00242 
00243 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
00244  *  @brief    Initialization and Configuration functions
00245  *
00246 @verbatim
00247  ===============================================================================
00248               ##### Initialization and de-initialization functions #####
00249  ===============================================================================
00250     [..]  This subsection provides a set of functions allowing to initialize and
00251           deinitialize the SMBUSx peripheral:
00252 
00253       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
00254           all related peripherals resources (CLOCK, GPIO, IT and NVIC).
00255 
00256       (+) Call the function HAL_SMBUS_Init() to configure the selected device with
00257           the selected configuration:
00258         (++) Communication Speed
00259         (++) Addressing mode
00260         (++) Own Address 1
00261         (++) Dual Addressing mode
00262         (++) Own Address 2
00263         (++) General call mode
00264         (++) Nostretch mode
00265         (++) Packet Error Check mode
00266         (++) Peripheral mode
00267 
00268       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
00269           of the selected SMBUSx peripheral.
00270 
00271 @endverbatim
00272   * @{
00273   */
00274 
00275 /**
00276   * @brief  Initializes the SMBUS according to the specified parameters
00277   *         in the SMBUS_InitTypeDef and initialize the associated handle.
00278   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00279   *         the configuration information for the specified SMBUS
00280   * @retval HAL status
00281   */
00282 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
00283 {
00284   uint32_t freqrange = 0U;
00285   uint32_t pclk1 = 0U;
00286 
00287   /* Check the SMBUS handle allocation */
00288   if (hsmbus == NULL)
00289   {
00290     return HAL_ERROR;
00291   }
00292 
00293   /* Check the parameters */
00294   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00295 #if  defined(I2C_FLTR_ANOFF)
00296   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
00297 #endif
00298   assert_param(IS_SMBUS_CLOCK_SPEED(hsmbus->Init.ClockSpeed));
00299   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
00300   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
00301   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
00302   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
00303   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
00304   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
00305   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
00306   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
00307 
00308   if (hsmbus->State == HAL_SMBUS_STATE_RESET)
00309   {
00310     /* Allocate lock resource and initialize it */
00311     hsmbus->Lock = HAL_UNLOCKED;
00312     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00313 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00314     /* Init the SMBUS Callback settings */
00315     hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00316     hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00317     hsmbus->SlaveTxCpltCallback  = HAL_SMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
00318     hsmbus->SlaveRxCpltCallback  = HAL_SMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
00319     hsmbus->ListenCpltCallback   = HAL_SMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
00320     hsmbus->ErrorCallback        = HAL_SMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
00321     hsmbus->AbortCpltCallback    = HAL_SMBUS_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
00322     hsmbus->AddrCallback         = HAL_SMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
00323 
00324     if (hsmbus->MspInitCallback == NULL)
00325     {
00326       hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit  */
00327     }
00328 
00329     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00330     hsmbus->MspInitCallback(hsmbus);
00331 #else
00332     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00333     HAL_SMBUS_MspInit(hsmbus);
00334 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00335   }
00336 
00337   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00338 
00339   /* Disable the selected SMBUS peripheral */
00340   __HAL_SMBUS_DISABLE(hsmbus);
00341 
00342   /* Get PCLK1 frequency */
00343   pclk1 = HAL_RCC_GetPCLK1Freq();
00344 
00345   /* Calculate frequency range */
00346   freqrange = SMBUS_FREQRANGE(pclk1);
00347 
00348   /*---------------------------- SMBUSx CR2 Configuration ----------------------*/
00349   /* Configure SMBUSx: Frequency range */
00350   MODIFY_REG(hsmbus->Instance->CR2, I2C_CR2_FREQ, freqrange);
00351 
00352   /*---------------------------- SMBUSx TRISE Configuration --------------------*/
00353   /* Configure SMBUSx: Rise Time */
00354   MODIFY_REG(hsmbus->Instance->TRISE, I2C_TRISE_TRISE, SMBUS_RISE_TIME(freqrange));
00355 
00356   /*---------------------------- SMBUSx CCR Configuration ----------------------*/
00357   /* Configure SMBUSx: Speed */
00358   MODIFY_REG(hsmbus->Instance->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), SMBUS_SPEED_STANDARD(pclk1, hsmbus->Init.ClockSpeed));
00359 
00360   /*---------------------------- SMBUSx CR1 Configuration ----------------------*/
00361   /* Configure SMBUSx: Generalcall , PEC , Peripheral mode and  NoStretch mode */
00362   MODIFY_REG(hsmbus->Instance->CR1, (I2C_CR1_NOSTRETCH | I2C_CR1_ENGC | I2C_CR1_ENPEC | I2C_CR1_ENARP | I2C_CR1_SMBTYPE | I2C_CR1_SMBUS), (hsmbus->Init.NoStretchMode | hsmbus->Init.GeneralCallMode |  hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode));
00363 
00364   /*---------------------------- SMBUSx OAR1 Configuration ---------------------*/
00365   /* Configure SMBUSx: Own Address1 and addressing mode */
00366   MODIFY_REG(hsmbus->Instance->OAR1, (I2C_OAR1_ADDMODE | I2C_OAR1_ADD8_9 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD0), (hsmbus->Init.AddressingMode | hsmbus->Init.OwnAddress1));
00367 
00368   /*---------------------------- SMBUSx OAR2 Configuration ---------------------*/
00369   /* Configure SMBUSx: Dual mode and Own Address2 */
00370   MODIFY_REG(hsmbus->Instance->OAR2, (I2C_OAR2_ENDUAL | I2C_OAR2_ADD2), (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2));
00371 #if  defined(I2C_FLTR_ANOFF)
00372   /*---------------------------- SMBUSx FLTR Configuration ------------------------*/
00373   /* Configure SMBUSx: Analog noise filter */
00374   SET_BIT(hsmbus->Instance->FLTR, hsmbus->Init.AnalogFilter);
00375 #endif
00376 
00377   /* Enable the selected SMBUS peripheral */
00378   __HAL_SMBUS_ENABLE(hsmbus);
00379 
00380   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00381   hsmbus->State = HAL_SMBUS_STATE_READY;
00382   hsmbus->PreviousState = SMBUS_STATE_NONE;
00383   hsmbus->Mode = HAL_SMBUS_MODE_NONE;
00384   hsmbus->XferPEC = 0x00;
00385 
00386   return HAL_OK;
00387 }
00388 
00389 /**
00390   * @brief  DeInitializes the SMBUS peripheral.
00391   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00392   *         the configuration information for the specified SMBUS.
00393   * @retval HAL status
00394   */
00395 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
00396 {
00397   /* Check the SMBUS handle allocation */
00398   if (hsmbus == NULL)
00399   {
00400     return HAL_ERROR;
00401   }
00402 
00403   /* Check the parameters */
00404   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00405 
00406   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00407 
00408   /* Disable the SMBUS Peripheral Clock */
00409   __HAL_SMBUS_DISABLE(hsmbus);
00410 
00411 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00412   if (hsmbus->MspDeInitCallback == NULL)
00413   {
00414     hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit  */
00415   }
00416 
00417   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00418   hsmbus->MspDeInitCallback(hsmbus);
00419 #else
00420   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00421   HAL_SMBUS_MspDeInit(hsmbus);
00422 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00423 
00424   hsmbus->ErrorCode     = HAL_SMBUS_ERROR_NONE;
00425   hsmbus->State         = HAL_SMBUS_STATE_RESET;
00426   hsmbus->PreviousState = SMBUS_STATE_NONE;
00427   hsmbus->Mode          = HAL_SMBUS_MODE_NONE;
00428 
00429   /* Release Lock */
00430   __HAL_UNLOCK(hsmbus);
00431 
00432   return HAL_OK;
00433 }
00434 
00435 /**
00436   * @brief  Initialize the SMBUS MSP.
00437   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00438   *         the configuration information for the specified SMBUS
00439   * @retval None
00440   */
00441 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
00442 {
00443   /* Prevent unused argument(s) compilation warning */
00444   UNUSED(hsmbus);
00445   /* NOTE : This function Should not be modified, when the callback is needed,
00446             the HAL_SMBUS_MspInit could be implemented in the user file
00447    */
00448 }
00449 
00450 /**
00451   * @brief  DeInitialize the SMBUS MSP.
00452   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00453   *         the configuration information for the specified SMBUS
00454   * @retval None
00455   */
00456 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
00457 {
00458   /* Prevent unused argument(s) compilation warning */
00459   UNUSED(hsmbus);
00460   /* NOTE : This function Should not be modified, when the callback is needed,
00461             the HAL_SMBUS_MspDeInit could be implemented in the user file
00462    */
00463 }
00464 
00465 #if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
00466 /**
00467   * @brief  Configures SMBUS Analog noise filter.
00468   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00469   *                the configuration information for the specified SMBUSx peripheral.
00470   * @param  AnalogFilter new state of the Analog filter.
00471   * @retval HAL status
00472   */
00473 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
00474 {
00475   /* Check the parameters */
00476   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00477   assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
00478 
00479   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00480   {
00481     hsmbus->State = HAL_SMBUS_STATE_BUSY;
00482 
00483     /* Disable the selected SMBUS peripheral */
00484     __HAL_SMBUS_DISABLE(hsmbus);
00485 
00486     /* Reset SMBUSx ANOFF bit */
00487     hsmbus->Instance->FLTR &= ~(I2C_FLTR_ANOFF);
00488 
00489     /* Disable the analog filter */
00490     hsmbus->Instance->FLTR |= AnalogFilter;
00491 
00492     __HAL_SMBUS_ENABLE(hsmbus);
00493 
00494     hsmbus->State = HAL_SMBUS_STATE_READY;
00495 
00496     return HAL_OK;
00497   }
00498   else
00499   {
00500     return HAL_BUSY;
00501   }
00502 }
00503 
00504 /**
00505   * @brief  Configures SMBUS Digital noise filter.
00506   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
00507   *                the configuration information for the specified SMBUSx peripheral.
00508   * @param  DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F.
00509   * @retval HAL status
00510   */
00511 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
00512 {
00513   uint16_t tmpreg = 0;
00514 
00515   /* Check the parameters */
00516   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00517   assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
00518 
00519   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00520   {
00521     hsmbus->State = HAL_SMBUS_STATE_BUSY;
00522 
00523     /* Disable the selected SMBUS peripheral */
00524     __HAL_SMBUS_DISABLE(hsmbus);
00525 
00526     /* Get the old register value */
00527     tmpreg = hsmbus->Instance->FLTR;
00528 
00529     /* Reset SMBUSx DNF bit [3:0] */
00530     tmpreg &= ~(I2C_FLTR_DNF);
00531 
00532     /* Set SMBUSx DNF coefficient */
00533     tmpreg |= DigitalFilter;
00534 
00535     /* Store the new register value */
00536     hsmbus->Instance->FLTR = tmpreg;
00537 
00538     __HAL_SMBUS_ENABLE(hsmbus);
00539 
00540     hsmbus->State = HAL_SMBUS_STATE_READY;
00541 
00542     return HAL_OK;
00543   }
00544   else
00545   {
00546     return HAL_BUSY;
00547   }
00548 }
00549 #endif
00550 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00551 /**
00552   * @brief  Register a User SMBUS Callback
00553   *         To be used instead of the weak predefined callback
00554   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00555   *                the configuration information for the specified SMBUS.
00556   * @param  CallbackID ID of the callback to be registered
00557   *         This parameter can be one of the following values:
00558   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00559   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00560   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00561   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00562   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00563   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
00564   *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
00565   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
00566   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00567   * @param  pCallback pointer to the Callback function
00568   * @retval HAL status
00569   */
00570 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback)
00571 {
00572   HAL_StatusTypeDef status = HAL_OK;
00573 
00574   if (pCallback == NULL)
00575   {
00576     /* Update the error code */
00577     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00578 
00579     return HAL_ERROR;
00580   }
00581   /* Process locked */
00582   __HAL_LOCK(hsmbus);
00583 
00584   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00585   {
00586     switch (CallbackID)
00587     {
00588       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
00589         hsmbus->MasterTxCpltCallback = pCallback;
00590         break;
00591 
00592       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
00593         hsmbus->MasterRxCpltCallback = pCallback;
00594         break;
00595 
00596       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
00597         hsmbus->SlaveTxCpltCallback = pCallback;
00598         break;
00599 
00600       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
00601         hsmbus->SlaveRxCpltCallback = pCallback;
00602         break;
00603 
00604       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
00605         hsmbus->ListenCpltCallback = pCallback;
00606         break;
00607 
00608       case HAL_SMBUS_ERROR_CB_ID :
00609         hsmbus->ErrorCallback = pCallback;
00610         break;
00611 
00612       case HAL_SMBUS_ABORT_CB_ID :
00613         hsmbus->AbortCpltCallback = pCallback;
00614         break;
00615 
00616       case HAL_SMBUS_MSPINIT_CB_ID :
00617         hsmbus->MspInitCallback = pCallback;
00618         break;
00619 
00620       case HAL_SMBUS_MSPDEINIT_CB_ID :
00621         hsmbus->MspDeInitCallback = pCallback;
00622         break;
00623 
00624       default :
00625         /* Update the error code */
00626         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00627 
00628         /* Return error status */
00629         status =  HAL_ERROR;
00630         break;
00631     }
00632   }
00633   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
00634   {
00635     switch (CallbackID)
00636     {
00637       case HAL_SMBUS_MSPINIT_CB_ID :
00638         hsmbus->MspInitCallback = pCallback;
00639         break;
00640 
00641       case HAL_SMBUS_MSPDEINIT_CB_ID :
00642         hsmbus->MspDeInitCallback = pCallback;
00643         break;
00644 
00645       default :
00646         /* Update the error code */
00647         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00648 
00649         /* Return error status */
00650         status =  HAL_ERROR;
00651         break;
00652     }
00653   }
00654   else
00655   {
00656     /* Update the error code */
00657     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00658 
00659     /* Return error status */
00660     status =  HAL_ERROR;
00661   }
00662 
00663   /* Release Lock */
00664   __HAL_UNLOCK(hsmbus);
00665   return status;
00666 }
00667 
00668 /**
00669   * @brief  Unregister an SMBUS Callback
00670   *         SMBUS callback is redirected to the weak predefined callback
00671   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00672   *                the configuration information for the specified SMBUS.
00673   * @param  CallbackID ID of the callback to be unregistered
00674   *         This parameter can be one of the following values:
00675   *         This parameter can be one of the following values:
00676   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00677   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00678   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00679   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00680   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00681   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
00682   *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
00683   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
00684   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00685   * @retval HAL status
00686   */
00687 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID)
00688 {
00689   HAL_StatusTypeDef status = HAL_OK;
00690 
00691   /* Process locked */
00692   __HAL_LOCK(hsmbus);
00693 
00694   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00695   {
00696     switch (CallbackID)
00697     {
00698       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
00699         hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00700         break;
00701 
00702       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
00703         hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00704         break;
00705 
00706       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
00707         hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
00708         break;
00709 
00710       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
00711         hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
00712         break;
00713 
00714       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
00715         hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
00716         break;
00717 
00718       case HAL_SMBUS_ERROR_CB_ID :
00719         hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
00720         break;
00721 
00722       case HAL_SMBUS_ABORT_CB_ID :
00723         hsmbus->AbortCpltCallback = HAL_SMBUS_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
00724         break;
00725 
00726       case HAL_SMBUS_MSPINIT_CB_ID :
00727         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
00728         break;
00729 
00730       case HAL_SMBUS_MSPDEINIT_CB_ID :
00731         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00732         break;
00733 
00734       default :
00735         /* Update the error code */
00736         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00737 
00738         /* Return error status */
00739         status =  HAL_ERROR;
00740         break;
00741     }
00742   }
00743   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
00744   {
00745     switch (CallbackID)
00746     {
00747       case HAL_SMBUS_MSPINIT_CB_ID :
00748         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
00749         break;
00750 
00751       case HAL_SMBUS_MSPDEINIT_CB_ID :
00752         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00753         break;
00754 
00755       default :
00756         /* Update the error code */
00757         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00758 
00759         /* Return error status */
00760         status =  HAL_ERROR;
00761         break;
00762     }
00763   }
00764   else
00765   {
00766     /* Update the error code */
00767     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00768 
00769     /* Return error status */
00770     status =  HAL_ERROR;
00771   }
00772 
00773   /* Release Lock */
00774   __HAL_UNLOCK(hsmbus);
00775   return status;
00776 }
00777 
00778 /**
00779   * @brief  Register the Slave Address Match SMBUS Callback
00780   *         To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
00781   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00782   *                the configuration information for the specified SMBUS.
00783   * @param  pCallback pointer to the Address Match Callback function
00784   * @retval HAL status
00785   */
00786 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback)
00787 {
00788   HAL_StatusTypeDef status = HAL_OK;
00789 
00790   if (pCallback == NULL)
00791   {
00792     return HAL_ERROR;
00793   }
00794   /* Process locked */
00795   __HAL_LOCK(hsmbus);
00796 
00797   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00798   {
00799     hsmbus->AddrCallback = pCallback;
00800   }
00801   else
00802   {
00803     /* Update the error code */
00804     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00805 
00806     /* Return error status */
00807     status =  HAL_ERROR;
00808   }
00809 
00810   /* Release Lock */
00811   __HAL_UNLOCK(hsmbus);
00812   return status;
00813 }
00814 
00815 /**
00816   * @brief  UnRegister the Slave Address Match SMBUS Callback
00817   *         Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
00818   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00819   *                the configuration information for the specified SMBUS.
00820   * @retval HAL status
00821   */
00822 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
00823 {
00824   HAL_StatusTypeDef status = HAL_OK;
00825 
00826   /* Process locked */
00827   __HAL_LOCK(hsmbus);
00828 
00829   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00830   {
00831     hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback  */
00832   }
00833   else
00834   {
00835     /* Update the error code */
00836     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00837 
00838     /* Return error status */
00839     status =  HAL_ERROR;
00840   }
00841 
00842   /* Release Lock */
00843   __HAL_UNLOCK(hsmbus);
00844   return status;
00845 }
00846 
00847 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00848 
00849 /**
00850   * @}
00851   */
00852 
00853 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
00854  *  @brief    Data transfers functions
00855  *
00856 @verbatim
00857  ===============================================================================
00858                       ##### IO operation functions #####
00859  ===============================================================================
00860     [..]
00861     This subsection provides a set of functions allowing to manage the SMBUS data
00862     transfers.
00863 
00864     (#) Blocking mode function to check if device is ready for usage is :
00865         (++) HAL_SMBUS_IsDeviceReady()
00866 
00867     (#) There is only one mode of transfer:
00868        (++) Non Blocking mode : The communication is performed using Interrupts.
00869             These functions return the status of the transfer startup.
00870             The end of the data processing will be indicated through the
00871             dedicated SMBUS IRQ when using Interrupt mode.
00872 
00873     (#) Non Blocking mode functions with Interrupt are :
00874         (++) HAL_SMBUS_Master_Transmit_IT()
00875         (++) HAL_SMBUS_Master_Receive_IT()
00876         (++) HAL_SMBUS_Master_Abort_IT()
00877         (++) HAL_SMBUS_Slave_Transmit_IT()
00878         (++) HAL_SMBUS_Slave_Receive_IT()
00879         (++) HAL_SMBUS_EnableAlert_IT()
00880         (++) HAL_SMBUS_DisableAlert_IT()
00881 
00882     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
00883         (++) HAL_SMBUS_MasterTxCpltCallback()
00884         (++) HAL_SMBUS_MasterRxCpltCallback()
00885         (++) HAL_SMBUS_SlaveTxCpltCallback()
00886         (++) HAL_SMBUS_SlaveRxCpltCallback()
00887         (++) HAL_SMBUS_AddrCallback()
00888         (++) HAL_SMBUS_ListenCpltCallback()
00889         (++) HAL_SMBUS_ErrorCallback()
00890         (++) HAL_SMBUS_AbortCpltCallback()
00891 
00892 @endverbatim
00893   * @{
00894   */
00895 
00896 /**
00897   * @brief  Transmits in master mode an amount of data in blocking mode.
00898   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00899   *         the configuration information for the specified SMBUS.
00900   * @param  DevAddress Target device address The device 7 bits address value
00901   *         in datasheet must be shifted to the left before calling the interface
00902   * @param  pData Pointer to data buffer
00903   * @param  Size Amount of data to be sent
00904   * @param  XferOptions Options of Transfer
00905   * @retval HAL status
00906   */
00907 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00908 {
00909   uint32_t count      = 0x00U;
00910 
00911   /* Check the parameters */
00912   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00913 
00914   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00915   {
00916     /* Check Busy Flag only if FIRST call of Master interface */
00917     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
00918     {
00919       /* Wait until BUSY flag is reset */
00920       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
00921       do
00922       {
00923         if (count-- == 0U)
00924         {
00925           hsmbus->PreviousState = SMBUS_STATE_NONE;
00926           hsmbus->State = HAL_SMBUS_STATE_READY;
00927 
00928           /* Process Unlocked */
00929           __HAL_UNLOCK(hsmbus);
00930 
00931           return HAL_TIMEOUT;
00932         }
00933       }
00934       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
00935     }
00936 
00937     /* Process Locked */
00938     __HAL_LOCK(hsmbus);
00939 
00940     /* Check if the SMBUS is already enabled */
00941     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
00942     {
00943       /* Enable SMBUS peripheral */
00944       __HAL_SMBUS_ENABLE(hsmbus);
00945     }
00946 
00947     /* Disable Pos */
00948     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
00949 
00950     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX;
00951     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00952     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
00953 
00954     /* Prepare transfer parameters */
00955     hsmbus->pBuffPtr    = pData;
00956     hsmbus->XferCount   = Size;
00957     hsmbus->XferOptions = XferOptions;
00958     hsmbus->XferSize    = hsmbus->XferCount;
00959     hsmbus->Devaddress  = DevAddress;
00960 
00961     /* Generate Start */
00962     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
00963 
00964     /* Process Unlocked */
00965     __HAL_UNLOCK(hsmbus);
00966 
00967     /* Note : The SMBUS interrupts must be enabled after unlocking current process
00968     to avoid the risk of hsmbus interrupt handle execution before current
00969     process unlock */
00970 
00971     /* Enable EVT, BUF and ERR interrupt */
00972     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
00973 
00974     return HAL_OK;
00975   }
00976   else
00977   {
00978     return HAL_BUSY;
00979   }
00980 }
00981 /**
00982   * @brief  Receive in master/host SMBUS mode an amount of data in non blocking mode with Interrupt.
00983   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00984   *         the configuration information for the specified SMBUS.
00985   * @param  DevAddress Target device address The device 7 bits address value
00986   *         in datasheet must be shifted to the left before calling the interface
00987   * @param  pData Pointer to data buffer
00988   * @param  Size Amount of data to be sent
00989   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
00990   * @retval HAL status
00991   */
00992 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00993 {
00994   __IO uint32_t count = 0U;
00995 
00996   /* Check the parameters */
00997   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00998 
00999   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01000   {
01001     /* Check Busy Flag only if FIRST call of Master interface */
01002     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
01003     {
01004       /* Wait until BUSY flag is reset */
01005       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
01006       do
01007       {
01008         if (count-- == 0U)
01009         {
01010           hsmbus->PreviousState = SMBUS_STATE_NONE;
01011           hsmbus->State = HAL_SMBUS_STATE_READY;
01012 
01013           /* Process Unlocked */
01014           __HAL_UNLOCK(hsmbus);
01015 
01016           return HAL_TIMEOUT;
01017         }
01018       }
01019       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
01020     }
01021 
01022     /* Process Locked */
01023     __HAL_LOCK(hsmbus);
01024 
01025     /* Check if the SMBUS is already enabled */
01026     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
01027     {
01028       /* Enable SMBUS peripheral */
01029       __HAL_SMBUS_ENABLE(hsmbus);
01030     }
01031 
01032     /* Disable Pos */
01033     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
01034 
01035     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX;
01036     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01037     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
01038 
01039     /* Prepare transfer parameters */
01040     hsmbus->pBuffPtr    = pData;
01041     hsmbus->XferCount   = Size;
01042     hsmbus->XferOptions = XferOptions;
01043     hsmbus->XferSize    = hsmbus->XferCount;
01044     hsmbus->Devaddress  = DevAddress;
01045 
01046     if ((hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX) || (hsmbus->PreviousState == SMBUS_STATE_NONE))
01047     {
01048       /* Generate Start condition if first transfer */
01049       if ((XferOptions == SMBUS_NEXT_FRAME)  || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME)  || (XferOptions == SMBUS_NO_OPTION_FRAME))
01050       {
01051         /* Enable Acknowledge */
01052         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01053 
01054         /* Generate Start */
01055         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
01056       }
01057 
01058       if ((XferOptions == SMBUS_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_LAST_FRAME_WITH_PEC))
01059       {
01060         if (hsmbus->PreviousState == SMBUS_STATE_NONE)
01061         {
01062           /* Enable Acknowledge */
01063           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01064         }
01065 
01066         if (hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX)
01067         {
01068           /* Enable Acknowledge */
01069           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01070 
01071           /* Generate Start */
01072           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
01073         }
01074       }
01075     }
01076 
01077 
01078 
01079     /* Process Unlocked */
01080     __HAL_UNLOCK(hsmbus);
01081 
01082     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01083     to avoid the risk of SMBUS interrupt handle execution before current
01084     process unlock */
01085 
01086     /* Enable EVT, BUF and ERR interrupt */
01087     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01088 
01089     return HAL_OK;
01090   }
01091   else
01092   {
01093     return HAL_BUSY;
01094   }
01095 }
01096 
01097 /**
01098   * @brief  Abort a master/host SMBUS process communication with Interrupt.
01099   * @note   This abort can be called only if state is ready
01100   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01101   *         the configuration information for the specified SMBUS.
01102   * @param  DevAddress Target device address The device 7 bits address value
01103   *         in datasheet must be shifted to the left before calling the interface
01104   * @retval HAL status
01105   */
01106 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
01107 {
01108   /* Prevent unused argument(s) compilation warning */
01109   UNUSED(DevAddress);
01110   if (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_HOST)
01111   {
01112     /* Process Locked */
01113     __HAL_LOCK(hsmbus);
01114 
01115     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01116 
01117     hsmbus->PreviousState = SMBUS_STATE_NONE;
01118     hsmbus->State = HAL_SMBUS_STATE_ABORT;
01119 
01120 
01121     /* Disable Acknowledge */
01122     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01123 
01124     /* Generate Stop */
01125     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
01126 
01127     hsmbus->XferCount = 0U;
01128 
01129     /* Disable EVT, BUF and ERR interrupt */
01130     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01131 
01132     /* Process Unlocked */
01133     __HAL_UNLOCK(hsmbus);
01134 
01135     /* Call the corresponding callback to inform upper layer of End of Transfer */
01136     SMBUS_ITError(hsmbus);
01137 
01138     return HAL_OK;
01139   }
01140   else
01141   {
01142     return HAL_BUSY;
01143   }
01144 }
01145 
01146 
01147 /**
01148   * @brief  Transmit in slave/device SMBUS mode an amount of data in non blocking mode with Interrupt.
01149   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01150   *         the configuration information for the specified SMBUS.
01151   * @param  pData Pointer to data buffer
01152   * @param  Size Amount of data to be sent
01153   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
01154   * @retval HAL status
01155   */
01156 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
01157 {
01158   /* Check the parameters */
01159   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01160 
01161   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
01162   {
01163     if ((pData == NULL) || (Size == 0U))
01164     {
01165       return  HAL_ERROR;
01166     }
01167 
01168     /* Process Locked */
01169     __HAL_LOCK(hsmbus);
01170 
01171     /* Check if the SMBUS is already enabled */
01172     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
01173     {
01174       /* Enable SMBUS peripheral */
01175       __HAL_SMBUS_ENABLE(hsmbus);
01176     }
01177 
01178     /* Disable Pos */
01179     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
01180 
01181     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX_LISTEN;
01182     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01183     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
01184 
01185     /* Prepare transfer parameters */
01186     hsmbus->pBuffPtr    = pData;
01187     hsmbus->XferCount   = Size;
01188     hsmbus->XferOptions = XferOptions;
01189     hsmbus->XferSize    = hsmbus->XferCount;
01190 
01191     /* Clear ADDR flag after prepare the transfer parameters */
01192     /* This action will generate an acknowledge to the HOST */
01193     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
01194 
01195     /* Process Unlocked */
01196     __HAL_UNLOCK(hsmbus);
01197 
01198     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01199               to avoid the risk of SMBUS interrupt handle execution before current
01200               process unlock */
01201 
01202     /* Enable EVT, BUF and ERR interrupt */
01203     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01204 
01205     return HAL_OK;
01206   }
01207   else
01208   {
01209     return HAL_BUSY;
01210   }
01211 }
01212 
01213 /**
01214   * @brief  Enable the Address listen mode with Interrupt.
01215   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01216   *         the configuration information for the specified SMBUS.
01217   * @param  pData Pointer to data buffer
01218   * @param  Size Amount of data to be sent
01219   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
01220   * @retval HAL status
01221   */
01222 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
01223 {
01224   /* Check the parameters */
01225   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01226 
01227   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
01228   {
01229     if ((pData == NULL) || (Size == 0U))
01230     {
01231       return  HAL_ERROR;
01232     }
01233 
01234     /* Process Locked */
01235     __HAL_LOCK(hsmbus);
01236 
01237     /* Check if the SMBUS is already enabled */
01238     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
01239     {
01240       /* Enable SMBUS peripheral */
01241       __HAL_SMBUS_ENABLE(hsmbus);
01242     }
01243 
01244     /* Disable Pos */
01245     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
01246 
01247     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX_LISTEN;
01248     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01249     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
01250 
01251 
01252 
01253     /* Prepare transfer parameters */
01254     hsmbus->pBuffPtr = pData;
01255     hsmbus->XferCount = Size;
01256     hsmbus->XferOptions = XferOptions;
01257     hsmbus->XferSize    = hsmbus->XferCount;
01258 
01259     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
01260 
01261     /* Process Unlocked */
01262     __HAL_UNLOCK(hsmbus);
01263 
01264     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01265               to avoid the risk of SMBUS interrupt handle execution before current
01266               process unlock */
01267 
01268     /* Enable EVT, BUF and ERR interrupt */
01269     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01270 
01271     return HAL_OK;
01272   }
01273   else
01274   {
01275     return HAL_BUSY;
01276   }
01277 }
01278 
01279 
01280 /**
01281   * @brief  Enable the Address listen mode with Interrupt.
01282   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01283   *                the configuration information for the specified SMBUS.
01284   * @retval HAL status
01285   */
01286 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
01287 {
01288   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01289   {
01290     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
01291 
01292     /* Check if the SMBUS is already enabled */
01293     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
01294     {
01295       /* Enable SMBUS peripheral */
01296       __HAL_SMBUS_ENABLE(hsmbus);
01297     }
01298 
01299     /* Enable Address Acknowledge */
01300     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01301 
01302     /* Enable EVT and ERR interrupt */
01303     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
01304 
01305     return HAL_OK;
01306   }
01307   else
01308   {
01309     return HAL_BUSY;
01310   }
01311 }
01312 
01313 /**
01314   * @brief  Disable the Address listen mode with Interrupt.
01315   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01316   *         the configuration information for the specified SMBUS.
01317   * @retval HAL status
01318   */
01319 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
01320 {
01321   /* Declaration of tmp to prevent undefined behavior of volatile usage */
01322   uint32_t tmp;
01323 
01324   /* Disable Address listen mode only if a transfer is not ongoing */
01325   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
01326   {
01327     tmp = (uint32_t)(hsmbus->State) & SMBUS_STATE_MSK;
01328     hsmbus->PreviousState = tmp | (uint32_t)(hsmbus->Mode);
01329     hsmbus->State = HAL_SMBUS_STATE_READY;
01330     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
01331 
01332     /* Disable Address Acknowledge */
01333     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
01334 
01335     /* Disable EVT and ERR interrupt */
01336     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
01337 
01338     return HAL_OK;
01339   }
01340   else
01341   {
01342     return HAL_BUSY;
01343   }
01344 }
01345 
01346 /**
01347   * @brief  Enable the SMBUS alert mode with Interrupt.
01348   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01349   *         the configuration information for the specified SMBUSx peripheral.
01350   * @retval HAL status
01351   */
01352 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
01353 {
01354   /* Enable SMBus alert */
01355   SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
01356 
01357   /* Clear ALERT flag */
01358   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
01359 
01360   /* Enable Alert Interrupt */
01361   __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_ERR);
01362 
01363   return HAL_OK;
01364 }
01365 /**
01366   * @brief  Disable the SMBUS alert mode with Interrupt.
01367   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01368   *                the configuration information for the specified SMBUSx peripheral.
01369   * @retval HAL status
01370   */
01371 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
01372 {
01373   /* Disable SMBus alert */
01374   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
01375 
01376   /* Disable Alert Interrupt */
01377   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ERR);
01378 
01379   return HAL_OK;
01380 }
01381 
01382 
01383 /**
01384   * @brief  Check if target device is ready for communication.
01385   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01386   *         the configuration information for the specified SMBUS.
01387   * @param  DevAddress Target device address The device 7 bits address value
01388   *         in datasheet must be shifted to the left before calling the interface
01389   * @param  Trials Number of trials
01390   * @param  Timeout Timeout duration
01391   * @retval HAL status
01392   */
01393 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
01394 {
01395   uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, SMBUS_Trials = 1U;
01396 
01397   /* Get tick */
01398   tickstart = HAL_GetTick();
01399 
01400   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01401   {
01402     /* Wait until BUSY flag is reset */
01403     if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
01404     {
01405       return HAL_BUSY;
01406     }
01407 
01408     /* Process Locked */
01409     __HAL_LOCK(hsmbus);
01410 
01411     /* Check if the SMBUS is already enabled */
01412     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
01413     {
01414       /* Enable SMBUS peripheral */
01415       __HAL_SMBUS_ENABLE(hsmbus);
01416     }
01417 
01418     /* Disable Pos */
01419     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
01420 
01421     hsmbus->State = HAL_SMBUS_STATE_BUSY;
01422     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01423     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
01424 
01425     do
01426     {
01427       /* Generate Start */
01428       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
01429 
01430       /* Wait until SB flag is set */
01431       if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
01432       {
01433         return HAL_TIMEOUT;
01434       }
01435 
01436       /* Send slave address */
01437       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(DevAddress);
01438 
01439       /* Wait until ADDR or AF flag are set */
01440       /* Get tick */
01441       tickstart = HAL_GetTick();
01442 
01443       tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
01444       tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
01445       tmp3 = hsmbus->State;
01446       while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_SMBUS_STATE_TIMEOUT))
01447       {
01448         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
01449         {
01450           hsmbus->State = HAL_SMBUS_STATE_TIMEOUT;
01451         }
01452         tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
01453         tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
01454         tmp3 = hsmbus->State;
01455       }
01456 
01457       hsmbus->State = HAL_SMBUS_STATE_READY;
01458 
01459       /* Check if the ADDR flag has been set */
01460       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) == SET)
01461       {
01462         /* Generate Stop */
01463         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
01464 
01465         /* Clear ADDR Flag */
01466         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
01467 
01468         /* Wait until BUSY flag is reset */
01469         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
01470         {
01471           return HAL_TIMEOUT;
01472         }
01473 
01474         hsmbus->State = HAL_SMBUS_STATE_READY;
01475 
01476         /* Process Unlocked */
01477         __HAL_UNLOCK(hsmbus);
01478 
01479         return HAL_OK;
01480       }
01481       else
01482       {
01483         /* Generate Stop */
01484         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
01485 
01486         /* Clear AF Flag */
01487         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01488 
01489         /* Wait until BUSY flag is reset */
01490         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
01491         {
01492           return HAL_TIMEOUT;
01493         }
01494       }
01495     }
01496     while (SMBUS_Trials++ < Trials);
01497 
01498     hsmbus->State = HAL_SMBUS_STATE_READY;
01499 
01500     /* Process Unlocked */
01501     __HAL_UNLOCK(hsmbus);
01502 
01503     return HAL_ERROR;
01504   }
01505   else
01506   {
01507     return HAL_BUSY;
01508   }
01509 }
01510 
01511 /**
01512   * @brief  This function handles SMBUS event interrupt request.
01513   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01514   *                the configuration information for the specified SMBUS.
01515   * @retval None
01516   */
01517 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01518 {
01519   uint32_t sr2itflags   = READ_REG(hsmbus->Instance->SR2);
01520   uint32_t sr1itflags   = READ_REG(hsmbus->Instance->SR1);
01521   uint32_t itsources    = READ_REG(hsmbus->Instance->CR2);
01522 
01523   uint32_t CurrentMode  = hsmbus->Mode;
01524 
01525   /* Master mode selected */
01526   if (CurrentMode == HAL_SMBUS_MODE_MASTER)
01527   {
01528     /* SB Set ----------------------------------------------------------------*/
01529     if (((sr1itflags & SMBUS_FLAG_SB) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01530     {
01531       SMBUS_Master_SB(hsmbus);
01532     }
01533     /* ADD10 Set -------------------------------------------------------------*/
01534     else if (((sr1itflags & SMBUS_FLAG_ADD10) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01535     {
01536       SMBUS_Master_ADD10(hsmbus);
01537     }
01538     /* ADDR Set --------------------------------------------------------------*/
01539     else if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01540     {
01541       SMBUS_Master_ADDR(hsmbus);
01542     }
01543     /* SMBUS in mode Transmitter -----------------------------------------------*/
01544     if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
01545     {
01546       /* TXE set and BTF reset -----------------------------------------------*/
01547       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
01548       {
01549         SMBUS_MasterTransmit_TXE(hsmbus);
01550       }
01551       /* BTF set -------------------------------------------------------------*/
01552       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01553       {
01554         SMBUS_MasterTransmit_BTF(hsmbus);
01555       }
01556     }
01557     /* SMBUS in mode Receiver --------------------------------------------------*/
01558     else
01559     {
01560       /* RXNE set and BTF reset -----------------------------------------------*/
01561       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
01562       {
01563         SMBUS_MasterReceive_RXNE(hsmbus);
01564       }
01565       /* BTF set -------------------------------------------------------------*/
01566       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01567       {
01568         SMBUS_MasterReceive_BTF(hsmbus);
01569       }
01570     }
01571   }
01572   /* Slave mode selected */
01573   else
01574   {
01575     /* ADDR set --------------------------------------------------------------*/
01576     if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01577     {
01578       SMBUS_Slave_ADDR(hsmbus);
01579     }
01580     /* STOPF set --------------------------------------------------------------*/
01581     else if (((sr1itflags & SMBUS_FLAG_STOPF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01582     {
01583       SMBUS_Slave_STOPF(hsmbus);
01584     }
01585     /* SMBUS in mode Transmitter -----------------------------------------------*/
01586     else if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
01587     {
01588       /* TXE set and BTF reset -----------------------------------------------*/
01589       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
01590       {
01591         SMBUS_SlaveTransmit_TXE(hsmbus);
01592       }
01593       /* BTF set -------------------------------------------------------------*/
01594       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01595       {
01596         SMBUS_SlaveTransmit_BTF(hsmbus);
01597       }
01598     }
01599     /* SMBUS in mode Receiver --------------------------------------------------*/
01600     else
01601     {
01602       /* RXNE set and BTF reset ----------------------------------------------*/
01603       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
01604       {
01605         SMBUS_SlaveReceive_RXNE(hsmbus);
01606       }
01607       /* BTF set -------------------------------------------------------------*/
01608       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
01609       {
01610         SMBUS_SlaveReceive_BTF(hsmbus);
01611       }
01612     }
01613   }
01614 }
01615 
01616 /**
01617   * @brief  This function handles SMBUS error interrupt request.
01618   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01619   *                the configuration information for the specified SMBUS.
01620   * @retval None
01621   */
01622 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01623 {
01624   uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U;
01625   uint32_t sr1itflags = READ_REG(hsmbus->Instance->SR1);
01626   uint32_t itsources  = READ_REG(hsmbus->Instance->CR2);
01627 
01628   /* SMBUS Bus error interrupt occurred ------------------------------------*/
01629   if (((sr1itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01630   {
01631     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
01632 
01633     /* Clear BERR flag */
01634     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
01635 
01636   }
01637 
01638   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
01639   if (((sr1itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01640   {
01641     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
01642 
01643     /* Clear OVR flag */
01644     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
01645   }
01646 
01647   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
01648   if (((sr1itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01649   {
01650     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
01651 
01652     /* Clear ARLO flag */
01653     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
01654   }
01655 
01656   /* SMBUS Acknowledge failure error interrupt occurred ------------------------------------*/
01657   if (((sr1itflags & SMBUS_FLAG_AF) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01658   {
01659     tmp1 = hsmbus->Mode;
01660     tmp2 = hsmbus->XferCount;
01661     tmp3 = hsmbus->State;
01662     tmp4 = hsmbus->PreviousState;
01663 
01664     if ((tmp1 == HAL_SMBUS_MODE_SLAVE) && (tmp2 == 0U) && \
01665         ((tmp3 == HAL_SMBUS_STATE_BUSY_TX) || (tmp3 == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || \
01666          ((tmp3 == HAL_SMBUS_STATE_LISTEN) && (tmp4 == SMBUS_STATE_SLAVE_BUSY_TX))))
01667     {
01668       SMBUS_Slave_AF(hsmbus);
01669     }
01670     else
01671     {
01672       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_AF;
01673 
01674       /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
01675       if (hsmbus->Mode == HAL_SMBUS_MODE_MASTER)
01676       {
01677         /* Generate Stop */
01678         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
01679 
01680       }
01681 
01682       /* Clear AF flag */
01683       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01684     }
01685   }
01686 
01687   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
01688   if (((sr1itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01689   {
01690     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_TIMEOUT;
01691 
01692     /* Clear TIMEOUT flag */
01693     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
01694 
01695   }
01696 
01697   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
01698   if (((sr1itflags & SMBUS_FLAG_SMBALERT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01699   {
01700     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
01701 
01702     /* Clear ALERT flag */
01703     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
01704   }
01705 
01706   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
01707   if (((sr1itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
01708   {
01709     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
01710 
01711     /* Clear PEC error flag */
01712     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
01713   }
01714 
01715   /* Call the Error Callback in case of Error detected -----------------------*/
01716   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
01717   {
01718     SMBUS_ITError(hsmbus);
01719   }
01720 }
01721 
01722 /**
01723   * @brief  Master Tx Transfer completed callback.
01724   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01725   *                the configuration information for the specified SMBUS.
01726   * @retval None
01727   */
01728 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01729 {
01730   /* Prevent unused argument(s) compilation warning */
01731   UNUSED(hsmbus);
01732 
01733   /* NOTE : This function should not be modified, when the callback is needed,
01734             the HAL_SMBUS_MasterTxCpltCallback can be implemented in the user file
01735    */
01736 }
01737 
01738 /**
01739   * @brief  Master Rx Transfer completed callback.
01740   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01741   *                the configuration information for the specified SMBUS.
01742   * @retval None
01743   */
01744 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01745 {
01746   /* Prevent unused argument(s) compilation warning */
01747   UNUSED(hsmbus);
01748 
01749   /* NOTE : This function should not be modified, when the callback is needed,
01750             the HAL_SMBUS_MasterRxCpltCallback can be implemented in the user file
01751    */
01752 }
01753 
01754 /** @brief  Slave Tx Transfer completed callback.
01755   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01756   *                the configuration information for the specified SMBUS.
01757   * @retval None
01758   */
01759 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01760 {
01761   /* Prevent unused argument(s) compilation warning */
01762   UNUSED(hsmbus);
01763 
01764   /* NOTE : This function should not be modified, when the callback is needed,
01765             the HAL_SMBUS_SlaveTxCpltCallback can be implemented in the user file
01766    */
01767 }
01768 
01769 /**
01770   * @brief  Slave Rx Transfer completed callback.
01771   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01772   *                the configuration information for the specified SMBUS.
01773   * @retval None
01774   */
01775 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01776 {
01777   /* Prevent unused argument(s) compilation warning */
01778   UNUSED(hsmbus);
01779 
01780   /* NOTE : This function should not be modified, when the callback is needed,
01781             the HAL_SMBUS_SlaveRxCpltCallback can be implemented in the user file
01782    */
01783 }
01784 
01785 /**
01786   * @brief  Slave Address Match callback.
01787   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01788   *                the configuration information for the specified SMBUS.
01789   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref SMBUS_XferOptions_definition
01790   * @param  AddrMatchCode Address Match Code
01791   * @retval None
01792   */
01793 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
01794 {
01795   /* Prevent unused argument(s) compilation warning */
01796   UNUSED(hsmbus);
01797   UNUSED(TransferDirection);
01798   UNUSED(AddrMatchCode);
01799 
01800   /* NOTE : This function should not be modified, when the callback is needed,
01801             the HAL_SMBUS_AddrCallback can be implemented in the user file
01802    */
01803 }
01804 
01805 /**
01806   * @brief  Listen Complete callback.
01807   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01808   *                the configuration information for the specified SMBUS.
01809   * @retval None
01810   */
01811 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01812 {
01813   /* Prevent unused argument(s) compilation warning */
01814   UNUSED(hsmbus);
01815 
01816   /* NOTE : This function should not be modified, when the callback is needed,
01817           the HAL_SMBUS_ListenCpltCallback can be implemented in the user file
01818   */
01819 }
01820 
01821 /**
01822   * @brief  SMBUS error callback.
01823   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01824   *                the configuration information for the specified SMBUS.
01825   * @retval None
01826   */
01827 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
01828 {
01829   /* Prevent unused argument(s) compilation warning */
01830   UNUSED(hsmbus);
01831 
01832   /* NOTE : This function should not be modified, when the callback is needed,
01833             the HAL_SMBUS_ErrorCallback can be implemented in the user file
01834    */
01835 }
01836 
01837 /**
01838   * @brief  SMBUS abort callback.
01839   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01840   *                the configuration information for the specified SMBUS.
01841   * @retval None
01842   */
01843 __weak void HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01844 {
01845   /* Prevent unused argument(s) compilation warning */
01846   UNUSED(hsmbus);
01847 
01848   /* NOTE : This function should not be modified, when the callback is needed,
01849             the HAL_SMBUS_AbortCpltCallback could be implemented in the user file
01850    */
01851 }
01852 
01853 /**
01854   * @}
01855   */
01856 
01857 /** @defgroup   SMBUS_Exported_Functions_Group3 Peripheral State, Mode and Error functions
01858   *  @brief   Peripheral State and Errors functions
01859   *
01860 @verbatim
01861  ===============================================================================
01862             ##### Peripheral State, Mode and Error functions #####
01863  ===============================================================================
01864     [..]
01865     This subsection permits to get in run-time the status of the peripheral
01866     and the data flow.
01867 
01868 @endverbatim
01869   * @{
01870   */
01871 
01872 /**
01873   * @brief  Return the SMBUS handle state.
01874   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01875   *                the configuration information for the specified SMBUS.
01876   * @retval HAL state
01877   */
01878 HAL_SMBUS_StateTypeDef HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
01879 {
01880   /* Return SMBUS handle state */
01881   return hsmbus->State;
01882 }
01883 
01884 /**
01885   * @brief  Return the SMBUS Master, Slave or no mode.
01886   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01887   *                the configuration information for SMBUS module
01888   * @retval HAL mode
01889   */
01890 HAL_SMBUS_ModeTypeDef HAL_SMBUS_GetMode(SMBUS_HandleTypeDef *hsmbus)
01891 {
01892   return hsmbus->Mode;
01893 }
01894 
01895 /**
01896   * @brief  Return the SMBUS error code
01897   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01898   *              the configuration information for the specified SMBUS.
01899   * @retval SMBUS Error Code
01900   */
01901 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
01902 {
01903   return hsmbus->ErrorCode;
01904 }
01905 
01906 /**
01907   * @}
01908   */
01909 
01910 /**
01911   * @}
01912   */
01913 
01914 /** @addtogroup SMBUS_Private_Functions
01915   * @{
01916   */
01917 
01918 /**
01919   * @brief  Handle TXE flag for Master
01920   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01921   *         the configuration information for SMBUS module
01922   * @retval HAL status
01923   */
01924 static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
01925 {
01926   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
01927   uint32_t CurrentState       = hsmbus->State;
01928   uint32_t CurrentXferOptions = hsmbus->XferOptions;
01929 
01930   if ((hsmbus->XferSize == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_TX))
01931   {
01932     /* Call TxCpltCallback() directly if no stop mode is set */
01933     if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
01934     {
01935       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01936 
01937       hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
01938       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
01939       hsmbus->State = HAL_SMBUS_STATE_READY;
01940 
01941 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01942       hsmbus->MasterTxCpltCallback(hsmbus);
01943 #else
01944       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01945 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01946     }
01947     else /* Generate Stop condition then Call TxCpltCallback() */
01948     {
01949       /* Disable EVT, BUF and ERR interrupt */
01950       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
01951 
01952       /* Generate Stop */
01953       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
01954 
01955       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01956       hsmbus->State = HAL_SMBUS_STATE_READY;
01957 
01958       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
01959 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01960       hsmbus->MasterTxCpltCallback(hsmbus);
01961 #else
01962       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01963 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01964     }
01965   }
01966   else if (CurrentState == HAL_SMBUS_STATE_BUSY_TX)
01967   {
01968 
01969     if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
01970     {
01971       hsmbus->XferCount--;
01972     }
01973 
01974     if (hsmbus->XferCount == 0U)
01975     {
01976 
01977       /* Disable BUF interrupt */
01978       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
01979 
01980       if ((SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
01981       {
01982         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
01983       }
01984 
01985     }
01986     else
01987     {
01988       /* Write data to DR */
01989       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
01990       hsmbus->XferCount--;
01991     }
01992   }
01993   return HAL_OK;
01994 }
01995 
01996 /**
01997   * @brief  Handle BTF flag for Master transmitter
01998   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01999   *         the configuration information for SMBUS module
02000   * @retval HAL status
02001   */
02002 static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
02003 {
02004   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02005   uint32_t CurrentXferOptions = hsmbus->XferOptions;
02006 
02007   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
02008   {
02009     if (hsmbus->XferCount != 0U)
02010     {
02011       /* Write data to DR */
02012       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
02013       hsmbus->XferCount--;
02014     }
02015     else
02016     {
02017       /* Call TxCpltCallback() directly if no stop mode is set */
02018       if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
02019       {
02020         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
02021 
02022         hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
02023         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02024         hsmbus->State = HAL_SMBUS_STATE_READY;
02025 
02026 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02027         hsmbus->MasterTxCpltCallback(hsmbus);
02028 #else
02029         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
02030 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02031       }
02032       else /* Generate Stop condition then Call TxCpltCallback() */
02033       {
02034         /* Disable EVT, BUF and ERR interrupt */
02035         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
02036 
02037         /* Generate Stop */
02038         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
02039 
02040         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
02041         hsmbus->State = HAL_SMBUS_STATE_READY;
02042         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02043 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02044         hsmbus->MasterTxCpltCallback(hsmbus);
02045 #else
02046         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
02047 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02048       }
02049     }
02050   }
02051   return HAL_OK;
02052 }
02053 
02054 /**
02055   * @brief  Handle RXNE flag for Master
02056   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02057   *         the configuration information for SMBUS module
02058   * @retval HAL status
02059   */
02060 static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
02061 {
02062   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02063   uint32_t CurrentXferOptions = hsmbus->XferOptions;
02064 
02065   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
02066   {
02067     uint32_t tmp = hsmbus->XferCount;
02068 
02069     if (tmp > 3U)
02070     {
02071       /* Read data from DR */
02072       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02073       hsmbus->XferCount--;
02074 
02075       if (hsmbus->XferCount == 3)
02076       {
02077         /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
02078         on BTF subroutine */
02079         /* Disable BUF interrupt */
02080         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
02081       }
02082     }
02083 
02084     else if (tmp == 2U)
02085     {
02086 
02087       /* Read data from DR */
02088       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02089       hsmbus->XferCount--;
02090 
02091       if ((CurrentXferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (CurrentXferOptions == SMBUS_LAST_FRAME_WITH_PEC))
02092       {
02093         /* PEC of slave */
02094         hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
02095 
02096       }
02097       /* Generate Stop */
02098       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
02099     }
02100 
02101     else if ((tmp == 1U) || (tmp == 0U))
02102     {
02103       /* Disable Acknowledge */
02104       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02105 
02106       /* Disable EVT, BUF and ERR interrupt */
02107       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
02108 
02109       /* Read data from DR */
02110       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02111       hsmbus->XferCount--;
02112 
02113       hsmbus->State = HAL_SMBUS_STATE_READY;
02114       hsmbus->PreviousState = SMBUS_STATE_NONE;
02115       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02116 
02117 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02118       hsmbus->MasterRxCpltCallback(hsmbus);
02119 #else
02120       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
02121 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02122     }
02123   }
02124 
02125   return HAL_OK;
02126 }
02127 
02128 /**
02129   * @brief  Handle BTF flag for Master receiver
02130   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02131   *         the configuration information for SMBUS module
02132   * @retval HAL status
02133   */
02134 static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
02135 {
02136   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02137   uint32_t CurrentXferOptions = hsmbus->XferOptions;
02138 
02139   if (hsmbus->XferCount == 4U)
02140   {
02141     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
02142        on BTF subroutine if there is a reception delay between N-1 and N byte */
02143     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
02144 
02145     /* Read data from DR */
02146     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02147     hsmbus->XferCount--;
02148     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
02149   }
02150   else if (hsmbus->XferCount == 3U)
02151   {
02152     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
02153        on BTF subroutine if there is a reception delay between N-1 and N byte */
02154     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
02155 
02156     /* Disable Acknowledge */
02157     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02158 
02159     /* Read data from DR */
02160     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02161     hsmbus->XferCount--;
02162     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
02163   }
02164   else if (hsmbus->XferCount == 2U)
02165   {
02166     /* Prepare next transfer or stop current transfer */
02167     if ((CurrentXferOptions == SMBUS_NEXT_FRAME) || (CurrentXferOptions == SMBUS_FIRST_FRAME))
02168     {
02169       /* Disable Acknowledge */
02170       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02171 
02172       /* Generate ReStart */
02173       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
02174     }
02175     else
02176     {
02177       /* Generate Stop */
02178       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
02179     }
02180 
02181     /* Read data from DR */
02182     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02183     hsmbus->XferCount--;
02184 
02185     /* Read data from DR */
02186     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02187     hsmbus->XferCount--;
02188 
02189     /* Disable EVT and ERR interrupt */
02190     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
02191 
02192     hsmbus->State = HAL_SMBUS_STATE_READY;
02193     hsmbus->PreviousState = SMBUS_STATE_NONE;
02194     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02195 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02196     hsmbus->MasterRxCpltCallback(hsmbus);
02197 #else
02198     HAL_SMBUS_MasterRxCpltCallback(hsmbus);
02199 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02200   }
02201   else
02202   {
02203     /* Read data from DR */
02204     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02205     hsmbus->XferCount--;
02206   }
02207   return HAL_OK;
02208 }
02209 
02210 /**
02211   * @brief  Handle SB flag for Master
02212   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02213   *         the configuration information for SMBUS module
02214   * @retval HAL status
02215   */
02216 static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus)
02217 {
02218   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
02219   {
02220     /* Send slave 7 Bits address */
02221     if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
02222     {
02223       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(hsmbus->Devaddress);
02224     }
02225     else
02226     {
02227       hsmbus->Instance->DR = SMBUS_7BIT_ADD_READ(hsmbus->Devaddress);
02228     }
02229   }
02230   else
02231   {
02232     if (hsmbus->EventCount == 0U)
02233     {
02234       /* Send header of slave address */
02235       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_WRITE(hsmbus->Devaddress);
02236     }
02237     else if (hsmbus->EventCount == 1U)
02238     {
02239       /* Send header of slave address */
02240       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_READ(hsmbus->Devaddress);
02241     }
02242   }
02243   return HAL_OK;
02244 }
02245 
02246 /**
02247   * @brief  Handle ADD10 flag for Master
02248   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02249   *         the configuration information for SMBUS module
02250   * @retval HAL status
02251   */
02252 static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus)
02253 {
02254   /* Send slave address */
02255   hsmbus->Instance->DR = SMBUS_10BIT_ADDRESS(hsmbus->Devaddress);
02256 
02257   return HAL_OK;
02258 }
02259 
02260 /**
02261   * @brief  Handle ADDR flag for Master
02262   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02263   *         the configuration information for SMBUS module
02264   * @retval HAL status
02265   */
02266 static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus)
02267 {
02268   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
02269   uint32_t Prev_State         = hsmbus->PreviousState;
02270 
02271   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
02272   {
02273     if ((hsmbus->EventCount == 0U) && (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT))
02274     {
02275       /* Clear ADDR flag */
02276       __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02277 
02278       /* Generate Restart */
02279       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
02280 
02281       hsmbus->EventCount++;
02282     }
02283     else
02284     {
02285       /*  In the case of the Quick Command, the ADDR flag is cleared and a stop is generated */
02286       if (hsmbus->XferCount == 0U)
02287       {
02288         /* Clear ADDR flag */
02289         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02290 
02291         /* Generate Stop */
02292         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
02293       }
02294       else if (hsmbus->XferCount == 1U)
02295       {
02296         /* Prepare next transfer or stop current transfer */
02297         if ((hsmbus->XferOptions == SMBUS_FIRST_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
02298         {
02299           /* Disable Acknowledge */
02300           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02301 
02302           /* Clear ADDR flag */
02303           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02304         }
02305         else if ((hsmbus->XferOptions == SMBUS_NEXT_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
02306         {
02307           /* Enable Acknowledge */
02308           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02309 
02310           /* Clear ADDR flag */
02311           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02312         }
02313         else
02314         {
02315           /* Disable Acknowledge */
02316           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02317 
02318           /* Clear ADDR flag */
02319           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02320 
02321           /* Generate Stop */
02322           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
02323         }
02324       }
02325       else if (hsmbus->XferCount == 2U)
02326       {
02327         if (hsmbus->XferOptions != SMBUS_NEXT_FRAME)
02328         {
02329           /* Disable Acknowledge */
02330           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02331 
02332           /* Enable Pos */
02333           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
02334 
02335 
02336         }
02337         else
02338         {
02339           /* Enable Acknowledge */
02340           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02341         }
02342 
02343         /* Clear ADDR flag */
02344         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02345       }
02346       else
02347       {
02348         /* Enable Acknowledge */
02349         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02350 
02351         /* Clear ADDR flag */
02352         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02353       }
02354 
02355       /* Reset Event counter  */
02356       hsmbus->EventCount = 0U;
02357     }
02358   }
02359   else
02360   {
02361     /* Clear ADDR flag */
02362     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
02363   }
02364 
02365   return HAL_OK;
02366 }
02367 
02368 /**
02369   * @brief  Handle TXE flag for Slave
02370   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02371   *         the configuration information for SMBUS module
02372   * @retval HAL status
02373   */
02374 static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
02375 {
02376   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02377   uint32_t CurrentState = hsmbus->State;
02378 
02379   if (hsmbus->XferCount != 0U)
02380   {
02381     /* Write data to DR */
02382     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
02383     hsmbus->XferCount--;
02384 
02385     if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
02386     {
02387       hsmbus->XferCount--;
02388     }
02389 
02390     if ((hsmbus->XferCount == 0U) && (CurrentState == (HAL_SMBUS_STATE_BUSY_TX_LISTEN)))
02391     {
02392       /* Last Byte is received, disable Interrupt */
02393       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
02394 
02395       /* Set state at HAL_SMBUS_STATE_LISTEN */
02396       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_TX;
02397       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
02398 
02399       /* Call the corresponding callback to inform upper layer of End of Transfer */
02400 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02401       hsmbus->SlaveTxCpltCallback(hsmbus);
02402 #else
02403       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
02404 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02405     }
02406   }
02407   return HAL_OK;
02408 }
02409 
02410 /**
02411   * @brief  Handle BTF flag for Slave transmitter
02412   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02413   *         the configuration information for SMBUS module
02414   * @retval HAL status
02415   */
02416 static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
02417 {
02418   if (hsmbus->XferCount != 0U)
02419   {
02420     /* Write data to DR */
02421     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
02422     hsmbus->XferCount--;
02423   }
02424 
02425 
02426 
02427   else if ((hsmbus->XferCount == 0U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
02428   {
02429     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
02430   }
02431   return HAL_OK;
02432 }
02433 
02434 /**
02435   * @brief  Handle RXNE flag for Slave
02436   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02437   *         the configuration information for SMBUS module
02438   * @retval HAL status
02439   */
02440 static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
02441 {
02442   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02443   uint32_t CurrentState = hsmbus->State;
02444 
02445   if (hsmbus->XferCount != 0U)
02446   {
02447     /* Read data from DR */
02448     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02449     hsmbus->XferCount--;
02450 
02451     if ((hsmbus->XferCount == 1U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
02452     {
02453       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
02454       hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
02455     }
02456     if ((hsmbus->XferCount == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
02457     {
02458       /* Last Byte is received, disable Interrupt */
02459       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
02460 
02461       /* Set state at HAL_SMBUS_STATE_LISTEN */
02462       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_RX;
02463       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
02464 
02465       /* Call the corresponding callback to inform upper layer of End of Transfer */
02466 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02467       hsmbus->SlaveRxCpltCallback(hsmbus);
02468 #else
02469       HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
02470 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02471     }
02472   }
02473   return HAL_OK;
02474 }
02475 
02476 /**
02477   * @brief  Handle BTF flag for Slave receiver
02478   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02479   *         the configuration information for SMBUS module
02480   * @retval HAL status
02481   */
02482 static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
02483 {
02484   if (hsmbus->XferCount != 0U)
02485   {
02486     /* Read data from DR */
02487     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02488     hsmbus->XferCount--;
02489   }
02490 
02491   return HAL_OK;
02492 }
02493 
02494 /**
02495   * @brief  Handle ADD flag for Slave
02496   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02497   *         the configuration information for SMBUS module
02498   * @retval HAL status
02499   */
02500 static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus)
02501 {
02502   uint8_t TransferDirection = SMBUS_DIRECTION_RECEIVE ;
02503   uint16_t SlaveAddrCode = 0U;
02504 
02505   /* Transfer Direction requested by Master */
02506   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TRA) == RESET)
02507   {
02508     TransferDirection = SMBUS_DIRECTION_TRANSMIT;
02509   }
02510 
02511   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_DUALF) == RESET)
02512   {
02513     SlaveAddrCode = hsmbus->Init.OwnAddress1;
02514   }
02515   else
02516   {
02517     SlaveAddrCode = hsmbus->Init.OwnAddress2;
02518   }
02519 
02520   /* Call Slave Addr callback */
02521 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02522   hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
02523 #else
02524   HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
02525 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02526 
02527   return HAL_OK;
02528 }
02529 
02530 /**
02531   * @brief  Handle STOPF flag for Slave
02532   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02533   *         the configuration information for SMBUS module
02534   * @retval HAL status
02535   */
02536 static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus)
02537 {
02538   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
02539   uint32_t CurrentState = hsmbus->State;
02540 
02541   /* Disable EVT, BUF and ERR interrupt */
02542   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
02543 
02544   /* Clear STOPF flag */
02545   __HAL_SMBUS_CLEAR_STOPFLAG(hsmbus);
02546 
02547   /* Disable Acknowledge */
02548   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02549 
02550   /* All data are not transferred, so set error code accordingly */
02551   if (hsmbus->XferCount != 0U)
02552   {
02553     /* Store Last receive data if any */
02554     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BTF) == SET)
02555     {
02556       /* Read data from DR */
02557       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02558 
02559       if (hsmbus->XferCount > 0)
02560       {
02561         hsmbus->XferSize--;
02562         hsmbus->XferCount--;
02563       }
02564     }
02565 
02566     /* Store Last receive data if any */
02567     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
02568     {
02569       /* Read data from DR */
02570       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02571 
02572       if (hsmbus->XferCount > 0)
02573       {
02574         hsmbus->XferSize--;
02575         hsmbus->XferCount--;
02576       }
02577     }
02578   }
02579 
02580   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
02581   {
02582     /* Call the corresponding callback to inform upper layer of End of Transfer */
02583     SMBUS_ITError(hsmbus);
02584   }
02585   else
02586   {
02587     if ((CurrentState == HAL_SMBUS_STATE_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN)  || \
02588         (CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN))
02589     {
02590       hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
02591       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
02592       hsmbus->State = HAL_SMBUS_STATE_READY;
02593       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02594 
02595 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02596       hsmbus->ListenCpltCallback(hsmbus);
02597 #else
02598       HAL_SMBUS_ListenCpltCallback(hsmbus);
02599 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02600     }
02601   }
02602   return HAL_OK;
02603 }
02604 
02605 /**
02606   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02607   *         the configuration information for SMBUS module
02608   * @retval HAL status
02609   */
02610 static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus)
02611 {
02612   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
02613   uint32_t CurrentState       = hsmbus->State;
02614   uint32_t CurrentXferOptions = hsmbus->XferOptions;
02615 
02616   if (((CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \
02617        (CurrentXferOptions == SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_LAST_FRAME_WITH_PEC)) && \
02618       (CurrentState == HAL_SMBUS_STATE_LISTEN))
02619   {
02620     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
02621 
02622     /* Disable EVT, BUF and ERR interrupt */
02623     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
02624 
02625     /* Clear AF flag */
02626     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
02627 
02628     /* Disable Acknowledge */
02629     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
02630 
02631     hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
02632     hsmbus->State = HAL_SMBUS_STATE_READY;
02633     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02634 
02635     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
02636 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02637     hsmbus->ListenCpltCallback(hsmbus);
02638 #else
02639     HAL_SMBUS_ListenCpltCallback(hsmbus);
02640 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02641   }
02642   return HAL_OK;
02643 }
02644 
02645 
02646 
02647 /**
02648   * @brief SMBUS interrupts error process
02649   * @param  hsmbus SMBUS handle.
02650   * @retval None
02651   */
02652 static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus)
02653 {
02654   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
02655   uint32_t CurrentState = hsmbus->State;
02656 
02657   if ((CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
02658   {
02659     /* keep HAL_SMBUS_STATE_LISTEN */
02660     hsmbus->PreviousState = SMBUS_STATE_NONE;
02661     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
02662   }
02663   else
02664   {
02665     /* If state is an abort treatment on going, don't change state */
02666     /* This change will be done later */
02667     if (hsmbus->State != HAL_SMBUS_STATE_ABORT)
02668     {
02669       hsmbus->State = HAL_SMBUS_STATE_READY;
02670     }
02671     hsmbus->PreviousState = SMBUS_STATE_NONE;
02672     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02673   }
02674 
02675   /* Disable Pos bit in SMBUS CR1 when error occurred in Master/Mem Receive IT Process */
02676   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
02677 
02678   if (hsmbus->State == HAL_SMBUS_STATE_ABORT)
02679   {
02680     hsmbus->State = HAL_SMBUS_STATE_READY;
02681     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
02682 
02683     /* Store Last receive data if any */
02684     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
02685     {
02686       /* Read data from DR */
02687       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02688     }
02689 
02690     /* Disable SMBUS peripheral to prevent dummy data in buffer */
02691     __HAL_SMBUS_DISABLE(hsmbus);
02692 
02693     /* Call the corresponding callback to inform upper layer of End of Transfer */
02694 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02695     hsmbus->AbortCpltCallback(hsmbus);
02696 #else
02697     HAL_SMBUS_AbortCpltCallback(hsmbus);
02698 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02699   }
02700   else
02701   {
02702     /* Store Last receive data if any */
02703     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
02704     {
02705       /* Read data from DR */
02706       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
02707     }
02708 
02709     /* Call user error callback */
02710 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02711     hsmbus->ErrorCallback(hsmbus);
02712 #else
02713     HAL_SMBUS_ErrorCallback(hsmbus);
02714 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02715   }
02716   /* STOP Flag is not set after a NACK reception */
02717   /* So may inform upper layer that listen phase is stopped */
02718   /* during NACK error treatment */
02719   if ((hsmbus->State == HAL_SMBUS_STATE_LISTEN) && ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_AF) == HAL_SMBUS_ERROR_AF))
02720   {
02721     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
02722     hsmbus->PreviousState = SMBUS_STATE_NONE;
02723     hsmbus->State = HAL_SMBUS_STATE_READY;
02724     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02725 
02726     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
02727 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02728     hsmbus->ListenCpltCallback(hsmbus);
02729 #else
02730     HAL_SMBUS_ListenCpltCallback(hsmbus);
02731 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02732   }
02733 }
02734 
02735 /**
02736   * @brief  This function handles SMBUS Communication Timeout.
02737   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02738   *         the configuration information for SMBUS module
02739   * @param  Flag specifies the SMBUS flag to check.
02740   * @param  Status The new Flag status (SET or RESET).
02741   * @param  Timeout Timeout duration
02742   * @param  Tickstart Tick start value
02743   * @retval HAL status
02744   */
02745 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
02746 {
02747   /* Wait until flag is set */
02748   if (Status == RESET)
02749   {
02750     while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
02751     {
02752       /* Check for the Timeout */
02753       if (Timeout != HAL_MAX_DELAY)
02754       {
02755         if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
02756         {
02757           hsmbus->PreviousState = SMBUS_STATE_NONE;
02758           hsmbus->State = HAL_SMBUS_STATE_READY;
02759           hsmbus->Mode = HAL_SMBUS_MODE_NONE;
02760 
02761           /* Process Unlocked */
02762           __HAL_UNLOCK(hsmbus);
02763           return HAL_TIMEOUT;
02764         }
02765       }
02766     }
02767   }
02768   return HAL_OK;
02769 }
02770 
02771 /**
02772   * @}
02773   */
02774 
02775 
02776 #endif /* HAL_SMBUS_MODULE_ENABLED */
02777 
02778 /**
02779   * @}
02780   */
02781 
02782 /**
02783   * @}
02784   */
02785 
02786 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/