1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_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 stream
44             (+++) Enable the DMAx interface clock using
45             (+++) Configure the DMA handle parameters
46             (+++) Configure the DMA Tx or Rx stream
47             (+++) Associate the initialized DMA handle to the 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 stream
50 
51     (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode,
52         Own Address2, Own Address2 Mask, General call and Nostretch mode in the 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 or memory 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 or memory 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 or memory 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 "stm32f7xx_hal.h"
324 
325 /** @addtogroup STM32F7xx_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 = 1U;
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   uint16_t tmpXferCount;
1383   HAL_StatusTypeDef error;
1384 
1385   if (hi2c->State == HAL_I2C_STATE_READY)
1386   {
1387     if ((pData == NULL) || (Size == 0U))
1388     {
1389       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1390       return  HAL_ERROR;
1391     }
1392     /* Process Locked */
1393     __HAL_LOCK(hi2c);
1394 
1395     /* Init tickstart for timeout management*/
1396     tickstart = HAL_GetTick();
1397 
1398     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
1399     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1400     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1401 
1402     /* Prepare transfer parameters */
1403     hi2c->pBuffPtr  = pData;
1404     hi2c->XferCount = Size;
1405     hi2c->XferISR   = NULL;
1406 
1407     /* Enable Address Acknowledge */
1408     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1409 
1410     /* Preload TX data if no stretch enable */
1411     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
1412     {
1413       /* Preload TX register */
1414       /* Write data to TXDR */
1415       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1416 
1417       /* Increment Buffer pointer */
1418       hi2c->pBuffPtr++;
1419 
1420       hi2c->XferCount--;
1421     }
1422 
1423     /* Wait until ADDR flag is set */
1424     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1425     {
1426       /* Disable Address Acknowledge */
1427       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1428 
1429       /* Flush TX register */
1430       I2C_Flush_TXDR(hi2c);
1431 
1432       return HAL_ERROR;
1433     }
1434 
1435     /* Clear ADDR flag */
1436     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1437 
1438     /* If 10bit addressing mode is selected */
1439     if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
1440     {
1441       /* Wait until ADDR flag is set */
1442       if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1443       {
1444         /* Disable Address Acknowledge */
1445         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1446 
1447         /* Flush TX register */
1448         I2C_Flush_TXDR(hi2c);
1449 
1450         return HAL_ERROR;
1451       }
1452 
1453       /* Clear ADDR flag */
1454       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1455     }
1456 
1457     /* Wait until DIR flag is set Transmitter mode */
1458     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK)
1459     {
1460       /* Disable Address Acknowledge */
1461       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1462 
1463       /* Flush TX register */
1464       I2C_Flush_TXDR(hi2c);
1465 
1466       return HAL_ERROR;
1467     }
1468 
1469     while (hi2c->XferCount > 0U)
1470     {
1471       /* Wait until TXIS flag is set */
1472       if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1473       {
1474         /* Disable Address Acknowledge */
1475         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1476         return HAL_ERROR;
1477       }
1478 
1479       /* Write data to TXDR */
1480       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1481 
1482       /* Increment Buffer pointer */
1483       hi2c->pBuffPtr++;
1484 
1485       hi2c->XferCount--;
1486     }
1487 
1488     /* Wait until AF flag is set */
1489     error = I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart);
1490 
1491     if (error != HAL_OK)
1492     {
1493       /* Check that I2C transfer finished */
1494       /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
1495       /* Mean XferCount == 0 */
1496 
1497       tmpXferCount = hi2c->XferCount;
1498       if ((hi2c->ErrorCode == HAL_I2C_ERROR_AF) && (tmpXferCount == 0U))
1499       {
1500         /* Reset ErrorCode to NONE */
1501         hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1502       }
1503       else
1504       {
1505         /* Disable Address Acknowledge */
1506         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1507         return HAL_ERROR;
1508       }
1509     }
1510     else
1511     {
1512       /* Flush TX register */
1513       I2C_Flush_TXDR(hi2c);
1514 
1515       /* Clear AF flag */
1516       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
1517 
1518       /* Wait until STOP flag is set */
1519       if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1520       {
1521         /* Disable Address Acknowledge */
1522         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1523 
1524         return HAL_ERROR;
1525       }
1526 
1527       /* Clear STOP flag */
1528       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1529     }
1530 
1531     /* Wait until BUSY flag is reset */
1532     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1533     {
1534       /* Disable Address Acknowledge */
1535       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1536       return HAL_ERROR;
1537     }
1538 
1539     /* Disable Address Acknowledge */
1540     hi2c->Instance->CR2 |= I2C_CR2_NACK;
1541 
1542     hi2c->State = HAL_I2C_STATE_READY;
1543     hi2c->Mode  = HAL_I2C_MODE_NONE;
1544 
1545     /* Process Unlocked */
1546     __HAL_UNLOCK(hi2c);
1547 
1548     return HAL_OK;
1549   }
1550   else
1551   {
1552     return HAL_BUSY;
1553   }
1554 }
1555 
1556 /**
1557   * @brief  Receive in slave mode an amount of data in blocking mode
1558   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1559   *                the configuration information for the specified I2C.
1560   * @param  pData Pointer to data buffer
1561   * @param  Size Amount of data to be sent
1562   * @param  Timeout Timeout duration
1563   * @retval HAL status
1564   */
HAL_I2C_Slave_Receive(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size,uint32_t Timeout)1565 HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
1566                                         uint32_t Timeout)
1567 {
1568   uint32_t tickstart;
1569 
1570   if (hi2c->State == HAL_I2C_STATE_READY)
1571   {
1572     if ((pData == NULL) || (Size == 0U))
1573     {
1574       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
1575       return  HAL_ERROR;
1576     }
1577     /* Process Locked */
1578     __HAL_LOCK(hi2c);
1579 
1580     /* Init tickstart for timeout management*/
1581     tickstart = HAL_GetTick();
1582 
1583     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
1584     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
1585     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
1586 
1587     /* Prepare transfer parameters */
1588     hi2c->pBuffPtr  = pData;
1589     hi2c->XferCount = Size;
1590     hi2c->XferSize = hi2c->XferCount;
1591     hi2c->XferISR   = NULL;
1592 
1593     /* Enable Address Acknowledge */
1594     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1595 
1596     /* Wait until ADDR flag is set */
1597     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK)
1598     {
1599       /* Disable Address Acknowledge */
1600       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1601       return HAL_ERROR;
1602     }
1603 
1604     /* Clear ADDR flag */
1605     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
1606 
1607     /* Wait until DIR flag is reset Receiver mode */
1608     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK)
1609     {
1610       /* Disable Address Acknowledge */
1611       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1612       return HAL_ERROR;
1613     }
1614 
1615     while (hi2c->XferCount > 0U)
1616     {
1617       /* Wait until RXNE flag is set */
1618       if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1619       {
1620         /* Disable Address Acknowledge */
1621         hi2c->Instance->CR2 |= I2C_CR2_NACK;
1622 
1623         /* Store Last receive data if any */
1624         if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET)
1625         {
1626           /* Read data from RXDR */
1627           *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1628 
1629           /* Increment Buffer pointer */
1630           hi2c->pBuffPtr++;
1631 
1632           hi2c->XferCount--;
1633           hi2c->XferSize--;
1634         }
1635 
1636         return HAL_ERROR;
1637       }
1638 
1639       /* Read data from RXDR */
1640       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
1641 
1642       /* Increment Buffer pointer */
1643       hi2c->pBuffPtr++;
1644 
1645       hi2c->XferCount--;
1646       hi2c->XferSize--;
1647     }
1648 
1649     /* Wait until STOP flag is set */
1650     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
1651     {
1652       /* Disable Address Acknowledge */
1653       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1654       return HAL_ERROR;
1655     }
1656 
1657     /* Clear STOP flag */
1658     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
1659 
1660     /* Wait until BUSY flag is reset */
1661     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK)
1662     {
1663       /* Disable Address Acknowledge */
1664       hi2c->Instance->CR2 |= I2C_CR2_NACK;
1665       return HAL_ERROR;
1666     }
1667 
1668     /* Disable Address Acknowledge */
1669     hi2c->Instance->CR2 |= I2C_CR2_NACK;
1670 
1671     hi2c->State = HAL_I2C_STATE_READY;
1672     hi2c->Mode  = HAL_I2C_MODE_NONE;
1673 
1674     /* Process Unlocked */
1675     __HAL_UNLOCK(hi2c);
1676 
1677     return HAL_OK;
1678   }
1679   else
1680   {
1681     return HAL_BUSY;
1682   }
1683 }
1684 
1685 /**
1686   * @brief  Transmit in master mode an amount of data in non-blocking mode with Interrupt
1687   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1688   *                the configuration information for the specified I2C.
1689   * @param  DevAddress Target device address: The device 7 bits address value
1690   *         in datasheet must be shifted to the left before calling the interface
1691   * @param  pData Pointer to data buffer
1692   * @param  Size Amount of data to be sent
1693   * @retval HAL status
1694   */
HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1695 HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1696                                              uint16_t Size)
1697 {
1698   uint32_t xfermode;
1699 
1700   if (hi2c->State == HAL_I2C_STATE_READY)
1701   {
1702     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1703     {
1704       return HAL_BUSY;
1705     }
1706 
1707     /* Process Locked */
1708     __HAL_LOCK(hi2c);
1709 
1710     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1711     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1712     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1713 
1714     /* Prepare transfer parameters */
1715     hi2c->pBuffPtr    = pData;
1716     hi2c->XferCount   = Size;
1717     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1718     hi2c->XferISR     = I2C_Master_ISR_IT;
1719 
1720     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1721     {
1722       hi2c->XferSize = MAX_NBYTE_SIZE;
1723       xfermode = I2C_RELOAD_MODE;
1724     }
1725     else
1726     {
1727       hi2c->XferSize = hi2c->XferCount;
1728       xfermode = I2C_AUTOEND_MODE;
1729     }
1730 
1731     /* Send Slave Address */
1732     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1733     if (hi2c->XferSize > 0U)
1734     {
1735       /* Preload TX register */
1736       /* Write data to TXDR */
1737       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1738 
1739       /* Increment Buffer pointer */
1740       hi2c->pBuffPtr++;
1741 
1742       hi2c->XferCount--;
1743       hi2c->XferSize--;
1744 
1745       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)(hi2c->XferSize + 1U), xfermode,
1746                          I2C_GENERATE_START_WRITE);
1747     }
1748     else
1749     {
1750       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode,
1751                          I2C_GENERATE_START_WRITE);
1752     }
1753 
1754     /* Process Unlocked */
1755     __HAL_UNLOCK(hi2c);
1756 
1757     /* Note : The I2C interrupts must be enabled after unlocking current process
1758               to avoid the risk of I2C interrupt handle execution before current
1759               process unlock */
1760 
1761     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1762     /* possible to enable all of these */
1763     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1764       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1765     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
1766 
1767     return HAL_OK;
1768   }
1769   else
1770   {
1771     return HAL_BUSY;
1772   }
1773 }
1774 
1775 /**
1776   * @brief  Receive in master mode an amount of data in non-blocking mode with Interrupt
1777   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1778   *                the configuration information for the specified I2C.
1779   * @param  DevAddress Target device address: The device 7 bits address value
1780   *         in datasheet must be shifted to the left before calling the interface
1781   * @param  pData Pointer to data buffer
1782   * @param  Size Amount of data to be sent
1783   * @retval HAL status
1784   */
HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1785 HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1786                                             uint16_t Size)
1787 {
1788   uint32_t xfermode;
1789 
1790   if (hi2c->State == HAL_I2C_STATE_READY)
1791   {
1792     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1793     {
1794       return HAL_BUSY;
1795     }
1796 
1797     /* Process Locked */
1798     __HAL_LOCK(hi2c);
1799 
1800     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1801     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1802     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1803 
1804     /* Prepare transfer parameters */
1805     hi2c->pBuffPtr    = pData;
1806     hi2c->XferCount   = Size;
1807     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1808     hi2c->XferISR     = I2C_Master_ISR_IT;
1809 
1810     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1811     {
1812       hi2c->XferSize = 1U;
1813       xfermode = I2C_RELOAD_MODE;
1814     }
1815     else
1816     {
1817       hi2c->XferSize = hi2c->XferCount;
1818       xfermode = I2C_AUTOEND_MODE;
1819     }
1820 
1821     /* Send Slave Address */
1822     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
1823     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
1824 
1825     /* Process Unlocked */
1826     __HAL_UNLOCK(hi2c);
1827 
1828     /* Note : The I2C interrupts must be enabled after unlocking current process
1829               to avoid the risk of I2C interrupt handle execution before current
1830               process unlock */
1831 
1832     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1833     /* possible to enable all of these */
1834     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1835       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1836     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
1837 
1838     return HAL_OK;
1839   }
1840   else
1841   {
1842     return HAL_BUSY;
1843   }
1844 }
1845 
1846 /**
1847   * @brief  Transmit in slave mode an amount of data in non-blocking mode with Interrupt
1848   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1849   *                the configuration information for the specified I2C.
1850   * @param  pData Pointer to data buffer
1851   * @param  Size Amount of data to be sent
1852   * @retval HAL status
1853   */
HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size)1854 HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1855 {
1856   if (hi2c->State == HAL_I2C_STATE_READY)
1857   {
1858     /* Process Locked */
1859     __HAL_LOCK(hi2c);
1860 
1861     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1862     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1863     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1864 
1865     /* Enable Address Acknowledge */
1866     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1867 
1868     /* Prepare transfer parameters */
1869     hi2c->pBuffPtr    = pData;
1870     hi2c->XferCount   = Size;
1871     hi2c->XferSize    = hi2c->XferCount;
1872     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1873     hi2c->XferISR     = I2C_Slave_ISR_IT;
1874 
1875     /* Preload TX data if no stretch enable */
1876     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
1877     {
1878       /* Preload TX register */
1879       /* Write data to TXDR */
1880       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
1881 
1882       /* Increment Buffer pointer */
1883       hi2c->pBuffPtr++;
1884 
1885       hi2c->XferCount--;
1886       hi2c->XferSize--;
1887     }
1888 
1889     /* Process Unlocked */
1890     __HAL_UNLOCK(hi2c);
1891 
1892     /* Note : The I2C interrupts must be enabled after unlocking current process
1893               to avoid the risk of I2C interrupt handle execution before current
1894               process unlock */
1895 
1896     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1897     /* possible to enable all of these */
1898     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1899       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1900     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
1901 
1902     return HAL_OK;
1903   }
1904   else
1905   {
1906     return HAL_BUSY;
1907   }
1908 }
1909 
1910 /**
1911   * @brief  Receive in slave mode an amount of data in non-blocking mode with Interrupt
1912   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1913   *                the configuration information for the specified I2C.
1914   * @param  pData Pointer to data buffer
1915   * @param  Size Amount of data to be sent
1916   * @retval HAL status
1917   */
HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size)1918 HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
1919 {
1920   if (hi2c->State == HAL_I2C_STATE_READY)
1921   {
1922     /* Process Locked */
1923     __HAL_LOCK(hi2c);
1924 
1925     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
1926     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
1927     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1928 
1929     /* Enable Address Acknowledge */
1930     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
1931 
1932     /* Prepare transfer parameters */
1933     hi2c->pBuffPtr    = pData;
1934     hi2c->XferCount   = Size;
1935     hi2c->XferSize    = hi2c->XferCount;
1936     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1937     hi2c->XferISR     = I2C_Slave_ISR_IT;
1938 
1939     /* Process Unlocked */
1940     __HAL_UNLOCK(hi2c);
1941 
1942     /* Note : The I2C interrupts must be enabled after unlocking current process
1943               to avoid the risk of I2C interrupt handle execution before current
1944               process unlock */
1945 
1946     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1947     /* possible to enable all of these */
1948     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
1949       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
1950     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
1951 
1952     return HAL_OK;
1953   }
1954   else
1955   {
1956     return HAL_BUSY;
1957   }
1958 }
1959 
1960 /**
1961   * @brief  Transmit in master mode an amount of data in non-blocking mode with DMA
1962   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
1963   *                the configuration information for the specified I2C.
1964   * @param  DevAddress Target device address: The device 7 bits address value
1965   *         in datasheet must be shifted to the left before calling the interface
1966   * @param  pData Pointer to data buffer
1967   * @param  Size Amount of data to be sent
1968   * @retval HAL status
1969   */
HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)1970 HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
1971                                               uint16_t Size)
1972 {
1973   uint32_t xfermode;
1974   HAL_StatusTypeDef dmaxferstatus;
1975   uint32_t sizetoxfer = 0U;
1976 
1977   if (hi2c->State == HAL_I2C_STATE_READY)
1978   {
1979     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
1980     {
1981       return HAL_BUSY;
1982     }
1983 
1984     /* Process Locked */
1985     __HAL_LOCK(hi2c);
1986 
1987     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
1988     hi2c->Mode        = HAL_I2C_MODE_MASTER;
1989     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
1990 
1991     /* Prepare transfer parameters */
1992     hi2c->pBuffPtr    = pData;
1993     hi2c->XferCount   = Size;
1994     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
1995     hi2c->XferISR     = I2C_Master_ISR_DMA;
1996 
1997     if (hi2c->XferCount > MAX_NBYTE_SIZE)
1998     {
1999       hi2c->XferSize = MAX_NBYTE_SIZE;
2000       xfermode = I2C_RELOAD_MODE;
2001     }
2002     else
2003     {
2004       hi2c->XferSize = hi2c->XferCount;
2005       xfermode = I2C_AUTOEND_MODE;
2006     }
2007 
2008     if (hi2c->XferSize > 0U)
2009     {
2010       /* Preload TX register */
2011       /* Write data to TXDR */
2012       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2013 
2014       /* Increment Buffer pointer */
2015       hi2c->pBuffPtr++;
2016 
2017       sizetoxfer = hi2c->XferSize;
2018       hi2c->XferCount--;
2019       hi2c->XferSize--;
2020     }
2021 
2022     if (hi2c->XferSize > 0U)
2023     {
2024       if (hi2c->hdmatx != NULL)
2025       {
2026         /* Set the I2C DMA transfer complete callback */
2027         hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
2028 
2029         /* Set the DMA error callback */
2030         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2031 
2032         /* Set the unused DMA callbacks to NULL */
2033         hi2c->hdmatx->XferHalfCpltCallback = NULL;
2034         hi2c->hdmatx->XferAbortCallback = NULL;
2035 
2036         /* Enable the DMA stream */
2037         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr,
2038                                          (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
2039       }
2040       else
2041       {
2042         /* Update I2C state */
2043         hi2c->State     = HAL_I2C_STATE_READY;
2044         hi2c->Mode      = HAL_I2C_MODE_NONE;
2045 
2046         /* Update I2C error code */
2047         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2048 
2049         /* Process Unlocked */
2050         __HAL_UNLOCK(hi2c);
2051 
2052         return HAL_ERROR;
2053       }
2054 
2055       if (dmaxferstatus == HAL_OK)
2056       {
2057         /* Send Slave Address */
2058         /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2059         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)(hi2c->XferSize + 1U),
2060                            xfermode, I2C_GENERATE_START_WRITE);
2061 
2062         /* Update XferCount value */
2063         hi2c->XferCount -= hi2c->XferSize;
2064 
2065         /* Process Unlocked */
2066         __HAL_UNLOCK(hi2c);
2067 
2068         /* Note : The I2C interrupts must be enabled after unlocking current process
2069                   to avoid the risk of I2C interrupt handle execution before current
2070                   process unlock */
2071         /* Enable ERR and NACK interrupts */
2072         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2073 
2074         /* Enable DMA Request */
2075         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2076       }
2077       else
2078       {
2079         /* Update I2C state */
2080         hi2c->State     = HAL_I2C_STATE_READY;
2081         hi2c->Mode      = HAL_I2C_MODE_NONE;
2082 
2083         /* Update I2C error code */
2084         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2085 
2086         /* Process Unlocked */
2087         __HAL_UNLOCK(hi2c);
2088 
2089         return HAL_ERROR;
2090       }
2091     }
2092     else
2093     {
2094       /* Update Transfer ISR function pointer */
2095       hi2c->XferISR = I2C_Master_ISR_IT;
2096 
2097       /* Send Slave Address */
2098       /* Set NBYTES to write and generate START condition */
2099       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, I2C_AUTOEND_MODE,
2100                          I2C_GENERATE_START_WRITE);
2101 
2102       /* Process Unlocked */
2103       __HAL_UNLOCK(hi2c);
2104 
2105       /* Note : The I2C interrupts must be enabled after unlocking current process
2106                 to avoid the risk of I2C interrupt handle execution before current
2107                 process unlock */
2108       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2109       /* possible to enable all of these */
2110       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2111         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2112       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2113     }
2114 
2115     return HAL_OK;
2116   }
2117   else
2118   {
2119     return HAL_BUSY;
2120   }
2121 }
2122 
2123 /**
2124   * @brief  Receive in master mode an amount of data in non-blocking mode with DMA
2125   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2126   *                the configuration information for the specified I2C.
2127   * @param  DevAddress Target device address: The device 7 bits address value
2128   *         in datasheet must be shifted to the left before calling the interface
2129   * @param  pData Pointer to data buffer
2130   * @param  Size Amount of data to be sent
2131   * @retval HAL status
2132   */
HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size)2133 HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
2134                                              uint16_t Size)
2135 {
2136   uint32_t xfermode;
2137   HAL_StatusTypeDef dmaxferstatus;
2138 
2139   if (hi2c->State == HAL_I2C_STATE_READY)
2140   {
2141     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2142     {
2143       return HAL_BUSY;
2144     }
2145 
2146     /* Process Locked */
2147     __HAL_LOCK(hi2c);
2148 
2149     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2150     hi2c->Mode        = HAL_I2C_MODE_MASTER;
2151     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2152 
2153     /* Prepare transfer parameters */
2154     hi2c->pBuffPtr    = pData;
2155     hi2c->XferCount   = Size;
2156     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2157     hi2c->XferISR     = I2C_Master_ISR_DMA;
2158 
2159     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2160     {
2161       hi2c->XferSize = 1U;
2162       xfermode = I2C_RELOAD_MODE;
2163     }
2164     else
2165     {
2166       hi2c->XferSize = hi2c->XferCount;
2167       xfermode = I2C_AUTOEND_MODE;
2168     }
2169 
2170     if (hi2c->XferSize > 0U)
2171     {
2172       if (hi2c->hdmarx != NULL)
2173       {
2174         /* Set the I2C DMA transfer complete callback */
2175         hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
2176 
2177         /* Set the DMA error callback */
2178         hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2179 
2180         /* Set the unused DMA callbacks to NULL */
2181         hi2c->hdmarx->XferHalfCpltCallback = NULL;
2182         hi2c->hdmarx->XferAbortCallback = NULL;
2183 
2184         /* Enable the DMA stream */
2185         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2186                                          hi2c->XferSize);
2187       }
2188       else
2189       {
2190         /* Update I2C state */
2191         hi2c->State     = HAL_I2C_STATE_READY;
2192         hi2c->Mode      = HAL_I2C_MODE_NONE;
2193 
2194         /* Update I2C error code */
2195         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2196 
2197         /* Process Unlocked */
2198         __HAL_UNLOCK(hi2c);
2199 
2200         return HAL_ERROR;
2201       }
2202 
2203       if (dmaxferstatus == HAL_OK)
2204       {
2205         /* Send Slave Address */
2206         /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2207         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ);
2208 
2209         /* Update XferCount value */
2210         hi2c->XferCount -= hi2c->XferSize;
2211 
2212         /* Process Unlocked */
2213         __HAL_UNLOCK(hi2c);
2214 
2215         /* Note : The I2C interrupts must be enabled after unlocking current process
2216                   to avoid the risk of I2C interrupt handle execution before current
2217                   process unlock */
2218         /* Enable ERR and NACK interrupts */
2219         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
2220 
2221         /* Enable DMA Request */
2222         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2223       }
2224       else
2225       {
2226         /* Update I2C state */
2227         hi2c->State     = HAL_I2C_STATE_READY;
2228         hi2c->Mode      = HAL_I2C_MODE_NONE;
2229 
2230         /* Update I2C error code */
2231         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2232 
2233         /* Process Unlocked */
2234         __HAL_UNLOCK(hi2c);
2235 
2236         return HAL_ERROR;
2237       }
2238     }
2239     else
2240     {
2241       /* Update Transfer ISR function pointer */
2242       hi2c->XferISR = I2C_Master_ISR_IT;
2243 
2244       /* Send Slave Address */
2245       /* Set NBYTES to read and generate START condition */
2246       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2247                          I2C_GENERATE_START_READ);
2248 
2249       /* Process Unlocked */
2250       __HAL_UNLOCK(hi2c);
2251 
2252       /* Note : The I2C interrupts must be enabled after unlocking current process
2253                 to avoid the risk of I2C interrupt handle execution before current
2254                 process unlock */
2255       /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2256       /* possible to enable all of these */
2257       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2258         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2259       I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
2260     }
2261 
2262     return HAL_OK;
2263   }
2264   else
2265   {
2266     return HAL_BUSY;
2267   }
2268 }
2269 
2270 /**
2271   * @brief  Transmit in slave mode an amount of data in non-blocking mode with DMA
2272   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2273   *                the configuration information for the specified I2C.
2274   * @param  pData Pointer to data buffer
2275   * @param  Size Amount of data to be sent
2276   * @retval HAL status
2277   */
HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size)2278 HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2279 {
2280   HAL_StatusTypeDef dmaxferstatus;
2281 
2282   if (hi2c->State == HAL_I2C_STATE_READY)
2283   {
2284     if ((pData == NULL) || (Size == 0U))
2285     {
2286       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2287       return  HAL_ERROR;
2288     }
2289     /* Process Locked */
2290     __HAL_LOCK(hi2c);
2291 
2292     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2293     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2294     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2295 
2296     /* Prepare transfer parameters */
2297     hi2c->pBuffPtr    = pData;
2298     hi2c->XferCount   = Size;
2299     hi2c->XferSize    = hi2c->XferCount;
2300     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2301     hi2c->XferISR     = I2C_Slave_ISR_DMA;
2302 
2303     /* Preload TX data if no stretch enable */
2304     if (hi2c->Init.NoStretchMode == I2C_NOSTRETCH_ENABLE)
2305     {
2306       /* Preload TX register */
2307       /* Write data to TXDR */
2308       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2309 
2310       /* Increment Buffer pointer */
2311       hi2c->pBuffPtr++;
2312 
2313       hi2c->XferCount--;
2314       hi2c->XferSize--;
2315     }
2316 
2317     if (hi2c->XferCount != 0U)
2318     {
2319       if (hi2c->hdmatx != NULL)
2320       {
2321         /* Set the I2C DMA transfer complete callback */
2322         hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
2323 
2324         /* Set the DMA error callback */
2325         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
2326 
2327         /* Set the unused DMA callbacks to NULL */
2328         hi2c->hdmatx->XferHalfCpltCallback = NULL;
2329         hi2c->hdmatx->XferAbortCallback = NULL;
2330 
2331         /* Enable the DMA stream */
2332         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx,
2333                                          (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR,
2334                                          hi2c->XferSize);
2335       }
2336       else
2337       {
2338         /* Update I2C state */
2339         hi2c->State     = HAL_I2C_STATE_LISTEN;
2340         hi2c->Mode      = HAL_I2C_MODE_NONE;
2341 
2342         /* Update I2C error code */
2343         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2344 
2345         /* Process Unlocked */
2346         __HAL_UNLOCK(hi2c);
2347 
2348         return HAL_ERROR;
2349       }
2350 
2351       if (dmaxferstatus == HAL_OK)
2352       {
2353         /* Enable Address Acknowledge */
2354         hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2355 
2356         /* Process Unlocked */
2357         __HAL_UNLOCK(hi2c);
2358 
2359         /* Note : The I2C interrupts must be enabled after unlocking current process
2360                   to avoid the risk of I2C interrupt handle execution before current
2361                   process unlock */
2362         /* Enable ERR, STOP, NACK, ADDR interrupts */
2363         I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2364 
2365         /* Enable DMA Request */
2366         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
2367       }
2368       else
2369       {
2370         /* Update I2C state */
2371         hi2c->State     = HAL_I2C_STATE_LISTEN;
2372         hi2c->Mode      = HAL_I2C_MODE_NONE;
2373 
2374         /* Update I2C error code */
2375         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2376 
2377         /* Process Unlocked */
2378         __HAL_UNLOCK(hi2c);
2379 
2380         return HAL_ERROR;
2381       }
2382     }
2383     else
2384     {
2385       /* Enable Address Acknowledge */
2386       hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2387 
2388       /* Process Unlocked */
2389       __HAL_UNLOCK(hi2c);
2390 
2391       /* Note : The I2C interrupts must be enabled after unlocking current process
2392       to avoid the risk of I2C interrupt handle execution before current
2393       process unlock */
2394       /* Enable ERR, STOP, NACK, ADDR interrupts */
2395       I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2396     }
2397 
2398     return HAL_OK;
2399   }
2400   else
2401   {
2402     return HAL_BUSY;
2403   }
2404 }
2405 
2406 /**
2407   * @brief  Receive in slave mode an amount of data in non-blocking mode with DMA
2408   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2409   *                the configuration information for the specified I2C.
2410   * @param  pData Pointer to data buffer
2411   * @param  Size Amount of data to be sent
2412   * @retval HAL status
2413   */
HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size)2414 HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
2415 {
2416   HAL_StatusTypeDef dmaxferstatus;
2417 
2418   if (hi2c->State == HAL_I2C_STATE_READY)
2419   {
2420     if ((pData == NULL) || (Size == 0U))
2421     {
2422       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2423       return  HAL_ERROR;
2424     }
2425     /* Process Locked */
2426     __HAL_LOCK(hi2c);
2427 
2428     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2429     hi2c->Mode        = HAL_I2C_MODE_SLAVE;
2430     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2431 
2432     /* Prepare transfer parameters */
2433     hi2c->pBuffPtr    = pData;
2434     hi2c->XferCount   = Size;
2435     hi2c->XferSize    = hi2c->XferCount;
2436     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2437     hi2c->XferISR     = I2C_Slave_ISR_DMA;
2438 
2439     if (hi2c->hdmarx != NULL)
2440     {
2441       /* Set the I2C DMA transfer complete callback */
2442       hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
2443 
2444       /* Set the DMA error callback */
2445       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
2446 
2447       /* Set the unused DMA callbacks to NULL */
2448       hi2c->hdmarx->XferHalfCpltCallback = NULL;
2449       hi2c->hdmarx->XferAbortCallback = NULL;
2450 
2451       /* Enable the DMA stream */
2452       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
2453                                        hi2c->XferSize);
2454     }
2455     else
2456     {
2457       /* Update I2C state */
2458       hi2c->State     = HAL_I2C_STATE_LISTEN;
2459       hi2c->Mode      = HAL_I2C_MODE_NONE;
2460 
2461       /* Update I2C error code */
2462       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
2463 
2464       /* Process Unlocked */
2465       __HAL_UNLOCK(hi2c);
2466 
2467       return HAL_ERROR;
2468     }
2469 
2470     if (dmaxferstatus == HAL_OK)
2471     {
2472       /* Enable Address Acknowledge */
2473       hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
2474 
2475       /* Process Unlocked */
2476       __HAL_UNLOCK(hi2c);
2477 
2478       /* Note : The I2C interrupts must be enabled after unlocking current process
2479                 to avoid the risk of I2C interrupt handle execution before current
2480                 process unlock */
2481       /* Enable ERR, STOP, NACK, ADDR interrupts */
2482       I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
2483 
2484       /* Enable DMA Request */
2485       hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
2486     }
2487     else
2488     {
2489       /* Update I2C state */
2490       hi2c->State     = HAL_I2C_STATE_LISTEN;
2491       hi2c->Mode      = HAL_I2C_MODE_NONE;
2492 
2493       /* Update I2C error code */
2494       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
2495 
2496       /* Process Unlocked */
2497       __HAL_UNLOCK(hi2c);
2498 
2499       return HAL_ERROR;
2500     }
2501 
2502     return HAL_OK;
2503   }
2504   else
2505   {
2506     return HAL_BUSY;
2507   }
2508 }
2509 
2510 /**
2511   * @brief  Write an amount of data in blocking mode to a specific memory address
2512   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2513   *                the configuration information for the specified I2C.
2514   * @param  DevAddress Target device address: The device 7 bits address value
2515   *         in datasheet must be shifted to the left before calling the interface
2516   * @param  MemAddress Internal memory address
2517   * @param  MemAddSize Size of internal memory address
2518   * @param  pData Pointer to data buffer
2519   * @param  Size Amount of data to be sent
2520   * @param  Timeout Timeout duration
2521   * @retval HAL status
2522   */
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)2523 HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2524                                     uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2525 {
2526   uint32_t tickstart;
2527 
2528   /* Check the parameters */
2529   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2530 
2531   if (hi2c->State == HAL_I2C_STATE_READY)
2532   {
2533     if ((pData == NULL) || (Size == 0U))
2534     {
2535       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2536       return  HAL_ERROR;
2537     }
2538 
2539     /* Process Locked */
2540     __HAL_LOCK(hi2c);
2541 
2542     /* Init tickstart for timeout management*/
2543     tickstart = HAL_GetTick();
2544 
2545     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2546     {
2547       return HAL_ERROR;
2548     }
2549 
2550     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
2551     hi2c->Mode      = HAL_I2C_MODE_MEM;
2552     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2553 
2554     /* Prepare transfer parameters */
2555     hi2c->pBuffPtr  = pData;
2556     hi2c->XferCount = Size;
2557     hi2c->XferISR   = NULL;
2558 
2559     /* Send Slave Address and Memory Address */
2560     if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2561     {
2562       /* Process Unlocked */
2563       __HAL_UNLOCK(hi2c);
2564       return HAL_ERROR;
2565     }
2566 
2567     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */
2568     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2569     {
2570       hi2c->XferSize = MAX_NBYTE_SIZE;
2571       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
2572     }
2573     else
2574     {
2575       hi2c->XferSize = hi2c->XferCount;
2576       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
2577     }
2578 
2579     do
2580     {
2581       /* Wait until TXIS flag is set */
2582       if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2583       {
2584         return HAL_ERROR;
2585       }
2586 
2587       /* Write data to TXDR */
2588       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
2589 
2590       /* Increment Buffer pointer */
2591       hi2c->pBuffPtr++;
2592 
2593       hi2c->XferCount--;
2594       hi2c->XferSize--;
2595 
2596       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2597       {
2598         /* Wait until TCR flag is set */
2599         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2600         {
2601           return HAL_ERROR;
2602         }
2603 
2604         if (hi2c->XferCount > MAX_NBYTE_SIZE)
2605         {
2606           hi2c->XferSize = MAX_NBYTE_SIZE;
2607           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2608                              I2C_NO_STARTSTOP);
2609         }
2610         else
2611         {
2612           hi2c->XferSize = hi2c->XferCount;
2613           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2614                              I2C_NO_STARTSTOP);
2615         }
2616       }
2617 
2618     } while (hi2c->XferCount > 0U);
2619 
2620     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2621     /* Wait until STOPF flag is reset */
2622     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2623     {
2624       return HAL_ERROR;
2625     }
2626 
2627     /* Clear STOP Flag */
2628     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2629 
2630     /* Clear Configuration Register 2 */
2631     I2C_RESET_CR2(hi2c);
2632 
2633     hi2c->State = HAL_I2C_STATE_READY;
2634     hi2c->Mode  = HAL_I2C_MODE_NONE;
2635 
2636     /* Process Unlocked */
2637     __HAL_UNLOCK(hi2c);
2638 
2639     return HAL_OK;
2640   }
2641   else
2642   {
2643     return HAL_BUSY;
2644   }
2645 }
2646 
2647 /**
2648   * @brief  Read an amount of data in blocking mode from a specific memory address
2649   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2650   *                the configuration information for the specified I2C.
2651   * @param  DevAddress Target device address: The device 7 bits address value
2652   *         in datasheet must be shifted to the left before calling the interface
2653   * @param  MemAddress Internal memory address
2654   * @param  MemAddSize Size of internal memory address
2655   * @param  pData Pointer to data buffer
2656   * @param  Size Amount of data to be sent
2657   * @param  Timeout Timeout duration
2658   * @retval HAL status
2659   */
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)2660 HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2661                                    uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2662 {
2663   uint32_t tickstart;
2664 
2665   /* Check the parameters */
2666   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2667 
2668   if (hi2c->State == HAL_I2C_STATE_READY)
2669   {
2670     if ((pData == NULL) || (Size == 0U))
2671     {
2672       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2673       return  HAL_ERROR;
2674     }
2675 
2676     /* Process Locked */
2677     __HAL_LOCK(hi2c);
2678 
2679     /* Init tickstart for timeout management*/
2680     tickstart = HAL_GetTick();
2681 
2682     if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
2683     {
2684       return HAL_ERROR;
2685     }
2686 
2687     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
2688     hi2c->Mode      = HAL_I2C_MODE_MEM;
2689     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
2690 
2691     /* Prepare transfer parameters */
2692     hi2c->pBuffPtr  = pData;
2693     hi2c->XferCount = Size;
2694     hi2c->XferISR   = NULL;
2695 
2696     /* Send Slave Address and Memory Address */
2697     if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK)
2698     {
2699       /* Process Unlocked */
2700       __HAL_UNLOCK(hi2c);
2701       return HAL_ERROR;
2702     }
2703 
2704     /* Send Slave Address */
2705     /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
2706     if (hi2c->XferCount > MAX_NBYTE_SIZE)
2707     {
2708       hi2c->XferSize = 1U;
2709       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE,
2710                          I2C_GENERATE_START_READ);
2711     }
2712     else
2713     {
2714       hi2c->XferSize = hi2c->XferCount;
2715       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2716                          I2C_GENERATE_START_READ);
2717     }
2718 
2719     do
2720     {
2721       /* Wait until RXNE flag is set */
2722       if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK)
2723       {
2724         return HAL_ERROR;
2725       }
2726 
2727       /* Read data from RXDR */
2728       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
2729 
2730       /* Increment Buffer pointer */
2731       hi2c->pBuffPtr++;
2732 
2733       hi2c->XferSize--;
2734       hi2c->XferCount--;
2735 
2736       if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
2737       {
2738         /* Wait until TCR flag is set */
2739         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
2740         {
2741           return HAL_ERROR;
2742         }
2743 
2744         if (hi2c->XferCount > MAX_NBYTE_SIZE)
2745         {
2746           hi2c->XferSize = 1U;
2747           I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE,
2748                              I2C_NO_STARTSTOP);
2749         }
2750         else
2751         {
2752           hi2c->XferSize = hi2c->XferCount;
2753           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
2754                              I2C_NO_STARTSTOP);
2755         }
2756       }
2757     } while (hi2c->XferCount > 0U);
2758 
2759     /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2760     /* Wait until STOPF flag is reset */
2761     if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
2762     {
2763       return HAL_ERROR;
2764     }
2765 
2766     /* Clear STOP Flag */
2767     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
2768 
2769     /* Clear Configuration Register 2 */
2770     I2C_RESET_CR2(hi2c);
2771 
2772     hi2c->State = HAL_I2C_STATE_READY;
2773     hi2c->Mode  = HAL_I2C_MODE_NONE;
2774 
2775     /* Process Unlocked */
2776     __HAL_UNLOCK(hi2c);
2777 
2778     return HAL_OK;
2779   }
2780   else
2781   {
2782     return HAL_BUSY;
2783   }
2784 }
2785 /**
2786   * @brief  Write an amount of data in non-blocking mode with Interrupt to a specific memory address
2787   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2788   *                the configuration information for the specified I2C.
2789   * @param  DevAddress Target device address: The device 7 bits address value
2790   *         in datasheet must be shifted to the left before calling the interface
2791   * @param  MemAddress Internal memory address
2792   * @param  MemAddSize Size of internal memory address
2793   * @param  pData Pointer to data buffer
2794   * @param  Size Amount of data to be sent
2795   * @retval HAL status
2796   */
HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2797 HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2798                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2799 {
2800   /* Check the parameters */
2801   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2802 
2803   if (hi2c->State == HAL_I2C_STATE_READY)
2804   {
2805     if ((pData == NULL) || (Size == 0U))
2806     {
2807       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2808       return  HAL_ERROR;
2809     }
2810 
2811     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2812     {
2813       return HAL_BUSY;
2814     }
2815 
2816     /* Process Locked */
2817     __HAL_LOCK(hi2c);
2818 
2819     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2820     hi2c->Mode        = HAL_I2C_MODE_MEM;
2821     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2822 
2823     /* Prepare transfer parameters */
2824     hi2c->XferSize    = 0U;
2825     hi2c->pBuffPtr    = pData;
2826     hi2c->XferCount   = Size;
2827     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2828     hi2c->XferISR     = I2C_Mem_ISR_IT;
2829     hi2c->Devaddress  = DevAddress;
2830 
2831     /* If Memory address size is 8Bit */
2832     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
2833     {
2834       /* Prefetch Memory Address */
2835       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
2836 
2837       /* Reset Memaddress content */
2838       hi2c->Memaddress = 0xFFFFFFFFU;
2839     }
2840     /* If Memory address size is 16Bit */
2841     else
2842     {
2843       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2844       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
2845 
2846       /* Prepare Memaddress buffer for LSB part */
2847       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
2848     }
2849     /* Send Slave Address and Memory Address */
2850     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
2851 
2852     /* Process Unlocked */
2853     __HAL_UNLOCK(hi2c);
2854 
2855     /* Note : The I2C interrupts must be enabled after unlocking current process
2856               to avoid the risk of I2C interrupt handle execution before current
2857               process unlock */
2858 
2859     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2860     /* possible to enable all of these */
2861     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2862       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2863     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2864 
2865     return HAL_OK;
2866   }
2867   else
2868   {
2869     return HAL_BUSY;
2870   }
2871 }
2872 
2873 /**
2874   * @brief  Read an amount of data in non-blocking mode with Interrupt from a specific memory address
2875   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2876   *                the configuration information for the specified I2C.
2877   * @param  DevAddress Target device address: The device 7 bits address value
2878   *         in datasheet must be shifted to the left before calling the interface
2879   * @param  MemAddress Internal memory address
2880   * @param  MemAddSize Size of internal memory address
2881   * @param  pData Pointer to data buffer
2882   * @param  Size Amount of data to be sent
2883   * @retval HAL status
2884   */
HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2885 HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2886                                       uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2887 {
2888   /* Check the parameters */
2889   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2890 
2891   if (hi2c->State == HAL_I2C_STATE_READY)
2892   {
2893     if ((pData == NULL) || (Size == 0U))
2894     {
2895       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2896       return  HAL_ERROR;
2897     }
2898 
2899     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2900     {
2901       return HAL_BUSY;
2902     }
2903 
2904     /* Process Locked */
2905     __HAL_LOCK(hi2c);
2906 
2907     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
2908     hi2c->Mode        = HAL_I2C_MODE_MEM;
2909     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2910 
2911     /* Prepare transfer parameters */
2912     hi2c->pBuffPtr    = pData;
2913     hi2c->XferCount   = Size;
2914     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
2915     hi2c->XferISR     = I2C_Mem_ISR_IT;
2916     hi2c->Devaddress  = DevAddress;
2917 
2918     /* If Memory address size is 8Bit */
2919     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
2920     {
2921       /* Prefetch Memory Address */
2922       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
2923 
2924       /* Reset Memaddress content */
2925       hi2c->Memaddress = 0xFFFFFFFFU;
2926     }
2927     /* If Memory address size is 16Bit */
2928     else
2929     {
2930       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
2931       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
2932 
2933       /* Prepare Memaddress buffer for LSB part */
2934       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
2935     }
2936     /* Send Slave Address and Memory Address */
2937     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
2938 
2939     /* Process Unlocked */
2940     __HAL_UNLOCK(hi2c);
2941 
2942     /* Note : The I2C interrupts must be enabled after unlocking current process
2943               to avoid the risk of I2C interrupt handle execution before current
2944               process unlock */
2945 
2946     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2947     /* possible to enable all of these */
2948     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
2949       I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
2950     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
2951 
2952     return HAL_OK;
2953   }
2954   else
2955   {
2956     return HAL_BUSY;
2957   }
2958 }
2959 
2960 /**
2961   * @brief  Write an amount of data in non-blocking mode with DMA to a specific memory address
2962   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
2963   *                the configuration information for the specified I2C.
2964   * @param  DevAddress Target device address: The device 7 bits address value
2965   *         in datasheet must be shifted to the left before calling the interface
2966   * @param  MemAddress Internal memory address
2967   * @param  MemAddSize Size of internal memory address
2968   * @param  pData Pointer to data buffer
2969   * @param  Size Amount of data to be sent
2970   * @retval HAL status
2971   */
HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)2972 HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
2973                                         uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2974 {
2975   HAL_StatusTypeDef dmaxferstatus;
2976 
2977   /* Check the parameters */
2978   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
2979 
2980   if (hi2c->State == HAL_I2C_STATE_READY)
2981   {
2982     if ((pData == NULL) || (Size == 0U))
2983     {
2984       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
2985       return  HAL_ERROR;
2986     }
2987 
2988     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
2989     {
2990       return HAL_BUSY;
2991     }
2992 
2993     /* Process Locked */
2994     __HAL_LOCK(hi2c);
2995 
2996     hi2c->State       = HAL_I2C_STATE_BUSY_TX;
2997     hi2c->Mode        = HAL_I2C_MODE_MEM;
2998     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
2999 
3000     /* Prepare transfer parameters */
3001     hi2c->pBuffPtr    = pData;
3002     hi2c->XferCount   = Size;
3003     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
3004     hi2c->XferISR     = I2C_Mem_ISR_DMA;
3005     hi2c->Devaddress  = DevAddress;
3006 
3007     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3008     {
3009       hi2c->XferSize = MAX_NBYTE_SIZE;
3010     }
3011     else
3012     {
3013       hi2c->XferSize = hi2c->XferCount;
3014     }
3015 
3016     /* If Memory address size is 8Bit */
3017     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
3018     {
3019       /* Prefetch Memory Address */
3020       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
3021 
3022       /* Reset Memaddress content */
3023       hi2c->Memaddress = 0xFFFFFFFFU;
3024     }
3025     /* If Memory address size is 16Bit */
3026     else
3027     {
3028       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3029       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
3030 
3031       /* Prepare Memaddress buffer for LSB part */
3032       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
3033     }
3034 
3035     if (hi2c->hdmatx != NULL)
3036     {
3037       /* Set the I2C DMA transfer complete callback */
3038       hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
3039 
3040       /* Set the DMA error callback */
3041       hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3042 
3043       /* Set the unused DMA callbacks to NULL */
3044       hi2c->hdmatx->XferHalfCpltCallback = NULL;
3045       hi2c->hdmatx->XferAbortCallback = NULL;
3046 
3047       /* Enable the DMA stream */
3048       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
3049                                        hi2c->XferSize);
3050     }
3051     else
3052     {
3053       /* Update I2C state */
3054       hi2c->State     = HAL_I2C_STATE_READY;
3055       hi2c->Mode      = HAL_I2C_MODE_NONE;
3056 
3057       /* Update I2C error code */
3058       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3059 
3060       /* Process Unlocked */
3061       __HAL_UNLOCK(hi2c);
3062 
3063       return HAL_ERROR;
3064     }
3065 
3066     if (dmaxferstatus == HAL_OK)
3067     {
3068       /* Send Slave Address and Memory Address */
3069       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
3070 
3071       /* Process Unlocked */
3072       __HAL_UNLOCK(hi2c);
3073 
3074       /* Note : The I2C interrupts must be enabled after unlocking current process
3075                 to avoid the risk of I2C interrupt handle execution before current
3076                 process unlock */
3077       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3078       /* possible to enable all of these */
3079       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3080         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3081       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3082     }
3083     else
3084     {
3085       /* Update I2C state */
3086       hi2c->State     = HAL_I2C_STATE_READY;
3087       hi2c->Mode      = HAL_I2C_MODE_NONE;
3088 
3089       /* Update I2C error code */
3090       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3091 
3092       /* Process Unlocked */
3093       __HAL_UNLOCK(hi2c);
3094 
3095       return HAL_ERROR;
3096     }
3097 
3098     return HAL_OK;
3099   }
3100   else
3101   {
3102     return HAL_BUSY;
3103   }
3104 }
3105 
3106 /**
3107   * @brief  Reads an amount of data in non-blocking mode with DMA from a specific memory address.
3108   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3109   *                the configuration information for the specified I2C.
3110   * @param  DevAddress Target device address: The device 7 bits address value
3111   *         in datasheet must be shifted to the left before calling the interface
3112   * @param  MemAddress Internal memory address
3113   * @param  MemAddSize Size of internal memory address
3114   * @param  pData Pointer to data buffer
3115   * @param  Size Amount of data to be read
3116   * @retval HAL status
3117   */
HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint8_t * pData,uint16_t Size)3118 HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
3119                                        uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
3120 {
3121   HAL_StatusTypeDef dmaxferstatus;
3122 
3123   /* Check the parameters */
3124   assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
3125 
3126   if (hi2c->State == HAL_I2C_STATE_READY)
3127   {
3128     if ((pData == NULL) || (Size == 0U))
3129     {
3130       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3131       return  HAL_ERROR;
3132     }
3133 
3134     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
3135     {
3136       return HAL_BUSY;
3137     }
3138 
3139     /* Process Locked */
3140     __HAL_LOCK(hi2c);
3141 
3142     hi2c->State       = HAL_I2C_STATE_BUSY_RX;
3143     hi2c->Mode        = HAL_I2C_MODE_MEM;
3144     hi2c->ErrorCode   = HAL_I2C_ERROR_NONE;
3145 
3146     /* Prepare transfer parameters */
3147     hi2c->pBuffPtr    = pData;
3148     hi2c->XferCount   = Size;
3149     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
3150     hi2c->XferISR     = I2C_Mem_ISR_DMA;
3151     hi2c->Devaddress  = DevAddress;
3152 
3153     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3154     {
3155       hi2c->XferSize = MAX_NBYTE_SIZE;
3156     }
3157     else
3158     {
3159       hi2c->XferSize = hi2c->XferCount;
3160     }
3161 
3162     /* If Memory address size is 8Bit */
3163     if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
3164     {
3165       /* Prefetch Memory Address */
3166       hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
3167 
3168       /* Reset Memaddress content */
3169       hi2c->Memaddress = 0xFFFFFFFFU;
3170     }
3171     /* If Memory address size is 16Bit */
3172     else
3173     {
3174       /* Prefetch Memory Address (MSB part, LSB will be manage through interrupt) */
3175       hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
3176 
3177       /* Prepare Memaddress buffer for LSB part */
3178       hi2c->Memaddress = I2C_MEM_ADD_LSB(MemAddress);
3179     }
3180 
3181     if (hi2c->hdmarx != NULL)
3182     {
3183       /* Set the I2C DMA transfer complete callback */
3184       hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3185 
3186       /* Set the DMA error callback */
3187       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3188 
3189       /* Set the unused DMA callbacks to NULL */
3190       hi2c->hdmarx->XferHalfCpltCallback = NULL;
3191       hi2c->hdmarx->XferAbortCallback = NULL;
3192 
3193       /* Enable the DMA stream */
3194       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3195                                        hi2c->XferSize);
3196     }
3197     else
3198     {
3199       /* Update I2C state */
3200       hi2c->State     = HAL_I2C_STATE_READY;
3201       hi2c->Mode      = HAL_I2C_MODE_NONE;
3202 
3203       /* Update I2C error code */
3204       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3205 
3206       /* Process Unlocked */
3207       __HAL_UNLOCK(hi2c);
3208 
3209       return HAL_ERROR;
3210     }
3211 
3212     if (dmaxferstatus == HAL_OK)
3213     {
3214       /* Send Slave Address and Memory Address */
3215       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
3216 
3217       /* Process Unlocked */
3218       __HAL_UNLOCK(hi2c);
3219 
3220       /* Note : The I2C interrupts must be enabled after unlocking current process
3221                 to avoid the risk of I2C interrupt handle execution before current
3222                 process unlock */
3223       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3224       /* possible to enable all of these */
3225       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3226         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3227       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3228     }
3229     else
3230     {
3231       /* Update I2C state */
3232       hi2c->State     = HAL_I2C_STATE_READY;
3233       hi2c->Mode      = HAL_I2C_MODE_NONE;
3234 
3235       /* Update I2C error code */
3236       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3237 
3238       /* Process Unlocked */
3239       __HAL_UNLOCK(hi2c);
3240 
3241       return HAL_ERROR;
3242     }
3243 
3244     return HAL_OK;
3245   }
3246   else
3247   {
3248     return HAL_BUSY;
3249   }
3250 }
3251 
3252 /**
3253   * @brief  Checks if target device is ready for communication.
3254   * @note   This function is used with Memory devices
3255   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3256   *                the configuration information for the specified I2C.
3257   * @param  DevAddress Target device address: The device 7 bits address value
3258   *         in datasheet must be shifted to the left before calling the interface
3259   * @param  Trials Number of trials
3260   * @param  Timeout Timeout duration
3261   * @retval HAL status
3262   */
HAL_I2C_IsDeviceReady(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)3263 HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials,
3264                                         uint32_t Timeout)
3265 {
3266   uint32_t tickstart;
3267 
3268   __IO uint32_t I2C_Trials = 0UL;
3269 
3270   FlagStatus tmp1;
3271   FlagStatus tmp2;
3272 
3273   if (hi2c->State == HAL_I2C_STATE_READY)
3274   {
3275     if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
3276     {
3277       return HAL_BUSY;
3278     }
3279 
3280     /* Process Locked */
3281     __HAL_LOCK(hi2c);
3282 
3283     hi2c->State = HAL_I2C_STATE_BUSY;
3284     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3285 
3286     do
3287     {
3288       /* Generate Start */
3289       hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);
3290 
3291       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3292       /* Wait until STOPF flag is set or a NACK flag is set*/
3293       tickstart = HAL_GetTick();
3294 
3295       tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3296       tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3297 
3298       while ((tmp1 == RESET) && (tmp2 == RESET))
3299       {
3300         if (Timeout != HAL_MAX_DELAY)
3301         {
3302           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
3303           {
3304             /* Update I2C state */
3305             hi2c->State = HAL_I2C_STATE_READY;
3306 
3307             /* Update I2C error code */
3308             hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3309 
3310             /* Process Unlocked */
3311             __HAL_UNLOCK(hi2c);
3312 
3313             return HAL_ERROR;
3314           }
3315         }
3316 
3317         tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
3318         tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
3319       }
3320 
3321       /* Check if the NACKF flag has not been set */
3322       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET)
3323       {
3324         /* Wait until STOPF flag is reset */
3325         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3326         {
3327           return HAL_ERROR;
3328         }
3329 
3330         /* Clear STOP Flag */
3331         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3332 
3333         /* Device is ready */
3334         hi2c->State = HAL_I2C_STATE_READY;
3335 
3336         /* Process Unlocked */
3337         __HAL_UNLOCK(hi2c);
3338 
3339         return HAL_OK;
3340       }
3341       else
3342       {
3343         /* Wait until STOPF flag is reset */
3344         if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK)
3345         {
3346           return HAL_ERROR;
3347         }
3348 
3349         /* Clear NACK Flag */
3350         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
3351 
3352         /* Clear STOP Flag, auto generated with autoend*/
3353         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
3354       }
3355 
3356       /* Increment Trials */
3357       I2C_Trials++;
3358     } while (I2C_Trials < Trials);
3359 
3360     /* Update I2C state */
3361     hi2c->State = HAL_I2C_STATE_READY;
3362 
3363     /* Update I2C error code */
3364     hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
3365 
3366     /* Process Unlocked */
3367     __HAL_UNLOCK(hi2c);
3368 
3369     return HAL_ERROR;
3370   }
3371   else
3372   {
3373     return HAL_BUSY;
3374   }
3375 }
3376 
3377 /**
3378   * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt.
3379   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3380   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3381   *                the configuration information for the specified I2C.
3382   * @param  DevAddress Target device address: The device 7 bits address value
3383   *         in datasheet must be shifted to the left before calling the interface
3384   * @param  pData Pointer to data buffer
3385   * @param  Size Amount of data to be sent
3386   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3387   * @retval HAL status
3388   */
HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3389 HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3390                                                  uint16_t Size, uint32_t XferOptions)
3391 {
3392   uint32_t xfermode;
3393   uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3394   uint32_t sizetoxfer = 0U;
3395 
3396   /* Check the parameters */
3397   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3398 
3399   if (hi2c->State == HAL_I2C_STATE_READY)
3400   {
3401     /* Process Locked */
3402     __HAL_LOCK(hi2c);
3403 
3404     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3405     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3406     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3407 
3408     /* Prepare transfer parameters */
3409     hi2c->pBuffPtr    = pData;
3410     hi2c->XferCount   = Size;
3411     hi2c->XferOptions = XferOptions;
3412     hi2c->XferISR     = I2C_Master_ISR_IT;
3413 
3414     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3415     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3416     {
3417       hi2c->XferSize = MAX_NBYTE_SIZE;
3418       xfermode = I2C_RELOAD_MODE;
3419     }
3420     else
3421     {
3422       hi2c->XferSize = hi2c->XferCount;
3423       xfermode = hi2c->XferOptions;
3424     }
3425 
3426     if ((hi2c->XferSize > 0U) && ((XferOptions == I2C_FIRST_FRAME) || \
3427                                   (XferOptions == I2C_FIRST_AND_LAST_FRAME)))
3428     {
3429       /* Preload TX register */
3430       /* Write data to TXDR */
3431       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
3432 
3433       /* Increment Buffer pointer */
3434       hi2c->pBuffPtr++;
3435 
3436       sizetoxfer = hi2c->XferSize;
3437       hi2c->XferCount--;
3438       hi2c->XferSize--;
3439     }
3440 
3441     /* If transfer direction not change and there is no request to start another frame,
3442        do not generate Restart Condition */
3443     /* Mean Previous state is same as current state */
3444     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3445         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3446     {
3447       xferrequest = I2C_NO_STARTSTOP;
3448     }
3449     else
3450     {
3451       /* Convert OTHER_xxx XferOptions if any */
3452       I2C_ConvertOtherXferOptions(hi2c);
3453 
3454       /* Update xfermode accordingly if no reload is necessary */
3455       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3456       {
3457         xfermode = hi2c->XferOptions;
3458       }
3459     }
3460 
3461     /* Send Slave Address and set NBYTES to write */
3462     if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3463     {
3464       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3465     }
3466     else
3467     {
3468       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3469     }
3470 
3471     /* Process Unlocked */
3472     __HAL_UNLOCK(hi2c);
3473 
3474     /* Note : The I2C interrupts must be enabled after unlocking current process
3475               to avoid the risk of I2C interrupt handle execution before current
3476               process unlock */
3477     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3478     /* possible to enable all of these */
3479     /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3480        I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3481     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3482 
3483     return HAL_OK;
3484   }
3485   else
3486   {
3487     return HAL_BUSY;
3488   }
3489 }
3490 
3491 /**
3492   * @brief  Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA.
3493   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3494   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3495   *                the configuration information for the specified I2C.
3496   * @param  DevAddress Target device address: The device 7 bits address value
3497   *         in datasheet must be shifted to the left before calling the interface
3498   * @param  pData Pointer to data buffer
3499   * @param  Size Amount of data to be sent
3500   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3501   * @retval HAL status
3502   */
HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3503 HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3504                                                   uint16_t Size, uint32_t XferOptions)
3505 {
3506   uint32_t xfermode;
3507   uint32_t xferrequest = I2C_GENERATE_START_WRITE;
3508   HAL_StatusTypeDef dmaxferstatus;
3509   uint32_t sizetoxfer = 0U;
3510 
3511   /* Check the parameters */
3512   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3513 
3514   if (hi2c->State == HAL_I2C_STATE_READY)
3515   {
3516     /* Process Locked */
3517     __HAL_LOCK(hi2c);
3518 
3519     hi2c->State     = HAL_I2C_STATE_BUSY_TX;
3520     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3521     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3522 
3523     /* Prepare transfer parameters */
3524     hi2c->pBuffPtr    = pData;
3525     hi2c->XferCount   = Size;
3526     hi2c->XferOptions = XferOptions;
3527     hi2c->XferISR     = I2C_Master_ISR_DMA;
3528 
3529     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3530     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3531     {
3532       hi2c->XferSize = MAX_NBYTE_SIZE;
3533       xfermode = I2C_RELOAD_MODE;
3534     }
3535     else
3536     {
3537       hi2c->XferSize = hi2c->XferCount;
3538       xfermode = hi2c->XferOptions;
3539     }
3540 
3541     if ((hi2c->XferSize > 0U) && ((XferOptions == I2C_FIRST_FRAME) || \
3542                                   (XferOptions == I2C_FIRST_AND_LAST_FRAME)))
3543     {
3544       /* Preload TX register */
3545       /* Write data to TXDR */
3546       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
3547 
3548       /* Increment Buffer pointer */
3549       hi2c->pBuffPtr++;
3550 
3551       sizetoxfer = hi2c->XferSize;
3552       hi2c->XferCount--;
3553       hi2c->XferSize--;
3554     }
3555 
3556     /* If transfer direction not change and there is no request to start another frame,
3557        do not generate Restart Condition */
3558     /* Mean Previous state is same as current state */
3559     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && \
3560         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3561     {
3562       xferrequest = I2C_NO_STARTSTOP;
3563     }
3564     else
3565     {
3566       /* Convert OTHER_xxx XferOptions if any */
3567       I2C_ConvertOtherXferOptions(hi2c);
3568 
3569       /* Update xfermode accordingly if no reload is necessary */
3570       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3571       {
3572         xfermode = hi2c->XferOptions;
3573       }
3574     }
3575 
3576     if (hi2c->XferSize > 0U)
3577     {
3578       if (hi2c->hdmatx != NULL)
3579       {
3580         /* Set the I2C DMA transfer complete callback */
3581         hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt;
3582 
3583         /* Set the DMA error callback */
3584         hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
3585 
3586         /* Set the unused DMA callbacks to NULL */
3587         hi2c->hdmatx->XferHalfCpltCallback = NULL;
3588         hi2c->hdmatx->XferAbortCallback = NULL;
3589 
3590         /* Enable the DMA stream */
3591         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr,
3592                                          (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize);
3593       }
3594       else
3595       {
3596         /* Update I2C state */
3597         hi2c->State     = HAL_I2C_STATE_READY;
3598         hi2c->Mode      = HAL_I2C_MODE_NONE;
3599 
3600         /* Update I2C error code */
3601         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3602 
3603         /* Process Unlocked */
3604         __HAL_UNLOCK(hi2c);
3605 
3606         return HAL_ERROR;
3607       }
3608 
3609       if (dmaxferstatus == HAL_OK)
3610       {
3611         /* Send Slave Address and set NBYTES to write */
3612         if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3613         {
3614           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3615         }
3616         else
3617         {
3618           I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3619         }
3620 
3621         /* Update XferCount value */
3622         hi2c->XferCount -= hi2c->XferSize;
3623 
3624         /* Process Unlocked */
3625         __HAL_UNLOCK(hi2c);
3626 
3627         /* Note : The I2C interrupts must be enabled after unlocking current process
3628                   to avoid the risk of I2C interrupt handle execution before current
3629                   process unlock */
3630         /* Enable ERR and NACK interrupts */
3631         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3632 
3633         /* Enable DMA Request */
3634         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
3635       }
3636       else
3637       {
3638         /* Update I2C state */
3639         hi2c->State     = HAL_I2C_STATE_READY;
3640         hi2c->Mode      = HAL_I2C_MODE_NONE;
3641 
3642         /* Update I2C error code */
3643         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3644 
3645         /* Process Unlocked */
3646         __HAL_UNLOCK(hi2c);
3647 
3648         return HAL_ERROR;
3649       }
3650     }
3651     else
3652     {
3653       /* Update Transfer ISR function pointer */
3654       hi2c->XferISR = I2C_Master_ISR_IT;
3655 
3656       /* Send Slave Address */
3657       /* Set NBYTES to write and generate START condition */
3658       if ((XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_FIRST_AND_LAST_FRAME))
3659       {
3660         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)sizetoxfer, xfermode, xferrequest);
3661       }
3662       else
3663       {
3664         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3665       }
3666 
3667       /* Process Unlocked */
3668       __HAL_UNLOCK(hi2c);
3669 
3670       /* Note : The I2C interrupts must be enabled after unlocking current process
3671                 to avoid the risk of I2C interrupt handle execution before current
3672                 process unlock */
3673       /* Enable ERR, TC, STOP, NACK, TXI interrupt */
3674       /* possible to enable all of these */
3675       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3676         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3677       I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT);
3678     }
3679 
3680     return HAL_OK;
3681   }
3682   else
3683   {
3684     return HAL_BUSY;
3685   }
3686 }
3687 
3688 /**
3689   * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt
3690   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3691   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3692   *                the configuration information for the specified I2C.
3693   * @param  DevAddress Target device address: The device 7 bits address value
3694   *         in datasheet must be shifted to the left before calling the interface
3695   * @param  pData Pointer to data buffer
3696   * @param  Size Amount of data to be sent
3697   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3698   * @retval HAL status
3699   */
HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3700 HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3701                                                 uint16_t Size, uint32_t XferOptions)
3702 {
3703   uint32_t xfermode;
3704   uint32_t xferrequest = I2C_GENERATE_START_READ;
3705 
3706   /* Check the parameters */
3707   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3708 
3709   if (hi2c->State == HAL_I2C_STATE_READY)
3710   {
3711     /* Process Locked */
3712     __HAL_LOCK(hi2c);
3713 
3714     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3715     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3716     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3717 
3718     /* Prepare transfer parameters */
3719     hi2c->pBuffPtr    = pData;
3720     hi2c->XferCount   = Size;
3721     hi2c->XferOptions = XferOptions;
3722     hi2c->XferISR     = I2C_Master_ISR_IT;
3723 
3724     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3725     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3726     {
3727       hi2c->XferSize = MAX_NBYTE_SIZE;
3728       xfermode = I2C_RELOAD_MODE;
3729     }
3730     else
3731     {
3732       hi2c->XferSize = hi2c->XferCount;
3733       xfermode = hi2c->XferOptions;
3734     }
3735 
3736     /* If transfer direction not change and there is no request to start another frame,
3737        do not generate Restart Condition */
3738     /* Mean Previous state is same as current state */
3739     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3740         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3741     {
3742       xferrequest = I2C_NO_STARTSTOP;
3743     }
3744     else
3745     {
3746       /* Convert OTHER_xxx XferOptions if any */
3747       I2C_ConvertOtherXferOptions(hi2c);
3748 
3749       /* Update xfermode accordingly if no reload is necessary */
3750       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3751       {
3752         xfermode = hi2c->XferOptions;
3753       }
3754     }
3755 
3756     /* Send Slave Address and set NBYTES to read */
3757     I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3758 
3759     /* Process Unlocked */
3760     __HAL_UNLOCK(hi2c);
3761 
3762     /* Note : The I2C interrupts must be enabled after unlocking current process
3763               to avoid the risk of I2C interrupt handle execution before current
3764               process unlock */
3765     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
3766 
3767     return HAL_OK;
3768   }
3769   else
3770   {
3771     return HAL_BUSY;
3772   }
3773 }
3774 
3775 /**
3776   * @brief  Sequential receive in master I2C mode an amount of data in non-blocking mode with DMA
3777   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3778   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3779   *                the configuration information for the specified I2C.
3780   * @param  DevAddress Target device address: The device 7 bits address value
3781   *         in datasheet must be shifted to the left before calling the interface
3782   * @param  pData Pointer to data buffer
3783   * @param  Size Amount of data to be sent
3784   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3785   * @retval HAL status
3786   */
HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3787 HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData,
3788                                                  uint16_t Size, uint32_t XferOptions)
3789 {
3790   uint32_t xfermode;
3791   uint32_t xferrequest = I2C_GENERATE_START_READ;
3792   HAL_StatusTypeDef dmaxferstatus;
3793 
3794   /* Check the parameters */
3795   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3796 
3797   if (hi2c->State == HAL_I2C_STATE_READY)
3798   {
3799     /* Process Locked */
3800     __HAL_LOCK(hi2c);
3801 
3802     hi2c->State     = HAL_I2C_STATE_BUSY_RX;
3803     hi2c->Mode      = HAL_I2C_MODE_MASTER;
3804     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
3805 
3806     /* Prepare transfer parameters */
3807     hi2c->pBuffPtr    = pData;
3808     hi2c->XferCount   = Size;
3809     hi2c->XferOptions = XferOptions;
3810     hi2c->XferISR     = I2C_Master_ISR_DMA;
3811 
3812     /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */
3813     if (hi2c->XferCount > MAX_NBYTE_SIZE)
3814     {
3815       hi2c->XferSize = MAX_NBYTE_SIZE;
3816       xfermode = I2C_RELOAD_MODE;
3817     }
3818     else
3819     {
3820       hi2c->XferSize = hi2c->XferCount;
3821       xfermode = hi2c->XferOptions;
3822     }
3823 
3824     /* If transfer direction not change and there is no request to start another frame,
3825        do not generate Restart Condition */
3826     /* Mean Previous state is same as current state */
3827     if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && \
3828         (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0))
3829     {
3830       xferrequest = I2C_NO_STARTSTOP;
3831     }
3832     else
3833     {
3834       /* Convert OTHER_xxx XferOptions if any */
3835       I2C_ConvertOtherXferOptions(hi2c);
3836 
3837       /* Update xfermode accordingly if no reload is necessary */
3838       if (hi2c->XferCount <= MAX_NBYTE_SIZE)
3839       {
3840         xfermode = hi2c->XferOptions;
3841       }
3842     }
3843 
3844     if (hi2c->XferSize > 0U)
3845     {
3846       if (hi2c->hdmarx != NULL)
3847       {
3848         /* Set the I2C DMA transfer complete callback */
3849         hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt;
3850 
3851         /* Set the DMA error callback */
3852         hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
3853 
3854         /* Set the unused DMA callbacks to NULL */
3855         hi2c->hdmarx->XferHalfCpltCallback = NULL;
3856         hi2c->hdmarx->XferAbortCallback = NULL;
3857 
3858         /* Enable the DMA stream */
3859         dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData,
3860                                          hi2c->XferSize);
3861       }
3862       else
3863       {
3864         /* Update I2C state */
3865         hi2c->State     = HAL_I2C_STATE_READY;
3866         hi2c->Mode      = HAL_I2C_MODE_NONE;
3867 
3868         /* Update I2C error code */
3869         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
3870 
3871         /* Process Unlocked */
3872         __HAL_UNLOCK(hi2c);
3873 
3874         return HAL_ERROR;
3875       }
3876 
3877       if (dmaxferstatus == HAL_OK)
3878       {
3879         /* Send Slave Address and set NBYTES to read */
3880         I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest);
3881 
3882         /* Update XferCount value */
3883         hi2c->XferCount -= hi2c->XferSize;
3884 
3885         /* Process Unlocked */
3886         __HAL_UNLOCK(hi2c);
3887 
3888         /* Note : The I2C interrupts must be enabled after unlocking current process
3889                   to avoid the risk of I2C interrupt handle execution before current
3890                   process unlock */
3891         /* Enable ERR and NACK interrupts */
3892         I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
3893 
3894         /* Enable DMA Request */
3895         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
3896       }
3897       else
3898       {
3899         /* Update I2C state */
3900         hi2c->State     = HAL_I2C_STATE_READY;
3901         hi2c->Mode      = HAL_I2C_MODE_NONE;
3902 
3903         /* Update I2C error code */
3904         hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
3905 
3906         /* Process Unlocked */
3907         __HAL_UNLOCK(hi2c);
3908 
3909         return HAL_ERROR;
3910       }
3911     }
3912     else
3913     {
3914       /* Update Transfer ISR function pointer */
3915       hi2c->XferISR = I2C_Master_ISR_IT;
3916 
3917       /* Send Slave Address */
3918       /* Set NBYTES to read and generate START condition */
3919       I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE,
3920                          I2C_GENERATE_START_READ);
3921 
3922       /* Process Unlocked */
3923       __HAL_UNLOCK(hi2c);
3924 
3925       /* Note : The I2C interrupts must be enabled after unlocking current process
3926                 to avoid the risk of I2C interrupt handle execution before current
3927                 process unlock */
3928       /* Enable ERR, TC, STOP, NACK, RXI interrupt */
3929       /* possible to enable all of these */
3930       /* I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI |
3931         I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */
3932       I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
3933     }
3934 
3935     return HAL_OK;
3936   }
3937   else
3938   {
3939     return HAL_BUSY;
3940   }
3941 }
3942 
3943 /**
3944   * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
3945   * @note   This interface allow to manage repeated start condition when a direction change during transfer
3946   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
3947   *                the configuration information for the specified I2C.
3948   * @param  pData Pointer to data buffer
3949   * @param  Size Amount of data to be sent
3950   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
3951   * @retval HAL status
3952   */
HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)3953 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
3954                                                 uint32_t XferOptions)
3955 {
3956   /* Declaration of tmp to prevent undefined behavior of volatile usage */
3957   FlagStatus tmp;
3958 
3959   /* Check the parameters */
3960   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
3961 
3962   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
3963   {
3964     if ((pData == NULL) || (Size == 0U))
3965     {
3966       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
3967       return  HAL_ERROR;
3968     }
3969 
3970     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
3971     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
3972 
3973     /* Process Locked */
3974     __HAL_LOCK(hi2c);
3975 
3976     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
3977     /* and then toggle the HAL slave RX state to TX state */
3978     if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
3979     {
3980       /* Disable associated Interrupts */
3981       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
3982 
3983       /* Abort DMA Xfer if any */
3984       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
3985       {
3986         hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
3987 
3988         if (hi2c->hdmarx != NULL)
3989         {
3990           /* Set the I2C DMA Abort callback :
3991            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
3992           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
3993 
3994           /* Abort DMA RX */
3995           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
3996           {
3997             /* Call Directly XferAbortCallback function in case of error */
3998             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
3999           }
4000         }
4001       }
4002     }
4003 
4004     hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
4005     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4006     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4007 
4008     /* Enable Address Acknowledge */
4009     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4010 
4011     /* Prepare transfer parameters */
4012     hi2c->pBuffPtr    = pData;
4013     hi2c->XferCount   = Size;
4014     hi2c->XferSize    = hi2c->XferCount;
4015     hi2c->XferOptions = XferOptions;
4016     hi2c->XferISR     = I2C_Slave_ISR_IT;
4017 
4018     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4019     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET))
4020     {
4021       /* Clear ADDR flag after prepare the transfer parameters */
4022       /* This action will generate an acknowledge to the Master */
4023       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4024     }
4025 
4026     /* Process Unlocked */
4027     __HAL_UNLOCK(hi2c);
4028 
4029     /* Note : The I2C interrupts must be enabled after unlocking current process
4030     to avoid the risk of I2C interrupt handle execution before current
4031     process unlock */
4032     /* REnable ADDR interrupt */
4033     I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT);
4034 
4035     return HAL_OK;
4036   }
4037   else
4038   {
4039     return HAL_ERROR;
4040   }
4041 }
4042 
4043 /**
4044   * @brief  Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with DMA
4045   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4046   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4047   *                the configuration information for the specified I2C.
4048   * @param  pData Pointer to data buffer
4049   * @param  Size Amount of data to be sent
4050   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4051   * @retval HAL status
4052   */
HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)4053 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4054                                                  uint32_t XferOptions)
4055 {
4056   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4057   FlagStatus tmp;
4058   HAL_StatusTypeDef dmaxferstatus;
4059 
4060   /* Check the parameters */
4061   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4062 
4063   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4064   {
4065     if ((pData == NULL) || (Size == 0U))
4066     {
4067       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4068       return  HAL_ERROR;
4069     }
4070 
4071     /* Process Locked */
4072     __HAL_LOCK(hi2c);
4073 
4074     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4075     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
4076 
4077     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4078     /* and then toggle the HAL slave RX state to TX state */
4079     if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
4080     {
4081       /* Disable associated Interrupts */
4082       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
4083 
4084       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
4085       {
4086         /* Abort DMA Xfer if any */
4087         if (hi2c->hdmarx != NULL)
4088         {
4089           hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
4090 
4091           /* Set the I2C DMA Abort callback :
4092           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4093           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
4094 
4095           /* Abort DMA RX */
4096           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
4097           {
4098             /* Call Directly XferAbortCallback function in case of error */
4099             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
4100           }
4101         }
4102       }
4103     }
4104     else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4105     {
4106       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4107       {
4108         hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4109 
4110         /* Abort DMA Xfer if any */
4111         if (hi2c->hdmatx != NULL)
4112         {
4113           /* Set the I2C DMA Abort callback :
4114           will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4115           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4116 
4117           /* Abort DMA TX */
4118           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4119           {
4120             /* Call Directly XferAbortCallback function in case of error */
4121             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4122           }
4123         }
4124       }
4125     }
4126     else
4127     {
4128       /* Nothing to do */
4129     }
4130 
4131     hi2c->State     = HAL_I2C_STATE_BUSY_TX_LISTEN;
4132     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4133     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4134 
4135     /* Enable Address Acknowledge */
4136     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4137 
4138     /* Prepare transfer parameters */
4139     hi2c->pBuffPtr    = pData;
4140     hi2c->XferCount   = Size;
4141     hi2c->XferSize    = hi2c->XferCount;
4142     hi2c->XferOptions = XferOptions;
4143     hi2c->XferISR     = I2C_Slave_ISR_DMA;
4144 
4145     if (hi2c->hdmatx != NULL)
4146     {
4147       /* Set the I2C DMA transfer complete callback */
4148       hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt;
4149 
4150       /* Set the DMA error callback */
4151       hi2c->hdmatx->XferErrorCallback = I2C_DMAError;
4152 
4153       /* Set the unused DMA callbacks to NULL */
4154       hi2c->hdmatx->XferHalfCpltCallback = NULL;
4155       hi2c->hdmatx->XferAbortCallback = NULL;
4156 
4157       /* Enable the DMA stream */
4158       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR,
4159                                        hi2c->XferSize);
4160     }
4161     else
4162     {
4163       /* Update I2C state */
4164       hi2c->State     = HAL_I2C_STATE_LISTEN;
4165       hi2c->Mode      = HAL_I2C_MODE_NONE;
4166 
4167       /* Update I2C error code */
4168       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
4169 
4170       /* Process Unlocked */
4171       __HAL_UNLOCK(hi2c);
4172 
4173       return HAL_ERROR;
4174     }
4175 
4176     if (dmaxferstatus == HAL_OK)
4177     {
4178       /* Update XferCount value */
4179       hi2c->XferCount -= hi2c->XferSize;
4180 
4181       /* Reset XferSize */
4182       hi2c->XferSize = 0;
4183     }
4184     else
4185     {
4186       /* Update I2C state */
4187       hi2c->State     = HAL_I2C_STATE_LISTEN;
4188       hi2c->Mode      = HAL_I2C_MODE_NONE;
4189 
4190       /* Update I2C error code */
4191       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
4192 
4193       /* Process Unlocked */
4194       __HAL_UNLOCK(hi2c);
4195 
4196       return HAL_ERROR;
4197     }
4198 
4199     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4200     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) && (tmp != RESET))
4201     {
4202       /* Clear ADDR flag after prepare the transfer parameters */
4203       /* This action will generate an acknowledge to the Master */
4204       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4205     }
4206 
4207     /* Process Unlocked */
4208     __HAL_UNLOCK(hi2c);
4209 
4210     /* Enable DMA Request */
4211     hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
4212 
4213     /* Note : The I2C interrupts must be enabled after unlocking current process
4214     to avoid the risk of I2C interrupt handle execution before current
4215     process unlock */
4216     /* Enable ERR, STOP, NACK, ADDR interrupts */
4217     I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4218 
4219     return HAL_OK;
4220   }
4221   else
4222   {
4223     return HAL_ERROR;
4224   }
4225 }
4226 
4227 /**
4228   * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt
4229   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4230   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4231   *                the configuration information for the specified I2C.
4232   * @param  pData Pointer to data buffer
4233   * @param  Size Amount of data to be sent
4234   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4235   * @retval HAL status
4236   */
HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)4237 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4238                                                uint32_t XferOptions)
4239 {
4240   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4241   FlagStatus tmp;
4242 
4243   /* Check the parameters */
4244   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4245 
4246   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4247   {
4248     if ((pData == NULL) || (Size == 0U))
4249     {
4250       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4251       return  HAL_ERROR;
4252     }
4253 
4254     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4255     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4256 
4257     /* Process Locked */
4258     __HAL_LOCK(hi2c);
4259 
4260     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4261     /* and then toggle the HAL slave TX state to RX state */
4262     if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4263     {
4264       /* Disable associated Interrupts */
4265       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4266 
4267       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4268       {
4269         hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4270 
4271         /* Abort DMA Xfer if any */
4272         if (hi2c->hdmatx != NULL)
4273         {
4274           /* Set the I2C DMA Abort callback :
4275            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4276           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4277 
4278           /* Abort DMA TX */
4279           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4280           {
4281             /* Call Directly XferAbortCallback function in case of error */
4282             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4283           }
4284         }
4285       }
4286     }
4287 
4288     hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4289     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4290     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4291 
4292     /* Enable Address Acknowledge */
4293     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4294 
4295     /* Prepare transfer parameters */
4296     hi2c->pBuffPtr    = pData;
4297     hi2c->XferCount   = Size;
4298     hi2c->XferSize    = hi2c->XferCount;
4299     hi2c->XferOptions = XferOptions;
4300     hi2c->XferISR     = I2C_Slave_ISR_IT;
4301 
4302     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4303     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4304     {
4305       /* Clear ADDR flag after prepare the transfer parameters */
4306       /* This action will generate an acknowledge to the Master */
4307       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4308     }
4309 
4310     /* Process Unlocked */
4311     __HAL_UNLOCK(hi2c);
4312 
4313     /* Note : The I2C interrupts must be enabled after unlocking current process
4314     to avoid the risk of I2C interrupt handle execution before current
4315     process unlock */
4316     /* REnable ADDR interrupt */
4317     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4318 
4319     return HAL_OK;
4320   }
4321   else
4322   {
4323     return HAL_ERROR;
4324   }
4325 }
4326 
4327 /**
4328   * @brief  Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with DMA
4329   * @note   This interface allow to manage repeated start condition when a direction change during transfer
4330   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4331   *                the configuration information for the specified I2C.
4332   * @param  pData Pointer to data buffer
4333   * @param  Size Amount of data to be sent
4334   * @param  XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS
4335   * @retval HAL status
4336   */
HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef * hi2c,uint8_t * pData,uint16_t Size,uint32_t XferOptions)4337 HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size,
4338                                                 uint32_t XferOptions)
4339 {
4340   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4341   FlagStatus tmp;
4342   HAL_StatusTypeDef dmaxferstatus;
4343 
4344   /* Check the parameters */
4345   assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions));
4346 
4347   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
4348   {
4349     if ((pData == NULL) || (Size == 0U))
4350     {
4351       hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM;
4352       return  HAL_ERROR;
4353     }
4354 
4355     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
4356     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
4357 
4358     /* Process Locked */
4359     __HAL_LOCK(hi2c);
4360 
4361     /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */
4362     /* and then toggle the HAL slave TX state to RX state */
4363     if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
4364     {
4365       /* Disable associated Interrupts */
4366       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4367 
4368       if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
4369       {
4370         /* Abort DMA Xfer if any */
4371         if (hi2c->hdmatx != NULL)
4372         {
4373           hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
4374 
4375           /* Set the I2C DMA Abort callback :
4376            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4377           hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
4378 
4379           /* Abort DMA TX */
4380           if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
4381           {
4382             /* Call Directly XferAbortCallback function in case of error */
4383             hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
4384           }
4385         }
4386       }
4387     }
4388     else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
4389     {
4390       if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
4391       {
4392         hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
4393 
4394         /* Abort DMA Xfer if any */
4395         if (hi2c->hdmarx != NULL)
4396         {
4397           /* Set the I2C DMA Abort callback :
4398            will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
4399           hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
4400 
4401           /* Abort DMA RX */
4402           if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
4403           {
4404             /* Call Directly XferAbortCallback function in case of error */
4405             hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
4406           }
4407         }
4408       }
4409     }
4410     else
4411     {
4412       /* Nothing to do */
4413     }
4414 
4415     hi2c->State     = HAL_I2C_STATE_BUSY_RX_LISTEN;
4416     hi2c->Mode      = HAL_I2C_MODE_SLAVE;
4417     hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
4418 
4419     /* Enable Address Acknowledge */
4420     hi2c->Instance->CR2 &= ~I2C_CR2_NACK;
4421 
4422     /* Prepare transfer parameters */
4423     hi2c->pBuffPtr    = pData;
4424     hi2c->XferCount   = Size;
4425     hi2c->XferSize    = hi2c->XferCount;
4426     hi2c->XferOptions = XferOptions;
4427     hi2c->XferISR     = I2C_Slave_ISR_DMA;
4428 
4429     if (hi2c->hdmarx != NULL)
4430     {
4431       /* Set the I2C DMA transfer complete callback */
4432       hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt;
4433 
4434       /* Set the DMA error callback */
4435       hi2c->hdmarx->XferErrorCallback = I2C_DMAError;
4436 
4437       /* Set the unused DMA callbacks to NULL */
4438       hi2c->hdmarx->XferHalfCpltCallback = NULL;
4439       hi2c->hdmarx->XferAbortCallback = NULL;
4440 
4441       /* Enable the DMA stream */
4442       dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR,
4443                                        (uint32_t)pData, hi2c->XferSize);
4444     }
4445     else
4446     {
4447       /* Update I2C state */
4448       hi2c->State     = HAL_I2C_STATE_LISTEN;
4449       hi2c->Mode      = HAL_I2C_MODE_NONE;
4450 
4451       /* Update I2C error code */
4452       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM;
4453 
4454       /* Process Unlocked */
4455       __HAL_UNLOCK(hi2c);
4456 
4457       return HAL_ERROR;
4458     }
4459 
4460     if (dmaxferstatus == HAL_OK)
4461     {
4462       /* Update XferCount value */
4463       hi2c->XferCount -= hi2c->XferSize;
4464 
4465       /* Reset XferSize */
4466       hi2c->XferSize = 0;
4467     }
4468     else
4469     {
4470       /* Update I2C state */
4471       hi2c->State     = HAL_I2C_STATE_LISTEN;
4472       hi2c->Mode      = HAL_I2C_MODE_NONE;
4473 
4474       /* Update I2C error code */
4475       hi2c->ErrorCode |= HAL_I2C_ERROR_DMA;
4476 
4477       /* Process Unlocked */
4478       __HAL_UNLOCK(hi2c);
4479 
4480       return HAL_ERROR;
4481     }
4482 
4483     tmp = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR);
4484     if ((I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) && (tmp != RESET))
4485     {
4486       /* Clear ADDR flag after prepare the transfer parameters */
4487       /* This action will generate an acknowledge to the Master */
4488       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
4489     }
4490 
4491     /* Process Unlocked */
4492     __HAL_UNLOCK(hi2c);
4493 
4494     /* Enable DMA Request */
4495     hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
4496 
4497     /* Note : The I2C interrupts must be enabled after unlocking current process
4498     to avoid the risk of I2C interrupt handle execution before current
4499     process unlock */
4500     /* REnable ADDR interrupt */
4501     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT);
4502 
4503     return HAL_OK;
4504   }
4505   else
4506   {
4507     return HAL_ERROR;
4508   }
4509 }
4510 
4511 /**
4512   * @brief  Enable the Address listen mode with Interrupt.
4513   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4514   *                the configuration information for the specified I2C.
4515   * @retval HAL status
4516   */
HAL_I2C_EnableListen_IT(I2C_HandleTypeDef * hi2c)4517 HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c)
4518 {
4519   if (hi2c->State == HAL_I2C_STATE_READY)
4520   {
4521     hi2c->State = HAL_I2C_STATE_LISTEN;
4522     hi2c->XferISR = I2C_Slave_ISR_IT;
4523 
4524     /* Enable the Address Match interrupt */
4525     I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4526 
4527     return HAL_OK;
4528   }
4529   else
4530   {
4531     return HAL_BUSY;
4532   }
4533 }
4534 
4535 /**
4536   * @brief  Disable the Address listen mode with Interrupt.
4537   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4538   *                the configuration information for the specified I2C
4539   * @retval HAL status
4540   */
HAL_I2C_DisableListen_IT(I2C_HandleTypeDef * hi2c)4541 HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c)
4542 {
4543   /* Declaration of tmp to prevent undefined behavior of volatile usage */
4544   uint32_t tmp;
4545 
4546   /* Disable Address listen mode only if a transfer is not ongoing */
4547   if (hi2c->State == HAL_I2C_STATE_LISTEN)
4548   {
4549     tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK;
4550     hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode);
4551     hi2c->State = HAL_I2C_STATE_READY;
4552     hi2c->Mode = HAL_I2C_MODE_NONE;
4553     hi2c->XferISR = NULL;
4554 
4555     /* Disable the Address Match interrupt */
4556     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
4557 
4558     return HAL_OK;
4559   }
4560   else
4561   {
4562     return HAL_BUSY;
4563   }
4564 }
4565 
4566 /**
4567   * @brief  Abort a master or memory I2C IT or DMA process communication with Interrupt.
4568   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4569   *                the configuration information for the specified I2C.
4570   * @param  DevAddress Target device address: The device 7 bits address value
4571   *         in datasheet must be shifted to the left before calling the interface
4572   * @retval HAL status
4573   */
HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef * hi2c,uint16_t DevAddress)4574 HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress)
4575 {
4576   HAL_I2C_ModeTypeDef tmp_mode = hi2c->Mode;
4577 
4578   if ((tmp_mode == HAL_I2C_MODE_MASTER) || (tmp_mode == HAL_I2C_MODE_MEM))
4579   {
4580     /* Process Locked */
4581     __HAL_LOCK(hi2c);
4582 
4583     /* Disable Interrupts and Store Previous state */
4584     if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
4585     {
4586       I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
4587       hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
4588     }
4589     else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
4590     {
4591       I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
4592       hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
4593     }
4594     else
4595     {
4596       /* Do nothing */
4597     }
4598 
4599     /* Set State at HAL_I2C_STATE_ABORT */
4600     hi2c->State = HAL_I2C_STATE_ABORT;
4601 
4602     /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */
4603     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
4604     I2C_TransferConfig(hi2c, DevAddress, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP);
4605 
4606     /* Process Unlocked */
4607     __HAL_UNLOCK(hi2c);
4608 
4609     /* Note : The I2C interrupts must be enabled after unlocking current process
4610               to avoid the risk of I2C interrupt handle execution before current
4611               process unlock */
4612     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
4613 
4614     return HAL_OK;
4615   }
4616   else
4617   {
4618     /* Wrong usage of abort function */
4619     /* This function should be used only in case of abort monitored by master device */
4620     return HAL_ERROR;
4621   }
4622 }
4623 
4624 /**
4625   * @}
4626   */
4627 
4628 /** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
4629   * @{
4630   */
4631 
4632 /**
4633   * @brief  This function handles I2C event interrupt request.
4634   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4635   *                the configuration information for the specified I2C.
4636   * @retval None
4637   */
HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef * hi2c)4638 void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) /* Derogation MISRAC2012-Rule-8.13 */
4639 {
4640   /* Get current IT Flags and IT sources value */
4641   uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4642   uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4643 
4644   /* I2C events treatment -------------------------------------*/
4645   if (hi2c->XferISR != NULL)
4646   {
4647     hi2c->XferISR(hi2c, itflags, itsources);
4648   }
4649 }
4650 
4651 /**
4652   * @brief  This function handles I2C error interrupt request.
4653   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4654   *                the configuration information for the specified I2C.
4655   * @retval None
4656   */
HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef * hi2c)4657 void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c)
4658 {
4659   uint32_t itflags   = READ_REG(hi2c->Instance->ISR);
4660   uint32_t itsources = READ_REG(hi2c->Instance->CR1);
4661   uint32_t tmperror;
4662 
4663   /* I2C Bus error interrupt occurred ------------------------------------*/
4664   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_BERR) != RESET) && \
4665       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4666   {
4667     hi2c->ErrorCode |= HAL_I2C_ERROR_BERR;
4668 
4669     /* Clear BERR flag */
4670     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
4671   }
4672 
4673   /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
4674   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_OVR) != RESET) && \
4675       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4676   {
4677     hi2c->ErrorCode |= HAL_I2C_ERROR_OVR;
4678 
4679     /* Clear OVR flag */
4680     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
4681   }
4682 
4683   /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/
4684   if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_ARLO) != RESET) && \
4685       (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET))
4686   {
4687     hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO;
4688 
4689     /* Clear ARLO flag */
4690     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
4691   }
4692 
4693   /* Store current volatile hi2c->ErrorCode, misra rule */
4694   tmperror = hi2c->ErrorCode;
4695 
4696   /* Call the Error Callback in case of Error detected */
4697   if ((tmperror & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) !=  HAL_I2C_ERROR_NONE)
4698   {
4699     I2C_ITError(hi2c, tmperror);
4700   }
4701 }
4702 
4703 /**
4704   * @brief  Master Tx Transfer completed callback.
4705   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4706   *                the configuration information for the specified I2C.
4707   * @retval None
4708   */
HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef * hi2c)4709 __weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
4710 {
4711   /* Prevent unused argument(s) compilation warning */
4712   UNUSED(hi2c);
4713 
4714   /* NOTE : This function should not be modified, when the callback is needed,
4715             the HAL_I2C_MasterTxCpltCallback could be implemented in the user file
4716    */
4717 }
4718 
4719 /**
4720   * @brief  Master Rx Transfer completed callback.
4721   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4722   *                the configuration information for the specified I2C.
4723   * @retval None
4724   */
HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef * hi2c)4725 __weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
4726 {
4727   /* Prevent unused argument(s) compilation warning */
4728   UNUSED(hi2c);
4729 
4730   /* NOTE : This function should not be modified, when the callback is needed,
4731             the HAL_I2C_MasterRxCpltCallback could be implemented in the user file
4732    */
4733 }
4734 
4735 /** @brief  Slave Tx Transfer completed callback.
4736   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4737   *                the configuration information for the specified I2C.
4738   * @retval None
4739   */
HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef * hi2c)4740 __weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
4741 {
4742   /* Prevent unused argument(s) compilation warning */
4743   UNUSED(hi2c);
4744 
4745   /* NOTE : This function should not be modified, when the callback is needed,
4746             the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file
4747    */
4748 }
4749 
4750 /**
4751   * @brief  Slave Rx Transfer completed callback.
4752   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4753   *                the configuration information for the specified I2C.
4754   * @retval None
4755   */
HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef * hi2c)4756 __weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
4757 {
4758   /* Prevent unused argument(s) compilation warning */
4759   UNUSED(hi2c);
4760 
4761   /* NOTE : This function should not be modified, when the callback is needed,
4762             the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file
4763    */
4764 }
4765 
4766 /**
4767   * @brief  Slave Address Match callback.
4768   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4769   *                the configuration information for the specified I2C.
4770   * @param  TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION
4771   * @param  AddrMatchCode Address Match Code
4772   * @retval None
4773   */
HAL_I2C_AddrCallback(I2C_HandleTypeDef * hi2c,uint8_t TransferDirection,uint16_t AddrMatchCode)4774 __weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
4775 {
4776   /* Prevent unused argument(s) compilation warning */
4777   UNUSED(hi2c);
4778   UNUSED(TransferDirection);
4779   UNUSED(AddrMatchCode);
4780 
4781   /* NOTE : This function should not be modified, when the callback is needed,
4782             the HAL_I2C_AddrCallback() could be implemented in the user file
4783    */
4784 }
4785 
4786 /**
4787   * @brief  Listen Complete callback.
4788   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4789   *                the configuration information for the specified I2C.
4790   * @retval None
4791   */
HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef * hi2c)4792 __weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
4793 {
4794   /* Prevent unused argument(s) compilation warning */
4795   UNUSED(hi2c);
4796 
4797   /* NOTE : This function should not be modified, when the callback is needed,
4798             the HAL_I2C_ListenCpltCallback() could be implemented in the user file
4799    */
4800 }
4801 
4802 /**
4803   * @brief  Memory Tx Transfer completed callback.
4804   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4805   *                the configuration information for the specified I2C.
4806   * @retval None
4807   */
HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef * hi2c)4808 __weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
4809 {
4810   /* Prevent unused argument(s) compilation warning */
4811   UNUSED(hi2c);
4812 
4813   /* NOTE : This function should not be modified, when the callback is needed,
4814             the HAL_I2C_MemTxCpltCallback could be implemented in the user file
4815    */
4816 }
4817 
4818 /**
4819   * @brief  Memory Rx Transfer completed callback.
4820   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4821   *                the configuration information for the specified I2C.
4822   * @retval None
4823   */
HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef * hi2c)4824 __weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c)
4825 {
4826   /* Prevent unused argument(s) compilation warning */
4827   UNUSED(hi2c);
4828 
4829   /* NOTE : This function should not be modified, when the callback is needed,
4830             the HAL_I2C_MemRxCpltCallback could be implemented in the user file
4831    */
4832 }
4833 
4834 /**
4835   * @brief  I2C error callback.
4836   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4837   *                the configuration information for the specified I2C.
4838   * @retval None
4839   */
HAL_I2C_ErrorCallback(I2C_HandleTypeDef * hi2c)4840 __weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
4841 {
4842   /* Prevent unused argument(s) compilation warning */
4843   UNUSED(hi2c);
4844 
4845   /* NOTE : This function should not be modified, when the callback is needed,
4846             the HAL_I2C_ErrorCallback could be implemented in the user file
4847    */
4848 }
4849 
4850 /**
4851   * @brief  I2C abort callback.
4852   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4853   *                the configuration information for the specified I2C.
4854   * @retval None
4855   */
HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef * hi2c)4856 __weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c)
4857 {
4858   /* Prevent unused argument(s) compilation warning */
4859   UNUSED(hi2c);
4860 
4861   /* NOTE : This function should not be modified, when the callback is needed,
4862             the HAL_I2C_AbortCpltCallback could be implemented in the user file
4863    */
4864 }
4865 
4866 /**
4867   * @}
4868   */
4869 
4870 /** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
4871   *  @brief   Peripheral State, Mode and Error functions
4872   *
4873 @verbatim
4874  ===============================================================================
4875             ##### Peripheral State, Mode and Error functions #####
4876  ===============================================================================
4877     [..]
4878     This subsection permit to get in run-time the status of the peripheral
4879     and the data flow.
4880 
4881 @endverbatim
4882   * @{
4883   */
4884 
4885 /**
4886   * @brief  Return the I2C handle state.
4887   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4888   *                the configuration information for the specified I2C.
4889   * @retval HAL state
4890   */
HAL_I2C_GetState(const I2C_HandleTypeDef * hi2c)4891 HAL_I2C_StateTypeDef HAL_I2C_GetState(const I2C_HandleTypeDef *hi2c)
4892 {
4893   /* Return I2C handle state */
4894   return hi2c->State;
4895 }
4896 
4897 /**
4898   * @brief  Returns the I2C Master, Slave, Memory or no mode.
4899   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4900   *         the configuration information for I2C module
4901   * @retval HAL mode
4902   */
HAL_I2C_GetMode(const I2C_HandleTypeDef * hi2c)4903 HAL_I2C_ModeTypeDef HAL_I2C_GetMode(const I2C_HandleTypeDef *hi2c)
4904 {
4905   return hi2c->Mode;
4906 }
4907 
4908 /**
4909   * @brief  Return the I2C error code.
4910   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4911   *              the configuration information for the specified I2C.
4912   * @retval I2C Error Code
4913   */
HAL_I2C_GetError(const I2C_HandleTypeDef * hi2c)4914 uint32_t HAL_I2C_GetError(const I2C_HandleTypeDef *hi2c)
4915 {
4916   return hi2c->ErrorCode;
4917 }
4918 
4919 /**
4920   * @}
4921   */
4922 
4923 /**
4924   * @}
4925   */
4926 
4927 /** @addtogroup I2C_Private_Functions
4928   * @{
4929   */
4930 
4931 /**
4932   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt.
4933   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
4934   *                the configuration information for the specified I2C.
4935   * @param  ITFlags Interrupt flags to handle.
4936   * @param  ITSources Interrupt sources enabled.
4937   * @retval HAL status
4938   */
I2C_Master_ISR_IT(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)4939 static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
4940                                            uint32_t ITSources)
4941 {
4942   uint16_t devaddress;
4943   uint32_t tmpITFlags = ITFlags;
4944 
4945   /* Process Locked */
4946   __HAL_LOCK(hi2c);
4947 
4948   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
4949       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
4950   {
4951     /* Clear NACK Flag */
4952     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
4953 
4954     /* Set corresponding Error Code */
4955     /* No need to generate STOP, it is automatically done */
4956     /* Error callback will be send during stop flag treatment */
4957     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
4958 
4959     /* Flush TX register */
4960     I2C_Flush_TXDR(hi2c);
4961   }
4962   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
4963            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
4964   {
4965     /* Remove RXNE flag on temporary variable as read done */
4966     tmpITFlags &= ~I2C_FLAG_RXNE;
4967 
4968     /* Read data from RXDR */
4969     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
4970 
4971     /* Increment Buffer pointer */
4972     hi2c->pBuffPtr++;
4973 
4974     hi2c->XferSize--;
4975     hi2c->XferCount--;
4976   }
4977   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) == RESET) && \
4978            ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
4979             (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)))
4980   {
4981     /* Write data to TXDR */
4982     if (hi2c->XferCount != 0U)
4983     {
4984       /* Write data to TXDR */
4985       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
4986 
4987       /* Increment Buffer pointer */
4988       hi2c->pBuffPtr++;
4989 
4990       hi2c->XferSize--;
4991       hi2c->XferCount--;
4992     }
4993   }
4994   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \
4995            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
4996   {
4997     if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
4998     {
4999       devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
5000 
5001       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5002       {
5003         /* Errata workaround 170323 */
5004         if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5005         {
5006           hi2c->XferSize = 1U;
5007         }
5008         else
5009         {
5010           hi2c->XferSize = MAX_NBYTE_SIZE;
5011         }
5012         I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
5013       }
5014       else
5015       {
5016         hi2c->XferSize = hi2c->XferCount;
5017         if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5018         {
5019           I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
5020                              hi2c->XferOptions, I2C_NO_STARTSTOP);
5021         }
5022         else
5023         {
5024           I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize,
5025                              I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5026         }
5027       }
5028     }
5029     else
5030     {
5031       /* Call TxCpltCallback() if no stop mode is set */
5032       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5033       {
5034         /* Call I2C Master Sequential complete process */
5035         I2C_ITMasterSeqCplt(hi2c);
5036       }
5037       else
5038       {
5039         /* Wrong size Status regarding TCR flag event */
5040         /* Call the corresponding callback to inform upper layer of End of Transfer */
5041         I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5042       }
5043     }
5044   }
5045   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \
5046            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5047   {
5048     if (hi2c->XferCount == 0U)
5049     {
5050       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5051       {
5052         /* Generate a stop condition in case of no transfer option */
5053         if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
5054         {
5055           /* Generate Stop */
5056           hi2c->Instance->CR2 |= I2C_CR2_STOP;
5057         }
5058         else
5059         {
5060           /* Call I2C Master Sequential complete process */
5061           I2C_ITMasterSeqCplt(hi2c);
5062         }
5063       }
5064     }
5065     else
5066     {
5067       /* Wrong size Status regarding TC flag event */
5068       /* Call the corresponding callback to inform upper layer of End of Transfer */
5069       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5070     }
5071   }
5072   else
5073   {
5074     /* Nothing to do */
5075   }
5076 
5077   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5078       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5079   {
5080     /* Call I2C Master complete process */
5081     I2C_ITMasterCplt(hi2c, tmpITFlags);
5082   }
5083 
5084   /* Process Unlocked */
5085   __HAL_UNLOCK(hi2c);
5086 
5087   return HAL_OK;
5088 }
5089 
5090 /**
5091   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with Interrupt.
5092   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5093   *                the configuration information for the specified I2C.
5094   * @param  ITFlags Interrupt flags to handle.
5095   * @param  ITSources Interrupt sources enabled.
5096   * @retval HAL status
5097   */
I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)5098 static HAL_StatusTypeDef I2C_Mem_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5099                                         uint32_t ITSources)
5100 {
5101   uint32_t direction = I2C_GENERATE_START_WRITE;
5102   uint32_t tmpITFlags = ITFlags;
5103 
5104   /* Process Locked */
5105   __HAL_LOCK(hi2c);
5106 
5107   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
5108       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5109   {
5110     /* Clear NACK Flag */
5111     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5112 
5113     /* Set corresponding Error Code */
5114     /* No need to generate STOP, it is automatically done */
5115     /* Error callback will be send during stop flag treatment */
5116     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5117 
5118     /* Flush TX register */
5119     I2C_Flush_TXDR(hi2c);
5120   }
5121   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
5122            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
5123   {
5124     /* Remove RXNE flag on temporary variable as read done */
5125     tmpITFlags &= ~I2C_FLAG_RXNE;
5126 
5127     /* Read data from RXDR */
5128     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5129 
5130     /* Increment Buffer pointer */
5131     hi2c->pBuffPtr++;
5132 
5133     hi2c->XferSize--;
5134     hi2c->XferCount--;
5135   }
5136   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
5137            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5138   {
5139     if (hi2c->Memaddress == 0xFFFFFFFFU)
5140     {
5141       /* Write data to TXDR */
5142       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
5143 
5144       /* Increment Buffer pointer */
5145       hi2c->pBuffPtr++;
5146 
5147       hi2c->XferSize--;
5148       hi2c->XferCount--;
5149     }
5150     else
5151     {
5152       /* Write LSB part of Memory Address */
5153       hi2c->Instance->TXDR = hi2c->Memaddress;
5154 
5155       /* Reset Memaddress content */
5156       hi2c->Memaddress = 0xFFFFFFFFU;
5157     }
5158   }
5159   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && \
5160            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5161   {
5162     if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
5163     {
5164       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5165       {
5166         /* Errata workaround 170323 */
5167         if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5168         {
5169           hi2c->XferSize = 1U;
5170         }
5171         else
5172         {
5173           hi2c->XferSize = MAX_NBYTE_SIZE;
5174         }
5175         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5176                            I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
5177       }
5178       else
5179       {
5180         hi2c->XferSize = hi2c->XferCount;
5181         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5182                            I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5183       }
5184     }
5185     else
5186     {
5187       /* Wrong size Status regarding TCR flag event */
5188       /* Call the corresponding callback to inform upper layer of End of Transfer */
5189       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5190     }
5191   }
5192   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && \
5193            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5194   {
5195     /* Disable Interrupt related to address step */
5196     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5197 
5198     /* Enable ERR, TC, STOP, NACK and RXI interrupts */
5199     I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT);
5200 
5201     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5202     {
5203       direction = I2C_GENERATE_START_READ;
5204     }
5205 
5206     if (hi2c->XferCount > MAX_NBYTE_SIZE)
5207     {
5208       /* Errata workaround 170323 */
5209       if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5210       {
5211         hi2c->XferSize = 1U;
5212       }
5213       else
5214       {
5215         hi2c->XferSize = MAX_NBYTE_SIZE;
5216       }
5217 
5218       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5219       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5220                          I2C_RELOAD_MODE, direction);
5221     }
5222     else
5223     {
5224       hi2c->XferSize = hi2c->XferCount;
5225 
5226       /* Set NBYTES to write and generate RESTART */
5227       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5228                          I2C_AUTOEND_MODE, direction);
5229     }
5230   }
5231   else
5232   {
5233     /* Nothing to do */
5234   }
5235 
5236   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5237       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5238   {
5239     /* Call I2C Master complete process */
5240     I2C_ITMasterCplt(hi2c, tmpITFlags);
5241   }
5242 
5243   /* Process Unlocked */
5244   __HAL_UNLOCK(hi2c);
5245 
5246   return HAL_OK;
5247 }
5248 
5249 /**
5250   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt.
5251   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5252   *                the configuration information for the specified I2C.
5253   * @param  ITFlags Interrupt flags to handle.
5254   * @param  ITSources Interrupt sources enabled.
5255   * @retval HAL status
5256   */
I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)5257 static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5258                                           uint32_t ITSources)
5259 {
5260   uint32_t tmpoptions = hi2c->XferOptions;
5261   uint32_t tmpITFlags = ITFlags;
5262 
5263   /* Process locked */
5264   __HAL_LOCK(hi2c);
5265 
5266   /* Check if STOPF is set */
5267   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
5268       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5269   {
5270     /* Call I2C Slave complete process */
5271     I2C_ITSlaveCplt(hi2c, tmpITFlags);
5272   }
5273   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
5274            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5275   {
5276     /* Check that I2C transfer finished */
5277     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5278     /* Mean XferCount == 0*/
5279     /* So clear Flag NACKF only */
5280     if (hi2c->XferCount == 0U)
5281     {
5282       if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
5283         /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
5284            Warning[Pa134]: left and right operands are identical */
5285       {
5286         /* Call I2C Listen complete process */
5287         I2C_ITListenCplt(hi2c, tmpITFlags);
5288       }
5289       else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
5290       {
5291         /* Clear NACK Flag */
5292         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5293 
5294         /* Flush TX register */
5295         I2C_Flush_TXDR(hi2c);
5296 
5297         /* Last Byte is Transmitted */
5298         /* Call I2C Slave Sequential complete process */
5299         I2C_ITSlaveSeqCplt(hi2c);
5300       }
5301       else
5302       {
5303         /* Clear NACK Flag */
5304         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5305       }
5306     }
5307     else
5308     {
5309       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5310       /* Clear NACK Flag */
5311       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5312 
5313       /* Set ErrorCode corresponding to a Non-Acknowledge */
5314       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5315 
5316       if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
5317       {
5318         /* Call the corresponding callback to inform upper layer of End of Transfer */
5319         I2C_ITError(hi2c, hi2c->ErrorCode);
5320       }
5321     }
5322   }
5323   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && \
5324            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET))
5325   {
5326     if (hi2c->XferCount > 0U)
5327     {
5328       /* Read data from RXDR */
5329       *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
5330 
5331       /* Increment Buffer pointer */
5332       hi2c->pBuffPtr++;
5333 
5334       hi2c->XferSize--;
5335       hi2c->XferCount--;
5336     }
5337 
5338     if ((hi2c->XferCount == 0U) && \
5339         (tmpoptions != I2C_NO_OPTION_FRAME))
5340     {
5341       /* Call I2C Slave Sequential complete process */
5342       I2C_ITSlaveSeqCplt(hi2c);
5343     }
5344   }
5345   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_ADDR) != RESET) && \
5346            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
5347   {
5348     I2C_ITAddrCplt(hi2c, tmpITFlags);
5349   }
5350   else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && \
5351            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5352   {
5353     /* Write data to TXDR only if XferCount not reach "0" */
5354     /* A TXIS flag can be set, during STOP treatment      */
5355     /* Check if all Data have already been sent */
5356     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
5357     if (hi2c->XferCount > 0U)
5358     {
5359       /* Write data to TXDR */
5360       hi2c->Instance->TXDR = *hi2c->pBuffPtr;
5361 
5362       /* Increment Buffer pointer */
5363       hi2c->pBuffPtr++;
5364 
5365       hi2c->XferCount--;
5366       hi2c->XferSize--;
5367     }
5368     else
5369     {
5370       if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
5371       {
5372         /* Last Byte is Transmitted */
5373         /* Call I2C Slave Sequential complete process */
5374         I2C_ITSlaveSeqCplt(hi2c);
5375       }
5376     }
5377   }
5378   else
5379   {
5380     /* Nothing to do */
5381   }
5382 
5383   /* Process Unlocked */
5384   __HAL_UNLOCK(hi2c);
5385 
5386   return HAL_OK;
5387 }
5388 
5389 /**
5390   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA.
5391   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5392   *                the configuration information for the specified I2C.
5393   * @param  ITFlags Interrupt flags to handle.
5394   * @param  ITSources Interrupt sources enabled.
5395   * @retval HAL status
5396   */
I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)5397 static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5398                                             uint32_t ITSources)
5399 {
5400   uint16_t devaddress;
5401   uint32_t xfermode;
5402 
5403   /* Process Locked */
5404   __HAL_LOCK(hi2c);
5405 
5406   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5407       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5408   {
5409     /* Clear NACK Flag */
5410     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5411 
5412     /* Set corresponding Error Code */
5413     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5414 
5415     /* No need to generate STOP, it is automatically done */
5416     /* But enable STOP interrupt, to treat it */
5417     /* Error callback will be send during stop flag treatment */
5418     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
5419 
5420     /* Flush TX register */
5421     I2C_Flush_TXDR(hi2c);
5422   }
5423   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \
5424            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5425   {
5426     /* Disable TC interrupt */
5427     __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI);
5428 
5429     if (hi2c->XferCount != 0U)
5430     {
5431       /* Recover Slave address */
5432       devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD);
5433 
5434       /* Prepare the new XferSize to transfer */
5435       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5436       {
5437         /* Errata workaround 170323 */
5438         if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5439         {
5440           hi2c->XferSize = 1U;
5441         }
5442         else
5443         {
5444           hi2c->XferSize = MAX_NBYTE_SIZE;
5445         }
5446         xfermode = I2C_RELOAD_MODE;
5447       }
5448       else
5449       {
5450         hi2c->XferSize = hi2c->XferCount;
5451         if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
5452         {
5453           xfermode = hi2c->XferOptions;
5454         }
5455         else
5456         {
5457           xfermode = I2C_AUTOEND_MODE;
5458         }
5459       }
5460 
5461       /* Set the new XferSize in Nbytes register */
5462       I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP);
5463 
5464       /* Update XferCount value */
5465       hi2c->XferCount -= hi2c->XferSize;
5466 
5467       /* Enable DMA Request */
5468       if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5469       {
5470         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5471       }
5472       else
5473       {
5474         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5475       }
5476     }
5477     else
5478     {
5479       /* Call TxCpltCallback() if no stop mode is set */
5480       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5481       {
5482         /* Call I2C Master Sequential complete process */
5483         I2C_ITMasterSeqCplt(hi2c);
5484       }
5485       else
5486       {
5487         /* Wrong size Status regarding TCR flag event */
5488         /* Call the corresponding callback to inform upper layer of End of Transfer */
5489         I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5490       }
5491     }
5492   }
5493   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \
5494            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5495   {
5496     if (hi2c->XferCount == 0U)
5497     {
5498       if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE)
5499       {
5500         /* Generate a stop condition in case of no transfer option */
5501         if (hi2c->XferOptions == I2C_NO_OPTION_FRAME)
5502         {
5503           /* Generate Stop */
5504           hi2c->Instance->CR2 |= I2C_CR2_STOP;
5505         }
5506         else
5507         {
5508           /* Call I2C Master Sequential complete process */
5509           I2C_ITMasterSeqCplt(hi2c);
5510         }
5511       }
5512     }
5513     else
5514     {
5515       /* Wrong size Status regarding TC flag event */
5516       /* Call the corresponding callback to inform upper layer of End of Transfer */
5517       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5518     }
5519   }
5520   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5521            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5522   {
5523     /* Call I2C Master complete process */
5524     I2C_ITMasterCplt(hi2c, ITFlags);
5525   }
5526   else
5527   {
5528     /* Nothing to do */
5529   }
5530 
5531   /* Process Unlocked */
5532   __HAL_UNLOCK(hi2c);
5533 
5534   return HAL_OK;
5535 }
5536 
5537 /**
5538   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Memory Mode with DMA.
5539   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5540   *                the configuration information for the specified I2C.
5541   * @param  ITFlags Interrupt flags to handle.
5542   * @param  ITSources Interrupt sources enabled.
5543   * @retval HAL status
5544   */
I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)5545 static HAL_StatusTypeDef I2C_Mem_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5546                                          uint32_t ITSources)
5547 {
5548   uint32_t direction = I2C_GENERATE_START_WRITE;
5549 
5550   /* Process Locked */
5551   __HAL_LOCK(hi2c);
5552 
5553   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5554       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5555   {
5556     /* Clear NACK Flag */
5557     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5558 
5559     /* Set corresponding Error Code */
5560     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5561 
5562     /* No need to generate STOP, it is automatically done */
5563     /* But enable STOP interrupt, to treat it */
5564     /* Error callback will be send during stop flag treatment */
5565     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
5566 
5567     /* Flush TX register */
5568     I2C_Flush_TXDR(hi2c);
5569   }
5570   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TXIS) != RESET) && \
5571            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET))
5572   {
5573     /* Write LSB part of Memory Address */
5574     hi2c->Instance->TXDR = hi2c->Memaddress;
5575 
5576     /* Reset Memaddress content */
5577     hi2c->Memaddress = 0xFFFFFFFFU;
5578   }
5579   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && \
5580            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5581   {
5582     /* Disable Interrupt related to address step */
5583     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5584 
5585     /* Enable only Error interrupt */
5586     I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
5587 
5588     if (hi2c->XferCount != 0U)
5589     {
5590       /* Prepare the new XferSize to transfer */
5591       if (hi2c->XferCount > MAX_NBYTE_SIZE)
5592       {
5593         /* Errata workaround 170323 */
5594         if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5595         {
5596           hi2c->XferSize = 1U;
5597         }
5598         else
5599         {
5600           hi2c->XferSize = MAX_NBYTE_SIZE;
5601         }
5602         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5603                            I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
5604       }
5605       else
5606       {
5607         hi2c->XferSize = hi2c->XferCount;
5608         I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5609                            I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
5610       }
5611 
5612       /* Update XferCount value */
5613       hi2c->XferCount -= hi2c->XferSize;
5614 
5615       /* Enable DMA Request */
5616       if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5617       {
5618         hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5619       }
5620       else
5621       {
5622         hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5623       }
5624     }
5625     else
5626     {
5627       /* Wrong size Status regarding TCR flag event */
5628       /* Call the corresponding callback to inform upper layer of End of Transfer */
5629       I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE);
5630     }
5631   }
5632   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && \
5633            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET))
5634   {
5635     /* Disable Interrupt related to address step */
5636     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
5637 
5638     /* Enable only Error and NACK interrupt for data transfer */
5639     I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT);
5640 
5641     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5642     {
5643       direction = I2C_GENERATE_START_READ;
5644     }
5645 
5646     if (hi2c->XferCount > MAX_NBYTE_SIZE)
5647     {
5648       /* Errata workaround 170323 */
5649       if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
5650       {
5651         hi2c->XferSize = 1U;
5652       }
5653       else
5654       {
5655         hi2c->XferSize = MAX_NBYTE_SIZE;
5656       }
5657 
5658       /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
5659       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5660                          I2C_RELOAD_MODE, direction);
5661     }
5662     else
5663     {
5664       hi2c->XferSize = hi2c->XferCount;
5665 
5666       /* Set NBYTES to write and generate RESTART */
5667       I2C_TransferConfig(hi2c, (uint16_t)hi2c->Devaddress, (uint8_t)hi2c->XferSize,
5668                          I2C_AUTOEND_MODE, direction);
5669     }
5670 
5671     /* Update XferCount value */
5672     hi2c->XferCount -= hi2c->XferSize;
5673 
5674     /* Enable DMA Request */
5675     if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
5676     {
5677       hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN;
5678     }
5679     else
5680     {
5681       hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN;
5682     }
5683   }
5684   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5685            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5686   {
5687     /* Call I2C Master complete process */
5688     I2C_ITMasterCplt(hi2c, ITFlags);
5689   }
5690   else
5691   {
5692     /* Nothing to do */
5693   }
5694 
5695   /* Process Unlocked */
5696   __HAL_UNLOCK(hi2c);
5697 
5698   return HAL_OK;
5699 }
5700 
5701 /**
5702   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA.
5703   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5704   *                the configuration information for the specified I2C.
5705   * @param  ITFlags Interrupt flags to handle.
5706   * @param  ITSources Interrupt sources enabled.
5707   * @retval HAL status
5708   */
I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef * hi2c,uint32_t ITFlags,uint32_t ITSources)5709 static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags,
5710                                            uint32_t ITSources)
5711 {
5712   uint32_t tmpoptions = hi2c->XferOptions;
5713   uint32_t treatdmanack = 0U;
5714   HAL_I2C_StateTypeDef tmpstate;
5715 
5716   /* Process locked */
5717   __HAL_LOCK(hi2c);
5718 
5719   /* Check if STOPF is set */
5720   if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && \
5721       (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
5722   {
5723     /* Call I2C Slave complete process */
5724     I2C_ITSlaveCplt(hi2c, ITFlags);
5725   }
5726   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && \
5727            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET))
5728   {
5729     /* Check that I2C transfer finished */
5730     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
5731     /* Mean XferCount == 0 */
5732     /* So clear Flag NACKF only */
5733     if ((I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) ||
5734         (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET))
5735     {
5736       /* Split check of hdmarx, for MISRA compliance */
5737       if (hi2c->hdmarx != NULL)
5738       {
5739         if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET)
5740         {
5741           if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U)
5742           {
5743             treatdmanack = 1U;
5744           }
5745         }
5746       }
5747 
5748       /* Split check of hdmatx, for MISRA compliance  */
5749       if (hi2c->hdmatx != NULL)
5750       {
5751         if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET)
5752         {
5753           if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx) == 0U)
5754           {
5755             treatdmanack = 1U;
5756           }
5757         }
5758       }
5759 
5760       if (treatdmanack == 1U)
5761       {
5762         if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
5763           /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
5764              Warning[Pa134]: left and right operands are identical */
5765         {
5766           /* Call I2C Listen complete process */
5767           I2C_ITListenCplt(hi2c, ITFlags);
5768         }
5769         else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
5770         {
5771           /* Clear NACK Flag */
5772           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5773 
5774           /* Flush TX register */
5775           I2C_Flush_TXDR(hi2c);
5776 
5777           /* Last Byte is Transmitted */
5778           /* Call I2C Slave Sequential complete process */
5779           I2C_ITSlaveSeqCplt(hi2c);
5780         }
5781         else
5782         {
5783           /* Clear NACK Flag */
5784           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5785         }
5786       }
5787       else
5788       {
5789         /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
5790         /* Clear NACK Flag */
5791         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5792 
5793         /* Set ErrorCode corresponding to a Non-Acknowledge */
5794         hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
5795 
5796         /* Store current hi2c->State, solve MISRA2012-Rule-13.5 */
5797         tmpstate = hi2c->State;
5798 
5799         if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
5800         {
5801           if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
5802           {
5803             hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
5804           }
5805           else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
5806           {
5807             hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
5808           }
5809           else
5810           {
5811             /* Do nothing */
5812           }
5813 
5814           /* Call the corresponding callback to inform upper layer of End of Transfer */
5815           I2C_ITError(hi2c, hi2c->ErrorCode);
5816         }
5817       }
5818     }
5819     else
5820     {
5821       /* Only Clear NACK Flag, no DMA treatment is pending */
5822       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
5823     }
5824   }
5825   else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_ADDR) != RESET) && \
5826            (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET))
5827   {
5828     I2C_ITAddrCplt(hi2c, ITFlags);
5829   }
5830   else
5831   {
5832     /* Nothing to do */
5833   }
5834 
5835   /* Process Unlocked */
5836   __HAL_UNLOCK(hi2c);
5837 
5838   return HAL_OK;
5839 }
5840 
5841 /**
5842   * @brief  Master sends target device address followed by internal memory address for write request.
5843   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5844   *                the configuration information for the specified I2C.
5845   * @param  DevAddress Target device address: The device 7 bits address value
5846   *         in datasheet must be shifted to the left before calling the interface
5847   * @param  MemAddress Internal memory address
5848   * @param  MemAddSize Size of internal memory address
5849   * @param  Timeout Timeout duration
5850   * @param  Tickstart Tick start value
5851   * @retval HAL status
5852   */
I2C_RequestMemoryWrite(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint32_t Timeout,uint32_t Tickstart)5853 static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5854                                                 uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5855                                                 uint32_t Tickstart)
5856 {
5857   I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
5858 
5859   /* Wait until TXIS flag is set */
5860   if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5861   {
5862     return HAL_ERROR;
5863   }
5864 
5865   /* If Memory address size is 8Bit */
5866   if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5867   {
5868     /* Send Memory Address */
5869     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5870   }
5871   /* If Memory address size is 16Bit */
5872   else
5873   {
5874     /* Send MSB of Memory Address */
5875     hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5876 
5877     /* Wait until TXIS flag is set */
5878     if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5879     {
5880       return HAL_ERROR;
5881     }
5882 
5883     /* Send LSB of Memory Address */
5884     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5885   }
5886 
5887   /* Wait until TCR flag is set */
5888   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK)
5889   {
5890     return HAL_ERROR;
5891   }
5892 
5893   return HAL_OK;
5894 }
5895 
5896 /**
5897   * @brief  Master sends target device address followed by internal memory address for read request.
5898   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
5899   *                the configuration information for the specified I2C.
5900   * @param  DevAddress Target device address: The device 7 bits address value
5901   *         in datasheet must be shifted to the left before calling the interface
5902   * @param  MemAddress Internal memory address
5903   * @param  MemAddSize Size of internal memory address
5904   * @param  Timeout Timeout duration
5905   * @param  Tickstart Tick start value
5906   * @retval HAL status
5907   */
I2C_RequestMemoryRead(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint16_t MemAddress,uint16_t MemAddSize,uint32_t Timeout,uint32_t Tickstart)5908 static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress,
5909                                                uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout,
5910                                                uint32_t Tickstart)
5911 {
5912   I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
5913 
5914   /* Wait until TXIS flag is set */
5915   if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5916   {
5917     return HAL_ERROR;
5918   }
5919 
5920   /* If Memory address size is 8Bit */
5921   if (MemAddSize == I2C_MEMADD_SIZE_8BIT)
5922   {
5923     /* Send Memory Address */
5924     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5925   }
5926   /* If Memory address size is 16Bit */
5927   else
5928   {
5929     /* Send MSB of Memory Address */
5930     hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress);
5931 
5932     /* Wait until TXIS flag is set */
5933     if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK)
5934     {
5935       return HAL_ERROR;
5936     }
5937 
5938     /* Send LSB of Memory Address */
5939     hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress);
5940   }
5941 
5942   /* Wait until TC flag is set */
5943   if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK)
5944   {
5945     return HAL_ERROR;
5946   }
5947 
5948   return HAL_OK;
5949 }
5950 
5951 /**
5952   * @brief  I2C Address complete process callback.
5953   * @param  hi2c I2C handle.
5954   * @param  ITFlags Interrupt flags to handle.
5955   * @retval None
5956   */
I2C_ITAddrCplt(I2C_HandleTypeDef * hi2c,uint32_t ITFlags)5957 static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
5958 {
5959   uint8_t transferdirection;
5960   uint16_t slaveaddrcode;
5961   uint16_t ownadd1code;
5962   uint16_t ownadd2code;
5963 
5964   /* Prevent unused argument(s) compilation warning */
5965   UNUSED(ITFlags);
5966 
5967   /* In case of Listen state, need to inform upper layer of address match code event */
5968   if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN)
5969   {
5970     transferdirection = I2C_GET_DIR(hi2c);
5971     slaveaddrcode     = I2C_GET_ADDR_MATCH(hi2c);
5972     ownadd1code       = I2C_GET_OWN_ADDRESS1(hi2c);
5973     ownadd2code       = I2C_GET_OWN_ADDRESS2(hi2c);
5974 
5975     /* If 10bits addressing mode is selected */
5976     if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
5977     {
5978       if ((slaveaddrcode & SLAVE_ADDR_MSK) == ((ownadd1code >> SLAVE_ADDR_SHIFT) & SLAVE_ADDR_MSK))
5979       {
5980         slaveaddrcode = ownadd1code;
5981         hi2c->AddrEventCount++;
5982         if (hi2c->AddrEventCount == 2U)
5983         {
5984           /* Reset Address Event counter */
5985           hi2c->AddrEventCount = 0U;
5986 
5987           /* Clear ADDR flag */
5988           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
5989 
5990           /* Process Unlocked */
5991           __HAL_UNLOCK(hi2c);
5992 
5993           /* Call Slave Addr callback */
5994 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
5995           hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
5996 #else
5997           HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
5998 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
5999         }
6000       }
6001       else
6002       {
6003         slaveaddrcode = ownadd2code;
6004 
6005         /* Disable ADDR Interrupts */
6006         I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
6007 
6008         /* Process Unlocked */
6009         __HAL_UNLOCK(hi2c);
6010 
6011         /* Call Slave Addr callback */
6012 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6013         hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
6014 #else
6015         HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
6016 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6017       }
6018     }
6019     /* else 7 bits addressing mode is selected */
6020     else
6021     {
6022       /* Disable ADDR Interrupts */
6023       I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT);
6024 
6025       /* Process Unlocked */
6026       __HAL_UNLOCK(hi2c);
6027 
6028       /* Call Slave Addr callback */
6029 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6030       hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode);
6031 #else
6032       HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode);
6033 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6034     }
6035   }
6036   /* Else clear address flag only */
6037   else
6038   {
6039     /* Clear ADDR flag */
6040     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR);
6041 
6042     /* Process Unlocked */
6043     __HAL_UNLOCK(hi2c);
6044   }
6045 }
6046 
6047 /**
6048   * @brief  I2C Master sequential complete process.
6049   * @param  hi2c I2C handle.
6050   * @retval None
6051   */
I2C_ITMasterSeqCplt(I2C_HandleTypeDef * hi2c)6052 static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c)
6053 {
6054   /* Reset I2C handle mode */
6055   hi2c->Mode = HAL_I2C_MODE_NONE;
6056 
6057   /* No Generate Stop, to permit restart mode */
6058   /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */
6059   if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6060   {
6061     hi2c->State         = HAL_I2C_STATE_READY;
6062     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
6063     hi2c->XferISR       = NULL;
6064 
6065     /* Disable Interrupts */
6066     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6067 
6068     /* Process Unlocked */
6069     __HAL_UNLOCK(hi2c);
6070 
6071     /* Call the corresponding callback to inform upper layer of End of Transfer */
6072 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6073     hi2c->MasterTxCpltCallback(hi2c);
6074 #else
6075     HAL_I2C_MasterTxCpltCallback(hi2c);
6076 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6077   }
6078   /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
6079   else
6080   {
6081     hi2c->State         = HAL_I2C_STATE_READY;
6082     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
6083     hi2c->XferISR       = NULL;
6084 
6085     /* Disable Interrupts */
6086     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6087 
6088     /* Process Unlocked */
6089     __HAL_UNLOCK(hi2c);
6090 
6091     /* Call the corresponding callback to inform upper layer of End of Transfer */
6092 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6093     hi2c->MasterRxCpltCallback(hi2c);
6094 #else
6095     HAL_I2C_MasterRxCpltCallback(hi2c);
6096 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6097   }
6098 }
6099 
6100 /**
6101   * @brief  I2C Slave sequential complete process.
6102   * @param  hi2c I2C handle.
6103   * @retval None
6104   */
I2C_ITSlaveSeqCplt(I2C_HandleTypeDef * hi2c)6105 static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c)
6106 {
6107   uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
6108 
6109   /* Reset I2C handle mode */
6110   hi2c->Mode = HAL_I2C_MODE_NONE;
6111 
6112   /* If a DMA is ongoing, Update handle size context */
6113   if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
6114   {
6115     /* Disable DMA Request */
6116     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6117   }
6118   else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
6119   {
6120     /* Disable DMA Request */
6121     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6122   }
6123   else
6124   {
6125     /* Do nothing */
6126   }
6127 
6128   if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN)
6129   {
6130     /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */
6131     hi2c->State         = HAL_I2C_STATE_LISTEN;
6132     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
6133 
6134     /* Disable Interrupts */
6135     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6136 
6137     /* Process Unlocked */
6138     __HAL_UNLOCK(hi2c);
6139 
6140     /* Call the corresponding callback to inform upper layer of End of Transfer */
6141 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6142     hi2c->SlaveTxCpltCallback(hi2c);
6143 #else
6144     HAL_I2C_SlaveTxCpltCallback(hi2c);
6145 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6146   }
6147 
6148   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)
6149   {
6150     /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */
6151     hi2c->State         = HAL_I2C_STATE_LISTEN;
6152     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
6153 
6154     /* Disable Interrupts */
6155     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6156 
6157     /* Process Unlocked */
6158     __HAL_UNLOCK(hi2c);
6159 
6160     /* Call the corresponding callback to inform upper layer of End of Transfer */
6161 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6162     hi2c->SlaveRxCpltCallback(hi2c);
6163 #else
6164     HAL_I2C_SlaveRxCpltCallback(hi2c);
6165 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6166   }
6167   else
6168   {
6169     /* Nothing to do */
6170   }
6171 }
6172 
6173 /**
6174   * @brief  I2C Master complete process.
6175   * @param  hi2c I2C handle.
6176   * @param  ITFlags Interrupt flags to handle.
6177   * @retval None
6178   */
I2C_ITMasterCplt(I2C_HandleTypeDef * hi2c,uint32_t ITFlags)6179 static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6180 {
6181   uint32_t tmperror;
6182   uint32_t tmpITFlags = ITFlags;
6183   __IO uint32_t tmpreg;
6184 
6185   /* Clear STOP Flag */
6186   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6187 
6188   /* Disable Interrupts and Store Previous state */
6189   if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6190   {
6191     I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT);
6192     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX;
6193   }
6194   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6195   {
6196     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT);
6197     hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX;
6198   }
6199   else
6200   {
6201     /* Do nothing */
6202   }
6203 
6204   /* Clear Configuration Register 2 */
6205   I2C_RESET_CR2(hi2c);
6206 
6207   /* Reset handle parameters */
6208   hi2c->XferISR       = NULL;
6209   hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
6210 
6211   if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET)
6212   {
6213     /* Clear NACK Flag */
6214     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6215 
6216     /* Set acknowledge error code */
6217     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6218   }
6219 
6220   /* Fetch Last receive data if any */
6221   if ((hi2c->State == HAL_I2C_STATE_ABORT) && (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET))
6222   {
6223     /* Read data from RXDR */
6224     tmpreg = (uint8_t)hi2c->Instance->RXDR;
6225     UNUSED(tmpreg);
6226   }
6227 
6228   /* Flush TX register */
6229   I2C_Flush_TXDR(hi2c);
6230 
6231   /* Store current volatile hi2c->ErrorCode, misra rule */
6232   tmperror = hi2c->ErrorCode;
6233 
6234   /* Call the corresponding callback to inform upper layer of End of Transfer */
6235   if ((hi2c->State == HAL_I2C_STATE_ABORT) || (tmperror != HAL_I2C_ERROR_NONE))
6236   {
6237     /* Call the corresponding callback to inform upper layer of End of Transfer */
6238     I2C_ITError(hi2c, hi2c->ErrorCode);
6239   }
6240   /* hi2c->State == HAL_I2C_STATE_BUSY_TX */
6241   else if (hi2c->State == HAL_I2C_STATE_BUSY_TX)
6242   {
6243     hi2c->State = HAL_I2C_STATE_READY;
6244     hi2c->PreviousState = I2C_STATE_NONE;
6245 
6246     if (hi2c->Mode == HAL_I2C_MODE_MEM)
6247     {
6248       hi2c->Mode = HAL_I2C_MODE_NONE;
6249 
6250       /* Process Unlocked */
6251       __HAL_UNLOCK(hi2c);
6252 
6253       /* Call the corresponding callback to inform upper layer of End of Transfer */
6254 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6255       hi2c->MemTxCpltCallback(hi2c);
6256 #else
6257       HAL_I2C_MemTxCpltCallback(hi2c);
6258 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6259     }
6260     else
6261     {
6262       hi2c->Mode = HAL_I2C_MODE_NONE;
6263 
6264       /* Process Unlocked */
6265       __HAL_UNLOCK(hi2c);
6266 
6267       /* Call the corresponding callback to inform upper layer of End of Transfer */
6268 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6269       hi2c->MasterTxCpltCallback(hi2c);
6270 #else
6271       HAL_I2C_MasterTxCpltCallback(hi2c);
6272 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6273     }
6274   }
6275   /* hi2c->State == HAL_I2C_STATE_BUSY_RX */
6276   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6277   {
6278     hi2c->State = HAL_I2C_STATE_READY;
6279     hi2c->PreviousState = I2C_STATE_NONE;
6280 
6281     if (hi2c->Mode == HAL_I2C_MODE_MEM)
6282     {
6283       hi2c->Mode = HAL_I2C_MODE_NONE;
6284 
6285       /* Process Unlocked */
6286       __HAL_UNLOCK(hi2c);
6287 
6288       /* Call the corresponding callback to inform upper layer of End of Transfer */
6289 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6290       hi2c->MemRxCpltCallback(hi2c);
6291 #else
6292       HAL_I2C_MemRxCpltCallback(hi2c);
6293 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6294     }
6295     else
6296     {
6297       hi2c->Mode = HAL_I2C_MODE_NONE;
6298 
6299       /* Process Unlocked */
6300       __HAL_UNLOCK(hi2c);
6301 
6302       /* Call the corresponding callback to inform upper layer of End of Transfer */
6303 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6304       hi2c->MasterRxCpltCallback(hi2c);
6305 #else
6306       HAL_I2C_MasterRxCpltCallback(hi2c);
6307 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6308     }
6309   }
6310   else
6311   {
6312     /* Nothing to do */
6313   }
6314 }
6315 
6316 /**
6317   * @brief  I2C Slave complete process.
6318   * @param  hi2c I2C handle.
6319   * @param  ITFlags Interrupt flags to handle.
6320   * @retval None
6321   */
I2C_ITSlaveCplt(I2C_HandleTypeDef * hi2c,uint32_t ITFlags)6322 static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6323 {
6324   uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1);
6325   uint32_t tmpITFlags = ITFlags;
6326   uint32_t tmpoptions = hi2c->XferOptions;
6327   HAL_I2C_StateTypeDef tmpstate = hi2c->State;
6328 
6329   /* Clear STOP Flag */
6330   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6331 
6332   /* Disable Interrupts and Store Previous state */
6333   if ((tmpstate == HAL_I2C_STATE_BUSY_TX) || (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN))
6334   {
6335     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT);
6336     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
6337   }
6338   else if ((tmpstate == HAL_I2C_STATE_BUSY_RX) || (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
6339   {
6340     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT);
6341     hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX;
6342   }
6343   else if (tmpstate == HAL_I2C_STATE_LISTEN)
6344   {
6345     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT);
6346     hi2c->PreviousState = I2C_STATE_NONE;
6347   }
6348   else
6349   {
6350     /* Do nothing */
6351   }
6352 
6353   /* Disable Address Acknowledge */
6354   hi2c->Instance->CR2 |= I2C_CR2_NACK;
6355 
6356   /* Clear Configuration Register 2 */
6357   I2C_RESET_CR2(hi2c);
6358 
6359   /* Flush TX register */
6360   I2C_Flush_TXDR(hi2c);
6361 
6362   /* If a DMA is ongoing, Update handle size context */
6363   if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET)
6364   {
6365     /* Disable DMA Request */
6366     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6367 
6368     if (hi2c->hdmatx != NULL)
6369     {
6370       hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx);
6371     }
6372   }
6373   else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET)
6374   {
6375     /* Disable DMA Request */
6376     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6377 
6378     if (hi2c->hdmarx != NULL)
6379     {
6380       hi2c->XferCount = (uint16_t)I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx);
6381     }
6382   }
6383   else
6384   {
6385     /* Do nothing */
6386   }
6387 
6388   /* Store Last receive data if any */
6389   if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET)
6390   {
6391     /* Remove RXNE flag on temporary variable as read done */
6392     tmpITFlags &= ~I2C_FLAG_RXNE;
6393 
6394     /* Read data from RXDR */
6395     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
6396 
6397     /* Increment Buffer pointer */
6398     hi2c->pBuffPtr++;
6399 
6400     if ((hi2c->XferSize > 0U))
6401     {
6402       hi2c->XferSize--;
6403       hi2c->XferCount--;
6404     }
6405   }
6406 
6407   /* All data are not transferred, so set error code accordingly */
6408   if (hi2c->XferCount != 0U)
6409   {
6410     /* Set ErrorCode corresponding to a Non-Acknowledge */
6411     hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6412   }
6413 
6414   if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && \
6415       (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_IT_NACKI) != RESET))
6416   {
6417     /* Check that I2C transfer finished */
6418     /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */
6419     /* Mean XferCount == 0*/
6420     /* So clear Flag NACKF only */
6421     if (hi2c->XferCount == 0U)
6422     {
6423       if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME))
6424         /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for
6425            Warning[Pa134]: left and right operands are identical */
6426       {
6427         /* Call I2C Listen complete process */
6428         I2C_ITListenCplt(hi2c, tmpITFlags);
6429       }
6430       else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME))
6431       {
6432         /* Clear NACK Flag */
6433         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6434 
6435         /* Flush TX register */
6436         I2C_Flush_TXDR(hi2c);
6437 
6438         /* Last Byte is Transmitted */
6439         /* Call I2C Slave Sequential complete process */
6440         I2C_ITSlaveSeqCplt(hi2c);
6441       }
6442       else
6443       {
6444         /* Clear NACK Flag */
6445         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6446       }
6447     }
6448     else
6449     {
6450       /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/
6451       /* Clear NACK Flag */
6452       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6453 
6454       /* Set ErrorCode corresponding to a Non-Acknowledge */
6455       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6456 
6457       if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME))
6458       {
6459         /* Call the corresponding callback to inform upper layer of End of Transfer */
6460         I2C_ITError(hi2c, hi2c->ErrorCode);
6461       }
6462     }
6463   }
6464 
6465   hi2c->Mode = HAL_I2C_MODE_NONE;
6466   hi2c->XferISR = NULL;
6467 
6468   if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE)
6469   {
6470     /* Call the corresponding callback to inform upper layer of End of Transfer */
6471     I2C_ITError(hi2c, hi2c->ErrorCode);
6472 
6473     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6474     if (hi2c->State == HAL_I2C_STATE_LISTEN)
6475     {
6476       /* Call I2C Listen complete process */
6477       I2C_ITListenCplt(hi2c, tmpITFlags);
6478     }
6479   }
6480   else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME)
6481   {
6482     /* Call the Sequential Complete callback, to inform upper layer of the end of Transfer */
6483     I2C_ITSlaveSeqCplt(hi2c);
6484 
6485     hi2c->XferOptions = I2C_NO_OPTION_FRAME;
6486     hi2c->State = HAL_I2C_STATE_READY;
6487     hi2c->PreviousState = I2C_STATE_NONE;
6488 
6489     /* Process Unlocked */
6490     __HAL_UNLOCK(hi2c);
6491 
6492     /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6493 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6494     hi2c->ListenCpltCallback(hi2c);
6495 #else
6496     HAL_I2C_ListenCpltCallback(hi2c);
6497 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6498   }
6499   /* Call the corresponding callback to inform upper layer of End of Transfer */
6500   else if (hi2c->State == HAL_I2C_STATE_BUSY_RX)
6501   {
6502     hi2c->State = HAL_I2C_STATE_READY;
6503     hi2c->PreviousState = I2C_STATE_NONE;
6504 
6505     /* Process Unlocked */
6506     __HAL_UNLOCK(hi2c);
6507 
6508     /* Call the corresponding callback to inform upper layer of End of Transfer */
6509 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6510     hi2c->SlaveRxCpltCallback(hi2c);
6511 #else
6512     HAL_I2C_SlaveRxCpltCallback(hi2c);
6513 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6514   }
6515   else
6516   {
6517     hi2c->State = HAL_I2C_STATE_READY;
6518     hi2c->PreviousState = I2C_STATE_NONE;
6519 
6520     /* Process Unlocked */
6521     __HAL_UNLOCK(hi2c);
6522 
6523     /* Call the corresponding callback to inform upper layer of End of Transfer */
6524 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6525     hi2c->SlaveTxCpltCallback(hi2c);
6526 #else
6527     HAL_I2C_SlaveTxCpltCallback(hi2c);
6528 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6529   }
6530 }
6531 
6532 /**
6533   * @brief  I2C Listen complete process.
6534   * @param  hi2c I2C handle.
6535   * @param  ITFlags Interrupt flags to handle.
6536   * @retval None
6537   */
I2C_ITListenCplt(I2C_HandleTypeDef * hi2c,uint32_t ITFlags)6538 static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
6539 {
6540   /* Reset handle parameters */
6541   hi2c->XferOptions = I2C_NO_OPTION_FRAME;
6542   hi2c->PreviousState = I2C_STATE_NONE;
6543   hi2c->State = HAL_I2C_STATE_READY;
6544   hi2c->Mode = HAL_I2C_MODE_NONE;
6545   hi2c->XferISR = NULL;
6546 
6547   /* Store Last receive data if any */
6548   if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_RXNE) != RESET)
6549   {
6550     /* Read data from RXDR */
6551     *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
6552 
6553     /* Increment Buffer pointer */
6554     hi2c->pBuffPtr++;
6555 
6556     if ((hi2c->XferSize > 0U))
6557     {
6558       hi2c->XferSize--;
6559       hi2c->XferCount--;
6560 
6561       /* Set ErrorCode corresponding to a Non-Acknowledge */
6562       hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6563     }
6564   }
6565 
6566   /* Disable all Interrupts*/
6567   I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6568 
6569   /* Clear NACK Flag */
6570   __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6571 
6572   /* Process Unlocked */
6573   __HAL_UNLOCK(hi2c);
6574 
6575   /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
6576 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6577   hi2c->ListenCpltCallback(hi2c);
6578 #else
6579   HAL_I2C_ListenCpltCallback(hi2c);
6580 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6581 }
6582 
6583 /**
6584   * @brief  I2C interrupts error process.
6585   * @param  hi2c I2C handle.
6586   * @param  ErrorCode Error code to handle.
6587   * @retval None
6588   */
I2C_ITError(I2C_HandleTypeDef * hi2c,uint32_t ErrorCode)6589 static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode)
6590 {
6591   HAL_I2C_StateTypeDef tmpstate = hi2c->State;
6592 
6593   uint32_t tmppreviousstate;
6594 
6595   /* Reset handle parameters */
6596   hi2c->Mode          = HAL_I2C_MODE_NONE;
6597   hi2c->XferOptions   = I2C_NO_OPTION_FRAME;
6598   hi2c->XferCount     = 0U;
6599 
6600   /* Set new error code */
6601   hi2c->ErrorCode |= ErrorCode;
6602 
6603   /* Disable Interrupts */
6604   if ((tmpstate == HAL_I2C_STATE_LISTEN)         ||
6605       (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN) ||
6606       (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN))
6607   {
6608     /* Disable all interrupts, except interrupts related to LISTEN state */
6609     I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6610 
6611     /* keep HAL_I2C_STATE_LISTEN if set */
6612     hi2c->State         = HAL_I2C_STATE_LISTEN;
6613     hi2c->XferISR       = I2C_Slave_ISR_IT;
6614   }
6615   else
6616   {
6617     /* Disable all interrupts */
6618     I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT);
6619 
6620     /* Flush TX register */
6621     I2C_Flush_TXDR(hi2c);
6622 
6623     /* If state is an abort treatment on going, don't change state */
6624     /* This change will be do later */
6625     if (hi2c->State != HAL_I2C_STATE_ABORT)
6626     {
6627       /* Set HAL_I2C_STATE_READY */
6628       hi2c->State         = HAL_I2C_STATE_READY;
6629 
6630       /* Check if a STOPF is detected */
6631       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
6632       {
6633         if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
6634         {
6635           __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
6636           hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
6637         }
6638 
6639         /* Clear STOP Flag */
6640         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
6641       }
6642 
6643     }
6644     hi2c->XferISR       = NULL;
6645   }
6646 
6647   /* Abort DMA TX transfer if any */
6648   tmppreviousstate = hi2c->PreviousState;
6649 
6650   if ((hi2c->hdmatx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_TX) || \
6651                                  (tmppreviousstate == I2C_STATE_SLAVE_BUSY_TX)))
6652   {
6653     if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN)
6654     {
6655       hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6656     }
6657 
6658     if (HAL_DMA_GetState(hi2c->hdmatx) != HAL_DMA_STATE_READY)
6659     {
6660       /* Set the I2C DMA Abort callback :
6661        will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6662       hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort;
6663 
6664       /* Process Unlocked */
6665       __HAL_UNLOCK(hi2c);
6666 
6667       /* Abort DMA TX */
6668       if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK)
6669       {
6670         /* Call Directly XferAbortCallback function in case of error */
6671         hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx);
6672       }
6673     }
6674     else
6675     {
6676       I2C_TreatErrorCallback(hi2c);
6677     }
6678   }
6679   /* Abort DMA RX transfer if any */
6680   else if ((hi2c->hdmarx != NULL) && ((tmppreviousstate == I2C_STATE_MASTER_BUSY_RX) || \
6681                                       (tmppreviousstate == I2C_STATE_SLAVE_BUSY_RX)))
6682   {
6683     if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN)
6684     {
6685       hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6686     }
6687 
6688     if (HAL_DMA_GetState(hi2c->hdmarx) != HAL_DMA_STATE_READY)
6689     {
6690       /* Set the I2C DMA Abort callback :
6691         will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */
6692       hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort;
6693 
6694       /* Process Unlocked */
6695       __HAL_UNLOCK(hi2c);
6696 
6697       /* Abort DMA RX */
6698       if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK)
6699       {
6700         /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */
6701         hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx);
6702       }
6703     }
6704     else
6705     {
6706       I2C_TreatErrorCallback(hi2c);
6707     }
6708   }
6709   else
6710   {
6711     I2C_TreatErrorCallback(hi2c);
6712   }
6713 }
6714 
6715 /**
6716   * @brief  I2C Error callback treatment.
6717   * @param  hi2c I2C handle.
6718   * @retval None
6719   */
I2C_TreatErrorCallback(I2C_HandleTypeDef * hi2c)6720 static void I2C_TreatErrorCallback(I2C_HandleTypeDef *hi2c)
6721 {
6722   if (hi2c->State == HAL_I2C_STATE_ABORT)
6723   {
6724     hi2c->State = HAL_I2C_STATE_READY;
6725     hi2c->PreviousState = I2C_STATE_NONE;
6726 
6727     /* Process Unlocked */
6728     __HAL_UNLOCK(hi2c);
6729 
6730     /* Call the corresponding callback to inform upper layer of End of Transfer */
6731 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6732     hi2c->AbortCpltCallback(hi2c);
6733 #else
6734     HAL_I2C_AbortCpltCallback(hi2c);
6735 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6736   }
6737   else
6738   {
6739     hi2c->PreviousState = I2C_STATE_NONE;
6740 
6741     /* Process Unlocked */
6742     __HAL_UNLOCK(hi2c);
6743 
6744     /* Call the corresponding callback to inform upper layer of End of Transfer */
6745 #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
6746     hi2c->ErrorCallback(hi2c);
6747 #else
6748     HAL_I2C_ErrorCallback(hi2c);
6749 #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
6750   }
6751 }
6752 
6753 /**
6754   * @brief  I2C Tx data register flush process.
6755   * @param  hi2c I2C handle.
6756   * @retval None
6757   */
I2C_Flush_TXDR(I2C_HandleTypeDef * hi2c)6758 static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c)
6759 {
6760   /* If a pending TXIS flag is set */
6761   /* Write a dummy data in TXDR to clear it */
6762   if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET)
6763   {
6764     hi2c->Instance->TXDR = 0x00U;
6765   }
6766 
6767   /* Flush TX register if not empty */
6768   if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
6769   {
6770     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE);
6771   }
6772 }
6773 
6774 /**
6775   * @brief  DMA I2C master transmit process complete callback.
6776   * @param  hdma DMA handle
6777   * @retval None
6778   */
I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef * hdma)6779 static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
6780 {
6781   /* Derogation MISRAC2012-Rule-11.5 */
6782   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6783 
6784   /* Disable DMA Request */
6785   hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6786 
6787   /* If last transfer, enable STOP interrupt */
6788   if (hi2c->XferCount == 0U)
6789   {
6790     /* Enable STOP interrupt */
6791     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6792   }
6793   /* else prepare a new DMA transfer and enable TCReload interrupt */
6794   else
6795   {
6796     /* Update Buffer pointer */
6797     hi2c->pBuffPtr += hi2c->XferSize;
6798 
6799     /* Set the XferSize to transfer */
6800     if (hi2c->XferCount > MAX_NBYTE_SIZE)
6801     {
6802       hi2c->XferSize = MAX_NBYTE_SIZE;
6803     }
6804     else
6805     {
6806       hi2c->XferSize = hi2c->XferCount;
6807     }
6808 
6809     /* Enable the DMA stream */
6810     if (HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR,
6811                          hi2c->XferSize) != HAL_OK)
6812     {
6813       /* Call the corresponding callback to inform upper layer of End of Transfer */
6814       I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6815     }
6816     else
6817     {
6818       /* Enable TC interrupts */
6819       I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6820     }
6821   }
6822 }
6823 
6824 
6825 /**
6826   * @brief  DMA I2C slave transmit process complete callback.
6827   * @param  hdma DMA handle
6828   * @retval None
6829   */
I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef * hdma)6830 static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
6831 {
6832   /* Derogation MISRAC2012-Rule-11.5 */
6833   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6834   uint32_t tmpoptions = hi2c->XferOptions;
6835 
6836   if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME))
6837   {
6838     /* Disable DMA Request */
6839     hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN;
6840 
6841     /* Last Byte is Transmitted */
6842     /* Call I2C Slave Sequential complete process */
6843     I2C_ITSlaveSeqCplt(hi2c);
6844   }
6845   else
6846   {
6847     /* No specific action, Master fully manage the generation of STOP condition */
6848     /* Mean that this generation can arrive at any time, at the end or during DMA process */
6849     /* So STOP condition should be manage through Interrupt treatment */
6850   }
6851 }
6852 
6853 
6854 /**
6855   * @brief DMA I2C master receive process complete callback.
6856   * @param  hdma DMA handle
6857   * @retval None
6858   */
I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef * hdma)6859 static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
6860 {
6861   /* Derogation MISRAC2012-Rule-11.5 */
6862   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6863 
6864   /* Disable DMA Request */
6865   hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6866 
6867   /* If last transfer, enable STOP interrupt */
6868   if (hi2c->XferCount == 0U)
6869   {
6870     /* Enable STOP interrupt */
6871     I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
6872   }
6873   /* else prepare a new DMA transfer and enable TCReload interrupt */
6874   else
6875   {
6876     /* Update Buffer pointer */
6877     hi2c->pBuffPtr += hi2c->XferSize;
6878 
6879     /* Set the XferSize to transfer */
6880     if (hi2c->XferCount > MAX_NBYTE_SIZE)
6881     {
6882       /* Errata workaround 170323 */
6883       if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE)
6884       {
6885         hi2c->XferSize = 1U;
6886       }
6887       else
6888       {
6889         hi2c->XferSize = MAX_NBYTE_SIZE;
6890       }
6891     }
6892     else
6893     {
6894       hi2c->XferSize = hi2c->XferCount;
6895     }
6896 
6897     /* Enable the DMA stream */
6898     if (HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr,
6899                          hi2c->XferSize) != HAL_OK)
6900     {
6901       /* Call the corresponding callback to inform upper layer of End of Transfer */
6902       I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6903     }
6904     else
6905     {
6906       /* Enable TC interrupts */
6907       I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
6908     }
6909   }
6910 }
6911 
6912 
6913 /**
6914   * @brief  DMA I2C slave receive process complete callback.
6915   * @param  hdma DMA handle
6916   * @retval None
6917   */
I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef * hdma)6918 static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
6919 {
6920   /* Derogation MISRAC2012-Rule-11.5 */
6921   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6922   uint32_t tmpoptions = hi2c->XferOptions;
6923 
6924   if ((I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U) && \
6925       (tmpoptions != I2C_NO_OPTION_FRAME))
6926   {
6927     /* Disable DMA Request */
6928     hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
6929 
6930     /* Call I2C Slave Sequential complete process */
6931     I2C_ITSlaveSeqCplt(hi2c);
6932   }
6933   else
6934   {
6935     /* No specific action, Master fully manage the generation of STOP condition */
6936     /* Mean that this generation can arrive at any time, at the end or during DMA process */
6937     /* So STOP condition should be manage through Interrupt treatment */
6938   }
6939 }
6940 
6941 
6942 /**
6943   * @brief  DMA I2C communication error callback.
6944   * @param hdma DMA handle
6945   * @retval None
6946   */
I2C_DMAError(DMA_HandleTypeDef * hdma)6947 static void I2C_DMAError(DMA_HandleTypeDef *hdma)
6948 {
6949   uint32_t treatdmaerror = 0U;
6950   /* Derogation MISRAC2012-Rule-11.5 */
6951   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6952 
6953   if (hi2c->hdmatx != NULL)
6954   {
6955     if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmatx) == 0U)
6956     {
6957       treatdmaerror = 1U;
6958     }
6959   }
6960 
6961   if (hi2c->hdmarx != NULL)
6962   {
6963     if (I2C_GET_DMA_REMAIN_DATA(hi2c->hdmarx) == 0U)
6964     {
6965       treatdmaerror = 1U;
6966     }
6967   }
6968 
6969   /* Check if a FIFO error is detected, if true normal use case, so no specific action to perform */
6970   if (!((HAL_DMA_GetError(hdma) == HAL_DMA_ERROR_FE)) && (treatdmaerror != 0U))
6971   {
6972     /* Disable Acknowledge */
6973     hi2c->Instance->CR2 |= I2C_CR2_NACK;
6974 
6975     /* Call the corresponding callback to inform upper layer of End of Transfer */
6976     I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
6977   }
6978 }
6979 
6980 
6981 /**
6982   * @brief DMA I2C communication abort callback
6983   *        (To be called at end of DMA Abort procedure).
6984   * @param hdma DMA handle.
6985   * @retval None
6986   */
I2C_DMAAbort(DMA_HandleTypeDef * hdma)6987 static void I2C_DMAAbort(DMA_HandleTypeDef *hdma)
6988 {
6989   /* Derogation MISRAC2012-Rule-11.5 */
6990   I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
6991 
6992   /* Reset AbortCpltCallback */
6993   if (hi2c->hdmatx != NULL)
6994   {
6995     hi2c->hdmatx->XferAbortCallback = NULL;
6996   }
6997   if (hi2c->hdmarx != NULL)
6998   {
6999     hi2c->hdmarx->XferAbortCallback = NULL;
7000   }
7001 
7002   I2C_TreatErrorCallback(hi2c);
7003 }
7004 
7005 
7006 /**
7007   * @brief  This function handles I2C Communication Timeout. It waits
7008   *                until a flag is no longer in the specified status.
7009   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7010   *                the configuration information for the specified I2C.
7011   * @param  Flag Specifies the I2C flag to check.
7012   * @param  Status The actual Flag status (SET or RESET).
7013   * @param  Timeout Timeout duration
7014   * @param  Tickstart Tick start value
7015   * @retval HAL status
7016   */
I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)7017 static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
7018                                                     uint32_t Timeout, uint32_t Tickstart)
7019 {
7020   while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
7021   {
7022     /* Check if an error is detected */
7023     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7024     {
7025       return HAL_ERROR;
7026     }
7027 
7028     /* Check for the Timeout */
7029     if (Timeout != HAL_MAX_DELAY)
7030     {
7031       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7032       {
7033         if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == Status))
7034         {
7035           hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7036           hi2c->State = HAL_I2C_STATE_READY;
7037           hi2c->Mode = HAL_I2C_MODE_NONE;
7038 
7039           /* Process Unlocked */
7040           __HAL_UNLOCK(hi2c);
7041           return HAL_ERROR;
7042         }
7043       }
7044     }
7045   }
7046   return HAL_OK;
7047 }
7048 
7049 /**
7050   * @brief  This function handles I2C Communication Timeout for specific usage of TXIS flag.
7051   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7052   *                the configuration information for the specified I2C.
7053   * @param  Timeout Timeout duration
7054   * @param  Tickstart Tick start value
7055   * @retval HAL status
7056   */
I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)7057 static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
7058                                                         uint32_t Tickstart)
7059 {
7060   while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)
7061   {
7062     /* Check if an error is detected */
7063     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7064     {
7065       return HAL_ERROR;
7066     }
7067 
7068     /* Check for the Timeout */
7069     if (Timeout != HAL_MAX_DELAY)
7070     {
7071       if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7072       {
7073         if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET))
7074         {
7075           hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7076           hi2c->State = HAL_I2C_STATE_READY;
7077           hi2c->Mode = HAL_I2C_MODE_NONE;
7078 
7079           /* Process Unlocked */
7080           __HAL_UNLOCK(hi2c);
7081 
7082           return HAL_ERROR;
7083         }
7084       }
7085     }
7086   }
7087   return HAL_OK;
7088 }
7089 
7090 /**
7091   * @brief  This function handles I2C Communication Timeout for specific usage of STOP flag.
7092   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7093   *                the configuration information for the specified I2C.
7094   * @param  Timeout Timeout duration
7095   * @param  Tickstart Tick start value
7096   * @retval HAL status
7097   */
I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)7098 static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
7099                                                         uint32_t Tickstart)
7100 {
7101   while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
7102   {
7103     /* Check if an error is detected */
7104     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7105     {
7106       return HAL_ERROR;
7107     }
7108 
7109     /* Check for the Timeout */
7110     if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
7111     {
7112       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET))
7113       {
7114         hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7115         hi2c->State = HAL_I2C_STATE_READY;
7116         hi2c->Mode = HAL_I2C_MODE_NONE;
7117 
7118         /* Process Unlocked */
7119         __HAL_UNLOCK(hi2c);
7120 
7121         return HAL_ERROR;
7122       }
7123     }
7124   }
7125   return HAL_OK;
7126 }
7127 
7128 /**
7129   * @brief  This function handles I2C Communication Timeout for specific usage of RXNE flag.
7130   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7131   *                the configuration information for the specified I2C.
7132   * @param  Timeout Timeout duration
7133   * @param  Tickstart Tick start value
7134   * @retval HAL status
7135   */
I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)7136 static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
7137                                                         uint32_t Tickstart)
7138 {
7139   HAL_StatusTypeDef status = HAL_OK;
7140 
7141   while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) && (status == HAL_OK))
7142   {
7143     /* Check if an error is detected */
7144     if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
7145     {
7146       status = HAL_ERROR;
7147     }
7148 
7149     /* Check if a STOPF is detected */
7150     if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) && (status == HAL_OK))
7151     {
7152       /* Check if an RXNE is pending */
7153       /* Store Last receive data if any */
7154       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U))
7155       {
7156         /* Return HAL_OK */
7157         /* The Reading of data from RXDR will be done in caller function */
7158         status = HAL_OK;
7159       }
7160 
7161       /* Check a no-acknowledge have been detected */
7162       if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
7163       {
7164         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
7165         hi2c->ErrorCode = HAL_I2C_ERROR_AF;
7166 
7167         /* Clear STOP Flag */
7168         __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
7169 
7170         /* Clear Configuration Register 2 */
7171         I2C_RESET_CR2(hi2c);
7172 
7173         hi2c->State = HAL_I2C_STATE_READY;
7174         hi2c->Mode = HAL_I2C_MODE_NONE;
7175 
7176         /* Process Unlocked */
7177         __HAL_UNLOCK(hi2c);
7178 
7179         status = HAL_ERROR;
7180       }
7181       else
7182       {
7183         hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
7184       }
7185     }
7186 
7187     /* Check for the Timeout */
7188     if ((((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) && (status == HAL_OK))
7189     {
7190       if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET))
7191       {
7192         hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
7193         hi2c->State = HAL_I2C_STATE_READY;
7194 
7195         /* Process Unlocked */
7196         __HAL_UNLOCK(hi2c);
7197 
7198         status = HAL_ERROR;
7199       }
7200     }
7201   }
7202   return status;
7203 }
7204 
7205 /**
7206   * @brief  This function handles errors detection during an I2C Communication.
7207   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7208   *                the configuration information for the specified I2C.
7209   * @param  Timeout Timeout duration
7210   * @param  Tickstart Tick start value
7211   * @retval HAL status
7212   */
I2C_IsErrorOccurred(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)7213 static HAL_StatusTypeDef I2C_IsErrorOccurred(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
7214 {
7215   HAL_StatusTypeDef status = HAL_OK;
7216   uint32_t itflag   = hi2c->Instance->ISR;
7217   uint32_t error_code = 0;
7218   uint32_t tickstart = Tickstart;
7219   uint32_t tmp1;
7220   HAL_I2C_ModeTypeDef tmp2;
7221 
7222   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_AF))
7223   {
7224     /* Clear NACKF Flag */
7225     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
7226 
7227     /* Wait until STOP Flag is set or timeout occurred */
7228     /* AutoEnd should be initiate after AF */
7229     while ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) && (status == HAL_OK))
7230     {
7231       /* Check for the Timeout */
7232       if (Timeout != HAL_MAX_DELAY)
7233       {
7234         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
7235         {
7236           tmp1 = (uint32_t)(hi2c->Instance->CR2 & I2C_CR2_STOP);
7237           tmp2 = hi2c->Mode;
7238 
7239           /* In case of I2C still busy, try to regenerate a STOP manually */
7240           if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET) && \
7241               (tmp1 != I2C_CR2_STOP) && \
7242               (tmp2 != HAL_I2C_MODE_SLAVE))
7243           {
7244             /* Generate Stop */
7245             hi2c->Instance->CR2 |= I2C_CR2_STOP;
7246 
7247             /* Update Tick with new reference */
7248             tickstart = HAL_GetTick();
7249           }
7250 
7251           while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
7252           {
7253             /* Check for the Timeout */
7254             if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_STOPF)
7255             {
7256               error_code |= HAL_I2C_ERROR_TIMEOUT;
7257 
7258               status = HAL_ERROR;
7259 
7260               break;
7261             }
7262           }
7263         }
7264       }
7265     }
7266 
7267     /* In case STOP Flag is detected, clear it */
7268     if (status == HAL_OK)
7269     {
7270       /* Clear STOP Flag */
7271       __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
7272     }
7273 
7274     error_code |= HAL_I2C_ERROR_AF;
7275 
7276     status = HAL_ERROR;
7277   }
7278 
7279   /* Refresh Content of Status register */
7280   itflag = hi2c->Instance->ISR;
7281 
7282   /* Then verify if an additional errors occurs */
7283   /* Check if a Bus error occurred */
7284   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_BERR))
7285   {
7286     error_code |= HAL_I2C_ERROR_BERR;
7287 
7288     /* Clear BERR flag */
7289     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR);
7290 
7291     status = HAL_ERROR;
7292   }
7293 
7294   /* Check if an Over-Run/Under-Run error occurred */
7295   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_OVR))
7296   {
7297     error_code |= HAL_I2C_ERROR_OVR;
7298 
7299     /* Clear OVR flag */
7300     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR);
7301 
7302     status = HAL_ERROR;
7303   }
7304 
7305   /* Check if an Arbitration Loss error occurred */
7306   if (HAL_IS_BIT_SET(itflag, I2C_FLAG_ARLO))
7307   {
7308     error_code |= HAL_I2C_ERROR_ARLO;
7309 
7310     /* Clear ARLO flag */
7311     __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO);
7312 
7313     status = HAL_ERROR;
7314   }
7315 
7316   if (status != HAL_OK)
7317   {
7318     /* Flush TX register */
7319     I2C_Flush_TXDR(hi2c);
7320 
7321     /* Clear Configuration Register 2 */
7322     I2C_RESET_CR2(hi2c);
7323 
7324     hi2c->ErrorCode |= error_code;
7325     hi2c->State = HAL_I2C_STATE_READY;
7326     hi2c->Mode = HAL_I2C_MODE_NONE;
7327 
7328     /* Process Unlocked */
7329     __HAL_UNLOCK(hi2c);
7330   }
7331 
7332   return status;
7333 }
7334 
7335 /**
7336   * @brief  Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
7337   * @param  hi2c I2C handle.
7338   * @param  DevAddress Specifies the slave address to be programmed.
7339   * @param  Size Specifies the number of bytes to be programmed.
7340   *   This parameter must be a value between 0 and 255.
7341   * @param  Mode New state of the I2C START condition generation.
7342   *   This parameter can be one of the following values:
7343   *     @arg @ref I2C_RELOAD_MODE Enable Reload mode .
7344   *     @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode.
7345   *     @arg @ref I2C_SOFTEND_MODE Enable Software end mode.
7346   * @param  Request New state of the I2C START condition generation.
7347   *   This parameter can be one of the following values:
7348   *     @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition.
7349   *     @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
7350   *     @arg @ref I2C_GENERATE_START_READ Generate Restart for read request.
7351   *     @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request.
7352   * @retval None
7353   */
I2C_TransferConfig(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)7354 static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode,
7355                                uint32_t Request)
7356 {
7357   /* Check the parameters */
7358   assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));
7359   assert_param(IS_TRANSFER_MODE(Mode));
7360   assert_param(IS_TRANSFER_REQUEST(Request));
7361 
7362   /* Declaration of tmp to prevent undefined behavior of volatile usage */
7363   uint32_t tmp = ((uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | \
7364                              (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | \
7365                              (uint32_t)Mode | (uint32_t)Request) & (~0x80000000U));
7366 
7367   /* update CR2 register */
7368   MODIFY_REG(hi2c->Instance->CR2, \
7369              ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
7370                (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | \
7371                I2C_CR2_START | I2C_CR2_STOP)), tmp);
7372 }
7373 
7374 /**
7375   * @brief  Manage the enabling of Interrupts.
7376   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7377   *                the configuration information for the specified I2C.
7378   * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
7379   * @retval None
7380   */
I2C_Enable_IRQ(I2C_HandleTypeDef * hi2c,uint16_t InterruptRequest)7381 static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
7382 {
7383   uint32_t tmpisr = 0U;
7384 
7385   if ((hi2c->XferISR != I2C_Master_ISR_DMA) && \
7386       (hi2c->XferISR != I2C_Slave_ISR_DMA) && \
7387       (hi2c->XferISR != I2C_Mem_ISR_DMA))
7388   {
7389     if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7390     {
7391       /* Enable ERR, STOP, NACK and ADDR interrupts */
7392       tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7393     }
7394 
7395     if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7396     {
7397       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7398       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
7399     }
7400 
7401     if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7402     {
7403       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7404       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
7405     }
7406 
7407     if (InterruptRequest == I2C_XFER_ERROR_IT)
7408     {
7409       /* Enable ERR and NACK interrupts */
7410       tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7411     }
7412 
7413     if (InterruptRequest == I2C_XFER_CPLT_IT)
7414     {
7415       /* Enable STOP interrupts */
7416       tmpisr |= I2C_IT_STOPI;
7417     }
7418   }
7419 
7420   else
7421   {
7422     if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7423     {
7424       /* Enable ERR, STOP, NACK and ADDR interrupts */
7425       tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7426     }
7427 
7428     if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7429     {
7430       /* Enable ERR, TC, STOP, NACK and TXI interrupts */
7431       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI;
7432     }
7433 
7434     if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7435     {
7436       /* Enable ERR, TC, STOP, NACK and RXI interrupts */
7437       tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI;
7438     }
7439 
7440     if (InterruptRequest == I2C_XFER_ERROR_IT)
7441     {
7442       /* Enable ERR and NACK interrupts */
7443       tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7444     }
7445 
7446     if (InterruptRequest == I2C_XFER_CPLT_IT)
7447     {
7448       /* Enable STOP interrupts */
7449       tmpisr |= (I2C_IT_STOPI | I2C_IT_TCI);
7450     }
7451 
7452     if (InterruptRequest == I2C_XFER_RELOAD_IT)
7453     {
7454       /* Enable TC interrupts */
7455       tmpisr |= I2C_IT_TCI;
7456     }
7457   }
7458 
7459   /* Enable interrupts only at the end */
7460   /* to avoid the risk of I2C interrupt handle execution before */
7461   /* all interrupts requested done */
7462   __HAL_I2C_ENABLE_IT(hi2c, tmpisr);
7463 }
7464 
7465 /**
7466   * @brief  Manage the disabling of Interrupts.
7467   * @param  hi2c Pointer to a I2C_HandleTypeDef structure that contains
7468   *                the configuration information for the specified I2C.
7469   * @param  InterruptRequest Value of @ref I2C_Interrupt_configuration_definition.
7470   * @retval None
7471   */
I2C_Disable_IRQ(I2C_HandleTypeDef * hi2c,uint16_t InterruptRequest)7472 static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest)
7473 {
7474   uint32_t tmpisr = 0U;
7475 
7476   if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT)
7477   {
7478     /* Disable TC and TXI interrupts */
7479     tmpisr |= I2C_IT_TCI | I2C_IT_TXI;
7480 
7481     if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
7482     {
7483       /* Disable NACK and STOP interrupts */
7484       tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7485     }
7486   }
7487 
7488   if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT)
7489   {
7490     /* Disable TC and RXI interrupts */
7491     tmpisr |= I2C_IT_TCI | I2C_IT_RXI;
7492 
7493     if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN)
7494     {
7495       /* Disable NACK and STOP interrupts */
7496       tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7497     }
7498   }
7499 
7500   if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT)
7501   {
7502     /* Disable ADDR, NACK and STOP interrupts */
7503     tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI;
7504   }
7505 
7506   if (InterruptRequest == I2C_XFER_ERROR_IT)
7507   {
7508     /* Enable ERR and NACK interrupts */
7509     tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI;
7510   }
7511 
7512   if (InterruptRequest == I2C_XFER_CPLT_IT)
7513   {
7514     /* Enable STOP interrupts */
7515     tmpisr |= I2C_IT_STOPI;
7516   }
7517 
7518   if (InterruptRequest == I2C_XFER_RELOAD_IT)
7519   {
7520     /* Enable TC interrupts */
7521     tmpisr |= I2C_IT_TCI;
7522   }
7523 
7524   /* Disable interrupts only at the end */
7525   /* to avoid a breaking situation like at "t" time */
7526   /* all disable interrupts request are not done */
7527   __HAL_I2C_DISABLE_IT(hi2c, tmpisr);
7528 }
7529 
7530 /**
7531   * @brief  Convert I2Cx OTHER_xxx XferOptions to functional XferOptions.
7532   * @param  hi2c I2C handle.
7533   * @retval None
7534   */
I2C_ConvertOtherXferOptions(I2C_HandleTypeDef * hi2c)7535 static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c)
7536 {
7537   /* if user set XferOptions to I2C_OTHER_FRAME            */
7538   /* it request implicitly to generate a restart condition */
7539   /* set XferOptions to I2C_FIRST_FRAME                    */
7540   if (hi2c->XferOptions == I2C_OTHER_FRAME)
7541   {
7542     hi2c->XferOptions = I2C_FIRST_FRAME;
7543   }
7544   /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */
7545   /* it request implicitly to generate a restart condition    */
7546   /* then generate a stop condition at the end of transfer    */
7547   /* set XferOptions to I2C_FIRST_AND_LAST_FRAME              */
7548   else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME)
7549   {
7550     hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME;
7551   }
7552   else
7553   {
7554     /* Nothing to do */
7555   }
7556 }
7557 
7558 /**
7559   * @}
7560   */
7561 
7562 #endif /* HAL_I2C_MODULE_ENABLED */
7563 /**
7564   * @}
7565   */
7566 
7567 /**
7568   * @}
7569   */
7570