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