1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_hal_i2c.c
4 * @author MCD Application Team
5 * @brief I2C HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Inter Integrated Circuit (I2C) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral State and Errors functions
11 *
12 @verbatim
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
16 [..]
17 The I2C HAL driver can be used as follows:
18
19 (#) Declare a I2C_HandleTypeDef handle structure, for example:
20 I2C_HandleTypeDef hi2c;
21
22 (#)Initialize the I2C low level resources by implementing the @ref HAL_I2C_MspInit() API:
23 (##) Enable the I2Cx interface clock
24 (##) I2C pins configuration
25 (+++) Enable the clock for the I2C GPIOs
26 (+++) Configure I2C pins as alternate function open-drain
27 (##) NVIC configuration if you need to use interrupt process
28 (+++) Configure the I2Cx interrupt priority
29 (+++) Enable the NVIC I2C IRQ Channel
30 (##) DMA Configuration if you need to use DMA process
31 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream
32 (+++) Enable the DMAx interface clock using
33 (+++) Configure the DMA handle parameters
34 (+++) Configure the DMA Tx or Rx stream
35 (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle
36 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on
37 the DMA Tx or Rx stream
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>© Copyright (c) 2019 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 "stm32mp1xx_hal.h"
309 #include "los_sys.h"
310
311 /* Private typedef -----------------------------------------------------------*/
312 /* Private define ------------------------------------------------------------*/
313
314 /** @defgroup I2C_Private_Define I2C Private Define
315 * @{
316 */
317 #define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< I2C TIMING clear register Mask */
318 #define I2C_TIMEOUT_ADDR (10000U) /*!< 10 s */
319 #define I2C_TIMEOUT_BUSY (25U) /*!< 25 ms */
320 #define I2C_TIMEOUT_DIR (25U) /*!< 25 ms */
321 #define I2C_TIMEOUT_RXNE (25U) /*!< 25 ms */
322 #define I2C_TIMEOUT_STOPF (25U) /*!< 25 ms */
323 #define I2C_TIMEOUT_TC (25U) /*!< 25 ms */
324 #define I2C_TIMEOUT_TCR (25U) /*!< 25 ms */
325 #define I2C_TIMEOUT_TXIS (25U) /*!< 25 ms */
326 #define I2C_TIMEOUT_FLAG (25U) /*!< 25 ms */
327
328 #define MAX_NBYTE_SIZE 255U
329 #define SlaveAddr_SHIFT 7U
330 #define SlaveAddr_MSK 0x06U
331
332 /* Private define for @ref PreviousState usage */
333 #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 */
334 #define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */
335 #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 */
336 #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 */
337 #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 */
338 #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 */
339 #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 */
340 #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 */
341
342
343 /* Private define to centralize the enable/disable of Interrupts */
344 #define I2C_XFER_TX_IT (0x00000001U)
345 #define I2C_XFER_RX_IT (0x00000002U)
346 #define I2C_XFER_LISTEN_IT (0x00000004U)
347
348 #define I2C_XFER_ERROR_IT (0x00000011U)
349 #define I2C_XFER_CPLT_IT (0x00000012U)
350 #define I2C_XFER_RELOAD_IT (0x00000012U)
351
352 /* Private define Sequential Transfer Options default/reset value */
353 #define I2C_NO_OPTION_FRAME (0xFFFF0000U)
354 /**
355 * @}
356 */
357 /**
358 * @brief Initializes the I2C according to the specified parameters
359 * in the I2C_InitTypeDef and initialize the associated handle.
360 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
361 * the configuration information for the specified I2C.
362 * @retval HAL status
363 */
HAL_I2C_Init(I2C_HandleTypeDef * hi2c)364 HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)
365 {
366 /* Check the I2C handle allocation */
367 if (hi2c == NULL)
368 {
369 return HAL_ERROR;
370 }
371
372
373 if (hi2c->State == HAL_I2C_STATE_RESET)
374 {
375 /* Allocate lock resource and initialize it */
376 hi2c->Lock = HAL_UNLOCKED;
377 }
378
379 hi2c->State = HAL_I2C_STATE_BUSY;
380
381 /* Disable the selected I2C peripheral */
382 __HAL_I2C_DISABLE(hi2c);
383
384 /*---------------------------- I2Cx TIMINGR Configuration ------------------*/
385 /* Configure I2Cx: Frequency range */
386 hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK;
387
388 /*---------------------------- I2Cx OAR1 Configuration ---------------------*/
389 /* Disable Own Address1 before set the Own Address1 configuration */
390 hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN;
391
392 /* Configure I2Cx: Own Address1 and ack own address1 mode */
393 if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT)
394 {
395 hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1);
396 }
397 else /* I2C_ADDRESSINGMODE_10BIT */
398 {
399 hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1);
400 }
401
402 /*---------------------------- I2Cx CR2 Configuration ----------------------*/
403 /* Configure I2Cx: Addressing Master mode */
404 if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)
405 {
406 hi2c->Instance->CR2 = (I2C_CR2_ADD10);
407 }
408 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
409 hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
410
411 /*---------------------------- I2Cx OAR2 Configuration ---------------------*/
412 /* Disable Own Address2 before set the Own Address2 configuration */
413 hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE;
414
415 /* Configure I2Cx: Dual mode and Own Address2 */
416 hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8));
417
418 /*---------------------------- I2Cx CR1 Configuration ----------------------*/
419 /* Configure I2Cx: Generalcall and NoStretch mode */
420 hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode);
421
422 /* Enable the selected I2C peripheral */
423 __HAL_I2C_ENABLE(hi2c);
424
425 hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
426 hi2c->State = HAL_I2C_STATE_READY;
427 hi2c->PreviousState = I2C_STATE_NONE;
428 hi2c->Mode = HAL_I2C_MODE_NONE;
429
430 return HAL_OK;
431 }
432
433 /**
434 * @brief DeInitialize the I2C peripheral.
435 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
436 * the configuration information for the specified I2C.
437 * @retval HAL status
438 */
HAL_I2C_DeInit(I2C_HandleTypeDef * hi2c)439 HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c)
440 {
441 /* Check the I2C handle allocation */
442 if (hi2c == NULL)
443 {
444 return HAL_ERROR;
445 }
446
447 hi2c->State = HAL_I2C_STATE_BUSY;
448
449 /* Disable the I2C Peripheral Clock */
450 __HAL_I2C_DISABLE(hi2c);
451
452 hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
453 hi2c->State = HAL_I2C_STATE_RESET;
454 hi2c->PreviousState = I2C_STATE_NONE;
455 hi2c->Mode = HAL_I2C_MODE_NONE;
456
457 /* Release Lock */
458 __HAL_UNLOCK(hi2c);
459
460 return HAL_OK;
461 }
462
463 /**
464 * @brief I2C Tx data register flush process.
465 * @param hi2c I2C handle.
466 * @retval None
467 */
I2C_Flush_TXDR(I2C_HandleTypeDef * hi2c)468 static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c)
469 {
470 /* If a pending TXIS flag is set */
471 /* Write a dummy data in TXDR to clear it */
472 if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET)
473 {
474 hi2c->Instance->TXDR = 0x00U;
475 }
476
477 /* Flush TX register if not empty */
478 if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET)
479 {
480 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE);
481 }
482 }
483
484 /**
485 * @brief This function handles Acknowledge failed detection during an I2C Communication.
486 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
487 * the configuration information for the specified I2C.
488 * @param Timeout Timeout duration
489 * @param Tickstart Tick start value
490 * @retval HAL status
491 */
I2C_IsAcknowledgeFailed(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)492 static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
493 {
494 if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET)
495 {
496 /* Wait until STOP Flag is reset */
497 /* AutoEnd should be initiate after AF */
498 while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
499 {
500 /* Check for the Timeout */
501 if (Timeout != HAL_MAX_DELAY)
502 {
503 if (((LOS_TickCountGet() - Tickstart) > Timeout) || (Timeout == 0U))
504 {
505 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
506 hi2c->State = HAL_I2C_STATE_READY;
507 hi2c->Mode = HAL_I2C_MODE_NONE;
508
509 /* Process Unlocked */
510 __HAL_UNLOCK(hi2c);
511
512 return HAL_ERROR;
513 }
514 }
515 }
516
517 /* Clear NACKF Flag */
518 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF);
519
520 /* Clear STOP Flag */
521 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
522
523 /* Flush TX register */
524 I2C_Flush_TXDR(hi2c);
525
526 /* Clear Configuration Register 2 */
527 I2C_RESET_CR2(hi2c);
528
529 hi2c->ErrorCode |= HAL_I2C_ERROR_AF;
530 hi2c->State = HAL_I2C_STATE_READY;
531 hi2c->Mode = HAL_I2C_MODE_NONE;
532
533 /* Process Unlocked */
534 __HAL_UNLOCK(hi2c);
535
536 return HAL_ERROR;
537 }
538 return HAL_OK;
539 }
540
541 /**
542 * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
543 * @param hi2c I2C handle.
544 * @param DevAddress Specifies the slave address to be programmed.
545 * @param Size Specifies the number of bytes to be programmed.
546 * This parameter must be a value between 0 and 255.
547 * @param Mode New state of the I2C START condition generation.
548 * This parameter can be one of the following values:
549 * @arg @ref I2C_RELOAD_MODE Enable Reload mode .
550 * @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode.
551 * @arg @ref I2C_SOFTEND_MODE Enable Software end mode.
552 * @param Request New state of the I2C START condition generation.
553 * This parameter can be one of the following values:
554 * @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition.
555 * @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0).
556 * @arg @ref I2C_GENERATE_START_READ Generate Restart for read request.
557 * @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request.
558 * @retval None
559 */
I2C_TransferConfig(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)560 static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
561 {
562 /* update CR2 register */
563 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)), \
564 (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request));
565 }
566
567 /**
568 * @brief This function handles I2C Communication Timeout.
569 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
570 * the configuration information for the specified I2C.
571 * @param Flag Specifies the I2C flag to check.
572 * @param Status The new Flag status (SET or RESET).
573 * @param Timeout Timeout duration
574 * @param Tickstart Tick start value
575 * @retval HAL status
576 */
I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Flag,FlagStatus Status,uint32_t Timeout,uint32_t Tickstart)577 static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart)
578 {
579 while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
580 {
581 /* Check for the Timeout */
582 if (Timeout != HAL_MAX_DELAY)
583 {
584 if (((LOS_TickCountGet() - Tickstart) > Timeout) || (Timeout == 0U))
585 {
586 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
587 hi2c->State = HAL_I2C_STATE_READY;
588 hi2c->Mode = HAL_I2C_MODE_NONE;
589
590 /* Process Unlocked */
591 __HAL_UNLOCK(hi2c);
592 return HAL_ERROR;
593 }
594 }
595 }
596 return HAL_OK;
597 }
598
599 /**
600 * @brief This function handles I2C Communication Timeout for specific usage of TXIS flag.
601 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
602 * the configuration information for the specified I2C.
603 * @param Timeout Timeout duration
604 * @param Tickstart Tick start value
605 * @retval HAL status
606 */
I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)607 static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
608 {
609 while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET)
610 {
611 /* Check if a NACK is detected */
612 if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
613 {
614 return HAL_ERROR;
615 }
616
617 /* Check for the Timeout */
618 if (Timeout != HAL_MAX_DELAY)
619 {
620 if (((LOS_TickCountGet() - Tickstart) > Timeout) || (Timeout == 0U))
621 {
622 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
623 hi2c->State = HAL_I2C_STATE_READY;
624 hi2c->Mode = HAL_I2C_MODE_NONE;
625 /* Process Unlocked */
626 __HAL_UNLOCK(hi2c);
627
628 return HAL_ERROR;
629 }
630 }
631 }
632 return HAL_OK;
633 }
634
635 /**
636 * @brief This function handles I2C Communication Timeout for specific usage of STOP flag.
637 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
638 * the configuration information for the specified I2C.
639 * @param Timeout Timeout duration
640 * @param Tickstart Tick start value
641 * @retval HAL status
642 */
I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)643 static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
644 {
645 while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
646 {
647 /* Check if a NACK is detected */
648 if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
649 {
650 return HAL_ERROR;
651 }
652
653 /* Check for the Timeout */
654 if (((LOS_TickCountGet() - Tickstart) > Timeout) || (Timeout == 0U))
655 {
656 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
657 hi2c->State = HAL_I2C_STATE_READY;
658 hi2c->Mode = HAL_I2C_MODE_NONE;
659
660 /* Process Unlocked */
661 __HAL_UNLOCK(hi2c);
662
663 return HAL_ERROR;
664 }
665 }
666 return HAL_OK;
667 }
668
669 /**
670 * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag.
671 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
672 * the configuration information for the specified I2C.
673 * @param Timeout Timeout duration
674 * @param Tickstart Tick start value
675 * @retval HAL status
676 */
I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef * hi2c,uint32_t Timeout,uint32_t Tickstart)677 static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart)
678 {
679 while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET)
680 {
681 /* Check if a NACK is detected */
682 if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK)
683 {
684 return HAL_ERROR;
685 }
686
687 /* Check if a STOPF is detected */
688 if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET)
689 {
690 /* Check if an RXNE is pending */
691 /* Store Last receive data if any */
692 if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U))
693 {
694 /* Return HAL_OK */
695 /* The Reading of data from RXDR will be done in caller function */
696 return HAL_OK;
697 }
698 else
699 {
700 /* Clear STOP Flag */
701 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
702
703 /* Clear Configuration Register 2 */
704 I2C_RESET_CR2(hi2c);
705
706 hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
707 hi2c->State = HAL_I2C_STATE_READY;
708 hi2c->Mode = HAL_I2C_MODE_NONE;
709
710 /* Process Unlocked */
711 __HAL_UNLOCK(hi2c);
712
713 return HAL_ERROR;
714 }
715 }
716
717 /* Check for the Timeout */
718 if (((LOS_TickCountGet() - Tickstart) > Timeout) || (Timeout == 0U))
719 {
720 hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
721 hi2c->State = HAL_I2C_STATE_READY;
722
723 /* Process Unlocked */
724 __HAL_UNLOCK(hi2c);
725
726 return HAL_ERROR;
727 }
728 }
729 return HAL_OK;
730 }
731
732 /**
733 * @brief Transmits in master mode an amount of data in blocking mode.
734 * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
735 * the configuration information for the specified I2C.
736 * @param DevAddress Target device address: The device 7 bits address value
737 * in datasheet must be shifted to the left before calling the interface
738 * @param pData Pointer to data buffer
739 * @param Size Amount of data to be sent
740 * @param Timeout Timeout duration
741 * @retval HAL status
742 */
HAL_I2C_Master_Transmit(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t Timeout)743 HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
744 {
745 uint32_t tickstart;
746
747 if (hi2c->State == HAL_I2C_STATE_READY)
748 {
749 if(hi2c == NULL)
750 {
751 return -1;
752 }
753 /* Process Locked */
754 __HAL_LOCK(hi2c);
755
756 /* Init tickstart for timeout management*/
757 tickstart = LOS_TickCountGet();
758
759 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
760 {
761 return HAL_ERROR;
762 }
763
764 hi2c->State = HAL_I2C_STATE_BUSY_TX;
765 hi2c->Mode = HAL_I2C_MODE_MASTER;
766 hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
767
768 /* Prepare transfer parameters */
769 hi2c->pBuffPtr = pData;
770 hi2c->XferCount = Size;
771 hi2c->XferISR = NULL;
772
773 /* Send Slave Address */
774 /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
775 if (hi2c->XferCount > MAX_NBYTE_SIZE)
776 {
777 hi2c->XferSize = MAX_NBYTE_SIZE;
778 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
779 }
780 else
781 {
782 hi2c->XferSize = hi2c->XferCount;
783 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
784 }
785 while (hi2c->XferCount > 0U)
786 {
787 /* Wait until TXIS flag is set */
788 if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
789 {
790 return HAL_ERROR;
791 }
792 /* Write data to TXDR */
793 hi2c->Instance->TXDR = *hi2c->pBuffPtr;
794
795 /* Increment Buffer pointer */
796 hi2c->pBuffPtr++;
797
798 hi2c->XferCount--;
799 hi2c->XferSize--;
800
801 if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
802 {
803 /* Wait until TCR flag is set */
804 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
805 {
806 return HAL_ERROR;
807 }
808
809
810 if (hi2c->XferCount > MAX_NBYTE_SIZE)
811 {
812 hi2c->XferSize = MAX_NBYTE_SIZE;
813 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
814 }
815 else
816 {
817 hi2c->XferSize = hi2c->XferCount;
818 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
819 }
820 }
821 }
822 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
823 /* Wait until STOPF flag is set */
824 if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
825 {
826 return HAL_ERROR;
827 }
828
829 /* Clear STOP Flag */
830 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
831
832 /* Clear Configuration Register 2 */
833 I2C_RESET_CR2(hi2c);
834
835 hi2c->State = HAL_I2C_STATE_READY;
836 hi2c->Mode = HAL_I2C_MODE_NONE;
837
838 /* Process Unlocked */
839 __HAL_UNLOCK(hi2c);
840
841 return HAL_OK;
842 }
843 else
844 {
845 return HAL_BUSY;
846 }
847 }
848
HAL_I2C_Master_Receive(I2C_HandleTypeDef * hi2c,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t Timeout)849 HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
850 {
851 uint32_t tickstart;
852
853 if (hi2c->State == HAL_I2C_STATE_READY)
854 {
855 /* Process Locked */
856 __HAL_LOCK(hi2c);
857
858 /* Init tickstart for timeout management*/
859 tickstart = LOS_TickCountGet();
860
861 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
862 {
863 return HAL_ERROR;
864 }
865
866 hi2c->State = HAL_I2C_STATE_BUSY_RX;
867 hi2c->Mode = HAL_I2C_MODE_MASTER;
868 hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
869
870 /* Prepare transfer parameters */
871 hi2c->pBuffPtr = pData;
872 hi2c->XferCount = Size;
873 hi2c->XferISR = NULL;
874
875 /* Send Slave Address */
876 /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
877 if (hi2c->XferCount > MAX_NBYTE_SIZE)
878 {
879 hi2c->XferSize = MAX_NBYTE_SIZE;
880 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
881 }
882 else
883 {
884 hi2c->XferSize = hi2c->XferCount;
885 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
886 }
887 while (hi2c->XferCount > 0U)
888 {
889 /* Wait until RXNE flag is set */
890 if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
891 {
892 return HAL_ERROR;
893 }
894
895 /* Read data from RXDR */
896 *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;
897
898 /* Increment Buffer pointer */
899 hi2c->pBuffPtr++;
900
901 hi2c->XferSize--;
902 hi2c->XferCount--;
903
904 if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U))
905 {
906 /* Wait until TCR flag is set */
907 if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
908 {
909 return HAL_ERROR;
910 }
911
912 if (hi2c->XferCount > MAX_NBYTE_SIZE)
913 {
914 hi2c->XferSize = MAX_NBYTE_SIZE;
915 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
916 }
917 else
918 {
919 hi2c->XferSize = hi2c->XferCount;
920 I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
921 }
922 }
923 }
924
925 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
926 /* Wait until STOPF flag is set */
927 if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
928 {
929 return HAL_ERROR;
930 }
931
932 /* Clear STOP Flag */
933 __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
934
935 /* Clear Configuration Register 2 */
936 I2C_RESET_CR2(hi2c);
937
938 hi2c->State = HAL_I2C_STATE_READY;
939 hi2c->Mode = HAL_I2C_MODE_NONE;
940
941 /* Process Unlocked */
942 __HAL_UNLOCK(hi2c);
943
944 return HAL_OK;
945 }
946 else
947 {
948 return HAL_BUSY;
949 }
950 }
951
952 /**
953 * @}
954 */
955
956 /**
957 * @}
958 */
959
960 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
961