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