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 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2016 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ==============================================================================
25 ##### How to use this driver #####
26 ==============================================================================
27 [..]
28 The FMPI2C HAL driver can be used as follows:
29
30 (#) Declare a FMPI2C_HandleTypeDef handle structure, for example:
31 FMPI2C_HandleTypeDef hfmpi2c;
32
33 (#)Initialize the FMPI2C low level resources by implementing the HAL_FMPI2C_MspInit() API:
34 (##) Enable the FMPI2Cx interface clock
35 (##) FMPI2C pins configuration
36 (+++) Enable the clock for the FMPI2C GPIOs
37 (+++) Configure FMPI2C pins as alternate function open-drain
38 (##) NVIC configuration if you need to use interrupt process
39 (+++) Configure the FMPI2Cx interrupt priority
40 (+++) Enable the NVIC FMPI2C IRQ Channel
41 (##) DMA Configuration if you need to use DMA process
42 (+++) Declare a DMA_HandleTypeDef handle structure for
43 the transmit or receive stream
44 (+++) Enable the DMAx interface clock using
45 (+++) Configure the DMA handle parameters
46 (+++) Configure the DMA Tx or Rx stream
47 (+++) Associate the initialized DMA handle to the hfmpi2c DMA Tx or Rx handle
48 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
49 the DMA Tx or Rx stream
50
51 (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
52 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure.
53
54 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init(), configures also the low level Hardware
55 (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_FMPI2C_MspInit(&hfmpi2c) API.
56
57 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady()
58
59 (#) For FMPI2C IO and IO MEM operations, three operation modes are available within this driver :
60
61 *** Polling mode IO operation ***
62 =================================
63 [..]
64 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit()
65 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive()
66 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit()
67 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive()
68
69 *** Polling mode IO MEM operation ***
70 =====================================
71 [..]
72 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write()
73 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read()
74
75
76 *** Interrupt mode IO operation ***
77 ===================================
78 [..]
79 (+) Transmit in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Transmit_IT()
80 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and users can
81 add their own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
82 (+) Receive in master mode an amount of data in non-blocking mode using HAL_FMPI2C_Master_Receive_IT()
83 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and users can
84 add their own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
85 (+) Transmit in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Transmit_IT()
86 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and users can
87 add their own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
88 (+) Receive in slave mode an amount of data in non-blocking mode using HAL_FMPI2C_Slave_Receive_IT()
89 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and users can
90 add their own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
91 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and users can
92 add their own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
93 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
94 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and users can
95 add their own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
96 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
97 This action will inform Master to generate a Stop condition to discard the communication.
98
99
100 *** Interrupt mode or DMA mode IO sequential operation ***
101 ==========================================================
102 [..]
103 (@) These interfaces allow to manage a sequential transfer with a repeated start condition
104 when a direction change during transfer
105 [..]
106 (+) A specific option field manage the different steps of a sequential transfer
107 (+) Option field values are defined through FMPI2C_XFEROPTIONS and are listed below:
108 (++) FMPI2C_FIRST_AND_LAST_FRAME: No sequential usage, functional is same as associated interfaces in
109 no sequential mode
110 (++) FMPI2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address
111 and data to transfer without a final stop condition
112 (++) FMPI2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with
113 start condition, address and data to transfer without a final stop condition,
114 an then permit a call the same master sequential interface several times
115 (like HAL_FMPI2C_Master_Seq_Transmit_IT() then HAL_FMPI2C_Master_Seq_Transmit_IT()
116 or HAL_FMPI2C_Master_Seq_Transmit_DMA() then HAL_FMPI2C_Master_Seq_Transmit_DMA())
117 (++) FMPI2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address
118 and with new data to transfer if the direction change or manage only the new data to
119 transfer
120 if no direction change and without a final stop condition in both cases
121 (++) FMPI2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address
122 and with new data to transfer if the direction change or manage only the new data to
123 transfer
124 if no direction change and with a final stop condition in both cases
125 (++) FMPI2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition
126 after several call of the same master sequential interface several times
127 (link with option FMPI2C_FIRST_AND_NEXT_FRAME).
128 Usage can, transfer several bytes one by one using
129 HAL_FMPI2C_Master_Seq_Transmit_IT
130 or HAL_FMPI2C_Master_Seq_Receive_IT
131 or HAL_FMPI2C_Master_Seq_Transmit_DMA
132 or HAL_FMPI2C_Master_Seq_Receive_DMA
133 with option FMPI2C_FIRST_AND_NEXT_FRAME then FMPI2C_NEXT_FRAME.
134 Then usage of this option FMPI2C_LAST_FRAME_NO_STOP at the last Transmit or
135 Receive sequence permit to call the opposite interface Receive or Transmit
136 without stopping the communication and so generate a restart condition.
137 (++) FMPI2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after
138 each call of the same master sequential
139 interface.
140 Usage can, transfer several bytes one by one with a restart with slave address between
141 each bytes using
142 HAL_FMPI2C_Master_Seq_Transmit_IT
143 or HAL_FMPI2C_Master_Seq_Receive_IT
144 or HAL_FMPI2C_Master_Seq_Transmit_DMA
145 or HAL_FMPI2C_Master_Seq_Receive_DMA
146 with option FMPI2C_FIRST_FRAME then FMPI2C_OTHER_FRAME.
147 Then usage of this option FMPI2C_OTHER_AND_LAST_FRAME at the last frame to help automatic
148 generation of STOP condition.
149
150 (+) Different sequential FMPI2C interfaces are listed below:
151 (++) Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode using
152 HAL_FMPI2C_Master_Seq_Transmit_IT() or using HAL_FMPI2C_Master_Seq_Transmit_DMA()
153 (+++) At transmission end of current frame transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and
154 users can add their own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
155 (++) Sequential receive in master FMPI2C mode an amount of data in non-blocking mode using
156 HAL_FMPI2C_Master_Seq_Receive_IT() or using HAL_FMPI2C_Master_Seq_Receive_DMA()
157 (+++) At reception end of current frame transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and users can
158 add their own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
159 (++) Abort a master IT or DMA FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
160 (+++) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and users can
161 add their own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
162 (++) Enable/disable the Address listen mode in slave FMPI2C mode using HAL_FMPI2C_EnableListen_IT()
163 HAL_FMPI2C_DisableListen_IT()
164 (+++) When address slave FMPI2C match, HAL_FMPI2C_AddrCallback() is executed and users can
165 add their own code to check the Address Match Code and the transmission direction request by master
166 (Write/Read).
167 (+++) At Listen mode end HAL_FMPI2C_ListenCpltCallback() is executed and users can
168 add their own code by customization of function pointer HAL_FMPI2C_ListenCpltCallback()
169 (++) Sequential transmit in slave FMPI2C mode an amount of data in non-blocking mode using
170 HAL_FMPI2C_Slave_Seq_Transmit_IT() or using HAL_FMPI2C_Slave_Seq_Transmit_DMA()
171 (+++) At transmission end of current frame transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and
172 users can add their own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
173 (++) Sequential receive in slave FMPI2C mode an amount of data in non-blocking mode using
174 HAL_FMPI2C_Slave_Seq_Receive_IT() or using HAL_FMPI2C_Slave_Seq_Receive_DMA()
175 (+++) At reception end of current frame transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and users can
176 add their own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
177 (++) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and users can
178 add their own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
179 (++) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
180 This action will inform Master to generate a Stop condition to discard the communication.
181
182 *** Interrupt mode IO MEM operation ***
183 =======================================
184 [..]
185 (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using
186 HAL_FMPI2C_Mem_Write_IT()
187 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and users can
188 add their own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
189 (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using
190 HAL_FMPI2C_Mem_Read_IT()
191 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and users can
192 add their own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
193 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and users can
194 add their own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
195
196 *** DMA mode IO operation ***
197 ==============================
198 [..]
199 (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using
200 HAL_FMPI2C_Master_Transmit_DMA()
201 (+) At transmission end of transfer, HAL_FMPI2C_MasterTxCpltCallback() is executed and users can
202 add their own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback()
203 (+) Receive in master mode an amount of data in non-blocking mode (DMA) using
204 HAL_FMPI2C_Master_Receive_DMA()
205 (+) At reception end of transfer, HAL_FMPI2C_MasterRxCpltCallback() is executed and users can
206 add their own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback()
207 (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using
208 HAL_FMPI2C_Slave_Transmit_DMA()
209 (+) At transmission end of transfer, HAL_FMPI2C_SlaveTxCpltCallback() is executed and users can
210 add their own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback()
211 (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using
212 HAL_FMPI2C_Slave_Receive_DMA()
213 (+) At reception end of transfer, HAL_FMPI2C_SlaveRxCpltCallback() is executed and users can
214 add their own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback()
215 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and users can
216 add their own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
217 (+) Abort a master FMPI2C process communication with Interrupt using HAL_FMPI2C_Master_Abort_IT()
218 (+) End of abort process, HAL_FMPI2C_AbortCpltCallback() is executed and users can
219 add their own code by customization of function pointer HAL_FMPI2C_AbortCpltCallback()
220 (+) Discard a slave FMPI2C process communication using __HAL_FMPI2C_GENERATE_NACK() macro.
221 This action will inform Master to generate a Stop condition to discard the communication.
222
223 *** DMA mode IO MEM operation ***
224 =================================
225 [..]
226 (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using
227 HAL_FMPI2C_Mem_Write_DMA()
228 (+) At Memory end of write transfer, HAL_FMPI2C_MemTxCpltCallback() is executed and users can
229 add their own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback()
230 (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using
231 HAL_FMPI2C_Mem_Read_DMA()
232 (+) At Memory end of read transfer, HAL_FMPI2C_MemRxCpltCallback() is executed and users can
233 add their own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback()
234 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and users can
235 add their own code by customization of function pointer HAL_FMPI2C_ErrorCallback()
236
237
238 *** FMPI2C HAL driver macros list ***
239 ==================================
240 [..]
241 Below the list of most used macros in FMPI2C HAL driver.
242
243 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral
244 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral
245 (+) __HAL_FMPI2C_GENERATE_NACK: Generate a Non-Acknowledge FMPI2C peripheral in Slave mode
246 (+) __HAL_FMPI2C_GET_FLAG: Check whether the specified FMPI2C flag is set or not
247 (+) __HAL_FMPI2C_CLEAR_FLAG: Clear the specified FMPI2C pending flag
248 (+) __HAL_FMPI2C_ENABLE_IT: Enable the specified FMPI2C interrupt
249 (+) __HAL_FMPI2C_DISABLE_IT: Disable the specified FMPI2C interrupt
250
251 *** Callback registration ***
252 =============================================
253 [..]
254 The compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS when set to 1
255 allows the user to configure dynamically the driver callbacks.
256 Use Functions HAL_FMPI2C_RegisterCallback() or HAL_FMPI2C_RegisterAddrCallback()
257 to register an interrupt callback.
258 [..]
259 Function HAL_FMPI2C_RegisterCallback() allows to register following callbacks:
260 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
261 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
262 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
263 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
264 (+) ListenCpltCallback : callback for end of listen mode.
265 (+) MemTxCpltCallback : callback for Memory transmission end of transfer.
266 (+) MemRxCpltCallback : callback for Memory reception end of transfer.
267 (+) ErrorCallback : callback for error detection.
268 (+) AbortCpltCallback : callback for abort completion process.
269 (+) MspInitCallback : callback for Msp Init.
270 (+) MspDeInitCallback : callback for Msp DeInit.
271 This function takes as parameters the HAL peripheral handle, the Callback ID
272 and a pointer to the user callback function.
273 [..]
274 For specific callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_RegisterAddrCallback().
275 [..]
276 Use function HAL_FMPI2C_UnRegisterCallback to reset a callback to the default
277 weak function.
278 HAL_FMPI2C_UnRegisterCallback takes as parameters the HAL peripheral handle,
279 and the Callback ID.
280 This function allows to reset following callbacks:
281 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
282 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
283 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
284 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
285 (+) ListenCpltCallback : callback for end of listen mode.
286 (+) MemTxCpltCallback : callback for Memory transmission end of transfer.
287 (+) MemRxCpltCallback : callback for Memory reception end of transfer.
288 (+) ErrorCallback : callback for error detection.
289 (+) AbortCpltCallback : callback for abort completion process.
290 (+) MspInitCallback : callback for Msp Init.
291 (+) MspDeInitCallback : callback for Msp DeInit.
292 [..]
293 For callback AddrCallback use dedicated register callbacks : HAL_FMPI2C_UnRegisterAddrCallback().
294 [..]
295 By default, after the HAL_FMPI2C_Init() and when the state is HAL_FMPI2C_STATE_RESET
296 all callbacks are set to the corresponding weak functions:
297 examples HAL_FMPI2C_MasterTxCpltCallback(), HAL_FMPI2C_MasterRxCpltCallback().
298 Exception done for MspInit and MspDeInit functions that are
299 reset to the legacy weak functions in the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit() only when
300 these callbacks are null (not registered beforehand).
301 If MspInit or MspDeInit are not null, the HAL_FMPI2C_Init()/ HAL_FMPI2C_DeInit()
302 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
303 [..]
304 Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only.
305 Exception done MspInit/MspDeInit functions that can be registered/unregistered
306 in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state,
307 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
308 Then, the user first registers the MspInit/MspDeInit user callbacks
309 using HAL_FMPI2C_RegisterCallback() before calling HAL_FMPI2C_DeInit()
310 or HAL_FMPI2C_Init() function.
311 [..]
312 When the compilation flag USE_HAL_FMPI2C_REGISTER_CALLBACKS is set to 0 or
313 not defined, the callback registration feature is not available and all callbacks
314 are set to the corresponding weak functions.
315
316 [..]
317 (@) You can refer to the FMPI2C HAL driver header file for more useful macros
318
319 @endverbatim
320 */
321
322 /* Includes ------------------------------------------------------------------*/
323 #include "stm32f4xx_hal.h"
324
325 /** @addtogroup STM32F4xx_HAL_Driver
326 * @{
327 */
328
329 /** @defgroup FMPI2C FMPI2C
330 * @brief FMPI2C HAL module driver
331 * @{
332 */
333
334 #ifdef HAL_FMPI2C_MODULE_ENABLED
335 #if defined(FMPI2C_CR1_PE)
336
337 /* Private typedef -----------------------------------------------------------*/
338 /* Private define ------------------------------------------------------------*/
339
340 /** @defgroup FMPI2C_Private_Define FMPI2C Private Define
341 * @{
342 */
343 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< FMPI2C TIMING clear register Mask */
344 #define FMPI2C_TIMEOUT_ADDR (10000U) /*!< 10 s */
345 #define FMPI2C_TIMEOUT_BUSY (25U) /*!< 25 ms */
346 #define FMPI2C_TIMEOUT_DIR (25U) /*!< 25 ms */
347 #define FMPI2C_TIMEOUT_RXNE (25U) /*!< 25 ms */
348 #define FMPI2C_TIMEOUT_STOPF (25U) /*!< 25 ms */
349 #define FMPI2C_TIMEOUT_TC (25U) /*!< 25 ms */
350 #define FMPI2C_TIMEOUT_TCR (25U) /*!< 25 ms */
351 #define FMPI2C_TIMEOUT_TXIS (25U) /*!< 25 ms */
352 #define FMPI2C_TIMEOUT_FLAG (25U) /*!< 25 ms */
353
354 #define MAX_NBYTE_SIZE 255U
355 #define SLAVE_ADDR_SHIFT 7U
356 #define SLAVE_ADDR_MSK 0x06U
357
358 /* Private define for @ref PreviousState usage */
359 #define FMPI2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_FMPI2C_STATE_BUSY_TX | \
360 (uint32_t)HAL_FMPI2C_STATE_BUSY_RX) & \
361 (uint32_t)(~((uint32_t)HAL_FMPI2C_STATE_READY))))
362 /*!< Mask State define, keep only RX and TX bits */
363 #define FMPI2C_STATE_NONE ((uint32_t)(HAL_FMPI2C_MODE_NONE))
364 /*!< Default Value */
365 #define FMPI2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
366 (uint32_t)HAL_FMPI2C_MODE_MASTER))
367 /*!< Master Busy TX, combinaison of State LSB and Mode enum */
368 #define FMPI2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
369 (uint32_t)HAL_FMPI2C_MODE_MASTER))
370 /*!< Master Busy RX, combinaison of State LSB and Mode enum */
371 #define FMPI2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
372 (uint32_t)HAL_FMPI2C_MODE_SLAVE))
373 /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
374 #define FMPI2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
375 (uint32_t)HAL_FMPI2C_MODE_SLAVE))
376 /*!< Slave Busy RX, combinaison of State LSB and Mode enum */
377 #define FMPI2C_STATE_MEM_BUSY_TX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_TX & FMPI2C_STATE_MSK) | \
378 (uint32_t)HAL_FMPI2C_MODE_MEM))
379 /*!< Memory Busy TX, combinaison of State LSB and Mode enum */
380 #define FMPI2C_STATE_MEM_BUSY_RX ((uint32_t)(((uint32_t)HAL_FMPI2C_STATE_BUSY_RX & FMPI2C_STATE_MSK) | \
381 (uint32_t)HAL_FMPI2C_MODE_MEM))
382 /*!< Memory Busy RX, combinaison of State LSB and Mode enum */
383
384
385 /* Private define to centralize the enable/disable of Interrupts */
386 #define FMPI2C_XFER_TX_IT (uint16_t)(0x0001U) /*!< Bit field can be combinated with
387 @ref FMPI2C_XFER_LISTEN_IT */
388 #define FMPI2C_XFER_RX_IT (uint16_t)(0x0002U) /*!< Bit field can be combinated with
389 @ref FMPI2C_XFER_LISTEN_IT */
390 #define FMPI2C_XFER_LISTEN_IT (uint16_t)(0x8000U) /*!< Bit field can be combinated with @ref FMPI2C_XFER_TX_IT
391 and @ref FMPI2C_XFER_RX_IT */
392
393 #define FMPI2C_XFER_ERROR_IT (uint16_t)(0x0010U) /*!< Bit definition to manage addition of global Error
394 and NACK treatment */
395 #define FMPI2C_XFER_CPLT_IT (uint16_t)(0x0020U) /*!< Bit definition to manage only STOP evenement */
396 #define FMPI2C_XFER_RELOAD_IT (uint16_t)(0x0040U) /*!< Bit definition to manage only Reload of NBYTE */
397
398 /* Private define Sequential Transfer Options default/reset value */
399 #define FMPI2C_NO_OPTION_FRAME (0xFFFF0000U)
400 /**
401 * @}
402 */
403
404 /* Private macro -------------------------------------------------------------*/
405 /* Private variables ---------------------------------------------------------*/
406 /* Private function prototypes -----------------------------------------------*/
407
408 /** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions
409 * @{
410 */
411 /* Private functions to handle DMA transfer */
412 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
413 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
414 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
415 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
416 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
417 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma);
418
419 /* Private functions to handle IT transfer */
420 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
421 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
422 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c);
423 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
424 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
425 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags);
426 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode);
427
428 /* Private functions to handle IT transfer */
429 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
430 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
431 uint32_t Tickstart);
432 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
433 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
434 uint32_t Tickstart);
435
436 /* Private functions for FMPI2C transfer IRQ handler */
437 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
438 uint32_t ITSources);
439 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
440 uint32_t ITSources);
441 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
442 uint32_t ITSources);
443 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
444 uint32_t ITSources);
445
446 /* Private functions to handle flags during polling transfer */
447 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
448 uint32_t Timeout, uint32_t Tickstart);
449 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
450 uint32_t Tickstart);
451 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
452 uint32_t Tickstart);
453 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
454 uint32_t Tickstart);
455 static HAL_StatusTypeDef FMPI2C_IsErrorOccurred(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
456 uint32_t Tickstart);
457
458 /* Private functions to centralize the enable/disable of Interrupts */
459 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
460 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest);
461
462 /* Private function to treat different error callback */
463 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c);
464
465 /* Private function to flush TXDR register */
466 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c);
467
468 /* Private function to handle start, restart or stop a transfer */
469 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
470 uint32_t Request);
471
472 /* Private function to Convert Specific options */
473 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c);
474 /**
475 * @}
476 */
477
478 /* Exported functions --------------------------------------------------------*/
479
480 /** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions
481 * @{
482 */
483
484 /** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions
485 * @brief Initialization and Configuration functions
486 *
487 @verbatim
488 ===============================================================================
489 ##### Initialization and de-initialization functions #####
490 ===============================================================================
491 [..] This subsection provides a set of functions allowing to initialize and
492 deinitialize the FMPI2Cx peripheral:
493
494 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures
495 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
496
497 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with
498 the selected configuration:
499 (++) Clock Timing
500 (++) Own Address 1
501 (++) Addressing mode (Master, Slave)
502 (++) Dual Addressing mode
503 (++) Own Address 2
504 (++) Own Address 2 Mask
505 (++) General call mode
506 (++) Nostretch mode
507
508 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration
509 of the selected FMPI2Cx peripheral.
510
511 @endverbatim
512 * @{
513 */
514
515 /**
516 * @brief Initializes the FMPI2C according to the specified parameters
517 * in the FMPI2C_InitTypeDef and initialize the associated handle.
518 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
519 * the configuration information for the specified FMPI2C.
520 * @retval HAL status
521 */
HAL_FMPI2C_Init(FMPI2C_HandleTypeDef * hfmpi2c)522 HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
523 {
524 /* Check the FMPI2C handle allocation */
525 if (hfmpi2c == NULL)
526 {
527 return HAL_ERROR;
528 }
529
530 /* Check the parameters */
531 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
532 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
533 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
534 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
535 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
536 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
537 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
538 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
539
540 if (hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
541 {
542 /* Allocate lock resource and initialize it */
543 hfmpi2c->Lock = HAL_UNLOCKED;
544
545 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
546 /* Init the FMPI2C Callback settings */
547 hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
548 hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
549 hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
550 hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
551 hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
552 hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
553 hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
554 hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */
555 hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
556 hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */
557
558 if (hfmpi2c->MspInitCallback == NULL)
559 {
560 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
561 }
562
563 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
564 hfmpi2c->MspInitCallback(hfmpi2c);
565 #else
566 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
567 HAL_FMPI2C_MspInit(hfmpi2c);
568 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
569 }
570
571 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
572
573 /* Disable the selected FMPI2C peripheral */
574 __HAL_FMPI2C_DISABLE(hfmpi2c);
575
576 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
577 /* Configure FMPI2Cx: Frequency range */
578 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
579
580 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
581 /* Disable Own Address1 before set the Own Address1 configuration */
582 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
583
584 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
585 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
586 {
587 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
588 }
589 else /* FMPI2C_ADDRESSINGMODE_10BIT */
590 {
591 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
592 }
593
594 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
595 /* Configure FMPI2Cx: Addressing Master mode */
596 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
597 {
598 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10);
599 }
600 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
601 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
602
603 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
604 /* Disable Own Address2 before set the Own Address2 configuration */
605 hfmpi2c->Instance->OAR2 &= ~FMPI2C_DUALADDRESS_ENABLE;
606
607 /* Configure FMPI2Cx: Dual mode and Own Address2 */
608 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | \
609 (hfmpi2c->Init.OwnAddress2Masks << 8));
610
611 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
612 /* Configure FMPI2Cx: Generalcall and NoStretch mode */
613 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
614
615 /* Enable the selected FMPI2C peripheral */
616 __HAL_FMPI2C_ENABLE(hfmpi2c);
617
618 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
619 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
620 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
621 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
622
623 return HAL_OK;
624 }
625
626 /**
627 * @brief DeInitialize the FMPI2C peripheral.
628 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
629 * the configuration information for the specified FMPI2C.
630 * @retval HAL status
631 */
HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef * hfmpi2c)632 HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
633 {
634 /* Check the FMPI2C handle allocation */
635 if (hfmpi2c == NULL)
636 {
637 return HAL_ERROR;
638 }
639
640 /* Check the parameters */
641 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
642
643 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
644
645 /* Disable the FMPI2C Peripheral Clock */
646 __HAL_FMPI2C_DISABLE(hfmpi2c);
647
648 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
649 if (hfmpi2c->MspDeInitCallback == NULL)
650 {
651 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
652 }
653
654 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
655 hfmpi2c->MspDeInitCallback(hfmpi2c);
656 #else
657 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
658 HAL_FMPI2C_MspDeInit(hfmpi2c);
659 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
660
661 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
662 hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
663 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
664 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
665
666 /* Release Lock */
667 __HAL_UNLOCK(hfmpi2c);
668
669 return HAL_OK;
670 }
671
672 /**
673 * @brief Initialize the FMPI2C MSP.
674 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
675 * the configuration information for the specified FMPI2C.
676 * @retval None
677 */
HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef * hfmpi2c)678 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
679 {
680 /* Prevent unused argument(s) compilation warning */
681 UNUSED(hfmpi2c);
682
683 /* NOTE : This function should not be modified, when the callback is needed,
684 the HAL_FMPI2C_MspInit could be implemented in the user file
685 */
686 }
687
688 /**
689 * @brief DeInitialize the FMPI2C MSP.
690 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
691 * the configuration information for the specified FMPI2C.
692 * @retval None
693 */
HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef * hfmpi2c)694 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
695 {
696 /* Prevent unused argument(s) compilation warning */
697 UNUSED(hfmpi2c);
698
699 /* NOTE : This function should not be modified, when the callback is needed,
700 the HAL_FMPI2C_MspDeInit could be implemented in the user file
701 */
702 }
703
704 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
705 /**
706 * @brief Register a User FMPI2C Callback
707 * To be used instead of the weak predefined callback
708 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
709 * the configuration information for the specified FMPI2C.
710 * @param CallbackID ID of the callback to be registered
711 * This parameter can be one of the following values:
712 * @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
713 * @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
714 * @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
715 * @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
716 * @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
717 * @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
718 * @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
719 * @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID
720 * @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID
721 * @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID
722 * @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID
723 * @param pCallback pointer to the Callback function
724 * @retval HAL status
725 */
HAL_FMPI2C_RegisterCallback(FMPI2C_HandleTypeDef * hfmpi2c,HAL_FMPI2C_CallbackIDTypeDef CallbackID,pFMPI2C_CallbackTypeDef pCallback)726 HAL_StatusTypeDef HAL_FMPI2C_RegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID,
727 pFMPI2C_CallbackTypeDef pCallback)
728 {
729 HAL_StatusTypeDef status = HAL_OK;
730
731 if (pCallback == NULL)
732 {
733 /* Update the error code */
734 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
735
736 return HAL_ERROR;
737 }
738 /* Process locked */
739 __HAL_LOCK(hfmpi2c);
740
741 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
742 {
743 switch (CallbackID)
744 {
745 case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID :
746 hfmpi2c->MasterTxCpltCallback = pCallback;
747 break;
748
749 case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID :
750 hfmpi2c->MasterRxCpltCallback = pCallback;
751 break;
752
753 case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID :
754 hfmpi2c->SlaveTxCpltCallback = pCallback;
755 break;
756
757 case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID :
758 hfmpi2c->SlaveRxCpltCallback = pCallback;
759 break;
760
761 case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID :
762 hfmpi2c->ListenCpltCallback = pCallback;
763 break;
764
765 case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID :
766 hfmpi2c->MemTxCpltCallback = pCallback;
767 break;
768
769 case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID :
770 hfmpi2c->MemRxCpltCallback = pCallback;
771 break;
772
773 case HAL_FMPI2C_ERROR_CB_ID :
774 hfmpi2c->ErrorCallback = pCallback;
775 break;
776
777 case HAL_FMPI2C_ABORT_CB_ID :
778 hfmpi2c->AbortCpltCallback = pCallback;
779 break;
780
781 case HAL_FMPI2C_MSPINIT_CB_ID :
782 hfmpi2c->MspInitCallback = pCallback;
783 break;
784
785 case HAL_FMPI2C_MSPDEINIT_CB_ID :
786 hfmpi2c->MspDeInitCallback = pCallback;
787 break;
788
789 default :
790 /* Update the error code */
791 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
792
793 /* Return error status */
794 status = HAL_ERROR;
795 break;
796 }
797 }
798 else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
799 {
800 switch (CallbackID)
801 {
802 case HAL_FMPI2C_MSPINIT_CB_ID :
803 hfmpi2c->MspInitCallback = pCallback;
804 break;
805
806 case HAL_FMPI2C_MSPDEINIT_CB_ID :
807 hfmpi2c->MspDeInitCallback = pCallback;
808 break;
809
810 default :
811 /* Update the error code */
812 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
813
814 /* Return error status */
815 status = HAL_ERROR;
816 break;
817 }
818 }
819 else
820 {
821 /* Update the error code */
822 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
823
824 /* Return error status */
825 status = HAL_ERROR;
826 }
827
828 /* Release Lock */
829 __HAL_UNLOCK(hfmpi2c);
830 return status;
831 }
832
833 /**
834 * @brief Unregister an FMPI2C Callback
835 * FMPI2C callback is redirected to the weak predefined callback
836 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
837 * the configuration information for the specified FMPI2C.
838 * @param CallbackID ID of the callback to be unregistered
839 * This parameter can be one of the following values:
840 * This parameter can be one of the following values:
841 * @arg @ref HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
842 * @arg @ref HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
843 * @arg @ref HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
844 * @arg @ref HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
845 * @arg @ref HAL_FMPI2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
846 * @arg @ref HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID
847 * @arg @ref HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID
848 * @arg @ref HAL_FMPI2C_ERROR_CB_ID Error callback ID
849 * @arg @ref HAL_FMPI2C_ABORT_CB_ID Abort callback ID
850 * @arg @ref HAL_FMPI2C_MSPINIT_CB_ID MspInit callback ID
851 * @arg @ref HAL_FMPI2C_MSPDEINIT_CB_ID MspDeInit callback ID
852 * @retval HAL status
853 */
HAL_FMPI2C_UnRegisterCallback(FMPI2C_HandleTypeDef * hfmpi2c,HAL_FMPI2C_CallbackIDTypeDef CallbackID)854 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterCallback(FMPI2C_HandleTypeDef *hfmpi2c, HAL_FMPI2C_CallbackIDTypeDef CallbackID)
855 {
856 HAL_StatusTypeDef status = HAL_OK;
857
858 /* Process locked */
859 __HAL_LOCK(hfmpi2c);
860
861 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
862 {
863 switch (CallbackID)
864 {
865 case HAL_FMPI2C_MASTER_TX_COMPLETE_CB_ID :
866 hfmpi2c->MasterTxCpltCallback = HAL_FMPI2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
867 break;
868
869 case HAL_FMPI2C_MASTER_RX_COMPLETE_CB_ID :
870 hfmpi2c->MasterRxCpltCallback = HAL_FMPI2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
871 break;
872
873 case HAL_FMPI2C_SLAVE_TX_COMPLETE_CB_ID :
874 hfmpi2c->SlaveTxCpltCallback = HAL_FMPI2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
875 break;
876
877 case HAL_FMPI2C_SLAVE_RX_COMPLETE_CB_ID :
878 hfmpi2c->SlaveRxCpltCallback = HAL_FMPI2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
879 break;
880
881 case HAL_FMPI2C_LISTEN_COMPLETE_CB_ID :
882 hfmpi2c->ListenCpltCallback = HAL_FMPI2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
883 break;
884
885 case HAL_FMPI2C_MEM_TX_COMPLETE_CB_ID :
886 hfmpi2c->MemTxCpltCallback = HAL_FMPI2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */
887 break;
888
889 case HAL_FMPI2C_MEM_RX_COMPLETE_CB_ID :
890 hfmpi2c->MemRxCpltCallback = HAL_FMPI2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */
891 break;
892
893 case HAL_FMPI2C_ERROR_CB_ID :
894 hfmpi2c->ErrorCallback = HAL_FMPI2C_ErrorCallback; /* Legacy weak ErrorCallback */
895 break;
896
897 case HAL_FMPI2C_ABORT_CB_ID :
898 hfmpi2c->AbortCpltCallback = HAL_FMPI2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
899 break;
900
901 case HAL_FMPI2C_MSPINIT_CB_ID :
902 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
903 break;
904
905 case HAL_FMPI2C_MSPDEINIT_CB_ID :
906 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
907 break;
908
909 default :
910 /* Update the error code */
911 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
912
913 /* Return error status */
914 status = HAL_ERROR;
915 break;
916 }
917 }
918 else if (HAL_FMPI2C_STATE_RESET == hfmpi2c->State)
919 {
920 switch (CallbackID)
921 {
922 case HAL_FMPI2C_MSPINIT_CB_ID :
923 hfmpi2c->MspInitCallback = HAL_FMPI2C_MspInit; /* Legacy weak MspInit */
924 break;
925
926 case HAL_FMPI2C_MSPDEINIT_CB_ID :
927 hfmpi2c->MspDeInitCallback = HAL_FMPI2C_MspDeInit; /* Legacy weak MspDeInit */
928 break;
929
930 default :
931 /* Update the error code */
932 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
933
934 /* Return error status */
935 status = HAL_ERROR;
936 break;
937 }
938 }
939 else
940 {
941 /* Update the error code */
942 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
943
944 /* Return error status */
945 status = HAL_ERROR;
946 }
947
948 /* Release Lock */
949 __HAL_UNLOCK(hfmpi2c);
950 return status;
951 }
952
953 /**
954 * @brief Register the Slave Address Match FMPI2C Callback
955 * To be used instead of the weak HAL_FMPI2C_AddrCallback() predefined callback
956 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
957 * the configuration information for the specified FMPI2C.
958 * @param pCallback pointer to the Address Match Callback function
959 * @retval HAL status
960 */
HAL_FMPI2C_RegisterAddrCallback(FMPI2C_HandleTypeDef * hfmpi2c,pFMPI2C_AddrCallbackTypeDef pCallback)961 HAL_StatusTypeDef HAL_FMPI2C_RegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, pFMPI2C_AddrCallbackTypeDef pCallback)
962 {
963 HAL_StatusTypeDef status = HAL_OK;
964
965 if (pCallback == NULL)
966 {
967 /* Update the error code */
968 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
969
970 return HAL_ERROR;
971 }
972 /* Process locked */
973 __HAL_LOCK(hfmpi2c);
974
975 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
976 {
977 hfmpi2c->AddrCallback = pCallback;
978 }
979 else
980 {
981 /* Update the error code */
982 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
983
984 /* Return error status */
985 status = HAL_ERROR;
986 }
987
988 /* Release Lock */
989 __HAL_UNLOCK(hfmpi2c);
990 return status;
991 }
992
993 /**
994 * @brief UnRegister the Slave Address Match FMPI2C Callback
995 * Info Ready FMPI2C Callback is redirected to the weak HAL_FMPI2C_AddrCallback() predefined callback
996 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
997 * the configuration information for the specified FMPI2C.
998 * @retval HAL status
999 */
HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef * hfmpi2c)1000 HAL_StatusTypeDef HAL_FMPI2C_UnRegisterAddrCallback(FMPI2C_HandleTypeDef *hfmpi2c)
1001 {
1002 HAL_StatusTypeDef status = HAL_OK;
1003
1004 /* Process locked */
1005 __HAL_LOCK(hfmpi2c);
1006
1007 if (HAL_FMPI2C_STATE_READY == hfmpi2c->State)
1008 {
1009 hfmpi2c->AddrCallback = HAL_FMPI2C_AddrCallback; /* Legacy weak AddrCallback */
1010 }
1011 else
1012 {
1013 /* Update the error code */
1014 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_INVALID_CALLBACK;
1015
1016 /* Return error status */
1017 status = HAL_ERROR;
1018 }
1019
1020 /* Release Lock */
1021 __HAL_UNLOCK(hfmpi2c);
1022 return status;
1023 }
1024
1025 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
1026
1027 /**
1028 * @}
1029 */
1030
1031 /** @defgroup FMPI2C_Exported_Functions_Group2 Input and Output operation functions
1032 * @brief Data transfers functions
1033 *
1034 @verbatim
1035 ===============================================================================
1036 ##### IO operation functions #####
1037 ===============================================================================
1038 [..]
1039 This subsection provides a set of functions allowing to manage the FMPI2C data
1040 transfers.
1041
1042 (#) There are two modes of transfer:
1043 (++) Blocking mode : The communication is performed in the polling mode.
1044 The status of all data processing is returned by the same function
1045 after finishing transfer.
1046 (++) No-Blocking mode : The communication is performed using Interrupts
1047 or DMA. These functions return the status of the transfer startup.
1048 The end of the data processing will be indicated through the
1049 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when
1050 using DMA mode.
1051
1052 (#) Blocking mode functions are :
1053 (++) HAL_FMPI2C_Master_Transmit()
1054 (++) HAL_FMPI2C_Master_Receive()
1055 (++) HAL_FMPI2C_Slave_Transmit()
1056 (++) HAL_FMPI2C_Slave_Receive()
1057 (++) HAL_FMPI2C_Mem_Write()
1058 (++) HAL_FMPI2C_Mem_Read()
1059 (++) HAL_FMPI2C_IsDeviceReady()
1060
1061 (#) No-Blocking mode functions with Interrupt are :
1062 (++) HAL_FMPI2C_Master_Transmit_IT()
1063 (++) HAL_FMPI2C_Master_Receive_IT()
1064 (++) HAL_FMPI2C_Slave_Transmit_IT()
1065 (++) HAL_FMPI2C_Slave_Receive_IT()
1066 (++) HAL_FMPI2C_Mem_Write_IT()
1067 (++) HAL_FMPI2C_Mem_Read_IT()
1068 (++) HAL_FMPI2C_Master_Seq_Transmit_IT()
1069 (++) HAL_FMPI2C_Master_Seq_Receive_IT()
1070 (++) HAL_FMPI2C_Slave_Seq_Transmit_IT()
1071 (++) HAL_FMPI2C_Slave_Seq_Receive_IT()
1072 (++) HAL_FMPI2C_EnableListen_IT()
1073 (++) HAL_FMPI2C_DisableListen_IT()
1074 (++) HAL_FMPI2C_Master_Abort_IT()
1075
1076 (#) No-Blocking mode functions with DMA are :
1077 (++) HAL_FMPI2C_Master_Transmit_DMA()
1078 (++) HAL_FMPI2C_Master_Receive_DMA()
1079 (++) HAL_FMPI2C_Slave_Transmit_DMA()
1080 (++) HAL_FMPI2C_Slave_Receive_DMA()
1081 (++) HAL_FMPI2C_Mem_Write_DMA()
1082 (++) HAL_FMPI2C_Mem_Read_DMA()
1083 (++) HAL_FMPI2C_Master_Seq_Transmit_DMA()
1084 (++) HAL_FMPI2C_Master_Seq_Receive_DMA()
1085 (++) HAL_FMPI2C_Slave_Seq_Transmit_DMA()
1086 (++) HAL_FMPI2C_Slave_Seq_Receive_DMA()
1087
1088 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
1089 (++) HAL_FMPI2C_MasterTxCpltCallback()
1090 (++) HAL_FMPI2C_MasterRxCpltCallback()
1091 (++) HAL_FMPI2C_SlaveTxCpltCallback()
1092 (++) HAL_FMPI2C_SlaveRxCpltCallback()
1093 (++) HAL_FMPI2C_MemTxCpltCallback()
1094 (++) HAL_FMPI2C_MemRxCpltCallback()
1095 (++) HAL_FMPI2C_AddrCallback()
1096 (++) HAL_FMPI2C_ListenCpltCallback()
1097 (++) HAL_FMPI2C_ErrorCallback()
1098 (++) HAL_FMPI2C_AbortCpltCallback()
1099
1100 @endverbatim
1101 * @{
1102 */
1103
1104 /**
1105 * @brief Transmits in master mode an amount of data in blocking mode.
1106 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1107 * the configuration information for the specified FMPI2C.
1108 * @param DevAddress Target device address: The device 7 bits address value
1109 * in datasheet must be shifted to the left before calling the interface
1110 * @param pData Pointer to data buffer
1111 * @param Size Amount of data to be sent
1112 * @param Timeout Timeout duration
1113 * @retval HAL status
1114 */
HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t Timeout)1115 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1116 uint16_t Size, uint32_t Timeout)
1117 {
1118 uint32_t tickstart;
1119
1120 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1121 {
1122 /* Process Locked */
1123 __HAL_LOCK(hfmpi2c);
1124
1125 /* Init tickstart for timeout management*/
1126 tickstart = HAL_GetTick();
1127
1128 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1129 {
1130 return HAL_ERROR;
1131 }
1132
1133 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1134 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1135 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1136
1137 /* Prepare transfer parameters */
1138 hfmpi2c->pBuffPtr = pData;
1139 hfmpi2c->XferCount = Size;
1140 hfmpi2c->XferISR = NULL;
1141
1142 /* Send Slave Address */
1143 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1144 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1145 {
1146 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1147 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1148 FMPI2C_GENERATE_START_WRITE);
1149 }
1150 else
1151 {
1152 hfmpi2c->XferSize = hfmpi2c->XferCount;
1153 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1154 FMPI2C_GENERATE_START_WRITE);
1155 }
1156
1157 while (hfmpi2c->XferCount > 0U)
1158 {
1159 /* Wait until TXIS flag is set */
1160 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1161 {
1162 return HAL_ERROR;
1163 }
1164 /* Write data to TXDR */
1165 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1166
1167 /* Increment Buffer pointer */
1168 hfmpi2c->pBuffPtr++;
1169
1170 hfmpi2c->XferCount--;
1171 hfmpi2c->XferSize--;
1172
1173 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
1174 {
1175 /* Wait until TCR flag is set */
1176 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1177 {
1178 return HAL_ERROR;
1179 }
1180
1181 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1182 {
1183 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1184 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1185 FMPI2C_NO_STARTSTOP);
1186 }
1187 else
1188 {
1189 hfmpi2c->XferSize = hfmpi2c->XferCount;
1190 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1191 FMPI2C_NO_STARTSTOP);
1192 }
1193 }
1194 }
1195
1196 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1197 /* Wait until STOPF flag is set */
1198 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1199 {
1200 return HAL_ERROR;
1201 }
1202
1203 /* Clear STOP Flag */
1204 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1205
1206 /* Clear Configuration Register 2 */
1207 FMPI2C_RESET_CR2(hfmpi2c);
1208
1209 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1210 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1211
1212 /* Process Unlocked */
1213 __HAL_UNLOCK(hfmpi2c);
1214
1215 return HAL_OK;
1216 }
1217 else
1218 {
1219 return HAL_BUSY;
1220 }
1221 }
1222
1223 /**
1224 * @brief Receives in master mode an amount of data in blocking mode.
1225 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1226 * the configuration information for the specified FMPI2C.
1227 * @param DevAddress Target device address: The device 7 bits address value
1228 * in datasheet must be shifted to the left before calling the interface
1229 * @param pData Pointer to data buffer
1230 * @param Size Amount of data to be sent
1231 * @param Timeout Timeout duration
1232 * @retval HAL status
1233 */
HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t Timeout)1234 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1235 uint16_t Size, uint32_t Timeout)
1236 {
1237 uint32_t tickstart;
1238
1239 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1240 {
1241 /* Process Locked */
1242 __HAL_LOCK(hfmpi2c);
1243
1244 /* Init tickstart for timeout management*/
1245 tickstart = HAL_GetTick();
1246
1247 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
1248 {
1249 return HAL_ERROR;
1250 }
1251
1252 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1253 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1254 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1255
1256 /* Prepare transfer parameters */
1257 hfmpi2c->pBuffPtr = pData;
1258 hfmpi2c->XferCount = Size;
1259 hfmpi2c->XferISR = NULL;
1260
1261 /* Send Slave Address */
1262 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1263 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1264 {
1265 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1266 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1267 FMPI2C_GENERATE_START_READ);
1268 }
1269 else
1270 {
1271 hfmpi2c->XferSize = hfmpi2c->XferCount;
1272 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1273 FMPI2C_GENERATE_START_READ);
1274 }
1275
1276 while (hfmpi2c->XferCount > 0U)
1277 {
1278 /* Wait until RXNE flag is set */
1279 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1280 {
1281 return HAL_ERROR;
1282 }
1283
1284 /* Read data from RXDR */
1285 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1286
1287 /* Increment Buffer pointer */
1288 hfmpi2c->pBuffPtr++;
1289
1290 hfmpi2c->XferSize--;
1291 hfmpi2c->XferCount--;
1292
1293 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
1294 {
1295 /* Wait until TCR flag is set */
1296 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
1297 {
1298 return HAL_ERROR;
1299 }
1300
1301 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1302 {
1303 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1304 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
1305 FMPI2C_NO_STARTSTOP);
1306 }
1307 else
1308 {
1309 hfmpi2c->XferSize = hfmpi2c->XferCount;
1310 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1311 FMPI2C_NO_STARTSTOP);
1312 }
1313 }
1314 }
1315
1316 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1317 /* Wait until STOPF flag is set */
1318 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1319 {
1320 return HAL_ERROR;
1321 }
1322
1323 /* Clear STOP Flag */
1324 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1325
1326 /* Clear Configuration Register 2 */
1327 FMPI2C_RESET_CR2(hfmpi2c);
1328
1329 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1330 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1331
1332 /* Process Unlocked */
1333 __HAL_UNLOCK(hfmpi2c);
1334
1335 return HAL_OK;
1336 }
1337 else
1338 {
1339 return HAL_BUSY;
1340 }
1341 }
1342
1343 /**
1344 * @brief Transmits in slave mode an amount of data in blocking mode.
1345 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1346 * the configuration information for the specified FMPI2C.
1347 * @param pData Pointer to data buffer
1348 * @param Size Amount of data to be sent
1349 * @param Timeout Timeout duration
1350 * @retval HAL status
1351 */
HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t Timeout)1352 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
1353 uint32_t Timeout)
1354 {
1355 uint32_t tickstart;
1356
1357 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1358 {
1359 if ((pData == NULL) || (Size == 0U))
1360 {
1361 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
1362 return HAL_ERROR;
1363 }
1364 /* Process Locked */
1365 __HAL_LOCK(hfmpi2c);
1366
1367 /* Init tickstart for timeout management*/
1368 tickstart = HAL_GetTick();
1369
1370 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1371 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1372 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1373
1374 /* Prepare transfer parameters */
1375 hfmpi2c->pBuffPtr = pData;
1376 hfmpi2c->XferCount = Size;
1377 hfmpi2c->XferISR = NULL;
1378
1379 /* Enable Address Acknowledge */
1380 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1381
1382 /* Wait until ADDR flag is set */
1383 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1384 {
1385 /* Disable Address Acknowledge */
1386 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1387 return HAL_ERROR;
1388 }
1389
1390 /* Clear ADDR flag */
1391 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1392
1393 /* If 10bit addressing mode is selected */
1394 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
1395 {
1396 /* Wait until ADDR flag is set */
1397 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1398 {
1399 /* Disable Address Acknowledge */
1400 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1401 return HAL_ERROR;
1402 }
1403
1404 /* Clear ADDR flag */
1405 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1406 }
1407
1408 /* Wait until DIR flag is set Transmitter mode */
1409 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
1410 {
1411 /* Disable Address Acknowledge */
1412 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1413 return HAL_ERROR;
1414 }
1415
1416 while (hfmpi2c->XferCount > 0U)
1417 {
1418 /* Wait until TXIS flag is set */
1419 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1420 {
1421 /* Disable Address Acknowledge */
1422 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1423 return HAL_ERROR;
1424 }
1425
1426 /* Write data to TXDR */
1427 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
1428
1429 /* Increment Buffer pointer */
1430 hfmpi2c->pBuffPtr++;
1431
1432 hfmpi2c->XferCount--;
1433 }
1434
1435 /* Wait until STOP flag is set */
1436 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1437 {
1438 /* Disable Address Acknowledge */
1439 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1440
1441 if (hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1442 {
1443 /* Normal use case for Transmitter mode */
1444 /* A NACK is generated to confirm the end of transfer */
1445 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1446 }
1447 else
1448 {
1449 return HAL_ERROR;
1450 }
1451 }
1452
1453 /* Clear STOP flag */
1454 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1455
1456 /* Wait until BUSY flag is reset */
1457 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1458 {
1459 /* Disable Address Acknowledge */
1460 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1461 return HAL_ERROR;
1462 }
1463
1464 /* Disable Address Acknowledge */
1465 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1466
1467 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1468 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1469
1470 /* Process Unlocked */
1471 __HAL_UNLOCK(hfmpi2c);
1472
1473 return HAL_OK;
1474 }
1475 else
1476 {
1477 return HAL_BUSY;
1478 }
1479 }
1480
1481 /**
1482 * @brief Receive in slave mode an amount of data in blocking mode
1483 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1484 * the configuration information for the specified FMPI2C.
1485 * @param pData Pointer to data buffer
1486 * @param Size Amount of data to be sent
1487 * @param Timeout Timeout duration
1488 * @retval HAL status
1489 */
HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t Timeout)1490 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
1491 uint32_t Timeout)
1492 {
1493 uint32_t tickstart;
1494
1495 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1496 {
1497 if ((pData == NULL) || (Size == 0U))
1498 {
1499 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
1500 return HAL_ERROR;
1501 }
1502 /* Process Locked */
1503 __HAL_LOCK(hfmpi2c);
1504
1505 /* Init tickstart for timeout management*/
1506 tickstart = HAL_GetTick();
1507
1508 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1509 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1510 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1511
1512 /* Prepare transfer parameters */
1513 hfmpi2c->pBuffPtr = pData;
1514 hfmpi2c->XferCount = Size;
1515 hfmpi2c->XferISR = NULL;
1516
1517 /* Enable Address Acknowledge */
1518 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1519
1520 /* Wait until ADDR flag is set */
1521 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1522 {
1523 /* Disable Address Acknowledge */
1524 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1525 return HAL_ERROR;
1526 }
1527
1528 /* Clear ADDR flag */
1529 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
1530
1531 /* Wait until DIR flag is reset Receiver mode */
1532 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1533 {
1534 /* Disable Address Acknowledge */
1535 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1536 return HAL_ERROR;
1537 }
1538
1539 while (hfmpi2c->XferCount > 0U)
1540 {
1541 /* Wait until RXNE flag is set */
1542 if (FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1543 {
1544 /* Disable Address Acknowledge */
1545 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1546
1547 /* Store Last receive data if any */
1548 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
1549 {
1550 /* Read data from RXDR */
1551 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1552
1553 /* Increment Buffer pointer */
1554 hfmpi2c->pBuffPtr++;
1555
1556 hfmpi2c->XferCount--;
1557 }
1558
1559 return HAL_ERROR;
1560 }
1561
1562 /* Read data from RXDR */
1563 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
1564
1565 /* Increment Buffer pointer */
1566 hfmpi2c->pBuffPtr++;
1567
1568 hfmpi2c->XferCount--;
1569 }
1570
1571 /* Wait until STOP flag is set */
1572 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
1573 {
1574 /* Disable Address Acknowledge */
1575 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1576 return HAL_ERROR;
1577 }
1578
1579 /* Clear STOP flag */
1580 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1581
1582 /* Wait until BUSY flag is reset */
1583 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1584 {
1585 /* Disable Address Acknowledge */
1586 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1587 return HAL_ERROR;
1588 }
1589
1590 /* Disable Address Acknowledge */
1591 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1592
1593 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1594 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1595
1596 /* Process Unlocked */
1597 __HAL_UNLOCK(hfmpi2c);
1598
1599 return HAL_OK;
1600 }
1601 else
1602 {
1603 return HAL_BUSY;
1604 }
1605 }
1606
1607 /**
1608 * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt
1609 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1610 * the configuration information for the specified FMPI2C.
1611 * @param DevAddress Target device address: The device 7 bits address value
1612 * in datasheet must be shifted to the left before calling the interface
1613 * @param pData Pointer to data buffer
1614 * @param Size Amount of data to be sent
1615 * @retval HAL status
1616 */
HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1617 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1618 uint16_t Size)
1619 {
1620 uint32_t xfermode;
1621
1622 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1623 {
1624 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1625 {
1626 return HAL_BUSY;
1627 }
1628
1629 /* Process Locked */
1630 __HAL_LOCK(hfmpi2c);
1631
1632 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1633 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1634 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1635
1636 /* Prepare transfer parameters */
1637 hfmpi2c->pBuffPtr = pData;
1638 hfmpi2c->XferCount = Size;
1639 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1640 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1641
1642 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1643 {
1644 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1645 xfermode = FMPI2C_RELOAD_MODE;
1646 }
1647 else
1648 {
1649 hfmpi2c->XferSize = hfmpi2c->XferCount;
1650 xfermode = FMPI2C_AUTOEND_MODE;
1651 }
1652
1653 /* Send Slave Address */
1654 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1655 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
1656
1657 /* Process Unlocked */
1658 __HAL_UNLOCK(hfmpi2c);
1659
1660 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1661 to avoid the risk of FMPI2C interrupt handle execution before current
1662 process unlock */
1663
1664 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1665 /* possible to enable all of these */
1666 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1667 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1668 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1669
1670 return HAL_OK;
1671 }
1672 else
1673 {
1674 return HAL_BUSY;
1675 }
1676 }
1677
1678 /**
1679 * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt
1680 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1681 * the configuration information for the specified FMPI2C.
1682 * @param DevAddress Target device address: The device 7 bits address value
1683 * in datasheet must be shifted to the left before calling the interface
1684 * @param pData Pointer to data buffer
1685 * @param Size Amount of data to be sent
1686 * @retval HAL status
1687 */
HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1688 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1689 uint16_t Size)
1690 {
1691 uint32_t xfermode;
1692
1693 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1694 {
1695 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1696 {
1697 return HAL_BUSY;
1698 }
1699
1700 /* Process Locked */
1701 __HAL_LOCK(hfmpi2c);
1702
1703 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1704 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1705 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1706
1707 /* Prepare transfer parameters */
1708 hfmpi2c->pBuffPtr = pData;
1709 hfmpi2c->XferCount = Size;
1710 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1711 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1712
1713 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1714 {
1715 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1716 xfermode = FMPI2C_RELOAD_MODE;
1717 }
1718 else
1719 {
1720 hfmpi2c->XferSize = hfmpi2c->XferCount;
1721 xfermode = FMPI2C_AUTOEND_MODE;
1722 }
1723
1724 /* Send Slave Address */
1725 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
1726 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
1727
1728 /* Process Unlocked */
1729 __HAL_UNLOCK(hfmpi2c);
1730
1731 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1732 to avoid the risk of FMPI2C interrupt handle execution before current
1733 process unlock */
1734
1735 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1736 /* possible to enable all of these */
1737 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1738 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1739 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
1740
1741 return HAL_OK;
1742 }
1743 else
1744 {
1745 return HAL_BUSY;
1746 }
1747 }
1748
1749 /**
1750 * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt
1751 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1752 * the configuration information for the specified FMPI2C.
1753 * @param pData Pointer to data buffer
1754 * @param Size Amount of data to be sent
1755 * @retval HAL status
1756 */
HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size)1757 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1758 {
1759 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1760 {
1761 /* Process Locked */
1762 __HAL_LOCK(hfmpi2c);
1763
1764 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1765 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1766 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1767
1768 /* Enable Address Acknowledge */
1769 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1770
1771 /* Prepare transfer parameters */
1772 hfmpi2c->pBuffPtr = pData;
1773 hfmpi2c->XferCount = Size;
1774 hfmpi2c->XferSize = hfmpi2c->XferCount;
1775 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1776 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1777
1778 /* Process Unlocked */
1779 __HAL_UNLOCK(hfmpi2c);
1780
1781 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1782 to avoid the risk of FMPI2C interrupt handle execution before current
1783 process unlock */
1784
1785 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1786 /* possible to enable all of these */
1787 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1788 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1789 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
1790
1791 return HAL_OK;
1792 }
1793 else
1794 {
1795 return HAL_BUSY;
1796 }
1797 }
1798
1799 /**
1800 * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt
1801 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1802 * the configuration information for the specified FMPI2C.
1803 * @param pData Pointer to data buffer
1804 * @param Size Amount of data to be sent
1805 * @retval HAL status
1806 */
HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size)1807 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1808 {
1809 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1810 {
1811 /* Process Locked */
1812 __HAL_LOCK(hfmpi2c);
1813
1814 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
1815 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
1816 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1817
1818 /* Enable Address Acknowledge */
1819 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1820
1821 /* Prepare transfer parameters */
1822 hfmpi2c->pBuffPtr = pData;
1823 hfmpi2c->XferCount = Size;
1824 hfmpi2c->XferSize = hfmpi2c->XferCount;
1825 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1826 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
1827
1828 /* Process Unlocked */
1829 __HAL_UNLOCK(hfmpi2c);
1830
1831 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1832 to avoid the risk of FMPI2C interrupt handle execution before current
1833 process unlock */
1834
1835 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1836 /* possible to enable all of these */
1837 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1838 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1839 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
1840
1841 return HAL_OK;
1842 }
1843 else
1844 {
1845 return HAL_BUSY;
1846 }
1847 }
1848
1849 /**
1850 * @brief Transmit in master mode an amount of data in non-blocking mode with DMA
1851 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1852 * the configuration information for the specified FMPI2C.
1853 * @param DevAddress Target device address: The device 7 bits address value
1854 * in datasheet must be shifted to the left before calling the interface
1855 * @param pData Pointer to data buffer
1856 * @param Size Amount of data to be sent
1857 * @retval HAL status
1858 */
HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1859 HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
1860 uint16_t Size)
1861 {
1862 uint32_t xfermode;
1863 HAL_StatusTypeDef dmaxferstatus;
1864
1865 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1866 {
1867 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1868 {
1869 return HAL_BUSY;
1870 }
1871
1872 /* Process Locked */
1873 __HAL_LOCK(hfmpi2c);
1874
1875 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
1876 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
1877 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1878
1879 /* Prepare transfer parameters */
1880 hfmpi2c->pBuffPtr = pData;
1881 hfmpi2c->XferCount = Size;
1882 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
1883 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
1884
1885 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
1886 {
1887 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
1888 xfermode = FMPI2C_RELOAD_MODE;
1889 }
1890 else
1891 {
1892 hfmpi2c->XferSize = hfmpi2c->XferCount;
1893 xfermode = FMPI2C_AUTOEND_MODE;
1894 }
1895
1896 if (hfmpi2c->XferSize > 0U)
1897 {
1898 if (hfmpi2c->hdmatx != NULL)
1899 {
1900 /* Set the FMPI2C DMA transfer complete callback */
1901 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
1902
1903 /* Set the DMA error callback */
1904 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
1905
1906 /* Set the unused DMA callbacks to NULL */
1907 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
1908 hfmpi2c->hdmatx->XferAbortCallback = NULL;
1909
1910 /* Enable the DMA stream */
1911 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
1912 hfmpi2c->XferSize);
1913 }
1914 else
1915 {
1916 /* Update FMPI2C state */
1917 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1918 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1919
1920 /* Update FMPI2C error code */
1921 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
1922
1923 /* Process Unlocked */
1924 __HAL_UNLOCK(hfmpi2c);
1925
1926 return HAL_ERROR;
1927 }
1928
1929 if (dmaxferstatus == HAL_OK)
1930 {
1931 /* Send Slave Address */
1932 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
1933 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_WRITE);
1934
1935 /* Update XferCount value */
1936 hfmpi2c->XferCount -= hfmpi2c->XferSize;
1937
1938 /* Process Unlocked */
1939 __HAL_UNLOCK(hfmpi2c);
1940
1941 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1942 to avoid the risk of FMPI2C interrupt handle execution before current
1943 process unlock */
1944 /* Enable ERR and NACK interrupts */
1945 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
1946
1947 /* Enable DMA Request */
1948 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
1949 }
1950 else
1951 {
1952 /* Update FMPI2C state */
1953 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1954 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
1955
1956 /* Update FMPI2C error code */
1957 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
1958
1959 /* Process Unlocked */
1960 __HAL_UNLOCK(hfmpi2c);
1961
1962 return HAL_ERROR;
1963 }
1964 }
1965 else
1966 {
1967 /* Update Transfer ISR function pointer */
1968 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
1969
1970 /* Send Slave Address */
1971 /* Set NBYTES to write and generate START condition */
1972 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
1973 FMPI2C_GENERATE_START_WRITE);
1974
1975 /* Process Unlocked */
1976 __HAL_UNLOCK(hfmpi2c);
1977
1978 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1979 to avoid the risk of FMPI2C interrupt handle execution before current
1980 process unlock */
1981 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1982 /* possible to enable all of these */
1983 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
1984 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1985 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
1986 }
1987
1988 return HAL_OK;
1989 }
1990 else
1991 {
1992 return HAL_BUSY;
1993 }
1994 }
1995
1996 /**
1997 * @brief Receive in master mode an amount of data in non-blocking mode with DMA
1998 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
1999 * the configuration information for the specified FMPI2C.
2000 * @param DevAddress Target device address: The device 7 bits address value
2001 * in datasheet must be shifted to the left before calling the interface
2002 * @param pData Pointer to data buffer
2003 * @param Size Amount of data to be sent
2004 * @retval HAL status
2005 */
HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)2006 HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
2007 uint16_t Size)
2008 {
2009 uint32_t xfermode;
2010 HAL_StatusTypeDef dmaxferstatus;
2011
2012 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2013 {
2014 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2015 {
2016 return HAL_BUSY;
2017 }
2018
2019 /* Process Locked */
2020 __HAL_LOCK(hfmpi2c);
2021
2022 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2023 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
2024 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2025
2026 /* Prepare transfer parameters */
2027 hfmpi2c->pBuffPtr = pData;
2028 hfmpi2c->XferCount = Size;
2029 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2030 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
2031
2032 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2033 {
2034 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2035 xfermode = FMPI2C_RELOAD_MODE;
2036 }
2037 else
2038 {
2039 hfmpi2c->XferSize = hfmpi2c->XferCount;
2040 xfermode = FMPI2C_AUTOEND_MODE;
2041 }
2042
2043 if (hfmpi2c->XferSize > 0U)
2044 {
2045 if (hfmpi2c->hdmarx != NULL)
2046 {
2047 /* Set the FMPI2C DMA transfer complete callback */
2048 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
2049
2050 /* Set the DMA error callback */
2051 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2052
2053 /* Set the unused DMA callbacks to NULL */
2054 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
2055 hfmpi2c->hdmarx->XferAbortCallback = NULL;
2056
2057 /* Enable the DMA stream */
2058 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
2059 hfmpi2c->XferSize);
2060 }
2061 else
2062 {
2063 /* Update FMPI2C state */
2064 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2065 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2066
2067 /* Update FMPI2C error code */
2068 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2069
2070 /* Process Unlocked */
2071 __HAL_UNLOCK(hfmpi2c);
2072
2073 return HAL_ERROR;
2074 }
2075
2076 if (dmaxferstatus == HAL_OK)
2077 {
2078 /* Send Slave Address */
2079 /* Set NBYTES to read and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2080 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
2081
2082 /* Update XferCount value */
2083 hfmpi2c->XferCount -= hfmpi2c->XferSize;
2084
2085 /* Process Unlocked */
2086 __HAL_UNLOCK(hfmpi2c);
2087
2088 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2089 to avoid the risk of FMPI2C interrupt handle execution before current
2090 process unlock */
2091 /* Enable ERR and NACK interrupts */
2092 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2093
2094 /* Enable DMA Request */
2095 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2096 }
2097 else
2098 {
2099 /* Update FMPI2C state */
2100 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2101 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2102
2103 /* Update FMPI2C error code */
2104 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2105
2106 /* Process Unlocked */
2107 __HAL_UNLOCK(hfmpi2c);
2108
2109 return HAL_ERROR;
2110 }
2111 }
2112 else
2113 {
2114 /* Update Transfer ISR function pointer */
2115 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2116
2117 /* Send Slave Address */
2118 /* Set NBYTES to read and generate START condition */
2119 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2120 FMPI2C_GENERATE_START_READ);
2121
2122 /* Process Unlocked */
2123 __HAL_UNLOCK(hfmpi2c);
2124
2125 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2126 to avoid the risk of FMPI2C interrupt handle execution before current
2127 process unlock */
2128 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2129 /* possible to enable all of these */
2130 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2131 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2132 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2133 }
2134
2135 return HAL_OK;
2136 }
2137 else
2138 {
2139 return HAL_BUSY;
2140 }
2141 }
2142
2143 /**
2144 * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA
2145 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2146 * the configuration information for the specified FMPI2C.
2147 * @param pData Pointer to data buffer
2148 * @param Size Amount of data to be sent
2149 * @retval HAL status
2150 */
HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size)2151 HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
2152 {
2153 HAL_StatusTypeDef dmaxferstatus;
2154
2155 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2156 {
2157 if ((pData == NULL) || (Size == 0U))
2158 {
2159 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2160 return HAL_ERROR;
2161 }
2162 /* Process Locked */
2163 __HAL_LOCK(hfmpi2c);
2164
2165 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2166 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2167 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2168
2169 /* Prepare transfer parameters */
2170 hfmpi2c->pBuffPtr = pData;
2171 hfmpi2c->XferCount = Size;
2172 hfmpi2c->XferSize = hfmpi2c->XferCount;
2173 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2174 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
2175
2176 if (hfmpi2c->hdmatx != NULL)
2177 {
2178 /* Set the FMPI2C DMA transfer complete callback */
2179 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
2180
2181 /* Set the DMA error callback */
2182 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2183
2184 /* Set the unused DMA callbacks to NULL */
2185 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
2186 hfmpi2c->hdmatx->XferAbortCallback = NULL;
2187
2188 /* Enable the DMA stream */
2189 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
2190 hfmpi2c->XferSize);
2191 }
2192 else
2193 {
2194 /* Update FMPI2C state */
2195 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2196 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2197
2198 /* Update FMPI2C error code */
2199 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2200
2201 /* Process Unlocked */
2202 __HAL_UNLOCK(hfmpi2c);
2203
2204 return HAL_ERROR;
2205 }
2206
2207 if (dmaxferstatus == HAL_OK)
2208 {
2209 /* Enable Address Acknowledge */
2210 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2211
2212 /* Process Unlocked */
2213 __HAL_UNLOCK(hfmpi2c);
2214
2215 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2216 to avoid the risk of FMPI2C interrupt handle execution before current
2217 process unlock */
2218 /* Enable ERR, STOP, NACK, ADDR interrupts */
2219 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2220
2221 /* Enable DMA Request */
2222 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2223 }
2224 else
2225 {
2226 /* Update FMPI2C state */
2227 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2228 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2229
2230 /* Update FMPI2C error code */
2231 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2232
2233 /* Process Unlocked */
2234 __HAL_UNLOCK(hfmpi2c);
2235
2236 return HAL_ERROR;
2237 }
2238
2239 return HAL_OK;
2240 }
2241 else
2242 {
2243 return HAL_BUSY;
2244 }
2245 }
2246
2247 /**
2248 * @brief Receive in slave mode an amount of data in non-blocking mode with DMA
2249 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2250 * the configuration information for the specified FMPI2C.
2251 * @param pData Pointer to data buffer
2252 * @param Size Amount of data to be sent
2253 * @retval HAL status
2254 */
HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size)2255 HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
2256 {
2257 HAL_StatusTypeDef dmaxferstatus;
2258
2259 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2260 {
2261 if ((pData == NULL) || (Size == 0U))
2262 {
2263 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2264 return HAL_ERROR;
2265 }
2266 /* Process Locked */
2267 __HAL_LOCK(hfmpi2c);
2268
2269 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2270 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
2271 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2272
2273 /* Prepare transfer parameters */
2274 hfmpi2c->pBuffPtr = pData;
2275 hfmpi2c->XferCount = Size;
2276 hfmpi2c->XferSize = hfmpi2c->XferCount;
2277 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2278 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
2279
2280 if (hfmpi2c->hdmarx != NULL)
2281 {
2282 /* Set the FMPI2C DMA transfer complete callback */
2283 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
2284
2285 /* Set the DMA error callback */
2286 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2287
2288 /* Set the unused DMA callbacks to NULL */
2289 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
2290 hfmpi2c->hdmarx->XferAbortCallback = NULL;
2291
2292 /* Enable the DMA stream */
2293 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
2294 hfmpi2c->XferSize);
2295 }
2296 else
2297 {
2298 /* Update FMPI2C state */
2299 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2300 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2301
2302 /* Update FMPI2C error code */
2303 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2304
2305 /* Process Unlocked */
2306 __HAL_UNLOCK(hfmpi2c);
2307
2308 return HAL_ERROR;
2309 }
2310
2311 if (dmaxferstatus == HAL_OK)
2312 {
2313 /* Enable Address Acknowledge */
2314 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2315
2316 /* Process Unlocked */
2317 __HAL_UNLOCK(hfmpi2c);
2318
2319 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2320 to avoid the risk of FMPI2C interrupt handle execution before current
2321 process unlock */
2322 /* Enable ERR, STOP, NACK, ADDR interrupts */
2323 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
2324
2325 /* Enable DMA Request */
2326 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2327 }
2328 else
2329 {
2330 /* Update FMPI2C state */
2331 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
2332 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2333
2334 /* Update FMPI2C error code */
2335 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2336
2337 /* Process Unlocked */
2338 __HAL_UNLOCK(hfmpi2c);
2339
2340 return HAL_ERROR;
2341 }
2342
2343 return HAL_OK;
2344 }
2345 else
2346 {
2347 return HAL_BUSY;
2348 }
2349 }
2350 /**
2351 * @brief Write an amount of data in blocking mode to a specific memory address
2352 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2353 * the configuration information for the specified FMPI2C.
2354 * @param DevAddress Target device address: The device 7 bits address value
2355 * in datasheet must be shifted to the left before calling the interface
2356 * @param MemAddress Internal memory address
2357 * @param MemAddSize Size of internal memory address
2358 * @param pData Pointer to data buffer
2359 * @param Size Amount of data to be sent
2360 * @param Timeout Timeout duration
2361 * @retval HAL status
2362 */
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)2363 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2364 uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2365 {
2366 uint32_t tickstart;
2367
2368 /* Check the parameters */
2369 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2370
2371 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2372 {
2373 if ((pData == NULL) || (Size == 0U))
2374 {
2375 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2376 return HAL_ERROR;
2377 }
2378
2379 /* Process Locked */
2380 __HAL_LOCK(hfmpi2c);
2381
2382 /* Init tickstart for timeout management*/
2383 tickstart = HAL_GetTick();
2384
2385 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2386 {
2387 return HAL_ERROR;
2388 }
2389
2390 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2391 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2392 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2393
2394 /* Prepare transfer parameters */
2395 hfmpi2c->pBuffPtr = pData;
2396 hfmpi2c->XferCount = Size;
2397 hfmpi2c->XferISR = NULL;
2398
2399 /* Send Slave Address and Memory Address */
2400 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2401 {
2402 /* Process Unlocked */
2403 __HAL_UNLOCK(hfmpi2c);
2404 return HAL_ERROR;
2405 }
2406
2407 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE */
2408 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2409 {
2410 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2411 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
2412 }
2413 else
2414 {
2415 hfmpi2c->XferSize = hfmpi2c->XferCount;
2416 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
2417 }
2418
2419 do
2420 {
2421 /* Wait until TXIS flag is set */
2422 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2423 {
2424 return HAL_ERROR;
2425 }
2426
2427 /* Write data to TXDR */
2428 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
2429
2430 /* Increment Buffer pointer */
2431 hfmpi2c->pBuffPtr++;
2432
2433 hfmpi2c->XferCount--;
2434 hfmpi2c->XferSize--;
2435
2436 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
2437 {
2438 /* Wait until TCR flag is set */
2439 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2440 {
2441 return HAL_ERROR;
2442 }
2443
2444 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2445 {
2446 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2447 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2448 FMPI2C_NO_STARTSTOP);
2449 }
2450 else
2451 {
2452 hfmpi2c->XferSize = hfmpi2c->XferCount;
2453 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2454 FMPI2C_NO_STARTSTOP);
2455 }
2456 }
2457
2458 } while (hfmpi2c->XferCount > 0U);
2459
2460 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2461 /* Wait until STOPF flag is reset */
2462 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2463 {
2464 return HAL_ERROR;
2465 }
2466
2467 /* Clear STOP Flag */
2468 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2469
2470 /* Clear Configuration Register 2 */
2471 FMPI2C_RESET_CR2(hfmpi2c);
2472
2473 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2474 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2475
2476 /* Process Unlocked */
2477 __HAL_UNLOCK(hfmpi2c);
2478
2479 return HAL_OK;
2480 }
2481 else
2482 {
2483 return HAL_BUSY;
2484 }
2485 }
2486
2487 /**
2488 * @brief Read an amount of data in blocking mode from a specific memory address
2489 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2490 * the configuration information for the specified FMPI2C.
2491 * @param DevAddress Target device address: The device 7 bits address value
2492 * in datasheet must be shifted to the left before calling the interface
2493 * @param MemAddress Internal memory address
2494 * @param MemAddSize Size of internal memory address
2495 * @param pData Pointer to data buffer
2496 * @param Size Amount of data to be sent
2497 * @param Timeout Timeout duration
2498 * @retval HAL status
2499 */
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)2500 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2501 uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2502 {
2503 uint32_t tickstart;
2504
2505 /* Check the parameters */
2506 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2507
2508 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2509 {
2510 if ((pData == NULL) || (Size == 0U))
2511 {
2512 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2513 return HAL_ERROR;
2514 }
2515
2516 /* Process Locked */
2517 __HAL_LOCK(hfmpi2c);
2518
2519 /* Init tickstart for timeout management*/
2520 tickstart = HAL_GetTick();
2521
2522 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2523 {
2524 return HAL_ERROR;
2525 }
2526
2527 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2528 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2529 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2530
2531 /* Prepare transfer parameters */
2532 hfmpi2c->pBuffPtr = pData;
2533 hfmpi2c->XferCount = Size;
2534 hfmpi2c->XferISR = NULL;
2535
2536 /* Send Slave Address and Memory Address */
2537 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2538 {
2539 /* Process Unlocked */
2540 __HAL_UNLOCK(hfmpi2c);
2541 return HAL_ERROR;
2542 }
2543
2544 /* Send Slave Address */
2545 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2546 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2547 {
2548 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2549 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2550 FMPI2C_GENERATE_START_READ);
2551 }
2552 else
2553 {
2554 hfmpi2c->XferSize = hfmpi2c->XferCount;
2555 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2556 FMPI2C_GENERATE_START_READ);
2557 }
2558
2559 do
2560 {
2561 /* Wait until RXNE flag is set */
2562 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
2563 {
2564 return HAL_ERROR;
2565 }
2566
2567 /* Read data from RXDR */
2568 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
2569
2570 /* Increment Buffer pointer */
2571 hfmpi2c->pBuffPtr++;
2572
2573 hfmpi2c->XferSize--;
2574 hfmpi2c->XferCount--;
2575
2576 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
2577 {
2578 /* Wait until TCR flag is set */
2579 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2580 {
2581 return HAL_ERROR;
2582 }
2583
2584 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2585 {
2586 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2587 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t) hfmpi2c->XferSize, FMPI2C_RELOAD_MODE,
2588 FMPI2C_NO_STARTSTOP);
2589 }
2590 else
2591 {
2592 hfmpi2c->XferSize = hfmpi2c->XferCount;
2593 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
2594 FMPI2C_NO_STARTSTOP);
2595 }
2596 }
2597 } while (hfmpi2c->XferCount > 0U);
2598
2599 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2600 /* Wait until STOPF flag is reset */
2601 if (FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout, tickstart) != HAL_OK)
2602 {
2603 return HAL_ERROR;
2604 }
2605
2606 /* Clear STOP Flag */
2607 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2608
2609 /* Clear Configuration Register 2 */
2610 FMPI2C_RESET_CR2(hfmpi2c);
2611
2612 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2613 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2614
2615 /* Process Unlocked */
2616 __HAL_UNLOCK(hfmpi2c);
2617
2618 return HAL_OK;
2619 }
2620 else
2621 {
2622 return HAL_BUSY;
2623 }
2624 }
2625 /**
2626 * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address
2627 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2628 * the configuration information for the specified FMPI2C.
2629 * @param DevAddress Target device address: The device 7 bits address value
2630 * in datasheet must be shifted to the left before calling the interface
2631 * @param MemAddress Internal memory address
2632 * @param MemAddSize Size of internal memory address
2633 * @param pData Pointer to data buffer
2634 * @param Size Amount of data to be sent
2635 * @retval HAL status
2636 */
HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2637 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2638 uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2639 {
2640 uint32_t tickstart;
2641 uint32_t xfermode;
2642
2643 /* Check the parameters */
2644 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2645
2646 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2647 {
2648 if ((pData == NULL) || (Size == 0U))
2649 {
2650 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2651 return HAL_ERROR;
2652 }
2653
2654 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2655 {
2656 return HAL_BUSY;
2657 }
2658
2659 /* Process Locked */
2660 __HAL_LOCK(hfmpi2c);
2661
2662 /* Init tickstart for timeout management*/
2663 tickstart = HAL_GetTick();
2664
2665 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2666 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2667 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2668
2669 /* Prepare transfer parameters */
2670 hfmpi2c->pBuffPtr = pData;
2671 hfmpi2c->XferCount = Size;
2672 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2673 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2674
2675 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2676 {
2677 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2678 xfermode = FMPI2C_RELOAD_MODE;
2679 }
2680 else
2681 {
2682 hfmpi2c->XferSize = hfmpi2c->XferCount;
2683 xfermode = FMPI2C_AUTOEND_MODE;
2684 }
2685
2686 /* Send Slave Address and Memory Address */
2687 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart)
2688 != HAL_OK)
2689 {
2690 /* Process Unlocked */
2691 __HAL_UNLOCK(hfmpi2c);
2692 return HAL_ERROR;
2693 }
2694
2695 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2696 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
2697
2698 /* Process Unlocked */
2699 __HAL_UNLOCK(hfmpi2c);
2700
2701 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2702 to avoid the risk of FMPI2C interrupt handle execution before current
2703 process unlock */
2704
2705 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2706 /* possible to enable all of these */
2707 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2708 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2709 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
2710
2711 return HAL_OK;
2712 }
2713 else
2714 {
2715 return HAL_BUSY;
2716 }
2717 }
2718
2719 /**
2720 * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address
2721 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2722 * the configuration information for the specified FMPI2C.
2723 * @param DevAddress Target device address: The device 7 bits address value
2724 * in datasheet must be shifted to the left before calling the interface
2725 * @param MemAddress Internal memory address
2726 * @param MemAddSize Size of internal memory address
2727 * @param pData Pointer to data buffer
2728 * @param Size Amount of data to be sent
2729 * @retval HAL status
2730 */
HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2731 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2732 uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2733 {
2734 uint32_t tickstart;
2735 uint32_t xfermode;
2736
2737 /* Check the parameters */
2738 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2739
2740 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2741 {
2742 if ((pData == NULL) || (Size == 0U))
2743 {
2744 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2745 return HAL_ERROR;
2746 }
2747
2748 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2749 {
2750 return HAL_BUSY;
2751 }
2752
2753 /* Process Locked */
2754 __HAL_LOCK(hfmpi2c);
2755
2756 /* Init tickstart for timeout management*/
2757 tickstart = HAL_GetTick();
2758
2759 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
2760 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2761 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2762
2763 /* Prepare transfer parameters */
2764 hfmpi2c->pBuffPtr = pData;
2765 hfmpi2c->XferCount = Size;
2766 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2767 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
2768
2769 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2770 {
2771 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2772 xfermode = FMPI2C_RELOAD_MODE;
2773 }
2774 else
2775 {
2776 hfmpi2c->XferSize = hfmpi2c->XferCount;
2777 xfermode = FMPI2C_AUTOEND_MODE;
2778 }
2779
2780 /* Send Slave Address and Memory Address */
2781 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
2782 {
2783 /* Process Unlocked */
2784 __HAL_UNLOCK(hfmpi2c);
2785 return HAL_ERROR;
2786 }
2787
2788 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2789 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
2790
2791 /* Process Unlocked */
2792 __HAL_UNLOCK(hfmpi2c);
2793
2794 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2795 to avoid the risk of FMPI2C interrupt handle execution before current
2796 process unlock */
2797
2798 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2799 /* possible to enable all of these */
2800 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
2801 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
2802 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
2803
2804 return HAL_OK;
2805 }
2806 else
2807 {
2808 return HAL_BUSY;
2809 }
2810 }
2811 /**
2812 * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address
2813 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2814 * the configuration information for the specified FMPI2C.
2815 * @param DevAddress Target device address: The device 7 bits address value
2816 * in datasheet must be shifted to the left before calling the interface
2817 * @param MemAddress Internal memory address
2818 * @param MemAddSize Size of internal memory address
2819 * @param pData Pointer to data buffer
2820 * @param Size Amount of data to be sent
2821 * @retval HAL status
2822 */
HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2823 HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2824 uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2825 {
2826 uint32_t tickstart;
2827 uint32_t xfermode;
2828 HAL_StatusTypeDef dmaxferstatus;
2829
2830 /* Check the parameters */
2831 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2832
2833 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2834 {
2835 if ((pData == NULL) || (Size == 0U))
2836 {
2837 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2838 return HAL_ERROR;
2839 }
2840
2841 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2842 {
2843 return HAL_BUSY;
2844 }
2845
2846 /* Process Locked */
2847 __HAL_LOCK(hfmpi2c);
2848
2849 /* Init tickstart for timeout management*/
2850 tickstart = HAL_GetTick();
2851
2852 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
2853 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
2854 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2855
2856 /* Prepare transfer parameters */
2857 hfmpi2c->pBuffPtr = pData;
2858 hfmpi2c->XferCount = Size;
2859 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
2860 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
2861
2862 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
2863 {
2864 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
2865 xfermode = FMPI2C_RELOAD_MODE;
2866 }
2867 else
2868 {
2869 hfmpi2c->XferSize = hfmpi2c->XferCount;
2870 xfermode = FMPI2C_AUTOEND_MODE;
2871 }
2872
2873 /* Send Slave Address and Memory Address */
2874 if (FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart)
2875 != HAL_OK)
2876 {
2877 /* Process Unlocked */
2878 __HAL_UNLOCK(hfmpi2c);
2879 return HAL_ERROR;
2880 }
2881
2882
2883 if (hfmpi2c->hdmatx != NULL)
2884 {
2885 /* Set the FMPI2C DMA transfer complete callback */
2886 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
2887
2888 /* Set the DMA error callback */
2889 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2890
2891 /* Set the unused DMA callbacks to NULL */
2892 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
2893 hfmpi2c->hdmatx->XferAbortCallback = NULL;
2894
2895 /* Enable the DMA stream */
2896 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
2897 hfmpi2c->XferSize);
2898 }
2899 else
2900 {
2901 /* Update FMPI2C state */
2902 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2903 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2904
2905 /* Update FMPI2C error code */
2906 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
2907
2908 /* Process Unlocked */
2909 __HAL_UNLOCK(hfmpi2c);
2910
2911 return HAL_ERROR;
2912 }
2913
2914 if (dmaxferstatus == HAL_OK)
2915 {
2916 /* Send Slave Address */
2917 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2918 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
2919
2920 /* Update XferCount value */
2921 hfmpi2c->XferCount -= hfmpi2c->XferSize;
2922
2923 /* Process Unlocked */
2924 __HAL_UNLOCK(hfmpi2c);
2925
2926 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
2927 to avoid the risk of FMPI2C interrupt handle execution before current
2928 process unlock */
2929 /* Enable ERR and NACK interrupts */
2930 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
2931
2932 /* Enable DMA Request */
2933 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2934 }
2935 else
2936 {
2937 /* Update FMPI2C state */
2938 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2939 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
2940
2941 /* Update FMPI2C error code */
2942 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
2943
2944 /* Process Unlocked */
2945 __HAL_UNLOCK(hfmpi2c);
2946
2947 return HAL_ERROR;
2948 }
2949
2950 return HAL_OK;
2951 }
2952 else
2953 {
2954 return HAL_BUSY;
2955 }
2956 }
2957
2958 /**
2959 * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address.
2960 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
2961 * the configuration information for the specified FMPI2C.
2962 * @param DevAddress Target device address: The device 7 bits address value
2963 * in datasheet must be shifted to the left before calling the interface
2964 * @param MemAddress Internal memory address
2965 * @param MemAddSize Size of internal memory address
2966 * @param pData Pointer to data buffer
2967 * @param Size Amount of data to be read
2968 * @retval HAL status
2969 */
HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2970 HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress,
2971 uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2972 {
2973 uint32_t tickstart;
2974 uint32_t xfermode;
2975 HAL_StatusTypeDef dmaxferstatus;
2976
2977 /* Check the parameters */
2978 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2979
2980 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2981 {
2982 if ((pData == NULL) || (Size == 0U))
2983 {
2984 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
2985 return HAL_ERROR;
2986 }
2987
2988 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2989 {
2990 return HAL_BUSY;
2991 }
2992
2993 /* Process Locked */
2994 __HAL_LOCK(hfmpi2c);
2995
2996 /* Init tickstart for timeout management*/
2997 tickstart = HAL_GetTick();
2998
2999 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3000 hfmpi2c->Mode = HAL_FMPI2C_MODE_MEM;
3001 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3002
3003 /* Prepare transfer parameters */
3004 hfmpi2c->pBuffPtr = pData;
3005 hfmpi2c->XferCount = Size;
3006 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
3007 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
3008
3009 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3010 {
3011 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3012 xfermode = FMPI2C_RELOAD_MODE;
3013 }
3014 else
3015 {
3016 hfmpi2c->XferSize = hfmpi2c->XferCount;
3017 xfermode = FMPI2C_AUTOEND_MODE;
3018 }
3019
3020 /* Send Slave Address and Memory Address */
3021 if (FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG, tickstart) != HAL_OK)
3022 {
3023 /* Process Unlocked */
3024 __HAL_UNLOCK(hfmpi2c);
3025 return HAL_ERROR;
3026 }
3027
3028 if (hfmpi2c->hdmarx != NULL)
3029 {
3030 /* Set the FMPI2C DMA transfer complete callback */
3031 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
3032
3033 /* Set the DMA error callback */
3034 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
3035
3036 /* Set the unused DMA callbacks to NULL */
3037 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
3038 hfmpi2c->hdmarx->XferAbortCallback = NULL;
3039
3040 /* Enable the DMA stream */
3041 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
3042 hfmpi2c->XferSize);
3043 }
3044 else
3045 {
3046 /* Update FMPI2C state */
3047 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3048 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3049
3050 /* Update FMPI2C error code */
3051 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3052
3053 /* Process Unlocked */
3054 __HAL_UNLOCK(hfmpi2c);
3055
3056 return HAL_ERROR;
3057 }
3058
3059 if (dmaxferstatus == HAL_OK)
3060 {
3061 /* Set NBYTES to write and reload if hfmpi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
3062 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_GENERATE_START_READ);
3063
3064 /* Update XferCount value */
3065 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3066
3067 /* Process Unlocked */
3068 __HAL_UNLOCK(hfmpi2c);
3069
3070 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3071 to avoid the risk of FMPI2C interrupt handle execution before current
3072 process unlock */
3073 /* Enable ERR and NACK interrupts */
3074 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
3075
3076 /* Enable DMA Request */
3077 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3078 }
3079 else
3080 {
3081 /* Update FMPI2C state */
3082 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3083 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3084
3085 /* Update FMPI2C error code */
3086 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3087
3088 /* Process Unlocked */
3089 __HAL_UNLOCK(hfmpi2c);
3090
3091 return HAL_ERROR;
3092 }
3093
3094 return HAL_OK;
3095 }
3096 else
3097 {
3098 return HAL_BUSY;
3099 }
3100 }
3101
3102 /**
3103 * @brief Checks if target device is ready for communication.
3104 * @note This function is used with Memory devices
3105 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3106 * the configuration information for the specified FMPI2C.
3107 * @param DevAddress Target device address: The device 7 bits address value
3108 * in datasheet must be shifted to the left before calling the interface
3109 * @param Trials Number of trials
3110 * @param Timeout Timeout duration
3111 * @retval HAL status
3112 */
HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)3113 HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials,
3114 uint32_t Timeout)
3115 {
3116 uint32_t tickstart;
3117
3118 __IO uint32_t FMPI2C_Trials = 0UL;
3119
3120 FlagStatus tmp1;
3121 FlagStatus tmp2;
3122
3123 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3124 {
3125 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
3126 {
3127 return HAL_BUSY;
3128 }
3129
3130 /* Process Locked */
3131 __HAL_LOCK(hfmpi2c);
3132
3133 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
3134 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3135
3136 do
3137 {
3138 /* Generate Start */
3139 hfmpi2c->Instance->CR2 = FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode, DevAddress);
3140
3141 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3142 /* Wait until STOPF flag is set or a NACK flag is set*/
3143 tickstart = HAL_GetTick();
3144
3145 tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3146 tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3147
3148 while ((tmp1 == RESET) && (tmp2 == RESET))
3149 {
3150 if (Timeout != HAL_MAX_DELAY)
3151 {
3152 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3153 {
3154 /* Update FMPI2C state */
3155 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3156
3157 /* Update FMPI2C error code */
3158 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3159
3160 /* Process Unlocked */
3161 __HAL_UNLOCK(hfmpi2c);
3162
3163 return HAL_ERROR;
3164 }
3165 }
3166
3167 tmp1 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3168 tmp2 = __HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3169 }
3170
3171 /* Check if the NACKF flag has not been set */
3172 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
3173 {
3174 /* Wait until STOPF flag is reset */
3175 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3176 {
3177 return HAL_ERROR;
3178 }
3179
3180 /* Clear STOP Flag */
3181 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3182
3183 /* Device is ready */
3184 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3185
3186 /* Process Unlocked */
3187 __HAL_UNLOCK(hfmpi2c);
3188
3189 return HAL_OK;
3190 }
3191 else
3192 {
3193 /* Wait until STOPF flag is reset */
3194 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3195 {
3196 return HAL_ERROR;
3197 }
3198
3199 /* Clear NACK Flag */
3200 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
3201
3202 /* Clear STOP Flag, auto generated with autoend*/
3203 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3204 }
3205
3206 /* Check if the maximum allowed number of trials has been reached */
3207 if (FMPI2C_Trials == Trials)
3208 {
3209 /* Generate Stop */
3210 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
3211
3212 /* Wait until STOPF flag is reset */
3213 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3214 {
3215 return HAL_ERROR;
3216 }
3217
3218 /* Clear STOP Flag */
3219 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3220 }
3221
3222 /* Increment Trials */
3223 FMPI2C_Trials++;
3224 } while (FMPI2C_Trials < Trials);
3225
3226 /* Update FMPI2C state */
3227 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3228
3229 /* Update FMPI2C error code */
3230 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3231
3232 /* Process Unlocked */
3233 __HAL_UNLOCK(hfmpi2c);
3234
3235 return HAL_ERROR;
3236 }
3237 else
3238 {
3239 return HAL_BUSY;
3240 }
3241 }
3242
3243 /**
3244 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with Interrupt.
3245 * @note This interface allow to manage repeated start condition when a direction change during transfer
3246 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3247 * the configuration information for the specified FMPI2C.
3248 * @param DevAddress Target device address: The device 7 bits address value
3249 * in datasheet must be shifted to the left before calling the interface
3250 * @param pData Pointer to data buffer
3251 * @param Size Amount of data to be sent
3252 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3253 * @retval HAL status
3254 */
HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3255 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3256 uint16_t Size, uint32_t XferOptions)
3257 {
3258 uint32_t xfermode;
3259 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
3260
3261 /* Check the parameters */
3262 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3263
3264 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3265 {
3266 /* Process Locked */
3267 __HAL_LOCK(hfmpi2c);
3268
3269 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
3270 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3271 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3272
3273 /* Prepare transfer parameters */
3274 hfmpi2c->pBuffPtr = pData;
3275 hfmpi2c->XferCount = Size;
3276 hfmpi2c->XferOptions = XferOptions;
3277 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3278
3279 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3280 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3281 {
3282 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3283 xfermode = FMPI2C_RELOAD_MODE;
3284 }
3285 else
3286 {
3287 hfmpi2c->XferSize = hfmpi2c->XferCount;
3288 xfermode = hfmpi2c->XferOptions;
3289 }
3290
3291 /* If transfer direction not change and there is no request to start another frame,
3292 do not generate Restart Condition */
3293 /* Mean Previous state is same as current state */
3294 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
3295 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3296 {
3297 xferrequest = FMPI2C_NO_STARTSTOP;
3298 }
3299 else
3300 {
3301 /* Convert OTHER_xxx XferOptions if any */
3302 FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3303
3304 /* Update xfermode accordingly if no reload is necessary */
3305 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3306 {
3307 xfermode = hfmpi2c->XferOptions;
3308 }
3309 }
3310
3311 /* Send Slave Address and set NBYTES to write */
3312 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3313
3314 /* Process Unlocked */
3315 __HAL_UNLOCK(hfmpi2c);
3316
3317 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3318 to avoid the risk of FMPI2C interrupt handle execution before current
3319 process unlock */
3320 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3321
3322 return HAL_OK;
3323 }
3324 else
3325 {
3326 return HAL_BUSY;
3327 }
3328 }
3329
3330 /**
3331 * @brief Sequential transmit in master FMPI2C mode an amount of data in non-blocking mode with DMA.
3332 * @note This interface allow to manage repeated start condition when a direction change during transfer
3333 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3334 * the configuration information for the specified FMPI2C.
3335 * @param DevAddress Target device address: The device 7 bits address value
3336 * in datasheet must be shifted to the left before calling the interface
3337 * @param pData Pointer to data buffer
3338 * @param Size Amount of data to be sent
3339 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3340 * @retval HAL status
3341 */
HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3342 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3343 uint16_t Size, uint32_t XferOptions)
3344 {
3345 uint32_t xfermode;
3346 uint32_t xferrequest = FMPI2C_GENERATE_START_WRITE;
3347 HAL_StatusTypeDef dmaxferstatus;
3348
3349 /* Check the parameters */
3350 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3351
3352 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3353 {
3354 /* Process Locked */
3355 __HAL_LOCK(hfmpi2c);
3356
3357 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX;
3358 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3359 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3360
3361 /* Prepare transfer parameters */
3362 hfmpi2c->pBuffPtr = pData;
3363 hfmpi2c->XferCount = Size;
3364 hfmpi2c->XferOptions = XferOptions;
3365 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
3366
3367 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3368 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3369 {
3370 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3371 xfermode = FMPI2C_RELOAD_MODE;
3372 }
3373 else
3374 {
3375 hfmpi2c->XferSize = hfmpi2c->XferCount;
3376 xfermode = hfmpi2c->XferOptions;
3377 }
3378
3379 /* If transfer direction not change and there is no request to start another frame,
3380 do not generate Restart Condition */
3381 /* Mean Previous state is same as current state */
3382 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_TX) && \
3383 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3384 {
3385 xferrequest = FMPI2C_NO_STARTSTOP;
3386 }
3387 else
3388 {
3389 /* Convert OTHER_xxx XferOptions if any */
3390 FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3391
3392 /* Update xfermode accordingly if no reload is necessary */
3393 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3394 {
3395 xfermode = hfmpi2c->XferOptions;
3396 }
3397 }
3398
3399 if (hfmpi2c->XferSize > 0U)
3400 {
3401 if (hfmpi2c->hdmatx != NULL)
3402 {
3403 /* Set the FMPI2C DMA transfer complete callback */
3404 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
3405
3406 /* Set the DMA error callback */
3407 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
3408
3409 /* Set the unused DMA callbacks to NULL */
3410 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
3411 hfmpi2c->hdmatx->XferAbortCallback = NULL;
3412
3413 /* Enable the DMA stream */
3414 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
3415 hfmpi2c->XferSize);
3416 }
3417 else
3418 {
3419 /* Update FMPI2C state */
3420 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3421 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3422
3423 /* Update FMPI2C error code */
3424 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3425
3426 /* Process Unlocked */
3427 __HAL_UNLOCK(hfmpi2c);
3428
3429 return HAL_ERROR;
3430 }
3431
3432 if (dmaxferstatus == HAL_OK)
3433 {
3434 /* Send Slave Address and set NBYTES to write */
3435 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3436
3437 /* Update XferCount value */
3438 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3439
3440 /* Process Unlocked */
3441 __HAL_UNLOCK(hfmpi2c);
3442
3443 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3444 to avoid the risk of FMPI2C interrupt handle execution before current
3445 process unlock */
3446 /* Enable ERR and NACK interrupts */
3447 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
3448
3449 /* Enable DMA Request */
3450 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
3451 }
3452 else
3453 {
3454 /* Update FMPI2C state */
3455 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3456 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3457
3458 /* Update FMPI2C error code */
3459 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3460
3461 /* Process Unlocked */
3462 __HAL_UNLOCK(hfmpi2c);
3463
3464 return HAL_ERROR;
3465 }
3466 }
3467 else
3468 {
3469 /* Update Transfer ISR function pointer */
3470 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3471
3472 /* Send Slave Address */
3473 /* Set NBYTES to write and generate START condition */
3474 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
3475 FMPI2C_GENERATE_START_WRITE);
3476
3477 /* Process Unlocked */
3478 __HAL_UNLOCK(hfmpi2c);
3479
3480 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3481 to avoid the risk of FMPI2C interrupt handle execution before current
3482 process unlock */
3483 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3484 /* possible to enable all of these */
3485 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3486 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3487 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3488 }
3489
3490 return HAL_OK;
3491 }
3492 else
3493 {
3494 return HAL_BUSY;
3495 }
3496 }
3497
3498 /**
3499 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with Interrupt
3500 * @note This interface allow to manage repeated start condition when a direction change during transfer
3501 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3502 * the configuration information for the specified FMPI2C.
3503 * @param DevAddress Target device address: The device 7 bits address value
3504 * in datasheet must be shifted to the left before calling the interface
3505 * @param pData Pointer to data buffer
3506 * @param Size Amount of data to be sent
3507 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3508 * @retval HAL status
3509 */
HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3510 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3511 uint16_t Size, uint32_t XferOptions)
3512 {
3513 uint32_t xfermode;
3514 uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
3515
3516 /* Check the parameters */
3517 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3518
3519 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3520 {
3521 /* Process Locked */
3522 __HAL_LOCK(hfmpi2c);
3523
3524 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3525 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3526 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3527
3528 /* Prepare transfer parameters */
3529 hfmpi2c->pBuffPtr = pData;
3530 hfmpi2c->XferCount = Size;
3531 hfmpi2c->XferOptions = XferOptions;
3532 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3533
3534 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3535 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3536 {
3537 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3538 xfermode = FMPI2C_RELOAD_MODE;
3539 }
3540 else
3541 {
3542 hfmpi2c->XferSize = hfmpi2c->XferCount;
3543 xfermode = hfmpi2c->XferOptions;
3544 }
3545
3546 /* If transfer direction not change and there is no request to start another frame,
3547 do not generate Restart Condition */
3548 /* Mean Previous state is same as current state */
3549 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
3550 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3551 {
3552 xferrequest = FMPI2C_NO_STARTSTOP;
3553 }
3554 else
3555 {
3556 /* Convert OTHER_xxx XferOptions if any */
3557 FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3558
3559 /* Update xfermode accordingly if no reload is necessary */
3560 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3561 {
3562 xfermode = hfmpi2c->XferOptions;
3563 }
3564 }
3565
3566 /* Send Slave Address and set NBYTES to read */
3567 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3568
3569 /* Process Unlocked */
3570 __HAL_UNLOCK(hfmpi2c);
3571
3572 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3573 to avoid the risk of FMPI2C interrupt handle execution before current
3574 process unlock */
3575 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3576
3577 return HAL_OK;
3578 }
3579 else
3580 {
3581 return HAL_BUSY;
3582 }
3583 }
3584
3585 /**
3586 * @brief Sequential receive in master FMPI2C mode an amount of data in non-blocking mode with DMA
3587 * @note This interface allow to manage repeated start condition when a direction change during transfer
3588 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3589 * the configuration information for the specified FMPI2C.
3590 * @param DevAddress Target device address: The device 7 bits address value
3591 * in datasheet must be shifted to the left before calling the interface
3592 * @param pData Pointer to data buffer
3593 * @param Size Amount of data to be sent
3594 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3595 * @retval HAL status
3596 */
HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3597 HAL_StatusTypeDef HAL_FMPI2C_Master_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData,
3598 uint16_t Size, uint32_t XferOptions)
3599 {
3600 uint32_t xfermode;
3601 uint32_t xferrequest = FMPI2C_GENERATE_START_READ;
3602 HAL_StatusTypeDef dmaxferstatus;
3603
3604 /* Check the parameters */
3605 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3606
3607 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
3608 {
3609 /* Process Locked */
3610 __HAL_LOCK(hfmpi2c);
3611
3612 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX;
3613 hfmpi2c->Mode = HAL_FMPI2C_MODE_MASTER;
3614 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3615
3616 /* Prepare transfer parameters */
3617 hfmpi2c->pBuffPtr = pData;
3618 hfmpi2c->XferCount = Size;
3619 hfmpi2c->XferOptions = XferOptions;
3620 hfmpi2c->XferISR = FMPI2C_Master_ISR_DMA;
3621
3622 /* If hfmpi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3623 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
3624 {
3625 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
3626 xfermode = FMPI2C_RELOAD_MODE;
3627 }
3628 else
3629 {
3630 hfmpi2c->XferSize = hfmpi2c->XferCount;
3631 xfermode = hfmpi2c->XferOptions;
3632 }
3633
3634 /* If transfer direction not change and there is no request to start another frame,
3635 do not generate Restart Condition */
3636 /* Mean Previous state is same as current state */
3637 if ((hfmpi2c->PreviousState == FMPI2C_STATE_MASTER_BUSY_RX) && \
3638 (IS_FMPI2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3639 {
3640 xferrequest = FMPI2C_NO_STARTSTOP;
3641 }
3642 else
3643 {
3644 /* Convert OTHER_xxx XferOptions if any */
3645 FMPI2C_ConvertOtherXferOptions(hfmpi2c);
3646
3647 /* Update xfermode accordingly if no reload is necessary */
3648 if (hfmpi2c->XferCount <= MAX_NBYTE_SIZE)
3649 {
3650 xfermode = hfmpi2c->XferOptions;
3651 }
3652 }
3653
3654 if (hfmpi2c->XferSize > 0U)
3655 {
3656 if (hfmpi2c->hdmarx != NULL)
3657 {
3658 /* Set the FMPI2C DMA transfer complete callback */
3659 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
3660
3661 /* Set the DMA error callback */
3662 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
3663
3664 /* Set the unused DMA callbacks to NULL */
3665 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
3666 hfmpi2c->hdmarx->XferAbortCallback = NULL;
3667
3668 /* Enable the DMA stream */
3669 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData,
3670 hfmpi2c->XferSize);
3671 }
3672 else
3673 {
3674 /* Update FMPI2C state */
3675 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3676 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3677
3678 /* Update FMPI2C error code */
3679 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3680
3681 /* Process Unlocked */
3682 __HAL_UNLOCK(hfmpi2c);
3683
3684 return HAL_ERROR;
3685 }
3686
3687 if (dmaxferstatus == HAL_OK)
3688 {
3689 /* Send Slave Address and set NBYTES to read */
3690 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, xfermode, xferrequest);
3691
3692 /* Update XferCount value */
3693 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3694
3695 /* Process Unlocked */
3696 __HAL_UNLOCK(hfmpi2c);
3697
3698 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3699 to avoid the risk of FMPI2C interrupt handle execution before current
3700 process unlock */
3701 /* Enable ERR and NACK interrupts */
3702 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_ERROR_IT);
3703
3704 /* Enable DMA Request */
3705 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3706 }
3707 else
3708 {
3709 /* Update FMPI2C state */
3710 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3711 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3712
3713 /* Update FMPI2C error code */
3714 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3715
3716 /* Process Unlocked */
3717 __HAL_UNLOCK(hfmpi2c);
3718
3719 return HAL_ERROR;
3720 }
3721 }
3722 else
3723 {
3724 /* Update Transfer ISR function pointer */
3725 hfmpi2c->XferISR = FMPI2C_Master_ISR_IT;
3726
3727 /* Send Slave Address */
3728 /* Set NBYTES to read and generate START condition */
3729 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE,
3730 FMPI2C_GENERATE_START_READ);
3731
3732 /* Process Unlocked */
3733 __HAL_UNLOCK(hfmpi2c);
3734
3735 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3736 to avoid the risk of FMPI2C interrupt handle execution before current
3737 process unlock */
3738 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3739 /* possible to enable all of these */
3740 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI |
3741 FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
3742 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
3743 }
3744
3745 return HAL_OK;
3746 }
3747 else
3748 {
3749 return HAL_BUSY;
3750 }
3751 }
3752
3753 /**
3754 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
3755 * @note This interface allow to manage repeated start condition when a direction change during transfer
3756 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3757 * the configuration information for the specified FMPI2C.
3758 * @param pData Pointer to data buffer
3759 * @param Size Amount of data to be sent
3760 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3761 * @retval HAL status
3762 */
HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3763 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
3764 uint32_t XferOptions)
3765 {
3766 /* Check the parameters */
3767 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3768
3769 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
3770 {
3771 if ((pData == NULL) || (Size == 0U))
3772 {
3773 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
3774 return HAL_ERROR;
3775 }
3776
3777 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3778 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
3779
3780 /* Process Locked */
3781 __HAL_LOCK(hfmpi2c);
3782
3783 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
3784 /* and then toggle the HAL slave RX state to TX state */
3785 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
3786 {
3787 /* Disable associated Interrupts */
3788 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3789
3790 /* Abort DMA Xfer if any */
3791 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
3792 {
3793 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3794
3795 if (hfmpi2c->hdmarx != NULL)
3796 {
3797 /* Set the FMPI2C DMA Abort callback :
3798 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
3799 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
3800
3801 /* Abort DMA RX */
3802 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
3803 {
3804 /* Call Directly XferAbortCallback function in case of error */
3805 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
3806 }
3807 }
3808 }
3809 }
3810
3811 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
3812 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
3813 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3814
3815 /* Enable Address Acknowledge */
3816 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
3817
3818 /* Prepare transfer parameters */
3819 hfmpi2c->pBuffPtr = pData;
3820 hfmpi2c->XferCount = Size;
3821 hfmpi2c->XferSize = hfmpi2c->XferCount;
3822 hfmpi2c->XferOptions = XferOptions;
3823 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
3824
3825 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
3826 {
3827 /* Clear ADDR flag after prepare the transfer parameters */
3828 /* This action will generate an acknowledge to the Master */
3829 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
3830 }
3831
3832 /* Process Unlocked */
3833 __HAL_UNLOCK(hfmpi2c);
3834
3835 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
3836 to avoid the risk of FMPI2C interrupt handle execution before current
3837 process unlock */
3838 /* REnable ADDR interrupt */
3839 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT | FMPI2C_XFER_LISTEN_IT);
3840
3841 return HAL_OK;
3842 }
3843 else
3844 {
3845 return HAL_ERROR;
3846 }
3847 }
3848
3849 /**
3850 * @brief Sequential transmit in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA
3851 * @note This interface allow to manage repeated start condition when a direction change during transfer
3852 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
3853 * the configuration information for the specified FMPI2C.
3854 * @param pData Pointer to data buffer
3855 * @param Size Amount of data to be sent
3856 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
3857 * @retval HAL status
3858 */
HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3859 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
3860 uint32_t XferOptions)
3861 {
3862 HAL_StatusTypeDef dmaxferstatus;
3863
3864 /* Check the parameters */
3865 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3866
3867 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
3868 {
3869 if ((pData == NULL) || (Size == 0U))
3870 {
3871 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
3872 return HAL_ERROR;
3873 }
3874
3875 /* Process Locked */
3876 __HAL_LOCK(hfmpi2c);
3877
3878 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3879 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
3880
3881 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
3882 /* and then toggle the HAL slave RX state to TX state */
3883 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
3884 {
3885 /* Disable associated Interrupts */
3886 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
3887
3888 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
3889 {
3890 /* Abort DMA Xfer if any */
3891 if (hfmpi2c->hdmarx != NULL)
3892 {
3893 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3894
3895 /* Set the FMPI2C DMA Abort callback :
3896 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
3897 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
3898
3899 /* Abort DMA RX */
3900 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
3901 {
3902 /* Call Directly XferAbortCallback function in case of error */
3903 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
3904 }
3905 }
3906 }
3907 }
3908 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
3909 {
3910 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
3911 {
3912 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3913
3914 /* Abort DMA Xfer if any */
3915 if (hfmpi2c->hdmatx != NULL)
3916 {
3917 /* Set the FMPI2C DMA Abort callback :
3918 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
3919 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
3920
3921 /* Abort DMA TX */
3922 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
3923 {
3924 /* Call Directly XferAbortCallback function in case of error */
3925 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
3926 }
3927 }
3928 }
3929 }
3930 else
3931 {
3932 /* Nothing to do */
3933 }
3934
3935 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_TX_LISTEN;
3936 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
3937 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3938
3939 /* Enable Address Acknowledge */
3940 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
3941
3942 /* Prepare transfer parameters */
3943 hfmpi2c->pBuffPtr = pData;
3944 hfmpi2c->XferCount = Size;
3945 hfmpi2c->XferSize = hfmpi2c->XferCount;
3946 hfmpi2c->XferOptions = XferOptions;
3947 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
3948
3949 if (hfmpi2c->hdmatx != NULL)
3950 {
3951 /* Set the FMPI2C DMA transfer complete callback */
3952 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
3953
3954 /* Set the DMA error callback */
3955 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
3956
3957 /* Set the unused DMA callbacks to NULL */
3958 hfmpi2c->hdmatx->XferHalfCpltCallback = NULL;
3959 hfmpi2c->hdmatx->XferAbortCallback = NULL;
3960
3961 /* Enable the DMA stream */
3962 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR,
3963 hfmpi2c->XferSize);
3964 }
3965 else
3966 {
3967 /* Update FMPI2C state */
3968 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
3969 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3970
3971 /* Update FMPI2C error code */
3972 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
3973
3974 /* Process Unlocked */
3975 __HAL_UNLOCK(hfmpi2c);
3976
3977 return HAL_ERROR;
3978 }
3979
3980 if (dmaxferstatus == HAL_OK)
3981 {
3982 /* Update XferCount value */
3983 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3984
3985 /* Reset XferSize */
3986 hfmpi2c->XferSize = 0;
3987 }
3988 else
3989 {
3990 /* Update FMPI2C state */
3991 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
3992 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
3993
3994 /* Update FMPI2C error code */
3995 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3996
3997 /* Process Unlocked */
3998 __HAL_UNLOCK(hfmpi2c);
3999
4000 return HAL_ERROR;
4001 }
4002
4003 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_RECEIVE)
4004 {
4005 /* Clear ADDR flag after prepare the transfer parameters */
4006 /* This action will generate an acknowledge to the Master */
4007 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4008 }
4009
4010 /* Process Unlocked */
4011 __HAL_UNLOCK(hfmpi2c);
4012
4013 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4014 to avoid the risk of FMPI2C interrupt handle execution before current
4015 process unlock */
4016 /* Enable ERR, STOP, NACK, ADDR interrupts */
4017 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4018
4019 /* Enable DMA Request */
4020 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
4021
4022 return HAL_OK;
4023 }
4024 else
4025 {
4026 return HAL_ERROR;
4027 }
4028 }
4029
4030 /**
4031 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with Interrupt
4032 * @note This interface allow to manage repeated start condition when a direction change during transfer
4033 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4034 * the configuration information for the specified FMPI2C.
4035 * @param pData Pointer to data buffer
4036 * @param Size Amount of data to be sent
4037 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
4038 * @retval HAL status
4039 */
HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)4040 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
4041 uint32_t XferOptions)
4042 {
4043 /* Check the parameters */
4044 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4045
4046 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
4047 {
4048 if ((pData == NULL) || (Size == 0U))
4049 {
4050 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
4051 return HAL_ERROR;
4052 }
4053
4054 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4055 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
4056
4057 /* Process Locked */
4058 __HAL_LOCK(hfmpi2c);
4059
4060 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
4061 /* and then toggle the HAL slave TX state to RX state */
4062 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
4063 {
4064 /* Disable associated Interrupts */
4065 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4066
4067 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4068 {
4069 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4070
4071 /* Abort DMA Xfer if any */
4072 if (hfmpi2c->hdmatx != NULL)
4073 {
4074 /* Set the FMPI2C DMA Abort callback :
4075 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4076 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4077
4078 /* Abort DMA TX */
4079 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4080 {
4081 /* Call Directly XferAbortCallback function in case of error */
4082 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4083 }
4084 }
4085 }
4086 }
4087
4088 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
4089 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
4090 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4091
4092 /* Enable Address Acknowledge */
4093 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
4094
4095 /* Prepare transfer parameters */
4096 hfmpi2c->pBuffPtr = pData;
4097 hfmpi2c->XferCount = Size;
4098 hfmpi2c->XferSize = hfmpi2c->XferCount;
4099 hfmpi2c->XferOptions = XferOptions;
4100 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4101
4102 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
4103 {
4104 /* Clear ADDR flag after prepare the transfer parameters */
4105 /* This action will generate an acknowledge to the Master */
4106 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4107 }
4108
4109 /* Process Unlocked */
4110 __HAL_UNLOCK(hfmpi2c);
4111
4112 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4113 to avoid the risk of FMPI2C interrupt handle execution before current
4114 process unlock */
4115 /* REnable ADDR interrupt */
4116 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
4117
4118 return HAL_OK;
4119 }
4120 else
4121 {
4122 return HAL_ERROR;
4123 }
4124 }
4125
4126 /**
4127 * @brief Sequential receive in slave/device FMPI2C mode an amount of data in non-blocking mode with DMA
4128 * @note This interface allow to manage repeated start condition when a direction change during transfer
4129 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4130 * the configuration information for the specified FMPI2C.
4131 * @param pData Pointer to data buffer
4132 * @param Size Amount of data to be sent
4133 * @param XferOptions Options of Transfer, value of @ref FMPI2C_XFEROPTIONS
4134 * @retval HAL status
4135 */
HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)4136 HAL_StatusTypeDef HAL_FMPI2C_Slave_Seq_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size,
4137 uint32_t XferOptions)
4138 {
4139 HAL_StatusTypeDef dmaxferstatus;
4140
4141 /* Check the parameters */
4142 assert_param(IS_FMPI2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4143
4144 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
4145 {
4146 if ((pData == NULL) || (Size == 0U))
4147 {
4148 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_INVALID_PARAM;
4149 return HAL_ERROR;
4150 }
4151
4152 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4153 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
4154
4155 /* Process Locked */
4156 __HAL_LOCK(hfmpi2c);
4157
4158 /* FMPI2C cannot manage full duplex exchange so disable previous IT enabled if any */
4159 /* and then toggle the HAL slave TX state to RX state */
4160 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
4161 {
4162 /* Disable associated Interrupts */
4163 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4164
4165 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
4166 {
4167 /* Abort DMA Xfer if any */
4168 if (hfmpi2c->hdmatx != NULL)
4169 {
4170 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
4171
4172 /* Set the FMPI2C DMA Abort callback :
4173 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4174 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
4175
4176 /* Abort DMA TX */
4177 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
4178 {
4179 /* Call Directly XferAbortCallback function in case of error */
4180 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
4181 }
4182 }
4183 }
4184 }
4185 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
4186 {
4187 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
4188 {
4189 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
4190
4191 /* Abort DMA Xfer if any */
4192 if (hfmpi2c->hdmarx != NULL)
4193 {
4194 /* Set the FMPI2C DMA Abort callback :
4195 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
4196 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
4197
4198 /* Abort DMA RX */
4199 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
4200 {
4201 /* Call Directly XferAbortCallback function in case of error */
4202 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
4203 }
4204 }
4205 }
4206 }
4207 else
4208 {
4209 /* Nothing to do */
4210 }
4211
4212 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY_RX_LISTEN;
4213 hfmpi2c->Mode = HAL_FMPI2C_MODE_SLAVE;
4214 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
4215
4216 /* Enable Address Acknowledge */
4217 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
4218
4219 /* Prepare transfer parameters */
4220 hfmpi2c->pBuffPtr = pData;
4221 hfmpi2c->XferCount = Size;
4222 hfmpi2c->XferSize = hfmpi2c->XferCount;
4223 hfmpi2c->XferOptions = XferOptions;
4224 hfmpi2c->XferISR = FMPI2C_Slave_ISR_DMA;
4225
4226 if (hfmpi2c->hdmarx != NULL)
4227 {
4228 /* Set the FMPI2C DMA transfer complete callback */
4229 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
4230
4231 /* Set the DMA error callback */
4232 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
4233
4234 /* Set the unused DMA callbacks to NULL */
4235 hfmpi2c->hdmarx->XferHalfCpltCallback = NULL;
4236 hfmpi2c->hdmarx->XferAbortCallback = NULL;
4237
4238 /* Enable the DMA stream */
4239 dmaxferstatus = HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR,
4240 (uint32_t)pData, hfmpi2c->XferSize);
4241 }
4242 else
4243 {
4244 /* Update FMPI2C state */
4245 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4246 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4247
4248 /* Update FMPI2C error code */
4249 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA_PARAM;
4250
4251 /* Process Unlocked */
4252 __HAL_UNLOCK(hfmpi2c);
4253
4254 return HAL_ERROR;
4255 }
4256
4257 if (dmaxferstatus == HAL_OK)
4258 {
4259 /* Update XferCount value */
4260 hfmpi2c->XferCount -= hfmpi2c->XferSize;
4261
4262 /* Reset XferSize */
4263 hfmpi2c->XferSize = 0;
4264 }
4265 else
4266 {
4267 /* Update FMPI2C state */
4268 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4269 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4270
4271 /* Update FMPI2C error code */
4272 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
4273
4274 /* Process Unlocked */
4275 __HAL_UNLOCK(hfmpi2c);
4276
4277 return HAL_ERROR;
4278 }
4279
4280 if (FMPI2C_GET_DIR(hfmpi2c) == FMPI2C_DIRECTION_TRANSMIT)
4281 {
4282 /* Clear ADDR flag after prepare the transfer parameters */
4283 /* This action will generate an acknowledge to the Master */
4284 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
4285 }
4286
4287 /* Process Unlocked */
4288 __HAL_UNLOCK(hfmpi2c);
4289
4290 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4291 to avoid the risk of FMPI2C interrupt handle execution before current
4292 process unlock */
4293 /* REnable ADDR interrupt */
4294 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_LISTEN_IT);
4295
4296 /* Enable DMA Request */
4297 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
4298
4299 return HAL_OK;
4300 }
4301 else
4302 {
4303 return HAL_ERROR;
4304 }
4305 }
4306
4307 /**
4308 * @brief Enable the Address listen mode with Interrupt.
4309 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4310 * the configuration information for the specified FMPI2C.
4311 * @retval HAL status
4312 */
HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef * hfmpi2c)4313 HAL_StatusTypeDef HAL_FMPI2C_EnableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
4314 {
4315 if (hfmpi2c->State == HAL_FMPI2C_STATE_READY)
4316 {
4317 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
4318 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
4319
4320 /* Enable the Address Match interrupt */
4321 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4322
4323 return HAL_OK;
4324 }
4325 else
4326 {
4327 return HAL_BUSY;
4328 }
4329 }
4330
4331 /**
4332 * @brief Disable the Address listen mode with Interrupt.
4333 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4334 * the configuration information for the specified FMPI2C
4335 * @retval HAL status
4336 */
HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef * hfmpi2c)4337 HAL_StatusTypeDef HAL_FMPI2C_DisableListen_IT(FMPI2C_HandleTypeDef *hfmpi2c)
4338 {
4339 /* Declaration of tmp to prevent undefined behavior of volatile usage */
4340 uint32_t tmp;
4341
4342 /* Disable Address listen mode only if a transfer is not ongoing */
4343 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
4344 {
4345 tmp = (uint32_t)(hfmpi2c->State) & FMPI2C_STATE_MSK;
4346 hfmpi2c->PreviousState = tmp | (uint32_t)(hfmpi2c->Mode);
4347 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
4348 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
4349 hfmpi2c->XferISR = NULL;
4350
4351 /* Disable the Address Match interrupt */
4352 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
4353
4354 return HAL_OK;
4355 }
4356 else
4357 {
4358 return HAL_BUSY;
4359 }
4360 }
4361
4362 /**
4363 * @brief Abort a master FMPI2C IT or DMA process communication with Interrupt.
4364 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4365 * the configuration information for the specified FMPI2C.
4366 * @param DevAddress Target device address: The device 7 bits address value
4367 * in datasheet must be shifted to the left before calling the interface
4368 * @retval HAL status
4369 */
HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress)4370 HAL_StatusTypeDef HAL_FMPI2C_Master_Abort_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress)
4371 {
4372 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MASTER)
4373 {
4374 /* Process Locked */
4375 __HAL_LOCK(hfmpi2c);
4376
4377 /* Disable Interrupts and Store Previous state */
4378 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
4379 {
4380 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
4381 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
4382 }
4383 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
4384 {
4385 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
4386 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
4387 }
4388 else
4389 {
4390 /* Do nothing */
4391 }
4392
4393 /* Set State at HAL_FMPI2C_STATE_ABORT */
4394 hfmpi2c->State = HAL_FMPI2C_STATE_ABORT;
4395
4396 /* Set NBYTES to 1 to generate a dummy read on FMPI2C peripheral */
4397 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
4398 FMPI2C_TransferConfig(hfmpi2c, DevAddress, 1, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_STOP);
4399
4400 /* Process Unlocked */
4401 __HAL_UNLOCK(hfmpi2c);
4402
4403 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
4404 to avoid the risk of FMPI2C interrupt handle execution before current
4405 process unlock */
4406 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
4407
4408 return HAL_OK;
4409 }
4410 else
4411 {
4412 /* Wrong usage of abort function */
4413 /* This function should be used only in case of abort monitored by master device */
4414 return HAL_ERROR;
4415 }
4416 }
4417
4418 /**
4419 * @}
4420 */
4421
4422 /** @defgroup FMPI2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
4423 * @{
4424 */
4425
4426 /**
4427 * @brief This function handles FMPI2C event interrupt request.
4428 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4429 * the configuration information for the specified FMPI2C.
4430 * @retval None
4431 */
HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef * hfmpi2c)4432 void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
4433 {
4434 /* Get current IT Flags and IT sources value */
4435 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
4436 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
4437
4438 /* FMPI2C events treatment -------------------------------------*/
4439 if (hfmpi2c->XferISR != NULL)
4440 {
4441 hfmpi2c->XferISR(hfmpi2c, itflags, itsources);
4442 }
4443 }
4444
4445 /**
4446 * @brief This function handles FMPI2C error interrupt request.
4447 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4448 * the configuration information for the specified FMPI2C.
4449 * @retval None
4450 */
HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef * hfmpi2c)4451 void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
4452 {
4453 uint32_t itflags = READ_REG(hfmpi2c->Instance->ISR);
4454 uint32_t itsources = READ_REG(hfmpi2c->Instance->CR1);
4455 uint32_t tmperror;
4456
4457 /* FMPI2C Bus error interrupt occurred ------------------------------------*/
4458 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_BERR) != RESET) && \
4459 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4460 {
4461 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
4462
4463 /* Clear BERR flag */
4464 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
4465 }
4466
4467 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
4468 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_OVR) != RESET) && \
4469 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4470 {
4471 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
4472
4473 /* Clear OVR flag */
4474 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
4475 }
4476
4477 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
4478 if ((FMPI2C_CHECK_FLAG(itflags, FMPI2C_FLAG_ARLO) != RESET) && \
4479 (FMPI2C_CHECK_IT_SOURCE(itsources, FMPI2C_IT_ERRI) != RESET))
4480 {
4481 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
4482
4483 /* Clear ARLO flag */
4484 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
4485 }
4486
4487 /* Store current volatile hfmpi2c->ErrorCode, misra rule */
4488 tmperror = hfmpi2c->ErrorCode;
4489
4490 /* Call the Error Callback in case of Error detected */
4491 if ((tmperror & (HAL_FMPI2C_ERROR_BERR | HAL_FMPI2C_ERROR_OVR | HAL_FMPI2C_ERROR_ARLO)) != HAL_FMPI2C_ERROR_NONE)
4492 {
4493 FMPI2C_ITError(hfmpi2c, tmperror);
4494 }
4495 }
4496
4497 /**
4498 * @brief Master Tx Transfer completed callback.
4499 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4500 * the configuration information for the specified FMPI2C.
4501 * @retval None
4502 */
HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4503 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4504 {
4505 /* Prevent unused argument(s) compilation warning */
4506 UNUSED(hfmpi2c);
4507
4508 /* NOTE : This function should not be modified, when the callback is needed,
4509 the HAL_FMPI2C_MasterTxCpltCallback could be implemented in the user file
4510 */
4511 }
4512
4513 /**
4514 * @brief Master Rx Transfer completed callback.
4515 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4516 * the configuration information for the specified FMPI2C.
4517 * @retval None
4518 */
HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4519 __weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4520 {
4521 /* Prevent unused argument(s) compilation warning */
4522 UNUSED(hfmpi2c);
4523
4524 /* NOTE : This function should not be modified, when the callback is needed,
4525 the HAL_FMPI2C_MasterRxCpltCallback could be implemented in the user file
4526 */
4527 }
4528
4529 /** @brief Slave Tx Transfer completed callback.
4530 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4531 * the configuration information for the specified FMPI2C.
4532 * @retval None
4533 */
HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4534 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4535 {
4536 /* Prevent unused argument(s) compilation warning */
4537 UNUSED(hfmpi2c);
4538
4539 /* NOTE : This function should not be modified, when the callback is needed,
4540 the HAL_FMPI2C_SlaveTxCpltCallback could be implemented in the user file
4541 */
4542 }
4543
4544 /**
4545 * @brief Slave Rx Transfer completed callback.
4546 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4547 * the configuration information for the specified FMPI2C.
4548 * @retval None
4549 */
HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4550 __weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4551 {
4552 /* Prevent unused argument(s) compilation warning */
4553 UNUSED(hfmpi2c);
4554
4555 /* NOTE : This function should not be modified, when the callback is needed,
4556 the HAL_FMPI2C_SlaveRxCpltCallback could be implemented in the user file
4557 */
4558 }
4559
4560 /**
4561 * @brief Slave Address Match callback.
4562 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4563 * the configuration information for the specified FMPI2C.
4564 * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref FMPI2C_XFERDIRECTION
4565 * @param AddrMatchCode Address Match Code
4566 * @retval None
4567 */
HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef * hfmpi2c,uint8_t TransferDirection,uint16_t AddrMatchCode)4568 __weak void HAL_FMPI2C_AddrCallback(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
4569 {
4570 /* Prevent unused argument(s) compilation warning */
4571 UNUSED(hfmpi2c);
4572 UNUSED(TransferDirection);
4573 UNUSED(AddrMatchCode);
4574
4575 /* NOTE : This function should not be modified, when the callback is needed,
4576 the HAL_FMPI2C_AddrCallback() could be implemented in the user file
4577 */
4578 }
4579
4580 /**
4581 * @brief Listen Complete callback.
4582 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4583 * the configuration information for the specified FMPI2C.
4584 * @retval None
4585 */
HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4586 __weak void HAL_FMPI2C_ListenCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4587 {
4588 /* Prevent unused argument(s) compilation warning */
4589 UNUSED(hfmpi2c);
4590
4591 /* NOTE : This function should not be modified, when the callback is needed,
4592 the HAL_FMPI2C_ListenCpltCallback() could be implemented in the user file
4593 */
4594 }
4595
4596 /**
4597 * @brief Memory Tx Transfer completed callback.
4598 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4599 * the configuration information for the specified FMPI2C.
4600 * @retval None
4601 */
HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4602 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4603 {
4604 /* Prevent unused argument(s) compilation warning */
4605 UNUSED(hfmpi2c);
4606
4607 /* NOTE : This function should not be modified, when the callback is needed,
4608 the HAL_FMPI2C_MemTxCpltCallback could be implemented in the user file
4609 */
4610 }
4611
4612 /**
4613 * @brief Memory Rx Transfer completed callback.
4614 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4615 * the configuration information for the specified FMPI2C.
4616 * @retval None
4617 */
HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4618 __weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4619 {
4620 /* Prevent unused argument(s) compilation warning */
4621 UNUSED(hfmpi2c);
4622
4623 /* NOTE : This function should not be modified, when the callback is needed,
4624 the HAL_FMPI2C_MemRxCpltCallback could be implemented in the user file
4625 */
4626 }
4627
4628 /**
4629 * @brief FMPI2C error callback.
4630 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4631 * the configuration information for the specified FMPI2C.
4632 * @retval None
4633 */
HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef * hfmpi2c)4634 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4635 {
4636 /* Prevent unused argument(s) compilation warning */
4637 UNUSED(hfmpi2c);
4638
4639 /* NOTE : This function should not be modified, when the callback is needed,
4640 the HAL_FMPI2C_ErrorCallback could be implemented in the user file
4641 */
4642 }
4643
4644 /**
4645 * @brief FMPI2C abort callback.
4646 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4647 * the configuration information for the specified FMPI2C.
4648 * @retval None
4649 */
HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef * hfmpi2c)4650 __weak void HAL_FMPI2C_AbortCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
4651 {
4652 /* Prevent unused argument(s) compilation warning */
4653 UNUSED(hfmpi2c);
4654
4655 /* NOTE : This function should not be modified, when the callback is needed,
4656 the HAL_FMPI2C_AbortCpltCallback could be implemented in the user file
4657 */
4658 }
4659
4660 /**
4661 * @}
4662 */
4663
4664 /** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
4665 * @brief Peripheral State, Mode and Error functions
4666 *
4667 @verbatim
4668 ===============================================================================
4669 ##### Peripheral State, Mode and Error functions #####
4670 ===============================================================================
4671 [..]
4672 This subsection permit to get in run-time the status of the peripheral
4673 and the data flow.
4674
4675 @endverbatim
4676 * @{
4677 */
4678
4679 /**
4680 * @brief Return the FMPI2C handle state.
4681 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4682 * the configuration information for the specified FMPI2C.
4683 * @retval HAL state
4684 */
HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef * hfmpi2c)4685 HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c)
4686 {
4687 /* Return FMPI2C handle state */
4688 return hfmpi2c->State;
4689 }
4690
4691 /**
4692 * @brief Returns the FMPI2C Master, Slave, Memory or no mode.
4693 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4694 * the configuration information for FMPI2C module
4695 * @retval HAL mode
4696 */
HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef * hfmpi2c)4697 HAL_FMPI2C_ModeTypeDef HAL_FMPI2C_GetMode(FMPI2C_HandleTypeDef *hfmpi2c)
4698 {
4699 return hfmpi2c->Mode;
4700 }
4701
4702 /**
4703 * @brief Return the FMPI2C error code.
4704 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4705 * the configuration information for the specified FMPI2C.
4706 * @retval FMPI2C Error Code
4707 */
HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef * hfmpi2c)4708 uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c)
4709 {
4710 return hfmpi2c->ErrorCode;
4711 }
4712
4713 /**
4714 * @}
4715 */
4716
4717 /**
4718 * @}
4719 */
4720
4721 /** @addtogroup FMPI2C_Private_Functions
4722 * @{
4723 */
4724
4725 /**
4726 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
4727 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4728 * the configuration information for the specified FMPI2C.
4729 * @param ITFlags Interrupt flags to handle.
4730 * @param ITSources Interrupt sources enabled.
4731 * @retval HAL status
4732 */
FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags,uint32_t ITSources)4733 static HAL_StatusTypeDef FMPI2C_Master_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
4734 uint32_t ITSources)
4735 {
4736 uint16_t devaddress;
4737 uint32_t tmpITFlags = ITFlags;
4738
4739 /* Process Locked */
4740 __HAL_LOCK(hfmpi2c);
4741
4742 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
4743 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
4744 {
4745 /* Clear NACK Flag */
4746 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4747
4748 /* Set corresponding Error Code */
4749 /* No need to generate STOP, it is automatically done */
4750 /* Error callback will be send during stop flag treatment */
4751 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4752
4753 /* Flush TX register */
4754 FMPI2C_Flush_TXDR(hfmpi2c);
4755 }
4756 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
4757 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
4758 {
4759 /* Remove RXNE flag on temporary variable as read done */
4760 tmpITFlags &= ~FMPI2C_FLAG_RXNE;
4761
4762 /* Read data from RXDR */
4763 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
4764
4765 /* Increment Buffer pointer */
4766 hfmpi2c->pBuffPtr++;
4767
4768 hfmpi2c->XferSize--;
4769 hfmpi2c->XferCount--;
4770 }
4771 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
4772 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
4773 {
4774 /* Write data to TXDR */
4775 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
4776
4777 /* Increment Buffer pointer */
4778 hfmpi2c->pBuffPtr++;
4779
4780 hfmpi2c->XferSize--;
4781 hfmpi2c->XferCount--;
4782 }
4783 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TCR) != RESET) && \
4784 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
4785 {
4786 if ((hfmpi2c->XferCount != 0U) && (hfmpi2c->XferSize == 0U))
4787 {
4788 devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
4789
4790 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
4791 {
4792 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
4793 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
4794 }
4795 else
4796 {
4797 hfmpi2c->XferSize = hfmpi2c->XferCount;
4798 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
4799 {
4800 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
4801 hfmpi2c->XferOptions, FMPI2C_NO_STARTSTOP);
4802 }
4803 else
4804 {
4805 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize,
4806 FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
4807 }
4808 }
4809 }
4810 else
4811 {
4812 /* Call TxCpltCallback() if no stop mode is set */
4813 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
4814 {
4815 /* Call FMPI2C Master Sequential complete process */
4816 FMPI2C_ITMasterSeqCplt(hfmpi2c);
4817 }
4818 else
4819 {
4820 /* Wrong size Status regarding TCR flag event */
4821 /* Call the corresponding callback to inform upper layer of End of Transfer */
4822 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
4823 }
4824 }
4825 }
4826 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TC) != RESET) && \
4827 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
4828 {
4829 if (hfmpi2c->XferCount == 0U)
4830 {
4831 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
4832 {
4833 /* Generate a stop condition in case of no transfer option */
4834 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
4835 {
4836 /* Generate Stop */
4837 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
4838 }
4839 else
4840 {
4841 /* Call FMPI2C Master Sequential complete process */
4842 FMPI2C_ITMasterSeqCplt(hfmpi2c);
4843 }
4844 }
4845 }
4846 else
4847 {
4848 /* Wrong size Status regarding TC flag event */
4849 /* Call the corresponding callback to inform upper layer of End of Transfer */
4850 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
4851 }
4852 }
4853 else
4854 {
4855 /* Nothing to do */
4856 }
4857
4858 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
4859 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
4860 {
4861 /* Call FMPI2C Master complete process */
4862 FMPI2C_ITMasterCplt(hfmpi2c, tmpITFlags);
4863 }
4864
4865 /* Process Unlocked */
4866 __HAL_UNLOCK(hfmpi2c);
4867
4868 return HAL_OK;
4869 }
4870
4871 /**
4872 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
4873 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
4874 * the configuration information for the specified FMPI2C.
4875 * @param ITFlags Interrupt flags to handle.
4876 * @param ITSources Interrupt sources enabled.
4877 * @retval HAL status
4878 */
FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags,uint32_t ITSources)4879 static HAL_StatusTypeDef FMPI2C_Slave_ISR_IT(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
4880 uint32_t ITSources)
4881 {
4882 uint32_t tmpoptions = hfmpi2c->XferOptions;
4883 uint32_t tmpITFlags = ITFlags;
4884
4885 /* Process locked */
4886 __HAL_LOCK(hfmpi2c);
4887
4888 /* Check if STOPF is set */
4889 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
4890 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
4891 {
4892 /* Call FMPI2C Slave complete process */
4893 FMPI2C_ITSlaveCplt(hfmpi2c, tmpITFlags);
4894 }
4895
4896 if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET) && \
4897 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
4898 {
4899 /* Check that FMPI2C transfer finished */
4900 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
4901 /* Mean XferCount == 0*/
4902 /* So clear Flag NACKF only */
4903 if (hfmpi2c->XferCount == 0U)
4904 {
4905 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
4906 /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
4907 Warning[Pa134]: left and right operands are identical */
4908 {
4909 /* Call FMPI2C Listen complete process */
4910 FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
4911 }
4912 else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
4913 {
4914 /* Clear NACK Flag */
4915 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4916
4917 /* Flush TX register */
4918 FMPI2C_Flush_TXDR(hfmpi2c);
4919
4920 /* Last Byte is Transmitted */
4921 /* Call FMPI2C Slave Sequential complete process */
4922 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
4923 }
4924 else
4925 {
4926 /* Clear NACK Flag */
4927 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4928 }
4929 }
4930 else
4931 {
4932 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
4933 /* Clear NACK Flag */
4934 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4935
4936 /* Set ErrorCode corresponding to a Non-Acknowledge */
4937 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
4938
4939 if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
4940 {
4941 /* Call the corresponding callback to inform upper layer of End of Transfer */
4942 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
4943 }
4944 }
4945 }
4946 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET) && \
4947 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_RXI) != RESET))
4948 {
4949 if (hfmpi2c->XferCount > 0U)
4950 {
4951 /* Read data from RXDR */
4952 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
4953
4954 /* Increment Buffer pointer */
4955 hfmpi2c->pBuffPtr++;
4956
4957 hfmpi2c->XferSize--;
4958 hfmpi2c->XferCount--;
4959 }
4960
4961 if ((hfmpi2c->XferCount == 0U) && \
4962 (tmpoptions != FMPI2C_NO_OPTION_FRAME))
4963 {
4964 /* Call FMPI2C Slave Sequential complete process */
4965 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
4966 }
4967 }
4968 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
4969 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
4970 {
4971 FMPI2C_ITAddrCplt(hfmpi2c, tmpITFlags);
4972 }
4973 else if ((FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_TXIS) != RESET) && \
4974 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TXI) != RESET))
4975 {
4976 /* Write data to TXDR only if XferCount not reach "0" */
4977 /* A TXIS flag can be set, during STOP treatment */
4978 /* Check if all Data have already been sent */
4979 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
4980 if (hfmpi2c->XferCount > 0U)
4981 {
4982 /* Write data to TXDR */
4983 hfmpi2c->Instance->TXDR = *hfmpi2c->pBuffPtr;
4984
4985 /* Increment Buffer pointer */
4986 hfmpi2c->pBuffPtr++;
4987
4988 hfmpi2c->XferCount--;
4989 hfmpi2c->XferSize--;
4990 }
4991 else
4992 {
4993 if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
4994 {
4995 /* Last Byte is Transmitted */
4996 /* Call FMPI2C Slave Sequential complete process */
4997 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
4998 }
4999 }
5000 }
5001 else
5002 {
5003 /* Nothing to do */
5004 }
5005
5006 /* Process Unlocked */
5007 __HAL_UNLOCK(hfmpi2c);
5008
5009 return HAL_OK;
5010 }
5011
5012 /**
5013 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
5014 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
5015 * the configuration information for the specified FMPI2C.
5016 * @param ITFlags Interrupt flags to handle.
5017 * @param ITSources Interrupt sources enabled.
5018 * @retval HAL status
5019 */
FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags,uint32_t ITSources)5020 static HAL_StatusTypeDef FMPI2C_Master_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5021 uint32_t ITSources)
5022 {
5023 uint16_t devaddress;
5024 uint32_t xfermode;
5025
5026 /* Process Locked */
5027 __HAL_LOCK(hfmpi2c);
5028
5029 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
5030 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5031 {
5032 /* Clear NACK Flag */
5033 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5034
5035 /* Set corresponding Error Code */
5036 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5037
5038 /* No need to generate STOP, it is automatically done */
5039 /* But enable STOP interrupt, to treat it */
5040 /* Error callback will be send during stop flag treatment */
5041 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
5042
5043 /* Flush TX register */
5044 FMPI2C_Flush_TXDR(hfmpi2c);
5045 }
5046 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TCR) != RESET) && \
5047 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5048 {
5049 /* Disable TC interrupt */
5050 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, FMPI2C_IT_TCI);
5051
5052 if (hfmpi2c->XferCount != 0U)
5053 {
5054 /* Recover Slave address */
5055 devaddress = (uint16_t)(hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
5056
5057 /* Prepare the new XferSize to transfer */
5058 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
5059 {
5060 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
5061 xfermode = FMPI2C_RELOAD_MODE;
5062 }
5063 else
5064 {
5065 hfmpi2c->XferSize = hfmpi2c->XferCount;
5066 if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
5067 {
5068 xfermode = hfmpi2c->XferOptions;
5069 }
5070 else
5071 {
5072 xfermode = FMPI2C_AUTOEND_MODE;
5073 }
5074 }
5075
5076 /* Set the new XferSize in Nbytes register */
5077 FMPI2C_TransferConfig(hfmpi2c, devaddress, (uint8_t)hfmpi2c->XferSize, xfermode, FMPI2C_NO_STARTSTOP);
5078
5079 /* Update XferCount value */
5080 hfmpi2c->XferCount -= hfmpi2c->XferSize;
5081
5082 /* Enable DMA Request */
5083 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5084 {
5085 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
5086 }
5087 else
5088 {
5089 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
5090 }
5091 }
5092 else
5093 {
5094 /* Call TxCpltCallback() if no stop mode is set */
5095 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5096 {
5097 /* Call FMPI2C Master Sequential complete process */
5098 FMPI2C_ITMasterSeqCplt(hfmpi2c);
5099 }
5100 else
5101 {
5102 /* Wrong size Status regarding TCR flag event */
5103 /* Call the corresponding callback to inform upper layer of End of Transfer */
5104 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5105 }
5106 }
5107 }
5108 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_TC) != RESET) && \
5109 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_TCI) != RESET))
5110 {
5111 if (hfmpi2c->XferCount == 0U)
5112 {
5113 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
5114 {
5115 /* Generate a stop condition in case of no transfer option */
5116 if (hfmpi2c->XferOptions == FMPI2C_NO_OPTION_FRAME)
5117 {
5118 /* Generate Stop */
5119 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
5120 }
5121 else
5122 {
5123 /* Call FMPI2C Master Sequential complete process */
5124 FMPI2C_ITMasterSeqCplt(hfmpi2c);
5125 }
5126 }
5127 }
5128 else
5129 {
5130 /* Wrong size Status regarding TC flag event */
5131 /* Call the corresponding callback to inform upper layer of End of Transfer */
5132 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_SIZE);
5133 }
5134 }
5135 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5136 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5137 {
5138 /* Call FMPI2C Master complete process */
5139 FMPI2C_ITMasterCplt(hfmpi2c, ITFlags);
5140 }
5141 else
5142 {
5143 /* Nothing to do */
5144 }
5145
5146 /* Process Unlocked */
5147 __HAL_UNLOCK(hfmpi2c);
5148
5149 return HAL_OK;
5150 }
5151
5152 /**
5153 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
5154 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
5155 * the configuration information for the specified FMPI2C.
5156 * @param ITFlags Interrupt flags to handle.
5157 * @param ITSources Interrupt sources enabled.
5158 * @retval HAL status
5159 */
FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags,uint32_t ITSources)5160 static HAL_StatusTypeDef FMPI2C_Slave_ISR_DMA(struct __FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags,
5161 uint32_t ITSources)
5162 {
5163 uint32_t tmpoptions = hfmpi2c->XferOptions;
5164 uint32_t treatdmanack = 0U;
5165 HAL_FMPI2C_StateTypeDef tmpstate;
5166
5167 /* Process locked */
5168 __HAL_LOCK(hfmpi2c);
5169
5170 /* Check if STOPF is set */
5171 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_STOPF) != RESET) && \
5172 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_STOPI) != RESET))
5173 {
5174 /* Call FMPI2C Slave complete process */
5175 FMPI2C_ITSlaveCplt(hfmpi2c, ITFlags);
5176 }
5177
5178 if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_AF) != RESET) && \
5179 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_NACKI) != RESET))
5180 {
5181 /* Check that FMPI2C transfer finished */
5182 /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5183 /* Mean XferCount == 0 */
5184 /* So clear Flag NACKF only */
5185 if ((FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET) ||
5186 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET))
5187 {
5188 /* Split check of hdmarx, for MISRA compliance */
5189 if (hfmpi2c->hdmarx != NULL)
5190 {
5191 if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_RXDMAEN) != RESET)
5192 {
5193 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U)
5194 {
5195 treatdmanack = 1U;
5196 }
5197 }
5198 }
5199
5200 /* Split check of hdmatx, for MISRA compliance */
5201 if (hfmpi2c->hdmatx != NULL)
5202 {
5203 if (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_CR1_TXDMAEN) != RESET)
5204 {
5205 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U)
5206 {
5207 treatdmanack = 1U;
5208 }
5209 }
5210 }
5211
5212 if (treatdmanack == 1U)
5213 {
5214 if ((hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN) && (tmpoptions == FMPI2C_FIRST_AND_LAST_FRAME))
5215 /* Same action must be done for (tmpoptions == FMPI2C_LAST_FRAME) which removed for
5216 Warning[Pa134]: left and right operands are identical */
5217 {
5218 /* Call FMPI2C Listen complete process */
5219 FMPI2C_ITListenCplt(hfmpi2c, ITFlags);
5220 }
5221 else if ((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != FMPI2C_NO_OPTION_FRAME))
5222 {
5223 /* Clear NACK Flag */
5224 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5225
5226 /* Flush TX register */
5227 FMPI2C_Flush_TXDR(hfmpi2c);
5228
5229 /* Last Byte is Transmitted */
5230 /* Call FMPI2C Slave Sequential complete process */
5231 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5232 }
5233 else
5234 {
5235 /* Clear NACK Flag */
5236 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5237 }
5238 }
5239 else
5240 {
5241 /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5242 /* Clear NACK Flag */
5243 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5244
5245 /* Set ErrorCode corresponding to a Non-Acknowledge */
5246 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5247
5248 /* Store current hfmpi2c->State, solve MISRA2012-Rule-13.5 */
5249 tmpstate = hfmpi2c->State;
5250
5251 if ((tmpoptions == FMPI2C_FIRST_FRAME) || (tmpoptions == FMPI2C_NEXT_FRAME))
5252 {
5253 if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
5254 {
5255 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
5256 }
5257 else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
5258 {
5259 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
5260 }
5261 else
5262 {
5263 /* Do nothing */
5264 }
5265
5266 /* Call the corresponding callback to inform upper layer of End of Transfer */
5267 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
5268 }
5269 }
5270 }
5271 else
5272 {
5273 /* Only Clear NACK Flag, no DMA treatment is pending */
5274 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5275 }
5276 }
5277 else if ((FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_ADDR) != RESET) && \
5278 (FMPI2C_CHECK_IT_SOURCE(ITSources, FMPI2C_IT_ADDRI) != RESET))
5279 {
5280 FMPI2C_ITAddrCplt(hfmpi2c, ITFlags);
5281 }
5282 else
5283 {
5284 /* Nothing to do */
5285 }
5286
5287 /* Process Unlocked */
5288 __HAL_UNLOCK(hfmpi2c);
5289
5290 return HAL_OK;
5291 }
5292
5293 /**
5294 * @brief Master sends target device address followed by internal memory address for write request.
5295 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
5296 * the configuration information for the specified FMPI2C.
5297 * @param DevAddress Target device address: The device 7 bits address value
5298 * in datasheet must be shifted to the left before calling the interface
5299 * @param MemAddress Internal memory address
5300 * @param MemAddSize Size of internal memory address
5301 * @param Timeout Timeout duration
5302 * @param Tickstart Tick start value
5303 * @retval HAL status
5304 */
FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint32_t Timeout,uint32_t Tickstart)5305 static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
5306 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5307 uint32_t Tickstart)
5308 {
5309 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
5310
5311 /* Wait until TXIS flag is set */
5312 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5313 {
5314 return HAL_ERROR;
5315 }
5316
5317 /* If Memory address size is 8Bit */
5318 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
5319 {
5320 /* Send Memory Address */
5321 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5322 }
5323 /* If Memory address size is 16Bit */
5324 else
5325 {
5326 /* Send MSB of Memory Address */
5327 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
5328
5329 /* Wait until TXIS flag is set */
5330 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5331 {
5332 return HAL_ERROR;
5333 }
5334
5335 /* Send LSB of Memory Address */
5336 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5337 }
5338
5339 /* Wait until TCR flag is set */
5340 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
5341 {
5342 return HAL_ERROR;
5343 }
5344
5345 return HAL_OK;
5346 }
5347
5348 /**
5349 * @brief Master sends target device address followed by internal memory address for read request.
5350 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
5351 * the configuration information for the specified FMPI2C.
5352 * @param DevAddress Target device address: The device 7 bits address value
5353 * in datasheet must be shifted to the left before calling the interface
5354 * @param MemAddress Internal memory address
5355 * @param MemAddSize Size of internal memory address
5356 * @param Timeout Timeout duration
5357 * @param Tickstart Tick start value
5358 * @retval HAL status
5359 */
FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint32_t Timeout,uint32_t Tickstart)5360 static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress,
5361 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5362 uint32_t Tickstart)
5363 {
5364 FMPI2C_TransferConfig(hfmpi2c, DevAddress, (uint8_t)MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
5365
5366 /* Wait until TXIS flag is set */
5367 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5368 {
5369 return HAL_ERROR;
5370 }
5371
5372 /* If Memory address size is 8Bit */
5373 if (MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
5374 {
5375 /* Send Memory Address */
5376 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5377 }
5378 /* If Memory address size is 16Bit */
5379 else
5380 {
5381 /* Send MSB of Memory Address */
5382 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_MSB(MemAddress);
5383
5384 /* Wait until TXIS flag is set */
5385 if (FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout, Tickstart) != HAL_OK)
5386 {
5387 return HAL_ERROR;
5388 }
5389
5390 /* Send LSB of Memory Address */
5391 hfmpi2c->Instance->TXDR = FMPI2C_MEM_ADD_LSB(MemAddress);
5392 }
5393
5394 /* Wait until TC flag is set */
5395 if (FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
5396 {
5397 return HAL_ERROR;
5398 }
5399
5400 return HAL_OK;
5401 }
5402
5403 /**
5404 * @brief FMPI2C Address complete process callback.
5405 * @param hfmpi2c FMPI2C handle.
5406 * @param ITFlags Interrupt flags to handle.
5407 * @retval None
5408 */
FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags)5409 static void FMPI2C_ITAddrCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
5410 {
5411 uint8_t transferdirection;
5412 uint16_t slaveaddrcode;
5413 uint16_t ownadd1code;
5414 uint16_t ownadd2code;
5415
5416 /* Prevent unused argument(s) compilation warning */
5417 UNUSED(ITFlags);
5418
5419 /* In case of Listen state, need to inform upper layer of address match code event */
5420 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) == (uint32_t)HAL_FMPI2C_STATE_LISTEN)
5421 {
5422 transferdirection = FMPI2C_GET_DIR(hfmpi2c);
5423 slaveaddrcode = FMPI2C_GET_ADDR_MATCH(hfmpi2c);
5424 ownadd1code = FMPI2C_GET_OWN_ADDRESS1(hfmpi2c);
5425 ownadd2code = FMPI2C_GET_OWN_ADDRESS2(hfmpi2c);
5426
5427 /* If 10bits addressing mode is selected */
5428 if (hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
5429 {
5430 if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
5431 {
5432 slaveaddrcode = ownadd1code;
5433 hfmpi2c->AddrEventCount++;
5434 if (hfmpi2c->AddrEventCount == 2U)
5435 {
5436 /* Reset Address Event counter */
5437 hfmpi2c->AddrEventCount = 0U;
5438
5439 /* Clear ADDR flag */
5440 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
5441
5442 /* Process Unlocked */
5443 __HAL_UNLOCK(hfmpi2c);
5444
5445 /* Call Slave Addr callback */
5446 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5447 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5448 #else
5449 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5450 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5451 }
5452 }
5453 else
5454 {
5455 slaveaddrcode = ownadd2code;
5456
5457 /* Disable ADDR Interrupts */
5458 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
5459
5460 /* Process Unlocked */
5461 __HAL_UNLOCK(hfmpi2c);
5462
5463 /* Call Slave Addr callback */
5464 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5465 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5466 #else
5467 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5468 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5469 }
5470 }
5471 /* else 7 bits addressing mode is selected */
5472 else
5473 {
5474 /* Disable ADDR Interrupts */
5475 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT);
5476
5477 /* Process Unlocked */
5478 __HAL_UNLOCK(hfmpi2c);
5479
5480 /* Call Slave Addr callback */
5481 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5482 hfmpi2c->AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5483 #else
5484 HAL_FMPI2C_AddrCallback(hfmpi2c, transferdirection, slaveaddrcode);
5485 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5486 }
5487 }
5488 /* Else clear address flag only */
5489 else
5490 {
5491 /* Clear ADDR flag */
5492 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
5493
5494 /* Process Unlocked */
5495 __HAL_UNLOCK(hfmpi2c);
5496 }
5497 }
5498
5499 /**
5500 * @brief FMPI2C Master sequential complete process.
5501 * @param hfmpi2c FMPI2C handle.
5502 * @retval None
5503 */
FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef * hfmpi2c)5504 static void FMPI2C_ITMasterSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
5505 {
5506 /* Reset FMPI2C handle mode */
5507 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5508
5509 /* No Generate Stop, to permit restart mode */
5510 /* The stop will be done at the end of transfer, when FMPI2C_AUTOEND_MODE enable */
5511 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
5512 {
5513 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5514 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
5515 hfmpi2c->XferISR = NULL;
5516
5517 /* Disable Interrupts */
5518 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5519
5520 /* Process Unlocked */
5521 __HAL_UNLOCK(hfmpi2c);
5522
5523 /* Call the corresponding callback to inform upper layer of End of Transfer */
5524 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5525 hfmpi2c->MasterTxCpltCallback(hfmpi2c);
5526 #else
5527 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
5528 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5529 }
5530 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
5531 else
5532 {
5533 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5534 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
5535 hfmpi2c->XferISR = NULL;
5536
5537 /* Disable Interrupts */
5538 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
5539
5540 /* Process Unlocked */
5541 __HAL_UNLOCK(hfmpi2c);
5542
5543 /* Call the corresponding callback to inform upper layer of End of Transfer */
5544 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5545 hfmpi2c->MasterRxCpltCallback(hfmpi2c);
5546 #else
5547 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
5548 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5549 }
5550 }
5551
5552 /**
5553 * @brief FMPI2C Slave sequential complete process.
5554 * @param hfmpi2c FMPI2C handle.
5555 * @retval None
5556 */
FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef * hfmpi2c)5557 static void FMPI2C_ITSlaveSeqCplt(FMPI2C_HandleTypeDef *hfmpi2c)
5558 {
5559 uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
5560
5561 /* Reset FMPI2C handle mode */
5562 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5563
5564 /* If a DMA is ongoing, Update handle size context */
5565 if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
5566 {
5567 /* Disable DMA Request */
5568 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
5569 }
5570 else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
5571 {
5572 /* Disable DMA Request */
5573 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
5574 }
5575 else
5576 {
5577 /* Do nothing */
5578 }
5579
5580 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX_LISTEN)
5581 {
5582 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_TX, keep only HAL_FMPI2C_STATE_LISTEN */
5583 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
5584 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
5585
5586 /* Disable Interrupts */
5587 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5588
5589 /* Process Unlocked */
5590 __HAL_UNLOCK(hfmpi2c);
5591
5592 /* Call the corresponding callback to inform upper layer of End of Transfer */
5593 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5594 hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
5595 #else
5596 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
5597 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5598 }
5599
5600 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX_LISTEN)
5601 {
5602 /* Remove HAL_FMPI2C_STATE_SLAVE_BUSY_RX, keep only HAL_FMPI2C_STATE_LISTEN */
5603 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
5604 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
5605
5606 /* Disable Interrupts */
5607 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
5608
5609 /* Process Unlocked */
5610 __HAL_UNLOCK(hfmpi2c);
5611
5612 /* Call the corresponding callback to inform upper layer of End of Transfer */
5613 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5614 hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
5615 #else
5616 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
5617 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5618 }
5619 else
5620 {
5621 /* Nothing to do */
5622 }
5623 }
5624
5625 /**
5626 * @brief FMPI2C Master complete process.
5627 * @param hfmpi2c FMPI2C handle.
5628 * @param ITFlags Interrupt flags to handle.
5629 * @retval None
5630 */
FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags)5631 static void FMPI2C_ITMasterCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
5632 {
5633 uint32_t tmperror;
5634 uint32_t tmpITFlags = ITFlags;
5635 __IO uint32_t tmpreg;
5636
5637 /* Clear STOP Flag */
5638 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
5639
5640 /* Disable Interrupts and Store Previous state */
5641 if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
5642 {
5643 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_TX_IT);
5644 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_TX;
5645 }
5646 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5647 {
5648 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT);
5649 hfmpi2c->PreviousState = FMPI2C_STATE_MASTER_BUSY_RX;
5650 }
5651 else
5652 {
5653 /* Do nothing */
5654 }
5655
5656 /* Clear Configuration Register 2 */
5657 FMPI2C_RESET_CR2(hfmpi2c);
5658
5659 /* Reset handle parameters */
5660 hfmpi2c->XferISR = NULL;
5661 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
5662
5663 if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_AF) != RESET)
5664 {
5665 /* Clear NACK Flag */
5666 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5667
5668 /* Set acknowledge error code */
5669 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5670 }
5671
5672 /* Fetch Last receive data if any */
5673 if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) && (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET))
5674 {
5675 /* Read data from RXDR */
5676 tmpreg = (uint8_t)hfmpi2c->Instance->RXDR;
5677 UNUSED(tmpreg);
5678 }
5679
5680 /* Flush TX register */
5681 FMPI2C_Flush_TXDR(hfmpi2c);
5682
5683 /* Store current volatile hfmpi2c->ErrorCode, misra rule */
5684 tmperror = hfmpi2c->ErrorCode;
5685
5686 /* Call the corresponding callback to inform upper layer of End of Transfer */
5687 if ((hfmpi2c->State == HAL_FMPI2C_STATE_ABORT) || (tmperror != HAL_FMPI2C_ERROR_NONE))
5688 {
5689 /* Call the corresponding callback to inform upper layer of End of Transfer */
5690 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
5691 }
5692 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX */
5693 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_TX)
5694 {
5695 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5696 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5697
5698 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
5699 {
5700 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5701
5702 /* Process Unlocked */
5703 __HAL_UNLOCK(hfmpi2c);
5704
5705 /* Call the corresponding callback to inform upper layer of End of Transfer */
5706 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5707 hfmpi2c->MemTxCpltCallback(hfmpi2c);
5708 #else
5709 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
5710 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5711 }
5712 else
5713 {
5714 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5715
5716 /* Process Unlocked */
5717 __HAL_UNLOCK(hfmpi2c);
5718
5719 /* Call the corresponding callback to inform upper layer of End of Transfer */
5720 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5721 hfmpi2c->MasterTxCpltCallback(hfmpi2c);
5722 #else
5723 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
5724 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5725 }
5726 }
5727 /* hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX */
5728 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5729 {
5730 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5731 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5732
5733 if (hfmpi2c->Mode == HAL_FMPI2C_MODE_MEM)
5734 {
5735 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5736
5737 /* Process Unlocked */
5738 __HAL_UNLOCK(hfmpi2c);
5739
5740 /* Call the corresponding callback to inform upper layer of End of Transfer */
5741 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5742 hfmpi2c->MemRxCpltCallback(hfmpi2c);
5743 #else
5744 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
5745 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5746 }
5747 else
5748 {
5749 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5750
5751 /* Process Unlocked */
5752 __HAL_UNLOCK(hfmpi2c);
5753
5754 /* Call the corresponding callback to inform upper layer of End of Transfer */
5755 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5756 hfmpi2c->MasterRxCpltCallback(hfmpi2c);
5757 #else
5758 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
5759 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5760 }
5761 }
5762 else
5763 {
5764 /* Nothing to do */
5765 }
5766 }
5767
5768 /**
5769 * @brief FMPI2C Slave complete process.
5770 * @param hfmpi2c FMPI2C handle.
5771 * @param ITFlags Interrupt flags to handle.
5772 * @retval None
5773 */
FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags)5774 static void FMPI2C_ITSlaveCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
5775 {
5776 uint32_t tmpcr1value = READ_REG(hfmpi2c->Instance->CR1);
5777 uint32_t tmpITFlags = ITFlags;
5778 HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
5779
5780 /* Clear STOP Flag */
5781 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
5782
5783 /* Disable Interrupts and Store Previous state */
5784 if ((tmpstate == HAL_FMPI2C_STATE_BUSY_TX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN))
5785 {
5786 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_TX_IT);
5787 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_TX;
5788 }
5789 else if ((tmpstate == HAL_FMPI2C_STATE_BUSY_RX) || (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
5790 {
5791 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT);
5792 hfmpi2c->PreviousState = FMPI2C_STATE_SLAVE_BUSY_RX;
5793 }
5794 else
5795 {
5796 /* Do nothing */
5797 }
5798
5799 /* Disable Address Acknowledge */
5800 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
5801
5802 /* Clear Configuration Register 2 */
5803 FMPI2C_RESET_CR2(hfmpi2c);
5804
5805 /* Flush TX register */
5806 FMPI2C_Flush_TXDR(hfmpi2c);
5807
5808 /* If a DMA is ongoing, Update handle size context */
5809 if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_TXDMAEN) != RESET)
5810 {
5811 /* Disable DMA Request */
5812 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
5813
5814 if (hfmpi2c->hdmatx != NULL)
5815 {
5816 hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx);
5817 }
5818 }
5819 else if (FMPI2C_CHECK_IT_SOURCE(tmpcr1value, FMPI2C_CR1_RXDMAEN) != RESET)
5820 {
5821 /* Disable DMA Request */
5822 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
5823
5824 if (hfmpi2c->hdmarx != NULL)
5825 {
5826 hfmpi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx);
5827 }
5828 }
5829 else
5830 {
5831 /* Do nothing */
5832 }
5833
5834 /* Store Last receive data if any */
5835 if (FMPI2C_CHECK_FLAG(tmpITFlags, FMPI2C_FLAG_RXNE) != RESET)
5836 {
5837 /* Remove RXNE flag on temporary variable as read done */
5838 tmpITFlags &= ~FMPI2C_FLAG_RXNE;
5839
5840 /* Read data from RXDR */
5841 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
5842
5843 /* Increment Buffer pointer */
5844 hfmpi2c->pBuffPtr++;
5845
5846 if ((hfmpi2c->XferSize > 0U))
5847 {
5848 hfmpi2c->XferSize--;
5849 hfmpi2c->XferCount--;
5850 }
5851 }
5852
5853 /* All data are not transferred, so set error code accordingly */
5854 if (hfmpi2c->XferCount != 0U)
5855 {
5856 /* Set ErrorCode corresponding to a Non-Acknowledge */
5857 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5858 }
5859
5860 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5861 hfmpi2c->XferISR = NULL;
5862
5863 if (hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
5864 {
5865 /* Call the corresponding callback to inform upper layer of End of Transfer */
5866 FMPI2C_ITError(hfmpi2c, hfmpi2c->ErrorCode);
5867
5868 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5869 if (hfmpi2c->State == HAL_FMPI2C_STATE_LISTEN)
5870 {
5871 /* Call FMPI2C Listen complete process */
5872 FMPI2C_ITListenCplt(hfmpi2c, tmpITFlags);
5873 }
5874 }
5875 else if (hfmpi2c->XferOptions != FMPI2C_NO_OPTION_FRAME)
5876 {
5877 /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
5878 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
5879
5880 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
5881 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5882 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5883
5884 /* Process Unlocked */
5885 __HAL_UNLOCK(hfmpi2c);
5886
5887 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5888 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5889 hfmpi2c->ListenCpltCallback(hfmpi2c);
5890 #else
5891 HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
5892 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5893 }
5894 /* Call the corresponding callback to inform upper layer of End of Transfer */
5895 else if (hfmpi2c->State == HAL_FMPI2C_STATE_BUSY_RX)
5896 {
5897 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5898 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5899
5900 /* Process Unlocked */
5901 __HAL_UNLOCK(hfmpi2c);
5902
5903 /* Call the corresponding callback to inform upper layer of End of Transfer */
5904 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5905 hfmpi2c->SlaveRxCpltCallback(hfmpi2c);
5906 #else
5907 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
5908 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5909 }
5910 else
5911 {
5912 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5913 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5914
5915 /* Process Unlocked */
5916 __HAL_UNLOCK(hfmpi2c);
5917
5918 /* Call the corresponding callback to inform upper layer of End of Transfer */
5919 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5920 hfmpi2c->SlaveTxCpltCallback(hfmpi2c);
5921 #else
5922 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
5923 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5924 }
5925 }
5926
5927 /**
5928 * @brief FMPI2C Listen complete process.
5929 * @param hfmpi2c FMPI2C handle.
5930 * @param ITFlags Interrupt flags to handle.
5931 * @retval None
5932 */
FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ITFlags)5933 static void FMPI2C_ITListenCplt(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ITFlags)
5934 {
5935 /* Reset handle parameters */
5936 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
5937 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
5938 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
5939 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5940 hfmpi2c->XferISR = NULL;
5941
5942 /* Store Last receive data if any */
5943 if (FMPI2C_CHECK_FLAG(ITFlags, FMPI2C_FLAG_RXNE) != RESET)
5944 {
5945 /* Read data from RXDR */
5946 *hfmpi2c->pBuffPtr = (uint8_t)hfmpi2c->Instance->RXDR;
5947
5948 /* Increment Buffer pointer */
5949 hfmpi2c->pBuffPtr++;
5950
5951 if ((hfmpi2c->XferSize > 0U))
5952 {
5953 hfmpi2c->XferSize--;
5954 hfmpi2c->XferCount--;
5955
5956 /* Set ErrorCode corresponding to a Non-Acknowledge */
5957 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
5958 }
5959 }
5960
5961 /* Disable all Interrupts*/
5962 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
5963
5964 /* Clear NACK Flag */
5965 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
5966
5967 /* Process Unlocked */
5968 __HAL_UNLOCK(hfmpi2c);
5969
5970 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
5971 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
5972 hfmpi2c->ListenCpltCallback(hfmpi2c);
5973 #else
5974 HAL_FMPI2C_ListenCpltCallback(hfmpi2c);
5975 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
5976 }
5977
5978 /**
5979 * @brief FMPI2C interrupts error process.
5980 * @param hfmpi2c FMPI2C handle.
5981 * @param ErrorCode Error code to handle.
5982 * @retval None
5983 */
FMPI2C_ITError(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t ErrorCode)5984 static void FMPI2C_ITError(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t ErrorCode)
5985 {
5986 HAL_FMPI2C_StateTypeDef tmpstate = hfmpi2c->State;
5987 uint32_t tmppreviousstate;
5988
5989 /* Reset handle parameters */
5990 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
5991 hfmpi2c->XferOptions = FMPI2C_NO_OPTION_FRAME;
5992 hfmpi2c->XferCount = 0U;
5993
5994 /* Set new error code */
5995 hfmpi2c->ErrorCode |= ErrorCode;
5996
5997 /* Disable Interrupts */
5998 if ((tmpstate == HAL_FMPI2C_STATE_LISTEN) ||
5999 (tmpstate == HAL_FMPI2C_STATE_BUSY_TX_LISTEN) ||
6000 (tmpstate == HAL_FMPI2C_STATE_BUSY_RX_LISTEN))
6001 {
6002 /* Disable all interrupts, except interrupts related to LISTEN state */
6003 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
6004
6005 /* keep HAL_FMPI2C_STATE_LISTEN if set */
6006 hfmpi2c->State = HAL_FMPI2C_STATE_LISTEN;
6007 hfmpi2c->XferISR = FMPI2C_Slave_ISR_IT;
6008 }
6009 else
6010 {
6011 /* Disable all interrupts */
6012 FMPI2C_Disable_IRQ(hfmpi2c, FMPI2C_XFER_LISTEN_IT | FMPI2C_XFER_RX_IT | FMPI2C_XFER_TX_IT);
6013
6014 /* If state is an abort treatment on going, don't change state */
6015 /* This change will be do later */
6016 if (hfmpi2c->State != HAL_FMPI2C_STATE_ABORT)
6017 {
6018 /* Set HAL_FMPI2C_STATE_READY */
6019 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6020 }
6021 hfmpi2c->XferISR = NULL;
6022 }
6023
6024 /* Abort DMA TX transfer if any */
6025 tmppreviousstate = hfmpi2c->PreviousState;
6026 if ((hfmpi2c->hdmatx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_TX) || \
6027 (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_TX)))
6028 {
6029 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_TXDMAEN) == FMPI2C_CR1_TXDMAEN)
6030 {
6031 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6032 }
6033
6034 if (HAL_DMA_GetState(hfmpi2c->hdmatx) != HAL_DMA_STATE_READY)
6035 {
6036 /* Set the FMPI2C DMA Abort callback :
6037 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
6038 hfmpi2c->hdmatx->XferAbortCallback = FMPI2C_DMAAbort;
6039
6040 /* Process Unlocked */
6041 __HAL_UNLOCK(hfmpi2c);
6042
6043 /* Abort DMA TX */
6044 if (HAL_DMA_Abort_IT(hfmpi2c->hdmatx) != HAL_OK)
6045 {
6046 /* Call Directly XferAbortCallback function in case of error */
6047 hfmpi2c->hdmatx->XferAbortCallback(hfmpi2c->hdmatx);
6048 }
6049 }
6050 else
6051 {
6052 FMPI2C_TreatErrorCallback(hfmpi2c);
6053 }
6054 }
6055 /* Abort DMA RX transfer if any */
6056 else if ((hfmpi2c->hdmarx != NULL) && ((tmppreviousstate == FMPI2C_STATE_MASTER_BUSY_RX) || \
6057 (tmppreviousstate == FMPI2C_STATE_SLAVE_BUSY_RX)))
6058 {
6059 if ((hfmpi2c->Instance->CR1 & FMPI2C_CR1_RXDMAEN) == FMPI2C_CR1_RXDMAEN)
6060 {
6061 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6062 }
6063
6064 if (HAL_DMA_GetState(hfmpi2c->hdmarx) != HAL_DMA_STATE_READY)
6065 {
6066 /* Set the FMPI2C DMA Abort callback :
6067 will lead to call HAL_FMPI2C_ErrorCallback() at end of DMA abort procedure */
6068 hfmpi2c->hdmarx->XferAbortCallback = FMPI2C_DMAAbort;
6069
6070 /* Process Unlocked */
6071 __HAL_UNLOCK(hfmpi2c);
6072
6073 /* Abort DMA RX */
6074 if (HAL_DMA_Abort_IT(hfmpi2c->hdmarx) != HAL_OK)
6075 {
6076 /* Call Directly hfmpi2c->hdmarx->XferAbortCallback function in case of error */
6077 hfmpi2c->hdmarx->XferAbortCallback(hfmpi2c->hdmarx);
6078 }
6079 }
6080 else
6081 {
6082 FMPI2C_TreatErrorCallback(hfmpi2c);
6083 }
6084 }
6085 else
6086 {
6087 FMPI2C_TreatErrorCallback(hfmpi2c);
6088 }
6089 }
6090
6091 /**
6092 * @brief FMPI2C Error callback treatment.
6093 * @param hfmpi2c FMPI2C handle.
6094 * @retval None
6095 */
FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef * hfmpi2c)6096 static void FMPI2C_TreatErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
6097 {
6098 if (hfmpi2c->State == HAL_FMPI2C_STATE_ABORT)
6099 {
6100 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6101 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6102
6103 /* Process Unlocked */
6104 __HAL_UNLOCK(hfmpi2c);
6105
6106 /* Call the corresponding callback to inform upper layer of End of Transfer */
6107 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6108 hfmpi2c->AbortCpltCallback(hfmpi2c);
6109 #else
6110 HAL_FMPI2C_AbortCpltCallback(hfmpi2c);
6111 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6112 }
6113 else
6114 {
6115 hfmpi2c->PreviousState = FMPI2C_STATE_NONE;
6116
6117 /* Process Unlocked */
6118 __HAL_UNLOCK(hfmpi2c);
6119
6120 /* Call the corresponding callback to inform upper layer of End of Transfer */
6121 #if (USE_HAL_FMPI2C_REGISTER_CALLBACKS == 1)
6122 hfmpi2c->ErrorCallback(hfmpi2c);
6123 #else
6124 HAL_FMPI2C_ErrorCallback(hfmpi2c);
6125 #endif /* USE_HAL_FMPI2C_REGISTER_CALLBACKS */
6126 }
6127 }
6128
6129 /**
6130 * @brief FMPI2C Tx data register flush process.
6131 * @param hfmpi2c FMPI2C handle.
6132 * @retval None
6133 */
FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef * hfmpi2c)6134 static void FMPI2C_Flush_TXDR(FMPI2C_HandleTypeDef *hfmpi2c)
6135 {
6136 /* If a pending TXIS flag is set */
6137 /* Write a dummy data in TXDR to clear it */
6138 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) != RESET)
6139 {
6140 hfmpi2c->Instance->TXDR = 0x00U;
6141 }
6142
6143 /* Flush TX register if not empty */
6144 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXE) == RESET)
6145 {
6146 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_TXE);
6147 }
6148 }
6149
6150 /**
6151 * @brief DMA FMPI2C master transmit process complete callback.
6152 * @param hdma DMA handle
6153 * @retval None
6154 */
FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef * hdma)6155 static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
6156 {
6157 /* Derogation MISRAC2012-Rule-11.5 */
6158 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6159
6160 /* Disable DMA Request */
6161 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6162
6163 /* If last transfer, enable STOP interrupt */
6164 if (hfmpi2c->XferCount == 0U)
6165 {
6166 /* Enable STOP interrupt */
6167 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
6168 }
6169 /* else prepare a new DMA transfer and enable TCReload interrupt */
6170 else
6171 {
6172 /* Update Buffer pointer */
6173 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
6174
6175 /* Set the XferSize to transfer */
6176 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
6177 {
6178 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
6179 }
6180 else
6181 {
6182 hfmpi2c->XferSize = hfmpi2c->XferCount;
6183 }
6184
6185 /* Enable the DMA stream */
6186 if (HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR,
6187 hfmpi2c->XferSize) != HAL_OK)
6188 {
6189 /* Call the corresponding callback to inform upper layer of End of Transfer */
6190 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6191 }
6192 else
6193 {
6194 /* Enable TC interrupts */
6195 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
6196 }
6197 }
6198 }
6199
6200 /**
6201 * @brief DMA FMPI2C slave transmit process complete callback.
6202 * @param hdma DMA handle
6203 * @retval None
6204 */
FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef * hdma)6205 static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
6206 {
6207 /* Derogation MISRAC2012-Rule-11.5 */
6208 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6209 uint32_t tmpoptions = hfmpi2c->XferOptions;
6210
6211 if ((tmpoptions == FMPI2C_NEXT_FRAME) || (tmpoptions == FMPI2C_FIRST_FRAME))
6212 {
6213 /* Disable DMA Request */
6214 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
6215
6216 /* Last Byte is Transmitted */
6217 /* Call FMPI2C Slave Sequential complete process */
6218 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6219 }
6220 else
6221 {
6222 /* No specific action, Master fully manage the generation of STOP condition */
6223 /* Mean that this generation can arrive at any time, at the end or during DMA process */
6224 /* So STOP condition should be manage through Interrupt treatment */
6225 }
6226 }
6227
6228 /**
6229 * @brief DMA FMPI2C master receive process complete callback.
6230 * @param hdma DMA handle
6231 * @retval None
6232 */
FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef * hdma)6233 static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
6234 {
6235 /* Derogation MISRAC2012-Rule-11.5 */
6236 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6237
6238 /* Disable DMA Request */
6239 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6240
6241 /* If last transfer, enable STOP interrupt */
6242 if (hfmpi2c->XferCount == 0U)
6243 {
6244 /* Enable STOP interrupt */
6245 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_CPLT_IT);
6246 }
6247 /* else prepare a new DMA transfer and enable TCReload interrupt */
6248 else
6249 {
6250 /* Update Buffer pointer */
6251 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
6252
6253 /* Set the XferSize to transfer */
6254 if (hfmpi2c->XferCount > MAX_NBYTE_SIZE)
6255 {
6256 hfmpi2c->XferSize = MAX_NBYTE_SIZE;
6257 }
6258 else
6259 {
6260 hfmpi2c->XferSize = hfmpi2c->XferCount;
6261 }
6262
6263 /* Enable the DMA stream */
6264 if (HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr,
6265 hfmpi2c->XferSize) != HAL_OK)
6266 {
6267 /* Call the corresponding callback to inform upper layer of End of Transfer */
6268 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6269 }
6270 else
6271 {
6272 /* Enable TC interrupts */
6273 FMPI2C_Enable_IRQ(hfmpi2c, FMPI2C_XFER_RELOAD_IT);
6274 }
6275 }
6276 }
6277
6278 /**
6279 * @brief DMA FMPI2C slave receive process complete callback.
6280 * @param hdma DMA handle
6281 * @retval None
6282 */
FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef * hdma)6283 static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
6284 {
6285 /* Derogation MISRAC2012-Rule-11.5 */
6286 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6287 uint32_t tmpoptions = hfmpi2c->XferOptions;
6288
6289 if ((__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U) && \
6290 (tmpoptions != FMPI2C_NO_OPTION_FRAME))
6291 {
6292 /* Disable DMA Request */
6293 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
6294
6295 /* Call FMPI2C Slave Sequential complete process */
6296 FMPI2C_ITSlaveSeqCplt(hfmpi2c);
6297 }
6298 else
6299 {
6300 /* No specific action, Master fully manage the generation of STOP condition */
6301 /* Mean that this generation can arrive at any time, at the end or during DMA process */
6302 /* So STOP condition should be manage through Interrupt treatment */
6303 }
6304 }
6305
6306 /**
6307 * @brief DMA FMPI2C communication error callback.
6308 * @param hdma DMA handle
6309 * @retval None
6310 */
FMPI2C_DMAError(DMA_HandleTypeDef * hdma)6311 static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
6312 {
6313 uint32_t treatdmaerror = 0U;
6314 /* Derogation MISRAC2012-Rule-11.5 */
6315 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6316
6317 if (hfmpi2c->hdmatx != NULL)
6318 {
6319 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmatx) == 0U)
6320 {
6321 treatdmaerror = 1U;
6322 }
6323 }
6324
6325 if (hfmpi2c->hdmarx != NULL)
6326 {
6327 if (__HAL_DMA_GET_COUNTER(hfmpi2c->hdmarx) == 0U)
6328 {
6329 treatdmaerror = 1U;
6330 }
6331 }
6332
6333 /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */
6334 if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U))
6335 {
6336 /* Disable Acknowledge */
6337 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
6338
6339 /* Call the corresponding callback to inform upper layer of End of Transfer */
6340 FMPI2C_ITError(hfmpi2c, HAL_FMPI2C_ERROR_DMA);
6341 }
6342 }
6343
6344 /**
6345 * @brief DMA FMPI2C communication abort callback
6346 * (To be called at end of DMA Abort procedure).
6347 * @param hdma DMA handle.
6348 * @retval None
6349 */
FMPI2C_DMAAbort(DMA_HandleTypeDef * hdma)6350 static void FMPI2C_DMAAbort(DMA_HandleTypeDef *hdma)
6351 {
6352 /* Derogation MISRAC2012-Rule-11.5 */
6353 FMPI2C_HandleTypeDef *hfmpi2c = (FMPI2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6354
6355 /* Reset AbortCpltCallback */
6356 if (hfmpi2c->hdmatx != NULL)
6357 {
6358 hfmpi2c->hdmatx->XferAbortCallback = NULL;
6359 }
6360 if (hfmpi2c->hdmarx != NULL)
6361 {
6362 hfmpi2c->hdmarx->XferAbortCallback = NULL;
6363 }
6364
6365 FMPI2C_TreatErrorCallback(hfmpi2c);
6366 }
6367
6368 /**
6369 * @brief This function handles FMPI2C Communication Timeout. It waits
6370 * until a flag is no longer in the specified status.
6371 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6372 * the configuration information for the specified FMPI2C.
6373 * @param Flag Specifies the FMPI2C flag to check.
6374 * @param Status The actual Flag status (SET or RESET).
6375 * @param Timeout Timeout duration
6376 * @param Tickstart Tick start value
6377 * @retval HAL status
6378 */
FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)6379 static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status,
6380 uint32_t Timeout, uint32_t Tickstart)
6381 {
6382 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == Status)
6383 {
6384 /* Check for the Timeout */
6385 if (Timeout != HAL_MAX_DELAY)
6386 {
6387 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6388 {
6389 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
6390 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6391 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6392
6393 /* Process Unlocked */
6394 __HAL_UNLOCK(hfmpi2c);
6395 return HAL_ERROR;
6396 }
6397 }
6398 }
6399 return HAL_OK;
6400 }
6401
6402 /**
6403 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag.
6404 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6405 * the configuration information for the specified FMPI2C.
6406 * @param Timeout Timeout duration
6407 * @param Tickstart Tick start value
6408 * @retval HAL status
6409 */
FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t Timeout,uint32_t Tickstart)6410 static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
6411 uint32_t Tickstart)
6412 {
6413 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
6414 {
6415 /* Check if an error is detected */
6416 if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
6417 {
6418 return HAL_ERROR;
6419 }
6420
6421 /* Check for the Timeout */
6422 if (Timeout != HAL_MAX_DELAY)
6423 {
6424 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6425 {
6426 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
6427 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6428 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6429
6430 /* Process Unlocked */
6431 __HAL_UNLOCK(hfmpi2c);
6432
6433 return HAL_ERROR;
6434 }
6435 }
6436 }
6437 return HAL_OK;
6438 }
6439
6440 /**
6441 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag.
6442 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6443 * the configuration information for the specified FMPI2C.
6444 * @param Timeout Timeout duration
6445 * @param Tickstart Tick start value
6446 * @retval HAL status
6447 */
FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t Timeout,uint32_t Tickstart)6448 static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
6449 uint32_t Tickstart)
6450 {
6451 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
6452 {
6453 /* Check if an error is detected */
6454 if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
6455 {
6456 return HAL_ERROR;
6457 }
6458
6459 /* Check for the Timeout */
6460 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6461 {
6462 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
6463 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6464 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6465
6466 /* Process Unlocked */
6467 __HAL_UNLOCK(hfmpi2c);
6468
6469 return HAL_ERROR;
6470 }
6471 }
6472 return HAL_OK;
6473 }
6474
6475 /**
6476 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag.
6477 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6478 * the configuration information for the specified FMPI2C.
6479 * @param Timeout Timeout duration
6480 * @param Tickstart Tick start value
6481 * @retval HAL status
6482 */
FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t Timeout,uint32_t Tickstart)6483 static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout,
6484 uint32_t Tickstart)
6485 {
6486 while (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET)
6487 {
6488 /* Check if an error is detected */
6489 if (FMPI2C_IsErrorOccurred(hfmpi2c, Timeout, Tickstart) != HAL_OK)
6490 {
6491 return HAL_ERROR;
6492 }
6493
6494 /* Check if a STOPF is detected */
6495 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
6496 {
6497 /* Check if an RXNE is pending */
6498 /* Store Last receive data if any */
6499 if ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) && (hfmpi2c->XferSize > 0U))
6500 {
6501 /* Return HAL_OK */
6502 /* The Reading of data from RXDR will be done in caller function */
6503 return HAL_OK;
6504 }
6505 else
6506 {
6507 /* Clear STOP Flag */
6508 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
6509
6510 /* Clear Configuration Register 2 */
6511 FMPI2C_RESET_CR2(hfmpi2c);
6512
6513 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
6514 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6515 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6516
6517 /* Process Unlocked */
6518 __HAL_UNLOCK(hfmpi2c);
6519
6520 return HAL_ERROR;
6521 }
6522 }
6523
6524 /* Check for the Timeout */
6525 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6526 {
6527 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
6528 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6529
6530 /* Process Unlocked */
6531 __HAL_UNLOCK(hfmpi2c);
6532
6533 return HAL_ERROR;
6534 }
6535 }
6536 return HAL_OK;
6537 }
6538
6539 /**
6540 * @brief This function handles errors detection during an FMPI2C Communication.
6541 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6542 * the configuration information for the specified FMPI2C.
6543 * @param Timeout Timeout duration
6544 * @param Tickstart Tick start value
6545 * @retval HAL status
6546 */
FMPI2C_IsErrorOccurred(FMPI2C_HandleTypeDef * hfmpi2c,uint32_t Timeout,uint32_t Tickstart)6547 static HAL_StatusTypeDef FMPI2C_IsErrorOccurred(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout, uint32_t Tickstart)
6548 {
6549 HAL_StatusTypeDef status = HAL_OK;
6550 uint32_t itflag = hfmpi2c->Instance->ISR;
6551 uint32_t error_code = 0;
6552
6553 if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_AF))
6554 {
6555 /* In case of Soft End condition, generate the STOP condition */
6556 if (FMPI2C_GET_STOP_MODE(hfmpi2c) != FMPI2C_AUTOEND_MODE)
6557 {
6558 /* Generate Stop */
6559 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
6560 }
6561
6562 /* Wait until STOP Flag is set or timeout occurred */
6563 /* AutoEnd should be initiate after AF */
6564 while ((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (status == HAL_OK))
6565 {
6566 /* Check for the Timeout */
6567 if (Timeout != HAL_MAX_DELAY)
6568 {
6569 if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
6570 {
6571 error_code |= HAL_FMPI2C_ERROR_TIMEOUT;
6572
6573 status = HAL_ERROR;
6574 }
6575 }
6576 }
6577
6578 /* In case STOP Flag is detected, clear it */
6579 if (status == HAL_OK)
6580 {
6581 /* Clear STOP Flag */
6582 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
6583 }
6584
6585 /* Clear NACKF Flag */
6586 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
6587
6588 error_code |= HAL_FMPI2C_ERROR_AF;
6589
6590 status = HAL_ERROR;
6591 }
6592
6593 /* Refresh Content of Status register */
6594 itflag = hfmpi2c->Instance->ISR;
6595
6596 /* Then verify if an additional errors occurs */
6597 /* Check if a Bus error occurred */
6598 if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_BERR))
6599 {
6600 error_code |= HAL_FMPI2C_ERROR_BERR;
6601
6602 /* Clear BERR flag */
6603 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
6604
6605 status = HAL_ERROR;
6606 }
6607
6608 /* Check if an Over-Run/Under-Run error occurred */
6609 if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_OVR))
6610 {
6611 error_code |= HAL_FMPI2C_ERROR_OVR;
6612
6613 /* Clear OVR flag */
6614 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
6615
6616 status = HAL_ERROR;
6617 }
6618
6619 /* Check if an Arbitration Loss error occurred */
6620 if (HAL_IS_BIT_SET(itflag, FMPI2C_FLAG_ARLO))
6621 {
6622 error_code |= HAL_FMPI2C_ERROR_ARLO;
6623
6624 /* Clear ARLO flag */
6625 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
6626
6627 status = HAL_ERROR;
6628 }
6629
6630 if (status != HAL_OK)
6631 {
6632 /* Flush TX register */
6633 FMPI2C_Flush_TXDR(hfmpi2c);
6634
6635 /* Clear Configuration Register 2 */
6636 FMPI2C_RESET_CR2(hfmpi2c);
6637
6638 hfmpi2c->ErrorCode |= error_code;
6639 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
6640 hfmpi2c->Mode = HAL_FMPI2C_MODE_NONE;
6641
6642 /* Process Unlocked */
6643 __HAL_UNLOCK(hfmpi2c);
6644 }
6645
6646 return status;
6647 }
6648
6649 /**
6650 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
6651 * @param hfmpi2c FMPI2C handle.
6652 * @param DevAddress Specifies the slave address to be programmed.
6653 * @param Size Specifies the number of bytes to be programmed.
6654 * This parameter must be a value between 0 and 255.
6655 * @param Mode New state of the FMPI2C START condition generation.
6656 * This parameter can be one of the following values:
6657 * @arg @ref FMPI2C_RELOAD_MODE Enable Reload mode .
6658 * @arg @ref FMPI2C_AUTOEND_MODE Enable Automatic end mode.
6659 * @arg @ref FMPI2C_SOFTEND_MODE Enable Software end mode.
6660 * @param Request New state of the FMPI2C START condition generation.
6661 * This parameter can be one of the following values:
6662 * @arg @ref FMPI2C_NO_STARTSTOP Don't Generate stop and start condition.
6663 * @arg @ref FMPI2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
6664 * @arg @ref FMPI2C_GENERATE_START_READ Generate Restart for read request.
6665 * @arg @ref FMPI2C_GENERATE_START_WRITE Generate Restart for write request.
6666 * @retval None
6667 */
FMPI2C_TransferConfig(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)6668 static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
6669 uint32_t Request)
6670 {
6671 /* Check the parameters */
6672 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
6673 assert_param(IS_TRANSFER_MODE(Mode));
6674 assert_param(IS_TRANSFER_REQUEST(Request));
6675
6676 /* Declaration of tmp to prevent undefined behavior of volatile usage */
6677 uint32_t tmp = ((uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
6678 (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
6679 (uint32_t)Mode | (uint32_t)Request) & (~0x80000000U));
6680
6681 /* update CR2 register */
6682 MODIFY_REG(hfmpi2c->Instance->CR2, \
6683 ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
6684 (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - FMPI2C_CR2_RD_WRN_Pos))) | \
6685 FMPI2C_CR2_START | FMPI2C_CR2_STOP)), tmp);
6686 }
6687
6688 /**
6689 * @brief Manage the enabling of Interrupts.
6690 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6691 * the configuration information for the specified FMPI2C.
6692 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
6693 * @retval None
6694 */
FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t InterruptRequest)6695 static void FMPI2C_Enable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
6696 {
6697 uint32_t tmpisr = 0U;
6698
6699 if ((hfmpi2c->XferISR == FMPI2C_Master_ISR_DMA) || \
6700 (hfmpi2c->XferISR == FMPI2C_Slave_ISR_DMA))
6701 {
6702 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
6703 {
6704 /* Enable ERR, STOP, NACK and ADDR interrupts */
6705 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
6706 }
6707
6708 if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
6709 {
6710 /* Enable ERR and NACK interrupts */
6711 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
6712 }
6713
6714 if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
6715 {
6716 /* Enable STOP interrupts */
6717 tmpisr |= (FMPI2C_IT_STOPI | FMPI2C_IT_TCI);
6718 }
6719
6720 if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
6721 {
6722 /* Enable TC interrupts */
6723 tmpisr |= FMPI2C_IT_TCI;
6724 }
6725 }
6726 else
6727 {
6728 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
6729 {
6730 /* Enable ERR, STOP, NACK, and ADDR interrupts */
6731 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
6732 }
6733
6734 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
6735 {
6736 /* Enable ERR, TC, STOP, NACK and RXI interrupts */
6737 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI;
6738 }
6739
6740 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
6741 {
6742 /* Enable ERR, TC, STOP, NACK and TXI interrupts */
6743 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI;
6744 }
6745
6746 if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
6747 {
6748 /* Enable STOP interrupts */
6749 tmpisr |= FMPI2C_IT_STOPI;
6750 }
6751 }
6752
6753 /* Enable interrupts only at the end */
6754 /* to avoid the risk of FMPI2C interrupt handle execution before */
6755 /* all interrupts requested done */
6756 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, tmpisr);
6757 }
6758
6759 /**
6760 * @brief Manage the disabling of Interrupts.
6761 * @param hfmpi2c Pointer to a FMPI2C_HandleTypeDef structure that contains
6762 * the configuration information for the specified FMPI2C.
6763 * @param InterruptRequest Value of @ref FMPI2C_Interrupt_configuration_definition.
6764 * @retval None
6765 */
FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef * hfmpi2c,uint16_t InterruptRequest)6766 static void FMPI2C_Disable_IRQ(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t InterruptRequest)
6767 {
6768 uint32_t tmpisr = 0U;
6769
6770 if ((InterruptRequest & FMPI2C_XFER_TX_IT) == FMPI2C_XFER_TX_IT)
6771 {
6772 /* Disable TC and TXI interrupts */
6773 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_TXI;
6774
6775 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
6776 {
6777 /* Disable NACK and STOP interrupts */
6778 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
6779 }
6780 }
6781
6782 if ((InterruptRequest & FMPI2C_XFER_RX_IT) == FMPI2C_XFER_RX_IT)
6783 {
6784 /* Disable TC and RXI interrupts */
6785 tmpisr |= FMPI2C_IT_TCI | FMPI2C_IT_RXI;
6786
6787 if (((uint32_t)hfmpi2c->State & (uint32_t)HAL_FMPI2C_STATE_LISTEN) != (uint32_t)HAL_FMPI2C_STATE_LISTEN)
6788 {
6789 /* Disable NACK and STOP interrupts */
6790 tmpisr |= FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
6791 }
6792 }
6793
6794 if ((InterruptRequest & FMPI2C_XFER_LISTEN_IT) == FMPI2C_XFER_LISTEN_IT)
6795 {
6796 /* Disable ADDR, NACK and STOP interrupts */
6797 tmpisr |= FMPI2C_IT_ADDRI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ERRI;
6798 }
6799
6800 if (InterruptRequest == FMPI2C_XFER_ERROR_IT)
6801 {
6802 /* Enable ERR and NACK interrupts */
6803 tmpisr |= FMPI2C_IT_ERRI | FMPI2C_IT_NACKI;
6804 }
6805
6806 if (InterruptRequest == FMPI2C_XFER_CPLT_IT)
6807 {
6808 /* Enable STOP interrupts */
6809 tmpisr |= FMPI2C_IT_STOPI;
6810 }
6811
6812 if (InterruptRequest == FMPI2C_XFER_RELOAD_IT)
6813 {
6814 /* Enable TC interrupts */
6815 tmpisr |= FMPI2C_IT_TCI;
6816 }
6817
6818 /* Disable interrupts only at the end */
6819 /* to avoid a breaking situation like at "t" time */
6820 /* all disable interrupts request are not done */
6821 __HAL_FMPI2C_DISABLE_IT(hfmpi2c, tmpisr);
6822 }
6823
6824 /**
6825 * @brief Convert FMPI2Cx OTHER_xxx XferOptions to functional XferOptions.
6826 * @param hfmpi2c FMPI2C handle.
6827 * @retval None
6828 */
FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef * hfmpi2c)6829 static void FMPI2C_ConvertOtherXferOptions(FMPI2C_HandleTypeDef *hfmpi2c)
6830 {
6831 /* if user set XferOptions to FMPI2C_OTHER_FRAME */
6832 /* it request implicitly to generate a restart condition */
6833 /* set XferOptions to FMPI2C_FIRST_FRAME */
6834 if (hfmpi2c->XferOptions == FMPI2C_OTHER_FRAME)
6835 {
6836 hfmpi2c->XferOptions = FMPI2C_FIRST_FRAME;
6837 }
6838 /* else if user set XferOptions to FMPI2C_OTHER_AND_LAST_FRAME */
6839 /* it request implicitly to generate a restart condition */
6840 /* then generate a stop condition at the end of transfer */
6841 /* set XferOptions to FMPI2C_FIRST_AND_LAST_FRAME */
6842 else if (hfmpi2c->XferOptions == FMPI2C_OTHER_AND_LAST_FRAME)
6843 {
6844 hfmpi2c->XferOptions = FMPI2C_FIRST_AND_LAST_FRAME;
6845 }
6846 else
6847 {
6848 /* Nothing to do */
6849 }
6850 }
6851
6852 /**
6853 * @}
6854 */
6855
6856 #endif /* FMPI2C_CR1_PE */
6857 #endif /* HAL_FMPI2C_MODULE_ENABLED */
6858 /**
6859 * @}
6860 */
6861
6862 /**
6863 * @}
6864 */
6865