STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_fmpi2c.c 00004 * @author MCD Application Team 00005 * @brief FMPI2C HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral State and Errors functions 00011 * 00012 @verbatim 00013 ============================================================================== 00014 ##### How to use this driver ##### 00015 ============================================================================== 00016 [..] 00017 The FMPI2C HAL driver can be used as follows: 00018 00019 (#) Declare a FMPI2C_HandleTypeDef handle structure, for example: 00020 FMPI2C_HandleTypeDef hfmpi2c; 00021 00022 (#)Initialize the FMPI2C low level resources by implementing the HAL_FMPI2C_MspInit() API: 00023 (##) Enable the FMPI2Cx interface clock 00024 (##) FMPI2C pins configuration 00025 (+++) Enable the clock for the FMPI2C GPIOs 00026 (+++) Configure FMPI2C pins as alternate function open-drain 00027 (##) NVIC configuration if you need to use interrupt process 00028 (+++) Configure the FMPI2Cx interrupt priority 00029 (+++) Enable the NVIC FMPI2C IRQ Channel 00030 (##) DMA Configuration if you need to use DMA process 00031 (+++) Declare a DMA_HandleTypeDef handle structure for 00032 the transmit or receive stream 00033 (+++) Enable the DMAx interface clock using 00034 (+++) Configure the DMA handle parameters 00035 (+++) Configure the DMA Tx or Rx stream 00036 (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle 00037 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on 00038 the DMA Tx or Rx stream 00039 00040 (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode, 00041 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure. 00042 00043 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware 00044 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API. 00045 00046 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady() 00047 00048 (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver : 00049 00050 *** Polling mode IO operation *** 00051 ================================= 00052 [..] 00053 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit() 00054 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive() 00055 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit() 00056 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive() 00057 00058 *** Polling mode IO MEM operation *** 00059 ===================================== 00060 [..] 00061 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write() 00062 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read() 00063 00064 00065 *** Interrupt mode IO operation *** 00066 =================================== 00067 [..] 00068 (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT() 00069 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00070 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00071 (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT() 00072 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00073 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00074 (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT() 00075 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00076 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00077 (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT() 00078 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00079 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00080 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00081 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00082 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00083 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00084 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00085 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00086 This action will inform Master to generate a Stop condition to discard the communication. 00087 00088 00089 *** Interrupt mode or DMA mode IO sequential operation *** 00090 ========================================================== 00091 [..] 00092 (@) These interfaces allow to manage a sequential transfer with a repeated start condition 00093 when a direction change during transfer 00094 [..] 00095 (+) A specific option field manage the different steps of a sequential transfer 00096 (+) Option field values are defined through FMPI2C_XFEROPTIONS and are listed below: 00097 (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in no sequential mode 00098 (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address 00099 and data to transfer without a final stop condition 00100 (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address 00101 and data to transfer without a final stop condition, an then permit a call the same master sequential interface 00102 several times (like HAL_FMPI2C_Master_Seq_Transmit_IT() then HAL_FMPI2C_Master_Seq_Transmit_IT() 00103 or HAL_FMPI2C_Master_Seq_Transmit_DMA() then HAL_FMPI2C_Master_Seq_Transmit_DMA()) 00104 (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address 00105 and with new data to transfer if the direction change or manage only the new data to 00106 transfer 00107 if no direction change and without a final stop condition in both cases 00108 (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address 00109 and with new data to transfer if the direction change or manage only the new data to 00110 transfer 00111 if no direction change and with a final stop condition in both cases 00112 (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition 00113 after several call of the same master sequential interface several times 00114 (link with option FMPI2C_FIRST_AND_NEXT_FRAME). 00115 Usage can, transfer several bytes one by one using 00116 HAL_FMPI2C_Master_Seq_Transmit_IT 00117 or HAL_FMPI2C_Master_Seq_Receive_IT 00118 or HAL_FMPI2C_Master_Seq_Transmit_DMA 00119 or HAL_FMPI2C_Master_Seq_Receive_DMA 00120 with option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME. 00121 Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or 00122 Receive sequence permit to call the opposite interface Receive or Transmit 00123 without stopping the communication and so generate a restart condition. 00124 (++) FMPI2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after 00125 each call of the same master sequential 00126 interface. 00127 Usage can, transfer several bytes one by one with a restart with slave address between 00128 each bytes using 00129 HAL_FMPI2C_Master_Seq_Transmit_IT 00130 or HAL_FMPI2C_Master_Seq_Receive_IT 00131 or HAL_FMPI2C_Master_Seq_Transmit_DMA 00132 or HAL_FMPI2C_Master_Seq_Receive_DMA 00133 with option FMPI2C_FIRST_FRAME then FMPI2C_OTHER_FRAME. 00134 Then usage of this option FMPI2C_OTHER_AND_LAST_FRAME at the last frame to help automatic 00135 generation of STOP condition. 00136 00137 (+) Different sequential FMPI2C interfaces are listed below: 00138 (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Seq_Transmit_IT() 00139 or using HAL_FMPI2C_Master_Seq_Transmit_DMA() 00140 (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00141 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00142 (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Seq_Receive_IT() 00143 or using HAL_FMPI2C_Master_Seq_Receive_DMA() 00144 (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00145 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00146 (++) Abort a master IT or DMA FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00147 (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00148 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00149 (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT() 00150 (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can 00151 add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). 00152 (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can 00153 add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback() 00154 (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Seq_Transmit_IT() 00155 or using HAL_FMPI2C_Slave_Seq_Transmit_DMA() 00156 (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00157 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00158 (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Seq_Receive_IT() 00159 or using HAL_FMPI2C_Slave_Seq_Receive_DMA() 00160 (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00161 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00162 (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00163 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00164 (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00165 This action will inform Master to generate a Stop condition to discard the communication. 00166 00167 *** Interrupt mode IO MEM operation *** 00168 ======================================= 00169 [..] 00170 (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using 00171 HAL_FMPI2C_Mem_Write_IT() 00172 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can 00173 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() 00174 (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using 00175 HAL_FMPI2C_Mem_Read_IT() 00176 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can 00177 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() 00178 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00179 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00180 00181 *** DMA mode IO operation *** 00182 ============================== 00183 [..] 00184 (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using 00185 HAL_FMPI2C_Master_Transmit_DMA() 00186 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00187 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00188 (+) Receive in master mode an amount of data in non-blocking mode (DMA) using 00189 HAL_FMPI2C_Master_Receive_DMA() 00190 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00191 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00192 (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using 00193 HAL_FMPI2C_Slave_Transmit_DMA() 00194 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00195 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00196 (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using 00197 HAL_FMPI2C_Slave_Receive_DMA() 00198 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00199 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00200 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00201 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00202 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00203 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00204 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00205 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00206 This action will inform Master to generate a Stop condition to discard the communication. 00207 00208 *** DMA mode IO MEM operation *** 00209 ================================= 00210 [..] 00211 (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using 00212 HAL_FMPI2C_Mem_Write_DMA() 00213 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can 00214 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() 00215 (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using 00216 HAL_FMPI2C_Mem_Read_DMA() 00217 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can 00218 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() 00219 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00220 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00221 00222 00223 *** FMPI2C HAL driver macros list *** 00224 ================================== 00225 [..] 00226 Below the list of most used macros in FMPI2C HAL driver. 00227 00228 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral 00229 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral 00230 (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode 00231 (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not 00232 (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag 00233 (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt 00234 (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt 00235 00236 *** Callback registration *** 00237 ============================================= 00238 [..] 00239 The compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS when set to 1 00240 allows the user to configure dynamically the driver callbacks. 00241 Use Functions HAL_FMPI2C_RegisterCallback() or HAL_FMPI2C_RegisterAddrCallback() 00242 to register an interrupt callback. 00243 [..] 00244 Function HAL_FMPI2C_RegisterCallback() allows to register following callbacks: 00245 (+) MasterTxCpltCallback : callback for Master transmission end of transfer. 00246 (+) MasterRxCpltCallback : callback for Master reception end of transfer. 00247 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. 00248 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. 00249 (+) ListenCpltCallback : callback for end of listen mode. 00250 (+) MemTxCpltCallback : callback for Memory transmission end of transfer. 00251 (+) MemRxCpltCallback : callback for Memory reception end of transfer. 00252 (+) ErrorCallback : callback for error detection. 00253 (+) AbortCpltCallback : callback for abort completion process. 00254 (+) MspInitCallback : callback for Msp Init. 00255 (+) MspDeInitCallback : callback for Msp DeInit. 00256 This function takes as parameters the HAL peripheral handle, the Callback ID 00257 and a pointer to the user callback function. 00258 [..] 00259 For specific callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_RegisterAddrCallback(). 00260 [..] 00261 Use function HAL_FMPI2C_UnRegisterCallback to reset a callback to the default 00262 weak function. 00263 HAL_FMPI2C_UnRegisterCallback takes as parameters the HAL peripheral handle, 00264 and the Callback ID. 00265 This function allows to reset following callbacks: 00266 (+) MasterTxCpltCallback : callback for Master transmission end of transfer. 00267 (+) MasterRxCpltCallback : callback for Master reception end of transfer. 00268 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. 00269 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. 00270 (+) ListenCpltCallback : callback for end of listen mode. 00271 (+) MemTxCpltCallback : callback for Memory transmission end of transfer. 00272 (+) MemRxCpltCallback : callback for Memory reception end of transfer. 00273 (+) ErrorCallback : callback for error detection. 00274 (+) AbortCpltCallback : callback for abort completion process. 00275 (+) MspInitCallback : callback for Msp Init. 00276 (+) MspDeInitCallback : callback for Msp DeInit. 00277 [..] 00278 For callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_UnRegisterAddrCallback(). 00279 [..] 00280 By default, after the HAL_FMPI2C_Init() and when the state is HAL_FMPI2C_STATE_RESET 00281 all callbacks are set to the corresponding weak functions: 00282 examples HAL_FMPI2C_MasterTxCpltCallback(), HAL_FMPI2C_MasterRxCpltCallback(). 00283 Exception done for MspInit and MspDeInit functions that are 00284 reset to the legacy weak functions in the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit() only when 00285 these callbacks are null (not registered beforehand). 00286 If MspInit or MspDeInit are not null, the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit() 00287 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. 00288 [..] 00289 Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only. 00290 Exception done MspInit/MspDeInit functions that can be registered/unregistered 00291 in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state, 00292 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00293 Then, the user first registers the MspInit/MspDeInit user callbacks 00294 using HAL_FMPI2C_RegisterCallback() before calling HAL_FMPI2C_DeInit() 00295 or HAL_FMPI2C_Init() function. 00296 [..] 00297 When the compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS is set to 0 or 00298 not defined, the callback registration feature is not available and all callbacks 00299 are set to the corresponding weak functions. 00300 00301 [..] 00302 (@) You can refer to the FMPI2C HAL driver header file for more useful macros 00303 00304 @endverbatim 00305 ****************************************************************************** 00306 * @attention 00307 * 00308 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00309 * All rights reserved.</center></h2> 00310 * 00311 * This software component is licensed by ST under BSD 3-Clause license, 00312 * the "License"; You may not use this file except in compliance with the 00313 * License. You may obtain a copy of the License at: 00314 * opensource.org/licenses/BSD-3-Clause 00315 * 00316 ****************************************************************************** 00317 */ 00318 00319 /* Includes ------------------------------------------------------------------*/ 00320 #include "stm32f4xx_hal.h" 00321 00322 /** @addtogroup STM32F4xx_HAL_Driver 00323 * @{ 00324 */ 00325 00326 /** @defgroup FMPI2C FMPI2C 00327 * @brief FMPI2C HAL module driver 00328 * @{ 00329 */ 00330 00331 #ifdef HAL_FMPI2C_MODULE_ENABLED 00332 #if defined(FMPI2C_CR1_PE) 00333 00334 /* Private typedef -----------------------------------------------------------*/ 00335 /* Private define ------------------------------------------------------------*/ 00336 00337 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define 00338 * @{ 00339 */ 00340 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< FMPI2C TIMING clear register Mask */ 00341 #define FMPI2C_TIMEOUT_ADDR (10000U) /*!< 10 s */ 00342 #define FMPI2C_TIMEOUT_BUSY (25U) /*!< 25 ms */ 00343 #define FMPI2C_TIMEOUT_DIR (25U) /*!< 25 ms */ 00344 #define FMPI2C_TIMEOUT_RXNE (25U) /*!< 25 ms */ 00345 #define FMPI2C_TIMEOUT_STOPF (25U) /*!< 25 ms */ 00346 #define FMPI2C_TIMEOUT_TC (25U) /*!< 25 ms */ 00347 #define FMPI2C_TIMEOUT_TCR (25U) /*!< 25 ms */ 00348 #define FMPI2C_TIMEOUT_TXIS (25U) /*!< 25 ms */ 00349 #define FMPI2C_TIMEOUT_FLAG (25U) /*!< 25 ms */ 00350 00351 #define MAX_NBYTE_SIZE 255U 00352 #define SLAVE_ADDR_SHIFT 7U 00353 #define SLAVE_ADDR_MSK 0x06U 00354 00355 /* Private define for @ref PreviousState usage */ 00356 #define FMPI2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_FMPI2C_STATE_BUSY_TX | \ 00357 (uint32_t)HAL_FMPI2C_STATE_BUSY_RX) & \ 00358 (uint32_t)(~((uint32_t)HAL_FMPI2C_STATE_READY)))) 00359 /*!< Mask State define, keep only RX and TX bits */ 00360 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE)) 00361 /*!< Default Value */ 00362 #define FMPI2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \ 00363 (uint32_t)HAL_FMPI2C_MODE_MASTER)) 00364 /*!< Master Busy TX, combinaison of State LSB and Mode enum */ 00365 #define FMPI2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \ 00366 (uint32_t)HAL_FMPI2C_MODE_MASTER)) 00367 /*!< Master Busy RX, combinaison of State LSB and Mode enum */ 00368 #define FMPI2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \ 00369 (uint32_t)HAL_FMPI2C_MODE_SLAVE)) 00370 /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ 00371 #define FMPI2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \ 00372 (uint32_t)HAL_FMPI2C_MODE_SLAVE)) 00373 /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ 00374 #define FMPI2C_STATE_MEM_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \ 00375 (uint32_t)HAL_FMPI2C_MODE_MEM)) 00376 /*!< Memory Busy TX, combinaison of State LSB and Mode enum */ 00377 #define FMPI2C_STATE_MEM_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \ 00378 (uint32_t)HAL_FMPI2C_MODE_MEM)) 00379 /*!< Memory Busy RX, combinaison of State LSB and Mode enum */ 00380 00381 00382 /* Private define to centralize the enable/disable of Interrupts */ 00383 #define FMPI2C_XFER_TX_IT (uint16_t)(0x0001U) /*!< Bit field can be combinated with 00384 @ref FMPI2C_XFER_LISTEN_IT */ 00385 #define FMPI2C_XFER_RX_IT (uint16_t)(0x0002U) /*!< Bit field can be combinated with 00386 @ref FMPI2C_XFER_LISTEN_IT */ 00387 #define FMPI2C_XFER_LISTEN_IT (uint16_t)(0x8000U) /*!< Bit field can be combinated with @ref FMPI2C_XFER_TX_IT 00388 and @ref FMPI2C_XFER_RX_IT */ 00389 00390 #define FMPI2C_XFER_ERROR_IT (uint16_t)(0x0010U) /*!< Bit definition to manage addition of global Error 00391 and NACK treatment */ 00392 #define FMPI2C_XFER_CPLT_IT (uint16_t)(0x0020U) /*!< Bit definition to manage only STOP evenement */ 00393 #define FMPI2C_XFER_RELOAD_IT (uint16_t)(0x0040U) /*!< Bit definition to manage only Reload of NBYTE */ 00394 00395 /* Private define Sequential Transfer Options default/reset value */ 00396 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U) 00397 /** 00398 * @} 00399 */ 00400 00401 /* Private macro -------------------------------------------------------------*/ 00402 /* Private variables ---------------------------------------------------------*/ 00403 /* Private function prototypes -----------------------------------------------*/ 00404 00405 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions 00406 * @{ 00407 */ 00408 /* Private functions to handle DMA transfer */ 00409 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); 00410 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); 00411 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); 00412 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); 00413 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma); 00414 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma); 00415 00416 /* Private functions to handle IT transfer */ 00417 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00418 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c); 00419 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c); 00420 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00421 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00422 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00423 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode); 00424 00425 /* Private functions to handle IT transfer */ 00426 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, 00427 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, 00428 uint32_t Tickstart); 00429 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, 00430 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, 00431 uint32_t Tickstart); 00432 00433 /* Private functions for FMPI2C transfer IRQ handler */ 00434 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 00435 uint32_t ITSources); 00436 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 00437 uint32_t ITSources); 00438 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 00439 uint32_t ITSources); 00440 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 00441 uint32_t ITSources); 00442 00443 /* Private functions to handle flags during polling transfer */ 00444 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, 00445 uint32_t Timeout, uint32_t Tickstart); 00446 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 00447 uint32_t Tickstart); 00448 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 00449 uint32_t Tickstart); 00450 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 00451 uint32_t Tickstart); 00452 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 00453 uint32_t Tickstart); 00454 00455 /* Private functions to centralize the enable/disable of Interrupts */ 00456 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); 00457 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); 00458 00459 /* Private function to treat different error callback */ 00460 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c); 00461 00462 /* Private function to flush TXDR register */ 00463 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c); 00464 00465 /* Private function to handle start, restart or stop a transfer */ 00466 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, 00467 uint32_t Request); 00468 00469 /* Private function to Convert Specific options */ 00470 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c); 00471 /** 00472 * @} 00473 */ 00474 00475 /* Exported functions --------------------------------------------------------*/ 00476 00477 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions 00478 * @{ 00479 */ 00480 00481 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions 00482 * @brief Initialization and Configuration functions 00483 * 00484 @verbatim 00485 =============================================================================== 00486 ##### Initialization and de-initialization functions ##### 00487 =============================================================================== 00488 [..] This subsection provides a set of functions allowing to initialize and 00489 deinitialize the FMPI2Cx peripheral: 00490 00491 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures 00492 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). 00493 00494 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with 00495 the selected configuration: 00496 (++) Clock Timing 00497 (++) Own Address 1 00498 (++) Addressing mode (Master, Slave) 00499 (++) Dual Addressing mode 00500 (++) Own Address 2 00501 (++) Own Address 2 Mask 00502 (++) General call mode 00503 (++) Nostretch mode 00504 00505 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration 00506 of the selected FMPI2Cx peripheral. 00507 00508 @endverbatim 00509 * @{ 00510 */ 00511 00512 /** 00513 * @brief Initializes the FMPI2C according to the specified parameters 00514 * in the FMPI2C_InitTypeDef and initialize the associated handle. 00515 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00516 * the configuration information for the specified FMPI2C. 00517 * @retval HAL status 00518 */ 00519 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c) 00520 { 00521 /* Check the FMPI2C handle allocation */ 00522 if (hfmpi2c == NULL) 00523 { 00524 return HAL_ERROR; 00525 } 00526 00527 /* Check the parameters */ 00528 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 00529 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1)); 00530 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode)); 00531 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode)); 00532 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2)); 00533 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks)); 00534 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode)); 00535 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode)); 00536 00537 if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET) 00538 { 00539 /* Allocate lock resource and initialize it */ 00540 hfmpi2c->Lock = HAL_UNLOCKED; 00541 00542 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 00543 /* Init the FMPI2C Callback settings */ 00544 hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ 00545 hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ 00546 hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ 00547 hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ 00548 hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ 00549 hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ 00550 hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ 00551 hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */ 00552 hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 00553 hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */ 00554 00555 if (hfmpi2c->MspInitCallback == NULL) 00556 { 00557 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */ 00558 } 00559 00560 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00561 hfmpi2c->MspInitCallback(hfmpi2c); 00562 #else 00563 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00564 HAL_FMPI2C_MspInit(hfmpi2c); 00565 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 00566 } 00567 00568 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 00569 00570 /* Disable the selected FMPI2C peripheral */ 00571 __HAL_FMPI2C_DISABLE(hfmpi2c); 00572 00573 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/ 00574 /* Configure FMPI2Cx: Frequency range */ 00575 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK; 00576 00577 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/ 00578 /* Disable Own Address1 before set the Own Address1 configuration */ 00579 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN; 00580 00581 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */ 00582 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT) 00583 { 00584 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1); 00585 } 00586 else /* FMPI2C_ADDRESSINGMODE_10BIT */ 00587 { 00588 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1); 00589 } 00590 00591 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/ 00592 /* Configure FMPI2Cx: Addressing Master mode */ 00593 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 00594 { 00595 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10); 00596 } 00597 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ 00598 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK); 00599 00600 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/ 00601 /* Disable Own Address2 before set the Own Address2 configuration */ 00602 hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE; 00603 00604 /* Configure FMPI2Cx: Dual mode and Own Address2 */ 00605 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | \ 00606 (hfmpi2c->Init.OwnAddress2Masks << 8)); 00607 00608 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/ 00609 /* Configure FMPI2Cx: Generalcall and NoStretch mode */ 00610 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode); 00611 00612 /* Enable the selected FMPI2C peripheral */ 00613 __HAL_FMPI2C_ENABLE(hfmpi2c); 00614 00615 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00616 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 00617 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 00618 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00619 00620 return HAL_OK; 00621 } 00622 00623 /** 00624 * @brief DeInitialize the FMPI2C peripheral. 00625 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00626 * the configuration information for the specified FMPI2C. 00627 * @retval HAL status 00628 */ 00629 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c) 00630 { 00631 /* Check the FMPI2C handle allocation */ 00632 if (hfmpi2c == NULL) 00633 { 00634 return HAL_ERROR; 00635 } 00636 00637 /* Check the parameters */ 00638 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 00639 00640 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 00641 00642 /* Disable the FMPI2C Peripheral Clock */ 00643 __HAL_FMPI2C_DISABLE(hfmpi2c); 00644 00645 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 00646 if (hfmpi2c->MspDeInitCallback == NULL) 00647 { 00648 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */ 00649 } 00650 00651 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ 00652 hfmpi2c->MspDeInitCallback(hfmpi2c); 00653 #else 00654 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ 00655 HAL_FMPI2C_MspDeInit(hfmpi2c); 00656 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 00657 00658 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00659 hfmpi2c->State = HAL_FMPI2C_STATE_RESET; 00660 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 00661 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00662 00663 /* Release Lock */ 00664 __HAL_UNLOCK(hfmpi2c); 00665 00666 return HAL_OK; 00667 } 00668 00669 /** 00670 * @brief Initialize the FMPI2C MSP. 00671 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00672 * the configuration information for the specified FMPI2C. 00673 * @retval None 00674 */ 00675 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c) 00676 { 00677 /* Prevent unused argument(s) compilation warning */ 00678 UNUSED(hfmpi2c); 00679 00680 /* NOTE : This function should not be modified, when the callback is needed, 00681 the HAL_FMPI2C_MspInit could be implemented in the user file 00682 */ 00683 } 00684 00685 /** 00686 * @brief DeInitialize the FMPI2C MSP. 00687 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00688 * the configuration information for the specified FMPI2C. 00689 * @retval None 00690 */ 00691 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c) 00692 { 00693 /* Prevent unused argument(s) compilation warning */ 00694 UNUSED(hfmpi2c); 00695 00696 /* NOTE : This function should not be modified, when the callback is needed, 00697 the HAL_FMPI2C_MspDeInit could be implemented in the user file 00698 */ 00699 } 00700 00701 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 00702 /** 00703 * @brief Register a User FMPI2C Callback 00704 * To be used instead of the weak predefined callback 00705 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00706 * the configuration information for the specified FMPI2C. 00707 * @param CallbackID ID of the callback to be registered 00708 * This parameter can be one of the following values: 00709 * @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID 00710 * @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID 00711 * @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID 00712 * @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID 00713 * @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID 00714 * @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID 00715 * @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID 00716 * @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID 00717 * @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID 00718 * @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID 00719 * @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID 00720 * @param pCallback pointer to the Callback function 00721 * @retval HAL status 00722 */ 00723 HAL_StatusTypeDef HAL_FMPI2C_RegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID, 00724 pFMPI2C_CallbackTypeDef pCallback) 00725 { 00726 HAL_StatusTypeDef status = HAL_OK; 00727 00728 if (pCallback == NULL) 00729 { 00730 /* Update the error code */ 00731 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00732 00733 return HAL_ERROR; 00734 } 00735 /* Process locked */ 00736 __HAL_LOCK(hfmpi2c); 00737 00738 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State) 00739 { 00740 switch (CallbackID) 00741 { 00742 case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID : 00743 hfmpi2c->MasterTxCpltCallback = pCallback; 00744 break; 00745 00746 case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID : 00747 hfmpi2c->MasterRxCpltCallback = pCallback; 00748 break; 00749 00750 case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID : 00751 hfmpi2c->SlaveTxCpltCallback = pCallback; 00752 break; 00753 00754 case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID : 00755 hfmpi2c->SlaveRxCpltCallback = pCallback; 00756 break; 00757 00758 case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID : 00759 hfmpi2c->ListenCpltCallback = pCallback; 00760 break; 00761 00762 case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID : 00763 hfmpi2c->MemTxCpltCallback = pCallback; 00764 break; 00765 00766 case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID : 00767 hfmpi2c->MemRxCpltCallback = pCallback; 00768 break; 00769 00770 case HAL_FMPI2C_ERROR_CB_ID : 00771 hfmpi2c->ErrorCallback = pCallback; 00772 break; 00773 00774 case HAL_FMPI2C_ABORT_CB_ID : 00775 hfmpi2c->AbortCpltCallback = pCallback; 00776 break; 00777 00778 case HAL_FMPI2C_MSPINIT_CB_ID : 00779 hfmpi2c->MspInitCallback = pCallback; 00780 break; 00781 00782 case HAL_FMPI2C_MSPDEINIT_CB_ID : 00783 hfmpi2c->MspDeInitCallback = pCallback; 00784 break; 00785 00786 default : 00787 /* Update the error code */ 00788 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00789 00790 /* Return error status */ 00791 status = HAL_ERROR; 00792 break; 00793 } 00794 } 00795 else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State) 00796 { 00797 switch (CallbackID) 00798 { 00799 case HAL_FMPI2C_MSPINIT_CB_ID : 00800 hfmpi2c->MspInitCallback = pCallback; 00801 break; 00802 00803 case HAL_FMPI2C_MSPDEINIT_CB_ID : 00804 hfmpi2c->MspDeInitCallback = pCallback; 00805 break; 00806 00807 default : 00808 /* Update the error code */ 00809 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00810 00811 /* Return error status */ 00812 status = HAL_ERROR; 00813 break; 00814 } 00815 } 00816 else 00817 { 00818 /* Update the error code */ 00819 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00820 00821 /* Return error status */ 00822 status = HAL_ERROR; 00823 } 00824 00825 /* Release Lock */ 00826 __HAL_UNLOCK(hfmpi2c); 00827 return status; 00828 } 00829 00830 /** 00831 * @brief Unregister an FMPI2C Callback 00832 * FMPI2C callback is redirected to the weak predefined callback 00833 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00834 * the configuration information for the specified FMPI2C. 00835 * @param CallbackID ID of the callback to be unregistered 00836 * This parameter can be one of the following values: 00837 * This parameter can be one of the following values: 00838 * @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID 00839 * @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID 00840 * @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID 00841 * @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID 00842 * @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID 00843 * @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID 00844 * @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID 00845 * @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID 00846 * @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID 00847 * @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID 00848 * @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID 00849 * @retval HAL status 00850 */ 00851 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID) 00852 { 00853 HAL_StatusTypeDef status = HAL_OK; 00854 00855 /* Process locked */ 00856 __HAL_LOCK(hfmpi2c); 00857 00858 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State) 00859 { 00860 switch (CallbackID) 00861 { 00862 case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID : 00863 hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ 00864 break; 00865 00866 case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID : 00867 hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ 00868 break; 00869 00870 case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID : 00871 hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ 00872 break; 00873 00874 case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID : 00875 hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ 00876 break; 00877 00878 case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID : 00879 hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ 00880 break; 00881 00882 case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID : 00883 hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ 00884 break; 00885 00886 case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID : 00887 hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ 00888 break; 00889 00890 case HAL_FMPI2C_ERROR_CB_ID : 00891 hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */ 00892 break; 00893 00894 case HAL_FMPI2C_ABORT_CB_ID : 00895 hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ 00896 break; 00897 00898 case HAL_FMPI2C_MSPINIT_CB_ID : 00899 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */ 00900 break; 00901 00902 case HAL_FMPI2C_MSPDEINIT_CB_ID : 00903 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */ 00904 break; 00905 00906 default : 00907 /* Update the error code */ 00908 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00909 00910 /* Return error status */ 00911 status = HAL_ERROR; 00912 break; 00913 } 00914 } 00915 else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State) 00916 { 00917 switch (CallbackID) 00918 { 00919 case HAL_FMPI2C_MSPINIT_CB_ID : 00920 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */ 00921 break; 00922 00923 case HAL_FMPI2C_MSPDEINIT_CB_ID : 00924 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */ 00925 break; 00926 00927 default : 00928 /* Update the error code */ 00929 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00930 00931 /* Return error status */ 00932 status = HAL_ERROR; 00933 break; 00934 } 00935 } 00936 else 00937 { 00938 /* Update the error code */ 00939 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00940 00941 /* Return error status */ 00942 status = HAL_ERROR; 00943 } 00944 00945 /* Release Lock */ 00946 __HAL_UNLOCK(hfmpi2c); 00947 return status; 00948 } 00949 00950 /** 00951 * @brief Register the Slave Address Match FMPI2C Callback 00952 * To be used instead of the weak HAL_FMPI2C_AddrCallback() predefined callback 00953 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00954 * the configuration information for the specified FMPI2C. 00955 * @param pCallback pointer to the Address Match Callback function 00956 * @retval HAL status 00957 */ 00958 HAL_StatusTypeDef HAL_FMPI2C_RegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, pFMPI2C_AddrCallbackTypeDef pCallback) 00959 { 00960 HAL_StatusTypeDef status = HAL_OK; 00961 00962 if (pCallback == NULL) 00963 { 00964 /* Update the error code */ 00965 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00966 00967 return HAL_ERROR; 00968 } 00969 /* Process locked */ 00970 __HAL_LOCK(hfmpi2c); 00971 00972 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State) 00973 { 00974 hfmpi2c->AddrCallback = pCallback; 00975 } 00976 else 00977 { 00978 /* Update the error code */ 00979 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 00980 00981 /* Return error status */ 00982 status = HAL_ERROR; 00983 } 00984 00985 /* Release Lock */ 00986 __HAL_UNLOCK(hfmpi2c); 00987 return status; 00988 } 00989 00990 /** 00991 * @brief UnRegister the Slave Address Match FMPI2C Callback 00992 * Info Ready FMPI2C Callback is redirected to the weak HAL_FMPI2C_AddrCallback() predefined callback 00993 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00994 * the configuration information for the specified FMPI2C. 00995 * @retval HAL status 00996 */ 00997 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c) 00998 { 00999 HAL_StatusTypeDef status = HAL_OK; 01000 01001 /* Process locked */ 01002 __HAL_LOCK(hfmpi2c); 01003 01004 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State) 01005 { 01006 hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */ 01007 } 01008 else 01009 { 01010 /* Update the error code */ 01011 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK; 01012 01013 /* Return error status */ 01014 status = HAL_ERROR; 01015 } 01016 01017 /* Release Lock */ 01018 __HAL_UNLOCK(hfmpi2c); 01019 return status; 01020 } 01021 01022 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 01023 01024 /** 01025 * @} 01026 */ 01027 01028 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions 01029 * @brief Data transfers functions 01030 * 01031 @verbatim 01032 =============================================================================== 01033 ##### IO operation functions ##### 01034 =============================================================================== 01035 [..] 01036 This subsection provides a set of functions allowing to manage the FMPI2C data 01037 transfers. 01038 01039 (#) There are two modes of transfer: 01040 (++) Blocking mode : The communication is performed in the polling mode. 01041 The status of all data processing is returned by the same function 01042 after finishing transfer. 01043 (++) No-Blocking mode : The communication is performed using Interrupts 01044 or DMA. These functions return the status of the transfer startup. 01045 The end of the data processing will be indicated through the 01046 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when 01047 using DMA mode. 01048 01049 (#) Blocking mode functions are : 01050 (++) HAL_FMPI2C_Master_Transmit() 01051 (++) HAL_FMPI2C_Master_Receive() 01052 (++) HAL_FMPI2C_Slave_Transmit() 01053 (++) HAL_FMPI2C_Slave_Receive() 01054 (++) HAL_FMPI2C_Mem_Write() 01055 (++) HAL_FMPI2C_Mem_Read() 01056 (++) HAL_FMPI2C_IsDeviceReady() 01057 01058 (#) No-Blocking mode functions with Interrupt are : 01059 (++) HAL_FMPI2C_Master_Transmit_IT() 01060 (++) HAL_FMPI2C_Master_Receive_IT() 01061 (++) HAL_FMPI2C_Slave_Transmit_IT() 01062 (++) HAL_FMPI2C_Slave_Receive_IT() 01063 (++) HAL_FMPI2C_Mem_Write_IT() 01064 (++) HAL_FMPI2C_Mem_Read_IT() 01065 (++) HAL_FMPI2C_Master_Seq_Transmit_IT() 01066 (++) HAL_FMPI2C_Master_Seq_Receive_IT() 01067 (++) HAL_FMPI2C_Slave_Seq_Transmit_IT() 01068 (++) HAL_FMPI2C_Slave_Seq_Receive_IT() 01069 (++) HAL_FMPI2C_EnableListen_IT() 01070 (++) HAL_FMPI2C_DisableListen_IT() 01071 (++) HAL_FMPI2C_Master_Abort_IT() 01072 01073 (#) No-Blocking mode functions with DMA are : 01074 (++) HAL_FMPI2C_Master_Transmit_DMA() 01075 (++) HAL_FMPI2C_Master_Receive_DMA() 01076 (++) HAL_FMPI2C_Slave_Transmit_DMA() 01077 (++) HAL_FMPI2C_Slave_Receive_DMA() 01078 (++) HAL_FMPI2C_Mem_Write_DMA() 01079 (++) HAL_FMPI2C_Mem_Read_DMA() 01080 (++) HAL_FMPI2C_Master_Seq_Transmit_DMA() 01081 (++) HAL_FMPI2C_Master_Seq_Receive_DMA() 01082 (++) HAL_FMPI2C_Slave_Seq_Transmit_DMA() 01083 (++) HAL_FMPI2C_Slave_Seq_Receive_DMA() 01084 01085 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: 01086 (++) HAL_FMPI2C_MasterTxCpltCallback() 01087 (++) HAL_FMPI2C_MasterRxCpltCallback() 01088 (++) HAL_FMPI2C_SlaveTxCpltCallback() 01089 (++) HAL_FMPI2C_SlaveRxCpltCallback() 01090 (++) HAL_FMPI2C_MemTxCpltCallback() 01091 (++) HAL_FMPI2C_MemRxCpltCallback() 01092 (++) HAL_FMPI2C_AddrCallback() 01093 (++) HAL_FMPI2C_ListenCpltCallback() 01094 (++) HAL_FMPI2C_ErrorCallback() 01095 (++) HAL_FMPI2C_AbortCpltCallback() 01096 01097 @endverbatim 01098 * @{ 01099 */ 01100 01101 /** 01102 * @brief Transmits in master mode an amount of data in blocking mode. 01103 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01104 * the configuration information for the specified FMPI2C. 01105 * @param DevAddress Target device address: The device 7 bits address value 01106 * in datasheet must be shifted to the left before calling the interface 01107 * @param pData Pointer to data buffer 01108 * @param Size Amount of data to be sent 01109 * @param Timeout Timeout duration 01110 * @retval HAL status 01111 */ 01112 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 01113 uint16_t Size, uint32_t Timeout) 01114 { 01115 uint32_t tickstart; 01116 01117 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01118 { 01119 /* Process Locked */ 01120 __HAL_LOCK(hfmpi2c); 01121 01122 /* Init tickstart for timeout management*/ 01123 tickstart = HAL_GetTick(); 01124 01125 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 01126 { 01127 return HAL_ERROR; 01128 } 01129 01130 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01131 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01132 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01133 01134 /* Prepare transfer parameters */ 01135 hfmpi2c->pBuffPtr = pData; 01136 hfmpi2c->XferCount = Size; 01137 hfmpi2c->XferISR = NULL; 01138 01139 /* Send Slave Address */ 01140 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01141 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01142 { 01143 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01144 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 01145 FMPI2C_GENERATE_START_WRITE); 01146 } 01147 else 01148 { 01149 hfmpi2c->XferSize = hfmpi2c->XferCount; 01150 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 01151 FMPI2C_GENERATE_START_WRITE); 01152 } 01153 01154 while (hfmpi2c->XferCount > 0U) 01155 { 01156 /* Wait until TXIS flag is set */ 01157 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01158 { 01159 return HAL_ERROR; 01160 } 01161 /* Write data to TXDR */ 01162 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr; 01163 01164 /* Increment Buffer pointer */ 01165 hfmpi2c->pBuffPtr++; 01166 01167 hfmpi2c->XferCount--; 01168 hfmpi2c->XferSize--; 01169 01170 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U)) 01171 { 01172 /* Wait until TCR flag is set */ 01173 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 01174 { 01175 return HAL_ERROR; 01176 } 01177 01178 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01179 { 01180 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01181 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 01182 FMPI2C_NO_STARTSTOP); 01183 } 01184 else 01185 { 01186 hfmpi2c->XferSize = hfmpi2c->XferCount; 01187 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 01188 FMPI2C_NO_STARTSTOP); 01189 } 01190 } 01191 } 01192 01193 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 01194 /* Wait until STOPF flag is set */ 01195 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01196 { 01197 return HAL_ERROR; 01198 } 01199 01200 /* Clear STOP Flag */ 01201 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01202 01203 /* Clear Configuration Register 2 */ 01204 FMPI2C_RESET_CR2(hfmpi2c); 01205 01206 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01207 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01208 01209 /* Process Unlocked */ 01210 __HAL_UNLOCK(hfmpi2c); 01211 01212 return HAL_OK; 01213 } 01214 else 01215 { 01216 return HAL_BUSY; 01217 } 01218 } 01219 01220 /** 01221 * @brief Receives in master mode an amount of data in blocking mode. 01222 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01223 * the configuration information for the specified FMPI2C. 01224 * @param DevAddress Target device address: The device 7 bits address value 01225 * in datasheet must be shifted to the left before calling the interface 01226 * @param pData Pointer to data buffer 01227 * @param Size Amount of data to be sent 01228 * @param Timeout Timeout duration 01229 * @retval HAL status 01230 */ 01231 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 01232 uint16_t Size, uint32_t Timeout) 01233 { 01234 uint32_t tickstart; 01235 01236 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01237 { 01238 /* Process Locked */ 01239 __HAL_LOCK(hfmpi2c); 01240 01241 /* Init tickstart for timeout management*/ 01242 tickstart = HAL_GetTick(); 01243 01244 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 01245 { 01246 return HAL_ERROR; 01247 } 01248 01249 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01250 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01251 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01252 01253 /* Prepare transfer parameters */ 01254 hfmpi2c->pBuffPtr = pData; 01255 hfmpi2c->XferCount = Size; 01256 hfmpi2c->XferISR = NULL; 01257 01258 /* Send Slave Address */ 01259 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01260 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01261 { 01262 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01263 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 01264 FMPI2C_GENERATE_START_READ); 01265 } 01266 else 01267 { 01268 hfmpi2c->XferSize = hfmpi2c->XferCount; 01269 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 01270 FMPI2C_GENERATE_START_READ); 01271 } 01272 01273 while (hfmpi2c->XferCount > 0U) 01274 { 01275 /* Wait until RXNE flag is set */ 01276 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01277 { 01278 return HAL_ERROR; 01279 } 01280 01281 /* Read data from RXDR */ 01282 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 01283 01284 /* Increment Buffer pointer */ 01285 hfmpi2c->pBuffPtr++; 01286 01287 hfmpi2c->XferSize--; 01288 hfmpi2c->XferCount--; 01289 01290 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U)) 01291 { 01292 /* Wait until TCR flag is set */ 01293 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 01294 { 01295 return HAL_ERROR; 01296 } 01297 01298 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01299 { 01300 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01301 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 01302 FMPI2C_NO_STARTSTOP); 01303 } 01304 else 01305 { 01306 hfmpi2c->XferSize = hfmpi2c->XferCount; 01307 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 01308 FMPI2C_NO_STARTSTOP); 01309 } 01310 } 01311 } 01312 01313 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 01314 /* Wait until STOPF flag is set */ 01315 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01316 { 01317 return HAL_ERROR; 01318 } 01319 01320 /* Clear STOP Flag */ 01321 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01322 01323 /* Clear Configuration Register 2 */ 01324 FMPI2C_RESET_CR2(hfmpi2c); 01325 01326 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01327 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01328 01329 /* Process Unlocked */ 01330 __HAL_UNLOCK(hfmpi2c); 01331 01332 return HAL_OK; 01333 } 01334 else 01335 { 01336 return HAL_BUSY; 01337 } 01338 } 01339 01340 /** 01341 * @brief Transmits in slave mode an amount of data in blocking mode. 01342 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01343 * the configuration information for the specified FMPI2C. 01344 * @param pData Pointer to data buffer 01345 * @param Size Amount of data to be sent 01346 * @param Timeout Timeout duration 01347 * @retval HAL status 01348 */ 01349 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 01350 uint32_t Timeout) 01351 { 01352 uint32_t tickstart; 01353 01354 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01355 { 01356 if ((pData == NULL) || (Size == 0U)) 01357 { 01358 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 01359 return HAL_ERROR; 01360 } 01361 /* Process Locked */ 01362 __HAL_LOCK(hfmpi2c); 01363 01364 /* Init tickstart for timeout management*/ 01365 tickstart = HAL_GetTick(); 01366 01367 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01368 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01369 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01370 01371 /* Prepare transfer parameters */ 01372 hfmpi2c->pBuffPtr = pData; 01373 hfmpi2c->XferCount = Size; 01374 hfmpi2c->XferISR = NULL; 01375 01376 /* Enable Address Acknowledge */ 01377 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01378 01379 /* Wait until ADDR flag is set */ 01380 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 01381 { 01382 /* Disable Address Acknowledge */ 01383 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01384 return HAL_ERROR; 01385 } 01386 01387 /* Clear ADDR flag */ 01388 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 01389 01390 /* If 10bit addressing mode is selected */ 01391 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 01392 { 01393 /* Wait until ADDR flag is set */ 01394 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 01395 { 01396 /* Disable Address Acknowledge */ 01397 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01398 return HAL_ERROR; 01399 } 01400 01401 /* Clear ADDR flag */ 01402 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 01403 } 01404 01405 /* Wait until DIR flag is set Transmitter mode */ 01406 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) 01407 { 01408 /* Disable Address Acknowledge */ 01409 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01410 return HAL_ERROR; 01411 } 01412 01413 while (hfmpi2c->XferCount > 0U) 01414 { 01415 /* Wait until TXIS flag is set */ 01416 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01417 { 01418 /* Disable Address Acknowledge */ 01419 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01420 return HAL_ERROR; 01421 } 01422 01423 /* Write data to TXDR */ 01424 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr; 01425 01426 /* Increment Buffer pointer */ 01427 hfmpi2c->pBuffPtr++; 01428 01429 hfmpi2c->XferCount--; 01430 } 01431 01432 /* Wait until STOP flag is set */ 01433 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01434 { 01435 /* Disable Address Acknowledge */ 01436 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01437 01438 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01439 { 01440 /* Normal use case for Transmitter mode */ 01441 /* A NACK is generated to confirm the end of transfer */ 01442 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01443 } 01444 else 01445 { 01446 return HAL_ERROR; 01447 } 01448 } 01449 01450 /* Clear STOP flag */ 01451 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01452 01453 /* Wait until BUSY flag is reset */ 01454 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) 01455 { 01456 /* Disable Address Acknowledge */ 01457 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01458 return HAL_ERROR; 01459 } 01460 01461 /* Disable Address Acknowledge */ 01462 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01463 01464 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01465 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01466 01467 /* Process Unlocked */ 01468 __HAL_UNLOCK(hfmpi2c); 01469 01470 return HAL_OK; 01471 } 01472 else 01473 { 01474 return HAL_BUSY; 01475 } 01476 } 01477 01478 /** 01479 * @brief Receive in slave mode an amount of data in blocking mode 01480 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01481 * the configuration information for the specified FMPI2C. 01482 * @param pData Pointer to data buffer 01483 * @param Size Amount of data to be sent 01484 * @param Timeout Timeout duration 01485 * @retval HAL status 01486 */ 01487 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 01488 uint32_t Timeout) 01489 { 01490 uint32_t tickstart; 01491 01492 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01493 { 01494 if ((pData == NULL) || (Size == 0U)) 01495 { 01496 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 01497 return HAL_ERROR; 01498 } 01499 /* Process Locked */ 01500 __HAL_LOCK(hfmpi2c); 01501 01502 /* Init tickstart for timeout management*/ 01503 tickstart = HAL_GetTick(); 01504 01505 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01506 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01507 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01508 01509 /* Prepare transfer parameters */ 01510 hfmpi2c->pBuffPtr = pData; 01511 hfmpi2c->XferCount = Size; 01512 hfmpi2c->XferISR = NULL; 01513 01514 /* Enable Address Acknowledge */ 01515 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01516 01517 /* Wait until ADDR flag is set */ 01518 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 01519 { 01520 /* Disable Address Acknowledge */ 01521 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01522 return HAL_ERROR; 01523 } 01524 01525 /* Clear ADDR flag */ 01526 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 01527 01528 /* Wait until DIR flag is reset Receiver mode */ 01529 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) 01530 { 01531 /* Disable Address Acknowledge */ 01532 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01533 return HAL_ERROR; 01534 } 01535 01536 while (hfmpi2c->XferCount > 0U) 01537 { 01538 /* Wait until RXNE flag is set */ 01539 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01540 { 01541 /* Disable Address Acknowledge */ 01542 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01543 01544 /* Store Last receive data if any */ 01545 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) 01546 { 01547 /* Read data from RXDR */ 01548 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 01549 01550 /* Increment Buffer pointer */ 01551 hfmpi2c->pBuffPtr++; 01552 01553 hfmpi2c->XferCount--; 01554 } 01555 01556 return HAL_ERROR; 01557 } 01558 01559 /* Read data from RXDR */ 01560 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 01561 01562 /* Increment Buffer pointer */ 01563 hfmpi2c->pBuffPtr++; 01564 01565 hfmpi2c->XferCount--; 01566 } 01567 01568 /* Wait until STOP flag is set */ 01569 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01570 { 01571 /* Disable Address Acknowledge */ 01572 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01573 return HAL_ERROR; 01574 } 01575 01576 /* Clear STOP flag */ 01577 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01578 01579 /* Wait until BUSY flag is reset */ 01580 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) 01581 { 01582 /* Disable Address Acknowledge */ 01583 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01584 return HAL_ERROR; 01585 } 01586 01587 /* Disable Address Acknowledge */ 01588 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01589 01590 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01591 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01592 01593 /* Process Unlocked */ 01594 __HAL_UNLOCK(hfmpi2c); 01595 01596 return HAL_OK; 01597 } 01598 else 01599 { 01600 return HAL_BUSY; 01601 } 01602 } 01603 01604 /** 01605 * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt 01606 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01607 * the configuration information for the specified FMPI2C. 01608 * @param DevAddress Target device address: The device 7 bits address value 01609 * in datasheet must be shifted to the left before calling the interface 01610 * @param pData Pointer to data buffer 01611 * @param Size Amount of data to be sent 01612 * @retval HAL status 01613 */ 01614 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 01615 uint16_t Size) 01616 { 01617 uint32_t xfermode; 01618 01619 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01620 { 01621 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01622 { 01623 return HAL_BUSY; 01624 } 01625 01626 /* Process Locked */ 01627 __HAL_LOCK(hfmpi2c); 01628 01629 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01630 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01631 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01632 01633 /* Prepare transfer parameters */ 01634 hfmpi2c->pBuffPtr = pData; 01635 hfmpi2c->XferCount = Size; 01636 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01637 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01638 01639 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01640 { 01641 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01642 xfermode = FMPI2C_RELOAD_MODE; 01643 } 01644 else 01645 { 01646 hfmpi2c->XferSize = hfmpi2c->XferCount; 01647 xfermode = FMPI2C_AUTOEND_MODE; 01648 } 01649 01650 /* Send Slave Address */ 01651 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 01652 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); 01653 01654 /* Process Unlocked */ 01655 __HAL_UNLOCK(hfmpi2c); 01656 01657 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01658 to avoid the risk of FMPI2C interrupt handle execution before current 01659 process unlock */ 01660 01661 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01662 /* possible to enable all of these */ 01663 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 01664 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01665 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 01666 01667 return HAL_OK; 01668 } 01669 else 01670 { 01671 return HAL_BUSY; 01672 } 01673 } 01674 01675 /** 01676 * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt 01677 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01678 * the configuration information for the specified FMPI2C. 01679 * @param DevAddress Target device address: The device 7 bits address value 01680 * in datasheet must be shifted to the left before calling the interface 01681 * @param pData Pointer to data buffer 01682 * @param Size Amount of data to be sent 01683 * @retval HAL status 01684 */ 01685 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 01686 uint16_t Size) 01687 { 01688 uint32_t xfermode; 01689 01690 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01691 { 01692 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01693 { 01694 return HAL_BUSY; 01695 } 01696 01697 /* Process Locked */ 01698 __HAL_LOCK(hfmpi2c); 01699 01700 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01701 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01702 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01703 01704 /* Prepare transfer parameters */ 01705 hfmpi2c->pBuffPtr = pData; 01706 hfmpi2c->XferCount = Size; 01707 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01708 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01709 01710 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01711 { 01712 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01713 xfermode = FMPI2C_RELOAD_MODE; 01714 } 01715 else 01716 { 01717 hfmpi2c->XferSize = hfmpi2c->XferCount; 01718 xfermode = FMPI2C_AUTOEND_MODE; 01719 } 01720 01721 /* Send Slave Address */ 01722 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 01723 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 01724 01725 /* Process Unlocked */ 01726 __HAL_UNLOCK(hfmpi2c); 01727 01728 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01729 to avoid the risk of FMPI2C interrupt handle execution before current 01730 process unlock */ 01731 01732 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 01733 /* possible to enable all of these */ 01734 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 01735 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01736 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 01737 01738 return HAL_OK; 01739 } 01740 else 01741 { 01742 return HAL_BUSY; 01743 } 01744 } 01745 01746 /** 01747 * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt 01748 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01749 * the configuration information for the specified FMPI2C. 01750 * @param pData Pointer to data buffer 01751 * @param Size Amount of data to be sent 01752 * @retval HAL status 01753 */ 01754 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01755 { 01756 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01757 { 01758 /* Process Locked */ 01759 __HAL_LOCK(hfmpi2c); 01760 01761 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01762 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01763 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01764 01765 /* Enable Address Acknowledge */ 01766 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01767 01768 /* Prepare transfer parameters */ 01769 hfmpi2c->pBuffPtr = pData; 01770 hfmpi2c->XferCount = Size; 01771 hfmpi2c->XferSize = hfmpi2c->XferCount; 01772 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01773 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 01774 01775 /* Process Unlocked */ 01776 __HAL_UNLOCK(hfmpi2c); 01777 01778 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01779 to avoid the risk of FMPI2C interrupt handle execution before current 01780 process unlock */ 01781 01782 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01783 /* possible to enable all of these */ 01784 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 01785 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01786 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); 01787 01788 return HAL_OK; 01789 } 01790 else 01791 { 01792 return HAL_BUSY; 01793 } 01794 } 01795 01796 /** 01797 * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt 01798 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01799 * the configuration information for the specified FMPI2C. 01800 * @param pData Pointer to data buffer 01801 * @param Size Amount of data to be sent 01802 * @retval HAL status 01803 */ 01804 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01805 { 01806 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01807 { 01808 /* Process Locked */ 01809 __HAL_LOCK(hfmpi2c); 01810 01811 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01812 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01813 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01814 01815 /* Enable Address Acknowledge */ 01816 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01817 01818 /* Prepare transfer parameters */ 01819 hfmpi2c->pBuffPtr = pData; 01820 hfmpi2c->XferCount = Size; 01821 hfmpi2c->XferSize = hfmpi2c->XferCount; 01822 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01823 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 01824 01825 /* Process Unlocked */ 01826 __HAL_UNLOCK(hfmpi2c); 01827 01828 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01829 to avoid the risk of FMPI2C interrupt handle execution before current 01830 process unlock */ 01831 01832 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 01833 /* possible to enable all of these */ 01834 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 01835 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01836 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); 01837 01838 return HAL_OK; 01839 } 01840 else 01841 { 01842 return HAL_BUSY; 01843 } 01844 } 01845 01846 /** 01847 * @brief Transmit in master mode an amount of data in non-blocking mode with DMA 01848 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01849 * the configuration information for the specified FMPI2C. 01850 * @param DevAddress Target device address: The device 7 bits address value 01851 * in datasheet must be shifted to the left before calling the interface 01852 * @param pData Pointer to data buffer 01853 * @param Size Amount of data to be sent 01854 * @retval HAL status 01855 */ 01856 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 01857 uint16_t Size) 01858 { 01859 uint32_t xfermode; 01860 HAL_StatusTypeDef dmaxferstatus; 01861 01862 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01863 { 01864 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01865 { 01866 return HAL_BUSY; 01867 } 01868 01869 /* Process Locked */ 01870 __HAL_LOCK(hfmpi2c); 01871 01872 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01873 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01874 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01875 01876 /* Prepare transfer parameters */ 01877 hfmpi2c->pBuffPtr = pData; 01878 hfmpi2c->XferCount = Size; 01879 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01880 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 01881 01882 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01883 { 01884 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01885 xfermode = FMPI2C_RELOAD_MODE; 01886 } 01887 else 01888 { 01889 hfmpi2c->XferSize = hfmpi2c->XferCount; 01890 xfermode = FMPI2C_AUTOEND_MODE; 01891 } 01892 01893 if (hfmpi2c->XferSize > 0U) 01894 { 01895 if (hfmpi2c->hdmatx != NULL) 01896 { 01897 /* Set the FMPI2C DMA transfer complete callback */ 01898 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; 01899 01900 /* Set the DMA error callback */ 01901 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 01902 01903 /* Set the unused DMA callbacks to NULL */ 01904 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 01905 hfmpi2c->hdmatx->XferAbortCallback = NULL; 01906 01907 /* Enable the DMA stream */ 01908 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, 01909 hfmpi2c->XferSize); 01910 } 01911 else 01912 { 01913 /* Update FMPI2C state */ 01914 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01915 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01916 01917 /* Update FMPI2C error code */ 01918 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 01919 01920 /* Process Unlocked */ 01921 __HAL_UNLOCK(hfmpi2c); 01922 01923 return HAL_ERROR; 01924 } 01925 01926 if (dmaxferstatus == HAL_OK) 01927 { 01928 /* Send Slave Address */ 01929 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01930 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); 01931 01932 /* Update XferCount value */ 01933 hfmpi2c->XferCount -= hfmpi2c->XferSize; 01934 01935 /* Process Unlocked */ 01936 __HAL_UNLOCK(hfmpi2c); 01937 01938 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01939 to avoid the risk of FMPI2C interrupt handle execution before current 01940 process unlock */ 01941 /* Enable ERR and NACK interrupts */ 01942 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 01943 01944 /* Enable DMA Request */ 01945 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 01946 } 01947 else 01948 { 01949 /* Update FMPI2C state */ 01950 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01951 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01952 01953 /* Update FMPI2C error code */ 01954 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 01955 01956 /* Process Unlocked */ 01957 __HAL_UNLOCK(hfmpi2c); 01958 01959 return HAL_ERROR; 01960 } 01961 } 01962 else 01963 { 01964 /* Update Transfer ISR function pointer */ 01965 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01966 01967 /* Send Slave Address */ 01968 /* Set NBYTES to write and generate START condition */ 01969 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 01970 FMPI2C_GENERATE_START_WRITE); 01971 01972 /* Process Unlocked */ 01973 __HAL_UNLOCK(hfmpi2c); 01974 01975 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01976 to avoid the risk of FMPI2C interrupt handle execution before current 01977 process unlock */ 01978 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01979 /* possible to enable all of these */ 01980 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 01981 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01982 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 01983 } 01984 01985 return HAL_OK; 01986 } 01987 else 01988 { 01989 return HAL_BUSY; 01990 } 01991 } 01992 01993 /** 01994 * @brief Receive in master mode an amount of data in non-blocking mode with DMA 01995 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01996 * the configuration information for the specified FMPI2C. 01997 * @param DevAddress Target device address: The device 7 bits address value 01998 * in datasheet must be shifted to the left before calling the interface 01999 * @param pData Pointer to data buffer 02000 * @param Size Amount of data to be sent 02001 * @retval HAL status 02002 */ 02003 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 02004 uint16_t Size) 02005 { 02006 uint32_t xfermode; 02007 HAL_StatusTypeDef dmaxferstatus; 02008 02009 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02010 { 02011 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02012 { 02013 return HAL_BUSY; 02014 } 02015 02016 /* Process Locked */ 02017 __HAL_LOCK(hfmpi2c); 02018 02019 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02020 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 02021 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02022 02023 /* Prepare transfer parameters */ 02024 hfmpi2c->pBuffPtr = pData; 02025 hfmpi2c->XferCount = Size; 02026 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02027 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 02028 02029 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02030 { 02031 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02032 xfermode = FMPI2C_RELOAD_MODE; 02033 } 02034 else 02035 { 02036 hfmpi2c->XferSize = hfmpi2c->XferCount; 02037 xfermode = FMPI2C_AUTOEND_MODE; 02038 } 02039 02040 if (hfmpi2c->XferSize > 0U) 02041 { 02042 if (hfmpi2c->hdmarx != NULL) 02043 { 02044 /* Set the FMPI2C DMA transfer complete callback */ 02045 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; 02046 02047 /* Set the DMA error callback */ 02048 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 02049 02050 /* Set the unused DMA callbacks to NULL */ 02051 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 02052 hfmpi2c->hdmarx->XferAbortCallback = NULL; 02053 02054 /* Enable the DMA stream */ 02055 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, 02056 hfmpi2c->XferSize); 02057 } 02058 else 02059 { 02060 /* Update FMPI2C state */ 02061 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02062 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02063 02064 /* Update FMPI2C error code */ 02065 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 02066 02067 /* Process Unlocked */ 02068 __HAL_UNLOCK(hfmpi2c); 02069 02070 return HAL_ERROR; 02071 } 02072 02073 if (dmaxferstatus == HAL_OK) 02074 { 02075 /* Send Slave Address */ 02076 /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02077 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 02078 02079 /* Update XferCount value */ 02080 hfmpi2c->XferCount -= hfmpi2c->XferSize; 02081 02082 /* Process Unlocked */ 02083 __HAL_UNLOCK(hfmpi2c); 02084 02085 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02086 to avoid the risk of FMPI2C interrupt handle execution before current 02087 process unlock */ 02088 /* Enable ERR and NACK interrupts */ 02089 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 02090 02091 /* Enable DMA Request */ 02092 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 02093 } 02094 else 02095 { 02096 /* Update FMPI2C state */ 02097 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02098 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02099 02100 /* Update FMPI2C error code */ 02101 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 02102 02103 /* Process Unlocked */ 02104 __HAL_UNLOCK(hfmpi2c); 02105 02106 return HAL_ERROR; 02107 } 02108 } 02109 else 02110 { 02111 /* Update Transfer ISR function pointer */ 02112 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02113 02114 /* Send Slave Address */ 02115 /* Set NBYTES to read and generate START condition */ 02116 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 02117 FMPI2C_GENERATE_START_READ); 02118 02119 /* Process Unlocked */ 02120 __HAL_UNLOCK(hfmpi2c); 02121 02122 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02123 to avoid the risk of FMPI2C interrupt handle execution before current 02124 process unlock */ 02125 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 02126 /* possible to enable all of these */ 02127 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 02128 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 02129 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02130 } 02131 02132 return HAL_OK; 02133 } 02134 else 02135 { 02136 return HAL_BUSY; 02137 } 02138 } 02139 02140 /** 02141 * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA 02142 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02143 * the configuration information for the specified FMPI2C. 02144 * @param pData Pointer to data buffer 02145 * @param Size Amount of data to be sent 02146 * @retval HAL status 02147 */ 02148 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 02149 { 02150 HAL_StatusTypeDef dmaxferstatus; 02151 02152 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02153 { 02154 if ((pData == NULL) || (Size == 0U)) 02155 { 02156 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02157 return HAL_ERROR; 02158 } 02159 /* Process Locked */ 02160 __HAL_LOCK(hfmpi2c); 02161 02162 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02163 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 02164 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02165 02166 /* Prepare transfer parameters */ 02167 hfmpi2c->pBuffPtr = pData; 02168 hfmpi2c->XferCount = Size; 02169 hfmpi2c->XferSize = hfmpi2c->XferCount; 02170 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02171 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 02172 02173 if (hfmpi2c->hdmatx != NULL) 02174 { 02175 /* Set the FMPI2C DMA transfer complete callback */ 02176 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt; 02177 02178 /* Set the DMA error callback */ 02179 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 02180 02181 /* Set the unused DMA callbacks to NULL */ 02182 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 02183 hfmpi2c->hdmatx->XferAbortCallback = NULL; 02184 02185 /* Enable the DMA stream */ 02186 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, 02187 hfmpi2c->XferSize); 02188 } 02189 else 02190 { 02191 /* Update FMPI2C state */ 02192 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 02193 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02194 02195 /* Update FMPI2C error code */ 02196 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 02197 02198 /* Process Unlocked */ 02199 __HAL_UNLOCK(hfmpi2c); 02200 02201 return HAL_ERROR; 02202 } 02203 02204 if (dmaxferstatus == HAL_OK) 02205 { 02206 /* Enable Address Acknowledge */ 02207 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 02208 02209 /* Process Unlocked */ 02210 __HAL_UNLOCK(hfmpi2c); 02211 02212 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02213 to avoid the risk of FMPI2C interrupt handle execution before current 02214 process unlock */ 02215 /* Enable ERR, STOP, NACK, ADDR interrupts */ 02216 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 02217 02218 /* Enable DMA Request */ 02219 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 02220 } 02221 else 02222 { 02223 /* Update FMPI2C state */ 02224 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 02225 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02226 02227 /* Update FMPI2C error code */ 02228 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 02229 02230 /* Process Unlocked */ 02231 __HAL_UNLOCK(hfmpi2c); 02232 02233 return HAL_ERROR; 02234 } 02235 02236 return HAL_OK; 02237 } 02238 else 02239 { 02240 return HAL_BUSY; 02241 } 02242 } 02243 02244 /** 02245 * @brief Receive in slave mode an amount of data in non-blocking mode with DMA 02246 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02247 * the configuration information for the specified FMPI2C. 02248 * @param pData Pointer to data buffer 02249 * @param Size Amount of data to be sent 02250 * @retval HAL status 02251 */ 02252 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 02253 { 02254 HAL_StatusTypeDef dmaxferstatus; 02255 02256 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02257 { 02258 if ((pData == NULL) || (Size == 0U)) 02259 { 02260 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02261 return HAL_ERROR; 02262 } 02263 /* Process Locked */ 02264 __HAL_LOCK(hfmpi2c); 02265 02266 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02267 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 02268 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02269 02270 /* Prepare transfer parameters */ 02271 hfmpi2c->pBuffPtr = pData; 02272 hfmpi2c->XferCount = Size; 02273 hfmpi2c->XferSize = hfmpi2c->XferCount; 02274 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02275 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 02276 02277 if (hfmpi2c->hdmarx != NULL) 02278 { 02279 /* Set the FMPI2C DMA transfer complete callback */ 02280 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt; 02281 02282 /* Set the DMA error callback */ 02283 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 02284 02285 /* Set the unused DMA callbacks to NULL */ 02286 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 02287 hfmpi2c->hdmarx->XferAbortCallback = NULL; 02288 02289 /* Enable the DMA stream */ 02290 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, 02291 hfmpi2c->XferSize); 02292 } 02293 else 02294 { 02295 /* Update FMPI2C state */ 02296 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 02297 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02298 02299 /* Update FMPI2C error code */ 02300 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 02301 02302 /* Process Unlocked */ 02303 __HAL_UNLOCK(hfmpi2c); 02304 02305 return HAL_ERROR; 02306 } 02307 02308 if (dmaxferstatus == HAL_OK) 02309 { 02310 /* Enable Address Acknowledge */ 02311 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 02312 02313 /* Process Unlocked */ 02314 __HAL_UNLOCK(hfmpi2c); 02315 02316 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02317 to avoid the risk of FMPI2C interrupt handle execution before current 02318 process unlock */ 02319 /* Enable ERR, STOP, NACK, ADDR interrupts */ 02320 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 02321 02322 /* Enable DMA Request */ 02323 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 02324 } 02325 else 02326 { 02327 /* Update FMPI2C state */ 02328 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 02329 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02330 02331 /* Update FMPI2C error code */ 02332 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 02333 02334 /* Process Unlocked */ 02335 __HAL_UNLOCK(hfmpi2c); 02336 02337 return HAL_ERROR; 02338 } 02339 02340 return HAL_OK; 02341 } 02342 else 02343 { 02344 return HAL_BUSY; 02345 } 02346 } 02347 /** 02348 * @brief Write an amount of data in blocking mode to a specific memory address 02349 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02350 * the configuration information for the specified FMPI2C. 02351 * @param DevAddress Target device address: The device 7 bits address value 02352 * in datasheet must be shifted to the left before calling the interface 02353 * @param MemAddress Internal memory address 02354 * @param MemAddSize Size of internal memory address 02355 * @param pData Pointer to data buffer 02356 * @param Size Amount of data to be sent 02357 * @param Timeout Timeout duration 02358 * @retval HAL status 02359 */ 02360 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02361 uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) 02362 { 02363 uint32_t tickstart; 02364 02365 /* Check the parameters */ 02366 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02367 02368 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02369 { 02370 if ((pData == NULL) || (Size == 0U)) 02371 { 02372 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02373 return HAL_ERROR; 02374 } 02375 02376 /* Process Locked */ 02377 __HAL_LOCK(hfmpi2c); 02378 02379 /* Init tickstart for timeout management*/ 02380 tickstart = HAL_GetTick(); 02381 02382 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 02383 { 02384 return HAL_ERROR; 02385 } 02386 02387 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02388 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02389 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02390 02391 /* Prepare transfer parameters */ 02392 hfmpi2c->pBuffPtr = pData; 02393 hfmpi2c->XferCount = Size; 02394 hfmpi2c->XferISR = NULL; 02395 02396 /* Send Slave Address and Memory Address */ 02397 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) 02398 { 02399 /* Process Unlocked */ 02400 __HAL_UNLOCK(hfmpi2c); 02401 return HAL_ERROR; 02402 } 02403 02404 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 02405 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02406 { 02407 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02408 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 02409 } 02410 else 02411 { 02412 hfmpi2c->XferSize = hfmpi2c->XferCount; 02413 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 02414 } 02415 02416 do 02417 { 02418 /* Wait until TXIS flag is set */ 02419 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 02420 { 02421 return HAL_ERROR; 02422 } 02423 02424 /* Write data to TXDR */ 02425 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr; 02426 02427 /* Increment Buffer pointer */ 02428 hfmpi2c->pBuffPtr++; 02429 02430 hfmpi2c->XferCount--; 02431 hfmpi2c->XferSize--; 02432 02433 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U)) 02434 { 02435 /* Wait until TCR flag is set */ 02436 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 02437 { 02438 return HAL_ERROR; 02439 } 02440 02441 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02442 { 02443 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02444 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 02445 FMPI2C_NO_STARTSTOP); 02446 } 02447 else 02448 { 02449 hfmpi2c->XferSize = hfmpi2c->XferCount; 02450 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 02451 FMPI2C_NO_STARTSTOP); 02452 } 02453 } 02454 02455 } while (hfmpi2c->XferCount > 0U); 02456 02457 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 02458 /* Wait until STOPF flag is reset */ 02459 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 02460 { 02461 return HAL_ERROR; 02462 } 02463 02464 /* Clear STOP Flag */ 02465 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02466 02467 /* Clear Configuration Register 2 */ 02468 FMPI2C_RESET_CR2(hfmpi2c); 02469 02470 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02471 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02472 02473 /* Process Unlocked */ 02474 __HAL_UNLOCK(hfmpi2c); 02475 02476 return HAL_OK; 02477 } 02478 else 02479 { 02480 return HAL_BUSY; 02481 } 02482 } 02483 02484 /** 02485 * @brief Read an amount of data in blocking mode from a specific memory address 02486 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02487 * the configuration information for the specified FMPI2C. 02488 * @param DevAddress Target device address: The device 7 bits address value 02489 * in datasheet must be shifted to the left before calling the interface 02490 * @param MemAddress Internal memory address 02491 * @param MemAddSize Size of internal memory address 02492 * @param pData Pointer to data buffer 02493 * @param Size Amount of data to be sent 02494 * @param Timeout Timeout duration 02495 * @retval HAL status 02496 */ 02497 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02498 uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) 02499 { 02500 uint32_t tickstart; 02501 02502 /* Check the parameters */ 02503 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02504 02505 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02506 { 02507 if ((pData == NULL) || (Size == 0U)) 02508 { 02509 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02510 return HAL_ERROR; 02511 } 02512 02513 /* Process Locked */ 02514 __HAL_LOCK(hfmpi2c); 02515 02516 /* Init tickstart for timeout management*/ 02517 tickstart = HAL_GetTick(); 02518 02519 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 02520 { 02521 return HAL_ERROR; 02522 } 02523 02524 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02525 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02526 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02527 02528 /* Prepare transfer parameters */ 02529 hfmpi2c->pBuffPtr = pData; 02530 hfmpi2c->XferCount = Size; 02531 hfmpi2c->XferISR = NULL; 02532 02533 /* Send Slave Address and Memory Address */ 02534 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) 02535 { 02536 /* Process Unlocked */ 02537 __HAL_UNLOCK(hfmpi2c); 02538 return HAL_ERROR; 02539 } 02540 02541 /* Send Slave Address */ 02542 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02543 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02544 { 02545 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02546 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 02547 FMPI2C_GENERATE_START_READ); 02548 } 02549 else 02550 { 02551 hfmpi2c->XferSize = hfmpi2c->XferCount; 02552 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 02553 FMPI2C_GENERATE_START_READ); 02554 } 02555 02556 do 02557 { 02558 /* Wait until RXNE flag is set */ 02559 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) 02560 { 02561 return HAL_ERROR; 02562 } 02563 02564 /* Read data from RXDR */ 02565 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 02566 02567 /* Increment Buffer pointer */ 02568 hfmpi2c->pBuffPtr++; 02569 02570 hfmpi2c->XferSize--; 02571 hfmpi2c->XferCount--; 02572 02573 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U)) 02574 { 02575 /* Wait until TCR flag is set */ 02576 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 02577 { 02578 return HAL_ERROR; 02579 } 02580 02581 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02582 { 02583 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02584 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t) hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, 02585 FMPI2C_NO_STARTSTOP); 02586 } 02587 else 02588 { 02589 hfmpi2c->XferSize = hfmpi2c->XferCount; 02590 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 02591 FMPI2C_NO_STARTSTOP); 02592 } 02593 } 02594 } while (hfmpi2c->XferCount > 0U); 02595 02596 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 02597 /* Wait until STOPF flag is reset */ 02598 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 02599 { 02600 return HAL_ERROR; 02601 } 02602 02603 /* Clear STOP Flag */ 02604 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02605 02606 /* Clear Configuration Register 2 */ 02607 FMPI2C_RESET_CR2(hfmpi2c); 02608 02609 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02610 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02611 02612 /* Process Unlocked */ 02613 __HAL_UNLOCK(hfmpi2c); 02614 02615 return HAL_OK; 02616 } 02617 else 02618 { 02619 return HAL_BUSY; 02620 } 02621 } 02622 /** 02623 * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address 02624 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02625 * the configuration information for the specified FMPI2C. 02626 * @param DevAddress Target device address: The device 7 bits address value 02627 * in datasheet must be shifted to the left before calling the interface 02628 * @param MemAddress Internal memory address 02629 * @param MemAddSize Size of internal memory address 02630 * @param pData Pointer to data buffer 02631 * @param Size Amount of data to be sent 02632 * @retval HAL status 02633 */ 02634 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02635 uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02636 { 02637 uint32_t tickstart; 02638 uint32_t xfermode; 02639 02640 /* Check the parameters */ 02641 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02642 02643 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02644 { 02645 if ((pData == NULL) || (Size == 0U)) 02646 { 02647 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02648 return HAL_ERROR; 02649 } 02650 02651 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02652 { 02653 return HAL_BUSY; 02654 } 02655 02656 /* Process Locked */ 02657 __HAL_LOCK(hfmpi2c); 02658 02659 /* Init tickstart for timeout management*/ 02660 tickstart = HAL_GetTick(); 02661 02662 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02663 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02664 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02665 02666 /* Prepare transfer parameters */ 02667 hfmpi2c->pBuffPtr = pData; 02668 hfmpi2c->XferCount = Size; 02669 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02670 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02671 02672 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02673 { 02674 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02675 xfermode = FMPI2C_RELOAD_MODE; 02676 } 02677 else 02678 { 02679 hfmpi2c->XferSize = hfmpi2c->XferCount; 02680 xfermode = FMPI2C_AUTOEND_MODE; 02681 } 02682 02683 /* Send Slave Address and Memory Address */ 02684 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) 02685 != HAL_OK) 02686 { 02687 /* Process Unlocked */ 02688 __HAL_UNLOCK(hfmpi2c); 02689 return HAL_ERROR; 02690 } 02691 02692 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02693 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 02694 02695 /* Process Unlocked */ 02696 __HAL_UNLOCK(hfmpi2c); 02697 02698 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02699 to avoid the risk of FMPI2C interrupt handle execution before current 02700 process unlock */ 02701 02702 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 02703 /* possible to enable all of these */ 02704 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 02705 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 02706 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02707 02708 return HAL_OK; 02709 } 02710 else 02711 { 02712 return HAL_BUSY; 02713 } 02714 } 02715 02716 /** 02717 * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address 02718 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02719 * the configuration information for the specified FMPI2C. 02720 * @param DevAddress Target device address: The device 7 bits address value 02721 * in datasheet must be shifted to the left before calling the interface 02722 * @param MemAddress Internal memory address 02723 * @param MemAddSize Size of internal memory address 02724 * @param pData Pointer to data buffer 02725 * @param Size Amount of data to be sent 02726 * @retval HAL status 02727 */ 02728 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02729 uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02730 { 02731 uint32_t tickstart; 02732 uint32_t xfermode; 02733 02734 /* Check the parameters */ 02735 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02736 02737 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02738 { 02739 if ((pData == NULL) || (Size == 0U)) 02740 { 02741 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02742 return HAL_ERROR; 02743 } 02744 02745 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02746 { 02747 return HAL_BUSY; 02748 } 02749 02750 /* Process Locked */ 02751 __HAL_LOCK(hfmpi2c); 02752 02753 /* Init tickstart for timeout management*/ 02754 tickstart = HAL_GetTick(); 02755 02756 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02757 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02758 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02759 02760 /* Prepare transfer parameters */ 02761 hfmpi2c->pBuffPtr = pData; 02762 hfmpi2c->XferCount = Size; 02763 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02764 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02765 02766 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02767 { 02768 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02769 xfermode = FMPI2C_RELOAD_MODE; 02770 } 02771 else 02772 { 02773 hfmpi2c->XferSize = hfmpi2c->XferCount; 02774 xfermode = FMPI2C_AUTOEND_MODE; 02775 } 02776 02777 /* Send Slave Address and Memory Address */ 02778 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 02779 { 02780 /* Process Unlocked */ 02781 __HAL_UNLOCK(hfmpi2c); 02782 return HAL_ERROR; 02783 } 02784 02785 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02786 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 02787 02788 /* Process Unlocked */ 02789 __HAL_UNLOCK(hfmpi2c); 02790 02791 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02792 to avoid the risk of FMPI2C interrupt handle execution before current 02793 process unlock */ 02794 02795 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 02796 /* possible to enable all of these */ 02797 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 02798 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 02799 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 02800 02801 return HAL_OK; 02802 } 02803 else 02804 { 02805 return HAL_BUSY; 02806 } 02807 } 02808 /** 02809 * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address 02810 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02811 * the configuration information for the specified FMPI2C. 02812 * @param DevAddress Target device address: The device 7 bits address value 02813 * in datasheet must be shifted to the left before calling the interface 02814 * @param MemAddress Internal memory address 02815 * @param MemAddSize Size of internal memory address 02816 * @param pData Pointer to data buffer 02817 * @param Size Amount of data to be sent 02818 * @retval HAL status 02819 */ 02820 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02821 uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02822 { 02823 uint32_t tickstart; 02824 uint32_t xfermode; 02825 HAL_StatusTypeDef dmaxferstatus; 02826 02827 /* Check the parameters */ 02828 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02829 02830 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02831 { 02832 if ((pData == NULL) || (Size == 0U)) 02833 { 02834 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02835 return HAL_ERROR; 02836 } 02837 02838 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02839 { 02840 return HAL_BUSY; 02841 } 02842 02843 /* Process Locked */ 02844 __HAL_LOCK(hfmpi2c); 02845 02846 /* Init tickstart for timeout management*/ 02847 tickstart = HAL_GetTick(); 02848 02849 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02850 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02851 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02852 02853 /* Prepare transfer parameters */ 02854 hfmpi2c->pBuffPtr = pData; 02855 hfmpi2c->XferCount = Size; 02856 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02857 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 02858 02859 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02860 { 02861 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02862 xfermode = FMPI2C_RELOAD_MODE; 02863 } 02864 else 02865 { 02866 hfmpi2c->XferSize = hfmpi2c->XferCount; 02867 xfermode = FMPI2C_AUTOEND_MODE; 02868 } 02869 02870 /* Send Slave Address and Memory Address */ 02871 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) 02872 != HAL_OK) 02873 { 02874 /* Process Unlocked */ 02875 __HAL_UNLOCK(hfmpi2c); 02876 return HAL_ERROR; 02877 } 02878 02879 02880 if (hfmpi2c->hdmatx != NULL) 02881 { 02882 /* Set the FMPI2C DMA transfer complete callback */ 02883 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; 02884 02885 /* Set the DMA error callback */ 02886 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 02887 02888 /* Set the unused DMA callbacks to NULL */ 02889 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 02890 hfmpi2c->hdmatx->XferAbortCallback = NULL; 02891 02892 /* Enable the DMA stream */ 02893 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, 02894 hfmpi2c->XferSize); 02895 } 02896 else 02897 { 02898 /* Update FMPI2C state */ 02899 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02900 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02901 02902 /* Update FMPI2C error code */ 02903 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 02904 02905 /* Process Unlocked */ 02906 __HAL_UNLOCK(hfmpi2c); 02907 02908 return HAL_ERROR; 02909 } 02910 02911 if (dmaxferstatus == HAL_OK) 02912 { 02913 /* Send Slave Address */ 02914 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02915 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 02916 02917 /* Update XferCount value */ 02918 hfmpi2c->XferCount -= hfmpi2c->XferSize; 02919 02920 /* Process Unlocked */ 02921 __HAL_UNLOCK(hfmpi2c); 02922 02923 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02924 to avoid the risk of FMPI2C interrupt handle execution before current 02925 process unlock */ 02926 /* Enable ERR and NACK interrupts */ 02927 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 02928 02929 /* Enable DMA Request */ 02930 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 02931 } 02932 else 02933 { 02934 /* Update FMPI2C state */ 02935 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02936 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02937 02938 /* Update FMPI2C error code */ 02939 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 02940 02941 /* Process Unlocked */ 02942 __HAL_UNLOCK(hfmpi2c); 02943 02944 return HAL_ERROR; 02945 } 02946 02947 return HAL_OK; 02948 } 02949 else 02950 { 02951 return HAL_BUSY; 02952 } 02953 } 02954 02955 /** 02956 * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. 02957 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02958 * the configuration information for the specified FMPI2C. 02959 * @param DevAddress Target device address: The device 7 bits address value 02960 * in datasheet must be shifted to the left before calling the interface 02961 * @param MemAddress Internal memory address 02962 * @param MemAddSize Size of internal memory address 02963 * @param pData Pointer to data buffer 02964 * @param Size Amount of data to be read 02965 * @retval HAL status 02966 */ 02967 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, 02968 uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02969 { 02970 uint32_t tickstart; 02971 uint32_t xfermode; 02972 HAL_StatusTypeDef dmaxferstatus; 02973 02974 /* Check the parameters */ 02975 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02976 02977 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02978 { 02979 if ((pData == NULL) || (Size == 0U)) 02980 { 02981 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 02982 return HAL_ERROR; 02983 } 02984 02985 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02986 { 02987 return HAL_BUSY; 02988 } 02989 02990 /* Process Locked */ 02991 __HAL_LOCK(hfmpi2c); 02992 02993 /* Init tickstart for timeout management*/ 02994 tickstart = HAL_GetTick(); 02995 02996 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02997 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02998 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02999 03000 /* Prepare transfer parameters */ 03001 hfmpi2c->pBuffPtr = pData; 03002 hfmpi2c->XferCount = Size; 03003 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 03004 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 03005 03006 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03007 { 03008 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03009 xfermode = FMPI2C_RELOAD_MODE; 03010 } 03011 else 03012 { 03013 hfmpi2c->XferSize = hfmpi2c->XferCount; 03014 xfermode = FMPI2C_AUTOEND_MODE; 03015 } 03016 03017 /* Send Slave Address and Memory Address */ 03018 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 03019 { 03020 /* Process Unlocked */ 03021 __HAL_UNLOCK(hfmpi2c); 03022 return HAL_ERROR; 03023 } 03024 03025 if (hfmpi2c->hdmarx != NULL) 03026 { 03027 /* Set the FMPI2C DMA transfer complete callback */ 03028 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; 03029 03030 /* Set the DMA error callback */ 03031 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 03032 03033 /* Set the unused DMA callbacks to NULL */ 03034 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 03035 hfmpi2c->hdmarx->XferAbortCallback = NULL; 03036 03037 /* Enable the DMA stream */ 03038 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, 03039 hfmpi2c->XferSize); 03040 } 03041 else 03042 { 03043 /* Update FMPI2C state */ 03044 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03045 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03046 03047 /* Update FMPI2C error code */ 03048 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 03049 03050 /* Process Unlocked */ 03051 __HAL_UNLOCK(hfmpi2c); 03052 03053 return HAL_ERROR; 03054 } 03055 03056 if (dmaxferstatus == HAL_OK) 03057 { 03058 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 03059 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 03060 03061 /* Update XferCount value */ 03062 hfmpi2c->XferCount -= hfmpi2c->XferSize; 03063 03064 /* Process Unlocked */ 03065 __HAL_UNLOCK(hfmpi2c); 03066 03067 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03068 to avoid the risk of FMPI2C interrupt handle execution before current 03069 process unlock */ 03070 /* Enable ERR and NACK interrupts */ 03071 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 03072 03073 /* Enable DMA Request */ 03074 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 03075 } 03076 else 03077 { 03078 /* Update FMPI2C state */ 03079 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03080 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03081 03082 /* Update FMPI2C error code */ 03083 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 03084 03085 /* Process Unlocked */ 03086 __HAL_UNLOCK(hfmpi2c); 03087 03088 return HAL_ERROR; 03089 } 03090 03091 return HAL_OK; 03092 } 03093 else 03094 { 03095 return HAL_BUSY; 03096 } 03097 } 03098 03099 /** 03100 * @brief Checks if target device is ready for communication. 03101 * @note This function is used with Memory devices 03102 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03103 * the configuration information for the specified FMPI2C. 03104 * @param DevAddress Target device address: The device 7 bits address value 03105 * in datasheet must be shifted to the left before calling the interface 03106 * @param Trials Number of trials 03107 * @param Timeout Timeout duration 03108 * @retval HAL status 03109 */ 03110 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, 03111 uint32_t Timeout) 03112 { 03113 uint32_t tickstart; 03114 03115 __IO uint32_t FMPI2C_Trials = 0UL; 03116 03117 FlagStatus tmp1; 03118 FlagStatus tmp2; 03119 03120 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 03121 { 03122 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 03123 { 03124 return HAL_BUSY; 03125 } 03126 03127 /* Process Locked */ 03128 __HAL_LOCK(hfmpi2c); 03129 03130 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 03131 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03132 03133 do 03134 { 03135 /* Generate Start */ 03136 hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress); 03137 03138 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 03139 /* Wait until STOPF flag is set or a NACK flag is set*/ 03140 tickstart = HAL_GetTick(); 03141 03142 tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03143 tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03144 03145 while ((tmp1 == RESET) && (tmp2 == RESET)) 03146 { 03147 if (Timeout != HAL_MAX_DELAY) 03148 { 03149 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) 03150 { 03151 /* Update FMPI2C state */ 03152 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03153 03154 /* Update FMPI2C error code */ 03155 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 03156 03157 /* Process Unlocked */ 03158 __HAL_UNLOCK(hfmpi2c); 03159 03160 return HAL_ERROR; 03161 } 03162 } 03163 03164 tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03165 tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03166 } 03167 03168 /* Check if the NACKF flag has not been set */ 03169 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) 03170 { 03171 /* Wait until STOPF flag is reset */ 03172 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 03173 { 03174 return HAL_ERROR; 03175 } 03176 03177 /* Clear STOP Flag */ 03178 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03179 03180 /* Device is ready */ 03181 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03182 03183 /* Process Unlocked */ 03184 __HAL_UNLOCK(hfmpi2c); 03185 03186 return HAL_OK; 03187 } 03188 else 03189 { 03190 /* Wait until STOPF flag is reset */ 03191 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 03192 { 03193 return HAL_ERROR; 03194 } 03195 03196 /* Clear NACK Flag */ 03197 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03198 03199 /* Clear STOP Flag, auto generated with autoend*/ 03200 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03201 } 03202 03203 /* Check if the maximum allowed number of trials has been reached */ 03204 if (FMPI2C_Trials == Trials) 03205 { 03206 /* Generate Stop */ 03207 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 03208 03209 /* Wait until STOPF flag is reset */ 03210 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 03211 { 03212 return HAL_ERROR; 03213 } 03214 03215 /* Clear STOP Flag */ 03216 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03217 } 03218 03219 /* Increment Trials */ 03220 FMPI2C_Trials++; 03221 } while (FMPI2C_Trials < Trials); 03222 03223 /* Update FMPI2C state */ 03224 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03225 03226 /* Update FMPI2C error code */ 03227 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 03228 03229 /* Process Unlocked */ 03230 __HAL_UNLOCK(hfmpi2c); 03231 03232 return HAL_ERROR; 03233 } 03234 else 03235 { 03236 return HAL_BUSY; 03237 } 03238 } 03239 03240 /** 03241 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt. 03242 * @note This interface allow to manage repeated start condition when a direction change during transfer 03243 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03244 * the configuration information for the specified FMPI2C. 03245 * @param DevAddress Target device address: The device 7 bits address value 03246 * in datasheet must be shifted to the left before calling the interface 03247 * @param pData Pointer to data buffer 03248 * @param Size Amount of data to be sent 03249 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03250 * @retval HAL status 03251 */ 03252 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 03253 uint16_t Size, uint32_t XferOptions) 03254 { 03255 uint32_t xfermode; 03256 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE; 03257 03258 /* Check the parameters */ 03259 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03260 03261 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 03262 { 03263 /* Process Locked */ 03264 __HAL_LOCK(hfmpi2c); 03265 03266 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 03267 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 03268 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03269 03270 /* Prepare transfer parameters */ 03271 hfmpi2c->pBuffPtr = pData; 03272 hfmpi2c->XferCount = Size; 03273 hfmpi2c->XferOptions = XferOptions; 03274 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 03275 03276 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ 03277 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03278 { 03279 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03280 xfermode = FMPI2C_RELOAD_MODE; 03281 } 03282 else 03283 { 03284 hfmpi2c->XferSize = hfmpi2c->XferCount; 03285 xfermode = hfmpi2c->XferOptions; 03286 } 03287 03288 /* If transfer direction not change and there is no request to start another frame, 03289 do not generate Restart Condition */ 03290 /* Mean Previous state is same as current state */ 03291 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \ 03292 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) 03293 { 03294 xferrequest = FMPI2C_NO_STARTSTOP; 03295 } 03296 else 03297 { 03298 /* Convert OTHER_xxx XferOptions if any */ 03299 FMPI2C_ConvertOtherXferOptions(hfmpi2c); 03300 03301 /* Update xfermode accordingly if no reload is necessary */ 03302 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE) 03303 { 03304 xfermode = hfmpi2c->XferOptions; 03305 } 03306 } 03307 03308 /* Send Slave Address and set NBYTES to write */ 03309 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest); 03310 03311 /* Process Unlocked */ 03312 __HAL_UNLOCK(hfmpi2c); 03313 03314 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03315 to avoid the risk of FMPI2C interrupt handle execution before current 03316 process unlock */ 03317 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 03318 03319 return HAL_OK; 03320 } 03321 else 03322 { 03323 return HAL_BUSY; 03324 } 03325 } 03326 03327 /** 03328 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with DMA. 03329 * @note This interface allow to manage repeated start condition when a direction change during transfer 03330 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03331 * the configuration information for the specified FMPI2C. 03332 * @param DevAddress Target device address: The device 7 bits address value 03333 * in datasheet must be shifted to the left before calling the interface 03334 * @param pData Pointer to data buffer 03335 * @param Size Amount of data to be sent 03336 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03337 * @retval HAL status 03338 */ 03339 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 03340 uint16_t Size, uint32_t XferOptions) 03341 { 03342 uint32_t xfermode; 03343 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE; 03344 HAL_StatusTypeDef dmaxferstatus; 03345 03346 /* Check the parameters */ 03347 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03348 03349 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 03350 { 03351 /* Process Locked */ 03352 __HAL_LOCK(hfmpi2c); 03353 03354 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 03355 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 03356 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03357 03358 /* Prepare transfer parameters */ 03359 hfmpi2c->pBuffPtr = pData; 03360 hfmpi2c->XferCount = Size; 03361 hfmpi2c->XferOptions = XferOptions; 03362 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 03363 03364 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ 03365 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03366 { 03367 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03368 xfermode = FMPI2C_RELOAD_MODE; 03369 } 03370 else 03371 { 03372 hfmpi2c->XferSize = hfmpi2c->XferCount; 03373 xfermode = hfmpi2c->XferOptions; 03374 } 03375 03376 /* If transfer direction not change and there is no request to start another frame, 03377 do not generate Restart Condition */ 03378 /* Mean Previous state is same as current state */ 03379 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \ 03380 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) 03381 { 03382 xferrequest = FMPI2C_NO_STARTSTOP; 03383 } 03384 else 03385 { 03386 /* Convert OTHER_xxx XferOptions if any */ 03387 FMPI2C_ConvertOtherXferOptions(hfmpi2c); 03388 03389 /* Update xfermode accordingly if no reload is necessary */ 03390 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE) 03391 { 03392 xfermode = hfmpi2c->XferOptions; 03393 } 03394 } 03395 03396 if (hfmpi2c->XferSize > 0U) 03397 { 03398 if (hfmpi2c->hdmatx != NULL) 03399 { 03400 /* Set the FMPI2C DMA transfer complete callback */ 03401 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; 03402 03403 /* Set the DMA error callback */ 03404 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 03405 03406 /* Set the unused DMA callbacks to NULL */ 03407 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 03408 hfmpi2c->hdmatx->XferAbortCallback = NULL; 03409 03410 /* Enable the DMA stream */ 03411 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, 03412 hfmpi2c->XferSize); 03413 } 03414 else 03415 { 03416 /* Update FMPI2C state */ 03417 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03418 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03419 03420 /* Update FMPI2C error code */ 03421 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 03422 03423 /* Process Unlocked */ 03424 __HAL_UNLOCK(hfmpi2c); 03425 03426 return HAL_ERROR; 03427 } 03428 03429 if (dmaxferstatus == HAL_OK) 03430 { 03431 /* Send Slave Address and set NBYTES to write */ 03432 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest); 03433 03434 /* Update XferCount value */ 03435 hfmpi2c->XferCount -= hfmpi2c->XferSize; 03436 03437 /* Process Unlocked */ 03438 __HAL_UNLOCK(hfmpi2c); 03439 03440 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03441 to avoid the risk of FMPI2C interrupt handle execution before current 03442 process unlock */ 03443 /* Enable ERR and NACK interrupts */ 03444 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 03445 03446 /* Enable DMA Request */ 03447 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 03448 } 03449 else 03450 { 03451 /* Update FMPI2C state */ 03452 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03453 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03454 03455 /* Update FMPI2C error code */ 03456 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 03457 03458 /* Process Unlocked */ 03459 __HAL_UNLOCK(hfmpi2c); 03460 03461 return HAL_ERROR; 03462 } 03463 } 03464 else 03465 { 03466 /* Update Transfer ISR function pointer */ 03467 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 03468 03469 /* Send Slave Address */ 03470 /* Set NBYTES to write and generate START condition */ 03471 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 03472 FMPI2C_GENERATE_START_WRITE); 03473 03474 /* Process Unlocked */ 03475 __HAL_UNLOCK(hfmpi2c); 03476 03477 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03478 to avoid the risk of FMPI2C interrupt handle execution before current 03479 process unlock */ 03480 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 03481 /* possible to enable all of these */ 03482 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 03483 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 03484 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 03485 } 03486 03487 return HAL_OK; 03488 } 03489 else 03490 { 03491 return HAL_BUSY; 03492 } 03493 } 03494 03495 /** 03496 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt 03497 * @note This interface allow to manage repeated start condition when a direction change during transfer 03498 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03499 * the configuration information for the specified FMPI2C. 03500 * @param DevAddress Target device address: The device 7 bits address value 03501 * in datasheet must be shifted to the left before calling the interface 03502 * @param pData Pointer to data buffer 03503 * @param Size Amount of data to be sent 03504 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03505 * @retval HAL status 03506 */ 03507 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 03508 uint16_t Size, uint32_t XferOptions) 03509 { 03510 uint32_t xfermode; 03511 uint32_t xferrequest = FMPI2C_GENERATE_START_READ; 03512 03513 /* Check the parameters */ 03514 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03515 03516 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 03517 { 03518 /* Process Locked */ 03519 __HAL_LOCK(hfmpi2c); 03520 03521 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 03522 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 03523 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03524 03525 /* Prepare transfer parameters */ 03526 hfmpi2c->pBuffPtr = pData; 03527 hfmpi2c->XferCount = Size; 03528 hfmpi2c->XferOptions = XferOptions; 03529 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 03530 03531 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ 03532 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03533 { 03534 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03535 xfermode = FMPI2C_RELOAD_MODE; 03536 } 03537 else 03538 { 03539 hfmpi2c->XferSize = hfmpi2c->XferCount; 03540 xfermode = hfmpi2c->XferOptions; 03541 } 03542 03543 /* If transfer direction not change and there is no request to start another frame, 03544 do not generate Restart Condition */ 03545 /* Mean Previous state is same as current state */ 03546 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \ 03547 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) 03548 { 03549 xferrequest = FMPI2C_NO_STARTSTOP; 03550 } 03551 else 03552 { 03553 /* Convert OTHER_xxx XferOptions if any */ 03554 FMPI2C_ConvertOtherXferOptions(hfmpi2c); 03555 03556 /* Update xfermode accordingly if no reload is necessary */ 03557 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE) 03558 { 03559 xfermode = hfmpi2c->XferOptions; 03560 } 03561 } 03562 03563 /* Send Slave Address and set NBYTES to read */ 03564 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest); 03565 03566 /* Process Unlocked */ 03567 __HAL_UNLOCK(hfmpi2c); 03568 03569 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03570 to avoid the risk of FMPI2C interrupt handle execution before current 03571 process unlock */ 03572 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 03573 03574 return HAL_OK; 03575 } 03576 else 03577 { 03578 return HAL_BUSY; 03579 } 03580 } 03581 03582 /** 03583 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with DMA 03584 * @note This interface allow to manage repeated start condition when a direction change during transfer 03585 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03586 * the configuration information for the specified FMPI2C. 03587 * @param DevAddress Target device address: The device 7 bits address value 03588 * in datasheet must be shifted to the left before calling the interface 03589 * @param pData Pointer to data buffer 03590 * @param Size Amount of data to be sent 03591 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03592 * @retval HAL status 03593 */ 03594 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, 03595 uint16_t Size, uint32_t XferOptions) 03596 { 03597 uint32_t xfermode; 03598 uint32_t xferrequest = FMPI2C_GENERATE_START_READ; 03599 HAL_StatusTypeDef dmaxferstatus; 03600 03601 /* Check the parameters */ 03602 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03603 03604 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 03605 { 03606 /* Process Locked */ 03607 __HAL_LOCK(hfmpi2c); 03608 03609 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 03610 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 03611 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03612 03613 /* Prepare transfer parameters */ 03614 hfmpi2c->pBuffPtr = pData; 03615 hfmpi2c->XferCount = Size; 03616 hfmpi2c->XferOptions = XferOptions; 03617 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 03618 03619 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ 03620 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03621 { 03622 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03623 xfermode = FMPI2C_RELOAD_MODE; 03624 } 03625 else 03626 { 03627 hfmpi2c->XferSize = hfmpi2c->XferCount; 03628 xfermode = hfmpi2c->XferOptions; 03629 } 03630 03631 /* If transfer direction not change and there is no request to start another frame, 03632 do not generate Restart Condition */ 03633 /* Mean Previous state is same as current state */ 03634 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \ 03635 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) 03636 { 03637 xferrequest = FMPI2C_NO_STARTSTOP; 03638 } 03639 else 03640 { 03641 /* Convert OTHER_xxx XferOptions if any */ 03642 FMPI2C_ConvertOtherXferOptions(hfmpi2c); 03643 03644 /* Update xfermode accordingly if no reload is necessary */ 03645 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE) 03646 { 03647 xfermode = hfmpi2c->XferOptions; 03648 } 03649 } 03650 03651 if (hfmpi2c->XferSize > 0U) 03652 { 03653 if (hfmpi2c->hdmarx != NULL) 03654 { 03655 /* Set the FMPI2C DMA transfer complete callback */ 03656 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; 03657 03658 /* Set the DMA error callback */ 03659 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 03660 03661 /* Set the unused DMA callbacks to NULL */ 03662 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 03663 hfmpi2c->hdmarx->XferAbortCallback = NULL; 03664 03665 /* Enable the DMA stream */ 03666 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, 03667 hfmpi2c->XferSize); 03668 } 03669 else 03670 { 03671 /* Update FMPI2C state */ 03672 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03673 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03674 03675 /* Update FMPI2C error code */ 03676 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 03677 03678 /* Process Unlocked */ 03679 __HAL_UNLOCK(hfmpi2c); 03680 03681 return HAL_ERROR; 03682 } 03683 03684 if (dmaxferstatus == HAL_OK) 03685 { 03686 /* Send Slave Address and set NBYTES to read */ 03687 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest); 03688 03689 /* Update XferCount value */ 03690 hfmpi2c->XferCount -= hfmpi2c->XferSize; 03691 03692 /* Process Unlocked */ 03693 __HAL_UNLOCK(hfmpi2c); 03694 03695 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03696 to avoid the risk of FMPI2C interrupt handle execution before current 03697 process unlock */ 03698 /* Enable ERR and NACK interrupts */ 03699 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 03700 03701 /* Enable DMA Request */ 03702 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 03703 } 03704 else 03705 { 03706 /* Update FMPI2C state */ 03707 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03708 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03709 03710 /* Update FMPI2C error code */ 03711 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 03712 03713 /* Process Unlocked */ 03714 __HAL_UNLOCK(hfmpi2c); 03715 03716 return HAL_ERROR; 03717 } 03718 } 03719 else 03720 { 03721 /* Update Transfer ISR function pointer */ 03722 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 03723 03724 /* Send Slave Address */ 03725 /* Set NBYTES to read and generate START condition */ 03726 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, 03727 FMPI2C_GENERATE_START_READ); 03728 03729 /* Process Unlocked */ 03730 __HAL_UNLOCK(hfmpi2c); 03731 03732 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03733 to avoid the risk of FMPI2C interrupt handle execution before current 03734 process unlock */ 03735 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 03736 /* possible to enable all of these */ 03737 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | 03738 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 03739 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 03740 } 03741 03742 return HAL_OK; 03743 } 03744 else 03745 { 03746 return HAL_BUSY; 03747 } 03748 } 03749 03750 /** 03751 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt 03752 * @note This interface allow to manage repeated start condition when a direction change during transfer 03753 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03754 * the configuration information for the specified FMPI2C. 03755 * @param pData Pointer to data buffer 03756 * @param Size Amount of data to be sent 03757 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03758 * @retval HAL status 03759 */ 03760 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 03761 uint32_t XferOptions) 03762 { 03763 /* Check the parameters */ 03764 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03765 03766 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN) 03767 { 03768 if ((pData == NULL) || (Size == 0U)) 03769 { 03770 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 03771 return HAL_ERROR; 03772 } 03773 03774 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 03775 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT); 03776 03777 /* Process Locked */ 03778 __HAL_LOCK(hfmpi2c); 03779 03780 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 03781 /* and then toggle the HAL slave RX state to TX state */ 03782 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 03783 { 03784 /* Disable associated Interrupts */ 03785 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 03786 03787 /* Abort DMA Xfer if any */ 03788 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) 03789 { 03790 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 03791 03792 if (hfmpi2c->hdmarx != NULL) 03793 { 03794 /* Set the FMPI2C DMA Abort callback : 03795 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 03796 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; 03797 03798 /* Abort DMA RX */ 03799 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) 03800 { 03801 /* Call Directly XferAbortCallback function in case of error */ 03802 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); 03803 } 03804 } 03805 } 03806 } 03807 03808 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN; 03809 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 03810 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03811 03812 /* Enable Address Acknowledge */ 03813 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 03814 03815 /* Prepare transfer parameters */ 03816 hfmpi2c->pBuffPtr = pData; 03817 hfmpi2c->XferCount = Size; 03818 hfmpi2c->XferSize = hfmpi2c->XferCount; 03819 hfmpi2c->XferOptions = XferOptions; 03820 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 03821 03822 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) 03823 { 03824 /* Clear ADDR flag after prepare the transfer parameters */ 03825 /* This action will generate an acknowledge to the Master */ 03826 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 03827 } 03828 03829 /* Process Unlocked */ 03830 __HAL_UNLOCK(hfmpi2c); 03831 03832 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 03833 to avoid the risk of FMPI2C interrupt handle execution before current 03834 process unlock */ 03835 /* REnable ADDR interrupt */ 03836 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); 03837 03838 return HAL_OK; 03839 } 03840 else 03841 { 03842 return HAL_ERROR; 03843 } 03844 } 03845 03846 /** 03847 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA 03848 * @note This interface allow to manage repeated start condition when a direction change during transfer 03849 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03850 * the configuration information for the specified FMPI2C. 03851 * @param pData Pointer to data buffer 03852 * @param Size Amount of data to be sent 03853 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 03854 * @retval HAL status 03855 */ 03856 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 03857 uint32_t XferOptions) 03858 { 03859 HAL_StatusTypeDef dmaxferstatus; 03860 03861 /* Check the parameters */ 03862 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 03863 03864 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN) 03865 { 03866 if ((pData == NULL) || (Size == 0U)) 03867 { 03868 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 03869 return HAL_ERROR; 03870 } 03871 03872 /* Process Locked */ 03873 __HAL_LOCK(hfmpi2c); 03874 03875 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 03876 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT); 03877 03878 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 03879 /* and then toggle the HAL slave RX state to TX state */ 03880 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 03881 { 03882 /* Disable associated Interrupts */ 03883 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 03884 03885 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) 03886 { 03887 /* Abort DMA Xfer if any */ 03888 if (hfmpi2c->hdmarx != NULL) 03889 { 03890 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 03891 03892 /* Set the FMPI2C DMA Abort callback : 03893 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 03894 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; 03895 03896 /* Abort DMA RX */ 03897 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) 03898 { 03899 /* Call Directly XferAbortCallback function in case of error */ 03900 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); 03901 } 03902 } 03903 } 03904 } 03905 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 03906 { 03907 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) 03908 { 03909 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 03910 03911 /* Abort DMA Xfer if any */ 03912 if (hfmpi2c->hdmatx != NULL) 03913 { 03914 /* Set the FMPI2C DMA Abort callback : 03915 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 03916 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; 03917 03918 /* Abort DMA TX */ 03919 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) 03920 { 03921 /* Call Directly XferAbortCallback function in case of error */ 03922 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); 03923 } 03924 } 03925 } 03926 } 03927 else 03928 { 03929 /* Nothing to do */ 03930 } 03931 03932 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN; 03933 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 03934 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 03935 03936 /* Enable Address Acknowledge */ 03937 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 03938 03939 /* Prepare transfer parameters */ 03940 hfmpi2c->pBuffPtr = pData; 03941 hfmpi2c->XferCount = Size; 03942 hfmpi2c->XferSize = hfmpi2c->XferCount; 03943 hfmpi2c->XferOptions = XferOptions; 03944 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 03945 03946 if (hfmpi2c->hdmatx != NULL) 03947 { 03948 /* Set the FMPI2C DMA transfer complete callback */ 03949 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt; 03950 03951 /* Set the DMA error callback */ 03952 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 03953 03954 /* Set the unused DMA callbacks to NULL */ 03955 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 03956 hfmpi2c->hdmatx->XferAbortCallback = NULL; 03957 03958 /* Enable the DMA stream */ 03959 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, 03960 hfmpi2c->XferSize); 03961 } 03962 else 03963 { 03964 /* Update FMPI2C state */ 03965 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 03966 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03967 03968 /* Update FMPI2C error code */ 03969 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 03970 03971 /* Process Unlocked */ 03972 __HAL_UNLOCK(hfmpi2c); 03973 03974 return HAL_ERROR; 03975 } 03976 03977 if (dmaxferstatus == HAL_OK) 03978 { 03979 /* Update XferCount value */ 03980 hfmpi2c->XferCount -= hfmpi2c->XferSize; 03981 03982 /* Reset XferSize */ 03983 hfmpi2c->XferSize = 0; 03984 } 03985 else 03986 { 03987 /* Update FMPI2C state */ 03988 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 03989 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03990 03991 /* Update FMPI2C error code */ 03992 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 03993 03994 /* Process Unlocked */ 03995 __HAL_UNLOCK(hfmpi2c); 03996 03997 return HAL_ERROR; 03998 } 03999 04000 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) 04001 { 04002 /* Clear ADDR flag after prepare the transfer parameters */ 04003 /* This action will generate an acknowledge to the Master */ 04004 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 04005 } 04006 04007 /* Process Unlocked */ 04008 __HAL_UNLOCK(hfmpi2c); 04009 04010 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 04011 to avoid the risk of FMPI2C interrupt handle execution before current 04012 process unlock */ 04013 /* Enable ERR, STOP, NACK, ADDR interrupts */ 04014 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 04015 04016 /* Enable DMA Request */ 04017 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 04018 04019 return HAL_OK; 04020 } 04021 else 04022 { 04023 return HAL_ERROR; 04024 } 04025 } 04026 04027 /** 04028 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt 04029 * @note This interface allow to manage repeated start condition when a direction change during transfer 04030 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04031 * the configuration information for the specified FMPI2C. 04032 * @param pData Pointer to data buffer 04033 * @param Size Amount of data to be sent 04034 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 04035 * @retval HAL status 04036 */ 04037 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 04038 uint32_t XferOptions) 04039 { 04040 /* Check the parameters */ 04041 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 04042 04043 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN) 04044 { 04045 if ((pData == NULL) || (Size == 0U)) 04046 { 04047 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 04048 return HAL_ERROR; 04049 } 04050 04051 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 04052 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT); 04053 04054 /* Process Locked */ 04055 __HAL_LOCK(hfmpi2c); 04056 04057 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 04058 /* and then toggle the HAL slave TX state to RX state */ 04059 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 04060 { 04061 /* Disable associated Interrupts */ 04062 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 04063 04064 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) 04065 { 04066 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 04067 04068 /* Abort DMA Xfer if any */ 04069 if (hfmpi2c->hdmatx != NULL) 04070 { 04071 /* Set the FMPI2C DMA Abort callback : 04072 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 04073 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; 04074 04075 /* Abort DMA TX */ 04076 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) 04077 { 04078 /* Call Directly XferAbortCallback function in case of error */ 04079 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); 04080 } 04081 } 04082 } 04083 } 04084 04085 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN; 04086 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 04087 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 04088 04089 /* Enable Address Acknowledge */ 04090 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 04091 04092 /* Prepare transfer parameters */ 04093 hfmpi2c->pBuffPtr = pData; 04094 hfmpi2c->XferCount = Size; 04095 hfmpi2c->XferSize = hfmpi2c->XferCount; 04096 hfmpi2c->XferOptions = XferOptions; 04097 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 04098 04099 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) 04100 { 04101 /* Clear ADDR flag after prepare the transfer parameters */ 04102 /* This action will generate an acknowledge to the Master */ 04103 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 04104 } 04105 04106 /* Process Unlocked */ 04107 __HAL_UNLOCK(hfmpi2c); 04108 04109 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 04110 to avoid the risk of FMPI2C interrupt handle execution before current 04111 process unlock */ 04112 /* REnable ADDR interrupt */ 04113 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); 04114 04115 return HAL_OK; 04116 } 04117 else 04118 { 04119 return HAL_ERROR; 04120 } 04121 } 04122 04123 /** 04124 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA 04125 * @note This interface allow to manage repeated start condition when a direction change during transfer 04126 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04127 * the configuration information for the specified FMPI2C. 04128 * @param pData Pointer to data buffer 04129 * @param Size Amount of data to be sent 04130 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 04131 * @retval HAL status 04132 */ 04133 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, 04134 uint32_t XferOptions) 04135 { 04136 HAL_StatusTypeDef dmaxferstatus; 04137 04138 /* Check the parameters */ 04139 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 04140 04141 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN) 04142 { 04143 if ((pData == NULL) || (Size == 0U)) 04144 { 04145 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM; 04146 return HAL_ERROR; 04147 } 04148 04149 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 04150 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT); 04151 04152 /* Process Locked */ 04153 __HAL_LOCK(hfmpi2c); 04154 04155 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 04156 /* and then toggle the HAL slave TX state to RX state */ 04157 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 04158 { 04159 /* Disable associated Interrupts */ 04160 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 04161 04162 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) 04163 { 04164 /* Abort DMA Xfer if any */ 04165 if (hfmpi2c->hdmatx != NULL) 04166 { 04167 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 04168 04169 /* Set the FMPI2C DMA Abort callback : 04170 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 04171 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; 04172 04173 /* Abort DMA TX */ 04174 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) 04175 { 04176 /* Call Directly XferAbortCallback function in case of error */ 04177 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); 04178 } 04179 } 04180 } 04181 } 04182 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 04183 { 04184 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) 04185 { 04186 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 04187 04188 /* Abort DMA Xfer if any */ 04189 if (hfmpi2c->hdmarx != NULL) 04190 { 04191 /* Set the FMPI2C DMA Abort callback : 04192 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 04193 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; 04194 04195 /* Abort DMA RX */ 04196 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) 04197 { 04198 /* Call Directly XferAbortCallback function in case of error */ 04199 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); 04200 } 04201 } 04202 } 04203 } 04204 else 04205 { 04206 /* Nothing to do */ 04207 } 04208 04209 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN; 04210 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 04211 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 04212 04213 /* Enable Address Acknowledge */ 04214 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 04215 04216 /* Prepare transfer parameters */ 04217 hfmpi2c->pBuffPtr = pData; 04218 hfmpi2c->XferCount = Size; 04219 hfmpi2c->XferSize = hfmpi2c->XferCount; 04220 hfmpi2c->XferOptions = XferOptions; 04221 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 04222 04223 if (hfmpi2c->hdmarx != NULL) 04224 { 04225 /* Set the FMPI2C DMA transfer complete callback */ 04226 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt; 04227 04228 /* Set the DMA error callback */ 04229 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 04230 04231 /* Set the unused DMA callbacks to NULL */ 04232 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 04233 hfmpi2c->hdmarx->XferAbortCallback = NULL; 04234 04235 /* Enable the DMA stream */ 04236 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, 04237 (uint32_t)pData, hfmpi2c->XferSize); 04238 } 04239 else 04240 { 04241 /* Update FMPI2C state */ 04242 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 04243 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04244 04245 /* Update FMPI2C error code */ 04246 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM; 04247 04248 /* Process Unlocked */ 04249 __HAL_UNLOCK(hfmpi2c); 04250 04251 return HAL_ERROR; 04252 } 04253 04254 if (dmaxferstatus == HAL_OK) 04255 { 04256 /* Update XferCount value */ 04257 hfmpi2c->XferCount -= hfmpi2c->XferSize; 04258 04259 /* Reset XferSize */ 04260 hfmpi2c->XferSize = 0; 04261 } 04262 else 04263 { 04264 /* Update FMPI2C state */ 04265 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 04266 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04267 04268 /* Update FMPI2C error code */ 04269 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; 04270 04271 /* Process Unlocked */ 04272 __HAL_UNLOCK(hfmpi2c); 04273 04274 return HAL_ERROR; 04275 } 04276 04277 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) 04278 { 04279 /* Clear ADDR flag after prepare the transfer parameters */ 04280 /* This action will generate an acknowledge to the Master */ 04281 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 04282 } 04283 04284 /* Process Unlocked */ 04285 __HAL_UNLOCK(hfmpi2c); 04286 04287 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 04288 to avoid the risk of FMPI2C interrupt handle execution before current 04289 process unlock */ 04290 /* REnable ADDR interrupt */ 04291 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); 04292 04293 /* Enable DMA Request */ 04294 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 04295 04296 return HAL_OK; 04297 } 04298 else 04299 { 04300 return HAL_ERROR; 04301 } 04302 } 04303 04304 /** 04305 * @brief Enable the Address listen mode with Interrupt. 04306 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04307 * the configuration information for the specified FMPI2C. 04308 * @retval HAL status 04309 */ 04310 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) 04311 { 04312 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 04313 { 04314 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 04315 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 04316 04317 /* Enable the Address Match interrupt */ 04318 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 04319 04320 return HAL_OK; 04321 } 04322 else 04323 { 04324 return HAL_BUSY; 04325 } 04326 } 04327 04328 /** 04329 * @brief Disable the Address listen mode with Interrupt. 04330 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04331 * the configuration information for the specified FMPI2C 04332 * @retval HAL status 04333 */ 04334 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) 04335 { 04336 /* Declaration of tmp to prevent undefined behavior of volatile usage */ 04337 uint32_t tmp; 04338 04339 /* Disable Address listen mode only if a transfer is not ongoing */ 04340 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) 04341 { 04342 tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK; 04343 hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode); 04344 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04345 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04346 hfmpi2c->XferISR = NULL; 04347 04348 /* Disable the Address Match interrupt */ 04349 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 04350 04351 return HAL_OK; 04352 } 04353 else 04354 { 04355 return HAL_BUSY; 04356 } 04357 } 04358 04359 /** 04360 * @brief Abort a master FMPI2C IT or DMA process communication with Interrupt. 04361 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04362 * the configuration information for the specified FMPI2C. 04363 * @param DevAddress Target device address: The device 7 bits address value 04364 * in datasheet must be shifted to the left before calling the interface 04365 * @retval HAL status 04366 */ 04367 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress) 04368 { 04369 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER) 04370 { 04371 /* Process Locked */ 04372 __HAL_LOCK(hfmpi2c); 04373 04374 /* Disable Interrupts and Store Previous state */ 04375 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 04376 { 04377 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 04378 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX; 04379 } 04380 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 04381 { 04382 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 04383 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX; 04384 } 04385 else 04386 { 04387 /* Do nothing */ 04388 } 04389 04390 /* Set State at HAL_FMPI2C_STATE_ABORT */ 04391 hfmpi2c->State = HAL_FMPI2C_STATE_ABORT; 04392 04393 /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */ 04394 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ 04395 FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP); 04396 04397 /* Process Unlocked */ 04398 __HAL_UNLOCK(hfmpi2c); 04399 04400 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 04401 to avoid the risk of FMPI2C interrupt handle execution before current 04402 process unlock */ 04403 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 04404 04405 return HAL_OK; 04406 } 04407 else 04408 { 04409 /* Wrong usage of abort function */ 04410 /* This function should be used only in case of abort monitored by master device */ 04411 return HAL_ERROR; 04412 } 04413 } 04414 04415 /** 04416 * @} 04417 */ 04418 04419 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks 04420 * @{ 04421 */ 04422 04423 /** 04424 * @brief This function handles FMPI2C event interrupt request. 04425 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04426 * the configuration information for the specified FMPI2C. 04427 * @retval None 04428 */ 04429 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) 04430 { 04431 /* Get current IT Flags and IT sources value */ 04432 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); 04433 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); 04434 04435 /* FMPI2C events treatment -------------------------------------*/ 04436 if (hfmpi2c->XferISR != NULL) 04437 { 04438 hfmpi2c->XferISR(hfmpi2c, itflags, itsources); 04439 } 04440 } 04441 04442 /** 04443 * @brief This function handles FMPI2C error interrupt request. 04444 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04445 * the configuration information for the specified FMPI2C. 04446 * @retval None 04447 */ 04448 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) 04449 { 04450 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); 04451 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); 04452 uint32_t tmperror; 04453 04454 /* FMPI2C Bus error interrupt occurred ------------------------------------*/ 04455 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_BERR) != RESET) && \ 04456 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET)) 04457 { 04458 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR; 04459 04460 /* Clear BERR flag */ 04461 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR); 04462 } 04463 04464 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ 04465 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_OVR) != RESET) && \ 04466 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET)) 04467 { 04468 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR; 04469 04470 /* Clear OVR flag */ 04471 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR); 04472 } 04473 04474 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/ 04475 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_ARLO) != RESET) && \ 04476 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET)) 04477 { 04478 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO; 04479 04480 /* Clear ARLO flag */ 04481 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO); 04482 } 04483 04484 /* Store current volatile hfmpi2c->ErrorCode, misra rule */ 04485 tmperror = hfmpi2c->ErrorCode; 04486 04487 /* Call the Error Callback in case of Error detected */ 04488 if ((tmperror & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE) 04489 { 04490 FMPI2C_ITError(hfmpi2c, tmperror); 04491 } 04492 } 04493 04494 /** 04495 * @brief Master Tx Transfer completed callback. 04496 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04497 * the configuration information for the specified FMPI2C. 04498 * @retval None 04499 */ 04500 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04501 { 04502 /* Prevent unused argument(s) compilation warning */ 04503 UNUSED(hfmpi2c); 04504 04505 /* NOTE : This function should not be modified, when the callback is needed, 04506 the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file 04507 */ 04508 } 04509 04510 /** 04511 * @brief Master Rx Transfer completed callback. 04512 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04513 * the configuration information for the specified FMPI2C. 04514 * @retval None 04515 */ 04516 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04517 { 04518 /* Prevent unused argument(s) compilation warning */ 04519 UNUSED(hfmpi2c); 04520 04521 /* NOTE : This function should not be modified, when the callback is needed, 04522 the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file 04523 */ 04524 } 04525 04526 /** @brief Slave Tx Transfer completed callback. 04527 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04528 * the configuration information for the specified FMPI2C. 04529 * @retval None 04530 */ 04531 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04532 { 04533 /* Prevent unused argument(s) compilation warning */ 04534 UNUSED(hfmpi2c); 04535 04536 /* NOTE : This function should not be modified, when the callback is needed, 04537 the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file 04538 */ 04539 } 04540 04541 /** 04542 * @brief Slave Rx Transfer completed callback. 04543 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04544 * the configuration information for the specified FMPI2C. 04545 * @retval None 04546 */ 04547 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04548 { 04549 /* Prevent unused argument(s) compilation warning */ 04550 UNUSED(hfmpi2c); 04551 04552 /* NOTE : This function should not be modified, when the callback is needed, 04553 the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file 04554 */ 04555 } 04556 04557 /** 04558 * @brief Slave Address Match callback. 04559 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04560 * the configuration information for the specified FMPI2C. 04561 * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION 04562 * @param AddrMatchCode Address Match Code 04563 * @retval None 04564 */ 04565 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) 04566 { 04567 /* Prevent unused argument(s) compilation warning */ 04568 UNUSED(hfmpi2c); 04569 UNUSED(TransferDirection); 04570 UNUSED(AddrMatchCode); 04571 04572 /* NOTE : This function should not be modified, when the callback is needed, 04573 the HAL_FMPI2C_AddrCallback() could be implemented in the user file 04574 */ 04575 } 04576 04577 /** 04578 * @brief Listen Complete callback. 04579 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04580 * the configuration information for the specified FMPI2C. 04581 * @retval None 04582 */ 04583 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04584 { 04585 /* Prevent unused argument(s) compilation warning */ 04586 UNUSED(hfmpi2c); 04587 04588 /* NOTE : This function should not be modified, when the callback is needed, 04589 the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file 04590 */ 04591 } 04592 04593 /** 04594 * @brief Memory Tx Transfer completed callback. 04595 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04596 * the configuration information for the specified FMPI2C. 04597 * @retval None 04598 */ 04599 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04600 { 04601 /* Prevent unused argument(s) compilation warning */ 04602 UNUSED(hfmpi2c); 04603 04604 /* NOTE : This function should not be modified, when the callback is needed, 04605 the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file 04606 */ 04607 } 04608 04609 /** 04610 * @brief Memory Rx Transfer completed callback. 04611 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04612 * the configuration information for the specified FMPI2C. 04613 * @retval None 04614 */ 04615 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04616 { 04617 /* Prevent unused argument(s) compilation warning */ 04618 UNUSED(hfmpi2c); 04619 04620 /* NOTE : This function should not be modified, when the callback is needed, 04621 the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file 04622 */ 04623 } 04624 04625 /** 04626 * @brief FMPI2C error callback. 04627 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04628 * the configuration information for the specified FMPI2C. 04629 * @retval None 04630 */ 04631 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04632 { 04633 /* Prevent unused argument(s) compilation warning */ 04634 UNUSED(hfmpi2c); 04635 04636 /* NOTE : This function should not be modified, when the callback is needed, 04637 the HAL_FMPI2C_ErrorCallback could be implemented in the user file 04638 */ 04639 } 04640 04641 /** 04642 * @brief FMPI2C abort callback. 04643 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04644 * the configuration information for the specified FMPI2C. 04645 * @retval None 04646 */ 04647 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 04648 { 04649 /* Prevent unused argument(s) compilation warning */ 04650 UNUSED(hfmpi2c); 04651 04652 /* NOTE : This function should not be modified, when the callback is needed, 04653 the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file 04654 */ 04655 } 04656 04657 /** 04658 * @} 04659 */ 04660 04661 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions 04662 * @brief Peripheral State, Mode and Error functions 04663 * 04664 @verbatim 04665 =============================================================================== 04666 ##### Peripheral State, Mode and Error functions ##### 04667 =============================================================================== 04668 [..] 04669 This subsection permit to get in run-time the status of the peripheral 04670 and the data flow. 04671 04672 @endverbatim 04673 * @{ 04674 */ 04675 04676 /** 04677 * @brief Return the FMPI2C handle state. 04678 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04679 * the configuration information for the specified FMPI2C. 04680 * @retval HAL state 04681 */ 04682 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c) 04683 { 04684 /* Return FMPI2C handle state */ 04685 return hfmpi2c->State; 04686 } 04687 04688 /** 04689 * @brief Returns the FMPI2C Master, Slave, Memory or no mode. 04690 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04691 * the configuration information for FMPI2C module 04692 * @retval HAL mode 04693 */ 04694 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c) 04695 { 04696 return hfmpi2c->Mode; 04697 } 04698 04699 /** 04700 * @brief Return the FMPI2C error code. 04701 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04702 * the configuration information for the specified FMPI2C. 04703 * @retval FMPI2C Error Code 04704 */ 04705 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c) 04706 { 04707 return hfmpi2c->ErrorCode; 04708 } 04709 04710 /** 04711 * @} 04712 */ 04713 04714 /** 04715 * @} 04716 */ 04717 04718 /** @addtogroup FMPI2C_Private_Functions 04719 * @{ 04720 */ 04721 04722 /** 04723 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt. 04724 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04725 * the configuration information for the specified FMPI2C. 04726 * @param ITFlags Interrupt flags to handle. 04727 * @param ITSources Interrupt sources enabled. 04728 * @retval HAL status 04729 */ 04730 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 04731 uint32_t ITSources) 04732 { 04733 uint16_t devaddress; 04734 uint32_t tmpITFlags = ITFlags; 04735 04736 /* Process Locked */ 04737 __HAL_LOCK(hfmpi2c); 04738 04739 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \ 04740 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET)) 04741 { 04742 /* Clear NACK Flag */ 04743 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04744 04745 /* Set corresponding Error Code */ 04746 /* No need to generate STOP, it is automatically done */ 04747 /* Error callback will be send during stop flag treatment */ 04748 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 04749 04750 /* Flush TX register */ 04751 FMPI2C_Flush_TXDR(hfmpi2c); 04752 } 04753 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \ 04754 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET)) 04755 { 04756 /* Remove RXNE flag on temporary variable as read done */ 04757 tmpITFlags &= ~FMPI2C_FLAG_RXNE; 04758 04759 /* Read data from RXDR */ 04760 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 04761 04762 /* Increment Buffer pointer */ 04763 hfmpi2c->pBuffPtr++; 04764 04765 hfmpi2c->XferSize--; 04766 hfmpi2c->XferCount--; 04767 } 04768 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \ 04769 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET)) 04770 { 04771 /* Write data to TXDR */ 04772 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr; 04773 04774 /* Increment Buffer pointer */ 04775 hfmpi2c->pBuffPtr++; 04776 04777 hfmpi2c->XferSize--; 04778 hfmpi2c->XferCount--; 04779 } 04780 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TCR) != RESET) && \ 04781 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET)) 04782 { 04783 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U)) 04784 { 04785 devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); 04786 04787 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 04788 { 04789 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 04790 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 04791 } 04792 else 04793 { 04794 hfmpi2c->XferSize = hfmpi2c->XferCount; 04795 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) 04796 { 04797 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, 04798 hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP); 04799 } 04800 else 04801 { 04802 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, 04803 FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 04804 } 04805 } 04806 } 04807 else 04808 { 04809 /* Call TxCpltCallback() if no stop mode is set */ 04810 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 04811 { 04812 /* Call FMPI2C Master Sequential complete process */ 04813 FMPI2C_ITMasterSeqCplt(hfmpi2c); 04814 } 04815 else 04816 { 04817 /* Wrong size Status regarding TCR flag event */ 04818 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04819 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 04820 } 04821 } 04822 } 04823 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) != RESET) && \ 04824 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET)) 04825 { 04826 if (hfmpi2c->XferCount == 0U) 04827 { 04828 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 04829 { 04830 /* Generate a stop condition in case of no transfer option */ 04831 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME) 04832 { 04833 /* Generate Stop */ 04834 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 04835 } 04836 else 04837 { 04838 /* Call FMPI2C Master Sequential complete process */ 04839 FMPI2C_ITMasterSeqCplt(hfmpi2c); 04840 } 04841 } 04842 } 04843 else 04844 { 04845 /* Wrong size Status regarding TC flag event */ 04846 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04847 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 04848 } 04849 } 04850 else 04851 { 04852 /* Nothing to do */ 04853 } 04854 04855 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \ 04856 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET)) 04857 { 04858 /* Call FMPI2C Master complete process */ 04859 FMPI2C_ITMasterCplt(hfmpi2c, tmpITFlags); 04860 } 04861 04862 /* Process Unlocked */ 04863 __HAL_UNLOCK(hfmpi2c); 04864 04865 return HAL_OK; 04866 } 04867 04868 /** 04869 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt. 04870 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04871 * the configuration information for the specified FMPI2C. 04872 * @param ITFlags Interrupt flags to handle. 04873 * @param ITSources Interrupt sources enabled. 04874 * @retval HAL status 04875 */ 04876 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 04877 uint32_t ITSources) 04878 { 04879 uint32_t tmpoptions = hfmpi2c->XferOptions; 04880 uint32_t tmpITFlags = ITFlags; 04881 04882 /* Process locked */ 04883 __HAL_LOCK(hfmpi2c); 04884 04885 /* Check if STOPF is set */ 04886 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \ 04887 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET)) 04888 { 04889 /* Call FMPI2C Slave complete process */ 04890 FMPI2C_ITSlaveCplt(hfmpi2c, tmpITFlags); 04891 } 04892 04893 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \ 04894 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET)) 04895 { 04896 /* Check that FMPI2C transfer finished */ 04897 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ 04898 /* Mean XferCount == 0*/ 04899 /* So clear Flag NACKF only */ 04900 if (hfmpi2c->XferCount == 0U) 04901 { 04902 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME)) 04903 /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for 04904 Warning[Pa134]: left and right operands are identical */ 04905 { 04906 /* Call FMPI2C Listen complete process */ 04907 FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags); 04908 } 04909 else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME)) 04910 { 04911 /* Clear NACK Flag */ 04912 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04913 04914 /* Flush TX register */ 04915 FMPI2C_Flush_TXDR(hfmpi2c); 04916 04917 /* Last Byte is Transmitted */ 04918 /* Call FMPI2C Slave Sequential complete process */ 04919 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 04920 } 04921 else 04922 { 04923 /* Clear NACK Flag */ 04924 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04925 } 04926 } 04927 else 04928 { 04929 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ 04930 /* Clear NACK Flag */ 04931 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04932 04933 /* Set ErrorCode corresponding to a Non-Acknowledge */ 04934 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 04935 04936 if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME)) 04937 { 04938 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04939 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 04940 } 04941 } 04942 } 04943 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \ 04944 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET)) 04945 { 04946 if (hfmpi2c->XferCount > 0U) 04947 { 04948 /* Read data from RXDR */ 04949 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 04950 04951 /* Increment Buffer pointer */ 04952 hfmpi2c->pBuffPtr++; 04953 04954 hfmpi2c->XferSize--; 04955 hfmpi2c->XferCount--; 04956 } 04957 04958 if ((hfmpi2c->XferCount == 0U) && \ 04959 (tmpoptions != FMPI2C_NO_OPTION_FRAME)) 04960 { 04961 /* Call FMPI2C Slave Sequential complete process */ 04962 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 04963 } 04964 } 04965 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_ADDR) != RESET) && \ 04966 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET)) 04967 { 04968 FMPI2C_ITAddrCplt(hfmpi2c, tmpITFlags); 04969 } 04970 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \ 04971 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET)) 04972 { 04973 /* Write data to TXDR only if XferCount not reach "0" */ 04974 /* A TXIS flag can be set, during STOP treatment */ 04975 /* Check if all Data have already been sent */ 04976 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ 04977 if (hfmpi2c->XferCount > 0U) 04978 { 04979 /* Write data to TXDR */ 04980 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr; 04981 04982 /* Increment Buffer pointer */ 04983 hfmpi2c->pBuffPtr++; 04984 04985 hfmpi2c->XferCount--; 04986 hfmpi2c->XferSize--; 04987 } 04988 else 04989 { 04990 if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME)) 04991 { 04992 /* Last Byte is Transmitted */ 04993 /* Call FMPI2C Slave Sequential complete process */ 04994 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 04995 } 04996 } 04997 } 04998 else 04999 { 05000 /* Nothing to do */ 05001 } 05002 05003 /* Process Unlocked */ 05004 __HAL_UNLOCK(hfmpi2c); 05005 05006 return HAL_OK; 05007 } 05008 05009 /** 05010 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA. 05011 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 05012 * the configuration information for the specified FMPI2C. 05013 * @param ITFlags Interrupt flags to handle. 05014 * @param ITSources Interrupt sources enabled. 05015 * @retval HAL status 05016 */ 05017 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 05018 uint32_t ITSources) 05019 { 05020 uint16_t devaddress; 05021 uint32_t xfermode; 05022 05023 /* Process Locked */ 05024 __HAL_LOCK(hfmpi2c); 05025 05026 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \ 05027 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET)) 05028 { 05029 /* Clear NACK Flag */ 05030 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05031 05032 /* Set corresponding Error Code */ 05033 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 05034 05035 /* No need to generate STOP, it is automatically done */ 05036 /* But enable STOP interrupt, to treat it */ 05037 /* Error callback will be send during stop flag treatment */ 05038 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 05039 05040 /* Flush TX register */ 05041 FMPI2C_Flush_TXDR(hfmpi2c); 05042 } 05043 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TCR) != RESET) && \ 05044 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET)) 05045 { 05046 /* Disable TC interrupt */ 05047 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI); 05048 05049 if (hfmpi2c->XferCount != 0U) 05050 { 05051 /* Recover Slave address */ 05052 devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); 05053 05054 /* Prepare the new XferSize to transfer */ 05055 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 05056 { 05057 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 05058 xfermode = FMPI2C_RELOAD_MODE; 05059 } 05060 else 05061 { 05062 hfmpi2c->XferSize = hfmpi2c->XferCount; 05063 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) 05064 { 05065 xfermode = hfmpi2c->XferOptions; 05066 } 05067 else 05068 { 05069 xfermode = FMPI2C_AUTOEND_MODE; 05070 } 05071 } 05072 05073 /* Set the new XferSize in Nbytes register */ 05074 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 05075 05076 /* Update XferCount value */ 05077 hfmpi2c->XferCount -= hfmpi2c->XferSize; 05078 05079 /* Enable DMA Request */ 05080 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 05081 { 05082 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 05083 } 05084 else 05085 { 05086 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 05087 } 05088 } 05089 else 05090 { 05091 /* Call TxCpltCallback() if no stop mode is set */ 05092 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 05093 { 05094 /* Call FMPI2C Master Sequential complete process */ 05095 FMPI2C_ITMasterSeqCplt(hfmpi2c); 05096 } 05097 else 05098 { 05099 /* Wrong size Status regarding TCR flag event */ 05100 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05101 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 05102 } 05103 } 05104 } 05105 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TC) != RESET) && \ 05106 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET)) 05107 { 05108 if (hfmpi2c->XferCount == 0U) 05109 { 05110 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 05111 { 05112 /* Generate a stop condition in case of no transfer option */ 05113 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME) 05114 { 05115 /* Generate Stop */ 05116 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 05117 } 05118 else 05119 { 05120 /* Call FMPI2C Master Sequential complete process */ 05121 FMPI2C_ITMasterSeqCplt(hfmpi2c); 05122 } 05123 } 05124 } 05125 else 05126 { 05127 /* Wrong size Status regarding TC flag event */ 05128 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05129 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 05130 } 05131 } 05132 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \ 05133 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET)) 05134 { 05135 /* Call FMPI2C Master complete process */ 05136 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags); 05137 } 05138 else 05139 { 05140 /* Nothing to do */ 05141 } 05142 05143 /* Process Unlocked */ 05144 __HAL_UNLOCK(hfmpi2c); 05145 05146 return HAL_OK; 05147 } 05148 05149 /** 05150 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA. 05151 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 05152 * the configuration information for the specified FMPI2C. 05153 * @param ITFlags Interrupt flags to handle. 05154 * @param ITSources Interrupt sources enabled. 05155 * @retval HAL status 05156 */ 05157 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, 05158 uint32_t ITSources) 05159 { 05160 uint32_t tmpoptions = hfmpi2c->XferOptions; 05161 uint32_t treatdmanack = 0U; 05162 HAL_FMPI2C_StateTypeDef tmpstate; 05163 05164 /* Process locked */ 05165 __HAL_LOCK(hfmpi2c); 05166 05167 /* Check if STOPF is set */ 05168 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \ 05169 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET)) 05170 { 05171 /* Call FMPI2C Slave complete process */ 05172 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags); 05173 } 05174 05175 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \ 05176 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET)) 05177 { 05178 /* Check that FMPI2C transfer finished */ 05179 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ 05180 /* Mean XferCount == 0 */ 05181 /* So clear Flag NACKF only */ 05182 if ((FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET) || 05183 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET)) 05184 { 05185 /* Split check of hdmarx, for MISRA compliance */ 05186 if (hfmpi2c->hdmarx != NULL) 05187 { 05188 if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET) 05189 { 05190 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U) 05191 { 05192 treatdmanack = 1U; 05193 } 05194 } 05195 } 05196 05197 /* Split check of hdmatx, for MISRA compliance */ 05198 if (hfmpi2c->hdmatx != NULL) 05199 { 05200 if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET) 05201 { 05202 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U) 05203 { 05204 treatdmanack = 1U; 05205 } 05206 } 05207 } 05208 05209 if (treatdmanack == 1U) 05210 { 05211 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME)) 05212 /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for 05213 Warning[Pa134]: left and right operands are identical */ 05214 { 05215 /* Call FMPI2C Listen complete process */ 05216 FMPI2C_ITListenCplt(hfmpi2c, ITFlags); 05217 } 05218 else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME)) 05219 { 05220 /* Clear NACK Flag */ 05221 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05222 05223 /* Flush TX register */ 05224 FMPI2C_Flush_TXDR(hfmpi2c); 05225 05226 /* Last Byte is Transmitted */ 05227 /* Call FMPI2C Slave Sequential complete process */ 05228 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 05229 } 05230 else 05231 { 05232 /* Clear NACK Flag */ 05233 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05234 } 05235 } 05236 else 05237 { 05238 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ 05239 /* Clear NACK Flag */ 05240 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05241 05242 /* Set ErrorCode corresponding to a Non-Acknowledge */ 05243 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 05244 05245 /* Store current hfmpi2c->State, solve MISRA2012-Rule-13.5 */ 05246 tmpstate = hfmpi2c->State; 05247 05248 if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME)) 05249 { 05250 if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)) 05251 { 05252 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX; 05253 } 05254 else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)) 05255 { 05256 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX; 05257 } 05258 else 05259 { 05260 /* Do nothing */ 05261 } 05262 05263 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05264 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 05265 } 05266 } 05267 } 05268 else 05269 { 05270 /* Only Clear NACK Flag, no DMA treatment is pending */ 05271 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05272 } 05273 } 05274 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_ADDR) != RESET) && \ 05275 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET)) 05276 { 05277 FMPI2C_ITAddrCplt(hfmpi2c, ITFlags); 05278 } 05279 else 05280 { 05281 /* Nothing to do */ 05282 } 05283 05284 /* Process Unlocked */ 05285 __HAL_UNLOCK(hfmpi2c); 05286 05287 return HAL_OK; 05288 } 05289 05290 /** 05291 * @brief Master sends target device address followed by internal memory address for write request. 05292 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 05293 * the configuration information for the specified FMPI2C. 05294 * @param DevAddress Target device address: The device 7 bits address value 05295 * in datasheet must be shifted to the left before calling the interface 05296 * @param MemAddress Internal memory address 05297 * @param MemAddSize Size of internal memory address 05298 * @param Timeout Timeout duration 05299 * @param Tickstart Tick start value 05300 * @retval HAL status 05301 */ 05302 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, 05303 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, 05304 uint32_t Tickstart) 05305 { 05306 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); 05307 05308 /* Wait until TXIS flag is set */ 05309 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 05310 { 05311 return HAL_ERROR; 05312 } 05313 05314 /* If Memory address size is 8Bit */ 05315 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) 05316 { 05317 /* Send Memory Address */ 05318 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 05319 } 05320 /* If Memory address size is 16Bit */ 05321 else 05322 { 05323 /* Send MSB of Memory Address */ 05324 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); 05325 05326 /* Wait until TXIS flag is set */ 05327 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 05328 { 05329 return HAL_ERROR; 05330 } 05331 05332 /* Send LSB of Memory Address */ 05333 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 05334 } 05335 05336 /* Wait until TCR flag is set */ 05337 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) 05338 { 05339 return HAL_ERROR; 05340 } 05341 05342 return HAL_OK; 05343 } 05344 05345 /** 05346 * @brief Master sends target device address followed by internal memory address for read request. 05347 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 05348 * the configuration information for the specified FMPI2C. 05349 * @param DevAddress Target device address: The device 7 bits address value 05350 * in datasheet must be shifted to the left before calling the interface 05351 * @param MemAddress Internal memory address 05352 * @param MemAddSize Size of internal memory address 05353 * @param Timeout Timeout duration 05354 * @param Tickstart Tick start value 05355 * @retval HAL status 05356 */ 05357 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, 05358 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, 05359 uint32_t Tickstart) 05360 { 05361 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE); 05362 05363 /* Wait until TXIS flag is set */ 05364 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 05365 { 05366 return HAL_ERROR; 05367 } 05368 05369 /* If Memory address size is 8Bit */ 05370 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) 05371 { 05372 /* Send Memory Address */ 05373 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 05374 } 05375 /* If Memory address size is 16Bit */ 05376 else 05377 { 05378 /* Send MSB of Memory Address */ 05379 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); 05380 05381 /* Wait until TXIS flag is set */ 05382 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 05383 { 05384 return HAL_ERROR; 05385 } 05386 05387 /* Send LSB of Memory Address */ 05388 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 05389 } 05390 05391 /* Wait until TC flag is set */ 05392 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) 05393 { 05394 return HAL_ERROR; 05395 } 05396 05397 return HAL_OK; 05398 } 05399 05400 /** 05401 * @brief FMPI2C Address complete process callback. 05402 * @param hfmpi2c FMPI2C handle. 05403 * @param ITFlags Interrupt flags to handle. 05404 * @retval None 05405 */ 05406 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 05407 { 05408 uint8_t transferdirection; 05409 uint16_t slaveaddrcode; 05410 uint16_t ownadd1code; 05411 uint16_t ownadd2code; 05412 05413 /* Prevent unused argument(s) compilation warning */ 05414 UNUSED(ITFlags); 05415 05416 /* In case of Listen state, need to inform upper layer of address match code event */ 05417 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN) 05418 { 05419 transferdirection = FMPI2C_GET_DIR(hfmpi2c); 05420 slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c); 05421 ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c); 05422 ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c); 05423 05424 /* If 10bits addressing mode is selected */ 05425 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 05426 { 05427 if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK)) 05428 { 05429 slaveaddrcode = ownadd1code; 05430 hfmpi2c->AddrEventCount++; 05431 if (hfmpi2c->AddrEventCount == 2U) 05432 { 05433 /* Reset Address Event counter */ 05434 hfmpi2c->AddrEventCount = 0U; 05435 05436 /* Clear ADDR flag */ 05437 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 05438 05439 /* Process Unlocked */ 05440 __HAL_UNLOCK(hfmpi2c); 05441 05442 /* Call Slave Addr callback */ 05443 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05444 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05445 #else 05446 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05447 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05448 } 05449 } 05450 else 05451 { 05452 slaveaddrcode = ownadd2code; 05453 05454 /* Disable ADDR Interrupts */ 05455 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 05456 05457 /* Process Unlocked */ 05458 __HAL_UNLOCK(hfmpi2c); 05459 05460 /* Call Slave Addr callback */ 05461 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05462 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05463 #else 05464 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05465 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05466 } 05467 } 05468 /* else 7 bits addressing mode is selected */ 05469 else 05470 { 05471 /* Disable ADDR Interrupts */ 05472 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 05473 05474 /* Process Unlocked */ 05475 __HAL_UNLOCK(hfmpi2c); 05476 05477 /* Call Slave Addr callback */ 05478 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05479 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05480 #else 05481 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 05482 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05483 } 05484 } 05485 /* Else clear address flag only */ 05486 else 05487 { 05488 /* Clear ADDR flag */ 05489 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 05490 05491 /* Process Unlocked */ 05492 __HAL_UNLOCK(hfmpi2c); 05493 } 05494 } 05495 05496 /** 05497 * @brief FMPI2C Master sequential complete process. 05498 * @param hfmpi2c FMPI2C handle. 05499 * @retval None 05500 */ 05501 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c) 05502 { 05503 /* Reset FMPI2C handle mode */ 05504 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05505 05506 /* No Generate Stop, to permit restart mode */ 05507 /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */ 05508 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 05509 { 05510 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05511 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX; 05512 hfmpi2c->XferISR = NULL; 05513 05514 /* Disable Interrupts */ 05515 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 05516 05517 /* Process Unlocked */ 05518 __HAL_UNLOCK(hfmpi2c); 05519 05520 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05521 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05522 hfmpi2c->MasterTxCpltCallback(hfmpi2c); 05523 #else 05524 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); 05525 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05526 } 05527 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ 05528 else 05529 { 05530 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05531 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX; 05532 hfmpi2c->XferISR = NULL; 05533 05534 /* Disable Interrupts */ 05535 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 05536 05537 /* Process Unlocked */ 05538 __HAL_UNLOCK(hfmpi2c); 05539 05540 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05541 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05542 hfmpi2c->MasterRxCpltCallback(hfmpi2c); 05543 #else 05544 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); 05545 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05546 } 05547 } 05548 05549 /** 05550 * @brief FMPI2C Slave sequential complete process. 05551 * @param hfmpi2c FMPI2C handle. 05552 * @retval None 05553 */ 05554 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c) 05555 { 05556 uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1); 05557 05558 /* Reset FMPI2C handle mode */ 05559 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05560 05561 /* If a DMA is ongoing, Update handle size context */ 05562 if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET) 05563 { 05564 /* Disable DMA Request */ 05565 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 05566 } 05567 else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET) 05568 { 05569 /* Disable DMA Request */ 05570 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 05571 } 05572 else 05573 { 05574 /* Do nothing */ 05575 } 05576 05577 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 05578 { 05579 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */ 05580 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 05581 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX; 05582 05583 /* Disable Interrupts */ 05584 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 05585 05586 /* Process Unlocked */ 05587 __HAL_UNLOCK(hfmpi2c); 05588 05589 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05590 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05591 hfmpi2c->SlaveTxCpltCallback(hfmpi2c); 05592 #else 05593 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); 05594 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05595 } 05596 05597 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 05598 { 05599 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */ 05600 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 05601 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX; 05602 05603 /* Disable Interrupts */ 05604 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 05605 05606 /* Process Unlocked */ 05607 __HAL_UNLOCK(hfmpi2c); 05608 05609 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05610 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05611 hfmpi2c->SlaveRxCpltCallback(hfmpi2c); 05612 #else 05613 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); 05614 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05615 } 05616 else 05617 { 05618 /* Nothing to do */ 05619 } 05620 } 05621 05622 /** 05623 * @brief FMPI2C Master complete process. 05624 * @param hfmpi2c FMPI2C handle. 05625 * @param ITFlags Interrupt flags to handle. 05626 * @retval None 05627 */ 05628 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 05629 { 05630 uint32_t tmperror; 05631 uint32_t tmpITFlags = ITFlags; 05632 __IO uint32_t tmpreg; 05633 05634 /* Clear STOP Flag */ 05635 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 05636 05637 /* Disable Interrupts and Store Previous state */ 05638 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 05639 { 05640 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 05641 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX; 05642 } 05643 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 05644 { 05645 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 05646 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX; 05647 } 05648 else 05649 { 05650 /* Do nothing */ 05651 } 05652 05653 /* Clear Configuration Register 2 */ 05654 FMPI2C_RESET_CR2(hfmpi2c); 05655 05656 /* Reset handle parameters */ 05657 hfmpi2c->XferISR = NULL; 05658 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 05659 05660 if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) 05661 { 05662 /* Clear NACK Flag */ 05663 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05664 05665 /* Set acknowledge error code */ 05666 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 05667 } 05668 05669 /* Fetch Last receive data if any */ 05670 if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) && (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET)) 05671 { 05672 /* Read data from RXDR */ 05673 tmpreg = (uint8_t)hfmpi2c->Instance->RXDR; 05674 UNUSED(tmpreg); 05675 } 05676 05677 /* Flush TX register */ 05678 FMPI2C_Flush_TXDR(hfmpi2c); 05679 05680 /* Store current volatile hfmpi2c->ErrorCode, misra rule */ 05681 tmperror = hfmpi2c->ErrorCode; 05682 05683 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05684 if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) || (tmperror != HAL_FMPI2C_ERROR_NONE)) 05685 { 05686 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05687 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 05688 } 05689 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */ 05690 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 05691 { 05692 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05693 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05694 05695 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) 05696 { 05697 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05698 05699 /* Process Unlocked */ 05700 __HAL_UNLOCK(hfmpi2c); 05701 05702 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05703 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05704 hfmpi2c->MemTxCpltCallback(hfmpi2c); 05705 #else 05706 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c); 05707 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05708 } 05709 else 05710 { 05711 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05712 05713 /* Process Unlocked */ 05714 __HAL_UNLOCK(hfmpi2c); 05715 05716 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05717 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05718 hfmpi2c->MasterTxCpltCallback(hfmpi2c); 05719 #else 05720 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); 05721 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05722 } 05723 } 05724 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ 05725 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 05726 { 05727 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05728 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05729 05730 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) 05731 { 05732 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05733 05734 /* Process Unlocked */ 05735 __HAL_UNLOCK(hfmpi2c); 05736 05737 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05738 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05739 hfmpi2c->MemRxCpltCallback(hfmpi2c); 05740 #else 05741 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c); 05742 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05743 } 05744 else 05745 { 05746 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05747 05748 /* Process Unlocked */ 05749 __HAL_UNLOCK(hfmpi2c); 05750 05751 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05752 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05753 hfmpi2c->MasterRxCpltCallback(hfmpi2c); 05754 #else 05755 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); 05756 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05757 } 05758 } 05759 else 05760 { 05761 /* Nothing to do */ 05762 } 05763 } 05764 05765 /** 05766 * @brief FMPI2C Slave complete process. 05767 * @param hfmpi2c FMPI2C handle. 05768 * @param ITFlags Interrupt flags to handle. 05769 * @retval None 05770 */ 05771 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 05772 { 05773 uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1); 05774 uint32_t tmpITFlags = ITFlags; 05775 HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State; 05776 05777 /* Clear STOP Flag */ 05778 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 05779 05780 /* Disable Interrupts and Store Previous state */ 05781 if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)) 05782 { 05783 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT); 05784 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX; 05785 } 05786 else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)) 05787 { 05788 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT); 05789 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX; 05790 } 05791 else 05792 { 05793 /* Do nothing */ 05794 } 05795 05796 /* Disable Address Acknowledge */ 05797 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 05798 05799 /* Clear Configuration Register 2 */ 05800 FMPI2C_RESET_CR2(hfmpi2c); 05801 05802 /* Flush TX register */ 05803 FMPI2C_Flush_TXDR(hfmpi2c); 05804 05805 /* If a DMA is ongoing, Update handle size context */ 05806 if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET) 05807 { 05808 /* Disable DMA Request */ 05809 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 05810 05811 if (hfmpi2c->hdmatx != NULL) 05812 { 05813 hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx); 05814 } 05815 } 05816 else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET) 05817 { 05818 /* Disable DMA Request */ 05819 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 05820 05821 if (hfmpi2c->hdmarx != NULL) 05822 { 05823 hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx); 05824 } 05825 } 05826 else 05827 { 05828 /* Do nothing */ 05829 } 05830 05831 /* Store Last receive data if any */ 05832 if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) 05833 { 05834 /* Remove RXNE flag on temporary variable as read done */ 05835 tmpITFlags &= ~FMPI2C_FLAG_RXNE; 05836 05837 /* Read data from RXDR */ 05838 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 05839 05840 /* Increment Buffer pointer */ 05841 hfmpi2c->pBuffPtr++; 05842 05843 if ((hfmpi2c->XferSize > 0U)) 05844 { 05845 hfmpi2c->XferSize--; 05846 hfmpi2c->XferCount--; 05847 } 05848 } 05849 05850 /* All data are not transferred, so set error code accordingly */ 05851 if (hfmpi2c->XferCount != 0U) 05852 { 05853 /* Set ErrorCode corresponding to a Non-Acknowledge */ 05854 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 05855 } 05856 05857 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05858 hfmpi2c->XferISR = NULL; 05859 05860 if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) 05861 { 05862 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05863 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 05864 05865 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 05866 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) 05867 { 05868 /* Call FMPI2C Listen complete process */ 05869 FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags); 05870 } 05871 } 05872 else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) 05873 { 05874 /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */ 05875 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 05876 05877 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 05878 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05879 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05880 05881 /* Process Unlocked */ 05882 __HAL_UNLOCK(hfmpi2c); 05883 05884 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 05885 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05886 hfmpi2c->ListenCpltCallback(hfmpi2c); 05887 #else 05888 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); 05889 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05890 } 05891 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05892 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 05893 { 05894 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05895 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05896 05897 /* Process Unlocked */ 05898 __HAL_UNLOCK(hfmpi2c); 05899 05900 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05901 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05902 hfmpi2c->SlaveRxCpltCallback(hfmpi2c); 05903 #else 05904 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); 05905 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05906 } 05907 else 05908 { 05909 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05910 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05911 05912 /* Process Unlocked */ 05913 __HAL_UNLOCK(hfmpi2c); 05914 05915 /* Call the corresponding callback to inform upper layer of End of Transfer */ 05916 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05917 hfmpi2c->SlaveTxCpltCallback(hfmpi2c); 05918 #else 05919 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); 05920 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05921 } 05922 } 05923 05924 /** 05925 * @brief FMPI2C Listen complete process. 05926 * @param hfmpi2c FMPI2C handle. 05927 * @param ITFlags Interrupt flags to handle. 05928 * @retval None 05929 */ 05930 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 05931 { 05932 /* Reset handle parameters */ 05933 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 05934 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 05935 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 05936 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05937 hfmpi2c->XferISR = NULL; 05938 05939 /* Store Last receive data if any */ 05940 if (FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_RXNE) != RESET) 05941 { 05942 /* Read data from RXDR */ 05943 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR; 05944 05945 /* Increment Buffer pointer */ 05946 hfmpi2c->pBuffPtr++; 05947 05948 if ((hfmpi2c->XferSize > 0U)) 05949 { 05950 hfmpi2c->XferSize--; 05951 hfmpi2c->XferCount--; 05952 05953 /* Set ErrorCode corresponding to a Non-Acknowledge */ 05954 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 05955 } 05956 } 05957 05958 /* Disable all Interrupts*/ 05959 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 05960 05961 /* Clear NACK Flag */ 05962 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 05963 05964 /* Process Unlocked */ 05965 __HAL_UNLOCK(hfmpi2c); 05966 05967 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 05968 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 05969 hfmpi2c->ListenCpltCallback(hfmpi2c); 05970 #else 05971 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); 05972 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 05973 } 05974 05975 /** 05976 * @brief FMPI2C interrupts error process. 05977 * @param hfmpi2c FMPI2C handle. 05978 * @param ErrorCode Error code to handle. 05979 * @retval None 05980 */ 05981 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode) 05982 { 05983 HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State; 05984 uint32_t tmppreviousstate; 05985 05986 /* Reset handle parameters */ 05987 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 05988 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 05989 hfmpi2c->XferCount = 0U; 05990 05991 /* Set new error code */ 05992 hfmpi2c->ErrorCode |= ErrorCode; 05993 05994 /* Disable Interrupts */ 05995 if ((tmpstate == HAL_FMPI2C_STATE_LISTEN) || 05996 (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) || 05997 (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)) 05998 { 05999 /* Disable all interrupts, except interrupts related to LISTEN state */ 06000 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 06001 06002 /* keep HAL_FMPI2C_STATE_LISTEN if set */ 06003 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 06004 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 06005 } 06006 else 06007 { 06008 /* Disable all interrupts */ 06009 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 06010 06011 /* If state is an abort treatment on going, don't change state */ 06012 /* This change will be do later */ 06013 if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT) 06014 { 06015 /* Set HAL_FMPI2C_STATE_READY */ 06016 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06017 } 06018 hfmpi2c->XferISR = NULL; 06019 } 06020 06021 /* Abort DMA TX transfer if any */ 06022 tmppreviousstate = hfmpi2c->PreviousState; 06023 if ((hfmpi2c->hdmatx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_TX) || \ 06024 (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_TX))) 06025 { 06026 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) 06027 { 06028 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 06029 } 06030 06031 if (HAL_DMA_GetState(hfmpi2c->hdmatx) != HAL_DMA_STATE_READY) 06032 { 06033 /* Set the FMPI2C DMA Abort callback : 06034 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 06035 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; 06036 06037 /* Process Unlocked */ 06038 __HAL_UNLOCK(hfmpi2c); 06039 06040 /* Abort DMA TX */ 06041 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) 06042 { 06043 /* Call Directly XferAbortCallback function in case of error */ 06044 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); 06045 } 06046 } 06047 else 06048 { 06049 FMPI2C_TreatErrorCallback(hfmpi2c); 06050 } 06051 } 06052 /* Abort DMA RX transfer if any */ 06053 else if ((hfmpi2c->hdmarx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_RX) || \ 06054 (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_RX))) 06055 { 06056 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) 06057 { 06058 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 06059 } 06060 06061 if (HAL_DMA_GetState(hfmpi2c->hdmarx) != HAL_DMA_STATE_READY) 06062 { 06063 /* Set the FMPI2C DMA Abort callback : 06064 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 06065 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; 06066 06067 /* Process Unlocked */ 06068 __HAL_UNLOCK(hfmpi2c); 06069 06070 /* Abort DMA RX */ 06071 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) 06072 { 06073 /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */ 06074 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); 06075 } 06076 } 06077 else 06078 { 06079 FMPI2C_TreatErrorCallback(hfmpi2c); 06080 } 06081 } 06082 else 06083 { 06084 FMPI2C_TreatErrorCallback(hfmpi2c); 06085 } 06086 } 06087 06088 /** 06089 * @brief FMPI2C Error callback treatment. 06090 * @param hfmpi2c FMPI2C handle. 06091 * @retval None 06092 */ 06093 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c) 06094 { 06095 if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) 06096 { 06097 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06098 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 06099 06100 /* Process Unlocked */ 06101 __HAL_UNLOCK(hfmpi2c); 06102 06103 /* Call the corresponding callback to inform upper layer of End of Transfer */ 06104 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 06105 hfmpi2c->AbortCpltCallback(hfmpi2c); 06106 #else 06107 HAL_FMPI2C_AbortCpltCallback(hfmpi2c); 06108 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 06109 } 06110 else 06111 { 06112 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 06113 06114 /* Process Unlocked */ 06115 __HAL_UNLOCK(hfmpi2c); 06116 06117 /* Call the corresponding callback to inform upper layer of End of Transfer */ 06118 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1) 06119 hfmpi2c->ErrorCallback(hfmpi2c); 06120 #else 06121 HAL_FMPI2C_ErrorCallback(hfmpi2c); 06122 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */ 06123 } 06124 } 06125 06126 /** 06127 * @brief FMPI2C Tx data register flush process. 06128 * @param hfmpi2c FMPI2C handle. 06129 * @retval None 06130 */ 06131 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c) 06132 { 06133 /* If a pending TXIS flag is set */ 06134 /* Write a dummy data in TXDR to clear it */ 06135 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET) 06136 { 06137 hfmpi2c->Instance->TXDR = 0x00U; 06138 } 06139 06140 /* Flush TX register if not empty */ 06141 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET) 06142 { 06143 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE); 06144 } 06145 } 06146 06147 /** 06148 * @brief DMA FMPI2C master transmit process complete callback. 06149 * @param hdma DMA handle 06150 * @retval None 06151 */ 06152 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) 06153 { 06154 /* Derogation MISRAC2012-Rule-11.5 */ 06155 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06156 06157 /* Disable DMA Request */ 06158 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 06159 06160 /* If last transfer, enable STOP interrupt */ 06161 if (hfmpi2c->XferCount == 0U) 06162 { 06163 /* Enable STOP interrupt */ 06164 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 06165 } 06166 /* else prepare a new DMA transfer and enable TCReload interrupt */ 06167 else 06168 { 06169 /* Update Buffer pointer */ 06170 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; 06171 06172 /* Set the XferSize to transfer */ 06173 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 06174 { 06175 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 06176 } 06177 else 06178 { 06179 hfmpi2c->XferSize = hfmpi2c->XferCount; 06180 } 06181 06182 /* Enable the DMA stream */ 06183 if (HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, 06184 hfmpi2c->XferSize) != HAL_OK) 06185 { 06186 /* Call the corresponding callback to inform upper layer of End of Transfer */ 06187 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA); 06188 } 06189 else 06190 { 06191 /* Enable TC interrupts */ 06192 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); 06193 } 06194 } 06195 } 06196 06197 /** 06198 * @brief DMA FMPI2C slave transmit process complete callback. 06199 * @param hdma DMA handle 06200 * @retval None 06201 */ 06202 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) 06203 { 06204 /* Derogation MISRAC2012-Rule-11.5 */ 06205 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06206 uint32_t tmpoptions = hfmpi2c->XferOptions; 06207 06208 if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME)) 06209 { 06210 /* Disable DMA Request */ 06211 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 06212 06213 /* Last Byte is Transmitted */ 06214 /* Call FMPI2C Slave Sequential complete process */ 06215 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 06216 } 06217 else 06218 { 06219 /* No specific action, Master fully manage the generation of STOP condition */ 06220 /* Mean that this generation can arrive at any time, at the end or during DMA process */ 06221 /* So STOP condition should be manage through Interrupt treatment */ 06222 } 06223 } 06224 06225 /** 06226 * @brief DMA FMPI2C master receive process complete callback. 06227 * @param hdma DMA handle 06228 * @retval None 06229 */ 06230 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) 06231 { 06232 /* Derogation MISRAC2012-Rule-11.5 */ 06233 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06234 06235 /* Disable DMA Request */ 06236 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 06237 06238 /* If last transfer, enable STOP interrupt */ 06239 if (hfmpi2c->XferCount == 0U) 06240 { 06241 /* Enable STOP interrupt */ 06242 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 06243 } 06244 /* else prepare a new DMA transfer and enable TCReload interrupt */ 06245 else 06246 { 06247 /* Update Buffer pointer */ 06248 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; 06249 06250 /* Set the XferSize to transfer */ 06251 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 06252 { 06253 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 06254 } 06255 else 06256 { 06257 hfmpi2c->XferSize = hfmpi2c->XferCount; 06258 } 06259 06260 /* Enable the DMA stream */ 06261 if (HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, 06262 hfmpi2c->XferSize) != HAL_OK) 06263 { 06264 /* Call the corresponding callback to inform upper layer of End of Transfer */ 06265 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA); 06266 } 06267 else 06268 { 06269 /* Enable TC interrupts */ 06270 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); 06271 } 06272 } 06273 } 06274 06275 /** 06276 * @brief DMA FMPI2C slave receive process complete callback. 06277 * @param hdma DMA handle 06278 * @retval None 06279 */ 06280 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) 06281 { 06282 /* Derogation MISRAC2012-Rule-11.5 */ 06283 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06284 uint32_t tmpoptions = hfmpi2c->XferOptions; 06285 06286 if ((__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U) && \ 06287 (tmpoptions != FMPI2C_NO_OPTION_FRAME)) 06288 { 06289 /* Disable DMA Request */ 06290 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 06291 06292 /* Call FMPI2C Slave Sequential complete process */ 06293 FMPI2C_ITSlaveSeqCplt(hfmpi2c); 06294 } 06295 else 06296 { 06297 /* No specific action, Master fully manage the generation of STOP condition */ 06298 /* Mean that this generation can arrive at any time, at the end or during DMA process */ 06299 /* So STOP condition should be manage through Interrupt treatment */ 06300 } 06301 } 06302 06303 /** 06304 * @brief DMA FMPI2C communication error callback. 06305 * @param hdma DMA handle 06306 * @retval None 06307 */ 06308 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma) 06309 { 06310 uint32_t treatdmaerror = 0U; 06311 /* Derogation MISRAC2012-Rule-11.5 */ 06312 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06313 06314 if (hfmpi2c->hdmatx != NULL) 06315 { 06316 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U) 06317 { 06318 treatdmaerror = 1U; 06319 } 06320 } 06321 06322 if (hfmpi2c->hdmarx != NULL) 06323 { 06324 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U) 06325 { 06326 treatdmaerror = 1U; 06327 } 06328 } 06329 06330 /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */ 06331 if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U)) 06332 { 06333 /* Disable Acknowledge */ 06334 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 06335 06336 /* Call the corresponding callback to inform upper layer of End of Transfer */ 06337 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA); 06338 } 06339 } 06340 06341 /** 06342 * @brief DMA FMPI2C communication abort callback 06343 * (To be called at end of DMA Abort procedure). 06344 * @param hdma DMA handle. 06345 * @retval None 06346 */ 06347 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma) 06348 { 06349 /* Derogation MISRAC2012-Rule-11.5 */ 06350 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); 06351 06352 /* Reset AbortCpltCallback */ 06353 if (hfmpi2c->hdmatx != NULL) 06354 { 06355 hfmpi2c->hdmatx->XferAbortCallback = NULL; 06356 } 06357 if (hfmpi2c->hdmarx != NULL) 06358 { 06359 hfmpi2c->hdmarx->XferAbortCallback = NULL; 06360 } 06361 06362 FMPI2C_TreatErrorCallback(hfmpi2c); 06363 } 06364 06365 /** 06366 * @brief This function handles FMPI2C Communication Timeout. 06367 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06368 * the configuration information for the specified FMPI2C. 06369 * @param Flag Specifies the FMPI2C flag to check. 06370 * @param Status The new Flag status (SET or RESET). 06371 * @param Timeout Timeout duration 06372 * @param Tickstart Tick start value 06373 * @retval HAL status 06374 */ 06375 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, 06376 uint32_t Timeout, uint32_t Tickstart) 06377 { 06378 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status) 06379 { 06380 /* Check for the Timeout */ 06381 if (Timeout != HAL_MAX_DELAY) 06382 { 06383 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 06384 { 06385 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 06386 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06387 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06388 06389 /* Process Unlocked */ 06390 __HAL_UNLOCK(hfmpi2c); 06391 return HAL_ERROR; 06392 } 06393 } 06394 } 06395 return HAL_OK; 06396 } 06397 06398 /** 06399 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag. 06400 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06401 * the configuration information for the specified FMPI2C. 06402 * @param Timeout Timeout duration 06403 * @param Tickstart Tick start value 06404 * @retval HAL status 06405 */ 06406 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 06407 uint32_t Tickstart) 06408 { 06409 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET) 06410 { 06411 /* Check if a NACK is detected */ 06412 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 06413 { 06414 return HAL_ERROR; 06415 } 06416 06417 /* Check for the Timeout */ 06418 if (Timeout != HAL_MAX_DELAY) 06419 { 06420 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 06421 { 06422 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 06423 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06424 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06425 06426 /* Process Unlocked */ 06427 __HAL_UNLOCK(hfmpi2c); 06428 06429 return HAL_ERROR; 06430 } 06431 } 06432 } 06433 return HAL_OK; 06434 } 06435 06436 /** 06437 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag. 06438 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06439 * the configuration information for the specified FMPI2C. 06440 * @param Timeout Timeout duration 06441 * @param Tickstart Tick start value 06442 * @retval HAL status 06443 */ 06444 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 06445 uint32_t Tickstart) 06446 { 06447 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) 06448 { 06449 /* Check if a NACK is detected */ 06450 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 06451 { 06452 return HAL_ERROR; 06453 } 06454 06455 /* Check for the Timeout */ 06456 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 06457 { 06458 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 06459 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06460 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06461 06462 /* Process Unlocked */ 06463 __HAL_UNLOCK(hfmpi2c); 06464 06465 return HAL_ERROR; 06466 } 06467 } 06468 return HAL_OK; 06469 } 06470 06471 /** 06472 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag. 06473 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06474 * the configuration information for the specified FMPI2C. 06475 * @param Timeout Timeout duration 06476 * @param Tickstart Tick start value 06477 * @retval HAL status 06478 */ 06479 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, 06480 uint32_t Tickstart) 06481 { 06482 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET) 06483 { 06484 /* Check if a NACK is detected */ 06485 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 06486 { 06487 return HAL_ERROR; 06488 } 06489 06490 /* Check if a STOPF is detected */ 06491 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) 06492 { 06493 /* Check if an RXNE is pending */ 06494 /* Store Last receive data if any */ 06495 if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U)) 06496 { 06497 /* Return HAL_OK */ 06498 /* The Reading of data from RXDR will be done in caller function */ 06499 return HAL_OK; 06500 } 06501 else 06502 { 06503 /* Clear STOP Flag */ 06504 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 06505 06506 /* Clear Configuration Register 2 */ 06507 FMPI2C_RESET_CR2(hfmpi2c); 06508 06509 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 06510 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06511 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06512 06513 /* Process Unlocked */ 06514 __HAL_UNLOCK(hfmpi2c); 06515 06516 return HAL_ERROR; 06517 } 06518 } 06519 06520 /* Check for the Timeout */ 06521 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 06522 { 06523 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 06524 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06525 06526 /* Process Unlocked */ 06527 __HAL_UNLOCK(hfmpi2c); 06528 06529 return HAL_ERROR; 06530 } 06531 } 06532 return HAL_OK; 06533 } 06534 06535 /** 06536 * @brief This function handles Acknowledge failed detection during an FMPI2C Communication. 06537 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06538 * the configuration information for the specified FMPI2C. 06539 * @param Timeout Timeout duration 06540 * @param Tickstart Tick start value 06541 * @retval HAL status 06542 */ 06543 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) 06544 { 06545 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) 06546 { 06547 /* In case of Soft End condition, generate the STOP condition */ 06548 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 06549 { 06550 /* Generate Stop */ 06551 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 06552 } 06553 /* Wait until STOP Flag is reset */ 06554 /* AutoEnd should be initiate after AF */ 06555 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) 06556 { 06557 /* Check for the Timeout */ 06558 if (Timeout != HAL_MAX_DELAY) 06559 { 06560 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) 06561 { 06562 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 06563 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06564 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06565 06566 /* Process Unlocked */ 06567 __HAL_UNLOCK(hfmpi2c); 06568 06569 return HAL_ERROR; 06570 } 06571 } 06572 } 06573 06574 /* Clear NACKF Flag */ 06575 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 06576 06577 /* Clear STOP Flag */ 06578 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 06579 06580 /* Flush TX register */ 06581 FMPI2C_Flush_TXDR(hfmpi2c); 06582 06583 /* Clear Configuration Register 2 */ 06584 FMPI2C_RESET_CR2(hfmpi2c); 06585 06586 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 06587 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 06588 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 06589 06590 /* Process Unlocked */ 06591 __HAL_UNLOCK(hfmpi2c); 06592 06593 return HAL_ERROR; 06594 } 06595 return HAL_OK; 06596 } 06597 06598 /** 06599 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set). 06600 * @param hfmpi2c FMPI2C handle. 06601 * @param DevAddress Specifies the slave address to be programmed. 06602 * @param Size Specifies the number of bytes to be programmed. 06603 * This parameter must be a value between 0 and 255. 06604 * @param Mode New state of the FMPI2C START condition generation. 06605 * This parameter can be one of the following values: 06606 * @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode . 06607 * @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode. 06608 * @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode. 06609 * @param Request New state of the FMPI2C START condition generation. 06610 * This parameter can be one of the following values: 06611 * @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition. 06612 * @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0). 06613 * @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request. 06614 * @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request. 06615 * @retval None 06616 */ 06617 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, 06618 uint32_t Request) 06619 { 06620 /* Check the parameters */ 06621 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 06622 assert_param(IS_TRANSFER_MODE(Mode)); 06623 assert_param(IS_TRANSFER_REQUEST(Request)); 06624 06625 /* update CR2 register */ 06626 MODIFY_REG(hfmpi2c->Instance->CR2, 06627 ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \ 06628 (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | \ 06629 FMPI2C_CR2_START | FMPI2C_CR2_STOP)), \ 06630 (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \ 06631 (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \ 06632 (uint32_t)Mode | (uint32_t)Request)); 06633 } 06634 06635 /** 06636 * @brief Manage the enabling of Interrupts. 06637 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06638 * the configuration information for the specified FMPI2C. 06639 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. 06640 * @retval None 06641 */ 06642 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) 06643 { 06644 uint32_t tmpisr = 0U; 06645 06646 if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \ 06647 (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA)) 06648 { 06649 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 06650 { 06651 /* Enable ERR, STOP, NACK and ADDR interrupts */ 06652 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 06653 } 06654 06655 if (InterruptRequest == FMPI2C_XFER_ERROR_IT) 06656 { 06657 /* Enable ERR and NACK interrupts */ 06658 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; 06659 } 06660 06661 if (InterruptRequest == FMPI2C_XFER_CPLT_IT) 06662 { 06663 /* Enable STOP interrupts */ 06664 tmpisr |= (FMPI2C_IT_STOPI | FMPI2C_IT_TCI); 06665 } 06666 06667 if (InterruptRequest == FMPI2C_XFER_RELOAD_IT) 06668 { 06669 /* Enable TC interrupts */ 06670 tmpisr |= FMPI2C_IT_TCI; 06671 } 06672 } 06673 else 06674 { 06675 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 06676 { 06677 /* Enable ERR, STOP, NACK, and ADDR interrupts */ 06678 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 06679 } 06680 06681 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) 06682 { 06683 /* Enable ERR, TC, STOP, NACK and RXI interrupts */ 06684 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI; 06685 } 06686 06687 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) 06688 { 06689 /* Enable ERR, TC, STOP, NACK and TXI interrupts */ 06690 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI; 06691 } 06692 06693 if (InterruptRequest == FMPI2C_XFER_CPLT_IT) 06694 { 06695 /* Enable STOP interrupts */ 06696 tmpisr |= FMPI2C_IT_STOPI; 06697 } 06698 } 06699 06700 /* Enable interrupts only at the end */ 06701 /* to avoid the risk of FMPI2C interrupt handle execution before */ 06702 /* all interrupts requested done */ 06703 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr); 06704 } 06705 06706 /** 06707 * @brief Manage the disabling of Interrupts. 06708 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 06709 * the configuration information for the specified FMPI2C. 06710 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. 06711 * @retval None 06712 */ 06713 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) 06714 { 06715 uint32_t tmpisr = 0U; 06716 06717 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) 06718 { 06719 /* Disable TC and TXI interrupts */ 06720 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI; 06721 06722 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN) 06723 { 06724 /* Disable NACK and STOP interrupts */ 06725 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 06726 } 06727 } 06728 06729 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) 06730 { 06731 /* Disable TC and RXI interrupts */ 06732 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI; 06733 06734 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN) 06735 { 06736 /* Disable NACK and STOP interrupts */ 06737 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 06738 } 06739 } 06740 06741 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 06742 { 06743 /* Disable ADDR, NACK and STOP interrupts */ 06744 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 06745 } 06746 06747 if (InterruptRequest == FMPI2C_XFER_ERROR_IT) 06748 { 06749 /* Enable ERR and NACK interrupts */ 06750 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; 06751 } 06752 06753 if (InterruptRequest == FMPI2C_XFER_CPLT_IT) 06754 { 06755 /* Enable STOP interrupts */ 06756 tmpisr |= FMPI2C_IT_STOPI; 06757 } 06758 06759 if (InterruptRequest == FMPI2C_XFER_RELOAD_IT) 06760 { 06761 /* Enable TC interrupts */ 06762 tmpisr |= FMPI2C_IT_TCI; 06763 } 06764 06765 /* Disable interrupts only at the end */ 06766 /* to avoid a breaking situation like at "t" time */ 06767 /* all disable interrupts request are not done */ 06768 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr); 06769 } 06770 06771 /** 06772 * @brief Convert FMPI2Cx OTHER_xxx XferOptions to functional XferOptions. 06773 * @param hfmpi2c FMPI2C handle. 06774 * @retval None 06775 */ 06776 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c) 06777 { 06778 /* if user set XferOptions to FMPI2C_OTHER_FRAME */ 06779 /* it request implicitly to generate a restart condition */ 06780 /* set XferOptions to FMPI2C_FIRST_FRAME */ 06781 if (hfmpi2c->XferOptions == FMPI2C_OTHER_FRAME) 06782 { 06783 hfmpi2c->XferOptions = FMPI2C_FIRST_FRAME; 06784 } 06785 /* else if user set XferOptions to FMPI2C_OTHER_AND_LAST_FRAME */ 06786 /* it request implicitly to generate a restart condition */ 06787 /* then generate a stop condition at the end of transfer */ 06788 /* set XferOptions to FMPI2C_FIRST_AND_LAST_FRAME */ 06789 else if (hfmpi2c->XferOptions == FMPI2C_OTHER_AND_LAST_FRAME) 06790 { 06791 hfmpi2c->XferOptions = FMPI2C_FIRST_AND_LAST_FRAME; 06792 } 06793 else 06794 { 06795 /* Nothing to do */ 06796 } 06797 } 06798 06799 /** 06800 * @} 06801 */ 06802 06803 #endif /* FMPI2C_CR1_PE */ 06804 #endif /* HAL_FMPI2C_MODULE_ENABLED */ 06805 /** 06806 * @} 06807 */ 06808 06809 /** 06810 * @} 06811 */ 06812 06813 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/