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