comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c @ 160:e3ca52b8e7fa

Merge with FlipDisplay
author heinrichsweikamp
date Thu, 07 Mar 2019 15:06:43 +0100
parents c78bcbd5deda
children
comparison
equal deleted inserted replaced
80:cc2bb7bb8456 160:e3ca52b8e7fa
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_fmpi2c.c
4 * @author MCD Application Team
5 * @brief FMPI2C HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral State and Errors functions
11 *
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 The FMPI2C HAL driver can be used as follows:
18
19 (#) Declare a FMPI2C_HandleTypeDef handle structure, for example:
20 FMPI2C_HandleTypeDef hfmpi2c;
21
22 (#)Initialize the FMPI2C low level resources by implementing the HAL_FMPI2C_MspInit() API:
23 (##) Enable the FMPI2Cx interface clock
24 (##) FMPI2C pins configuration
25 (+++) Enable the clock for the FMPI2C GPIOs
26 (+++) Configure FMPI2C pins as alternate function open-drain
27 (##) NVIC configuration if you need to use interrupt process
28 (+++) Configure the FMPI2Cx interrupt priority
29 (+++) Enable the NVIC FMPI2C IRQ Channel
30 (##) DMA Configuration if you need to use DMA process
31 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream
32 (+++) Enable the DMAx interface clock using
33 (+++) Configure the DMA handle parameters
34 (+++) Configure the DMA Tx or Rx stream
35 (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle
36 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
37 the DMA Tx or Rx stream
38
39 (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
40 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure.
41
42 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware
43 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API.
44
45 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady()
46
47 (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver :
48
49 *** Polling mode IO operation ***
50 =================================
51 [..]
52 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit()
53 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive()
54 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit()
55 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive()
56
57 *** Polling mode IO MEM operation ***
58 =====================================
59 [..]
60 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write()
61 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read()
62
63
64 *** Interrupt mode IO operation ***
65 ===================================
66 [..]
67 (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT()
68 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
69 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
70 (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT()
71 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
72 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
73 (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT()
74 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
75 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
76 (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT()
77 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
78 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
79 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
80 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
81 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
82 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
83 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
84 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
85 This action will inform Master to generate a Stop condition to discard the communication.
86
87
88 *** Interrupt mode IO sequential operation ***
89 ==============================================
90 [..]
91 (@) These interfaces allow to manage a sequential transfer with a repeated start condition
92 when a direction change during transfer
93 [..]
94 (+) A specific option field manage the different steps of a sequential transfer
95 (+) Option field values are defined through @ref FMPI2C_XFEROPTIONS and are listed below:
96 (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode
97 (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
98 and data to transfer without a final stop condition
99 (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address
100 and data to transfer without a final stop condition, an then permit a call the same master sequential interface
101 several times (like HAL_FMPI2C_Master_Sequential_Transmit_IT() then HAL_FMPI2C_Master_Sequential_Transmit_IT())
102 (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
103 and with new data to transfer if the direction change or manage only the new data to transfer
104 if no direction change and without a final stop condition in both cases
105 (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
106 and with new data to transfer if the direction change or manage only the new data to transfer
107 if no direction change and with a final stop condition in both cases
108 (++) 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
109 interface several times (link with option FMPI2C_FIRST_AND_NEXT_FRAME).
110 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)
111 or HAL_FMPI2C_Master_Sequential_Receive_IT(option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME).
112 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
113 without stopping the communication and so generate a restart condition.
114
115 (+) Differents sequential FMPI2C interfaces are listed below:
116 (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Transmit_IT()
117 (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
118 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
119 (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Sequential_Receive_IT()
120 (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
121 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
122 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
123 (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
124 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
125 (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT() HAL_FMPI2C_DisableListen_IT()
126 (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and user can
127 add his own code to check the Address Match Code and the transmission direction request by master (Write/Read).
128 (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and user can
129 add his own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback()
130 (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Transmit_IT()
131 (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
132 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
133 (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Sequential_Receive_IT()
134 (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
135 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
136 (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
137 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
138 (++) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
139 (++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
140 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
141 (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
142 This action will inform Master to generate a Stop condition to discard the communication.
143
144 *** Interrupt mode IO MEM operation ***
145 =======================================
146 [..]
147 (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
148 HAL_FMPI2C_Mem_Write_IT()
149 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
150 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
151 (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
152 HAL_FMPI2C_Mem_Read_IT()
153 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
154 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
155 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
156 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
157
158 *** DMA mode IO operation ***
159 ==============================
160 [..]
161 (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
162 HAL_FMPI2C_Master_Transmit_DMA()
163 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and user can
164 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
165 (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
166 HAL_FMPI2C_Master_Receive_DMA()
167 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and user can
168 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
169 (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
170 HAL_FMPI2C_Slave_Transmit_DMA()
171 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and user can
172 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
173 (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
174 HAL_FMPI2C_Slave_Receive_DMA()
175 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and user can
176 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
177 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
178 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
179 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
180 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and user can
181 add his own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
182 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
183 This action will inform Master to generate a Stop condition to discard the communication.
184
185 *** DMA mode IO MEM operation ***
186 =================================
187 [..]
188 (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
189 HAL_FMPI2C_Mem_Write_DMA()
190 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and user can
191 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
192 (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
193 HAL_FMPI2C_Mem_Read_DMA()
194 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and user can
195 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
196 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
197 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
198
199
200 *** FMPI2C HAL driver macros list ***
201 ==================================
202 [..]
203 Below the list of most used macros in FMPI2C HAL driver.
204
205 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral
206 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral
207 (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode
208 (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not
209 (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag
210 (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt
211 (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt
212
213 [..]
214 (@) You can refer to the FMPI2C HAL driver header file for more useful macros
215
216 @endverbatim
217 ******************************************************************************
218 * @attention
219 *
220 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
221 *
222 * Redistribution and use in source and binary forms, with or without modification,
223 * are permitted provided that the following conditions are met:
224 * 1. Redistributions of source code must retain the above copyright notice,
225 * this list of conditions and the following disclaimer.
226 * 2. Redistributions in binary form must reproduce the above copyright notice,
227 * this list of conditions and the following disclaimer in the documentation
228 * and/or other materials provided with the distribution.
229 * 3. Neither the name of STMicroelectronics nor the names of its contributors
230 * may be used to endorse or promote products derived from this software
231 * without specific prior written permission.
232 *
233 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
234 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
236 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
237 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
238 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
239 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
240 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
242 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
243 *
244 ******************************************************************************
245 */
246
247 /* Includes ------------------------------------------------------------------*/
248 #include "stm32f4xx_hal.h"
249
250 /** @addtogroup STM32F4xx_HAL_Driver
251 * @{
252 */
253
254 /** @defgroup FMPI2C FMPI2C
255 * @brief FMPI2C HAL module driver
256 * @{
257 */
258
259 #ifdef HAL_FMPI2C_MODULE_ENABLED
260
261 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F412Zx) ||\
262 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
263
264 /* Private typedef -----------------------------------------------------------*/
265 /* Private define ------------------------------------------------------------*/
266
267 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define
268 * @{
269 */
270 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< FMPI2C TIMING clear register Mask */
271 #define FMPI2C_TIMEOUT_ADDR (10000U) /*!< 10 s */
272 #define FMPI2C_TIMEOUT_BUSY (25U) /*!< 25 ms */
273 #define FMPI2C_TIMEOUT_DIR (25U) /*!< 25 ms */
274 #define FMPI2C_TIMEOUT_RXNE (25U) /*!< 25 ms */
275 #define FMPI2C_TIMEOUT_STOPF (25U) /*!< 25 ms */
276 #define FMPI2C_TIMEOUT_TC (25U) /*!< 25 ms */
277 #define FMPI2C_TIMEOUT_TCR (25U) /*!< 25 ms */
278 #define FMPI2C_TIMEOUT_TXIS (25U) /*!< 25 ms */
279 #define FMPI2C_TIMEOUT_FLAG (25U) /*!< 25 ms */
280
281 #define MAX_NBYTE_SIZE 255U
282 #define SlaveAddr_SHIFT 7U
283 #define SlaveAddr_MSK 0x06U
284
285 /* Private define for @ref PreviousState usage */
286 #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 */
287 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE)) /*!< Default Value */
288 #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 */
289 #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 */
290 #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 */
291 #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 */
292 #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 */
293 #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 */
294
295
296 /* Private define to centralize the enable/disable of Interrupts */
297 #define FMPI2C_XFER_TX_IT (0x00000001U)
298 #define FMPI2C_XFER_RX_IT (0x00000002U)
299 #define FMPI2C_XFER_LISTEN_IT (0x00000004U)
300
301 #define FMPI2C_XFER_ERROR_IT (0x00000011U)
302 #define FMPI2C_XFER_CPLT_IT (0x00000012U)
303 #define FMPI2C_XFER_RELOAD_IT (0x00000012U)
304
305 /* Private define Sequential Transfer Options default/reset value */
306 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U)
307 /**
308 * @}
309 */
310
311 /* Private macro -------------------------------------------------------------*/
312 #define FMPI2C_GET_DMA_REMAIN_DATA(__HANDLE__) ((((__HANDLE__)->State) == HAL_FMPI2C_STATE_BUSY_TX) ? \
313 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmatx->Instance)->NDTR)) : \
314 ((uint32_t)(((DMA_Stream_TypeDef *)(__HANDLE__)->hdmarx->Instance)->NDTR)))
315
316 /* Private variables ---------------------------------------------------------*/
317 /* Private function prototypes -----------------------------------------------*/
318
319 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions
320 * @{
321 */
322 /* Private functions to handle DMA transfer */
323 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
324 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
325 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
326 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
327 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
328 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma);
329
330 /* Private functions to handle IT transfer */
331 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
332 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c);
333 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c);
334 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
335 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
336 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
337 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode);
338
339 /* Private functions to handle IT transfer */
340 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
341 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart);
342
343 /* Private functions for FMPI2C transfer IRQ handler */
344 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
345 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
346 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
347 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources);
348
349 /* Private functions to handle flags during polling transfer */
350 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart);
351 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
352 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
353 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
354 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart);
355
356 /* Private functions to centralize the enable/disable of Interrupts */
357 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
358 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
359
360 /* Private functions to flush TXDR register */
361 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c);
362
363 /* Private functions to handle start, restart or stop a transfer */
364 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
365 /**
366 * @}
367 */
368
369 /* Exported functions --------------------------------------------------------*/
370
371 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions
372 * @{
373 */
374
375 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions
376 * @brief Initialization and Configuration functions
377 *
378 @verbatim
379 ===============================================================================
380 ##### Initialization and de-initialization functions #####
381 ===============================================================================
382 [..] This subsection provides a set of functions allowing to initialize and
383 deinitialize the FMPI2Cx peripheral:
384
385 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures
386 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
387
388 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with
389 the selected configuration:
390 (++) Clock Timing
391 (++) Own Address 1
392 (++) Addressing mode (Master, Slave)
393 (++) Dual Addressing mode
394 (++) Own Address 2
395 (++) Own Address 2 Mask
396 (++) General call mode
397 (++) Nostretch mode
398
399 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration
400 of the selected FMPI2Cx peripheral.
401
402 @endverbatim
403 * @{
404 */
405
406 /**
407 * @brief Initializes the FMPI2C according to the specified parameters
408 * in the FMPI2C_InitTypeDef and initialize the associated handle.
409 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
410 * the configuration information for the specified FMPI2C.
411 * @retval HAL status
412 */
413 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
414 {
415 /* Check the FMPI2C handle allocation */
416 if (hfmpi2c == NULL)
417 {
418 return HAL_ERROR;
419 }
420
421 /* Check the parameters */
422 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
423 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
424 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
425 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
426 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
427 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
428 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
429 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
430
431 if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
432 {
433 /* Allocate lock resource and initialize it */
434 hfmpi2c->Lock = HAL_UNLOCKED;
435
436 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
437 HAL_FMPI2C_MspInit(hfmpi2c);
438 }
439
440 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
441
442 /* Disable the selected FMPI2C peripheral */
443 __HAL_FMPI2C_DISABLE(hfmpi2c);
444
445 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
446 /* Configure FMPI2Cx: Frequency range */
447 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
448
449 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
450 /* Disable Own Address1 before set the Own Address1 configuration */
451 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
452
453 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
454 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
455 {
456 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
457 }
458 else /* FMPI2C_ADDRESSINGMODE_10BIT */
459 {
460 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
461 }
462
463 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
464 /* Configure FMPI2Cx: Addressing Master mode */
465 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
466 {
467 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10);
468 }
469 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
470 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
471
472 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
473 /* Disable Own Address2 before set the Own Address2 configuration */
474 hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE;
475
476 /* Configure FMPI2Cx: Dual mode and Own Address2 */
477 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8));
478
479 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
480 /* Configure FMPI2Cx: Generalcall and NoStretch mode */
481 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
482
483 /* Enable the selected FMPI2C peripheral */
484 __HAL_FMPI2C_ENABLE(hfmpi2c);
485
486 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
487 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
488 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
489 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
490
491 return HAL_OK;
492 }
493
494 /**
495 * @brief DeInitialize the FMPI2C peripheral.
496 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
497 * the configuration information for the specified FMPI2C.
498 * @retval HAL status
499 */
500 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
501 {
502 /* Check the FMPI2C handle allocation */
503 if (hfmpi2c == NULL)
504 {
505 return HAL_ERROR;
506 }
507
508 /* Check the parameters */
509 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
510
511 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
512
513 /* Disable the FMPI2C Peripheral Clock */
514 __HAL_FMPI2C_DISABLE(hfmpi2c);
515
516 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
517 HAL_FMPI2C_MspDeInit(hfmpi2c);
518
519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
520 hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
521 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
522 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
523
524 /* Release Lock */
525 __HAL_UNLOCK(hfmpi2c);
526
527 return HAL_OK;
528 }
529
530 /**
531 * @brief Initialize the FMPI2C MSP.
532 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
533 * the configuration information for the specified FMPI2C.
534 * @retval None
535 */
536 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
537 {
538 /* Prevent unused argument(s) compilation warning */
539 UNUSED(hfmpi2c);
540
541 /* NOTE : This function should not be modified, when the callback is needed,
542 the HAL_FMPI2C_MspInit could be implemented in the user file
543 */
544 }
545
546 /**
547 * @brief DeInitialize the FMPI2C MSP.
548 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
549 * the configuration information for the specified FMPI2C.
550 * @retval None
551 */
552 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
553 {
554 /* Prevent unused argument(s) compilation warning */
555 UNUSED(hfmpi2c);
556
557 /* NOTE : This function should not be modified, when the callback is needed,
558 the HAL_FMPI2C_MspDeInit could be implemented in the user file
559 */
560 }
561
562 /**
563 * @}
564 */
565
566 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions
567 * @brief Data transfers functions
568 *
569 @verbatim
570 ===============================================================================
571 ##### IO operation functions #####
572 ===============================================================================
573 [..]
574 This subsection provides a set of functions allowing to manage the FMPI2C data
575 transfers.
576
577 (#) There are two modes of transfer:
578 (++) Blocking mode : The communication is performed in the polling mode.
579 The status of all data processing is returned by the same function
580 after finishing transfer.
581 (++) No-Blocking mode : The communication is performed using Interrupts
582 or DMA. These functions return the status of the transfer startup.
583 The end of the data processing will be indicated through the
584 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when
585 using DMA mode.
586
587 (#) Blocking mode functions are :
588 (++) HAL_FMPI2C_Master_Transmit()
589 (++) HAL_FMPI2C_Master_Receive()
590 (++) HAL_FMPI2C_Slave_Transmit()
591 (++) HAL_FMPI2C_Slave_Receive()
592 (++) HAL_FMPI2C_Mem_Write()
593 (++) HAL_FMPI2C_Mem_Read()
594 (++) HAL_FMPI2C_IsDeviceReady()
595
596 (#) No-Blocking mode functions with Interrupt are :
597 (++) HAL_FMPI2C_Master_Transmit_IT()
598 (++) HAL_FMPI2C_Master_Receive_IT()
599 (++) HAL_FMPI2C_Slave_Transmit_IT()
600 (++) HAL_FMPI2C_Slave_Receive_IT()
601 (++) HAL_FMPI2C_Master_Sequential_Transmit_IT()
602 (++) HAL_FMPI2C_Master_Sequential_Receive_IT()
603 (++) HAL_FMPI2C_Slave_Sequential_Transmit_IT()
604 (++) HAL_FMPI2C_Slave_Sequential_Receive_IT()
605 (++) HAL_FMPI2C_Mem_Write_IT()
606 (++) HAL_FMPI2C_Mem_Read_IT()
607
608 (#) No-Blocking mode functions with DMA are :
609 (++) HAL_FMPI2C_Master_Transmit_DMA()
610 (++) HAL_FMPI2C_Master_Receive_DMA()
611 (++) HAL_FMPI2C_Slave_Transmit_DMA()
612 (++) HAL_FMPI2C_Slave_Receive_DMA()
613 (++) HAL_FMPI2C_Mem_Write_DMA()
614 (++) HAL_FMPI2C_Mem_Read_DMA()
615
616 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
617 (++) HAL_FMPI2C_MemTxCpltCallback()
618 (++) HAL_FMPI2C_MemRxCpltCallback()
619 (++) HAL_FMPI2C_MasterTxCpltCallback()
620 (++) HAL_FMPI2C_MasterRxCpltCallback()
621 (++) HAL_FMPI2C_SlaveTxCpltCallback()
622 (++) HAL_FMPI2C_SlaveRxCpltCallback()
623 (++) HAL_FMPI2C_ErrorCallback()
624
625 @endverbatim
626 * @{
627 */
628
629 /**
630 * @brief Transmits in master mode an amount of data in blocking mode.
631 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
632 * the configuration information for the specified FMPI2C.
633 * @param DevAddress Target device address The device 7 bits address value
634 * in datasheet must be shifted to the left before calling the interface
635 * @param pData Pointer to data buffer
636 * @param Size Amount of data to be sent
637 * @param Timeout Timeout duration
638 * @retval HAL status
639 */
640 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
641 {
642 uint32_t tickstart = 0U;
643
644 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
645 {
646 /* Process Locked */
647 __HAL_LOCK(hfmpi2c);
648
649 /* Init tickstart for timeout management*/
650 tickstart = HAL_GetTick();
651
652 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
653 {
654 return HAL_TIMEOUT;
655 }
656
657 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
658 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
659 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
660
661 /* Prepare transfer parameters */
662 hfmpi2c->pBuffPtr = pData;
663 hfmpi2c->XferCount = Size;
664 hfmpi2c->XferISR = NULL;
665
666 /* Send Slave Address */
667 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
668 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
669 {
670 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
671 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
672 }
673 else
674 {
675 hfmpi2c->XferSize = hfmpi2c->XferCount;
676 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
677 }
678
679 while (hfmpi2c->XferCount > 0U)
680 {
681 /* Wait until TXIS flag is set */
682 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
683 {
684 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
685 {
686 return HAL_ERROR;
687 }
688 else
689 {
690 return HAL_TIMEOUT;
691 }
692 }
693 /* Write data to TXDR */
694 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
695 hfmpi2c->XferCount--;
696 hfmpi2c->XferSize--;
697
698 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
699 {
700 /* Wait until TCR flag is set */
701 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
702 {
703 return HAL_TIMEOUT;
704 }
705
706 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
707 {
708 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
709 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
710 }
711 else
712 {
713 hfmpi2c->XferSize = hfmpi2c->XferCount;
714 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
715 }
716 }
717 }
718
719 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
720 /* Wait until STOPF flag is set */
721 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
722 {
723 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
724 {
725 return HAL_ERROR;
726 }
727 else
728 {
729 return HAL_TIMEOUT;
730 }
731 }
732
733 /* Clear STOP Flag */
734 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
735
736 /* Clear Configuration Register 2 */
737 FMPI2C_RESET_CR2(hfmpi2c);
738
739 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
740 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
741
742 /* Process Unlocked */
743 __HAL_UNLOCK(hfmpi2c);
744
745 return HAL_OK;
746 }
747 else
748 {
749 return HAL_BUSY;
750 }
751 }
752
753 /**
754 * @brief Receives in master mode an amount of data in blocking mode.
755 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
756 * the configuration information for the specified FMPI2C.
757 * @param DevAddress Target device address The device 7 bits address value
758 * in datasheet must be shifted to the left before calling the interface
759 * @param pData Pointer to data buffer
760 * @param Size Amount of data to be sent
761 * @param Timeout Timeout duration
762 * @retval HAL status
763 */
764 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
765 {
766 uint32_t tickstart = 0U;
767
768 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
769 {
770 /* Process Locked */
771 __HAL_LOCK(hfmpi2c);
772
773 /* Init tickstart for timeout management*/
774 tickstart = HAL_GetTick();
775
776 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
777 {
778 return HAL_TIMEOUT;
779 }
780
781 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
782 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
783 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
784
785 /* Prepare transfer parameters */
786 hfmpi2c->pBuffPtr = pData;
787 hfmpi2c->XferCount = Size;
788 hfmpi2c->XferISR = NULL;
789
790 /* Send Slave Address */
791 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
792 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
793 {
794 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
795 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
796 }
797 else
798 {
799 hfmpi2c->XferSize = hfmpi2c->XferCount;
800 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
801 }
802
803 while (hfmpi2c->XferCount > 0U)
804 {
805 /* Wait until RXNE flag is set */
806 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
807 {
808 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
809 {
810 return HAL_ERROR;
811 }
812 else
813 {
814 return HAL_TIMEOUT;
815 }
816 }
817
818 /* Read data from RXDR */
819 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
820 hfmpi2c->XferSize--;
821 hfmpi2c->XferCount--;
822
823 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
824 {
825 /* Wait until TCR flag is set */
826 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
827 {
828 return HAL_TIMEOUT;
829 }
830
831 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
832 {
833 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
834 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
835 }
836 else
837 {
838 hfmpi2c->XferSize = hfmpi2c->XferCount;
839 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
840 }
841 }
842 }
843
844 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
845 /* Wait until STOPF flag is set */
846 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
847 {
848 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
849 {
850 return HAL_ERROR;
851 }
852 else
853 {
854 return HAL_TIMEOUT;
855 }
856 }
857
858 /* Clear STOP Flag */
859 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
860
861 /* Clear Configuration Register 2 */
862 FMPI2C_RESET_CR2(hfmpi2c);
863
864 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
865 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
866
867 /* Process Unlocked */
868 __HAL_UNLOCK(hfmpi2c);
869
870 return HAL_OK;
871 }
872 else
873 {
874 return HAL_BUSY;
875 }
876 }
877
878 /**
879 * @brief Transmits in slave mode an amount of data in blocking mode.
880 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
881 * the configuration information for the specified FMPI2C.
882 * @param pData Pointer to data buffer
883 * @param Size Amount of data to be sent
884 * @param Timeout Timeout duration
885 * @retval HAL status
886 */
887 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
888 {
889 uint32_t tickstart = 0U;
890
891 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
892 {
893 if ((pData == NULL) || (Size == 0U))
894 {
895 return HAL_ERROR;
896 }
897 /* Process Locked */
898 __HAL_LOCK(hfmpi2c);
899
900 /* Init tickstart for timeout management*/
901 tickstart = HAL_GetTick();
902
903 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
904 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
905 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
906
907 /* Prepare transfer parameters */
908 hfmpi2c->pBuffPtr = pData;
909 hfmpi2c->XferCount = Size;
910 hfmpi2c->XferISR = NULL;
911
912 /* Enable Address Acknowledge */
913 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
914
915 /* Wait until ADDR flag is set */
916 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
917 {
918 /* Disable Address Acknowledge */
919 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
920 return HAL_TIMEOUT;
921 }
922
923 /* Clear ADDR flag */
924 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
925
926 /* If 10bit addressing mode is selected */
927 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
928 {
929 /* Wait until ADDR flag is set */
930 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
931 {
932 /* Disable Address Acknowledge */
933 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
934 return HAL_TIMEOUT;
935 }
936
937 /* Clear ADDR flag */
938 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
939 }
940
941 /* Wait until DIR flag is set Transmitter mode */
942 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
943 {
944 /* Disable Address Acknowledge */
945 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
946 return HAL_TIMEOUT;
947 }
948
949 while (hfmpi2c->XferCount > 0U)
950 {
951 /* Wait until TXIS flag is set */
952 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
953 {
954 /* Disable Address Acknowledge */
955 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
956
957 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
958 {
959 return HAL_ERROR;
960 }
961 else
962 {
963 return HAL_TIMEOUT;
964 }
965 }
966
967 /* Write data to TXDR */
968 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
969 hfmpi2c->XferCount--;
970 }
971
972 /* Wait until STOP flag is set */
973 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
974 {
975 /* Disable Address Acknowledge */
976 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
977
978 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
979 {
980 /* Normal use case for Transmitter mode */
981 /* A NACK is generated to confirm the end of transfer */
982 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
983 }
984 else
985 {
986 return HAL_TIMEOUT;
987 }
988 }
989
990 /* Clear STOP flag */
991 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
992
993 /* Wait until BUSY flag is reset */
994 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
995 {
996 /* Disable Address Acknowledge */
997 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
998 return HAL_TIMEOUT;
999 }
1000
1001 /* Disable Address Acknowledge */
1002 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1003
1004 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1005 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1006
1007 /* Process Unlocked */
1008 __HAL_UNLOCK(hfmpi2c);
1009
1010 return HAL_OK;
1011 }
1012 else
1013 {
1014 return HAL_BUSY;
1015 }
1016 }
1017
1018 /**
1019 * @brief Receive in slave mode an amount of data in blocking mode
1020 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1021 * the configuration information for the specified FMPI2C.
1022 * @param pData Pointer to data buffer
1023 * @param Size Amount of data to be sent
1024 * @param Timeout Timeout duration
1025 * @retval HAL status
1026 */
1027 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1028 {
1029 uint32_t tickstart = 0U;
1030
1031 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1032 {
1033 if ((pData == NULL) || (Size == 0U))
1034 {
1035 return HAL_ERROR;
1036 }
1037 /* Process Locked */
1038 __HAL_LOCK(hfmpi2c);
1039
1040 /* Init tickstart for timeout management*/
1041 tickstart = HAL_GetTick();
1042
1043 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1044 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1045 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1046
1047 /* Prepare transfer parameters */
1048 hfmpi2c->pBuffPtr = pData;
1049 hfmpi2c->XferCount = Size;
1050 hfmpi2c->XferISR = NULL;
1051
1052 /* Enable Address Acknowledge */
1053 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1054
1055 /* Wait until ADDR flag is set */
1056 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1057 {
1058 /* Disable Address Acknowledge */
1059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1060 return HAL_TIMEOUT;
1061 }
1062
1063 /* Clear ADDR flag */
1064 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1065
1066 /* Wait until DIR flag is reset Receiver mode */
1067 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1068 {
1069 /* Disable Address Acknowledge */
1070 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1071 return HAL_TIMEOUT;
1072 }
1073
1074 while (hfmpi2c->XferCount > 0U)
1075 {
1076 /* Wait until RXNE flag is set */
1077 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1078 {
1079 /* Disable Address Acknowledge */
1080 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1081
1082 /* Store Last receive data if any */
1083 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
1084 {
1085 /* Read data from RXDR */
1086 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
1087 hfmpi2c->XferCount--;
1088 }
1089
1090 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT)
1091 {
1092 return HAL_TIMEOUT;
1093 }
1094 else
1095 {
1096 return HAL_ERROR;
1097 }
1098 }
1099
1100 /* Read data from RXDR */
1101 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
1102 hfmpi2c->XferCount--;
1103 }
1104
1105 /* Wait until STOP flag is set */
1106 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1107 {
1108 /* Disable Address Acknowledge */
1109 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1110
1111 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1112 {
1113 return HAL_ERROR;
1114 }
1115 else
1116 {
1117 return HAL_TIMEOUT;
1118 }
1119 }
1120
1121 /* Clear STOP flag */
1122 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1123
1124 /* Wait until BUSY flag is reset */
1125 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1126 {
1127 /* Disable Address Acknowledge */
1128 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1129 return HAL_TIMEOUT;
1130 }
1131
1132 /* Disable Address Acknowledge */
1133 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1134
1135 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1136 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1137
1138 /* Process Unlocked */
1139 __HAL_UNLOCK(hfmpi2c);
1140
1141 return HAL_OK;
1142 }
1143 else
1144 {
1145 return HAL_BUSY;
1146 }
1147 }
1148
1149 /**
1150 * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt
1151 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1152 * the configuration information for the specified FMPI2C.
1153 * @param DevAddress Target device address The device 7 bits address value
1154 * in datasheet must be shifted to the left before calling the interface
1155 * @param pData Pointer to data buffer
1156 * @param Size Amount of data to be sent
1157 * @retval HAL status
1158 */
1159 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1160 {
1161 uint32_t xfermode = 0U;
1162
1163 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1164 {
1165 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1166 {
1167 return HAL_BUSY;
1168 }
1169
1170 /* Process Locked */
1171 __HAL_LOCK(hfmpi2c);
1172
1173 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1174 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1175 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1176
1177 /* Prepare transfer parameters */
1178 hfmpi2c->pBuffPtr = pData;
1179 hfmpi2c->XferCount = Size;
1180 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1181 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1182
1183 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1184 {
1185 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1186 xfermode = FMPI2C_RELOAD_MODE;
1187 }
1188 else
1189 {
1190 hfmpi2c->XferSize = hfmpi2c->XferCount;
1191 xfermode = FMPI2C_AUTOEND_MODE;
1192 }
1193
1194 /* Send Slave Address */
1195 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1196 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
1197
1198 /* Process Unlocked */
1199 __HAL_UNLOCK(hfmpi2c);
1200
1201 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1202 to avoid the risk of FMPI2C interrupt handle execution before current
1203 process unlock */
1204
1205 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1206 /* possible to enable all of these */
1207 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1208 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1209
1210 return HAL_OK;
1211 }
1212 else
1213 {
1214 return HAL_BUSY;
1215 }
1216 }
1217
1218 /**
1219 * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt
1220 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1221 * the configuration information for the specified FMPI2C.
1222 * @param DevAddress Target device address The device 7 bits address value
1223 * in datasheet must be shifted to the left before calling the interface
1224 * @param pData Pointer to data buffer
1225 * @param Size Amount of data to be sent
1226 * @retval HAL status
1227 */
1228 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1229 {
1230 uint32_t xfermode = 0U;
1231
1232 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1233 {
1234 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1235 {
1236 return HAL_BUSY;
1237 }
1238
1239 /* Process Locked */
1240 __HAL_LOCK(hfmpi2c);
1241
1242 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1243 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1244 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1245
1246 /* Prepare transfer parameters */
1247 hfmpi2c->pBuffPtr = pData;
1248 hfmpi2c->XferCount = Size;
1249 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1250 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1251
1252 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1253 {
1254 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1255 xfermode = FMPI2C_RELOAD_MODE;
1256 }
1257 else
1258 {
1259 hfmpi2c->XferSize = hfmpi2c->XferCount;
1260 xfermode = FMPI2C_AUTOEND_MODE;
1261 }
1262
1263 /* Send Slave Address */
1264 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1265 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
1266
1267 /* Process Unlocked */
1268 __HAL_UNLOCK(hfmpi2c);
1269
1270 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1271 to avoid the risk of FMPI2C interrupt handle execution before current
1272 process unlock */
1273
1274 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1275 /* possible to enable all of these */
1276 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1277 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
1278
1279 return HAL_OK;
1280 }
1281 else
1282 {
1283 return HAL_BUSY;
1284 }
1285 }
1286
1287 /**
1288 * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt
1289 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1290 * the configuration information for the specified FMPI2C.
1291 * @param pData Pointer to data buffer
1292 * @param Size Amount of data to be sent
1293 * @retval HAL status
1294 */
1295 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1296 {
1297 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1298 {
1299 /* Process Locked */
1300 __HAL_LOCK(hfmpi2c);
1301
1302 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1303 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1304 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1305
1306 /* Enable Address Acknowledge */
1307 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1308
1309 /* Prepare transfer parameters */
1310 hfmpi2c->pBuffPtr = pData;
1311 hfmpi2c->XferCount = Size;
1312 hfmpi2c->XferSize = hfmpi2c->XferCount;
1313 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1314 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1315
1316 /* Process Unlocked */
1317 __HAL_UNLOCK(hfmpi2c);
1318
1319 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1320 to avoid the risk of FMPI2C interrupt handle execution before current
1321 process unlock */
1322
1323 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1324 /* possible to enable all of these */
1325 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1326 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
1327
1328 return HAL_OK;
1329 }
1330 else
1331 {
1332 return HAL_BUSY;
1333 }
1334 }
1335
1336 /**
1337 * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt
1338 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1339 * the configuration information for the specified FMPI2C.
1340 * @param pData Pointer to data buffer
1341 * @param Size Amount of data to be sent
1342 * @retval HAL status
1343 */
1344 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1345 {
1346 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1347 {
1348 /* Process Locked */
1349 __HAL_LOCK(hfmpi2c);
1350
1351 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1352 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1353 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1354
1355 /* Enable Address Acknowledge */
1356 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1357
1358 /* Prepare transfer parameters */
1359 hfmpi2c->pBuffPtr = pData;
1360 hfmpi2c->XferCount = Size;
1361 hfmpi2c->XferSize = hfmpi2c->XferCount;
1362 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1363 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1364
1365 /* Process Unlocked */
1366 __HAL_UNLOCK(hfmpi2c);
1367
1368 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1369 to avoid the risk of FMPI2C interrupt handle execution before current
1370 process unlock */
1371
1372 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1373 /* possible to enable all of these */
1374 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1375 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
1376
1377 return HAL_OK;
1378 }
1379 else
1380 {
1381 return HAL_BUSY;
1382 }
1383 }
1384
1385 /**
1386 * @brief Transmit in master mode an amount of data in non-blocking mode with DMA
1387 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1388 * the configuration information for the specified FMPI2C.
1389 * @param DevAddress Target device address The device 7 bits address value
1390 * in datasheet must be shifted to the left before calling the interface
1391 * @param pData Pointer to data buffer
1392 * @param Size Amount of data to be sent
1393 * @retval HAL status
1394 */
1395 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1396 {
1397 uint32_t xfermode = 0U;
1398
1399 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1400 {
1401 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1402 {
1403 return HAL_BUSY;
1404 }
1405
1406 /* Process Locked */
1407 __HAL_LOCK(hfmpi2c);
1408
1409 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1410 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1411 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1412
1413 /* Prepare transfer parameters */
1414 hfmpi2c->pBuffPtr = pData;
1415 hfmpi2c->XferCount = Size;
1416 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1417 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
1418
1419 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1420 {
1421 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1422 xfermode = FMPI2C_RELOAD_MODE;
1423 }
1424 else
1425 {
1426 hfmpi2c->XferSize = hfmpi2c->XferCount;
1427 xfermode = FMPI2C_AUTOEND_MODE;
1428 }
1429
1430 if (hfmpi2c->XferSize > 0U)
1431 {
1432 /* Set the FMPI2C DMA transfer complete callback */
1433 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
1434
1435 /* Set the DMA error callback */
1436 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
1437
1438 /* Set the unused DMA callbacks to NULL */
1439 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
1440 hfmpi2c->hdmatx->XferAbortCallback = NULL;
1441
1442 /* Enable the DMA stream */
1443 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
1444
1445 /* Send Slave Address */
1446 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1447 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
1448
1449 /* Update XferCount value */
1450 hfmpi2c->XferCount -= hfmpi2c->XferSize;
1451
1452 /* Process Unlocked */
1453 __HAL_UNLOCK(hfmpi2c);
1454
1455 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1456 to avoid the risk of FMPI2C interrupt handle execution before current
1457 process unlock */
1458 /* Enable ERR and NACK interrupts */
1459 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
1460
1461 /* Enable DMA Request */
1462 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
1463 }
1464 else
1465 {
1466 /* Update Transfer ISR function pointer */
1467 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1468
1469 /* Send Slave Address */
1470 /* Set NBYTES to write and generate START condition */
1471 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
1472
1473 /* Process Unlocked */
1474 __HAL_UNLOCK(hfmpi2c);
1475
1476 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1477 to avoid the risk of FMPI2C interrupt handle execution before current
1478 process unlock */
1479 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1480 /* possible to enable all of these */
1481 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1482 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1483 }
1484
1485 return HAL_OK;
1486 }
1487 else
1488 {
1489 return HAL_BUSY;
1490 }
1491 }
1492
1493 /**
1494 * @brief Receive in master mode an amount of data in non-blocking mode with DMA
1495 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1496 * the configuration information for the specified FMPI2C.
1497 * @param DevAddress Target device address The device 7 bits address value
1498 * in datasheet must be shifted to the left before calling the interface
1499 * @param pData Pointer to data buffer
1500 * @param Size Amount of data to be sent
1501 * @retval HAL status
1502 */
1503 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1504 {
1505 uint32_t xfermode = 0U;
1506
1507 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1508 {
1509 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1510 {
1511 return HAL_BUSY;
1512 }
1513
1514 /* Process Locked */
1515 __HAL_LOCK(hfmpi2c);
1516
1517 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1518 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1519 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1520
1521 /* Prepare transfer parameters */
1522 hfmpi2c->pBuffPtr = pData;
1523 hfmpi2c->XferCount = Size;
1524 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1525 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
1526
1527 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1528 {
1529 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1530 xfermode = FMPI2C_RELOAD_MODE;
1531 }
1532 else
1533 {
1534 hfmpi2c->XferSize = hfmpi2c->XferCount;
1535 xfermode = FMPI2C_AUTOEND_MODE;
1536 }
1537
1538 if (hfmpi2c->XferSize > 0U)
1539 {
1540 /* Set the FMPI2C DMA transfer complete callback */
1541 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
1542
1543 /* Set the DMA error callback */
1544 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
1545
1546 /* Set the unused DMA callbacks to NULL */
1547 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
1548 hfmpi2c->hdmarx->XferAbortCallback = NULL;
1549
1550 /* Enable the DMA stream */
1551 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
1552
1553 /* Send Slave Address */
1554 /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1555 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
1556
1557 /* Update XferCount value */
1558 hfmpi2c->XferCount -= hfmpi2c->XferSize;
1559
1560 /* Process Unlocked */
1561 __HAL_UNLOCK(hfmpi2c);
1562
1563 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1564 to avoid the risk of FMPI2C interrupt handle execution before current
1565 process unlock */
1566 /* Enable ERR and NACK interrupts */
1567 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
1568
1569 /* Enable DMA Request */
1570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
1571 }
1572 else
1573 {
1574 /* Update Transfer ISR function pointer */
1575 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1576
1577 /* Send Slave Address */
1578 /* Set NBYTES to read and generate START condition */
1579 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1580
1581 /* Process Unlocked */
1582 __HAL_UNLOCK(hfmpi2c);
1583
1584 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1585 to avoid the risk of FMPI2C interrupt handle execution before current
1586 process unlock */
1587 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1588 /* possible to enable all of these */
1589 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1590 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1591 }
1592 return HAL_OK;
1593 }
1594 else
1595 {
1596 return HAL_BUSY;
1597 }
1598 }
1599
1600 /**
1601 * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA
1602 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1603 * the configuration information for the specified FMPI2C.
1604 * @param pData Pointer to data buffer
1605 * @param Size Amount of data to be sent
1606 * @retval HAL status
1607 */
1608 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1609 {
1610 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1611 {
1612 if ((pData == NULL) || (Size == 0U))
1613 {
1614 return HAL_ERROR;
1615 }
1616 /* Process Locked */
1617 __HAL_LOCK(hfmpi2c);
1618
1619 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1620 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1621 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1622
1623 /* Prepare transfer parameters */
1624 hfmpi2c->pBuffPtr = pData;
1625 hfmpi2c->XferCount = Size;
1626 hfmpi2c->XferSize = hfmpi2c->XferCount;
1627 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1628 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
1629
1630 /* Set the FMPI2C DMA transfer complete callback */
1631 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
1632
1633 /* Set the DMA error callback */
1634 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
1635
1636 /* Set the unused DMA callbacks to NULL */
1637 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
1638 hfmpi2c->hdmatx->XferAbortCallback = NULL;
1639
1640 /* Enable the DMA stream */
1641 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
1642
1643 /* Enable Address Acknowledge */
1644 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1645
1646 /* Process Unlocked */
1647 __HAL_UNLOCK(hfmpi2c);
1648
1649 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1650 to avoid the risk of FMPI2C interrupt handle execution before current
1651 process unlock */
1652 /* Enable ERR, STOP, NACK, ADDR interrupts */
1653 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
1654
1655 /* Enable DMA Request */
1656 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
1657
1658 return HAL_OK;
1659 }
1660 else
1661 {
1662 return HAL_BUSY;
1663 }
1664 }
1665
1666 /**
1667 * @brief Receive in slave mode an amount of data in non-blocking mode with DMA
1668 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1669 * the configuration information for the specified FMPI2C.
1670 * @param pData Pointer to data buffer
1671 * @param Size Amount of data to be sent
1672 * @retval HAL status
1673 */
1674 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1675 {
1676 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1677 {
1678 if ((pData == NULL) || (Size == 0U))
1679 {
1680 return HAL_ERROR;
1681 }
1682 /* Process Locked */
1683 __HAL_LOCK(hfmpi2c);
1684
1685 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1686 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1687 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1688
1689 /* Prepare transfer parameters */
1690 hfmpi2c->pBuffPtr = pData;
1691 hfmpi2c->XferCount = Size;
1692 hfmpi2c->XferSize = hfmpi2c->XferCount;
1693 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1694 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
1695
1696 /* Set the FMPI2C DMA transfer complete callback */
1697 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
1698
1699 /* Set the DMA error callback */
1700 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
1701
1702 /* Set the unused DMA callbacks to NULL */
1703 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
1704 hfmpi2c->hdmarx->XferAbortCallback = NULL;
1705
1706 /* Enable the DMA stream */
1707 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
1708
1709 /* Enable Address Acknowledge */
1710 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1711
1712 /* Process Unlocked */
1713 __HAL_UNLOCK(hfmpi2c);
1714
1715 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1716 to avoid the risk of FMPI2C interrupt handle execution before current
1717 process unlock */
1718 /* Enable ERR, STOP, NACK, ADDR interrupts */
1719 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
1720
1721 /* Enable DMA Request */
1722 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
1723
1724 return HAL_OK;
1725 }
1726 else
1727 {
1728 return HAL_BUSY;
1729 }
1730 }
1731 /**
1732 * @brief Write an amount of data in blocking mode to a specific memory address
1733 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1734 * the configuration information for the specified FMPI2C.
1735 * @param DevAddress Target device address The device 7 bits address value
1736 * in datasheet must be shifted to the left before calling the interface
1737 * @param MemAddress Internal memory address
1738 * @param MemAddSize Size of internal memory address
1739 * @param pData Pointer to data buffer
1740 * @param Size Amount of data to be sent
1741 * @param Timeout Timeout duration
1742 * @retval HAL status
1743 */
1744 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)
1745 {
1746 uint32_t tickstart = 0U;
1747
1748 /* Check the parameters */
1749 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1750
1751 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1752 {
1753 if ((pData == NULL) || (Size == 0U))
1754 {
1755 return HAL_ERROR;
1756 }
1757
1758 /* Process Locked */
1759 __HAL_LOCK(hfmpi2c);
1760
1761 /* Init tickstart for timeout management*/
1762 tickstart = HAL_GetTick();
1763
1764 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1765 {
1766 return HAL_TIMEOUT;
1767 }
1768
1769 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1770 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
1771 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1772
1773 /* Prepare transfer parameters */
1774 hfmpi2c->pBuffPtr = pData;
1775 hfmpi2c->XferCount = Size;
1776 hfmpi2c->XferISR = NULL;
1777
1778 /* Send Slave Address and Memory Address */
1779 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
1780 {
1781 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1782 {
1783 /* Process Unlocked */
1784 __HAL_UNLOCK(hfmpi2c);
1785 return HAL_ERROR;
1786 }
1787 else
1788 {
1789 /* Process Unlocked */
1790 __HAL_UNLOCK(hfmpi2c);
1791 return HAL_TIMEOUT;
1792 }
1793 }
1794
1795 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1796 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1797 {
1798 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1799 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1800 }
1801 else
1802 {
1803 hfmpi2c->XferSize = hfmpi2c->XferCount;
1804 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1805 }
1806
1807 do
1808 {
1809 /* Wait until TXIS flag is set */
1810 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1811 {
1812 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1813 {
1814 return HAL_ERROR;
1815 }
1816 else
1817 {
1818 return HAL_TIMEOUT;
1819 }
1820 }
1821
1822 /* Write data to TXDR */
1823 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
1824 hfmpi2c->XferCount--;
1825 hfmpi2c->XferSize--;
1826
1827 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
1828 {
1829 /* Wait until TCR flag is set */
1830 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1831 {
1832 return HAL_TIMEOUT;
1833 }
1834
1835 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1836 {
1837 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1838 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1839 }
1840 else
1841 {
1842 hfmpi2c->XferSize = hfmpi2c->XferCount;
1843 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1844 }
1845 }
1846
1847 }
1848 while (hfmpi2c->XferCount > 0U);
1849
1850 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1851 /* Wait until STOPF flag is reset */
1852 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1853 {
1854 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1855 {
1856 return HAL_ERROR;
1857 }
1858 else
1859 {
1860 return HAL_TIMEOUT;
1861 }
1862 }
1863
1864 /* Clear STOP Flag */
1865 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1866
1867 /* Clear Configuration Register 2 */
1868 FMPI2C_RESET_CR2(hfmpi2c);
1869
1870 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1871 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1872
1873 /* Process Unlocked */
1874 __HAL_UNLOCK(hfmpi2c);
1875
1876 return HAL_OK;
1877 }
1878 else
1879 {
1880 return HAL_BUSY;
1881 }
1882 }
1883
1884 /**
1885 * @brief Read an amount of data in blocking mode from a specific memory address
1886 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1887 * the configuration information for the specified FMPI2C.
1888 * @param DevAddress Target device address The device 7 bits address value
1889 * in datasheet must be shifted to the left before calling the interface
1890 * @param MemAddress Internal memory address
1891 * @param MemAddSize Size of internal memory address
1892 * @param pData Pointer to data buffer
1893 * @param Size Amount of data to be sent
1894 * @param Timeout Timeout duration
1895 * @retval HAL status
1896 */
1897 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)
1898 {
1899 uint32_t tickstart = 0U;
1900
1901 /* Check the parameters */
1902 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1903
1904 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1905 {
1906 if ((pData == NULL) || (Size == 0U))
1907 {
1908 return HAL_ERROR;
1909 }
1910
1911 /* Process Locked */
1912 __HAL_LOCK(hfmpi2c);
1913
1914 /* Init tickstart for timeout management*/
1915 tickstart = HAL_GetTick();
1916
1917 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1918 {
1919 return HAL_TIMEOUT;
1920 }
1921
1922 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1923 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
1924 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1925
1926 /* Prepare transfer parameters */
1927 hfmpi2c->pBuffPtr = pData;
1928 hfmpi2c->XferCount = Size;
1929 hfmpi2c->XferISR = NULL;
1930
1931 /* Send Slave Address and Memory Address */
1932 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
1933 {
1934 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1935 {
1936 /* Process Unlocked */
1937 __HAL_UNLOCK(hfmpi2c);
1938 return HAL_ERROR;
1939 }
1940 else
1941 {
1942 /* Process Unlocked */
1943 __HAL_UNLOCK(hfmpi2c);
1944 return HAL_TIMEOUT;
1945 }
1946 }
1947
1948 /* Send Slave Address */
1949 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1950 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1951 {
1952 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1953 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
1954 }
1955 else
1956 {
1957 hfmpi2c->XferSize = hfmpi2c->XferCount;
1958 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1959 }
1960
1961 do
1962 {
1963 /* Wait until RXNE flag is set */
1964 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
1965 {
1966 return HAL_TIMEOUT;
1967 }
1968
1969 /* Read data from RXDR */
1970 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
1971 hfmpi2c->XferSize--;
1972 hfmpi2c->XferCount--;
1973
1974 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
1975 {
1976 /* Wait until TCR flag is set */
1977 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1978 {
1979 return HAL_TIMEOUT;
1980 }
1981
1982 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1983 {
1984 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1985 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1986 }
1987 else
1988 {
1989 hfmpi2c->XferSize = hfmpi2c->XferCount;
1990 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1991 }
1992 }
1993 }
1994 while (hfmpi2c->XferCount > 0U);
1995
1996 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1997 /* Wait until STOPF flag is reset */
1998 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1999 {
2000 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2001 {
2002 return HAL_ERROR;
2003 }
2004 else
2005 {
2006 return HAL_TIMEOUT;
2007 }
2008 }
2009
2010 /* Clear STOP Flag */
2011 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2012
2013 /* Clear Configuration Register 2 */
2014 FMPI2C_RESET_CR2(hfmpi2c);
2015
2016 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2017 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2018
2019 /* Process Unlocked */
2020 __HAL_UNLOCK(hfmpi2c);
2021
2022 return HAL_OK;
2023 }
2024 else
2025 {
2026 return HAL_BUSY;
2027 }
2028 }
2029 /**
2030 * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address
2031 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2032 * the configuration information for the specified FMPI2C.
2033 * @param DevAddress Target device address The device 7 bits address value
2034 * in datasheet must be shifted to the left before calling the interface
2035 * @param MemAddress Internal memory address
2036 * @param MemAddSize Size of internal memory address
2037 * @param pData Pointer to data buffer
2038 * @param Size Amount of data to be sent
2039 * @retval HAL status
2040 */
2041 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)
2042 {
2043 uint32_t tickstart = 0U;
2044 uint32_t xfermode = 0U;
2045
2046 /* Check the parameters */
2047 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2048
2049 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2050 {
2051 if ((pData == NULL) || (Size == 0U))
2052 {
2053 return HAL_ERROR;
2054 }
2055
2056 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2057 {
2058 return HAL_BUSY;
2059 }
2060
2061 /* Process Locked */
2062 __HAL_LOCK(hfmpi2c);
2063
2064 /* Init tickstart for timeout management*/
2065 tickstart = HAL_GetTick();
2066
2067 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2068 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2069 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2070
2071 /* Prepare transfer parameters */
2072 hfmpi2c->pBuffPtr = pData;
2073 hfmpi2c->XferCount = Size;
2074 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2075 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2076
2077 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2078 {
2079 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2080 xfermode = FMPI2C_RELOAD_MODE;
2081 }
2082 else
2083 {
2084 hfmpi2c->XferSize = hfmpi2c->XferCount;
2085 xfermode = FMPI2C_AUTOEND_MODE;
2086 }
2087
2088 /* Send Slave Address and Memory Address */
2089 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2090 {
2091 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2092 {
2093 /* Process Unlocked */
2094 __HAL_UNLOCK(hfmpi2c);
2095 return HAL_ERROR;
2096 }
2097 else
2098 {
2099 /* Process Unlocked */
2100 __HAL_UNLOCK(hfmpi2c);
2101 return HAL_TIMEOUT;
2102 }
2103 }
2104
2105 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2106 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
2107
2108 /* Process Unlocked */
2109 __HAL_UNLOCK(hfmpi2c);
2110
2111 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2112 to avoid the risk of FMPI2C interrupt handle execution before current
2113 process unlock */
2114
2115 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2116 /* possible to enable all of these */
2117 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2118 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2119
2120 return HAL_OK;
2121 }
2122 else
2123 {
2124 return HAL_BUSY;
2125 }
2126 }
2127
2128 /**
2129 * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address
2130 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2131 * the configuration information for the specified FMPI2C.
2132 * @param DevAddress Target device address The device 7 bits address value
2133 * in datasheet must be shifted to the left before calling the interface
2134 * @param MemAddress Internal memory address
2135 * @param MemAddSize Size of internal memory address
2136 * @param pData Pointer to data buffer
2137 * @param Size Amount of data to be sent
2138 * @retval HAL status
2139 */
2140 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)
2141 {
2142 uint32_t tickstart = 0U;
2143 uint32_t xfermode = 0U;
2144
2145 /* Check the parameters */
2146 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2147
2148 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2149 {
2150 if ((pData == NULL) || (Size == 0U))
2151 {
2152 return HAL_ERROR;
2153 }
2154
2155 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2156 {
2157 return HAL_BUSY;
2158 }
2159
2160 /* Process Locked */
2161 __HAL_LOCK(hfmpi2c);
2162
2163 /* Init tickstart for timeout management*/
2164 tickstart = HAL_GetTick();
2165
2166 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2167 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2168 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2169
2170 /* Prepare transfer parameters */
2171 hfmpi2c->pBuffPtr = pData;
2172 hfmpi2c->XferCount = Size;
2173 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2174 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2175
2176 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2177 {
2178 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2179 xfermode = FMPI2C_RELOAD_MODE;
2180 }
2181 else
2182 {
2183 hfmpi2c->XferSize = hfmpi2c->XferCount;
2184 xfermode = FMPI2C_AUTOEND_MODE;
2185 }
2186
2187 /* Send Slave Address and Memory Address */
2188 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2189 {
2190 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2191 {
2192 /* Process Unlocked */
2193 __HAL_UNLOCK(hfmpi2c);
2194 return HAL_ERROR;
2195 }
2196 else
2197 {
2198 /* Process Unlocked */
2199 __HAL_UNLOCK(hfmpi2c);
2200 return HAL_TIMEOUT;
2201 }
2202 }
2203
2204 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2205 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
2206
2207 /* Process Unlocked */
2208 __HAL_UNLOCK(hfmpi2c);
2209
2210 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2211 to avoid the risk of FMPI2C interrupt handle execution before current
2212 process unlock */
2213
2214 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2215 /* possible to enable all of these */
2216 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2217 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2218
2219 return HAL_OK;
2220 }
2221 else
2222 {
2223 return HAL_BUSY;
2224 }
2225 }
2226 /**
2227 * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address
2228 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2229 * the configuration information for the specified FMPI2C.
2230 * @param DevAddress Target device address The device 7 bits address value
2231 * in datasheet must be shifted to the left before calling the interface
2232 * @param MemAddress Internal memory address
2233 * @param MemAddSize Size of internal memory address
2234 * @param pData Pointer to data buffer
2235 * @param Size Amount of data to be sent
2236 * @retval HAL status
2237 */
2238 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)
2239 {
2240 uint32_t tickstart = 0U;
2241 uint32_t xfermode = 0U;
2242
2243 /* Check the parameters */
2244 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2245
2246 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2247 {
2248 if ((pData == NULL) || (Size == 0U))
2249 {
2250 return HAL_ERROR;
2251 }
2252
2253 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2254 {
2255 return HAL_BUSY;
2256 }
2257
2258 /* Process Locked */
2259 __HAL_LOCK(hfmpi2c);
2260
2261 /* Init tickstart for timeout management*/
2262 tickstart = HAL_GetTick();
2263
2264 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2265 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2266 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2267
2268 /* Prepare transfer parameters */
2269 hfmpi2c->pBuffPtr = pData;
2270 hfmpi2c->XferCount = Size;
2271 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2272 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
2273
2274 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2275 {
2276 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2277 xfermode = FMPI2C_RELOAD_MODE;
2278 }
2279 else
2280 {
2281 hfmpi2c->XferSize = hfmpi2c->XferCount;
2282 xfermode = FMPI2C_AUTOEND_MODE;
2283 }
2284
2285 /* Send Slave Address and Memory Address */
2286 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2287 {
2288 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2289 {
2290 /* Process Unlocked */
2291 __HAL_UNLOCK(hfmpi2c);
2292 return HAL_ERROR;
2293 }
2294 else
2295 {
2296 /* Process Unlocked */
2297 __HAL_UNLOCK(hfmpi2c);
2298 return HAL_TIMEOUT;
2299 }
2300 }
2301
2302 /* Set the FMPI2C DMA transfer complete callback */
2303 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
2304
2305 /* Set the DMA error callback */
2306 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2307
2308 /* Set the unused DMA callbacks to NULL */
2309 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
2310 hfmpi2c->hdmatx->XferAbortCallback = NULL;
2311
2312 /* Enable the DMA stream */
2313 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
2314
2315 /* Send Slave Address */
2316 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2317 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
2318
2319 /* Update XferCount value */
2320 hfmpi2c->XferCount -= hfmpi2c->XferSize;
2321
2322 /* Process Unlocked */
2323 __HAL_UNLOCK(hfmpi2c);
2324
2325 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2326 to avoid the risk of FMPI2C interrupt handle execution before current
2327 process unlock */
2328 /* Enable ERR and NACK interrupts */
2329 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2330
2331 /* Enable DMA Request */
2332 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2333
2334 return HAL_OK;
2335 }
2336 else
2337 {
2338 return HAL_BUSY;
2339 }
2340 }
2341
2342 /**
2343 * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address.
2344 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2345 * the configuration information for the specified FMPI2C.
2346 * @param DevAddress Target device address The device 7 bits address value
2347 * in datasheet must be shifted to the left before calling the interface
2348 * @param MemAddress Internal memory address
2349 * @param MemAddSize Size of internal memory address
2350 * @param pData Pointer to data buffer
2351 * @param Size Amount of data to be read
2352 * @retval HAL status
2353 */
2354 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)
2355 {
2356 uint32_t tickstart = 0U;
2357 uint32_t xfermode = 0U;
2358
2359 /* Check the parameters */
2360 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2361
2362 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2363 {
2364 if ((pData == NULL) || (Size == 0U))
2365 {
2366 return HAL_ERROR;
2367 }
2368
2369 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2370 {
2371 return HAL_BUSY;
2372 }
2373
2374 /* Process Locked */
2375 __HAL_LOCK(hfmpi2c);
2376
2377 /* Init tickstart for timeout management*/
2378 tickstart = HAL_GetTick();
2379
2380 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2381 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2382 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2383
2384 /* Prepare transfer parameters */
2385 hfmpi2c->pBuffPtr = pData;
2386 hfmpi2c->XferCount = Size;
2387 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2388 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
2389
2390 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2391 {
2392 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2393 xfermode = FMPI2C_RELOAD_MODE;
2394 }
2395 else
2396 {
2397 hfmpi2c->XferSize = hfmpi2c->XferCount;
2398 xfermode = FMPI2C_AUTOEND_MODE;
2399 }
2400
2401 /* Send Slave Address and Memory Address */
2402 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2403 {
2404 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2405 {
2406 /* Process Unlocked */
2407 __HAL_UNLOCK(hfmpi2c);
2408 return HAL_ERROR;
2409 }
2410 else
2411 {
2412 /* Process Unlocked */
2413 __HAL_UNLOCK(hfmpi2c);
2414 return HAL_TIMEOUT;
2415 }
2416 }
2417
2418 /* Set the FMPI2C DMA transfer complete callback */
2419 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
2420
2421 /* Set the DMA error callback */
2422 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2423
2424 /* Set the unused DMA callbacks to NULL */
2425 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
2426 hfmpi2c->hdmarx->XferAbortCallback = NULL;
2427
2428 /* Enable the DMA stream */
2429 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
2430
2431 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2432 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
2433
2434 /* Update XferCount value */
2435 hfmpi2c->XferCount -= hfmpi2c->XferSize;
2436
2437 /* Process Unlocked */
2438 __HAL_UNLOCK(hfmpi2c);
2439
2440 /* Enable DMA Request */
2441 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2442
2443 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2444 to avoid the risk of FMPI2C interrupt handle execution before current
2445 process unlock */
2446 /* Enable ERR and NACK interrupts */
2447 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2448
2449 return HAL_OK;
2450 }
2451 else
2452 {
2453 return HAL_BUSY;
2454 }
2455 }
2456
2457 /**
2458 * @brief Checks if target device is ready for communication.
2459 * @note This function is used with Memory devices
2460 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2461 * the configuration information for the specified FMPI2C.
2462 * @param DevAddress Target device address The device 7 bits address value
2463 * in datasheet must be shifted to the left before calling the interface
2464 * @param Trials Number of trials
2465 * @param Timeout Timeout duration
2466 * @retval HAL status
2467 */
2468 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
2469 {
2470 uint32_t tickstart = 0U;
2471
2472 __IO uint32_t FMPI2C_Trials = 0U;
2473
2474 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2475 {
2476 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2477 {
2478 return HAL_BUSY;
2479 }
2480
2481 /* Process Locked */
2482 __HAL_LOCK(hfmpi2c);
2483
2484 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
2485 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2486
2487 do
2488 {
2489 /* Generate Start */
2490 hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress);
2491
2492 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2493 /* Wait until STOPF flag is set or a NACK flag is set*/
2494 tickstart = HAL_GetTick();
2495 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))
2496 {
2497 if (Timeout != HAL_MAX_DELAY)
2498 {
2499 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
2500 {
2501 /* Device is ready */
2502 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2503 /* Process Unlocked */
2504 __HAL_UNLOCK(hfmpi2c);
2505 return HAL_TIMEOUT;
2506 }
2507 }
2508 }
2509
2510 /* Check if the NACKF flag has not been set */
2511 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
2512 {
2513 /* Wait until STOPF flag is reset */
2514 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
2515 {
2516 return HAL_TIMEOUT;
2517 }
2518
2519 /* Clear STOP Flag */
2520 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2521
2522 /* Device is ready */
2523 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2524
2525 /* Process Unlocked */
2526 __HAL_UNLOCK(hfmpi2c);
2527
2528 return HAL_OK;
2529 }
2530 else
2531 {
2532 /* Wait until STOPF flag is reset */
2533 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
2534 {
2535 return HAL_TIMEOUT;
2536 }
2537
2538 /* Clear NACK Flag */
2539 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2540
2541 /* Clear STOP Flag, auto generated with autoend*/
2542 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2543 }
2544
2545 /* Check if the maximum allowed number of trials has been reached */
2546 if (FMPI2C_Trials++ == Trials)
2547 {
2548 /* Generate Stop */
2549 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
2550
2551 /* Wait until STOPF flag is reset */
2552 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
2553 {
2554 return HAL_TIMEOUT;
2555 }
2556
2557 /* Clear STOP Flag */
2558 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2559 }
2560 }
2561 while (FMPI2C_Trials < Trials);
2562
2563 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2564
2565 /* Process Unlocked */
2566 __HAL_UNLOCK(hfmpi2c);
2567
2568 return HAL_TIMEOUT;
2569 }
2570 else
2571 {
2572 return HAL_BUSY;
2573 }
2574 }
2575
2576 /**
2577 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
2578 * @note This interface allow to manage repeated start condition when a direction change during transfer
2579 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2580 * the configuration information for the specified FMPI2C.
2581 * @param DevAddress Target device address The device 7 bits address value
2582 * in datasheet must be shifted to the left before calling the interface
2583 * @param pData Pointer to data buffer
2584 * @param Size Amount of data to be sent
2585 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
2586 * @retval HAL status
2587 */
2588 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
2589 {
2590 uint32_t xfermode = 0U;
2591 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
2592
2593 /* Check the parameters */
2594 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
2595
2596 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2597 {
2598 /* Process Locked */
2599 __HAL_LOCK(hfmpi2c);
2600
2601 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2602 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
2603 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2604
2605 /* Prepare transfer parameters */
2606 hfmpi2c->pBuffPtr = pData;
2607 hfmpi2c->XferCount = Size;
2608 hfmpi2c->XferOptions = XferOptions;
2609 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2610
2611 /* If size > MAX_NBYTE_SIZE, use reload mode */
2612 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2613 {
2614 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2615 xfermode = FMPI2C_RELOAD_MODE;
2616 }
2617 else
2618 {
2619 hfmpi2c->XferSize = hfmpi2c->XferCount;
2620 xfermode = hfmpi2c->XferOptions;
2621 }
2622
2623 /* If transfer direction not change, do not generate Restart Condition */
2624 /* Mean Previous state is same as current state */
2625 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX)
2626 {
2627 xferrequest = FMPI2C_NO_STARTSTOP;
2628 }
2629
2630 /* Send Slave Address and set NBYTES to write */
2631 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest);
2632
2633 /* Process Unlocked */
2634 __HAL_UNLOCK(hfmpi2c);
2635
2636 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2637 to avoid the risk of FMPI2C interrupt handle execution before current
2638 process unlock */
2639 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2640
2641 return HAL_OK;
2642 }
2643 else
2644 {
2645 return HAL_BUSY;
2646 }
2647 }
2648
2649 /**
2650 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt
2651 * @note This interface allow to manage repeated start condition when a direction change during transfer
2652 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2653 * the configuration information for the specified FMPI2C.
2654 * @param DevAddress Target device address The device 7 bits address value
2655 * in datasheet must be shifted to the left before calling the interface
2656 * @param pData Pointer to data buffer
2657 * @param Size Amount of data to be sent
2658 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
2659 * @retval HAL status
2660 */
2661 HAL_StatusTypeDef HAL_FMPI2C_Master_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
2662 {
2663 uint32_t xfermode = 0U;
2664 uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
2665
2666 /* Check the parameters */
2667 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
2668
2669 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2670 {
2671 /* Process Locked */
2672 __HAL_LOCK(hfmpi2c);
2673
2674 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2675 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
2676 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2677
2678 /* Prepare transfer parameters */
2679 hfmpi2c->pBuffPtr = pData;
2680 hfmpi2c->XferCount = Size;
2681 hfmpi2c->XferOptions = XferOptions;
2682 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2683
2684 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
2685 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2686 {
2687 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2688 xfermode = FMPI2C_RELOAD_MODE;
2689 }
2690 else
2691 {
2692 hfmpi2c->XferSize = hfmpi2c->XferCount;
2693 xfermode = hfmpi2c->XferOptions;
2694 }
2695
2696 /* If transfer direction not change, do not generate Restart Condition */
2697 /* Mean Previous state is same as current state */
2698 if (hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX)
2699 {
2700 xferrequest = FMPI2C_NO_STARTSTOP;
2701 }
2702
2703 /* Send Slave Address and set NBYTES to read */
2704 FMPI2C_TransferConfig(hfmpi2c, DevAddress, hfmpi2c->XferSize, xfermode, xferrequest);
2705
2706 /* Process Unlocked */
2707 __HAL_UNLOCK(hfmpi2c);
2708
2709 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2710 to avoid the risk of FMPI2C interrupt handle execution before current
2711 process unlock */
2712 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2713
2714 return HAL_OK;
2715 }
2716 else
2717 {
2718 return HAL_BUSY;
2719 }
2720 }
2721
2722 /**
2723 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
2724 * @note This interface allow to manage repeated start condition when a direction change during transfer
2725 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2726 * the configuration information for the specified FMPI2C.
2727 * @param pData Pointer to data buffer
2728 * @param Size Amount of data to be sent
2729 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
2730 * @retval HAL status
2731 */
2732 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
2733 {
2734 /* Check the parameters */
2735 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
2736
2737 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
2738 {
2739 if ((pData == NULL) || (Size == 0U))
2740 {
2741 return HAL_ERROR;
2742 }
2743
2744 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
2745 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
2746
2747 /* Process Locked */
2748 __HAL_LOCK(hfmpi2c);
2749
2750 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
2751 /* and then toggle the HAL slave RX state to TX state */
2752 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
2753 {
2754 /* Disable associated Interrupts */
2755 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2756 }
2757
2758 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
2759 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2760 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2761
2762 /* Enable Address Acknowledge */
2763 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2764
2765 /* Prepare transfer parameters */
2766 hfmpi2c->pBuffPtr = pData;
2767 hfmpi2c->XferCount = Size;
2768 hfmpi2c->XferSize = hfmpi2c->XferCount;
2769 hfmpi2c->XferOptions = XferOptions;
2770 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
2771
2772 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
2773 {
2774 /* Clear ADDR flag after prepare the transfer parameters */
2775 /* This action will generate an acknowledge to the Master */
2776 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
2777 }
2778
2779 /* Process Unlocked */
2780 __HAL_UNLOCK(hfmpi2c);
2781
2782 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2783 to avoid the risk of FMPI2C interrupt handle execution before current
2784 process unlock */
2785 /* REnable ADDR interrupt */
2786 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
2787
2788 return HAL_OK;
2789 }
2790 else
2791 {
2792 return HAL_ERROR;
2793 }
2794 }
2795
2796 /**
2797 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
2798 * @note This interface allow to manage repeated start condition when a direction change during transfer
2799 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2800 * the configuration information for the specified FMPI2C.
2801 * @param pData Pointer to data buffer
2802 * @param Size Amount of data to be sent
2803 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
2804 * @retval HAL status
2805 */
2806 HAL_StatusTypeDef HAL_FMPI2C_Slave_Sequential_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions)
2807 {
2808 /* Check the parameters */
2809 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
2810
2811 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
2812 {
2813 if ((pData == NULL) || (Size == 0U))
2814 {
2815 return HAL_ERROR;
2816 }
2817
2818 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
2819 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
2820
2821 /* Process Locked */
2822 __HAL_LOCK(hfmpi2c);
2823
2824 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
2825 /* and then toggle the HAL slave TX state to RX state */
2826 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
2827 {
2828 /* Disable associated Interrupts */
2829 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2830 }
2831
2832 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
2833 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2834 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2835
2836 /* Enable Address Acknowledge */
2837 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2838
2839 /* Prepare transfer parameters */
2840 hfmpi2c->pBuffPtr = pData;
2841 hfmpi2c->XferCount = Size;
2842 hfmpi2c->XferSize = hfmpi2c->XferCount;
2843 hfmpi2c->XferOptions = XferOptions;
2844 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
2845
2846 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
2847 {
2848 /* Clear ADDR flag after prepare the transfer parameters */
2849 /* This action will generate an acknowledge to the Master */
2850 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
2851 }
2852
2853 /* Process Unlocked */
2854 __HAL_UNLOCK(hfmpi2c);
2855
2856 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2857 to avoid the risk of FMPI2C interrupt handle execution before current
2858 process unlock */
2859 /* REnable ADDR interrupt */
2860 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
2861
2862 return HAL_OK;
2863 }
2864 else
2865 {
2866 return HAL_ERROR;
2867 }
2868 }
2869
2870 /**
2871 * @brief Enable the Address listen mode with Interrupt.
2872 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2873 * the configuration information for the specified FMPI2C.
2874 * @retval HAL status
2875 */
2876 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
2877 {
2878 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2879 {
2880 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2881 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
2882
2883 /* Enable the Address Match interrupt */
2884 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2885
2886 return HAL_OK;
2887 }
2888 else
2889 {
2890 return HAL_BUSY;
2891 }
2892 }
2893
2894 /**
2895 * @brief Disable the Address listen mode with Interrupt.
2896 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2897 * the configuration information for the specified FMPI2C
2898 * @retval HAL status
2899 */
2900 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
2901 {
2902 /* Declaration of tmp to prevent undefined behavior of volatile usage */
2903 uint32_t tmp;
2904
2905 /* Disable Address listen mode only if a transfer is not ongoing */
2906 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
2907 {
2908 tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK;
2909 hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode);
2910 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2911 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2912 hfmpi2c->XferISR = NULL;
2913
2914 /* Disable the Address Match interrupt */
2915 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2916
2917 return HAL_OK;
2918 }
2919 else
2920 {
2921 return HAL_BUSY;
2922 }
2923 }
2924
2925 /**
2926 * @brief Abort a master FMPI2C IT or DMA process communication with Interrupt.
2927 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2928 * the configuration information for the specified FMPI2C.
2929 * @param DevAddress Target device address The device 7 bits address value
2930 * in datasheet must be shifted to the left before calling the interface
2931 * @retval HAL status
2932 */
2933 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
2934 {
2935 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER)
2936 {
2937 /* Process Locked */
2938 __HAL_LOCK(hfmpi2c);
2939
2940 /* Disable Interrupts */
2941 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2942 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2943
2944 /* Set State at HAL_FMPI2C_STATE_ABORT */
2945 hfmpi2c->State = HAL_FMPI2C_STATE_ABORT;
2946
2947 /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */
2948 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
2949 FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP);
2950
2951 /* Process Unlocked */
2952 __HAL_UNLOCK(hfmpi2c);
2953
2954 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2955 to avoid the risk of FMPI2C interrupt handle execution before current
2956 process unlock */
2957 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
2958
2959 return HAL_OK;
2960 }
2961 else
2962 {
2963 /* Wrong usage of abort function */
2964 /* This function should be used only in case of abort monitored by master device */
2965 return HAL_ERROR;
2966 }
2967 }
2968
2969 /**
2970 * @}
2971 */
2972
2973 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
2974 * @{
2975 */
2976
2977 /**
2978 * @brief This function handles FMPI2C event interrupt request.
2979 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2980 * the configuration information for the specified FMPI2C.
2981 * @retval None
2982 */
2983 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
2984 {
2985 /* Get current IT Flags and IT sources value */
2986 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
2987 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
2988
2989 /* FMPI2C events treatment -------------------------------------*/
2990 if (hfmpi2c->XferISR != NULL)
2991 {
2992 hfmpi2c->XferISR(hfmpi2c, itflags, itsources);
2993 }
2994 }
2995
2996 /**
2997 * @brief This function handles FMPI2C error interrupt request.
2998 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2999 * the configuration information for the specified FMPI2C.
3000 * @retval None
3001 */
3002 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
3003 {
3004 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
3005 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
3006
3007 /* FMPI2C Bus error interrupt occurred ------------------------------------*/
3008 if (((itflags & FMPI2C_FLAG_BERR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
3009 {
3010 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
3011
3012 /* Clear BERR flag */
3013 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
3014 }
3015
3016 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
3017 if (((itflags & FMPI2C_FLAG_OVR) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
3018 {
3019 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
3020
3021 /* Clear OVR flag */
3022 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
3023 }
3024
3025 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
3026 if (((itflags & FMPI2C_FLAG_ARLO) != RESET) && ((itsources & FMPI2C_IT_ERRI) != RESET))
3027 {
3028 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
3029
3030 /* Clear ARLO flag */
3031 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
3032 }
3033
3034 /* Call the Error Callback in case of Error detected */
3035 if ((hfmpi2c->ErrorCode & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE)
3036 {
3037 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
3038 }
3039 }
3040
3041 /**
3042 * @brief Master Tx Transfer completed callback.
3043 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3044 * the configuration information for the specified FMPI2C.
3045 * @retval None
3046 */
3047 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3048 {
3049 /* Prevent unused argument(s) compilation warning */
3050 UNUSED(hfmpi2c);
3051
3052 /* NOTE : This function should not be modified, when the callback is needed,
3053 the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file
3054 */
3055 }
3056
3057 /**
3058 * @brief Master Rx Transfer completed callback.
3059 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3060 * the configuration information for the specified FMPI2C.
3061 * @retval None
3062 */
3063 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3064 {
3065 /* Prevent unused argument(s) compilation warning */
3066 UNUSED(hfmpi2c);
3067
3068 /* NOTE : This function should not be modified, when the callback is needed,
3069 the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file
3070 */
3071 }
3072
3073 /** @brief Slave Tx Transfer completed callback.
3074 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3075 * the configuration information for the specified FMPI2C.
3076 * @retval None
3077 */
3078 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3079 {
3080 /* Prevent unused argument(s) compilation warning */
3081 UNUSED(hfmpi2c);
3082
3083 /* NOTE : This function should not be modified, when the callback is needed,
3084 the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file
3085 */
3086 }
3087
3088 /**
3089 * @brief Slave Rx Transfer completed callback.
3090 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3091 * the configuration information for the specified FMPI2C.
3092 * @retval None
3093 */
3094 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3095 {
3096 /* Prevent unused argument(s) compilation warning */
3097 UNUSED(hfmpi2c);
3098
3099 /* NOTE : This function should not be modified, when the callback is needed,
3100 the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file
3101 */
3102 }
3103
3104 /**
3105 * @brief Slave Address Match callback.
3106 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3107 * the configuration information for the specified FMPI2C.
3108 * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION
3109 * @param AddrMatchCode Address Match Code
3110 * @retval None
3111 */
3112 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
3113 {
3114 /* Prevent unused argument(s) compilation warning */
3115 UNUSED(hfmpi2c);
3116 UNUSED(TransferDirection);
3117 UNUSED(AddrMatchCode);
3118
3119 /* NOTE : This function should not be modified, when the callback is needed,
3120 the HAL_FMPI2C_AddrCallback() could be implemented in the user file
3121 */
3122 }
3123
3124 /**
3125 * @brief Listen Complete callback.
3126 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3127 * the configuration information for the specified FMPI2C.
3128 * @retval None
3129 */
3130 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3131 {
3132 /* Prevent unused argument(s) compilation warning */
3133 UNUSED(hfmpi2c);
3134
3135 /* NOTE : This function should not be modified, when the callback is needed,
3136 the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file
3137 */
3138 }
3139
3140 /**
3141 * @brief Memory Tx Transfer completed callback.
3142 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3143 * the configuration information for the specified FMPI2C.
3144 * @retval None
3145 */
3146 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3147 {
3148 /* Prevent unused argument(s) compilation warning */
3149 UNUSED(hfmpi2c);
3150
3151 /* NOTE : This function should not be modified, when the callback is needed,
3152 the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file
3153 */
3154 }
3155
3156 /**
3157 * @brief Memory Rx Transfer completed callback.
3158 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3159 * the configuration information for the specified FMPI2C.
3160 * @retval None
3161 */
3162 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3163 {
3164 /* Prevent unused argument(s) compilation warning */
3165 UNUSED(hfmpi2c);
3166
3167 /* NOTE : This function should not be modified, when the callback is needed,
3168 the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file
3169 */
3170 }
3171
3172 /**
3173 * @brief FMPI2C error callback.
3174 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3175 * the configuration information for the specified FMPI2C.
3176 * @retval None
3177 */
3178 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3179 {
3180 /* Prevent unused argument(s) compilation warning */
3181 UNUSED(hfmpi2c);
3182
3183 /* NOTE : This function should not be modified, when the callback is needed,
3184 the HAL_FMPI2C_ErrorCallback could be implemented in the user file
3185 */
3186 }
3187
3188 /**
3189 * @brief FMPI2C abort callback.
3190 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3191 * the configuration information for the specified FMPI2C.
3192 * @retval None
3193 */
3194 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
3195 {
3196 /* Prevent unused argument(s) compilation warning */
3197 UNUSED(hfmpi2c);
3198
3199 /* NOTE : This function should not be modified, when the callback is needed,
3200 the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file
3201 */
3202 }
3203
3204 /**
3205 * @}
3206 */
3207
3208 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
3209 * @brief Peripheral State, Mode and Error functions
3210 *
3211 @verbatim
3212 ===============================================================================
3213 ##### Peripheral State, Mode and Error functions #####
3214 ===============================================================================
3215 [..]
3216 This subsection permit to get in run-time the status of the peripheral
3217 and the data flow.
3218
3219 @endverbatim
3220 * @{
3221 */
3222
3223 /**
3224 * @brief Return the FMPI2C handle state.
3225 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3226 * the configuration information for the specified FMPI2C.
3227 * @retval HAL state
3228 */
3229 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c)
3230 {
3231 /* Return FMPI2C handle state */
3232 return hfmpi2c->State;
3233 }
3234
3235 /**
3236 * @brief Returns the FMPI2C Master, Slave, Memory or no mode.
3237 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3238 * the configuration information for FMPI2C module
3239 * @retval HAL mode
3240 */
3241 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c)
3242 {
3243 return hfmpi2c->Mode;
3244 }
3245
3246 /**
3247 * @brief Return the FMPI2C error code.
3248 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3249 * the configuration information for the specified FMPI2C.
3250 * @retval FMPI2C Error Code
3251 */
3252 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c)
3253 {
3254 return hfmpi2c->ErrorCode;
3255 }
3256
3257 /**
3258 * @}
3259 */
3260
3261 /**
3262 * @}
3263 */
3264
3265 /** @addtogroup FMPI2C_Private_Functions
3266 * @{
3267 */
3268
3269 /**
3270 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
3271 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3272 * the configuration information for the specified FMPI2C.
3273 * @param ITFlags Interrupt flags to handle.
3274 * @param ITSources Interrupt sources enabled.
3275 * @retval HAL status
3276 */
3277 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
3278 {
3279 uint16_t devaddress = 0U;
3280
3281 /* Process Locked */
3282 __HAL_LOCK(hfmpi2c);
3283
3284 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
3285 {
3286 /* Clear NACK Flag */
3287 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3288
3289 /* Set corresponding Error Code */
3290 /* No need to generate STOP, it is automatically done */
3291 /* Error callback will be send during stop flag treatment */
3292 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3293
3294 /* Flush TX register */
3295 FMPI2C_Flush_TXDR(hfmpi2c);
3296 }
3297 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET))
3298 {
3299 /* Read data from RXDR */
3300 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
3301 hfmpi2c->XferSize--;
3302 hfmpi2c->XferCount--;
3303 }
3304 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET))
3305 {
3306 /* Write data to TXDR */
3307 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
3308 hfmpi2c->XferSize--;
3309 hfmpi2c->XferCount--;
3310 }
3311 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
3312 {
3313 if ((hfmpi2c->XferSize == 0U) && (hfmpi2c->XferCount != 0U))
3314 {
3315 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3316
3317 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3318 {
3319 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3320 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
3321 }
3322 else
3323 {
3324 hfmpi2c->XferSize = hfmpi2c->XferCount;
3325 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
3326 {
3327 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP);
3328 }
3329 else
3330 {
3331 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
3332 }
3333 }
3334 }
3335 else
3336 {
3337 /* Call TxCpltCallback() if no stop mode is set */
3338 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
3339 {
3340 /* Call FMPI2C Master Sequential complete process */
3341 FMPI2C_ITMasterSequentialCplt(hfmpi2c);
3342 }
3343 else
3344 {
3345 /* Wrong size Status regarding TCR flag event */
3346 /* Call the corresponding callback to inform upper layer of End of Transfer */
3347 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
3348 }
3349 }
3350 }
3351 else if (((ITFlags & FMPI2C_FLAG_TC) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
3352 {
3353 if (hfmpi2c->XferCount == 0U)
3354 {
3355 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
3356 {
3357 /* Generate a stop condition in case of no transfer option */
3358 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
3359 {
3360 /* Generate Stop */
3361 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
3362 }
3363 else
3364 {
3365 /* Call FMPI2C Master Sequential complete process */
3366 FMPI2C_ITMasterSequentialCplt(hfmpi2c);
3367 }
3368 }
3369 }
3370 else
3371 {
3372 /* Wrong size Status regarding TC flag event */
3373 /* Call the corresponding callback to inform upper layer of End of Transfer */
3374 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
3375 }
3376 }
3377
3378 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
3379 {
3380 /* Call FMPI2C Master complete process */
3381 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
3382 }
3383
3384 /* Process Unlocked */
3385 __HAL_UNLOCK(hfmpi2c);
3386
3387 return HAL_OK;
3388 }
3389
3390 /**
3391 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
3392 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3393 * the configuration information for the specified FMPI2C.
3394 * @param ITFlags Interrupt flags to handle.
3395 * @param ITSources Interrupt sources enabled.
3396 * @retval HAL status
3397 */
3398 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
3399 {
3400 /* Process locked */
3401 __HAL_LOCK(hfmpi2c);
3402
3403 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
3404 {
3405 /* Check that FMPI2C transfer finished */
3406 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
3407 /* Mean XferCount == 0*/
3408 /* So clear Flag NACKF only */
3409 if (hfmpi2c->XferCount == 0U)
3410 {
3411 if (((hfmpi2c->XferOptions == FMPI2C_FIRST_AND_LAST_FRAME) || (hfmpi2c->XferOptions == FMPI2C_LAST_FRAME)) && \
3412 (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN))
3413 {
3414 /* Call FMPI2C Listen complete process */
3415 FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
3416 }
3417 else if ((hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME) && (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
3418 {
3419 /* Clear NACK Flag */
3420 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3421
3422 /* Flush TX register */
3423 FMPI2C_Flush_TXDR(hfmpi2c);
3424
3425 /* Last Byte is Transmitted */
3426 /* Call FMPI2C Slave Sequential complete process */
3427 FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
3428 }
3429 else
3430 {
3431 /* Clear NACK Flag */
3432 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3433 }
3434 }
3435 else
3436 {
3437 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
3438 /* Clear NACK Flag */
3439 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3440
3441 /* Set ErrorCode corresponding to a Non-Acknowledge */
3442 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3443 }
3444 }
3445 else if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET) && ((ITSources & FMPI2C_IT_RXI) != RESET))
3446 {
3447 if (hfmpi2c->XferCount > 0U)
3448 {
3449 /* Read data from RXDR */
3450 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
3451 hfmpi2c->XferSize--;
3452 hfmpi2c->XferCount--;
3453 }
3454
3455 if ((hfmpi2c->XferCount == 0U) && \
3456 (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME))
3457 {
3458 /* Call FMPI2C Slave Sequential complete process */
3459 FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
3460 }
3461 }
3462 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET))
3463 {
3464 FMPI2C_ITAddrCplt(hfmpi2c, ITFlags);
3465 }
3466 else if (((ITFlags & FMPI2C_FLAG_TXIS) != RESET) && ((ITSources & FMPI2C_IT_TXI) != RESET))
3467 {
3468 /* Write data to TXDR only if XferCount not reach "0" */
3469 /* A TXIS flag can be set, during STOP treatment */
3470 /* Check if all Datas have already been sent */
3471 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
3472 if (hfmpi2c->XferCount > 0U)
3473 {
3474 /* Write data to TXDR */
3475 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
3476 hfmpi2c->XferCount--;
3477 hfmpi2c->XferSize--;
3478 }
3479 else
3480 {
3481 if ((hfmpi2c->XferOptions == FMPI2C_NEXT_FRAME) || (hfmpi2c->XferOptions == FMPI2C_FIRST_FRAME))
3482 {
3483 /* Last Byte is Transmitted */
3484 /* Call FMPI2C Slave Sequential complete process */
3485 FMPI2C_ITSlaveSequentialCplt(hfmpi2c);
3486 }
3487 }
3488 }
3489
3490 /* Check if STOPF is set */
3491 if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
3492 {
3493 /* Call FMPI2C Slave complete process */
3494 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
3495 }
3496
3497 /* Process Unlocked */
3498 __HAL_UNLOCK(hfmpi2c);
3499
3500 return HAL_OK;
3501 }
3502
3503 /**
3504 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
3505 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3506 * the configuration information for the specified FMPI2C.
3507 * @param ITFlags Interrupt flags to handle.
3508 * @param ITSources Interrupt sources enabled.
3509 * @retval HAL status
3510 */
3511 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
3512 {
3513 uint16_t devaddress = 0U;
3514 uint32_t xfermode = 0U;
3515
3516 /* Process Locked */
3517 __HAL_LOCK(hfmpi2c);
3518
3519 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
3520 {
3521 /* Clear NACK Flag */
3522 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3523
3524 /* Set corresponding Error Code */
3525 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3526
3527 /* No need to generate STOP, it is automatically done */
3528 /* But enable STOP interrupt, to treat it */
3529 /* Error callback will be send during stop flag treatment */
3530 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
3531
3532 /* Flush TX register */
3533 FMPI2C_Flush_TXDR(hfmpi2c);
3534 }
3535 else if (((ITFlags & FMPI2C_FLAG_TCR) != RESET) && ((ITSources & FMPI2C_IT_TCI) != RESET))
3536 {
3537 /* Disable TC interrupt */
3538 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI);
3539
3540 if (hfmpi2c->XferCount != 0U)
3541 {
3542 /* Recover Slave address */
3543 devaddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3544
3545 /* Prepare the new XferSize to transfer */
3546 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3547 {
3548 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3549 xfermode = FMPI2C_RELOAD_MODE;
3550 }
3551 else
3552 {
3553 hfmpi2c->XferSize = hfmpi2c->XferCount;
3554 xfermode = FMPI2C_AUTOEND_MODE;
3555 }
3556
3557 /* Set the new XferSize in Nbytes register */
3558 FMPI2C_TransferConfig(hfmpi2c, devaddress, hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
3559
3560 /* Update XferCount value */
3561 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3562
3563 /* Enable DMA Request */
3564 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
3565 {
3566 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3567 }
3568 else
3569 {
3570 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
3571 }
3572 }
3573 else
3574 {
3575 /* Wrong size Status regarding TCR flag event */
3576 /* Call the corresponding callback to inform upper layer of End of Transfer */
3577 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
3578 }
3579 }
3580 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
3581 {
3582 /* Call FMPI2C Master complete process */
3583 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
3584 }
3585
3586 /* Process Unlocked */
3587 __HAL_UNLOCK(hfmpi2c);
3588
3589 return HAL_OK;
3590 }
3591
3592 /**
3593 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
3594 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3595 * the configuration information for the specified FMPI2C.
3596 * @param ITFlags Interrupt flags to handle.
3597 * @param ITSources Interrupt sources enabled.
3598 * @retval HAL status
3599 */
3600 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags, uint32_t ITSources)
3601 {
3602 /* Process locked */
3603 __HAL_LOCK(hfmpi2c);
3604
3605 if (((ITFlags & FMPI2C_FLAG_AF) != RESET) && ((ITSources & FMPI2C_IT_NACKI) != RESET))
3606 {
3607 /* Check that FMPI2C transfer finished */
3608 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
3609 /* Mean XferCount == 0 */
3610 /* So clear Flag NACKF only */
3611 if (FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c) == 0U)
3612 {
3613 /* Clear NACK Flag */
3614 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3615 }
3616 else
3617 {
3618 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
3619 /* Clear NACK Flag */
3620 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3621
3622 /* Set ErrorCode corresponding to a Non-Acknowledge */
3623 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3624 }
3625 }
3626 else if (((ITFlags & FMPI2C_FLAG_ADDR) != RESET) && ((ITSources & FMPI2C_IT_ADDRI) != RESET))
3627 {
3628 /* Clear ADDR flag */
3629 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
3630 }
3631 else if (((ITFlags & FMPI2C_FLAG_STOPF) != RESET) && ((ITSources & FMPI2C_IT_STOPI) != RESET))
3632 {
3633 /* Call FMPI2C Slave complete process */
3634 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
3635 }
3636
3637 /* Process Unlocked */
3638 __HAL_UNLOCK(hfmpi2c);
3639
3640 return HAL_OK;
3641 }
3642
3643 /**
3644 * @brief Master sends target device address followed by internal memory address for write request.
3645 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3646 * the configuration information for the specified FMPI2C.
3647 * @param DevAddress Target device address The device 7 bits address value
3648 * in datasheet must be shifted to the left before calling the interface
3649 * @param MemAddress Internal memory address
3650 * @param MemAddSize Size of internal memory address
3651 * @param Timeout Timeout duration
3652 * @param Tickstart Tick start value
3653 * @retval HAL status
3654 */
3655 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
3656 {
3657 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
3658
3659 /* Wait until TXIS flag is set */
3660 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
3661 {
3662 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3663 {
3664 return HAL_ERROR;
3665 }
3666 else
3667 {
3668 return HAL_TIMEOUT;
3669 }
3670 }
3671
3672 /* If Memory address size is 8Bit */
3673 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
3674 {
3675 /* Send Memory Address */
3676 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3677 }
3678 /* If Memory address size is 16Bit */
3679 else
3680 {
3681 /* Send MSB of Memory Address */
3682 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
3683
3684 /* Wait until TXIS flag is set */
3685 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
3686 {
3687 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3688 {
3689 return HAL_ERROR;
3690 }
3691 else
3692 {
3693 return HAL_TIMEOUT;
3694 }
3695 }
3696
3697 /* Send LSB of Memory Address */
3698 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3699 }
3700
3701 /* Wait until TCR flag is set */
3702 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
3703 {
3704 return HAL_TIMEOUT;
3705 }
3706
3707 return HAL_OK;
3708 }
3709
3710 /**
3711 * @brief Master sends target device address followed by internal memory address for read request.
3712 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3713 * the configuration information for the specified FMPI2C.
3714 * @param DevAddress Target device address The device 7 bits address value
3715 * in datasheet must be shifted to the left before calling the interface
3716 * @param MemAddress Internal memory address
3717 * @param MemAddSize Size of internal memory address
3718 * @param Timeout Timeout duration
3719 * @param Tickstart Tick start value
3720 * @retval HAL status
3721 */
3722 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart)
3723 {
3724 FMPI2C_TransferConfig(hfmpi2c, DevAddress, MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
3725
3726 /* Wait until TXIS flag is set */
3727 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
3728 {
3729 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3730 {
3731 return HAL_ERROR;
3732 }
3733 else
3734 {
3735 return HAL_TIMEOUT;
3736 }
3737 }
3738
3739 /* If Memory address size is 8Bit */
3740 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
3741 {
3742 /* Send Memory Address */
3743 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3744 }
3745 /* If Memory address size is 16Bit */
3746 else
3747 {
3748 /* Send MSB of Memory Address */
3749 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
3750
3751 /* Wait until TXIS flag is set */
3752 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
3753 {
3754 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3755 {
3756 return HAL_ERROR;
3757 }
3758 else
3759 {
3760 return HAL_TIMEOUT;
3761 }
3762 }
3763
3764 /* Send LSB of Memory Address */
3765 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
3766 }
3767
3768 /* Wait until TC flag is set */
3769 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
3770 {
3771 return HAL_TIMEOUT;
3772 }
3773
3774 return HAL_OK;
3775 }
3776
3777 /**
3778 * @brief FMPI2C Address complete process callback.
3779 * @param hfmpi2c FMPI2C handle.
3780 * @param ITFlags Interrupt flags to handle.
3781 * @retval None
3782 */
3783 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
3784 {
3785 uint8_t transferdirection = 0;
3786 uint16_t slaveaddrcode = 0;
3787 uint16_t ownadd1code = 0;
3788 uint16_t ownadd2code = 0;
3789
3790 /* Prevent unused argument(s) compilation warning */
3791 UNUSED(ITFlags);
3792
3793 /* In case of Listen state, need to inform upper layer of address match code event */
3794 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) == HAL_FMPI2C_STATE_LISTEN)
3795 {
3796 transferdirection = FMPI2C_GET_DIR(hfmpi2c);
3797 slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c);
3798 ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c);
3799 ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c);
3800
3801 /* If 10bits addressing mode is selected */
3802 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
3803 {
3804 if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK))
3805 {
3806 slaveaddrcode = ownadd1code;
3807 hfmpi2c->AddrEventCount++;
3808 if (hfmpi2c->AddrEventCount == 2U)
3809 {
3810 /* Reset Address Event counter */
3811 hfmpi2c->AddrEventCount = 0U;
3812
3813 /* Clear ADDR flag */
3814 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
3815
3816 /* Process Unlocked */
3817 __HAL_UNLOCK(hfmpi2c);
3818
3819 /* Call Slave Addr callback */
3820 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
3821 }
3822 }
3823 else
3824 {
3825 slaveaddrcode = ownadd2code;
3826
3827 /* Disable ADDR Interrupts */
3828 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
3829
3830 /* Process Unlocked */
3831 __HAL_UNLOCK(hfmpi2c);
3832
3833 /* Call Slave Addr callback */
3834 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
3835 }
3836 }
3837 /* else 7 bits addressing mode is selected */
3838 else
3839 {
3840 /* Disable ADDR Interrupts */
3841 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
3842
3843 /* Process Unlocked */
3844 __HAL_UNLOCK(hfmpi2c);
3845
3846 /* Call Slave Addr callback */
3847 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
3848 }
3849 }
3850 /* Else clear address flag only */
3851 else
3852 {
3853 /* Clear ADDR flag */
3854 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
3855
3856 /* Process Unlocked */
3857 __HAL_UNLOCK(hfmpi2c);
3858 }
3859 }
3860
3861 /**
3862 * @brief FMPI2C Master sequential complete process.
3863 * @param hfmpi2c FMPI2C handle.
3864 * @retval None
3865 */
3866 static void FMPI2C_ITMasterSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c)
3867 {
3868 /* Reset FMPI2C handle mode */
3869 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3870
3871 /* No Generate Stop, to permit restart mode */
3872 /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */
3873 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
3874 {
3875 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3876 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
3877 hfmpi2c->XferISR = NULL;
3878
3879 /* Disable Interrupts */
3880 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3881
3882 /* Process Unlocked */
3883 __HAL_UNLOCK(hfmpi2c);
3884
3885 /* Call the corresponding callback to inform upper layer of End of Transfer */
3886 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
3887 }
3888 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
3889 else
3890 {
3891 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3892 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
3893 hfmpi2c->XferISR = NULL;
3894
3895 /* Disable Interrupts */
3896 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3897
3898 /* Process Unlocked */
3899 __HAL_UNLOCK(hfmpi2c);
3900
3901 /* Call the corresponding callback to inform upper layer of End of Transfer */
3902 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
3903 }
3904 }
3905
3906 /**
3907 * @brief FMPI2C Slave sequential complete process.
3908 * @param hfmpi2c FMPI2C handle.
3909 * @retval None
3910 */
3911 static void FMPI2C_ITSlaveSequentialCplt(FMPI2C_HandleTypeDef *hfmpi2c)
3912 {
3913 /* Reset FMPI2C handle mode */
3914 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3915
3916 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
3917 {
3918 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */
3919 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
3920 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
3921
3922 /* Disable Interrupts */
3923 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3924
3925 /* Process Unlocked */
3926 __HAL_UNLOCK(hfmpi2c);
3927
3928 /* Call the Tx complete callback to inform upper layer of the end of transmit process */
3929 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
3930 }
3931
3932 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
3933 {
3934 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */
3935 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
3936 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
3937
3938 /* Disable Interrupts */
3939 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3940
3941 /* Process Unlocked */
3942 __HAL_UNLOCK(hfmpi2c);
3943
3944 /* Call the Rx complete callback to inform upper layer of the end of receive process */
3945 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
3946 }
3947 }
3948
3949 /**
3950 * @brief FMPI2C Master complete process.
3951 * @param hfmpi2c FMPI2C handle.
3952 * @param ITFlags Interrupt flags to handle.
3953 * @retval None
3954 */
3955 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
3956 {
3957 /* Clear STOP Flag */
3958 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3959
3960 /* Clear Configuration Register 2 */
3961 FMPI2C_RESET_CR2(hfmpi2c);
3962
3963 /* Reset handle parameters */
3964 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
3965 hfmpi2c->XferISR = NULL;
3966 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
3967
3968 if ((ITFlags & FMPI2C_FLAG_AF) != RESET)
3969 {
3970 /* Clear NACK Flag */
3971 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3972
3973 /* Set acknowledge error code */
3974 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3975 }
3976
3977 /* Flush TX register */
3978 FMPI2C_Flush_TXDR(hfmpi2c);
3979
3980 /* Disable Interrupts */
3981 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT);
3982
3983 /* Call the corresponding callback to inform upper layer of End of Transfer */
3984 if ((hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) || (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT))
3985 {
3986 /* Call the corresponding callback to inform upper layer of End of Transfer */
3987 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
3988 }
3989 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */
3990 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
3991 {
3992 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3993
3994 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
3995 {
3996 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3997
3998 /* Process Unlocked */
3999 __HAL_UNLOCK(hfmpi2c);
4000
4001 /* Call the corresponding callback to inform upper layer of End of Transfer */
4002 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
4003 }
4004 else
4005 {
4006 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4007
4008 /* Process Unlocked */
4009 __HAL_UNLOCK(hfmpi2c);
4010
4011 /* Call the corresponding callback to inform upper layer of End of Transfer */
4012 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
4013 }
4014 }
4015 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
4016 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
4017 {
4018 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4019
4020 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
4021 {
4022 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4023
4024 /* Process Unlocked */
4025 __HAL_UNLOCK(hfmpi2c);
4026
4027 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
4028 }
4029 else
4030 {
4031 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4032
4033 /* Process Unlocked */
4034 __HAL_UNLOCK(hfmpi2c);
4035
4036 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
4037 }
4038 }
4039 }
4040
4041 /**
4042 * @brief FMPI2C Slave complete process.
4043 * @param hfmpi2c FMPI2C handle.
4044 * @param ITFlags Interrupt flags to handle.
4045 * @retval None
4046 */
4047 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
4048 {
4049 /* Clear STOP Flag */
4050 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
4051
4052 /* Clear ADDR flag */
4053 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4054
4055 /* Disable all interrupts */
4056 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT | FMPI2C_XFER_RX_IT);
4057
4058 /* Disable Address Acknowledge */
4059 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
4060
4061 /* Clear Configuration Register 2 */
4062 FMPI2C_RESET_CR2(hfmpi2c);
4063
4064 /* Flush TX register */
4065 FMPI2C_Flush_TXDR(hfmpi2c);
4066
4067 /* If a DMA is ongoing, Update handle size context */
4068 if (((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN) ||
4069 ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN))
4070 {
4071 hfmpi2c->XferCount = FMPI2C_GET_DMA_REMAIN_DATA(hfmpi2c);
4072 }
4073
4074 /* All data are not transferred, so set error code accordingly */
4075 if (hfmpi2c->XferCount != 0U)
4076 {
4077 /* Set ErrorCode corresponding to a Non-Acknowledge */
4078 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4079 }
4080
4081 /* Store Last receive data if any */
4082 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET))
4083 {
4084 /* Read data from RXDR */
4085 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
4086
4087 if ((hfmpi2c->XferSize > 0U))
4088 {
4089 hfmpi2c->XferSize--;
4090 hfmpi2c->XferCount--;
4091
4092 /* Set ErrorCode corresponding to a Non-Acknowledge */
4093 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4094 }
4095 }
4096
4097 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
4098 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4099 hfmpi2c->XferISR = NULL;
4100
4101 if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
4102 {
4103 /* Call the corresponding callback to inform upper layer of End of Transfer */
4104 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
4105
4106 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
4107 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
4108 {
4109 /* Call FMPI2C Listen complete process */
4110 FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
4111 }
4112 }
4113 else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
4114 {
4115 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
4116 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4117
4118 /* Process Unlocked */
4119 __HAL_UNLOCK(hfmpi2c);
4120
4121 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
4122 HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
4123 }
4124 /* Call the corresponding callback to inform upper layer of End of Transfer */
4125 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
4126 {
4127 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4128
4129 /* Process Unlocked */
4130 __HAL_UNLOCK(hfmpi2c);
4131
4132 /* Call the Slave Rx Complete callback */
4133 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
4134 }
4135 else
4136 {
4137 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4138
4139 /* Process Unlocked */
4140 __HAL_UNLOCK(hfmpi2c);
4141
4142 /* Call the Slave Tx Complete callback */
4143 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
4144 }
4145 }
4146
4147 /**
4148 * @brief FMPI2C Listen complete process.
4149 * @param hfmpi2c FMPI2C handle.
4150 * @param ITFlags Interrupt flags to handle.
4151 * @retval None
4152 */
4153 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
4154 {
4155 /* Reset handle parameters */
4156 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
4157 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
4158 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4159 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4160 hfmpi2c->XferISR = NULL;
4161
4162 /* Store Last receive data if any */
4163 if (((ITFlags & FMPI2C_FLAG_RXNE) != RESET))
4164 {
4165 /* Read data from RXDR */
4166 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
4167
4168 if ((hfmpi2c->XferSize > 0U))
4169 {
4170 hfmpi2c->XferSize--;
4171 hfmpi2c->XferCount--;
4172
4173 /* Set ErrorCode corresponding to a Non-Acknowledge */
4174 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4175 }
4176 }
4177
4178 /* Disable all Interrupts*/
4179 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
4180
4181 /* Clear NACK Flag */
4182 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4183
4184 /* Process Unlocked */
4185 __HAL_UNLOCK(hfmpi2c);
4186
4187 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
4188 HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
4189 }
4190
4191 /**
4192 * @brief FMPI2C interrupts error process.
4193 * @param hfmpi2c FMPI2C handle.
4194 * @param ErrorCode Error code to handle.
4195 * @retval None
4196 */
4197 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode)
4198 {
4199 /* Reset handle parameters */
4200 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4201 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
4202 hfmpi2c->XferCount = 0U;
4203
4204 /* Set new error code */
4205 hfmpi2c->ErrorCode |= ErrorCode;
4206
4207 /* Disable Interrupts */
4208 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) ||
4209 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) ||
4210 (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
4211 {
4212 /* Disable all interrupts, except interrupts related to LISTEN state */
4213 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
4214
4215 /* keep HAL_FMPI2C_STATE_LISTEN if set */
4216 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4217 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
4218 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4219 }
4220 else
4221 {
4222 /* Disable all interrupts */
4223 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
4224
4225 /* If state is an abort treatment on goind, don't change state */
4226 /* This change will be do later */
4227 if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT)
4228 {
4229 /* Set HAL_FMPI2C_STATE_READY */
4230 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4231 }
4232 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
4233 hfmpi2c->XferISR = NULL;
4234 }
4235
4236 /* Abort DMA TX transfer if any */
4237 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4238 {
4239 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4240
4241 /* Set the FMPI2C DMA Abort callback :
4242 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4243 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4244
4245 /* Process Unlocked */
4246 __HAL_UNLOCK(hfmpi2c);
4247
4248 /* Abort DMA TX */
4249 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4250 {
4251 /* Call Directly XferAbortCallback function in case of error */
4252 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4253 }
4254 }
4255 /* Abort DMA RX transfer if any */
4256 else if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
4257 {
4258 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
4259
4260 /* Set the FMPI2C DMA Abort callback :
4261 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4262 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
4263
4264 /* Process Unlocked */
4265 __HAL_UNLOCK(hfmpi2c);
4266
4267 /* Abort DMA RX */
4268 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
4269 {
4270 /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */
4271 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
4272 }
4273 }
4274 else if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
4275 {
4276 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4277
4278 /* Process Unlocked */
4279 __HAL_UNLOCK(hfmpi2c);
4280
4281 /* Call the corresponding callback to inform upper layer of End of Transfer */
4282 HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
4283 }
4284 else
4285 {
4286 /* Process Unlocked */
4287 __HAL_UNLOCK(hfmpi2c);
4288
4289 /* Call the corresponding callback to inform upper layer of End of Transfer */
4290 HAL_FMPI2C_ErrorCallback(hfmpi2c);
4291 }
4292 }
4293
4294 /**
4295 * @brief FMPI2C Tx data register flush process.
4296 * @param hfmpi2c FMPI2C handle.
4297 * @retval None
4298 */
4299 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c)
4300 {
4301 /* If a pending TXIS flag is set */
4302 /* Write a dummy data in TXDR to clear it */
4303 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET)
4304 {
4305 hfmpi2c->Instance->TXDR = 0x00U;
4306 }
4307
4308 /* Flush TX register if not empty */
4309 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET)
4310 {
4311 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE);
4312 }
4313 }
4314
4315 /**
4316 * @brief DMA FMPI2C master transmit process complete callback.
4317 * @param hdma DMA handle
4318 * @retval None
4319 */
4320 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
4321 {
4322 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4323
4324 /* Disable DMA Request */
4325 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4326
4327 /* If last transfer, enable STOP interrupt */
4328 if (hfmpi2c->XferCount == 0U)
4329 {
4330 /* Enable STOP interrupt */
4331 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
4332 }
4333 /* else prepare a new DMA transfer and enable TCReload interrupt */
4334 else
4335 {
4336 /* Update Buffer pointer */
4337 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
4338
4339 /* Set the XferSize to transfer */
4340 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
4341 {
4342 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
4343 }
4344 else
4345 {
4346 hfmpi2c->XferSize = hfmpi2c->XferCount;
4347 }
4348
4349 /* Enable the DMA stream */
4350 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
4351
4352 /* Enable TC interrupts */
4353 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
4354 }
4355 }
4356
4357 /**
4358 * @brief DMA FMPI2C slave transmit process complete callback.
4359 * @param hdma DMA handle
4360 * @retval None
4361 */
4362 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
4363 {
4364 /* Prevent unused argument(s) compilation warning */
4365 UNUSED(hdma);
4366
4367 /* No specific action, Master fully manage the generation of STOP condition */
4368 /* Mean that this generation can arrive at any time, at the end or during DMA process */
4369 /* So STOP condition should be manage through Interrupt treatment */
4370 }
4371
4372 /**
4373 * @brief DMA FMPI2C master receive process complete callback.
4374 * @param hdma DMA handle
4375 * @retval None
4376 */
4377 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
4378 {
4379 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4380
4381 /* Disable DMA Request */
4382 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
4383
4384 /* If last transfer, enable STOP interrupt */
4385 if (hfmpi2c->XferCount == 0U)
4386 {
4387 /* Enable STOP interrupt */
4388 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
4389 }
4390 /* else prepare a new DMA transfer and enable TCReload interrupt */
4391 else
4392 {
4393 /* Update Buffer pointer */
4394 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
4395
4396 /* Set the XferSize to transfer */
4397 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
4398 {
4399 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
4400 }
4401 else
4402 {
4403 hfmpi2c->XferSize = hfmpi2c->XferCount;
4404 }
4405
4406 /* Enable the DMA stream */
4407 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize);
4408
4409 /* Enable TC interrupts */
4410 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
4411 }
4412 }
4413
4414 /**
4415 * @brief DMA FMPI2C slave receive process complete callback.
4416 * @param hdma DMA handle
4417 * @retval None
4418 */
4419 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
4420 {
4421 /* Prevent unused argument(s) compilation warning */
4422 UNUSED(hdma);
4423
4424 /* No specific action, Master fully manage the generation of STOP condition */
4425 /* Mean that this generation can arrive at any time, at the end or during DMA process */
4426 /* So STOP condition should be manage through Interrupt treatment */
4427 }
4428
4429 /**
4430 * @brief DMA FMPI2C communication error callback.
4431 * @param hdma DMA handle
4432 * @retval None
4433 */
4434 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
4435 {
4436 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4437
4438 /* Disable Acknowledge */
4439 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
4440
4441 /* Call the corresponding callback to inform upper layer of End of Transfer */
4442 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
4443 }
4444
4445 /**
4446 * @brief DMA FMPI2C communication abort callback
4447 * (To be called at end of DMA Abort procedure).
4448 * @param hdma DMA handle.
4449 * @retval None
4450 */
4451 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma)
4452 {
4453 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
4454
4455 /* Disable Acknowledge */
4456 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
4457
4458 /* Reset AbortCpltCallback */
4459 hfmpi2c->hdmatx->XferAbortCallback = NULL;
4460 hfmpi2c->hdmarx->XferAbortCallback = NULL;
4461
4462 /* Check if come from abort from user */
4463 if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
4464 {
4465 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4466
4467 /* Call the corresponding callback to inform upper layer of End of Transfer */
4468 HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
4469 }
4470 else
4471 {
4472 /* Call the corresponding callback to inform upper layer of End of Transfer */
4473 HAL_FMPI2C_ErrorCallback(hfmpi2c);
4474 }
4475 }
4476
4477 /**
4478 * @brief This function handles FMPI2C Communication Timeout.
4479 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4480 * the configuration information for the specified FMPI2C.
4481 * @param Flag Specifies the FMPI2C flag to check.
4482 * @param Status The new Flag status (SET or RESET).
4483 * @param Timeout Timeout duration
4484 * @param Tickstart Tick start value
4485 * @retval HAL status
4486 */
4487 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
4488 {
4489 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status)
4490 {
4491 /* Check for the Timeout */
4492 if (Timeout != HAL_MAX_DELAY)
4493 {
4494 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
4495 {
4496 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4497 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4498
4499 /* Process Unlocked */
4500 __HAL_UNLOCK(hfmpi2c);
4501 return HAL_TIMEOUT;
4502 }
4503 }
4504 }
4505 return HAL_OK;
4506 }
4507
4508 /**
4509 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag.
4510 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4511 * the configuration information for the specified FMPI2C.
4512 * @param Timeout Timeout duration
4513 * @param Tickstart Tick start value
4514 * @retval HAL status
4515 */
4516 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
4517 {
4518 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
4519 {
4520 /* Check if a NACK is detected */
4521 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
4522 {
4523 return HAL_ERROR;
4524 }
4525
4526 /* Check for the Timeout */
4527 if (Timeout != HAL_MAX_DELAY)
4528 {
4529 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
4530 {
4531 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
4532 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4533 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4534
4535 /* Process Unlocked */
4536 __HAL_UNLOCK(hfmpi2c);
4537
4538 return HAL_TIMEOUT;
4539 }
4540 }
4541 }
4542 return HAL_OK;
4543 }
4544
4545 /**
4546 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag.
4547 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4548 * the configuration information for the specified FMPI2C.
4549 * @param Timeout Timeout duration
4550 * @param Tickstart Tick start value
4551 * @retval HAL status
4552 */
4553 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
4554 {
4555 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
4556 {
4557 /* Check if a NACK is detected */
4558 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
4559 {
4560 return HAL_ERROR;
4561 }
4562
4563 /* Check for the Timeout */
4564 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
4565 {
4566 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
4567 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4568 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4569
4570 /* Process Unlocked */
4571 __HAL_UNLOCK(hfmpi2c);
4572
4573 return HAL_TIMEOUT;
4574 }
4575 }
4576 return HAL_OK;
4577 }
4578
4579 /**
4580 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag.
4581 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4582 * the configuration information for the specified FMPI2C.
4583 * @param Timeout Timeout duration
4584 * @param Tickstart Tick start value
4585 * @retval HAL status
4586 */
4587 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
4588 {
4589 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET)
4590 {
4591 /* Check if a NACK is detected */
4592 if (FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout, Tickstart) != HAL_OK)
4593 {
4594 return HAL_ERROR;
4595 }
4596
4597 /* Check if a STOPF is detected */
4598 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
4599 {
4600 /* Check if an RXNE is pending */
4601 /* Store Last receive data if any */
4602 if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U))
4603 {
4604 /* Return HAL_OK */
4605 /* The Reading of data from RXDR will be done in caller function */
4606 return HAL_OK;
4607 }
4608 else
4609 {
4610 /* Clear STOP Flag */
4611 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
4612
4613 /* Clear Configuration Register 2 */
4614 FMPI2C_RESET_CR2(hfmpi2c);
4615
4616 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4617 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4618 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4619
4620 /* Process Unlocked */
4621 __HAL_UNLOCK(hfmpi2c);
4622
4623 return HAL_ERROR;
4624 }
4625 }
4626
4627 /* Check for the Timeout */
4628 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
4629 {
4630 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
4631 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4632
4633 /* Process Unlocked */
4634 __HAL_UNLOCK(hfmpi2c);
4635
4636 return HAL_TIMEOUT;
4637 }
4638 }
4639 return HAL_OK;
4640 }
4641
4642 /**
4643 * @brief This function handles Acknowledge failed detection during an FMPI2C Communication.
4644 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4645 * the configuration information for the specified FMPI2C.
4646 * @param Timeout Timeout duration
4647 * @param Tickstart Tick start value
4648 * @retval HAL status
4649 */
4650 static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
4651 {
4652 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
4653 {
4654 /* Wait until STOP Flag is reset */
4655 /* AutoEnd should be initiate after AF */
4656 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
4657 {
4658 /* Check for the Timeout */
4659 if (Timeout != HAL_MAX_DELAY)
4660 {
4661 if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
4662 {
4663 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4664 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4665
4666 /* Process Unlocked */
4667 __HAL_UNLOCK(hfmpi2c);
4668 return HAL_TIMEOUT;
4669 }
4670 }
4671 }
4672
4673 /* Clear NACKF Flag */
4674 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4675
4676 /* Clear STOP Flag */
4677 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
4678
4679 /* Flush TX register */
4680 FMPI2C_Flush_TXDR(hfmpi2c);
4681
4682 /* Clear Configuration Register 2 */
4683 FMPI2C_RESET_CR2(hfmpi2c);
4684
4685 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF;
4686 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4687 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4688
4689 /* Process Unlocked */
4690 __HAL_UNLOCK(hfmpi2c);
4691
4692 return HAL_ERROR;
4693 }
4694 return HAL_OK;
4695 }
4696
4697 /**
4698 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
4699 * @param hfmpi2c FMPI2C handle.
4700 * @param DevAddress Specifies the slave address to be programmed.
4701 * @param Size Specifies the number of bytes to be programmed.
4702 * This parameter must be a value between 0 and 255.
4703 * @param Mode New state of the FMPI2C START condition generation.
4704 * This parameter can be one of the following values:
4705 * @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode .
4706 * @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode.
4707 * @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode.
4708 * @param Request New state of the FMPI2C START condition generation.
4709 * This parameter can be one of the following values:
4710 * @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition.
4711 * @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
4712 * @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request.
4713 * @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request.
4714 * @retval None
4715 */
4716 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
4717 {
4718 /* Check the parameters */
4719 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
4720 assert_param(IS_TRANSFER_MODE(Mode));
4721 assert_param(IS_TRANSFER_REQUEST(Request));
4722
4723 /* update CR2 register */
4724 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)), \
4725 (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
4726 }
4727
4728 /**
4729 * @brief Manage the enabling of Interrupts.
4730 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4731 * the configuration information for the specified FMPI2C.
4732 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
4733 * @retval HAL status
4734 */
4735 static HAL_StatusTypeDef FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
4736 {
4737 uint32_t tmpisr = 0U;
4738
4739 if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \
4740 (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA))
4741 {
4742 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
4743 {
4744 /* Enable ERR, STOP, NACK and ADDR interrupts */
4745 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
4746 }
4747
4748 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT)
4749 {
4750 /* Enable ERR and NACK interrupts */
4751 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
4752 }
4753
4754 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
4755 {
4756 /* Enable STOP interrupts */
4757 tmpisr |= FMPI2C_IT_STOPI;
4758 }
4759
4760 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT)
4761 {
4762 /* Enable TC interrupts */
4763 tmpisr |= FMPI2C_IT_TCI;
4764 }
4765 }
4766 else
4767 {
4768 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
4769 {
4770 /* Enable ERR, STOP, NACK, and ADDR interrupts */
4771 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
4772 }
4773
4774 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
4775 {
4776 /* Enable ERR, TC, STOP, NACK and RXI interrupts */
4777 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
4778 }
4779
4780 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
4781 {
4782 /* Enable ERR, TC, STOP, NACK and TXI interrupts */
4783 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
4784 }
4785
4786 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
4787 {
4788 /* Enable STOP interrupts */
4789 tmpisr |= FMPI2C_IT_STOPI;
4790 }
4791 }
4792
4793 /* Enable interrupts only at the end */
4794 /* to avoid the risk of FMPI2C interrupt handle execution before */
4795 /* all interrupts requested done */
4796 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr);
4797
4798 return HAL_OK;
4799 }
4800
4801 /**
4802 * @brief Manage the disabling of Interrupts.
4803 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4804 * the configuration information for the specified FMPI2C.
4805 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
4806 * @retval HAL status
4807 */
4808 static HAL_StatusTypeDef FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
4809 {
4810 uint32_t tmpisr = 0U;
4811
4812 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
4813 {
4814 /* Disable TC and TXI interrupts */
4815 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI;
4816
4817 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN)
4818 {
4819 /* Disable NACK and STOP interrupts */
4820 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
4821 }
4822 }
4823
4824 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
4825 {
4826 /* Disable TC and RXI interrupts */
4827 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI;
4828
4829 if ((hfmpi2c->State & HAL_FMPI2C_STATE_LISTEN) != HAL_FMPI2C_STATE_LISTEN)
4830 {
4831 /* Disable NACK and STOP interrupts */
4832 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
4833 }
4834 }
4835
4836 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
4837 {
4838 /* Disable ADDR, NACK and STOP interrupts */
4839 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
4840 }
4841
4842 if ((InterruptRequest & FMPI2C_XFER_ERROR_IT) == FMPI2C_XFER_ERROR_IT)
4843 {
4844 /* Enable ERR and NACK interrupts */
4845 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
4846 }
4847
4848 if ((InterruptRequest & FMPI2C_XFER_CPLT_IT) == FMPI2C_XFER_CPLT_IT)
4849 {
4850 /* Enable STOP interrupts */
4851 tmpisr |= FMPI2C_IT_STOPI;
4852 }
4853
4854 if ((InterruptRequest & FMPI2C_XFER_RELOAD_IT) == FMPI2C_XFER_RELOAD_IT)
4855 {
4856 /* Enable TC interrupts */
4857 tmpisr |= FMPI2C_IT_TCI;
4858 }
4859
4860 /* Disable interrupts only at the end */
4861 /* to avoid a breaking situation like at "t" time */
4862 /* all disable interrupts request are not done */
4863 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr);
4864
4865 return HAL_OK;
4866 }
4867
4868 /**
4869 * @}
4870 */
4871 #endif /* STM32F410xx || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
4872 #endif /* HAL_FMPI2C_MODULE_ENABLED */
4873 /**
4874 * @}
4875 */
4876
4877 /**
4878 * @}
4879 */
4880
4881 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/