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