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