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