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