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