source: S-port/trunk/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c

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