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>© 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