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