1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_fmpsmbus.c
4 * @author MCD Application Team
5 * @brief FMPSMBUS HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the System Management Bus (SMBus) peripheral,
8 * based on I2C principles of operation :
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral State and Errors functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2016 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 The FMPSMBUS HAL driver can be used as follows:
30
31 (#) Declare a FMPSMBUS_HandleTypeDef handle structure, for example:
32 FMPSMBUS_HandleTypeDef hfmpsmbus;
33
34 (#)Initialize the FMPSMBUS low level resources by implementing the HAL_FMPSMBUS_MspInit() API:
35 (##) Enable the FMPSMBUSx interface clock
36 (##) FMPSMBUS pins configuration
37 (+++) Enable the clock for the FMPSMBUS GPIOs
38 (+++) Configure FMPSMBUS pins as alternate function open-drain
39 (##) NVIC configuration if you need to use interrupt process
40 (+++) Configure the FMPSMBUSx interrupt priority
41 (+++) Enable the NVIC FMPSMBUS IRQ Channel
42
43 (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
44 Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
45 Peripheral mode and Packet Error Check mode in the hfmpsmbus Init structure.
46
47 (#) Initialize the FMPSMBUS registers by calling the HAL_FMPSMBUS_Init() API:
48 (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
49 by calling the customized HAL_FMPSMBUS_MspInit(&hfmpsmbus) API.
50
51 (#) To check if target device is ready for communication, use the function HAL_FMPSMBUS_IsDeviceReady()
52
53 (#) For FMPSMBUS IO operations, only one mode of operations is available within this driver
54
55 *** Interrupt mode IO operation ***
56 ===================================
57 [..]
58 (+) Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode
59 using HAL_FMPSMBUS_Master_Transmit_IT()
60 (++) At transmission end of transfer HAL_FMPSMBUS_MasterTxCpltCallback() is executed and users can
61 add their own code by customization of function pointer HAL_FMPSMBUS_MasterTxCpltCallback()
62 (+) Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode
63 using HAL_FMPSMBUS_Master_Receive_IT()
64 (++) At reception end of transfer HAL_FMPSMBUS_MasterRxCpltCallback() is executed and users can
65 add their own code by customization of function pointer HAL_FMPSMBUS_MasterRxCpltCallback()
66 (+) Abort a master/host FMPSMBUS process communication with Interrupt using HAL_FMPSMBUS_Master_Abort_IT()
67 (++) The associated previous transfer callback is called at the end of abort process
68 (++) mean HAL_FMPSMBUS_MasterTxCpltCallback() in case of previous state was master transmit
69 (++) mean HAL_FMPSMBUS_MasterRxCpltCallback() in case of previous state was master receive
70 (+) Enable/disable the Address listen mode in slave/device or host/slave FMPSMBUS mode
71 using HAL_FMPSMBUS_EnableListen_IT() HAL_FMPSMBUS_DisableListen_IT()
72 (++) When address slave/device FMPSMBUS match, HAL_FMPSMBUS_AddrCallback() is executed and users can
73 add their own code to check the Address Match Code and the transmission direction
74 request by master/host (Write/Read).
75 (++) At Listen mode end HAL_FMPSMBUS_ListenCpltCallback() is executed and users can
76 add their own code by customization of function pointer HAL_FMPSMBUS_ListenCpltCallback()
77 (+) Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode
78 using HAL_FMPSMBUS_Slave_Transmit_IT()
79 (++) At transmission end of transfer HAL_FMPSMBUS_SlaveTxCpltCallback() is executed and users can
80 add their own code by customization of function pointer HAL_FMPSMBUS_SlaveTxCpltCallback()
81 (+) Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode
82 using HAL_FMPSMBUS_Slave_Receive_IT()
83 (++) At reception end of transfer HAL_FMPSMBUS_SlaveRxCpltCallback() is executed and users can
84 add their own code by customization of function pointer HAL_FMPSMBUS_SlaveRxCpltCallback()
85 (+) Enable/Disable the FMPSMBUS alert mode using
86 HAL_FMPSMBUS_EnableAlert_IT() or HAL_FMPSMBUS_DisableAlert_IT()
87 (++) When FMPSMBUS Alert is generated HAL_FMPSMBUS_ErrorCallback() is executed and users can
88 add their own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
89 to check the Alert Error Code using function HAL_FMPSMBUS_GetError()
90 (+) Get HAL state machine or error values using HAL_FMPSMBUS_GetState() or HAL_FMPSMBUS_GetError()
91 (+) In case of transfer Error, HAL_FMPSMBUS_ErrorCallback() function is executed and users can
92 add their own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
93 to check the Error Code using function HAL_FMPSMBUS_GetError()
94
95 *** FMPSMBUS HAL driver macros list ***
96 ==================================
97 [..]
98 Below the list of most used macros in FMPSMBUS HAL driver.
99
100 (+) __HAL_FMPSMBUS_ENABLE: Enable the FMPSMBUS peripheral
101 (+) __HAL_FMPSMBUS_DISABLE: Disable the FMPSMBUS peripheral
102 (+) __HAL_FMPSMBUS_GET_FLAG: Check whether the specified FMPSMBUS flag is set or not
103 (+) __HAL_FMPSMBUS_CLEAR_FLAG: Clear the specified FMPSMBUS pending flag
104 (+) __HAL_FMPSMBUS_ENABLE_IT: Enable the specified FMPSMBUS interrupt
105 (+) __HAL_FMPSMBUS_DISABLE_IT: Disable the specified FMPSMBUS interrupt
106
107 *** Callback registration ***
108 =============================================
109 [..]
110 The compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS when set to 1
111 allows the user to configure dynamically the driver callbacks.
112 Use Functions HAL_FMPSMBUS_RegisterCallback() or HAL_FMPSMBUS_RegisterAddrCallback()
113 to register an interrupt callback.
114 [..]
115 Function HAL_FMPSMBUS_RegisterCallback() allows to register following callbacks:
116 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
117 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
118 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
119 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
120 (+) ListenCpltCallback : callback for end of listen mode.
121 (+) ErrorCallback : callback for error detection.
122 (+) MspInitCallback : callback for Msp Init.
123 (+) MspDeInitCallback : callback for Msp DeInit.
124 This function takes as parameters the HAL peripheral handle, the Callback ID
125 and a pointer to the user callback function.
126 [..]
127 For specific callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_RegisterAddrCallback.
128 [..]
129 Use function HAL_FMPSMBUS_UnRegisterCallback to reset a callback to the default
130 weak function.
131 HAL_FMPSMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
132 and the Callback ID.
133 This function allows to reset following callbacks:
134 (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
135 (+) MasterRxCpltCallback : callback for Master reception end of transfer.
136 (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer.
137 (+) SlaveRxCpltCallback : callback for Slave reception end of transfer.
138 (+) ListenCpltCallback : callback for end of listen mode.
139 (+) ErrorCallback : callback for error detection.
140 (+) MspInitCallback : callback for Msp Init.
141 (+) MspDeInitCallback : callback for Msp DeInit.
142 [..]
143 For callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_UnRegisterAddrCallback.
144 [..]
145 By default, after the HAL_FMPSMBUS_Init() and when the state is HAL_FMPI2C_STATE_RESET
146 all callbacks are set to the corresponding weak functions:
147 examples HAL_FMPSMBUS_MasterTxCpltCallback(), HAL_FMPSMBUS_MasterRxCpltCallback().
148 Exception done for MspInit and MspDeInit functions that are
149 reset to the legacy weak functions in the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit() only when
150 these callbacks are null (not registered beforehand).
151 If MspInit or MspDeInit are not null, the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit()
152 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
153 [..]
154 Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only.
155 Exception done MspInit/MspDeInit functions that can be registered/unregistered
156 in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state,
157 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
158 Then, the user first registers the MspInit/MspDeInit user callbacks
159 using HAL_FMPSMBUS_RegisterCallback() before calling HAL_FMPSMBUS_DeInit()
160 or HAL_FMPSMBUS_Init() function.
161 [..]
162 When the compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS is set to 0 or
163 not defined, the callback registration feature is not available and all callbacks
164 are set to the corresponding weak functions.
165
166 [..]
167 (@) You can refer to the FMPSMBUS HAL driver header file for more useful macros
168
169 @endverbatim
170 */
171
172 /* Includes ------------------------------------------------------------------*/
173 #include "stm32f4xx_hal.h"
174
175 /** @addtogroup STM32F4xx_HAL_Driver
176 * @{
177 */
178
179 /** @defgroup FMPSMBUS FMPSMBUS
180 * @brief FMPSMBUS HAL module driver
181 * @{
182 */
183
184 #ifdef HAL_FMPSMBUS_MODULE_ENABLED
185
186 #if defined(FMPI2C_CR1_PE)
187 /* Private typedef -----------------------------------------------------------*/
188 /* Private constants ---------------------------------------------------------*/
189 /** @defgroup FMPSMBUS_Private_Define FMPSMBUS Private Constants
190 * @{
191 */
192 #define TIMING_CLEAR_MASK (0xF0FFFFFFUL) /*!< FMPSMBUS TIMING clear register Mask */
193 #define HAL_TIMEOUT_ADDR (10000U) /*!< 10 s */
194 #define HAL_TIMEOUT_BUSY (25U) /*!< 25 ms */
195 #define HAL_TIMEOUT_DIR (25U) /*!< 25 ms */
196 #define HAL_TIMEOUT_RXNE (25U) /*!< 25 ms */
197 #define HAL_TIMEOUT_STOPF (25U) /*!< 25 ms */
198 #define HAL_TIMEOUT_TC (25U) /*!< 25 ms */
199 #define HAL_TIMEOUT_TCR (25U) /*!< 25 ms */
200 #define HAL_TIMEOUT_TXIS (25U) /*!< 25 ms */
201 #define MAX_NBYTE_SIZE 255U
202 /**
203 * @}
204 */
205
206 /* Private macro -------------------------------------------------------------*/
207 /* Private variables ---------------------------------------------------------*/
208 /* Private function prototypes -----------------------------------------------*/
209 /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
210 * @{
211 */
212 static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
213 FlagStatus Status, uint32_t Timeout);
214
215 static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
216 static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
217 static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
218 static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
219
220 static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus);
221
222 static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus);
223
224 static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t Size,
225 uint32_t Mode, uint32_t Request);
226 /**
227 * @}
228 */
229
230 /* Exported functions --------------------------------------------------------*/
231
232 /** @defgroup FMPSMBUS_Exported_Functions FMPSMBUS Exported Functions
233 * @{
234 */
235
236 /** @defgroup FMPSMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
237 * @brief Initialization and Configuration functions
238 *
239 @verbatim
240 ===============================================================================
241 ##### Initialization and de-initialization functions #####
242 ===============================================================================
243 [..] This subsection provides a set of functions allowing to initialize and
244 deinitialize the FMPSMBUSx peripheral:
245
246 (+) User must Implement HAL_FMPSMBUS_MspInit() function in which he configures
247 all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
248
249 (+) Call the function HAL_FMPSMBUS_Init() to configure the selected device with
250 the selected configuration:
251 (++) Clock Timing
252 (++) Bus Timeout
253 (++) Analog Filer mode
254 (++) Own Address 1
255 (++) Addressing mode (Master, Slave)
256 (++) Dual Addressing mode
257 (++) Own Address 2
258 (++) Own Address 2 Mask
259 (++) General call mode
260 (++) Nostretch mode
261 (++) Packet Error Check mode
262 (++) Peripheral mode
263
264
265 (+) Call the function HAL_FMPSMBUS_DeInit() to restore the default configuration
266 of the selected FMPSMBUSx peripheral.
267
268 (+) Enable/Disable Analog/Digital filters with HAL_FMPSMBUS_ConfigAnalogFilter() and
269 HAL_FMPSMBUS_ConfigDigitalFilter().
270
271 @endverbatim
272 * @{
273 */
274
275 /**
276 * @brief Initialize the FMPSMBUS according to the specified parameters
277 * in the FMPSMBUS_InitTypeDef and initialize the associated handle.
278 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
279 * the configuration information for the specified FMPSMBUS.
280 * @retval HAL status
281 */
HAL_FMPSMBUS_Init(FMPSMBUS_HandleTypeDef * hfmpsmbus)282 HAL_StatusTypeDef HAL_FMPSMBUS_Init(FMPSMBUS_HandleTypeDef *hfmpsmbus)
283 {
284 /* Check the FMPSMBUS handle allocation */
285 if (hfmpsmbus == NULL)
286 {
287 return HAL_ERROR;
288 }
289
290 /* Check the parameters */
291 assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
292 assert_param(IS_FMPSMBUS_ANALOG_FILTER(hfmpsmbus->Init.AnalogFilter));
293 assert_param(IS_FMPSMBUS_OWN_ADDRESS1(hfmpsmbus->Init.OwnAddress1));
294 assert_param(IS_FMPSMBUS_ADDRESSING_MODE(hfmpsmbus->Init.AddressingMode));
295 assert_param(IS_FMPSMBUS_DUAL_ADDRESS(hfmpsmbus->Init.DualAddressMode));
296 assert_param(IS_FMPSMBUS_OWN_ADDRESS2(hfmpsmbus->Init.OwnAddress2));
297 assert_param(IS_FMPSMBUS_OWN_ADDRESS2_MASK(hfmpsmbus->Init.OwnAddress2Masks));
298 assert_param(IS_FMPSMBUS_GENERAL_CALL(hfmpsmbus->Init.GeneralCallMode));
299 assert_param(IS_FMPSMBUS_NO_STRETCH(hfmpsmbus->Init.NoStretchMode));
300 assert_param(IS_FMPSMBUS_PEC(hfmpsmbus->Init.PacketErrorCheckMode));
301 assert_param(IS_FMPSMBUS_PERIPHERAL_MODE(hfmpsmbus->Init.PeripheralMode));
302
303 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_RESET)
304 {
305 /* Allocate lock resource and initialize it */
306 hfmpsmbus->Lock = HAL_UNLOCKED;
307
308 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
309 hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
310 hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
311 hfmpsmbus->SlaveTxCpltCallback = HAL_FMPSMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
312 hfmpsmbus->SlaveRxCpltCallback = HAL_FMPSMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
313 hfmpsmbus->ListenCpltCallback = HAL_FMPSMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
314 hfmpsmbus->ErrorCallback = HAL_FMPSMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
315 hfmpsmbus->AddrCallback = HAL_FMPSMBUS_AddrCallback; /* Legacy weak AddrCallback */
316
317 if (hfmpsmbus->MspInitCallback == NULL)
318 {
319 hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
320 }
321
322 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
323 hfmpsmbus->MspInitCallback(hfmpsmbus);
324 #else
325 /* Init the low level hardware : GPIO, CLOCK, NVIC */
326 HAL_FMPSMBUS_MspInit(hfmpsmbus);
327 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
328 }
329
330 hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
331
332 /* Disable the selected FMPSMBUS peripheral */
333 __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
334
335 /*---------------------------- FMPSMBUSx TIMINGR Configuration ------------------------*/
336 /* Configure FMPSMBUSx: Frequency range */
337 hfmpsmbus->Instance->TIMINGR = hfmpsmbus->Init.Timing & TIMING_CLEAR_MASK;
338
339 /*---------------------------- FMPSMBUSx TIMEOUTR Configuration ------------------------*/
340 /* Configure FMPSMBUSx: Bus Timeout */
341 hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TIMOUTEN;
342 hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TEXTEN;
343 hfmpsmbus->Instance->TIMEOUTR = hfmpsmbus->Init.SMBusTimeout;
344
345 /*---------------------------- FMPSMBUSx OAR1 Configuration -----------------------*/
346 /* Configure FMPSMBUSx: Own Address1 and ack own address1 mode */
347 hfmpsmbus->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
348
349 if (hfmpsmbus->Init.OwnAddress1 != 0UL)
350 {
351 if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_7BIT)
352 {
353 hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpsmbus->Init.OwnAddress1);
354 }
355 else /* FMPSMBUS_ADDRESSINGMODE_10BIT */
356 {
357 hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpsmbus->Init.OwnAddress1);
358 }
359 }
360
361 /*---------------------------- FMPSMBUSx CR2 Configuration ------------------------*/
362 /* Configure FMPSMBUSx: Addressing Master mode */
363 if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_10BIT)
364 {
365 hfmpsmbus->Instance->CR2 = (FMPI2C_CR2_ADD10);
366 }
367 /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
368 /* AUTOEND and NACK bit will be manage during Transfer process */
369 hfmpsmbus->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
370
371 /*---------------------------- FMPSMBUSx OAR2 Configuration -----------------------*/
372 /* Configure FMPSMBUSx: Dual mode and Own Address2 */
373 hfmpsmbus->Instance->OAR2 = (hfmpsmbus->Init.DualAddressMode | hfmpsmbus->Init.OwnAddress2 | \
374 (hfmpsmbus->Init.OwnAddress2Masks << 8U));
375
376 /*---------------------------- FMPSMBUSx CR1 Configuration ------------------------*/
377 /* Configure FMPSMBUSx: Generalcall and NoStretch mode */
378 hfmpsmbus->Instance->CR1 = (hfmpsmbus->Init.GeneralCallMode | hfmpsmbus->Init.NoStretchMode | \
379 hfmpsmbus->Init.PacketErrorCheckMode | hfmpsmbus->Init.PeripheralMode | \
380 hfmpsmbus->Init.AnalogFilter);
381
382 /* Enable Slave Byte Control only in case of Packet Error Check is enabled
383 and FMPSMBUS Peripheral is set in Slave mode */
384 if ((hfmpsmbus->Init.PacketErrorCheckMode == FMPSMBUS_PEC_ENABLE) && \
385 ((hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE) || \
386 (hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE_ARP)))
387 {
388 hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
389 }
390
391 /* Enable the selected FMPSMBUS peripheral */
392 __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
393
394 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
395 hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
396 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
397
398 return HAL_OK;
399 }
400
401 /**
402 * @brief DeInitialize the FMPSMBUS peripheral.
403 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
404 * the configuration information for the specified FMPSMBUS.
405 * @retval HAL status
406 */
HAL_FMPSMBUS_DeInit(FMPSMBUS_HandleTypeDef * hfmpsmbus)407 HAL_StatusTypeDef HAL_FMPSMBUS_DeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
408 {
409 /* Check the FMPSMBUS handle allocation */
410 if (hfmpsmbus == NULL)
411 {
412 return HAL_ERROR;
413 }
414
415 /* Check the parameters */
416 assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
417
418 hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
419
420 /* Disable the FMPSMBUS Peripheral Clock */
421 __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
422
423 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
424 if (hfmpsmbus->MspDeInitCallback == NULL)
425 {
426 hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
427 }
428
429 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
430 hfmpsmbus->MspDeInitCallback(hfmpsmbus);
431 #else
432 /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
433 HAL_FMPSMBUS_MspDeInit(hfmpsmbus);
434 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
435
436 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
437 hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_RESET;
438 hfmpsmbus->State = HAL_FMPSMBUS_STATE_RESET;
439
440 /* Release Lock */
441 __HAL_UNLOCK(hfmpsmbus);
442
443 return HAL_OK;
444 }
445
446 /**
447 * @brief Initialize the FMPSMBUS MSP.
448 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
449 * the configuration information for the specified FMPSMBUS.
450 * @retval None
451 */
HAL_FMPSMBUS_MspInit(FMPSMBUS_HandleTypeDef * hfmpsmbus)452 __weak void HAL_FMPSMBUS_MspInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
453 {
454 /* Prevent unused argument(s) compilation warning */
455 UNUSED(hfmpsmbus);
456
457 /* NOTE : This function should not be modified, when the callback is needed,
458 the HAL_FMPSMBUS_MspInit could be implemented in the user file
459 */
460 }
461
462 /**
463 * @brief DeInitialize the FMPSMBUS MSP.
464 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
465 * the configuration information for the specified FMPSMBUS.
466 * @retval None
467 */
HAL_FMPSMBUS_MspDeInit(FMPSMBUS_HandleTypeDef * hfmpsmbus)468 __weak void HAL_FMPSMBUS_MspDeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
469 {
470 /* Prevent unused argument(s) compilation warning */
471 UNUSED(hfmpsmbus);
472
473 /* NOTE : This function should not be modified, when the callback is needed,
474 the HAL_FMPSMBUS_MspDeInit could be implemented in the user file
475 */
476 }
477
478 /**
479 * @brief Configure Analog noise filter.
480 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
481 * the configuration information for the specified FMPSMBUS.
482 * @param AnalogFilter This parameter can be one of the following values:
483 * @arg @ref FMPSMBUS_ANALOGFILTER_ENABLE
484 * @arg @ref FMPSMBUS_ANALOGFILTER_DISABLE
485 * @retval HAL status
486 */
HAL_FMPSMBUS_ConfigAnalogFilter(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t AnalogFilter)487 HAL_StatusTypeDef HAL_FMPSMBUS_ConfigAnalogFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t AnalogFilter)
488 {
489 /* Check the parameters */
490 assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
491 assert_param(IS_FMPSMBUS_ANALOG_FILTER(AnalogFilter));
492
493 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
494 {
495 /* Process Locked */
496 __HAL_LOCK(hfmpsmbus);
497
498 hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
499
500 /* Disable the selected FMPSMBUS peripheral */
501 __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
502
503 /* Reset ANOFF bit */
504 hfmpsmbus->Instance->CR1 &= ~(FMPI2C_CR1_ANFOFF);
505
506 /* Set analog filter bit*/
507 hfmpsmbus->Instance->CR1 |= AnalogFilter;
508
509 __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
510
511 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
512
513 /* Process Unlocked */
514 __HAL_UNLOCK(hfmpsmbus);
515
516 return HAL_OK;
517 }
518 else
519 {
520 return HAL_BUSY;
521 }
522 }
523
524 /**
525 * @brief Configure Digital noise filter.
526 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
527 * the configuration information for the specified FMPSMBUS.
528 * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
529 * @retval HAL status
530 */
HAL_FMPSMBUS_ConfigDigitalFilter(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t DigitalFilter)531 HAL_StatusTypeDef HAL_FMPSMBUS_ConfigDigitalFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t DigitalFilter)
532 {
533 uint32_t tmpreg;
534
535 /* Check the parameters */
536 assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
537 assert_param(IS_FMPSMBUS_DIGITAL_FILTER(DigitalFilter));
538
539 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
540 {
541 /* Process Locked */
542 __HAL_LOCK(hfmpsmbus);
543
544 hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
545
546 /* Disable the selected FMPSMBUS peripheral */
547 __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
548
549 /* Get the old register value */
550 tmpreg = hfmpsmbus->Instance->CR1;
551
552 /* Reset FMPI2C DNF bits [11:8] */
553 tmpreg &= ~(FMPI2C_CR1_DNF);
554
555 /* Set FMPI2Cx DNF coefficient */
556 tmpreg |= DigitalFilter << FMPI2C_CR1_DNF_Pos;
557
558 /* Store the new register value */
559 hfmpsmbus->Instance->CR1 = tmpreg;
560
561 __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
562
563 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
564
565 /* Process Unlocked */
566 __HAL_UNLOCK(hfmpsmbus);
567
568 return HAL_OK;
569 }
570 else
571 {
572 return HAL_BUSY;
573 }
574 }
575
576 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
577 /**
578 * @brief Register a User FMPSMBUS Callback
579 * To be used instead of the weak predefined callback
580 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
581 * the configuration information for the specified FMPSMBUS.
582 * @param CallbackID ID of the callback to be registered
583 * This parameter can be one of the following values:
584 * @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
585 * @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
586 * @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
587 * @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
588 * @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
589 * @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
590 * @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
591 * @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
592 * @param pCallback pointer to the Callback function
593 * @retval HAL status
594 */
HAL_FMPSMBUS_RegisterCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus,HAL_FMPSMBUS_CallbackIDTypeDef CallbackID,pFMPSMBUS_CallbackTypeDef pCallback)595 HAL_StatusTypeDef HAL_FMPSMBUS_RegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
596 HAL_FMPSMBUS_CallbackIDTypeDef CallbackID,
597 pFMPSMBUS_CallbackTypeDef pCallback)
598 {
599 HAL_StatusTypeDef status = HAL_OK;
600
601 if (pCallback == NULL)
602 {
603 /* Update the error code */
604 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
605
606 return HAL_ERROR;
607 }
608
609 /* Process locked */
610 __HAL_LOCK(hfmpsmbus);
611
612 if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
613 {
614 switch (CallbackID)
615 {
616 case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
617 hfmpsmbus->MasterTxCpltCallback = pCallback;
618 break;
619
620 case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
621 hfmpsmbus->MasterRxCpltCallback = pCallback;
622 break;
623
624 case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
625 hfmpsmbus->SlaveTxCpltCallback = pCallback;
626 break;
627
628 case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
629 hfmpsmbus->SlaveRxCpltCallback = pCallback;
630 break;
631
632 case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
633 hfmpsmbus->ListenCpltCallback = pCallback;
634 break;
635
636 case HAL_FMPSMBUS_ERROR_CB_ID :
637 hfmpsmbus->ErrorCallback = pCallback;
638 break;
639
640 case HAL_FMPSMBUS_MSPINIT_CB_ID :
641 hfmpsmbus->MspInitCallback = pCallback;
642 break;
643
644 case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
645 hfmpsmbus->MspDeInitCallback = pCallback;
646 break;
647
648 default :
649 /* Update the error code */
650 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
651
652 /* Return error status */
653 status = HAL_ERROR;
654 break;
655 }
656 }
657 else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
658 {
659 switch (CallbackID)
660 {
661 case HAL_FMPSMBUS_MSPINIT_CB_ID :
662 hfmpsmbus->MspInitCallback = pCallback;
663 break;
664
665 case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
666 hfmpsmbus->MspDeInitCallback = pCallback;
667 break;
668
669 default :
670 /* Update the error code */
671 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
672
673 /* Return error status */
674 status = HAL_ERROR;
675 break;
676 }
677 }
678 else
679 {
680 /* Update the error code */
681 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
682
683 /* Return error status */
684 status = HAL_ERROR;
685 }
686
687 /* Release Lock */
688 __HAL_UNLOCK(hfmpsmbus);
689 return status;
690 }
691
692 /**
693 * @brief Unregister an FMPSMBUS Callback
694 * FMPSMBUS callback is redirected to the weak predefined callback
695 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
696 * the configuration information for the specified FMPSMBUS.
697 * @param CallbackID ID of the callback to be unregistered
698 * This parameter can be one of the following values:
699 * This parameter can be one of the following values:
700 * @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
701 * @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
702 * @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
703 * @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
704 * @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
705 * @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
706 * @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
707 * @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
708 * @retval HAL status
709 */
HAL_FMPSMBUS_UnRegisterCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus,HAL_FMPSMBUS_CallbackIDTypeDef CallbackID)710 HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
711 HAL_FMPSMBUS_CallbackIDTypeDef CallbackID)
712 {
713 HAL_StatusTypeDef status = HAL_OK;
714
715 /* Process locked */
716 __HAL_LOCK(hfmpsmbus);
717
718 if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
719 {
720 switch (CallbackID)
721 {
722 case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
723 hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
724 break;
725
726 case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
727 hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
728 break;
729
730 case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
731 hfmpsmbus->SlaveTxCpltCallback = HAL_FMPSMBUS_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */
732 break;
733
734 case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
735 hfmpsmbus->SlaveRxCpltCallback = HAL_FMPSMBUS_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */
736 break;
737
738 case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
739 hfmpsmbus->ListenCpltCallback = HAL_FMPSMBUS_ListenCpltCallback; /* Legacy weak ListenCpltCallback */
740 break;
741
742 case HAL_FMPSMBUS_ERROR_CB_ID :
743 hfmpsmbus->ErrorCallback = HAL_FMPSMBUS_ErrorCallback; /* Legacy weak ErrorCallback */
744 break;
745
746 case HAL_FMPSMBUS_MSPINIT_CB_ID :
747 hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
748 break;
749
750 case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
751 hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
752 break;
753
754 default :
755 /* Update the error code */
756 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
757
758 /* Return error status */
759 status = HAL_ERROR;
760 break;
761 }
762 }
763 else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
764 {
765 switch (CallbackID)
766 {
767 case HAL_FMPSMBUS_MSPINIT_CB_ID :
768 hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit */
769 break;
770
771 case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
772 hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit */
773 break;
774
775 default :
776 /* Update the error code */
777 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
778
779 /* Return error status */
780 status = HAL_ERROR;
781 break;
782 }
783 }
784 else
785 {
786 /* Update the error code */
787 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
788
789 /* Return error status */
790 status = HAL_ERROR;
791 }
792
793 /* Release Lock */
794 __HAL_UNLOCK(hfmpsmbus);
795 return status;
796 }
797
798 /**
799 * @brief Register the Slave Address Match FMPSMBUS Callback
800 * To be used instead of the weak HAL_FMPSMBUS_AddrCallback() predefined callback
801 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
802 * the configuration information for the specified FMPSMBUS.
803 * @param pCallback pointer to the Address Match Callback function
804 * @retval HAL status
805 */
HAL_FMPSMBUS_RegisterAddrCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus,pFMPSMBUS_AddrCallbackTypeDef pCallback)806 HAL_StatusTypeDef HAL_FMPSMBUS_RegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
807 pFMPSMBUS_AddrCallbackTypeDef pCallback)
808 {
809 HAL_StatusTypeDef status = HAL_OK;
810
811 if (pCallback == NULL)
812 {
813 /* Update the error code */
814 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
815
816 return HAL_ERROR;
817 }
818 /* Process locked */
819 __HAL_LOCK(hfmpsmbus);
820
821 if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
822 {
823 hfmpsmbus->AddrCallback = pCallback;
824 }
825 else
826 {
827 /* Update the error code */
828 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
829
830 /* Return error status */
831 status = HAL_ERROR;
832 }
833
834 /* Release Lock */
835 __HAL_UNLOCK(hfmpsmbus);
836 return status;
837 }
838
839 /**
840 * @brief UnRegister the Slave Address Match FMPSMBUS Callback
841 * Info Ready FMPSMBUS Callback is redirected to the weak HAL_FMPSMBUS_AddrCallback() predefined callback
842 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
843 * the configuration information for the specified FMPSMBUS.
844 * @retval HAL status
845 */
HAL_FMPSMBUS_UnRegisterAddrCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)846 HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
847 {
848 HAL_StatusTypeDef status = HAL_OK;
849
850 /* Process locked */
851 __HAL_LOCK(hfmpsmbus);
852
853 if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
854 {
855 hfmpsmbus->AddrCallback = HAL_FMPSMBUS_AddrCallback; /* Legacy weak AddrCallback */
856 }
857 else
858 {
859 /* Update the error code */
860 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
861
862 /* Return error status */
863 status = HAL_ERROR;
864 }
865
866 /* Release Lock */
867 __HAL_UNLOCK(hfmpsmbus);
868 return status;
869 }
870
871 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
872
873 /**
874 * @}
875 */
876
877 /** @defgroup FMPSMBUS_Exported_Functions_Group2 Input and Output operation functions
878 * @brief Data transfers functions
879 *
880 @verbatim
881 ===============================================================================
882 ##### IO operation functions #####
883 ===============================================================================
884 [..]
885 This subsection provides a set of functions allowing to manage the FMPSMBUS data
886 transfers.
887
888 (#) Blocking mode function to check if device is ready for usage is :
889 (++) HAL_FMPSMBUS_IsDeviceReady()
890
891 (#) There is only one mode of transfer:
892 (++) Non-Blocking mode : The communication is performed using Interrupts.
893 These functions return the status of the transfer startup.
894 The end of the data processing will be indicated through the
895 dedicated FMPSMBUS IRQ when using Interrupt mode.
896
897 (#) Non-Blocking mode functions with Interrupt are :
898 (++) HAL_FMPSMBUS_Master_Transmit_IT()
899 (++) HAL_FMPSMBUS_Master_Receive_IT()
900 (++) HAL_FMPSMBUS_Slave_Transmit_IT()
901 (++) HAL_FMPSMBUS_Slave_Receive_IT()
902 (++) HAL_FMPSMBUS_EnableListen_IT() or alias HAL_FMPSMBUS_EnableListen_IT()
903 (++) HAL_FMPSMBUS_DisableListen_IT()
904 (++) HAL_FMPSMBUS_EnableAlert_IT()
905 (++) HAL_FMPSMBUS_DisableAlert_IT()
906
907 (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
908 (++) HAL_FMPSMBUS_MasterTxCpltCallback()
909 (++) HAL_FMPSMBUS_MasterRxCpltCallback()
910 (++) HAL_FMPSMBUS_SlaveTxCpltCallback()
911 (++) HAL_FMPSMBUS_SlaveRxCpltCallback()
912 (++) HAL_FMPSMBUS_AddrCallback()
913 (++) HAL_FMPSMBUS_ListenCpltCallback()
914 (++) HAL_FMPSMBUS_ErrorCallback()
915
916 @endverbatim
917 * @{
918 */
919
920 /**
921 * @brief Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
922 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
923 * the configuration information for the specified FMPSMBUS.
924 * @param DevAddress Target device address: The device 7 bits address value
925 * in datasheet must be shifted to the left before calling the interface
926 * @param pData Pointer to data buffer
927 * @param Size Amount of data to be sent
928 * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
929 * @retval HAL status
930 */
HAL_FMPSMBUS_Master_Transmit_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)931 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress,
932 uint8_t *pData, uint16_t Size, uint32_t XferOptions)
933 {
934 uint32_t tmp;
935
936 /* Check the parameters */
937 assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
938
939 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
940 {
941 /* Process Locked */
942 __HAL_LOCK(hfmpsmbus);
943
944 hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
945 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
946 /* Prepare transfer parameters */
947 hfmpsmbus->pBuffPtr = pData;
948 hfmpsmbus->XferCount = Size;
949 hfmpsmbus->XferOptions = XferOptions;
950
951 /* In case of Quick command, remove autoend mode */
952 /* Manage the stop generation by software */
953 if (hfmpsmbus->pBuffPtr == NULL)
954 {
955 hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
956 }
957
958 if (Size > MAX_NBYTE_SIZE)
959 {
960 hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
961 }
962 else
963 {
964 hfmpsmbus->XferSize = Size;
965 }
966
967 /* Send Slave Address */
968 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
969 if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
970 {
971 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
972 FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
973 FMPSMBUS_GENERATE_START_WRITE);
974 }
975 else
976 {
977 /* If transfer direction not change, do not generate Restart Condition */
978 /* Mean Previous state is same as current state */
979
980 /* Store current volatile XferOptions, misra rule */
981 tmp = hfmpsmbus->XferOptions;
982
983 if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) && \
984 (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
985 {
986 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
987 FMPSMBUS_NO_STARTSTOP);
988 }
989 /* Else transfer direction change, so generate Restart with new transfer direction */
990 else
991 {
992 /* Convert OTHER_xxx XferOptions if any */
993 FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
994
995 /* Handle Transfer */
996 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
997 hfmpsmbus->XferOptions,
998 FMPSMBUS_GENERATE_START_WRITE);
999 }
1000
1001 /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
1002 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1003 if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
1004 {
1005 hfmpsmbus->XferSize--;
1006 hfmpsmbus->XferCount--;
1007 }
1008 }
1009
1010 /* Process Unlocked */
1011 __HAL_UNLOCK(hfmpsmbus);
1012
1013 /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
1014 to avoid the risk of FMPSMBUS interrupt handle execution before current
1015 process unlock */
1016 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
1017
1018 return HAL_OK;
1019 }
1020 else
1021 {
1022 return HAL_BUSY;
1023 }
1024 }
1025
1026 /**
1027 * @brief Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
1028 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1029 * the configuration information for the specified FMPSMBUS.
1030 * @param DevAddress Target device address: The device 7 bits address value
1031 * in datasheet must be shifted to the left before calling the interface
1032 * @param pData Pointer to data buffer
1033 * @param Size Amount of data to be sent
1034 * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
1035 * @retval HAL status
1036 */
HAL_FMPSMBUS_Master_Receive_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint16_t DevAddress,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1037 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t *pData,
1038 uint16_t Size, uint32_t XferOptions)
1039 {
1040 uint32_t tmp;
1041
1042 /* Check the parameters */
1043 assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1044
1045 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
1046 {
1047 /* Process Locked */
1048 __HAL_LOCK(hfmpsmbus);
1049
1050 hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
1051 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
1052
1053 /* Prepare transfer parameters */
1054 hfmpsmbus->pBuffPtr = pData;
1055 hfmpsmbus->XferCount = Size;
1056 hfmpsmbus->XferOptions = XferOptions;
1057
1058 /* In case of Quick command, remove autoend mode */
1059 /* Manage the stop generation by software */
1060 if (hfmpsmbus->pBuffPtr == NULL)
1061 {
1062 hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
1063 }
1064
1065 if (Size > MAX_NBYTE_SIZE)
1066 {
1067 hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
1068 }
1069 else
1070 {
1071 hfmpsmbus->XferSize = Size;
1072 }
1073
1074 /* Send Slave Address */
1075 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1076 if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
1077 {
1078 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
1079 FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
1080 FMPSMBUS_GENERATE_START_READ);
1081 }
1082 else
1083 {
1084 /* If transfer direction not change, do not generate Restart Condition */
1085 /* Mean Previous state is same as current state */
1086
1087 /* Store current volatile XferOptions, Misra rule */
1088 tmp = hfmpsmbus->XferOptions;
1089
1090 if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) && \
1091 (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
1092 {
1093 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
1094 FMPSMBUS_NO_STARTSTOP);
1095 }
1096 /* Else transfer direction change, so generate Restart with new transfer direction */
1097 else
1098 {
1099 /* Convert OTHER_xxx XferOptions if any */
1100 FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
1101
1102 /* Handle Transfer */
1103 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
1104 hfmpsmbus->XferOptions,
1105 FMPSMBUS_GENERATE_START_READ);
1106 }
1107 }
1108
1109 /* Process Unlocked */
1110 __HAL_UNLOCK(hfmpsmbus);
1111
1112 /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
1113 to avoid the risk of FMPSMBUS interrupt handle execution before current
1114 process unlock */
1115 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
1116
1117 return HAL_OK;
1118 }
1119 else
1120 {
1121 return HAL_BUSY;
1122 }
1123 }
1124
1125 /**
1126 * @brief Abort a master/host FMPSMBUS process communication with Interrupt.
1127 * @note This abort can be called only if state is ready
1128 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1129 * the configuration information for the specified FMPSMBUS.
1130 * @param DevAddress Target device address: The device 7 bits address value
1131 * in datasheet must be shifted to the left before calling the interface
1132 * @retval HAL status
1133 */
HAL_FMPSMBUS_Master_Abort_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint16_t DevAddress)1134 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Abort_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress)
1135 {
1136 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
1137 {
1138 /* Process Locked */
1139 __HAL_LOCK(hfmpsmbus);
1140
1141 /* Keep the same state as previous */
1142 /* to perform as well the call of the corresponding end of transfer callback */
1143 if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
1144 {
1145 hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
1146 }
1147 else if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
1148 {
1149 hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
1150 }
1151 else
1152 {
1153 /* Wrong usage of abort function */
1154 /* This function should be used only in case of abort monitored by master device */
1155 return HAL_ERROR;
1156 }
1157 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
1158
1159 /* Set NBYTES to 1 to generate a dummy read on FMPSMBUS peripheral */
1160 /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
1161 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, 1, FMPSMBUS_AUTOEND_MODE, FMPSMBUS_NO_STARTSTOP);
1162
1163 /* Process Unlocked */
1164 __HAL_UNLOCK(hfmpsmbus);
1165
1166 /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
1167 to avoid the risk of FMPSMBUS interrupt handle execution before current
1168 process unlock */
1169 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
1170 {
1171 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
1172 }
1173 else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
1174 {
1175 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
1176 }
1177 else
1178 {
1179 /* Nothing to do */
1180 }
1181
1182 return HAL_OK;
1183 }
1184 else
1185 {
1186 return HAL_BUSY;
1187 }
1188 }
1189
1190 /**
1191 * @brief Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
1192 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1193 * the configuration information for the specified FMPSMBUS.
1194 * @param pData Pointer to data buffer
1195 * @param Size Amount of data to be sent
1196 * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
1197 * @retval HAL status
1198 */
HAL_FMPSMBUS_Slave_Transmit_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1199 HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
1200 uint32_t XferOptions)
1201 {
1202 /* Check the parameters */
1203 assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1204
1205 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
1206 {
1207 if ((pData == NULL) || (Size == 0UL))
1208 {
1209 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
1210 return HAL_ERROR;
1211 }
1212
1213 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1214 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_TX);
1215
1216 /* Process Locked */
1217 __HAL_LOCK(hfmpsmbus);
1218
1219 hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX | HAL_FMPSMBUS_STATE_LISTEN);
1220 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
1221
1222 /* Set SBC bit to manage Acknowledge at each bit */
1223 hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
1224
1225 /* Enable Address Acknowledge */
1226 hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1227
1228 /* Prepare transfer parameters */
1229 hfmpsmbus->pBuffPtr = pData;
1230 hfmpsmbus->XferCount = Size;
1231 hfmpsmbus->XferOptions = XferOptions;
1232
1233 /* Convert OTHER_xxx XferOptions if any */
1234 FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
1235
1236 if (Size > MAX_NBYTE_SIZE)
1237 {
1238 hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
1239 }
1240 else
1241 {
1242 hfmpsmbus->XferSize = Size;
1243 }
1244
1245 /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
1246 if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
1247 {
1248 FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize,
1249 FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
1250 FMPSMBUS_NO_STARTSTOP);
1251 }
1252 else
1253 {
1254 /* Set NBYTE to transmit */
1255 FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
1256 FMPSMBUS_NO_STARTSTOP);
1257
1258 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
1259 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
1260 if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
1261 {
1262 hfmpsmbus->XferSize--;
1263 hfmpsmbus->XferCount--;
1264 }
1265 }
1266
1267 /* Clear ADDR flag after prepare the transfer parameters */
1268 /* This action will generate an acknowledge to the HOST */
1269 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
1270
1271 /* Process Unlocked */
1272 __HAL_UNLOCK(hfmpsmbus);
1273
1274 /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
1275 to avoid the risk of FMPSMBUS interrupt handle execution before current
1276 process unlock */
1277 /* REnable ADDR interrupt */
1278 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX | FMPSMBUS_IT_ADDR);
1279
1280 return HAL_OK;
1281 }
1282 else
1283 {
1284 return HAL_BUSY;
1285 }
1286 }
1287
1288 /**
1289 * @brief Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
1290 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1291 * the configuration information for the specified FMPSMBUS.
1292 * @param pData Pointer to data buffer
1293 * @param Size Amount of data to be sent
1294 * @param XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
1295 * @retval HAL status
1296 */
HAL_FMPSMBUS_Slave_Receive_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint8_t * pData,uint16_t Size,uint32_t XferOptions)1297 HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
1298 uint32_t XferOptions)
1299 {
1300 /* Check the parameters */
1301 assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
1302
1303 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
1304 {
1305 if ((pData == NULL) || (Size == 0UL))
1306 {
1307 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
1308 return HAL_ERROR;
1309 }
1310
1311 /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
1312 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_RX);
1313
1314 /* Process Locked */
1315 __HAL_LOCK(hfmpsmbus);
1316
1317 hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX | HAL_FMPSMBUS_STATE_LISTEN);
1318 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
1319
1320 /* Set SBC bit to manage Acknowledge at each bit */
1321 hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
1322
1323 /* Enable Address Acknowledge */
1324 hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
1325
1326 /* Prepare transfer parameters */
1327 hfmpsmbus->pBuffPtr = pData;
1328 hfmpsmbus->XferSize = Size;
1329 hfmpsmbus->XferCount = Size;
1330 hfmpsmbus->XferOptions = XferOptions;
1331
1332 /* Convert OTHER_xxx XferOptions if any */
1333 FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
1334
1335 /* Set NBYTE to receive */
1336 /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
1337 /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
1338 /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
1339 /* This RELOAD bit will be reset for last BYTE to be receive in FMPSMBUS_Slave_ISR */
1340 if (((FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL) && (hfmpsmbus->XferSize == 2U)) || (hfmpsmbus->XferSize == 1U))
1341 {
1342 FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
1343 FMPSMBUS_NO_STARTSTOP);
1344 }
1345 else
1346 {
1347 FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions | FMPSMBUS_RELOAD_MODE, FMPSMBUS_NO_STARTSTOP);
1348 }
1349
1350 /* Clear ADDR flag after prepare the transfer parameters */
1351 /* This action will generate an acknowledge to the HOST */
1352 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
1353
1354 /* Process Unlocked */
1355 __HAL_UNLOCK(hfmpsmbus);
1356
1357 /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
1358 to avoid the risk of FMPSMBUS interrupt handle execution before current
1359 process unlock */
1360 /* REnable ADDR interrupt */
1361 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_ADDR);
1362
1363 return HAL_OK;
1364 }
1365 else
1366 {
1367 return HAL_BUSY;
1368 }
1369 }
1370
1371 /**
1372 * @brief Enable the Address listen mode with Interrupt.
1373 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1374 * the configuration information for the specified FMPSMBUS.
1375 * @retval HAL status
1376 */
HAL_FMPSMBUS_EnableListen_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus)1377 HAL_StatusTypeDef HAL_FMPSMBUS_EnableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1378 {
1379 hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
1380
1381 /* Enable the Address Match interrupt */
1382 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
1383
1384 return HAL_OK;
1385 }
1386
1387 /**
1388 * @brief Disable the Address listen mode with Interrupt.
1389 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1390 * the configuration information for the specified FMPSMBUS.
1391 * @retval HAL status
1392 */
HAL_FMPSMBUS_DisableListen_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus)1393 HAL_StatusTypeDef HAL_FMPSMBUS_DisableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1394 {
1395 /* Disable Address listen mode only if a transfer is not ongoing */
1396 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_LISTEN)
1397 {
1398 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1399
1400 /* Disable the Address Match interrupt */
1401 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
1402
1403 return HAL_OK;
1404 }
1405 else
1406 {
1407 return HAL_BUSY;
1408 }
1409 }
1410
1411 /**
1412 * @brief Enable the FMPSMBUS alert mode with Interrupt.
1413 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1414 * the configuration information for the specified FMPSMBUSx peripheral.
1415 * @retval HAL status
1416 */
HAL_FMPSMBUS_EnableAlert_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus)1417 HAL_StatusTypeDef HAL_FMPSMBUS_EnableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1418 {
1419 /* Enable SMBus alert */
1420 hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_ALERTEN;
1421
1422 /* Clear ALERT flag */
1423 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
1424
1425 /* Enable Alert Interrupt */
1426 FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
1427
1428 return HAL_OK;
1429 }
1430 /**
1431 * @brief Disable the FMPSMBUS alert mode with Interrupt.
1432 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1433 * the configuration information for the specified FMPSMBUSx peripheral.
1434 * @retval HAL status
1435 */
HAL_FMPSMBUS_DisableAlert_IT(FMPSMBUS_HandleTypeDef * hfmpsmbus)1436 HAL_StatusTypeDef HAL_FMPSMBUS_DisableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1437 {
1438 /* Enable SMBus alert */
1439 hfmpsmbus->Instance->CR1 &= ~FMPI2C_CR1_ALERTEN;
1440
1441 /* Disable Alert Interrupt */
1442 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
1443
1444 return HAL_OK;
1445 }
1446
1447 /**
1448 * @brief Check if target device is ready for communication.
1449 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1450 * the configuration information for the specified FMPSMBUS.
1451 * @param DevAddress Target device address: The device 7 bits address value
1452 * in datasheet must be shifted to the left before calling the interface
1453 * @param Trials Number of trials
1454 * @param Timeout Timeout duration
1455 * @retval HAL status
1456 */
HAL_FMPSMBUS_IsDeviceReady(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint16_t DevAddress,uint32_t Trials,uint32_t Timeout)1457 HAL_StatusTypeDef HAL_FMPSMBUS_IsDeviceReady(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint32_t Trials,
1458 uint32_t Timeout)
1459 {
1460 uint32_t tickstart;
1461
1462 __IO uint32_t FMPSMBUS_Trials = 0UL;
1463
1464 FlagStatus tmp1;
1465 FlagStatus tmp2;
1466
1467 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
1468 {
1469 if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BUSY) != RESET)
1470 {
1471 return HAL_BUSY;
1472 }
1473
1474 /* Process Locked */
1475 __HAL_LOCK(hfmpsmbus);
1476
1477 hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
1478 hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
1479
1480 do
1481 {
1482 /* Generate Start */
1483 hfmpsmbus->Instance->CR2 = FMPSMBUS_GENERATE_START(hfmpsmbus->Init.AddressingMode, DevAddress);
1484
1485 /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
1486 /* Wait until STOPF flag is set or a NACK flag is set*/
1487 tickstart = HAL_GetTick();
1488
1489 tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1490 tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
1491
1492 while ((tmp1 == RESET) && (tmp2 == RESET))
1493 {
1494 if (Timeout != HAL_MAX_DELAY)
1495 {
1496 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
1497 {
1498 /* Device is ready */
1499 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1500
1501 /* Update FMPSMBUS error code */
1502 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
1503
1504 /* Process Unlocked */
1505 __HAL_UNLOCK(hfmpsmbus);
1506 return HAL_ERROR;
1507 }
1508 }
1509
1510 tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1511 tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
1512 }
1513
1514 /* Check if the NACKF flag has not been set */
1515 if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF) == RESET)
1516 {
1517 /* Wait until STOPF flag is reset */
1518 if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1519 {
1520 return HAL_ERROR;
1521 }
1522
1523 /* Clear STOP Flag */
1524 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1525
1526 /* Device is ready */
1527 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1528
1529 /* Process Unlocked */
1530 __HAL_UNLOCK(hfmpsmbus);
1531
1532 return HAL_OK;
1533 }
1534 else
1535 {
1536 /* Wait until STOPF flag is reset */
1537 if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1538 {
1539 return HAL_ERROR;
1540 }
1541
1542 /* Clear NACK Flag */
1543 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
1544
1545 /* Clear STOP Flag, auto generated with autoend*/
1546 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1547 }
1548
1549 /* Check if the maximum allowed number of trials has been reached */
1550 if (FMPSMBUS_Trials == Trials)
1551 {
1552 /* Generate Stop */
1553 hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
1554
1555 /* Wait until STOPF flag is reset */
1556 if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
1557 {
1558 return HAL_ERROR;
1559 }
1560
1561 /* Clear STOP Flag */
1562 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1563 }
1564
1565 /* Increment Trials */
1566 FMPSMBUS_Trials++;
1567 } while (FMPSMBUS_Trials < Trials);
1568
1569 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1570
1571 /* Update FMPSMBUS error code */
1572 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
1573
1574 /* Process Unlocked */
1575 __HAL_UNLOCK(hfmpsmbus);
1576
1577 return HAL_ERROR;
1578 }
1579 else
1580 {
1581 return HAL_BUSY;
1582 }
1583 }
1584 /**
1585 * @}
1586 */
1587
1588 /** @defgroup FMPSMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
1589 * @{
1590 */
1591
1592 /**
1593 * @brief Handle FMPSMBUS event interrupt request.
1594 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1595 * the configuration information for the specified FMPSMBUS.
1596 * @retval None
1597 */
HAL_FMPSMBUS_EV_IRQHandler(FMPSMBUS_HandleTypeDef * hfmpsmbus)1598 void HAL_FMPSMBUS_EV_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1599 {
1600 /* Use a local variable to store the current ISR flags */
1601 /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
1602 uint32_t tmpisrvalue = READ_REG(hfmpsmbus->Instance->ISR);
1603 uint32_t tmpcr1value = READ_REG(hfmpsmbus->Instance->CR1);
1604
1605 /* FMPSMBUS in mode Transmitter ---------------------------------------------------*/
1606 if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
1607 FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI)) != RESET) &&
1608 ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TXIS) != RESET) ||
1609 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
1610 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
1611 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
1612 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
1613 {
1614 /* Slave mode selected */
1615 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
1616 {
1617 (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
1618 }
1619 /* Master mode selected */
1620 else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
1621 {
1622 (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
1623 }
1624 else
1625 {
1626 /* Nothing to do */
1627 }
1628 }
1629
1630 /* FMPSMBUS in mode Receiver ----------------------------------------------------*/
1631 if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
1632 FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI)) != RESET) &&
1633 ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_RXNE) != RESET) ||
1634 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
1635 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
1636 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
1637 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
1638 {
1639 /* Slave mode selected */
1640 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
1641 {
1642 (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
1643 }
1644 /* Master mode selected */
1645 else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
1646 {
1647 (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
1648 }
1649 else
1650 {
1651 /* Nothing to do */
1652 }
1653 }
1654
1655 /* FMPSMBUS in mode Listener Only --------------------------------------------------*/
1656 if (((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_ADDRI) != RESET) ||
1657 (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_STOPI) != RESET) ||
1658 (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_NACKI) != RESET)) &&
1659 ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_ADDR) != RESET) ||
1660 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
1661 (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
1662 {
1663 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
1664 {
1665 (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
1666 }
1667 }
1668 }
1669
1670 /**
1671 * @brief Handle FMPSMBUS error interrupt request.
1672 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1673 * the configuration information for the specified FMPSMBUS.
1674 * @retval None
1675 */
HAL_FMPSMBUS_ER_IRQHandler(FMPSMBUS_HandleTypeDef * hfmpsmbus)1676 void HAL_FMPSMBUS_ER_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1677 {
1678 FMPSMBUS_ITErrorHandler(hfmpsmbus);
1679 }
1680
1681 /**
1682 * @brief Master Tx Transfer completed callback.
1683 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1684 * the configuration information for the specified FMPSMBUS.
1685 * @retval None
1686 */
HAL_FMPSMBUS_MasterTxCpltCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1687 __weak void HAL_FMPSMBUS_MasterTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1688 {
1689 /* Prevent unused argument(s) compilation warning */
1690 UNUSED(hfmpsmbus);
1691
1692 /* NOTE : This function should not be modified, when the callback is needed,
1693 the HAL_FMPSMBUS_MasterTxCpltCallback() could be implemented in the user file
1694 */
1695 }
1696
1697 /**
1698 * @brief Master Rx Transfer completed callback.
1699 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1700 * the configuration information for the specified FMPSMBUS.
1701 * @retval None
1702 */
HAL_FMPSMBUS_MasterRxCpltCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1703 __weak void HAL_FMPSMBUS_MasterRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1704 {
1705 /* Prevent unused argument(s) compilation warning */
1706 UNUSED(hfmpsmbus);
1707
1708 /* NOTE : This function should not be modified, when the callback is needed,
1709 the HAL_FMPSMBUS_MasterRxCpltCallback() could be implemented in the user file
1710 */
1711 }
1712
1713 /** @brief Slave Tx Transfer completed callback.
1714 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1715 * the configuration information for the specified FMPSMBUS.
1716 * @retval None
1717 */
HAL_FMPSMBUS_SlaveTxCpltCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1718 __weak void HAL_FMPSMBUS_SlaveTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1719 {
1720 /* Prevent unused argument(s) compilation warning */
1721 UNUSED(hfmpsmbus);
1722
1723 /* NOTE : This function should not be modified, when the callback is needed,
1724 the HAL_FMPSMBUS_SlaveTxCpltCallback() could be implemented in the user file
1725 */
1726 }
1727
1728 /**
1729 * @brief Slave Rx Transfer completed callback.
1730 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1731 * the configuration information for the specified FMPSMBUS.
1732 * @retval None
1733 */
HAL_FMPSMBUS_SlaveRxCpltCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1734 __weak void HAL_FMPSMBUS_SlaveRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1735 {
1736 /* Prevent unused argument(s) compilation warning */
1737 UNUSED(hfmpsmbus);
1738
1739 /* NOTE : This function should not be modified, when the callback is needed,
1740 the HAL_FMPSMBUS_SlaveRxCpltCallback() could be implemented in the user file
1741 */
1742 }
1743
1744 /**
1745 * @brief Slave Address Match callback.
1746 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1747 * the configuration information for the specified FMPSMBUS.
1748 * @param TransferDirection Master request Transfer Direction (Write/Read)
1749 * @param AddrMatchCode Address Match Code
1750 * @retval None
1751 */
HAL_FMPSMBUS_AddrCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint8_t TransferDirection,uint16_t AddrMatchCode)1752 __weak void HAL_FMPSMBUS_AddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t TransferDirection,
1753 uint16_t AddrMatchCode)
1754 {
1755 /* Prevent unused argument(s) compilation warning */
1756 UNUSED(hfmpsmbus);
1757 UNUSED(TransferDirection);
1758 UNUSED(AddrMatchCode);
1759
1760 /* NOTE : This function should not be modified, when the callback is needed,
1761 the HAL_FMPSMBUS_AddrCallback() could be implemented in the user file
1762 */
1763 }
1764
1765 /**
1766 * @brief Listen Complete callback.
1767 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1768 * the configuration information for the specified FMPSMBUS.
1769 * @retval None
1770 */
HAL_FMPSMBUS_ListenCpltCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1771 __weak void HAL_FMPSMBUS_ListenCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1772 {
1773 /* Prevent unused argument(s) compilation warning */
1774 UNUSED(hfmpsmbus);
1775
1776 /* NOTE : This function should not be modified, when the callback is needed,
1777 the HAL_FMPSMBUS_ListenCpltCallback() could be implemented in the user file
1778 */
1779 }
1780
1781 /**
1782 * @brief FMPSMBUS error callback.
1783 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1784 * the configuration information for the specified FMPSMBUS.
1785 * @retval None
1786 */
HAL_FMPSMBUS_ErrorCallback(FMPSMBUS_HandleTypeDef * hfmpsmbus)1787 __weak void HAL_FMPSMBUS_ErrorCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1788 {
1789 /* Prevent unused argument(s) compilation warning */
1790 UNUSED(hfmpsmbus);
1791
1792 /* NOTE : This function should not be modified, when the callback is needed,
1793 the HAL_FMPSMBUS_ErrorCallback() could be implemented in the user file
1794 */
1795 }
1796
1797 /**
1798 * @}
1799 */
1800
1801 /** @defgroup FMPSMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
1802 * @brief Peripheral State and Errors functions
1803 *
1804 @verbatim
1805 ===============================================================================
1806 ##### Peripheral State and Errors functions #####
1807 ===============================================================================
1808 [..]
1809 This subsection permits to get in run-time the status of the peripheral
1810 and the data flow.
1811
1812 @endverbatim
1813 * @{
1814 */
1815
1816 /**
1817 * @brief Return the FMPSMBUS handle state.
1818 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1819 * the configuration information for the specified FMPSMBUS.
1820 * @retval HAL state
1821 */
HAL_FMPSMBUS_GetState(FMPSMBUS_HandleTypeDef * hfmpsmbus)1822 uint32_t HAL_FMPSMBUS_GetState(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1823 {
1824 /* Return FMPSMBUS handle state */
1825 return hfmpsmbus->State;
1826 }
1827
1828 /**
1829 * @brief Return the FMPSMBUS error code.
1830 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1831 * the configuration information for the specified FMPSMBUS.
1832 * @retval FMPSMBUS Error Code
1833 */
HAL_FMPSMBUS_GetError(FMPSMBUS_HandleTypeDef * hfmpsmbus)1834 uint32_t HAL_FMPSMBUS_GetError(FMPSMBUS_HandleTypeDef *hfmpsmbus)
1835 {
1836 return hfmpsmbus->ErrorCode;
1837 }
1838
1839 /**
1840 * @}
1841 */
1842
1843 /**
1844 * @}
1845 */
1846
1847 /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
1848 * @brief Data transfers Private functions
1849 * @{
1850 */
1851
1852 /**
1853 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
1854 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
1855 * the configuration information for the specified FMPSMBUS.
1856 * @param StatusFlags Value of Interrupt Flags.
1857 * @retval HAL status
1858 */
FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t StatusFlags)1859 static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
1860 {
1861 uint16_t DevAddress;
1862
1863 /* Process Locked */
1864 __HAL_LOCK(hfmpsmbus);
1865
1866 if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
1867 {
1868 /* Clear NACK Flag */
1869 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
1870
1871 /* Set corresponding Error Code */
1872 /* No need to generate STOP, it is automatically done */
1873 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
1874
1875 /* Process Unlocked */
1876 __HAL_UNLOCK(hfmpsmbus);
1877
1878 /* Call the Error callback to inform upper layer */
1879 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
1880 hfmpsmbus->ErrorCallback(hfmpsmbus);
1881 #else
1882 HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
1883 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
1884 }
1885 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
1886 {
1887 /* Check and treat errors if errors occurs during STOP process */
1888 FMPSMBUS_ITErrorHandler(hfmpsmbus);
1889
1890 /* Call the corresponding callback to inform upper layer of End of Transfer */
1891 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
1892 {
1893 /* Disable Interrupt */
1894 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
1895
1896 /* Clear STOP Flag */
1897 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1898
1899 /* Clear Configuration Register 2 */
1900 FMPSMBUS_RESET_CR2(hfmpsmbus);
1901
1902 /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
1903 /* Disable the selected FMPSMBUS peripheral */
1904 __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
1905
1906 hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
1907 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1908
1909 /* Process Unlocked */
1910 __HAL_UNLOCK(hfmpsmbus);
1911
1912 /* Re-enable the selected FMPSMBUS peripheral */
1913 __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
1914
1915 /* Call the corresponding callback to inform upper layer of End of Transfer */
1916 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
1917 hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
1918 #else
1919 HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
1920 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
1921 }
1922 else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
1923 {
1924 /* Store Last receive data if any */
1925 if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
1926 {
1927 /* Read data from RXDR */
1928 *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
1929
1930 /* Increment Buffer pointer */
1931 hfmpsmbus->pBuffPtr++;
1932
1933 if ((hfmpsmbus->XferSize > 0U))
1934 {
1935 hfmpsmbus->XferSize--;
1936 hfmpsmbus->XferCount--;
1937 }
1938 }
1939
1940 /* Disable Interrupt */
1941 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
1942
1943 /* Clear STOP Flag */
1944 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
1945
1946 /* Clear Configuration Register 2 */
1947 FMPSMBUS_RESET_CR2(hfmpsmbus);
1948
1949 hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
1950 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
1951
1952 /* Process Unlocked */
1953 __HAL_UNLOCK(hfmpsmbus);
1954
1955 /* Call the corresponding callback to inform upper layer of End of Transfer */
1956 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
1957 hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
1958 #else
1959 HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
1960 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
1961 }
1962 else
1963 {
1964 /* Nothing to do */
1965 }
1966 }
1967 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
1968 {
1969 /* Read data from RXDR */
1970 *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
1971
1972 /* Increment Buffer pointer */
1973 hfmpsmbus->pBuffPtr++;
1974
1975 /* Increment Size counter */
1976 hfmpsmbus->XferSize--;
1977 hfmpsmbus->XferCount--;
1978 }
1979 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
1980 {
1981 /* Write data to TXDR */
1982 hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
1983
1984 /* Increment Buffer pointer */
1985 hfmpsmbus->pBuffPtr++;
1986
1987 /* Increment Size counter */
1988 hfmpsmbus->XferSize--;
1989 hfmpsmbus->XferCount--;
1990 }
1991 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET)
1992 {
1993 if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
1994 {
1995 DevAddress = (uint16_t)(hfmpsmbus->Instance->CR2 & FMPI2C_CR2_SADD);
1996
1997 if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
1998 {
1999 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, MAX_NBYTE_SIZE,
2000 (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
2001 FMPSMBUS_NO_STARTSTOP);
2002 hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
2003 }
2004 else
2005 {
2006 hfmpsmbus->XferSize = hfmpsmbus->XferCount;
2007 FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
2008 FMPSMBUS_NO_STARTSTOP);
2009 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2010 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2011 if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
2012 {
2013 hfmpsmbus->XferSize--;
2014 hfmpsmbus->XferCount--;
2015 }
2016 }
2017 }
2018 else if ((hfmpsmbus->XferCount == 0U) && (hfmpsmbus->XferSize == 0U))
2019 {
2020 /* Call TxCpltCallback() if no stop mode is set */
2021 if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
2022 {
2023 /* Call the corresponding callback to inform upper layer of End of Transfer */
2024 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
2025 {
2026 /* Disable Interrupt */
2027 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
2028 hfmpsmbus->PreviousState = hfmpsmbus->State;
2029 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2030
2031 /* Process Unlocked */
2032 __HAL_UNLOCK(hfmpsmbus);
2033
2034 /* Call the corresponding callback to inform upper layer of End of Transfer */
2035 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2036 hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
2037 #else
2038 HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
2039 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2040 }
2041 else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
2042 {
2043 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
2044 hfmpsmbus->PreviousState = hfmpsmbus->State;
2045 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2046
2047 /* Process Unlocked */
2048 __HAL_UNLOCK(hfmpsmbus);
2049
2050 /* Call the corresponding callback to inform upper layer of End of Transfer */
2051 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2052 hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
2053 #else
2054 HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
2055 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2056 }
2057 else
2058 {
2059 /* Nothing to do */
2060 }
2061 }
2062 }
2063 else
2064 {
2065 /* Nothing to do */
2066 }
2067 }
2068 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TC) != RESET)
2069 {
2070 if (hfmpsmbus->XferCount == 0U)
2071 {
2072 /* Specific use case for Quick command */
2073 if (hfmpsmbus->pBuffPtr == NULL)
2074 {
2075 /* Generate a Stop command */
2076 hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
2077 }
2078 /* Call TxCpltCallback() if no stop mode is set */
2079 else if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
2080 {
2081 /* No Generate Stop, to permit restart mode */
2082 /* The stop will be done at the end of transfer, when FMPSMBUS_AUTOEND_MODE enable */
2083
2084 /* Call the corresponding callback to inform upper layer of End of Transfer */
2085 if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
2086 {
2087 /* Disable Interrupt */
2088 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
2089 hfmpsmbus->PreviousState = hfmpsmbus->State;
2090 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2091
2092 /* Process Unlocked */
2093 __HAL_UNLOCK(hfmpsmbus);
2094
2095 /* Call the corresponding callback to inform upper layer of End of Transfer */
2096 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2097 hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
2098 #else
2099 HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
2100 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2101 }
2102 else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
2103 {
2104 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
2105 hfmpsmbus->PreviousState = hfmpsmbus->State;
2106 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2107
2108 /* Process Unlocked */
2109 __HAL_UNLOCK(hfmpsmbus);
2110
2111 /* Call the corresponding callback to inform upper layer of End of Transfer */
2112 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2113 hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
2114 #else
2115 HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
2116 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2117 }
2118 else
2119 {
2120 /* Nothing to do */
2121 }
2122 }
2123 else
2124 {
2125 /* Nothing to do */
2126 }
2127 }
2128 }
2129 else
2130 {
2131 /* Nothing to do */
2132 }
2133
2134 /* Process Unlocked */
2135 __HAL_UNLOCK(hfmpsmbus);
2136
2137 return HAL_OK;
2138 }
2139 /**
2140 * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
2141 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
2142 * the configuration information for the specified FMPSMBUS.
2143 * @param StatusFlags Value of Interrupt Flags.
2144 * @retval HAL status
2145 */
FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t StatusFlags)2146 static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
2147 {
2148 uint8_t TransferDirection;
2149 uint16_t SlaveAddrCode;
2150
2151 /* Process Locked */
2152 __HAL_LOCK(hfmpsmbus);
2153
2154 if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
2155 {
2156 /* Check that FMPSMBUS transfer finished */
2157 /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
2158 /* Mean XferCount == 0*/
2159 /* So clear Flag NACKF only */
2160 if (hfmpsmbus->XferCount == 0U)
2161 {
2162 /* Clear NACK Flag */
2163 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
2164
2165 /* Process Unlocked */
2166 __HAL_UNLOCK(hfmpsmbus);
2167 }
2168 else
2169 {
2170 /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
2171 /* Clear NACK Flag */
2172 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
2173
2174 /* Set HAL State to "Idle" State, mean to LISTEN state */
2175 /* So reset Slave Busy state */
2176 hfmpsmbus->PreviousState = hfmpsmbus->State;
2177 hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
2178 hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
2179
2180 /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
2181 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
2182
2183 /* Set ErrorCode corresponding to a Non-Acknowledge */
2184 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
2185
2186 /* Process Unlocked */
2187 __HAL_UNLOCK(hfmpsmbus);
2188
2189 /* Call the Error callback to inform upper layer */
2190 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2191 hfmpsmbus->ErrorCallback(hfmpsmbus);
2192 #else
2193 HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
2194 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2195 }
2196 }
2197 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_ADDR) != RESET)
2198 {
2199 TransferDirection = (uint8_t)(FMPSMBUS_GET_DIR(hfmpsmbus));
2200 SlaveAddrCode = (uint16_t)(FMPSMBUS_GET_ADDR_MATCH(hfmpsmbus));
2201
2202 /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
2203 /* Other ADDRInterrupt will be treat in next Listen usecase */
2204 __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, FMPSMBUS_IT_ADDRI);
2205
2206 /* Process Unlocked */
2207 __HAL_UNLOCK(hfmpsmbus);
2208
2209 /* Call Slave Addr callback */
2210 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2211 hfmpsmbus->AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
2212 #else
2213 HAL_FMPSMBUS_AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
2214 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2215 }
2216 else if ((FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET) ||
2217 (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET))
2218 {
2219 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
2220 {
2221 /* Read data from RXDR */
2222 *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
2223
2224 /* Increment Buffer pointer */
2225 hfmpsmbus->pBuffPtr++;
2226
2227 hfmpsmbus->XferSize--;
2228 hfmpsmbus->XferCount--;
2229
2230 if (hfmpsmbus->XferCount == 1U)
2231 {
2232 /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
2233 /* or only the last Byte of Transfer */
2234 /* So reset the RELOAD bit mode */
2235 hfmpsmbus->XferOptions &= ~FMPSMBUS_RELOAD_MODE;
2236 FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions, FMPSMBUS_NO_STARTSTOP);
2237 }
2238 else if (hfmpsmbus->XferCount == 0U)
2239 {
2240 /* Last Byte is received, disable Interrupt */
2241 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
2242
2243 /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_FMPSMBUS_STATE_LISTEN */
2244 hfmpsmbus->PreviousState = hfmpsmbus->State;
2245 hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
2246
2247 /* Process Unlocked */
2248 __HAL_UNLOCK(hfmpsmbus);
2249
2250 /* Call the corresponding callback to inform upper layer of End of Transfer */
2251 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2252 hfmpsmbus->SlaveRxCpltCallback(hfmpsmbus);
2253 #else
2254 HAL_FMPSMBUS_SlaveRxCpltCallback(hfmpsmbus);
2255 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2256 }
2257 else
2258 {
2259 /* Set Reload for next Bytes */
2260 FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1,
2261 FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
2262 FMPSMBUS_NO_STARTSTOP);
2263
2264 /* Ack last Byte Read */
2265 hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
2266 }
2267 }
2268 else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
2269 {
2270 if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
2271 {
2272 if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
2273 {
2274 FMPSMBUS_TransferConfig(hfmpsmbus, 0, MAX_NBYTE_SIZE,
2275 (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
2276 FMPSMBUS_NO_STARTSTOP);
2277 hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
2278 }
2279 else
2280 {
2281 hfmpsmbus->XferSize = hfmpsmbus->XferCount;
2282 FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
2283 FMPSMBUS_NO_STARTSTOP);
2284 /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
2285 /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
2286 if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
2287 {
2288 hfmpsmbus->XferSize--;
2289 hfmpsmbus->XferCount--;
2290 }
2291 }
2292 }
2293 }
2294 else
2295 {
2296 /* Nothing to do */
2297 }
2298 }
2299 else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
2300 {
2301 /* Write data to TXDR only if XferCount not reach "0" */
2302 /* A TXIS flag can be set, during STOP treatment */
2303 /* Check if all Data have already been sent */
2304 /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
2305 if (hfmpsmbus->XferCount > 0U)
2306 {
2307 /* Write data to TXDR */
2308 hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
2309
2310 /* Increment Buffer pointer */
2311 hfmpsmbus->pBuffPtr++;
2312
2313 hfmpsmbus->XferCount--;
2314 hfmpsmbus->XferSize--;
2315 }
2316
2317 if (hfmpsmbus->XferCount == 0U)
2318 {
2319 /* Last Byte is Transmitted */
2320 /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_FMPSMBUS_STATE_LISTEN */
2321 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
2322 hfmpsmbus->PreviousState = hfmpsmbus->State;
2323 hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
2324
2325 /* Process Unlocked */
2326 __HAL_UNLOCK(hfmpsmbus);
2327
2328 /* Call the corresponding callback to inform upper layer of End of Transfer */
2329 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2330 hfmpsmbus->SlaveTxCpltCallback(hfmpsmbus);
2331 #else
2332 HAL_FMPSMBUS_SlaveTxCpltCallback(hfmpsmbus);
2333 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2334 }
2335 }
2336 else
2337 {
2338 /* Nothing to do */
2339 }
2340
2341 /* Check if STOPF is set */
2342 if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
2343 {
2344 if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
2345 {
2346 /* Store Last receive data if any */
2347 if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_RXNE) != RESET)
2348 {
2349 /* Read data from RXDR */
2350 *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
2351
2352 /* Increment Buffer pointer */
2353 hfmpsmbus->pBuffPtr++;
2354
2355 if ((hfmpsmbus->XferSize > 0U))
2356 {
2357 hfmpsmbus->XferSize--;
2358 hfmpsmbus->XferCount--;
2359 }
2360 }
2361
2362 /* Disable RX and TX Interrupts */
2363 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
2364
2365 /* Disable ADDR Interrupt */
2366 FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
2367
2368 /* Disable Address Acknowledge */
2369 hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_NACK;
2370
2371 /* Clear Configuration Register 2 */
2372 FMPSMBUS_RESET_CR2(hfmpsmbus);
2373
2374 /* Clear STOP Flag */
2375 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
2376
2377 /* Clear ADDR flag */
2378 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
2379
2380 hfmpsmbus->XferOptions = 0;
2381 hfmpsmbus->PreviousState = hfmpsmbus->State;
2382 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2383
2384 /* Process Unlocked */
2385 __HAL_UNLOCK(hfmpsmbus);
2386
2387 /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
2388 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2389 hfmpsmbus->ListenCpltCallback(hfmpsmbus);
2390 #else
2391 HAL_FMPSMBUS_ListenCpltCallback(hfmpsmbus);
2392 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2393 }
2394 }
2395
2396 /* Process Unlocked */
2397 __HAL_UNLOCK(hfmpsmbus);
2398
2399 return HAL_OK;
2400 }
2401 /**
2402 * @brief Manage the enabling of Interrupts.
2403 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
2404 * the configuration information for the specified FMPSMBUS.
2405 * @param InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
2406 * @retval HAL status
2407 */
FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t InterruptRequest)2408 static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
2409 {
2410 uint32_t tmpisr = 0UL;
2411
2412 if ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT)
2413 {
2414 /* Enable ERR interrupt */
2415 tmpisr |= FMPSMBUS_IT_ERRI;
2416 }
2417
2418 if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
2419 {
2420 /* Enable ADDR, STOP interrupt */
2421 tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_ERRI;
2422 }
2423
2424 if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
2425 {
2426 /* Enable ERR, TC, STOP, NACK, RXI interrupt */
2427 tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI;
2428 }
2429
2430 if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
2431 {
2432 /* Enable ERR, TC, STOP, NACK, TXI interrupt */
2433 tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI;
2434 }
2435
2436 /* Enable interrupts only at the end */
2437 /* to avoid the risk of FMPSMBUS interrupt handle execution before */
2438 /* all interrupts requested done */
2439 __HAL_FMPSMBUS_ENABLE_IT(hfmpsmbus, tmpisr);
2440 }
2441 /**
2442 * @brief Manage the disabling of Interrupts.
2443 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
2444 * the configuration information for the specified FMPSMBUS.
2445 * @param InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
2446 * @retval HAL status
2447 */
FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t InterruptRequest)2448 static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
2449 {
2450 uint32_t tmpisr = 0UL;
2451 uint32_t tmpstate = hfmpsmbus->State;
2452
2453 if ((tmpstate == HAL_FMPSMBUS_STATE_READY) && ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT))
2454 {
2455 /* Disable ERR interrupt */
2456 tmpisr |= FMPSMBUS_IT_ERRI;
2457 }
2458
2459 if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
2460 {
2461 /* Disable TC, STOP, NACK and TXI interrupt */
2462 tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_TXI;
2463
2464 if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
2465 && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
2466 {
2467 /* Disable ERR interrupt */
2468 tmpisr |= FMPSMBUS_IT_ERRI;
2469 }
2470
2471 if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
2472 {
2473 /* Disable STOP and NACK interrupt */
2474 tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
2475 }
2476 }
2477
2478 if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
2479 {
2480 /* Disable TC, STOP, NACK and RXI interrupt */
2481 tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_RXI;
2482
2483 if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
2484 && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
2485 {
2486 /* Disable ERR interrupt */
2487 tmpisr |= FMPSMBUS_IT_ERRI;
2488 }
2489
2490 if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
2491 {
2492 /* Disable STOP and NACK interrupt */
2493 tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
2494 }
2495 }
2496
2497 if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
2498 {
2499 /* Disable ADDR, STOP and NACK interrupt */
2500 tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
2501
2502 if (FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
2503 {
2504 /* Disable ERR interrupt */
2505 tmpisr |= FMPSMBUS_IT_ERRI;
2506 }
2507 }
2508
2509 /* Disable interrupts only at the end */
2510 /* to avoid a breaking situation like at "t" time */
2511 /* all disable interrupts request are not done */
2512 __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, tmpisr);
2513 }
2514
2515 /**
2516 * @brief FMPSMBUS interrupts error handler.
2517 * @param hfmpsmbus FMPSMBUS handle.
2518 * @retval None
2519 */
FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef * hfmpsmbus)2520 static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
2521 {
2522 uint32_t itflags = READ_REG(hfmpsmbus->Instance->ISR);
2523 uint32_t itsources = READ_REG(hfmpsmbus->Instance->CR1);
2524 uint32_t tmpstate;
2525 uint32_t tmperror;
2526
2527 /* FMPSMBUS Bus error interrupt occurred ------------------------------------*/
2528 if (((itflags & FMPSMBUS_FLAG_BERR) == FMPSMBUS_FLAG_BERR) && \
2529 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2530 {
2531 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BERR;
2532
2533 /* Clear BERR flag */
2534 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BERR);
2535 }
2536
2537 /* FMPSMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
2538 if (((itflags & FMPSMBUS_FLAG_OVR) == FMPSMBUS_FLAG_OVR) && \
2539 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2540 {
2541 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_OVR;
2542
2543 /* Clear OVR flag */
2544 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_OVR);
2545 }
2546
2547 /* FMPSMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
2548 if (((itflags & FMPSMBUS_FLAG_ARLO) == FMPSMBUS_FLAG_ARLO) && \
2549 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2550 {
2551 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ARLO;
2552
2553 /* Clear ARLO flag */
2554 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ARLO);
2555 }
2556
2557 /* FMPSMBUS Timeout error interrupt occurred ---------------------------------------------*/
2558 if (((itflags & FMPSMBUS_FLAG_TIMEOUT) == FMPSMBUS_FLAG_TIMEOUT) && \
2559 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2560 {
2561 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BUSTIMEOUT;
2562
2563 /* Clear TIMEOUT flag */
2564 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TIMEOUT);
2565 }
2566
2567 /* FMPSMBUS Alert error interrupt occurred -----------------------------------------------*/
2568 if (((itflags & FMPSMBUS_FLAG_ALERT) == FMPSMBUS_FLAG_ALERT) && \
2569 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2570 {
2571 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ALERT;
2572
2573 /* Clear ALERT flag */
2574 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
2575 }
2576
2577 /* FMPSMBUS Packet Error Check error interrupt occurred ----------------------------------*/
2578 if (((itflags & FMPSMBUS_FLAG_PECERR) == FMPSMBUS_FLAG_PECERR) && \
2579 ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
2580 {
2581 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_PECERR;
2582
2583 /* Clear PEC error flag */
2584 __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_PECERR);
2585 }
2586
2587 /* Store current volatile hfmpsmbus->State, misra rule */
2588 tmperror = hfmpsmbus->ErrorCode;
2589
2590 /* Call the Error Callback in case of Error detected */
2591 if ((tmperror != HAL_FMPSMBUS_ERROR_NONE) && (tmperror != HAL_FMPSMBUS_ERROR_ACKF))
2592 {
2593 /* Do not Reset the HAL state in case of ALERT error */
2594 if ((tmperror & HAL_FMPSMBUS_ERROR_ALERT) != HAL_FMPSMBUS_ERROR_ALERT)
2595 {
2596 /* Store current volatile hfmpsmbus->State, misra rule */
2597 tmpstate = hfmpsmbus->State;
2598
2599 if (((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
2600 || ((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX))
2601 {
2602 /* Reset only HAL_FMPSMBUS_STATE_SLAVE_BUSY_XX */
2603 /* keep HAL_FMPSMBUS_STATE_LISTEN if set */
2604 hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
2605 hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
2606 }
2607 }
2608
2609 /* Call the Error callback to inform upper layer */
2610 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
2611 hfmpsmbus->ErrorCallback(hfmpsmbus);
2612 #else
2613 HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
2614 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
2615 }
2616 }
2617
2618 /**
2619 * @brief Handle FMPSMBUS Communication Timeout.
2620 * @param hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
2621 * the configuration information for the specified FMPSMBUS.
2622 * @param Flag Specifies the FMPSMBUS flag to check.
2623 * @param Status The new Flag status (SET or RESET).
2624 * @param Timeout Timeout duration
2625 * @retval HAL status
2626 */
FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint32_t Flag,FlagStatus Status,uint32_t Timeout)2627 static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
2628 FlagStatus Status, uint32_t Timeout)
2629 {
2630 uint32_t tickstart = HAL_GetTick();
2631
2632 /* Wait until flag is set */
2633 while ((FlagStatus)(__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, Flag)) == Status)
2634 {
2635 /* Check for the Timeout */
2636 if (Timeout != HAL_MAX_DELAY)
2637 {
2638 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
2639 {
2640 hfmpsmbus->PreviousState = hfmpsmbus->State;
2641 hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
2642
2643 /* Update FMPSMBUS error code */
2644 hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
2645
2646 /* Process Unlocked */
2647 __HAL_UNLOCK(hfmpsmbus);
2648
2649 return HAL_ERROR;
2650 }
2651 }
2652 }
2653
2654 return HAL_OK;
2655 }
2656
2657 /**
2658 * @brief Handle FMPSMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
2659 * @param hfmpsmbus FMPSMBUS handle.
2660 * @param DevAddress specifies the slave address to be programmed.
2661 * @param Size specifies the number of bytes to be programmed.
2662 * This parameter must be a value between 0 and 255.
2663 * @param Mode New state of the FMPSMBUS START condition generation.
2664 * This parameter can be one or a combination of the following values:
2665 * @arg @ref FMPSMBUS_RELOAD_MODE Enable Reload mode.
2666 * @arg @ref FMPSMBUS_AUTOEND_MODE Enable Automatic end mode.
2667 * @arg @ref FMPSMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
2668 * @arg @ref FMPSMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
2669 * @param Request New state of the FMPSMBUS START condition generation.
2670 * This parameter can be one of the following values:
2671 * @arg @ref FMPSMBUS_NO_STARTSTOP Don't Generate stop and start condition.
2672 * @arg @ref FMPSMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
2673 * @arg @ref FMPSMBUS_GENERATE_START_READ Generate Restart for read request.
2674 * @arg @ref FMPSMBUS_GENERATE_START_WRITE Generate Restart for write request.
2675 * @retval None
2676 */
FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef * hfmpsmbus,uint16_t DevAddress,uint8_t Size,uint32_t Mode,uint32_t Request)2677 static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t Size,
2678 uint32_t Mode, uint32_t Request)
2679 {
2680 /* Check the parameters */
2681 assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
2682 assert_param(IS_FMPSMBUS_TRANSFER_MODE(Mode));
2683 assert_param(IS_FMPSMBUS_TRANSFER_REQUEST(Request));
2684
2685 /* update CR2 register */
2686 MODIFY_REG(hfmpsmbus->Instance->CR2,
2687 ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
2688 (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - FMPI2C_CR2_RD_WRN_Pos))) | \
2689 FMPI2C_CR2_START | FMPI2C_CR2_STOP | FMPI2C_CR2_PECBYTE)), \
2690 (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
2691 (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
2692 (uint32_t)Mode | (uint32_t)Request));
2693 }
2694
2695 /**
2696 * @brief Convert FMPSMBUSx OTHER_xxx XferOptions to functional XferOptions.
2697 * @param hfmpsmbus FMPSMBUS handle.
2698 * @retval None
2699 */
FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef * hfmpsmbus)2700 static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus)
2701 {
2702 /* if user set XferOptions to FMPSMBUS_OTHER_FRAME_NO_PEC */
2703 /* it request implicitly to generate a restart condition */
2704 /* set XferOptions to FMPSMBUS_FIRST_FRAME */
2705 if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_NO_PEC)
2706 {
2707 hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME;
2708 }
2709 /* else if user set XferOptions to FMPSMBUS_OTHER_FRAME_WITH_PEC */
2710 /* it request implicitly to generate a restart condition */
2711 /* set XferOptions to FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE */
2712 else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_WITH_PEC)
2713 {
2714 hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE;
2715 }
2716 /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
2717 /* it request implicitly to generate a restart condition */
2718 /* then generate a stop condition at the end of transfer */
2719 /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC */
2720 else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
2721 {
2722 hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
2723 }
2724 /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
2725 /* it request implicitly to generate a restart condition */
2726 /* then generate a stop condition at the end of transfer */
2727 /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC */
2728 else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
2729 {
2730 hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
2731 }
2732 else
2733 {
2734 /* Nothing to do */
2735 }
2736 }
2737 /**
2738 * @}
2739 */
2740
2741 #endif /* FMPI2C_CR1_PE */
2742 #endif /* HAL_FMPSMBUS_MODULE_ENABLED */
2743 /**
2744 * @}
2745 */
2746
2747 /**
2748 * @}
2749 */
2750