1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_smbus.c
4   * @author  MCD Application Team
5   * @brief   SMBUS HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the System Management Bus (SMBus) peripheral,
8   *          based on SMBUS principals of operation :
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *           + Peripheral State, Mode and Error functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     The SMBUS HAL driver can be used as follows:
30 
31     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
32         SMBUS_HandleTypeDef  hsmbus;
33 
34     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
35         (##) Enable the SMBUSx interface clock
36         (##) SMBUS pins configuration
37             (+++) Enable the clock for the SMBUS GPIOs
38             (+++) Configure SMBUS pins as alternate function open-drain
39         (##) NVIC configuration if you need to use interrupt process
40             (+++) Configure the SMBUSx interrupt priority
41             (+++) Enable the NVIC SMBUS IRQ Channel
42 
43     (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
44         Dual Addressing mode, Own Address2, General call and Nostretch mode in the hsmbus Init structure.
45 
46     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init(), configures also the low level Hardware
47         (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
48 
49     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
50 
51     (#) For SMBUS IO operations, only one mode of operations is available within this driver :
52 
53 
54     *** Interrupt mode IO operation ***
55     ===================================
56 
57   [..]
58       (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Transmit_IT()
59       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and user can
60            add his own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
61       (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Master_Receive_IT()
62       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and user can
63            add his own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
64       (+) Abort a master/Host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
65       (++) End of abort process, HAL_SMBUS_AbortCpltCallback() is executed and user can
66            add his own code by customization of function pointer HAL_SMBUS_AbortCpltCallback()
67       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
68            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
69       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and user can
70            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
71       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and user can
72            add his own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
73       (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Transmit_IT()
74       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
75            add his own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
76       (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using HAL_SMBUS_Slave_Receive_IT()
77       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
78            add his own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
79       (+) Enable/Disable the SMBUS alert mode using HAL_SMBUS_EnableAlert_IT() and HAL_SMBUS_DisableAlert_IT()
80       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and user can
81            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
82            to check the Alert Error Code using function HAL_SMBUS_GetError()
83       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
84       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and user can
85            add his own code by customization of function pointer HAL_SMBUS_ErrorCallback()
86            to check the Error Code using function HAL_SMBUS_GetError()
87 
88 
89      *** SMBUS HAL driver macros list ***
90      ==================================
91      [..]
92        Below the list of most used macros in SMBUS HAL driver.
93 
94       (+) __HAL_SMBUS_ENABLE    : Enable the SMBUS peripheral
95       (+) __HAL_SMBUS_DISABLE   : Disable the SMBUS peripheral
96       (+) __HAL_SMBUS_GET_FLAG  : Checks whether the specified SMBUS flag is set or not
97       (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag
98       (+) __HAL_SMBUS_ENABLE_IT : Enable the specified SMBUS interrupt
99       (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt
100 
101      [..]
102        (@) You can refer to the SMBUS HAL driver header file for more useful macros
103 
104      *** Callback registration ***
105      =============================================
106     [..]
107      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
108      allows the user to configure dynamically the driver callbacks.
109      Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterXXXCallback()
110      to register an interrupt callback.
111 
112      Function HAL_SMBUS_RegisterCallback() allows to register following callbacks:
113        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
114        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
115        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
116        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
117        (+) ListenCpltCallback   : callback for end of listen mode.
118        (+) ErrorCallback        : callback for error detection.
119        (+) AbortCpltCallback    : callback for abort completion process.
120        (+) MspInitCallback      : callback for Msp Init.
121        (+) MspDeInitCallback    : callback for Msp DeInit.
122      This function takes as parameters the HAL peripheral handle, the Callback ID
123      and a pointer to the user callback function.
124     [..]
125      For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback().
126     [..]
127      Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default
128      weak function.
129      HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
130      and the Callback ID.
131      This function allows to reset following callbacks:
132        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
133        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
134        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
135        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
136        (+) ListenCpltCallback   : callback for end of listen mode.
137        (+) ErrorCallback        : callback for error detection.
138        (+) AbortCpltCallback    : callback for abort completion process.
139        (+) MspInitCallback      : callback for Msp Init.
140        (+) MspDeInitCallback    : callback for Msp DeInit.
141     [..]
142      For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback().
143     [..]
144      By default, after the HAL_SMBUS_Init() and when the state is HAL_SMBUS_STATE_RESET
145      all callbacks are set to the corresponding weak functions:
146      examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback().
147      Exception done for MspInit and MspDeInit functions that are
148      reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when
149      these callbacks are null (not registered beforehand).
150      If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit()
151      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
152     [..]
153      Callbacks can be registered/unregistered in HAL_SMBUS_STATE_READY state only.
154      Exception done MspInit/MspDeInit functions that can be registered/unregistered
155      in HAL_SMBUS_STATE_READY or HAL_SMBUS_STATE_RESET state,
156      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
157      Then, the user first registers the MspInit/MspDeInit user callbacks
158      using HAL_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit()
159      or HAL_SMBUS_Init() function.
160     [..]
161      When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
162      not defined, the callback registration feature is not available and all callbacks
163      are set to the corresponding weak functions.
164 
165   @endverbatim
166   */
167 
168 /* Includes ------------------------------------------------------------------*/
169 #include "stm32f4xx_hal.h"
170 
171 /** @addtogroup STM32F4xx_HAL_Driver
172   * @{
173   */
174 
175 /** @defgroup SMBUS SMBUS
176   * @brief SMBUS HAL module driver
177   * @{
178   */
179 
180 #ifdef HAL_SMBUS_MODULE_ENABLED
181 
182 /* Private typedef -----------------------------------------------------------*/
183 /* Private define ------------------------------------------------------------*/
184 /** @addtogroup SMBUS_Private_Define
185   * @{
186   */
187 #define SMBUS_TIMEOUT_FLAG          35U         /*!< Timeout 35 ms             */
188 #define SMBUS_TIMEOUT_BUSY_FLAG     25U         /*!< Timeout 25 ms             */
189 #define SMBUS_NO_OPTION_FRAME       0xFFFF0000U /*!< XferOptions default value */
190 
191 #define SMBUS_SENDPEC_MODE          I2C_CR1_PEC
192 #define SMBUS_GET_PEC(__HANDLE__)             (((__HANDLE__)->Instance->SR2 & I2C_SR2_PEC) >> 8)
193 
194 /* Private define for @ref PreviousState usage */
195 #define SMBUS_STATE_MSK             ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX | HAL_SMBUS_STATE_BUSY_RX) & (~(uint32_t)HAL_SMBUS_STATE_READY))) /*!< Mask State define, keep only RX and TX bits            */
196 #define SMBUS_STATE_NONE            ((uint32_t)(HAL_SMBUS_MODE_NONE))                                                                      /*!< Default Value                                          */
197 #define SMBUS_STATE_MASTER_BUSY_TX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy TX, combinaison of State LSB and Mode enum */
198 #define SMBUS_STATE_MASTER_BUSY_RX  ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_MASTER))                      /*!< Master Busy RX, combinaison of State LSB and Mode enum */
199 #define SMBUS_STATE_SLAVE_BUSY_TX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_TX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy TX, combinaison of State LSB and Mode enum  */
200 #define SMBUS_STATE_SLAVE_BUSY_RX   ((uint32_t)((HAL_SMBUS_STATE_BUSY_RX & SMBUS_STATE_MSK) | HAL_SMBUS_MODE_SLAVE))                       /*!< Slave Busy RX, combinaison of State LSB and Mode enum  */
201 
202 /**
203   * @}
204   */
205 
206 /* Private macro -------------------------------------------------------------*/
207 /* Private variables ---------------------------------------------------------*/
208 /* Private function prototypes -----------------------------------------------*/
209 
210 /** @addtogroup SMBUS_Private_Functions
211   * @{
212   */
213 
214 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
215 static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus);
216 
217 /* Private functions for SMBUS transfer IRQ handler */
218 static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
219 static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
220 static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
221 static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
222 static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus);
223 static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus);
224 static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus);
225 
226 static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus);
227 static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus);
228 static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus);
229 static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus);
230 static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus);
231 static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus);
232 static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus);
233 /**
234   * @}
235   */
236 
237 /* Exported functions --------------------------------------------------------*/
238 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
239   * @{
240   */
241 
242 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
243  *  @brief    Initialization and Configuration functions
244  *
245 @verbatim
246  ===============================================================================
247               ##### Initialization and de-initialization functions #####
248  ===============================================================================
249     [..]  This subsection provides a set of functions allowing to initialize and
250           deinitialize the SMBUSx peripheral:
251 
252       (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
253           all related peripherals resources (CLOCK, GPIO, IT and NVIC).
254 
255       (+) Call the function HAL_SMBUS_Init() to configure the selected device with
256           the selected configuration:
257         (++) Communication Speed
258         (++) Addressing mode
259         (++) Own Address 1
260         (++) Dual Addressing mode
261         (++) Own Address 2
262         (++) General call mode
263         (++) Nostretch mode
264         (++) Packet Error Check mode
265         (++) Peripheral mode
266 
267       (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
268           of the selected SMBUSx peripheral.
269 
270 @endverbatim
271   * @{
272   */
273 
274 /**
275   * @brief  Initializes the SMBUS according to the specified parameters
276   *         in the SMBUS_InitTypeDef and initialize the associated handle.
277   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
278   *         the configuration information for the specified SMBUS
279   * @retval HAL status
280   */
HAL_SMBUS_Init(SMBUS_HandleTypeDef * hsmbus)281 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
282 {
283   uint32_t freqrange = 0U;
284   uint32_t pclk1 = 0U;
285 
286   /* Check the SMBUS handle allocation */
287   if (hsmbus == NULL)
288   {
289     return HAL_ERROR;
290   }
291 
292   /* Check the parameters */
293   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
294 #if  defined(I2C_FLTR_ANOFF)
295   assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
296 #endif
297   assert_param(IS_SMBUS_CLOCK_SPEED(hsmbus->Init.ClockSpeed));
298   assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
299   assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
300   assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
301   assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
302   assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
303   assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
304   assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
305   assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
306 
307   if (hsmbus->State == HAL_SMBUS_STATE_RESET)
308   {
309     /* Allocate lock resource and initialize it */
310     hsmbus->Lock = HAL_UNLOCKED;
311     /* Init the low level hardware : GPIO, CLOCK, NVIC */
312 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
313     /* Init the SMBUS Callback settings */
314     hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
315     hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
316     hsmbus->SlaveTxCpltCallback  = HAL_SMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
317     hsmbus->SlaveRxCpltCallback  = HAL_SMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
318     hsmbus->ListenCpltCallback   = HAL_SMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
319     hsmbus->ErrorCallback        = HAL_SMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
320     hsmbus->AbortCpltCallback    = HAL_SMBUS_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
321     hsmbus->AddrCallback         = HAL_SMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
322 
323     if (hsmbus->MspInitCallback == NULL)
324     {
325       hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit  */
326     }
327 
328     /* Init the low level hardware : GPIO, CLOCK, NVIC */
329     hsmbus->MspInitCallback(hsmbus);
330 #else
331     /* Init the low level hardware : GPIO, CLOCK, NVIC */
332     HAL_SMBUS_MspInit(hsmbus);
333 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
334   }
335 
336   hsmbus->State = HAL_SMBUS_STATE_BUSY;
337 
338   /* Disable the selected SMBUS peripheral */
339   __HAL_SMBUS_DISABLE(hsmbus);
340 
341   /* Get PCLK1 frequency */
342   pclk1 = HAL_RCC_GetPCLK1Freq();
343 
344   /* Calculate frequency range */
345   freqrange = SMBUS_FREQRANGE(pclk1);
346 
347   /*---------------------------- SMBUSx CR2 Configuration ----------------------*/
348   /* Configure SMBUSx: Frequency range */
349   MODIFY_REG(hsmbus->Instance->CR2, I2C_CR2_FREQ, freqrange);
350 
351   /*---------------------------- SMBUSx TRISE Configuration --------------------*/
352   /* Configure SMBUSx: Rise Time */
353   MODIFY_REG(hsmbus->Instance->TRISE, I2C_TRISE_TRISE, SMBUS_RISE_TIME(freqrange));
354 
355   /*---------------------------- SMBUSx CCR Configuration ----------------------*/
356   /* Configure SMBUSx: Speed */
357   MODIFY_REG(hsmbus->Instance->CCR, (I2C_CCR_FS | I2C_CCR_DUTY | I2C_CCR_CCR), SMBUS_SPEED_STANDARD(pclk1, hsmbus->Init.ClockSpeed));
358 
359   /*---------------------------- SMBUSx CR1 Configuration ----------------------*/
360   /* Configure SMBUSx: Generalcall , PEC , Peripheral mode and  NoStretch mode */
361   MODIFY_REG(hsmbus->Instance->CR1, (I2C_CR1_NOSTRETCH | I2C_CR1_ENGC | I2C_CR1_ENPEC | I2C_CR1_ENARP | I2C_CR1_SMBTYPE | I2C_CR1_SMBUS), (hsmbus->Init.NoStretchMode | hsmbus->Init.GeneralCallMode |  hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode));
362 
363   /*---------------------------- SMBUSx OAR1 Configuration ---------------------*/
364   /* Configure SMBUSx: Own Address1 and addressing mode */
365   MODIFY_REG(hsmbus->Instance->OAR1, (I2C_OAR1_ADDMODE | I2C_OAR1_ADD8_9 | I2C_OAR1_ADD1_7 | I2C_OAR1_ADD0), (hsmbus->Init.AddressingMode | hsmbus->Init.OwnAddress1));
366 
367   /*---------------------------- SMBUSx OAR2 Configuration ---------------------*/
368   /* Configure SMBUSx: Dual mode and Own Address2 */
369   MODIFY_REG(hsmbus->Instance->OAR2, (I2C_OAR2_ENDUAL | I2C_OAR2_ADD2), (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2));
370 #if  defined(I2C_FLTR_ANOFF)
371   /*---------------------------- SMBUSx FLTR Configuration ------------------------*/
372   /* Configure SMBUSx: Analog noise filter */
373   SET_BIT(hsmbus->Instance->FLTR, hsmbus->Init.AnalogFilter);
374 #endif
375 
376   /* Enable the selected SMBUS peripheral */
377   __HAL_SMBUS_ENABLE(hsmbus);
378 
379   hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
380   hsmbus->State = HAL_SMBUS_STATE_READY;
381   hsmbus->PreviousState = SMBUS_STATE_NONE;
382   hsmbus->Mode = HAL_SMBUS_MODE_NONE;
383   hsmbus->XferPEC = 0x00;
384 
385   return HAL_OK;
386 }
387 
388 /**
389   * @brief  DeInitializes the SMBUS peripheral.
390   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
391   *         the configuration information for the specified SMBUS.
392   * @retval HAL status
393   */
HAL_SMBUS_DeInit(SMBUS_HandleTypeDef * hsmbus)394 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
395 {
396   /* Check the SMBUS handle allocation */
397   if (hsmbus == NULL)
398   {
399     return HAL_ERROR;
400   }
401 
402   /* Check the parameters */
403   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
404 
405   hsmbus->State = HAL_SMBUS_STATE_BUSY;
406 
407   /* Disable the SMBUS Peripheral Clock */
408   __HAL_SMBUS_DISABLE(hsmbus);
409 
410 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
411   if (hsmbus->MspDeInitCallback == NULL)
412   {
413     hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit  */
414   }
415 
416   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
417   hsmbus->MspDeInitCallback(hsmbus);
418 #else
419   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
420   HAL_SMBUS_MspDeInit(hsmbus);
421 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
422 
423   hsmbus->ErrorCode     = HAL_SMBUS_ERROR_NONE;
424   hsmbus->State         = HAL_SMBUS_STATE_RESET;
425   hsmbus->PreviousState = SMBUS_STATE_NONE;
426   hsmbus->Mode          = HAL_SMBUS_MODE_NONE;
427 
428   /* Release Lock */
429   __HAL_UNLOCK(hsmbus);
430 
431   return HAL_OK;
432 }
433 
434 /**
435   * @brief  Initialize the SMBUS MSP.
436   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
437   *         the configuration information for the specified SMBUS
438   * @retval None
439   */
HAL_SMBUS_MspInit(SMBUS_HandleTypeDef * hsmbus)440 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
441 {
442   /* Prevent unused argument(s) compilation warning */
443   UNUSED(hsmbus);
444   /* NOTE : This function Should not be modified, when the callback is needed,
445             the HAL_SMBUS_MspInit could be implemented in the user file
446    */
447 }
448 
449 /**
450   * @brief  DeInitialize the SMBUS MSP.
451   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
452   *         the configuration information for the specified SMBUS
453   * @retval None
454   */
HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef * hsmbus)455 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
456 {
457   /* Prevent unused argument(s) compilation warning */
458   UNUSED(hsmbus);
459   /* NOTE : This function Should not be modified, when the callback is needed,
460             the HAL_SMBUS_MspDeInit could be implemented in the user file
461    */
462 }
463 
464 #if  defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
465 /**
466   * @brief  Configures SMBUS Analog noise filter.
467   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
468   *                the configuration information for the specified SMBUSx peripheral.
469   * @param  AnalogFilter new state of the Analog filter.
470   * @retval HAL status
471   */
HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef * hsmbus,uint32_t AnalogFilter)472 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
473 {
474   /* Check the parameters */
475   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
476   assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
477 
478   if (hsmbus->State == HAL_SMBUS_STATE_READY)
479   {
480     hsmbus->State = HAL_SMBUS_STATE_BUSY;
481 
482     /* Disable the selected SMBUS peripheral */
483     __HAL_SMBUS_DISABLE(hsmbus);
484 
485     /* Reset SMBUSx ANOFF bit */
486     hsmbus->Instance->FLTR &= ~(I2C_FLTR_ANOFF);
487 
488     /* Disable the analog filter */
489     hsmbus->Instance->FLTR |= AnalogFilter;
490 
491     __HAL_SMBUS_ENABLE(hsmbus);
492 
493     hsmbus->State = HAL_SMBUS_STATE_READY;
494 
495     return HAL_OK;
496   }
497   else
498   {
499     return HAL_BUSY;
500   }
501 }
502 
503 /**
504   * @brief  Configures SMBUS Digital noise filter.
505   * @param  hsmbus pointer to a SMBUS_HandleTypeDef structure that contains
506   *                the configuration information for the specified SMBUSx peripheral.
507   * @param  DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F.
508   * @retval HAL status
509   */
HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef * hsmbus,uint32_t DigitalFilter)510 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
511 {
512   uint16_t tmpreg = 0;
513 
514   /* Check the parameters */
515   assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
516   assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
517 
518   if (hsmbus->State == HAL_SMBUS_STATE_READY)
519   {
520     hsmbus->State = HAL_SMBUS_STATE_BUSY;
521 
522     /* Disable the selected SMBUS peripheral */
523     __HAL_SMBUS_DISABLE(hsmbus);
524 
525     /* Get the old register value */
526     tmpreg = hsmbus->Instance->FLTR;
527 
528     /* Reset SMBUSx DNF bit [3:0] */
529     tmpreg &= ~(I2C_FLTR_DNF);
530 
531     /* Set SMBUSx DNF coefficient */
532     tmpreg |= DigitalFilter;
533 
534     /* Store the new register value */
535     hsmbus->Instance->FLTR = tmpreg;
536 
537     __HAL_SMBUS_ENABLE(hsmbus);
538 
539     hsmbus->State = HAL_SMBUS_STATE_READY;
540 
541     return HAL_OK;
542   }
543   else
544   {
545     return HAL_BUSY;
546   }
547 }
548 #endif
549 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
550 /**
551   * @brief  Register a User SMBUS Callback
552   *         To be used instead of the weak predefined callback
553   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
554   *                the configuration information for the specified SMBUS.
555   * @param  CallbackID ID of the callback to be registered
556   *         This parameter can be one of the following values:
557   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
558   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
559   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
560   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
561   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
562   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
563   *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
564   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
565   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
566   * @param  pCallback pointer to the Callback function
567   * @retval HAL status
568   */
HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef * hsmbus,HAL_SMBUS_CallbackIDTypeDef CallbackID,pSMBUS_CallbackTypeDef pCallback)569 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback)
570 {
571   HAL_StatusTypeDef status = HAL_OK;
572 
573   if (pCallback == NULL)
574   {
575     /* Update the error code */
576     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
577 
578     return HAL_ERROR;
579   }
580   /* Process locked */
581   __HAL_LOCK(hsmbus);
582 
583   if (HAL_SMBUS_STATE_READY == hsmbus->State)
584   {
585     switch (CallbackID)
586     {
587       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
588         hsmbus->MasterTxCpltCallback = pCallback;
589         break;
590 
591       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
592         hsmbus->MasterRxCpltCallback = pCallback;
593         break;
594 
595       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
596         hsmbus->SlaveTxCpltCallback = pCallback;
597         break;
598 
599       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
600         hsmbus->SlaveRxCpltCallback = pCallback;
601         break;
602 
603       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
604         hsmbus->ListenCpltCallback = pCallback;
605         break;
606 
607       case HAL_SMBUS_ERROR_CB_ID :
608         hsmbus->ErrorCallback = pCallback;
609         break;
610 
611       case HAL_SMBUS_ABORT_CB_ID :
612         hsmbus->AbortCpltCallback = pCallback;
613         break;
614 
615       case HAL_SMBUS_MSPINIT_CB_ID :
616         hsmbus->MspInitCallback = pCallback;
617         break;
618 
619       case HAL_SMBUS_MSPDEINIT_CB_ID :
620         hsmbus->MspDeInitCallback = pCallback;
621         break;
622 
623       default :
624         /* Update the error code */
625         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
626 
627         /* Return error status */
628         status =  HAL_ERROR;
629         break;
630     }
631   }
632   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
633   {
634     switch (CallbackID)
635     {
636       case HAL_SMBUS_MSPINIT_CB_ID :
637         hsmbus->MspInitCallback = pCallback;
638         break;
639 
640       case HAL_SMBUS_MSPDEINIT_CB_ID :
641         hsmbus->MspDeInitCallback = pCallback;
642         break;
643 
644       default :
645         /* Update the error code */
646         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
647 
648         /* Return error status */
649         status =  HAL_ERROR;
650         break;
651     }
652   }
653   else
654   {
655     /* Update the error code */
656     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
657 
658     /* Return error status */
659     status =  HAL_ERROR;
660   }
661 
662   /* Release Lock */
663   __HAL_UNLOCK(hsmbus);
664   return status;
665 }
666 
667 /**
668   * @brief  Unregister an SMBUS Callback
669   *         SMBUS callback is redirected to the weak predefined callback
670   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
671   *                the configuration information for the specified SMBUS.
672   * @param  CallbackID ID of the callback to be unregistered
673   *         This parameter can be one of the following values:
674   *         This parameter can be one of the following values:
675   *          @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
676   *          @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
677   *          @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
678   *          @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
679   *          @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
680   *          @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
681   *          @arg @ref HAL_SMBUS_ABORT_CB_ID Abort callback ID
682   *          @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
683   *          @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
684   * @retval HAL status
685   */
HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef * hsmbus,HAL_SMBUS_CallbackIDTypeDef CallbackID)686 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID)
687 {
688   HAL_StatusTypeDef status = HAL_OK;
689 
690   /* Process locked */
691   __HAL_LOCK(hsmbus);
692 
693   if (HAL_SMBUS_STATE_READY == hsmbus->State)
694   {
695     switch (CallbackID)
696     {
697       case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
698         hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
699         break;
700 
701       case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
702         hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
703         break;
704 
705       case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
706         hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
707         break;
708 
709       case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
710         hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
711         break;
712 
713       case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
714         hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
715         break;
716 
717       case HAL_SMBUS_ERROR_CB_ID :
718         hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
719         break;
720 
721       case HAL_SMBUS_ABORT_CB_ID :
722         hsmbus->AbortCpltCallback = HAL_SMBUS_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
723         break;
724 
725       case HAL_SMBUS_MSPINIT_CB_ID :
726         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
727         break;
728 
729       case HAL_SMBUS_MSPDEINIT_CB_ID :
730         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
731         break;
732 
733       default :
734         /* Update the error code */
735         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
736 
737         /* Return error status */
738         status =  HAL_ERROR;
739         break;
740     }
741   }
742   else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
743   {
744     switch (CallbackID)
745     {
746       case HAL_SMBUS_MSPINIT_CB_ID :
747         hsmbus->MspInitCallback = HAL_SMBUS_MspInit;                   /* Legacy weak MspInit              */
748         break;
749 
750       case HAL_SMBUS_MSPDEINIT_CB_ID :
751         hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
752         break;
753 
754       default :
755         /* Update the error code */
756         hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
757 
758         /* Return error status */
759         status =  HAL_ERROR;
760         break;
761     }
762   }
763   else
764   {
765     /* Update the error code */
766     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
767 
768     /* Return error status */
769     status =  HAL_ERROR;
770   }
771 
772   /* Release Lock */
773   __HAL_UNLOCK(hsmbus);
774   return status;
775 }
776 
777 /**
778   * @brief  Register the Slave Address Match SMBUS Callback
779   *         To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
780   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
781   *                the configuration information for the specified SMBUS.
782   * @param  pCallback pointer to the Address Match Callback function
783   * @retval HAL status
784   */
HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef * hsmbus,pSMBUS_AddrCallbackTypeDef pCallback)785 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback)
786 {
787   HAL_StatusTypeDef status = HAL_OK;
788 
789   if (pCallback == NULL)
790   {
791     return HAL_ERROR;
792   }
793   /* Process locked */
794   __HAL_LOCK(hsmbus);
795 
796   if (HAL_SMBUS_STATE_READY == hsmbus->State)
797   {
798     hsmbus->AddrCallback = pCallback;
799   }
800   else
801   {
802     /* Update the error code */
803     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
804 
805     /* Return error status */
806     status =  HAL_ERROR;
807   }
808 
809   /* Release Lock */
810   __HAL_UNLOCK(hsmbus);
811   return status;
812 }
813 
814 /**
815   * @brief  UnRegister the Slave Address Match SMBUS Callback
816   *         Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
817   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
818   *                the configuration information for the specified SMBUS.
819   * @retval HAL status
820   */
HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef * hsmbus)821 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
822 {
823   HAL_StatusTypeDef status = HAL_OK;
824 
825   /* Process locked */
826   __HAL_LOCK(hsmbus);
827 
828   if (HAL_SMBUS_STATE_READY == hsmbus->State)
829   {
830     hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback  */
831   }
832   else
833   {
834     /* Update the error code */
835     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
836 
837     /* Return error status */
838     status =  HAL_ERROR;
839   }
840 
841   /* Release Lock */
842   __HAL_UNLOCK(hsmbus);
843   return status;
844 }
845 
846 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
847 
848 /**
849   * @}
850   */
851 
852 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
853  *  @brief    Data transfers functions
854  *
855 @verbatim
856  ===============================================================================
857                       ##### IO operation functions #####
858  ===============================================================================
859     [..]
860     This subsection provides a set of functions allowing to manage the SMBUS data
861     transfers.
862 
863     (#) Blocking mode function to check if device is ready for usage is :
864         (++) HAL_SMBUS_IsDeviceReady()
865 
866     (#) There is only one mode of transfer:
867        (++) Non Blocking mode : The communication is performed using Interrupts.
868             These functions return the status of the transfer startup.
869             The end of the data processing will be indicated through the
870             dedicated SMBUS IRQ when using Interrupt mode.
871 
872     (#) Non Blocking mode functions with Interrupt are :
873         (++) HAL_SMBUS_Master_Transmit_IT()
874         (++) HAL_SMBUS_Master_Receive_IT()
875         (++) HAL_SMBUS_Master_Abort_IT()
876         (++) HAL_SMBUS_Slave_Transmit_IT()
877         (++) HAL_SMBUS_Slave_Receive_IT()
878         (++) HAL_SMBUS_EnableAlert_IT()
879         (++) HAL_SMBUS_DisableAlert_IT()
880 
881     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
882         (++) HAL_SMBUS_MasterTxCpltCallback()
883         (++) HAL_SMBUS_MasterRxCpltCallback()
884         (++) HAL_SMBUS_SlaveTxCpltCallback()
885         (++) HAL_SMBUS_SlaveRxCpltCallback()
886         (++) HAL_SMBUS_AddrCallback()
887         (++) HAL_SMBUS_ListenCpltCallback()
888         (++) HAL_SMBUS_ErrorCallback()
889         (++) HAL_SMBUS_AbortCpltCallback()
890 
891 @endverbatim
892   * @{
893   */
894 
895 /**
896   * @brief  Transmits in master mode an amount of data in blocking mode.
897   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
898   *         the configuration information for the specified SMBUS.
899   * @param  DevAddress Target device address The device 7 bits address value
900   *         in datasheet must be shifted to the left before calling the interface
901   * @param  pData Pointer to data buffer
902   * @param  Size Amount of data to be sent
903   * @param  XferOptions Options of Transfer
904   * @retval HAL status
905   */
HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)906 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
907 {
908   uint32_t count      = 0x00U;
909 
910   /* Check the parameters */
911   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
912 
913   if (hsmbus->State == HAL_SMBUS_STATE_READY)
914   {
915     /* Check Busy Flag only if FIRST call of Master interface */
916     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
917     {
918       /* Wait until BUSY flag is reset */
919       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
920       do
921       {
922         if (count-- == 0U)
923         {
924           hsmbus->PreviousState = SMBUS_STATE_NONE;
925           hsmbus->State = HAL_SMBUS_STATE_READY;
926 
927           /* Process Unlocked */
928           __HAL_UNLOCK(hsmbus);
929 
930           return HAL_TIMEOUT;
931         }
932       }
933       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
934     }
935 
936     /* Process Locked */
937     __HAL_LOCK(hsmbus);
938 
939     /* Check if the SMBUS is already enabled */
940     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
941     {
942       /* Enable SMBUS peripheral */
943       __HAL_SMBUS_ENABLE(hsmbus);
944     }
945 
946     /* Disable Pos */
947     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
948 
949     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX;
950     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
951     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
952 
953     /* Prepare transfer parameters */
954     hsmbus->pBuffPtr    = pData;
955     hsmbus->XferCount   = Size;
956     hsmbus->XferOptions = XferOptions;
957     hsmbus->XferSize    = hsmbus->XferCount;
958     hsmbus->Devaddress  = DevAddress;
959 
960     /* Generate Start */
961     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
962 
963     /* Process Unlocked */
964     __HAL_UNLOCK(hsmbus);
965 
966     /* Note : The SMBUS interrupts must be enabled after unlocking current process
967     to avoid the risk of hsmbus interrupt handle execution before current
968     process unlock */
969 
970     /* Enable EVT, BUF and ERR interrupt */
971     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
972 
973     return HAL_OK;
974   }
975   else
976   {
977     return HAL_BUSY;
978   }
979 }
980 /**
981   * @brief  Receive in master/host SMBUS mode an amount of data in non blocking mode with Interrupt.
982   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
983   *         the configuration information for the specified SMBUS.
984   * @param  DevAddress Target device address The device 7 bits address value
985   *         in datasheet must be shifted to the left before calling the interface
986   * @param  pData Pointer to data buffer
987   * @param  Size Amount of data to be sent
988   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
989   * @retval HAL status
990   */
HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)991 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
992 {
993   __IO uint32_t count = 0U;
994 
995   /* Check the parameters */
996   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
997 
998   if (hsmbus->State == HAL_SMBUS_STATE_READY)
999   {
1000     /* Check Busy Flag only if FIRST call of Master interface */
1001     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
1002     {
1003       /* Wait until BUSY flag is reset */
1004       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
1005       do
1006       {
1007         if (count-- == 0U)
1008         {
1009           hsmbus->PreviousState = SMBUS_STATE_NONE;
1010           hsmbus->State = HAL_SMBUS_STATE_READY;
1011 
1012           /* Process Unlocked */
1013           __HAL_UNLOCK(hsmbus);
1014 
1015           return HAL_TIMEOUT;
1016         }
1017       }
1018       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
1019     }
1020 
1021     /* Process Locked */
1022     __HAL_LOCK(hsmbus);
1023 
1024     /* Check if the SMBUS is already enabled */
1025     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1026     {
1027       /* Enable SMBUS peripheral */
1028       __HAL_SMBUS_ENABLE(hsmbus);
1029     }
1030 
1031     /* Disable Pos */
1032     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1033 
1034     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX;
1035     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1036     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
1037 
1038     /* Prepare transfer parameters */
1039     hsmbus->pBuffPtr    = pData;
1040     hsmbus->XferCount   = Size;
1041     hsmbus->XferOptions = XferOptions;
1042     hsmbus->XferSize    = hsmbus->XferCount;
1043     hsmbus->Devaddress  = DevAddress;
1044 
1045     if ((hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX) || (hsmbus->PreviousState == SMBUS_STATE_NONE))
1046     {
1047       /* Generate Start condition if first transfer */
1048       if ((XferOptions == SMBUS_NEXT_FRAME)  || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME)  || (XferOptions == SMBUS_NO_OPTION_FRAME))
1049       {
1050         /* Enable Acknowledge */
1051         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1052 
1053         /* Generate Start */
1054         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1055       }
1056 
1057       if ((XferOptions == SMBUS_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_LAST_FRAME_WITH_PEC))
1058       {
1059         if (hsmbus->PreviousState == SMBUS_STATE_NONE)
1060         {
1061           /* Enable Acknowledge */
1062           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1063         }
1064 
1065         if (hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX)
1066         {
1067           /* Enable Acknowledge */
1068           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1069 
1070           /* Generate Start */
1071           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1072         }
1073       }
1074     }
1075 
1076 
1077 
1078     /* Process Unlocked */
1079     __HAL_UNLOCK(hsmbus);
1080 
1081     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1082     to avoid the risk of SMBUS interrupt handle execution before current
1083     process unlock */
1084 
1085     /* Enable EVT, BUF and ERR interrupt */
1086     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1087 
1088     return HAL_OK;
1089   }
1090   else
1091   {
1092     return HAL_BUSY;
1093   }
1094 }
1095 
1096 /**
1097   * @brief  Abort a master/host SMBUS process communication with Interrupt.
1098   * @note   This abort can be called only if state is ready
1099   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1100   *         the configuration information for the specified SMBUS.
1101   * @param  DevAddress Target device address The device 7 bits address value
1102   *         in datasheet must be shifted to the left before calling the interface
1103   * @retval HAL status
1104   */
HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress)1105 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
1106 {
1107   /* Prevent unused argument(s) compilation warning */
1108   UNUSED(DevAddress);
1109   if (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_HOST)
1110   {
1111     /* Process Locked */
1112     __HAL_LOCK(hsmbus);
1113 
1114     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1115 
1116     hsmbus->PreviousState = SMBUS_STATE_NONE;
1117     hsmbus->State = HAL_SMBUS_STATE_ABORT;
1118 
1119 
1120     /* Disable Acknowledge */
1121     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1122 
1123     /* Generate Stop */
1124     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1125 
1126     hsmbus->XferCount = 0U;
1127 
1128     /* Disable EVT, BUF and ERR interrupt */
1129     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1130 
1131     /* Process Unlocked */
1132     __HAL_UNLOCK(hsmbus);
1133 
1134     /* Call the corresponding callback to inform upper layer of End of Transfer */
1135     SMBUS_ITError(hsmbus);
1136 
1137     return HAL_OK;
1138   }
1139   else
1140   {
1141     return HAL_BUSY;
1142   }
1143 }
1144 
1145 
1146 /**
1147   * @brief  Transmit in slave/device SMBUS mode an amount of data in non blocking mode with Interrupt.
1148   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1149   *         the configuration information for the specified SMBUS.
1150   * @param  pData Pointer to data buffer
1151   * @param  Size Amount of data to be sent
1152   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1153   * @retval HAL status
1154   */
HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1155 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1156 {
1157   /* Check the parameters */
1158   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1159 
1160   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1161   {
1162     if ((pData == NULL) || (Size == 0U))
1163     {
1164       return  HAL_ERROR;
1165     }
1166 
1167     /* Process Locked */
1168     __HAL_LOCK(hsmbus);
1169 
1170     /* Check if the SMBUS is already enabled */
1171     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1172     {
1173       /* Enable SMBUS peripheral */
1174       __HAL_SMBUS_ENABLE(hsmbus);
1175     }
1176 
1177     /* Disable Pos */
1178     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1179 
1180     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX_LISTEN;
1181     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1182     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
1183 
1184     /* Prepare transfer parameters */
1185     hsmbus->pBuffPtr    = pData;
1186     hsmbus->XferCount   = Size;
1187     hsmbus->XferOptions = XferOptions;
1188     hsmbus->XferSize    = hsmbus->XferCount;
1189 
1190     /* Clear ADDR flag after prepare the transfer parameters */
1191     /* This action will generate an acknowledge to the HOST */
1192     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
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 
1201     /* Enable EVT, BUF and ERR interrupt */
1202     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1203 
1204     return HAL_OK;
1205   }
1206   else
1207   {
1208     return HAL_BUSY;
1209   }
1210 }
1211 
1212 /**
1213   * @brief  Enable the Address listen mode with Interrupt.
1214   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1215   *         the configuration information for the specified SMBUS.
1216   * @param  pData Pointer to data buffer
1217   * @param  Size Amount of data to be sent
1218   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1219   * @retval HAL status
1220   */
HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1221 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1222 {
1223   /* Check the parameters */
1224   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1225 
1226   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1227   {
1228     if ((pData == NULL) || (Size == 0U))
1229     {
1230       return  HAL_ERROR;
1231     }
1232 
1233     /* Process Locked */
1234     __HAL_LOCK(hsmbus);
1235 
1236     /* Check if the SMBUS is already enabled */
1237     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1238     {
1239       /* Enable SMBUS peripheral */
1240       __HAL_SMBUS_ENABLE(hsmbus);
1241     }
1242 
1243     /* Disable Pos */
1244     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1245 
1246     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX_LISTEN;
1247     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1248     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
1249 
1250 
1251 
1252     /* Prepare transfer parameters */
1253     hsmbus->pBuffPtr = pData;
1254     hsmbus->XferCount = Size;
1255     hsmbus->XferOptions = XferOptions;
1256     hsmbus->XferSize    = hsmbus->XferCount;
1257 
1258     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
1259 
1260     /* Process Unlocked */
1261     __HAL_UNLOCK(hsmbus);
1262 
1263     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1264               to avoid the risk of SMBUS interrupt handle execution before current
1265               process unlock */
1266 
1267     /* Enable EVT, BUF and ERR interrupt */
1268     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1269 
1270     return HAL_OK;
1271   }
1272   else
1273   {
1274     return HAL_BUSY;
1275   }
1276 }
1277 
1278 
1279 /**
1280   * @brief  Enable the Address listen mode with Interrupt.
1281   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1282   *                the configuration information for the specified SMBUS.
1283   * @retval HAL status
1284   */
HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef * hsmbus)1285 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1286 {
1287   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1288   {
1289     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1290 
1291     /* Check if the SMBUS is already enabled */
1292     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1293     {
1294       /* Enable SMBUS peripheral */
1295       __HAL_SMBUS_ENABLE(hsmbus);
1296     }
1297 
1298     /* Enable Address Acknowledge */
1299     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1300 
1301     /* Enable EVT and ERR interrupt */
1302     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
1303 
1304     return HAL_OK;
1305   }
1306   else
1307   {
1308     return HAL_BUSY;
1309   }
1310 }
1311 
1312 /**
1313   * @brief  Disable the Address listen mode with Interrupt.
1314   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1315   *         the configuration information for the specified SMBUS.
1316   * @retval HAL status
1317   */
HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef * hsmbus)1318 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1319 {
1320   /* Declaration of tmp to prevent undefined behavior of volatile usage */
1321   uint32_t tmp;
1322 
1323   /* Disable Address listen mode only if a transfer is not ongoing */
1324   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1325   {
1326     tmp = (uint32_t)(hsmbus->State) & SMBUS_STATE_MSK;
1327     hsmbus->PreviousState = tmp | (uint32_t)(hsmbus->Mode);
1328     hsmbus->State = HAL_SMBUS_STATE_READY;
1329     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1330 
1331     /* Disable Address Acknowledge */
1332     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1333 
1334     /* Disable EVT and ERR interrupt */
1335     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
1336 
1337     return HAL_OK;
1338   }
1339   else
1340   {
1341     return HAL_BUSY;
1342   }
1343 }
1344 
1345 /**
1346   * @brief  Enable the SMBUS alert mode with Interrupt.
1347   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1348   *         the configuration information for the specified SMBUSx peripheral.
1349   * @retval HAL status
1350   */
HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1351 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1352 {
1353   /* Enable SMBus alert */
1354   SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
1355 
1356   /* Clear ALERT flag */
1357   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
1358 
1359   /* Enable Alert Interrupt */
1360   __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_ERR);
1361 
1362   return HAL_OK;
1363 }
1364 /**
1365   * @brief  Disable the SMBUS alert mode with Interrupt.
1366   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1367   *                the configuration information for the specified SMBUSx peripheral.
1368   * @retval HAL status
1369   */
HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1370 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1371 {
1372   /* Disable SMBus alert */
1373   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
1374 
1375   /* Disable Alert Interrupt */
1376   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ERR);
1377 
1378   return HAL_OK;
1379 }
1380 
1381 
1382 /**
1383   * @brief  Check if target device is ready for communication.
1384   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1385   *         the configuration information for the specified SMBUS.
1386   * @param  DevAddress Target device address The device 7 bits address value
1387   *         in datasheet must be shifted to the left before calling the interface
1388   * @param  Trials Number of trials
1389   * @param  Timeout Timeout duration
1390   * @retval HAL status
1391   */
HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)1392 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
1393 {
1394   uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, SMBUS_Trials = 1U;
1395 
1396   /* Get tick */
1397   tickstart = HAL_GetTick();
1398 
1399   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1400   {
1401     /* Wait until BUSY flag is reset */
1402     if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1403     {
1404       return HAL_BUSY;
1405     }
1406 
1407     /* Process Locked */
1408     __HAL_LOCK(hsmbus);
1409 
1410     /* Check if the SMBUS is already enabled */
1411     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1412     {
1413       /* Enable SMBUS peripheral */
1414       __HAL_SMBUS_ENABLE(hsmbus);
1415     }
1416 
1417     /* Disable Pos */
1418     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1419 
1420     hsmbus->State = HAL_SMBUS_STATE_BUSY;
1421     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1422     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
1423 
1424     do
1425     {
1426       /* Generate Start */
1427       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1428 
1429       /* Wait until SB flag is set */
1430       if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
1431       {
1432         return HAL_TIMEOUT;
1433       }
1434 
1435       /* Send slave address */
1436       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(DevAddress);
1437 
1438       /* Wait until ADDR or AF flag are set */
1439       /* Get tick */
1440       tickstart = HAL_GetTick();
1441 
1442       tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1443       tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1444       tmp3 = hsmbus->State;
1445       while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_SMBUS_STATE_TIMEOUT))
1446       {
1447         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1448         {
1449           hsmbus->State = HAL_SMBUS_STATE_TIMEOUT;
1450         }
1451         tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1452         tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1453         tmp3 = hsmbus->State;
1454       }
1455 
1456       hsmbus->State = HAL_SMBUS_STATE_READY;
1457 
1458       /* Check if the ADDR flag has been set */
1459       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) == SET)
1460       {
1461         /* Generate Stop */
1462         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1463 
1464         /* Clear ADDR Flag */
1465         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
1466 
1467         /* Wait until BUSY flag is reset */
1468         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1469         {
1470           return HAL_TIMEOUT;
1471         }
1472 
1473         hsmbus->State = HAL_SMBUS_STATE_READY;
1474 
1475         /* Process Unlocked */
1476         __HAL_UNLOCK(hsmbus);
1477 
1478         return HAL_OK;
1479       }
1480       else
1481       {
1482         /* Generate Stop */
1483         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1484 
1485         /* Clear AF Flag */
1486         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1487 
1488         /* Wait until BUSY flag is reset */
1489         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1490         {
1491           return HAL_TIMEOUT;
1492         }
1493       }
1494     }
1495     while (SMBUS_Trials++ < Trials);
1496 
1497     hsmbus->State = HAL_SMBUS_STATE_READY;
1498 
1499     /* Process Unlocked */
1500     __HAL_UNLOCK(hsmbus);
1501 
1502     return HAL_ERROR;
1503   }
1504   else
1505   {
1506     return HAL_BUSY;
1507   }
1508 }
1509 
1510 /**
1511   * @brief  This function handles SMBUS event interrupt request.
1512   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1513   *                the configuration information for the specified SMBUS.
1514   * @retval None
1515   */
HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1516 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1517 {
1518   uint32_t sr2itflags   = READ_REG(hsmbus->Instance->SR2);
1519   uint32_t sr1itflags   = READ_REG(hsmbus->Instance->SR1);
1520   uint32_t itsources    = READ_REG(hsmbus->Instance->CR2);
1521 
1522   uint32_t CurrentMode  = hsmbus->Mode;
1523 
1524   /* Master mode selected */
1525   if (CurrentMode == HAL_SMBUS_MODE_MASTER)
1526   {
1527     /* SB Set ----------------------------------------------------------------*/
1528     if (((sr1itflags & SMBUS_FLAG_SB) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1529     {
1530       SMBUS_Master_SB(hsmbus);
1531     }
1532     /* ADD10 Set -------------------------------------------------------------*/
1533     else if (((sr1itflags & SMBUS_FLAG_ADD10) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1534     {
1535       SMBUS_Master_ADD10(hsmbus);
1536     }
1537     /* ADDR Set --------------------------------------------------------------*/
1538     else if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1539     {
1540       SMBUS_Master_ADDR(hsmbus);
1541     }
1542     /* SMBUS in mode Transmitter -----------------------------------------------*/
1543     if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
1544     {
1545       /* TXE set and BTF reset -----------------------------------------------*/
1546       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1547       {
1548         SMBUS_MasterTransmit_TXE(hsmbus);
1549       }
1550       /* BTF set -------------------------------------------------------------*/
1551       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1552       {
1553         SMBUS_MasterTransmit_BTF(hsmbus);
1554       }
1555     }
1556     /* SMBUS in mode Receiver --------------------------------------------------*/
1557     else
1558     {
1559       /* RXNE set and BTF reset -----------------------------------------------*/
1560       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1561       {
1562         SMBUS_MasterReceive_RXNE(hsmbus);
1563       }
1564       /* BTF set -------------------------------------------------------------*/
1565       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1566       {
1567         SMBUS_MasterReceive_BTF(hsmbus);
1568       }
1569     }
1570   }
1571   /* Slave mode selected */
1572   else
1573   {
1574     /* ADDR set --------------------------------------------------------------*/
1575     if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1576     {
1577       SMBUS_Slave_ADDR(hsmbus);
1578     }
1579     /* STOPF set --------------------------------------------------------------*/
1580     else if (((sr1itflags & SMBUS_FLAG_STOPF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1581     {
1582       SMBUS_Slave_STOPF(hsmbus);
1583     }
1584     /* SMBUS in mode Transmitter -----------------------------------------------*/
1585     else if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
1586     {
1587       /* TXE set and BTF reset -----------------------------------------------*/
1588       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1589       {
1590         SMBUS_SlaveTransmit_TXE(hsmbus);
1591       }
1592       /* BTF set -------------------------------------------------------------*/
1593       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1594       {
1595         SMBUS_SlaveTransmit_BTF(hsmbus);
1596       }
1597     }
1598     /* SMBUS in mode Receiver --------------------------------------------------*/
1599     else
1600     {
1601       /* RXNE set and BTF reset ----------------------------------------------*/
1602       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1603       {
1604         SMBUS_SlaveReceive_RXNE(hsmbus);
1605       }
1606       /* BTF set -------------------------------------------------------------*/
1607       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1608       {
1609         SMBUS_SlaveReceive_BTF(hsmbus);
1610       }
1611     }
1612   }
1613 }
1614 
1615 /**
1616   * @brief  This function handles SMBUS error interrupt request.
1617   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1618   *                the configuration information for the specified SMBUS.
1619   * @retval None
1620   */
HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1621 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1622 {
1623   uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U;
1624   uint32_t sr1itflags = READ_REG(hsmbus->Instance->SR1);
1625   uint32_t itsources  = READ_REG(hsmbus->Instance->CR2);
1626 
1627   /* SMBUS Bus error interrupt occurred ------------------------------------*/
1628   if (((sr1itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1629   {
1630     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
1631 
1632     /* Clear BERR flag */
1633     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
1634 
1635   }
1636 
1637   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
1638   if (((sr1itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1639   {
1640     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
1641 
1642     /* Clear OVR flag */
1643     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
1644   }
1645 
1646   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
1647   if (((sr1itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1648   {
1649     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
1650 
1651     /* Clear ARLO flag */
1652     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
1653   }
1654 
1655   /* SMBUS Acknowledge failure error interrupt occurred ------------------------------------*/
1656   if (((sr1itflags & SMBUS_FLAG_AF) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1657   {
1658     tmp1 = hsmbus->Mode;
1659     tmp2 = hsmbus->XferCount;
1660     tmp3 = hsmbus->State;
1661     tmp4 = hsmbus->PreviousState;
1662 
1663     if ((tmp1 == HAL_SMBUS_MODE_SLAVE) && (tmp2 == 0U) && \
1664         ((tmp3 == HAL_SMBUS_STATE_BUSY_TX) || (tmp3 == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || \
1665          ((tmp3 == HAL_SMBUS_STATE_LISTEN) && (tmp4 == SMBUS_STATE_SLAVE_BUSY_TX))))
1666     {
1667       SMBUS_Slave_AF(hsmbus);
1668     }
1669     else
1670     {
1671       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_AF;
1672 
1673       /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
1674       if (hsmbus->Mode == HAL_SMBUS_MODE_MASTER)
1675       {
1676         /* Generate Stop */
1677         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1678 
1679       }
1680 
1681       /* Clear AF flag */
1682       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1683     }
1684   }
1685 
1686   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
1687   if (((sr1itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1688   {
1689     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_TIMEOUT;
1690 
1691     /* Clear TIMEOUT flag */
1692     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
1693 
1694   }
1695 
1696   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
1697   if (((sr1itflags & SMBUS_FLAG_SMBALERT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1698   {
1699     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
1700 
1701     /* Clear ALERT flag */
1702     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
1703   }
1704 
1705   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
1706   if (((sr1itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1707   {
1708     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
1709 
1710     /* Clear PEC error flag */
1711     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
1712   }
1713 
1714   /* Call the Error Callback in case of Error detected -----------------------*/
1715   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
1716   {
1717     SMBUS_ITError(hsmbus);
1718   }
1719 }
1720 
1721 /**
1722   * @brief  Master Tx Transfer completed callback.
1723   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1724   *                the configuration information for the specified SMBUS.
1725   * @retval None
1726   */
HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1727 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1728 {
1729   /* Prevent unused argument(s) compilation warning */
1730   UNUSED(hsmbus);
1731 
1732   /* NOTE : This function should not be modified, when the callback is needed,
1733             the HAL_SMBUS_MasterTxCpltCallback can be implemented in the user file
1734    */
1735 }
1736 
1737 /**
1738   * @brief  Master Rx Transfer completed callback.
1739   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1740   *                the configuration information for the specified SMBUS.
1741   * @retval None
1742   */
HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1743 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1744 {
1745   /* Prevent unused argument(s) compilation warning */
1746   UNUSED(hsmbus);
1747 
1748   /* NOTE : This function should not be modified, when the callback is needed,
1749             the HAL_SMBUS_MasterRxCpltCallback can be implemented in the user file
1750    */
1751 }
1752 
1753 /** @brief  Slave Tx Transfer completed callback.
1754   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1755   *                the configuration information for the specified SMBUS.
1756   * @retval None
1757   */
HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1758 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1759 {
1760   /* Prevent unused argument(s) compilation warning */
1761   UNUSED(hsmbus);
1762 
1763   /* NOTE : This function should not be modified, when the callback is needed,
1764             the HAL_SMBUS_SlaveTxCpltCallback can be implemented in the user file
1765    */
1766 }
1767 
1768 /**
1769   * @brief  Slave Rx Transfer completed callback.
1770   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1771   *                the configuration information for the specified SMBUS.
1772   * @retval None
1773   */
HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1774 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1775 {
1776   /* Prevent unused argument(s) compilation warning */
1777   UNUSED(hsmbus);
1778 
1779   /* NOTE : This function should not be modified, when the callback is needed,
1780             the HAL_SMBUS_SlaveRxCpltCallback can be implemented in the user file
1781    */
1782 }
1783 
1784 /**
1785   * @brief  Slave Address Match callback.
1786   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1787   *                the configuration information for the specified SMBUS.
1788   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref SMBUS_XferOptions_definition
1789   * @param  AddrMatchCode Address Match Code
1790   * @retval None
1791   */
HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef * hsmbus,uint8_t TransferDirection,uint16_t AddrMatchCode)1792 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1793 {
1794   /* Prevent unused argument(s) compilation warning */
1795   UNUSED(hsmbus);
1796   UNUSED(TransferDirection);
1797   UNUSED(AddrMatchCode);
1798 
1799   /* NOTE : This function should not be modified, when the callback is needed,
1800             the HAL_SMBUS_AddrCallback can be implemented in the user file
1801    */
1802 }
1803 
1804 /**
1805   * @brief  Listen Complete callback.
1806   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1807   *                the configuration information for the specified SMBUS.
1808   * @retval None
1809   */
HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef * hsmbus)1810 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1811 {
1812   /* Prevent unused argument(s) compilation warning */
1813   UNUSED(hsmbus);
1814 
1815   /* NOTE : This function should not be modified, when the callback is needed,
1816           the HAL_SMBUS_ListenCpltCallback can be implemented in the user file
1817   */
1818 }
1819 
1820 /**
1821   * @brief  SMBUS error callback.
1822   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1823   *                the configuration information for the specified SMBUS.
1824   * @retval None
1825   */
HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef * hsmbus)1826 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1827 {
1828   /* Prevent unused argument(s) compilation warning */
1829   UNUSED(hsmbus);
1830 
1831   /* NOTE : This function should not be modified, when the callback is needed,
1832             the HAL_SMBUS_ErrorCallback can be implemented in the user file
1833    */
1834 }
1835 
1836 /**
1837   * @brief  SMBUS abort callback.
1838   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1839   *                the configuration information for the specified SMBUS.
1840   * @retval None
1841   */
HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef * hsmbus)1842 __weak void HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1843 {
1844   /* Prevent unused argument(s) compilation warning */
1845   UNUSED(hsmbus);
1846 
1847   /* NOTE : This function should not be modified, when the callback is needed,
1848             the HAL_SMBUS_AbortCpltCallback could be implemented in the user file
1849    */
1850 }
1851 
1852 /**
1853   * @}
1854   */
1855 
1856 /** @defgroup   SMBUS_Exported_Functions_Group3 Peripheral State, Mode and Error functions
1857   *  @brief   Peripheral State and Errors functions
1858   *
1859 @verbatim
1860  ===============================================================================
1861             ##### Peripheral State, Mode and Error functions #####
1862  ===============================================================================
1863     [..]
1864     This subsection permits to get in run-time the status of the peripheral
1865     and the data flow.
1866 
1867 @endverbatim
1868   * @{
1869   */
1870 
1871 /**
1872   * @brief  Return the SMBUS handle state.
1873   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1874   *                the configuration information for the specified SMBUS.
1875   * @retval HAL state
1876   */
HAL_SMBUS_GetState(SMBUS_HandleTypeDef * hsmbus)1877 HAL_SMBUS_StateTypeDef HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1878 {
1879   /* Return SMBUS handle state */
1880   return hsmbus->State;
1881 }
1882 
1883 /**
1884   * @brief  Return the SMBUS Master, Slave or no mode.
1885   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1886   *                the configuration information for SMBUS module
1887   * @retval HAL mode
1888   */
HAL_SMBUS_GetMode(SMBUS_HandleTypeDef * hsmbus)1889 HAL_SMBUS_ModeTypeDef HAL_SMBUS_GetMode(SMBUS_HandleTypeDef *hsmbus)
1890 {
1891   return hsmbus->Mode;
1892 }
1893 
1894 /**
1895   * @brief  Return the SMBUS error code
1896   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1897   *              the configuration information for the specified SMBUS.
1898   * @retval SMBUS Error Code
1899   */
HAL_SMBUS_GetError(SMBUS_HandleTypeDef * hsmbus)1900 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1901 {
1902   return hsmbus->ErrorCode;
1903 }
1904 
1905 /**
1906   * @}
1907   */
1908 
1909 /**
1910   * @}
1911   */
1912 
1913 /** @addtogroup SMBUS_Private_Functions
1914   * @{
1915   */
1916 
1917 /**
1918   * @brief  Handle TXE flag for Master
1919   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1920   *         the configuration information for SMBUS module
1921   * @retval HAL status
1922   */
SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef * hsmbus)1923 static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
1924 {
1925   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
1926   uint32_t CurrentState       = hsmbus->State;
1927   uint32_t CurrentXferOptions = hsmbus->XferOptions;
1928 
1929   if ((hsmbus->XferSize == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_TX))
1930   {
1931     /* Call TxCpltCallback() directly if no stop mode is set */
1932     if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
1933     {
1934       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1935 
1936       hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
1937       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1938       hsmbus->State = HAL_SMBUS_STATE_READY;
1939 
1940 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1941       hsmbus->MasterTxCpltCallback(hsmbus);
1942 #else
1943       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1944 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1945     }
1946     else /* Generate Stop condition then Call TxCpltCallback() */
1947     {
1948       /* Disable EVT, BUF and ERR interrupt */
1949       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1950 
1951       /* Generate Stop */
1952       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1953 
1954       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1955       hsmbus->State = HAL_SMBUS_STATE_READY;
1956 
1957       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1958 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1959       hsmbus->MasterTxCpltCallback(hsmbus);
1960 #else
1961       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1962 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1963     }
1964   }
1965   else if (CurrentState == HAL_SMBUS_STATE_BUSY_TX)
1966   {
1967 
1968     if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
1969     {
1970       hsmbus->XferCount--;
1971     }
1972 
1973     if (hsmbus->XferCount == 0U)
1974     {
1975 
1976       /* Disable BUF interrupt */
1977       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
1978 
1979       if ((SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
1980       {
1981         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
1982       }
1983 
1984     }
1985     else
1986     {
1987       /* Write data to DR */
1988       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
1989       hsmbus->XferCount--;
1990     }
1991   }
1992   return HAL_OK;
1993 }
1994 
1995 /**
1996   * @brief  Handle BTF flag for Master transmitter
1997   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1998   *         the configuration information for SMBUS module
1999   * @retval HAL status
2000   */
SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef * hsmbus)2001 static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
2002 {
2003   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2004   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2005 
2006   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
2007   {
2008     if (hsmbus->XferCount != 0U)
2009     {
2010       /* Write data to DR */
2011       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2012       hsmbus->XferCount--;
2013     }
2014     else
2015     {
2016       /* Call TxCpltCallback() directly if no stop mode is set */
2017       if (((CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_NEXT_FRAME)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
2018       {
2019         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2020 
2021         hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
2022         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2023         hsmbus->State = HAL_SMBUS_STATE_READY;
2024 
2025 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2026         hsmbus->MasterTxCpltCallback(hsmbus);
2027 #else
2028         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2029 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2030       }
2031       else /* Generate Stop condition then Call TxCpltCallback() */
2032       {
2033         /* Disable EVT, BUF and ERR interrupt */
2034         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2035 
2036         /* Generate Stop */
2037         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2038 
2039         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2040         hsmbus->State = HAL_SMBUS_STATE_READY;
2041         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2042 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2043         hsmbus->MasterTxCpltCallback(hsmbus);
2044 #else
2045         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2046 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2047       }
2048     }
2049   }
2050   return HAL_OK;
2051 }
2052 
2053 /**
2054   * @brief  Handle RXNE flag for Master
2055   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2056   *         the configuration information for SMBUS module
2057   * @retval HAL status
2058   */
SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef * hsmbus)2059 static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
2060 {
2061   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2062   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2063 
2064   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
2065   {
2066     uint32_t tmp = hsmbus->XferCount;
2067 
2068     if (tmp > 3U)
2069     {
2070       /* Read data from DR */
2071       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2072       hsmbus->XferCount--;
2073 
2074       if (hsmbus->XferCount == 3)
2075       {
2076         /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
2077         on BTF subroutine */
2078         /* Disable BUF interrupt */
2079         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2080       }
2081     }
2082 
2083     else if (tmp == 2U)
2084     {
2085 
2086       /* Read data from DR */
2087       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2088       hsmbus->XferCount--;
2089 
2090       if ((CurrentXferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (CurrentXferOptions == SMBUS_LAST_FRAME_WITH_PEC))
2091       {
2092         /* PEC of slave */
2093         hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2094 
2095       }
2096       /* Generate Stop */
2097       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2098     }
2099 
2100     else if ((tmp == 1U) || (tmp == 0U))
2101     {
2102       /* Disable Acknowledge */
2103       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2104 
2105       /* Disable EVT, BUF and ERR interrupt */
2106       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2107 
2108       /* Read data from DR */
2109       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2110       hsmbus->XferCount--;
2111 
2112       hsmbus->State = HAL_SMBUS_STATE_READY;
2113       hsmbus->PreviousState = SMBUS_STATE_NONE;
2114       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2115 
2116 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2117       hsmbus->MasterRxCpltCallback(hsmbus);
2118 #else
2119       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2120 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2121     }
2122   }
2123 
2124   return HAL_OK;
2125 }
2126 
2127 /**
2128   * @brief  Handle BTF flag for Master receiver
2129   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2130   *         the configuration information for SMBUS module
2131   * @retval HAL status
2132   */
SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef * hsmbus)2133 static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
2134 {
2135   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2136   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2137 
2138   if (hsmbus->XferCount == 4U)
2139   {
2140     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
2141        on BTF subroutine if there is a reception delay between N-1 and N byte */
2142     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2143 
2144     /* Read data from DR */
2145     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2146     hsmbus->XferCount--;
2147     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2148   }
2149   else if (hsmbus->XferCount == 3U)
2150   {
2151     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
2152        on BTF subroutine if there is a reception delay between N-1 and N byte */
2153     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2154 
2155     /* Disable Acknowledge */
2156     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2157 
2158     /* Read data from DR */
2159     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2160     hsmbus->XferCount--;
2161     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2162   }
2163   else if (hsmbus->XferCount == 2U)
2164   {
2165     /* Prepare next transfer or stop current transfer */
2166     if ((CurrentXferOptions == SMBUS_NEXT_FRAME) || (CurrentXferOptions == SMBUS_FIRST_FRAME))
2167     {
2168       /* Disable Acknowledge */
2169       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2170 
2171       /* Generate ReStart */
2172       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
2173     }
2174     else
2175     {
2176       /* Generate Stop */
2177       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2178     }
2179 
2180     /* Read data from DR */
2181     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2182     hsmbus->XferCount--;
2183 
2184     /* Read data from DR */
2185     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2186     hsmbus->XferCount--;
2187 
2188     /* Disable EVT and ERR interrupt */
2189     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
2190 
2191     hsmbus->State = HAL_SMBUS_STATE_READY;
2192     hsmbus->PreviousState = SMBUS_STATE_NONE;
2193     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2194 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2195     hsmbus->MasterRxCpltCallback(hsmbus);
2196 #else
2197     HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2198 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2199   }
2200   else
2201   {
2202     /* Read data from DR */
2203     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2204     hsmbus->XferCount--;
2205   }
2206   return HAL_OK;
2207 }
2208 
2209 /**
2210   * @brief  Handle SB flag for Master
2211   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2212   *         the configuration information for SMBUS module
2213   * @retval HAL status
2214   */
SMBUS_Master_SB(SMBUS_HandleTypeDef * hsmbus)2215 static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus)
2216 {
2217   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
2218   {
2219     /* Send slave 7 Bits address */
2220     if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
2221     {
2222       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(hsmbus->Devaddress);
2223     }
2224     else
2225     {
2226       hsmbus->Instance->DR = SMBUS_7BIT_ADD_READ(hsmbus->Devaddress);
2227     }
2228   }
2229   else
2230   {
2231     if (hsmbus->EventCount == 0U)
2232     {
2233       /* Send header of slave address */
2234       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_WRITE(hsmbus->Devaddress);
2235     }
2236     else if (hsmbus->EventCount == 1U)
2237     {
2238       /* Send header of slave address */
2239       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_READ(hsmbus->Devaddress);
2240     }
2241   }
2242   return HAL_OK;
2243 }
2244 
2245 /**
2246   * @brief  Handle ADD10 flag for Master
2247   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2248   *         the configuration information for SMBUS module
2249   * @retval HAL status
2250   */
SMBUS_Master_ADD10(SMBUS_HandleTypeDef * hsmbus)2251 static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus)
2252 {
2253   /* Send slave address */
2254   hsmbus->Instance->DR = SMBUS_10BIT_ADDRESS(hsmbus->Devaddress);
2255 
2256   return HAL_OK;
2257 }
2258 
2259 /**
2260   * @brief  Handle ADDR flag for Master
2261   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2262   *         the configuration information for SMBUS module
2263   * @retval HAL status
2264   */
SMBUS_Master_ADDR(SMBUS_HandleTypeDef * hsmbus)2265 static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus)
2266 {
2267   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2268   uint32_t Prev_State         = hsmbus->PreviousState;
2269 
2270   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
2271   {
2272     if ((hsmbus->EventCount == 0U) && (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT))
2273     {
2274       /* Clear ADDR flag */
2275       __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2276 
2277       /* Generate Restart */
2278       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
2279 
2280       hsmbus->EventCount++;
2281     }
2282     else
2283     {
2284       /*  In the case of the Quick Command, the ADDR flag is cleared and a stop is generated */
2285       if (hsmbus->XferCount == 0U)
2286       {
2287         /* Clear ADDR flag */
2288         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2289 
2290         /* Generate Stop */
2291         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2292       }
2293       else if (hsmbus->XferCount == 1U)
2294       {
2295         /* Prepare next transfer or stop current transfer */
2296         if ((hsmbus->XferOptions == SMBUS_FIRST_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
2297         {
2298           /* Disable Acknowledge */
2299           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2300 
2301           /* Clear ADDR flag */
2302           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2303         }
2304         else if ((hsmbus->XferOptions == SMBUS_NEXT_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
2305         {
2306           /* Enable Acknowledge */
2307           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2308 
2309           /* Clear ADDR flag */
2310           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2311         }
2312         else
2313         {
2314           /* Disable Acknowledge */
2315           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2316 
2317           /* Clear ADDR flag */
2318           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2319 
2320           /* Generate Stop */
2321           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2322         }
2323       }
2324       else if (hsmbus->XferCount == 2U)
2325       {
2326         if (hsmbus->XferOptions != SMBUS_NEXT_FRAME)
2327         {
2328           /* Disable Acknowledge */
2329           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2330 
2331           /* Enable Pos */
2332           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
2333 
2334 
2335         }
2336         else
2337         {
2338           /* Enable Acknowledge */
2339           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2340         }
2341 
2342         /* Clear ADDR flag */
2343         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2344       }
2345       else
2346       {
2347         /* Enable Acknowledge */
2348         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2349 
2350         /* Clear ADDR flag */
2351         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2352       }
2353 
2354       /* Reset Event counter  */
2355       hsmbus->EventCount = 0U;
2356     }
2357   }
2358   else
2359   {
2360     /* Clear ADDR flag */
2361     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2362   }
2363 
2364   return HAL_OK;
2365 }
2366 
2367 /**
2368   * @brief  Handle TXE flag for Slave
2369   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2370   *         the configuration information for SMBUS module
2371   * @retval HAL status
2372   */
SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef * hsmbus)2373 static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
2374 {
2375   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2376   uint32_t CurrentState = hsmbus->State;
2377 
2378   if (hsmbus->XferCount != 0U)
2379   {
2380     /* Write data to DR */
2381     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2382     hsmbus->XferCount--;
2383 
2384     if ((hsmbus->XferCount == 2U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
2385     {
2386       hsmbus->XferCount--;
2387     }
2388 
2389     if ((hsmbus->XferCount == 0U) && (CurrentState == (HAL_SMBUS_STATE_BUSY_TX_LISTEN)))
2390     {
2391       /* Last Byte is received, disable Interrupt */
2392       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2393 
2394       /* Set state at HAL_SMBUS_STATE_LISTEN */
2395       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_TX;
2396       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2397 
2398       /* Call the corresponding callback to inform upper layer of End of Transfer */
2399 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2400       hsmbus->SlaveTxCpltCallback(hsmbus);
2401 #else
2402       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
2403 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2404     }
2405   }
2406   return HAL_OK;
2407 }
2408 
2409 /**
2410   * @brief  Handle BTF flag for Slave transmitter
2411   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2412   *         the configuration information for SMBUS module
2413   * @retval HAL status
2414   */
SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef * hsmbus)2415 static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
2416 {
2417   if (hsmbus->XferCount != 0U)
2418   {
2419     /* Write data to DR */
2420     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2421     hsmbus->XferCount--;
2422   }
2423 
2424 
2425 
2426   else if ((hsmbus->XferCount == 0U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
2427   {
2428     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
2429   }
2430   return HAL_OK;
2431 }
2432 
2433 /**
2434   * @brief  Handle RXNE flag for Slave
2435   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2436   *         the configuration information for SMBUS module
2437   * @retval HAL status
2438   */
SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef * hsmbus)2439 static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
2440 {
2441   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2442   uint32_t CurrentState = hsmbus->State;
2443 
2444   if (hsmbus->XferCount != 0U)
2445   {
2446     /* Read data from DR */
2447     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2448     hsmbus->XferCount--;
2449 
2450     if ((hsmbus->XferCount == 1U) && (SMBUS_GET_PEC_MODE(hsmbus) == SMBUS_PEC_ENABLE) && ((hsmbus->XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (hsmbus->XferOptions == SMBUS_LAST_FRAME_WITH_PEC)))
2451     {
2452       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
2453       hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2454     }
2455     if ((hsmbus->XferCount == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
2456     {
2457       /* Last Byte is received, disable Interrupt */
2458       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2459 
2460       /* Set state at HAL_SMBUS_STATE_LISTEN */
2461       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_RX;
2462       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2463 
2464       /* Call the corresponding callback to inform upper layer of End of Transfer */
2465 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2466       hsmbus->SlaveRxCpltCallback(hsmbus);
2467 #else
2468       HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
2469 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2470     }
2471   }
2472   return HAL_OK;
2473 }
2474 
2475 /**
2476   * @brief  Handle BTF flag for Slave receiver
2477   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2478   *         the configuration information for SMBUS module
2479   * @retval HAL status
2480   */
SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef * hsmbus)2481 static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
2482 {
2483   if (hsmbus->XferCount != 0U)
2484   {
2485     /* Read data from DR */
2486     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2487     hsmbus->XferCount--;
2488   }
2489 
2490   return HAL_OK;
2491 }
2492 
2493 /**
2494   * @brief  Handle ADD flag for Slave
2495   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2496   *         the configuration information for SMBUS module
2497   * @retval HAL status
2498   */
SMBUS_Slave_ADDR(SMBUS_HandleTypeDef * hsmbus)2499 static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus)
2500 {
2501   uint8_t TransferDirection = SMBUS_DIRECTION_RECEIVE ;
2502   uint16_t SlaveAddrCode = 0U;
2503 
2504   /* Transfer Direction requested by Master */
2505   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TRA) == RESET)
2506   {
2507     TransferDirection = SMBUS_DIRECTION_TRANSMIT;
2508   }
2509 
2510   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_DUALF) == RESET)
2511   {
2512     SlaveAddrCode = hsmbus->Init.OwnAddress1;
2513   }
2514   else
2515   {
2516     SlaveAddrCode = hsmbus->Init.OwnAddress2;
2517   }
2518 
2519   /* Call Slave Addr callback */
2520 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2521   hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2522 #else
2523   HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2524 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2525 
2526   return HAL_OK;
2527 }
2528 
2529 /**
2530   * @brief  Handle STOPF flag for Slave
2531   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2532   *         the configuration information for SMBUS module
2533   * @retval HAL status
2534   */
SMBUS_Slave_STOPF(SMBUS_HandleTypeDef * hsmbus)2535 static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus)
2536 {
2537   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2538   uint32_t CurrentState = hsmbus->State;
2539 
2540   /* Disable EVT, BUF and ERR interrupt */
2541   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2542 
2543   /* Clear STOPF flag */
2544   __HAL_SMBUS_CLEAR_STOPFLAG(hsmbus);
2545 
2546   /* Disable Acknowledge */
2547   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2548 
2549   /* All data are not transferred, so set error code accordingly */
2550   if (hsmbus->XferCount != 0U)
2551   {
2552     /* Store Last receive data if any */
2553     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BTF) == SET)
2554     {
2555       /* Read data from DR */
2556       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2557 
2558       if (hsmbus->XferCount > 0)
2559       {
2560         hsmbus->XferSize--;
2561         hsmbus->XferCount--;
2562       }
2563     }
2564 
2565     /* Store Last receive data if any */
2566     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
2567     {
2568       /* Read data from DR */
2569       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2570 
2571       if (hsmbus->XferCount > 0)
2572       {
2573         hsmbus->XferSize--;
2574         hsmbus->XferCount--;
2575       }
2576     }
2577   }
2578 
2579   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
2580   {
2581     /* Call the corresponding callback to inform upper layer of End of Transfer */
2582     SMBUS_ITError(hsmbus);
2583   }
2584   else
2585   {
2586     if ((CurrentState == HAL_SMBUS_STATE_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN)  || \
2587         (CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN))
2588     {
2589       hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2590       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2591       hsmbus->State = HAL_SMBUS_STATE_READY;
2592       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2593 
2594 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2595       hsmbus->ListenCpltCallback(hsmbus);
2596 #else
2597       HAL_SMBUS_ListenCpltCallback(hsmbus);
2598 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2599     }
2600   }
2601   return HAL_OK;
2602 }
2603 
2604 /**
2605   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2606   *         the configuration information for SMBUS module
2607   * @retval HAL status
2608   */
SMBUS_Slave_AF(SMBUS_HandleTypeDef * hsmbus)2609 static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus)
2610 {
2611   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2612   uint32_t CurrentState       = hsmbus->State;
2613   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2614 
2615   if (((CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \
2616        (CurrentXferOptions == SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_LAST_FRAME_WITH_PEC)) && \
2617       (CurrentState == HAL_SMBUS_STATE_LISTEN))
2618   {
2619     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2620 
2621     /* Disable EVT, BUF and ERR interrupt */
2622     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2623 
2624     /* Clear AF flag */
2625     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2626 
2627     /* Disable Acknowledge */
2628     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2629 
2630     hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2631     hsmbus->State = HAL_SMBUS_STATE_READY;
2632     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2633 
2634     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2635 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2636     hsmbus->ListenCpltCallback(hsmbus);
2637 #else
2638     HAL_SMBUS_ListenCpltCallback(hsmbus);
2639 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2640   }
2641   return HAL_OK;
2642 }
2643 
2644 
2645 
2646 /**
2647   * @brief SMBUS interrupts error process
2648   * @param  hsmbus SMBUS handle.
2649   * @retval None
2650   */
SMBUS_ITError(SMBUS_HandleTypeDef * hsmbus)2651 static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus)
2652 {
2653   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2654   uint32_t CurrentState = hsmbus->State;
2655 
2656   if ((CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
2657   {
2658     /* keep HAL_SMBUS_STATE_LISTEN */
2659     hsmbus->PreviousState = SMBUS_STATE_NONE;
2660     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2661   }
2662   else
2663   {
2664     /* If state is an abort treatment on going, don't change state */
2665     /* This change will be done later */
2666     if (hsmbus->State != HAL_SMBUS_STATE_ABORT)
2667     {
2668       hsmbus->State = HAL_SMBUS_STATE_READY;
2669     }
2670     hsmbus->PreviousState = SMBUS_STATE_NONE;
2671     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2672   }
2673 
2674   /* Disable Pos bit in SMBUS CR1 when error occurred in Master/Mem Receive IT Process */
2675   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
2676 
2677   if (hsmbus->State == HAL_SMBUS_STATE_ABORT)
2678   {
2679     hsmbus->State = HAL_SMBUS_STATE_READY;
2680     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
2681 
2682     /* Store Last receive data if any */
2683     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
2684     {
2685       /* Read data from DR */
2686       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2687     }
2688 
2689     /* Disable SMBUS peripheral to prevent dummy data in buffer */
2690     __HAL_SMBUS_DISABLE(hsmbus);
2691 
2692     /* Call the corresponding callback to inform upper layer of End of Transfer */
2693 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2694     hsmbus->AbortCpltCallback(hsmbus);
2695 #else
2696     HAL_SMBUS_AbortCpltCallback(hsmbus);
2697 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2698   }
2699   else
2700   {
2701     /* Store Last receive data if any */
2702     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
2703     {
2704       /* Read data from DR */
2705       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2706     }
2707 
2708     /* Call user error callback */
2709 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2710     hsmbus->ErrorCallback(hsmbus);
2711 #else
2712     HAL_SMBUS_ErrorCallback(hsmbus);
2713 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2714   }
2715   /* STOP Flag is not set after a NACK reception */
2716   /* So may inform upper layer that listen phase is stopped */
2717   /* during NACK error treatment */
2718   if ((hsmbus->State == HAL_SMBUS_STATE_LISTEN) && ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_AF) == HAL_SMBUS_ERROR_AF))
2719   {
2720     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2721     hsmbus->PreviousState = SMBUS_STATE_NONE;
2722     hsmbus->State = HAL_SMBUS_STATE_READY;
2723     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2724 
2725     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2726 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2727     hsmbus->ListenCpltCallback(hsmbus);
2728 #else
2729     HAL_SMBUS_ListenCpltCallback(hsmbus);
2730 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2731   }
2732 }
2733 
2734 /**
2735   * @brief  This function handles SMBUS Communication Timeout.
2736   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2737   *         the configuration information for SMBUS module
2738   * @param  Flag specifies the SMBUS flag to check.
2739   * @param  Status The new Flag status (SET or RESET).
2740   * @param  Timeout Timeout duration
2741   * @param  Tickstart Tick start value
2742   * @retval HAL status
2743   */
SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef * hsmbus,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)2744 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
2745 {
2746   /* Wait until flag is set */
2747   if (Status == RESET)
2748   {
2749     while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
2750     {
2751       /* Check for the Timeout */
2752       if (Timeout != HAL_MAX_DELAY)
2753       {
2754         if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
2755         {
2756           hsmbus->PreviousState = SMBUS_STATE_NONE;
2757           hsmbus->State = HAL_SMBUS_STATE_READY;
2758           hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2759 
2760           /* Process Unlocked */
2761           __HAL_UNLOCK(hsmbus);
2762           return HAL_TIMEOUT;
2763         }
2764       }
2765     }
2766   }
2767   return HAL_OK;
2768 }
2769 
2770 /**
2771   * @}
2772   */
2773 
2774 
2775 #endif /* HAL_SMBUS_MODULE_ENABLED */
2776 
2777 /**
2778   * @}
2779   */
2780 
2781 /**
2782   * @}
2783   */
2784 
2785