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