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