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