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