STM32F439xx 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 the transmit or receive stream 00032 (+++) Enable the DMAx interface clock using 00033 (+++) Configure the DMA handle parameters 00034 (+++) Configure the DMA Tx or Rx stream 00035 (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle 00036 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on 00037 the DMA Tx or Rx stream 00038 00039 (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode, 00040 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure. 00041 00042 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware 00043 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API. 00044 00045 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady() 00046 00047 (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver : 00048 00049 *** Polling mode IO operation *** 00050 ================================= 00051 [..] 00052 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit() 00053 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive() 00054 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit() 00055 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive() 00056 00057 *** Polling mode IO MEM operation *** 00058 ===================================== 00059 [..] 00060 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write() 00061 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read() 00062 00063 00064 *** Interrupt mode IO operation *** 00065 =================================== 00066 [..] 00067 (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT() 00068 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00069 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00070 (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT() 00071 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00072 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00073 (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT() 00074 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00075 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00076 (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT() 00077 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00078 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00079 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00080 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00081 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00082 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00083 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00084 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00085 This action will inform Master to generate a Stop condition to discard the communication. 00086 00087 00088 *** Interrupt mode IO sequential operation *** 00089 ============================================== 00090 [..] 00091 (@) These interfaces allow to manage a sequential transfer with a repeated start condition 00092 when a direction change during transfer 00093 [..] 00094 (+) A specific option field manage the different steps of a sequential transfer 00095 (+) Option field values are defined through @ref FMPI2C_XFEROPTIONS and are listed below: 00096 (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode 00097 (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address 00098 and data to transfer without a final stop condition 00099 (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address 00100 and data to transfer without a final stop condition, an then permit a call the same master sequential interface 00101 several times (like HAL_FMPI2C_Master_Sequential_Transmit_IT() then HAL_FMPI2C_Master_Sequential_Transmit_IT()) 00102 (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address 00103 and with new data to transfer if the direction change or manage only the new data to transfer 00104 if no direction change and without a final stop condition in both cases 00105 (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address 00106 and with new data to transfer if the direction change or manage only the new data to transfer 00107 if no direction change and with a final stop condition in both cases 00108 (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential 00109 interface several times (link with option FMPI2C_FIRST_AND_NEXT_FRAME). 00110 Usage can, transfer several bytes one by one using HAL_FMPI2C_Master_Sequential_Transmit_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME) 00111 or HAL_FMPI2C_Master_Sequential_Receive_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME). 00112 Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the oposite interface Receive or Transmit 00113 without stopping the communication and so generate a restart condition. 00114 00115 (+) Differents sequential FMPI2C interfaces are listed below: 00116 (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Transmit_IT() 00117 (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00118 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00119 (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Receive_IT() 00120 (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00121 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00122 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00123 (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00124 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00125 (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT() 00126 (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can 00127 add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). 00128 (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can 00129 add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback() 00130 (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Transmit_IT() 00131 (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00132 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00133 (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Receive_IT() 00134 (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00135 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00136 (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00137 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00138 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00139 (++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00140 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00141 (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00142 This action will inform Master to generate a Stop condition to discard the communication. 00143 00144 *** Interrupt mode IO MEM operation *** 00145 ======================================= 00146 [..] 00147 (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using 00148 HAL_FMPI2C_Mem_Write_IT() 00149 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can 00150 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() 00151 (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using 00152 HAL_FMPI2C_Mem_Read_IT() 00153 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can 00154 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() 00155 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00156 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00157 00158 *** DMA mode IO operation *** 00159 ============================== 00160 [..] 00161 (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using 00162 HAL_FMPI2C_Master_Transmit_DMA() 00163 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can 00164 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback() 00165 (+) Receive in master mode an amount of data in non-blocking mode (DMA) using 00166 HAL_FMPI2C_Master_Receive_DMA() 00167 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can 00168 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback() 00169 (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using 00170 HAL_FMPI2C_Slave_Transmit_DMA() 00171 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can 00172 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback() 00173 (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using 00174 HAL_FMPI2C_Slave_Receive_DMA() 00175 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can 00176 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback() 00177 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00178 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00179 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT() 00180 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can 00181 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback() 00182 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro. 00183 This action will inform Master to generate a Stop condition to discard the communication. 00184 00185 *** DMA mode IO MEM operation *** 00186 ================================= 00187 [..] 00188 (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using 00189 HAL_FMPI2C_Mem_Write_DMA() 00190 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can 00191 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback() 00192 (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using 00193 HAL_FMPI2C_Mem_Read_DMA() 00194 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can 00195 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback() 00196 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can 00197 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback() 00198 00199 00200 *** FMPI2C HAL driver macros list *** 00201 ================================== 00202 [..] 00203 Below the list of most used macros in FMPI2C HAL driver. 00204 00205 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral 00206 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral 00207 (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode 00208 (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not 00209 (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag 00210 (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt 00211 (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt 00212 00213 [..] 00214 (@) You can refer to the FMPI2C HAL driver header file for more useful macros 00215 00216 @endverbatim 00217 ****************************************************************************** 00218 * @attention 00219 * 00220 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00221 * 00222 * Redistribution and use in source and binary forms, with or without modification, 00223 * are permitted provided that the following conditions are met: 00224 * 1. Redistributions of source code must retain the above copyright notice, 00225 * this list of conditions and the following disclaimer. 00226 * 2. Redistributions in binary form must reproduce the above copyright notice, 00227 * this list of conditions and the following disclaimer in the documentation 00228 * and/or other materials provided with the distribution. 00229 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00230 * may be used to endorse or promote products derived from this software 00231 * without specific prior written permission. 00232 * 00233 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00234 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00235 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00236 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00237 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00238 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00239 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00240 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00241 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00242 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00243 * 00244 ****************************************************************************** 00245 */ 00246 00247 /* Includes ------------------------------------------------------------------*/ 00248 #include "stm32f4xx_hal.h" 00249 00250 /** @addtogroup STM32F4xx_HAL_Driver 00251 * @{ 00252 */ 00253 00254 /** @defgroup FMPI2C FMPI2C 00255 * @brief FMPI2C HAL module driver 00256 * @{ 00257 */ 00258 00259 #ifdef HAL_FMPI2C_MODULE_ENABLED 00260 00261 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F412Zx) ||\ 00262 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 00263 00264 /* Private typedef -----------------------------------------------------------*/ 00265 /* Private define ------------------------------------------------------------*/ 00266 00267 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define 00268 * @{ 00269 */ 00270 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< FMPI2C TIMING clear register Mask */ 00271 #define FMPI2C_TIMEOUT_ADDR (10000U) /*!< 10 s */ 00272 #define FMPI2C_TIMEOUT_BUSY (25U) /*!< 25 ms */ 00273 #define FMPI2C_TIMEOUT_DIR (25U) /*!< 25 ms */ 00274 #define FMPI2C_TIMEOUT_RXNE (25U) /*!< 25 ms */ 00275 #define FMPI2C_TIMEOUT_STOPF (25U) /*!< 25 ms */ 00276 #define FMPI2C_TIMEOUT_TC (25U) /*!< 25 ms */ 00277 #define FMPI2C_TIMEOUT_TCR (25U) /*!< 25 ms */ 00278 #define FMPI2C_TIMEOUT_TXIS (25U) /*!< 25 ms */ 00279 #define FMPI2C_TIMEOUT_FLAG (25U) /*!< 25 ms */ 00280 00281 #define MAX_NBYTE_SIZE 255U 00282 #define SlaveAddr_SHIFT 7U 00283 #define SlaveAddr_MSK 0x06U 00284 00285 /* Private define for @ref PreviousState usage */ 00286 #define FMPI2C_STATE_MSK ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX | HAL_FMPI2C_STATE_BUSY_RX) & (~((uint32_t)HAL_FMPI2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits */ 00287 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE)) /*!< Default Value */ 00288 #define FMPI2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ 00289 #define FMPI2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ 00290 #define FMPI2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ 00291 #define FMPI2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ 00292 #define FMPI2C_STATE_MEM_BUSY_TX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM)) /*!< Memory Busy TX, combinaison of State LSB and Mode enum */ 00293 #define FMPI2C_STATE_MEM_BUSY_RX ((uint32_t)((HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | HAL_FMPI2C_MODE_MEM)) /*!< Memory Busy RX, combinaison of State LSB and Mode enum */ 00294 00295 00296 /* Private define to centralize the enable/disable of Interrupts */ 00297 #define FMPI2C_XFER_TX_IT (0x00000001U) 00298 #define FMPI2C_XFER_RX_IT (0x00000002U) 00299 #define FMPI2C_XFER_LISTEN_IT (0x00000004U) 00300 00301 #define FMPI2C_XFER_ERROR_IT (0x00000011U) 00302 #define FMPI2C_XFER_CPLT_IT (0x00000012U) 00303 #define FMPI2C_XFER_RELOAD_IT (0x00000012U) 00304 00305 /* Private define Sequential Transfer Options default/reset value */ 00306 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U) 00307 /** 00308 * @} 00309 */ 00310 00311 /* Private macro -------------------------------------------------------------*/ 00312 #define FMPI2C_GET_DMA_REMAIN_DATA(__HANDLE__) ((((__HANDLE__)->State) == HAL_FMPI2C_STATE_BUSY_TX) ? \ 00313 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmatx->Instance)->NDTR)) : \ 00314 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmarx->Instance)->NDTR))) 00315 00316 /* Private variables ---------------------------------------------------------*/ 00317 /* Private function prototypes -----------------------------------------------*/ 00318 00319 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions 00320 * @{ 00321 */ 00322 /* Private functions to handle DMA transfer */ 00323 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); 00324 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); 00325 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); 00326 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); 00327 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma); 00328 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma); 00329 00330 /* Private functions to handle IT transfer */ 00331 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00332 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c); 00333 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c); 00334 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00335 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00336 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags); 00337 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode); 00338 00339 /* Private functions to handle IT transfer */ 00340 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); 00341 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); 00342 00343 /* Private functions for FMPI2C transfer IRQ handler */ 00344 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); 00345 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); 00346 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); 00347 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources); 00348 00349 /* Private functions to handle flags during polling transfer */ 00350 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); 00351 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); 00352 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); 00353 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); 00354 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart); 00355 00356 /* Private functions to centralize the enable/disable of Interrupts */ 00357 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); 00358 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest); 00359 00360 /* Private functions to flush TXDR register */ 00361 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c); 00362 00363 /* Private functions to handle start, restart or stop a transfer */ 00364 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request); 00365 /** 00366 * @} 00367 */ 00368 00369 /* Exported functions --------------------------------------------------------*/ 00370 00371 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions 00372 * @{ 00373 */ 00374 00375 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions 00376 * @brief Initialization and Configuration functions 00377 * 00378 @verbatim 00379 =============================================================================== 00380 ##### Initialization and de-initialization functions ##### 00381 =============================================================================== 00382 [..] This subsection provides a set of functions allowing to initialize and 00383 deinitialize the FMPI2Cx peripheral: 00384 00385 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures 00386 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). 00387 00388 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with 00389 the selected configuration: 00390 (++) Clock Timing 00391 (++) Own Address 1 00392 (++) Addressing mode (Master, Slave) 00393 (++) Dual Addressing mode 00394 (++) Own Address 2 00395 (++) Own Address 2 Mask 00396 (++) General call mode 00397 (++) Nostretch mode 00398 00399 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration 00400 of the selected FMPI2Cx peripheral. 00401 00402 @endverbatim 00403 * @{ 00404 */ 00405 00406 /** 00407 * @brief Initializes the FMPI2C according to the specified parameters 00408 * in the FMPI2C_InitTypeDef and initialize the associated handle. 00409 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00410 * the configuration information for the specified FMPI2C. 00411 * @retval HAL status 00412 */ 00413 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c) 00414 { 00415 /* Check the FMPI2C handle allocation */ 00416 if (hfmpi2c == NULL) 00417 { 00418 return HAL_ERROR; 00419 } 00420 00421 /* Check the parameters */ 00422 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 00423 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1)); 00424 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode)); 00425 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode)); 00426 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2)); 00427 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks)); 00428 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode)); 00429 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode)); 00430 00431 if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET) 00432 { 00433 /* Allocate lock resource and initialize it */ 00434 hfmpi2c->Lock = HAL_UNLOCKED; 00435 00436 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00437 HAL_FMPI2C_MspInit(hfmpi2c); 00438 } 00439 00440 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 00441 00442 /* Disable the selected FMPI2C peripheral */ 00443 __HAL_FMPI2C_DISABLE(hfmpi2c); 00444 00445 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/ 00446 /* Configure FMPI2Cx: Frequency range */ 00447 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK; 00448 00449 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/ 00450 /* Disable Own Address1 before set the Own Address1 configuration */ 00451 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN; 00452 00453 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */ 00454 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT) 00455 { 00456 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1); 00457 } 00458 else /* FMPI2C_ADDRESSINGMODE_10BIT */ 00459 { 00460 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1); 00461 } 00462 00463 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/ 00464 /* Configure FMPI2Cx: Addressing Master mode */ 00465 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 00466 { 00467 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10); 00468 } 00469 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ 00470 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK); 00471 00472 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/ 00473 /* Disable Own Address2 before set the Own Address2 configuration */ 00474 hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE; 00475 00476 /* Configure FMPI2Cx: Dual mode and Own Address2 */ 00477 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8)); 00478 00479 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/ 00480 /* Configure FMPI2Cx: Generalcall and NoStretch mode */ 00481 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode); 00482 00483 /* Enable the selected FMPI2C peripheral */ 00484 __HAL_FMPI2C_ENABLE(hfmpi2c); 00485 00486 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00487 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 00488 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 00489 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00490 00491 return HAL_OK; 00492 } 00493 00494 /** 00495 * @brief DeInitialize the FMPI2C peripheral. 00496 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00497 * the configuration information for the specified FMPI2C. 00498 * @retval HAL status 00499 */ 00500 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c) 00501 { 00502 /* Check the FMPI2C handle allocation */ 00503 if (hfmpi2c == NULL) 00504 { 00505 return HAL_ERROR; 00506 } 00507 00508 /* Check the parameters */ 00509 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 00510 00511 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 00512 00513 /* Disable the FMPI2C Peripheral Clock */ 00514 __HAL_FMPI2C_DISABLE(hfmpi2c); 00515 00516 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ 00517 HAL_FMPI2C_MspDeInit(hfmpi2c); 00518 00519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00520 hfmpi2c->State = HAL_FMPI2C_STATE_RESET; 00521 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 00522 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00523 00524 /* Release Lock */ 00525 __HAL_UNLOCK(hfmpi2c); 00526 00527 return HAL_OK; 00528 } 00529 00530 /** 00531 * @brief Initialize the FMPI2C MSP. 00532 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00533 * the configuration information for the specified FMPI2C. 00534 * @retval None 00535 */ 00536 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c) 00537 { 00538 /* Prevent unused argument(s) compilation warning */ 00539 UNUSED(hfmpi2c); 00540 00541 /* NOTE : This function should not be modified, when the callback is needed, 00542 the HAL_FMPI2C_MspInit could be implemented in the user file 00543 */ 00544 } 00545 00546 /** 00547 * @brief DeInitialize the FMPI2C MSP. 00548 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00549 * the configuration information for the specified FMPI2C. 00550 * @retval None 00551 */ 00552 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c) 00553 { 00554 /* Prevent unused argument(s) compilation warning */ 00555 UNUSED(hfmpi2c); 00556 00557 /* NOTE : This function should not be modified, when the callback is needed, 00558 the HAL_FMPI2C_MspDeInit could be implemented in the user file 00559 */ 00560 } 00561 00562 /** 00563 * @} 00564 */ 00565 00566 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions 00567 * @brief Data transfers functions 00568 * 00569 @verbatim 00570 =============================================================================== 00571 ##### IO operation functions ##### 00572 =============================================================================== 00573 [..] 00574 This subsection provides a set of functions allowing to manage the FMPI2C data 00575 transfers. 00576 00577 (#) There are two modes of transfer: 00578 (++) Blocking mode : The communication is performed in the polling mode. 00579 The status of all data processing is returned by the same function 00580 after finishing transfer. 00581 (++) No-Blocking mode : The communication is performed using Interrupts 00582 or DMA. These functions return the status of the transfer startup. 00583 The end of the data processing will be indicated through the 00584 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when 00585 using DMA mode. 00586 00587 (#) Blocking mode functions are : 00588 (++) HAL_FMPI2C_Master_Transmit() 00589 (++) HAL_FMPI2C_Master_Receive() 00590 (++) HAL_FMPI2C_Slave_Transmit() 00591 (++) HAL_FMPI2C_Slave_Receive() 00592 (++) HAL_FMPI2C_Mem_Write() 00593 (++) HAL_FMPI2C_Mem_Read() 00594 (++) HAL_FMPI2C_IsDeviceReady() 00595 00596 (#) No-Blocking mode functions with Interrupt are : 00597 (++) HAL_FMPI2C_Master_Transmit_IT() 00598 (++) HAL_FMPI2C_Master_Receive_IT() 00599 (++) HAL_FMPI2C_Slave_Transmit_IT() 00600 (++) HAL_FMPI2C_Slave_Receive_IT() 00601 (++) HAL_FMPI2C_Master_Sequential_Transmit_IT() 00602 (++) HAL_FMPI2C_Master_Sequential_Receive_IT() 00603 (++) HAL_FMPI2C_Slave_Sequential_Transmit_IT() 00604 (++) HAL_FMPI2C_Slave_Sequential_Receive_IT() 00605 (++) HAL_FMPI2C_Mem_Write_IT() 00606 (++) HAL_FMPI2C_Mem_Read_IT() 00607 00608 (#) No-Blocking mode functions with DMA are : 00609 (++) HAL_FMPI2C_Master_Transmit_DMA() 00610 (++) HAL_FMPI2C_Master_Receive_DMA() 00611 (++) HAL_FMPI2C_Slave_Transmit_DMA() 00612 (++) HAL_FMPI2C_Slave_Receive_DMA() 00613 (++) HAL_FMPI2C_Mem_Write_DMA() 00614 (++) HAL_FMPI2C_Mem_Read_DMA() 00615 00616 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: 00617 (++) HAL_FMPI2C_MemTxCpltCallback() 00618 (++) HAL_FMPI2C_MemRxCpltCallback() 00619 (++) HAL_FMPI2C_MasterTxCpltCallback() 00620 (++) HAL_FMPI2C_MasterRxCpltCallback() 00621 (++) HAL_FMPI2C_SlaveTxCpltCallback() 00622 (++) HAL_FMPI2C_SlaveRxCpltCallback() 00623 (++) HAL_FMPI2C_ErrorCallback() 00624 00625 @endverbatim 00626 * @{ 00627 */ 00628 00629 /** 00630 * @brief Transmits in master mode an amount of data in blocking mode. 00631 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00632 * the configuration information for the specified FMPI2C. 00633 * @param DevAddress Target device address The device 7 bits address value 00634 * in datasheet must be shifted to the left before calling the interface 00635 * @param pData Pointer to data buffer 00636 * @param Size Amount of data to be sent 00637 * @param Timeout Timeout duration 00638 * @retval HAL status 00639 */ 00640 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00641 { 00642 uint32_t tickstart = 0U; 00643 00644 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 00645 { 00646 /* Process Locked */ 00647 __HAL_LOCK(hfmpi2c); 00648 00649 /* Init tickstart for timeout management*/ 00650 tickstart = HAL_GetTick(); 00651 00652 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 00653 { 00654 return HAL_TIMEOUT; 00655 } 00656 00657 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 00658 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 00659 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00660 00661 /* Prepare transfer parameters */ 00662 hfmpi2c->pBuffPtr = pData; 00663 hfmpi2c->XferCount = Size; 00664 hfmpi2c->XferISR = NULL; 00665 00666 /* Send Slave Address */ 00667 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 00668 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 00669 { 00670 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 00671 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); 00672 } 00673 else 00674 { 00675 hfmpi2c->XferSize = hfmpi2c->XferCount; 00676 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); 00677 } 00678 00679 while (hfmpi2c->XferCount > 0U) 00680 { 00681 /* Wait until TXIS flag is set */ 00682 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00683 { 00684 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00685 { 00686 return HAL_ERROR; 00687 } 00688 else 00689 { 00690 return HAL_TIMEOUT; 00691 } 00692 } 00693 /* Write data to TXDR */ 00694 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); 00695 hfmpi2c->XferCount--; 00696 hfmpi2c->XferSize--; 00697 00698 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) 00699 { 00700 /* Wait until TCR flag is set */ 00701 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 00702 { 00703 return HAL_TIMEOUT; 00704 } 00705 00706 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 00707 { 00708 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 00709 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 00710 } 00711 else 00712 { 00713 hfmpi2c->XferSize = hfmpi2c->XferCount; 00714 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 00715 } 00716 } 00717 } 00718 00719 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 00720 /* Wait until STOPF flag is set */ 00721 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00722 { 00723 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00724 { 00725 return HAL_ERROR; 00726 } 00727 else 00728 { 00729 return HAL_TIMEOUT; 00730 } 00731 } 00732 00733 /* Clear STOP Flag */ 00734 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 00735 00736 /* Clear Configuration Register 2 */ 00737 FMPI2C_RESET_CR2(hfmpi2c); 00738 00739 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 00740 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00741 00742 /* Process Unlocked */ 00743 __HAL_UNLOCK(hfmpi2c); 00744 00745 return HAL_OK; 00746 } 00747 else 00748 { 00749 return HAL_BUSY; 00750 } 00751 } 00752 00753 /** 00754 * @brief Receives in master mode an amount of data in blocking mode. 00755 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00756 * the configuration information for the specified FMPI2C. 00757 * @param DevAddress Target device address The device 7 bits address value 00758 * in datasheet must be shifted to the left before calling the interface 00759 * @param pData Pointer to data buffer 00760 * @param Size Amount of data to be sent 00761 * @param Timeout Timeout duration 00762 * @retval HAL status 00763 */ 00764 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00765 { 00766 uint32_t tickstart = 0U; 00767 00768 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 00769 { 00770 /* Process Locked */ 00771 __HAL_LOCK(hfmpi2c); 00772 00773 /* Init tickstart for timeout management*/ 00774 tickstart = HAL_GetTick(); 00775 00776 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 00777 { 00778 return HAL_TIMEOUT; 00779 } 00780 00781 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 00782 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 00783 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00784 00785 /* Prepare transfer parameters */ 00786 hfmpi2c->pBuffPtr = pData; 00787 hfmpi2c->XferCount = Size; 00788 hfmpi2c->XferISR = NULL; 00789 00790 /* Send Slave Address */ 00791 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 00792 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 00793 { 00794 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 00795 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); 00796 } 00797 else 00798 { 00799 hfmpi2c->XferSize = hfmpi2c->XferCount; 00800 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); 00801 } 00802 00803 while (hfmpi2c->XferCount > 0U) 00804 { 00805 /* Wait until RXNE flag is set */ 00806 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00807 { 00808 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00809 { 00810 return HAL_ERROR; 00811 } 00812 else 00813 { 00814 return HAL_TIMEOUT; 00815 } 00816 } 00817 00818 /* Read data from RXDR */ 00819 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 00820 hfmpi2c->XferSize--; 00821 hfmpi2c->XferCount--; 00822 00823 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) 00824 { 00825 /* Wait until TCR flag is set */ 00826 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 00827 { 00828 return HAL_TIMEOUT; 00829 } 00830 00831 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 00832 { 00833 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 00834 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 00835 } 00836 else 00837 { 00838 hfmpi2c->XferSize = hfmpi2c->XferCount; 00839 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 00840 } 00841 } 00842 } 00843 00844 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 00845 /* Wait until STOPF flag is set */ 00846 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00847 { 00848 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00849 { 00850 return HAL_ERROR; 00851 } 00852 else 00853 { 00854 return HAL_TIMEOUT; 00855 } 00856 } 00857 00858 /* Clear STOP Flag */ 00859 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 00860 00861 /* Clear Configuration Register 2 */ 00862 FMPI2C_RESET_CR2(hfmpi2c); 00863 00864 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 00865 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 00866 00867 /* Process Unlocked */ 00868 __HAL_UNLOCK(hfmpi2c); 00869 00870 return HAL_OK; 00871 } 00872 else 00873 { 00874 return HAL_BUSY; 00875 } 00876 } 00877 00878 /** 00879 * @brief Transmits in slave mode an amount of data in blocking mode. 00880 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 00881 * the configuration information for the specified FMPI2C. 00882 * @param pData Pointer to data buffer 00883 * @param Size Amount of data to be sent 00884 * @param Timeout Timeout duration 00885 * @retval HAL status 00886 */ 00887 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00888 { 00889 uint32_t tickstart = 0U; 00890 00891 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 00892 { 00893 if ((pData == NULL) || (Size == 0U)) 00894 { 00895 return HAL_ERROR; 00896 } 00897 /* Process Locked */ 00898 __HAL_LOCK(hfmpi2c); 00899 00900 /* Init tickstart for timeout management*/ 00901 tickstart = HAL_GetTick(); 00902 00903 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 00904 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 00905 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00906 00907 /* Prepare transfer parameters */ 00908 hfmpi2c->pBuffPtr = pData; 00909 hfmpi2c->XferCount = Size; 00910 hfmpi2c->XferISR = NULL; 00911 00912 /* Enable Address Acknowledge */ 00913 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 00914 00915 /* Wait until ADDR flag is set */ 00916 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 00917 { 00918 /* Disable Address Acknowledge */ 00919 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00920 return HAL_TIMEOUT; 00921 } 00922 00923 /* Clear ADDR flag */ 00924 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 00925 00926 /* If 10bit addressing mode is selected */ 00927 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 00928 { 00929 /* Wait until ADDR flag is set */ 00930 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 00931 { 00932 /* Disable Address Acknowledge */ 00933 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00934 return HAL_TIMEOUT; 00935 } 00936 00937 /* Clear ADDR flag */ 00938 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 00939 } 00940 00941 /* Wait until DIR flag is set Transmitter mode */ 00942 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) 00943 { 00944 /* Disable Address Acknowledge */ 00945 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00946 return HAL_TIMEOUT; 00947 } 00948 00949 while (hfmpi2c->XferCount > 0U) 00950 { 00951 /* Wait until TXIS flag is set */ 00952 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00953 { 00954 /* Disable Address Acknowledge */ 00955 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00956 00957 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00958 { 00959 return HAL_ERROR; 00960 } 00961 else 00962 { 00963 return HAL_TIMEOUT; 00964 } 00965 } 00966 00967 /* Write data to TXDR */ 00968 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); 00969 hfmpi2c->XferCount--; 00970 } 00971 00972 /* Wait until STOP flag is set */ 00973 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 00974 { 00975 /* Disable Address Acknowledge */ 00976 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00977 00978 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 00979 { 00980 /* Normal use case for Transmitter mode */ 00981 /* A NACK is generated to confirm the end of transfer */ 00982 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 00983 } 00984 else 00985 { 00986 return HAL_TIMEOUT; 00987 } 00988 } 00989 00990 /* Clear STOP flag */ 00991 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 00992 00993 /* Wait until BUSY flag is reset */ 00994 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) 00995 { 00996 /* Disable Address Acknowledge */ 00997 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 00998 return HAL_TIMEOUT; 00999 } 01000 01001 /* Disable Address Acknowledge */ 01002 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01003 01004 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01005 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01006 01007 /* Process Unlocked */ 01008 __HAL_UNLOCK(hfmpi2c); 01009 01010 return HAL_OK; 01011 } 01012 else 01013 { 01014 return HAL_BUSY; 01015 } 01016 } 01017 01018 /** 01019 * @brief Receive in slave mode an amount of data in blocking mode 01020 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01021 * the configuration information for the specified FMPI2C. 01022 * @param pData Pointer to data buffer 01023 * @param Size Amount of data to be sent 01024 * @param Timeout Timeout duration 01025 * @retval HAL status 01026 */ 01027 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) 01028 { 01029 uint32_t tickstart = 0U; 01030 01031 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01032 { 01033 if ((pData == NULL) || (Size == 0U)) 01034 { 01035 return HAL_ERROR; 01036 } 01037 /* Process Locked */ 01038 __HAL_LOCK(hfmpi2c); 01039 01040 /* Init tickstart for timeout management*/ 01041 tickstart = HAL_GetTick(); 01042 01043 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01044 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01045 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01046 01047 /* Prepare transfer parameters */ 01048 hfmpi2c->pBuffPtr = pData; 01049 hfmpi2c->XferCount = Size; 01050 hfmpi2c->XferISR = NULL; 01051 01052 /* Enable Address Acknowledge */ 01053 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01054 01055 /* Wait until ADDR flag is set */ 01056 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) 01057 { 01058 /* Disable Address Acknowledge */ 01059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01060 return HAL_TIMEOUT; 01061 } 01062 01063 /* Clear ADDR flag */ 01064 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 01065 01066 /* Wait until DIR flag is reset Receiver mode */ 01067 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) 01068 { 01069 /* Disable Address Acknowledge */ 01070 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01071 return HAL_TIMEOUT; 01072 } 01073 01074 while (hfmpi2c->XferCount > 0U) 01075 { 01076 /* Wait until RXNE flag is set */ 01077 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01078 { 01079 /* Disable Address Acknowledge */ 01080 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01081 01082 /* Store Last receive data if any */ 01083 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) 01084 { 01085 /* Read data from RXDR */ 01086 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 01087 hfmpi2c->XferCount--; 01088 } 01089 01090 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT) 01091 { 01092 return HAL_TIMEOUT; 01093 } 01094 else 01095 { 01096 return HAL_ERROR; 01097 } 01098 } 01099 01100 /* Read data from RXDR */ 01101 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 01102 hfmpi2c->XferCount--; 01103 } 01104 01105 /* Wait until STOP flag is set */ 01106 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01107 { 01108 /* Disable Address Acknowledge */ 01109 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01110 01111 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01112 { 01113 return HAL_ERROR; 01114 } 01115 else 01116 { 01117 return HAL_TIMEOUT; 01118 } 01119 } 01120 01121 /* Clear STOP flag */ 01122 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01123 01124 /* Wait until BUSY flag is reset */ 01125 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) 01126 { 01127 /* Disable Address Acknowledge */ 01128 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01129 return HAL_TIMEOUT; 01130 } 01131 01132 /* Disable Address Acknowledge */ 01133 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 01134 01135 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01136 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01137 01138 /* Process Unlocked */ 01139 __HAL_UNLOCK(hfmpi2c); 01140 01141 return HAL_OK; 01142 } 01143 else 01144 { 01145 return HAL_BUSY; 01146 } 01147 } 01148 01149 /** 01150 * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt 01151 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01152 * the configuration information for the specified FMPI2C. 01153 * @param DevAddress Target device address The device 7 bits address value 01154 * in datasheet must be shifted to the left before calling the interface 01155 * @param pData Pointer to data buffer 01156 * @param Size Amount of data to be sent 01157 * @retval HAL status 01158 */ 01159 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) 01160 { 01161 uint32_t xfermode = 0U; 01162 01163 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01164 { 01165 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01166 { 01167 return HAL_BUSY; 01168 } 01169 01170 /* Process Locked */ 01171 __HAL_LOCK(hfmpi2c); 01172 01173 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01174 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01175 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01176 01177 /* Prepare transfer parameters */ 01178 hfmpi2c->pBuffPtr = pData; 01179 hfmpi2c->XferCount = Size; 01180 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01181 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01182 01183 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01184 { 01185 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01186 xfermode = FMPI2C_RELOAD_MODE; 01187 } 01188 else 01189 { 01190 hfmpi2c->XferSize = hfmpi2c->XferCount; 01191 xfermode = FMPI2C_AUTOEND_MODE; 01192 } 01193 01194 /* Send Slave Address */ 01195 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 01196 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); 01197 01198 /* Process Unlocked */ 01199 __HAL_UNLOCK(hfmpi2c); 01200 01201 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01202 to avoid the risk of FMPI2C interrupt handle execution before current 01203 process unlock */ 01204 01205 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01206 /* possible to enable all of these */ 01207 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01208 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 01209 01210 return HAL_OK; 01211 } 01212 else 01213 { 01214 return HAL_BUSY; 01215 } 01216 } 01217 01218 /** 01219 * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt 01220 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01221 * the configuration information for the specified FMPI2C. 01222 * @param DevAddress Target device address The device 7 bits address value 01223 * in datasheet must be shifted to the left before calling the interface 01224 * @param pData Pointer to data buffer 01225 * @param Size Amount of data to be sent 01226 * @retval HAL status 01227 */ 01228 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) 01229 { 01230 uint32_t xfermode = 0U; 01231 01232 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01233 { 01234 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01235 { 01236 return HAL_BUSY; 01237 } 01238 01239 /* Process Locked */ 01240 __HAL_LOCK(hfmpi2c); 01241 01242 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01243 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01244 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01245 01246 /* Prepare transfer parameters */ 01247 hfmpi2c->pBuffPtr = pData; 01248 hfmpi2c->XferCount = Size; 01249 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01250 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01251 01252 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01253 { 01254 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01255 xfermode = FMPI2C_RELOAD_MODE; 01256 } 01257 else 01258 { 01259 hfmpi2c->XferSize = hfmpi2c->XferCount; 01260 xfermode = FMPI2C_AUTOEND_MODE; 01261 } 01262 01263 /* Send Slave Address */ 01264 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 01265 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 01266 01267 /* Process Unlocked */ 01268 __HAL_UNLOCK(hfmpi2c); 01269 01270 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01271 to avoid the risk of FMPI2C interrupt handle execution before current 01272 process unlock */ 01273 01274 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 01275 /* possible to enable all of these */ 01276 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01277 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 01278 01279 return HAL_OK; 01280 } 01281 else 01282 { 01283 return HAL_BUSY; 01284 } 01285 } 01286 01287 /** 01288 * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt 01289 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01290 * the configuration information for the specified FMPI2C. 01291 * @param pData Pointer to data buffer 01292 * @param Size Amount of data to be sent 01293 * @retval HAL status 01294 */ 01295 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01296 { 01297 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01298 { 01299 /* Process Locked */ 01300 __HAL_LOCK(hfmpi2c); 01301 01302 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01303 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01304 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01305 01306 /* Enable Address Acknowledge */ 01307 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01308 01309 /* Prepare transfer parameters */ 01310 hfmpi2c->pBuffPtr = pData; 01311 hfmpi2c->XferCount = Size; 01312 hfmpi2c->XferSize = hfmpi2c->XferCount; 01313 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01314 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 01315 01316 /* Process Unlocked */ 01317 __HAL_UNLOCK(hfmpi2c); 01318 01319 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01320 to avoid the risk of FMPI2C interrupt handle execution before current 01321 process unlock */ 01322 01323 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01324 /* possible to enable all of these */ 01325 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01326 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); 01327 01328 return HAL_OK; 01329 } 01330 else 01331 { 01332 return HAL_BUSY; 01333 } 01334 } 01335 01336 /** 01337 * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt 01338 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01339 * the configuration information for the specified FMPI2C. 01340 * @param pData Pointer to data buffer 01341 * @param Size Amount of data to be sent 01342 * @retval HAL status 01343 */ 01344 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01345 { 01346 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01347 { 01348 /* Process Locked */ 01349 __HAL_LOCK(hfmpi2c); 01350 01351 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01352 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01353 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01354 01355 /* Enable Address Acknowledge */ 01356 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01357 01358 /* Prepare transfer parameters */ 01359 hfmpi2c->pBuffPtr = pData; 01360 hfmpi2c->XferCount = Size; 01361 hfmpi2c->XferSize = hfmpi2c->XferCount; 01362 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01363 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 01364 01365 /* Process Unlocked */ 01366 __HAL_UNLOCK(hfmpi2c); 01367 01368 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01369 to avoid the risk of FMPI2C interrupt handle execution before current 01370 process unlock */ 01371 01372 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 01373 /* possible to enable all of these */ 01374 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01375 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); 01376 01377 return HAL_OK; 01378 } 01379 else 01380 { 01381 return HAL_BUSY; 01382 } 01383 } 01384 01385 /** 01386 * @brief Transmit in master mode an amount of data in non-blocking mode with DMA 01387 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01388 * the configuration information for the specified FMPI2C. 01389 * @param DevAddress Target device address The device 7 bits address value 01390 * in datasheet must be shifted to the left before calling the interface 01391 * @param pData Pointer to data buffer 01392 * @param Size Amount of data to be sent 01393 * @retval HAL status 01394 */ 01395 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) 01396 { 01397 uint32_t xfermode = 0U; 01398 01399 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01400 { 01401 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01402 { 01403 return HAL_BUSY; 01404 } 01405 01406 /* Process Locked */ 01407 __HAL_LOCK(hfmpi2c); 01408 01409 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01410 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01411 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01412 01413 /* Prepare transfer parameters */ 01414 hfmpi2c->pBuffPtr = pData; 01415 hfmpi2c->XferCount = Size; 01416 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01417 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 01418 01419 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01420 { 01421 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01422 xfermode = FMPI2C_RELOAD_MODE; 01423 } 01424 else 01425 { 01426 hfmpi2c->XferSize = hfmpi2c->XferCount; 01427 xfermode = FMPI2C_AUTOEND_MODE; 01428 } 01429 01430 if (hfmpi2c->XferSize > 0U) 01431 { 01432 /* Set the FMPI2C DMA transfer complete callback */ 01433 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; 01434 01435 /* Set the DMA error callback */ 01436 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 01437 01438 /* Set the unused DMA callbacks to NULL */ 01439 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 01440 hfmpi2c->hdmatx->XferAbortCallback = NULL; 01441 01442 /* Enable the DMA stream */ 01443 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); 01444 01445 /* Send Slave Address */ 01446 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01447 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE); 01448 01449 /* Update XferCount value */ 01450 hfmpi2c->XferCount -= hfmpi2c->XferSize; 01451 01452 /* Process Unlocked */ 01453 __HAL_UNLOCK(hfmpi2c); 01454 01455 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01456 to avoid the risk of FMPI2C interrupt handle execution before current 01457 process unlock */ 01458 /* Enable ERR and NACK interrupts */ 01459 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 01460 01461 /* Enable DMA Request */ 01462 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 01463 } 01464 else 01465 { 01466 /* Update Transfer ISR function pointer */ 01467 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01468 01469 /* Send Slave Address */ 01470 /* Set NBYTES to write and generate START condition */ 01471 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); 01472 01473 /* Process Unlocked */ 01474 __HAL_UNLOCK(hfmpi2c); 01475 01476 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01477 to avoid the risk of FMPI2C interrupt handle execution before current 01478 process unlock */ 01479 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01480 /* possible to enable all of these */ 01481 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01482 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 01483 } 01484 01485 return HAL_OK; 01486 } 01487 else 01488 { 01489 return HAL_BUSY; 01490 } 01491 } 01492 01493 /** 01494 * @brief Receive in master mode an amount of data in non-blocking mode with DMA 01495 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01496 * the configuration information for the specified FMPI2C. 01497 * @param DevAddress Target device address The device 7 bits address value 01498 * in datasheet must be shifted to the left before calling the interface 01499 * @param pData Pointer to data buffer 01500 * @param Size Amount of data to be sent 01501 * @retval HAL status 01502 */ 01503 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) 01504 { 01505 uint32_t xfermode = 0U; 01506 01507 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01508 { 01509 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 01510 { 01511 return HAL_BUSY; 01512 } 01513 01514 /* Process Locked */ 01515 __HAL_LOCK(hfmpi2c); 01516 01517 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01518 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 01519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01520 01521 /* Prepare transfer parameters */ 01522 hfmpi2c->pBuffPtr = pData; 01523 hfmpi2c->XferCount = Size; 01524 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01525 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 01526 01527 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01528 { 01529 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01530 xfermode = FMPI2C_RELOAD_MODE; 01531 } 01532 else 01533 { 01534 hfmpi2c->XferSize = hfmpi2c->XferCount; 01535 xfermode = FMPI2C_AUTOEND_MODE; 01536 } 01537 01538 if (hfmpi2c->XferSize > 0U) 01539 { 01540 /* Set the FMPI2C DMA transfer complete callback */ 01541 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; 01542 01543 /* Set the DMA error callback */ 01544 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 01545 01546 /* Set the unused DMA callbacks to NULL */ 01547 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 01548 hfmpi2c->hdmarx->XferAbortCallback = NULL; 01549 01550 /* Enable the DMA stream */ 01551 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); 01552 01553 /* Send Slave Address */ 01554 /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01555 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 01556 01557 /* Update XferCount value */ 01558 hfmpi2c->XferCount -= hfmpi2c->XferSize; 01559 01560 /* Process Unlocked */ 01561 __HAL_UNLOCK(hfmpi2c); 01562 01563 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01564 to avoid the risk of FMPI2C interrupt handle execution before current 01565 process unlock */ 01566 /* Enable ERR and NACK interrupts */ 01567 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 01568 01569 /* Enable DMA Request */ 01570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 01571 } 01572 else 01573 { 01574 /* Update Transfer ISR function pointer */ 01575 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 01576 01577 /* Send Slave Address */ 01578 /* Set NBYTES to read and generate START condition */ 01579 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); 01580 01581 /* Process Unlocked */ 01582 __HAL_UNLOCK(hfmpi2c); 01583 01584 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01585 to avoid the risk of FMPI2C interrupt handle execution before current 01586 process unlock */ 01587 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 01588 /* possible to enable all of these */ 01589 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 01590 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 01591 } 01592 return HAL_OK; 01593 } 01594 else 01595 { 01596 return HAL_BUSY; 01597 } 01598 } 01599 01600 /** 01601 * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA 01602 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01603 * the configuration information for the specified FMPI2C. 01604 * @param pData Pointer to data buffer 01605 * @param Size Amount of data to be sent 01606 * @retval HAL status 01607 */ 01608 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01609 { 01610 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01611 { 01612 if ((pData == NULL) || (Size == 0U)) 01613 { 01614 return HAL_ERROR; 01615 } 01616 /* Process Locked */ 01617 __HAL_LOCK(hfmpi2c); 01618 01619 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01620 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01621 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01622 01623 /* Prepare transfer parameters */ 01624 hfmpi2c->pBuffPtr = pData; 01625 hfmpi2c->XferCount = Size; 01626 hfmpi2c->XferSize = hfmpi2c->XferCount; 01627 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01628 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 01629 01630 /* Set the FMPI2C DMA transfer complete callback */ 01631 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt; 01632 01633 /* Set the DMA error callback */ 01634 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 01635 01636 /* Set the unused DMA callbacks to NULL */ 01637 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 01638 hfmpi2c->hdmatx->XferAbortCallback = NULL; 01639 01640 /* Enable the DMA stream */ 01641 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); 01642 01643 /* Enable Address Acknowledge */ 01644 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01645 01646 /* Process Unlocked */ 01647 __HAL_UNLOCK(hfmpi2c); 01648 01649 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01650 to avoid the risk of FMPI2C interrupt handle execution before current 01651 process unlock */ 01652 /* Enable ERR, STOP, NACK, ADDR interrupts */ 01653 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 01654 01655 /* Enable DMA Request */ 01656 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 01657 01658 return HAL_OK; 01659 } 01660 else 01661 { 01662 return HAL_BUSY; 01663 } 01664 } 01665 01666 /** 01667 * @brief Receive in slave mode an amount of data in non-blocking mode with DMA 01668 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01669 * the configuration information for the specified FMPI2C. 01670 * @param pData Pointer to data buffer 01671 * @param Size Amount of data to be sent 01672 * @retval HAL status 01673 */ 01674 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) 01675 { 01676 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01677 { 01678 if ((pData == NULL) || (Size == 0U)) 01679 { 01680 return HAL_ERROR; 01681 } 01682 /* Process Locked */ 01683 __HAL_LOCK(hfmpi2c); 01684 01685 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01686 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 01687 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01688 01689 /* Prepare transfer parameters */ 01690 hfmpi2c->pBuffPtr = pData; 01691 hfmpi2c->XferCount = Size; 01692 hfmpi2c->XferSize = hfmpi2c->XferCount; 01693 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 01694 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA; 01695 01696 /* Set the FMPI2C DMA transfer complete callback */ 01697 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt; 01698 01699 /* Set the DMA error callback */ 01700 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 01701 01702 /* Set the unused DMA callbacks to NULL */ 01703 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 01704 hfmpi2c->hdmarx->XferAbortCallback = NULL; 01705 01706 /* Enable the DMA stream */ 01707 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); 01708 01709 /* Enable Address Acknowledge */ 01710 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 01711 01712 /* Process Unlocked */ 01713 __HAL_UNLOCK(hfmpi2c); 01714 01715 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 01716 to avoid the risk of FMPI2C interrupt handle execution before current 01717 process unlock */ 01718 /* Enable ERR, STOP, NACK, ADDR interrupts */ 01719 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 01720 01721 /* Enable DMA Request */ 01722 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 01723 01724 return HAL_OK; 01725 } 01726 else 01727 { 01728 return HAL_BUSY; 01729 } 01730 } 01731 /** 01732 * @brief Write an amount of data in blocking mode to a specific memory address 01733 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01734 * the configuration information for the specified FMPI2C. 01735 * @param DevAddress Target device address The device 7 bits address value 01736 * in datasheet must be shifted to the left before calling the interface 01737 * @param MemAddress Internal memory address 01738 * @param MemAddSize Size of internal memory address 01739 * @param pData Pointer to data buffer 01740 * @param Size Amount of data to be sent 01741 * @param Timeout Timeout duration 01742 * @retval HAL status 01743 */ 01744 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) 01745 { 01746 uint32_t tickstart = 0U; 01747 01748 /* Check the parameters */ 01749 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 01750 01751 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01752 { 01753 if ((pData == NULL) || (Size == 0U)) 01754 { 01755 return HAL_ERROR; 01756 } 01757 01758 /* Process Locked */ 01759 __HAL_LOCK(hfmpi2c); 01760 01761 /* Init tickstart for timeout management*/ 01762 tickstart = HAL_GetTick(); 01763 01764 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 01765 { 01766 return HAL_TIMEOUT; 01767 } 01768 01769 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 01770 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 01771 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01772 01773 /* Prepare transfer parameters */ 01774 hfmpi2c->pBuffPtr = pData; 01775 hfmpi2c->XferCount = Size; 01776 hfmpi2c->XferISR = NULL; 01777 01778 /* Send Slave Address and Memory Address */ 01779 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) 01780 { 01781 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01782 { 01783 /* Process Unlocked */ 01784 __HAL_UNLOCK(hfmpi2c); 01785 return HAL_ERROR; 01786 } 01787 else 01788 { 01789 /* Process Unlocked */ 01790 __HAL_UNLOCK(hfmpi2c); 01791 return HAL_TIMEOUT; 01792 } 01793 } 01794 01795 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */ 01796 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01797 { 01798 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01799 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 01800 } 01801 else 01802 { 01803 hfmpi2c->XferSize = hfmpi2c->XferCount; 01804 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 01805 } 01806 01807 do 01808 { 01809 /* Wait until TXIS flag is set */ 01810 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01811 { 01812 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01813 { 01814 return HAL_ERROR; 01815 } 01816 else 01817 { 01818 return HAL_TIMEOUT; 01819 } 01820 } 01821 01822 /* Write data to TXDR */ 01823 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); 01824 hfmpi2c->XferCount--; 01825 hfmpi2c->XferSize--; 01826 01827 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) 01828 { 01829 /* Wait until TCR flag is set */ 01830 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 01831 { 01832 return HAL_TIMEOUT; 01833 } 01834 01835 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01836 { 01837 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01838 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 01839 } 01840 else 01841 { 01842 hfmpi2c->XferSize = hfmpi2c->XferCount; 01843 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 01844 } 01845 } 01846 01847 } 01848 while (hfmpi2c->XferCount > 0U); 01849 01850 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 01851 /* Wait until STOPF flag is reset */ 01852 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01853 { 01854 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01855 { 01856 return HAL_ERROR; 01857 } 01858 else 01859 { 01860 return HAL_TIMEOUT; 01861 } 01862 } 01863 01864 /* Clear STOP Flag */ 01865 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 01866 01867 /* Clear Configuration Register 2 */ 01868 FMPI2C_RESET_CR2(hfmpi2c); 01869 01870 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 01871 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 01872 01873 /* Process Unlocked */ 01874 __HAL_UNLOCK(hfmpi2c); 01875 01876 return HAL_OK; 01877 } 01878 else 01879 { 01880 return HAL_BUSY; 01881 } 01882 } 01883 01884 /** 01885 * @brief Read an amount of data in blocking mode from a specific memory address 01886 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 01887 * the configuration information for the specified FMPI2C. 01888 * @param DevAddress Target device address The device 7 bits address value 01889 * in datasheet must be shifted to the left before calling the interface 01890 * @param MemAddress Internal memory address 01891 * @param MemAddSize Size of internal memory address 01892 * @param pData Pointer to data buffer 01893 * @param Size Amount of data to be sent 01894 * @param Timeout Timeout duration 01895 * @retval HAL status 01896 */ 01897 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) 01898 { 01899 uint32_t tickstart = 0U; 01900 01901 /* Check the parameters */ 01902 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 01903 01904 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 01905 { 01906 if ((pData == NULL) || (Size == 0U)) 01907 { 01908 return HAL_ERROR; 01909 } 01910 01911 /* Process Locked */ 01912 __HAL_LOCK(hfmpi2c); 01913 01914 /* Init tickstart for timeout management*/ 01915 tickstart = HAL_GetTick(); 01916 01917 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK) 01918 { 01919 return HAL_TIMEOUT; 01920 } 01921 01922 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 01923 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 01924 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 01925 01926 /* Prepare transfer parameters */ 01927 hfmpi2c->pBuffPtr = pData; 01928 hfmpi2c->XferCount = Size; 01929 hfmpi2c->XferISR = NULL; 01930 01931 /* Send Slave Address and Memory Address */ 01932 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) 01933 { 01934 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 01935 { 01936 /* Process Unlocked */ 01937 __HAL_UNLOCK(hfmpi2c); 01938 return HAL_ERROR; 01939 } 01940 else 01941 { 01942 /* Process Unlocked */ 01943 __HAL_UNLOCK(hfmpi2c); 01944 return HAL_TIMEOUT; 01945 } 01946 } 01947 01948 /* Send Slave Address */ 01949 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 01950 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01951 { 01952 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01953 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); 01954 } 01955 else 01956 { 01957 hfmpi2c->XferSize = hfmpi2c->XferCount; 01958 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); 01959 } 01960 01961 do 01962 { 01963 /* Wait until RXNE flag is set */ 01964 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) 01965 { 01966 return HAL_TIMEOUT; 01967 } 01968 01969 /* Read data from RXDR */ 01970 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 01971 hfmpi2c->XferSize--; 01972 hfmpi2c->XferCount--; 01973 01974 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) 01975 { 01976 /* Wait until TCR flag is set */ 01977 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) 01978 { 01979 return HAL_TIMEOUT; 01980 } 01981 01982 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 01983 { 01984 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 01985 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 01986 } 01987 else 01988 { 01989 hfmpi2c->XferSize = hfmpi2c->XferCount; 01990 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 01991 } 01992 } 01993 } 01994 while (hfmpi2c->XferCount > 0U); 01995 01996 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 01997 /* Wait until STOPF flag is reset */ 01998 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK) 01999 { 02000 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 02001 { 02002 return HAL_ERROR; 02003 } 02004 else 02005 { 02006 return HAL_TIMEOUT; 02007 } 02008 } 02009 02010 /* Clear STOP Flag */ 02011 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02012 02013 /* Clear Configuration Register 2 */ 02014 FMPI2C_RESET_CR2(hfmpi2c); 02015 02016 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02017 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02018 02019 /* Process Unlocked */ 02020 __HAL_UNLOCK(hfmpi2c); 02021 02022 return HAL_OK; 02023 } 02024 else 02025 { 02026 return HAL_BUSY; 02027 } 02028 } 02029 /** 02030 * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address 02031 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02032 * the configuration information for the specified FMPI2C. 02033 * @param DevAddress Target device address The device 7 bits address value 02034 * in datasheet must be shifted to the left before calling the interface 02035 * @param MemAddress Internal memory address 02036 * @param MemAddSize Size of internal memory address 02037 * @param pData Pointer to data buffer 02038 * @param Size Amount of data to be sent 02039 * @retval HAL status 02040 */ 02041 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02042 { 02043 uint32_t tickstart = 0U; 02044 uint32_t xfermode = 0U; 02045 02046 /* Check the parameters */ 02047 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02048 02049 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02050 { 02051 if ((pData == NULL) || (Size == 0U)) 02052 { 02053 return HAL_ERROR; 02054 } 02055 02056 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02057 { 02058 return HAL_BUSY; 02059 } 02060 02061 /* Process Locked */ 02062 __HAL_LOCK(hfmpi2c); 02063 02064 /* Init tickstart for timeout management*/ 02065 tickstart = HAL_GetTick(); 02066 02067 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02068 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02069 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02070 02071 /* Prepare transfer parameters */ 02072 hfmpi2c->pBuffPtr = pData; 02073 hfmpi2c->XferCount = Size; 02074 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02075 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02076 02077 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02078 { 02079 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02080 xfermode = FMPI2C_RELOAD_MODE; 02081 } 02082 else 02083 { 02084 hfmpi2c->XferSize = hfmpi2c->XferCount; 02085 xfermode = FMPI2C_AUTOEND_MODE; 02086 } 02087 02088 /* Send Slave Address and Memory Address */ 02089 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 02090 { 02091 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 02092 { 02093 /* Process Unlocked */ 02094 __HAL_UNLOCK(hfmpi2c); 02095 return HAL_ERROR; 02096 } 02097 else 02098 { 02099 /* Process Unlocked */ 02100 __HAL_UNLOCK(hfmpi2c); 02101 return HAL_TIMEOUT; 02102 } 02103 } 02104 02105 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02106 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 02107 02108 /* Process Unlocked */ 02109 __HAL_UNLOCK(hfmpi2c); 02110 02111 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02112 to avoid the risk of FMPI2C interrupt handle execution before current 02113 process unlock */ 02114 02115 /* Enable ERR, TC, STOP, NACK, TXI interrupt */ 02116 /* possible to enable all of these */ 02117 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 02118 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02119 02120 return HAL_OK; 02121 } 02122 else 02123 { 02124 return HAL_BUSY; 02125 } 02126 } 02127 02128 /** 02129 * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address 02130 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02131 * the configuration information for the specified FMPI2C. 02132 * @param DevAddress Target device address The device 7 bits address value 02133 * in datasheet must be shifted to the left before calling the interface 02134 * @param MemAddress Internal memory address 02135 * @param MemAddSize Size of internal memory address 02136 * @param pData Pointer to data buffer 02137 * @param Size Amount of data to be sent 02138 * @retval HAL status 02139 */ 02140 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02141 { 02142 uint32_t tickstart = 0U; 02143 uint32_t xfermode = 0U; 02144 02145 /* Check the parameters */ 02146 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02147 02148 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02149 { 02150 if ((pData == NULL) || (Size == 0U)) 02151 { 02152 return HAL_ERROR; 02153 } 02154 02155 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02156 { 02157 return HAL_BUSY; 02158 } 02159 02160 /* Process Locked */ 02161 __HAL_LOCK(hfmpi2c); 02162 02163 /* Init tickstart for timeout management*/ 02164 tickstart = HAL_GetTick(); 02165 02166 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02167 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02168 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02169 02170 /* Prepare transfer parameters */ 02171 hfmpi2c->pBuffPtr = pData; 02172 hfmpi2c->XferCount = Size; 02173 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02174 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02175 02176 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02177 { 02178 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02179 xfermode = FMPI2C_RELOAD_MODE; 02180 } 02181 else 02182 { 02183 hfmpi2c->XferSize = hfmpi2c->XferCount; 02184 xfermode = FMPI2C_AUTOEND_MODE; 02185 } 02186 02187 /* Send Slave Address and Memory Address */ 02188 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 02189 { 02190 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 02191 { 02192 /* Process Unlocked */ 02193 __HAL_UNLOCK(hfmpi2c); 02194 return HAL_ERROR; 02195 } 02196 else 02197 { 02198 /* Process Unlocked */ 02199 __HAL_UNLOCK(hfmpi2c); 02200 return HAL_TIMEOUT; 02201 } 02202 } 02203 02204 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02205 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 02206 02207 /* Process Unlocked */ 02208 __HAL_UNLOCK(hfmpi2c); 02209 02210 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02211 to avoid the risk of FMPI2C interrupt handle execution before current 02212 process unlock */ 02213 02214 /* Enable ERR, TC, STOP, NACK, RXI interrupt */ 02215 /* possible to enable all of these */ 02216 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ 02217 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 02218 02219 return HAL_OK; 02220 } 02221 else 02222 { 02223 return HAL_BUSY; 02224 } 02225 } 02226 /** 02227 * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address 02228 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02229 * the configuration information for the specified FMPI2C. 02230 * @param DevAddress Target device address The device 7 bits address value 02231 * in datasheet must be shifted to the left before calling the interface 02232 * @param MemAddress Internal memory address 02233 * @param MemAddSize Size of internal memory address 02234 * @param pData Pointer to data buffer 02235 * @param Size Amount of data to be sent 02236 * @retval HAL status 02237 */ 02238 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02239 { 02240 uint32_t tickstart = 0U; 02241 uint32_t xfermode = 0U; 02242 02243 /* Check the parameters */ 02244 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02245 02246 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02247 { 02248 if ((pData == NULL) || (Size == 0U)) 02249 { 02250 return HAL_ERROR; 02251 } 02252 02253 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02254 { 02255 return HAL_BUSY; 02256 } 02257 02258 /* Process Locked */ 02259 __HAL_LOCK(hfmpi2c); 02260 02261 /* Init tickstart for timeout management*/ 02262 tickstart = HAL_GetTick(); 02263 02264 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02265 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02266 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02267 02268 /* Prepare transfer parameters */ 02269 hfmpi2c->pBuffPtr = pData; 02270 hfmpi2c->XferCount = Size; 02271 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02272 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 02273 02274 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02275 { 02276 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02277 xfermode = FMPI2C_RELOAD_MODE; 02278 } 02279 else 02280 { 02281 hfmpi2c->XferSize = hfmpi2c->XferCount; 02282 xfermode = FMPI2C_AUTOEND_MODE; 02283 } 02284 02285 /* Send Slave Address and Memory Address */ 02286 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 02287 { 02288 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 02289 { 02290 /* Process Unlocked */ 02291 __HAL_UNLOCK(hfmpi2c); 02292 return HAL_ERROR; 02293 } 02294 else 02295 { 02296 /* Process Unlocked */ 02297 __HAL_UNLOCK(hfmpi2c); 02298 return HAL_TIMEOUT; 02299 } 02300 } 02301 02302 /* Set the FMPI2C DMA transfer complete callback */ 02303 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; 02304 02305 /* Set the DMA error callback */ 02306 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; 02307 02308 /* Set the unused DMA callbacks to NULL */ 02309 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL; 02310 hfmpi2c->hdmatx->XferAbortCallback = NULL; 02311 02312 /* Enable the DMA stream */ 02313 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); 02314 02315 /* Send Slave Address */ 02316 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02317 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 02318 02319 /* Update XferCount value */ 02320 hfmpi2c->XferCount -= hfmpi2c->XferSize; 02321 02322 /* Process Unlocked */ 02323 __HAL_UNLOCK(hfmpi2c); 02324 02325 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02326 to avoid the risk of FMPI2C interrupt handle execution before current 02327 process unlock */ 02328 /* Enable ERR and NACK interrupts */ 02329 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 02330 02331 /* Enable DMA Request */ 02332 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 02333 02334 return HAL_OK; 02335 } 02336 else 02337 { 02338 return HAL_BUSY; 02339 } 02340 } 02341 02342 /** 02343 * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. 02344 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02345 * the configuration information for the specified FMPI2C. 02346 * @param DevAddress Target device address The device 7 bits address value 02347 * in datasheet must be shifted to the left before calling the interface 02348 * @param MemAddress Internal memory address 02349 * @param MemAddSize Size of internal memory address 02350 * @param pData Pointer to data buffer 02351 * @param Size Amount of data to be read 02352 * @retval HAL status 02353 */ 02354 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 02355 { 02356 uint32_t tickstart = 0U; 02357 uint32_t xfermode = 0U; 02358 02359 /* Check the parameters */ 02360 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); 02361 02362 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02363 { 02364 if ((pData == NULL) || (Size == 0U)) 02365 { 02366 return HAL_ERROR; 02367 } 02368 02369 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02370 { 02371 return HAL_BUSY; 02372 } 02373 02374 /* Process Locked */ 02375 __HAL_LOCK(hfmpi2c); 02376 02377 /* Init tickstart for timeout management*/ 02378 tickstart = HAL_GetTick(); 02379 02380 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02381 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM; 02382 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02383 02384 /* Prepare transfer parameters */ 02385 hfmpi2c->pBuffPtr = pData; 02386 hfmpi2c->XferCount = Size; 02387 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 02388 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA; 02389 02390 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02391 { 02392 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02393 xfermode = FMPI2C_RELOAD_MODE; 02394 } 02395 else 02396 { 02397 hfmpi2c->XferSize = hfmpi2c->XferCount; 02398 xfermode = FMPI2C_AUTOEND_MODE; 02399 } 02400 02401 /* Send Slave Address and Memory Address */ 02402 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK) 02403 { 02404 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 02405 { 02406 /* Process Unlocked */ 02407 __HAL_UNLOCK(hfmpi2c); 02408 return HAL_ERROR; 02409 } 02410 else 02411 { 02412 /* Process Unlocked */ 02413 __HAL_UNLOCK(hfmpi2c); 02414 return HAL_TIMEOUT; 02415 } 02416 } 02417 02418 /* Set the FMPI2C DMA transfer complete callback */ 02419 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; 02420 02421 /* Set the DMA error callback */ 02422 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; 02423 02424 /* Set the unused DMA callbacks to NULL */ 02425 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL; 02426 hfmpi2c->hdmarx->XferAbortCallback = NULL; 02427 02428 /* Enable the DMA stream */ 02429 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); 02430 02431 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ 02432 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ); 02433 02434 /* Update XferCount value */ 02435 hfmpi2c->XferCount -= hfmpi2c->XferSize; 02436 02437 /* Process Unlocked */ 02438 __HAL_UNLOCK(hfmpi2c); 02439 02440 /* Enable DMA Request */ 02441 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 02442 02443 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02444 to avoid the risk of FMPI2C interrupt handle execution before current 02445 process unlock */ 02446 /* Enable ERR and NACK interrupts */ 02447 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT); 02448 02449 return HAL_OK; 02450 } 02451 else 02452 { 02453 return HAL_BUSY; 02454 } 02455 } 02456 02457 /** 02458 * @brief Checks if target device is ready for communication. 02459 * @note This function is used with Memory devices 02460 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02461 * the configuration information for the specified FMPI2C. 02462 * @param DevAddress Target device address The device 7 bits address value 02463 * in datasheet must be shifted to the left before calling the interface 02464 * @param Trials Number of trials 02465 * @param Timeout Timeout duration 02466 * @retval HAL status 02467 */ 02468 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) 02469 { 02470 uint32_t tickstart = 0U; 02471 02472 __IO uint32_t FMPI2C_Trials = 0U; 02473 02474 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02475 { 02476 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) 02477 { 02478 return HAL_BUSY; 02479 } 02480 02481 /* Process Locked */ 02482 __HAL_LOCK(hfmpi2c); 02483 02484 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; 02485 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02486 02487 do 02488 { 02489 /* Generate Start */ 02490 hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress); 02491 02492 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ 02493 /* Wait until STOPF flag is set or a NACK flag is set*/ 02494 tickstart = HAL_GetTick(); 02495 while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) && (hfmpi2c->State != HAL_FMPI2C_STATE_TIMEOUT)) 02496 { 02497 if (Timeout != HAL_MAX_DELAY) 02498 { 02499 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) 02500 { 02501 /* Device is ready */ 02502 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02503 /* Process Unlocked */ 02504 __HAL_UNLOCK(hfmpi2c); 02505 return HAL_TIMEOUT; 02506 } 02507 } 02508 } 02509 02510 /* Check if the NACKF flag has not been set */ 02511 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) 02512 { 02513 /* Wait until STOPF flag is reset */ 02514 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 02515 { 02516 return HAL_TIMEOUT; 02517 } 02518 02519 /* Clear STOP Flag */ 02520 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02521 02522 /* Device is ready */ 02523 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02524 02525 /* Process Unlocked */ 02526 __HAL_UNLOCK(hfmpi2c); 02527 02528 return HAL_OK; 02529 } 02530 else 02531 { 02532 /* Wait until STOPF flag is reset */ 02533 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 02534 { 02535 return HAL_TIMEOUT; 02536 } 02537 02538 /* Clear NACK Flag */ 02539 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 02540 02541 /* Clear STOP Flag, auto generated with autoend*/ 02542 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02543 } 02544 02545 /* Check if the maximum allowed number of trials has been reached */ 02546 if (FMPI2C_Trials++ == Trials) 02547 { 02548 /* Generate Stop */ 02549 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 02550 02551 /* Wait until STOPF flag is reset */ 02552 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) 02553 { 02554 return HAL_TIMEOUT; 02555 } 02556 02557 /* Clear STOP Flag */ 02558 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 02559 } 02560 } 02561 while (FMPI2C_Trials < Trials); 02562 02563 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02564 02565 /* Process Unlocked */ 02566 __HAL_UNLOCK(hfmpi2c); 02567 02568 return HAL_TIMEOUT; 02569 } 02570 else 02571 { 02572 return HAL_BUSY; 02573 } 02574 } 02575 02576 /** 02577 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt. 02578 * @note This interface allow to manage repeated start condition when a direction change during transfer 02579 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02580 * the configuration information for the specified FMPI2C. 02581 * @param DevAddress Target device address The device 7 bits address value 02582 * in datasheet must be shifted to the left before calling the interface 02583 * @param pData Pointer to data buffer 02584 * @param Size Amount of data to be sent 02585 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 02586 * @retval HAL status 02587 */ 02588 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) 02589 { 02590 uint32_t xfermode = 0U; 02591 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE; 02592 02593 /* Check the parameters */ 02594 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 02595 02596 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02597 { 02598 /* Process Locked */ 02599 __HAL_LOCK(hfmpi2c); 02600 02601 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX; 02602 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 02603 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02604 02605 /* Prepare transfer parameters */ 02606 hfmpi2c->pBuffPtr = pData; 02607 hfmpi2c->XferCount = Size; 02608 hfmpi2c->XferOptions = XferOptions; 02609 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02610 02611 /* If size > MAX_NBYTE_SIZE, use reload mode */ 02612 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02613 { 02614 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02615 xfermode = FMPI2C_RELOAD_MODE; 02616 } 02617 else 02618 { 02619 hfmpi2c->XferSize = hfmpi2c->XferCount; 02620 xfermode = hfmpi2c->XferOptions; 02621 } 02622 02623 /* If transfer direction not change, do not generate Restart Condition */ 02624 /* Mean Previous state is same as current state */ 02625 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) 02626 { 02627 xferrequest = FMPI2C_NO_STARTSTOP; 02628 } 02629 02630 /* Send Slave Address and set NBYTES to write */ 02631 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest); 02632 02633 /* Process Unlocked */ 02634 __HAL_UNLOCK(hfmpi2c); 02635 02636 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02637 to avoid the risk of FMPI2C interrupt handle execution before current 02638 process unlock */ 02639 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02640 02641 return HAL_OK; 02642 } 02643 else 02644 { 02645 return HAL_BUSY; 02646 } 02647 } 02648 02649 /** 02650 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt 02651 * @note This interface allow to manage repeated start condition when a direction change during transfer 02652 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02653 * the configuration information for the specified FMPI2C. 02654 * @param DevAddress Target device address The device 7 bits address value 02655 * in datasheet must be shifted to the left before calling the interface 02656 * @param pData Pointer to data buffer 02657 * @param Size Amount of data to be sent 02658 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 02659 * @retval HAL status 02660 */ 02661 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) 02662 { 02663 uint32_t xfermode = 0U; 02664 uint32_t xferrequest = FMPI2C_GENERATE_START_READ; 02665 02666 /* Check the parameters */ 02667 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 02668 02669 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02670 { 02671 /* Process Locked */ 02672 __HAL_LOCK(hfmpi2c); 02673 02674 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX; 02675 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER; 02676 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02677 02678 /* Prepare transfer parameters */ 02679 hfmpi2c->pBuffPtr = pData; 02680 hfmpi2c->XferCount = Size; 02681 hfmpi2c->XferOptions = XferOptions; 02682 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT; 02683 02684 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ 02685 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 02686 { 02687 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 02688 xfermode = FMPI2C_RELOAD_MODE; 02689 } 02690 else 02691 { 02692 hfmpi2c->XferSize = hfmpi2c->XferCount; 02693 xfermode = hfmpi2c->XferOptions; 02694 } 02695 02696 /* If transfer direction not change, do not generate Restart Condition */ 02697 /* Mean Previous state is same as current state */ 02698 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) 02699 { 02700 xferrequest = FMPI2C_NO_STARTSTOP; 02701 } 02702 02703 /* Send Slave Address and set NBYTES to read */ 02704 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest); 02705 02706 /* Process Unlocked */ 02707 __HAL_UNLOCK(hfmpi2c); 02708 02709 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02710 to avoid the risk of FMPI2C interrupt handle execution before current 02711 process unlock */ 02712 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 02713 02714 return HAL_OK; 02715 } 02716 else 02717 { 02718 return HAL_BUSY; 02719 } 02720 } 02721 02722 /** 02723 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt 02724 * @note This interface allow to manage repeated start condition when a direction change during transfer 02725 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02726 * the configuration information for the specified FMPI2C. 02727 * @param pData Pointer to data buffer 02728 * @param Size Amount of data to be sent 02729 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 02730 * @retval HAL status 02731 */ 02732 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) 02733 { 02734 /* Check the parameters */ 02735 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 02736 02737 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) 02738 { 02739 if ((pData == NULL) || (Size == 0U)) 02740 { 02741 return HAL_ERROR; 02742 } 02743 02744 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 02745 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT); 02746 02747 /* Process Locked */ 02748 __HAL_LOCK(hfmpi2c); 02749 02750 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 02751 /* and then toggle the HAL slave RX state to TX state */ 02752 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 02753 { 02754 /* Disable associated Interrupts */ 02755 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 02756 } 02757 02758 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN; 02759 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 02760 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02761 02762 /* Enable Address Acknowledge */ 02763 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 02764 02765 /* Prepare transfer parameters */ 02766 hfmpi2c->pBuffPtr = pData; 02767 hfmpi2c->XferCount = Size; 02768 hfmpi2c->XferSize = hfmpi2c->XferCount; 02769 hfmpi2c->XferOptions = XferOptions; 02770 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 02771 02772 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE) 02773 { 02774 /* Clear ADDR flag after prepare the transfer parameters */ 02775 /* This action will generate an acknowledge to the Master */ 02776 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 02777 } 02778 02779 /* Process Unlocked */ 02780 __HAL_UNLOCK(hfmpi2c); 02781 02782 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02783 to avoid the risk of FMPI2C interrupt handle execution before current 02784 process unlock */ 02785 /* REnable ADDR interrupt */ 02786 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT); 02787 02788 return HAL_OK; 02789 } 02790 else 02791 { 02792 return HAL_ERROR; 02793 } 02794 } 02795 02796 /** 02797 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt 02798 * @note This interface allow to manage repeated start condition when a direction change during transfer 02799 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02800 * the configuration information for the specified FMPI2C. 02801 * @param pData Pointer to data buffer 02802 * @param Size Amount of data to be sent 02803 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS 02804 * @retval HAL status 02805 */ 02806 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) 02807 { 02808 /* Check the parameters */ 02809 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); 02810 02811 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) 02812 { 02813 if ((pData == NULL) || (Size == 0U)) 02814 { 02815 return HAL_ERROR; 02816 } 02817 02818 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ 02819 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT); 02820 02821 /* Process Locked */ 02822 __HAL_LOCK(hfmpi2c); 02823 02824 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */ 02825 /* and then toggle the HAL slave TX state to RX state */ 02826 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 02827 { 02828 /* Disable associated Interrupts */ 02829 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02830 } 02831 02832 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN; 02833 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE; 02834 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 02835 02836 /* Enable Address Acknowledge */ 02837 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; 02838 02839 /* Prepare transfer parameters */ 02840 hfmpi2c->pBuffPtr = pData; 02841 hfmpi2c->XferCount = Size; 02842 hfmpi2c->XferSize = hfmpi2c->XferCount; 02843 hfmpi2c->XferOptions = XferOptions; 02844 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 02845 02846 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT) 02847 { 02848 /* Clear ADDR flag after prepare the transfer parameters */ 02849 /* This action will generate an acknowledge to the Master */ 02850 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 02851 } 02852 02853 /* Process Unlocked */ 02854 __HAL_UNLOCK(hfmpi2c); 02855 02856 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02857 to avoid the risk of FMPI2C interrupt handle execution before current 02858 process unlock */ 02859 /* REnable ADDR interrupt */ 02860 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT); 02861 02862 return HAL_OK; 02863 } 02864 else 02865 { 02866 return HAL_ERROR; 02867 } 02868 } 02869 02870 /** 02871 * @brief Enable the Address listen mode with Interrupt. 02872 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02873 * the configuration information for the specified FMPI2C. 02874 * @retval HAL status 02875 */ 02876 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) 02877 { 02878 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY) 02879 { 02880 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 02881 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 02882 02883 /* Enable the Address Match interrupt */ 02884 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 02885 02886 return HAL_OK; 02887 } 02888 else 02889 { 02890 return HAL_BUSY; 02891 } 02892 } 02893 02894 /** 02895 * @brief Disable the Address listen mode with Interrupt. 02896 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02897 * the configuration information for the specified FMPI2C 02898 * @retval HAL status 02899 */ 02900 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c) 02901 { 02902 /* Declaration of tmp to prevent undefined behavior of volatile usage */ 02903 uint32_t tmp; 02904 02905 /* Disable Address listen mode only if a transfer is not ongoing */ 02906 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) 02907 { 02908 tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK; 02909 hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode); 02910 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 02911 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 02912 hfmpi2c->XferISR = NULL; 02913 02914 /* Disable the Address Match interrupt */ 02915 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 02916 02917 return HAL_OK; 02918 } 02919 else 02920 { 02921 return HAL_BUSY; 02922 } 02923 } 02924 02925 /** 02926 * @brief Abort a master FMPI2C IT or DMA process communication with Interrupt. 02927 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02928 * the configuration information for the specified FMPI2C. 02929 * @param DevAddress Target device address The device 7 bits address value 02930 * in datasheet must be shifted to the left before calling the interface 02931 * @retval HAL status 02932 */ 02933 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress) 02934 { 02935 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER) 02936 { 02937 /* Process Locked */ 02938 __HAL_LOCK(hfmpi2c); 02939 02940 /* Disable Interrupts */ 02941 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 02942 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 02943 02944 /* Set State at HAL_FMPI2C_STATE_ABORT */ 02945 hfmpi2c->State = HAL_FMPI2C_STATE_ABORT; 02946 02947 /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */ 02948 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ 02949 FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP); 02950 02951 /* Process Unlocked */ 02952 __HAL_UNLOCK(hfmpi2c); 02953 02954 /* Note : The FMPI2C interrupts must be enabled after unlocking current process 02955 to avoid the risk of FMPI2C interrupt handle execution before current 02956 process unlock */ 02957 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 02958 02959 return HAL_OK; 02960 } 02961 else 02962 { 02963 /* Wrong usage of abort function */ 02964 /* This function should be used only in case of abort monitored by master device */ 02965 return HAL_ERROR; 02966 } 02967 } 02968 02969 /** 02970 * @} 02971 */ 02972 02973 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks 02974 * @{ 02975 */ 02976 02977 /** 02978 * @brief This function handles FMPI2C event interrupt request. 02979 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02980 * the configuration information for the specified FMPI2C. 02981 * @retval None 02982 */ 02983 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) 02984 { 02985 /* Get current IT Flags and IT sources value */ 02986 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); 02987 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); 02988 02989 /* FMPI2C events treatment -------------------------------------*/ 02990 if (hfmpi2c->XferISR != NULL) 02991 { 02992 hfmpi2c->XferISR(hfmpi2c, itflags, itsources); 02993 } 02994 } 02995 02996 /** 02997 * @brief This function handles FMPI2C error interrupt request. 02998 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 02999 * the configuration information for the specified FMPI2C. 03000 * @retval None 03001 */ 03002 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) 03003 { 03004 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR); 03005 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1); 03006 03007 /* FMPI2C Bus error interrupt occurred ------------------------------------*/ 03008 if (((itflags & FMPI2C_FLAG_BERR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) 03009 { 03010 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR; 03011 03012 /* Clear BERR flag */ 03013 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR); 03014 } 03015 03016 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ 03017 if (((itflags & FMPI2C_FLAG_OVR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) 03018 { 03019 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR; 03020 03021 /* Clear OVR flag */ 03022 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR); 03023 } 03024 03025 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/ 03026 if (((itflags & FMPI2C_FLAG_ARLO) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET)) 03027 { 03028 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO; 03029 03030 /* Clear ARLO flag */ 03031 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO); 03032 } 03033 03034 /* Call the Error Callback in case of Error detected */ 03035 if ((hfmpi2c->ErrorCode & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE) 03036 { 03037 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 03038 } 03039 } 03040 03041 /** 03042 * @brief Master Tx Transfer completed callback. 03043 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03044 * the configuration information for the specified FMPI2C. 03045 * @retval None 03046 */ 03047 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03048 { 03049 /* Prevent unused argument(s) compilation warning */ 03050 UNUSED(hfmpi2c); 03051 03052 /* NOTE : This function should not be modified, when the callback is needed, 03053 the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file 03054 */ 03055 } 03056 03057 /** 03058 * @brief Master Rx Transfer completed callback. 03059 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03060 * the configuration information for the specified FMPI2C. 03061 * @retval None 03062 */ 03063 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03064 { 03065 /* Prevent unused argument(s) compilation warning */ 03066 UNUSED(hfmpi2c); 03067 03068 /* NOTE : This function should not be modified, when the callback is needed, 03069 the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file 03070 */ 03071 } 03072 03073 /** @brief Slave Tx Transfer completed callback. 03074 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03075 * the configuration information for the specified FMPI2C. 03076 * @retval None 03077 */ 03078 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03079 { 03080 /* Prevent unused argument(s) compilation warning */ 03081 UNUSED(hfmpi2c); 03082 03083 /* NOTE : This function should not be modified, when the callback is needed, 03084 the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file 03085 */ 03086 } 03087 03088 /** 03089 * @brief Slave Rx Transfer completed callback. 03090 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03091 * the configuration information for the specified FMPI2C. 03092 * @retval None 03093 */ 03094 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03095 { 03096 /* Prevent unused argument(s) compilation warning */ 03097 UNUSED(hfmpi2c); 03098 03099 /* NOTE : This function should not be modified, when the callback is needed, 03100 the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file 03101 */ 03102 } 03103 03104 /** 03105 * @brief Slave Address Match callback. 03106 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03107 * the configuration information for the specified FMPI2C. 03108 * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION 03109 * @param AddrMatchCode Address Match Code 03110 * @retval None 03111 */ 03112 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) 03113 { 03114 /* Prevent unused argument(s) compilation warning */ 03115 UNUSED(hfmpi2c); 03116 UNUSED(TransferDirection); 03117 UNUSED(AddrMatchCode); 03118 03119 /* NOTE : This function should not be modified, when the callback is needed, 03120 the HAL_FMPI2C_AddrCallback() could be implemented in the user file 03121 */ 03122 } 03123 03124 /** 03125 * @brief Listen Complete callback. 03126 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03127 * the configuration information for the specified FMPI2C. 03128 * @retval None 03129 */ 03130 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03131 { 03132 /* Prevent unused argument(s) compilation warning */ 03133 UNUSED(hfmpi2c); 03134 03135 /* NOTE : This function should not be modified, when the callback is needed, 03136 the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file 03137 */ 03138 } 03139 03140 /** 03141 * @brief Memory Tx Transfer completed callback. 03142 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03143 * the configuration information for the specified FMPI2C. 03144 * @retval None 03145 */ 03146 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03147 { 03148 /* Prevent unused argument(s) compilation warning */ 03149 UNUSED(hfmpi2c); 03150 03151 /* NOTE : This function should not be modified, when the callback is needed, 03152 the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file 03153 */ 03154 } 03155 03156 /** 03157 * @brief Memory Rx Transfer completed callback. 03158 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03159 * the configuration information for the specified FMPI2C. 03160 * @retval None 03161 */ 03162 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03163 { 03164 /* Prevent unused argument(s) compilation warning */ 03165 UNUSED(hfmpi2c); 03166 03167 /* NOTE : This function should not be modified, when the callback is needed, 03168 the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file 03169 */ 03170 } 03171 03172 /** 03173 * @brief FMPI2C error callback. 03174 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03175 * the configuration information for the specified FMPI2C. 03176 * @retval None 03177 */ 03178 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03179 { 03180 /* Prevent unused argument(s) compilation warning */ 03181 UNUSED(hfmpi2c); 03182 03183 /* NOTE : This function should not be modified, when the callback is needed, 03184 the HAL_FMPI2C_ErrorCallback could be implemented in the user file 03185 */ 03186 } 03187 03188 /** 03189 * @brief FMPI2C abort callback. 03190 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03191 * the configuration information for the specified FMPI2C. 03192 * @retval None 03193 */ 03194 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) 03195 { 03196 /* Prevent unused argument(s) compilation warning */ 03197 UNUSED(hfmpi2c); 03198 03199 /* NOTE : This function should not be modified, when the callback is needed, 03200 the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file 03201 */ 03202 } 03203 03204 /** 03205 * @} 03206 */ 03207 03208 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions 03209 * @brief Peripheral State, Mode and Error functions 03210 * 03211 @verbatim 03212 =============================================================================== 03213 ##### Peripheral State, Mode and Error functions ##### 03214 =============================================================================== 03215 [..] 03216 This subsection permit to get in run-time the status of the peripheral 03217 and the data flow. 03218 03219 @endverbatim 03220 * @{ 03221 */ 03222 03223 /** 03224 * @brief Return the FMPI2C handle state. 03225 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03226 * the configuration information for the specified FMPI2C. 03227 * @retval HAL state 03228 */ 03229 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c) 03230 { 03231 /* Return FMPI2C handle state */ 03232 return hfmpi2c->State; 03233 } 03234 03235 /** 03236 * @brief Returns the FMPI2C Master, Slave, Memory or no mode. 03237 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03238 * the configuration information for FMPI2C module 03239 * @retval HAL mode 03240 */ 03241 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c) 03242 { 03243 return hfmpi2c->Mode; 03244 } 03245 03246 /** 03247 * @brief Return the FMPI2C error code. 03248 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03249 * the configuration information for the specified FMPI2C. 03250 * @retval FMPI2C Error Code 03251 */ 03252 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c) 03253 { 03254 return hfmpi2c->ErrorCode; 03255 } 03256 03257 /** 03258 * @} 03259 */ 03260 03261 /** 03262 * @} 03263 */ 03264 03265 /** @addtogroup FMPI2C_Private_Functions 03266 * @{ 03267 */ 03268 03269 /** 03270 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt. 03271 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03272 * the configuration information for the specified FMPI2C. 03273 * @param ITFlags Interrupt flags to handle. 03274 * @param ITSources Interrupt sources enabled. 03275 * @retval HAL status 03276 */ 03277 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) 03278 { 03279 uint16_t devaddress = 0U; 03280 03281 /* Process Locked */ 03282 __HAL_LOCK(hfmpi2c); 03283 03284 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) 03285 { 03286 /* Clear NACK Flag */ 03287 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03288 03289 /* Set corresponding Error Code */ 03290 /* No need to generate STOP, it is automatically done */ 03291 /* Error callback will be send during stop flag treatment */ 03292 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 03293 03294 /* Flush TX register */ 03295 FMPI2C_Flush_TXDR(hfmpi2c); 03296 } 03297 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET)) 03298 { 03299 /* Read data from RXDR */ 03300 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 03301 hfmpi2c->XferSize--; 03302 hfmpi2c->XferCount--; 03303 } 03304 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET)) 03305 { 03306 /* Write data to TXDR */ 03307 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); 03308 hfmpi2c->XferSize--; 03309 hfmpi2c->XferCount--; 03310 } 03311 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) 03312 { 03313 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U)) 03314 { 03315 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); 03316 03317 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03318 { 03319 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03320 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); 03321 } 03322 else 03323 { 03324 hfmpi2c->XferSize = hfmpi2c->XferCount; 03325 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) 03326 { 03327 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP); 03328 } 03329 else 03330 { 03331 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); 03332 } 03333 } 03334 } 03335 else 03336 { 03337 /* Call TxCpltCallback() if no stop mode is set */ 03338 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 03339 { 03340 /* Call FMPI2C Master Sequential complete process */ 03341 FMPI2C_ITMasterSequentialCplt(hfmpi2c); 03342 } 03343 else 03344 { 03345 /* Wrong size Status regarding TCR flag event */ 03346 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03347 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 03348 } 03349 } 03350 } 03351 else if (((ITFlags & FMPI2C_FLAG_TC) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) 03352 { 03353 if (hfmpi2c->XferCount == 0U) 03354 { 03355 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE) 03356 { 03357 /* Generate a stop condition in case of no transfer option */ 03358 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME) 03359 { 03360 /* Generate Stop */ 03361 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; 03362 } 03363 else 03364 { 03365 /* Call FMPI2C Master Sequential complete process */ 03366 FMPI2C_ITMasterSequentialCplt(hfmpi2c); 03367 } 03368 } 03369 } 03370 else 03371 { 03372 /* Wrong size Status regarding TC flag event */ 03373 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03374 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 03375 } 03376 } 03377 03378 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) 03379 { 03380 /* Call FMPI2C Master complete process */ 03381 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags); 03382 } 03383 03384 /* Process Unlocked */ 03385 __HAL_UNLOCK(hfmpi2c); 03386 03387 return HAL_OK; 03388 } 03389 03390 /** 03391 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt. 03392 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03393 * the configuration information for the specified FMPI2C. 03394 * @param ITFlags Interrupt flags to handle. 03395 * @param ITSources Interrupt sources enabled. 03396 * @retval HAL status 03397 */ 03398 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) 03399 { 03400 /* Process locked */ 03401 __HAL_LOCK(hfmpi2c); 03402 03403 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) 03404 { 03405 /* Check that FMPI2C transfer finished */ 03406 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ 03407 /* Mean XferCount == 0*/ 03408 /* So clear Flag NACKF only */ 03409 if (hfmpi2c->XferCount == 0U) 03410 { 03411 if (((hfmpi2c->XferOptions == FMPI2C_FIRST_AND_LAST_FRAME) || (hfmpi2c->XferOptions == FMPI2C_LAST_FRAME)) && \ 03412 (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)) 03413 { 03414 /* Call FMPI2C Listen complete process */ 03415 FMPI2C_ITListenCplt(hfmpi2c, ITFlags); 03416 } 03417 else if ((hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) && (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)) 03418 { 03419 /* Clear NACK Flag */ 03420 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03421 03422 /* Flush TX register */ 03423 FMPI2C_Flush_TXDR(hfmpi2c); 03424 03425 /* Last Byte is Transmitted */ 03426 /* Call FMPI2C Slave Sequential complete process */ 03427 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); 03428 } 03429 else 03430 { 03431 /* Clear NACK Flag */ 03432 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03433 } 03434 } 03435 else 03436 { 03437 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ 03438 /* Clear NACK Flag */ 03439 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03440 03441 /* Set ErrorCode corresponding to a Non-Acknowledge */ 03442 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 03443 } 03444 } 03445 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET)) 03446 { 03447 if (hfmpi2c->XferCount > 0U) 03448 { 03449 /* Read data from RXDR */ 03450 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 03451 hfmpi2c->XferSize--; 03452 hfmpi2c->XferCount--; 03453 } 03454 03455 if ((hfmpi2c->XferCount == 0U) && \ 03456 (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)) 03457 { 03458 /* Call FMPI2C Slave Sequential complete process */ 03459 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); 03460 } 03461 } 03462 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET)) 03463 { 03464 FMPI2C_ITAddrCplt(hfmpi2c, ITFlags); 03465 } 03466 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET)) 03467 { 03468 /* Write data to TXDR only if XferCount not reach "0" */ 03469 /* A TXIS flag can be set, during STOP treatment */ 03470 /* Check if all Datas have already been sent */ 03471 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ 03472 if (hfmpi2c->XferCount > 0U) 03473 { 03474 /* Write data to TXDR */ 03475 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); 03476 hfmpi2c->XferCount--; 03477 hfmpi2c->XferSize--; 03478 } 03479 else 03480 { 03481 if ((hfmpi2c->XferOptions == FMPI2C_NEXT_FRAME) || (hfmpi2c->XferOptions == FMPI2C_FIRST_FRAME)) 03482 { 03483 /* Last Byte is Transmitted */ 03484 /* Call FMPI2C Slave Sequential complete process */ 03485 FMPI2C_ITSlaveSequentialCplt(hfmpi2c); 03486 } 03487 } 03488 } 03489 03490 /* Check if STOPF is set */ 03491 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) 03492 { 03493 /* Call FMPI2C Slave complete process */ 03494 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags); 03495 } 03496 03497 /* Process Unlocked */ 03498 __HAL_UNLOCK(hfmpi2c); 03499 03500 return HAL_OK; 03501 } 03502 03503 /** 03504 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA. 03505 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03506 * the configuration information for the specified FMPI2C. 03507 * @param ITFlags Interrupt flags to handle. 03508 * @param ITSources Interrupt sources enabled. 03509 * @retval HAL status 03510 */ 03511 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) 03512 { 03513 uint16_t devaddress = 0U; 03514 uint32_t xfermode = 0U; 03515 03516 /* Process Locked */ 03517 __HAL_LOCK(hfmpi2c); 03518 03519 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) 03520 { 03521 /* Clear NACK Flag */ 03522 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03523 03524 /* Set corresponding Error Code */ 03525 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 03526 03527 /* No need to generate STOP, it is automatically done */ 03528 /* But enable STOP interrupt, to treat it */ 03529 /* Error callback will be send during stop flag treatment */ 03530 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 03531 03532 /* Flush TX register */ 03533 FMPI2C_Flush_TXDR(hfmpi2c); 03534 } 03535 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET)) 03536 { 03537 /* Disable TC interrupt */ 03538 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI); 03539 03540 if (hfmpi2c->XferCount != 0U) 03541 { 03542 /* Recover Slave address */ 03543 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); 03544 03545 /* Prepare the new XferSize to transfer */ 03546 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 03547 { 03548 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 03549 xfermode = FMPI2C_RELOAD_MODE; 03550 } 03551 else 03552 { 03553 hfmpi2c->XferSize = hfmpi2c->XferCount; 03554 xfermode = FMPI2C_AUTOEND_MODE; 03555 } 03556 03557 /* Set the new XferSize in Nbytes register */ 03558 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP); 03559 03560 /* Update XferCount value */ 03561 hfmpi2c->XferCount -= hfmpi2c->XferSize; 03562 03563 /* Enable DMA Request */ 03564 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 03565 { 03566 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; 03567 } 03568 else 03569 { 03570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; 03571 } 03572 } 03573 else 03574 { 03575 /* Wrong size Status regarding TCR flag event */ 03576 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03577 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE); 03578 } 03579 } 03580 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) 03581 { 03582 /* Call FMPI2C Master complete process */ 03583 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags); 03584 } 03585 03586 /* Process Unlocked */ 03587 __HAL_UNLOCK(hfmpi2c); 03588 03589 return HAL_OK; 03590 } 03591 03592 /** 03593 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA. 03594 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03595 * the configuration information for the specified FMPI2C. 03596 * @param ITFlags Interrupt flags to handle. 03597 * @param ITSources Interrupt sources enabled. 03598 * @retval HAL status 03599 */ 03600 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources) 03601 { 03602 /* Process locked */ 03603 __HAL_LOCK(hfmpi2c); 03604 03605 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET)) 03606 { 03607 /* Check that FMPI2C transfer finished */ 03608 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ 03609 /* Mean XferCount == 0 */ 03610 /* So clear Flag NACKF only */ 03611 if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c) == 0U) 03612 { 03613 /* Clear NACK Flag */ 03614 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03615 } 03616 else 03617 { 03618 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ 03619 /* Clear NACK Flag */ 03620 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03621 03622 /* Set ErrorCode corresponding to a Non-Acknowledge */ 03623 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 03624 } 03625 } 03626 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET)) 03627 { 03628 /* Clear ADDR flag */ 03629 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 03630 } 03631 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET)) 03632 { 03633 /* Call FMPI2C Slave complete process */ 03634 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags); 03635 } 03636 03637 /* Process Unlocked */ 03638 __HAL_UNLOCK(hfmpi2c); 03639 03640 return HAL_OK; 03641 } 03642 03643 /** 03644 * @brief Master sends target device address followed by internal memory address for write request. 03645 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03646 * the configuration information for the specified FMPI2C. 03647 * @param DevAddress Target device address The device 7 bits address value 03648 * in datasheet must be shifted to the left before calling the interface 03649 * @param MemAddress Internal memory address 03650 * @param MemAddSize Size of internal memory address 03651 * @param Timeout Timeout duration 03652 * @param Tickstart Tick start value 03653 * @retval HAL status 03654 */ 03655 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) 03656 { 03657 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); 03658 03659 /* Wait until TXIS flag is set */ 03660 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 03661 { 03662 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 03663 { 03664 return HAL_ERROR; 03665 } 03666 else 03667 { 03668 return HAL_TIMEOUT; 03669 } 03670 } 03671 03672 /* If Memory address size is 8Bit */ 03673 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) 03674 { 03675 /* Send Memory Address */ 03676 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 03677 } 03678 /* If Memory address size is 16Bit */ 03679 else 03680 { 03681 /* Send MSB of Memory Address */ 03682 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); 03683 03684 /* Wait until TXIS flag is set */ 03685 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 03686 { 03687 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 03688 { 03689 return HAL_ERROR; 03690 } 03691 else 03692 { 03693 return HAL_TIMEOUT; 03694 } 03695 } 03696 03697 /* Send LSB of Memory Address */ 03698 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 03699 } 03700 03701 /* Wait until TCR flag is set */ 03702 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) 03703 { 03704 return HAL_TIMEOUT; 03705 } 03706 03707 return HAL_OK; 03708 } 03709 03710 /** 03711 * @brief Master sends target device address followed by internal memory address for read request. 03712 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 03713 * the configuration information for the specified FMPI2C. 03714 * @param DevAddress Target device address The device 7 bits address value 03715 * in datasheet must be shifted to the left before calling the interface 03716 * @param MemAddress Internal memory address 03717 * @param MemAddSize Size of internal memory address 03718 * @param Timeout Timeout duration 03719 * @param Tickstart Tick start value 03720 * @retval HAL status 03721 */ 03722 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) 03723 { 03724 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE); 03725 03726 /* Wait until TXIS flag is set */ 03727 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 03728 { 03729 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 03730 { 03731 return HAL_ERROR; 03732 } 03733 else 03734 { 03735 return HAL_TIMEOUT; 03736 } 03737 } 03738 03739 /* If Memory address size is 8Bit */ 03740 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) 03741 { 03742 /* Send Memory Address */ 03743 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 03744 } 03745 /* If Memory address size is 16Bit */ 03746 else 03747 { 03748 /* Send MSB of Memory Address */ 03749 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress); 03750 03751 /* Wait until TXIS flag is set */ 03752 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK) 03753 { 03754 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) 03755 { 03756 return HAL_ERROR; 03757 } 03758 else 03759 { 03760 return HAL_TIMEOUT; 03761 } 03762 } 03763 03764 /* Send LSB of Memory Address */ 03765 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress); 03766 } 03767 03768 /* Wait until TC flag is set */ 03769 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) 03770 { 03771 return HAL_TIMEOUT; 03772 } 03773 03774 return HAL_OK; 03775 } 03776 03777 /** 03778 * @brief FMPI2C Address complete process callback. 03779 * @param hfmpi2c FMPI2C handle. 03780 * @param ITFlags Interrupt flags to handle. 03781 * @retval None 03782 */ 03783 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 03784 { 03785 uint8_t transferdirection = 0; 03786 uint16_t slaveaddrcode = 0; 03787 uint16_t ownadd1code = 0; 03788 uint16_t ownadd2code = 0; 03789 03790 /* Prevent unused argument(s) compilation warning */ 03791 UNUSED(ITFlags); 03792 03793 /* In case of Listen state, need to inform upper layer of address match code event */ 03794 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN) 03795 { 03796 transferdirection = FMPI2C_GET_DIR(hfmpi2c); 03797 slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c); 03798 ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c); 03799 ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c); 03800 03801 /* If 10bits addressing mode is selected */ 03802 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) 03803 { 03804 if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK)) 03805 { 03806 slaveaddrcode = ownadd1code; 03807 hfmpi2c->AddrEventCount++; 03808 if (hfmpi2c->AddrEventCount == 2U) 03809 { 03810 /* Reset Address Event counter */ 03811 hfmpi2c->AddrEventCount = 0U; 03812 03813 /* Clear ADDR flag */ 03814 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 03815 03816 /* Process Unlocked */ 03817 __HAL_UNLOCK(hfmpi2c); 03818 03819 /* Call Slave Addr callback */ 03820 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 03821 } 03822 } 03823 else 03824 { 03825 slaveaddrcode = ownadd2code; 03826 03827 /* Disable ADDR Interrupts */ 03828 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 03829 03830 /* Process Unlocked */ 03831 __HAL_UNLOCK(hfmpi2c); 03832 03833 /* Call Slave Addr callback */ 03834 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 03835 } 03836 } 03837 /* else 7 bits addressing mode is selected */ 03838 else 03839 { 03840 /* Disable ADDR Interrupts */ 03841 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT); 03842 03843 /* Process Unlocked */ 03844 __HAL_UNLOCK(hfmpi2c); 03845 03846 /* Call Slave Addr callback */ 03847 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode); 03848 } 03849 } 03850 /* Else clear address flag only */ 03851 else 03852 { 03853 /* Clear ADDR flag */ 03854 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 03855 03856 /* Process Unlocked */ 03857 __HAL_UNLOCK(hfmpi2c); 03858 } 03859 } 03860 03861 /** 03862 * @brief FMPI2C Master sequential complete process. 03863 * @param hfmpi2c FMPI2C handle. 03864 * @retval None 03865 */ 03866 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c) 03867 { 03868 /* Reset FMPI2C handle mode */ 03869 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03870 03871 /* No Generate Stop, to permit restart mode */ 03872 /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */ 03873 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 03874 { 03875 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03876 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX; 03877 hfmpi2c->XferISR = NULL; 03878 03879 /* Disable Interrupts */ 03880 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 03881 03882 /* Process Unlocked */ 03883 __HAL_UNLOCK(hfmpi2c); 03884 03885 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03886 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); 03887 } 03888 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ 03889 else 03890 { 03891 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03892 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX; 03893 hfmpi2c->XferISR = NULL; 03894 03895 /* Disable Interrupts */ 03896 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 03897 03898 /* Process Unlocked */ 03899 __HAL_UNLOCK(hfmpi2c); 03900 03901 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03902 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); 03903 } 03904 } 03905 03906 /** 03907 * @brief FMPI2C Slave sequential complete process. 03908 * @param hfmpi2c FMPI2C handle. 03909 * @retval None 03910 */ 03911 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c) 03912 { 03913 /* Reset FMPI2C handle mode */ 03914 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03915 03916 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) 03917 { 03918 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */ 03919 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 03920 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX; 03921 03922 /* Disable Interrupts */ 03923 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT); 03924 03925 /* Process Unlocked */ 03926 __HAL_UNLOCK(hfmpi2c); 03927 03928 /* Call the Tx complete callback to inform upper layer of the end of transmit process */ 03929 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); 03930 } 03931 03932 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN) 03933 { 03934 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */ 03935 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 03936 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX; 03937 03938 /* Disable Interrupts */ 03939 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT); 03940 03941 /* Process Unlocked */ 03942 __HAL_UNLOCK(hfmpi2c); 03943 03944 /* Call the Rx complete callback to inform upper layer of the end of receive process */ 03945 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); 03946 } 03947 } 03948 03949 /** 03950 * @brief FMPI2C Master complete process. 03951 * @param hfmpi2c FMPI2C handle. 03952 * @param ITFlags Interrupt flags to handle. 03953 * @retval None 03954 */ 03955 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 03956 { 03957 /* Clear STOP Flag */ 03958 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 03959 03960 /* Clear Configuration Register 2 */ 03961 FMPI2C_RESET_CR2(hfmpi2c); 03962 03963 /* Reset handle parameters */ 03964 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 03965 hfmpi2c->XferISR = NULL; 03966 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 03967 03968 if ((ITFlags & FMPI2C_FLAG_AF) != RESET) 03969 { 03970 /* Clear NACK Flag */ 03971 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 03972 03973 /* Set acknowledge error code */ 03974 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 03975 } 03976 03977 /* Flush TX register */ 03978 FMPI2C_Flush_TXDR(hfmpi2c); 03979 03980 /* Disable Interrupts */ 03981 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT); 03982 03983 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03984 if ((hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) || (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)) 03985 { 03986 /* Call the corresponding callback to inform upper layer of End of Transfer */ 03987 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 03988 } 03989 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */ 03990 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX) 03991 { 03992 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 03993 03994 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) 03995 { 03996 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 03997 03998 /* Process Unlocked */ 03999 __HAL_UNLOCK(hfmpi2c); 04000 04001 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04002 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c); 04003 } 04004 else 04005 { 04006 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04007 04008 /* Process Unlocked */ 04009 __HAL_UNLOCK(hfmpi2c); 04010 04011 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04012 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); 04013 } 04014 } 04015 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */ 04016 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 04017 { 04018 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04019 04020 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM) 04021 { 04022 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04023 04024 /* Process Unlocked */ 04025 __HAL_UNLOCK(hfmpi2c); 04026 04027 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c); 04028 } 04029 else 04030 { 04031 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04032 04033 /* Process Unlocked */ 04034 __HAL_UNLOCK(hfmpi2c); 04035 04036 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); 04037 } 04038 } 04039 } 04040 04041 /** 04042 * @brief FMPI2C Slave complete process. 04043 * @param hfmpi2c FMPI2C handle. 04044 * @param ITFlags Interrupt flags to handle. 04045 * @retval None 04046 */ 04047 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 04048 { 04049 /* Clear STOP Flag */ 04050 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 04051 04052 /* Clear ADDR flag */ 04053 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); 04054 04055 /* Disable all interrupts */ 04056 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT); 04057 04058 /* Disable Address Acknowledge */ 04059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 04060 04061 /* Clear Configuration Register 2 */ 04062 FMPI2C_RESET_CR2(hfmpi2c); 04063 04064 /* Flush TX register */ 04065 FMPI2C_Flush_TXDR(hfmpi2c); 04066 04067 /* If a DMA is ongoing, Update handle size context */ 04068 if (((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) || 04069 ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)) 04070 { 04071 hfmpi2c->XferCount = FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c); 04072 } 04073 04074 /* All data are not transferred, so set error code accordingly */ 04075 if (hfmpi2c->XferCount != 0U) 04076 { 04077 /* Set ErrorCode corresponding to a Non-Acknowledge */ 04078 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 04079 } 04080 04081 /* Store Last receive data if any */ 04082 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET)) 04083 { 04084 /* Read data from RXDR */ 04085 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 04086 04087 if ((hfmpi2c->XferSize > 0U)) 04088 { 04089 hfmpi2c->XferSize--; 04090 hfmpi2c->XferCount--; 04091 04092 /* Set ErrorCode corresponding to a Non-Acknowledge */ 04093 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 04094 } 04095 } 04096 04097 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 04098 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04099 hfmpi2c->XferISR = NULL; 04100 04101 if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) 04102 { 04103 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04104 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode); 04105 04106 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 04107 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) 04108 { 04109 /* Call FMPI2C Listen complete process */ 04110 FMPI2C_ITListenCplt(hfmpi2c, ITFlags); 04111 } 04112 } 04113 else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) 04114 { 04115 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 04116 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04117 04118 /* Process Unlocked */ 04119 __HAL_UNLOCK(hfmpi2c); 04120 04121 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 04122 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); 04123 } 04124 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04125 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX) 04126 { 04127 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04128 04129 /* Process Unlocked */ 04130 __HAL_UNLOCK(hfmpi2c); 04131 04132 /* Call the Slave Rx Complete callback */ 04133 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); 04134 } 04135 else 04136 { 04137 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04138 04139 /* Process Unlocked */ 04140 __HAL_UNLOCK(hfmpi2c); 04141 04142 /* Call the Slave Tx Complete callback */ 04143 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); 04144 } 04145 } 04146 04147 /** 04148 * @brief FMPI2C Listen complete process. 04149 * @param hfmpi2c FMPI2C handle. 04150 * @param ITFlags Interrupt flags to handle. 04151 * @retval None 04152 */ 04153 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags) 04154 { 04155 /* Reset handle parameters */ 04156 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 04157 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 04158 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04159 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04160 hfmpi2c->XferISR = NULL; 04161 04162 /* Store Last receive data if any */ 04163 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET)) 04164 { 04165 /* Read data from RXDR */ 04166 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; 04167 04168 if ((hfmpi2c->XferSize > 0U)) 04169 { 04170 hfmpi2c->XferSize--; 04171 hfmpi2c->XferCount--; 04172 04173 /* Set ErrorCode corresponding to a Non-Acknowledge */ 04174 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; 04175 } 04176 } 04177 04178 /* Disable all Interrupts*/ 04179 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 04180 04181 /* Clear NACK Flag */ 04182 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04183 04184 /* Process Unlocked */ 04185 __HAL_UNLOCK(hfmpi2c); 04186 04187 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ 04188 HAL_FMPI2C_ListenCpltCallback(hfmpi2c); 04189 } 04190 04191 /** 04192 * @brief FMPI2C interrupts error process. 04193 * @param hfmpi2c FMPI2C handle. 04194 * @param ErrorCode Error code to handle. 04195 * @retval None 04196 */ 04197 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode) 04198 { 04199 /* Reset handle parameters */ 04200 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04201 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME; 04202 hfmpi2c->XferCount = 0U; 04203 04204 /* Set new error code */ 04205 hfmpi2c->ErrorCode |= ErrorCode; 04206 04207 /* Disable Interrupts */ 04208 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) || 04209 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) || 04210 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)) 04211 { 04212 /* Disable all interrupts, except interrupts related to LISTEN state */ 04213 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 04214 04215 /* keep HAL_FMPI2C_STATE_LISTEN if set */ 04216 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN; 04217 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 04218 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT; 04219 } 04220 else 04221 { 04222 /* Disable all interrupts */ 04223 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT); 04224 04225 /* If state is an abort treatment on goind, don't change state */ 04226 /* This change will be do later */ 04227 if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT) 04228 { 04229 /* Set HAL_FMPI2C_STATE_READY */ 04230 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04231 } 04232 hfmpi2c->PreviousState = FMPI2C_STATE_NONE; 04233 hfmpi2c->XferISR = NULL; 04234 } 04235 04236 /* Abort DMA TX transfer if any */ 04237 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) 04238 { 04239 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 04240 04241 /* Set the FMPI2C DMA Abort callback : 04242 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 04243 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort; 04244 04245 /* Process Unlocked */ 04246 __HAL_UNLOCK(hfmpi2c); 04247 04248 /* Abort DMA TX */ 04249 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK) 04250 { 04251 /* Call Directly XferAbortCallback function in case of error */ 04252 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx); 04253 } 04254 } 04255 /* Abort DMA RX transfer if any */ 04256 else if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN) 04257 { 04258 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 04259 04260 /* Set the FMPI2C DMA Abort callback : 04261 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */ 04262 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort; 04263 04264 /* Process Unlocked */ 04265 __HAL_UNLOCK(hfmpi2c); 04266 04267 /* Abort DMA RX */ 04268 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK) 04269 { 04270 /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */ 04271 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx); 04272 } 04273 } 04274 else if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) 04275 { 04276 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04277 04278 /* Process Unlocked */ 04279 __HAL_UNLOCK(hfmpi2c); 04280 04281 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04282 HAL_FMPI2C_AbortCpltCallback(hfmpi2c); 04283 } 04284 else 04285 { 04286 /* Process Unlocked */ 04287 __HAL_UNLOCK(hfmpi2c); 04288 04289 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04290 HAL_FMPI2C_ErrorCallback(hfmpi2c); 04291 } 04292 } 04293 04294 /** 04295 * @brief FMPI2C Tx data register flush process. 04296 * @param hfmpi2c FMPI2C handle. 04297 * @retval None 04298 */ 04299 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c) 04300 { 04301 /* If a pending TXIS flag is set */ 04302 /* Write a dummy data in TXDR to clear it */ 04303 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET) 04304 { 04305 hfmpi2c->Instance->TXDR = 0x00U; 04306 } 04307 04308 /* Flush TX register if not empty */ 04309 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET) 04310 { 04311 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE); 04312 } 04313 } 04314 04315 /** 04316 * @brief DMA FMPI2C master transmit process complete callback. 04317 * @param hdma DMA handle 04318 * @retval None 04319 */ 04320 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) 04321 { 04322 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 04323 04324 /* Disable DMA Request */ 04325 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; 04326 04327 /* If last transfer, enable STOP interrupt */ 04328 if (hfmpi2c->XferCount == 0U) 04329 { 04330 /* Enable STOP interrupt */ 04331 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 04332 } 04333 /* else prepare a new DMA transfer and enable TCReload interrupt */ 04334 else 04335 { 04336 /* Update Buffer pointer */ 04337 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; 04338 04339 /* Set the XferSize to transfer */ 04340 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 04341 { 04342 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 04343 } 04344 else 04345 { 04346 hfmpi2c->XferSize = hfmpi2c->XferCount; 04347 } 04348 04349 /* Enable the DMA stream */ 04350 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); 04351 04352 /* Enable TC interrupts */ 04353 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); 04354 } 04355 } 04356 04357 /** 04358 * @brief DMA FMPI2C slave transmit process complete callback. 04359 * @param hdma DMA handle 04360 * @retval None 04361 */ 04362 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) 04363 { 04364 /* Prevent unused argument(s) compilation warning */ 04365 UNUSED(hdma); 04366 04367 /* No specific action, Master fully manage the generation of STOP condition */ 04368 /* Mean that this generation can arrive at any time, at the end or during DMA process */ 04369 /* So STOP condition should be manage through Interrupt treatment */ 04370 } 04371 04372 /** 04373 * @brief DMA FMPI2C master receive process complete callback. 04374 * @param hdma DMA handle 04375 * @retval None 04376 */ 04377 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) 04378 { 04379 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 04380 04381 /* Disable DMA Request */ 04382 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; 04383 04384 /* If last transfer, enable STOP interrupt */ 04385 if (hfmpi2c->XferCount == 0U) 04386 { 04387 /* Enable STOP interrupt */ 04388 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT); 04389 } 04390 /* else prepare a new DMA transfer and enable TCReload interrupt */ 04391 else 04392 { 04393 /* Update Buffer pointer */ 04394 hfmpi2c->pBuffPtr += hfmpi2c->XferSize; 04395 04396 /* Set the XferSize to transfer */ 04397 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE) 04398 { 04399 hfmpi2c->XferSize = MAX_NBYTE_SIZE; 04400 } 04401 else 04402 { 04403 hfmpi2c->XferSize = hfmpi2c->XferCount; 04404 } 04405 04406 /* Enable the DMA stream */ 04407 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize); 04408 04409 /* Enable TC interrupts */ 04410 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT); 04411 } 04412 } 04413 04414 /** 04415 * @brief DMA FMPI2C slave receive process complete callback. 04416 * @param hdma DMA handle 04417 * @retval None 04418 */ 04419 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) 04420 { 04421 /* Prevent unused argument(s) compilation warning */ 04422 UNUSED(hdma); 04423 04424 /* No specific action, Master fully manage the generation of STOP condition */ 04425 /* Mean that this generation can arrive at any time, at the end or during DMA process */ 04426 /* So STOP condition should be manage through Interrupt treatment */ 04427 } 04428 04429 /** 04430 * @brief DMA FMPI2C communication error callback. 04431 * @param hdma DMA handle 04432 * @retval None 04433 */ 04434 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma) 04435 { 04436 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 04437 04438 /* Disable Acknowledge */ 04439 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 04440 04441 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04442 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA); 04443 } 04444 04445 /** 04446 * @brief DMA FMPI2C communication abort callback 04447 * (To be called at end of DMA Abort procedure). 04448 * @param hdma DMA handle. 04449 * @retval None 04450 */ 04451 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma) 04452 { 04453 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 04454 04455 /* Disable Acknowledge */ 04456 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; 04457 04458 /* Reset AbortCpltCallback */ 04459 hfmpi2c->hdmatx->XferAbortCallback = NULL; 04460 hfmpi2c->hdmarx->XferAbortCallback = NULL; 04461 04462 /* Check if come from abort from user */ 04463 if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) 04464 { 04465 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04466 04467 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04468 HAL_FMPI2C_AbortCpltCallback(hfmpi2c); 04469 } 04470 else 04471 { 04472 /* Call the corresponding callback to inform upper layer of End of Transfer */ 04473 HAL_FMPI2C_ErrorCallback(hfmpi2c); 04474 } 04475 } 04476 04477 /** 04478 * @brief This function handles FMPI2C Communication Timeout. 04479 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04480 * the configuration information for the specified FMPI2C. 04481 * @param Flag Specifies the FMPI2C flag to check. 04482 * @param Status The new Flag status (SET or RESET). 04483 * @param Timeout Timeout duration 04484 * @param Tickstart Tick start value 04485 * @retval HAL status 04486 */ 04487 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) 04488 { 04489 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status) 04490 { 04491 /* Check for the Timeout */ 04492 if (Timeout != HAL_MAX_DELAY) 04493 { 04494 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 04495 { 04496 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04497 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04498 04499 /* Process Unlocked */ 04500 __HAL_UNLOCK(hfmpi2c); 04501 return HAL_TIMEOUT; 04502 } 04503 } 04504 } 04505 return HAL_OK; 04506 } 04507 04508 /** 04509 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag. 04510 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04511 * the configuration information for the specified FMPI2C. 04512 * @param Timeout Timeout duration 04513 * @param Tickstart Tick start value 04514 * @retval HAL status 04515 */ 04516 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) 04517 { 04518 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET) 04519 { 04520 /* Check if a NACK is detected */ 04521 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 04522 { 04523 return HAL_ERROR; 04524 } 04525 04526 /* Check for the Timeout */ 04527 if (Timeout != HAL_MAX_DELAY) 04528 { 04529 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 04530 { 04531 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 04532 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04533 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04534 04535 /* Process Unlocked */ 04536 __HAL_UNLOCK(hfmpi2c); 04537 04538 return HAL_TIMEOUT; 04539 } 04540 } 04541 } 04542 return HAL_OK; 04543 } 04544 04545 /** 04546 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag. 04547 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04548 * the configuration information for the specified FMPI2C. 04549 * @param Timeout Timeout duration 04550 * @param Tickstart Tick start value 04551 * @retval HAL status 04552 */ 04553 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) 04554 { 04555 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) 04556 { 04557 /* Check if a NACK is detected */ 04558 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 04559 { 04560 return HAL_ERROR; 04561 } 04562 04563 /* Check for the Timeout */ 04564 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 04565 { 04566 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 04567 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04568 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04569 04570 /* Process Unlocked */ 04571 __HAL_UNLOCK(hfmpi2c); 04572 04573 return HAL_TIMEOUT; 04574 } 04575 } 04576 return HAL_OK; 04577 } 04578 04579 /** 04580 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag. 04581 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04582 * the configuration information for the specified FMPI2C. 04583 * @param Timeout Timeout duration 04584 * @param Tickstart Tick start value 04585 * @retval HAL status 04586 */ 04587 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) 04588 { 04589 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET) 04590 { 04591 /* Check if a NACK is detected */ 04592 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK) 04593 { 04594 return HAL_ERROR; 04595 } 04596 04597 /* Check if a STOPF is detected */ 04598 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) 04599 { 04600 /* Check if an RXNE is pending */ 04601 /* Store Last receive data if any */ 04602 if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U)) 04603 { 04604 /* Return HAL_OK */ 04605 /* The Reading of data from RXDR will be done in caller function */ 04606 return HAL_OK; 04607 } 04608 else 04609 { 04610 /* Clear STOP Flag */ 04611 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 04612 04613 /* Clear Configuration Register 2 */ 04614 FMPI2C_RESET_CR2(hfmpi2c); 04615 04616 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; 04617 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04618 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04619 04620 /* Process Unlocked */ 04621 __HAL_UNLOCK(hfmpi2c); 04622 04623 return HAL_ERROR; 04624 } 04625 } 04626 04627 /* Check for the Timeout */ 04628 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 04629 { 04630 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; 04631 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04632 04633 /* Process Unlocked */ 04634 __HAL_UNLOCK(hfmpi2c); 04635 04636 return HAL_TIMEOUT; 04637 } 04638 } 04639 return HAL_OK; 04640 } 04641 04642 /** 04643 * @brief This function handles Acknowledge failed detection during an FMPI2C Communication. 04644 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04645 * the configuration information for the specified FMPI2C. 04646 * @param Timeout Timeout duration 04647 * @param Tickstart Tick start value 04648 * @retval HAL status 04649 */ 04650 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart) 04651 { 04652 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) 04653 { 04654 /* Wait until STOP Flag is reset */ 04655 /* AutoEnd should be initiate after AF */ 04656 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) 04657 { 04658 /* Check for the Timeout */ 04659 if (Timeout != HAL_MAX_DELAY) 04660 { 04661 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout)) 04662 { 04663 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04664 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04665 04666 /* Process Unlocked */ 04667 __HAL_UNLOCK(hfmpi2c); 04668 return HAL_TIMEOUT; 04669 } 04670 } 04671 } 04672 04673 /* Clear NACKF Flag */ 04674 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); 04675 04676 /* Clear STOP Flag */ 04677 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); 04678 04679 /* Flush TX register */ 04680 FMPI2C_Flush_TXDR(hfmpi2c); 04681 04682 /* Clear Configuration Register 2 */ 04683 FMPI2C_RESET_CR2(hfmpi2c); 04684 04685 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF; 04686 hfmpi2c->State = HAL_FMPI2C_STATE_READY; 04687 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE; 04688 04689 /* Process Unlocked */ 04690 __HAL_UNLOCK(hfmpi2c); 04691 04692 return HAL_ERROR; 04693 } 04694 return HAL_OK; 04695 } 04696 04697 /** 04698 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set). 04699 * @param hfmpi2c FMPI2C handle. 04700 * @param DevAddress Specifies the slave address to be programmed. 04701 * @param Size Specifies the number of bytes to be programmed. 04702 * This parameter must be a value between 0 and 255. 04703 * @param Mode New state of the FMPI2C START condition generation. 04704 * This parameter can be one of the following values: 04705 * @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode . 04706 * @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode. 04707 * @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode. 04708 * @param Request New state of the FMPI2C START condition generation. 04709 * This parameter can be one of the following values: 04710 * @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition. 04711 * @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0). 04712 * @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request. 04713 * @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request. 04714 * @retval None 04715 */ 04716 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) 04717 { 04718 /* Check the parameters */ 04719 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); 04720 assert_param(IS_TRANSFER_MODE(Mode)); 04721 assert_param(IS_TRANSFER_REQUEST(Request)); 04722 04723 /* update CR2 register */ 04724 MODIFY_REG(hfmpi2c->Instance->CR2, ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | FMPI2C_CR2_START | FMPI2C_CR2_STOP)), \ 04725 (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); 04726 } 04727 04728 /** 04729 * @brief Manage the enabling of Interrupts. 04730 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04731 * the configuration information for the specified FMPI2C. 04732 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. 04733 * @retval HAL status 04734 */ 04735 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) 04736 { 04737 uint32_t tmpisr = 0U; 04738 04739 if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \ 04740 (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA)) 04741 { 04742 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 04743 { 04744 /* Enable ERR, STOP, NACK and ADDR interrupts */ 04745 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 04746 } 04747 04748 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT) 04749 { 04750 /* Enable ERR and NACK interrupts */ 04751 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; 04752 } 04753 04754 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) 04755 { 04756 /* Enable STOP interrupts */ 04757 tmpisr |= FMPI2C_IT_STOPI; 04758 } 04759 04760 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT) 04761 { 04762 /* Enable TC interrupts */ 04763 tmpisr |= FMPI2C_IT_TCI; 04764 } 04765 } 04766 else 04767 { 04768 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 04769 { 04770 /* Enable ERR, STOP, NACK, and ADDR interrupts */ 04771 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 04772 } 04773 04774 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) 04775 { 04776 /* Enable ERR, TC, STOP, NACK and RXI interrupts */ 04777 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI; 04778 } 04779 04780 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) 04781 { 04782 /* Enable ERR, TC, STOP, NACK and TXI interrupts */ 04783 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI; 04784 } 04785 04786 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) 04787 { 04788 /* Enable STOP interrupts */ 04789 tmpisr |= FMPI2C_IT_STOPI; 04790 } 04791 } 04792 04793 /* Enable interrupts only at the end */ 04794 /* to avoid the risk of FMPI2C interrupt handle execution before */ 04795 /* all interrupts requested done */ 04796 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr); 04797 04798 return HAL_OK; 04799 } 04800 04801 /** 04802 * @brief Manage the disabling of Interrupts. 04803 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains 04804 * the configuration information for the specified FMPI2C. 04805 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition. 04806 * @retval HAL status 04807 */ 04808 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest) 04809 { 04810 uint32_t tmpisr = 0U; 04811 04812 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT) 04813 { 04814 /* Disable TC and TXI interrupts */ 04815 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI; 04816 04817 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN) 04818 { 04819 /* Disable NACK and STOP interrupts */ 04820 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 04821 } 04822 } 04823 04824 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT) 04825 { 04826 /* Disable TC and RXI interrupts */ 04827 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI; 04828 04829 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN) 04830 { 04831 /* Disable NACK and STOP interrupts */ 04832 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 04833 } 04834 } 04835 04836 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT) 04837 { 04838 /* Disable ADDR, NACK and STOP interrupts */ 04839 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI; 04840 } 04841 04842 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT) 04843 { 04844 /* Enable ERR and NACK interrupts */ 04845 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI; 04846 } 04847 04848 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT) 04849 { 04850 /* Enable STOP interrupts */ 04851 tmpisr |= FMPI2C_IT_STOPI; 04852 } 04853 04854 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT) 04855 { 04856 /* Enable TC interrupts */ 04857 tmpisr |= FMPI2C_IT_TCI; 04858 } 04859 04860 /* Disable interrupts only at the end */ 04861 /* to avoid a breaking situation like at "t" time */ 04862 /* all disable interrupts request are not done */ 04863 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr); 04864 04865 return HAL_OK; 04866 } 04867 04868 /** 04869 * @} 04870 */ 04871 #endif /* STM32F410xx || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ 04872 #endif /* HAL_FMPI2C_MODULE_ENABLED */ 04873 /** 04874 * @} 04875 */ 04876 04877 /** 04878 * @} 04879 */ 04880 04881 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/