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