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