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