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