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