Back to home page

LXR

 
 

    


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

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_smbus.c
0004   * @author  MCD Application Team
0005   * @brief   SMBUS HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the System Management Bus (SMBus) peripheral,
0008   *          based on I2C principles of operation :
0009   *           + Initialization and de-initialization functions
0010   *           + IO operation functions
0011   *           + Peripheral State and Errors functions
0012   *
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025   ==============================================================================
0026                         ##### How to use this driver #####
0027   ==============================================================================
0028     [..]
0029     The SMBUS HAL driver can be used as follows:
0030 
0031     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
0032         SMBUS_HandleTypeDef  hsmbus;
0033 
0034     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
0035         (##) Enable the SMBUSx interface clock
0036         (##) SMBUS pins configuration
0037             (+++) Enable the clock for the SMBUS GPIOs
0038             (+++) Configure SMBUS pins as alternate function open-drain
0039         (##) NVIC configuration if you need to use interrupt process
0040             (+++) Configure the SMBUSx interrupt priority
0041             (+++) Enable the NVIC SMBUS IRQ Channel
0042 
0043     (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
0044         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
0045         Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
0046 
0047     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
0048         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
0049              by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
0050 
0051     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
0052 
0053     (#) For SMBUS IO operations, only one mode of operations is available within this driver
0054 
0055     *** Interrupt mode IO operation ***
0056     ===================================
0057     [..]
0058       (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode
0059           using HAL_SMBUS_Master_Transmit_IT()
0060       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and users can
0061            add their own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
0062       (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode
0063           using HAL_SMBUS_Master_Receive_IT()
0064       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and users can
0065            add their own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
0066       (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
0067       (++) The associated previous transfer callback is called at the end of abort process
0068       (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
0069       (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
0070       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
0071            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
0072       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and users can
0073            add their own code to check the Address Match Code and the transmission direction
0074            request by master/host (Write/Read).
0075       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and users can
0076            add their own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
0077       (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode
0078           using HAL_SMBUS_Slave_Transmit_IT()
0079       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and users can
0080            add their own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
0081       (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode
0082           using HAL_SMBUS_Slave_Receive_IT()
0083       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and users can
0084            add their own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
0085       (+) Enable/Disable the SMBUS alert mode using
0086           HAL_SMBUS_EnableAlert_IT() or HAL_SMBUS_DisableAlert_IT()
0087       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and users can
0088            add their own code by customization of function pointer HAL_SMBUS_ErrorCallback()
0089            to check the Alert Error Code using function HAL_SMBUS_GetError()
0090       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
0091       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and users can
0092            add their own code by customization of function pointer HAL_SMBUS_ErrorCallback()
0093            to check the Error Code using function HAL_SMBUS_GetError()
0094 
0095      *** SMBUS HAL driver macros list ***
0096      ==================================
0097      [..]
0098        Below the list of most used macros in SMBUS HAL driver.
0099 
0100       (+) __HAL_SMBUS_ENABLE:      Enable the SMBUS peripheral
0101       (+) __HAL_SMBUS_DISABLE:     Disable the SMBUS peripheral
0102       (+) __HAL_SMBUS_GET_FLAG:    Check whether the specified SMBUS flag is set or not
0103       (+) __HAL_SMBUS_CLEAR_FLAG:  Clear the specified SMBUS pending flag
0104       (+) __HAL_SMBUS_ENABLE_IT:   Enable the specified SMBUS interrupt
0105       (+) __HAL_SMBUS_DISABLE_IT:  Disable the specified SMBUS interrupt
0106 
0107      *** Callback registration ***
0108      =============================================
0109     [..]
0110      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
0111      allows the user to configure dynamically the driver callbacks.
0112      Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterAddrCallback()
0113      to register an interrupt callback.
0114     [..]
0115      Function HAL_SMBUS_RegisterCallback() allows to register following callbacks:
0116        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
0117        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
0118        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
0119        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
0120        (+) ListenCpltCallback   : callback for end of listen mode.
0121        (+) ErrorCallback        : callback for error detection.
0122        (+) MspInitCallback      : callback for Msp Init.
0123        (+) MspDeInitCallback    : callback for Msp DeInit.
0124      This function takes as parameters the HAL peripheral handle, the Callback ID
0125      and a pointer to the user callback function.
0126     [..]
0127      For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback.
0128     [..]
0129      Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default
0130      weak function.
0131      HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
0132      and the Callback ID.
0133      This function allows to reset following callbacks:
0134        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
0135        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
0136        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
0137        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
0138        (+) ListenCpltCallback   : callback for end of listen mode.
0139        (+) ErrorCallback        : callback for error detection.
0140        (+) MspInitCallback      : callback for Msp Init.
0141        (+) MspDeInitCallback    : callback for Msp DeInit.
0142     [..]
0143      For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback.
0144     [..]
0145      By default, after the HAL_SMBUS_Init() and when the state is HAL_I2C_STATE_RESET
0146      all callbacks are set to the corresponding weak functions:
0147      examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback().
0148      Exception done for MspInit and MspDeInit functions that are
0149      reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when
0150      these callbacks are null (not registered beforehand).
0151      If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit()
0152      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
0153     [..]
0154      Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
0155      Exception done MspInit/MspDeInit functions that can be registered/unregistered
0156      in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state,
0157      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0158      Then, the user first registers the MspInit/MspDeInit user callbacks
0159      using HAL_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit()
0160      or HAL_SMBUS_Init() function.
0161     [..]
0162      When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
0163      not defined, the callback registration feature is not available and all callbacks
0164      are set to the corresponding weak functions.
0165 
0166      [..]
0167        (@) You can refer to the SMBUS HAL driver header file for more useful macros
0168 
0169   @endverbatim
0170   */
0171 
0172 /* Includes ------------------------------------------------------------------*/
0173 #include "stm32h7xx_hal.h"
0174 
0175 /** @addtogroup STM32H7xx_HAL_Driver
0176   * @{
0177   */
0178 
0179 /** @defgroup SMBUS SMBUS
0180   * @ingroup RTEMSBSPsARMSTM32H7
0181   * @brief SMBUS HAL module driver
0182   * @{
0183   */
0184 
0185 #ifdef HAL_SMBUS_MODULE_ENABLED
0186 
0187 /* Private typedef -----------------------------------------------------------*/
0188 /* Private constants ---------------------------------------------------------*/
0189 /** @defgroup SMBUS_Private_Define SMBUS Private Constants
0190   * @ingroup RTEMSBSPsARMSTM32H7
0191   * @{
0192   */
0193 #define TIMING_CLEAR_MASK   (0xF0FFFFFFUL)     /*!< SMBUS TIMING clear register Mask */
0194 #define HAL_TIMEOUT_ADDR    (10000U)           /*!< 10 s  */
0195 #define HAL_TIMEOUT_BUSY    (25U)              /*!< 25 ms */
0196 #define HAL_TIMEOUT_DIR     (25U)              /*!< 25 ms */
0197 #define HAL_TIMEOUT_RXNE    (25U)              /*!< 25 ms */
0198 #define HAL_TIMEOUT_STOPF   (25U)              /*!< 25 ms */
0199 #define HAL_TIMEOUT_TC      (25U)              /*!< 25 ms */
0200 #define HAL_TIMEOUT_TCR     (25U)              /*!< 25 ms */
0201 #define HAL_TIMEOUT_TXIS    (25U)              /*!< 25 ms */
0202 #define MAX_NBYTE_SIZE      255U
0203 /**
0204   * @}
0205   */
0206 
0207 /* Private macro -------------------------------------------------------------*/
0208 /* Private variables ---------------------------------------------------------*/
0209 /* Private function prototypes -----------------------------------------------*/
0210 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
0211   * @{
0212   */
0213 /* Private functions to handle flags during polling transfer */
0214 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag,
0215                                                       FlagStatus Status, uint32_t Timeout);
0216 
0217 /* Private functions for SMBUS transfer IRQ handler */
0218 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
0219 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
0220 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus);
0221 
0222 /* Private functions to centralize the enable/disable of Interrupts */
0223 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);
0224 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);
0225 
0226 /* Private function to flush TXDR register */
0227 static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus);
0228 
0229 /* Private function to handle start, restart or stop a transfer */
0230 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size,
0231                                  uint32_t Mode, uint32_t Request);
0232 
0233 /* Private function to Convert Specific options */
0234 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus);
0235 /**
0236   * @}
0237   */
0238 
0239 /* Exported functions --------------------------------------------------------*/
0240 
0241 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
0242   * @ingroup RTEMSBSPsARMSTM32H7
0243   * @{
0244   */
0245 
0246 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
0247   * @ingroup RTEMSBSPsARMSTM32H7
0248   *  @brief    Initialization and Configuration functions
0249   *
0250 @verbatim
0251  ===============================================================================
0252               ##### Initialization and de-initialization functions #####
0253  ===============================================================================
0254     [..]  This subsection provides a set of functions allowing to initialize and
0255           deinitialize the SMBUSx peripheral:
0256 
0257       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
0258           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
0259 
0260       (+) Call the function HAL_SMBUS_Init() to configure the selected device with
0261           the selected configuration:
0262         (++) Clock Timing
0263         (++) Bus Timeout
0264         (++) Analog Filer mode
0265         (++) Own Address 1
0266         (++) Addressing mode (Master, Slave)
0267         (++) Dual Addressing mode
0268         (++) Own Address 2
0269         (++) Own Address 2 Mask
0270         (++) General call mode
0271         (++) Nostretch mode
0272         (++) Packet Error Check mode
0273         (++) Peripheral mode
0274 
0275 
0276       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
0277           of the selected SMBUSx peripheral.
0278 
0279       (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and
0280           HAL_SMBUS_ConfigDigitalFilter().
0281 
0282 @endverbatim
0283   * @{
0284   */
0285 
0286 /**
0287   * @brief  Initialize the SMBUS according to the specified parameters
0288   *         in the SMBUS_InitTypeDef and initialize the associated handle.
0289   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0290   *                the configuration information for the specified SMBUS.
0291   * @retval HAL status
0292   */
0293 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
0294 {
0295   /* Check the SMBUS handle allocation */
0296   if (hsmbus == NULL)
0297   {
0298     return HAL_ERROR;
0299   }
0300 
0301   /* Check the parameters */
0302   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
0303   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
0304   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
0305   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
0306   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
0307   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
0308   assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
0309   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
0310   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
0311   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
0312   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
0313 
0314   if (hsmbus->State == HAL_SMBUS_STATE_RESET)
0315   {
0316     /* Allocate lock resource and initialize it */
0317     hsmbus->Lock = HAL_UNLOCKED;
0318 
0319 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
0320     hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
0321     hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
0322     hsmbus->SlaveTxCpltCallback  = HAL_SMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
0323     hsmbus->SlaveRxCpltCallback  = HAL_SMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
0324     hsmbus->ListenCpltCallback   = HAL_SMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
0325     hsmbus->ErrorCallback        = HAL_SMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
0326     hsmbus->AddrCallback         = HAL_SMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
0327 
0328     if (hsmbus->MspInitCallback == NULL)
0329     {
0330       hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit  */
0331     }
0332 
0333     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
0334     hsmbus->MspInitCallback(hsmbus);
0335 #else
0336     /* Init the low level hardware : GPIO, CLOCK, NVIC */
0337     HAL_SMBUS_MspInit(hsmbus);
0338 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
0339   }
0340 
0341   hsmbus->State = HAL_SMBUS_STATE_BUSY;
0342 
0343   /* Disable the selected SMBUS peripheral */
0344   __HAL_SMBUS_DISABLE(hsmbus);
0345 
0346   /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
0347   /* Configure SMBUSx: Frequency range */
0348   hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
0349 
0350   /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
0351   /* Configure SMBUSx: Bus Timeout  */
0352   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
0353   hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
0354   hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
0355 
0356   /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
0357   /* Configure SMBUSx: Own Address1 and ack own address1 mode */
0358   hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
0359 
0360   if (hsmbus->Init.OwnAddress1 != 0UL)
0361   {
0362     if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
0363     {
0364       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
0365     }
0366     else /* SMBUS_ADDRESSINGMODE_10BIT */
0367     {
0368       hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
0369     }
0370   }
0371 
0372   /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
0373   /* Configure SMBUSx: Addressing Master mode */
0374   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
0375   {
0376     hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
0377   }
0378   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
0379   /* AUTOEND and NACK bit will be manage during Transfer process */
0380   hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
0381 
0382   /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
0383   /* Configure SMBUSx: Dual mode and Own Address2 */
0384   hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | \
0385                             (hsmbus->Init.OwnAddress2Masks << 8U));
0386 
0387   /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
0388   /* Configure SMBUSx: Generalcall and NoStretch mode */
0389   hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | \
0390                            hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | \
0391                            hsmbus->Init.AnalogFilter);
0392 
0393   /* Enable Slave Byte Control only in case of Packet Error Check is enabled
0394      and SMBUS Peripheral is set in Slave mode */
0395   if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE) && \
0396       ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \
0397        (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)))
0398   {
0399     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
0400   }
0401 
0402   /* Enable the selected SMBUS peripheral */
0403   __HAL_SMBUS_ENABLE(hsmbus);
0404 
0405   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
0406   hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
0407   hsmbus->State = HAL_SMBUS_STATE_READY;
0408 
0409   return HAL_OK;
0410 }
0411 
0412 /**
0413   * @brief  DeInitialize the SMBUS peripheral.
0414   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0415   *                the configuration information for the specified SMBUS.
0416   * @retval HAL status
0417   */
0418 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
0419 {
0420   /* Check the SMBUS handle allocation */
0421   if (hsmbus == NULL)
0422   {
0423     return HAL_ERROR;
0424   }
0425 
0426   /* Check the parameters */
0427   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
0428 
0429   hsmbus->State = HAL_SMBUS_STATE_BUSY;
0430 
0431   /* Disable the SMBUS Peripheral Clock */
0432   __HAL_SMBUS_DISABLE(hsmbus);
0433 
0434 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
0435   if (hsmbus->MspDeInitCallback == NULL)
0436   {
0437     hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit  */
0438   }
0439 
0440   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
0441   hsmbus->MspDeInitCallback(hsmbus);
0442 #else
0443   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
0444   HAL_SMBUS_MspDeInit(hsmbus);
0445 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
0446 
0447   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
0448   hsmbus->PreviousState =  HAL_SMBUS_STATE_RESET;
0449   hsmbus->State = HAL_SMBUS_STATE_RESET;
0450 
0451   /* Release Lock */
0452   __HAL_UNLOCK(hsmbus);
0453 
0454   return HAL_OK;
0455 }
0456 
0457 /**
0458   * @brief Initialize the SMBUS MSP.
0459   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0460   *                the configuration information for the specified SMBUS.
0461   * @retval None
0462   */
0463 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
0464 {
0465   /* Prevent unused argument(s) compilation warning */
0466   UNUSED(hsmbus);
0467 
0468   /* NOTE : This function should not be modified, when the callback is needed,
0469             the HAL_SMBUS_MspInit could be implemented in the user file
0470    */
0471 }
0472 
0473 /**
0474   * @brief DeInitialize the SMBUS MSP.
0475   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0476   *                the configuration information for the specified SMBUS.
0477   * @retval None
0478   */
0479 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
0480 {
0481   /* Prevent unused argument(s) compilation warning */
0482   UNUSED(hsmbus);
0483 
0484   /* NOTE : This function should not be modified, when the callback is needed,
0485             the HAL_SMBUS_MspDeInit could be implemented in the user file
0486    */
0487 }
0488 
0489 /**
0490   * @brief  Configure Analog noise filter.
0491   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0492   *                the configuration information for the specified SMBUS.
0493   * @param  AnalogFilter This parameter can be one of the following values:
0494   *         @arg @ref SMBUS_ANALOGFILTER_ENABLE
0495   *         @arg @ref SMBUS_ANALOGFILTER_DISABLE
0496   * @retval HAL status
0497   */
0498 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
0499 {
0500   /* Check the parameters */
0501   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
0502   assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
0503 
0504   if (hsmbus->State == HAL_SMBUS_STATE_READY)
0505   {
0506     /* Process Locked */
0507     __HAL_LOCK(hsmbus);
0508 
0509     hsmbus->State = HAL_SMBUS_STATE_BUSY;
0510 
0511     /* Disable the selected SMBUS peripheral */
0512     __HAL_SMBUS_DISABLE(hsmbus);
0513 
0514     /* Reset ANOFF bit */
0515     hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
0516 
0517     /* Set analog filter bit*/
0518     hsmbus->Instance->CR1 |= AnalogFilter;
0519 
0520     __HAL_SMBUS_ENABLE(hsmbus);
0521 
0522     hsmbus->State = HAL_SMBUS_STATE_READY;
0523 
0524     /* Process Unlocked */
0525     __HAL_UNLOCK(hsmbus);
0526 
0527     return HAL_OK;
0528   }
0529   else
0530   {
0531     return HAL_BUSY;
0532   }
0533 }
0534 
0535 /**
0536   * @brief  Configure Digital noise filter.
0537   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0538   *                the configuration information for the specified SMBUS.
0539   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
0540   * @retval HAL status
0541   */
0542 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
0543 {
0544   uint32_t tmpreg;
0545 
0546   /* Check the parameters */
0547   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
0548   assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
0549 
0550   if (hsmbus->State == HAL_SMBUS_STATE_READY)
0551   {
0552     /* Process Locked */
0553     __HAL_LOCK(hsmbus);
0554 
0555     hsmbus->State = HAL_SMBUS_STATE_BUSY;
0556 
0557     /* Disable the selected SMBUS peripheral */
0558     __HAL_SMBUS_DISABLE(hsmbus);
0559 
0560     /* Get the old register value */
0561     tmpreg = hsmbus->Instance->CR1;
0562 
0563     /* Reset I2C DNF bits [11:8] */
0564     tmpreg &= ~(I2C_CR1_DNF);
0565 
0566     /* Set I2Cx DNF coefficient */
0567     tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos;
0568 
0569     /* Store the new register value */
0570     hsmbus->Instance->CR1 = tmpreg;
0571 
0572     __HAL_SMBUS_ENABLE(hsmbus);
0573 
0574     hsmbus->State = HAL_SMBUS_STATE_READY;
0575 
0576     /* Process Unlocked */
0577     __HAL_UNLOCK(hsmbus);
0578 
0579     return HAL_OK;
0580   }
0581   else
0582   {
0583     return HAL_BUSY;
0584   }
0585 }
0586 
0587 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
0588 /**
0589   * @brief  Register a User SMBUS Callback
0590   *         To be used instead of the weak predefined callback
0591   * @note   The HAL_SMBUS_RegisterCallback() may be called before HAL_SMBUS_Init() in
0592   *         HAL_SMBUS_STATE_RESET to register callbacks for HAL_SMBUS_MSPINIT_CB_ID and
0593   *         HAL_SMBUS_MSPDEINIT_CB_ID.
0594   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0595   *                the configuration information for the specified SMBUS.
0596   * @param  CallbackID ID of the callback to be registered
0597   *         This parameter can be one of the following values:
0598   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
0599   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
0600   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
0601   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
0602   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
0603   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
0604   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
0605   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
0606   * @param  pCallback pointer to the Callback function
0607   * @retval HAL status
0608   */
0609 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus,
0610                                              HAL_SMBUS_CallbackIDTypeDef CallbackID,
0611                                              pSMBUS_CallbackTypeDef pCallback)
0612 {
0613   HAL_StatusTypeDef status = HAL_OK;
0614 
0615   if (pCallback == NULL)
0616   {
0617     /* Update the error code */
0618     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0619 
0620     return HAL_ERROR;
0621   }
0622 
0623   if (HAL_SMBUS_STATE_READY == hsmbus->State)
0624   {
0625     switch (CallbackID)
0626     {
0627       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
0628         hsmbus->MasterTxCpltCallback = pCallback;
0629         break;
0630 
0631       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
0632         hsmbus->MasterRxCpltCallback = pCallback;
0633         break;
0634 
0635       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
0636         hsmbus->SlaveTxCpltCallback = pCallback;
0637         break;
0638 
0639       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
0640         hsmbus->SlaveRxCpltCallback = pCallback;
0641         break;
0642 
0643       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
0644         hsmbus->ListenCpltCallback = pCallback;
0645         break;
0646 
0647       case HAL_SMBUS_ERROR_CB_ID :
0648         hsmbus->ErrorCallback = pCallback;
0649         break;
0650 
0651       case HAL_SMBUS_MSPINIT_CB_ID :
0652         hsmbus->MspInitCallback = pCallback;
0653         break;
0654 
0655       case HAL_SMBUS_MSPDEINIT_CB_ID :
0656         hsmbus->MspDeInitCallback = pCallback;
0657         break;
0658 
0659       default :
0660         /* Update the error code */
0661         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0662 
0663         /* Return error status */
0664         status =  HAL_ERROR;
0665         break;
0666     }
0667   }
0668   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
0669   {
0670     switch (CallbackID)
0671     {
0672       case HAL_SMBUS_MSPINIT_CB_ID :
0673         hsmbus->MspInitCallback = pCallback;
0674         break;
0675 
0676       case HAL_SMBUS_MSPDEINIT_CB_ID :
0677         hsmbus->MspDeInitCallback = pCallback;
0678         break;
0679 
0680       default :
0681         /* Update the error code */
0682         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0683 
0684         /* Return error status */
0685         status =  HAL_ERROR;
0686         break;
0687     }
0688   }
0689   else
0690   {
0691     /* Update the error code */
0692     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0693 
0694     /* Return error status */
0695     status =  HAL_ERROR;
0696   }
0697 
0698   return status;
0699 }
0700 
0701 /**
0702   * @brief  Unregister an SMBUS Callback
0703   *         SMBUS callback is redirected to the weak predefined callback
0704   * @note   The HAL_SMBUS_UnRegisterCallback() may be called before HAL_SMBUS_Init() in
0705   *         HAL_SMBUS_STATE_RESET to un-register callbacks for HAL_SMBUS_MSPINIT_CB_ID and
0706   *         HAL_SMBUS_MSPDEINIT_CB_ID
0707   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0708   *                the configuration information for the specified SMBUS.
0709   * @param  CallbackID ID of the callback to be unregistered
0710   *         This parameter can be one of the following values:
0711   *         This parameter can be one of the following values:
0712   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
0713   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
0714   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
0715   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
0716   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
0717   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
0718   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
0719   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
0720   * @retval HAL status
0721   */
0722 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus,
0723                                                HAL_SMBUS_CallbackIDTypeDef CallbackID)
0724 {
0725   HAL_StatusTypeDef status = HAL_OK;
0726 
0727   if (HAL_SMBUS_STATE_READY == hsmbus->State)
0728   {
0729     switch (CallbackID)
0730     {
0731       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
0732         hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
0733         break;
0734 
0735       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
0736         hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
0737         break;
0738 
0739       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
0740         hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
0741         break;
0742 
0743       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
0744         hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
0745         break;
0746 
0747       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
0748         hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
0749         break;
0750 
0751       case HAL_SMBUS_ERROR_CB_ID :
0752         hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
0753         break;
0754 
0755       case HAL_SMBUS_MSPINIT_CB_ID :
0756         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
0757         break;
0758 
0759       case HAL_SMBUS_MSPDEINIT_CB_ID :
0760         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
0761         break;
0762 
0763       default :
0764         /* Update the error code */
0765         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0766 
0767         /* Return error status */
0768         status =  HAL_ERROR;
0769         break;
0770     }
0771   }
0772   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
0773   {
0774     switch (CallbackID)
0775     {
0776       case HAL_SMBUS_MSPINIT_CB_ID :
0777         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
0778         break;
0779 
0780       case HAL_SMBUS_MSPDEINIT_CB_ID :
0781         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
0782         break;
0783 
0784       default :
0785         /* Update the error code */
0786         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0787 
0788         /* Return error status */
0789         status =  HAL_ERROR;
0790         break;
0791     }
0792   }
0793   else
0794   {
0795     /* Update the error code */
0796     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0797 
0798     /* Return error status */
0799     status =  HAL_ERROR;
0800   }
0801 
0802   return status;
0803 }
0804 
0805 /**
0806   * @brief  Register the Slave Address Match SMBUS Callback
0807   *         To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
0808   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0809   *                the configuration information for the specified SMBUS.
0810   * @param  pCallback pointer to the Address Match Callback function
0811   * @retval HAL status
0812   */
0813 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus,
0814                                                  pSMBUS_AddrCallbackTypeDef pCallback)
0815 {
0816   HAL_StatusTypeDef status = HAL_OK;
0817 
0818   if (pCallback == NULL)
0819   {
0820     /* Update the error code */
0821     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0822 
0823     return HAL_ERROR;
0824   }
0825 
0826   if (HAL_SMBUS_STATE_READY == hsmbus->State)
0827   {
0828     hsmbus->AddrCallback = pCallback;
0829   }
0830   else
0831   {
0832     /* Update the error code */
0833     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0834 
0835     /* Return error status */
0836     status =  HAL_ERROR;
0837   }
0838 
0839   return status;
0840 }
0841 
0842 /**
0843   * @brief  UnRegister the Slave Address Match SMBUS Callback
0844   *         Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
0845   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0846   *                the configuration information for the specified SMBUS.
0847   * @retval HAL status
0848   */
0849 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
0850 {
0851   HAL_StatusTypeDef status = HAL_OK;
0852 
0853   if (HAL_SMBUS_STATE_READY == hsmbus->State)
0854   {
0855     hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback  */
0856   }
0857   else
0858   {
0859     /* Update the error code */
0860     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
0861 
0862     /* Return error status */
0863     status =  HAL_ERROR;
0864   }
0865 
0866   return status;
0867 }
0868 
0869 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
0870 
0871 /**
0872   * @}
0873   */
0874 
0875 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
0876   * @ingroup RTEMSBSPsARMSTM32H7
0877   *  @brief   Data transfers functions
0878   *
0879 @verbatim
0880  ===============================================================================
0881                       ##### IO operation functions #####
0882  ===============================================================================
0883     [..]
0884     This subsection provides a set of functions allowing to manage the SMBUS data
0885     transfers.
0886 
0887     (#) Blocking mode function to check if device is ready for usage is :
0888         (++) HAL_SMBUS_IsDeviceReady()
0889 
0890     (#) There is only one mode of transfer:
0891        (++) Non-Blocking mode : The communication is performed using Interrupts.
0892             These functions return the status of the transfer startup.
0893             The end of the data processing will be indicated through the
0894             dedicated SMBUS IRQ when using Interrupt mode.
0895 
0896     (#) Non-Blocking mode functions with Interrupt are :
0897         (++) HAL_SMBUS_Master_Transmit_IT()
0898         (++) HAL_SMBUS_Master_Receive_IT()
0899         (++) HAL_SMBUS_Slave_Transmit_IT()
0900         (++) HAL_SMBUS_Slave_Receive_IT()
0901         (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT()
0902         (++) HAL_SMBUS_DisableListen_IT()
0903         (++) HAL_SMBUS_EnableAlert_IT()
0904         (++) HAL_SMBUS_DisableAlert_IT()
0905 
0906     (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
0907         (++) HAL_SMBUS_MasterTxCpltCallback()
0908         (++) HAL_SMBUS_MasterRxCpltCallback()
0909         (++) HAL_SMBUS_SlaveTxCpltCallback()
0910         (++) HAL_SMBUS_SlaveRxCpltCallback()
0911         (++) HAL_SMBUS_AddrCallback()
0912         (++) HAL_SMBUS_ListenCpltCallback()
0913         (++) HAL_SMBUS_ErrorCallback()
0914 
0915 @endverbatim
0916   * @{
0917   */
0918 
0919 /**
0920   * @brief  Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
0921   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
0922   *                the configuration information for the specified SMBUS.
0923   * @param  DevAddress Target device address: The device 7 bits address value
0924   *         in datasheet must be shifted to the left before calling the interface
0925   * @param  pData Pointer to data buffer
0926   * @param  Size Amount of data to be sent
0927   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
0928   * @retval HAL status
0929   */
0930 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress,
0931                                                uint8_t *pData, uint16_t Size, uint32_t XferOptions)
0932 {
0933   uint32_t tmp;
0934   uint32_t sizetoxfer;
0935 
0936   /* Check the parameters */
0937   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
0938 
0939   if (hsmbus->State == HAL_SMBUS_STATE_READY)
0940   {
0941     /* Process Locked */
0942     __HAL_LOCK(hsmbus);
0943 
0944     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
0945     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
0946     /* Prepare transfer parameters */
0947     hsmbus->pBuffPtr = pData;
0948     hsmbus->XferCount = Size;
0949     hsmbus->XferOptions = XferOptions;
0950 
0951     /* In case of Quick command, remove autoend mode */
0952     /* Manage the stop generation by software */
0953     if (hsmbus->pBuffPtr == NULL)
0954     {
0955       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
0956     }
0957 
0958     if (Size > MAX_NBYTE_SIZE)
0959     {
0960       hsmbus->XferSize = MAX_NBYTE_SIZE;
0961     }
0962     else
0963     {
0964       hsmbus->XferSize = Size;
0965     }
0966 
0967     sizetoxfer = hsmbus->XferSize;
0968     if ((sizetoxfer > 0U) && ((XferOptions == SMBUS_FIRST_FRAME) ||
0969                               (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) ||
0970                               (XferOptions == SMBUS_FIRST_FRAME_WITH_PEC) ||
0971                               (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC)))
0972     {
0973       if (hsmbus->pBuffPtr != NULL)
0974       {
0975         /* Preload TX register */
0976         /* Write data to TXDR */
0977         hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
0978 
0979         /* Increment Buffer pointer */
0980         hsmbus->pBuffPtr++;
0981 
0982         hsmbus->XferCount--;
0983         hsmbus->XferSize--;
0984       }
0985       else
0986       {
0987         return HAL_ERROR;
0988       }
0989     }
0990 
0991     /* Send Slave Address */
0992     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
0993     if ((sizetoxfer < hsmbus->XferCount) && (sizetoxfer == MAX_NBYTE_SIZE))
0994     {
0995       SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)sizetoxfer,
0996                            SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
0997                            SMBUS_GENERATE_START_WRITE);
0998     }
0999     else
1000     {
1001       /* If transfer direction not change, do not generate Restart Condition */
1002       /* Mean Previous state is same as current state */
1003 
1004       /* Store current volatile XferOptions, misra rule */
1005       tmp = hsmbus->XferOptions;
1006 
1007       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && \
1008           (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
1009       {
1010         SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)sizetoxfer, hsmbus->XferOptions,
1011                              SMBUS_NO_STARTSTOP);
1012       }
1013       /* Else transfer direction change, so generate Restart with new transfer direction */
1014       else
1015       {
1016         /* Convert OTHER_xxx XferOptions if any */
1017         SMBUS_ConvertOtherXferOptions(hsmbus);
1018 
1019         /* Handle Transfer */
1020         SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)sizetoxfer,
1021                              hsmbus->XferOptions,
1022                              SMBUS_GENERATE_START_WRITE);
1023       }
1024 
1025       /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
1026       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1027       if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1028       {
1029         if (hsmbus->XferSize > 0U)
1030         {
1031           hsmbus->XferSize--;
1032           hsmbus->XferCount--;
1033         }
1034         else
1035         {
1036           return HAL_ERROR;
1037         }
1038       }
1039     }
1040 
1041     /* Process Unlocked */
1042     __HAL_UNLOCK(hsmbus);
1043 
1044     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1045               to avoid the risk of SMBUS interrupt handle execution before current
1046               process unlock */
1047     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
1048 
1049     return HAL_OK;
1050   }
1051   else
1052   {
1053     return HAL_BUSY;
1054   }
1055 }
1056 
1057 /**
1058   * @brief  Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
1059   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1060   *                the configuration information for the specified SMBUS.
1061   * @param  DevAddress Target device address: The device 7 bits address value
1062   *         in datasheet must be shifted to the left before calling the interface
1063   * @param  pData Pointer to data buffer
1064   * @param  Size Amount of data to be sent
1065   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1066   * @retval HAL status
1067   */
1068 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData,
1069                                               uint16_t Size, uint32_t XferOptions)
1070 {
1071   uint32_t tmp;
1072 
1073   /* Check the parameters */
1074   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1075 
1076   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1077   {
1078     /* Process Locked */
1079     __HAL_LOCK(hsmbus);
1080 
1081     hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1082     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1083 
1084     /* Prepare transfer parameters */
1085     hsmbus->pBuffPtr = pData;
1086     hsmbus->XferCount = Size;
1087     hsmbus->XferOptions = XferOptions;
1088 
1089     /* In case of Quick command, remove autoend mode */
1090     /* Manage the stop generation by software */
1091     if (hsmbus->pBuffPtr == NULL)
1092     {
1093       hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
1094     }
1095 
1096     if (Size > MAX_NBYTE_SIZE)
1097     {
1098       hsmbus->XferSize = MAX_NBYTE_SIZE;
1099     }
1100     else
1101     {
1102       hsmbus->XferSize = Size;
1103     }
1104 
1105     /* Send Slave Address */
1106     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1107     if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1108     {
1109       SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1110                            SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
1111                            SMBUS_GENERATE_START_READ);
1112     }
1113     else
1114     {
1115       /* If transfer direction not change, do not generate Restart Condition */
1116       /* Mean Previous state is same as current state */
1117 
1118       /* Store current volatile XferOptions, Misra rule */
1119       tmp = hsmbus->XferOptions;
1120 
1121       if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && \
1122           (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
1123       {
1124         SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1125                              SMBUS_NO_STARTSTOP);
1126       }
1127       /* Else transfer direction change, so generate Restart with new transfer direction */
1128       else
1129       {
1130         /* Convert OTHER_xxx XferOptions if any */
1131         SMBUS_ConvertOtherXferOptions(hsmbus);
1132 
1133         /* Handle Transfer */
1134         SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1135                              hsmbus->XferOptions,
1136                              SMBUS_GENERATE_START_READ);
1137       }
1138     }
1139 
1140     /* Process Unlocked */
1141     __HAL_UNLOCK(hsmbus);
1142 
1143     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1144               to avoid the risk of SMBUS interrupt handle execution before current
1145               process unlock */
1146     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1147 
1148     return HAL_OK;
1149   }
1150   else
1151   {
1152     return HAL_BUSY;
1153   }
1154 }
1155 
1156 /**
1157   * @brief  Abort a master/host SMBUS process communication with Interrupt.
1158   * @note   This abort can be called only if state is ready
1159   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1160   *                the configuration information for the specified SMBUS.
1161   * @param  DevAddress Target device address: The device 7 bits address value
1162   *         in datasheet must be shifted to the left before calling the interface
1163   * @retval HAL status
1164   */
1165 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
1166 {
1167   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1168   {
1169     /* Process Locked */
1170     __HAL_LOCK(hsmbus);
1171 
1172     /* Keep the same state as previous */
1173     /* to perform as well the call of the corresponding end of transfer callback */
1174     if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1175     {
1176       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
1177     }
1178     else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1179     {
1180       hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1181     }
1182     else
1183     {
1184       /* Wrong usage of abort function */
1185       /* This function should be used only in case of abort monitored by master device */
1186       return HAL_ERROR;
1187     }
1188     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1189 
1190     /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
1191     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
1192     SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
1193 
1194     /* Process Unlocked */
1195     __HAL_UNLOCK(hsmbus);
1196 
1197     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1198               to avoid the risk of SMBUS interrupt handle execution before current
1199               process unlock */
1200     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1201     {
1202       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
1203     }
1204     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1205     {
1206       SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1207     }
1208     else
1209     {
1210       /* Nothing to do */
1211     }
1212 
1213     return HAL_OK;
1214   }
1215   else
1216   {
1217     return HAL_BUSY;
1218   }
1219 }
1220 
1221 /**
1222   * @brief  Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1223   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1224   *                the configuration information for the specified SMBUS.
1225   * @param  pData Pointer to data buffer
1226   * @param  Size Amount of data to be sent
1227   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1228   * @retval HAL status
1229   */
1230 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size,
1231                                               uint32_t XferOptions)
1232 {
1233   /* Check the parameters */
1234   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1235 
1236   if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1237   {
1238     if ((pData == NULL) || (Size == 0UL))
1239     {
1240       hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1241       return HAL_ERROR;
1242     }
1243 
1244     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1245     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
1246 
1247     /* Process Locked */
1248     __HAL_LOCK(hsmbus);
1249 
1250     hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN);
1251     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1252 
1253     /* Set SBC bit to manage Acknowledge at each bit */
1254     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1255 
1256     /* Enable Address Acknowledge */
1257     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1258 
1259     /* Prepare transfer parameters */
1260     hsmbus->pBuffPtr = pData;
1261     hsmbus->XferCount = Size;
1262     hsmbus->XferOptions = XferOptions;
1263 
1264     /* Convert OTHER_xxx XferOptions if any */
1265     SMBUS_ConvertOtherXferOptions(hsmbus);
1266 
1267     if (Size > MAX_NBYTE_SIZE)
1268     {
1269       hsmbus->XferSize = MAX_NBYTE_SIZE;
1270     }
1271     else
1272     {
1273       hsmbus->XferSize = Size;
1274     }
1275 
1276     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1277     if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1278     {
1279       SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize,
1280                            SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
1281                            SMBUS_NO_STARTSTOP);
1282     }
1283     else
1284     {
1285       /* Set NBYTE to transmit */
1286       SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1287                            SMBUS_NO_STARTSTOP);
1288 
1289       /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1290       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1291       if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1292       {
1293         hsmbus->XferSize--;
1294         hsmbus->XferCount--;
1295       }
1296     }
1297 
1298     /* Clear ADDR flag after prepare the transfer parameters */
1299     /* This action will generate an acknowledge to the HOST */
1300     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1301 
1302     /* Process Unlocked */
1303     __HAL_UNLOCK(hsmbus);
1304 
1305     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1306               to avoid the risk of SMBUS interrupt handle execution before current
1307               process unlock */
1308     /* REnable ADDR interrupt */
1309     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
1310 
1311     return HAL_OK;
1312   }
1313   else
1314   {
1315     return HAL_BUSY;
1316   }
1317 }
1318 
1319 /**
1320   * @brief  Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1321   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1322   *                the configuration information for the specified SMBUS.
1323   * @param  pData Pointer to data buffer
1324   * @param  Size Amount of data to be sent
1325   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1326   * @retval HAL status
1327   */
1328 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size,
1329                                              uint32_t XferOptions)
1330 {
1331   /* Check the parameters */
1332   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1333 
1334   if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1335   {
1336     if ((pData == NULL) || (Size == 0UL))
1337     {
1338       hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1339       return HAL_ERROR;
1340     }
1341 
1342     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1343     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
1344 
1345     /* Process Locked */
1346     __HAL_LOCK(hsmbus);
1347 
1348     hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN);
1349     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1350 
1351     /* Set SBC bit to manage Acknowledge at each bit */
1352     hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1353 
1354     /* Enable Address Acknowledge */
1355     hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1356 
1357     /* Prepare transfer parameters */
1358     hsmbus->pBuffPtr = pData;
1359     hsmbus->XferSize = Size;
1360     hsmbus->XferCount = Size;
1361     hsmbus->XferOptions = XferOptions;
1362 
1363     /* Convert OTHER_xxx XferOptions if any */
1364     SMBUS_ConvertOtherXferOptions(hsmbus);
1365 
1366     /* Set NBYTE to receive */
1367     /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
1368     /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
1369     /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
1370     /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
1371     if (((SMBUS_GET_PEC_MODE(hsmbus) != 0UL) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U))
1372     {
1373       SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1374                            SMBUS_NO_STARTSTOP);
1375     }
1376     else
1377     {
1378       SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
1379     }
1380 
1381     /* Clear ADDR flag after prepare the transfer parameters */
1382     /* This action will generate an acknowledge to the HOST */
1383     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1384 
1385     /* Process Unlocked */
1386     __HAL_UNLOCK(hsmbus);
1387 
1388     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1389               to avoid the risk of SMBUS interrupt handle execution before current
1390               process unlock */
1391     /* REnable ADDR interrupt */
1392     SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
1393 
1394     return HAL_OK;
1395   }
1396   else
1397   {
1398     return HAL_BUSY;
1399   }
1400 }
1401 
1402 /**
1403   * @brief  Enable the Address listen mode with Interrupt.
1404   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1405   *                the configuration information for the specified SMBUS.
1406   * @retval HAL status
1407   */
1408 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1409 {
1410   hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1411 
1412   /* Enable the Address Match interrupt */
1413   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
1414 
1415   return HAL_OK;
1416 }
1417 
1418 /**
1419   * @brief  Disable the Address listen mode with Interrupt.
1420   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1421   *                the configuration information for the specified SMBUS.
1422   * @retval HAL status
1423   */
1424 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1425 {
1426   /* Disable Address listen mode only if a transfer is not ongoing */
1427   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1428   {
1429     hsmbus->State = HAL_SMBUS_STATE_READY;
1430 
1431     /* Disable the Address Match interrupt */
1432     SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1433 
1434     return HAL_OK;
1435   }
1436   else
1437   {
1438     return HAL_BUSY;
1439   }
1440 }
1441 
1442 /**
1443   * @brief  Enable the SMBUS alert mode with Interrupt.
1444   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1445   *                the configuration information for the specified SMBUSx peripheral.
1446   * @retval HAL status
1447   */
1448 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1449 {
1450   /* Enable SMBus alert */
1451   hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
1452 
1453   /* Clear ALERT flag */
1454   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1455 
1456   /* Enable Alert Interrupt */
1457   SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
1458 
1459   return HAL_OK;
1460 }
1461 /**
1462   * @brief  Disable the SMBUS alert mode with Interrupt.
1463   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1464   *                the configuration information for the specified SMBUSx peripheral.
1465   * @retval HAL status
1466   */
1467 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1468 {
1469   /* Enable SMBus alert */
1470   hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
1471 
1472   /* Disable Alert Interrupt */
1473   SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
1474 
1475   return HAL_OK;
1476 }
1477 
1478 /**
1479   * @brief  Check if target device is ready for communication.
1480   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1481   *                the configuration information for the specified SMBUS.
1482   * @param  DevAddress Target device address: The device 7 bits address value
1483   *         in datasheet must be shifted to the left before calling the interface
1484   * @param  Trials Number of trials
1485   * @param  Timeout Timeout duration
1486   * @retval HAL status
1487   */
1488 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials,
1489                                           uint32_t Timeout)
1490 {
1491   uint32_t tickstart;
1492 
1493   __IO uint32_t SMBUS_Trials = 0UL;
1494 
1495   FlagStatus tmp1;
1496   FlagStatus tmp2;
1497 
1498   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1499   {
1500     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
1501     {
1502       return HAL_BUSY;
1503     }
1504 
1505     /* Process Locked */
1506     __HAL_LOCK(hsmbus);
1507 
1508     hsmbus->State = HAL_SMBUS_STATE_BUSY;
1509     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1510 
1511     do
1512     {
1513       /* Generate Start */
1514       hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress);
1515 
1516       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1517       /* Wait until STOPF flag is set or a NACK flag is set*/
1518       tickstart = HAL_GetTick();
1519 
1520       tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1521       tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1522 
1523       while ((tmp1 == RESET) && (tmp2 == RESET))
1524       {
1525         if (Timeout != HAL_MAX_DELAY)
1526         {
1527           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
1528           {
1529             /* Device is ready */
1530             hsmbus->State = HAL_SMBUS_STATE_READY;
1531 
1532             /* Update SMBUS error code */
1533             hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1534 
1535             /* Process Unlocked */
1536             __HAL_UNLOCK(hsmbus);
1537             return HAL_ERROR;
1538           }
1539         }
1540 
1541         tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1542         tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1543       }
1544 
1545       /* Check if the NACKF flag has not been set */
1546       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
1547       {
1548         /* Wait until STOPF flag is reset */
1549         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1550         {
1551           return HAL_ERROR;
1552         }
1553 
1554         /* Clear STOP Flag */
1555         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1556 
1557         /* Device is ready */
1558         hsmbus->State = HAL_SMBUS_STATE_READY;
1559 
1560         /* Process Unlocked */
1561         __HAL_UNLOCK(hsmbus);
1562 
1563         return HAL_OK;
1564       }
1565       else
1566       {
1567         /* Wait until STOPF flag is reset */
1568         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1569         {
1570           return HAL_ERROR;
1571         }
1572 
1573         /* Clear NACK Flag */
1574         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1575 
1576         /* Clear STOP Flag, auto generated with autoend*/
1577         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1578       }
1579 
1580       /* Check if the maximum allowed number of trials has been reached */
1581       if (SMBUS_Trials == Trials)
1582       {
1583         /* Generate Stop */
1584         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1585 
1586         /* Wait until STOPF flag is reset */
1587         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1588         {
1589           return HAL_ERROR;
1590         }
1591 
1592         /* Clear STOP Flag */
1593         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1594       }
1595 
1596       /* Increment Trials */
1597       SMBUS_Trials++;
1598     } while (SMBUS_Trials < Trials);
1599 
1600     hsmbus->State = HAL_SMBUS_STATE_READY;
1601 
1602     /* Update SMBUS error code */
1603     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1604 
1605     /* Process Unlocked */
1606     __HAL_UNLOCK(hsmbus);
1607 
1608     return HAL_ERROR;
1609   }
1610   else
1611   {
1612     return HAL_BUSY;
1613   }
1614 }
1615 /**
1616   * @}
1617   */
1618 
1619 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1620   * @ingroup RTEMSBSPsARMSTM32H7
1621   * @{
1622   */
1623 
1624 /**
1625   * @brief  Handle SMBUS event interrupt request.
1626   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1627   *                the configuration information for the specified SMBUS.
1628   * @retval None
1629   */
1630 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1631 {
1632   /* Use a local variable to store the current ISR flags */
1633   /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1634   uint32_t tmpisrvalue = READ_REG(hsmbus->Instance->ISR);
1635   uint32_t tmpcr1value = READ_REG(hsmbus->Instance->CR1);
1636 
1637   /* SMBUS in mode Transmitter ---------------------------------------------------*/
1638   if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI |
1639                                            SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) &&
1640       ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) ||
1641        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) ||
1642        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) ||
1643        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1644        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1645   {
1646     /* Slave mode selected */
1647     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1648     {
1649       (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1650     }
1651     /* Master mode selected */
1652     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1653     {
1654       (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1655     }
1656     else
1657     {
1658       /* Nothing to do */
1659     }
1660   }
1661 
1662   /* SMBUS in mode Receiver ----------------------------------------------------*/
1663   if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI |
1664                                            SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET) &&
1665       ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) ||
1666        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) ||
1667        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) ||
1668        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1669        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1670   {
1671     /* Slave mode selected */
1672     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1673     {
1674       (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1675     }
1676     /* Master mode selected */
1677     else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1678     {
1679       (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1680     }
1681     else
1682     {
1683       /* Nothing to do */
1684     }
1685   }
1686 
1687   /* SMBUS in mode Listener Only --------------------------------------------------*/
1688   if (((SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_ADDRI) != RESET) ||
1689        (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_STOPI) != RESET) ||
1690        (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_NACKI) != RESET)) &&
1691       ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) ||
1692        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1693        (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1694   {
1695     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1696     {
1697       (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1698     }
1699   }
1700 }
1701 
1702 /**
1703   * @brief  Handle SMBUS error interrupt request.
1704   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1705   *                the configuration information for the specified SMBUS.
1706   * @retval None
1707   */
1708 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1709 {
1710   SMBUS_ITErrorHandler(hsmbus);
1711 }
1712 
1713 /**
1714   * @brief  Master Tx Transfer completed callback.
1715   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1716   *                the configuration information for the specified SMBUS.
1717   * @retval None
1718   */
1719 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1720 {
1721   /* Prevent unused argument(s) compilation warning */
1722   UNUSED(hsmbus);
1723 
1724   /* NOTE : This function should not be modified, when the callback is needed,
1725             the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
1726    */
1727 }
1728 
1729 /**
1730   * @brief  Master Rx Transfer completed callback.
1731   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1732   *                the configuration information for the specified SMBUS.
1733   * @retval None
1734   */
1735 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1736 {
1737   /* Prevent unused argument(s) compilation warning */
1738   UNUSED(hsmbus);
1739 
1740   /* NOTE : This function should not be modified, when the callback is needed,
1741             the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
1742    */
1743 }
1744 
1745 /** @brief  Slave Tx Transfer completed callback.
1746   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1747   *                the configuration information for the specified SMBUS.
1748   * @retval None
1749   */
1750 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1751 {
1752   /* Prevent unused argument(s) compilation warning */
1753   UNUSED(hsmbus);
1754 
1755   /* NOTE : This function should not be modified, when the callback is needed,
1756             the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
1757    */
1758 }
1759 
1760 /**
1761   * @brief  Slave Rx Transfer completed callback.
1762   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1763   *                the configuration information for the specified SMBUS.
1764   * @retval None
1765   */
1766 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1767 {
1768   /* Prevent unused argument(s) compilation warning */
1769   UNUSED(hsmbus);
1770 
1771   /* NOTE : This function should not be modified, when the callback is needed,
1772             the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
1773    */
1774 }
1775 
1776 /**
1777   * @brief  Slave Address Match callback.
1778   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1779   *                the configuration information for the specified SMBUS.
1780   * @param  TransferDirection Master request Transfer Direction (Write/Read)
1781   * @param  AddrMatchCode Address Match Code
1782   * @retval None
1783   */
1784 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection,
1785                                    uint16_t AddrMatchCode)
1786 {
1787   /* Prevent unused argument(s) compilation warning */
1788   UNUSED(hsmbus);
1789   UNUSED(TransferDirection);
1790   UNUSED(AddrMatchCode);
1791 
1792   /* NOTE : This function should not be modified, when the callback is needed,
1793             the HAL_SMBUS_AddrCallback() could be implemented in the user file
1794    */
1795 }
1796 
1797 /**
1798   * @brief  Listen Complete callback.
1799   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1800   *                the configuration information for the specified SMBUS.
1801   * @retval None
1802   */
1803 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1804 {
1805   /* Prevent unused argument(s) compilation warning */
1806   UNUSED(hsmbus);
1807 
1808   /* NOTE : This function should not be modified, when the callback is needed,
1809             the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
1810    */
1811 }
1812 
1813 /**
1814   * @brief  SMBUS error callback.
1815   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1816   *                the configuration information for the specified SMBUS.
1817   * @retval None
1818   */
1819 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1820 {
1821   /* Prevent unused argument(s) compilation warning */
1822   UNUSED(hsmbus);
1823 
1824   /* NOTE : This function should not be modified, when the callback is needed,
1825             the HAL_SMBUS_ErrorCallback() could be implemented in the user file
1826    */
1827 }
1828 
1829 /**
1830   * @}
1831   */
1832 
1833 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1834   * @ingroup RTEMSBSPsARMSTM32H7
1835   *  @brief   Peripheral State and Errors functions
1836   *
1837 @verbatim
1838  ===============================================================================
1839             ##### Peripheral State and Errors functions #####
1840  ===============================================================================
1841     [..]
1842     This subsection permits to get in run-time the status of the peripheral
1843     and the data flow.
1844 
1845 @endverbatim
1846   * @{
1847   */
1848 
1849 /**
1850   * @brief  Return the SMBUS handle state.
1851   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1852   *                the configuration information for the specified SMBUS.
1853   * @retval HAL state
1854   */
1855 uint32_t HAL_SMBUS_GetState(const SMBUS_HandleTypeDef *hsmbus)
1856 {
1857   /* Return SMBUS handle state */
1858   return hsmbus->State;
1859 }
1860 
1861 /**
1862   * @brief  Return the SMBUS error code.
1863   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1864   *              the configuration information for the specified SMBUS.
1865   * @retval SMBUS Error Code
1866   */
1867 uint32_t HAL_SMBUS_GetError(const SMBUS_HandleTypeDef *hsmbus)
1868 {
1869   return hsmbus->ErrorCode;
1870 }
1871 
1872 /**
1873   * @}
1874   */
1875 
1876 /**
1877   * @}
1878   */
1879 
1880 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1881   *  @brief   Data transfers Private functions
1882   * @{
1883   */
1884 
1885 /**
1886   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
1887   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1888   *                the configuration information for the specified SMBUS.
1889   * @param  StatusFlags Value of Interrupt Flags.
1890   * @retval HAL status
1891   */
1892 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
1893 {
1894   uint16_t DevAddress;
1895 
1896   /* Process Locked */
1897   __HAL_LOCK(hsmbus);
1898 
1899   if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
1900   {
1901     /* Clear NACK Flag */
1902     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1903 
1904     /* Set corresponding Error Code */
1905     /* No need to generate STOP, it is automatically done */
1906     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1907 
1908     /* Flush TX register */
1909     SMBUS_Flush_TXDR(hsmbus);
1910 
1911     /* Process Unlocked */
1912     __HAL_UNLOCK(hsmbus);
1913 
1914     /* Call the Error callback to inform upper layer */
1915 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1916     hsmbus->ErrorCallback(hsmbus);
1917 #else
1918     HAL_SMBUS_ErrorCallback(hsmbus);
1919 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1920   }
1921   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
1922   {
1923     /* Check and treat errors if errors occurs during STOP process */
1924     SMBUS_ITErrorHandler(hsmbus);
1925 
1926     /* Call the corresponding callback to inform upper layer of End of Transfer */
1927     if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1928     {
1929       /* Disable Interrupt */
1930       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1931 
1932       /* Clear STOP Flag */
1933       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1934 
1935       /* Clear Configuration Register 2 */
1936       SMBUS_RESET_CR2(hsmbus);
1937 
1938       /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1939       /* Disable the selected SMBUS peripheral */
1940       __HAL_SMBUS_DISABLE(hsmbus);
1941 
1942       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1943       hsmbus->State = HAL_SMBUS_STATE_READY;
1944 
1945       /* Process Unlocked */
1946       __HAL_UNLOCK(hsmbus);
1947 
1948       /* Re-enable the selected SMBUS peripheral */
1949       __HAL_SMBUS_ENABLE(hsmbus);
1950 
1951       /* Call the corresponding callback to inform upper layer of End of Transfer */
1952 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1953       hsmbus->MasterTxCpltCallback(hsmbus);
1954 #else
1955       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1956 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1957     }
1958     else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1959     {
1960       /* Store Last receive data if any */
1961       if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
1962       {
1963         /* Read data from RXDR */
1964         *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
1965 
1966         /* Increment Buffer pointer */
1967         hsmbus->pBuffPtr++;
1968 
1969         if ((hsmbus->XferSize > 0U))
1970         {
1971           hsmbus->XferSize--;
1972           hsmbus->XferCount--;
1973         }
1974       }
1975 
1976       /* Disable Interrupt */
1977       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1978 
1979       /* Clear STOP Flag */
1980       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1981 
1982       /* Clear Configuration Register 2 */
1983       SMBUS_RESET_CR2(hsmbus);
1984 
1985       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1986       hsmbus->State = HAL_SMBUS_STATE_READY;
1987 
1988       /* Process Unlocked */
1989       __HAL_UNLOCK(hsmbus);
1990 
1991       /* Call the corresponding callback to inform upper layer of End of Transfer */
1992 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1993       hsmbus->MasterRxCpltCallback(hsmbus);
1994 #else
1995       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1996 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1997     }
1998     else
1999     {
2000       /* Nothing to do */
2001     }
2002   }
2003   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
2004   {
2005     /* Read data from RXDR */
2006     *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2007 
2008     /* Increment Buffer pointer */
2009     hsmbus->pBuffPtr++;
2010 
2011     /* Increment Size counter */
2012     hsmbus->XferSize--;
2013     hsmbus->XferCount--;
2014   }
2015   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
2016   {
2017     /* Write data to TXDR */
2018     hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
2019 
2020     /* Increment Buffer pointer */
2021     hsmbus->pBuffPtr++;
2022 
2023     /* Increment Size counter */
2024     hsmbus->XferSize--;
2025     hsmbus->XferCount--;
2026   }
2027   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET)
2028   {
2029     if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
2030     {
2031       DevAddress = (uint16_t)(hsmbus->Instance->CR2 & I2C_CR2_SADD);
2032 
2033       if (hsmbus->XferCount > MAX_NBYTE_SIZE)
2034       {
2035         SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE,
2036                              (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)),
2037                              SMBUS_NO_STARTSTOP);
2038         hsmbus->XferSize = MAX_NBYTE_SIZE;
2039       }
2040       else
2041       {
2042         hsmbus->XferSize = hsmbus->XferCount;
2043         SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
2044                              SMBUS_NO_STARTSTOP);
2045         /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2046         /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2047         if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
2048         {
2049           hsmbus->XferSize--;
2050           hsmbus->XferCount--;
2051         }
2052       }
2053     }
2054     else if ((hsmbus->XferCount == 0U) && (hsmbus->XferSize == 0U))
2055     {
2056       /* Call TxCpltCallback() if no stop mode is set */
2057       if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
2058       {
2059         /* Call the corresponding callback to inform upper layer of End of Transfer */
2060         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
2061         {
2062           /* Disable Interrupt */
2063           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2064           hsmbus->PreviousState = hsmbus->State;
2065           hsmbus->State = HAL_SMBUS_STATE_READY;
2066 
2067           /* Process Unlocked */
2068           __HAL_UNLOCK(hsmbus);
2069 
2070           /* Call the corresponding callback to inform upper layer of End of Transfer */
2071 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2072           hsmbus->MasterTxCpltCallback(hsmbus);
2073 #else
2074           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2075 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2076         }
2077         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
2078         {
2079           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2080           hsmbus->PreviousState = hsmbus->State;
2081           hsmbus->State = HAL_SMBUS_STATE_READY;
2082 
2083           /* Process Unlocked */
2084           __HAL_UNLOCK(hsmbus);
2085 
2086           /* Call the corresponding callback to inform upper layer of End of Transfer */
2087 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2088           hsmbus->MasterRxCpltCallback(hsmbus);
2089 #else
2090           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2091 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2092         }
2093         else
2094         {
2095           /* Nothing to do */
2096         }
2097       }
2098     }
2099     else
2100     {
2101       /* Nothing to do */
2102     }
2103   }
2104   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TC) != RESET)
2105   {
2106     if (hsmbus->XferCount == 0U)
2107     {
2108       /* Specific use case for Quick command */
2109       if (hsmbus->pBuffPtr == NULL)
2110       {
2111         /* Generate a Stop command */
2112         hsmbus->Instance->CR2 |= I2C_CR2_STOP;
2113       }
2114       /* Call TxCpltCallback() if no stop mode is set */
2115       else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
2116       {
2117         /* No Generate Stop, to permit restart mode */
2118         /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
2119 
2120         /* Call the corresponding callback to inform upper layer of End of Transfer */
2121         if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
2122         {
2123           /* Disable Interrupt */
2124           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2125           hsmbus->PreviousState = hsmbus->State;
2126           hsmbus->State = HAL_SMBUS_STATE_READY;
2127 
2128           /* Process Unlocked */
2129           __HAL_UNLOCK(hsmbus);
2130 
2131           /* Call the corresponding callback to inform upper layer of End of Transfer */
2132 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2133           hsmbus->MasterTxCpltCallback(hsmbus);
2134 #else
2135           HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2136 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2137         }
2138         else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
2139         {
2140           SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2141           hsmbus->PreviousState = hsmbus->State;
2142           hsmbus->State = HAL_SMBUS_STATE_READY;
2143 
2144           /* Process Unlocked */
2145           __HAL_UNLOCK(hsmbus);
2146 
2147           /* Call the corresponding callback to inform upper layer of End of Transfer */
2148 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2149           hsmbus->MasterRxCpltCallback(hsmbus);
2150 #else
2151           HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2152 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2153         }
2154         else
2155         {
2156           /* Nothing to do */
2157         }
2158       }
2159       else
2160       {
2161         /* Nothing to do */
2162       }
2163     }
2164   }
2165   else
2166   {
2167     /* Nothing to do */
2168   }
2169 
2170   /* Process Unlocked */
2171   __HAL_UNLOCK(hsmbus);
2172 
2173   return HAL_OK;
2174 }
2175 /**
2176   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
2177   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2178   *                the configuration information for the specified SMBUS.
2179   * @param  StatusFlags Value of Interrupt Flags.
2180   * @retval HAL status
2181   */
2182 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
2183 {
2184   uint8_t TransferDirection;
2185   uint16_t SlaveAddrCode;
2186 
2187   /* Process Locked */
2188   __HAL_LOCK(hsmbus);
2189 
2190   if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
2191   {
2192     /* Check that SMBUS transfer finished */
2193     /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
2194     /* Mean XferCount == 0*/
2195     /* So clear Flag NACKF only */
2196     if (hsmbus->XferCount == 0U)
2197     {
2198       /* Clear NACK Flag */
2199       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2200 
2201       /* Flush TX register */
2202       SMBUS_Flush_TXDR(hsmbus);
2203 
2204       /* Process Unlocked */
2205       __HAL_UNLOCK(hsmbus);
2206     }
2207     else
2208     {
2209       /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
2210       /* Clear NACK Flag */
2211       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2212 
2213       /* Set HAL State to "Idle" State, mean to LISTEN state */
2214       /* So reset Slave Busy state */
2215       hsmbus->PreviousState = hsmbus->State;
2216       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2217       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2218 
2219       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
2220       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2221 
2222       /* Set ErrorCode corresponding to a Non-Acknowledge */
2223       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
2224 
2225       /* Flush TX register */
2226       SMBUS_Flush_TXDR(hsmbus);
2227 
2228       /* Process Unlocked */
2229       __HAL_UNLOCK(hsmbus);
2230 
2231       /* Call the Error callback to inform upper layer */
2232 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2233       hsmbus->ErrorCallback(hsmbus);
2234 #else
2235       HAL_SMBUS_ErrorCallback(hsmbus);
2236 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2237     }
2238   }
2239   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_ADDR) != RESET)
2240   {
2241     TransferDirection = (uint8_t)(SMBUS_GET_DIR(hsmbus));
2242     SlaveAddrCode = (uint16_t)(SMBUS_GET_ADDR_MATCH(hsmbus));
2243 
2244     /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
2245     /* Other ADDRInterrupt will be treat in next Listen usecase */
2246     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
2247 
2248     /* Process Unlocked */
2249     __HAL_UNLOCK(hsmbus);
2250 
2251     /* Call Slave Addr callback */
2252 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2253     hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2254 #else
2255     HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2256 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2257   }
2258   else if ((SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) ||
2259            (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET))
2260   {
2261     if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
2262     {
2263       /* Read data from RXDR */
2264       *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2265 
2266       /* Increment Buffer pointer */
2267       hsmbus->pBuffPtr++;
2268 
2269       hsmbus->XferSize--;
2270       hsmbus->XferCount--;
2271 
2272       if (hsmbus->XferCount == 1U)
2273       {
2274         /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
2275         /* or only the last Byte of Transfer */
2276         /* So reset the RELOAD bit mode */
2277         hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
2278         SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
2279       }
2280       else if (hsmbus->XferCount == 0U)
2281       {
2282         /* Last Byte is received, disable Interrupt */
2283         SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2284 
2285         /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
2286         hsmbus->PreviousState = hsmbus->State;
2287         hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2288 
2289         /* Process Unlocked */
2290         __HAL_UNLOCK(hsmbus);
2291 
2292         /* Call the corresponding callback to inform upper layer of End of Transfer */
2293 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2294         hsmbus->SlaveRxCpltCallback(hsmbus);
2295 #else
2296         HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
2297 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2298       }
2299       else
2300       {
2301         /* Set Reload for next Bytes */
2302         SMBUS_TransferConfig(hsmbus, 0, 1,
2303                              SMBUS_RELOAD_MODE  | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
2304                              SMBUS_NO_STARTSTOP);
2305 
2306         /* Ack last Byte Read */
2307         hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
2308       }
2309     }
2310     else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2311     {
2312       if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
2313       {
2314         if (hsmbus->XferCount > MAX_NBYTE_SIZE)
2315         {
2316           SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE,
2317                                (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)),
2318                                SMBUS_NO_STARTSTOP);
2319           hsmbus->XferSize = MAX_NBYTE_SIZE;
2320         }
2321         else
2322         {
2323           hsmbus->XferSize = hsmbus->XferCount;
2324           SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
2325                                SMBUS_NO_STARTSTOP);
2326           /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2327           /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2328           if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
2329           {
2330             hsmbus->XferSize--;
2331             hsmbus->XferCount--;
2332           }
2333         }
2334       }
2335     }
2336     else
2337     {
2338       /* Nothing to do */
2339     }
2340   }
2341   else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
2342   {
2343     /* Write data to TXDR only if XferCount not reach "0" */
2344     /* A TXIS flag can be set, during STOP treatment      */
2345     /* Check if all Data have already been sent */
2346     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
2347     if (hsmbus->XferCount > 0U)
2348     {
2349       /* Write data to TXDR */
2350       hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
2351 
2352       /* Increment Buffer pointer */
2353       hsmbus->pBuffPtr++;
2354 
2355       hsmbus->XferCount--;
2356       hsmbus->XferSize--;
2357     }
2358 
2359     if (hsmbus->XferCount == 0U)
2360     {
2361       /* Last Byte is Transmitted */
2362       /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
2363       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2364       hsmbus->PreviousState = hsmbus->State;
2365       hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2366 
2367       /* Process Unlocked */
2368       __HAL_UNLOCK(hsmbus);
2369 
2370       /* Call the corresponding callback to inform upper layer of End of Transfer */
2371 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2372       hsmbus->SlaveTxCpltCallback(hsmbus);
2373 #else
2374       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
2375 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2376     }
2377   }
2378   else
2379   {
2380     /* Nothing to do */
2381   }
2382 
2383   /* Check if STOPF is set */
2384   if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
2385   {
2386     if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
2387     {
2388       /* Store Last receive data if any */
2389       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
2390       {
2391         /* Read data from RXDR */
2392         *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2393 
2394         /* Increment Buffer pointer */
2395         hsmbus->pBuffPtr++;
2396 
2397         if ((hsmbus->XferSize > 0U))
2398         {
2399           hsmbus->XferSize--;
2400           hsmbus->XferCount--;
2401         }
2402       }
2403 
2404       /* Disable RX and TX Interrupts */
2405       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2406 
2407       /* Disable ADDR Interrupt */
2408       SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
2409 
2410       /* Disable Address Acknowledge */
2411       hsmbus->Instance->CR2 |= I2C_CR2_NACK;
2412 
2413       /* Clear Configuration Register 2 */
2414       SMBUS_RESET_CR2(hsmbus);
2415 
2416       /* Clear STOP Flag */
2417       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
2418 
2419       /* Clear ADDR flag */
2420       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
2421 
2422       hsmbus->XferOptions = 0;
2423       hsmbus->PreviousState = hsmbus->State;
2424       hsmbus->State = HAL_SMBUS_STATE_READY;
2425 
2426       /* Process Unlocked */
2427       __HAL_UNLOCK(hsmbus);
2428 
2429       /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2430 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2431       hsmbus->ListenCpltCallback(hsmbus);
2432 #else
2433       HAL_SMBUS_ListenCpltCallback(hsmbus);
2434 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2435     }
2436   }
2437 
2438   /* Process Unlocked */
2439   __HAL_UNLOCK(hsmbus);
2440 
2441   return HAL_OK;
2442 }
2443 /**
2444   * @brief  Manage the enabling of Interrupts.
2445   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2446   *                the configuration information for the specified SMBUS.
2447   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2448   * @retval HAL status
2449   */
2450 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2451 {
2452   uint32_t tmpisr = 0UL;
2453 
2454   if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
2455   {
2456     /* Enable ERR interrupt */
2457     tmpisr |= SMBUS_IT_ERRI;
2458   }
2459 
2460   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2461   {
2462     /* Enable ADDR, STOP interrupt */
2463     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
2464   }
2465 
2466   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2467   {
2468     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2469     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
2470   }
2471 
2472   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2473   {
2474     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2475     tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
2476   }
2477 
2478   /* Enable interrupts only at the end */
2479   /* to avoid the risk of SMBUS interrupt handle execution before */
2480   /* all interrupts requested done */
2481   __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
2482 }
2483 /**
2484   * @brief  Manage the disabling of Interrupts.
2485   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2486   *                the configuration information for the specified SMBUS.
2487   * @param  InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2488   * @retval HAL status
2489   */
2490 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2491 {
2492   uint32_t tmpisr = 0UL;
2493   uint32_t tmpstate = hsmbus->State;
2494 
2495   if ((tmpstate == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT))
2496   {
2497     /* Disable ERR interrupt */
2498     tmpisr |= SMBUS_IT_ERRI;
2499   }
2500 
2501   if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2502   {
2503     /* Disable TC, STOP, NACK and TXI interrupt */
2504     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
2505 
2506     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2507         && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2508     {
2509       /* Disable ERR interrupt */
2510       tmpisr |= SMBUS_IT_ERRI;
2511     }
2512 
2513     if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2514     {
2515       /* Disable STOP and NACK interrupt */
2516       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2517     }
2518   }
2519 
2520   if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2521   {
2522     /* Disable TC, STOP, NACK and RXI interrupt */
2523     tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
2524 
2525     if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2526         && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2527     {
2528       /* Disable ERR interrupt */
2529       tmpisr |= SMBUS_IT_ERRI;
2530     }
2531 
2532     if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2533     {
2534       /* Disable STOP and NACK interrupt */
2535       tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2536     }
2537   }
2538 
2539   if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2540   {
2541     /* Disable ADDR, STOP and NACK interrupt */
2542     tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2543 
2544     if (SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2545     {
2546       /* Disable ERR interrupt */
2547       tmpisr |= SMBUS_IT_ERRI;
2548     }
2549   }
2550 
2551   /* Disable interrupts only at the end */
2552   /* to avoid a breaking situation like at "t" time */
2553   /* all disable interrupts request are not done */
2554   __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
2555 }
2556 
2557 /**
2558   * @brief  SMBUS interrupts error handler.
2559   * @param  hsmbus SMBUS handle.
2560   * @retval None
2561   */
2562 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus)
2563 {
2564   uint32_t itflags   = READ_REG(hsmbus->Instance->ISR);
2565   uint32_t itsources = READ_REG(hsmbus->Instance->CR1);
2566   uint32_t tmpstate;
2567   uint32_t tmperror;
2568 
2569   /* SMBUS Bus error interrupt occurred ------------------------------------*/
2570   if (((itflags & SMBUS_FLAG_BERR) == SMBUS_FLAG_BERR) && \
2571       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2572   {
2573     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
2574 
2575     /* Clear BERR flag */
2576     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
2577   }
2578 
2579   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
2580   if (((itflags & SMBUS_FLAG_OVR) == SMBUS_FLAG_OVR) && \
2581       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2582   {
2583     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
2584 
2585     /* Clear OVR flag */
2586     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
2587   }
2588 
2589   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
2590   if (((itflags & SMBUS_FLAG_ARLO) == SMBUS_FLAG_ARLO) && \
2591       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2592   {
2593     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
2594 
2595     /* Clear ARLO flag */
2596     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
2597   }
2598 
2599   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
2600   if (((itflags & SMBUS_FLAG_TIMEOUT) == SMBUS_FLAG_TIMEOUT) && \
2601       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2602   {
2603     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
2604 
2605     /* Clear TIMEOUT flag */
2606     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
2607   }
2608 
2609   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
2610   if (((itflags & SMBUS_FLAG_ALERT) == SMBUS_FLAG_ALERT) && \
2611       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2612   {
2613     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
2614 
2615     /* Clear ALERT flag */
2616     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
2617   }
2618 
2619   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
2620   if (((itflags & SMBUS_FLAG_PECERR) == SMBUS_FLAG_PECERR) && \
2621       ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2622   {
2623     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
2624 
2625     /* Clear PEC error flag */
2626     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
2627   }
2628 
2629   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
2630   {
2631     /* Flush TX register */
2632     SMBUS_Flush_TXDR(hsmbus);
2633   }
2634 
2635   /* Store current volatile hsmbus->ErrorCode, misra rule */
2636   tmperror = hsmbus->ErrorCode;
2637 
2638   /* Call the Error Callback in case of Error detected */
2639   if ((tmperror != HAL_SMBUS_ERROR_NONE) && (tmperror != HAL_SMBUS_ERROR_ACKF))
2640   {
2641     /* Do not Reset the HAL state in case of ALERT error */
2642     if ((tmperror & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
2643     {
2644       /* Store current volatile hsmbus->State, misra rule */
2645       tmpstate = hsmbus->State;
2646 
2647       if (((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2648           || ((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
2649       {
2650         /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
2651         /* keep HAL_SMBUS_STATE_LISTEN if set */
2652         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2653         hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2654       }
2655     }
2656 
2657     /* Call the Error callback to inform upper layer */
2658 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2659     hsmbus->ErrorCallback(hsmbus);
2660 #else
2661     HAL_SMBUS_ErrorCallback(hsmbus);
2662 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2663   }
2664 }
2665 
2666 /**
2667   * @brief  Handle SMBUS Communication Timeout.
2668   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2669   *                the configuration information for the specified SMBUS.
2670   * @param  Flag Specifies the SMBUS flag to check.
2671   * @param  Status The new Flag status (SET or RESET).
2672   * @param  Timeout Timeout duration
2673   * @retval HAL status
2674   */
2675 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag,
2676                                                       FlagStatus Status, uint32_t Timeout)
2677 {
2678   uint32_t tickstart = HAL_GetTick();
2679 
2680   /* Wait until flag is set */
2681   while ((FlagStatus)(__HAL_SMBUS_GET_FLAG(hsmbus, Flag)) == Status)
2682   {
2683     /* Check for the Timeout */
2684     if (Timeout != HAL_MAX_DELAY)
2685     {
2686       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
2687       {
2688         hsmbus->PreviousState = hsmbus->State;
2689         hsmbus->State = HAL_SMBUS_STATE_READY;
2690 
2691         /* Update SMBUS error code */
2692         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
2693 
2694         /* Process Unlocked */
2695         __HAL_UNLOCK(hsmbus);
2696 
2697         return HAL_ERROR;
2698       }
2699     }
2700   }
2701 
2702   return HAL_OK;
2703 }
2704 
2705 /**
2706   * @brief  SMBUS Tx data register flush process.
2707   * @param  hsmbus SMBUS handle.
2708   * @retval None
2709   */
2710 static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus)
2711 {
2712   /* If a pending TXIS flag is set */
2713   /* Write a dummy data in TXDR to clear it */
2714   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
2715   {
2716     hsmbus->Instance->TXDR = 0x00U;
2717   }
2718 
2719   /* Flush TX register if not empty */
2720   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXE) == RESET)
2721   {
2722     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TXE);
2723   }
2724 }
2725 
2726 /**
2727   * @brief  Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
2728   * @param  hsmbus SMBUS handle.
2729   * @param  DevAddress specifies the slave address to be programmed.
2730   * @param  Size specifies the number of bytes to be programmed.
2731   *   This parameter must be a value between 0 and 255.
2732   * @param  Mode New state of the SMBUS START condition generation.
2733   *   This parameter can be one or a combination  of the following values:
2734   *     @arg @ref SMBUS_RELOAD_MODE Enable Reload mode.
2735   *     @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode.
2736   *     @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
2737   *     @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
2738   * @param  Request New state of the SMBUS START condition generation.
2739   *   This parameter can be one of the following values:
2740   *     @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition.
2741   *     @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
2742   *     @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request.
2743   *     @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request.
2744   * @retval None
2745   */
2746 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus,  uint16_t DevAddress, uint8_t Size,
2747                                  uint32_t Mode, uint32_t Request)
2748 {
2749   /* Check the parameters */
2750   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
2751   assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
2752   assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
2753 
2754   /* update CR2 register */
2755   MODIFY_REG(hsmbus->Instance->CR2,
2756              ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
2757                (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - I2C_CR2_RD_WRN_Pos))) | \
2758                I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \
2759              (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \
2760                         (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \
2761                         (uint32_t)Mode | (uint32_t)Request));
2762 }
2763 
2764 /**
2765   * @brief  Convert SMBUSx OTHER_xxx XferOptions to functional XferOptions.
2766   * @param  hsmbus SMBUS handle.
2767   * @retval None
2768   */
2769 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus)
2770 {
2771   /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC   */
2772   /* it request implicitly to generate a restart condition */
2773   /* set XferOptions to SMBUS_FIRST_FRAME                  */
2774   if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
2775   {
2776     hsmbus->XferOptions = SMBUS_FIRST_FRAME;
2777   }
2778   /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
2779   /* it request implicitly to generate a restart condition      */
2780   /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE  */
2781   else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
2782   {
2783     hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
2784   }
2785   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
2786   /* it request implicitly to generate a restart condition             */
2787   /* then generate a stop condition at the end of transfer             */
2788   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC              */
2789   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
2790   {
2791     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
2792   }
2793   /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
2794   /* it request implicitly to generate a restart condition               */
2795   /* then generate a stop condition at the end of transfer               */
2796   /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC              */
2797   else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
2798   {
2799     hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
2800   }
2801   else
2802   {
2803     /* Nothing to do */
2804   }
2805 }
2806 /**
2807   * @}
2808   */
2809 
2810 #endif /* HAL_SMBUS_MODULE_ENABLED */
2811 /**
2812   * @}
2813   */
2814 
2815 /**
2816   * @}
2817   */