xref: /btstack/port/stm32-f4discovery-usb/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smbus.c (revision a8f7f3fcbcd51f8d2e92aca076b6a9f812db358c)
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   @verbatim
14   ==============================================================================
15                         ##### How to use this driver #####
16   ==============================================================================
17   [..]
18     The SMBUS HAL driver can be used as follows:
19 
20     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
21         SMBUS_HandleTypeDef  hsmbus;
22 
23     (#)Initialize the SMBUS low level resources by implementing the @ref HAL_SMBUS_MspInit() API:
24         (##) Enable the SMBUSx interface clock
25         (##) SMBUS pins configuration
26             (+++) Enable the clock for the SMBUS GPIOs
27             (+++) Configure SMBUS pins as alternate function open-drain
28         (##) NVIC configuration if you need to use interrupt process
29             (+++) Configure the SMBUSx interrupt priority
30             (+++) Enable the NVIC SMBUS IRQ Channel
31 
32     (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,
33         Dual Addressing mode, Own Address2, General call and Nostretch mode in the hsmbus Init structure.
34 
35     (#) Initialize the SMBUS registers by calling the @ref HAL_SMBUS_Init(), configures also the low level Hardware
36         (GPIO, CLOCK, NVIC...etc) by calling the customized @ref HAL_SMBUS_MspInit(&hsmbus) API.
37 
38     (#) To check if target device is ready for communication, use the function @ref HAL_SMBUS_IsDeviceReady()
39 
40     (#) For SMBUS IO operations, only one mode of operations is available within this driver :
41 
42 
43     *** Interrupt mode IO operation ***
44     ===================================
45 
46   [..]
47       (+) Transmit in master/host SMBUS mode an amount of data in non blocking mode using @ref HAL_SMBUS_Master_Transmit_IT()
48       (++) At transmission end of transfer @ref HAL_SMBUS_MasterTxCpltCallback() is executed and user can
49            add his own code by customization of function pointer @ref HAL_SMBUS_MasterTxCpltCallback()
50       (+) Receive in master/host SMBUS mode an amount of data in non blocking mode using @ref HAL_SMBUS_Master_Receive_IT()
51       (++) At reception end of transfer @ref HAL_SMBUS_MasterRxCpltCallback() is executed and user can
52            add his own code by customization of function pointer @ref HAL_SMBUS_MasterRxCpltCallback()
53       (+) Abort a master/Host SMBUS process communication with Interrupt using @ref HAL_SMBUS_Master_Abort_IT()
54       (++) End of abort process, @ref HAL_SMBUS_AbortCpltCallback() is executed and user can
55            add his own code by customization of function pointer @ref HAL_SMBUS_AbortCpltCallback()
56       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
57            using @ref HAL_SMBUS_EnableListen_IT() @ref HAL_SMBUS_DisableListen_IT()
58       (++) When address slave/device SMBUS match, @ref HAL_SMBUS_AddrCallback() is executed and user can
59            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
60       (++) At Listen mode end @ref HAL_SMBUS_ListenCpltCallback() is executed and user can
61            add his own code by customization of function pointer @ref HAL_SMBUS_ListenCpltCallback()
62       (+) Transmit in slave/device SMBUS mode an amount of data in non blocking mode using @ref HAL_SMBUS_Slave_Transmit_IT()
63       (++) At transmission end of transfer @ref HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
64            add his own code by customization of function pointer @ref HAL_SMBUS_SlaveTxCpltCallback()
65       (+) Receive in slave/device SMBUS mode an amount of data in non blocking mode using @ref HAL_SMBUS_Slave_Receive_IT()
66       (++) At reception end of transfer @ref HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
67            add his own code by customization of function pointer @ref HAL_SMBUS_SlaveRxCpltCallback()
68       (+) Enable/Disable the SMBUS alert mode using @ref HAL_SMBUS_EnableAlert_IT() and @ref HAL_SMBUS_DisableAlert_IT()
69       (++) When SMBUS Alert is generated @ref HAL_SMBUS_ErrorCallback() is executed and user can
70            add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
71            to check the Alert Error Code using function @ref HAL_SMBUS_GetError()
72       (+) Get HAL state machine or error values using @ref HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
73       (+) In case of transfer Error, @ref HAL_SMBUS_ErrorCallback() function is executed and user can
74            add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
75            to check the Error Code using function @ref HAL_SMBUS_GetError()
76 
77 
78      *** SMBUS HAL driver macros list ***
79      ==================================
80      [..]
81        Below the list of most used macros in SMBUS HAL driver.
82 
83       (+) @ref __HAL_SMBUS_ENABLE    : Enable the SMBUS peripheral
84       (+) @ref __HAL_SMBUS_DISABLE   : Disable the SMBUS peripheral
85       (+) @ref __HAL_SMBUS_GET_FLAG  : Checks whether the specified SMBUS flag is set or not
86       (+) @ref __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag
87       (+) @ref __HAL_SMBUS_ENABLE_IT : Enable the specified SMBUS interrupt
88       (+) @ref __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt
89 
90      [..]
91        (@) You can refer to the SMBUS HAL driver header file for more useful macros
92 
93      *** Callback registration ***
94      =============================================
95     [..]
96      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
97      allows the user to configure dynamically the driver callbacks.
98      Use Functions @ref HAL_SMBUS_RegisterCallback() or @ref HAL_SMBUS_RegisterXXXCallback()
99      to register an interrupt callback.
100 
101      Function @ref HAL_SMBUS_RegisterCallback() allows to register following callbacks:
102        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
103        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
104        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
105        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
106        (+) ListenCpltCallback   : callback for end of listen mode.
107        (+) ErrorCallback        : callback for error detection.
108        (+) AbortCpltCallback    : callback for abort completion process.
109        (+) MspInitCallback      : callback for Msp Init.
110        (+) MspDeInitCallback    : callback for Msp DeInit.
111      This function takes as parameters the HAL peripheral handle, the Callback ID
112      and a pointer to the user callback function.
113     [..]
114      For specific callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_RegisterAddrCallback().
115     [..]
116      Use function @ref HAL_SMBUS_UnRegisterCallback to reset a callback to the default
117      weak function.
118      @ref HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
119      and the Callback ID.
120      This function allows to reset following callbacks:
121        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
122        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
123        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
124        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
125        (+) ListenCpltCallback   : callback for end of listen mode.
126        (+) ErrorCallback        : callback for error detection.
127        (+) AbortCpltCallback    : callback for abort completion process.
128        (+) MspInitCallback      : callback for Msp Init.
129        (+) MspDeInitCallback    : callback for Msp DeInit.
130     [..]
131      For callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_UnRegisterAddrCallback().
132     [..]
133      By default, after the @ref HAL_SMBUS_Init() and when the state is @ref HAL_SMBUS_STATE_RESET
134      all callbacks are set to the corresponding weak functions:
135      examples @ref HAL_SMBUS_MasterTxCpltCallback(), @ref HAL_SMBUS_MasterRxCpltCallback().
136      Exception done for MspInit and MspDeInit functions that are
137      reset to the legacy weak functions in the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit() only when
138      these callbacks are null (not registered beforehand).
139      If MspInit or MspDeInit are not null, the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit()
140      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
141     [..]
142      Callbacks can be registered/unregistered in @ref HAL_SMBUS_STATE_READY state only.
143      Exception done MspInit/MspDeInit functions that can be registered/unregistered
144      in @ref HAL_SMBUS_STATE_READY or @ref HAL_SMBUS_STATE_RESET state,
145      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
146      Then, the user first registers the MspInit/MspDeInit user callbacks
147      using @ref HAL_SMBUS_RegisterCallback() before calling @ref HAL_SMBUS_DeInit()
148      or @ref HAL_SMBUS_Init() function.
149     [..]
150      When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
151      not defined, the callback registration feature is not available and all callbacks
152      are set to the corresponding weak functions.
153 
154   @endverbatim
155   ******************************************************************************
156   * @attention
157   *
158   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
159   * All rights reserved.</center></h2>
160   *
161   * This software component is licensed by ST under BSD 3-Clause license,
162   * the "License"; You may not use this file except in compliance with the
163   * License. You may obtain a copy of the License at:
164   *                        opensource.org/licenses/BSD-3-Clause
165   *
166   ******************************************************************************
167   */
168 
169 /* Includes ------------------------------------------------------------------*/
170 #include "stm32f4xx_hal.h"
171 
172 /** @addtogroup STM32F4xx_HAL_Driver
173   * @{
174   */
175 
176 /** @defgroup SMBUS SMBUS
177   * @brief SMBUS HAL module driver
178   * @{
179   */
180 
181 #ifdef HAL_SMBUS_MODULE_ENABLED
182 
183 /* Private typedef -----------------------------------------------------------*/
184 /* Private define ------------------------------------------------------------*/
185 /** @addtogroup SMBUS_Private_Define
186   * @{
187   */
188 #define SMBUS_TIMEOUT_FLAG          35U         /*!< Timeout 35 ms             */
189 #define SMBUS_TIMEOUT_BUSY_FLAG     25U         /*!< Timeout 25 ms             */
190 #define SMBUS_NO_OPTION_FRAME       0xFFFF0000U /*!< XferOptions default value */
191 
192 #define SMBUS_SENDPEC_MODE          I2C_CR1_PEC
193 #define SMBUS_GET_PEC(__HANDLE__)             (((__HANDLE__)->Instance->SR2 & I2C_SR2_PEC) >> 8)
194 
195 /* Private define for @ref PreviousState usage */
196 #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            */
197 #define SMBUS_STATE_NONE            ((uint32_t)(HAL_SMBUS_MODE_NONE))                                                                      /*!< Default Value                                          */
198 #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 */
199 #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 */
200 #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  */
201 #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  */
202 
203 /**
204   * @}
205   */
206 
207 /* Private macro -------------------------------------------------------------*/
208 /* Private variables ---------------------------------------------------------*/
209 /* Private function prototypes -----------------------------------------------*/
210 
211 /** @addtogroup SMBUS_Private_Functions
212   * @{
213   */
214 
215 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
216 static void SMBUS_ITError(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_PEC | 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   * @}
851   */
852 
853 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
854  *  @brief    Data transfers functions
855  *
856 @verbatim
857  ===============================================================================
858                       ##### IO operation functions #####
859  ===============================================================================
860     [..]
861     This subsection provides a set of functions allowing to manage the SMBUS data
862     transfers.
863 
864     (#) Blocking mode function to check if device is ready for usage is :
865         (++) HAL_SMBUS_IsDeviceReady()
866 
867     (#) There is only one mode of transfer:
868        (++) Non Blocking mode : The communication is performed using Interrupts.
869             These functions return the status of the transfer startup.
870             The end of the data processing will be indicated through the
871             dedicated SMBUS IRQ when using Interrupt mode.
872 
873     (#) Non Blocking mode functions with Interrupt are :
874         (++) HAL_SMBUS_Master_Transmit_IT()
875         (++) HAL_SMBUS_Master_Receive_IT()
876         (++) HAL_SMBUS_Master_Abort_IT()
877         (++) HAL_SMBUS_Slave_Transmit_IT()
878         (++) HAL_SMBUS_Slave_Receive_IT()
879         (++) HAL_SMBUS_EnableAlert_IT()
880         (++) HAL_SMBUS_DisableAlert_IT()
881 
882     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
883         (++) HAL_SMBUS_MasterTxCpltCallback()
884         (++) HAL_SMBUS_MasterRxCpltCallback()
885         (++) HAL_SMBUS_SlaveTxCpltCallback()
886         (++) HAL_SMBUS_SlaveRxCpltCallback()
887         (++) HAL_SMBUS_AddrCallback()
888         (++) HAL_SMBUS_ListenCpltCallback()
889         (++) HAL_SMBUS_ErrorCallback()
890         (++) HAL_SMBUS_AbortCpltCallback()
891 
892 @endverbatim
893   * @{
894   */
895 
896 /**
897   * @brief  Transmits in master mode an amount of data in blocking mode.
898   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
899   *         the configuration information for the specified SMBUS.
900   * @param  DevAddress Target device address The device 7 bits address value
901   *         in datasheet must be shifted to the left before calling the interface
902   * @param  pData Pointer to data buffer
903   * @param  Size Amount of data to be sent
904   * @param  XferOptions Options of Transfer
905   * @retval HAL status
906   */
HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)907 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
908 {
909   uint32_t count      = 0x00U;
910 
911   /* Check the parameters */
912   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
913 
914   if (hsmbus->State == HAL_SMBUS_STATE_READY)
915   {
916     /* Check Busy Flag only if FIRST call of Master interface */
917     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
918     {
919       /* Wait until BUSY flag is reset */
920       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
921       do
922       {
923         if (count-- == 0U)
924         {
925           hsmbus->PreviousState = SMBUS_STATE_NONE;
926           hsmbus->State = HAL_SMBUS_STATE_READY;
927 
928           /* Process Unlocked */
929           __HAL_UNLOCK(hsmbus);
930 
931           return HAL_TIMEOUT;
932         }
933       }
934       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
935     }
936 
937     /* Process Locked */
938     __HAL_LOCK(hsmbus);
939 
940     /* Check if the SMBUS is already enabled */
941     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
942     {
943       /* Enable SMBUS peripheral */
944       __HAL_SMBUS_ENABLE(hsmbus);
945     }
946 
947     /* Disable Pos */
948     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
949 
950     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX;
951     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
952     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
953 
954     /* Prepare transfer parameters */
955     hsmbus->pBuffPtr    = pData;
956     hsmbus->XferCount   = Size;
957     hsmbus->XferOptions = XferOptions;
958     hsmbus->XferSize    = hsmbus->XferCount;
959     hsmbus->Devaddress  = DevAddress;
960 
961     /* Generate Start */
962     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
963 
964     /* Process Unlocked */
965     __HAL_UNLOCK(hsmbus);
966 
967     /* Note : The SMBUS interrupts must be enabled after unlocking current process
968     to avoid the risk of hsmbus interrupt handle execution before current
969     process unlock */
970 
971     /* Enable EVT, BUF and ERR interrupt */
972     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
973 
974     return HAL_OK;
975   }
976   else
977   {
978     return HAL_BUSY;
979   }
980 }
981 /**
982   * @brief  Receive in master/host SMBUS mode an amount of data in non blocking mode with Interrupt.
983   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
984   *         the configuration information for the specified SMBUS.
985   * @param  DevAddress Target device address The device 7 bits address value
986   *         in datasheet must be shifted to the left before calling the interface
987   * @param  pData Pointer to data buffer
988   * @param  Size Amount of data to be sent
989   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
990   * @retval HAL status
991   */
HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)992 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
993 {
994   __IO uint32_t count = 0U;
995 
996   /* Check the parameters */
997   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
998 
999   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1000   {
1001     /* Check Busy Flag only if FIRST call of Master interface */
1002     if ((XferOptions == SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (XferOptions == SMBUS_FIRST_FRAME))
1003     {
1004       /* Wait until BUSY flag is reset */
1005       count = SMBUS_TIMEOUT_BUSY_FLAG * (SystemCoreClock / 25U / 1000U);
1006       do
1007       {
1008         if (count-- == 0U)
1009         {
1010           hsmbus->PreviousState = SMBUS_STATE_NONE;
1011           hsmbus->State = HAL_SMBUS_STATE_READY;
1012 
1013           /* Process Unlocked */
1014           __HAL_UNLOCK(hsmbus);
1015 
1016           return HAL_TIMEOUT;
1017         }
1018       }
1019       while (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET);
1020     }
1021 
1022     /* Process Locked */
1023     __HAL_LOCK(hsmbus);
1024 
1025     /* Check if the SMBUS is already enabled */
1026     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1027     {
1028       /* Enable SMBUS peripheral */
1029       __HAL_SMBUS_ENABLE(hsmbus);
1030     }
1031 
1032     /* Disable Pos */
1033     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1034 
1035     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX;
1036     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1037     hsmbus->Mode      = HAL_SMBUS_MODE_MASTER;
1038 
1039     /* Prepare transfer parameters */
1040     hsmbus->pBuffPtr    = pData;
1041     hsmbus->XferCount   = Size;
1042     hsmbus->XferOptions = XferOptions;
1043     hsmbus->XferSize    = hsmbus->XferCount;
1044     hsmbus->Devaddress  = DevAddress;
1045 
1046     if ((hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX) || (hsmbus->PreviousState == SMBUS_STATE_NONE))
1047     {
1048       /* Generate Start condition if first transfer */
1049       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))
1050       {
1051         /* Enable Acknowledge */
1052         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1053 
1054         /* Generate Start */
1055         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1056       }
1057 
1058       if ((XferOptions == SMBUS_LAST_FRAME_NO_PEC) || (XferOptions == SMBUS_LAST_FRAME_WITH_PEC))
1059       {
1060         if (hsmbus->PreviousState == SMBUS_STATE_NONE)
1061         {
1062           /* Enable Acknowledge */
1063           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1064         }
1065 
1066         if (hsmbus->PreviousState == SMBUS_STATE_MASTER_BUSY_TX)
1067         {
1068           /* Enable Acknowledge */
1069           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1070 
1071           /* Generate Start */
1072           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1073         }
1074       }
1075     }
1076 
1077 
1078 
1079     /* Process Unlocked */
1080     __HAL_UNLOCK(hsmbus);
1081 
1082     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1083     to avoid the risk of SMBUS interrupt handle execution before current
1084     process unlock */
1085 
1086     /* Enable EVT, BUF and ERR interrupt */
1087     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1088 
1089     return HAL_OK;
1090   }
1091   else
1092   {
1093     return HAL_BUSY;
1094   }
1095 }
1096 
1097 /**
1098   * @brief  Abort a master/host SMBUS process communication with Interrupt.
1099   * @note   This abort can be called only if state is ready
1100   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1101   *         the configuration information for the specified SMBUS.
1102   * @param  DevAddress Target device address The device 7 bits address value
1103   *         in datasheet must be shifted to the left before calling the interface
1104   * @retval HAL status
1105   */
HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress)1106 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
1107 {
1108   /* Prevent unused argument(s) compilation warning */
1109   UNUSED(DevAddress);
1110   if (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_HOST)
1111   {
1112     /* Process Locked */
1113     __HAL_LOCK(hsmbus);
1114 
1115     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1116 
1117     hsmbus->PreviousState = SMBUS_STATE_NONE;
1118     hsmbus->State = HAL_SMBUS_STATE_ABORT;
1119 
1120 
1121     /* Disable Acknowledge */
1122     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1123 
1124     /* Generate Stop */
1125     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1126 
1127     hsmbus->XferCount = 0U;
1128 
1129     /* Disable EVT, BUF and ERR interrupt */
1130     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1131 
1132     /* Process Unlocked */
1133     __HAL_UNLOCK(hsmbus);
1134 
1135     /* Call the corresponding callback to inform upper layer of End of Transfer */
1136     SMBUS_ITError(hsmbus);
1137 
1138     return HAL_OK;
1139   }
1140   else
1141   {
1142     return HAL_BUSY;
1143   }
1144 }
1145 
1146 
1147 /**
1148   * @brief  Transmit in slave/device SMBUS mode an amount of data in non blocking mode with Interrupt.
1149   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1150   *         the configuration information for the specified SMBUS.
1151   * @param  pData Pointer to data buffer
1152   * @param  Size Amount of data to be sent
1153   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1154   * @retval HAL status
1155   */
HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1156 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1157 {
1158   /* Check the parameters */
1159   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1160 
1161   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1162   {
1163     if ((pData == NULL) || (Size == 0U))
1164     {
1165       return  HAL_ERROR;
1166     }
1167 
1168     /* Process Locked */
1169     __HAL_LOCK(hsmbus);
1170 
1171     /* Check if the SMBUS is already enabled */
1172     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1173     {
1174       /* Enable SMBUS peripheral */
1175       __HAL_SMBUS_ENABLE(hsmbus);
1176     }
1177 
1178     /* Disable Pos */
1179     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1180 
1181     hsmbus->State     = HAL_SMBUS_STATE_BUSY_TX_LISTEN;
1182     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1183     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
1184 
1185     /* Prepare transfer parameters */
1186     hsmbus->pBuffPtr    = pData;
1187     hsmbus->XferCount   = Size;
1188     hsmbus->XferOptions = XferOptions;
1189     hsmbus->XferSize    = hsmbus->XferCount;
1190 
1191     /* Clear ADDR flag after prepare the transfer parameters */
1192     /* This action will generate an acknowledge to the HOST */
1193     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
1194 
1195     /* Process Unlocked */
1196     __HAL_UNLOCK(hsmbus);
1197 
1198     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1199               to avoid the risk of SMBUS interrupt handle execution before current
1200               process unlock */
1201 
1202     /* Enable EVT, BUF and ERR interrupt */
1203     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1204 
1205     return HAL_OK;
1206   }
1207   else
1208   {
1209     return HAL_BUSY;
1210   }
1211 }
1212 
1213 /**
1214   * @brief  Enable the Address listen mode with Interrupt.
1215   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1216   *         the configuration information for the specified SMBUS.
1217   * @param  pData Pointer to data buffer
1218   * @param  Size Amount of data to be sent
1219   * @param  XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1220   * @retval HAL status
1221   */
HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1222 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1223 {
1224   /* Check the parameters */
1225   assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1226 
1227   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1228   {
1229     if ((pData == NULL) || (Size == 0U))
1230     {
1231       return  HAL_ERROR;
1232     }
1233 
1234     /* Process Locked */
1235     __HAL_LOCK(hsmbus);
1236 
1237     /* Check if the SMBUS is already enabled */
1238     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1239     {
1240       /* Enable SMBUS peripheral */
1241       __HAL_SMBUS_ENABLE(hsmbus);
1242     }
1243 
1244     /* Disable Pos */
1245     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1246 
1247     hsmbus->State     = HAL_SMBUS_STATE_BUSY_RX_LISTEN;
1248     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1249     hsmbus->Mode      = HAL_SMBUS_MODE_SLAVE;
1250 
1251 
1252 
1253     /* Prepare transfer parameters */
1254     hsmbus->pBuffPtr = pData;
1255     hsmbus->XferCount = Size;
1256     hsmbus->XferOptions = XferOptions;
1257     hsmbus->XferSize    = hsmbus->XferCount;
1258 
1259     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
1260 
1261     /* Process Unlocked */
1262     __HAL_UNLOCK(hsmbus);
1263 
1264     /* Note : The SMBUS interrupts must be enabled after unlocking current process
1265               to avoid the risk of SMBUS interrupt handle execution before current
1266               process unlock */
1267 
1268     /* Enable EVT, BUF and ERR interrupt */
1269     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1270 
1271     return HAL_OK;
1272   }
1273   else
1274   {
1275     return HAL_BUSY;
1276   }
1277 }
1278 
1279 
1280 /**
1281   * @brief  Enable the Address listen mode with Interrupt.
1282   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1283   *                the configuration information for the specified SMBUS.
1284   * @retval HAL status
1285   */
HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef * hsmbus)1286 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1287 {
1288   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1289   {
1290     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1291 
1292     /* Check if the SMBUS is already enabled */
1293     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1294     {
1295       /* Enable SMBUS peripheral */
1296       __HAL_SMBUS_ENABLE(hsmbus);
1297     }
1298 
1299     /* Enable Address Acknowledge */
1300     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1301 
1302     /* Enable EVT and ERR interrupt */
1303     __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
1304 
1305     return HAL_OK;
1306   }
1307   else
1308   {
1309     return HAL_BUSY;
1310   }
1311 }
1312 
1313 /**
1314   * @brief  Disable the Address listen mode with Interrupt.
1315   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1316   *         the configuration information for the specified SMBUS.
1317   * @retval HAL status
1318   */
HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef * hsmbus)1319 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1320 {
1321   /* Declaration of tmp to prevent undefined behavior of volatile usage */
1322   uint32_t tmp;
1323 
1324   /* Disable Address listen mode only if a transfer is not ongoing */
1325   if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1326   {
1327     tmp = (uint32_t)(hsmbus->State) & SMBUS_STATE_MSK;
1328     hsmbus->PreviousState = tmp | (uint32_t)(hsmbus->Mode);
1329     hsmbus->State = HAL_SMBUS_STATE_READY;
1330     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1331 
1332     /* Disable Address Acknowledge */
1333     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
1334 
1335     /* Disable EVT and ERR interrupt */
1336     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
1337 
1338     return HAL_OK;
1339   }
1340   else
1341   {
1342     return HAL_BUSY;
1343   }
1344 }
1345 
1346 /**
1347   * @brief  Enable the SMBUS alert mode with Interrupt.
1348   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1349   *         the configuration information for the specified SMBUSx peripheral.
1350   * @retval HAL status
1351   */
HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1352 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1353 {
1354   /* Enable SMBus alert */
1355   SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
1356 
1357   /* Clear ALERT flag */
1358   __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
1359 
1360   /* Enable Alert Interrupt */
1361   __HAL_SMBUS_ENABLE_IT(hsmbus, SMBUS_IT_ERR);
1362 
1363   return HAL_OK;
1364 }
1365 /**
1366   * @brief  Disable the SMBUS alert mode with Interrupt.
1367   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1368   *                the configuration information for the specified SMBUSx peripheral.
1369   * @retval HAL status
1370   */
HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1371 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1372 {
1373   /* Disable SMBus alert */
1374   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ALERT);
1375 
1376   /* Disable Alert Interrupt */
1377   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ERR);
1378 
1379   return HAL_OK;
1380 }
1381 
1382 
1383 /**
1384   * @brief  Check if target device is ready for communication.
1385   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1386   *         the configuration information for the specified SMBUS.
1387   * @param  DevAddress Target device address The device 7 bits address value
1388   *         in datasheet must be shifted to the left before calling the interface
1389   * @param  Trials Number of trials
1390   * @param  Timeout Timeout duration
1391   * @retval HAL status
1392   */
HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)1393 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
1394 {
1395   uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, SMBUS_Trials = 1U;
1396 
1397   /* Get tick */
1398   tickstart = HAL_GetTick();
1399 
1400   if (hsmbus->State == HAL_SMBUS_STATE_READY)
1401   {
1402     /* Wait until BUSY flag is reset */
1403     if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1404     {
1405       return HAL_BUSY;
1406     }
1407 
1408     /* Process Locked */
1409     __HAL_LOCK(hsmbus);
1410 
1411     /* Check if the SMBUS is already enabled */
1412     if ((hsmbus->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE)
1413     {
1414       /* Enable SMBUS peripheral */
1415       __HAL_SMBUS_ENABLE(hsmbus);
1416     }
1417 
1418     /* Disable Pos */
1419     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
1420 
1421     hsmbus->State = HAL_SMBUS_STATE_BUSY;
1422     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1423     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
1424 
1425     do
1426     {
1427       /* Generate Start */
1428       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
1429 
1430       /* Wait until SB flag is set */
1431       if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
1432       {
1433         return HAL_TIMEOUT;
1434       }
1435 
1436       /* Send slave address */
1437       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(DevAddress);
1438 
1439       /* Wait until ADDR or AF flag are set */
1440       /* Get tick */
1441       tickstart = HAL_GetTick();
1442 
1443       tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1444       tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1445       tmp3 = hsmbus->State;
1446       while ((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_SMBUS_STATE_TIMEOUT))
1447       {
1448         if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1449         {
1450           hsmbus->State = HAL_SMBUS_STATE_TIMEOUT;
1451         }
1452         tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1453         tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1454         tmp3 = hsmbus->State;
1455       }
1456 
1457       hsmbus->State = HAL_SMBUS_STATE_READY;
1458 
1459       /* Check if the ADDR flag has been set */
1460       if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_ADDR) == SET)
1461       {
1462         /* Generate Stop */
1463         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1464 
1465         /* Clear ADDR Flag */
1466         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
1467 
1468         /* Wait until BUSY flag is reset */
1469         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1470         {
1471           return HAL_TIMEOUT;
1472         }
1473 
1474         hsmbus->State = HAL_SMBUS_STATE_READY;
1475 
1476         /* Process Unlocked */
1477         __HAL_UNLOCK(hsmbus);
1478 
1479         return HAL_OK;
1480       }
1481       else
1482       {
1483         /* Generate Stop */
1484         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1485 
1486         /* Clear AF Flag */
1487         __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1488 
1489         /* Wait until BUSY flag is reset */
1490         if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_BUSY, SET, SMBUS_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
1491         {
1492           return HAL_TIMEOUT;
1493         }
1494       }
1495     }
1496     while (SMBUS_Trials++ < Trials);
1497 
1498     hsmbus->State = HAL_SMBUS_STATE_READY;
1499 
1500     /* Process Unlocked */
1501     __HAL_UNLOCK(hsmbus);
1502 
1503     return HAL_ERROR;
1504   }
1505   else
1506   {
1507     return HAL_BUSY;
1508   }
1509 }
1510 
1511 /**
1512   * @brief  This function handles SMBUS event interrupt request.
1513   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1514   *                the configuration information for the specified SMBUS.
1515   * @retval None
1516   */
HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1517 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1518 {
1519   uint32_t sr2itflags   = READ_REG(hsmbus->Instance->SR2);
1520   uint32_t sr1itflags   = READ_REG(hsmbus->Instance->SR1);
1521   uint32_t itsources    = READ_REG(hsmbus->Instance->CR2);
1522 
1523   uint32_t CurrentMode  = hsmbus->Mode;
1524 
1525   /* Master mode selected */
1526   if (CurrentMode == HAL_SMBUS_MODE_MASTER)
1527   {
1528     /* SB Set ----------------------------------------------------------------*/
1529     if (((sr1itflags & SMBUS_FLAG_SB) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1530     {
1531       SMBUS_Master_SB(hsmbus);
1532     }
1533     /* ADD10 Set -------------------------------------------------------------*/
1534     else if (((sr1itflags & SMBUS_FLAG_ADD10) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1535     {
1536       SMBUS_Master_ADD10(hsmbus);
1537     }
1538     /* ADDR Set --------------------------------------------------------------*/
1539     else if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1540     {
1541       SMBUS_Master_ADDR(hsmbus);
1542     }
1543     /* SMBUS in mode Transmitter -----------------------------------------------*/
1544     if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
1545     {
1546       /* TXE set and BTF reset -----------------------------------------------*/
1547       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1548       {
1549         SMBUS_MasterTransmit_TXE(hsmbus);
1550       }
1551       /* BTF set -------------------------------------------------------------*/
1552       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1553       {
1554         SMBUS_MasterTransmit_BTF(hsmbus);
1555       }
1556     }
1557     /* SMBUS in mode Receiver --------------------------------------------------*/
1558     else
1559     {
1560       /* RXNE set and BTF reset -----------------------------------------------*/
1561       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1562       {
1563         SMBUS_MasterReceive_RXNE(hsmbus);
1564       }
1565       /* BTF set -------------------------------------------------------------*/
1566       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1567       {
1568         SMBUS_MasterReceive_BTF(hsmbus);
1569       }
1570     }
1571   }
1572   /* Slave mode selected */
1573   else
1574   {
1575     /* ADDR set --------------------------------------------------------------*/
1576     if (((sr1itflags & SMBUS_FLAG_ADDR) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1577     {
1578       SMBUS_Slave_ADDR(hsmbus);
1579     }
1580     /* STOPF set --------------------------------------------------------------*/
1581     else if (((sr1itflags & SMBUS_FLAG_STOPF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1582     {
1583       SMBUS_Slave_STOPF(hsmbus);
1584     }
1585     /* SMBUS in mode Transmitter -----------------------------------------------*/
1586     else if ((sr2itflags & SMBUS_FLAG_TRA) != RESET)
1587     {
1588       /* TXE set and BTF reset -----------------------------------------------*/
1589       if (((sr1itflags & SMBUS_FLAG_TXE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1590       {
1591         SMBUS_SlaveTransmit_TXE(hsmbus);
1592       }
1593       /* BTF set -------------------------------------------------------------*/
1594       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1595       {
1596         SMBUS_SlaveTransmit_BTF(hsmbus);
1597       }
1598     }
1599     /* SMBUS in mode Receiver --------------------------------------------------*/
1600     else
1601     {
1602       /* RXNE set and BTF reset ----------------------------------------------*/
1603       if (((sr1itflags & SMBUS_FLAG_RXNE) != RESET) && ((itsources & SMBUS_IT_BUF) != RESET) && ((sr1itflags & SMBUS_FLAG_BTF) == RESET))
1604       {
1605         SMBUS_SlaveReceive_RXNE(hsmbus);
1606       }
1607       /* BTF set -------------------------------------------------------------*/
1608       else if (((sr1itflags & SMBUS_FLAG_BTF) != RESET) && ((itsources & SMBUS_IT_EVT) != RESET))
1609       {
1610         SMBUS_SlaveReceive_BTF(hsmbus);
1611       }
1612     }
1613   }
1614 }
1615 
1616 /**
1617   * @brief  This function handles SMBUS error interrupt request.
1618   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1619   *                the configuration information for the specified SMBUS.
1620   * @retval None
1621   */
HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1622 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1623 {
1624   uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U;
1625   uint32_t sr1itflags = READ_REG(hsmbus->Instance->SR1);
1626   uint32_t itsources  = READ_REG(hsmbus->Instance->CR2);
1627 
1628   /* SMBUS Bus error interrupt occurred ------------------------------------*/
1629   if (((sr1itflags & SMBUS_FLAG_BERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1630   {
1631     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
1632 
1633     /* Clear BERR flag */
1634     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
1635 
1636   }
1637 
1638   /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
1639   if (((sr1itflags & SMBUS_FLAG_OVR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1640   {
1641     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
1642 
1643     /* Clear OVR flag */
1644     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
1645   }
1646 
1647   /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
1648   if (((sr1itflags & SMBUS_FLAG_ARLO) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1649   {
1650     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
1651 
1652     /* Clear ARLO flag */
1653     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
1654   }
1655 
1656   /* SMBUS Acknowledge failure error interrupt occurred ------------------------------------*/
1657   if (((sr1itflags & SMBUS_FLAG_AF) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1658   {
1659     tmp1 = hsmbus->Mode;
1660     tmp2 = hsmbus->XferCount;
1661     tmp3 = hsmbus->State;
1662     tmp4 = hsmbus->PreviousState;
1663 
1664     if ((tmp1 == HAL_SMBUS_MODE_SLAVE) && (tmp2 == 0U) && \
1665         ((tmp3 == HAL_SMBUS_STATE_BUSY_TX) || (tmp3 == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || \
1666          ((tmp3 == HAL_SMBUS_STATE_LISTEN) && (tmp4 == SMBUS_STATE_SLAVE_BUSY_TX))))
1667     {
1668       SMBUS_Slave_AF(hsmbus);
1669     }
1670     else
1671     {
1672       hsmbus->ErrorCode |= HAL_SMBUS_ERROR_AF;
1673 
1674       /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */
1675       if (hsmbus->Mode == HAL_SMBUS_MODE_MASTER)
1676       {
1677         /* Generate Stop */
1678         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1679 
1680       }
1681 
1682       /* Clear AF flag */
1683       __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1684     }
1685   }
1686 
1687   /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
1688   if (((sr1itflags & SMBUS_FLAG_TIMEOUT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1689   {
1690     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_TIMEOUT;
1691 
1692     /* Clear TIMEOUT flag */
1693     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
1694 
1695   }
1696 
1697   /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
1698   if (((sr1itflags & SMBUS_FLAG_SMBALERT) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1699   {
1700     hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
1701 
1702     /* Clear ALERT flag */
1703     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_SMBALERT);
1704   }
1705 
1706   /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
1707   if (((sr1itflags & SMBUS_FLAG_PECERR) != RESET) && ((itsources & SMBUS_IT_ERR) != RESET))
1708   {
1709     hsmbus->ErrorCode |= SMBUS_FLAG_PECERR;
1710 
1711     /* Clear PEC error flag */
1712     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
1713   }
1714 
1715   /* Call the Error Callback in case of Error detected -----------------------*/
1716   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
1717   {
1718     SMBUS_ITError(hsmbus);
1719   }
1720 }
1721 
1722 /**
1723   * @brief  Master Tx Transfer completed callback.
1724   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1725   *                the configuration information for the specified SMBUS.
1726   * @retval None
1727   */
HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1728 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1729 {
1730   /* Prevent unused argument(s) compilation warning */
1731   UNUSED(hsmbus);
1732 
1733   /* NOTE : This function should not be modified, when the callback is needed,
1734             the HAL_SMBUS_MasterTxCpltCallback can be implemented in the user file
1735    */
1736 }
1737 
1738 /**
1739   * @brief  Master Rx Transfer completed callback.
1740   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1741   *                the configuration information for the specified SMBUS.
1742   * @retval None
1743   */
HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1744 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1745 {
1746   /* Prevent unused argument(s) compilation warning */
1747   UNUSED(hsmbus);
1748 
1749   /* NOTE : This function should not be modified, when the callback is needed,
1750             the HAL_SMBUS_MasterRxCpltCallback can be implemented in the user file
1751    */
1752 }
1753 
1754 /** @brief  Slave Tx Transfer completed callback.
1755   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1756   *                the configuration information for the specified SMBUS.
1757   * @retval None
1758   */
HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1759 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1760 {
1761   /* Prevent unused argument(s) compilation warning */
1762   UNUSED(hsmbus);
1763 
1764   /* NOTE : This function should not be modified, when the callback is needed,
1765             the HAL_SMBUS_SlaveTxCpltCallback can be implemented in the user file
1766    */
1767 }
1768 
1769 /**
1770   * @brief  Slave Rx Transfer completed callback.
1771   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1772   *                the configuration information for the specified SMBUS.
1773   * @retval None
1774   */
HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1775 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1776 {
1777   /* Prevent unused argument(s) compilation warning */
1778   UNUSED(hsmbus);
1779 
1780   /* NOTE : This function should not be modified, when the callback is needed,
1781             the HAL_SMBUS_SlaveRxCpltCallback can be implemented in the user file
1782    */
1783 }
1784 
1785 /**
1786   * @brief  Slave Address Match callback.
1787   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1788   *                the configuration information for the specified SMBUS.
1789   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref SMBUS_XferOptions_definition
1790   * @param  AddrMatchCode Address Match Code
1791   * @retval None
1792   */
HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef * hsmbus,uint8_t TransferDirection,uint16_t AddrMatchCode)1793 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1794 {
1795   /* Prevent unused argument(s) compilation warning */
1796   UNUSED(hsmbus);
1797   UNUSED(TransferDirection);
1798   UNUSED(AddrMatchCode);
1799 
1800   /* NOTE : This function should not be modified, when the callback is needed,
1801             the HAL_SMBUS_AddrCallback can be implemented in the user file
1802    */
1803 }
1804 
1805 /**
1806   * @brief  Listen Complete callback.
1807   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1808   *                the configuration information for the specified SMBUS.
1809   * @retval None
1810   */
HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef * hsmbus)1811 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1812 {
1813   /* Prevent unused argument(s) compilation warning */
1814   UNUSED(hsmbus);
1815 
1816   /* NOTE : This function should not be modified, when the callback is needed,
1817           the HAL_SMBUS_ListenCpltCallback can be implemented in the user file
1818   */
1819 }
1820 
1821 /**
1822   * @brief  SMBUS error callback.
1823   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1824   *                the configuration information for the specified SMBUS.
1825   * @retval None
1826   */
HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef * hsmbus)1827 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1828 {
1829   /* Prevent unused argument(s) compilation warning */
1830   UNUSED(hsmbus);
1831 
1832   /* NOTE : This function should not be modified, when the callback is needed,
1833             the HAL_SMBUS_ErrorCallback can be implemented in the user file
1834    */
1835 }
1836 
1837 /**
1838   * @brief  SMBUS abort callback.
1839   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1840   *                the configuration information for the specified SMBUS.
1841   * @retval None
1842   */
HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef * hsmbus)1843 __weak void HAL_SMBUS_AbortCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1844 {
1845   /* Prevent unused argument(s) compilation warning */
1846   UNUSED(hsmbus);
1847 
1848   /* NOTE : This function should not be modified, when the callback is needed,
1849             the HAL_SMBUS_AbortCpltCallback could be implemented in the user file
1850    */
1851 }
1852 
1853 /**
1854   * @}
1855   */
1856 
1857 /** @defgroup   SMBUS_Exported_Functions_Group3 Peripheral State, Mode and Error functions
1858   *  @brief   Peripheral State and Errors functions
1859   *
1860 @verbatim
1861  ===============================================================================
1862             ##### Peripheral State, Mode and Error functions #####
1863  ===============================================================================
1864     [..]
1865     This subsection permits to get in run-time the status of the peripheral
1866     and the data flow.
1867 
1868 @endverbatim
1869   * @{
1870   */
1871 
1872 /**
1873   * @brief  Return the SMBUS handle state.
1874   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1875   *                the configuration information for the specified SMBUS.
1876   * @retval HAL state
1877   */
HAL_SMBUS_GetState(SMBUS_HandleTypeDef * hsmbus)1878 HAL_SMBUS_StateTypeDef HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1879 {
1880   /* Return SMBUS handle state */
1881   return hsmbus->State;
1882 }
1883 
1884 /**
1885   * @brief  Return the SMBUS Master, Slave or no mode.
1886   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1887   *                the configuration information for SMBUS module
1888   * @retval HAL mode
1889   */
HAL_SMBUS_GetMode(SMBUS_HandleTypeDef * hsmbus)1890 HAL_SMBUS_ModeTypeDef HAL_SMBUS_GetMode(SMBUS_HandleTypeDef *hsmbus)
1891 {
1892   return hsmbus->Mode;
1893 }
1894 
1895 /**
1896   * @brief  Return the SMBUS error code
1897   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1898   *              the configuration information for the specified SMBUS.
1899   * @retval SMBUS Error Code
1900   */
HAL_SMBUS_GetError(SMBUS_HandleTypeDef * hsmbus)1901 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1902 {
1903   return hsmbus->ErrorCode;
1904 }
1905 
1906 /**
1907   * @}
1908   */
1909 
1910 /**
1911   * @}
1912   */
1913 
1914 /** @addtogroup SMBUS_Private_Functions
1915   * @{
1916   */
1917 
1918 /**
1919   * @brief  Handle TXE flag for Master
1920   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1921   *         the configuration information for SMBUS module
1922   * @retval HAL status
1923   */
SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef * hsmbus)1924 static HAL_StatusTypeDef SMBUS_MasterTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
1925 {
1926   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
1927   uint32_t CurrentState       = hsmbus->State;
1928   uint32_t CurrentMode        = hsmbus->Mode;
1929   uint32_t CurrentXferOptions = hsmbus->XferOptions;
1930 
1931   if ((hsmbus->XferSize == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_TX))
1932   {
1933     /* Call TxCpltCallback() directly if no stop mode is set */
1934     if (((CurrentXferOptions != SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions != SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC)) && \
1935         ((CurrentXferOptions != SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions != SMBUS_LAST_FRAME_WITH_PEC)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
1936     {
1937       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1938 
1939       hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
1940       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1941       hsmbus->State = HAL_SMBUS_STATE_READY;
1942 
1943 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1944       hsmbus->MasterTxCpltCallback(hsmbus);
1945 #else
1946       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1947 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1948     }
1949     else /* Generate Stop condition then Call TxCpltCallback() */
1950     {
1951       /* Disable EVT, BUF and ERR interrupt */
1952       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
1953 
1954       /* Generate Stop */
1955       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
1956 
1957       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1958       hsmbus->State = HAL_SMBUS_STATE_READY;
1959 
1960       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
1961 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1962       hsmbus->MasterTxCpltCallback(hsmbus);
1963 #else
1964       HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1965 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1966     }
1967   }
1968   else if ((CurrentState == HAL_SMBUS_STATE_BUSY_TX))
1969   {
1970 
1971     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)))
1972     {
1973       hsmbus->XferCount--;
1974     }
1975 
1976     if (hsmbus->XferCount == 0U)
1977     {
1978 
1979       /* Disable BUF interrupt */
1980       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
1981 
1982       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)))
1983       {
1984         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
1985       }
1986 
1987     }
1988     else
1989     {
1990       /* Write data to DR */
1991       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
1992       hsmbus->XferCount--;
1993     }
1994   }
1995   return HAL_OK;
1996 }
1997 
1998 /**
1999   * @brief  Handle BTF flag for Master transmitter
2000   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2001   *         the configuration information for SMBUS module
2002   * @retval HAL status
2003   */
SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef * hsmbus)2004 static HAL_StatusTypeDef SMBUS_MasterTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
2005 {
2006   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2007   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2008 
2009   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
2010   {
2011     if (hsmbus->XferCount != 0U)
2012     {
2013       /* Write data to DR */
2014       hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2015       hsmbus->XferCount--;
2016     }
2017     else
2018     {
2019       /* Call TxCpltCallback() directly if no stop mode is set */
2020       if (((CurrentXferOptions != SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions != SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC)) && ((CurrentXferOptions != SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions != SMBUS_LAST_FRAME_WITH_PEC)) && (CurrentXferOptions != SMBUS_NO_OPTION_FRAME))
2021       {
2022         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2023 
2024         hsmbus->PreviousState = SMBUS_STATE_MASTER_BUSY_TX;
2025         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2026         hsmbus->State = HAL_SMBUS_STATE_READY;
2027 
2028 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2029         hsmbus->MasterTxCpltCallback(hsmbus);
2030 #else
2031         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2032 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2033       }
2034       else /* Generate Stop condition then Call TxCpltCallback() */
2035       {
2036         /* Disable EVT, BUF and ERR interrupt */
2037         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2038 
2039         /* Generate Stop */
2040         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2041 
2042         hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2043         hsmbus->State = HAL_SMBUS_STATE_READY;
2044         hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2045 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2046         hsmbus->MasterTxCpltCallback(hsmbus);
2047 #else
2048         HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2049 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2050       }
2051     }
2052   }
2053   return HAL_OK;
2054 }
2055 
2056 /**
2057   * @brief  Handle RXNE flag for Master
2058   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2059   *         the configuration information for SMBUS module
2060   * @retval HAL status
2061   */
SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef * hsmbus)2062 static HAL_StatusTypeDef SMBUS_MasterReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
2063 {
2064   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2065   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2066 
2067   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
2068   {
2069     uint32_t tmp = hsmbus->XferCount;
2070 
2071     if (tmp > 3U)
2072     {
2073       /* Read data from DR */
2074       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2075       hsmbus->XferCount--;
2076 
2077       if (hsmbus->XferCount == 3)
2078       {
2079         /* Disable BUF interrupt, this help to treat correctly the last 4 bytes
2080         on BTF subroutine */
2081         /* Disable BUF interrupt */
2082         __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2083       }
2084     }
2085 
2086     else if (tmp == 2U)
2087     {
2088 
2089       /* Read data from DR */
2090       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2091       hsmbus->XferCount--;
2092 
2093       if ((CurrentXferOptions == SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || (CurrentXferOptions == SMBUS_LAST_FRAME_WITH_PEC))
2094       {
2095         /* PEC of slave */
2096         hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2097 
2098       }
2099       /* Generate Stop */
2100       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2101     }
2102 
2103     else if ((tmp == 1U) || (tmp == 0U))
2104     {
2105       /* Disable Acknowledge */
2106       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2107 
2108       /* Disable EVT, BUF and ERR interrupt */
2109       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2110 
2111       /* Read data from DR */
2112       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2113       hsmbus->XferCount--;
2114 
2115       hsmbus->State = HAL_SMBUS_STATE_READY;
2116       hsmbus->PreviousState = SMBUS_STATE_NONE;
2117       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2118 
2119 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2120       hsmbus->MasterRxCpltCallback(hsmbus);
2121 #else
2122       HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2123 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2124     }
2125   }
2126 
2127   return HAL_OK;
2128 }
2129 
2130 /**
2131   * @brief  Handle BTF flag for Master receiver
2132   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2133   *         the configuration information for SMBUS module
2134   * @retval HAL status
2135   */
SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef * hsmbus)2136 static HAL_StatusTypeDef SMBUS_MasterReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
2137 {
2138   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2139   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2140 
2141   if (hsmbus->XferCount == 4U)
2142   {
2143     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
2144        on BTF subroutine if there is a reception delay between N-1 and N byte */
2145     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2146 
2147     /* Read data from DR */
2148     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2149     hsmbus->XferCount--;
2150     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2151   }
2152   else if (hsmbus->XferCount == 3U)
2153   {
2154     /* Disable BUF interrupt, this help to treat correctly the last 2 bytes
2155        on BTF subroutine if there is a reception delay between N-1 and N byte */
2156     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2157 
2158     /* Disable Acknowledge */
2159     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2160 
2161     /* Read data from DR */
2162     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2163     hsmbus->XferCount--;
2164     hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2165   }
2166   else if (hsmbus->XferCount == 2U)
2167   {
2168     /* Prepare next transfer or stop current transfer */
2169     if ((CurrentXferOptions == SMBUS_NEXT_FRAME) || (CurrentXferOptions == SMBUS_FIRST_FRAME) || (CurrentXferOptions == SMBUS_LAST_FRAME_NO_PEC))
2170     {
2171       /* Disable Acknowledge */
2172       CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2173 
2174       /* Generate ReStart */
2175       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
2176     }
2177     else
2178     {
2179       /* Generate Stop */
2180       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2181     }
2182 
2183     /* Read data from DR */
2184     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2185     hsmbus->XferCount--;
2186 
2187     /* Read data from DR */
2188     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2189     hsmbus->XferCount--;
2190 
2191     /* Disable EVT and ERR interrupt */
2192     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_ERR);
2193 
2194     hsmbus->State = HAL_SMBUS_STATE_READY;
2195     hsmbus->PreviousState = SMBUS_STATE_NONE;
2196     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2197 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2198     hsmbus->MasterRxCpltCallback(hsmbus);
2199 #else
2200     HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2201 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2202   }
2203   else
2204   {
2205     /* Read data from DR */
2206     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2207     hsmbus->XferCount--;
2208   }
2209   return HAL_OK;
2210 }
2211 
2212 /**
2213   * @brief  Handle SB flag for Master
2214   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2215   *         the configuration information for SMBUS module
2216   * @retval HAL status
2217   */
SMBUS_Master_SB(SMBUS_HandleTypeDef * hsmbus)2218 static HAL_StatusTypeDef SMBUS_Master_SB(SMBUS_HandleTypeDef *hsmbus)
2219 {
2220   if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
2221   {
2222     /* Send slave 7 Bits address */
2223     if (hsmbus->State == HAL_SMBUS_STATE_BUSY_TX)
2224     {
2225       hsmbus->Instance->DR = SMBUS_7BIT_ADD_WRITE(hsmbus->Devaddress);
2226     }
2227     else
2228     {
2229       hsmbus->Instance->DR = SMBUS_7BIT_ADD_READ(hsmbus->Devaddress);
2230     }
2231   }
2232   else
2233   {
2234     if (hsmbus->EventCount == 0U)
2235     {
2236       /* Send header of slave address */
2237       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_WRITE(hsmbus->Devaddress);
2238     }
2239     else if (hsmbus->EventCount == 1U)
2240     {
2241       /* Send header of slave address */
2242       hsmbus->Instance->DR = SMBUS_10BIT_HEADER_READ(hsmbus->Devaddress);
2243     }
2244   }
2245   return HAL_OK;
2246 }
2247 
2248 /**
2249   * @brief  Handle ADD10 flag for Master
2250   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2251   *         the configuration information for SMBUS module
2252   * @retval HAL status
2253   */
SMBUS_Master_ADD10(SMBUS_HandleTypeDef * hsmbus)2254 static HAL_StatusTypeDef SMBUS_Master_ADD10(SMBUS_HandleTypeDef *hsmbus)
2255 {
2256   /* Send slave address */
2257   hsmbus->Instance->DR = SMBUS_10BIT_ADDRESS(hsmbus->Devaddress);
2258 
2259   return HAL_OK;
2260 }
2261 
2262 /**
2263   * @brief  Handle ADDR flag for Master
2264   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2265   *         the configuration information for SMBUS module
2266   * @retval HAL status
2267   */
SMBUS_Master_ADDR(SMBUS_HandleTypeDef * hsmbus)2268 static HAL_StatusTypeDef SMBUS_Master_ADDR(SMBUS_HandleTypeDef *hsmbus)
2269 {
2270   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2271   uint32_t CurrentMode        = hsmbus->Mode;
2272   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2273   uint32_t Prev_State         = hsmbus->PreviousState;
2274 
2275   if (hsmbus->State == HAL_SMBUS_STATE_BUSY_RX)
2276   {
2277     if ((hsmbus->EventCount == 0U) && (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT))
2278     {
2279       /* Clear ADDR flag */
2280       __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2281 
2282       /* Generate Restart */
2283       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_START);
2284 
2285       hsmbus->EventCount++;
2286     }
2287     else
2288     {
2289       /*  In the case of the Quick Command, the ADDR flag is cleared and a stop is generated */
2290       if (hsmbus->XferCount == 0U)
2291       {
2292         /* Clear ADDR flag */
2293         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2294 
2295         /* Generate Stop */
2296         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2297       }
2298       else if (hsmbus->XferCount == 1U)
2299       {
2300         /* Prepare next transfer or stop current transfer */
2301         if ((hsmbus->XferOptions == SMBUS_FIRST_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
2302         {
2303           /* Disable Acknowledge */
2304           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2305 
2306           /* Clear ADDR flag */
2307           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2308         }
2309         else if ((hsmbus->XferOptions == SMBUS_NEXT_FRAME) && (Prev_State != SMBUS_STATE_MASTER_BUSY_RX))
2310         {
2311           /* Enable Acknowledge */
2312           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2313 
2314           /* Clear ADDR flag */
2315           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2316         }
2317         else
2318         {
2319           /* Disable Acknowledge */
2320           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2321 
2322           /* Clear ADDR flag */
2323           __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2324 
2325           /* Generate Stop */
2326           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_STOP);
2327         }
2328       }
2329       else if (hsmbus->XferCount == 2U)
2330       {
2331         if (hsmbus->XferOptions != SMBUS_NEXT_FRAME)
2332         {
2333           /* Disable Acknowledge */
2334           CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2335 
2336           /* Enable Pos */
2337           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
2338 
2339 
2340         }
2341         else
2342         {
2343           /* Enable Acknowledge */
2344           SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2345         }
2346 
2347         /* Clear ADDR flag */
2348         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2349       }
2350       else
2351       {
2352         /* Enable Acknowledge */
2353         SET_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2354 
2355         /* Clear ADDR flag */
2356         __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2357       }
2358 
2359       /* Reset Event counter  */
2360       hsmbus->EventCount = 0U;
2361     }
2362   }
2363   else
2364   {
2365     /* Clear ADDR flag */
2366     __HAL_SMBUS_CLEAR_ADDRFLAG(hsmbus);
2367   }
2368 
2369   return HAL_OK;
2370 }
2371 
2372 /**
2373   * @brief  Handle TXE flag for Slave
2374   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2375   *         the configuration information for SMBUS module
2376   * @retval HAL status
2377   */
SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef * hsmbus)2378 static HAL_StatusTypeDef SMBUS_SlaveTransmit_TXE(SMBUS_HandleTypeDef *hsmbus)
2379 {
2380   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2381   uint32_t CurrentState = hsmbus->State;
2382 
2383   if (hsmbus->XferCount != 0U)
2384   {
2385     /* Write data to DR */
2386     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2387     hsmbus->XferCount--;
2388 
2389     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)))
2390     {
2391       hsmbus->XferCount--;
2392     }
2393 
2394     if ((hsmbus->XferCount == 0U) && (CurrentState == (HAL_SMBUS_STATE_BUSY_TX_LISTEN)))
2395     {
2396       /* Last Byte is received, disable Interrupt */
2397       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2398 
2399       /* Set state at HAL_SMBUS_STATE_LISTEN */
2400       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_TX;
2401       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2402 
2403       /* Call the corresponding callback to inform upper layer of End of Transfer */
2404 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2405       hsmbus->SlaveTxCpltCallback(hsmbus);
2406 #else
2407       HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
2408 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2409     }
2410   }
2411   return HAL_OK;
2412 }
2413 
2414 /**
2415   * @brief  Handle BTF flag for Slave transmitter
2416   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2417   *         the configuration information for SMBUS module
2418   * @retval HAL status
2419   */
SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef * hsmbus)2420 static HAL_StatusTypeDef SMBUS_SlaveTransmit_BTF(SMBUS_HandleTypeDef *hsmbus)
2421 {
2422   if (hsmbus->XferCount != 0U)
2423   {
2424     /* Write data to DR */
2425     hsmbus->Instance->DR = (*hsmbus->pBuffPtr++);
2426     hsmbus->XferCount--;
2427   }
2428 
2429 
2430 
2431   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)))
2432   {
2433     SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
2434   }
2435   return HAL_OK;
2436 }
2437 
2438 /**
2439   * @brief  Handle RXNE flag for Slave
2440   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2441   *         the configuration information for SMBUS module
2442   * @retval HAL status
2443   */
SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef * hsmbus)2444 static HAL_StatusTypeDef SMBUS_SlaveReceive_RXNE(SMBUS_HandleTypeDef *hsmbus)
2445 {
2446   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2447   uint32_t CurrentState = hsmbus->State;
2448 
2449   if (hsmbus->XferCount != 0U)
2450   {
2451     /* Read data from DR */
2452     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2453     hsmbus->XferCount--;
2454 
2455     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)))
2456     {
2457       SET_BIT(hsmbus->Instance->CR1, I2C_CR1_PEC);
2458       hsmbus->XferPEC = SMBUS_GET_PEC(hsmbus);
2459     }
2460     if ((hsmbus->XferCount == 0U) && (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
2461     {
2462       /* Last Byte is received, disable Interrupt */
2463       __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_BUF);
2464 
2465       /* Set state at HAL_SMBUS_STATE_LISTEN */
2466       hsmbus->PreviousState = SMBUS_STATE_SLAVE_BUSY_RX;
2467       hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2468 
2469       /* Call the corresponding callback to inform upper layer of End of Transfer */
2470 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2471       hsmbus->SlaveRxCpltCallback(hsmbus);
2472 #else
2473       HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
2474 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2475     }
2476   }
2477   return HAL_OK;
2478 }
2479 
2480 /**
2481   * @brief  Handle BTF flag for Slave receiver
2482   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2483   *         the configuration information for SMBUS module
2484   * @retval HAL status
2485   */
SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef * hsmbus)2486 static HAL_StatusTypeDef SMBUS_SlaveReceive_BTF(SMBUS_HandleTypeDef *hsmbus)
2487 {
2488   if (hsmbus->XferCount != 0U)
2489   {
2490     /* Read data from DR */
2491     (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2492     hsmbus->XferCount--;
2493   }
2494 
2495   return HAL_OK;
2496 }
2497 
2498 /**
2499   * @brief  Handle ADD flag for Slave
2500   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2501   *         the configuration information for SMBUS module
2502   * @retval HAL status
2503   */
SMBUS_Slave_ADDR(SMBUS_HandleTypeDef * hsmbus)2504 static HAL_StatusTypeDef SMBUS_Slave_ADDR(SMBUS_HandleTypeDef *hsmbus)
2505 {
2506   uint8_t TransferDirection = SMBUS_DIRECTION_RECEIVE ;
2507   uint16_t SlaveAddrCode = 0U;
2508 
2509   /* Transfer Direction requested by Master */
2510   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TRA) == RESET)
2511   {
2512     TransferDirection = SMBUS_DIRECTION_TRANSMIT;
2513   }
2514 
2515   if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_DUALF) == RESET)
2516   {
2517     SlaveAddrCode = hsmbus->Init.OwnAddress1;
2518   }
2519   else
2520   {
2521     SlaveAddrCode = hsmbus->Init.OwnAddress2;
2522   }
2523 
2524   /* Call Slave Addr callback */
2525 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2526   hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2527 #else
2528   HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2529 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2530 
2531   return HAL_OK;
2532 }
2533 
2534 /**
2535   * @brief  Handle STOPF flag for Slave
2536   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2537   *         the configuration information for SMBUS module
2538   * @retval HAL status
2539   */
SMBUS_Slave_STOPF(SMBUS_HandleTypeDef * hsmbus)2540 static HAL_StatusTypeDef SMBUS_Slave_STOPF(SMBUS_HandleTypeDef *hsmbus)
2541 {
2542   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2543   uint32_t CurrentState = hsmbus->State;
2544 
2545   /* Disable EVT, BUF and ERR interrupt */
2546   __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2547 
2548   /* Clear STOPF flag */
2549   __HAL_SMBUS_CLEAR_STOPFLAG(hsmbus);
2550 
2551   /* Disable Acknowledge */
2552   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2553 
2554   /* All data are not transferred, so set error code accordingly */
2555   if (hsmbus->XferCount != 0U)
2556   {
2557     /* Store Last receive data if any */
2558     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BTF) == SET)
2559     {
2560       /* Read data from DR */
2561       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2562 
2563       if (hsmbus->XferCount > 0)
2564       {
2565         hsmbus->XferSize--;
2566         hsmbus->XferCount--;
2567       }
2568     }
2569 
2570     /* Store Last receive data if any */
2571     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == 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 
2584   if (hsmbus->ErrorCode != HAL_SMBUS_ERROR_NONE)
2585   {
2586     /* Call the corresponding callback to inform upper layer of End of Transfer */
2587     SMBUS_ITError(hsmbus);
2588   }
2589   else
2590   {
2591     if ((CurrentState == HAL_SMBUS_STATE_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN)  || \
2592         (CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN))
2593     {
2594       hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2595       hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2596       hsmbus->State = HAL_SMBUS_STATE_READY;
2597       hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2598 
2599 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2600       hsmbus->ListenCpltCallback(hsmbus);
2601 #else
2602       HAL_SMBUS_ListenCpltCallback(hsmbus);
2603 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2604     }
2605   }
2606   return HAL_OK;
2607 }
2608 
2609 /**
2610   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2611   *         the configuration information for SMBUS module
2612   * @retval HAL status
2613   */
SMBUS_Slave_AF(SMBUS_HandleTypeDef * hsmbus)2614 static HAL_StatusTypeDef SMBUS_Slave_AF(SMBUS_HandleTypeDef *hsmbus)
2615 {
2616   /* Declaration of temporary variables to prevent undefined behavior of volatile usage */
2617   uint32_t CurrentState       = hsmbus->State;
2618   uint32_t CurrentXferOptions = hsmbus->XferOptions;
2619 
2620   if (((CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) || \
2621        (CurrentXferOptions == SMBUS_LAST_FRAME_NO_PEC) || (CurrentXferOptions ==  SMBUS_LAST_FRAME_WITH_PEC)) && \
2622       (CurrentState == HAL_SMBUS_STATE_LISTEN))
2623   {
2624     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2625 
2626     /* Disable EVT, BUF and ERR interrupt */
2627     __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_EVT | SMBUS_IT_BUF | SMBUS_IT_ERR);
2628 
2629     /* Clear AF flag */
2630     __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2631 
2632     /* Disable Acknowledge */
2633     CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_ACK);
2634 
2635     hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2636     hsmbus->State = HAL_SMBUS_STATE_READY;
2637     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2638 
2639     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2640 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2641     hsmbus->ListenCpltCallback(hsmbus);
2642 #else
2643     HAL_SMBUS_ListenCpltCallback(hsmbus);
2644 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2645   }
2646   return HAL_OK;
2647 }
2648 
2649 
2650 
2651 /**
2652   * @brief SMBUS interrupts error process
2653   * @param  hsmbus SMBUS handle.
2654   * @retval None
2655   */
SMBUS_ITError(SMBUS_HandleTypeDef * hsmbus)2656 static void SMBUS_ITError(SMBUS_HandleTypeDef *hsmbus)
2657 {
2658   /* Declaration of temporary variable to prevent undefined behavior of volatile usage */
2659   uint32_t CurrentState = hsmbus->State;
2660 
2661   if ((CurrentState == HAL_SMBUS_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_SMBUS_STATE_BUSY_RX_LISTEN))
2662   {
2663     /* keep HAL_SMBUS_STATE_LISTEN */
2664     hsmbus->PreviousState = SMBUS_STATE_NONE;
2665     hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2666   }
2667   else
2668   {
2669     /* If state is an abort treatment on going, don't change state */
2670     /* This change will be done later */
2671     if (hsmbus->State != HAL_SMBUS_STATE_ABORT)
2672     {
2673       hsmbus->State = HAL_SMBUS_STATE_READY;
2674     }
2675     hsmbus->PreviousState = SMBUS_STATE_NONE;
2676     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2677   }
2678 
2679   /* Disable Pos bit in SMBUS CR1 when error occurred in Master/Mem Receive IT Process */
2680   CLEAR_BIT(hsmbus->Instance->CR1, I2C_CR1_POS);
2681 
2682   if (hsmbus->State == HAL_SMBUS_STATE_ABORT)
2683   {
2684     hsmbus->State = HAL_SMBUS_STATE_READY;
2685     hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
2686 
2687     /* Store Last receive data if any */
2688     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
2689     {
2690       /* Read data from DR */
2691       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2692     }
2693 
2694     /* Disable SMBUS peripheral to prevent dummy data in buffer */
2695     __HAL_SMBUS_DISABLE(hsmbus);
2696 
2697     /* Call the corresponding callback to inform upper layer of End of Transfer */
2698 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2699     hsmbus->AbortCpltCallback(hsmbus);
2700 #else
2701     HAL_SMBUS_AbortCpltCallback(hsmbus);
2702 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2703   }
2704   else
2705   {
2706     /* Store Last receive data if any */
2707     if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) == SET)
2708     {
2709       /* Read data from DR */
2710       (*hsmbus->pBuffPtr++) = hsmbus->Instance->DR;
2711     }
2712 
2713     /* Call user error callback */
2714     HAL_SMBUS_ErrorCallback(hsmbus);
2715 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2716     hsmbus->ErrorCallback(hsmbus);
2717 #else
2718     HAL_SMBUS_ErrorCallback(hsmbus);
2719 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2720   }
2721   /* STOP Flag is not set after a NACK reception */
2722   /* So may inform upper layer that listen phase is stopped */
2723   /* during NACK error treatment */
2724   if ((hsmbus->State == HAL_SMBUS_STATE_LISTEN) && ((hsmbus->ErrorCode & HAL_SMBUS_ERROR_AF) == HAL_SMBUS_ERROR_AF))
2725   {
2726     hsmbus->XferOptions = SMBUS_NO_OPTION_FRAME;
2727     hsmbus->PreviousState = SMBUS_STATE_NONE;
2728     hsmbus->State = HAL_SMBUS_STATE_READY;
2729     hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2730 
2731     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2732 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2733     hsmbus->ListenCpltCallback(hsmbus);
2734 #else
2735     HAL_SMBUS_ListenCpltCallback(hsmbus);
2736 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2737   }
2738 }
2739 
2740 /**
2741   * @brief  This function handles SMBUS Communication Timeout.
2742   * @param  hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2743   *         the configuration information for SMBUS module
2744   * @param  Flag specifies the SMBUS flag to check.
2745   * @param  Status The new Flag status (SET or RESET).
2746   * @param  Timeout Timeout duration
2747   * @param  Tickstart Tick start value
2748   * @retval HAL status
2749   */
SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef * hsmbus,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)2750 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
2751 {
2752   /* Wait until flag is set */
2753   if (Status == RESET)
2754   {
2755     while (__HAL_SMBUS_GET_FLAG(hsmbus, Flag) == RESET)
2756     {
2757       /* Check for the Timeout */
2758       if (Timeout != HAL_MAX_DELAY)
2759       {
2760         if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
2761         {
2762           hsmbus->PreviousState = SMBUS_STATE_NONE;
2763           hsmbus->State = HAL_SMBUS_STATE_READY;
2764           hsmbus->Mode = HAL_SMBUS_MODE_NONE;
2765 
2766           /* Process Unlocked */
2767           __HAL_UNLOCK(hsmbus);
2768           return HAL_TIMEOUT;
2769         }
2770       }
2771     }
2772   }
2773   return HAL_OK;
2774 }
2775 
2776 /**
2777   * @}
2778   */
2779 
2780 
2781 #endif /* HAL_SMBUS_MODULE_ENABLED */
2782 
2783 /**
2784   * @}
2785   */
2786 
2787 /**
2788   * @}
2789   */
2790 
2791 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2792