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