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