Merge pull request #11189 from klutvott123/move-telemetry-displayport-init
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_hal_smbus.c
blobaf699a2ed84b75368e3e8e310c3c77177529e71b
1 /**
2 ******************************************************************************
3 * @file stm32g4xx_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 I2C principles of operation :
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral State and Errors functions
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 The SMBUS HAL driver can be used as follows:
20 (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
21 SMBUS_HandleTypeDef hsmbus;
23 (#)Initialize the SMBUS low level resources by implementing the @ref HAL_SMBUS_MspInit() API:
24 (##) Enable the SMBUSx interface clock
25 (##) SMBUS pins configuration
26 (+++) Enable the clock for the SMBUS GPIOs
27 (+++) Configure SMBUS pins as alternate function open-drain
28 (##) NVIC configuration if you need to use interrupt process
29 (+++) Configure the SMBUSx interrupt priority
30 (+++) Enable the NVIC SMBUS IRQ Channel
32 (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
33 Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
34 Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
36 (#) Initialize the SMBUS registers by calling the @ref HAL_SMBUS_Init() API:
37 (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
38 by calling the customized @ref HAL_SMBUS_MspInit(&hsmbus) API.
40 (#) To check if target device is ready for communication, use the function @ref HAL_SMBUS_IsDeviceReady()
42 (#) For SMBUS IO operations, only one mode of operations is available within this driver
44 *** Interrupt mode IO operation ***
45 ===================================
46 [..]
47 (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Master_Transmit_IT()
48 (++) At transmission end of transfer @ref HAL_SMBUS_MasterTxCpltCallback() is executed and user can
49 add his own code by customization of function pointer @ref HAL_SMBUS_MasterTxCpltCallback()
50 (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Master_Receive_IT()
51 (++) At reception end of transfer @ref HAL_SMBUS_MasterRxCpltCallback() is executed and user can
52 add his own code by customization of function pointer @ref HAL_SMBUS_MasterRxCpltCallback()
53 (+) Abort a master/host SMBUS process communication with Interrupt using @ref HAL_SMBUS_Master_Abort_IT()
54 (++) The associated previous transfer callback is called at the end of abort process
55 (++) mean @ref HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
56 (++) mean @ref HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
57 (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
58 using @ref HAL_SMBUS_EnableListen_IT() @ref HAL_SMBUS_DisableListen_IT()
59 (++) When address slave/device SMBUS match, @ref HAL_SMBUS_AddrCallback() is executed and user can
60 add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
61 (++) At Listen mode end @ref HAL_SMBUS_ListenCpltCallback() is executed and user can
62 add his own code by customization of function pointer @ref HAL_SMBUS_ListenCpltCallback()
63 (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Slave_Transmit_IT()
64 (++) At transmission end of transfer @ref HAL_SMBUS_SlaveTxCpltCallback() is executed and user can
65 add his own code by customization of function pointer @ref HAL_SMBUS_SlaveTxCpltCallback()
66 (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode using @ref HAL_SMBUS_Slave_Receive_IT()
67 (++) At reception end of transfer @ref HAL_SMBUS_SlaveRxCpltCallback() is executed and user can
68 add his own code by customization of function pointer @ref HAL_SMBUS_SlaveRxCpltCallback()
69 (+) Enable/Disable the SMBUS alert mode using @ref HAL_SMBUS_EnableAlert_IT() @ref HAL_SMBUS_DisableAlert_IT()
70 (++) When SMBUS Alert is generated @ref HAL_SMBUS_ErrorCallback() is executed and user can
71 add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
72 to check the Alert Error Code using function @ref HAL_SMBUS_GetError()
73 (+) Get HAL state machine or error values using @ref HAL_SMBUS_GetState() or @ref HAL_SMBUS_GetError()
74 (+) In case of transfer Error, @ref HAL_SMBUS_ErrorCallback() function is executed and user can
75 add his own code by customization of function pointer @ref HAL_SMBUS_ErrorCallback()
76 to check the Error Code using function @ref HAL_SMBUS_GetError()
78 *** SMBUS HAL driver macros list ***
79 ==================================
80 [..]
81 Below the list of most used macros in SMBUS HAL driver.
83 (+) @ref __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral
84 (+) @ref __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral
85 (+) @ref __HAL_SMBUS_GET_FLAG: Check whether the specified SMBUS flag is set or not
86 (+) @ref __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag
87 (+) @ref __HAL_SMBUS_ENABLE_IT: Enable the specified SMBUS interrupt
88 (+) @ref __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt
90 *** Callback registration ***
91 =============================================
93 The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
94 allows the user to configure dynamically the driver callbacks.
95 Use Functions @ref HAL_SMBUS_RegisterCallback() or @ref HAL_SMBUS_RegisterAddrCallback()
96 to register an interrupt callback.
98 Function @ref HAL_SMBUS_RegisterCallback() allows to register following callbacks:
99 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
100 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
101 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
102 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
103 (+) ListenCpltCallback : callback for end of listen mode.
104 (+) ErrorCallback : callback for error detection.
105 (+) MspInitCallback : callback for Msp Init.
106 (+) MspDeInitCallback : callback for Msp DeInit.
107 This function takes as parameters the HAL peripheral handle, the Callback ID
108 and a pointer to the user callback function.
110 For specific callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_RegisterAddrCallback.
112 Use function @ref HAL_SMBUS_UnRegisterCallback to reset a callback to the default
113 weak function.
114 @ref HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
115 and the Callback ID.
116 This function allows to reset following callbacks:
117 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
118 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
119 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
120 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
121 (+) ListenCpltCallback : callback for end of listen mode.
122 (+) ErrorCallback : callback for error detection.
123 (+) MspInitCallback : callback for Msp Init.
124 (+) MspDeInitCallback : callback for Msp DeInit.
126 For callback AddrCallback use dedicated register callbacks : @ref HAL_SMBUS_UnRegisterAddrCallback.
128 By default, after the @ref HAL_SMBUS_Init() and when the state is @ref HAL_I2C_STATE_RESET
129 all callbacks are set to the corresponding weak functions:
130 examples @ref HAL_SMBUS_MasterTxCpltCallback(), @ref HAL_SMBUS_MasterRxCpltCallback().
131 Exception done for MspInit and MspDeInit functions that are
132 reset to the legacy weak functions in the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit() only when
133 these callbacks are null (not registered beforehand).
134 If MspInit or MspDeInit are not null, the @ref HAL_SMBUS_Init()/ @ref HAL_SMBUS_DeInit()
135 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
137 Callbacks can be registered/unregistered in @ref HAL_I2C_STATE_READY state only.
138 Exception done MspInit/MspDeInit functions that can be registered/unregistered
139 in @ref HAL_I2C_STATE_READY or @ref HAL_I2C_STATE_RESET state,
140 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
141 Then, the user first registers the MspInit/MspDeInit user callbacks
142 using @ref HAL_SMBUS_RegisterCallback() before calling @ref HAL_SMBUS_DeInit()
143 or @ref HAL_SMBUS_Init() function.
145 When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
146 not defined, the callback registration feature is not available and all callbacks
147 are set to the corresponding weak functions.
149 [..]
150 (@) You can refer to the SMBUS HAL driver header file for more useful macros
152 @endverbatim
153 ******************************************************************************
154 * @attention
156 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
157 * All rights reserved.</center></h2>
159 * This software component is licensed by ST under BSD 3-Clause license,
160 * the "License"; You may not use this file except in compliance with the
161 * License. You may obtain a copy of the License at:
162 * opensource.org/licenses/BSD-3-Clause
164 ******************************************************************************
167 /* Includes ------------------------------------------------------------------*/
168 #include "stm32g4xx_hal.h"
170 /** @addtogroup STM32G4xx_HAL_Driver
171 * @{
174 /** @defgroup SMBUS SMBUS
175 * @brief SMBUS HAL module driver
176 * @{
179 #ifdef HAL_SMBUS_MODULE_ENABLED
181 /* Private typedef -----------------------------------------------------------*/
182 /* Private constants ---------------------------------------------------------*/
183 /** @defgroup SMBUS_Private_Define SMBUS Private Constants
184 * @{
186 #define TIMING_CLEAR_MASK (0xF0FFFFFFUL) /*!< SMBUS TIMING clear register Mask */
187 #define HAL_TIMEOUT_ADDR (10000U) /*!< 10 s */
188 #define HAL_TIMEOUT_BUSY (25U) /*!< 25 ms */
189 #define HAL_TIMEOUT_DIR (25U) /*!< 25 ms */
190 #define HAL_TIMEOUT_RXNE (25U) /*!< 25 ms */
191 #define HAL_TIMEOUT_STOPF (25U) /*!< 25 ms */
192 #define HAL_TIMEOUT_TC (25U) /*!< 25 ms */
193 #define HAL_TIMEOUT_TCR (25U) /*!< 25 ms */
194 #define HAL_TIMEOUT_TXIS (25U) /*!< 25 ms */
195 #define MAX_NBYTE_SIZE 255U
197 * @}
200 /* Private macro -------------------------------------------------------------*/
201 /* Private variables ---------------------------------------------------------*/
202 /* Private function prototypes -----------------------------------------------*/
203 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
204 * @{
206 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
208 static void SMBUS_Enable_IRQ(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);
209 static void SMBUS_Disable_IRQ(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);
210 static HAL_StatusTypeDef SMBUS_Master_ISR(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
211 static HAL_StatusTypeDef SMBUS_Slave_ISR(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
213 static void SMBUS_ConvertOtherXferOptions(struct __SMBUS_HandleTypeDef *hsmbus);
215 static void SMBUS_ITErrorHandler(struct __SMBUS_HandleTypeDef *hsmbus);
217 static void SMBUS_TransferConfig(struct __SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
219 * @}
222 /* Exported functions --------------------------------------------------------*/
224 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions
225 * @{
228 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
229 * @brief Initialization and Configuration functions
231 @verbatim
232 ===============================================================================
233 ##### Initialization and de-initialization functions #####
234 ===============================================================================
235 [..] This subsection provides a set of functions allowing to initialize and
236 deinitialize the SMBUSx peripheral:
238 (+) User must Implement HAL_SMBUS_MspInit() function in which he configures
239 all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
241 (+) Call the function HAL_SMBUS_Init() to configure the selected device with
242 the selected configuration:
243 (++) Clock Timing
244 (++) Bus Timeout
245 (++) Analog Filer mode
246 (++) Own Address 1
247 (++) Addressing mode (Master, Slave)
248 (++) Dual Addressing mode
249 (++) Own Address 2
250 (++) Own Address 2 Mask
251 (++) General call mode
252 (++) Nostretch mode
253 (++) Packet Error Check mode
254 (++) Peripheral mode
257 (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration
258 of the selected SMBUSx peripheral.
260 (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and
261 HAL_SMBUS_ConfigDigitalFilter().
263 @endverbatim
264 * @{
268 * @brief Initialize the SMBUS according to the specified parameters
269 * in the SMBUS_InitTypeDef and initialize the associated handle.
270 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
271 * the configuration information for the specified SMBUS.
272 * @retval HAL status
274 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus)
276 /* Check the SMBUS handle allocation */
277 if (hsmbus == NULL)
279 return HAL_ERROR;
282 /* Check the parameters */
283 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
284 assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter));
285 assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1));
286 assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode));
287 assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode));
288 assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2));
289 assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks));
290 assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode));
291 assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode));
292 assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode));
293 assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode));
295 if (hsmbus->State == HAL_SMBUS_STATE_RESET)
297 /* Allocate lock resource and initialize it */
298 hsmbus->Lock = HAL_UNLOCKED;
300 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
301 hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
302 hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
303 hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
304 hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
305 hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
306 hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
307 hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */
309 if (hsmbus->MspInitCallback == NULL)
311 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */
314 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
315 hsmbus->MspInitCallback(hsmbus);
316 #else
317 /* Init the low level hardware : GPIO, CLOCK, NVIC */
318 HAL_SMBUS_MspInit(hsmbus);
319 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
322 hsmbus->State = HAL_SMBUS_STATE_BUSY;
324 /* Disable the selected SMBUS peripheral */
325 __HAL_SMBUS_DISABLE(hsmbus);
327 /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/
328 /* Configure SMBUSx: Frequency range */
329 hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK;
331 /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/
332 /* Configure SMBUSx: Bus Timeout */
333 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN;
334 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN;
335 hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout;
337 /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/
338 /* Configure SMBUSx: Own Address1 and ack own address1 mode */
339 hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
341 if (hsmbus->Init.OwnAddress1 != 0UL)
343 if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT)
345 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1);
347 else /* SMBUS_ADDRESSINGMODE_10BIT */
349 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1);
353 /*---------------------------- SMBUSx CR2 Configuration ------------------------*/
354 /* Configure SMBUSx: Addressing Master mode */
355 if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT)
357 hsmbus->Instance->CR2 = (I2C_CR2_ADD10);
359 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
360 /* AUTOEND and NACK bit will be manage during Transfer process */
361 hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
363 /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/
364 /* Configure SMBUSx: Dual mode and Own Address2 */
365 hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | (hsmbus->Init.OwnAddress2Masks << 8U));
367 /*---------------------------- SMBUSx CR1 Configuration ------------------------*/
368 /* Configure SMBUSx: Generalcall and NoStretch mode */
369 hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | hsmbus->Init.AnalogFilter);
371 /* Enable Slave Byte Control only in case of Packet Error Check is enabled and SMBUS Peripheral is set in Slave mode */
372 if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE)
373 && ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP)))
375 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
378 /* Enable the selected SMBUS peripheral */
379 __HAL_SMBUS_ENABLE(hsmbus);
381 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
382 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
383 hsmbus->State = HAL_SMBUS_STATE_READY;
385 return HAL_OK;
389 * @brief DeInitialize 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
394 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus)
396 /* Check the SMBUS handle allocation */
397 if (hsmbus == NULL)
399 return HAL_ERROR;
402 /* Check the parameters */
403 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
405 hsmbus->State = HAL_SMBUS_STATE_BUSY;
407 /* Disable the SMBUS Peripheral Clock */
408 __HAL_SMBUS_DISABLE(hsmbus);
410 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
411 if (hsmbus->MspDeInitCallback == NULL)
413 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */
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 */
423 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
424 hsmbus->PreviousState = HAL_SMBUS_STATE_RESET;
425 hsmbus->State = HAL_SMBUS_STATE_RESET;
427 /* Release Lock */
428 __HAL_UNLOCK(hsmbus);
430 return HAL_OK;
434 * @brief Initialize the SMBUS MSP.
435 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
436 * the configuration information for the specified SMBUS.
437 * @retval None
439 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus)
441 /* Prevent unused argument(s) compilation warning */
442 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
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
455 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus)
457 /* Prevent unused argument(s) compilation warning */
458 UNUSED(hsmbus);
460 /* NOTE : This function should not be modified, when the callback is needed,
461 the HAL_SMBUS_MspDeInit could be implemented in the user file
466 * @brief Configure Analog noise filter.
467 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
468 * the configuration information for the specified SMBUS.
469 * @param AnalogFilter This parameter can be one of the following values:
470 * @arg @ref SMBUS_ANALOGFILTER_ENABLE
471 * @arg @ref SMBUS_ANALOGFILTER_DISABLE
472 * @retval HAL status
474 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter)
476 /* Check the parameters */
477 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
478 assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter));
480 if (hsmbus->State == HAL_SMBUS_STATE_READY)
482 /* Process Locked */
483 __HAL_LOCK(hsmbus);
485 hsmbus->State = HAL_SMBUS_STATE_BUSY;
487 /* Disable the selected SMBUS peripheral */
488 __HAL_SMBUS_DISABLE(hsmbus);
490 /* Reset ANOFF bit */
491 hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF);
493 /* Set analog filter bit*/
494 hsmbus->Instance->CR1 |= AnalogFilter;
496 __HAL_SMBUS_ENABLE(hsmbus);
498 hsmbus->State = HAL_SMBUS_STATE_READY;
500 /* Process Unlocked */
501 __HAL_UNLOCK(hsmbus);
503 return HAL_OK;
505 else
507 return HAL_BUSY;
512 * @brief Configure Digital noise filter.
513 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
514 * the configuration information for the specified SMBUS.
515 * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
516 * @retval HAL status
518 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter)
520 uint32_t tmpreg;
522 /* Check the parameters */
523 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
524 assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter));
526 if (hsmbus->State == HAL_SMBUS_STATE_READY)
528 /* Process Locked */
529 __HAL_LOCK(hsmbus);
531 hsmbus->State = HAL_SMBUS_STATE_BUSY;
533 /* Disable the selected SMBUS peripheral */
534 __HAL_SMBUS_DISABLE(hsmbus);
536 /* Get the old register value */
537 tmpreg = hsmbus->Instance->CR1;
539 /* Reset I2C DNF bits [11:8] */
540 tmpreg &= ~(I2C_CR1_DNF);
542 /* Set I2Cx DNF coefficient */
543 tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos;
545 /* Store the new register value */
546 hsmbus->Instance->CR1 = tmpreg;
548 __HAL_SMBUS_ENABLE(hsmbus);
550 hsmbus->State = HAL_SMBUS_STATE_READY;
552 /* Process Unlocked */
553 __HAL_UNLOCK(hsmbus);
555 return HAL_OK;
557 else
559 return HAL_BUSY;
563 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
565 * @brief Register a User SMBUS Callback
566 * To be used instead of the weak predefined callback
567 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
568 * the configuration information for the specified SMBUS.
569 * @param CallbackID ID of the callback to be registered
570 * This parameter can be one of the following values:
571 * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
572 * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
573 * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
574 * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
575 * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
576 * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
577 * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
578 * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
579 * @param pCallback pointer to the Callback function
580 * @retval HAL status
582 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID, pSMBUS_CallbackTypeDef pCallback)
584 HAL_StatusTypeDef status = HAL_OK;
586 if (pCallback == NULL)
588 /* Update the error code */
589 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
591 return HAL_ERROR;
594 /* Process locked */
595 __HAL_LOCK(hsmbus);
597 if (HAL_SMBUS_STATE_READY == hsmbus->State)
599 switch (CallbackID)
601 case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
602 hsmbus->MasterTxCpltCallback = pCallback;
603 break;
605 case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
606 hsmbus->MasterRxCpltCallback = pCallback;
607 break;
609 case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
610 hsmbus->SlaveTxCpltCallback = pCallback;
611 break;
613 case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
614 hsmbus->SlaveRxCpltCallback = pCallback;
615 break;
617 case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
618 hsmbus->ListenCpltCallback = pCallback;
619 break;
621 case HAL_SMBUS_ERROR_CB_ID :
622 hsmbus->ErrorCallback = pCallback;
623 break;
625 case HAL_SMBUS_MSPINIT_CB_ID :
626 hsmbus->MspInitCallback = pCallback;
627 break;
629 case HAL_SMBUS_MSPDEINIT_CB_ID :
630 hsmbus->MspDeInitCallback = pCallback;
631 break;
633 default :
634 /* Update the error code */
635 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
637 /* Return error status */
638 status = HAL_ERROR;
639 break;
642 else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
644 switch (CallbackID)
646 case HAL_SMBUS_MSPINIT_CB_ID :
647 hsmbus->MspInitCallback = pCallback;
648 break;
650 case HAL_SMBUS_MSPDEINIT_CB_ID :
651 hsmbus->MspDeInitCallback = pCallback;
652 break;
654 default :
655 /* Update the error code */
656 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
658 /* Return error status */
659 status = HAL_ERROR;
660 break;
663 else
665 /* Update the error code */
666 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
668 /* Return error status */
669 status = HAL_ERROR;
672 /* Release Lock */
673 __HAL_UNLOCK(hsmbus);
674 return status;
678 * @brief Unregister an SMBUS Callback
679 * SMBUS callback is redirected to the weak predefined callback
680 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
681 * the configuration information for the specified SMBUS.
682 * @param CallbackID ID of the callback to be unregistered
683 * This parameter can be one of the following values:
684 * This parameter can be one of the following values:
685 * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
686 * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
687 * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
688 * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
689 * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
690 * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID
691 * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID
692 * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
693 * @retval HAL status
695 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, HAL_SMBUS_CallbackIDTypeDef CallbackID)
697 HAL_StatusTypeDef status = HAL_OK;
699 /* Process locked */
700 __HAL_LOCK(hsmbus);
702 if (HAL_SMBUS_STATE_READY == hsmbus->State)
704 switch (CallbackID)
706 case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID :
707 hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
708 break;
710 case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID :
711 hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
712 break;
714 case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID :
715 hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
716 break;
718 case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID :
719 hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
720 break;
722 case HAL_SMBUS_LISTEN_COMPLETE_CB_ID :
723 hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
724 break;
726 case HAL_SMBUS_ERROR_CB_ID :
727 hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
728 break;
730 case HAL_SMBUS_MSPINIT_CB_ID :
731 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */
732 break;
734 case HAL_SMBUS_MSPDEINIT_CB_ID :
735 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */
736 break;
738 default :
739 /* Update the error code */
740 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
742 /* Return error status */
743 status = HAL_ERROR;
744 break;
747 else if (HAL_SMBUS_STATE_RESET == hsmbus->State)
749 switch (CallbackID)
751 case HAL_SMBUS_MSPINIT_CB_ID :
752 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */
753 break;
755 case HAL_SMBUS_MSPDEINIT_CB_ID :
756 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */
757 break;
759 default :
760 /* Update the error code */
761 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
763 /* Return error status */
764 status = HAL_ERROR;
765 break;
768 else
770 /* Update the error code */
771 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
773 /* Return error status */
774 status = HAL_ERROR;
777 /* Release Lock */
778 __HAL_UNLOCK(hsmbus);
779 return status;
783 * @brief Register the Slave Address Match SMBUS Callback
784 * To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback
785 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
786 * the configuration information for the specified SMBUS.
787 * @param pCallback pointer to the Address Match Callback function
788 * @retval HAL status
790 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, pSMBUS_AddrCallbackTypeDef pCallback)
792 HAL_StatusTypeDef status = HAL_OK;
794 if (pCallback == NULL)
796 /* Update the error code */
797 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
799 return HAL_ERROR;
801 /* Process locked */
802 __HAL_LOCK(hsmbus);
804 if (HAL_SMBUS_STATE_READY == hsmbus->State)
806 hsmbus->AddrCallback = pCallback;
808 else
810 /* Update the error code */
811 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
813 /* Return error status */
814 status = HAL_ERROR;
817 /* Release Lock */
818 __HAL_UNLOCK(hsmbus);
819 return status;
823 * @brief UnRegister the Slave Address Match SMBUS Callback
824 * Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback
825 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
826 * the configuration information for the specified SMBUS.
827 * @retval HAL status
829 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus)
831 HAL_StatusTypeDef status = HAL_OK;
833 /* Process locked */
834 __HAL_LOCK(hsmbus);
836 if (HAL_SMBUS_STATE_READY == hsmbus->State)
838 hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */
840 else
842 /* Update the error code */
843 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK;
845 /* Return error status */
846 status = HAL_ERROR;
849 /* Release Lock */
850 __HAL_UNLOCK(hsmbus);
851 return status;
854 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
857 * @}
860 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions
861 * @brief Data transfers functions
863 @verbatim
864 ===============================================================================
865 ##### IO operation functions #####
866 ===============================================================================
867 [..]
868 This subsection provides a set of functions allowing to manage the SMBUS data
869 transfers.
871 (#) Blocking mode function to check if device is ready for usage is :
872 (++) HAL_SMBUS_IsDeviceReady()
874 (#) There is only one mode of transfer:
875 (++) Non-Blocking mode : The communication is performed using Interrupts.
876 These functions return the status of the transfer startup.
877 The end of the data processing will be indicated through the
878 dedicated SMBUS IRQ when using Interrupt mode.
880 (#) Non-Blocking mode functions with Interrupt are :
881 (++) HAL_SMBUS_Master_Transmit_IT()
882 (++) HAL_SMBUS_Master_Receive_IT()
883 (++) HAL_SMBUS_Slave_Transmit_IT()
884 (++) HAL_SMBUS_Slave_Receive_IT()
885 (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT()
886 (++) HAL_SMBUS_DisableListen_IT()
887 (++) HAL_SMBUS_EnableAlert_IT()
888 (++) HAL_SMBUS_DisableAlert_IT()
890 (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
891 (++) HAL_SMBUS_MasterTxCpltCallback()
892 (++) HAL_SMBUS_MasterRxCpltCallback()
893 (++) HAL_SMBUS_SlaveTxCpltCallback()
894 (++) HAL_SMBUS_SlaveRxCpltCallback()
895 (++) HAL_SMBUS_AddrCallback()
896 (++) HAL_SMBUS_ListenCpltCallback()
897 (++) HAL_SMBUS_ErrorCallback()
899 @endverbatim
900 * @{
904 * @brief Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
905 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
906 * the configuration information for the specified SMBUS.
907 * @param DevAddress Target device address: The device 7 bits address value
908 * in datasheet must be shifted to the left before calling the interface
909 * @param pData Pointer to data buffer
910 * @param Size Amount of data to be sent
911 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
912 * @retval HAL status
914 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
916 uint32_t tmp;
918 /* Check the parameters */
919 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
921 if (hsmbus->State == HAL_SMBUS_STATE_READY)
923 /* Process Locked */
924 __HAL_LOCK(hsmbus);
926 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
927 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
928 /* Prepare transfer parameters */
929 hsmbus->pBuffPtr = pData;
930 hsmbus->XferCount = Size;
931 hsmbus->XferOptions = XferOptions;
933 /* In case of Quick command, remove autoend mode */
934 /* Manage the stop generation by software */
935 if (hsmbus->pBuffPtr == NULL)
937 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
940 if (Size > MAX_NBYTE_SIZE)
942 hsmbus->XferSize = MAX_NBYTE_SIZE;
944 else
946 hsmbus->XferSize = Size;
949 /* Send Slave Address */
950 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
951 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
953 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_WRITE);
955 else
957 /* If transfer direction not change, do not generate Restart Condition */
958 /* Mean Previous state is same as current state */
960 /* Store current volatile XferOptions, misra rule */
961 tmp = hsmbus->XferOptions;
963 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
965 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
967 /* Else transfer direction change, so generate Restart with new transfer direction */
968 else
970 /* Convert OTHER_xxx XferOptions if any */
971 SMBUS_ConvertOtherXferOptions(hsmbus);
973 /* Handle Transfer */
974 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_WRITE);
977 /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
978 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
979 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
981 hsmbus->XferSize--;
982 hsmbus->XferCount--;
986 /* Process Unlocked */
987 __HAL_UNLOCK(hsmbus);
989 /* Note : The SMBUS interrupts must be enabled after unlocking current process
990 to avoid the risk of SMBUS interrupt handle execution before current
991 process unlock */
992 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
994 return HAL_OK;
996 else
998 return HAL_BUSY;
1003 * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
1004 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1005 * the configuration information for the specified SMBUS.
1006 * @param DevAddress Target device address: The device 7 bits address value
1007 * in datasheet must be shifted to the left before calling the interface
1008 * @param pData Pointer to data buffer
1009 * @param Size Amount of data to be sent
1010 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1011 * @retval HAL status
1013 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1015 uint32_t tmp;
1017 /* Check the parameters */
1018 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1020 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1022 /* Process Locked */
1023 __HAL_LOCK(hsmbus);
1025 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1026 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1028 /* Prepare transfer parameters */
1029 hsmbus->pBuffPtr = pData;
1030 hsmbus->XferCount = Size;
1031 hsmbus->XferOptions = XferOptions;
1033 /* In case of Quick command, remove autoend mode */
1034 /* Manage the stop generation by software */
1035 if (hsmbus->pBuffPtr == NULL)
1037 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
1040 if (Size > MAX_NBYTE_SIZE)
1042 hsmbus->XferSize = MAX_NBYTE_SIZE;
1044 else
1046 hsmbus->XferSize = Size;
1049 /* Send Slave Address */
1050 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1051 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1053 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_GENERATE_START_READ);
1055 else
1057 /* If transfer direction not change, do not generate Restart Condition */
1058 /* Mean Previous state is same as current state */
1060 /* Store current volatile XferOptions, Misra rule */
1061 tmp = hsmbus->XferOptions;
1063 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
1065 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1067 /* Else transfer direction change, so generate Restart with new transfer direction */
1068 else
1070 /* Convert OTHER_xxx XferOptions if any */
1071 SMBUS_ConvertOtherXferOptions(hsmbus);
1073 /* Handle Transfer */
1074 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_GENERATE_START_READ);
1078 /* Process Unlocked */
1079 __HAL_UNLOCK(hsmbus);
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 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1086 return HAL_OK;
1088 else
1090 return HAL_BUSY;
1095 * @brief Abort a master/host SMBUS process communication with Interrupt.
1096 * @note This abort can be called only if state is ready
1097 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1098 * the configuration information for the specified SMBUS.
1099 * @param DevAddress Target device address: The device 7 bits address value
1100 * in datasheet must be shifted to the left before calling the interface
1101 * @retval HAL status
1103 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
1105 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1107 /* Process Locked */
1108 __HAL_LOCK(hsmbus);
1110 /* Keep the same state as previous */
1111 /* to perform as well the call of the corresponding end of transfer callback */
1112 if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1114 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
1116 else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1118 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1120 else
1122 /* Wrong usage of abort function */
1123 /* This function should be used only in case of abort monitored by master device */
1124 return HAL_ERROR;
1126 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1128 /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
1129 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
1130 SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
1132 /* Process Unlocked */
1133 __HAL_UNLOCK(hsmbus);
1135 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1136 to avoid the risk of SMBUS interrupt handle execution before current
1137 process unlock */
1138 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1140 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
1142 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1144 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1146 else
1148 /* Nothing to do */
1151 return HAL_OK;
1153 else
1155 return HAL_BUSY;
1160 * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1161 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1162 * the configuration information for the specified SMBUS.
1163 * @param pData Pointer to data buffer
1164 * @param Size Amount of data to be sent
1165 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1166 * @retval HAL status
1168 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1170 /* Check the parameters */
1171 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1173 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1175 if ((pData == NULL) || (Size == 0UL))
1177 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1178 return HAL_ERROR;
1181 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1182 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
1184 /* Process Locked */
1185 __HAL_LOCK(hsmbus);
1187 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN);
1188 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1190 /* Set SBC bit to manage Acknowledge at each bit */
1191 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1193 /* Enable Address Acknowledge */
1194 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1196 /* Prepare transfer parameters */
1197 hsmbus->pBuffPtr = pData;
1198 hsmbus->XferCount = Size;
1199 hsmbus->XferOptions = XferOptions;
1201 /* Convert OTHER_xxx XferOptions if any */
1202 SMBUS_ConvertOtherXferOptions(hsmbus);
1204 if (Size > MAX_NBYTE_SIZE)
1206 hsmbus->XferSize = MAX_NBYTE_SIZE;
1208 else
1210 hsmbus->XferSize = Size;
1213 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1214 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1216 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
1218 else
1220 /* Set NBYTE to transmit */
1221 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1223 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1224 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1225 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1227 hsmbus->XferSize--;
1228 hsmbus->XferCount--;
1232 /* Clear ADDR flag after prepare the transfer parameters */
1233 /* This action will generate an acknowledge to the HOST */
1234 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1236 /* Process Unlocked */
1237 __HAL_UNLOCK(hsmbus);
1239 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1240 to avoid the risk of SMBUS interrupt handle execution before current
1241 process unlock */
1242 /* REnable ADDR interrupt */
1243 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
1245 return HAL_OK;
1247 else
1249 return HAL_BUSY;
1254 * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1255 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1256 * the configuration information for the specified SMBUS.
1257 * @param pData Pointer to data buffer
1258 * @param Size Amount of data to be sent
1259 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1260 * @retval HAL status
1262 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
1264 /* Check the parameters */
1265 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1267 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1269 if ((pData == NULL) || (Size == 0UL))
1271 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1272 return HAL_ERROR;
1275 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1276 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
1278 /* Process Locked */
1279 __HAL_LOCK(hsmbus);
1281 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN);
1282 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1284 /* Set SBC bit to manage Acknowledge at each bit */
1285 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1287 /* Enable Address Acknowledge */
1288 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1290 /* Prepare transfer parameters */
1291 hsmbus->pBuffPtr = pData;
1292 hsmbus->XferSize = Size;
1293 hsmbus->XferCount = Size;
1294 hsmbus->XferOptions = XferOptions;
1296 /* Convert OTHER_xxx XferOptions if any */
1297 SMBUS_ConvertOtherXferOptions(hsmbus);
1299 /* Set NBYTE to receive */
1300 /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
1301 /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
1302 /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
1303 /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
1304 if (((SMBUS_GET_PEC_MODE(hsmbus) != 0UL) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U))
1306 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1308 else
1310 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
1313 /* Clear ADDR flag after prepare the transfer parameters */
1314 /* This action will generate an acknowledge to the HOST */
1315 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1317 /* Process Unlocked */
1318 __HAL_UNLOCK(hsmbus);
1320 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1321 to avoid the risk of SMBUS interrupt handle execution before current
1322 process unlock */
1323 /* REnable ADDR interrupt */
1324 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
1326 return HAL_OK;
1328 else
1330 return HAL_BUSY;
1335 * @brief Enable the Address listen mode with Interrupt.
1336 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1337 * the configuration information for the specified SMBUS.
1338 * @retval HAL status
1340 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1342 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1344 /* Enable the Address Match interrupt */
1345 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
1347 return HAL_OK;
1351 * @brief Disable the Address listen mode with Interrupt.
1352 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1353 * the configuration information for the specified SMBUS.
1354 * @retval HAL status
1356 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1358 /* Disable Address listen mode only if a transfer is not ongoing */
1359 if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1361 hsmbus->State = HAL_SMBUS_STATE_READY;
1363 /* Disable the Address Match interrupt */
1364 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1366 return HAL_OK;
1368 else
1370 return HAL_BUSY;
1375 * @brief Enable the SMBUS alert mode with Interrupt.
1376 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1377 * the configuration information for the specified SMBUSx peripheral.
1378 * @retval HAL status
1380 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1382 /* Enable SMBus alert */
1383 hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
1385 /* Clear ALERT flag */
1386 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1388 /* Enable Alert Interrupt */
1389 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
1391 return HAL_OK;
1394 * @brief Disable the SMBUS alert mode with Interrupt.
1395 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1396 * the configuration information for the specified SMBUSx peripheral.
1397 * @retval HAL status
1399 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1401 /* Enable SMBus alert */
1402 hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
1404 /* Disable Alert Interrupt */
1405 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
1407 return HAL_OK;
1411 * @brief Check if target device is ready for communication.
1412 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1413 * the configuration information for the specified SMBUS.
1414 * @param DevAddress Target device address: The device 7 bits address value
1415 * in datasheet must be shifted to the left before calling the interface
1416 * @param Trials Number of trials
1417 * @param Timeout Timeout duration
1418 * @retval HAL status
1420 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
1422 uint32_t tickstart;
1424 __IO uint32_t SMBUS_Trials = 0UL;
1426 FlagStatus tmp1;
1427 FlagStatus tmp2;
1429 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1431 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
1433 return HAL_BUSY;
1436 /* Process Locked */
1437 __HAL_LOCK(hsmbus);
1439 hsmbus->State = HAL_SMBUS_STATE_BUSY;
1440 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1444 /* Generate Start */
1445 hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress);
1447 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1448 /* Wait until STOPF flag is set or a NACK flag is set*/
1449 tickstart = HAL_GetTick();
1451 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1452 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1454 while ((tmp1 == RESET) && (tmp2 == RESET))
1456 if (Timeout != HAL_MAX_DELAY)
1458 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
1460 /* Device is ready */
1461 hsmbus->State = HAL_SMBUS_STATE_READY;
1463 /* Update SMBUS error code */
1464 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1466 /* Process Unlocked */
1467 __HAL_UNLOCK(hsmbus);
1468 return HAL_ERROR;
1472 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1473 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1476 /* Check if the NACKF flag has not been set */
1477 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
1479 /* Wait until STOPF flag is reset */
1480 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1482 return HAL_ERROR;
1485 /* Clear STOP Flag */
1486 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1488 /* Device is ready */
1489 hsmbus->State = HAL_SMBUS_STATE_READY;
1491 /* Process Unlocked */
1492 __HAL_UNLOCK(hsmbus);
1494 return HAL_OK;
1496 else
1498 /* Wait until STOPF flag is reset */
1499 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1501 return HAL_ERROR;
1504 /* Clear NACK Flag */
1505 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1507 /* Clear STOP Flag, auto generated with autoend*/
1508 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1511 /* Check if the maximum allowed number of trials has been reached */
1512 if (SMBUS_Trials == Trials)
1514 /* Generate Stop */
1515 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1517 /* Wait until STOPF flag is reset */
1518 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1520 return HAL_ERROR;
1523 /* Clear STOP Flag */
1524 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1527 /* Increment Trials */
1528 SMBUS_Trials++;
1530 while (SMBUS_Trials < Trials);
1532 hsmbus->State = HAL_SMBUS_STATE_READY;
1534 /* Update SMBUS error code */
1535 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1537 /* Process Unlocked */
1538 __HAL_UNLOCK(hsmbus);
1540 return HAL_ERROR;
1542 else
1544 return HAL_BUSY;
1548 * @}
1551 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1552 * @{
1556 * @brief Handle SMBUS event interrupt request.
1557 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1558 * the configuration information for the specified SMBUS.
1559 * @retval None
1561 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1563 /* Use a local variable to store the current ISR flags */
1564 /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1565 uint32_t tmpisrvalue = READ_REG(hsmbus->Instance->ISR);
1566 uint32_t tmpcr1value = READ_REG(hsmbus->Instance->CR1);
1568 /* SMBUS in mode Transmitter ---------------------------------------------------*/
1569 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) && ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1571 /* Slave mode selected */
1572 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1574 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1576 /* Master mode selected */
1577 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1579 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1581 else
1583 /* Nothing to do */
1587 /* SMBUS in mode Receiver ----------------------------------------------------*/
1588 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET) && ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1590 /* Slave mode selected */
1591 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1593 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1595 /* Master mode selected */
1596 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1598 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1600 else
1602 /* Nothing to do */
1606 /* SMBUS in mode Listener Only --------------------------------------------------*/
1607 if (((SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_ADDRI) != RESET) || (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_STOPI) != RESET) || (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_NACKI) != RESET)) && ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1609 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1611 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1617 * @brief Handle SMBUS error interrupt request.
1618 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1619 * the configuration information for the specified SMBUS.
1620 * @retval None
1622 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1624 SMBUS_ITErrorHandler(hsmbus);
1628 * @brief Master Tx Transfer completed callback.
1629 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1630 * the configuration information for the specified SMBUS.
1631 * @retval None
1633 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1635 /* Prevent unused argument(s) compilation warning */
1636 UNUSED(hsmbus);
1638 /* NOTE : This function should not be modified, when the callback is needed,
1639 the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
1644 * @brief Master Rx Transfer completed callback.
1645 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1646 * the configuration information for the specified SMBUS.
1647 * @retval None
1649 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1651 /* Prevent unused argument(s) compilation warning */
1652 UNUSED(hsmbus);
1654 /* NOTE : This function should not be modified, when the callback is needed,
1655 the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
1659 /** @brief Slave Tx Transfer completed callback.
1660 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1661 * the configuration information for the specified SMBUS.
1662 * @retval None
1664 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1666 /* Prevent unused argument(s) compilation warning */
1667 UNUSED(hsmbus);
1669 /* NOTE : This function should not be modified, when the callback is needed,
1670 the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
1675 * @brief Slave Rx Transfer completed callback.
1676 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1677 * the configuration information for the specified SMBUS.
1678 * @retval None
1680 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1682 /* Prevent unused argument(s) compilation warning */
1683 UNUSED(hsmbus);
1685 /* NOTE : This function should not be modified, when the callback is needed,
1686 the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
1691 * @brief Slave Address Match callback.
1692 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1693 * the configuration information for the specified SMBUS.
1694 * @param TransferDirection Master request Transfer Direction (Write/Read)
1695 * @param AddrMatchCode Address Match Code
1696 * @retval None
1698 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
1700 /* Prevent unused argument(s) compilation warning */
1701 UNUSED(hsmbus);
1702 UNUSED(TransferDirection);
1703 UNUSED(AddrMatchCode);
1705 /* NOTE : This function should not be modified, when the callback is needed,
1706 the HAL_SMBUS_AddrCallback() could be implemented in the user file
1711 * @brief Listen Complete callback.
1712 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1713 * the configuration information for the specified SMBUS.
1714 * @retval None
1716 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1718 /* Prevent unused argument(s) compilation warning */
1719 UNUSED(hsmbus);
1721 /* NOTE : This function should not be modified, when the callback is needed,
1722 the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
1727 * @brief SMBUS error callback.
1728 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1729 * the configuration information for the specified SMBUS.
1730 * @retval None
1732 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1734 /* Prevent unused argument(s) compilation warning */
1735 UNUSED(hsmbus);
1737 /* NOTE : This function should not be modified, when the callback is needed,
1738 the HAL_SMBUS_ErrorCallback() could be implemented in the user file
1743 * @}
1746 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1747 * @brief Peripheral State and Errors functions
1749 @verbatim
1750 ===============================================================================
1751 ##### Peripheral State and Errors functions #####
1752 ===============================================================================
1753 [..]
1754 This subsection permits to get in run-time the status of the peripheral
1755 and the data flow.
1757 @endverbatim
1758 * @{
1762 * @brief Return the SMBUS handle state.
1763 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1764 * the configuration information for the specified SMBUS.
1765 * @retval HAL state
1767 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus)
1769 /* Return SMBUS handle state */
1770 return hsmbus->State;
1774 * @brief Return the SMBUS error code.
1775 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1776 * the configuration information for the specified SMBUS.
1777 * @retval SMBUS Error Code
1779 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus)
1781 return hsmbus->ErrorCode;
1785 * @}
1789 * @}
1792 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1793 * @brief Data transfers Private functions
1794 * @{
1798 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
1799 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1800 * the configuration information for the specified SMBUS.
1801 * @param StatusFlags Value of Interrupt Flags.
1802 * @retval HAL status
1804 static HAL_StatusTypeDef SMBUS_Master_ISR(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
1806 uint16_t DevAddress;
1808 /* Process Locked */
1809 __HAL_LOCK(hsmbus);
1811 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
1813 /* Clear NACK Flag */
1814 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1816 /* Set corresponding Error Code */
1817 /* No need to generate STOP, it is automatically done */
1818 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1820 /* Process Unlocked */
1821 __HAL_UNLOCK(hsmbus);
1823 /* Call the Error callback to inform upper layer */
1824 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1825 hsmbus->ErrorCallback(hsmbus);
1826 #else
1827 HAL_SMBUS_ErrorCallback(hsmbus);
1828 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1830 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
1832 /* Check and treat errors if errors occurs during STOP process */
1833 SMBUS_ITErrorHandler(hsmbus);
1835 /* Call the corresponding callback to inform upper layer of End of Transfer */
1836 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1838 /* Disable Interrupt */
1839 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1841 /* Clear STOP Flag */
1842 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1844 /* Clear Configuration Register 2 */
1845 SMBUS_RESET_CR2(hsmbus);
1847 /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1848 /* Disable the selected SMBUS peripheral */
1849 __HAL_SMBUS_DISABLE(hsmbus);
1851 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1852 hsmbus->State = HAL_SMBUS_STATE_READY;
1854 /* Process Unlocked */
1855 __HAL_UNLOCK(hsmbus);
1857 /* REenable the selected SMBUS peripheral */
1858 __HAL_SMBUS_ENABLE(hsmbus);
1860 /* Call the corresponding callback to inform upper layer of End of Transfer */
1861 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1862 hsmbus->MasterTxCpltCallback(hsmbus);
1863 #else
1864 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1865 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1867 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1869 /* Store Last receive data if any */
1870 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
1872 /* Read data from RXDR */
1873 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
1875 /* Increment Buffer pointer */
1876 hsmbus->pBuffPtr++;
1878 if ((hsmbus->XferSize > 0U))
1880 hsmbus->XferSize--;
1881 hsmbus->XferCount--;
1885 /* Disable Interrupt */
1886 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1888 /* Clear STOP Flag */
1889 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1891 /* Clear Configuration Register 2 */
1892 SMBUS_RESET_CR2(hsmbus);
1894 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1895 hsmbus->State = HAL_SMBUS_STATE_READY;
1897 /* Process Unlocked */
1898 __HAL_UNLOCK(hsmbus);
1900 /* Call the corresponding callback to inform upper layer of End of Transfer */
1901 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1902 hsmbus->MasterRxCpltCallback(hsmbus);
1903 #else
1904 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1905 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1907 else
1909 /* Nothing to do */
1912 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
1914 /* Read data from RXDR */
1915 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
1917 /* Increment Buffer pointer */
1918 hsmbus->pBuffPtr++;
1920 /* Increment Size counter */
1921 hsmbus->XferSize--;
1922 hsmbus->XferCount--;
1924 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
1926 /* Write data to TXDR */
1927 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
1929 /* Increment Buffer pointer */
1930 hsmbus->pBuffPtr++;
1932 /* Increment Size counter */
1933 hsmbus->XferSize--;
1934 hsmbus->XferCount--;
1936 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET)
1938 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
1940 DevAddress = (uint16_t)(hsmbus->Instance->CR2 & I2C_CR2_SADD);
1942 if (hsmbus->XferCount > MAX_NBYTE_SIZE)
1944 SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
1945 hsmbus->XferSize = MAX_NBYTE_SIZE;
1947 else
1949 hsmbus->XferSize = hsmbus->XferCount;
1950 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
1951 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1952 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1953 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1955 hsmbus->XferSize--;
1956 hsmbus->XferCount--;
1960 else if ((hsmbus->XferCount == 0U) && (hsmbus->XferSize == 0U))
1962 /* Call TxCpltCallback() if no stop mode is set */
1963 if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
1965 /* Call the corresponding callback to inform upper layer of End of Transfer */
1966 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1968 /* Disable Interrupt */
1969 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1970 hsmbus->PreviousState = hsmbus->State;
1971 hsmbus->State = HAL_SMBUS_STATE_READY;
1973 /* Process Unlocked */
1974 __HAL_UNLOCK(hsmbus);
1976 /* Call the corresponding callback to inform upper layer of End of Transfer */
1977 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1978 hsmbus->MasterTxCpltCallback(hsmbus);
1979 #else
1980 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1981 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1983 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1985 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1986 hsmbus->PreviousState = hsmbus->State;
1987 hsmbus->State = HAL_SMBUS_STATE_READY;
1989 /* Process Unlocked */
1990 __HAL_UNLOCK(hsmbus);
1992 /* Call the corresponding callback to inform upper layer of End of Transfer */
1993 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1994 hsmbus->MasterRxCpltCallback(hsmbus);
1995 #else
1996 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1997 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1999 else
2001 /* Nothing to do */
2005 else
2007 /* Nothing to do */
2010 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TC) != RESET)
2012 if (hsmbus->XferCount == 0U)
2014 /* Specific use case for Quick command */
2015 if (hsmbus->pBuffPtr == NULL)
2017 /* Generate a Stop command */
2018 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
2020 /* Call TxCpltCallback() if no stop mode is set */
2021 else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
2023 /* No Generate Stop, to permit restart mode */
2024 /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
2026 /* Call the corresponding callback to inform upper layer of End of Transfer */
2027 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
2029 /* Disable Interrupt */
2030 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2031 hsmbus->PreviousState = hsmbus->State;
2032 hsmbus->State = HAL_SMBUS_STATE_READY;
2034 /* Process Unlocked */
2035 __HAL_UNLOCK(hsmbus);
2037 /* Call the corresponding callback to inform upper layer of End of Transfer */
2038 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2039 hsmbus->MasterTxCpltCallback(hsmbus);
2040 #else
2041 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2042 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2044 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
2046 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2047 hsmbus->PreviousState = hsmbus->State;
2048 hsmbus->State = HAL_SMBUS_STATE_READY;
2050 /* Process Unlocked */
2051 __HAL_UNLOCK(hsmbus);
2053 /* Call the corresponding callback to inform upper layer of End of Transfer */
2054 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2055 hsmbus->MasterRxCpltCallback(hsmbus);
2056 #else
2057 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2058 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2060 else
2062 /* Nothing to do */
2065 else
2067 /* Nothing to do */
2071 else
2073 /* Nothing to do */
2076 /* Process Unlocked */
2077 __HAL_UNLOCK(hsmbus);
2079 return HAL_OK;
2082 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
2083 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2084 * the configuration information for the specified SMBUS.
2085 * @param StatusFlags Value of Interrupt Flags.
2086 * @retval HAL status
2088 static HAL_StatusTypeDef SMBUS_Slave_ISR(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
2090 uint8_t TransferDirection;
2091 uint16_t SlaveAddrCode;
2093 /* Process Locked */
2094 __HAL_LOCK(hsmbus);
2096 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
2098 /* Check that SMBUS transfer finished */
2099 /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
2100 /* Mean XferCount == 0*/
2101 /* So clear Flag NACKF only */
2102 if (hsmbus->XferCount == 0U)
2104 /* Clear NACK Flag */
2105 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2107 /* Process Unlocked */
2108 __HAL_UNLOCK(hsmbus);
2110 else
2112 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
2113 /* Clear NACK Flag */
2114 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2116 /* Set HAL State to "Idle" State, mean to LISTEN state */
2117 /* So reset Slave Busy state */
2118 hsmbus->PreviousState = hsmbus->State;
2119 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2120 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2122 /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
2123 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2125 /* Set ErrorCode corresponding to a Non-Acknowledge */
2126 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
2128 /* Process Unlocked */
2129 __HAL_UNLOCK(hsmbus);
2131 /* Call the Error callback to inform upper layer */
2132 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2133 hsmbus->ErrorCallback(hsmbus);
2134 #else
2135 HAL_SMBUS_ErrorCallback(hsmbus);
2136 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2139 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_ADDR) != RESET)
2141 TransferDirection = (uint8_t)(SMBUS_GET_DIR(hsmbus));
2142 SlaveAddrCode = (uint16_t)(SMBUS_GET_ADDR_MATCH(hsmbus));
2144 /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
2145 /* Other ADDRInterrupt will be treat in next Listen usecase */
2146 __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
2148 /* Process Unlocked */
2149 __HAL_UNLOCK(hsmbus);
2151 /* Call Slave Addr callback */
2152 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2153 hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2154 #else
2155 HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2156 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2158 else if ((SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) || (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET))
2160 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
2162 /* Read data from RXDR */
2163 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2165 /* Increment Buffer pointer */
2166 hsmbus->pBuffPtr++;
2168 hsmbus->XferSize--;
2169 hsmbus->XferCount--;
2171 if (hsmbus->XferCount == 1U)
2173 /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
2174 /* or only the last Byte of Transfer */
2175 /* So reset the RELOAD bit mode */
2176 hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
2177 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
2179 else if (hsmbus->XferCount == 0U)
2181 /* Last Byte is received, disable Interrupt */
2182 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2184 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
2185 hsmbus->PreviousState = hsmbus->State;
2186 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2188 /* Process Unlocked */
2189 __HAL_UNLOCK(hsmbus);
2191 /* Call the corresponding callback to inform upper layer of End of Transfer */
2192 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2193 hsmbus->SlaveRxCpltCallback(hsmbus);
2194 #else
2195 HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
2196 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2198 else
2200 /* Set Reload for next Bytes */
2201 SMBUS_TransferConfig(hsmbus, 0, 1, SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), SMBUS_NO_STARTSTOP);
2203 /* Ack last Byte Read */
2204 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
2207 else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2209 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
2211 if (hsmbus->XferCount > MAX_NBYTE_SIZE)
2213 SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE, (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), SMBUS_NO_STARTSTOP);
2214 hsmbus->XferSize = MAX_NBYTE_SIZE;
2216 else
2218 hsmbus->XferSize = hsmbus->XferCount;
2219 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
2220 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2221 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2222 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
2224 hsmbus->XferSize--;
2225 hsmbus->XferCount--;
2230 else
2232 /* Nothing to do */
2235 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
2237 /* Write data to TXDR only if XferCount not reach "0" */
2238 /* A TXIS flag can be set, during STOP treatment */
2239 /* Check if all Data have already been sent */
2240 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
2241 if (hsmbus->XferCount > 0U)
2243 /* Write data to TXDR */
2244 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
2246 /* Increment Buffer pointer */
2247 hsmbus->pBuffPtr++;
2249 hsmbus->XferCount--;
2250 hsmbus->XferSize--;
2253 if (hsmbus->XferCount == 0U)
2255 /* Last Byte is Transmitted */
2256 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
2257 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2258 hsmbus->PreviousState = hsmbus->State;
2259 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2261 /* Process Unlocked */
2262 __HAL_UNLOCK(hsmbus);
2264 /* Call the corresponding callback to inform upper layer of End of Transfer */
2265 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2266 hsmbus->SlaveTxCpltCallback(hsmbus);
2267 #else
2268 HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
2269 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2272 else
2274 /* Nothing to do */
2277 /* Check if STOPF is set */
2278 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
2280 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
2282 /* Store Last receive data if any */
2283 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
2285 /* Read data from RXDR */
2286 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2288 /* Increment Buffer pointer */
2289 hsmbus->pBuffPtr++;
2291 if ((hsmbus->XferSize > 0U))
2293 hsmbus->XferSize--;
2294 hsmbus->XferCount--;
2298 /* Disable RX and TX Interrupts */
2299 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2301 /* Disable ADDR Interrupt */
2302 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
2304 /* Disable Address Acknowledge */
2305 hsmbus->Instance->CR2 |= I2C_CR2_NACK;
2307 /* Clear Configuration Register 2 */
2308 SMBUS_RESET_CR2(hsmbus);
2310 /* Clear STOP Flag */
2311 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
2313 /* Clear ADDR flag */
2314 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
2316 hsmbus->XferOptions = 0;
2317 hsmbus->PreviousState = hsmbus->State;
2318 hsmbus->State = HAL_SMBUS_STATE_READY;
2320 /* Process Unlocked */
2321 __HAL_UNLOCK(hsmbus);
2323 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2324 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2325 hsmbus->ListenCpltCallback(hsmbus);
2326 #else
2327 HAL_SMBUS_ListenCpltCallback(hsmbus);
2328 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2332 /* Process Unlocked */
2333 __HAL_UNLOCK(hsmbus);
2335 return HAL_OK;
2338 * @brief Manage the enabling of Interrupts.
2339 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2340 * the configuration information for the specified SMBUS.
2341 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2342 * @retval HAL status
2344 static void SMBUS_Enable_IRQ(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2346 uint32_t tmpisr = 0UL;
2348 if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
2350 /* Enable ERR interrupt */
2351 tmpisr |= SMBUS_IT_ERRI;
2354 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2356 /* Enable ADDR, STOP interrupt */
2357 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
2360 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2362 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2363 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
2366 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2368 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2369 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
2372 /* Enable interrupts only at the end */
2373 /* to avoid the risk of SMBUS interrupt handle execution before */
2374 /* all interrupts requested done */
2375 __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
2378 * @brief Manage the disabling of Interrupts.
2379 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2380 * the configuration information for the specified SMBUS.
2381 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2382 * @retval HAL status
2384 static void SMBUS_Disable_IRQ(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2386 uint32_t tmpisr = 0UL;
2387 uint32_t tmpstate = hsmbus->State;
2389 if ((tmpstate == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT))
2391 /* Disable ERR interrupt */
2392 tmpisr |= SMBUS_IT_ERRI;
2395 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2397 /* Disable TC, STOP, NACK and TXI interrupt */
2398 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
2400 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2401 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2403 /* Disable ERR interrupt */
2404 tmpisr |= SMBUS_IT_ERRI;
2407 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2409 /* Disable STOP and NACK interrupt */
2410 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2414 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2416 /* Disable TC, STOP, NACK and RXI interrupt */
2417 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
2419 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2420 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2422 /* Disable ERR interrupt */
2423 tmpisr |= SMBUS_IT_ERRI;
2426 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2428 /* Disable STOP and NACK interrupt */
2429 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2433 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2435 /* Disable ADDR, STOP and NACK interrupt */
2436 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2438 if (SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2440 /* Disable ERR interrupt */
2441 tmpisr |= SMBUS_IT_ERRI;
2445 /* Disable interrupts only at the end */
2446 /* to avoid a breaking situation like at "t" time */
2447 /* all disable interrupts request are not done */
2448 __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
2452 * @brief SMBUS interrupts error handler.
2453 * @param hsmbus SMBUS handle.
2454 * @retval None
2456 static void SMBUS_ITErrorHandler(struct __SMBUS_HandleTypeDef *hsmbus)
2458 uint32_t itflags = READ_REG(hsmbus->Instance->ISR);
2459 uint32_t itsources = READ_REG(hsmbus->Instance->CR1);
2460 uint32_t tmpstate;
2461 uint32_t tmperror;
2463 /* SMBUS Bus error interrupt occurred ------------------------------------*/
2464 if (((itflags & SMBUS_FLAG_BERR) == SMBUS_FLAG_BERR) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2466 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
2468 /* Clear BERR flag */
2469 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
2472 /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
2473 if (((itflags & SMBUS_FLAG_OVR) == SMBUS_FLAG_OVR) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2475 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
2477 /* Clear OVR flag */
2478 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
2481 /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
2482 if (((itflags & SMBUS_FLAG_ARLO) == SMBUS_FLAG_ARLO) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2484 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
2486 /* Clear ARLO flag */
2487 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
2490 /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
2491 if (((itflags & SMBUS_FLAG_TIMEOUT) == SMBUS_FLAG_TIMEOUT) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2493 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
2495 /* Clear TIMEOUT flag */
2496 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
2499 /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
2500 if (((itflags & SMBUS_FLAG_ALERT) == SMBUS_FLAG_ALERT) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2502 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
2504 /* Clear ALERT flag */
2505 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
2508 /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
2509 if (((itflags & SMBUS_FLAG_PECERR) == SMBUS_FLAG_PECERR) && ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2511 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
2513 /* Clear PEC error flag */
2514 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
2517 /* Store current volatile hsmbus->State, misra rule */
2518 tmperror = hsmbus->ErrorCode;
2520 /* Call the Error Callback in case of Error detected */
2521 if ((tmperror != HAL_SMBUS_ERROR_NONE) && (tmperror != HAL_SMBUS_ERROR_ACKF))
2523 /* Do not Reset the HAL state in case of ALERT error */
2524 if ((tmperror & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
2526 /* Store current volatile hsmbus->State, misra rule */
2527 tmpstate = hsmbus->State;
2529 if (((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2530 || ((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
2532 /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
2533 /* keep HAL_SMBUS_STATE_LISTEN if set */
2534 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2535 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2539 /* Call the Error callback to inform upper layer */
2540 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2541 hsmbus->ErrorCallback(hsmbus);
2542 #else
2543 HAL_SMBUS_ErrorCallback(hsmbus);
2544 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2549 * @brief Handle SMBUS Communication Timeout.
2550 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2551 * the configuration information for the specified SMBUS.
2552 * @param Flag Specifies the SMBUS flag to check.
2553 * @param Status The new Flag status (SET or RESET).
2554 * @param Timeout Timeout duration
2555 * @retval HAL status
2557 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(struct __SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
2559 uint32_t tickstart = HAL_GetTick();
2561 /* Wait until flag is set */
2562 while ((FlagStatus)(__HAL_SMBUS_GET_FLAG(hsmbus, Flag)) == Status)
2564 /* Check for the Timeout */
2565 if (Timeout != HAL_MAX_DELAY)
2567 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
2569 hsmbus->PreviousState = hsmbus->State;
2570 hsmbus->State = HAL_SMBUS_STATE_READY;
2572 /* Update SMBUS error code */
2573 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
2575 /* Process Unlocked */
2576 __HAL_UNLOCK(hsmbus);
2578 return HAL_ERROR;
2583 return HAL_OK;
2587 * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
2588 * @param hsmbus SMBUS handle.
2589 * @param DevAddress specifies the slave address to be programmed.
2590 * @param Size specifies the number of bytes to be programmed.
2591 * This parameter must be a value between 0 and 255.
2592 * @param Mode New state of the SMBUS START condition generation.
2593 * This parameter can be one or a combination of the following values:
2594 * @arg @ref SMBUS_RELOAD_MODE Enable Reload mode.
2595 * @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode.
2596 * @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
2597 * @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
2598 * @param Request New state of the SMBUS START condition generation.
2599 * This parameter can be one of the following values:
2600 * @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition.
2601 * @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
2602 * @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request.
2603 * @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request.
2604 * @retval None
2606 static void SMBUS_TransferConfig(struct __SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
2608 /* Check the parameters */
2609 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
2610 assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
2611 assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
2613 /* update CR2 register */
2614 MODIFY_REG(hsmbus->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \
2615 (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
2619 * @brief Convert SMBUSx OTHER_xxx XferOptions to functionnal XferOptions.
2620 * @param hsmbus SMBUS handle.
2621 * @retval None
2623 static void SMBUS_ConvertOtherXferOptions(struct __SMBUS_HandleTypeDef *hsmbus)
2625 /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */
2626 /* it request implicitly to generate a restart condition */
2627 /* set XferOptions to SMBUS_FIRST_FRAME */
2628 if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
2630 hsmbus->XferOptions = SMBUS_FIRST_FRAME;
2632 /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
2633 /* it request implicitly to generate a restart condition */
2634 /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */
2635 else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
2637 hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
2639 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
2640 /* it request implicitly to generate a restart condition */
2641 /* then generate a stop condition at the end of transfer */
2642 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */
2643 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
2645 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
2647 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
2648 /* it request implicitly to generate a restart condition */
2649 /* then generate a stop condition at the end of transfer */
2650 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */
2651 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
2653 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
2655 else
2657 /* Nothing to do */
2661 * @}
2664 #endif /* HAL_SMBUS_MODULE_ENABLED */
2666 * @}
2670 * @}
2673 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/