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