STM32L486xx HAL User Manual
stm32l4xx_hal_smbus.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_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 I2C principles of operation :
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State and Errors 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 @ref 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 Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
00033         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
00034         Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
00035 
00036     (#) Initialize the SMBUS registers by calling the @ref HAL_SMBUS_Init() API:
00037         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00038              by calling the customized @ref HAL_SMBUS_MspInit(&hsmbus) API.
00039 
00040     (#) To check if target device is ready for communication, use the function @ref HAL_SMBUS_IsDeviceReady()
00041 
00042     (#) For SMBUS IO operations, only one mode of operations is available within this driver
00043 
00044     *** Interrupt mode IO operation ***
00045     ===================================
00046     [..]
00047       (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Master_Transmit_IT()
00048       (++) At transmission end of transfer @ref HAL_SMBUS_MasterTxCpltCallback() is executed and user can
00049            add his own code by customization of function pointer @ref HAL_SMBUS_MasterTxCpltCallback()
00050       (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Master_Receive_IT()
00051       (++) At reception end of transfer @ref HAL_SMBUS_MasterRxCpltCallback() is executed and user can
00052            add his own code by customization of function pointer @ref HAL_SMBUS_MasterRxCpltCallback()
00053       (+) Abort a master/host SMBUS process communication with Interrupt using @ref HAL_SMBUS_Master_Abort_IT()
00054       (++) The associated previous transfer callback is called at the end of abort process
00055       (++) mean @ref HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
00056       (++) mean @ref HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
00057       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
00058            using @ref HAL_SMBUS_EnableListen_IT() @ref HAL_SMBUS_DisableListen_IT()
00059       (++) When address slave/device SMBUS match, @ref HAL_SMBUS_AddrCallback() is executed and user can
00060            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
00061       (++) At Listen mode end @ref HAL_SMBUS_ListenCpltCallback() is executed and user can
00062            add his own code by customization of function pointer @ref HAL_SMBUS_ListenCpltCallback()
00063       (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Slave_Transmit_IT()
00064       (++) At transmission end of transfer @ref HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
00065            add his own code by customization of function pointer @ref HAL_SMBUS_SlaveTxCpltCallback()
00066       (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Slave_Receive_IT()
00067       (++) At reception end of transfer @ref HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
00068            add his own code by customization of function pointer @ref HAL_SMBUS_SlaveRxCpltCallback()
00069       (+) Enable/Disable the SMBUS alert mode using @ref HAL_SMBUS_EnableAlert_IT() @ref HAL_SMBUS_DisableAlert_IT()
00070       (++) When SMBUS Alert is generated @ref HAL_SMBUS_ErrorCallback() is executed and user can
00071            add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
00072            to check the Alert Error Code using function @ref HAL_SMBUS_GetError()
00073       (+) Get HAL state machine or error values using @ref HAL_SMBUS_GetState() or @ref HAL_SMBUS_GetError()
00074       (+) In case of transfer Error, @ref HAL_SMBUS_ErrorCallback() function is executed and user can
00075            add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
00076            to check the Error Code using function @ref HAL_SMBUS_GetError()
00077 
00078      *** SMBUS HAL driver macros list ***
00079      ==================================
00080      [..]
00081        Below the list of most used macros in SMBUS HAL driver.
00082 
00083       (+) @ref __HAL_SMBUS_ENABLE:      Enable the SMBUS peripheral
00084       (+) @ref __HAL_SMBUS_DISABLE:     Disable the SMBUS peripheral
00085       (+) @ref __HAL_SMBUS_GET_FLAG:    Check whether the specified SMBUS flag is set or not
00086       (+) @ref __HAL_SMBUS_CLEAR_FLAG:  Clear the specified SMBUS pending flag
00087       (+) @ref __HAL_SMBUS_ENABLE_IT:   Enable the specified SMBUS interrupt
00088       (+) @ref __HAL_SMBUS_DISABLE_IT:  Disable the specified SMBUS interrupt
00089 
00090      *** Callback registration ***
00091      =============================================
00092 
00093      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
00094      allows the user to configure dynamically the driver callbacks.
00095      Use Functions @ref HAL_SMBUS_RegisterCallback() or @ref HAL_SMBUS_RegisterAddrCallback()
00096      to register an interrupt callback.
00097 
00098      Function @ref HAL_SMBUS_RegisterCallback() allows to register following callbacks:
00099        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00100        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00101        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00102        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00103        (+) ListenCpltCallback   : callback for end of listen mode.
00104        (+) ErrorCallback        : callback for error detection.
00105        (+) MspInitCallback      : callback for Msp Init.
00106        (+) MspDeInitCallback    : callback for Msp DeInit.
00107      This function takes as parameters the HAL peripheral handle, the Callback ID
00108      and a pointer to the user callback function.
00109 
00110      For specific callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_RegisterAddrCallback.
00111 
00112      Use function @ref HAL_SMBUS_UnRegisterCallback to reset a callback to the default
00113      weak function.
00114      @ref HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
00115      and the Callback ID.
00116      This function allows to reset following callbacks:
00117        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00118        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00119        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00120        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00121        (+) ListenCpltCallback   : callback for end of listen mode.
00122        (+) ErrorCallback        : callback for error detection.
00123        (+) MspInitCallback      : callback for Msp Init.
00124        (+) MspDeInitCallback    : callback for Msp DeInit.
00125 
00126      For callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_UnRegisterAddrCallback.
00127 
00128      By default, after the @ref HAL_SMBUS_Init() and when the state is @ref HAL_I2C_STATE_RESET
00129      all callbacks are set to the corresponding weak functions:
00130      examples @ref HAL_SMBUS_MasterTxCpltCallback(), @ref HAL_SMBUS_MasterRxCpltCallback().
00131      Exception done for MspInit and MspDeInit functions that are
00132      reset to the legacy weak functions in the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit() only when
00133      these callbacks are null (not registered beforehand).
00134      If MspInit or MspDeInit are not null, the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit()
00135      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00136 
00137      Callbacks can be registered/unregistered in @ref HAL_I2C_STATE_READY state only.
00138      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00139      in @ref HAL_I2C_STATE_READY or @ref HAL_I2C_STATE_RESET state,
00140      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00141      Then, the user first registers the MspInit/MspDeInit user callbacks
00142      using @ref HAL_SMBUS_RegisterCallback() before calling @ref HAL_SMBUS_DeInit()
00143      or @ref HAL_SMBUS_Init() function.
00144 
00145      When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
00146      not defined, the callback registration feature is not available and all callbacks
00147      are set to the corresponding weak functions.
00148 
00149      [..]
00150        (@) You can refer to the SMBUS HAL driver header file for more useful macros
00151 
00152   @endverbatim
00153   ******************************************************************************
00154   * @attention
00155   *
00156   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00157   *
00158   * Redistribution and use in source and binary forms, with or without modification,
00159   * are permitted provided that the following conditions are met:
00160   *   1. Redistributions of source code must retain the above copyright notice,
00161   *      this list of conditions and the following disclaimer.
00162   *   2. Redistributions in binary form must reproduce the above copyright notice,
00163   *      this list of conditions and the following disclaimer in the documentation
00164   *      and/or other materials provided with the distribution.
00165   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00166   *      may be used to endorse or promote products derived from this software
00167   *      without specific prior written permission.
00168   *
00169   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00170   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00171   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00172   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00173   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00174   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00175   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00176   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00177   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00178   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00179   *
00180   ******************************************************************************
00181   */
00182 
00183 /* Includes ------------------------------------------------------------------*/
00184 #include "stm32l4xx_hal.h"
00185 
00186 /** @addtogroup STM32L4xx_HAL_Driver
00187   * @{
00188   */
00189 
00190 /** @defgroup SMBUS SMBUS
00191   * @brief SMBUS HAL module driver
00192   * @{
00193   */
00194 
00195 #ifdef HAL_SMBUS_MODULE_ENABLED
00196 
00197 /* Private typedef -----------------------------------------------------------*/
00198 /* Private constants ---------------------------------------------------------*/
00199 /** @defgroup SMBUS_Private_Define SMBUS Private Constants
00200   * @{
00201   */
00202 #define TIMING_CLEAR_MASK   (0xF0FFFFFFU)      /*!< SMBUS TIMING clear register Mask */
00203 #define HAL_TIMEOUT_ADDR    (10000U)           /*!< 10 s  */
00204 #define HAL_TIMEOUT_BUSY    (25U)              /*!< 25 ms */
00205 #define HAL_TIMEOUT_DIR     (25U)              /*!< 25 ms */
00206 #define HAL_TIMEOUT_RXNE    (25U)              /*!< 25 ms */
00207 #define HAL_TIMEOUT_STOPF   (25U)              /*!< 25 ms */
00208 #define HAL_TIMEOUT_TC      (25U)              /*!< 25 ms */
00209 #define HAL_TIMEOUT_TCR     (25U)              /*!< 25 ms */
00210 #define HAL_TIMEOUT_TXIS    (25U)              /*!< 25 ms */
00211 #define MAX_NBYTE_SIZE      255U
00212 /**
00213   * @}
00214   */
00215 
00216 /* Private macro -------------------------------------------------------------*/
00217 /* Private variables ---------------------------------------------------------*/
00218 /* Private function prototypes -----------------------------------------------*/
00219 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
00220   * @{
00221   */
00222 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
00223 
00224 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
00225 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest);
00226 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus);
00227 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus);
00228 
00229 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus);
00230 
00231 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus);
00232 
00233 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
00234 /**
00235   * @}
00236   */
00237 
00238 /* Exported functions --------------------------------------------------------*/
00239 
00240 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
00241   * @{
00242   */
00243 
00244 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
00245  *  @brief    Initialization and Configuration functions
00246  *
00247 @verbatim
00248  ===============================================================================
00249               ##### Initialization and de-initialization functions #####
00250  ===============================================================================
00251     [..]  This subsection provides a set of functions allowing to initialize and
00252           deinitialize the SMBUSx peripheral:
00253 
00254       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
00255           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
00256 
00257       (+) Call the function HAL_SMBUS_Init() to configure the selected device with
00258           the selected configuration:
00259         (++) Clock Timing
00260         (++) Bus Timeout
00261         (++) Analog Filer mode
00262         (++) Own Address 1
00263         (++) Addressing mode (Master, Slave)
00264         (++) Dual Addressing mode
00265         (++) Own Address 2
00266         (++) Own Address 2 Mask
00267         (++) General call mode
00268         (++) Nostretch mode
00269         (++) Packet Error Check mode
00270         (++) Peripheral mode
00271 
00272 
00273       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
00274           of the selected SMBUSx peripheral.
00275 
00276       (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and
00277           HAL_SMBUS_ConfigDigitalFilter().
00278 
00279 @endverbatim
00280   * @{
00281   */
00282 
00283 /**
00284   * @brief  Initialize the SMBUS according to the specified parameters
00285   *         in the SMBUS_InitTypeDef and initialize the associated handle.
00286   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00287   *                the configuration information for the specified SMBUS.
00288   * @retval HAL status
00289   */
00290 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
00291 {
00292   /* Check the SMBUS handle allocation */
00293   if (hsmbus == NULL)
00294   {
00295     return HAL_ERROR;
00296   }
00297 
00298   /* Check the parameters */
00299   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00300   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
00301   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
00302   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
00303   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
00304   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
00305   assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
00306   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
00307   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
00308   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
00309   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
00310 
00311   if (hsmbus->State == HAL_SMBUS_STATE_RESET)
00312   {
00313     /* Allocate lock resource and initialize it */
00314     hsmbus->Lock = HAL_UNLOCKED;
00315 
00316 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00317     hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00318     hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00319     hsmbus->SlaveTxCpltCallback  = HAL_SMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
00320     hsmbus->SlaveRxCpltCallback  = HAL_SMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
00321     hsmbus->ListenCpltCallback   = HAL_SMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
00322     hsmbus->ErrorCallback        = HAL_SMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
00323     hsmbus->AddrCallback         = HAL_SMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
00324 
00325     if (hsmbus->MspInitCallback == NULL)
00326     {
00327       hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit  */
00328     }
00329 
00330     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00331     hsmbus->MspInitCallback(hsmbus);
00332 #else
00333     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00334     HAL_SMBUS_MspInit(hsmbus);
00335 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00336   }
00337 
00338   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00339 
00340   /* Disable the selected SMBUS peripheral */
00341   __HAL_SMBUS_DISABLE(hsmbus);
00342 
00343   /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
00344   /* Configure SMBUSx: Frequency range */
00345   hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
00346 
00347   /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
00348   /* Configure SMBUSx: Bus Timeout  */
00349   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
00350   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
00351   hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
00352 
00353   /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
00354   /* Configure SMBUSx: Own Address1 and ack own address1 mode */
00355   hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
00356 
00357   if (hsmbus->Init.OwnAddress1 != 0U)
00358   {
00359     if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
00360     {
00361       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
00362     }
00363     else /* SMBUS_ADDRESSINGMODE_10BIT */
00364     {
00365       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
00366     }
00367   }
00368 
00369   /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
00370   /* Configure SMBUSx: Addressing Master mode */
00371   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
00372   {
00373     hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
00374   }
00375   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
00376   /* AUTOEND and NACK bit will be manage during Transfer process */
00377   hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
00378 
00379   /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
00380   /* Configure SMBUSx: Dual mode and Own Address2 */
00381   hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8U));
00382 
00383   /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
00384   /* Configure SMBUSx: Generalcall and NoStretch mode */
00385   hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
00386 
00387   /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
00388   if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE)
00389       && ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)))
00390   {
00391     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
00392   }
00393 
00394   /* Enable the selected SMBUS peripheral */
00395   __HAL_SMBUS_ENABLE(hsmbus);
00396 
00397   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00398   hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
00399   hsmbus->State = HAL_SMBUS_STATE_READY;
00400 
00401   return HAL_OK;
00402 }
00403 
00404 /**
00405   * @brief  DeInitialize the SMBUS peripheral.
00406   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00407   *                the configuration information for the specified SMBUS.
00408   * @retval HAL status
00409   */
00410 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
00411 {
00412   /* Check the SMBUS handle allocation */
00413   if (hsmbus == NULL)
00414   {
00415     return HAL_ERROR;
00416   }
00417 
00418   /* Check the parameters */
00419   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00420 
00421   hsmbus->State = HAL_SMBUS_STATE_BUSY;
00422 
00423   /* Disable the SMBUS Peripheral Clock */
00424   __HAL_SMBUS_DISABLE(hsmbus);
00425 
00426 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00427   if (hsmbus->MspDeInitCallback == NULL)
00428   {
00429     hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit  */
00430   }
00431 
00432   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00433   hsmbus->MspDeInitCallback(hsmbus);
00434 #else
00435   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00436   HAL_SMBUS_MspDeInit(hsmbus);
00437 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00438 
00439   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00440   hsmbus->PreviousState =  HAL_SMBUS_STATE_RESET;
00441   hsmbus->State = HAL_SMBUS_STATE_RESET;
00442 
00443   /* Release Lock */
00444   __HAL_UNLOCK(hsmbus);
00445 
00446   return HAL_OK;
00447 }
00448 
00449 /**
00450   * @brief Initialize the SMBUS MSP.
00451   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00452   *                the configuration information for the specified SMBUS.
00453   * @retval None
00454   */
00455 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
00456 {
00457   /* Prevent unused argument(s) compilation warning */
00458   UNUSED(hsmbus);
00459 
00460   /* NOTE : This function should not be modified, when the callback is needed,
00461             the HAL_SMBUS_MspInit could be implemented in the user file
00462    */
00463 }
00464 
00465 /**
00466   * @brief DeInitialize the SMBUS MSP.
00467   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00468   *                the configuration information for the specified SMBUS.
00469   * @retval None
00470   */
00471 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
00472 {
00473   /* Prevent unused argument(s) compilation warning */
00474   UNUSED(hsmbus);
00475 
00476   /* NOTE : This function should not be modified, when the callback is needed,
00477             the HAL_SMBUS_MspDeInit could be implemented in the user file
00478    */
00479 }
00480 
00481 /**
00482   * @brief  Configure Analog noise filter.
00483   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00484   *                the configuration information for the specified SMBUS.
00485   * @param  AnalogFilter This parameter can be one of the following values:
00486   *         @arg @ref SMBUS_ANALOGFILTER_ENABLE
00487   *         @arg @ref SMBUS_ANALOGFILTER_DISABLE
00488   * @retval HAL status
00489   */
00490 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
00491 {
00492   /* Check the parameters */
00493   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00494   assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
00495 
00496   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00497   {
00498     /* Process Locked */
00499     __HAL_LOCK(hsmbus);
00500 
00501     hsmbus->State = HAL_SMBUS_STATE_BUSY;
00502 
00503     /* Disable the selected SMBUS peripheral */
00504     __HAL_SMBUS_DISABLE(hsmbus);
00505 
00506     /* Reset ANOFF bit */
00507     hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
00508 
00509     /* Set analog filter bit*/
00510     hsmbus->Instance->CR1 |= AnalogFilter;
00511 
00512     __HAL_SMBUS_ENABLE(hsmbus);
00513 
00514     hsmbus->State = HAL_SMBUS_STATE_READY;
00515 
00516     /* Process Unlocked */
00517     __HAL_UNLOCK(hsmbus);
00518 
00519     return HAL_OK;
00520   }
00521   else
00522   {
00523     return HAL_BUSY;
00524   }
00525 }
00526 
00527 /**
00528   * @brief  Configure Digital noise filter.
00529   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00530   *                the configuration information for the specified SMBUS.
00531   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
00532   * @retval HAL status
00533   */
00534 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
00535 {
00536   uint32_t tmpreg = 0U;
00537 
00538   /* Check the parameters */
00539   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
00540   assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
00541 
00542   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00543   {
00544     /* Process Locked */
00545     __HAL_LOCK(hsmbus);
00546 
00547     hsmbus->State = HAL_SMBUS_STATE_BUSY;
00548 
00549     /* Disable the selected SMBUS peripheral */
00550     __HAL_SMBUS_DISABLE(hsmbus);
00551 
00552     /* Get the old register value */
00553     tmpreg = hsmbus->Instance->CR1;
00554 
00555     /* Reset I2C DNF bits [11:8] */
00556     tmpreg &= ~(I2C_CR1_DNF);
00557 
00558     /* Set I2Cx DNF coefficient */
00559     tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos;
00560 
00561     /* Store the new register value */
00562     hsmbus->Instance->CR1 = tmpreg;
00563 
00564     __HAL_SMBUS_ENABLE(hsmbus);
00565 
00566     hsmbus->State = HAL_SMBUS_STATE_READY;
00567 
00568     /* Process Unlocked */
00569     __HAL_UNLOCK(hsmbus);
00570 
00571     return HAL_OK;
00572   }
00573   else
00574   {
00575     return HAL_BUSY;
00576   }
00577 }
00578 
00579 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
00580 /**
00581   * @brief  Register a User SMBUS Callback
00582   *         To be used instead of the weak predefined callback
00583   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00584   *                the configuration information for the specified SMBUS.
00585   * @param  CallbackID ID of the callback to be registered
00586   *         This parameter can be one of the following values:
00587   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00588   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00589   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00590   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00591   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00592   *          @arg @ref HAL_SMBUS_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
00593   *          @arg @ref HAL_SMBUS_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
00594   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
00595   *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
00596   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
00597   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00598   * @param  pCallback pointer to the Callback function
00599   * @retval HAL status
00600   */
00601 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback)
00602 {
00603   HAL_StatusTypeDef status = HAL_OK;
00604 
00605   if (pCallback == NULL)
00606   {
00607     /* Update the error code */
00608     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00609 
00610     return HAL_ERROR;
00611   }
00612   /* Process locked */
00613   __HAL_LOCK(hsmbus);
00614 
00615   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00616   {
00617     switch (CallbackID)
00618     {
00619       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
00620         hsmbus->MasterTxCpltCallback = pCallback;
00621         break;
00622 
00623       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
00624         hsmbus->MasterRxCpltCallback = pCallback;
00625         break;
00626 
00627       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
00628         hsmbus->SlaveTxCpltCallback = pCallback;
00629         break;
00630 
00631       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
00632         hsmbus->SlaveRxCpltCallback = pCallback;
00633         break;
00634 
00635       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
00636         hsmbus->ListenCpltCallback = pCallback;
00637         break;
00638 
00639       case HAL_SMBUS_ERROR_CB_ID :
00640         hsmbus->ErrorCallback = pCallback;
00641         break;
00642 
00643       case HAL_SMBUS_MSPINIT_CB_ID :
00644         hsmbus->MspInitCallback = pCallback;
00645         break;
00646 
00647       case HAL_SMBUS_MSPDEINIT_CB_ID :
00648         hsmbus->MspDeInitCallback = pCallback;
00649         break;
00650 
00651       default :
00652         /* Update the error code */
00653         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00654 
00655         /* Return error status */
00656         status =  HAL_ERROR;
00657         break;
00658     }
00659   }
00660   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
00661   {
00662     switch (CallbackID)
00663     {
00664       case HAL_SMBUS_MSPINIT_CB_ID :
00665         hsmbus->MspInitCallback = pCallback;
00666         break;
00667 
00668       case HAL_SMBUS_MSPDEINIT_CB_ID :
00669         hsmbus->MspDeInitCallback = pCallback;
00670         break;
00671 
00672       default :
00673         /* Update the error code */
00674         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00675 
00676         /* Return error status */
00677         status =  HAL_ERROR;
00678         break;
00679     }
00680   }
00681   else
00682   {
00683     /* Update the error code */
00684     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00685 
00686     /* Return error status */
00687     status =  HAL_ERROR;
00688   }
00689 
00690   /* Release Lock */
00691   __HAL_UNLOCK(hsmbus);
00692   return status;
00693 }
00694 
00695 /**
00696   * @brief  Unregister an SMBUS Callback
00697   *         SMBUS callback is redirected to the weak predefined callback
00698   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00699   *                the configuration information for the specified SMBUS.
00700   * @param  CallbackID ID of the callback to be unregistered
00701   *         This parameter can be one of the following values:
00702   *         This parameter can be one of the following values:
00703   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00704   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00705   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00706   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00707   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00708   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
00709   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
00710   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00711   * @retval HAL status
00712   */
00713 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID)
00714 {
00715   HAL_StatusTypeDef status = HAL_OK;
00716 
00717   /* Process locked */
00718   __HAL_LOCK(hsmbus);
00719 
00720   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00721   {
00722     switch (CallbackID)
00723     {
00724       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
00725         hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00726         break;
00727 
00728       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
00729         hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00730         break;
00731 
00732       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
00733         hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
00734         break;
00735 
00736       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
00737         hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
00738         break;
00739 
00740       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
00741         hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
00742         break;
00743 
00744       case HAL_SMBUS_ERROR_CB_ID :
00745         hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
00746         break;
00747 
00748       case HAL_SMBUS_MSPINIT_CB_ID :
00749         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
00750         break;
00751 
00752       case HAL_SMBUS_MSPDEINIT_CB_ID :
00753         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00754         break;
00755 
00756       default :
00757         /* Update the error code */
00758         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00759 
00760         /* Return error status */
00761         status =  HAL_ERROR;
00762         break;
00763     }
00764   }
00765   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
00766   {
00767     switch (CallbackID)
00768     {
00769       case HAL_SMBUS_MSPINIT_CB_ID :
00770         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
00771         break;
00772 
00773       case HAL_SMBUS_MSPDEINIT_CB_ID :
00774         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00775         break;
00776 
00777       default :
00778         /* Update the error code */
00779         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00780 
00781         /* Return error status */
00782         status =  HAL_ERROR;
00783         break;
00784     }
00785   }
00786   else
00787   {
00788     /* Update the error code */
00789     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00790 
00791     /* Return error status */
00792     status =  HAL_ERROR;
00793   }
00794 
00795   /* Release Lock */
00796   __HAL_UNLOCK(hsmbus);
00797   return status;
00798 }
00799 
00800 /**
00801   * @brief  Register the Slave Address Match SMBUS Callback
00802   *         To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
00803   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00804   *                the configuration information for the specified SMBUS.
00805   * @param  pCallback pointer to the Address Match Callback function
00806   * @retval HAL status
00807   */
00808 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback)
00809 {
00810   HAL_StatusTypeDef status = HAL_OK;
00811 
00812   if (pCallback == NULL)
00813   {
00814     return HAL_ERROR;
00815   }
00816   /* Process locked */
00817   __HAL_LOCK(hsmbus);
00818 
00819   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00820   {
00821     hsmbus->AddrCallback = pCallback;
00822   }
00823   else
00824   {
00825     /* Update the error code */
00826     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00827 
00828     /* Return error status */
00829     status =  HAL_ERROR;
00830   }
00831 
00832   /* Release Lock */
00833   __HAL_UNLOCK(hsmbus);
00834   return status;
00835 }
00836 
00837 /**
00838   * @brief  UnRegister the Slave Address Match SMBUS Callback
00839   *         Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
00840   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00841   *                the configuration information for the specified SMBUS.
00842   * @retval HAL status
00843   */
00844 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
00845 {
00846   HAL_StatusTypeDef status = HAL_OK;
00847 
00848   /* Process locked */
00849   __HAL_LOCK(hsmbus);
00850 
00851   if (HAL_SMBUS_STATE_READY == hsmbus->State)
00852   {
00853     hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback  */
00854   }
00855   else
00856   {
00857     /* Update the error code */
00858     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
00859 
00860     /* Return error status */
00861     status =  HAL_ERROR;
00862   }
00863 
00864   /* Release Lock */
00865   __HAL_UNLOCK(hsmbus);
00866   return status;
00867 }
00868 
00869 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
00870 
00871 /**
00872   * @}
00873   */
00874 
00875 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
00876  *  @brief   Data transfers functions
00877  *
00878 @verbatim
00879  ===============================================================================
00880                       ##### IO operation functions #####
00881  ===============================================================================
00882     [..]
00883     This subsection provides a set of functions allowing to manage the SMBUS data
00884     transfers.
00885 
00886     (#) Blocking mode function to check if device is ready for usage is :
00887         (++) HAL_SMBUS_IsDeviceReady()
00888 
00889     (#) There is only one mode of transfer:
00890        (++) Non-Blocking mode : The communication is performed using Interrupts.
00891             These functions return the status of the transfer startup.
00892             The end of the data processing will be indicated through the
00893             dedicated SMBUS IRQ when using Interrupt mode.
00894 
00895     (#) Non-Blocking mode functions with Interrupt are :
00896         (++) HAL_SMBUS_Master_Transmit_IT()
00897         (++) HAL_SMBUS_Master_Receive_IT()
00898         (++) HAL_SMBUS_Slave_Transmit_IT()
00899         (++) HAL_SMBUS_Slave_Receive_IT()
00900         (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT()
00901         (++) HAL_SMBUS_DisableListen_IT()
00902         (++) HAL_SMBUS_EnableAlert_IT()
00903         (++) HAL_SMBUS_DisableAlert_IT()
00904 
00905     (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
00906         (++) HAL_SMBUS_MasterTxCpltCallback()
00907         (++) HAL_SMBUS_MasterRxCpltCallback()
00908         (++) HAL_SMBUS_SlaveTxCpltCallback()
00909         (++) HAL_SMBUS_SlaveRxCpltCallback()
00910         (++) HAL_SMBUS_AddrCallback()
00911         (++) HAL_SMBUS_ListenCpltCallback()
00912         (++) HAL_SMBUS_ErrorCallback()
00913 
00914 @endverbatim
00915   * @{
00916   */
00917 
00918 /**
00919   * @brief  Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
00920   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
00921   *                the configuration information for the specified SMBUS.
00922   * @param  DevAddress Target device address: The device 7 bits address value
00923   *         in datasheet must be shifted to the left before calling the interface
00924   * @param  pData Pointer to data buffer
00925   * @param  Size Amount of data to be sent
00926   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
00927   * @retval HAL status
00928   */
00929 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00930 {
00931   /* Check the parameters */
00932   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00933 
00934   if (hsmbus->State == HAL_SMBUS_STATE_READY)
00935   {
00936     /* Process Locked */
00937     __HAL_LOCK(hsmbus);
00938 
00939     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
00940     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
00941     /* Prepare transfer parameters */
00942     hsmbus->pBuffPtr = pData;
00943     hsmbus->XferCount = Size;
00944     hsmbus->XferOptions = XferOptions;
00945 
00946     /* In case of Quick command, remove autoend mode */
00947     /* Manage the stop generation by software */
00948     if (hsmbus->pBuffPtr == NULL)
00949     {
00950       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
00951     }
00952 
00953     if (Size > MAX_NBYTE_SIZE)
00954     {
00955       hsmbus->XferSize = MAX_NBYTE_SIZE;
00956     }
00957     else
00958     {
00959       hsmbus->XferSize = Size;
00960     }
00961 
00962     /* Send Slave Address */
00963     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
00964     if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
00965     {
00966       SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
00967     }
00968     else
00969     {
00970       /* If transfer direction not change, do not generate Restart Condition */
00971       /* Mean Previous state is same as current state */
00972       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
00973       {
00974         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
00975       }
00976       /* Else transfer direction change, so generate Restart with new transfer direction */
00977       else
00978       {
00979         /* Convert OTHER_xxx XferOptions if any */
00980         SMBUS_ConvertOtherXferOptions(hsmbus);
00981 
00982         /* Handle Transfer */
00983         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
00984       }
00985 
00986       /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
00987       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
00988       if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
00989       {
00990         hsmbus->XferSize--;
00991         hsmbus->XferCount--;
00992       }
00993     }
00994 
00995     /* Process Unlocked */
00996     __HAL_UNLOCK(hsmbus);
00997 
00998     /* Note : The SMBUS interrupts must be enabled after unlocking current process
00999               to avoid the risk of SMBUS interrupt handle execution before current
01000               process unlock */
01001     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
01002 
01003     return HAL_OK;
01004   }
01005   else
01006   {
01007     return HAL_BUSY;
01008   }
01009 }
01010 
01011 /**
01012   * @brief  Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
01013   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01014   *                the configuration information for the specified SMBUS.
01015   * @param  DevAddress Target device address: The device 7 bits address value
01016   *         in datasheet must be shifted to the left before calling the interface
01017   * @param  pData Pointer to data buffer
01018   * @param  Size Amount of data to be sent
01019   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
01020   * @retval HAL status
01021   */
01022 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
01023 {
01024   /* Check the parameters */
01025   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01026 
01027   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01028   {
01029     /* Process Locked */
01030     __HAL_LOCK(hsmbus);
01031 
01032     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
01033     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01034 
01035     /* Prepare transfer parameters */
01036     hsmbus->pBuffPtr = pData;
01037     hsmbus->XferCount = Size;
01038     hsmbus->XferOptions = XferOptions;
01039 
01040     /* In case of Quick command, remove autoend mode */
01041     /* Manage the stop generation by software */
01042     if (hsmbus->pBuffPtr == NULL)
01043     {
01044       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
01045     }
01046 
01047     if (Size > MAX_NBYTE_SIZE)
01048     {
01049       hsmbus->XferSize = MAX_NBYTE_SIZE;
01050     }
01051     else
01052     {
01053       hsmbus->XferSize = Size;
01054     }
01055 
01056     /* Send Slave Address */
01057     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
01058     if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
01059     {
01060       SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
01061     }
01062     else
01063     {
01064       /* If transfer direction not change, do not generate Restart Condition */
01065       /* Mean Previous state is same as current state */
01066       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(hsmbus->XferOptions) == 0))
01067       {
01068         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01069       }
01070       /* Else transfer direction change, so generate Restart with new transfer direction */
01071       else
01072       {
01073         /* Convert OTHER_xxx XferOptions if any */
01074         SMBUS_ConvertOtherXferOptions(hsmbus);
01075 
01076         /* Handle Transfer */
01077         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
01078       }
01079     }
01080 
01081     /* Process Unlocked */
01082     __HAL_UNLOCK(hsmbus);
01083 
01084     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01085               to avoid the risk of SMBUS interrupt handle execution before current
01086               process unlock */
01087     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
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   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01109   {
01110     /* Process Locked */
01111     __HAL_LOCK(hsmbus);
01112 
01113     /* Keep the same state as previous */
01114     /* to perform as well the call of the corresponding end of transfer callback */
01115     if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01116     {
01117       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
01118     }
01119     else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01120     {
01121       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
01122     }
01123     else
01124     {
01125       /* Wrong usage of abort function */
01126       /* This function should be used only in case of abort monitored by master device */
01127       return HAL_ERROR;
01128     }
01129     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01130 
01131     /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
01132     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
01133     SMBUS_TransferConfig(hsmbus, DevAddress, 1U, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
01134 
01135     /* Process Unlocked */
01136     __HAL_UNLOCK(hsmbus);
01137 
01138     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01139               to avoid the risk of SMBUS interrupt handle execution before current
01140               process unlock */
01141     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01142     {
01143       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
01144     }
01145     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01146     {
01147       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
01148     }
01149     else
01150     {
01151       /* Nothing to do */
01152     }
01153 
01154     return HAL_OK;
01155   }
01156   else
01157   {
01158     return HAL_BUSY;
01159   }
01160 }
01161 
01162 /**
01163   * @brief  Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
01164   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01165   *                the configuration information for the specified SMBUS.
01166   * @param  pData Pointer to data buffer
01167   * @param  Size Amount of data to be sent
01168   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
01169   * @retval HAL status
01170   */
01171 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
01172 {
01173   /* Check the parameters */
01174   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01175 
01176   if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
01177   {
01178     if ((pData == NULL) || (Size == 0U))
01179     {
01180       return  HAL_ERROR;
01181     }
01182 
01183     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
01184     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
01185 
01186     /* Process Locked */
01187     __HAL_LOCK(hsmbus);
01188 
01189     hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN);
01190     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01191 
01192     /* Set SBC bit to manage Acknowledge at each bit */
01193     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
01194 
01195     /* Enable Address Acknowledge */
01196     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
01197 
01198     /* Prepare transfer parameters */
01199     hsmbus->pBuffPtr = pData;
01200     hsmbus->XferCount = Size;
01201     hsmbus->XferOptions = XferOptions;
01202 
01203     /* Convert OTHER_xxx XferOptions if any */
01204     SMBUS_ConvertOtherXferOptions(hsmbus);
01205 
01206     if (Size > MAX_NBYTE_SIZE)
01207     {
01208       hsmbus->XferSize = MAX_NBYTE_SIZE;
01209     }
01210     else
01211     {
01212       hsmbus->XferSize = Size;
01213     }
01214 
01215     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
01216     if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
01217     {
01218       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
01219     }
01220     else
01221     {
01222       /* Set NBYTE to transmit */
01223       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01224 
01225       /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
01226       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
01227       if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
01228       {
01229         hsmbus->XferSize--;
01230         hsmbus->XferCount--;
01231       }
01232     }
01233 
01234     /* Clear ADDR flag after prepare the transfer parameters */
01235     /* This action will generate an acknowledge to the HOST */
01236     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
01237 
01238     /* Process Unlocked */
01239     __HAL_UNLOCK(hsmbus);
01240 
01241     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01242               to avoid the risk of SMBUS interrupt handle execution before current
01243               process unlock */
01244     /* REnable ADDR interrupt */
01245     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
01246 
01247     return HAL_OK;
01248   }
01249   else
01250   {
01251     return HAL_ERROR;
01252   }
01253 }
01254 
01255 /**
01256   * @brief  Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
01257   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01258   *                the configuration information for the specified SMBUS.
01259   * @param  pData Pointer to data buffer
01260   * @param  Size Amount of data to be sent
01261   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
01262   * @retval HAL status
01263   */
01264 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
01265 {
01266   /* Check the parameters */
01267   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01268 
01269   if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
01270   {
01271     if ((pData == NULL) || (Size == 0U))
01272     {
01273       return  HAL_ERROR;
01274     }
01275 
01276     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
01277     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
01278 
01279     /* Process Locked */
01280     __HAL_LOCK(hsmbus);
01281 
01282     hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN);
01283     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01284 
01285     /* Set SBC bit to manage Acknowledge at each bit */
01286     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
01287 
01288     /* Enable Address Acknowledge */
01289     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
01290 
01291     /* Prepare transfer parameters */
01292     hsmbus->pBuffPtr = pData;
01293     hsmbus->XferSize = Size;
01294     hsmbus->XferCount = Size;
01295     hsmbus->XferOptions = XferOptions;
01296 
01297     /* Convert OTHER_xxx XferOptions if any */
01298     SMBUS_ConvertOtherXferOptions(hsmbus);
01299 
01300     /* Set NBYTE to receive */
01301     /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
01302     /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
01303     /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
01304     /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
01305     if (((SMBUS_GET_PEC_MODE(hsmbus) != RESET) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U))
01306     {
01307       SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01308     }
01309     else
01310     {
01311       SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
01312     }
01313 
01314     /* Clear ADDR flag after prepare the transfer parameters */
01315     /* This action will generate an acknowledge to the HOST */
01316     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
01317 
01318     /* Process Unlocked */
01319     __HAL_UNLOCK(hsmbus);
01320 
01321     /* Note : The SMBUS interrupts must be enabled after unlocking current process
01322               to avoid the risk of SMBUS interrupt handle execution before current
01323               process unlock */
01324     /* REnable ADDR interrupt */
01325     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
01326 
01327     return HAL_OK;
01328   }
01329   else
01330   {
01331     return HAL_ERROR;
01332   }
01333 }
01334 
01335 /**
01336   * @brief  Enable the Address listen mode with Interrupt.
01337   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01338   *                the configuration information for the specified SMBUS.
01339   * @retval HAL status
01340   */
01341 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
01342 {
01343   hsmbus->State = HAL_SMBUS_STATE_LISTEN;
01344 
01345   /* Enable the Address Match interrupt */
01346   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
01347 
01348   return HAL_OK;
01349 }
01350 
01351 /**
01352   * @brief  Disable the Address listen mode with Interrupt.
01353   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01354   *                the configuration information for the specified SMBUS.
01355   * @retval HAL status
01356   */
01357 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
01358 {
01359   /* Disable Address listen mode only if a transfer is not ongoing */
01360   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
01361   {
01362     hsmbus->State = HAL_SMBUS_STATE_READY;
01363 
01364     /* Disable the Address Match interrupt */
01365     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
01366 
01367     return HAL_OK;
01368   }
01369   else
01370   {
01371     return HAL_BUSY;
01372   }
01373 }
01374 
01375 /**
01376   * @brief  Enable the SMBUS alert mode with Interrupt.
01377   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01378   *                the configuration information for the specified SMBUSx peripheral.
01379   * @retval HAL status
01380   */
01381 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
01382 {
01383   /* Enable SMBus alert */
01384   hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
01385 
01386   /* Clear ALERT flag */
01387   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
01388 
01389   /* Enable Alert Interrupt */
01390   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
01391 
01392   return HAL_OK;
01393 }
01394 /**
01395   * @brief  Disable the SMBUS alert mode with Interrupt.
01396   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01397   *                the configuration information for the specified SMBUSx peripheral.
01398   * @retval HAL status
01399   */
01400 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
01401 {
01402   /* Enable SMBus alert */
01403   hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
01404 
01405   /* Disable Alert Interrupt */
01406   SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
01407 
01408   return HAL_OK;
01409 }
01410 
01411 /**
01412   * @brief  Check if target device is ready for communication.
01413   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01414   *                the configuration information for the specified SMBUS.
01415   * @param  DevAddress Target device address: The device 7 bits address value
01416   *         in datasheet must be shifted to the left before calling the interface
01417   * @param  Trials Number of trials
01418   * @param  Timeout Timeout duration
01419   * @retval HAL status
01420   */
01421 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
01422 {
01423   uint32_t tickstart;
01424 
01425   __IO uint32_t SMBUS_Trials = 0U;
01426 
01427   if (hsmbus->State == HAL_SMBUS_STATE_READY)
01428   {
01429     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
01430     {
01431       return HAL_BUSY;
01432     }
01433 
01434     /* Process Locked */
01435     __HAL_LOCK(hsmbus);
01436 
01437     hsmbus->State = HAL_SMBUS_STATE_BUSY;
01438     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
01439 
01440     do
01441     {
01442       /* Generate Start */
01443       hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress);
01444 
01445       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01446       /* Wait until STOPF flag is set or a NACK flag is set*/
01447       tickstart = HAL_GetTick();
01448       while ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) == RESET) && (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) && (hsmbus->State != HAL_SMBUS_STATE_TIMEOUT))
01449       {
01450         if (Timeout != HAL_MAX_DELAY)
01451         {
01452           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01453           {
01454             /* Device is ready */
01455             hsmbus->State = HAL_SMBUS_STATE_READY;
01456 
01457             /* Process Unlocked */
01458             __HAL_UNLOCK(hsmbus);
01459             return HAL_TIMEOUT;
01460           }
01461         }
01462       }
01463 
01464       /* Check if the NACKF flag has not been set */
01465       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
01466       {
01467         /* Wait until STOPF flag is reset */
01468         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01469         {
01470           return HAL_TIMEOUT;
01471         }
01472 
01473         /* Clear STOP Flag */
01474         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01475 
01476         /* Device is ready */
01477         hsmbus->State = HAL_SMBUS_STATE_READY;
01478 
01479         /* Process Unlocked */
01480         __HAL_UNLOCK(hsmbus);
01481 
01482         return HAL_OK;
01483       }
01484       else
01485       {
01486         /* Wait until STOPF flag is reset */
01487         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01488         {
01489           return HAL_TIMEOUT;
01490         }
01491 
01492         /* Clear NACK Flag */
01493         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01494 
01495         /* Clear STOP Flag, auto generated with autoend*/
01496         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01497       }
01498 
01499       /* Check if the maximum allowed number of trials has been reached */
01500       if (SMBUS_Trials++ == Trials)
01501       {
01502         /* Generate Stop */
01503         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
01504 
01505         /* Wait until STOPF flag is reset */
01506         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01507         {
01508           return HAL_TIMEOUT;
01509         }
01510 
01511         /* Clear STOP Flag */
01512         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01513       }
01514     }
01515     while (SMBUS_Trials < Trials);
01516 
01517     hsmbus->State = HAL_SMBUS_STATE_READY;
01518 
01519     /* Process Unlocked */
01520     __HAL_UNLOCK(hsmbus);
01521 
01522     return HAL_TIMEOUT;
01523   }
01524   else
01525   {
01526     return HAL_BUSY;
01527   }
01528 }
01529 /**
01530   * @}
01531   */
01532 
01533 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
01534  * @{
01535  */
01536 
01537 /**
01538   * @brief  Handle SMBUS event interrupt request.
01539   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01540   *                the configuration information for the specified SMBUS.
01541   * @retval None
01542   */
01543 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01544 {
01545   /* Use a local variable to store the current ISR flags */
01546   /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
01547   uint32_t tmpisrvalue = SMBUS_GET_ISR_REG(hsmbus);
01548 
01549   /* SMBUS in mode Transmitter ---------------------------------------------------*/
01550   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET))
01551   {
01552     /* Slave mode selected */
01553     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
01554     {
01555       (void)SMBUS_Slave_ISR(hsmbus);
01556     }
01557     /* Master mode selected */
01558     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01559     {
01560       (void)SMBUS_Master_ISR(hsmbus);
01561     }
01562     else
01563     {
01564       /* Nothing to do */
01565     }
01566   }
01567 
01568   /* SMBUS in mode Receiver ----------------------------------------------------*/
01569   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)) && (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET))
01570   {
01571     /* Slave mode selected */
01572     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
01573     {
01574       (void)SMBUS_Slave_ISR(hsmbus);
01575     }
01576     /* Master mode selected */
01577     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01578     {
01579       (void)SMBUS_Master_ISR(hsmbus);
01580     }
01581     else
01582     {
01583       /* Nothing to do */
01584     }
01585   }
01586 
01587   /* SMBUS in mode Listener Only --------------------------------------------------*/
01588   if (((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))
01589       && ((__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_ADDRI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_STOPI) != RESET) || (__HAL_SMBUS_GET_IT_SOURCE(hsmbus, SMBUS_IT_NACKI) != RESET)))
01590   {
01591     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
01592     {
01593       (void)SMBUS_Slave_ISR(hsmbus);
01594     }
01595   }
01596 }
01597 
01598 /**
01599   * @brief  Handle SMBUS error interrupt request.
01600   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01601   *                the configuration information for the specified SMBUS.
01602   * @retval None
01603   */
01604 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
01605 {
01606   SMBUS_ITErrorHandler(hsmbus);
01607 }
01608 
01609 /**
01610   * @brief  Master Tx Transfer completed callback.
01611   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01612   *                the configuration information for the specified SMBUS.
01613   * @retval None
01614   */
01615 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01616 {
01617   /* Prevent unused argument(s) compilation warning */
01618   UNUSED(hsmbus);
01619 
01620   /* NOTE : This function should not be modified, when the callback is needed,
01621             the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
01622    */
01623 }
01624 
01625 /**
01626   * @brief  Master Rx Transfer completed callback.
01627   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01628   *                the configuration information for the specified SMBUS.
01629   * @retval None
01630   */
01631 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01632 {
01633   /* Prevent unused argument(s) compilation warning */
01634   UNUSED(hsmbus);
01635 
01636   /* NOTE : This function should not be modified, when the callback is needed,
01637             the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
01638    */
01639 }
01640 
01641 /** @brief  Slave Tx Transfer completed callback.
01642   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01643   *                the configuration information for the specified SMBUS.
01644   * @retval None
01645   */
01646 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01647 {
01648   /* Prevent unused argument(s) compilation warning */
01649   UNUSED(hsmbus);
01650 
01651   /* NOTE : This function should not be modified, when the callback is needed,
01652             the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
01653    */
01654 }
01655 
01656 /**
01657   * @brief  Slave Rx Transfer completed callback.
01658   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01659   *                the configuration information for the specified SMBUS.
01660   * @retval None
01661   */
01662 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01663 {
01664   /* Prevent unused argument(s) compilation warning */
01665   UNUSED(hsmbus);
01666 
01667   /* NOTE : This function should not be modified, when the callback is needed,
01668             the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
01669    */
01670 }
01671 
01672 /**
01673   * @brief  Slave Address Match callback.
01674   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01675   *                the configuration information for the specified SMBUS.
01676   * @param  TransferDirection Master request Transfer Direction (Write/Read)
01677   * @param  AddrMatchCode Address Match Code
01678   * @retval None
01679   */
01680 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
01681 {
01682   /* Prevent unused argument(s) compilation warning */
01683   UNUSED(hsmbus);
01684   UNUSED(TransferDirection);
01685   UNUSED(AddrMatchCode);
01686 
01687   /* NOTE : This function should not be modified, when the callback is needed,
01688             the HAL_SMBUS_AddrCallback() could be implemented in the user file
01689    */
01690 }
01691 
01692 /**
01693   * @brief  Listen Complete callback.
01694   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01695   *                the configuration information for the specified SMBUS.
01696   * @retval None
01697   */
01698 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
01699 {
01700   /* Prevent unused argument(s) compilation warning */
01701   UNUSED(hsmbus);
01702 
01703   /* NOTE : This function should not be modified, when the callback is needed,
01704             the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
01705    */
01706 }
01707 
01708 /**
01709   * @brief  SMBUS error callback.
01710   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01711   *                the configuration information for the specified SMBUS.
01712   * @retval None
01713   */
01714 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
01715 {
01716   /* Prevent unused argument(s) compilation warning */
01717   UNUSED(hsmbus);
01718 
01719   /* NOTE : This function should not be modified, when the callback is needed,
01720             the HAL_SMBUS_ErrorCallback() could be implemented in the user file
01721    */
01722 }
01723 
01724 /**
01725   * @}
01726   */
01727 
01728 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
01729  *  @brief   Peripheral State and Errors functions
01730  *
01731 @verbatim
01732  ===============================================================================
01733             ##### Peripheral State and Errors functions #####
01734  ===============================================================================
01735     [..]
01736     This subsection permits to get in run-time the status of the peripheral
01737     and the data flow.
01738 
01739 @endverbatim
01740   * @{
01741   */
01742 
01743 /**
01744   * @brief  Return the SMBUS handle state.
01745   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01746   *                the configuration information for the specified SMBUS.
01747   * @retval HAL state
01748   */
01749 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
01750 {
01751   /* Return SMBUS handle state */
01752   return hsmbus->State;
01753 }
01754 
01755 /**
01756 * @brief  Return the SMBUS error code.
01757   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01758   *              the configuration information for the specified SMBUS.
01759 * @retval SMBUS Error Code
01760 */
01761 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
01762 {
01763   return hsmbus->ErrorCode;
01764 }
01765 
01766 /**
01767   * @}
01768   */
01769 
01770 /**
01771   * @}
01772   */
01773 
01774 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
01775  *  @brief   Data transfers Private functions
01776   * @{
01777   */
01778 
01779 /**
01780   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
01781   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
01782   *                the configuration information for the specified SMBUS.
01783   * @retval HAL status
01784   */
01785 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus)
01786 {
01787   uint16_t DevAddress;
01788 
01789   /* Process Locked */
01790   __HAL_LOCK(hsmbus);
01791 
01792   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
01793   {
01794     /* Clear NACK Flag */
01795     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
01796 
01797     /* Set corresponding Error Code */
01798     /* No need to generate STOP, it is automatically done */
01799     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
01800 
01801     /* Process Unlocked */
01802     __HAL_UNLOCK(hsmbus);
01803 
01804     /* Call the Error callback to inform upper layer */
01805 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01806     hsmbus->ErrorCallback(hsmbus);
01807 #else
01808     HAL_SMBUS_ErrorCallback(hsmbus);
01809 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01810   }
01811   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
01812   {
01813     /* Check and treat errors if errors occurs during STOP process */
01814     SMBUS_ITErrorHandler(hsmbus);
01815 
01816     /* Call the corresponding callback to inform upper layer of End of Transfer */
01817     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01818     {
01819       /* Disable Interrupt */
01820       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01821 
01822       /* Clear STOP Flag */
01823       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01824 
01825       /* Clear Configuration Register 2 */
01826       SMBUS_RESET_CR2(hsmbus);
01827 
01828       /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
01829       /* Disable the selected SMBUS peripheral */
01830       __HAL_SMBUS_DISABLE(hsmbus);
01831 
01832       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01833       hsmbus->State = HAL_SMBUS_STATE_READY;
01834 
01835       /* Process Unlocked */
01836       __HAL_UNLOCK(hsmbus);
01837 
01838       /* REenable the selected SMBUS peripheral */
01839       __HAL_SMBUS_ENABLE(hsmbus);
01840 
01841       /* Call the corresponding callback to inform upper layer of End of Transfer */
01842 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01843       hsmbus->MasterTxCpltCallback(hsmbus);
01844 #else
01845       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01846 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01847     }
01848     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01849     {
01850       /* Store Last receive data if any */
01851       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
01852       {
01853         /* Read data from RXDR */
01854         (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
01855 
01856         if ((hsmbus->XferSize > 0U))
01857         {
01858           hsmbus->XferSize--;
01859           hsmbus->XferCount--;
01860         }
01861       }
01862 
01863       /* Disable Interrupt */
01864       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01865 
01866       /* Clear STOP Flag */
01867       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
01868 
01869       /* Clear Configuration Register 2 */
01870       SMBUS_RESET_CR2(hsmbus);
01871 
01872       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
01873       hsmbus->State = HAL_SMBUS_STATE_READY;
01874 
01875       /* Process Unlocked */
01876       __HAL_UNLOCK(hsmbus);
01877 
01878       /* Call the corresponding callback to inform upper layer of End of Transfer */
01879 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01880       hsmbus->MasterRxCpltCallback(hsmbus);
01881 #else
01882       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
01883 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01884     }
01885     else
01886     {
01887       /* Nothing to do */
01888     }
01889   }
01890   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
01891   {
01892     /* Read data from RXDR */
01893     (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
01894     hsmbus->XferSize--;
01895     hsmbus->XferCount--;
01896   }
01897   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
01898   {
01899     /* Write data to TXDR */
01900     hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
01901     hsmbus->XferSize--;
01902     hsmbus->XferCount--;
01903   }
01904   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET)
01905   {
01906     if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
01907     {
01908       DevAddress = (hsmbus->Instance->CR2 & I2C_CR2_SADD);
01909 
01910       if (hsmbus->XferCount > MAX_NBYTE_SIZE)
01911       {
01912         SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
01913         hsmbus->XferSize = MAX_NBYTE_SIZE;
01914       }
01915       else
01916       {
01917         hsmbus->XferSize = hsmbus->XferCount;
01918         SMBUS_TransferConfig(hsmbus, DevAddress, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
01919         /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
01920         /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
01921         if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
01922         {
01923           hsmbus->XferSize--;
01924           hsmbus->XferCount--;
01925         }
01926       }
01927     }
01928     else if ((hsmbus->XferSize == 0U) && (hsmbus->XferCount == 0U))
01929     {
01930       /* Call TxCpltCallback() if no stop mode is set */
01931       if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
01932       {
01933         /* Call the corresponding callback to inform upper layer of End of Transfer */
01934         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01935         {
01936           /* Disable Interrupt */
01937           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01938           hsmbus->PreviousState = hsmbus->State;
01939           hsmbus->State = HAL_SMBUS_STATE_READY;
01940 
01941           /* Process Unlocked */
01942           __HAL_UNLOCK(hsmbus);
01943 
01944           /* Call the corresponding callback to inform upper layer of End of Transfer */
01945 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01946           hsmbus->MasterTxCpltCallback(hsmbus);
01947 #else
01948           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
01949 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01950         }
01951         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
01952         {
01953           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
01954           hsmbus->PreviousState = hsmbus->State;
01955           hsmbus->State = HAL_SMBUS_STATE_READY;
01956 
01957           /* Process Unlocked */
01958           __HAL_UNLOCK(hsmbus);
01959 
01960           /* Call the corresponding callback to inform upper layer of End of Transfer */
01961 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
01962           hsmbus->MasterRxCpltCallback(hsmbus);
01963 #else
01964           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
01965 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
01966         }
01967         else
01968         {
01969           /* Nothing to do */
01970         }
01971       }
01972     }
01973     else
01974     {
01975       /* Nothing to do */
01976     }
01977   }
01978   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TC) != RESET)
01979   {
01980     if (hsmbus->XferCount == 0U)
01981     {
01982       /* Specific use case for Quick command */
01983       if (hsmbus->pBuffPtr == NULL)
01984       {
01985         /* Generate a Stop command */
01986         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
01987       }
01988       /* Call TxCpltCallback() if no stop mode is set */
01989       else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
01990       {
01991         /* No Generate Stop, to permit restart mode */
01992         /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
01993 
01994         /* Call the corresponding callback to inform upper layer of End of Transfer */
01995         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
01996         {
01997           /* Disable Interrupt */
01998           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
01999           hsmbus->PreviousState = hsmbus->State;
02000           hsmbus->State = HAL_SMBUS_STATE_READY;
02001 
02002           /* Process Unlocked */
02003           __HAL_UNLOCK(hsmbus);
02004 
02005           /* Call the corresponding callback to inform upper layer of End of Transfer */
02006 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02007           hsmbus->MasterTxCpltCallback(hsmbus);
02008 #else
02009           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
02010 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02011         }
02012         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
02013         {
02014           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
02015           hsmbus->PreviousState = hsmbus->State;
02016           hsmbus->State = HAL_SMBUS_STATE_READY;
02017 
02018           /* Process Unlocked */
02019           __HAL_UNLOCK(hsmbus);
02020 
02021           /* Call the corresponding callback to inform upper layer of End of Transfer */
02022 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02023           hsmbus->MasterRxCpltCallback(hsmbus);
02024 #else
02025           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
02026 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02027         }
02028         else
02029         {
02030           /* Nothing to do */
02031         }
02032       }
02033       else
02034       {
02035         /* Nothing to do */
02036       }
02037     }
02038   }
02039   else
02040   {
02041     /* Nothing to do */
02042   }
02043 
02044   /* Process Unlocked */
02045   __HAL_UNLOCK(hsmbus);
02046 
02047   return HAL_OK;
02048 }
02049 /**
02050   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
02051   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02052   *                the configuration information for the specified SMBUS.
02053   * @retval HAL status
02054   */
02055 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus)
02056 {
02057   uint8_t TransferDirection;
02058   uint16_t SlaveAddrCode;
02059 
02060   /* Process Locked */
02061   __HAL_LOCK(hsmbus);
02062 
02063   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) != RESET)
02064   {
02065     /* Check that SMBUS transfer finished */
02066     /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
02067     /* Mean XferCount == 0*/
02068     /* So clear Flag NACKF only */
02069     if (hsmbus->XferCount == 0U)
02070     {
02071       /* Clear NACK Flag */
02072       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
02073 
02074       /* Process Unlocked */
02075       __HAL_UNLOCK(hsmbus);
02076     }
02077     else
02078     {
02079       /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
02080       /* Clear NACK Flag */
02081       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
02082 
02083       /* Set HAL State to "Idle" State, mean to LISTEN state */
02084       /* So reset Slave Busy state */
02085       hsmbus->PreviousState = hsmbus->State;
02086       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
02087       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
02088 
02089       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
02090       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
02091 
02092       /* Set ErrorCode corresponding to a Non-Acknowledge */
02093       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
02094 
02095       /* Process Unlocked */
02096       __HAL_UNLOCK(hsmbus);
02097 
02098       /* Call the Error callback to inform upper layer */
02099 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02100       hsmbus->ErrorCallback(hsmbus);
02101 #else
02102       HAL_SMBUS_ErrorCallback(hsmbus);
02103 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02104     }
02105   }
02106   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) != RESET)
02107   {
02108     TransferDirection = SMBUS_GET_DIR(hsmbus);
02109     SlaveAddrCode = SMBUS_GET_ADDR_MATCH(hsmbus);
02110 
02111     /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
02112     /* Other ADDRInterrupt will be treat in next Listen usecase */
02113     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
02114 
02115     /* Process Unlocked */
02116     __HAL_UNLOCK(hsmbus);
02117 
02118     /* Call Slave Addr callback */
02119 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02120     hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
02121 #else
02122     HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
02123 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02124   }
02125   else if ((__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) || (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TCR) != RESET))
02126   {
02127     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
02128     {
02129       /* Read data from RXDR */
02130       (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
02131       hsmbus->XferSize--;
02132       hsmbus->XferCount--;
02133 
02134       if (hsmbus->XferCount == 1U)
02135       {
02136         /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
02137         /* or only the last Byte of Transfer */
02138         /* So reset the RELOAD bit mode */
02139         hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
02140         SMBUS_TransferConfig(hsmbus, 0U, 1U, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
02141       }
02142       else if (hsmbus->XferCount == 0U)
02143       {
02144         /* Last Byte is received, disable Interrupt */
02145         SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
02146 
02147         /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
02148         hsmbus->PreviousState = hsmbus->State;
02149         hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
02150 
02151         /* Process Unlocked */
02152         __HAL_UNLOCK(hsmbus);
02153 
02154         /* Call the corresponding callback to inform upper layer of End of Transfer */
02155 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02156         hsmbus->SlaveRxCpltCallback(hsmbus);
02157 #else
02158         HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
02159 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02160       }
02161       else
02162       {
02163         /* Set Reload for next Bytes */
02164         SMBUS_TransferConfig(hsmbus, 0U, 1U, SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
02165 
02166         /* Ack last Byte Read */
02167         hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
02168       }
02169     }
02170     else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
02171     {
02172       if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
02173       {
02174         if (hsmbus->XferCount > MAX_NBYTE_SIZE)
02175         {
02176           SMBUS_TransferConfig(hsmbus, 0U, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
02177           hsmbus->XferSize = MAX_NBYTE_SIZE;
02178         }
02179         else
02180         {
02181           hsmbus->XferSize = hsmbus->XferCount;
02182           SMBUS_TransferConfig(hsmbus, 0U, hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
02183           /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
02184           /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
02185           if (SMBUS_GET_PEC_MODE(hsmbus) != RESET)
02186           {
02187             hsmbus->XferSize--;
02188             hsmbus->XferCount--;
02189           }
02190         }
02191       }
02192     }
02193     else
02194     {
02195       /* Nothing to do */
02196     }
02197   }
02198   else if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
02199   {
02200     /* Write data to TXDR only if XferCount not reach "0" */
02201     /* A TXIS flag can be set, during STOP treatment      */
02202     /* Check if all Data have already been sent */
02203     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
02204     if (hsmbus->XferCount > 0U)
02205     {
02206       /* Write data to TXDR */
02207       hsmbus->Instance->TXDR = (*hsmbus->pBuffPtr++);
02208       hsmbus->XferCount--;
02209       hsmbus->XferSize--;
02210     }
02211 
02212     if (hsmbus->XferCount == 0U)
02213     {
02214       /* Last Byte is Transmitted */
02215       /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
02216       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
02217       hsmbus->PreviousState = hsmbus->State;
02218       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
02219 
02220       /* Process Unlocked */
02221       __HAL_UNLOCK(hsmbus);
02222 
02223       /* Call the corresponding callback to inform upper layer of End of Transfer */
02224 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02225       hsmbus->SlaveTxCpltCallback(hsmbus);
02226 #else
02227       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
02228 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02229     }
02230   }
02231   else
02232   {
02233     /* Nothing to do */
02234   }
02235 
02236   /* Check if STOPF is set */
02237   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF) != RESET)
02238   {
02239     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
02240     {
02241       /* Store Last receive data if any */
02242       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
02243       {
02244         /* Read data from RXDR */
02245         (*hsmbus->pBuffPtr++) = hsmbus->Instance->RXDR;
02246 
02247         if ((hsmbus->XferSize > 0U))
02248         {
02249           hsmbus->XferSize--;
02250           hsmbus->XferCount--;
02251         }
02252       }
02253 
02254       /* Disable RX and TX Interrupts */
02255       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
02256 
02257       /* Disable ADDR Interrupt */
02258       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
02259 
02260       /* Disable Address Acknowledge */
02261       hsmbus->Instance->CR2 |= I2C_CR2_NACK;
02262 
02263       /* Clear Configuration Register 2 */
02264       SMBUS_RESET_CR2(hsmbus);
02265 
02266       /* Clear STOP Flag */
02267       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
02268 
02269       /* Clear ADDR flag */
02270       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
02271 
02272       hsmbus->XferOptions = 0U;
02273       hsmbus->PreviousState = hsmbus->State;
02274       hsmbus->State = HAL_SMBUS_STATE_READY;
02275 
02276       /* Process Unlocked */
02277       __HAL_UNLOCK(hsmbus);
02278 
02279       /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
02280 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02281       hsmbus->ListenCpltCallback(hsmbus);
02282 #else
02283       HAL_SMBUS_ListenCpltCallback(hsmbus);
02284 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02285     }
02286   }
02287 
02288   /* Process Unlocked */
02289   __HAL_UNLOCK(hsmbus);
02290 
02291   return HAL_OK;
02292 }
02293 /**
02294   * @brief  Manage the enabling of Interrupts.
02295   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02296   *                the configuration information for the specified SMBUS.
02297   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
02298   * @retval HAL status
02299   */
02300 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
02301 {
02302   uint32_t tmpisr = 0U;
02303 
02304   if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
02305   {
02306     /* Enable ERR interrupt */
02307     tmpisr |= SMBUS_IT_ERRI;
02308   }
02309 
02310   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
02311   {
02312     /* Enable ADDR, STOP interrupt */
02313     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
02314   }
02315 
02316   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
02317   {
02318     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
02319     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
02320   }
02321 
02322   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
02323   {
02324     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
02325     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
02326   }
02327 
02328   /* Enable interrupts only at the end */
02329   /* to avoid the risk of SMBUS interrupt handle execution before */
02330   /* all interrupts requested done */
02331   __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
02332 }
02333 /**
02334   * @brief  Manage the disabling of Interrupts.
02335   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02336   *                the configuration information for the specified SMBUS.
02337   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
02338   * @retval HAL status
02339   */
02340 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint16_t InterruptRequest)
02341 {
02342   uint32_t tmpisr = 0U;
02343 
02344   if ((hsmbus->State == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT))
02345   {
02346     /* Disable ERR interrupt */
02347     tmpisr |= SMBUS_IT_ERRI;
02348   }
02349 
02350   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
02351   {
02352     /* Disable TC, STOP, NACK, TXI interrupt */
02353     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
02354 
02355     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
02356         && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
02357     {
02358       /* Disable ERR interrupt */
02359       tmpisr |= SMBUS_IT_ERRI;
02360     }
02361 
02362     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
02363     {
02364       /* Disable STOPI, NACKI */
02365       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
02366     }
02367   }
02368 
02369   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
02370   {
02371     /* Disable TC, STOP, NACK, RXI interrupt */
02372     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
02373 
02374     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
02375         && ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
02376     {
02377       /* Disable ERR interrupt */
02378       tmpisr |= SMBUS_IT_ERRI;
02379     }
02380 
02381     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
02382     {
02383       /* Disable STOPI, NACKI */
02384       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
02385     }
02386   }
02387 
02388   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
02389   {
02390     /* Enable ADDR, STOP interrupt */
02391     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
02392 
02393     if (SMBUS_GET_ALERT_ENABLED(hsmbus) == RESET)
02394     {
02395       /* Disable ERR interrupt */
02396       tmpisr |= SMBUS_IT_ERRI;
02397     }
02398   }
02399 
02400   /* Disable interrupts only at the end */
02401   /* to avoid a breaking situation like at "t" time */
02402   /* all disable interrupts request are not done */
02403   __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
02404 }
02405 
02406 /**
02407   * @brief  SMBUS interrupts error handler.
02408   * @param  hsmbus SMBUS handle.
02409   * @retval None
02410   */
02411 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus)
02412 {
02413   uint32_t itflags   = READ_REG(hsmbus->Instance->ISR);
02414   uint32_t itsources = READ_REG(hsmbus->Instance->CR1);
02415 
02416   /* SMBUS Bus error interrupt occurred ------------------------------------*/
02417   if (((itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02418   {
02419     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
02420 
02421     /* Clear BERR flag */
02422     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
02423   }
02424 
02425   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
02426   if (((itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02427   {
02428     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
02429 
02430     /* Clear OVR flag */
02431     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
02432   }
02433 
02434   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
02435   if (((itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02436   {
02437     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
02438 
02439     /* Clear ARLO flag */
02440     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
02441   }
02442 
02443   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
02444   if (((itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02445   {
02446     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
02447 
02448     /* Clear TIMEOUT flag */
02449     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
02450   }
02451 
02452   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
02453   if (((itflags & SMBUS_FLAG_ALERT) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02454   {
02455     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
02456 
02457     /* Clear ALERT flag */
02458     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
02459   }
02460 
02461   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
02462   if (((itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERRI) != RESET))
02463   {
02464     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
02465 
02466     /* Clear PEC error flag */
02467     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
02468   }
02469 
02470   /* Call the Error Callback in case of Error detected */
02471   if ((hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE) && (hsmbus->ErrorCode != HAL_SMBUS_ERROR_ACKF))
02472   {
02473     /* Do not Reset the HAL state in case of ALERT error */
02474     if ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
02475     {
02476       if (((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
02477           || ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
02478       {
02479         /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
02480         /* keep HAL_SMBUS_STATE_LISTEN if set */
02481         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
02482         hsmbus->State = HAL_SMBUS_STATE_LISTEN;
02483       }
02484     }
02485 
02486     /* Call the Error callback to inform upper layer */
02487 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
02488     hsmbus->ErrorCallback(hsmbus);
02489 #else
02490     HAL_SMBUS_ErrorCallback(hsmbus);
02491 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
02492   }
02493 }
02494 
02495 /**
02496   * @brief  Handle SMBUS Communication Timeout.
02497   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
02498   *                the configuration information for the specified SMBUS.
02499   * @param  Flag Specifies the SMBUS flag to check.
02500   * @param  Status The new Flag status (SET or RESET).
02501   * @param  Timeout Timeout duration
02502   * @retval HAL status
02503   */
02504 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
02505 {
02506   uint32_t tickstart = HAL_GetTick();
02507 
02508   /* Wait until flag is set */
02509   while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == Status)
02510   {
02511     /* Check for the Timeout */
02512     if (Timeout != HAL_MAX_DELAY)
02513     {
02514       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
02515       {
02516         hsmbus->PreviousState = hsmbus->State;
02517         hsmbus->State = HAL_SMBUS_STATE_READY;
02518 
02519         /* Process Unlocked */
02520         __HAL_UNLOCK(hsmbus);
02521 
02522         return HAL_TIMEOUT;
02523       }
02524     }
02525   }
02526 
02527   return HAL_OK;
02528 }
02529 
02530 /**
02531   * @brief  Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
02532   * @param  hsmbus SMBUS handle.
02533   * @param  DevAddress specifies the slave address to be programmed.
02534   * @param  Size specifies the number of bytes to be programmed.
02535   *   This parameter must be a value between 0 and 255.
02536   * @param  Mode New state of the SMBUS START condition generation.
02537   *   This parameter can be one or a combination  of the following values:
02538   *     @arg @ref SMBUS_RELOAD_MODE Enable Reload mode.
02539   *     @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode.
02540   *     @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
02541   *     @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
02542   * @param  Request New state of the SMBUS START condition generation.
02543   *   This parameter can be one of the following values:
02544   *     @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition.
02545   *     @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
02546   *     @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request.
02547   *     @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request.
02548   * @retval None
02549   */
02550 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
02551 {
02552   /* Check the parameters */
02553   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
02554   assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
02555   assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
02556 
02557   /* update CR2 register */
02558   MODIFY_REG(hsmbus->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP  | I2C_CR2_PECBYTE)), \
02559              (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
02560 }
02561 
02562 /**
02563   * @brief  Convert SMBUSx OTHER_xxx XferOptions to functionnal XferOptions.
02564   * @param  hsmbus SMBUS handle.
02565   * @retval None
02566   */
02567 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus)
02568 {
02569   /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC   */
02570   /* it request implicitly to generate a restart condition */
02571   /* set XferOptions to SMBUS_FIRST_FRAME                  */
02572   if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
02573   {
02574     hsmbus->XferOptions = SMBUS_FIRST_FRAME;
02575   }
02576   /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
02577   /* it request implicitly to generate a restart condition      */
02578   /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE  */
02579   else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
02580   {
02581     hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
02582   }
02583   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
02584   /* it request implicitly to generate a restart condition             */
02585   /* then generate a stop condition at the end of transfer             */
02586   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC              */
02587   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
02588   {
02589     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
02590   }
02591   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
02592   /* it request implicitly to generate a restart condition               */
02593   /* then generate a stop condition at the end of transfer               */
02594   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC              */
02595   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
02596   {
02597     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
02598   }
02599   else
02600   {
02601     /* Nothing to do */
02602   }
02603 }
02604 /**
02605   * @}
02606   */
02607 
02608 #endif /* HAL_SMBUS_MODULE_ENABLED */
02609 /**
02610   * @}
02611   */
02612 
02613 /**
02614   * @}
02615   */
02616 
02617 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/