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