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