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