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