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