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