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