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