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