source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

File size: 129.2 KB
Line 
1/**
2 ******************************************************************************
3 * @file stm32f4xx_hal_fmpi2c.c
4 * @author MCD Application Team
5 * @version V1.4.1
6 * @date 09-October-2015
7 * @brief FMPI2C HAL module driver.
8 *
9 * This file provides firmware functions to manage the following
10 * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral:
11 * + Initialization and de-initialization functions
12 * + IO operation functions
13 * + Peripheral State functions
14 *
15 @verbatim
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
19 [..]
20 The FMPI2C HAL driver can be used as follows:
21
22 (#) Declare a FMPI2C_HandleTypeDef handle structure, for example:
23 FMPI2C_HandleTypeDef hfmpi2c;
24
25 (#)Initialize the FMPI2C low level resources by implement the HAL_FMPI2C_MspInit ()API:
26 (##) Enable the FMPI2Cx interface clock
27 (##) FMPI2C pins configuration
28 (+++) Enable the clock for the FMPI2C GPIOs
29 (+++) Configure FMPI2C pins as alternate function open-drain
30 (##) NVIC configuration if you need to use interrupt process
31 (+++) Configure the FMPI2Cx interrupt priority
32 (+++) Enable the NVIC FMPI2C IRQ Channel
33 (##) DMA Configuration if you need to use DMA process
34 (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream
35 (+++) Enable the DMAx interface clock using
36 (+++) Configure the DMA handle parameters
37 (+++) Configure the DMA Tx or Rx Stream
38 (+++) Associate the initilalized DMA handle to the hfmpi2c DMA Tx or Rx handle
39 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream
40
41 (#) Configure the Communication Clock Timing, Own Address1, Master Adressing Mode, Dual Addressing mode,
42 Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure.
43
44 (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init() API:
45 (+++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
46 by calling the customed HAL_FMPI2C_MspInit(&hfmpi2c) API.
47
48 (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady()
49
50 (#) For FMPI2C IO and IO MEM operations, three mode of operations are available within this driver :
51
52 *** Polling mode IO operation ***
53 =================================
54 [..]
55 (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit()
56 (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive()
57 (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit()
58 (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive()
59
60 *** Polling mode IO MEM operation ***
61 =====================================
62 [..]
63 (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write()
64 (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read()
65
66
67 *** Interrupt mode IO operation ***
68 ===================================
69 [..]
70 (+) Transmit in master mode an amount of data in non blocking mode using HAL_FMPI2C_Master_Transmit_IT()
71 (+) At transmission end of transfer HAL_FMPI2C_MasterTxCpltCallback is executed and user can
72 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback
73 (+) Receive in master mode an amount of data in non blocking mode using HAL_FMPI2C_Master_Receive_IT()
74 (+) At reception end of transfer HAL_FMPI2C_MasterRxCpltCallback is executed and user can
75 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback
76 (+) Transmit in slave mode an amount of data in non blocking mode using HAL_FMPI2C_Slave_Transmit_IT()
77 (+) At transmission end of transfer HAL_FMPI2C_SlaveTxCpltCallback is executed and user can
78 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback
79 (+) Receive in slave mode an amount of data in non blocking mode using HAL_FMPI2C_Slave_Receive_IT()
80 (+) At reception end of transfer HAL_FMPI2C_SlaveRxCpltCallback is executed and user can
81 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback
82 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
83 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback
84
85 *** Interrupt mode IO MEM operation ***
86 =======================================
87 [..]
88 (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using
89 HAL_FMPI2C_Mem_Write_IT()
90 (+) At MEM end of write transfer HAL_FMPI2C_MemTxCpltCallback is executed and user can
91 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback
92 (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using
93 HAL_FMPI2C_Mem_Read_IT()
94 (+) At MEM end of read transfer HAL_FMPI2C_MemRxCpltCallback is executed and user can
95 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback
96 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
97 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback
98
99 *** DMA mode IO operation ***
100 ==============================
101 [..]
102 (+) Transmit in master mode an amount of data in non blocking mode (DMA) using
103 HAL_FMPI2C_Master_Transmit_DMA()
104 (+) At transmission end of transfer HAL_FMPI2C_MasterTxCpltCallback is executed and user can
105 add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback
106 (+) Receive in master mode an amount of data in non blocking mode (DMA) using
107 HAL_FMPI2C_Master_Receive_DMA()
108 (+) At reception end of transfer HAL_FMPI2C_MasterRxCpltCallback is executed and user can
109 add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback
110 (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using
111 HAL_FMPI2C_Slave_Transmit_DMA()
112 (+) At transmission end of transfer HAL_FMPI2C_SlaveTxCpltCallback is executed and user can
113 add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback
114 (+) Receive in slave mode an amount of data in non blocking mode (DMA) using
115 HAL_FMPI2C_Slave_Receive_DMA()
116 (+) At reception end of transfer HAL_FMPI2C_SlaveRxCpltCallback is executed and user can
117 add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback
118 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
119 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback
120
121 *** DMA mode IO MEM operation ***
122 =================================
123 [..]
124 (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using
125 HAL_FMPI2C_Mem_Write_DMA()
126 (+) At MEM end of write transfer HAL_FMPI2C_MemTxCpltCallback is executed and user can
127 add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback
128 (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using
129 HAL_FMPI2C_Mem_Read_DMA()
130 (+) At MEM end of read transfer HAL_FMPI2C_MemRxCpltCallback is executed and user can
131 add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback
132 (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can
133 add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback
134
135
136 *** FMPI2C HAL driver macros list ***
137 ==================================
138 [..]
139 Below the list of most used macros in FMPI2C HAL driver.
140
141 (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral
142 (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral
143 (+) __HAL_FMPI2C_GET_FLAG : Checks whether the specified FMPI2C flag is set or not
144 (+) __HAL_FMPI2C_CLEAR_FLAG : Clears the specified FMPI2C pending flag
145 (+) __HAL_FMPI2C_ENABLE_IT: Enables the specified FMPI2C interrupt
146 (+) __HAL_FMPI2C_DISABLE_IT: Disables the specified FMPI2C interrupt
147
148 [..]
149 (@) You can refer to the FMPI2C HAL driver header file for more useful macros
150
151 @endverbatim
152 ******************************************************************************
153 * @attention
154 *
155 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
156 *
157 * Redistribution and use in source and binary forms, with or without modification,
158 * are permitted provided that the following conditions are met:
159 * 1. Redistributions of source code must retain the above copyright notice,
160 * this list of conditions and the following disclaimer.
161 * 2. Redistributions in binary form must reproduce the above copyright notice,
162 * this list of conditions and the following disclaimer in the documentation
163 * and/or other materials provided with the distribution.
164 * 3. Neither the name of STMicroelectronics nor the names of its contributors
165 * may be used to endorse or promote products derived from this software
166 * without specific prior written permission.
167 *
168 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
169 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
170 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
171 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
172 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
173 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
174 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
175 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
176 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
177 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
178 *
179 ******************************************************************************
180 */
181
182/* Includes ------------------------------------------------------------------*/
183#include "stm32f4xx_hal.h"
184
185/** @addtogroup STM32F4xx_HAL_Driver
186 * @{
187 */
188
189/** @defgroup FMPI2C FMPI2C
190 * @brief FMPI2C HAL module driver
191 * @{
192 */
193
194#ifdef HAL_FMPI2C_MODULE_ENABLED
195
196#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx)
197
198/* Private typedef -----------------------------------------------------------*/
199/* Private define ------------------------------------------------------------*/
200/** @addtogroup FMPI2C_Private_Constants
201 * @{
202 */
203#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*<! FMPI2C TIMING clear register Mask */
204#define FMPI2C_TIMEOUT_ADDR ((uint32_t)10000) /* 10 s */
205#define FMPI2C_TIMEOUT_BUSY ((uint32_t)25) /* 25 ms */
206#define FMPI2C_TIMEOUT_DIR ((uint32_t)25) /* 25 ms */
207#define FMPI2C_TIMEOUT_RXNE ((uint32_t)25) /* 25 ms */
208#define FMPI2C_TIMEOUT_STOPF ((uint32_t)25) /* 25 ms */
209#define FMPI2C_TIMEOUT_TC ((uint32_t)25) /* 25 ms */
210#define FMPI2C_TIMEOUT_TCR ((uint32_t)25) /* 25 ms */
211#define FMPI2C_TIMEOUT_TXIS ((uint32_t)25) /* 25 ms */
212#define FMPI2C_TIMEOUT_FLAG ((uint32_t)25) /* 25 ms */
213/**
214 * @}
215 */
216
217/* Private macro -------------------------------------------------------------*/
218/* Private variables ---------------------------------------------------------*/
219/* Private function prototypes -----------------------------------------------*/
220/** @addtogroup FMPI2C_Private_Functions
221 * @brief FMPI2C private functions
222 * @{
223 */
224static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma);
225static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma);
226static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma);
227static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma);
228static void FMPI2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma);
229static void FMPI2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma);
230static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma);
231
232static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout);
233static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout);
234static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
235static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout);
236static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout);
237static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout);
238static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout);
239
240static HAL_StatusTypeDef FMPI2C_MasterTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c);
241static HAL_StatusTypeDef FMPI2C_MasterReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c);
242
243static HAL_StatusTypeDef FMPI2C_SlaveTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c);
244static HAL_StatusTypeDef FMPI2C_SlaveReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c);
245
246static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request);
247/**
248 * @}
249 */
250
251/* Exported functions --------------------------------------------------------*/
252/** @defgroup FMPI2C_Exported_Functions FMPI2C Exported Functions
253 * @{
254 */
255
256/** @defgroup FMPI2C_Exported_Functions_Group1 Initialization and de-initialization functions
257 * @brief Initialization and Configuration functions
258 *
259@verbatim
260 ===============================================================================
261 ##### Initialization and de-initialization functions #####
262 ===============================================================================
263 [..] This subsection provides a set of functions allowing to initialize and
264 de-initialiaze the FMPI2Cx peripheral:
265
266 (+) User must Implement HAL_FMPI2C_MspInit() function in which he configures
267 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
268
269 (+) Call the function HAL_FMPI2C_Init() to configure the selected device with
270 the selected configuration:
271 (++) Clock Timing
272 (++) Own Address 1
273 (++) Addressing mode (Master, Slave)
274 (++) Dual Addressing mode
275 (++) Own Address 2
276 (++) Own Address 2 Mask
277 (++) General call mode
278 (++) Nostretch mode
279
280 (+) Call the function HAL_FMPI2C_DeInit() to restore the default configuration
281 of the selected FMPI2Cx periperal.
282
283@endverbatim
284 * @{
285 */
286
287/**
288 * @brief Initializes the FMPI2C according to the specified parameters
289 * in the FMPI2C_InitTypeDef and create the associated handle.
290 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
291 * the configuration information for the specified FMPI2C.
292 * @retval HAL status
293 */
294HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hfmpi2c)
295{
296 /* Check the FMPI2C handle allocation */
297 if(hfmpi2c == NULL)
298 {
299 return HAL_ERROR;
300 }
301
302 /* Check the parameters */
303 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
304 assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1));
305 assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode));
306 assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode));
307 assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2));
308 assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks));
309 assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode));
310 assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode));
311
312 if(hfmpi2c->State == HAL_FMPI2C_STATE_RESET)
313 {
314 /* Allocate lock resource and initialize it */
315 hfmpi2c->Lock = HAL_UNLOCKED;
316 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
317 HAL_FMPI2C_MspInit(hfmpi2c);
318 }
319
320 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
321
322 /* Disable the selected FMPI2C peripheral */
323 __HAL_FMPI2C_DISABLE(hfmpi2c);
324
325 /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/
326 /* Configure FMPI2Cx: Frequency range */
327 hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK;
328
329 /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/
330 /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */
331 hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
332 if(hfmpi2c->Init.OwnAddress1 != 0)
333 {
334 if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT)
335 {
336 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1);
337 }
338 else /* FMPI2C_ADDRESSINGMODE_10BIT */
339 {
340 hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1);
341 }
342 }
343
344 /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/
345 /* Configure FMPI2Cx: Addressing Master mode */
346 if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
347 {
348 hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10);
349 }
350 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
351 hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
352
353 /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/
354 /* Configure FMPI2Cx: Dual mode and Own Address2 */
355 hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8));
356
357 /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/
358 /* Configure FMPI2Cx: Generalcall and NoStretch mode */
359 hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode);
360
361 /* Enable the selected FMPI2C peripheral */
362 __HAL_FMPI2C_ENABLE(hfmpi2c);
363
364 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
365 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
366
367 return HAL_OK;
368}
369
370/**
371 * @brief DeInitializes the FMPI2C peripheral.
372 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
373 * the configuration information for the specified FMPI2C.
374 * @retval HAL status
375 */
376HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c)
377{
378 /* Check the FMPI2C handle allocation */
379 if(hfmpi2c == NULL)
380 {
381 return HAL_ERROR;
382 }
383
384 /* Check the parameters */
385 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
386
387 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
388
389 /* Disable the FMPI2C Peripheral Clock */
390 __HAL_FMPI2C_DISABLE(hfmpi2c);
391
392 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
393 HAL_FMPI2C_MspDeInit(hfmpi2c);
394
395 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
396 hfmpi2c->State = HAL_FMPI2C_STATE_RESET;
397
398 /* Release Lock */
399 __HAL_UNLOCK(hfmpi2c);
400
401 return HAL_OK;
402}
403
404/**
405 * @brief FMPI2C MSP Init.
406 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
407 * the configuration information for the specified FMPI2C.
408 * @retval None
409 */
410 __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c)
411{
412 /* NOTE : This function Should not be modified, when the callback is needed,
413 the HAL_FMPI2C_MspInit could be implemented in the user file
414 */
415}
416
417/**
418 * @brief FMPI2C MSP DeInit
419 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
420 * the configuration information for the specified FMPI2C.
421 * @retval None
422 */
423 __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c)
424{
425 /* NOTE : This function Should not be modified, when the callback is needed,
426 the HAL_FMPI2C_MspDeInit could be implemented in the user file
427 */
428}
429
430/**
431 * @}
432 */
433
434/** @defgroup FMPI2C_Exported_Functions_Group2 I/O operation functions
435 * @brief Data transfers functions
436 *
437@verbatim
438 ===============================================================================
439 ##### IO operation functions #####
440 ===============================================================================
441 [..]
442 This subsection provides a set of functions allowing to manage the FMPI2C data
443 transfers.
444
445 (#) There is two mode of transfer:
446 (++) Blocking mode : The communication is performed in the polling mode.
447 The status of all data processing is returned by the same function
448 after finishing transfer.
449 (++) No-Blocking mode : The communication is performed using Interrupts
450 or DMA. These functions return the status of the transfer startup.
451 The end of the data processing will be indicated through the
452 dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when
453 using DMA mode.
454
455 (#) Blocking mode functions are :
456 (++) HAL_FMPI2C_Master_Transmit()
457 (++) HAL_FMPI2C_Master_Receive()
458 (++) HAL_FMPI2C_Slave_Transmit()
459 (++) HAL_FMPI2C_Slave_Receive()
460 (++) HAL_FMPI2C_Mem_Write()
461 (++) HAL_FMPI2C_Mem_Read()
462 (++) HAL_FMPI2C_IsDeviceReady()
463
464 (#) No-Blocking mode functions with Interrupt are :
465 (++) HAL_FMPI2C_Master_Transmit_IT()
466 (++) HAL_FMPI2C_Master_Receive_IT()
467 (++) HAL_FMPI2C_Slave_Transmit_IT()
468 (++) HAL_FMPI2C_Slave_Receive_IT()
469 (++) HAL_FMPI2C_Mem_Write_IT()
470 (++) HAL_FMPI2C_Mem_Read_IT()
471
472 (#) No-Blocking mode functions with DMA are :
473 (++) HAL_FMPI2C_Master_Transmit_DMA()
474 (++) HAL_FMPI2C_Master_Receive_DMA()
475 (++) HAL_FMPI2C_Slave_Transmit_DMA()
476 (++) HAL_FMPI2C_Slave_Receive_DMA()
477 (++) HAL_FMPI2C_Mem_Write_DMA()
478 (++) HAL_FMPI2C_Mem_Read_DMA()
479
480 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
481 (++) HAL_FMPI2C_MemTxCpltCallback()
482 (++) HAL_FMPI2C_MemRxCpltCallback()
483 (++) HAL_FMPI2C_MasterTxCpltCallback()
484 (++) HAL_FMPI2C_MasterRxCpltCallback()
485 (++) HAL_FMPI2C_SlaveTxCpltCallback()
486 (++) HAL_FMPI2C_SlaveRxCpltCallback()
487 (++) HAL_FMPI2C_ErrorCallback()
488
489@endverbatim
490 * @{
491 */
492
493/**
494 * @brief Transmits in master mode an amount of data in blocking mode.
495 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
496 * the configuration information for the specified FMPI2C.
497 * @param DevAddress: Target device address
498 * @param pData: Pointer to data buffer
499 * @param Size: Amount of data to be sent
500 * @param Timeout: Timeout duration
501 * @retval HAL status
502 */
503HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
504{
505 uint32_t sizetmp = 0;
506
507 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
508 {
509 if((pData == NULL ) || (Size == 0))
510 {
511 return HAL_ERROR;
512 }
513
514 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
515 {
516 return HAL_BUSY;
517 }
518
519 /* Process Locked */
520 __HAL_LOCK(hfmpi2c);
521
522 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX;
523 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
524
525 /* Send Slave Address */
526 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
527 /* Size > 255, need to set RELOAD bit */
528 if(Size > 255)
529 {
530 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
531 sizetmp = 255;
532 }
533 else
534 {
535 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
536 sizetmp = Size;
537 }
538
539 do
540 {
541 /* Wait until TXIS flag is set */
542 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
543 {
544 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
545 {
546 return HAL_ERROR;
547 }
548 else
549 {
550 return HAL_TIMEOUT;
551 }
552 }
553 /* Write data to TXDR */
554 hfmpi2c->Instance->TXDR = (*pData++);
555 sizetmp--;
556 Size--;
557
558 if((sizetmp == 0)&&(Size!=0))
559 {
560 /* Wait until TXE flag is set */
561 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
562 {
563 return HAL_TIMEOUT;
564 }
565
566 if(Size > 255)
567 {
568 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
569 sizetmp = 255;
570 }
571 else
572 {
573 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
574 sizetmp = Size;
575 }
576 }
577
578 }while(Size > 0);
579
580 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
581 /* Wait until STOPF flag is set */
582 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
583 {
584 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
585 {
586 return HAL_ERROR;
587 }
588 else
589 {
590 return HAL_TIMEOUT;
591 }
592 }
593
594 /* Clear STOP Flag */
595 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
596
597 /* Clear Configuration Register 2 */
598 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
599
600 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
601
602 /* Process Unlocked */
603 __HAL_UNLOCK(hfmpi2c);
604
605 return HAL_OK;
606 }
607 else
608 {
609 return HAL_BUSY;
610 }
611}
612
613/**
614 * @brief Receives in master mode an amount of data in blocking mode.
615 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
616 * the configuration information for the specified FMPI2C.
617 * @param DevAddress: Target device address
618 * @param pData: Pointer to data buffer
619 * @param Size: Amount of data to be sent
620 * @param Timeout: Timeout duration
621 * @retval HAL status
622 */
623HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
624{
625 uint32_t sizetmp = 0;
626
627 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
628 {
629 if((pData == NULL ) || (Size == 0))
630 {
631 return HAL_ERROR;
632 }
633
634 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
635 {
636 return HAL_BUSY;
637 }
638
639 /* Process Locked */
640 __HAL_LOCK(hfmpi2c);
641
642 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX;
643 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
644
645 /* Send Slave Address */
646 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
647 /* Size > 255, need to set RELOAD bit */
648 if(Size > 255)
649 {
650 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
651 sizetmp = 255;
652 }
653 else
654 {
655 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
656 sizetmp = Size;
657 }
658
659 do
660 {
661 /* Wait until RXNE flag is set */
662 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
663 {
664 return HAL_TIMEOUT;
665 }
666
667 /* Write data to RXDR */
668 (*pData++) =hfmpi2c->Instance->RXDR;
669 sizetmp--;
670 Size--;
671
672 if((sizetmp == 0)&&(Size!=0))
673 {
674 /* Wait until TCR flag is set */
675 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
676 {
677 return HAL_TIMEOUT;
678 }
679
680 if(Size > 255)
681 {
682 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
683 sizetmp = 255;
684 }
685 else
686 {
687 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
688 sizetmp = Size;
689 }
690 }
691
692 }while(Size > 0);
693
694 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
695 /* Wait until STOPF flag is set */
696 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
697 {
698 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
699 {
700 return HAL_ERROR;
701 }
702 else
703 {
704 return HAL_TIMEOUT;
705 }
706 }
707
708 /* Clear STOP Flag */
709 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
710
711 /* Clear Configuration Register 2 */
712 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
713
714 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
715
716 /* Process Unlocked */
717 __HAL_UNLOCK(hfmpi2c);
718
719 return HAL_OK;
720 }
721 else
722 {
723 return HAL_BUSY;
724 }
725}
726
727/**
728 * @brief Transmits in slave mode an amount of data in blocking mode.
729 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
730 * the configuration information for the specified FMPI2C.
731 * @param pData: Pointer to data buffer
732 * @param Size: Amount of data to be sent
733 * @param Timeout: Timeout duration
734 * @retval HAL status
735 */
736HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
737{
738 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
739 {
740 if((pData == NULL ) || (Size == 0))
741 {
742 return HAL_ERROR;
743 }
744
745 /* Process Locked */
746 __HAL_LOCK(hfmpi2c);
747
748 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX;
749 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
750
751 /* Enable Address Acknowledge */
752 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
753
754 /* Wait until ADDR flag is set */
755 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
756 {
757 /* Disable Address Acknowledge */
758 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
759 return HAL_TIMEOUT;
760 }
761
762 /* Clear ADDR flag */
763 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
764
765 /* If 10bit addressing mode is selected */
766 if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
767 {
768 /* Wait until ADDR flag is set */
769 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
770 {
771 /* Disable Address Acknowledge */
772 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
773 return HAL_TIMEOUT;
774 }
775
776 /* Clear ADDR flag */
777 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
778 }
779
780 /* Wait until DIR flag is set Transmitter mode */
781 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout) != HAL_OK)
782 {
783 /* Disable Address Acknowledge */
784 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
785 return HAL_TIMEOUT;
786 }
787
788 do
789 {
790 /* Wait until TXIS flag is set */
791 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
792 {
793 /* Disable Address Acknowledge */
794 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
795
796 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
797 {
798 return HAL_ERROR;
799 }
800 else
801 {
802 return HAL_TIMEOUT;
803 }
804 }
805
806 /* Read data from TXDR */
807 hfmpi2c->Instance->TXDR = (*pData++);
808 Size--;
809 }while(Size > 0);
810
811 /* Wait until STOP flag is set */
812 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
813 {
814 /* Disable Address Acknowledge */
815 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
816
817 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
818 {
819 /* Normal use case for Transmitter mode */
820 /* A NACK is generated to confirm the end of transfer */
821 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
822 }
823 else
824 {
825 return HAL_TIMEOUT;
826 }
827 }
828
829 /* Clear STOP flag */
830 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF);
831
832 /* Wait until BUSY flag is reset */
833 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout) != HAL_OK)
834 {
835 /* Disable Address Acknowledge */
836 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
837 return HAL_TIMEOUT;
838 }
839
840 /* Disable Address Acknowledge */
841 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
842
843 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
844
845 /* Process Unlocked */
846 __HAL_UNLOCK(hfmpi2c);
847
848 return HAL_OK;
849 }
850 else
851 {
852 return HAL_BUSY;
853 }
854}
855
856/**
857 * @brief Receive in slave mode an amount of data in blocking mode
858 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
859 * the configuration information for the specified FMPI2C.
860 * @param pData: Pointer to data buffer
861 * @param Size: Amount of data to be sent
862 * @param Timeout: Timeout duration
863 * @retval HAL status
864 */
865HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
866{
867 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
868 {
869 if((pData == NULL ) || (Size == 0))
870 {
871 return HAL_ERROR;
872 }
873
874 /* Process Locked */
875 __HAL_LOCK(hfmpi2c);
876
877 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX;
878 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
879
880 /* Enable Address Acknowledge */
881 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
882
883 /* Wait until ADDR flag is set */
884 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK)
885 {
886 /* Disable Address Acknowledge */
887 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
888 return HAL_TIMEOUT;
889 }
890
891 /* Clear ADDR flag */
892 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
893
894 /* Wait until DIR flag is reset Receiver mode */
895 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout) != HAL_OK)
896 {
897 /* Disable Address Acknowledge */
898 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
899 return HAL_TIMEOUT;
900 }
901
902 while(Size > 0)
903 {
904 /* Wait until RXNE flag is set */
905 if(FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
906 {
907 /* Disable Address Acknowledge */
908 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
909 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT)
910 {
911 return HAL_TIMEOUT;
912 }
913 else
914 {
915 return HAL_ERROR;
916 }
917 }
918
919 /* Read data from RXDR */
920 (*pData++) = hfmpi2c->Instance->RXDR;
921 Size--;
922 }
923
924 /* Wait until STOP flag is set */
925 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
926 {
927 /* Disable Address Acknowledge */
928 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
929
930 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
931 {
932 return HAL_ERROR;
933 }
934 else
935 {
936 return HAL_TIMEOUT;
937 }
938 }
939
940 /* Clear STOP flag */
941 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF);
942
943 /* Wait until BUSY flag is reset */
944 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout) != HAL_OK)
945 {
946 /* Disable Address Acknowledge */
947 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
948 return HAL_TIMEOUT;
949 }
950
951
952 /* Disable Address Acknowledge */
953 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
954
955 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
956
957 /* Process Unlocked */
958 __HAL_UNLOCK(hfmpi2c);
959
960 return HAL_OK;
961 }
962 else
963 {
964 return HAL_BUSY;
965 }
966}
967
968/**
969 * @brief Transmit in master mode an amount of data in no-blocking mode with Interrupt
970 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
971 * the configuration information for the specified FMPI2C.
972 * @param DevAddress: Target device address
973 * @param pData: Pointer to data buffer
974 * @param Size: Amount of data to be sent
975 * @retval HAL status
976 */
977HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
978{
979 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
980 {
981 if((pData == NULL) || (Size == 0))
982 {
983 return HAL_ERROR;
984 }
985
986 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
987 {
988 return HAL_BUSY;
989 }
990
991 /* Process Locked */
992 __HAL_LOCK(hfmpi2c);
993
994 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX;
995 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
996
997 hfmpi2c->pBuffPtr = pData;
998 hfmpi2c->XferCount = Size;
999 if(Size > 255)
1000 {
1001 hfmpi2c->XferSize = 255;
1002 }
1003 else
1004 {
1005 hfmpi2c->XferSize = Size;
1006 }
1007
1008 /* Send Slave Address */
1009 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1010 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1011 {
1012 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
1013 }
1014 else
1015 {
1016 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
1017 }
1018
1019 /* Process Unlocked */
1020 __HAL_UNLOCK(hfmpi2c);
1021
1022 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1023 to avoid the risk of FMPI2C interrupt handle execution before current
1024 process unlock */
1025
1026
1027 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1028 /* possible to enable all of these */
1029 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1030 __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI );
1031
1032 return HAL_OK;
1033 }
1034 else
1035 {
1036 return HAL_BUSY;
1037 }
1038}
1039
1040/**
1041 * @brief Receive in master mode an amount of data in no-blocking mode with Interrupt
1042 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1043 * the configuration information for the specified FMPI2C.
1044 * @param DevAddress: Target device address
1045 * @param pData: Pointer to data buffer
1046 * @param Size: Amount of data to be sent
1047 * @retval HAL status
1048 */
1049HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1050{
1051 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1052 {
1053 if((pData == NULL) || (Size == 0))
1054 {
1055 return HAL_ERROR;
1056 }
1057
1058 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1059 {
1060 return HAL_BUSY;
1061 }
1062
1063 /* Process Locked */
1064 __HAL_LOCK(hfmpi2c);
1065
1066 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX;
1067 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1068
1069 hfmpi2c->pBuffPtr = pData;
1070 hfmpi2c->XferCount = Size;
1071 if(Size > 255)
1072 {
1073 hfmpi2c->XferSize = 255;
1074 }
1075 else
1076 {
1077 hfmpi2c->XferSize = Size;
1078 }
1079
1080 /* Send Slave Address */
1081 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1082 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1083 {
1084 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
1085 }
1086 else
1087 {
1088 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1089 }
1090
1091 /* Process Unlocked */
1092 __HAL_UNLOCK(hfmpi2c);
1093
1094 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1095 to avoid the risk of FMPI2C interrupt handle execution before current
1096 process unlock */
1097
1098 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1099 /* possible to enable all of these */
1100 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1101 __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI );
1102
1103 return HAL_OK;
1104 }
1105 else
1106 {
1107 return HAL_BUSY;
1108 }
1109}
1110
1111/**
1112 * @brief Transmit in slave mode an amount of data in no-blocking mode with Interrupt
1113 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1114 * the configuration information for the specified FMPI2C.
1115 * @param pData: Pointer to data buffer
1116 * @param Size: Amount of data to be sent
1117 * @retval HAL status
1118 */
1119HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1120{
1121 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1122 {
1123 if((pData == NULL) || (Size == 0))
1124 {
1125 return HAL_ERROR;
1126 }
1127
1128 /* Process Locked */
1129 __HAL_LOCK(hfmpi2c);
1130
1131 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_TX;
1132 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1133
1134 /* Enable Address Acknowledge */
1135 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1136
1137 hfmpi2c->pBuffPtr = pData;
1138 hfmpi2c->XferSize = Size;
1139 hfmpi2c->XferCount = Size;
1140
1141 /* Process Unlocked */
1142 __HAL_UNLOCK(hfmpi2c);
1143
1144 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1145 to avoid the risk of FMPI2C interrupt handle execution before current
1146 process unlock */
1147
1148 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1149 /* possible to enable all of these */
1150 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1151 __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_TXI );
1152
1153 return HAL_OK;
1154 }
1155 else
1156 {
1157 return HAL_BUSY;
1158 }
1159}
1160
1161/**
1162 * @brief Receive in slave mode an amount of data in no-blocking mode with Interrupt
1163 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1164 * the configuration information for the specified FMPI2C.
1165 * @param pData: Pointer to data buffer
1166 * @param Size: Amount of data to be sent
1167 * @retval HAL status
1168 */
1169HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1170{
1171 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1172 {
1173 if((pData == NULL) || (Size == 0))
1174 {
1175 return HAL_ERROR;
1176 }
1177
1178 /* Process Locked */
1179 __HAL_LOCK(hfmpi2c);
1180
1181 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX;
1182 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1183
1184 /* Enable Address Acknowledge */
1185 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1186
1187 hfmpi2c->pBuffPtr = pData;
1188 hfmpi2c->XferSize = Size;
1189 hfmpi2c->XferCount = Size;
1190
1191 /* Process Unlocked */
1192 __HAL_UNLOCK(hfmpi2c);
1193
1194 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1195 to avoid the risk of FMPI2C interrupt handle execution before current
1196 process unlock */
1197
1198 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1199 /* possible to enable all of these */
1200 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1201 __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI);
1202
1203 return HAL_OK;
1204 }
1205 else
1206 {
1207 return HAL_BUSY;
1208 }
1209}
1210
1211/**
1212 * @brief Transmit in master mode an amount of data in no-blocking mode with DMA
1213 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1214 * the configuration information for the specified FMPI2C.
1215 * @param DevAddress: Target device address
1216 * @param pData: Pointer to data buffer
1217 * @param Size: Amount of data to be sent
1218 * @retval HAL status
1219 */
1220HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1221{
1222 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1223 {
1224 if((pData == NULL) || (Size == 0))
1225 {
1226 return HAL_ERROR;
1227 }
1228
1229 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1230 {
1231 return HAL_BUSY;
1232 }
1233
1234 /* Process Locked */
1235 __HAL_LOCK(hfmpi2c);
1236
1237 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX;
1238 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1239
1240 hfmpi2c->pBuffPtr = pData;
1241 hfmpi2c->XferCount = Size;
1242 if(Size > 255)
1243 {
1244 hfmpi2c->XferSize = 255;
1245 }
1246 else
1247 {
1248 hfmpi2c->XferSize = Size;
1249 }
1250
1251 /* Set the FMPI2C DMA transfer complete callback */
1252 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt;
1253
1254 /* Set the DMA error callback */
1255 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
1256
1257 /* Enable the DMA channel */
1258 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
1259
1260 /* Send Slave Address */
1261 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1262 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1263 {
1264 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
1265 }
1266 else
1267 {
1268 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE);
1269 }
1270
1271 /* Wait until TXIS flag is set */
1272 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK)
1273 {
1274 /* Disable Address Acknowledge */
1275 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1276
1277 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1278 {
1279 return HAL_ERROR;
1280 }
1281 else
1282 {
1283 return HAL_TIMEOUT;
1284 }
1285 }
1286
1287
1288 /* Enable DMA Request */
1289 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
1290
1291 /* Process Unlocked */
1292 __HAL_UNLOCK(hfmpi2c);
1293
1294 return HAL_OK;
1295 }
1296 else
1297 {
1298 return HAL_BUSY;
1299 }
1300}
1301
1302/**
1303 * @brief Receive in master mode an amount of data in no-blocking mode with DMA
1304 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1305 * the configuration information for the specified FMPI2C.
1306 * @param DevAddress: Target device address
1307 * @param pData: Pointer to data buffer
1308 * @param Size: Amount of data to be sent
1309 * @retval HAL status
1310 */
1311HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
1312{
1313 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1314 {
1315 if((pData == NULL) || (Size == 0))
1316 {
1317 return HAL_ERROR;
1318 }
1319
1320 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1321 {
1322 return HAL_BUSY;
1323 }
1324
1325 /* Process Locked */
1326 __HAL_LOCK(hfmpi2c);
1327
1328 hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX;
1329 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1330
1331 hfmpi2c->pBuffPtr = pData;
1332 hfmpi2c->XferCount = Size;
1333 if(Size > 255)
1334 {
1335 hfmpi2c->XferSize = 255;
1336 }
1337 else
1338 {
1339 hfmpi2c->XferSize = Size;
1340 }
1341
1342 /* Set the FMPI2C DMA transfer complete callback */
1343 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt;
1344
1345 /* Set the DMA error callback */
1346 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
1347
1348 /* Enable the DMA channel */
1349 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
1350
1351 /* Send Slave Address */
1352 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1353 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1354 {
1355 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
1356 }
1357 else
1358 {
1359 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1360 }
1361
1362 /* Wait until RXNE flag is set */
1363 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK)
1364 {
1365 return HAL_TIMEOUT;
1366 }
1367
1368
1369 /* Enable DMA Request */
1370 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
1371
1372 /* Process Unlocked */
1373 __HAL_UNLOCK(hfmpi2c);
1374
1375 return HAL_OK;
1376 }
1377 else
1378 {
1379 return HAL_BUSY;
1380 }
1381}
1382
1383/**
1384 * @brief Transmit in slave mode an amount of data in no-blocking mode with DMA
1385 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1386 * the configuration information for the specified FMPI2C.
1387 * @param pData: Pointer to data buffer
1388 * @param Size: Amount of data to be sent
1389 * @retval HAL status
1390 */
1391HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1392{
1393 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1394 {
1395 if((pData == NULL) || (Size == 0))
1396 {
1397 return HAL_ERROR;
1398 }
1399 /* Process Locked */
1400 __HAL_LOCK(hfmpi2c);
1401
1402 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_TX;
1403 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1404
1405 hfmpi2c->pBuffPtr = pData;
1406 hfmpi2c->XferCount = Size;
1407 hfmpi2c->XferSize = Size;
1408
1409 /* Set the FMPI2C DMA transfer complete callback */
1410 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt;
1411
1412 /* Set the DMA error callback */
1413 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
1414
1415 /* Enable the DMA channel */
1416 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
1417
1418 /* Enable Address Acknowledge */
1419 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1420
1421 /* Wait until ADDR flag is set */
1422 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK)
1423 {
1424 /* Disable Address Acknowledge */
1425 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1426 return HAL_TIMEOUT;
1427 }
1428
1429 /* Clear ADDR flag */
1430 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
1431
1432 /* If 10bits addressing mode is selected */
1433 if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT)
1434 {
1435 /* Wait until ADDR flag is set */
1436 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK)
1437 {
1438 /* Disable Address Acknowledge */
1439 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1440 return HAL_TIMEOUT;
1441 }
1442
1443 /* Clear ADDR flag */
1444 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
1445 }
1446
1447 /* Wait until DIR flag is set Transmitter mode */
1448 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, FMPI2C_TIMEOUT_BUSY) != HAL_OK)
1449 {
1450 /* Disable Address Acknowledge */
1451 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1452 return HAL_TIMEOUT;
1453 }
1454
1455 /* Enable DMA Request */
1456 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
1457
1458 /* Process Unlocked */
1459 __HAL_UNLOCK(hfmpi2c);
1460
1461 return HAL_OK;
1462 }
1463 else
1464 {
1465 return HAL_BUSY;
1466 }
1467}
1468
1469/**
1470 * @brief Receive in slave mode an amount of data in no-blocking mode with DMA
1471 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1472 * the configuration information for the specified FMPI2C.
1473 * @param pData: Pointer to data buffer
1474 * @param Size: Amount of data to be sent
1475 * @retval HAL status
1476 */
1477HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size)
1478{
1479 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1480 {
1481 if((pData == NULL) || (Size == 0))
1482 {
1483 return HAL_ERROR;
1484 }
1485 /* Process Locked */
1486 __HAL_LOCK(hfmpi2c);
1487
1488 hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX;
1489 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1490
1491 hfmpi2c->pBuffPtr = pData;
1492 hfmpi2c->XferSize = Size;
1493 hfmpi2c->XferCount = Size;
1494
1495 /* Set the FMPI2C DMA transfer complete callback */
1496 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt;
1497
1498 /* Set the DMA error callback */
1499 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
1500
1501 /* Enable the DMA channel */
1502 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, Size);
1503
1504 /* Enable Address Acknowledge */
1505 hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1506
1507 /* Wait until ADDR flag is set */
1508 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK)
1509 {
1510 /* Disable Address Acknowledge */
1511 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1512 return HAL_TIMEOUT;
1513 }
1514
1515 /* Clear ADDR flag */
1516 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR);
1517
1518 /* Wait until DIR flag is set Receiver mode */
1519 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, FMPI2C_TIMEOUT_DIR) != HAL_OK)
1520 {
1521 /* Disable Address Acknowledge */
1522 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
1523 return HAL_TIMEOUT;
1524 }
1525
1526 /* Enable DMA Request */
1527 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
1528
1529 /* Process Unlocked */
1530 __HAL_UNLOCK(hfmpi2c);
1531
1532 return HAL_OK;
1533 }
1534 else
1535 {
1536 return HAL_BUSY;
1537 }
1538}
1539/**
1540 * @brief Write an amount of data in blocking mode to a specific memory address
1541 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1542 * the configuration information for the specified FMPI2C.
1543 * @param DevAddress: Target device address
1544 * @param MemAddress: Internal memory address
1545 * @param MemAddSize: Size of internal memory address
1546 * @param pData: Pointer to data buffer
1547 * @param Size: Amount of data to be sent
1548 * @param Timeout: Timeout duration
1549 * @retval HAL status
1550 */
1551HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1552{
1553 uint32_t Sizetmp = 0;
1554
1555 /* Check the parameters */
1556 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1557
1558 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1559 {
1560 if((pData == NULL) || (Size == 0))
1561 {
1562 return HAL_ERROR;
1563 }
1564
1565 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1566 {
1567 return HAL_BUSY;
1568 }
1569
1570 /* Process Locked */
1571 __HAL_LOCK(hfmpi2c);
1572
1573 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX;
1574 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1575
1576 /* Send Slave Address and Memory Address */
1577 if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
1578 {
1579 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1580 {
1581 /* Process Unlocked */
1582 __HAL_UNLOCK(hfmpi2c);
1583 return HAL_ERROR;
1584 }
1585 else
1586 {
1587 /* Process Unlocked */
1588 __HAL_UNLOCK(hfmpi2c);
1589 return HAL_TIMEOUT;
1590 }
1591 }
1592
1593 /* Set NBYTES to write and reload if size > 255 */
1594 /* Size > 255, need to set RELOAD bit */
1595 if(Size > 255)
1596 {
1597 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1598 Sizetmp = 255;
1599 }
1600 else
1601 {
1602 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1603 Sizetmp = Size;
1604 }
1605
1606 do
1607 {
1608 /* Wait until TXIS flag is set */
1609 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
1610 {
1611 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1612 {
1613 return HAL_ERROR;
1614 }
1615 else
1616 {
1617 return HAL_TIMEOUT;
1618 }
1619 }
1620
1621 /* Write data to DR */
1622 hfmpi2c->Instance->TXDR = (*pData++);
1623 Sizetmp--;
1624 Size--;
1625
1626 if((Sizetmp == 0)&&(Size!=0))
1627 {
1628 /* Wait until TCR flag is set */
1629 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
1630 {
1631 return HAL_TIMEOUT;
1632 }
1633
1634
1635 if(Size > 255)
1636 {
1637 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1638 Sizetmp = 255;
1639 }
1640 else
1641 {
1642 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1643 Sizetmp = Size;
1644 }
1645 }
1646
1647 }while(Size > 0);
1648
1649 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1650 /* Wait until STOPF flag is reset */
1651 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
1652 {
1653 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1654 {
1655 return HAL_ERROR;
1656 }
1657 else
1658 {
1659 return HAL_TIMEOUT;
1660 }
1661 }
1662
1663 /* Clear STOP Flag */
1664 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1665
1666 /* Clear Configuration Register 2 */
1667 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
1668
1669 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1670
1671 /* Process Unlocked */
1672 __HAL_UNLOCK(hfmpi2c);
1673
1674 return HAL_OK;
1675 }
1676 else
1677 {
1678 return HAL_BUSY;
1679 }
1680}
1681
1682/**
1683 * @brief Read an amount of data in blocking mode from a specific memory address
1684 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1685 * the configuration information for the specified FMPI2C.
1686 * @param DevAddress: Target device address
1687 * @param MemAddress: Internal memory address
1688 * @param MemAddSize: Size of internal memory address
1689 * @param pData: Pointer to data buffer
1690 * @param Size: Amount of data to be sent
1691 * @param Timeout: Timeout duration
1692 * @retval HAL status
1693 */
1694HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1695{
1696 uint32_t Sizetmp = 0;
1697
1698 /* Check the parameters */
1699 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1700
1701 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1702 {
1703 if((pData == NULL) || (Size == 0))
1704 {
1705 return HAL_ERROR;
1706 }
1707
1708 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1709 {
1710 return HAL_BUSY;
1711 }
1712
1713 /* Process Locked */
1714 __HAL_LOCK(hfmpi2c);
1715
1716 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX;
1717 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1718
1719 /* Send Slave Address and Memory Address */
1720 if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
1721 {
1722 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1723 {
1724 /* Process Unlocked */
1725 __HAL_UNLOCK(hfmpi2c);
1726 return HAL_ERROR;
1727 }
1728 else
1729 {
1730 /* Process Unlocked */
1731 __HAL_UNLOCK(hfmpi2c);
1732 return HAL_TIMEOUT;
1733 }
1734 }
1735
1736 /* Send Slave Address */
1737 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1738 /* Size > 255, need to set RELOAD bit */
1739 if(Size > 255)
1740 {
1741 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
1742 Sizetmp = 255;
1743 }
1744 else
1745 {
1746 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1747 Sizetmp = Size;
1748 }
1749
1750 do
1751 {
1752 /* Wait until RXNE flag is set */
1753 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)
1754 {
1755 return HAL_TIMEOUT;
1756 }
1757
1758 /* Read data from RXDR */
1759 (*pData++) = hfmpi2c->Instance->RXDR;
1760
1761 /* Decrement the Size counter */
1762 Sizetmp--;
1763 Size--;
1764
1765 if((Sizetmp == 0)&&(Size!=0))
1766 {
1767 /* Wait until TCR flag is set */
1768 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
1769 {
1770 return HAL_TIMEOUT;
1771 }
1772
1773 if(Size > 255)
1774 {
1775 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1776 Sizetmp = 255;
1777 }
1778 else
1779 {
1780 FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1781 Sizetmp = Size;
1782 }
1783 }
1784
1785 }while(Size > 0);
1786
1787 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1788 /* Wait until STOPF flag is reset */
1789 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
1790 {
1791 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1792 {
1793 return HAL_ERROR;
1794 }
1795 else
1796 {
1797 return HAL_TIMEOUT;
1798 }
1799 }
1800
1801 /* Clear STOP Flag */
1802 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
1803
1804 /* Clear Configuration Register 2 */
1805 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
1806
1807 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
1808
1809 /* Process Unlocked */
1810 __HAL_UNLOCK(hfmpi2c);
1811
1812 return HAL_OK;
1813 }
1814 else
1815 {
1816 return HAL_BUSY;
1817 }
1818}
1819/**
1820 * @brief Write an amount of data in no-blocking mode with Interrupt to a specific memory address
1821 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1822 * the configuration information for the specified FMPI2C.
1823 * @param DevAddress: Target device address
1824 * @param MemAddress: Internal memory address
1825 * @param MemAddSize: Size of internal memory address
1826 * @param pData: Pointer to data buffer
1827 * @param Size: Amount of data to be sent
1828 * @retval HAL status
1829 */
1830HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
1831{
1832 /* Check the parameters */
1833 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1834
1835 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1836 {
1837 if((pData == NULL) || (Size == 0))
1838 {
1839 return HAL_ERROR;
1840 }
1841
1842 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1843 {
1844 return HAL_BUSY;
1845 }
1846
1847 /* Process Locked */
1848 __HAL_LOCK(hfmpi2c);
1849
1850 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX;
1851 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
1852
1853 hfmpi2c->pBuffPtr = pData;
1854 hfmpi2c->XferCount = Size;
1855 if(Size > 255)
1856 {
1857 hfmpi2c->XferSize = 255;
1858 }
1859 else
1860 {
1861 hfmpi2c->XferSize = Size;
1862 }
1863
1864 /* Send Slave Address and Memory Address */
1865 if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK)
1866 {
1867 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1868 {
1869 /* Process Unlocked */
1870 __HAL_UNLOCK(hfmpi2c);
1871 return HAL_ERROR;
1872 }
1873 else
1874 {
1875 /* Process Unlocked */
1876 __HAL_UNLOCK(hfmpi2c);
1877 return HAL_TIMEOUT;
1878 }
1879 }
1880
1881 /* Set NBYTES to write and reload if size > 255 */
1882 /* Size > 255, need to set RELOAD bit */
1883 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1884 {
1885 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
1886 }
1887 else
1888 {
1889 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
1890 }
1891
1892 /* Process Unlocked */
1893 __HAL_UNLOCK(hfmpi2c);
1894
1895 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1896 to avoid the risk of FMPI2C interrupt handle execution before current
1897 process unlock */
1898
1899 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
1900 /* possible to enable all of these */
1901 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1902 __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI );
1903
1904 return HAL_OK;
1905 }
1906 else
1907 {
1908 return HAL_BUSY;
1909 }
1910}
1911
1912/**
1913 * @brief Read an amount of data in no-blocking mode with Interrupt from a specific memory address
1914 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
1915 * the configuration information for the specified FMPI2C.
1916 * @param DevAddress: Target device address
1917 * @param MemAddress: Internal memory address
1918 * @param MemAddSize: Size of internal memory address
1919 * @param pData: Pointer to data buffer
1920 * @param Size: Amount of data to be sent
1921 * @retval HAL status
1922 */
1923HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
1924{
1925 /* Check the parameters */
1926 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
1927
1928 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
1929 {
1930 if((pData == NULL) || (Size == 0))
1931 {
1932 return HAL_ERROR;
1933 }
1934
1935 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
1936 {
1937 return HAL_BUSY;
1938 }
1939
1940 /* Process Locked */
1941 __HAL_LOCK(hfmpi2c);
1942
1943 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX;
1944
1945 hfmpi2c->pBuffPtr = pData;
1946 hfmpi2c->XferCount = Size;
1947 if(Size > 255)
1948 {
1949 hfmpi2c->XferSize = 255;
1950 }
1951 else
1952 {
1953 hfmpi2c->XferSize = Size;
1954 }
1955
1956 /* Send Slave Address and Memory Address */
1957 if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK)
1958 {
1959 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
1960 {
1961 /* Process Unlocked */
1962 __HAL_UNLOCK(hfmpi2c);
1963 return HAL_ERROR;
1964 }
1965 else
1966 {
1967 /* Process Unlocked */
1968 __HAL_UNLOCK(hfmpi2c);
1969 return HAL_TIMEOUT;
1970 }
1971 }
1972
1973 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
1974 /* Size > 255, need to set RELOAD bit */
1975 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
1976 {
1977 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
1978 }
1979 else
1980 {
1981 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
1982 }
1983
1984 /* Process Unlocked */
1985 __HAL_UNLOCK(hfmpi2c);
1986
1987 /* Note : The FMPI2C interrupts must be enabled after unlocking current process
1988 to avoid the risk of FMPI2C interrupt handle execution before current
1989 process unlock */
1990
1991 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
1992 /* possible to enable all of these */
1993 /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */
1994 __HAL_FMPI2C_ENABLE_IT(hfmpi2c, FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI );
1995
1996 return HAL_OK;
1997 }
1998 else
1999 {
2000 return HAL_BUSY;
2001 }
2002}
2003/**
2004 * @brief Write an amount of data in no-blocking mode with DMA to a specific memory address
2005 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2006 * the configuration information for the specified FMPI2C.
2007 * @param DevAddress: Target device address
2008 * @param MemAddress: Internal memory address
2009 * @param MemAddSize: Size of internal memory address
2010 * @param pData: Pointer to data buffer
2011 * @param Size: Amount of data to be sent
2012 * @retval HAL status
2013 */
2014HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2015{
2016 /* Check the parameters */
2017 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2018
2019 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2020 {
2021 if((pData == NULL) || (Size == 0))
2022 {
2023 return HAL_ERROR;
2024 }
2025
2026 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2027 {
2028 return HAL_BUSY;
2029 }
2030
2031 /* Process Locked */
2032 __HAL_LOCK(hfmpi2c);
2033
2034 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX;
2035 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2036
2037 hfmpi2c->pBuffPtr = pData;
2038 hfmpi2c->XferCount = Size;
2039 if(Size > 255)
2040 {
2041 hfmpi2c->XferSize = 255;
2042 }
2043 else
2044 {
2045 hfmpi2c->XferSize = Size;
2046 }
2047
2048 /* Set the FMPI2C DMA transfer complete callback */
2049 hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMemTransmitCplt;
2050
2051 /* Set the DMA error callback */
2052 hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError;
2053
2054 /* Enable the DMA channel */
2055 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
2056
2057 /* Send Slave Address and Memory Address */
2058 if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK)
2059 {
2060 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2061 {
2062 /* Process Unlocked */
2063 __HAL_UNLOCK(hfmpi2c);
2064 return HAL_ERROR;
2065 }
2066 else
2067 {
2068 /* Process Unlocked */
2069 __HAL_UNLOCK(hfmpi2c);
2070 return HAL_TIMEOUT;
2071 }
2072 }
2073
2074 /* Send Slave Address */
2075 /* Set NBYTES to write and reload if size > 255 */
2076 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
2077 {
2078 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
2079 }
2080 else
2081 {
2082 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
2083 }
2084
2085 /* Wait until TXIS flag is set */
2086 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK)
2087 {
2088 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2089 {
2090 return HAL_ERROR;
2091 }
2092 else
2093 {
2094 return HAL_TIMEOUT;
2095 }
2096 }
2097
2098 /* Enable DMA Request */
2099 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
2100
2101 /* Process Unlocked */
2102 __HAL_UNLOCK(hfmpi2c);
2103
2104 return HAL_OK;
2105 }
2106 else
2107 {
2108 return HAL_BUSY;
2109 }
2110}
2111
2112/**
2113 * @brief Reads an amount of data in no-blocking mode with DMA from a specific memory address.
2114 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2115 * the configuration information for the specified FMPI2C.
2116 * @param DevAddress: Target device address
2117 * @param MemAddress: Internal memory address
2118 * @param MemAddSize: Size of internal memory address
2119 * @param pData: Pointer to data buffer
2120 * @param Size: Amount of data to be read
2121 * @retval HAL status
2122 */
2123HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size)
2124{
2125 /* Check the parameters */
2126 assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize));
2127
2128 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2129 {
2130 if((pData == NULL) || (Size == 0))
2131 {
2132 return HAL_ERROR;
2133 }
2134
2135 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2136 {
2137 return HAL_BUSY;
2138 }
2139
2140 /* Process Locked */
2141 __HAL_LOCK(hfmpi2c);
2142
2143 hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX;
2144
2145 hfmpi2c->pBuffPtr = pData;
2146 hfmpi2c->XferCount = Size;
2147 if(Size > 255)
2148 {
2149 hfmpi2c->XferSize = 255;
2150 }
2151 else
2152 {
2153 hfmpi2c->XferSize = Size;
2154 }
2155
2156 /* Set the FMPI2C DMA transfer complete callback */
2157 hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMemReceiveCplt;
2158
2159 /* Set the DMA error callback */
2160 hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError;
2161
2162 /* Enable the DMA channel */
2163 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize);
2164
2165 /* Send Slave Address and Memory Address */
2166 if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK)
2167 {
2168 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2169 {
2170 /* Process Unlocked */
2171 __HAL_UNLOCK(hfmpi2c);
2172 return HAL_ERROR;
2173 }
2174 else
2175 {
2176 /* Process Unlocked */
2177 __HAL_UNLOCK(hfmpi2c);
2178 return HAL_TIMEOUT;
2179 }
2180 }
2181
2182 /* Set NBYTES to write and reload if size > 255 and generate RESTART */
2183 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
2184 {
2185 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ);
2186 }
2187 else
2188 {
2189 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ);
2190 }
2191
2192 /* Wait until RXNE flag is set */
2193 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK)
2194 {
2195 return HAL_TIMEOUT;
2196 }
2197
2198 /* Enable DMA Request */
2199 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
2200
2201 /* Process Unlocked */
2202 __HAL_UNLOCK(hfmpi2c);
2203
2204 return HAL_OK;
2205 }
2206 else
2207 {
2208 return HAL_BUSY;
2209 }
2210}
2211
2212/**
2213 * @brief Checks if target device is ready for communication.
2214 * @note This function is used with Memory devices
2215 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2216 * the configuration information for the specified FMPI2C.
2217 * @param DevAddress: Target device address
2218 * @param Trials: Number of trials
2219 * @param Timeout: Timeout duration
2220 * @retval HAL status
2221 */
2222HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
2223{
2224 uint32_t tickstart = 0;
2225
2226 __IO uint32_t FMPI2C_Trials = 0;
2227
2228 if(hfmpi2c->State == HAL_FMPI2C_STATE_READY)
2229 {
2230 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET)
2231 {
2232 return HAL_BUSY;
2233 }
2234
2235 /* Process Locked */
2236 __HAL_LOCK(hfmpi2c);
2237
2238 hfmpi2c->State = HAL_FMPI2C_STATE_BUSY;
2239 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
2240
2241 do
2242 {
2243 /* Generate Start */
2244 hfmpi2c->Instance->CR2 = __HAL_FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode,DevAddress);
2245
2246 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
2247 /* Wait until STOPF flag is set or a NACK flag is set*/
2248 tickstart = HAL_GetTick();
2249 while((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) && (hfmpi2c->State != HAL_FMPI2C_STATE_TIMEOUT))
2250 {
2251 if(Timeout != HAL_MAX_DELAY)
2252 {
2253 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
2254 {
2255 /* Device is ready */
2256 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2257 /* Process Unlocked */
2258 __HAL_UNLOCK(hfmpi2c);
2259 return HAL_TIMEOUT;
2260 }
2261 }
2262 }
2263
2264 /* Check if the NACKF flag has not been set */
2265 if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET)
2266 {
2267 /* Wait until STOPF flag is reset */
2268 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
2269 {
2270 return HAL_TIMEOUT;
2271 }
2272
2273 /* Clear STOP Flag */
2274 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2275
2276 /* Device is ready */
2277 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2278
2279 /* Process Unlocked */
2280 __HAL_UNLOCK(hfmpi2c);
2281
2282 return HAL_OK;
2283 }
2284 else
2285 {
2286 /* Wait until STOPF flag is reset */
2287 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
2288 {
2289 return HAL_TIMEOUT;
2290 }
2291
2292 /* Clear NACK Flag */
2293 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2294
2295 /* Clear STOP Flag, auto generated with autoend*/
2296 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2297 }
2298
2299 /* Check if the maximum allowed number of trials has been reached */
2300 if (FMPI2C_Trials++ == Trials)
2301 {
2302 /* Generate Stop */
2303 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
2304
2305 /* Wait until STOPF flag is reset */
2306 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK)
2307 {
2308 return HAL_TIMEOUT;
2309 }
2310
2311 /* Clear STOP Flag */
2312 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2313 }
2314 }while(FMPI2C_Trials < Trials);
2315
2316 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2317
2318 /* Process Unlocked */
2319 __HAL_UNLOCK(hfmpi2c);
2320
2321 return HAL_TIMEOUT;
2322 }
2323 else
2324 {
2325 return HAL_BUSY;
2326 }
2327}
2328
2329/**
2330 * @brief This function handles FMPI2C event interrupt request.
2331 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2332 * the configuration information for the specified FMPI2C.
2333 * @retval None
2334 */
2335void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
2336{
2337 /* FMPI2C in mode Transmitter ---------------------------------------------------*/
2338 if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI | FMPI2C_IT_ADDRI)) == SET))
2339 {
2340 /* Slave mode selected */
2341 if (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX)
2342 {
2343 FMPI2C_SlaveTransmit_ISR(hfmpi2c);
2344 }
2345 }
2346
2347 if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI)) == SET))
2348 {
2349 /* Master mode selected */
2350 if ((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX))
2351 {
2352 FMPI2C_MasterTransmit_ISR(hfmpi2c);
2353 }
2354 }
2355
2356 /* FMPI2C in mode Receiver ----------------------------------------------------*/
2357 if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI | FMPI2C_IT_ADDRI)) == SET))
2358 {
2359 /* Slave mode selected */
2360 if (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX)
2361 {
2362 FMPI2C_SlaveReceive_ISR(hfmpi2c);
2363 }
2364 }
2365 if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI)) == SET))
2366 {
2367 /* Master mode selected */
2368 if ((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX))
2369 {
2370 FMPI2C_MasterReceive_ISR(hfmpi2c);
2371 }
2372 }
2373}
2374
2375/**
2376 * @brief This function handles FMPI2C error interrupt request.
2377 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2378 * the configuration information for the specified FMPI2C.
2379 * @retval None
2380 */
2381void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c)
2382{
2383 /* FMPI2C Bus error interrupt occurred ------------------------------------*/
2384 if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BERR) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET))
2385 {
2386 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR;
2387
2388 /* Clear BERR flag */
2389 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR);
2390 }
2391
2392 /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/
2393 if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_OVR) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET))
2394 {
2395 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR;
2396
2397 /* Clear OVR flag */
2398 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR);
2399 }
2400
2401 /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/
2402 if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET))
2403 {
2404 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO;
2405
2406 /* Clear ARLO flag */
2407 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO);
2408 }
2409
2410 /* Call the Error Callback in case of Error detected */
2411 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
2412 {
2413 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2414
2415 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2416 }
2417}
2418
2419/**
2420 * @brief Master Tx Transfer completed callbacks.
2421 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2422 * the configuration information for the specified FMPI2C.
2423 * @retval None
2424 */
2425 __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2426{
2427 /* NOTE : This function Should not be modified, when the callback is needed,
2428 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2429 */
2430}
2431
2432/**
2433 * @brief Master Rx Transfer completed callbacks.
2434 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2435 * the configuration information for the specified FMPI2C.
2436 * @retval None
2437 */
2438__weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2439{
2440 /* NOTE : This function Should not be modified, when the callback is needed,
2441 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2442 */
2443}
2444
2445/** @brief Slave Tx Transfer completed callbacks.
2446 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2447 * the configuration information for the specified FMPI2C.
2448 * @retval None
2449 */
2450 __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2451{
2452 /* NOTE : This function Should not be modified, when the callback is needed,
2453 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2454 */
2455}
2456
2457/**
2458 * @brief Slave Rx Transfer completed callbacks.
2459 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2460 * the configuration information for the specified FMPI2C.
2461 * @retval None
2462 */
2463__weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2464{
2465 /* NOTE : This function Should not be modified, when the callback is needed,
2466 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2467 */
2468}
2469
2470/**
2471 * @brief Memory Tx Transfer completed callbacks.
2472 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2473 * the configuration information for the specified FMPI2C.
2474 * @retval None
2475 */
2476 __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2477{
2478 /* NOTE : This function Should not be modified, when the callback is needed,
2479 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2480 */
2481}
2482
2483/**
2484 * @brief Memory Rx Transfer completed callbacks.
2485 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2486 * the configuration information for the specified FMPI2C.
2487 * @retval None
2488 */
2489__weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2490{
2491 /* NOTE : This function Should not be modified, when the callback is needed,
2492 the HAL_FMPI2C_TxCpltCallback could be implemented in the user file
2493 */
2494}
2495
2496/**
2497 * @brief FMPI2C error callbacks.
2498 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2499 * the configuration information for the specified FMPI2C.
2500 * @retval None
2501 */
2502 __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c)
2503{
2504 /* NOTE : This function Should not be modified, when the callback is needed,
2505 the HAL_FMPI2C_ErrorCallback could be implemented in the user file
2506 */
2507}
2508
2509/**
2510 * @}
2511 */
2512
2513/** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State and Errors functions
2514 * @brief Peripheral State and Errors functions
2515 *
2516@verbatim
2517 ===============================================================================
2518 ##### Peripheral State and Errors functions #####
2519 ===============================================================================
2520 [..]
2521 This subsection permit to get in run-time the status of the peripheral
2522 and the data flow.
2523
2524@endverbatim
2525 * @{
2526 */
2527
2528/**
2529 * @brief Returns the FMPI2C state.
2530 * @param hfmpi2c : FMPI2C handle
2531 * @retval HAL state
2532 */
2533HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c)
2534{
2535 return hfmpi2c->State;
2536}
2537
2538/**
2539* @brief Return the FMPI2C error code
2540* @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains
2541 * the configuration information for the specified FMPI2C.
2542* @retval FMPI2C Error Code
2543*/
2544uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c)
2545{
2546 return hfmpi2c->ErrorCode;
2547}
2548
2549/**
2550 * @}
2551 */
2552
2553/**
2554 * @brief Handle Interrupt Flags Master Transmit Mode
2555 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2556 * the configuration information for the specified FMPI2C.
2557 * @retval HAL status
2558 */
2559static HAL_StatusTypeDef FMPI2C_MasterTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c)
2560{
2561 uint16_t DevAddress;
2562
2563 /* Process Locked */
2564 __HAL_LOCK(hfmpi2c);
2565
2566 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET)
2567 {
2568 /* Write data to TXDR */
2569 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
2570 hfmpi2c->XferSize--;
2571 hfmpi2c->XferCount--;
2572 }
2573 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET)
2574 {
2575 if((hfmpi2c->XferSize == 0)&&(hfmpi2c->XferCount!=0))
2576 {
2577 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
2578
2579 if(hfmpi2c->XferCount > 255)
2580 {
2581 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
2582 hfmpi2c->XferSize = 255;
2583 }
2584 else
2585 {
2586 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferCount, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
2587 hfmpi2c->XferSize = hfmpi2c->XferCount;
2588 }
2589 }
2590 else
2591 {
2592 /* Process Unlocked */
2593 __HAL_UNLOCK(hfmpi2c);
2594
2595 /* Wrong size Status regarding TCR flag event */
2596 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE;
2597 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2598 }
2599 }
2600 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET)
2601 {
2602 if(hfmpi2c->XferCount == 0)
2603 {
2604 /* Generate Stop */
2605 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
2606 }
2607 else
2608 {
2609 /* Process Unlocked */
2610 __HAL_UNLOCK(hfmpi2c);
2611
2612 /* Wrong size Status regarding TCR flag event */
2613 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE;
2614 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2615 }
2616 }
2617 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
2618 {
2619 /* Disable ERR, TC, STOP, NACK, TXI interrupt */
2620 __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI );
2621
2622 /* Clear STOP Flag */
2623 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2624
2625 /* Clear Configuration Register 2 */
2626 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
2627
2628 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2629
2630 /* Process Unlocked */
2631 __HAL_UNLOCK(hfmpi2c);
2632
2633 if(hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX)
2634 {
2635 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
2636 }
2637 else
2638 {
2639 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
2640 }
2641 }
2642 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
2643 {
2644 /* Clear NACK Flag */
2645 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2646
2647 /* Process Unlocked */
2648 __HAL_UNLOCK(hfmpi2c);
2649
2650 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
2651 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2652 }
2653
2654 /* Process Unlocked */
2655 __HAL_UNLOCK(hfmpi2c);
2656
2657 return HAL_OK;
2658}
2659
2660/**
2661 * @brief Handle Interrupt Flags Master Receive Mode
2662 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2663 * the configuration information for the specified FMPI2C.
2664 * @retval HAL status
2665 */
2666static HAL_StatusTypeDef FMPI2C_MasterReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c)
2667{
2668 uint16_t DevAddress;
2669
2670 /* Process Locked */
2671 __HAL_LOCK(hfmpi2c);
2672
2673 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
2674 {
2675 /* Read data from RXDR */
2676 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
2677 hfmpi2c->XferSize--;
2678 hfmpi2c->XferCount--;
2679 }
2680 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET)
2681 {
2682 if((hfmpi2c->XferSize == 0)&&(hfmpi2c->XferCount!=0))
2683 {
2684 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
2685
2686 if(hfmpi2c->XferCount > 255)
2687 {
2688 FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
2689 hfmpi2c->XferSize = 255;
2690 }
2691 else
2692 {
2693 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferCount, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
2694 hfmpi2c->XferSize = hfmpi2c->XferCount;
2695 }
2696 }
2697 else
2698 {
2699 /* Process Unlocked */
2700 __HAL_UNLOCK(hfmpi2c);
2701
2702 /* Wrong size Status regarding TCR flag event */
2703 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE;
2704 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2705 }
2706 }
2707 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET)
2708 {
2709 if(hfmpi2c->XferCount == 0)
2710 {
2711 /* Generate Stop */
2712 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
2713 }
2714 else
2715 {
2716 /* Process Unlocked */
2717 __HAL_UNLOCK(hfmpi2c);
2718
2719 /* Wrong size Status regarding TCR flag event */
2720 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE;
2721 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2722 }
2723 }
2724 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
2725 {
2726 /* Disable ERR, TC, STOP, NACK, TXI interrupt */
2727 __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI );
2728
2729 /* Clear STOP Flag */
2730 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2731
2732 /* Clear Configuration Register 2 */
2733 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
2734
2735 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2736
2737 /* Process Unlocked */
2738 __HAL_UNLOCK(hfmpi2c);
2739
2740 if(hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX)
2741 {
2742 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
2743 }
2744 else
2745 {
2746 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
2747 }
2748 }
2749 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
2750 {
2751 /* Clear NACK Flag */
2752 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2753
2754 /* Process Unlocked */
2755 __HAL_UNLOCK(hfmpi2c);
2756
2757 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
2758 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2759 }
2760
2761 /* Process Unlocked */
2762 __HAL_UNLOCK(hfmpi2c);
2763
2764 return HAL_OK;
2765
2766}
2767
2768/**
2769 * @brief Handle Interrupt Flags Slave Transmit Mode
2770 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2771 * the configuration information for the specified FMPI2C.
2772 * @retval HAL status
2773 */
2774static HAL_StatusTypeDef FMPI2C_SlaveTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c)
2775{
2776 /* Process locked */
2777 __HAL_LOCK(hfmpi2c);
2778
2779 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) != RESET)
2780 {
2781 /* Check that FMPI2C transfer finished */
2782 /* if yes, normal usecase, a NACK is sent by the MASTER when Transfer is finished */
2783 /* Mean XferCount == 0*/
2784 /* So clear Flag NACKF only */
2785 if(hfmpi2c->XferCount == 0)
2786 {
2787 /* Clear NACK Flag */
2788 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2789
2790 /* Process Unlocked */
2791 __HAL_UNLOCK(hfmpi2c);
2792 }
2793 else
2794 {
2795 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the MASTER*/
2796 /* Clear NACK Flag */
2797 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2798
2799 /* Set ErrorCode corresponding to a Non-Acknowledge */
2800 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
2801
2802 /* Process Unlocked */
2803 __HAL_UNLOCK(hfmpi2c);
2804
2805 /* Call the Error callback to prevent upper layer */
2806 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2807 }
2808 }
2809 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)
2810 {
2811 /* Clear ADDR flag */
2812 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
2813 }
2814 /* Check first if STOPF is set */
2815 /* to prevent a Write Data in TX buffer */
2816 /* which is stuck in TXDR until next */
2817 /* communication with Master */
2818 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
2819 {
2820 /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */
2821 __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI );
2822
2823 /* Disable Address Acknowledge */
2824 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
2825
2826 /* Clear STOP Flag */
2827 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2828
2829 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2830
2831 /* Process Unlocked */
2832 __HAL_UNLOCK(hfmpi2c);
2833
2834 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
2835 }
2836 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET)
2837 {
2838 /* Write data to TXDR only if XferCount not reach "0" */
2839 /* A TXIS flag can be set, during STOP treatment */
2840 if(hfmpi2c->XferCount > 0)
2841 {
2842 /* Write data to TXDR */
2843 hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++);
2844 hfmpi2c->XferCount--;
2845 }
2846 }
2847
2848 /* Process Unlocked */
2849 __HAL_UNLOCK(hfmpi2c);
2850
2851 return HAL_OK;
2852}
2853
2854/**
2855 * @brief Handle Interrupt Flags Slave Receive Mode
2856 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2857 * the configuration information for the specified FMPI2C.
2858 * @retval HAL status
2859 */
2860static HAL_StatusTypeDef FMPI2C_SlaveReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c)
2861{
2862 /* Process Locked */
2863 __HAL_LOCK(hfmpi2c);
2864
2865 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) != RESET)
2866 {
2867 /* Clear NACK Flag */
2868 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
2869
2870 /* Process Unlocked */
2871 __HAL_UNLOCK(hfmpi2c);
2872
2873 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
2874 HAL_FMPI2C_ErrorCallback(hfmpi2c);
2875 }
2876 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)
2877 {
2878 /* Clear ADDR flag */
2879 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR);
2880 }
2881 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET)
2882 {
2883 /* Read data from RXDR */
2884 (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR;
2885 hfmpi2c->XferSize--;
2886 hfmpi2c->XferCount--;
2887 }
2888 else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
2889 {
2890 /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */
2891 __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_RXI );
2892
2893 /* Disable Address Acknowledge */
2894 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
2895
2896 /* Clear STOP Flag */
2897 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
2898
2899 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
2900
2901 /* Process Unlocked */
2902 __HAL_UNLOCK(hfmpi2c);
2903
2904 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
2905 }
2906
2907 /* Process Unlocked */
2908 __HAL_UNLOCK(hfmpi2c);
2909
2910 return HAL_OK;
2911}
2912
2913/**
2914 * @brief Master sends target device address followed by internal memory address for write request.
2915 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2916 * the configuration information for the specified FMPI2C.
2917 * @param DevAddress: Target device address
2918 * @param MemAddress: Internal memory address
2919 * @param MemAddSize: Size of internal memory address
2920 * @param Timeout: Timeout duration
2921 * @retval HAL status
2922 */
2923static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout)
2924{
2925 FMPI2C_TransferConfig(hfmpi2c,DevAddress,MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE);
2926
2927 /* Wait until TXIS flag is set */
2928 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
2929 {
2930 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2931 {
2932 return HAL_ERROR;
2933 }
2934 else
2935 {
2936 return HAL_TIMEOUT;
2937 }
2938 }
2939
2940 /* If Memory address size is 8Bit */
2941 if(MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
2942 {
2943 /* Send Memory Address */
2944 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress);
2945 }
2946 /* If Memory address size is 16Bit */
2947 else
2948 {
2949 /* Send MSB of Memory Address */
2950 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_MSB(MemAddress);
2951
2952 /* Wait until TXIS flag is set */
2953 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
2954 {
2955 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2956 {
2957 return HAL_ERROR;
2958 }
2959 else
2960 {
2961 return HAL_TIMEOUT;
2962 }
2963 }
2964
2965 /* Send LSB of Memory Address */
2966 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress);
2967 }
2968
2969 /* Wait until TCR flag is set */
2970 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK)
2971 {
2972 return HAL_TIMEOUT;
2973 }
2974
2975return HAL_OK;
2976}
2977
2978/**
2979 * @brief Master sends target device address followed by internal memory address for read request.
2980 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
2981 * the configuration information for the specified FMPI2C.
2982 * @param DevAddress: Target device address
2983 * @param MemAddress: Internal memory address
2984 * @param MemAddSize: Size of internal memory address
2985 * @param Timeout: Timeout duration
2986 * @retval HAL status
2987 */
2988static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout)
2989{
2990 FMPI2C_TransferConfig(hfmpi2c,DevAddress,MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE);
2991
2992 /* Wait until TXIS flag is set */
2993 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
2994 {
2995 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
2996 {
2997 return HAL_ERROR;
2998 }
2999 else
3000 {
3001 return HAL_TIMEOUT;
3002 }
3003 }
3004
3005 /* If Memory address size is 8Bit */
3006 if(MemAddSize == FMPI2C_MEMADD_SIZE_8BIT)
3007 {
3008 /* Send Memory Address */
3009 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress);
3010 }
3011 /* If Mememory address size is 16Bit */
3012 else
3013 {
3014 /* Send MSB of Memory Address */
3015 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_MSB(MemAddress);
3016
3017 /* Wait until TXIS flag is set */
3018 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK)
3019 {
3020 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3021 {
3022 return HAL_ERROR;
3023 }
3024 else
3025 {
3026 return HAL_TIMEOUT;
3027 }
3028 }
3029
3030 /* Send LSB of Memory Address */
3031 hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress);
3032 }
3033
3034 /* Wait until TC flag is set */
3035 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout) != HAL_OK)
3036 {
3037 return HAL_TIMEOUT;
3038 }
3039
3040 return HAL_OK;
3041}
3042
3043
3044/**
3045 * @brief DMA FMPI2C master transmit process complete callback.
3046 * @param hdma: DMA handle
3047 * @retval None
3048 */
3049static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma)
3050{
3051 uint16_t DevAddress;
3052 FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
3053
3054 /* Check if last DMA request was done with RELOAD */
3055 /* Set NBYTES to write and reload if size > 255 */
3056 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3057 {
3058 /* Wait until TCR flag is set */
3059 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK)
3060 {
3061 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3062 }
3063
3064 /* Disable DMA Request */
3065 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3066
3067 /* Check if Errors has been detected during transfer */
3068 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3069 {
3070 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3071 /* Wait until STOPF flag is reset */
3072 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3073 {
3074 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3075 {
3076 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3077 }
3078 else
3079 {
3080 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3081 }
3082 }
3083
3084 /* Clear STOP Flag */
3085 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3086
3087 /* Clear Configuration Register 2 */
3088 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3089
3090 hfmpi2c->XferCount = 0;
3091
3092 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3093 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3094 }
3095 else
3096 {
3097 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
3098 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3099 if(hfmpi2c->XferCount > 255)
3100 {
3101 hfmpi2c->XferSize = 255;
3102 }
3103 else
3104 {
3105 hfmpi2c->XferSize = hfmpi2c->XferCount;
3106 }
3107
3108 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3109
3110 /* Enable the DMA channel */
3111 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
3112
3113 /* Send Slave Address */
3114 /* Set NBYTES to write and reload if size > 255 */
3115 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3116 {
3117 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
3118 }
3119 else
3120 {
3121 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
3122 }
3123
3124 /* Wait until TXIS flag is set */
3125 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK)
3126 {
3127 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3128 /* Wait until STOPF flag is reset */
3129 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3130 {
3131 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3132 {
3133 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3134 }
3135 else
3136 {
3137 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3138 }
3139 }
3140
3141 /* Clear STOP Flag */
3142 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3143
3144 /* Clear Configuration Register 2 */
3145 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3146
3147 hfmpi2c->XferCount = 0;
3148
3149 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3150 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3151 }
3152 else
3153 {
3154 /* Enable DMA Request */
3155 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
3156 }
3157 }
3158 }
3159 else
3160 {
3161 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3162 /* Wait until STOPF flag is reset */
3163 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3164 {
3165 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3166 {
3167 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3168 }
3169 else
3170 {
3171 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3172 }
3173 }
3174
3175 /* Clear STOP Flag */
3176 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3177
3178 /* Clear Configuration Register 2 */
3179 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3180
3181 /* Disable DMA Request */
3182 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3183
3184 hfmpi2c->XferCount = 0;
3185
3186 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3187
3188 /* Check if Errors has been detected during transfer */
3189 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3190 {
3191 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3192 }
3193 else
3194 {
3195 HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c);
3196 }
3197 }
3198}
3199
3200/**
3201 * @brief DMA FMPI2C slave transmit process complete callback.
3202 * @param hdma: DMA handle
3203 * @retval None
3204 */
3205static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma)
3206{
3207 FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
3208
3209 /* Wait until STOP flag is set */
3210 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3211 {
3212 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3213 {
3214 /* Normal Use case, a AF is generated by master */
3215 /* to inform slave the end of transfer */
3216 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3217 }
3218 else
3219 {
3220 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3221 }
3222 }
3223
3224 /* Clear STOP flag */
3225 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF);
3226
3227 /* Wait until BUSY flag is reset */
3228 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY) != HAL_OK)
3229 {
3230 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3231 }
3232
3233 /* Disable DMA Request */
3234 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3235
3236 hfmpi2c->XferCount = 0;
3237
3238 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3239
3240 /* Check if Errors has been detected during transfer */
3241 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3242 {
3243 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3244 }
3245 else
3246 {
3247 HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c);
3248 }
3249}
3250
3251/**
3252 * @brief DMA FMPI2C master receive process complete callback
3253 * @param hdma: DMA handle
3254 * @retval None
3255 */
3256static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
3257{
3258 FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
3259 uint16_t DevAddress;
3260
3261 /* Check if last DMA request was done with RELOAD */
3262 /* Set NBYTES to write and reload if size > 255 */
3263 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3264 {
3265 /* Wait until TCR flag is set */
3266 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK)
3267 {
3268 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3269 }
3270
3271 /* Disable DMA Request */
3272 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3273
3274 /* Check if Errors has been detected during transfer */
3275 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3276 {
3277 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3278 /* Wait until STOPF flag is reset */
3279 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3280 {
3281 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3282 {
3283 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3284 }
3285 else
3286 {
3287 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3288 }
3289 }
3290
3291 /* Clear STOP Flag */
3292 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3293
3294 /* Clear Configuration Register 2 */
3295 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3296
3297 hfmpi2c->XferCount = 0;
3298
3299 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3300 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3301 }
3302 else
3303 {
3304 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
3305 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3306 if(hfmpi2c->XferCount > 255)
3307 {
3308 hfmpi2c->XferSize = 255;
3309 }
3310 else
3311 {
3312 hfmpi2c->XferSize = hfmpi2c->XferCount;
3313 }
3314
3315 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3316
3317 /* Enable the DMA channel */
3318 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize);
3319
3320 /* Send Slave Address */
3321 /* Set NBYTES to write and reload if size > 255 */
3322 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3323 {
3324 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
3325 }
3326 else
3327 {
3328 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
3329 }
3330
3331 /* Wait until RXNE flag is set */
3332 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK)
3333 {
3334 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3335 }
3336
3337 /* Check if Errors has been detected during transfer */
3338 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3339 {
3340 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3341 /* Wait until STOPF flag is reset */
3342 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3343 {
3344 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3345 {
3346 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3347 }
3348 else
3349 {
3350 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3351 }
3352 }
3353
3354 /* Clear STOP Flag */
3355 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3356
3357 /* Clear Configuration Register 2 */
3358 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3359
3360 hfmpi2c->XferCount = 0;
3361
3362 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3363
3364 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3365 }
3366 else
3367 {
3368 /* Enable DMA Request */
3369 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3370 }
3371 }
3372 }
3373 else
3374 {
3375 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3376 /* Wait until STOPF flag is reset */
3377 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3378 {
3379 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3380 {
3381 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3382 }
3383 else
3384 {
3385 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3386 }
3387 }
3388
3389 /* Clear STOP Flag */
3390 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3391
3392 /* Clear Configuration Register 2 */
3393 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3394
3395 /* Disable DMA Request */
3396 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3397
3398 hfmpi2c->XferCount = 0;
3399
3400 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3401
3402 /* Check if Errors has been detected during transfer */
3403 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3404 {
3405 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3406 }
3407 else
3408 {
3409 HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c);
3410 }
3411 }
3412}
3413
3414/**
3415 * @brief DMA FMPI2C slave receive process complete callback.
3416 * @param hdma: DMA handle
3417 * @retval None
3418 */
3419static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma)
3420{
3421 FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
3422
3423 /* Wait until STOPF flag is reset */
3424 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3425 {
3426 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3427 {
3428 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3429 }
3430 else
3431 {
3432 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3433 }
3434 }
3435
3436 /* Clear STOPF flag */
3437 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3438
3439 /* Wait until BUSY flag is reset */
3440 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY) != HAL_OK)
3441 {
3442 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3443 }
3444
3445 /* Disable DMA Request */
3446 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3447
3448 /* Disable Address Acknowledge */
3449 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
3450
3451 hfmpi2c->XferCount = 0;
3452
3453 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3454
3455 /* Check if Errors has been detected during transfer */
3456 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3457 {
3458 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3459 }
3460 else
3461 {
3462 HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c);
3463 }
3464}
3465
3466/**
3467 * @brief DMA FMPI2C Memory Write process complete callback
3468 * @param hdma : DMA handle
3469 * @retval None
3470 */
3471static void FMPI2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma)
3472{
3473 uint16_t DevAddress;
3474 FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
3475
3476 /* Check if last DMA request was done with RELOAD */
3477 /* Set NBYTES to write and reload if size > 255 */
3478 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3479 {
3480 /* Wait until TCR flag is set */
3481 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK)
3482 {
3483 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3484 }
3485
3486 /* Disable DMA Request */
3487 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3488
3489 /* Check if Errors has been detected during transfer */
3490 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3491 {
3492 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3493 /* Wait until STOPF flag is reset */
3494 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3495 {
3496 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3497 {
3498 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3499 }
3500 else
3501 {
3502 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3503 }
3504 }
3505
3506 /* Clear STOP Flag */
3507 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3508
3509 /* Clear Configuration Register 2 */
3510 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3511
3512 hfmpi2c->XferCount = 0;
3513
3514 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3515 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3516 }
3517 else
3518 {
3519 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
3520 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3521 if(hfmpi2c->XferCount > 255)
3522 {
3523 hfmpi2c->XferSize = 255;
3524 }
3525 else
3526 {
3527 hfmpi2c->XferSize = hfmpi2c->XferCount;
3528 }
3529
3530 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3531
3532 /* Enable the DMA channel */
3533 HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize);
3534
3535 /* Send Slave Address */
3536 /* Set NBYTES to write and reload if size > 255 */
3537 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3538 {
3539 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
3540 }
3541 else
3542 {
3543 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
3544 }
3545
3546 /* Wait until TXIS flag is set */
3547 if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK)
3548 {
3549 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3550 /* Wait until STOPF flag is reset */
3551 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3552 {
3553 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3554 {
3555 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3556 }
3557 else
3558 {
3559 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3560 }
3561 }
3562
3563 /* Clear STOP Flag */
3564 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3565
3566 /* Clear Configuration Register 2 */
3567 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3568
3569 hfmpi2c->XferCount = 0;
3570
3571 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3572 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3573 }
3574 else
3575 {
3576 /* Enable DMA Request */
3577 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN;
3578 }
3579 }
3580 }
3581 else
3582 {
3583 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3584 /* Wait until STOPF flag is reset */
3585 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3586 {
3587 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3588 {
3589 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3590 }
3591 else
3592 {
3593 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3594 }
3595 }
3596
3597 /* Clear STOP Flag */
3598 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3599
3600 /* Clear Configuration Register 2 */
3601 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3602
3603 /* Disable DMA Request */
3604 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN;
3605
3606 hfmpi2c->XferCount = 0;
3607
3608 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3609
3610 /* Check if Errors has been detected during transfer */
3611 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3612 {
3613 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3614 }
3615 else
3616 {
3617 HAL_FMPI2C_MemTxCpltCallback(hfmpi2c);
3618 }
3619 }
3620}
3621
3622/**
3623 * @brief DMA FMPI2C Memory Read process complete callback
3624 * @param hdma: DMA handle
3625 * @retval None
3626 */
3627static void FMPI2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma)
3628{
3629 FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
3630 uint16_t DevAddress;
3631
3632 /* Check if last DMA request was done with RELOAD */
3633 /* Set NBYTES to write and reload if size > 255 */
3634 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3635 {
3636 /* Wait until TCR flag is set */
3637 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK)
3638 {
3639 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3640 }
3641
3642 /* Disable DMA Request */
3643 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3644
3645 /* Check if Errors has been detected during transfer */
3646 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3647 {
3648 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3649 /* Wait until STOPF flag is reset */
3650 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3651 {
3652 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3653 {
3654 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3655 }
3656 else
3657 {
3658 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3659 }
3660 }
3661
3662 /* Clear STOP Flag */
3663 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3664
3665 /* Clear Configuration Register 2 */
3666 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3667
3668 hfmpi2c->XferCount = 0;
3669
3670 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3671 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3672 }
3673 else
3674 {
3675 hfmpi2c->pBuffPtr += hfmpi2c->XferSize;
3676 hfmpi2c->XferCount -= hfmpi2c->XferSize;
3677 if(hfmpi2c->XferCount > 255)
3678 {
3679 hfmpi2c->XferSize = 255;
3680 }
3681 else
3682 {
3683 hfmpi2c->XferSize = hfmpi2c->XferCount;
3684 }
3685
3686 DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD);
3687
3688 /* Enable the DMA channel */
3689 HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize);
3690
3691 /* Send Slave Address */
3692 /* Set NBYTES to write and reload if size > 255 */
3693 if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) )
3694 {
3695 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP);
3696 }
3697 else
3698 {
3699 FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP);
3700 }
3701
3702 /* Wait until RXNE flag is set */
3703 if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK)
3704 {
3705 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3706 }
3707
3708 /* Check if Errors has been detected during transfer */
3709 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3710 {
3711 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3712 /* Wait until STOPF flag is reset */
3713 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3714 {
3715 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3716 {
3717 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3718 }
3719 else
3720 {
3721 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3722 }
3723 }
3724
3725 /* Clear STOP Flag */
3726 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3727
3728 /* Clear Configuration Register 2 */
3729 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3730
3731 hfmpi2c->XferCount = 0;
3732
3733 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3734 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3735 }
3736 else
3737 {
3738 /* Enable DMA Request */
3739 hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN;
3740 }
3741 }
3742 }
3743 else
3744 {
3745 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
3746 /* Wait until STOPF flag is reset */
3747 if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK)
3748 {
3749 if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF)
3750 {
3751 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF;
3752 }
3753 else
3754 {
3755 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3756 }
3757 }
3758
3759 /* Clear STOP Flag */
3760 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3761
3762 /* Clear Configuration Register 2 */
3763 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3764
3765 /* Disable DMA Request */
3766 hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN;
3767
3768 hfmpi2c->XferCount = 0;
3769
3770 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3771
3772 /* Check if Errors has been detected during transfer */
3773 if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE)
3774 {
3775 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3776 }
3777 else
3778 {
3779 HAL_FMPI2C_MemRxCpltCallback(hfmpi2c);
3780 }
3781 }
3782}
3783
3784/**
3785 * @brief DMA FMPI2C communication error callback.
3786 * @param hdma : DMA handle
3787 * @retval None
3788 */
3789static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma)
3790{
3791 FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
3792
3793 /* Disable Acknowledge */
3794 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK;
3795
3796 hfmpi2c->XferCount = 0;
3797
3798 hfmpi2c->State = HAL_FMPI2C_STATE_READY;
3799
3800 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA;
3801
3802 HAL_FMPI2C_ErrorCallback(hfmpi2c);
3803}
3804
3805/**
3806 * @brief This function handles FMPI2C Communication Timeout.
3807 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
3808 * the configuration information for the specified FMPI2C.
3809 * @param Flag: specifies the FMPI2C flag to check.
3810 * @param Status: The new Flag status (SET or RESET).
3811 * @param Timeout: Timeout duration
3812 * @retval HAL status
3813 */
3814static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
3815{
3816 uint32_t tickstart = HAL_GetTick();
3817
3818 /* Wait until flag is set */
3819 if(Status == RESET)
3820 {
3821 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == RESET)
3822 {
3823 /* Check for the Timeout */
3824 if(Timeout != HAL_MAX_DELAY)
3825 {
3826 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
3827 {
3828 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3829 /* Process Unlocked */
3830 __HAL_UNLOCK(hfmpi2c);
3831 return HAL_TIMEOUT;
3832 }
3833 }
3834 }
3835 }
3836 else
3837 {
3838 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) != RESET)
3839 {
3840 /* Check for the Timeout */
3841 if(Timeout != HAL_MAX_DELAY)
3842 {
3843 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
3844 {
3845 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3846 /* Process Unlocked */
3847 __HAL_UNLOCK(hfmpi2c);
3848 return HAL_TIMEOUT;
3849 }
3850 }
3851 }
3852 }
3853 return HAL_OK;
3854}
3855
3856/**
3857 * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag.
3858 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
3859 * the configuration information for the specified FMPI2C.
3860 * @param Timeout: Timeout duration
3861 * @retval HAL status
3862 */
3863static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout)
3864{
3865 uint32_t tickstart = HAL_GetTick();
3866
3867 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET)
3868 {
3869 /* Check if a NACK is detected */
3870 if(FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout) != HAL_OK)
3871 {
3872 return HAL_ERROR;
3873 }
3874
3875 /* Check for the Timeout */
3876 if(Timeout != HAL_MAX_DELAY)
3877 {
3878 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
3879 {
3880 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3881 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3882
3883 /* Process Unlocked */
3884 __HAL_UNLOCK(hfmpi2c);
3885
3886 return HAL_TIMEOUT;
3887 }
3888 }
3889 }
3890 return HAL_OK;
3891}
3892
3893/**
3894 * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag.
3895 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
3896 * the configuration information for the specified FMPI2C.
3897 * @param Timeout: Timeout duration
3898 * @retval HAL status
3899 */
3900static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout)
3901{
3902 uint32_t tickstart = 0x00;
3903 tickstart = HAL_GetTick();
3904
3905 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
3906 {
3907 /* Check if a NACK is detected */
3908 if(FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout) != HAL_OK)
3909 {
3910 return HAL_ERROR;
3911 }
3912
3913 /* Check for the Timeout */
3914 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
3915 {
3916 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3917 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3918
3919 /* Process Unlocked */
3920 __HAL_UNLOCK(hfmpi2c);
3921
3922 return HAL_TIMEOUT;
3923 }
3924 }
3925 return HAL_OK;
3926}
3927
3928/**
3929 * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag.
3930 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
3931 * the configuration information for the specified FMPI2C.
3932 * @param Timeout: Timeout duration
3933 * @retval HAL status
3934 */
3935static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout)
3936{
3937 uint32_t tickstart = 0x00;
3938 tickstart = HAL_GetTick();
3939
3940 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET)
3941 {
3942 /* Check if a STOPF is detected */
3943 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET)
3944 {
3945 /* Clear STOP Flag */
3946 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
3947
3948 /* Clear Configuration Register 2 */
3949 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
3950
3951 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE;
3952 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3953
3954 /* Process Unlocked */
3955 __HAL_UNLOCK(hfmpi2c);
3956
3957 return HAL_ERROR;
3958 }
3959
3960 /* Check for the Timeout */
3961 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
3962 {
3963 hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT;
3964 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
3965
3966 /* Process Unlocked */
3967 __HAL_UNLOCK(hfmpi2c);
3968
3969 return HAL_TIMEOUT;
3970 }
3971 }
3972 return HAL_OK;
3973}
3974
3975/**
3976 * @brief This function handles Acknowledge failed detection during an FMPI2C Communication.
3977 * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains
3978 * the configuration information for the specified FMPI2C.
3979 * @param Timeout: Timeout duration
3980 * @retval HAL status
3981 */
3982static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout)
3983{
3984 uint32_t tickstart = 0x00;
3985 tickstart = HAL_GetTick();
3986
3987 if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)
3988 {
3989 /* Generate stop if necessary only in case of FMPI2C peripheral in MASTER mode */
3990 if((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX)
3991 || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX))
3992 {
3993 /* No need to generate the STOP condition if AUTOEND mode is enabled */
3994 /* Generate the STOP condition only in case of SOFTEND mode is enabled */
3995 if((hfmpi2c->Instance->CR2 & FMPI2C_AUTOEND_MODE) != FMPI2C_AUTOEND_MODE)
3996 {
3997 /* Generate Stop */
3998 hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP;
3999 }
4000 }
4001
4002 /* Wait until STOP Flag is reset */
4003 /* AutoEnd should be initiate after AF */
4004 while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET)
4005 {
4006 /* Check for the Timeout */
4007 if(Timeout != HAL_MAX_DELAY)
4008 {
4009 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
4010 {
4011 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
4012 /* Process Unlocked */
4013 __HAL_UNLOCK(hfmpi2c);
4014 return HAL_TIMEOUT;
4015 }
4016 }
4017 }
4018
4019 /* Clear NACKF Flag */
4020 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF);
4021
4022 /* Clear STOP Flag */
4023 __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF);
4024
4025 /* Clear Configuration Register 2 */
4026 __HAL_FMPI2C_RESET_CR2(hfmpi2c);
4027
4028 hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF;
4029 hfmpi2c->State= HAL_FMPI2C_STATE_READY;
4030
4031 /* Process Unlocked */
4032 __HAL_UNLOCK(hfmpi2c);
4033
4034 return HAL_ERROR;
4035 }
4036 return HAL_OK;
4037}
4038
4039/**
4040 * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set).
4041 * @param hfmpi2c: FMPI2C handle.
4042 * @param DevAddress: specifies the slave address to be programmed.
4043 * @param Size: specifies the number of bytes to be programmed.
4044 * This parameter must be a value between 0 and 255.
4045 * @param Mode: new state of the FMPI2C START condition generation.
4046 * This parameter can be one of the following values:
4047 * @arg FMPI2C_RELOAD_MODE: Enable Reload mode .
4048 * @arg FMPI2C_AUTOEND_MODE: Enable Automatic end mode.
4049 * @arg FMPI2C_SOFTEND_MODE: Enable Software end mode.
4050 * @param Request: new state of the FMPI2C START condition generation.
4051 * This parameter can be one of the following values:
4052 * @arg FMPI2C_NO_STARTSTOP: Don't Generate stop and start condition.
4053 * @arg FMPI2C_GENERATE_STOP: Generate stop condition (Size should be set to 0).
4054 * @arg FMPI2C_GENERATE_START_READ: Generate Restart for read request.
4055 * @arg FMPI2C_GENERATE_START_WRITE: Generate Restart for write request.
4056 * @retval None
4057 */
4058static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request)
4059{
4060 uint32_t tmpreg = 0;
4061
4062 /* Check the parameters */
4063 assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance));
4064 assert_param(IS_TRANSFER_MODE(Mode));
4065 assert_param(IS_TRANSFER_REQUEST(Request));
4066
4067 /* Get the CR2 register value */
4068 tmpreg = hfmpi2c->Instance->CR2;
4069
4070 /* clear tmpreg specific bits */
4071 tmpreg &= (uint32_t)~((uint32_t)(FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | FMPI2C_CR2_RD_WRN | FMPI2C_CR2_START | FMPI2C_CR2_STOP));
4072
4073 /* update tmpreg */
4074 tmpreg |= (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << 16 ) & FMPI2C_CR2_NBYTES) | \
4075 (uint32_t)Mode | (uint32_t)Request);
4076
4077 /* update CR2 register */
4078 hfmpi2c->Instance->CR2 = tmpreg;
4079}
4080
4081/**
4082 * @}
4083 */
4084
4085/**
4086 * @}
4087 */
4088#endif /* STM32F410xx || STM32F446xx */
4089#endif /* HAL_FMPI2C_MODULE_ENABLED */
4090/**
4091 * @}
4092 */
4093
4094/**
4095 * @}
4096 */
4097
4098/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.