STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_smbus.c 00004 * @author MCD Application Team 00005 * @brief SMBUS HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the System Management Bus (SMBus) peripheral, 00008 * based on I2C principles of operation : 00009 * + Initialization and de-initialization functions 00010 * + IO operation functions 00011 * + Peripheral State and Errors functions 00012 * 00013 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2017 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 ============================================================================== 00026 ##### How to use this driver ##### 00027 ============================================================================== 00028 [..] 00029 The SMBUS HAL driver can be used as follows: 00030 00031 (#) Declare a SMBUS_HandleTypeDef handle structure, for example: 00032 SMBUS_HandleTypeDef hsmbus; 00033 00034 (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API: 00035 (##) Enable the SMBUSx interface clock 00036 (##) SMBUS pins configuration 00037 (+++) Enable the clock for the SMBUS GPIOs 00038 (+++) Configure SMBUS pins as alternate function open-drain 00039 (##) NVIC configuration if you need to use interrupt process 00040 (+++) Configure the SMBUSx interrupt priority 00041 (+++) Enable the NVIC SMBUS IRQ Channel 00042 00043 (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode, 00044 Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode, 00045 Peripheral mode and Packet Error Check mode in the hsmbus Init structure. 00046 00047 (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API: 00048 (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) 00049 by calling the customized HAL_SMBUS_MspInit(&hsmbus) API. 00050 00051 (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady() 00052 00053 (#) For SMBUS IO operations, only one mode of operations is available within this driver 00054 00055 *** Interrupt mode IO operation *** 00056 =================================== 00057 [..] 00058 (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode 00059 using HAL_SMBUS_Master_Transmit_IT() 00060 (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and users can 00061 add their own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback() 00062 (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode 00063 using HAL_SMBUS_Master_Receive_IT() 00064 (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and users can 00065 add their own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback() 00066 (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT() 00067 (++) The associated previous transfer callback is called at the end of abort process 00068 (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit 00069 (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive 00070 (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode 00071 using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT() 00072 (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and users can 00073 add their own code to check the Address Match Code and the transmission direction 00074 request by master/host (Write/Read). 00075 (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and users can 00076 add their own code by customization of function pointer HAL_SMBUS_ListenCpltCallback() 00077 (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode 00078 using HAL_SMBUS_Slave_Transmit_IT() 00079 (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and users can 00080 add their own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback() 00081 (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode 00082 using HAL_SMBUS_Slave_Receive_IT() 00083 (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and users can 00084 add their own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback() 00085 (+) Enable/Disable the SMBUS alert mode using 00086 HAL_SMBUS_EnableAlert_IT() or HAL_SMBUS_DisableAlert_IT() 00087 (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and users can 00088 add their own code by customization of function pointer HAL_SMBUS_ErrorCallback() 00089 to check the Alert Error Code using function HAL_SMBUS_GetError() 00090 (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError() 00091 (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and users can 00092 add their own code by customization of function pointer HAL_SMBUS_ErrorCallback() 00093 to check the Error Code using function HAL_SMBUS_GetError() 00094 00095 *** SMBUS HAL driver macros list *** 00096 ================================== 00097 [..] 00098 Below the list of most used macros in SMBUS HAL driver. 00099 00100 (+) __HAL_SMBUS_ENABLE: Enable the SMBUS peripheral 00101 (+) __HAL_SMBUS_DISABLE: Disable the SMBUS peripheral 00102 (+) __HAL_SMBUS_GET_FLAG: Check whether the specified SMBUS flag is set or not 00103 (+) __HAL_SMBUS_CLEAR_FLAG: Clear the specified SMBUS pending flag 00104 (+) __HAL_SMBUS_ENABLE_IT: Enable the specified SMBUS interrupt 00105 (+) __HAL_SMBUS_DISABLE_IT: Disable the specified SMBUS interrupt 00106 00107 *** Callback registration *** 00108 ============================================= 00109 [..] 00110 The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1 00111 allows the user to configure dynamically the driver callbacks. 00112 Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterAddrCallback() 00113 to register an interrupt callback. 00114 [..] 00115 Function HAL_SMBUS_RegisterCallback() allows to register following callbacks: 00116 (+) MasterTxCpltCallback : callback for Master transmission end of transfer. 00117 (+) MasterRxCpltCallback : callback for Master reception end of transfer. 00118 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. 00119 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. 00120 (+) ListenCpltCallback : callback for end of listen mode. 00121 (+) ErrorCallback : callback for error detection. 00122 (+) MspInitCallback : callback for Msp Init. 00123 (+) MspDeInitCallback : callback for Msp DeInit. 00124 This function takes as parameters the HAL peripheral handle, the Callback ID 00125 and a pointer to the user callback function. 00126 [..] 00127 For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback. 00128 [..] 00129 Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default 00130 weak function. 00131 HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle, 00132 and the Callback ID. 00133 This function allows to reset following callbacks: 00134 (+) MasterTxCpltCallback : callback for Master transmission end of transfer. 00135 (+) MasterRxCpltCallback : callback for Master reception end of transfer. 00136 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. 00137 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. 00138 (+) ListenCpltCallback : callback for end of listen mode. 00139 (+) ErrorCallback : callback for error detection. 00140 (+) MspInitCallback : callback for Msp Init. 00141 (+) MspDeInitCallback : callback for Msp DeInit. 00142 [..] 00143 For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback. 00144 [..] 00145 By default, after the HAL_SMBUS_Init() and when the state is HAL_I2C_STATE_RESET 00146 all callbacks are set to the corresponding weak functions: 00147 examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback(). 00148 Exception done for MspInit and MspDeInit functions that are 00149 reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when 00150 these callbacks are null (not registered beforehand). 00151 If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() 00152 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. 00153 [..] 00154 Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only. 00155 Exception done MspInit/MspDeInit functions that can be registered/unregistered 00156 in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state, 00157 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00158 Then, the user first registers the MspInit/MspDeInit user callbacks 00159 using HAL_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit() 00160 or HAL_SMBUS_Init() function. 00161 [..] 00162 When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or 00163 not defined, the callback registration feature is not available and all callbacks 00164 are set to the corresponding weak functions. 00165 00166 [..] 00167 (@) You can refer to the SMBUS HAL driver header file for more useful macros 00168 00169 @endverbatim 00170 */ 00171 00172 /* Includes ------------------------------------------------------------------*/ 00173 #include "stm32l4xx_hal.h" 00174 00175 /** @addtogroup STM32L4xx_HAL_Driver 00176 * @{ 00177 */ 00178 00179 /** @defgroup SMBUS SMBUS 00180 * @brief SMBUS HAL module driver 00181 * @{ 00182 */ 00183 00184 #ifdef HAL_SMBUS_MODULE_ENABLED 00185 00186 /* Private typedef -----------------------------------------------------------*/ 00187 /* Private constants ---------------------------------------------------------*/ 00188 /** @defgroup SMBUS_Private_Define SMBUS Private Constants 00189 * @{ 00190 */ 00191 #define TIMING_CLEAR_MASK (0xF0FFFFFFUL) /*!< SMBUS TIMING clear register Mask */ 00192 #define HAL_TIMEOUT_ADDR (10000U) /*!< 10 s */ 00193 #define HAL_TIMEOUT_BUSY (25U) /*!< 25 ms */ 00194 #define HAL_TIMEOUT_DIR (25U) /*!< 25 ms */ 00195 #define HAL_TIMEOUT_RXNE (25U) /*!< 25 ms */ 00196 #define HAL_TIMEOUT_STOPF (25U) /*!< 25 ms */ 00197 #define HAL_TIMEOUT_TC (25U) /*!< 25 ms */ 00198 #define HAL_TIMEOUT_TCR (25U) /*!< 25 ms */ 00199 #define HAL_TIMEOUT_TXIS (25U) /*!< 25 ms */ 00200 #define MAX_NBYTE_SIZE 255U 00201 /** 00202 * @} 00203 */ 00204 00205 /* Private macro -------------------------------------------------------------*/ 00206 /* Private variables ---------------------------------------------------------*/ 00207 /* Private function prototypes -----------------------------------------------*/ 00208 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions 00209 * @{ 00210 */ 00211 /* Private functions to handle flags during polling transfer */ 00212 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, 00213 FlagStatus Status, uint32_t Timeout); 00214 00215 /* Private functions for SMBUS transfer IRQ handler */ 00216 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags); 00217 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags); 00218 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus); 00219 00220 /* Private functions to centralize the enable/disable of Interrupts */ 00221 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest); 00222 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest); 00223 00224 /* Private function to flush TXDR register */ 00225 static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus); 00226 00227 /* Private function to handle start, restart or stop a transfer */ 00228 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, 00229 uint32_t Mode, uint32_t Request); 00230 00231 /* Private function to Convert Specific options */ 00232 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus); 00233 /** 00234 * @} 00235 */ 00236 00237 /* Exported functions --------------------------------------------------------*/ 00238 00239 /** @defgroup SMBUS_Exported_Functions SMBUS Exported Functions 00240 * @{ 00241 */ 00242 00243 /** @defgroup SMBUS_Exported_Functions_Group1 Initialization and de-initialization functions 00244 * @brief Initialization and Configuration functions 00245 * 00246 @verbatim 00247 =============================================================================== 00248 ##### Initialization and de-initialization functions ##### 00249 =============================================================================== 00250 [..] This subsection provides a set of functions allowing to initialize and 00251 deinitialize the SMBUSx peripheral: 00252 00253 (+) User must Implement HAL_SMBUS_MspInit() function in which he configures 00254 all related peripherals resources (CLOCK, GPIO, IT and NVIC ). 00255 00256 (+) Call the function HAL_SMBUS_Init() to configure the selected device with 00257 the selected configuration: 00258 (++) Clock Timing 00259 (++) Bus Timeout 00260 (++) Analog Filer mode 00261 (++) Own Address 1 00262 (++) Addressing mode (Master, Slave) 00263 (++) Dual Addressing mode 00264 (++) Own Address 2 00265 (++) Own Address 2 Mask 00266 (++) General call mode 00267 (++) Nostretch mode 00268 (++) Packet Error Check mode 00269 (++) Peripheral mode 00270 00271 00272 (+) Call the function HAL_SMBUS_DeInit() to restore the default configuration 00273 of the selected SMBUSx peripheral. 00274 00275 (+) Enable/Disable Analog/Digital filters with HAL_SMBUS_ConfigAnalogFilter() and 00276 HAL_SMBUS_ConfigDigitalFilter(). 00277 00278 @endverbatim 00279 * @{ 00280 */ 00281 00282 /** 00283 * @brief Initialize the SMBUS according to the specified parameters 00284 * in the SMBUS_InitTypeDef and initialize the associated handle. 00285 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00286 * the configuration information for the specified SMBUS. 00287 * @retval HAL status 00288 */ 00289 HAL_StatusTypeDef HAL_SMBUS_Init(SMBUS_HandleTypeDef *hsmbus) 00290 { 00291 /* Check the SMBUS handle allocation */ 00292 if (hsmbus == NULL) 00293 { 00294 return HAL_ERROR; 00295 } 00296 00297 /* Check the parameters */ 00298 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); 00299 assert_param(IS_SMBUS_ANALOG_FILTER(hsmbus->Init.AnalogFilter)); 00300 assert_param(IS_SMBUS_OWN_ADDRESS1(hsmbus->Init.OwnAddress1)); 00301 assert_param(IS_SMBUS_ADDRESSING_MODE(hsmbus->Init.AddressingMode)); 00302 assert_param(IS_SMBUS_DUAL_ADDRESS(hsmbus->Init.DualAddressMode)); 00303 assert_param(IS_SMBUS_OWN_ADDRESS2(hsmbus->Init.OwnAddress2)); 00304 assert_param(IS_SMBUS_OWN_ADDRESS2_MASK(hsmbus->Init.OwnAddress2Masks)); 00305 assert_param(IS_SMBUS_GENERAL_CALL(hsmbus->Init.GeneralCallMode)); 00306 assert_param(IS_SMBUS_NO_STRETCH(hsmbus->Init.NoStretchMode)); 00307 assert_param(IS_SMBUS_PEC(hsmbus->Init.PacketErrorCheckMode)); 00308 assert_param(IS_SMBUS_PERIPHERAL_MODE(hsmbus->Init.PeripheralMode)); 00309 00310 if (hsmbus->State == HAL_SMBUS_STATE_RESET) 00311 { 00312 /* Allocate lock resource and initialize it */ 00313 hsmbus->Lock = HAL_UNLOCKED; 00314 00315 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 00316 hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ 00317 hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ 00318 hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ 00319 hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ 00320 hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ 00321 hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */ 00322 hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */ 00323 00324 if (hsmbus->MspInitCallback == NULL) 00325 { 00326 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ 00327 } 00328 00329 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00330 hsmbus->MspInitCallback(hsmbus); 00331 #else 00332 /* Init the low level hardware : GPIO, CLOCK, NVIC */ 00333 HAL_SMBUS_MspInit(hsmbus); 00334 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 00335 } 00336 00337 hsmbus->State = HAL_SMBUS_STATE_BUSY; 00338 00339 /* Disable the selected SMBUS peripheral */ 00340 __HAL_SMBUS_DISABLE(hsmbus); 00341 00342 /*---------------------------- SMBUSx TIMINGR Configuration ------------------------*/ 00343 /* Configure SMBUSx: Frequency range */ 00344 hsmbus->Instance->TIMINGR = hsmbus->Init.Timing & TIMING_CLEAR_MASK; 00345 00346 /*---------------------------- SMBUSx TIMEOUTR Configuration ------------------------*/ 00347 /* Configure SMBUSx: Bus Timeout */ 00348 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TIMOUTEN; 00349 hsmbus->Instance->TIMEOUTR &= ~I2C_TIMEOUTR_TEXTEN; 00350 hsmbus->Instance->TIMEOUTR = hsmbus->Init.SMBusTimeout; 00351 00352 /*---------------------------- SMBUSx OAR1 Configuration -----------------------*/ 00353 /* Configure SMBUSx: Own Address1 and ack own address1 mode */ 00354 hsmbus->Instance->OAR1 &= ~I2C_OAR1_OA1EN; 00355 00356 if (hsmbus->Init.OwnAddress1 != 0UL) 00357 { 00358 if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT) 00359 { 00360 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | hsmbus->Init.OwnAddress1); 00361 } 00362 else /* SMBUS_ADDRESSINGMODE_10BIT */ 00363 { 00364 hsmbus->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hsmbus->Init.OwnAddress1); 00365 } 00366 } 00367 00368 /*---------------------------- SMBUSx CR2 Configuration ------------------------*/ 00369 /* Configure SMBUSx: Addressing Master mode */ 00370 if (hsmbus->Init.AddressingMode == SMBUS_ADDRESSINGMODE_10BIT) 00371 { 00372 hsmbus->Instance->CR2 = (I2C_CR2_ADD10); 00373 } 00374 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */ 00375 /* AUTOEND and NACK bit will be manage during Transfer process */ 00376 hsmbus->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); 00377 00378 /*---------------------------- SMBUSx OAR2 Configuration -----------------------*/ 00379 /* Configure SMBUSx: Dual mode and Own Address2 */ 00380 hsmbus->Instance->OAR2 = (hsmbus->Init.DualAddressMode | hsmbus->Init.OwnAddress2 | \ 00381 (hsmbus->Init.OwnAddress2Masks << 8U)); 00382 00383 /*---------------------------- SMBUSx CR1 Configuration ------------------------*/ 00384 /* Configure SMBUSx: Generalcall and NoStretch mode */ 00385 hsmbus->Instance->CR1 = (hsmbus->Init.GeneralCallMode | hsmbus->Init.NoStretchMode | \ 00386 hsmbus->Init.PacketErrorCheckMode | hsmbus->Init.PeripheralMode | \ 00387 hsmbus->Init.AnalogFilter); 00388 00389 /* Enable Slave Byte Control only in case of Packet Error Check is enabled 00390 and SMBUS Peripheral is set in Slave mode */ 00391 if ((hsmbus->Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE) && \ 00392 ((hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE) || \ 00393 (hsmbus->Init.PeripheralMode == SMBUS_PERIPHERAL_MODE_SMBUS_SLAVE_ARP))) 00394 { 00395 hsmbus->Instance->CR1 |= I2C_CR1_SBC; 00396 } 00397 00398 /* Enable the selected SMBUS peripheral */ 00399 __HAL_SMBUS_ENABLE(hsmbus); 00400 00401 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 00402 hsmbus->PreviousState = HAL_SMBUS_STATE_READY; 00403 hsmbus->State = HAL_SMBUS_STATE_READY; 00404 00405 return HAL_OK; 00406 } 00407 00408 /** 00409 * @brief DeInitialize the SMBUS peripheral. 00410 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00411 * the configuration information for the specified SMBUS. 00412 * @retval HAL status 00413 */ 00414 HAL_StatusTypeDef HAL_SMBUS_DeInit(SMBUS_HandleTypeDef *hsmbus) 00415 { 00416 /* Check the SMBUS handle allocation */ 00417 if (hsmbus == NULL) 00418 { 00419 return HAL_ERROR; 00420 } 00421 00422 /* Check the parameters */ 00423 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); 00424 00425 hsmbus->State = HAL_SMBUS_STATE_BUSY; 00426 00427 /* Disable the SMBUS Peripheral Clock */ 00428 __HAL_SMBUS_DISABLE(hsmbus); 00429 00430 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 00431 if (hsmbus->MspDeInitCallback == NULL) 00432 { 00433 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ 00434 } 00435 00436 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ 00437 hsmbus->MspDeInitCallback(hsmbus); 00438 #else 00439 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ 00440 HAL_SMBUS_MspDeInit(hsmbus); 00441 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 00442 00443 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 00444 hsmbus->PreviousState = HAL_SMBUS_STATE_RESET; 00445 hsmbus->State = HAL_SMBUS_STATE_RESET; 00446 00447 /* Release Lock */ 00448 __HAL_UNLOCK(hsmbus); 00449 00450 return HAL_OK; 00451 } 00452 00453 /** 00454 * @brief Initialize the SMBUS MSP. 00455 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00456 * the configuration information for the specified SMBUS. 00457 * @retval None 00458 */ 00459 __weak void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef *hsmbus) 00460 { 00461 /* Prevent unused argument(s) compilation warning */ 00462 UNUSED(hsmbus); 00463 00464 /* NOTE : This function should not be modified, when the callback is needed, 00465 the HAL_SMBUS_MspInit could be implemented in the user file 00466 */ 00467 } 00468 00469 /** 00470 * @brief DeInitialize the SMBUS MSP. 00471 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00472 * the configuration information for the specified SMBUS. 00473 * @retval None 00474 */ 00475 __weak void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef *hsmbus) 00476 { 00477 /* Prevent unused argument(s) compilation warning */ 00478 UNUSED(hsmbus); 00479 00480 /* NOTE : This function should not be modified, when the callback is needed, 00481 the HAL_SMBUS_MspDeInit could be implemented in the user file 00482 */ 00483 } 00484 00485 /** 00486 * @brief Configure Analog noise filter. 00487 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00488 * the configuration information for the specified SMBUS. 00489 * @param AnalogFilter This parameter can be one of the following values: 00490 * @arg @ref SMBUS_ANALOGFILTER_ENABLE 00491 * @arg @ref SMBUS_ANALOGFILTER_DISABLE 00492 * @retval HAL status 00493 */ 00494 HAL_StatusTypeDef HAL_SMBUS_ConfigAnalogFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t AnalogFilter) 00495 { 00496 /* Check the parameters */ 00497 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); 00498 assert_param(IS_SMBUS_ANALOG_FILTER(AnalogFilter)); 00499 00500 if (hsmbus->State == HAL_SMBUS_STATE_READY) 00501 { 00502 /* Process Locked */ 00503 __HAL_LOCK(hsmbus); 00504 00505 hsmbus->State = HAL_SMBUS_STATE_BUSY; 00506 00507 /* Disable the selected SMBUS peripheral */ 00508 __HAL_SMBUS_DISABLE(hsmbus); 00509 00510 /* Reset ANOFF bit */ 00511 hsmbus->Instance->CR1 &= ~(I2C_CR1_ANFOFF); 00512 00513 /* Set analog filter bit*/ 00514 hsmbus->Instance->CR1 |= AnalogFilter; 00515 00516 __HAL_SMBUS_ENABLE(hsmbus); 00517 00518 hsmbus->State = HAL_SMBUS_STATE_READY; 00519 00520 /* Process Unlocked */ 00521 __HAL_UNLOCK(hsmbus); 00522 00523 return HAL_OK; 00524 } 00525 else 00526 { 00527 return HAL_BUSY; 00528 } 00529 } 00530 00531 /** 00532 * @brief Configure Digital noise filter. 00533 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00534 * the configuration information for the specified SMBUS. 00535 * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F. 00536 * @retval HAL status 00537 */ 00538 HAL_StatusTypeDef HAL_SMBUS_ConfigDigitalFilter(SMBUS_HandleTypeDef *hsmbus, uint32_t DigitalFilter) 00539 { 00540 uint32_t tmpreg; 00541 00542 /* Check the parameters */ 00543 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); 00544 assert_param(IS_SMBUS_DIGITAL_FILTER(DigitalFilter)); 00545 00546 if (hsmbus->State == HAL_SMBUS_STATE_READY) 00547 { 00548 /* Process Locked */ 00549 __HAL_LOCK(hsmbus); 00550 00551 hsmbus->State = HAL_SMBUS_STATE_BUSY; 00552 00553 /* Disable the selected SMBUS peripheral */ 00554 __HAL_SMBUS_DISABLE(hsmbus); 00555 00556 /* Get the old register value */ 00557 tmpreg = hsmbus->Instance->CR1; 00558 00559 /* Reset I2C DNF bits [11:8] */ 00560 tmpreg &= ~(I2C_CR1_DNF); 00561 00562 /* Set I2Cx DNF coefficient */ 00563 tmpreg |= DigitalFilter << I2C_CR1_DNF_Pos; 00564 00565 /* Store the new register value */ 00566 hsmbus->Instance->CR1 = tmpreg; 00567 00568 __HAL_SMBUS_ENABLE(hsmbus); 00569 00570 hsmbus->State = HAL_SMBUS_STATE_READY; 00571 00572 /* Process Unlocked */ 00573 __HAL_UNLOCK(hsmbus); 00574 00575 return HAL_OK; 00576 } 00577 else 00578 { 00579 return HAL_BUSY; 00580 } 00581 } 00582 00583 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 00584 /** 00585 * @brief Register a User SMBUS Callback 00586 * To be used instead of the weak predefined callback 00587 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00588 * the configuration information for the specified SMBUS. 00589 * @param CallbackID ID of the callback to be registered 00590 * This parameter can be one of the following values: 00591 * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID 00592 * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID 00593 * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID 00594 * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID 00595 * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID 00596 * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID 00597 * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID 00598 * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID 00599 * @param pCallback pointer to the Callback function 00600 * @retval HAL status 00601 */ 00602 HAL_StatusTypeDef HAL_SMBUS_RegisterCallback(SMBUS_HandleTypeDef *hsmbus, 00603 HAL_SMBUS_CallbackIDTypeDef CallbackID, 00604 pSMBUS_CallbackTypeDef pCallback) 00605 { 00606 HAL_StatusTypeDef status = HAL_OK; 00607 00608 if (pCallback == NULL) 00609 { 00610 /* Update the error code */ 00611 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00612 00613 return HAL_ERROR; 00614 } 00615 00616 /* Process locked */ 00617 __HAL_LOCK(hsmbus); 00618 00619 if (HAL_SMBUS_STATE_READY == hsmbus->State) 00620 { 00621 switch (CallbackID) 00622 { 00623 case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID : 00624 hsmbus->MasterTxCpltCallback = pCallback; 00625 break; 00626 00627 case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID : 00628 hsmbus->MasterRxCpltCallback = pCallback; 00629 break; 00630 00631 case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID : 00632 hsmbus->SlaveTxCpltCallback = pCallback; 00633 break; 00634 00635 case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID : 00636 hsmbus->SlaveRxCpltCallback = pCallback; 00637 break; 00638 00639 case HAL_SMBUS_LISTEN_COMPLETE_CB_ID : 00640 hsmbus->ListenCpltCallback = pCallback; 00641 break; 00642 00643 case HAL_SMBUS_ERROR_CB_ID : 00644 hsmbus->ErrorCallback = pCallback; 00645 break; 00646 00647 case HAL_SMBUS_MSPINIT_CB_ID : 00648 hsmbus->MspInitCallback = pCallback; 00649 break; 00650 00651 case HAL_SMBUS_MSPDEINIT_CB_ID : 00652 hsmbus->MspDeInitCallback = pCallback; 00653 break; 00654 00655 default : 00656 /* Update the error code */ 00657 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00658 00659 /* Return error status */ 00660 status = HAL_ERROR; 00661 break; 00662 } 00663 } 00664 else if (HAL_SMBUS_STATE_RESET == hsmbus->State) 00665 { 00666 switch (CallbackID) 00667 { 00668 case HAL_SMBUS_MSPINIT_CB_ID : 00669 hsmbus->MspInitCallback = pCallback; 00670 break; 00671 00672 case HAL_SMBUS_MSPDEINIT_CB_ID : 00673 hsmbus->MspDeInitCallback = pCallback; 00674 break; 00675 00676 default : 00677 /* Update the error code */ 00678 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00679 00680 /* Return error status */ 00681 status = HAL_ERROR; 00682 break; 00683 } 00684 } 00685 else 00686 { 00687 /* Update the error code */ 00688 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00689 00690 /* Return error status */ 00691 status = HAL_ERROR; 00692 } 00693 00694 /* Release Lock */ 00695 __HAL_UNLOCK(hsmbus); 00696 return status; 00697 } 00698 00699 /** 00700 * @brief Unregister an SMBUS Callback 00701 * SMBUS callback is redirected to the weak predefined callback 00702 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00703 * the configuration information for the specified SMBUS. 00704 * @param CallbackID ID of the callback to be unregistered 00705 * This parameter can be one of the following values: 00706 * This parameter can be one of the following values: 00707 * @arg @ref HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID 00708 * @arg @ref HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID 00709 * @arg @ref HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID 00710 * @arg @ref HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID 00711 * @arg @ref HAL_SMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID 00712 * @arg @ref HAL_SMBUS_ERROR_CB_ID Error callback ID 00713 * @arg @ref HAL_SMBUS_MSPINIT_CB_ID MspInit callback ID 00714 * @arg @ref HAL_SMBUS_MSPDEINIT_CB_ID MspDeInit callback ID 00715 * @retval HAL status 00716 */ 00717 HAL_StatusTypeDef HAL_SMBUS_UnRegisterCallback(SMBUS_HandleTypeDef *hsmbus, 00718 HAL_SMBUS_CallbackIDTypeDef CallbackID) 00719 { 00720 HAL_StatusTypeDef status = HAL_OK; 00721 00722 /* Process locked */ 00723 __HAL_LOCK(hsmbus); 00724 00725 if (HAL_SMBUS_STATE_READY == hsmbus->State) 00726 { 00727 switch (CallbackID) 00728 { 00729 case HAL_SMBUS_MASTER_TX_COMPLETE_CB_ID : 00730 hsmbus->MasterTxCpltCallback = HAL_SMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ 00731 break; 00732 00733 case HAL_SMBUS_MASTER_RX_COMPLETE_CB_ID : 00734 hsmbus->MasterRxCpltCallback = HAL_SMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ 00735 break; 00736 00737 case HAL_SMBUS_SLAVE_TX_COMPLETE_CB_ID : 00738 hsmbus->SlaveTxCpltCallback = HAL_SMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ 00739 break; 00740 00741 case HAL_SMBUS_SLAVE_RX_COMPLETE_CB_ID : 00742 hsmbus->SlaveRxCpltCallback = HAL_SMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ 00743 break; 00744 00745 case HAL_SMBUS_LISTEN_COMPLETE_CB_ID : 00746 hsmbus->ListenCpltCallback = HAL_SMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ 00747 break; 00748 00749 case HAL_SMBUS_ERROR_CB_ID : 00750 hsmbus->ErrorCallback = HAL_SMBUS_ErrorCallback; /* Legacy weak ErrorCallback */ 00751 break; 00752 00753 case HAL_SMBUS_MSPINIT_CB_ID : 00754 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ 00755 break; 00756 00757 case HAL_SMBUS_MSPDEINIT_CB_ID : 00758 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ 00759 break; 00760 00761 default : 00762 /* Update the error code */ 00763 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00764 00765 /* Return error status */ 00766 status = HAL_ERROR; 00767 break; 00768 } 00769 } 00770 else if (HAL_SMBUS_STATE_RESET == hsmbus->State) 00771 { 00772 switch (CallbackID) 00773 { 00774 case HAL_SMBUS_MSPINIT_CB_ID : 00775 hsmbus->MspInitCallback = HAL_SMBUS_MspInit; /* Legacy weak MspInit */ 00776 break; 00777 00778 case HAL_SMBUS_MSPDEINIT_CB_ID : 00779 hsmbus->MspDeInitCallback = HAL_SMBUS_MspDeInit; /* Legacy weak MspDeInit */ 00780 break; 00781 00782 default : 00783 /* Update the error code */ 00784 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00785 00786 /* Return error status */ 00787 status = HAL_ERROR; 00788 break; 00789 } 00790 } 00791 else 00792 { 00793 /* Update the error code */ 00794 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00795 00796 /* Return error status */ 00797 status = HAL_ERROR; 00798 } 00799 00800 /* Release Lock */ 00801 __HAL_UNLOCK(hsmbus); 00802 return status; 00803 } 00804 00805 /** 00806 * @brief Register the Slave Address Match SMBUS Callback 00807 * To be used instead of the weak HAL_SMBUS_AddrCallback() predefined callback 00808 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00809 * the configuration information for the specified SMBUS. 00810 * @param pCallback pointer to the Address Match Callback function 00811 * @retval HAL status 00812 */ 00813 HAL_StatusTypeDef HAL_SMBUS_RegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus, 00814 pSMBUS_AddrCallbackTypeDef pCallback) 00815 { 00816 HAL_StatusTypeDef status = HAL_OK; 00817 00818 if (pCallback == NULL) 00819 { 00820 /* Update the error code */ 00821 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00822 00823 return HAL_ERROR; 00824 } 00825 /* Process locked */ 00826 __HAL_LOCK(hsmbus); 00827 00828 if (HAL_SMBUS_STATE_READY == hsmbus->State) 00829 { 00830 hsmbus->AddrCallback = pCallback; 00831 } 00832 else 00833 { 00834 /* Update the error code */ 00835 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00836 00837 /* Return error status */ 00838 status = HAL_ERROR; 00839 } 00840 00841 /* Release Lock */ 00842 __HAL_UNLOCK(hsmbus); 00843 return status; 00844 } 00845 00846 /** 00847 * @brief UnRegister the Slave Address Match SMBUS Callback 00848 * Info Ready SMBUS Callback is redirected to the weak HAL_SMBUS_AddrCallback() predefined callback 00849 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00850 * the configuration information for the specified SMBUS. 00851 * @retval HAL status 00852 */ 00853 HAL_StatusTypeDef HAL_SMBUS_UnRegisterAddrCallback(SMBUS_HandleTypeDef *hsmbus) 00854 { 00855 HAL_StatusTypeDef status = HAL_OK; 00856 00857 /* Process locked */ 00858 __HAL_LOCK(hsmbus); 00859 00860 if (HAL_SMBUS_STATE_READY == hsmbus->State) 00861 { 00862 hsmbus->AddrCallback = HAL_SMBUS_AddrCallback; /* Legacy weak AddrCallback */ 00863 } 00864 else 00865 { 00866 /* Update the error code */ 00867 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_INVALID_CALLBACK; 00868 00869 /* Return error status */ 00870 status = HAL_ERROR; 00871 } 00872 00873 /* Release Lock */ 00874 __HAL_UNLOCK(hsmbus); 00875 return status; 00876 } 00877 00878 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 00879 00880 /** 00881 * @} 00882 */ 00883 00884 /** @defgroup SMBUS_Exported_Functions_Group2 Input and Output operation functions 00885 * @brief Data transfers functions 00886 * 00887 @verbatim 00888 =============================================================================== 00889 ##### IO operation functions ##### 00890 =============================================================================== 00891 [..] 00892 This subsection provides a set of functions allowing to manage the SMBUS data 00893 transfers. 00894 00895 (#) Blocking mode function to check if device is ready for usage is : 00896 (++) HAL_SMBUS_IsDeviceReady() 00897 00898 (#) There is only one mode of transfer: 00899 (++) Non-Blocking mode : The communication is performed using Interrupts. 00900 These functions return the status of the transfer startup. 00901 The end of the data processing will be indicated through the 00902 dedicated SMBUS IRQ when using Interrupt mode. 00903 00904 (#) Non-Blocking mode functions with Interrupt are : 00905 (++) HAL_SMBUS_Master_Transmit_IT() 00906 (++) HAL_SMBUS_Master_Receive_IT() 00907 (++) HAL_SMBUS_Slave_Transmit_IT() 00908 (++) HAL_SMBUS_Slave_Receive_IT() 00909 (++) HAL_SMBUS_EnableListen_IT() or alias HAL_SMBUS_EnableListen_IT() 00910 (++) HAL_SMBUS_DisableListen_IT() 00911 (++) HAL_SMBUS_EnableAlert_IT() 00912 (++) HAL_SMBUS_DisableAlert_IT() 00913 00914 (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode: 00915 (++) HAL_SMBUS_MasterTxCpltCallback() 00916 (++) HAL_SMBUS_MasterRxCpltCallback() 00917 (++) HAL_SMBUS_SlaveTxCpltCallback() 00918 (++) HAL_SMBUS_SlaveRxCpltCallback() 00919 (++) HAL_SMBUS_AddrCallback() 00920 (++) HAL_SMBUS_ListenCpltCallback() 00921 (++) HAL_SMBUS_ErrorCallback() 00922 00923 @endverbatim 00924 * @{ 00925 */ 00926 00927 /** 00928 * @brief Transmit in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. 00929 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 00930 * the configuration information for the specified SMBUS. 00931 * @param DevAddress Target device address: The device 7 bits address value 00932 * in datasheet must be shifted to the left before calling the interface 00933 * @param pData Pointer to data buffer 00934 * @param Size Amount of data to be sent 00935 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition 00936 * @retval HAL status 00937 */ 00938 HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, 00939 uint8_t *pData, uint16_t Size, uint32_t XferOptions) 00940 { 00941 uint32_t tmp; 00942 00943 /* Check the parameters */ 00944 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); 00945 00946 if (hsmbus->State == HAL_SMBUS_STATE_READY) 00947 { 00948 /* Process Locked */ 00949 __HAL_LOCK(hsmbus); 00950 00951 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; 00952 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 00953 /* Prepare transfer parameters */ 00954 hsmbus->pBuffPtr = pData; 00955 hsmbus->XferCount = Size; 00956 hsmbus->XferOptions = XferOptions; 00957 00958 /* In case of Quick command, remove autoend mode */ 00959 /* Manage the stop generation by software */ 00960 if (hsmbus->pBuffPtr == NULL) 00961 { 00962 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; 00963 } 00964 00965 if (Size > MAX_NBYTE_SIZE) 00966 { 00967 hsmbus->XferSize = MAX_NBYTE_SIZE; 00968 } 00969 else 00970 { 00971 hsmbus->XferSize = Size; 00972 } 00973 00974 /* Send Slave Address */ 00975 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ 00976 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) 00977 { 00978 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, 00979 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), 00980 SMBUS_GENERATE_START_WRITE); 00981 } 00982 else 00983 { 00984 /* If transfer direction not change, do not generate Restart Condition */ 00985 /* Mean Previous state is same as current state */ 00986 00987 /* Store current volatile XferOptions, misra rule */ 00988 tmp = hsmbus->XferOptions; 00989 00990 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) && \ 00991 (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0)) 00992 { 00993 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 00994 SMBUS_NO_STARTSTOP); 00995 } 00996 /* Else transfer direction change, so generate Restart with new transfer direction */ 00997 else 00998 { 00999 /* Convert OTHER_xxx XferOptions if any */ 01000 SMBUS_ConvertOtherXferOptions(hsmbus); 01001 01002 /* Handle Transfer */ 01003 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, 01004 hsmbus->XferOptions, 01005 SMBUS_GENERATE_START_WRITE); 01006 } 01007 01008 /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */ 01009 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ 01010 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) 01011 { 01012 hsmbus->XferSize--; 01013 hsmbus->XferCount--; 01014 } 01015 } 01016 01017 /* Process Unlocked */ 01018 __HAL_UNLOCK(hsmbus); 01019 01020 /* Note : The SMBUS interrupts must be enabled after unlocking current process 01021 to avoid the risk of SMBUS interrupt handle execution before current 01022 process unlock */ 01023 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); 01024 01025 return HAL_OK; 01026 } 01027 else 01028 { 01029 return HAL_BUSY; 01030 } 01031 } 01032 01033 /** 01034 * @brief Receive in master/host SMBUS mode an amount of data in non-blocking mode with Interrupt. 01035 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01036 * the configuration information for the specified SMBUS. 01037 * @param DevAddress Target device address: The device 7 bits address value 01038 * in datasheet must be shifted to the left before calling the interface 01039 * @param pData Pointer to data buffer 01040 * @param Size Amount of data to be sent 01041 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition 01042 * @retval HAL status 01043 */ 01044 HAL_StatusTypeDef HAL_SMBUS_Master_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, 01045 uint16_t Size, uint32_t XferOptions) 01046 { 01047 uint32_t tmp; 01048 01049 /* Check the parameters */ 01050 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); 01051 01052 if (hsmbus->State == HAL_SMBUS_STATE_READY) 01053 { 01054 /* Process Locked */ 01055 __HAL_LOCK(hsmbus); 01056 01057 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX; 01058 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 01059 01060 /* Prepare transfer parameters */ 01061 hsmbus->pBuffPtr = pData; 01062 hsmbus->XferCount = Size; 01063 hsmbus->XferOptions = XferOptions; 01064 01065 /* In case of Quick command, remove autoend mode */ 01066 /* Manage the stop generation by software */ 01067 if (hsmbus->pBuffPtr == NULL) 01068 { 01069 hsmbus->XferOptions &= ~SMBUS_AUTOEND_MODE; 01070 } 01071 01072 if (Size > MAX_NBYTE_SIZE) 01073 { 01074 hsmbus->XferSize = MAX_NBYTE_SIZE; 01075 } 01076 else 01077 { 01078 hsmbus->XferSize = Size; 01079 } 01080 01081 /* Send Slave Address */ 01082 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ 01083 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) 01084 { 01085 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, 01086 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), 01087 SMBUS_GENERATE_START_READ); 01088 } 01089 else 01090 { 01091 /* If transfer direction not change, do not generate Restart Condition */ 01092 /* Mean Previous state is same as current state */ 01093 01094 /* Store current volatile XferOptions, Misra rule */ 01095 tmp = hsmbus->XferOptions; 01096 01097 if ((hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) && \ 01098 (IS_SMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0)) 01099 { 01100 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 01101 SMBUS_NO_STARTSTOP); 01102 } 01103 /* Else transfer direction change, so generate Restart with new transfer direction */ 01104 else 01105 { 01106 /* Convert OTHER_xxx XferOptions if any */ 01107 SMBUS_ConvertOtherXferOptions(hsmbus); 01108 01109 /* Handle Transfer */ 01110 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, 01111 hsmbus->XferOptions, 01112 SMBUS_GENERATE_START_READ); 01113 } 01114 } 01115 01116 /* Process Unlocked */ 01117 __HAL_UNLOCK(hsmbus); 01118 01119 /* Note : The SMBUS interrupts must be enabled after unlocking current process 01120 to avoid the risk of SMBUS interrupt handle execution before current 01121 process unlock */ 01122 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); 01123 01124 return HAL_OK; 01125 } 01126 else 01127 { 01128 return HAL_BUSY; 01129 } 01130 } 01131 01132 /** 01133 * @brief Abort a master/host SMBUS process communication with Interrupt. 01134 * @note This abort can be called only if state is ready 01135 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01136 * the configuration information for the specified SMBUS. 01137 * @param DevAddress Target device address: The device 7 bits address value 01138 * in datasheet must be shifted to the left before calling the interface 01139 * @retval HAL status 01140 */ 01141 HAL_StatusTypeDef HAL_SMBUS_Master_Abort_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress) 01142 { 01143 if (hsmbus->State == HAL_SMBUS_STATE_READY) 01144 { 01145 /* Process Locked */ 01146 __HAL_LOCK(hsmbus); 01147 01148 /* Keep the same state as previous */ 01149 /* to perform as well the call of the corresponding end of transfer callback */ 01150 if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_TX) 01151 { 01152 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_TX; 01153 } 01154 else if (hsmbus->PreviousState == HAL_SMBUS_STATE_MASTER_BUSY_RX) 01155 { 01156 hsmbus->State = HAL_SMBUS_STATE_MASTER_BUSY_RX; 01157 } 01158 else 01159 { 01160 /* Wrong usage of abort function */ 01161 /* This function should be used only in case of abort monitored by master device */ 01162 return HAL_ERROR; 01163 } 01164 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 01165 01166 /* Set NBYTES to 1 to generate a dummy read on SMBUS peripheral */ 01167 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ 01168 SMBUS_TransferConfig(hsmbus, DevAddress, 1, SMBUS_AUTOEND_MODE, SMBUS_NO_STARTSTOP); 01169 01170 /* Process Unlocked */ 01171 __HAL_UNLOCK(hsmbus); 01172 01173 /* Note : The SMBUS interrupts must be enabled after unlocking current process 01174 to avoid the risk of SMBUS interrupt handle execution before current 01175 process unlock */ 01176 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) 01177 { 01178 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX); 01179 } 01180 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) 01181 { 01182 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX); 01183 } 01184 else 01185 { 01186 /* Nothing to do */ 01187 } 01188 01189 return HAL_OK; 01190 } 01191 else 01192 { 01193 return HAL_BUSY; 01194 } 01195 } 01196 01197 /** 01198 * @brief Transmit in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. 01199 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01200 * the configuration information for the specified SMBUS. 01201 * @param pData Pointer to data buffer 01202 * @param Size Amount of data to be sent 01203 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition 01204 * @retval HAL status 01205 */ 01206 HAL_StatusTypeDef HAL_SMBUS_Slave_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, 01207 uint32_t XferOptions) 01208 { 01209 /* Check the parameters */ 01210 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); 01211 01212 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) 01213 { 01214 if ((pData == NULL) || (Size == 0UL)) 01215 { 01216 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM; 01217 return HAL_ERROR; 01218 } 01219 01220 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 01221 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_TX); 01222 01223 /* Process Locked */ 01224 __HAL_LOCK(hsmbus); 01225 01226 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_TX | HAL_SMBUS_STATE_LISTEN); 01227 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 01228 01229 /* Set SBC bit to manage Acknowledge at each bit */ 01230 hsmbus->Instance->CR1 |= I2C_CR1_SBC; 01231 01232 /* Enable Address Acknowledge */ 01233 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; 01234 01235 /* Prepare transfer parameters */ 01236 hsmbus->pBuffPtr = pData; 01237 hsmbus->XferCount = Size; 01238 hsmbus->XferOptions = XferOptions; 01239 01240 /* Convert OTHER_xxx XferOptions if any */ 01241 SMBUS_ConvertOtherXferOptions(hsmbus); 01242 01243 if (Size > MAX_NBYTE_SIZE) 01244 { 01245 hsmbus->XferSize = MAX_NBYTE_SIZE; 01246 } 01247 else 01248 { 01249 hsmbus->XferSize = Size; 01250 } 01251 01252 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */ 01253 if ((hsmbus->XferSize < hsmbus->XferCount) && (hsmbus->XferSize == MAX_NBYTE_SIZE)) 01254 { 01255 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, 01256 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), 01257 SMBUS_NO_STARTSTOP); 01258 } 01259 else 01260 { 01261 /* Set NBYTE to transmit */ 01262 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 01263 SMBUS_NO_STARTSTOP); 01264 01265 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ 01266 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ 01267 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) 01268 { 01269 hsmbus->XferSize--; 01270 hsmbus->XferCount--; 01271 } 01272 } 01273 01274 /* Clear ADDR flag after prepare the transfer parameters */ 01275 /* This action will generate an acknowledge to the HOST */ 01276 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); 01277 01278 /* Process Unlocked */ 01279 __HAL_UNLOCK(hsmbus); 01280 01281 /* Note : The SMBUS interrupts must be enabled after unlocking current process 01282 to avoid the risk of SMBUS interrupt handle execution before current 01283 process unlock */ 01284 /* REnable ADDR interrupt */ 01285 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_TX | SMBUS_IT_ADDR); 01286 01287 return HAL_OK; 01288 } 01289 else 01290 { 01291 return HAL_BUSY; 01292 } 01293 } 01294 01295 /** 01296 * @brief Receive in slave/device SMBUS mode an amount of data in non-blocking mode with Interrupt. 01297 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01298 * the configuration information for the specified SMBUS. 01299 * @param pData Pointer to data buffer 01300 * @param Size Amount of data to be sent 01301 * @param XferOptions Options of Transfer, value of @ref SMBUS_XferOptions_definition 01302 * @retval HAL status 01303 */ 01304 HAL_StatusTypeDef HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size, 01305 uint32_t XferOptions) 01306 { 01307 /* Check the parameters */ 01308 assert_param(IS_SMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions)); 01309 01310 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) 01311 { 01312 if ((pData == NULL) || (Size == 0UL)) 01313 { 01314 hsmbus->ErrorCode = HAL_SMBUS_ERROR_INVALID_PARAM; 01315 return HAL_ERROR; 01316 } 01317 01318 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 01319 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR | SMBUS_IT_RX); 01320 01321 /* Process Locked */ 01322 __HAL_LOCK(hsmbus); 01323 01324 hsmbus->State = (HAL_SMBUS_STATE_SLAVE_BUSY_RX | HAL_SMBUS_STATE_LISTEN); 01325 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 01326 01327 /* Set SBC bit to manage Acknowledge at each bit */ 01328 hsmbus->Instance->CR1 |= I2C_CR1_SBC; 01329 01330 /* Enable Address Acknowledge */ 01331 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; 01332 01333 /* Prepare transfer parameters */ 01334 hsmbus->pBuffPtr = pData; 01335 hsmbus->XferSize = Size; 01336 hsmbus->XferCount = Size; 01337 hsmbus->XferOptions = XferOptions; 01338 01339 /* Convert OTHER_xxx XferOptions if any */ 01340 SMBUS_ConvertOtherXferOptions(hsmbus); 01341 01342 /* Set NBYTE to receive */ 01343 /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */ 01344 /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */ 01345 /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */ 01346 /* This RELOAD bit will be reset for last BYTE to be receive in SMBUS_Slave_ISR */ 01347 if (((SMBUS_GET_PEC_MODE(hsmbus) != 0UL) && (hsmbus->XferSize == 2U)) || (hsmbus->XferSize == 1U)) 01348 { 01349 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 01350 SMBUS_NO_STARTSTOP); 01351 } 01352 else 01353 { 01354 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions | SMBUS_RELOAD_MODE, SMBUS_NO_STARTSTOP); 01355 } 01356 01357 /* Clear ADDR flag after prepare the transfer parameters */ 01358 /* This action will generate an acknowledge to the HOST */ 01359 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); 01360 01361 /* Process Unlocked */ 01362 __HAL_UNLOCK(hsmbus); 01363 01364 /* Note : The SMBUS interrupts must be enabled after unlocking current process 01365 to avoid the risk of SMBUS interrupt handle execution before current 01366 process unlock */ 01367 /* REnable ADDR interrupt */ 01368 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_ADDR); 01369 01370 return HAL_OK; 01371 } 01372 else 01373 { 01374 return HAL_BUSY; 01375 } 01376 } 01377 01378 /** 01379 * @brief Enable the Address listen mode with Interrupt. 01380 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01381 * the configuration information for the specified SMBUS. 01382 * @retval HAL status 01383 */ 01384 HAL_StatusTypeDef HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus) 01385 { 01386 hsmbus->State = HAL_SMBUS_STATE_LISTEN; 01387 01388 /* Enable the Address Match interrupt */ 01389 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ADDR); 01390 01391 return HAL_OK; 01392 } 01393 01394 /** 01395 * @brief Disable the Address listen mode with Interrupt. 01396 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01397 * the configuration information for the specified SMBUS. 01398 * @retval HAL status 01399 */ 01400 HAL_StatusTypeDef HAL_SMBUS_DisableListen_IT(SMBUS_HandleTypeDef *hsmbus) 01401 { 01402 /* Disable Address listen mode only if a transfer is not ongoing */ 01403 if (hsmbus->State == HAL_SMBUS_STATE_LISTEN) 01404 { 01405 hsmbus->State = HAL_SMBUS_STATE_READY; 01406 01407 /* Disable the Address Match interrupt */ 01408 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); 01409 01410 return HAL_OK; 01411 } 01412 else 01413 { 01414 return HAL_BUSY; 01415 } 01416 } 01417 01418 /** 01419 * @brief Enable the SMBUS alert mode with Interrupt. 01420 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01421 * the configuration information for the specified SMBUSx peripheral. 01422 * @retval HAL status 01423 */ 01424 HAL_StatusTypeDef HAL_SMBUS_EnableAlert_IT(SMBUS_HandleTypeDef *hsmbus) 01425 { 01426 /* Enable SMBus alert */ 01427 hsmbus->Instance->CR1 |= I2C_CR1_ALERTEN; 01428 01429 /* Clear ALERT flag */ 01430 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); 01431 01432 /* Enable Alert Interrupt */ 01433 SMBUS_Enable_IRQ(hsmbus, SMBUS_IT_ALERT); 01434 01435 return HAL_OK; 01436 } 01437 /** 01438 * @brief Disable the SMBUS alert mode with Interrupt. 01439 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01440 * the configuration information for the specified SMBUSx peripheral. 01441 * @retval HAL status 01442 */ 01443 HAL_StatusTypeDef HAL_SMBUS_DisableAlert_IT(SMBUS_HandleTypeDef *hsmbus) 01444 { 01445 /* Enable SMBus alert */ 01446 hsmbus->Instance->CR1 &= ~I2C_CR1_ALERTEN; 01447 01448 /* Disable Alert Interrupt */ 01449 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ALERT); 01450 01451 return HAL_OK; 01452 } 01453 01454 /** 01455 * @brief Check if target device is ready for communication. 01456 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01457 * the configuration information for the specified SMBUS. 01458 * @param DevAddress Target device address: The device 7 bits address value 01459 * in datasheet must be shifted to the left before calling the interface 01460 * @param Trials Number of trials 01461 * @param Timeout Timeout duration 01462 * @retval HAL status 01463 */ 01464 HAL_StatusTypeDef HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, 01465 uint32_t Timeout) 01466 { 01467 uint32_t tickstart; 01468 01469 __IO uint32_t SMBUS_Trials = 0UL; 01470 01471 FlagStatus tmp1; 01472 FlagStatus tmp2; 01473 01474 if (hsmbus->State == HAL_SMBUS_STATE_READY) 01475 { 01476 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_BUSY) != RESET) 01477 { 01478 return HAL_BUSY; 01479 } 01480 01481 /* Process Locked */ 01482 __HAL_LOCK(hsmbus); 01483 01484 hsmbus->State = HAL_SMBUS_STATE_BUSY; 01485 hsmbus->ErrorCode = HAL_SMBUS_ERROR_NONE; 01486 01487 do 01488 { 01489 /* Generate Start */ 01490 hsmbus->Instance->CR2 = SMBUS_GENERATE_START(hsmbus->Init.AddressingMode, DevAddress); 01491 01492 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 01493 /* Wait until STOPF flag is set or a NACK flag is set*/ 01494 tickstart = HAL_GetTick(); 01495 01496 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01497 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF); 01498 01499 while ((tmp1 == RESET) && (tmp2 == RESET)) 01500 { 01501 if (Timeout != HAL_MAX_DELAY) 01502 { 01503 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) 01504 { 01505 /* Device is ready */ 01506 hsmbus->State = HAL_SMBUS_STATE_READY; 01507 01508 /* Update SMBUS error code */ 01509 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; 01510 01511 /* Process Unlocked */ 01512 __HAL_UNLOCK(hsmbus); 01513 return HAL_ERROR; 01514 } 01515 } 01516 01517 tmp1 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01518 tmp2 = __HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF); 01519 } 01520 01521 /* Check if the NACKF flag has not been set */ 01522 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_AF) == RESET) 01523 { 01524 /* Wait until STOPF flag is reset */ 01525 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) 01526 { 01527 return HAL_ERROR; 01528 } 01529 01530 /* Clear STOP Flag */ 01531 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01532 01533 /* Device is ready */ 01534 hsmbus->State = HAL_SMBUS_STATE_READY; 01535 01536 /* Process Unlocked */ 01537 __HAL_UNLOCK(hsmbus); 01538 01539 return HAL_OK; 01540 } 01541 else 01542 { 01543 /* Wait until STOPF flag is reset */ 01544 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) 01545 { 01546 return HAL_ERROR; 01547 } 01548 01549 /* Clear NACK Flag */ 01550 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); 01551 01552 /* Clear STOP Flag, auto generated with autoend*/ 01553 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01554 } 01555 01556 /* Check if the maximum allowed number of trials has been reached */ 01557 if (SMBUS_Trials == Trials) 01558 { 01559 /* Generate Stop */ 01560 hsmbus->Instance->CR2 |= I2C_CR2_STOP; 01561 01562 /* Wait until STOPF flag is reset */ 01563 if (SMBUS_WaitOnFlagUntilTimeout(hsmbus, SMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK) 01564 { 01565 return HAL_ERROR; 01566 } 01567 01568 /* Clear STOP Flag */ 01569 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01570 } 01571 01572 /* Increment Trials */ 01573 SMBUS_Trials++; 01574 } while (SMBUS_Trials < Trials); 01575 01576 hsmbus->State = HAL_SMBUS_STATE_READY; 01577 01578 /* Update SMBUS error code */ 01579 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; 01580 01581 /* Process Unlocked */ 01582 __HAL_UNLOCK(hsmbus); 01583 01584 return HAL_ERROR; 01585 } 01586 else 01587 { 01588 return HAL_BUSY; 01589 } 01590 } 01591 /** 01592 * @} 01593 */ 01594 01595 /** @defgroup SMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks 01596 * @{ 01597 */ 01598 01599 /** 01600 * @brief Handle SMBUS event interrupt request. 01601 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01602 * the configuration information for the specified SMBUS. 01603 * @retval None 01604 */ 01605 void HAL_SMBUS_EV_IRQHandler(SMBUS_HandleTypeDef *hsmbus) 01606 { 01607 /* Use a local variable to store the current ISR flags */ 01608 /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */ 01609 uint32_t tmpisrvalue = READ_REG(hsmbus->Instance->ISR); 01610 uint32_t tmpcr1value = READ_REG(hsmbus->Instance->CR1); 01611 01612 /* SMBUS in mode Transmitter ---------------------------------------------------*/ 01613 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | 01614 SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) && 01615 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) || 01616 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || 01617 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || 01618 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || 01619 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) 01620 { 01621 /* Slave mode selected */ 01622 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) 01623 { 01624 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); 01625 } 01626 /* Master mode selected */ 01627 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_TX) == HAL_SMBUS_STATE_MASTER_BUSY_TX) 01628 { 01629 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue); 01630 } 01631 else 01632 { 01633 /* Nothing to do */ 01634 } 01635 } 01636 01637 /* SMBUS in mode Receiver ----------------------------------------------------*/ 01638 if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI | 01639 SMBUS_IT_NACKI | SMBUS_IT_RXI)) != RESET) && 01640 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_RXNE) != RESET) || 01641 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) || 01642 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) || 01643 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || 01644 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) 01645 { 01646 /* Slave mode selected */ 01647 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) 01648 { 01649 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); 01650 } 01651 /* Master mode selected */ 01652 else if ((hsmbus->State & HAL_SMBUS_STATE_MASTER_BUSY_RX) == HAL_SMBUS_STATE_MASTER_BUSY_RX) 01653 { 01654 (void)SMBUS_Master_ISR(hsmbus, tmpisrvalue); 01655 } 01656 else 01657 { 01658 /* Nothing to do */ 01659 } 01660 } 01661 01662 /* SMBUS in mode Listener Only --------------------------------------------------*/ 01663 if (((SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_ADDRI) != RESET) || 01664 (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_STOPI) != RESET) || 01665 (SMBUS_CHECK_IT_SOURCE(tmpcr1value, SMBUS_IT_NACKI) != RESET)) && 01666 ((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_ADDR) != RESET) || 01667 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) || 01668 (SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET))) 01669 { 01670 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) 01671 { 01672 (void)SMBUS_Slave_ISR(hsmbus, tmpisrvalue); 01673 } 01674 } 01675 } 01676 01677 /** 01678 * @brief Handle SMBUS error interrupt request. 01679 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01680 * the configuration information for the specified SMBUS. 01681 * @retval None 01682 */ 01683 void HAL_SMBUS_ER_IRQHandler(SMBUS_HandleTypeDef *hsmbus) 01684 { 01685 SMBUS_ITErrorHandler(hsmbus); 01686 } 01687 01688 /** 01689 * @brief Master Tx Transfer completed callback. 01690 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01691 * the configuration information for the specified SMBUS. 01692 * @retval None 01693 */ 01694 __weak void HAL_SMBUS_MasterTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) 01695 { 01696 /* Prevent unused argument(s) compilation warning */ 01697 UNUSED(hsmbus); 01698 01699 /* NOTE : This function should not be modified, when the callback is needed, 01700 the HAL_SMBUS_MasterTxCpltCallback() could be implemented in the user file 01701 */ 01702 } 01703 01704 /** 01705 * @brief Master Rx Transfer completed callback. 01706 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01707 * the configuration information for the specified SMBUS. 01708 * @retval None 01709 */ 01710 __weak void HAL_SMBUS_MasterRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) 01711 { 01712 /* Prevent unused argument(s) compilation warning */ 01713 UNUSED(hsmbus); 01714 01715 /* NOTE : This function should not be modified, when the callback is needed, 01716 the HAL_SMBUS_MasterRxCpltCallback() could be implemented in the user file 01717 */ 01718 } 01719 01720 /** @brief Slave Tx Transfer completed callback. 01721 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01722 * the configuration information for the specified SMBUS. 01723 * @retval None 01724 */ 01725 __weak void HAL_SMBUS_SlaveTxCpltCallback(SMBUS_HandleTypeDef *hsmbus) 01726 { 01727 /* Prevent unused argument(s) compilation warning */ 01728 UNUSED(hsmbus); 01729 01730 /* NOTE : This function should not be modified, when the callback is needed, 01731 the HAL_SMBUS_SlaveTxCpltCallback() could be implemented in the user file 01732 */ 01733 } 01734 01735 /** 01736 * @brief Slave Rx Transfer completed callback. 01737 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01738 * the configuration information for the specified SMBUS. 01739 * @retval None 01740 */ 01741 __weak void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef *hsmbus) 01742 { 01743 /* Prevent unused argument(s) compilation warning */ 01744 UNUSED(hsmbus); 01745 01746 /* NOTE : This function should not be modified, when the callback is needed, 01747 the HAL_SMBUS_SlaveRxCpltCallback() could be implemented in the user file 01748 */ 01749 } 01750 01751 /** 01752 * @brief Slave Address Match callback. 01753 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01754 * the configuration information for the specified SMBUS. 01755 * @param TransferDirection Master request Transfer Direction (Write/Read) 01756 * @param AddrMatchCode Address Match Code 01757 * @retval None 01758 */ 01759 __weak void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, 01760 uint16_t AddrMatchCode) 01761 { 01762 /* Prevent unused argument(s) compilation warning */ 01763 UNUSED(hsmbus); 01764 UNUSED(TransferDirection); 01765 UNUSED(AddrMatchCode); 01766 01767 /* NOTE : This function should not be modified, when the callback is needed, 01768 the HAL_SMBUS_AddrCallback() could be implemented in the user file 01769 */ 01770 } 01771 01772 /** 01773 * @brief Listen Complete callback. 01774 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01775 * the configuration information for the specified SMBUS. 01776 * @retval None 01777 */ 01778 __weak void HAL_SMBUS_ListenCpltCallback(SMBUS_HandleTypeDef *hsmbus) 01779 { 01780 /* Prevent unused argument(s) compilation warning */ 01781 UNUSED(hsmbus); 01782 01783 /* NOTE : This function should not be modified, when the callback is needed, 01784 the HAL_SMBUS_ListenCpltCallback() could be implemented in the user file 01785 */ 01786 } 01787 01788 /** 01789 * @brief SMBUS error callback. 01790 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01791 * the configuration information for the specified SMBUS. 01792 * @retval None 01793 */ 01794 __weak void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus) 01795 { 01796 /* Prevent unused argument(s) compilation warning */ 01797 UNUSED(hsmbus); 01798 01799 /* NOTE : This function should not be modified, when the callback is needed, 01800 the HAL_SMBUS_ErrorCallback() could be implemented in the user file 01801 */ 01802 } 01803 01804 /** 01805 * @} 01806 */ 01807 01808 /** @defgroup SMBUS_Exported_Functions_Group3 Peripheral State and Errors functions 01809 * @brief Peripheral State and Errors functions 01810 * 01811 @verbatim 01812 =============================================================================== 01813 ##### Peripheral State and Errors functions ##### 01814 =============================================================================== 01815 [..] 01816 This subsection permits to get in run-time the status of the peripheral 01817 and the data flow. 01818 01819 @endverbatim 01820 * @{ 01821 */ 01822 01823 /** 01824 * @brief Return the SMBUS handle state. 01825 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01826 * the configuration information for the specified SMBUS. 01827 * @retval HAL state 01828 */ 01829 uint32_t HAL_SMBUS_GetState(SMBUS_HandleTypeDef *hsmbus) 01830 { 01831 /* Return SMBUS handle state */ 01832 return hsmbus->State; 01833 } 01834 01835 /** 01836 * @brief Return the SMBUS error code. 01837 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01838 * the configuration information for the specified SMBUS. 01839 * @retval SMBUS Error Code 01840 */ 01841 uint32_t HAL_SMBUS_GetError(SMBUS_HandleTypeDef *hsmbus) 01842 { 01843 return hsmbus->ErrorCode; 01844 } 01845 01846 /** 01847 * @} 01848 */ 01849 01850 /** 01851 * @} 01852 */ 01853 01854 /** @addtogroup SMBUS_Private_Functions SMBUS Private Functions 01855 * @brief Data transfers Private functions 01856 * @{ 01857 */ 01858 01859 /** 01860 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode. 01861 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 01862 * the configuration information for the specified SMBUS. 01863 * @param StatusFlags Value of Interrupt Flags. 01864 * @retval HAL status 01865 */ 01866 static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags) 01867 { 01868 uint16_t DevAddress; 01869 01870 /* Process Locked */ 01871 __HAL_LOCK(hsmbus); 01872 01873 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET) 01874 { 01875 /* Clear NACK Flag */ 01876 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); 01877 01878 /* Set corresponding Error Code */ 01879 /* No need to generate STOP, it is automatically done */ 01880 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF; 01881 01882 /* Flush TX register */ 01883 SMBUS_Flush_TXDR(hsmbus); 01884 01885 /* Process Unlocked */ 01886 __HAL_UNLOCK(hsmbus); 01887 01888 /* Call the Error callback to inform upper layer */ 01889 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 01890 hsmbus->ErrorCallback(hsmbus); 01891 #else 01892 HAL_SMBUS_ErrorCallback(hsmbus); 01893 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 01894 } 01895 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET) 01896 { 01897 /* Check and treat errors if errors occurs during STOP process */ 01898 SMBUS_ITErrorHandler(hsmbus); 01899 01900 /* Call the corresponding callback to inform upper layer of End of Transfer */ 01901 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) 01902 { 01903 /* Disable Interrupt */ 01904 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); 01905 01906 /* Clear STOP Flag */ 01907 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01908 01909 /* Clear Configuration Register 2 */ 01910 SMBUS_RESET_CR2(hsmbus); 01911 01912 /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */ 01913 /* Disable the selected SMBUS peripheral */ 01914 __HAL_SMBUS_DISABLE(hsmbus); 01915 01916 hsmbus->PreviousState = HAL_SMBUS_STATE_READY; 01917 hsmbus->State = HAL_SMBUS_STATE_READY; 01918 01919 /* Process Unlocked */ 01920 __HAL_UNLOCK(hsmbus); 01921 01922 /* Re-enable the selected SMBUS peripheral */ 01923 __HAL_SMBUS_ENABLE(hsmbus); 01924 01925 /* Call the corresponding callback to inform upper layer of End of Transfer */ 01926 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 01927 hsmbus->MasterTxCpltCallback(hsmbus); 01928 #else 01929 HAL_SMBUS_MasterTxCpltCallback(hsmbus); 01930 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 01931 } 01932 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) 01933 { 01934 /* Store Last receive data if any */ 01935 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) 01936 { 01937 /* Read data from RXDR */ 01938 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); 01939 01940 /* Increment Buffer pointer */ 01941 hsmbus->pBuffPtr++; 01942 01943 if ((hsmbus->XferSize > 0U)) 01944 { 01945 hsmbus->XferSize--; 01946 hsmbus->XferCount--; 01947 } 01948 } 01949 01950 /* Disable Interrupt */ 01951 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); 01952 01953 /* Clear STOP Flag */ 01954 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 01955 01956 /* Clear Configuration Register 2 */ 01957 SMBUS_RESET_CR2(hsmbus); 01958 01959 hsmbus->PreviousState = HAL_SMBUS_STATE_READY; 01960 hsmbus->State = HAL_SMBUS_STATE_READY; 01961 01962 /* Process Unlocked */ 01963 __HAL_UNLOCK(hsmbus); 01964 01965 /* Call the corresponding callback to inform upper layer of End of Transfer */ 01966 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 01967 hsmbus->MasterRxCpltCallback(hsmbus); 01968 #else 01969 HAL_SMBUS_MasterRxCpltCallback(hsmbus); 01970 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 01971 } 01972 else 01973 { 01974 /* Nothing to do */ 01975 } 01976 } 01977 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) 01978 { 01979 /* Read data from RXDR */ 01980 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); 01981 01982 /* Increment Buffer pointer */ 01983 hsmbus->pBuffPtr++; 01984 01985 /* Increment Size counter */ 01986 hsmbus->XferSize--; 01987 hsmbus->XferCount--; 01988 } 01989 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET) 01990 { 01991 /* Write data to TXDR */ 01992 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr; 01993 01994 /* Increment Buffer pointer */ 01995 hsmbus->pBuffPtr++; 01996 01997 /* Increment Size counter */ 01998 hsmbus->XferSize--; 01999 hsmbus->XferCount--; 02000 } 02001 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET) 02002 { 02003 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U)) 02004 { 02005 DevAddress = (uint16_t)(hsmbus->Instance->CR2 & I2C_CR2_SADD); 02006 02007 if (hsmbus->XferCount > MAX_NBYTE_SIZE) 02008 { 02009 SMBUS_TransferConfig(hsmbus, DevAddress, MAX_NBYTE_SIZE, 02010 (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), 02011 SMBUS_NO_STARTSTOP); 02012 hsmbus->XferSize = MAX_NBYTE_SIZE; 02013 } 02014 else 02015 { 02016 hsmbus->XferSize = hsmbus->XferCount; 02017 SMBUS_TransferConfig(hsmbus, DevAddress, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 02018 SMBUS_NO_STARTSTOP); 02019 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ 02020 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ 02021 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) 02022 { 02023 hsmbus->XferSize--; 02024 hsmbus->XferCount--; 02025 } 02026 } 02027 } 02028 else if ((hsmbus->XferCount == 0U) && (hsmbus->XferSize == 0U)) 02029 { 02030 /* Call TxCpltCallback() if no stop mode is set */ 02031 if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) 02032 { 02033 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02034 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) 02035 { 02036 /* Disable Interrupt */ 02037 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); 02038 hsmbus->PreviousState = hsmbus->State; 02039 hsmbus->State = HAL_SMBUS_STATE_READY; 02040 02041 /* Process Unlocked */ 02042 __HAL_UNLOCK(hsmbus); 02043 02044 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02045 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02046 hsmbus->MasterTxCpltCallback(hsmbus); 02047 #else 02048 HAL_SMBUS_MasterTxCpltCallback(hsmbus); 02049 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02050 } 02051 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) 02052 { 02053 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); 02054 hsmbus->PreviousState = hsmbus->State; 02055 hsmbus->State = HAL_SMBUS_STATE_READY; 02056 02057 /* Process Unlocked */ 02058 __HAL_UNLOCK(hsmbus); 02059 02060 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02061 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02062 hsmbus->MasterRxCpltCallback(hsmbus); 02063 #else 02064 HAL_SMBUS_MasterRxCpltCallback(hsmbus); 02065 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02066 } 02067 else 02068 { 02069 /* Nothing to do */ 02070 } 02071 } 02072 } 02073 else 02074 { 02075 /* Nothing to do */ 02076 } 02077 } 02078 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TC) != RESET) 02079 { 02080 if (hsmbus->XferCount == 0U) 02081 { 02082 /* Specific use case for Quick command */ 02083 if (hsmbus->pBuffPtr == NULL) 02084 { 02085 /* Generate a Stop command */ 02086 hsmbus->Instance->CR2 |= I2C_CR2_STOP; 02087 } 02088 /* Call TxCpltCallback() if no stop mode is set */ 02089 else if (SMBUS_GET_STOP_MODE(hsmbus) != SMBUS_AUTOEND_MODE) 02090 { 02091 /* No Generate Stop, to permit restart mode */ 02092 /* The stop will be done at the end of transfer, when SMBUS_AUTOEND_MODE enable */ 02093 02094 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02095 if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_TX) 02096 { 02097 /* Disable Interrupt */ 02098 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); 02099 hsmbus->PreviousState = hsmbus->State; 02100 hsmbus->State = HAL_SMBUS_STATE_READY; 02101 02102 /* Process Unlocked */ 02103 __HAL_UNLOCK(hsmbus); 02104 02105 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02106 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02107 hsmbus->MasterTxCpltCallback(hsmbus); 02108 #else 02109 HAL_SMBUS_MasterTxCpltCallback(hsmbus); 02110 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02111 } 02112 else if (hsmbus->State == HAL_SMBUS_STATE_MASTER_BUSY_RX) 02113 { 02114 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); 02115 hsmbus->PreviousState = hsmbus->State; 02116 hsmbus->State = HAL_SMBUS_STATE_READY; 02117 02118 /* Process Unlocked */ 02119 __HAL_UNLOCK(hsmbus); 02120 02121 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02122 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02123 hsmbus->MasterRxCpltCallback(hsmbus); 02124 #else 02125 HAL_SMBUS_MasterRxCpltCallback(hsmbus); 02126 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02127 } 02128 else 02129 { 02130 /* Nothing to do */ 02131 } 02132 } 02133 else 02134 { 02135 /* Nothing to do */ 02136 } 02137 } 02138 } 02139 else 02140 { 02141 /* Nothing to do */ 02142 } 02143 02144 /* Process Unlocked */ 02145 __HAL_UNLOCK(hsmbus); 02146 02147 return HAL_OK; 02148 } 02149 /** 02150 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode. 02151 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 02152 * the configuration information for the specified SMBUS. 02153 * @param StatusFlags Value of Interrupt Flags. 02154 * @retval HAL status 02155 */ 02156 static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags) 02157 { 02158 uint8_t TransferDirection; 02159 uint16_t SlaveAddrCode; 02160 02161 /* Process Locked */ 02162 __HAL_LOCK(hsmbus); 02163 02164 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_AF) != RESET) 02165 { 02166 /* Check that SMBUS transfer finished */ 02167 /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */ 02168 /* Mean XferCount == 0*/ 02169 /* So clear Flag NACKF only */ 02170 if (hsmbus->XferCount == 0U) 02171 { 02172 /* Clear NACK Flag */ 02173 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); 02174 02175 /* Flush TX register */ 02176 SMBUS_Flush_TXDR(hsmbus); 02177 02178 /* Process Unlocked */ 02179 __HAL_UNLOCK(hsmbus); 02180 } 02181 else 02182 { 02183 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/ 02184 /* Clear NACK Flag */ 02185 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_AF); 02186 02187 /* Set HAL State to "Idle" State, mean to LISTEN state */ 02188 /* So reset Slave Busy state */ 02189 hsmbus->PreviousState = hsmbus->State; 02190 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); 02191 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); 02192 02193 /* Disable RX/TX Interrupts, keep only ADDR Interrupt */ 02194 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); 02195 02196 /* Set ErrorCode corresponding to a Non-Acknowledge */ 02197 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ACKF; 02198 02199 /* Flush TX register */ 02200 SMBUS_Flush_TXDR(hsmbus); 02201 02202 /* Process Unlocked */ 02203 __HAL_UNLOCK(hsmbus); 02204 02205 /* Call the Error callback to inform upper layer */ 02206 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02207 hsmbus->ErrorCallback(hsmbus); 02208 #else 02209 HAL_SMBUS_ErrorCallback(hsmbus); 02210 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02211 } 02212 } 02213 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_ADDR) != RESET) 02214 { 02215 TransferDirection = (uint8_t)(SMBUS_GET_DIR(hsmbus)); 02216 SlaveAddrCode = (uint16_t)(SMBUS_GET_ADDR_MATCH(hsmbus)); 02217 02218 /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/ 02219 /* Other ADDRInterrupt will be treat in next Listen usecase */ 02220 __HAL_SMBUS_DISABLE_IT(hsmbus, SMBUS_IT_ADDRI); 02221 02222 /* Process Unlocked */ 02223 __HAL_UNLOCK(hsmbus); 02224 02225 /* Call Slave Addr callback */ 02226 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02227 hsmbus->AddrCallback(hsmbus, TransferDirection, SlaveAddrCode); 02228 #else 02229 HAL_SMBUS_AddrCallback(hsmbus, TransferDirection, SlaveAddrCode); 02230 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02231 } 02232 else if ((SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_RXNE) != RESET) || 02233 (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TCR) != RESET)) 02234 { 02235 if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX) 02236 { 02237 /* Read data from RXDR */ 02238 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); 02239 02240 /* Increment Buffer pointer */ 02241 hsmbus->pBuffPtr++; 02242 02243 hsmbus->XferSize--; 02244 hsmbus->XferCount--; 02245 02246 if (hsmbus->XferCount == 1U) 02247 { 02248 /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */ 02249 /* or only the last Byte of Transfer */ 02250 /* So reset the RELOAD bit mode */ 02251 hsmbus->XferOptions &= ~SMBUS_RELOAD_MODE; 02252 SMBUS_TransferConfig(hsmbus, 0, 1, hsmbus->XferOptions, SMBUS_NO_STARTSTOP); 02253 } 02254 else if (hsmbus->XferCount == 0U) 02255 { 02256 /* Last Byte is received, disable Interrupt */ 02257 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX); 02258 02259 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_SMBUS_STATE_LISTEN */ 02260 hsmbus->PreviousState = hsmbus->State; 02261 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_RX); 02262 02263 /* Process Unlocked */ 02264 __HAL_UNLOCK(hsmbus); 02265 02266 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02267 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02268 hsmbus->SlaveRxCpltCallback(hsmbus); 02269 #else 02270 HAL_SMBUS_SlaveRxCpltCallback(hsmbus); 02271 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02272 } 02273 else 02274 { 02275 /* Set Reload for next Bytes */ 02276 SMBUS_TransferConfig(hsmbus, 0, 1, 02277 SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE), 02278 SMBUS_NO_STARTSTOP); 02279 02280 /* Ack last Byte Read */ 02281 hsmbus->Instance->CR2 &= ~I2C_CR2_NACK; 02282 } 02283 } 02284 else if ((hsmbus->State & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) 02285 { 02286 if ((hsmbus->XferCount != 0U) && (hsmbus->XferSize == 0U)) 02287 { 02288 if (hsmbus->XferCount > MAX_NBYTE_SIZE) 02289 { 02290 SMBUS_TransferConfig(hsmbus, 0, MAX_NBYTE_SIZE, 02291 (SMBUS_RELOAD_MODE | (hsmbus->XferOptions & SMBUS_SENDPEC_MODE)), 02292 SMBUS_NO_STARTSTOP); 02293 hsmbus->XferSize = MAX_NBYTE_SIZE; 02294 } 02295 else 02296 { 02297 hsmbus->XferSize = hsmbus->XferCount; 02298 SMBUS_TransferConfig(hsmbus, 0, (uint8_t)hsmbus->XferSize, hsmbus->XferOptions, 02299 SMBUS_NO_STARTSTOP); 02300 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */ 02301 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */ 02302 if (SMBUS_GET_PEC_MODE(hsmbus) != 0UL) 02303 { 02304 hsmbus->XferSize--; 02305 hsmbus->XferCount--; 02306 } 02307 } 02308 } 02309 } 02310 else 02311 { 02312 /* Nothing to do */ 02313 } 02314 } 02315 else if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_TXIS) != RESET) 02316 { 02317 /* Write data to TXDR only if XferCount not reach "0" */ 02318 /* A TXIS flag can be set, during STOP treatment */ 02319 /* Check if all Data have already been sent */ 02320 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ 02321 if (hsmbus->XferCount > 0U) 02322 { 02323 /* Write data to TXDR */ 02324 hsmbus->Instance->TXDR = *hsmbus->pBuffPtr; 02325 02326 /* Increment Buffer pointer */ 02327 hsmbus->pBuffPtr++; 02328 02329 hsmbus->XferCount--; 02330 hsmbus->XferSize--; 02331 } 02332 02333 if (hsmbus->XferCount == 0U) 02334 { 02335 /* Last Byte is Transmitted */ 02336 /* Remove HAL_SMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_SMBUS_STATE_LISTEN */ 02337 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_TX); 02338 hsmbus->PreviousState = hsmbus->State; 02339 hsmbus->State &= ~((uint32_t)HAL_SMBUS_STATE_SLAVE_BUSY_TX); 02340 02341 /* Process Unlocked */ 02342 __HAL_UNLOCK(hsmbus); 02343 02344 /* Call the corresponding callback to inform upper layer of End of Transfer */ 02345 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02346 hsmbus->SlaveTxCpltCallback(hsmbus); 02347 #else 02348 HAL_SMBUS_SlaveTxCpltCallback(hsmbus); 02349 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02350 } 02351 } 02352 else 02353 { 02354 /* Nothing to do */ 02355 } 02356 02357 /* Check if STOPF is set */ 02358 if (SMBUS_CHECK_FLAG(StatusFlags, SMBUS_FLAG_STOPF) != RESET) 02359 { 02360 if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN) 02361 { 02362 /* Store Last receive data if any */ 02363 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_RXNE) != RESET) 02364 { 02365 /* Read data from RXDR */ 02366 *hsmbus->pBuffPtr = (uint8_t)(hsmbus->Instance->RXDR); 02367 02368 /* Increment Buffer pointer */ 02369 hsmbus->pBuffPtr++; 02370 02371 if ((hsmbus->XferSize > 0U)) 02372 { 02373 hsmbus->XferSize--; 02374 hsmbus->XferCount--; 02375 } 02376 } 02377 02378 /* Disable RX and TX Interrupts */ 02379 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_RX | SMBUS_IT_TX); 02380 02381 /* Disable ADDR Interrupt */ 02382 SMBUS_Disable_IRQ(hsmbus, SMBUS_IT_ADDR); 02383 02384 /* Disable Address Acknowledge */ 02385 hsmbus->Instance->CR2 |= I2C_CR2_NACK; 02386 02387 /* Clear Configuration Register 2 */ 02388 SMBUS_RESET_CR2(hsmbus); 02389 02390 /* Clear STOP Flag */ 02391 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_STOPF); 02392 02393 /* Clear ADDR flag */ 02394 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ADDR); 02395 02396 hsmbus->XferOptions = 0; 02397 hsmbus->PreviousState = hsmbus->State; 02398 hsmbus->State = HAL_SMBUS_STATE_READY; 02399 02400 /* Process Unlocked */ 02401 __HAL_UNLOCK(hsmbus); 02402 02403 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 02404 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02405 hsmbus->ListenCpltCallback(hsmbus); 02406 #else 02407 HAL_SMBUS_ListenCpltCallback(hsmbus); 02408 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02409 } 02410 } 02411 02412 /* Process Unlocked */ 02413 __HAL_UNLOCK(hsmbus); 02414 02415 return HAL_OK; 02416 } 02417 /** 02418 * @brief Manage the enabling of Interrupts. 02419 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 02420 * the configuration information for the specified SMBUS. 02421 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. 02422 * @retval HAL status 02423 */ 02424 static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest) 02425 { 02426 uint32_t tmpisr = 0UL; 02427 02428 if ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT) 02429 { 02430 /* Enable ERR interrupt */ 02431 tmpisr |= SMBUS_IT_ERRI; 02432 } 02433 02434 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) 02435 { 02436 /* Enable ADDR, STOP interrupt */ 02437 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_ERRI; 02438 } 02439 02440 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) 02441 { 02442 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 02443 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_TXI; 02444 } 02445 02446 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) 02447 { 02448 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 02449 tmpisr |= SMBUS_IT_ERRI | SMBUS_IT_TCI | SMBUS_IT_STOPI | SMBUS_IT_NACKI | SMBUS_IT_RXI; 02450 } 02451 02452 /* Enable interrupts only at the end */ 02453 /* to avoid the risk of SMBUS interrupt handle execution before */ 02454 /* all interrupts requested done */ 02455 __HAL_SMBUS_ENABLE_IT(hsmbus, tmpisr); 02456 } 02457 /** 02458 * @brief Manage the disabling of Interrupts. 02459 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 02460 * the configuration information for the specified SMBUS. 02461 * @param InterruptRequest Value of @ref SMBUS_Interrupt_configuration_definition. 02462 * @retval HAL status 02463 */ 02464 static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest) 02465 { 02466 uint32_t tmpisr = 0UL; 02467 uint32_t tmpstate = hsmbus->State; 02468 02469 if ((tmpstate == HAL_SMBUS_STATE_READY) && ((InterruptRequest & SMBUS_IT_ALERT) == SMBUS_IT_ALERT)) 02470 { 02471 /* Disable ERR interrupt */ 02472 tmpisr |= SMBUS_IT_ERRI; 02473 } 02474 02475 if ((InterruptRequest & SMBUS_IT_TX) == SMBUS_IT_TX) 02476 { 02477 /* Disable TC, STOP, NACK and TXI interrupt */ 02478 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_TXI; 02479 02480 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) 02481 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) 02482 { 02483 /* Disable ERR interrupt */ 02484 tmpisr |= SMBUS_IT_ERRI; 02485 } 02486 02487 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) 02488 { 02489 /* Disable STOP and NACK interrupt */ 02490 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; 02491 } 02492 } 02493 02494 if ((InterruptRequest & SMBUS_IT_RX) == SMBUS_IT_RX) 02495 { 02496 /* Disable TC, STOP, NACK and RXI interrupt */ 02497 tmpisr |= SMBUS_IT_TCI | SMBUS_IT_RXI; 02498 02499 if ((SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) 02500 && ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN)) 02501 { 02502 /* Disable ERR interrupt */ 02503 tmpisr |= SMBUS_IT_ERRI; 02504 } 02505 02506 if ((tmpstate & HAL_SMBUS_STATE_LISTEN) != HAL_SMBUS_STATE_LISTEN) 02507 { 02508 /* Disable STOP and NACK interrupt */ 02509 tmpisr |= SMBUS_IT_STOPI | SMBUS_IT_NACKI; 02510 } 02511 } 02512 02513 if ((InterruptRequest & SMBUS_IT_ADDR) == SMBUS_IT_ADDR) 02514 { 02515 /* Disable ADDR, STOP and NACK interrupt */ 02516 tmpisr |= SMBUS_IT_ADDRI | SMBUS_IT_STOPI | SMBUS_IT_NACKI; 02517 02518 if (SMBUS_GET_ALERT_ENABLED(hsmbus) == 0UL) 02519 { 02520 /* Disable ERR interrupt */ 02521 tmpisr |= SMBUS_IT_ERRI; 02522 } 02523 } 02524 02525 /* Disable interrupts only at the end */ 02526 /* to avoid a breaking situation like at "t" time */ 02527 /* all disable interrupts request are not done */ 02528 __HAL_SMBUS_DISABLE_IT(hsmbus, tmpisr); 02529 } 02530 02531 /** 02532 * @brief SMBUS interrupts error handler. 02533 * @param hsmbus SMBUS handle. 02534 * @retval None 02535 */ 02536 static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus) 02537 { 02538 uint32_t itflags = READ_REG(hsmbus->Instance->ISR); 02539 uint32_t itsources = READ_REG(hsmbus->Instance->CR1); 02540 uint32_t tmpstate; 02541 uint32_t tmperror; 02542 02543 /* SMBUS Bus error interrupt occurred ------------------------------------*/ 02544 if (((itflags & SMBUS_FLAG_BERR) == SMBUS_FLAG_BERR) && \ 02545 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02546 { 02547 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BERR; 02548 02549 /* Clear BERR flag */ 02550 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_BERR); 02551 } 02552 02553 /* SMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/ 02554 if (((itflags & SMBUS_FLAG_OVR) == SMBUS_FLAG_OVR) && \ 02555 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02556 { 02557 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_OVR; 02558 02559 /* Clear OVR flag */ 02560 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_OVR); 02561 } 02562 02563 /* SMBUS Arbitration Loss error interrupt occurred ------------------------------------*/ 02564 if (((itflags & SMBUS_FLAG_ARLO) == SMBUS_FLAG_ARLO) && \ 02565 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02566 { 02567 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ARLO; 02568 02569 /* Clear ARLO flag */ 02570 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ARLO); 02571 } 02572 02573 /* SMBUS Timeout error interrupt occurred ---------------------------------------------*/ 02574 if (((itflags & SMBUS_FLAG_TIMEOUT) == SMBUS_FLAG_TIMEOUT) && \ 02575 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02576 { 02577 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_BUSTIMEOUT; 02578 02579 /* Clear TIMEOUT flag */ 02580 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TIMEOUT); 02581 } 02582 02583 /* SMBUS Alert error interrupt occurred -----------------------------------------------*/ 02584 if (((itflags & SMBUS_FLAG_ALERT) == SMBUS_FLAG_ALERT) && \ 02585 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02586 { 02587 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_ALERT; 02588 02589 /* Clear ALERT flag */ 02590 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_ALERT); 02591 } 02592 02593 /* SMBUS Packet Error Check error interrupt occurred ----------------------------------*/ 02594 if (((itflags & SMBUS_FLAG_PECERR) == SMBUS_FLAG_PECERR) && \ 02595 ((itsources & SMBUS_IT_ERRI) == SMBUS_IT_ERRI)) 02596 { 02597 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_PECERR; 02598 02599 /* Clear PEC error flag */ 02600 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_PECERR); 02601 } 02602 02603 /* Flush TX register */ 02604 SMBUS_Flush_TXDR(hsmbus); 02605 02606 /* Store current volatile hsmbus->ErrorCode, misra rule */ 02607 tmperror = hsmbus->ErrorCode; 02608 02609 /* Call the Error Callback in case of Error detected */ 02610 if ((tmperror != HAL_SMBUS_ERROR_NONE) && (tmperror != HAL_SMBUS_ERROR_ACKF)) 02611 { 02612 /* Do not Reset the HAL state in case of ALERT error */ 02613 if ((tmperror & HAL_SMBUS_ERROR_ALERT) != HAL_SMBUS_ERROR_ALERT) 02614 { 02615 /* Store current volatile hsmbus->State, misra rule */ 02616 tmpstate = hsmbus->State; 02617 02618 if (((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_TX) == HAL_SMBUS_STATE_SLAVE_BUSY_TX) 02619 || ((tmpstate & HAL_SMBUS_STATE_SLAVE_BUSY_RX) == HAL_SMBUS_STATE_SLAVE_BUSY_RX)) 02620 { 02621 /* Reset only HAL_SMBUS_STATE_SLAVE_BUSY_XX */ 02622 /* keep HAL_SMBUS_STATE_LISTEN if set */ 02623 hsmbus->PreviousState = HAL_SMBUS_STATE_READY; 02624 hsmbus->State = HAL_SMBUS_STATE_LISTEN; 02625 } 02626 } 02627 02628 /* Call the Error callback to inform upper layer */ 02629 #if (USE_HAL_SMBUS_REGISTER_CALLBACKS == 1) 02630 hsmbus->ErrorCallback(hsmbus); 02631 #else 02632 HAL_SMBUS_ErrorCallback(hsmbus); 02633 #endif /* USE_HAL_SMBUS_REGISTER_CALLBACKS */ 02634 } 02635 } 02636 02637 /** 02638 * @brief Handle SMBUS Communication Timeout. 02639 * @param hsmbus Pointer to a SMBUS_HandleTypeDef structure that contains 02640 * the configuration information for the specified SMBUS. 02641 * @param Flag Specifies the SMBUS flag to check. 02642 * @param Status The new Flag status (SET or RESET). 02643 * @param Timeout Timeout duration 02644 * @retval HAL status 02645 */ 02646 static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag, 02647 FlagStatus Status, uint32_t Timeout) 02648 { 02649 uint32_t tickstart = HAL_GetTick(); 02650 02651 /* Wait until flag is set */ 02652 while ((FlagStatus)(__HAL_SMBUS_GET_FLAG(hsmbus, Flag)) == Status) 02653 { 02654 /* Check for the Timeout */ 02655 if (Timeout != HAL_MAX_DELAY) 02656 { 02657 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL)) 02658 { 02659 hsmbus->PreviousState = hsmbus->State; 02660 hsmbus->State = HAL_SMBUS_STATE_READY; 02661 02662 /* Update SMBUS error code */ 02663 hsmbus->ErrorCode |= HAL_SMBUS_ERROR_HALTIMEOUT; 02664 02665 /* Process Unlocked */ 02666 __HAL_UNLOCK(hsmbus); 02667 02668 return HAL_ERROR; 02669 } 02670 } 02671 } 02672 02673 return HAL_OK; 02674 } 02675 02676 /** 02677 * @brief SMBUS Tx data register flush process. 02678 * @param hsmbus SMBUS handle. 02679 * @retval None 02680 */ 02681 static void SMBUS_Flush_TXDR(SMBUS_HandleTypeDef *hsmbus) 02682 { 02683 /* If a pending TXIS flag is set */ 02684 /* Write a dummy data in TXDR to clear it */ 02685 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXIS) != RESET) 02686 { 02687 hsmbus->Instance->TXDR = 0x00U; 02688 } 02689 02690 /* Flush TX register if not empty */ 02691 if (__HAL_SMBUS_GET_FLAG(hsmbus, SMBUS_FLAG_TXE) == RESET) 02692 { 02693 __HAL_SMBUS_CLEAR_FLAG(hsmbus, SMBUS_FLAG_TXE); 02694 } 02695 } 02696 02697 /** 02698 * @brief Handle SMBUSx communication when starting transfer or during transfer (TC or TCR flag are set). 02699 * @param hsmbus SMBUS handle. 02700 * @param DevAddress specifies the slave address to be programmed. 02701 * @param Size specifies the number of bytes to be programmed. 02702 * This parameter must be a value between 0 and 255. 02703 * @param Mode New state of the SMBUS START condition generation. 02704 * This parameter can be one or a combination of the following values: 02705 * @arg @ref SMBUS_RELOAD_MODE Enable Reload mode. 02706 * @arg @ref SMBUS_AUTOEND_MODE Enable Automatic end mode. 02707 * @arg @ref SMBUS_SOFTEND_MODE Enable Software end mode and Reload mode. 02708 * @arg @ref SMBUS_SENDPEC_MODE Enable Packet Error Calculation mode. 02709 * @param Request New state of the SMBUS START condition generation. 02710 * This parameter can be one of the following values: 02711 * @arg @ref SMBUS_NO_STARTSTOP Don't Generate stop and start condition. 02712 * @arg @ref SMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0). 02713 * @arg @ref SMBUS_GENERATE_START_READ Generate Restart for read request. 02714 * @arg @ref SMBUS_GENERATE_START_WRITE Generate Restart for write request. 02715 * @retval None 02716 */ 02717 static void SMBUS_TransferConfig(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t Size, 02718 uint32_t Mode, uint32_t Request) 02719 { 02720 /* Check the parameters */ 02721 assert_param(IS_SMBUS_ALL_INSTANCE(hsmbus->Instance)); 02722 assert_param(IS_SMBUS_TRANSFER_MODE(Mode)); 02723 assert_param(IS_SMBUS_TRANSFER_REQUEST(Request)); 02724 02725 /* update CR2 register */ 02726 MODIFY_REG(hsmbus->Instance->CR2, 02727 ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \ 02728 (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - I2C_CR2_RD_WRN_Pos))) | \ 02729 I2C_CR2_START | I2C_CR2_STOP | I2C_CR2_PECBYTE)), \ 02730 (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \ 02731 (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \ 02732 (uint32_t)Mode | (uint32_t)Request)); 02733 } 02734 02735 /** 02736 * @brief Convert SMBUSx OTHER_xxx XferOptions to functional XferOptions. 02737 * @param hsmbus SMBUS handle. 02738 * @retval None 02739 */ 02740 static void SMBUS_ConvertOtherXferOptions(SMBUS_HandleTypeDef *hsmbus) 02741 { 02742 /* if user set XferOptions to SMBUS_OTHER_FRAME_NO_PEC */ 02743 /* it request implicitly to generate a restart condition */ 02744 /* set XferOptions to SMBUS_FIRST_FRAME */ 02745 if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_NO_PEC) 02746 { 02747 hsmbus->XferOptions = SMBUS_FIRST_FRAME; 02748 } 02749 /* else if user set XferOptions to SMBUS_OTHER_FRAME_WITH_PEC */ 02750 /* it request implicitly to generate a restart condition */ 02751 /* set XferOptions to SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE */ 02752 else if (hsmbus->XferOptions == SMBUS_OTHER_FRAME_WITH_PEC) 02753 { 02754 hsmbus->XferOptions = SMBUS_FIRST_FRAME | SMBUS_SENDPEC_MODE; 02755 } 02756 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_NO_PEC */ 02757 /* it request implicitly to generate a restart condition */ 02758 /* then generate a stop condition at the end of transfer */ 02759 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_NO_PEC */ 02760 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_NO_PEC) 02761 { 02762 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_NO_PEC; 02763 } 02764 /* else if user set XferOptions to SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */ 02765 /* it request implicitly to generate a restart condition */ 02766 /* then generate a stop condition at the end of transfer */ 02767 /* set XferOptions to SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */ 02768 else if (hsmbus->XferOptions == SMBUS_OTHER_AND_LAST_FRAME_WITH_PEC) 02769 { 02770 hsmbus->XferOptions = SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC; 02771 } 02772 else 02773 { 02774 /* Nothing to do */ 02775 } 02776 } 02777 /** 02778 * @} 02779 */ 02780 02781 #endif /* HAL_SMBUS_MODULE_ENABLED */ 02782 /** 02783 * @} 02784 */ 02785 02786 /** 02787 * @} 02788 */