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