1 /**
2 ******************************************************************************
3 * @file stm32u5xx_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) 2021 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 "stm32u5xx_hal.h"
174
175 /** @addtogroup STM32U5xx_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 /* Check if the Autonomous mode is enabled */
957 if ((hsmbus->Instance->AUTOCR & I2C_AUTOCR_TRIGEN) == I2C_AUTOCR_TRIGEN)
958 {
959 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
960 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
961 SMBUS_GENERATE_NO_START_WRITE);
962 }
963 else
964 {
965 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
966 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
967 SMBUS_GENERATE_START_WRITE);
968 }
969 }
970 else
971 {
972 /* If transfer direction not change, do not generate Restart Condition */
973 /* Mean Previous state is same as current state */
974
975 /* Store current volatile XferOptions, misra rule */
976 tmp = hsmbus->XferOptions;
977
978 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && \
979 (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
980 {
981 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
982 SMBUS_NO_STARTSTOP);
983 }
984 /* Else transfer direction change, so generate Restart with new transfer direction */
985 else
986 {
987 /* Convert OTHER_xxx XferOptions if any */
988 SMBUS_ConvertOtherXferOptions(hsmbus);
989
990 /* Handle Transfer */
991 /* Check if the Autonomous mode is enabled */
992 if ((hsmbus->Instance->AUTOCR & I2C_AUTOCR_TRIGEN) == I2C_AUTOCR_TRIGEN)
993 {
994 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
995 hsmbus->XferOptions,
996 SMBUS_GENERATE_NO_START_WRITE);
997 }
998 else
999 {
1000 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1001 hsmbus->XferOptions,
1002 SMBUS_GENERATE_START_WRITE);
1003 }
1004 }
1005
1006 /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
1007 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1008 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1009 {
1010 hsmbus->XferSize--;
1011 hsmbus->XferCount--;
1012 }
1013 }
1014
1015 /* Process Unlocked */
1016 __HAL_UNLOCK(hsmbus);
1017
1018 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1019 to avoid the risk of SMBUS interrupt handle execution before current
1020 process unlock */
1021 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
1022
1023 return HAL_OK;
1024 }
1025 else
1026 {
1027 return HAL_BUSY;
1028 }
1029 }
1030
1031 /**
1032 * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt.
1033 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1034 * the configuration information for the specified SMBUS.
1035 * @param DevAddress Target device address: The device 7 bits address value
1036 * in datasheet must be shifted to the left before calling the interface
1037 * @param pData Pointer to data buffer
1038 * @param Size Amount of data to be sent
1039 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1040 * @retval HAL status
1041 */
HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1042 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData,
1043 uint16_t Size, uint32_t XferOptions)
1044 {
1045 uint32_t tmp;
1046
1047 /* Check the parameters */
1048 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1049
1050 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1051 {
1052 /* Process Locked */
1053 __HAL_LOCK(hsmbus);
1054
1055 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1056 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1057
1058 /* Prepare transfer parameters */
1059 hsmbus->pBuffPtr = pData;
1060 hsmbus->XferCount = Size;
1061 hsmbus->XferOptions = XferOptions;
1062
1063 /* In case of Quick command, remove autoend mode */
1064 /* Manage the stop generation by software */
1065 if (hsmbus->pBuffPtr == NULL)
1066 {
1067 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE;
1068 }
1069
1070 if (Size > MAX_NBYTE_SIZE)
1071 {
1072 hsmbus->XferSize = MAX_NBYTE_SIZE;
1073 }
1074 else
1075 {
1076 hsmbus->XferSize = Size;
1077 }
1078
1079 /* Send Slave Address */
1080 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1081 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1082 {
1083 /* Check if the Autonomous mode is enabled */
1084 if ((hsmbus->Instance->AUTOCR & I2C_AUTOCR_TRIGEN) == I2C_AUTOCR_TRIGEN)
1085 {
1086 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1087 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
1088 SMBUS_GENERATE_NO_START_READ);
1089 }
1090 else
1091 {
1092 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1093 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
1094 SMBUS_GENERATE_START_READ);
1095 }
1096 }
1097 else
1098 {
1099 /* If transfer direction not change, do not generate Restart Condition */
1100 /* Mean Previous state is same as current state */
1101
1102 /* Store current volatile XferOptions, Misra rule */
1103 tmp = hsmbus->XferOptions;
1104
1105 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && \
1106 (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
1107 {
1108 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1109 SMBUS_NO_STARTSTOP);
1110 }
1111 /* Else transfer direction change, so generate Restart with new transfer direction */
1112 else
1113 {
1114 /* Convert OTHER_xxx XferOptions if any */
1115 SMBUS_ConvertOtherXferOptions(hsmbus);
1116
1117 /* Handle Transfer */
1118 /* Check if the Autonomous mode is enabled */
1119 if ((hsmbus->Instance->AUTOCR & I2C_AUTOCR_TRIGEN) == I2C_AUTOCR_TRIGEN)
1120 {
1121 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1122 hsmbus->XferOptions,
1123 SMBUS_GENERATE_NO_START_READ);
1124 }
1125 else
1126 {
1127 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize,
1128 hsmbus->XferOptions,
1129 SMBUS_GENERATE_START_READ);
1130 }
1131 }
1132 }
1133
1134 /* Process Unlocked */
1135 __HAL_UNLOCK(hsmbus);
1136
1137 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1138 to avoid the risk of SMBUS interrupt handle execution before current
1139 process unlock */
1140 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1141
1142 return HAL_OK;
1143 }
1144 else
1145 {
1146 return HAL_BUSY;
1147 }
1148 }
1149
1150 /**
1151 * @brief Abort a master/host SMBUS process communication with Interrupt.
1152 * @note This abort can be called only if state is ready
1153 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1154 * the configuration information for the specified SMBUS.
1155 * @param DevAddress Target device address: The device 7 bits address value
1156 * in datasheet must be shifted to the left before calling the interface
1157 * @retval HAL status
1158 */
HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress)1159 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress)
1160 {
1161 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1162 {
1163 /* Process Locked */
1164 __HAL_LOCK(hsmbus);
1165
1166 /* Keep the same state as previous */
1167 /* to perform as well the call of the corresponding end of transfer callback */
1168 if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1169 {
1170 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX;
1171 }
1172 else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1173 {
1174 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX;
1175 }
1176 else
1177 {
1178 /* Wrong usage of abort function */
1179 /* This function should be used only in case of abort monitored by master device */
1180 return HAL_ERROR;
1181 }
1182 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1183
1184 /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */
1185 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
1186 SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP);
1187
1188 /* Process Unlocked */
1189 __HAL_UNLOCK(hsmbus);
1190
1191 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1192 to avoid the risk of SMBUS interrupt handle execution before current
1193 process unlock */
1194 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1195 {
1196 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX);
1197 }
1198 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1199 {
1200 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX);
1201 }
1202 else
1203 {
1204 /* Nothing to do */
1205 }
1206
1207 return HAL_OK;
1208 }
1209 else
1210 {
1211 return HAL_BUSY;
1212 }
1213 }
1214
1215 /**
1216 * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1217 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1218 * the configuration information for the specified SMBUS.
1219 * @param pData Pointer to data buffer
1220 * @param Size Amount of data to be sent
1221 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1222 * @retval HAL status
1223 */
HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1224 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size,
1225 uint32_t XferOptions)
1226 {
1227 /* Check the parameters */
1228 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1229
1230 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1231 {
1232 if ((pData == NULL) || (Size == 0UL))
1233 {
1234 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1235 return HAL_ERROR;
1236 }
1237
1238 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1239 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX);
1240
1241 /* Process Locked */
1242 __HAL_LOCK(hsmbus);
1243
1244 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN);
1245 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1246
1247 /* Set SBC bit to manage Acknowledge at each bit */
1248 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1249
1250 /* Enable Address Acknowledge */
1251 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1252
1253 /* Prepare transfer parameters */
1254 hsmbus->pBuffPtr = pData;
1255 hsmbus->XferCount = Size;
1256 hsmbus->XferOptions = XferOptions;
1257
1258 /* Convert OTHER_xxx XferOptions if any */
1259 SMBUS_ConvertOtherXferOptions(hsmbus);
1260
1261 if (Size > MAX_NBYTE_SIZE)
1262 {
1263 hsmbus->XferSize = MAX_NBYTE_SIZE;
1264 }
1265 else
1266 {
1267 hsmbus->XferSize = Size;
1268 }
1269
1270 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1271 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE))
1272 {
1273 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize,
1274 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
1275 SMBUS_NO_STARTSTOP);
1276 }
1277 else
1278 {
1279 /* Set NBYTE to transmit */
1280 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1281 SMBUS_NO_STARTSTOP);
1282
1283 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1284 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1285 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
1286 {
1287 hsmbus->XferSize--;
1288 hsmbus->XferCount--;
1289 }
1290 }
1291
1292 /* Clear ADDR flag after prepare the transfer parameters */
1293 /* This action will generate an acknowledge to the HOST */
1294 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1295
1296 /* Process Unlocked */
1297 __HAL_UNLOCK(hsmbus);
1298
1299 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1300 to avoid the risk of SMBUS interrupt handle execution before current
1301 process unlock */
1302 /* REnable ADDR interrupt */
1303 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR);
1304
1305 return HAL_OK;
1306 }
1307 else
1308 {
1309 return HAL_BUSY;
1310 }
1311 }
1312
1313 /**
1314 * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt.
1315 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1316 * the configuration information for the specified SMBUS.
1317 * @param pData Pointer to data buffer
1318 * @param Size Amount of data to be sent
1319 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition
1320 * @retval HAL status
1321 */
HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef * hsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1322 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size,
1323 uint32_t XferOptions)
1324 {
1325 /* Check the parameters */
1326 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1327
1328 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1329 {
1330 if ((pData == NULL) || (Size == 0UL))
1331 {
1332 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM;
1333 return HAL_ERROR;
1334 }
1335
1336 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1337 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX);
1338
1339 /* Process Locked */
1340 __HAL_LOCK(hsmbus);
1341
1342 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN);
1343 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1344
1345 /* Set SBC bit to manage Acknowledge at each bit */
1346 hsmbus->Instance->CR1 |= I2C_CR1_SBC;
1347
1348 /* Enable Address Acknowledge */
1349 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
1350
1351 /* Prepare transfer parameters */
1352 hsmbus->pBuffPtr = pData;
1353 hsmbus->XferSize = Size;
1354 hsmbus->XferCount = Size;
1355 hsmbus->XferOptions = XferOptions;
1356
1357 /* Convert OTHER_xxx XferOptions if any */
1358 SMBUS_ConvertOtherXferOptions(hsmbus);
1359
1360 /* Set NBYTE to receive */
1361 /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
1362 /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
1363 /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
1364 /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */
1365 if (((SMBUS_GET_PEC_MODE(hsmbus) != 0UL) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U))
1366 {
1367 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
1368 SMBUS_NO_STARTSTOP);
1369 }
1370 else
1371 {
1372 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP);
1373 }
1374
1375 /* Clear ADDR flag after prepare the transfer parameters */
1376 /* This action will generate an acknowledge to the HOST */
1377 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
1378
1379 /* Process Unlocked */
1380 __HAL_UNLOCK(hsmbus);
1381
1382 /* Note : The SMBUS interrupts must be enabled after unlocking current process
1383 to avoid the risk of SMBUS interrupt handle execution before current
1384 process unlock */
1385 /* REnable ADDR interrupt */
1386 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR);
1387
1388 return HAL_OK;
1389 }
1390 else
1391 {
1392 return HAL_BUSY;
1393 }
1394 }
1395
1396 /**
1397 * @brief Enable the Address listen mode with Interrupt.
1398 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1399 * the configuration information for the specified SMBUS.
1400 * @retval HAL status
1401 */
HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef * hsmbus)1402 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1403 {
1404 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
1405
1406 /* Enable the Address Match interrupt */
1407 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR);
1408
1409 return HAL_OK;
1410 }
1411
1412 /**
1413 * @brief Disable the Address listen mode with Interrupt.
1414 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1415 * the configuration information for the specified SMBUS.
1416 * @retval HAL status
1417 */
HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef * hsmbus)1418 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus)
1419 {
1420 /* Disable Address listen mode only if a transfer is not ongoing */
1421 if (hsmbus->State == HAL_SMBUS_STATE_LISTEN)
1422 {
1423 hsmbus->State = HAL_SMBUS_STATE_READY;
1424
1425 /* Disable the Address Match interrupt */
1426 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
1427
1428 return HAL_OK;
1429 }
1430 else
1431 {
1432 return HAL_BUSY;
1433 }
1434 }
1435
1436 /**
1437 * @brief Enable the SMBUS alert mode with Interrupt.
1438 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1439 * the configuration information for the specified SMBUSx peripheral.
1440 * @retval HAL status
1441 */
HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1442 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1443 {
1444 /* Enable SMBus alert */
1445 hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN;
1446
1447 /* Clear ALERT flag */
1448 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
1449
1450 /* Enable Alert Interrupt */
1451 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT);
1452
1453 return HAL_OK;
1454 }
1455 /**
1456 * @brief Disable the SMBUS alert mode with Interrupt.
1457 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1458 * the configuration information for the specified SMBUSx peripheral.
1459 * @retval HAL status
1460 */
HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef * hsmbus)1461 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus)
1462 {
1463 /* Enable SMBus alert */
1464 hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN;
1465
1466 /* Disable Alert Interrupt */
1467 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT);
1468
1469 return HAL_OK;
1470 }
1471
1472 /**
1473 * @brief Check if target device is ready for communication.
1474 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1475 * the configuration information for the specified SMBUS.
1476 * @param DevAddress Target device address: The device 7 bits address value
1477 * in datasheet must be shifted to the left before calling the interface
1478 * @param Trials Number of trials
1479 * @param Timeout Timeout duration
1480 * @retval HAL status
1481 */
HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)1482 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials,
1483 uint32_t Timeout)
1484 {
1485 uint32_t tickstart;
1486
1487 __IO uint32_t SMBUS_Trials = 0UL;
1488
1489 FlagStatus tmp1;
1490 FlagStatus tmp2;
1491
1492 if (hsmbus->State == HAL_SMBUS_STATE_READY)
1493 {
1494 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET)
1495 {
1496 return HAL_BUSY;
1497 }
1498
1499 /* Process Locked */
1500 __HAL_LOCK(hsmbus);
1501
1502 hsmbus->State = HAL_SMBUS_STATE_BUSY;
1503 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE;
1504
1505 do
1506 {
1507 /* Generate Start */
1508 hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress);
1509
1510 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1511 /* Wait until STOPF flag is set or a NACK flag is set*/
1512 tickstart = HAL_GetTick();
1513
1514 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1515 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1516
1517 while ((tmp1 == RESET) && (tmp2 == RESET))
1518 {
1519 if (Timeout != HAL_MAX_DELAY)
1520 {
1521 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
1522 {
1523 /* Device is ready */
1524 hsmbus->State = HAL_SMBUS_STATE_READY;
1525
1526 /* Update SMBUS error code */
1527 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1528
1529 /* Process Unlocked */
1530 __HAL_UNLOCK(hsmbus);
1531 return HAL_ERROR;
1532 }
1533 }
1534
1535 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1536 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF);
1537 }
1538
1539 /* Check if the NACKF flag has not been set */
1540 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET)
1541 {
1542 /* Wait until STOPF flag is reset */
1543 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1544 {
1545 return HAL_ERROR;
1546 }
1547
1548 /* Clear STOP Flag */
1549 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1550
1551 /* Device is ready */
1552 hsmbus->State = HAL_SMBUS_STATE_READY;
1553
1554 /* Process Unlocked */
1555 __HAL_UNLOCK(hsmbus);
1556
1557 return HAL_OK;
1558 }
1559 else
1560 {
1561 /* Wait until STOPF flag is reset */
1562 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1563 {
1564 return HAL_ERROR;
1565 }
1566
1567 /* Clear NACK Flag */
1568 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1569
1570 /* Clear STOP Flag, auto generated with autoend*/
1571 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1572 }
1573
1574 /* Check if the maximum allowed number of trials has been reached */
1575 if (SMBUS_Trials == Trials)
1576 {
1577 /* Generate Stop */
1578 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
1579
1580 /* Wait until STOPF flag is reset */
1581 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1582 {
1583 return HAL_ERROR;
1584 }
1585
1586 /* Clear STOP Flag */
1587 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1588 }
1589
1590 /* Increment Trials */
1591 SMBUS_Trials++;
1592 } while (SMBUS_Trials < Trials);
1593
1594 hsmbus->State = HAL_SMBUS_STATE_READY;
1595
1596 /* Update SMBUS error code */
1597 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
1598
1599 /* Process Unlocked */
1600 __HAL_UNLOCK(hsmbus);
1601
1602 return HAL_ERROR;
1603 }
1604 else
1605 {
1606 return HAL_BUSY;
1607 }
1608 }
1609 /**
1610 * @}
1611 */
1612
1613 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1614 * @{
1615 */
1616
1617 /**
1618 * @brief Handle SMBUS event interrupt request.
1619 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1620 * the configuration information for the specified SMBUS.
1621 * @retval None
1622 */
HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1623 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1624 {
1625 /* Use a local variable to store the current ISR flags */
1626 /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1627 uint32_t tmpisrvalue = READ_REG(hsmbus->Instance->ISR);
1628 uint32_t tmpcr1value = READ_REG(hsmbus->Instance->CR1);
1629
1630 /* SMBUS in mode Transmitter ---------------------------------------------------*/
1631 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI |
1632 SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) &&
1633 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) ||
1634 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) ||
1635 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) ||
1636 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1637 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1638 {
1639 /* Slave mode selected */
1640 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
1641 {
1642 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1643 }
1644 /* Master mode selected */
1645 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1646 {
1647 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1648 }
1649 else
1650 {
1651 /* Nothing to do */
1652 }
1653 }
1654
1655 /* SMBUS in mode Receiver ----------------------------------------------------*/
1656 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI |
1657 SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET) &&
1658 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) ||
1659 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) ||
1660 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) ||
1661 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1662 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1663 {
1664 /* Slave mode selected */
1665 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
1666 {
1667 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1668 }
1669 /* Master mode selected */
1670 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1671 {
1672 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue);
1673 }
1674 else
1675 {
1676 /* Nothing to do */
1677 }
1678 }
1679
1680 /* SMBUS in mode Listener Only --------------------------------------------------*/
1681 if (((SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_ADDRI) != RESET) ||
1682 (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_STOPI) != RESET) ||
1683 (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_NACKI) != RESET)) &&
1684 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) ||
1685 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
1686 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
1687 {
1688 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
1689 {
1690 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue);
1691 }
1692 }
1693 }
1694
1695 /**
1696 * @brief Handle SMBUS error interrupt request.
1697 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1698 * the configuration information for the specified SMBUS.
1699 * @retval None
1700 */
HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef * hsmbus)1701 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus)
1702 {
1703 SMBUS_ITErrorHandler(hsmbus);
1704 }
1705
1706 /**
1707 * @brief Master Tx Transfer completed callback.
1708 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1709 * the configuration information for the specified SMBUS.
1710 * @retval None
1711 */
HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1712 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1713 {
1714 /* Prevent unused argument(s) compilation warning */
1715 UNUSED(hsmbus);
1716
1717 /* NOTE : This function should not be modified, when the callback is needed,
1718 the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file
1719 */
1720 }
1721
1722 /**
1723 * @brief Master Rx Transfer completed callback.
1724 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1725 * the configuration information for the specified SMBUS.
1726 * @retval None
1727 */
HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1728 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1729 {
1730 /* Prevent unused argument(s) compilation warning */
1731 UNUSED(hsmbus);
1732
1733 /* NOTE : This function should not be modified, when the callback is needed,
1734 the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file
1735 */
1736 }
1737
1738 /** @brief Slave Tx Transfer completed callback.
1739 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1740 * the configuration information for the specified SMBUS.
1741 * @retval None
1742 */
HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1743 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1744 {
1745 /* Prevent unused argument(s) compilation warning */
1746 UNUSED(hsmbus);
1747
1748 /* NOTE : This function should not be modified, when the callback is needed,
1749 the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file
1750 */
1751 }
1752
1753 /**
1754 * @brief Slave Rx Transfer completed callback.
1755 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1756 * the configuration information for the specified SMBUS.
1757 * @retval None
1758 */
HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef * hsmbus)1759 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1760 {
1761 /* Prevent unused argument(s) compilation warning */
1762 UNUSED(hsmbus);
1763
1764 /* NOTE : This function should not be modified, when the callback is needed,
1765 the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file
1766 */
1767 }
1768
1769 /**
1770 * @brief Slave Address Match callback.
1771 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1772 * the configuration information for the specified SMBUS.
1773 * @param TransferDirection Master request Transfer Direction (Write/Read)
1774 * @param AddrMatchCode Address Match Code
1775 * @retval None
1776 */
HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef * hsmbus,uint8_t TransferDirection,uint16_t AddrMatchCode)1777 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection,
1778 uint16_t AddrMatchCode)
1779 {
1780 /* Prevent unused argument(s) compilation warning */
1781 UNUSED(hsmbus);
1782 UNUSED(TransferDirection);
1783 UNUSED(AddrMatchCode);
1784
1785 /* NOTE : This function should not be modified, when the callback is needed,
1786 the HAL_SMBUS_AddrCallback() could be implemented in the user file
1787 */
1788 }
1789
1790 /**
1791 * @brief Listen Complete callback.
1792 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1793 * the configuration information for the specified SMBUS.
1794 * @retval None
1795 */
HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef * hsmbus)1796 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus)
1797 {
1798 /* Prevent unused argument(s) compilation warning */
1799 UNUSED(hsmbus);
1800
1801 /* NOTE : This function should not be modified, when the callback is needed,
1802 the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file
1803 */
1804 }
1805
1806 /**
1807 * @brief SMBUS error callback.
1808 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1809 * the configuration information for the specified SMBUS.
1810 * @retval None
1811 */
HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef * hsmbus)1812 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
1813 {
1814 /* Prevent unused argument(s) compilation warning */
1815 UNUSED(hsmbus);
1816
1817 /* NOTE : This function should not be modified, when the callback is needed,
1818 the HAL_SMBUS_ErrorCallback() could be implemented in the user file
1819 */
1820 }
1821
1822 /**
1823 * @}
1824 */
1825
1826 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1827 * @brief Peripheral State and Errors functions
1828 *
1829 @verbatim
1830 ===============================================================================
1831 ##### Peripheral State and Errors functions #####
1832 ===============================================================================
1833 [..]
1834 This subsection permits to get in run-time the status of the peripheral
1835 and the data flow.
1836
1837 @endverbatim
1838 * @{
1839 */
1840
1841 /**
1842 * @brief Return the SMBUS handle state.
1843 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1844 * the configuration information for the specified SMBUS.
1845 * @retval HAL state
1846 */
HAL_SMBUS_GetState(const SMBUS_HandleTypeDef * hsmbus)1847 uint32_t HAL_SMBUS_GetState(const SMBUS_HandleTypeDef *hsmbus)
1848 {
1849 /* Return SMBUS handle state */
1850 return hsmbus->State;
1851 }
1852
1853 /**
1854 * @brief Return the SMBUS error code.
1855 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1856 * the configuration information for the specified SMBUS.
1857 * @retval SMBUS Error Code
1858 */
HAL_SMBUS_GetError(const SMBUS_HandleTypeDef * hsmbus)1859 uint32_t HAL_SMBUS_GetError(const SMBUS_HandleTypeDef *hsmbus)
1860 {
1861 return hsmbus->ErrorCode;
1862 }
1863
1864 /**
1865 * @}
1866 */
1867
1868 /**
1869 * @}
1870 */
1871
1872 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
1873 * @brief Data transfers Private functions
1874 * @{
1875 */
1876
1877 /**
1878 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
1879 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
1880 * the configuration information for the specified SMBUS.
1881 * @param StatusFlags Value of Interrupt Flags.
1882 * @retval HAL status
1883 */
SMBUS_Master_ISR(SMBUS_HandleTypeDef * hsmbus,uint32_t StatusFlags)1884 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
1885 {
1886 uint16_t DevAddress;
1887
1888 /* Process Locked */
1889 __HAL_LOCK(hsmbus);
1890
1891 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
1892 {
1893 /* Clear NACK Flag */
1894 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
1895
1896 /* Set corresponding Error Code */
1897 /* No need to generate STOP, it is automatically done */
1898 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
1899
1900 /* Flush TX register */
1901 SMBUS_Flush_TXDR(hsmbus);
1902
1903 /* Process Unlocked */
1904 __HAL_UNLOCK(hsmbus);
1905
1906 /* Call the Error callback to inform upper layer */
1907 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1908 hsmbus->ErrorCallback(hsmbus);
1909 #else
1910 HAL_SMBUS_ErrorCallback(hsmbus);
1911 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1912 }
1913 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
1914 {
1915 /* Check and treat errors if errors occurs during STOP process */
1916 SMBUS_ITErrorHandler(hsmbus);
1917
1918 /* Call the corresponding callback to inform upper layer of End of Transfer */
1919 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
1920 {
1921 /* Disable Interrupt */
1922 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
1923
1924 /* Clear STOP Flag */
1925 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1926
1927 /* Clear Configuration Register 2 */
1928 SMBUS_RESET_CR2(hsmbus);
1929
1930 /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1931 /* Disable the selected SMBUS peripheral */
1932 __HAL_SMBUS_DISABLE(hsmbus);
1933
1934 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1935 hsmbus->State = HAL_SMBUS_STATE_READY;
1936
1937 /* Process Unlocked */
1938 __HAL_UNLOCK(hsmbus);
1939
1940 /* Re-enable the selected SMBUS peripheral */
1941 __HAL_SMBUS_ENABLE(hsmbus);
1942
1943 /* Call the corresponding callback to inform upper layer of End of Transfer */
1944 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1945 hsmbus->MasterTxCpltCallback(hsmbus);
1946 #else
1947 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
1948 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1949 }
1950 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
1951 {
1952 /* Store Last receive data if any */
1953 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
1954 {
1955 /* Read data from RXDR */
1956 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
1957
1958 /* Increment Buffer pointer */
1959 hsmbus->pBuffPtr++;
1960
1961 if ((hsmbus->XferSize > 0U))
1962 {
1963 hsmbus->XferSize--;
1964 hsmbus->XferCount--;
1965 }
1966 }
1967
1968 /* Disable Interrupt */
1969 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
1970
1971 /* Clear STOP Flag */
1972 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
1973
1974 /* Clear Configuration Register 2 */
1975 SMBUS_RESET_CR2(hsmbus);
1976
1977 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
1978 hsmbus->State = HAL_SMBUS_STATE_READY;
1979
1980 /* Process Unlocked */
1981 __HAL_UNLOCK(hsmbus);
1982
1983 /* Call the corresponding callback to inform upper layer of End of Transfer */
1984 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
1985 hsmbus->MasterRxCpltCallback(hsmbus);
1986 #else
1987 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
1988 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
1989 }
1990 else
1991 {
1992 /* Nothing to do */
1993 }
1994 }
1995 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET)
1996 {
1997 /* Read data from RXDR */
1998 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
1999
2000 /* Increment Buffer pointer */
2001 hsmbus->pBuffPtr++;
2002
2003 /* Increment Size counter */
2004 hsmbus->XferSize--;
2005 hsmbus->XferCount--;
2006 }
2007 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
2008 {
2009 /* Write data to TXDR */
2010 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
2011
2012 /* Increment Buffer pointer */
2013 hsmbus->pBuffPtr++;
2014
2015 /* Increment Size counter */
2016 hsmbus->XferSize--;
2017 hsmbus->XferCount--;
2018 }
2019 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET)
2020 {
2021 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
2022 {
2023 DevAddress = (uint16_t)(hsmbus->Instance->CR2 & I2C_CR2_SADD);
2024
2025 if (hsmbus->XferCount > MAX_NBYTE_SIZE)
2026 {
2027 SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE,
2028 (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)),
2029 SMBUS_NO_STARTSTOP);
2030 hsmbus->XferSize = MAX_NBYTE_SIZE;
2031 }
2032 else
2033 {
2034 hsmbus->XferSize = hsmbus->XferCount;
2035 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
2036 SMBUS_NO_STARTSTOP);
2037 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2038 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2039 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
2040 {
2041 hsmbus->XferSize--;
2042 hsmbus->XferCount--;
2043 }
2044 }
2045 }
2046 else if ((hsmbus->XferCount == 0U) && (hsmbus->XferSize == 0U))
2047 {
2048 /* Call TxCpltCallback() if no stop mode is set */
2049 if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
2050 {
2051 /* Call the corresponding callback to inform upper layer of End of Transfer */
2052 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
2053 {
2054 /* Disable Interrupt */
2055 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2056 hsmbus->PreviousState = hsmbus->State;
2057 hsmbus->State = HAL_SMBUS_STATE_READY;
2058
2059 /* Process Unlocked */
2060 __HAL_UNLOCK(hsmbus);
2061
2062 /* Call the corresponding callback to inform upper layer of End of Transfer */
2063 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2064 hsmbus->MasterTxCpltCallback(hsmbus);
2065 #else
2066 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2067 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2068 }
2069 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
2070 {
2071 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2072 hsmbus->PreviousState = hsmbus->State;
2073 hsmbus->State = HAL_SMBUS_STATE_READY;
2074
2075 /* Process Unlocked */
2076 __HAL_UNLOCK(hsmbus);
2077
2078 /* Call the corresponding callback to inform upper layer of End of Transfer */
2079 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2080 hsmbus->MasterRxCpltCallback(hsmbus);
2081 #else
2082 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2083 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2084 }
2085 else
2086 {
2087 /* Nothing to do */
2088 }
2089 }
2090 }
2091 else
2092 {
2093 /* Nothing to do */
2094 }
2095 }
2096 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TC) != RESET)
2097 {
2098 if (hsmbus->XferCount == 0U)
2099 {
2100 /* Specific use case for Quick command */
2101 if (hsmbus->pBuffPtr == NULL)
2102 {
2103 /* Generate a Stop command */
2104 hsmbus->Instance->CR2 |= I2C_CR2_STOP;
2105 }
2106 /* Call TxCpltCallback() if no stop mode is set */
2107 else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE)
2108 {
2109 /* No Generate Stop, to permit restart mode */
2110 /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */
2111
2112 /* Call the corresponding callback to inform upper layer of End of Transfer */
2113 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX)
2114 {
2115 /* Disable Interrupt */
2116 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2117 hsmbus->PreviousState = hsmbus->State;
2118 hsmbus->State = HAL_SMBUS_STATE_READY;
2119
2120 /* Process Unlocked */
2121 __HAL_UNLOCK(hsmbus);
2122
2123 /* Call the corresponding callback to inform upper layer of End of Transfer */
2124 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2125 hsmbus->MasterTxCpltCallback(hsmbus);
2126 #else
2127 HAL_SMBUS_MasterTxCpltCallback(hsmbus);
2128 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2129 }
2130 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX)
2131 {
2132 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2133 hsmbus->PreviousState = hsmbus->State;
2134 hsmbus->State = HAL_SMBUS_STATE_READY;
2135
2136 /* Process Unlocked */
2137 __HAL_UNLOCK(hsmbus);
2138
2139 /* Call the corresponding callback to inform upper layer of End of Transfer */
2140 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2141 hsmbus->MasterRxCpltCallback(hsmbus);
2142 #else
2143 HAL_SMBUS_MasterRxCpltCallback(hsmbus);
2144 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2145 }
2146 else
2147 {
2148 /* Nothing to do */
2149 }
2150 }
2151 else
2152 {
2153 /* Nothing to do */
2154 }
2155 }
2156 }
2157 else
2158 {
2159 /* Nothing to do */
2160 }
2161
2162 /* Process Unlocked */
2163 __HAL_UNLOCK(hsmbus);
2164
2165 return HAL_OK;
2166 }
2167 /**
2168 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
2169 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2170 * the configuration information for the specified SMBUS.
2171 * @param StatusFlags Value of Interrupt Flags.
2172 * @retval HAL status
2173 */
SMBUS_Slave_ISR(SMBUS_HandleTypeDef * hsmbus,uint32_t StatusFlags)2174 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags)
2175 {
2176 uint8_t TransferDirection;
2177 uint16_t SlaveAddrCode;
2178
2179 /* Process Locked */
2180 __HAL_LOCK(hsmbus);
2181
2182 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET)
2183 {
2184 /* Check that SMBUS transfer finished */
2185 /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
2186 /* Mean XferCount == 0*/
2187 /* So clear Flag NACKF only */
2188 if (hsmbus->XferCount == 0U)
2189 {
2190 /* Clear NACK Flag */
2191 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2192
2193 /* Flush TX register */
2194 SMBUS_Flush_TXDR(hsmbus);
2195
2196 /* Process Unlocked */
2197 __HAL_UNLOCK(hsmbus);
2198 }
2199 else
2200 {
2201 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
2202 /* Clear NACK Flag */
2203 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF);
2204
2205 /* Set HAL State to "Idle" State, mean to LISTEN state */
2206 /* So reset Slave Busy state */
2207 hsmbus->PreviousState = hsmbus->State;
2208 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2209 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2210
2211 /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
2212 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2213
2214 /* Set ErrorCode corresponding to a Non-Acknowledge */
2215 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF;
2216
2217 /* Flush TX register */
2218 SMBUS_Flush_TXDR(hsmbus);
2219
2220 /* Process Unlocked */
2221 __HAL_UNLOCK(hsmbus);
2222
2223 /* Call the Error callback to inform upper layer */
2224 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2225 hsmbus->ErrorCallback(hsmbus);
2226 #else
2227 HAL_SMBUS_ErrorCallback(hsmbus);
2228 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2229 }
2230 }
2231 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_ADDR) != RESET)
2232 {
2233 TransferDirection = (uint8_t)(SMBUS_GET_DIR(hsmbus));
2234 SlaveAddrCode = (uint16_t)(SMBUS_GET_ADDR_MATCH(hsmbus));
2235
2236 /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
2237 /* Other ADDRInterrupt will be treat in next Listen usecase */
2238 __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI);
2239
2240 /* Process Unlocked */
2241 __HAL_UNLOCK(hsmbus);
2242
2243 /* Call Slave Addr callback */
2244 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2245 hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2246 #else
2247 HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode);
2248 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2249 }
2250 else if ((SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) ||
2251 (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET))
2252 {
2253 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)
2254 {
2255 /* Read data from RXDR */
2256 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2257
2258 /* Increment Buffer pointer */
2259 hsmbus->pBuffPtr++;
2260
2261 hsmbus->XferSize--;
2262 hsmbus->XferCount--;
2263
2264 if (hsmbus->XferCount == 1U)
2265 {
2266 /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
2267 /* or only the last Byte of Transfer */
2268 /* So reset the RELOAD bit mode */
2269 hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE;
2270 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions, SMBUS_NO_STARTSTOP);
2271 }
2272 else if (hsmbus->XferCount == 0U)
2273 {
2274 /* Last Byte is received, disable Interrupt */
2275 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX);
2276
2277 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */
2278 hsmbus->PreviousState = hsmbus->State;
2279 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX);
2280
2281 /* Process Unlocked */
2282 __HAL_UNLOCK(hsmbus);
2283
2284 /* Call the corresponding callback to inform upper layer of End of Transfer */
2285 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2286 hsmbus->SlaveRxCpltCallback(hsmbus);
2287 #else
2288 HAL_SMBUS_SlaveRxCpltCallback(hsmbus);
2289 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2290 }
2291 else
2292 {
2293 /* Set Reload for next Bytes */
2294 SMBUS_TransferConfig(hsmbus, 0, 1,
2295 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE),
2296 SMBUS_NO_STARTSTOP);
2297
2298 /* Ack last Byte Read */
2299 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK;
2300 }
2301 }
2302 else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2303 {
2304 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U))
2305 {
2306 if (hsmbus->XferCount > MAX_NBYTE_SIZE)
2307 {
2308 SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE,
2309 (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)),
2310 SMBUS_NO_STARTSTOP);
2311 hsmbus->XferSize = MAX_NBYTE_SIZE;
2312 }
2313 else
2314 {
2315 hsmbus->XferSize = hsmbus->XferCount;
2316 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions,
2317 SMBUS_NO_STARTSTOP);
2318 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2319 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2320 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL)
2321 {
2322 hsmbus->XferSize--;
2323 hsmbus->XferCount--;
2324 }
2325 }
2326 }
2327 }
2328 else
2329 {
2330 /* Nothing to do */
2331 }
2332 }
2333 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET)
2334 {
2335 /* Write data to TXDR only if XferCount not reach "0" */
2336 /* A TXIS flag can be set, during STOP treatment */
2337 /* Check if all Data have already been sent */
2338 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
2339 if (hsmbus->XferCount > 0U)
2340 {
2341 /* Write data to TXDR */
2342 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr;
2343
2344 /* Increment Buffer pointer */
2345 hsmbus->pBuffPtr++;
2346
2347 hsmbus->XferCount--;
2348 hsmbus->XferSize--;
2349 }
2350
2351 if (hsmbus->XferCount == 0U)
2352 {
2353 /* Last Byte is Transmitted */
2354 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */
2355 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX);
2356 hsmbus->PreviousState = hsmbus->State;
2357 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX);
2358
2359 /* Process Unlocked */
2360 __HAL_UNLOCK(hsmbus);
2361
2362 /* Call the corresponding callback to inform upper layer of End of Transfer */
2363 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2364 hsmbus->SlaveTxCpltCallback(hsmbus);
2365 #else
2366 HAL_SMBUS_SlaveTxCpltCallback(hsmbus);
2367 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2368 }
2369 }
2370 else
2371 {
2372 /* Nothing to do */
2373 }
2374
2375 /* Check if STOPF is set */
2376 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET)
2377 {
2378 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)
2379 {
2380 /* Store Last receive data if any */
2381 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET)
2382 {
2383 /* Read data from RXDR */
2384 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR);
2385
2386 /* Increment Buffer pointer */
2387 hsmbus->pBuffPtr++;
2388
2389 if ((hsmbus->XferSize > 0U))
2390 {
2391 hsmbus->XferSize--;
2392 hsmbus->XferCount--;
2393 }
2394 }
2395
2396 /* Disable RX and TX Interrupts */
2397 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX);
2398
2399 /* Disable ADDR Interrupt */
2400 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR);
2401
2402 /* Disable Address Acknowledge */
2403 hsmbus->Instance->CR2 |= I2C_CR2_NACK;
2404
2405 /* Clear Configuration Register 2 */
2406 SMBUS_RESET_CR2(hsmbus);
2407
2408 /* Clear STOP Flag */
2409 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF);
2410
2411 /* Clear ADDR flag */
2412 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR);
2413
2414 hsmbus->XferOptions = 0;
2415 hsmbus->PreviousState = hsmbus->State;
2416 hsmbus->State = HAL_SMBUS_STATE_READY;
2417
2418 /* Process Unlocked */
2419 __HAL_UNLOCK(hsmbus);
2420
2421 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2422 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2423 hsmbus->ListenCpltCallback(hsmbus);
2424 #else
2425 HAL_SMBUS_ListenCpltCallback(hsmbus);
2426 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2427 }
2428 }
2429
2430 /* Process Unlocked */
2431 __HAL_UNLOCK(hsmbus);
2432
2433 return HAL_OK;
2434 }
2435 /**
2436 * @brief Manage the enabling of Interrupts.
2437 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2438 * the configuration information for the specified SMBUS.
2439 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2440 * @retval HAL status
2441 */
SMBUS_Enable_IRQ(SMBUS_HandleTypeDef * hsmbus,uint32_t InterruptRequest)2442 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2443 {
2444 uint32_t tmpisr = 0UL;
2445
2446 if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)
2447 {
2448 /* Enable ERR interrupt */
2449 tmpisr |= SMBUS_IT_ERRI;
2450 }
2451
2452 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2453 {
2454 /* Enable ADDR, STOP interrupt */
2455 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI;
2456 }
2457
2458 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2459 {
2460 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2461 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI;
2462 }
2463
2464 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2465 {
2466 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2467 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI;
2468 }
2469
2470 /* Enable interrupts only at the end */
2471 /* to avoid the risk of SMBUS interrupt handle execution before */
2472 /* all interrupts requested done */
2473 __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr);
2474 }
2475 /**
2476 * @brief Manage the disabling of Interrupts.
2477 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2478 * the configuration information for the specified SMBUS.
2479 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition.
2480 * @retval HAL status
2481 */
SMBUS_Disable_IRQ(SMBUS_HandleTypeDef * hsmbus,uint32_t InterruptRequest)2482 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest)
2483 {
2484 uint32_t tmpisr = 0UL;
2485 uint32_t tmpstate = hsmbus->State;
2486
2487 if ((tmpstate == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT))
2488 {
2489 /* Disable ERR interrupt */
2490 tmpisr |= SMBUS_IT_ERRI;
2491 }
2492
2493 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX)
2494 {
2495 /* Disable TC, STOP, NACK and TXI interrupt */
2496 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI;
2497
2498 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2499 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2500 {
2501 /* Disable ERR interrupt */
2502 tmpisr |= SMBUS_IT_ERRI;
2503 }
2504
2505 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2506 {
2507 /* Disable STOP and NACK interrupt */
2508 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2509 }
2510 }
2511
2512 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX)
2513 {
2514 /* Disable TC, STOP, NACK and RXI interrupt */
2515 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI;
2516
2517 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2518 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN))
2519 {
2520 /* Disable ERR interrupt */
2521 tmpisr |= SMBUS_IT_ERRI;
2522 }
2523
2524 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)
2525 {
2526 /* Disable STOP and NACK interrupt */
2527 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2528 }
2529 }
2530
2531 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR)
2532 {
2533 /* Disable ADDR, STOP and NACK interrupt */
2534 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI;
2535
2536 if (SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL)
2537 {
2538 /* Disable ERR interrupt */
2539 tmpisr |= SMBUS_IT_ERRI;
2540 }
2541 }
2542
2543 /* Disable interrupts only at the end */
2544 /* to avoid a breaking situation like at "t" time */
2545 /* all disable interrupts request are not done */
2546 __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr);
2547 }
2548
2549 /**
2550 * @brief SMBUS interrupts error handler.
2551 * @param hsmbus SMBUS handle.
2552 * @retval None
2553 */
SMBUS_ITErrorHandler(SMBUS_HandleTypeDef * hsmbus)2554 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus)
2555 {
2556 uint32_t itflags = READ_REG(hsmbus->Instance->ISR);
2557 uint32_t itsources = READ_REG(hsmbus->Instance->CR1);
2558 uint32_t tmpstate;
2559 uint32_t tmperror;
2560
2561 /* SMBUS Bus error interrupt occurred ------------------------------------*/
2562 if (((itflags & SMBUS_FLAG_BERR) == SMBUS_FLAG_BERR) && \
2563 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2564 {
2565 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR;
2566
2567 /* Clear BERR flag */
2568 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR);
2569 }
2570
2571 /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
2572 if (((itflags & SMBUS_FLAG_OVR) == SMBUS_FLAG_OVR) && \
2573 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2574 {
2575 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR;
2576
2577 /* Clear OVR flag */
2578 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR);
2579 }
2580
2581 /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
2582 if (((itflags & SMBUS_FLAG_ARLO) == SMBUS_FLAG_ARLO) && \
2583 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2584 {
2585 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO;
2586
2587 /* Clear ARLO flag */
2588 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO);
2589 }
2590
2591 /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/
2592 if (((itflags & SMBUS_FLAG_TIMEOUT) == SMBUS_FLAG_TIMEOUT) && \
2593 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2594 {
2595 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT;
2596
2597 /* Clear TIMEOUT flag */
2598 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT);
2599 }
2600
2601 /* SMBUS Alert error interrupt occurred -----------------------------------------------*/
2602 if (((itflags & SMBUS_FLAG_ALERT) == SMBUS_FLAG_ALERT) && \
2603 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2604 {
2605 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT;
2606
2607 /* Clear ALERT flag */
2608 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT);
2609 }
2610
2611 /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/
2612 if (((itflags & SMBUS_FLAG_PECERR) == SMBUS_FLAG_PECERR) && \
2613 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI))
2614 {
2615 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR;
2616
2617 /* Clear PEC error flag */
2618 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR);
2619 }
2620
2621 /* Flush TX register */
2622 SMBUS_Flush_TXDR(hsmbus);
2623
2624 /* Store current volatile hsmbus->ErrorCode, misra rule */
2625 tmperror = hsmbus->ErrorCode;
2626
2627 /* Call the Error Callback in case of Error detected */
2628 if ((tmperror != HAL_SMBUS_ERROR_NONE) && (tmperror != HAL_SMBUS_ERROR_ACKF))
2629 {
2630 /* Do not Reset the HAL state in case of ALERT error */
2631 if ((tmperror & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT)
2632 {
2633 /* Store current volatile hsmbus->State, misra rule */
2634 tmpstate = hsmbus->State;
2635
2636 if (((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX)
2637 || ((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX))
2638 {
2639 /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */
2640 /* keep HAL_SMBUS_STATE_LISTEN if set */
2641 hsmbus->PreviousState = HAL_SMBUS_STATE_READY;
2642 hsmbus->State = HAL_SMBUS_STATE_LISTEN;
2643 }
2644 }
2645
2646 /* Call the Error callback to inform upper layer */
2647 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1)
2648 hsmbus->ErrorCallback(hsmbus);
2649 #else
2650 HAL_SMBUS_ErrorCallback(hsmbus);
2651 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */
2652 }
2653 }
2654
2655 /**
2656 * @brief Handle SMBUS Communication Timeout.
2657 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains
2658 * the configuration information for the specified SMBUS.
2659 * @param Flag Specifies the SMBUS flag to check.
2660 * @param Status The new Flag status (SET or RESET).
2661 * @param Timeout Timeout duration
2662 * @retval HAL status
2663 */
SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef * hsmbus,uint32_t Flag,FlagStatus Status,uint32_t Timeout)2664 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag,
2665 FlagStatus Status, uint32_t Timeout)
2666 {
2667 uint32_t tickstart = HAL_GetTick();
2668
2669 /* Wait until flag is set */
2670 while ((FlagStatus)(__HAL_SMBUS_GET_FLAG(hsmbus, Flag)) == Status)
2671 {
2672 /* Check for the Timeout */
2673 if (Timeout != HAL_MAX_DELAY)
2674 {
2675 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
2676 {
2677 hsmbus->PreviousState = hsmbus->State;
2678 hsmbus->State = HAL_SMBUS_STATE_READY;
2679
2680 /* Update SMBUS error code */
2681 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT;
2682
2683 /* Process Unlocked */
2684 __HAL_UNLOCK(hsmbus);
2685
2686 return HAL_ERROR;
2687 }
2688 }
2689 }
2690
2691 return HAL_OK;
2692 }
2693
2694 /**
2695 * @brief SMBUS Tx data register flush process.
2696 * @param hsmbus SMBUS handle.
2697 * @retval None
2698 */
SMBUS_Flush_TXDR(SMBUS_HandleTypeDef * hsmbus)2699 static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus)
2700 {
2701 /* If a pending TXIS flag is set */
2702 /* Write a dummy data in TXDR to clear it */
2703 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET)
2704 {
2705 hsmbus->Instance->TXDR = 0x00U;
2706 }
2707
2708 /* Flush TX register if not empty */
2709 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXE) == RESET)
2710 {
2711 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TXE);
2712 }
2713 }
2714
2715 /**
2716 * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
2717 * @param hsmbus SMBUS handle.
2718 * @param DevAddress specifies the slave address to be programmed.
2719 * @param Size specifies the number of bytes to be programmed.
2720 * This parameter must be a value between 0 and 255.
2721 * @param Mode New state of the SMBUS START condition generation.
2722 * This parameter can be one or a combination of the following values:
2723 * @arg @ref SMBUS_RELOAD_MODE Enable Reload mode.
2724 * @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode.
2725 * @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
2726 * @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
2727 * @param Request New state of the SMBUS START condition generation.
2728 * This parameter can be one of the following values:
2729 * @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition.
2730 * @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
2731 * @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request.
2732 * @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request.
2733 * @retval None
2734 */
SMBUS_TransferConfig(SMBUS_HandleTypeDef * hsmbus,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)2735 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size,
2736 uint32_t Mode, uint32_t Request)
2737 {
2738 /* Check the parameters */
2739 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance));
2740 assert_param(IS_SMBUS_TRANSFER_MODE(Mode));
2741 assert_param(IS_SMBUS_TRANSFER_REQUEST(Request));
2742
2743 /* update CR2 register */
2744 MODIFY_REG(hsmbus->Instance->CR2,
2745 ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
2746 (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - I2C_CR2_RD_WRN_Pos))) | \
2747 I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \
2748 (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \
2749 (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \
2750 (uint32_t)Mode | (uint32_t)Request));
2751 }
2752
2753 /**
2754 * @brief Convert SMBUSx OTHER_xxx XferOptions to functional XferOptions.
2755 * @param hsmbus SMBUS handle.
2756 * @retval None
2757 */
SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef * hsmbus)2758 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus)
2759 {
2760 /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */
2761 /* it request implicitly to generate a restart condition */
2762 /* set XferOptions to SMBUS_FIRST_FRAME */
2763 if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC)
2764 {
2765 hsmbus->XferOptions = SMBUS_FIRST_FRAME;
2766 }
2767 /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */
2768 /* it request implicitly to generate a restart condition */
2769 /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */
2770 else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC)
2771 {
2772 hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE;
2773 }
2774 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
2775 /* it request implicitly to generate a restart condition */
2776 /* then generate a stop condition at the end of transfer */
2777 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */
2778 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
2779 {
2780 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
2781 }
2782 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
2783 /* it request implicitly to generate a restart condition */
2784 /* then generate a stop condition at the end of transfer */
2785 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */
2786 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
2787 {
2788 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
2789 }
2790 else
2791 {
2792 /* Nothing to do */
2793 }
2794 }
2795 /**
2796 * @}
2797 */
2798
2799 #endif /* HAL_SMBUS_MODULE_ENABLED */
2800 /**
2801 * @}
2802 */
2803
2804 /**
2805 * @}
2806 */
2807