STM32F479xx HAL User Manual
stm32f4xx_hal_fmpsmbus.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_fmpsmbus.c
00004   * @author  MCD Application Team
00005   * @brief   FMPSMBUS HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the System Management Bus (SMBus) peripheral,
00008   *          based on I2C principles of operation :
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State and Errors functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017     [..]
00018     The FMPSMBUS HAL driver can be used as follows:
00019 
00020     (#) Declare a FMPSMBUS_HandleTypeDef handle structure, for example:
00021         FMPSMBUS_HandleTypeDef  hfmpsmbus;
00022 
00023     (#)Initialize the FMPSMBUS low level resources by implementing the HAL_FMPSMBUS_MspInit() API:
00024         (##) Enable the FMPSMBUSx interface clock
00025         (##) FMPSMBUS pins configuration
00026             (+++) Enable the clock for the FMPSMBUS GPIOs
00027             (+++) Configure FMPSMBUS pins as alternate function open-drain
00028         (##) NVIC configuration if you need to use interrupt process
00029             (+++) Configure the FMPSMBUSx interrupt priority
00030             (+++) Enable the NVIC FMPSMBUS IRQ Channel
00031 
00032     (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
00033         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
00034         Peripheral mode and Packet Error Check mode in the hfmpsmbus Init structure.
00035 
00036     (#) Initialize the FMPSMBUS registers by calling the HAL_FMPSMBUS_Init() API:
00037         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00038              by calling the customized HAL_FMPSMBUS_MspInit(&hfmpsmbus) API.
00039 
00040     (#) To check if target device is ready for communication, use the function HAL_FMPSMBUS_IsDeviceReady()
00041 
00042     (#) For FMPSMBUS IO operations, only one mode of operations is available within this driver
00043 
00044     *** Interrupt mode IO operation ***
00045     ===================================
00046     [..]
00047       (+) Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode using HAL_FMPSMBUS_Master_Transmit_IT()
00048       (++) At transmission end of transfer HAL_FMPSMBUS_MasterTxCpltCallback() is executed and user can
00049            add his own code by customization of function pointer HAL_FMPSMBUS_MasterTxCpltCallback()
00050       (+) Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode using HAL_FMPSMBUS_Master_Receive_IT()
00051       (++) At reception end of transfer HAL_FMPSMBUS_MasterRxCpltCallback() is executed and user can
00052            add his own code by customization of function pointer HAL_FMPSMBUS_MasterRxCpltCallback()
00053       (+) Abort a master/host FMPSMBUS process communication with Interrupt using HAL_FMPSMBUS_Master_Abort_IT()
00054       (++) The associated previous transfer callback is called at the end of abort process
00055       (++) mean HAL_FMPSMBUS_MasterTxCpltCallback() in case of previous state was master transmit
00056       (++) mean HAL_FMPSMBUS_MasterRxCpltCallback() in case of previous state was master receive
00057       (+) Enable/disable the Address listen mode in slave/device or host/slave FMPSMBUS mode
00058            using HAL_FMPSMBUS_EnableListen_IT() HAL_FMPSMBUS_DisableListen_IT()
00059       (++) When address slave/device FMPSMBUS match, HAL_FMPSMBUS_AddrCallback() is executed and user can
00060            add his own code to check the Address Match Code and the transmission direction request by master/host (Write/Read).
00061       (++) At Listen mode end HAL_FMPSMBUS_ListenCpltCallback() is executed and user can
00062            add his own code by customization of function pointer HAL_FMPSMBUS_ListenCpltCallback()
00063       (+) Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode using HAL_FMPSMBUS_Slave_Transmit_IT()
00064       (++) At transmission end of transfer HAL_FMPSMBUS_SlaveTxCpltCallback() is executed and user can
00065            add his own code by customization of function pointer HAL_FMPSMBUS_SlaveTxCpltCallback()
00066       (+) Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode using HAL_FMPSMBUS_Slave_Receive_IT()
00067       (++) At reception end of transfer HAL_FMPSMBUS_SlaveRxCpltCallback() is executed and user can
00068            add his own code by customization of function pointer HAL_FMPSMBUS_SlaveRxCpltCallback()
00069       (+) Enable/Disable the FMPSMBUS alert mode using HAL_FMPSMBUS_EnableAlert_IT() HAL_FMPSMBUS_DisableAlert_IT()
00070       (++) When FMPSMBUS Alert is generated HAL_FMPSMBUS_ErrorCallback() is executed and user can
00071            add his own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
00072            to check the Alert Error Code using function HAL_FMPSMBUS_GetError()
00073       (+) Get HAL state machine or error values using HAL_FMPSMBUS_GetState() or HAL_FMPSMBUS_GetError()
00074       (+) In case of transfer Error, HAL_FMPSMBUS_ErrorCallback() function is executed and user can
00075            add his own code by customization of function pointer HAL_FMPSMBUS_ErrorCallback()
00076            to check the Error Code using function HAL_FMPSMBUS_GetError()
00077 
00078      *** FMPSMBUS HAL driver macros list ***
00079      ==================================
00080      [..]
00081        Below the list of most used macros in FMPSMBUS HAL driver.
00082 
00083       (+) __HAL_FMPSMBUS_ENABLE:      Enable the FMPSMBUS peripheral
00084       (+) __HAL_FMPSMBUS_DISABLE:     Disable the FMPSMBUS peripheral
00085       (+) __HAL_FMPSMBUS_GET_FLAG:    Check whether the specified FMPSMBUS flag is set or not
00086       (+) __HAL_FMPSMBUS_CLEAR_FLAG:  Clear the specified FMPSMBUS pending flag
00087       (+) __HAL_FMPSMBUS_ENABLE_IT:   Enable the specified FMPSMBUS interrupt
00088       (+) __HAL_FMPSMBUS_DISABLE_IT:  Disable the specified FMPSMBUS interrupt
00089 
00090      *** Callback registration ***
00091      =============================================
00092     [..]
00093      The compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS when set to 1
00094      allows the user to configure dynamically the driver callbacks.
00095      Use Functions HAL_FMPSMBUS_RegisterCallback() or HAL_FMPSMBUS_RegisterAddrCallback()
00096      to register an interrupt callback.
00097     [..]
00098      Function HAL_FMPSMBUS_RegisterCallback() allows to register following callbacks:
00099        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00100        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00101        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00102        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00103        (+) ListenCpltCallback   : callback for end of listen mode.
00104        (+) ErrorCallback        : callback for error detection.
00105        (+) MspInitCallback      : callback for Msp Init.
00106        (+) MspDeInitCallback    : callback for Msp DeInit.
00107      This function takes as parameters the HAL peripheral handle, the Callback ID
00108      and a pointer to the user callback function.
00109     [..]
00110      For specific callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_RegisterAddrCallback.
00111     [..]
00112      Use function HAL_FMPSMBUS_UnRegisterCallback to reset a callback to the default
00113      weak function.
00114      HAL_FMPSMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
00115      and the Callback ID.
00116      This function allows to reset following callbacks:
00117        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00118        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00119        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00120        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00121        (+) ListenCpltCallback   : callback for end of listen mode.
00122        (+) ErrorCallback        : callback for error detection.
00123        (+) MspInitCallback      : callback for Msp Init.
00124        (+) MspDeInitCallback    : callback for Msp DeInit.
00125     [..]
00126      For callback AddrCallback use dedicated register callbacks : HAL_FMPSMBUS_UnRegisterAddrCallback.
00127     [..]
00128      By default, after the HAL_FMPSMBUS_Init() and when the state is HAL_FMPI2C_STATE_RESET
00129      all callbacks are set to the corresponding weak functions:
00130      examples HAL_FMPSMBUS_MasterTxCpltCallback(), HAL_FMPSMBUS_MasterRxCpltCallback().
00131      Exception done for MspInit and MspDeInit functions that are
00132      reset to the legacy weak functions in the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit() only when
00133      these callbacks are null (not registered beforehand).
00134      If MspInit or MspDeInit are not null, the HAL_FMPSMBUS_Init()/ HAL_FMPSMBUS_DeInit()
00135      keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00136     [..]
00137      Callbacks can be registered/unregistered in HAL_FMPI2C_STATE_READY state only.
00138      Exception done MspInit/MspDeInit functions that can be registered/unregistered
00139      in HAL_FMPI2C_STATE_READY or HAL_FMPI2C_STATE_RESET state,
00140      thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00141      Then, the user first registers the MspInit/MspDeInit user callbacks
00142      using HAL_FMPSMBUS_RegisterCallback() before calling HAL_FMPSMBUS_DeInit()
00143      or HAL_FMPSMBUS_Init() function.
00144     [..]
00145      When the compilation flag USE_HAL_FMPSMBUS_REGISTER_CALLBACKS is set to 0 or
00146      not defined, the callback registration feature is not available and all callbacks
00147      are set to the corresponding weak functions.
00148 
00149      [..]
00150        (@) You can refer to the FMPSMBUS HAL driver header file for more useful macros
00151 
00152   @endverbatim
00153   ******************************************************************************
00154   * @attention
00155   *
00156   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00157   * All rights reserved.</center></h2>
00158   *
00159   * This software component is licensed by ST under BSD 3-Clause license,
00160   * the "License"; You may not use this file except in compliance with the
00161   * License. You may obtain a copy of the License at:
00162   *                        opensource.org/licenses/BSD-3-Clause
00163   *
00164   ******************************************************************************
00165   */
00166 
00167 /* Includes ------------------------------------------------------------------*/
00168 #include "stm32f4xx_hal.h"
00169 
00170 /** @addtogroup STM32F4xx_HAL_Driver
00171   * @{
00172   */
00173 
00174 /** @defgroup FMPSMBUS FMPSMBUS
00175   * @brief FMPSMBUS HAL module driver
00176   * @{
00177   */
00178 
00179 #ifdef HAL_FMPSMBUS_MODULE_ENABLED
00180 
00181 #if defined(FMPI2C_CR1_PE)
00182 /* Private typedef -----------------------------------------------------------*/
00183 /* Private constants ---------------------------------------------------------*/
00184 /** @defgroup FMPSMBUS_Private_Define FMPSMBUS Private Constants
00185   * @{
00186   */
00187 #define TIMING_CLEAR_MASK   (0xF0FFFFFFUL)     /*!< FMPSMBUS TIMING clear register Mask */
00188 #define HAL_TIMEOUT_ADDR    (10000U)           /*!< 10 s  */
00189 #define HAL_TIMEOUT_BUSY    (25U)              /*!< 25 ms */
00190 #define HAL_TIMEOUT_DIR     (25U)              /*!< 25 ms */
00191 #define HAL_TIMEOUT_RXNE    (25U)              /*!< 25 ms */
00192 #define HAL_TIMEOUT_STOPF   (25U)              /*!< 25 ms */
00193 #define HAL_TIMEOUT_TC      (25U)              /*!< 25 ms */
00194 #define HAL_TIMEOUT_TCR     (25U)              /*!< 25 ms */
00195 #define HAL_TIMEOUT_TXIS    (25U)              /*!< 25 ms */
00196 #define MAX_NBYTE_SIZE      255U
00197 /**
00198   * @}
00199   */
00200 
00201 /* Private macro -------------------------------------------------------------*/
00202 /* Private variables ---------------------------------------------------------*/
00203 /* Private function prototypes -----------------------------------------------*/
00204 /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
00205   * @{
00206   */
00207 static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
00208                                                          FlagStatus Status, uint32_t Timeout);
00209 
00210 static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
00211 static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest);
00212 static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
00213 static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags);
00214 
00215 static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus);
00216 
00217 static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus);
00218 
00219 static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus,  uint16_t DevAddress, uint8_t Size,
00220                                     uint32_t Mode, uint32_t Request);
00221 /**
00222   * @}
00223   */
00224 
00225 /* Exported functions --------------------------------------------------------*/
00226 
00227 /** @defgroup FMPSMBUS_Exported_Functions FMPSMBUS Exported Functions
00228   * @{
00229   */
00230 
00231 /** @defgroup FMPSMBUS_Exported_Functions_Group1 Initialization and de-initialization functions
00232   *  @brief    Initialization and Configuration functions
00233   *
00234 @verbatim
00235  ===============================================================================
00236               ##### Initialization and de-initialization functions #####
00237  ===============================================================================
00238     [..]  This subsection provides a set of functions allowing to initialize and
00239           deinitialize the FMPSMBUSx peripheral:
00240 
00241       (+) User must Implement HAL_FMPSMBUS_MspInit() function in which he configures
00242           all related peripherals resources (CLOCK, GPIO, IT and NVIC ).
00243 
00244       (+) Call the function HAL_FMPSMBUS_Init() to configure the selected device with
00245           the selected configuration:
00246         (++) Clock Timing
00247         (++) Bus Timeout
00248         (++) Analog Filer mode
00249         (++) Own Address 1
00250         (++) Addressing mode (Master, Slave)
00251         (++) Dual Addressing mode
00252         (++) Own Address 2
00253         (++) Own Address 2 Mask
00254         (++) General call mode
00255         (++) Nostretch mode
00256         (++) Packet Error Check mode
00257         (++) Peripheral mode
00258 
00259 
00260       (+) Call the function HAL_FMPSMBUS_DeInit() to restore the default configuration
00261           of the selected FMPSMBUSx peripheral.
00262 
00263       (+) Enable/Disable Analog/Digital filters with HAL_FMPSMBUS_ConfigAnalogFilter() and
00264           HAL_FMPSMBUS_ConfigDigitalFilter().
00265 
00266 @endverbatim
00267   * @{
00268   */
00269 
00270 /**
00271   * @brief  Initialize the FMPSMBUS according to the specified parameters
00272   *         in the FMPSMBUS_InitTypeDef and initialize the associated handle.
00273   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00274   *                the configuration information for the specified FMPSMBUS.
00275   * @retval HAL status
00276   */
00277 HAL_StatusTypeDef HAL_FMPSMBUS_Init(FMPSMBUS_HandleTypeDef *hfmpsmbus)
00278 {
00279   /* Check the FMPSMBUS handle allocation */
00280   if (hfmpsmbus == NULL)
00281   {
00282     return HAL_ERROR;
00283   }
00284 
00285   /* Check the parameters */
00286   assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
00287   assert_param(IS_FMPSMBUS_ANALOG_FILTER(hfmpsmbus->Init.AnalogFilter));
00288   assert_param(IS_FMPSMBUS_OWN_ADDRESS1(hfmpsmbus->Init.OwnAddress1));
00289   assert_param(IS_FMPSMBUS_ADDRESSING_MODE(hfmpsmbus->Init.AddressingMode));
00290   assert_param(IS_FMPSMBUS_DUAL_ADDRESS(hfmpsmbus->Init.DualAddressMode));
00291   assert_param(IS_FMPSMBUS_OWN_ADDRESS2(hfmpsmbus->Init.OwnAddress2));
00292   assert_param(IS_FMPSMBUS_OWN_ADDRESS2_MASK(hfmpsmbus->Init.OwnAddress2Masks));
00293   assert_param(IS_FMPSMBUS_GENERAL_CALL(hfmpsmbus->Init.GeneralCallMode));
00294   assert_param(IS_FMPSMBUS_NO_STRETCH(hfmpsmbus->Init.NoStretchMode));
00295   assert_param(IS_FMPSMBUS_PEC(hfmpsmbus->Init.PacketErrorCheckMode));
00296   assert_param(IS_FMPSMBUS_PERIPHERAL_MODE(hfmpsmbus->Init.PeripheralMode));
00297 
00298   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_RESET)
00299   {
00300     /* Allocate lock resource and initialize it */
00301     hfmpsmbus->Lock = HAL_UNLOCKED;
00302 
00303 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
00304     hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00305     hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00306     hfmpsmbus->SlaveTxCpltCallback  = HAL_FMPSMBUS_SlaveTxCpltCallback;  /* Legacy weak SlaveTxCpltCallback  */
00307     hfmpsmbus->SlaveRxCpltCallback  = HAL_FMPSMBUS_SlaveRxCpltCallback;  /* Legacy weak SlaveRxCpltCallback  */
00308     hfmpsmbus->ListenCpltCallback   = HAL_FMPSMBUS_ListenCpltCallback;   /* Legacy weak ListenCpltCallback   */
00309     hfmpsmbus->ErrorCallback        = HAL_FMPSMBUS_ErrorCallback;        /* Legacy weak ErrorCallback        */
00310     hfmpsmbus->AddrCallback         = HAL_FMPSMBUS_AddrCallback;         /* Legacy weak AddrCallback         */
00311 
00312     if (hfmpsmbus->MspInitCallback == NULL)
00313     {
00314       hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit; /* Legacy weak MspInit  */
00315     }
00316 
00317     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00318     hfmpsmbus->MspInitCallback(hfmpsmbus);
00319 #else
00320     /* Init the low level hardware : GPIO, CLOCK, NVIC */
00321     HAL_FMPSMBUS_MspInit(hfmpsmbus);
00322 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
00323   }
00324 
00325   hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
00326 
00327   /* Disable the selected FMPSMBUS peripheral */
00328   __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
00329 
00330   /*---------------------------- FMPSMBUSx TIMINGR Configuration ------------------------*/
00331   /* Configure FMPSMBUSx: Frequency range */
00332   hfmpsmbus->Instance->TIMINGR = hfmpsmbus->Init.Timing & TIMING_CLEAR_MASK;
00333 
00334   /*---------------------------- FMPSMBUSx TIMEOUTR Configuration ------------------------*/
00335   /* Configure FMPSMBUSx: Bus Timeout  */
00336   hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TIMOUTEN;
00337   hfmpsmbus->Instance->TIMEOUTR &= ~FMPI2C_TIMEOUTR_TEXTEN;
00338   hfmpsmbus->Instance->TIMEOUTR = hfmpsmbus->Init.SMBusTimeout;
00339 
00340   /*---------------------------- FMPSMBUSx OAR1 Configuration -----------------------*/
00341   /* Configure FMPSMBUSx: Own Address1 and ack own address1 mode */
00342   hfmpsmbus->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN;
00343 
00344   if (hfmpsmbus->Init.OwnAddress1 != 0UL)
00345   {
00346     if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_7BIT)
00347     {
00348       hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpsmbus->Init.OwnAddress1);
00349     }
00350     else /* FMPSMBUS_ADDRESSINGMODE_10BIT */
00351     {
00352       hfmpsmbus->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpsmbus->Init.OwnAddress1);
00353     }
00354   }
00355 
00356   /*---------------------------- FMPSMBUSx CR2 Configuration ------------------------*/
00357   /* Configure FMPSMBUSx: Addressing Master mode */
00358   if (hfmpsmbus->Init.AddressingMode == FMPSMBUS_ADDRESSINGMODE_10BIT)
00359   {
00360     hfmpsmbus->Instance->CR2 = (FMPI2C_CR2_ADD10);
00361   }
00362   /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process) */
00363   /* AUTOEND and NACK bit will be manage during Transfer process */
00364   hfmpsmbus->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK);
00365 
00366   /*---------------------------- FMPSMBUSx OAR2 Configuration -----------------------*/
00367   /* Configure FMPSMBUSx: Dual mode and Own Address2 */
00368   hfmpsmbus->Instance->OAR2 = (hfmpsmbus->Init.DualAddressMode | hfmpsmbus->Init.OwnAddress2 | \
00369                             (hfmpsmbus->Init.OwnAddress2Masks << 8U));
00370 
00371   /*---------------------------- FMPSMBUSx CR1 Configuration ------------------------*/
00372   /* Configure FMPSMBUSx: Generalcall and NoStretch mode */
00373   hfmpsmbus->Instance->CR1 = (hfmpsmbus->Init.GeneralCallMode | hfmpsmbus->Init.NoStretchMode | \
00374                            hfmpsmbus->Init.PacketErrorCheckMode | hfmpsmbus->Init.PeripheralMode | \
00375                            hfmpsmbus->Init.AnalogFilter);
00376 
00377   /* Enable Slave Byte Control only in case of Packet Error Check is enabled
00378      and FMPSMBUS Peripheral is set in Slave mode */
00379   if ((hfmpsmbus->Init.PacketErrorCheckMode == FMPSMBUS_PEC_ENABLE) && \
00380       ((hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE) || \
00381        (hfmpsmbus->Init.PeripheralMode == FMPSMBUS_PERIPHERAL_MODE_FMPSMBUS_SLAVE_ARP)))
00382   {
00383     hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
00384   }
00385 
00386   /* Enable the selected FMPSMBUS peripheral */
00387   __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
00388 
00389   hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
00390   hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
00391   hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
00392 
00393   return HAL_OK;
00394 }
00395 
00396 /**
00397   * @brief  DeInitialize the FMPSMBUS peripheral.
00398   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00399   *                the configuration information for the specified FMPSMBUS.
00400   * @retval HAL status
00401   */
00402 HAL_StatusTypeDef HAL_FMPSMBUS_DeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
00403 {
00404   /* Check the FMPSMBUS handle allocation */
00405   if (hfmpsmbus == NULL)
00406   {
00407     return HAL_ERROR;
00408   }
00409 
00410   /* Check the parameters */
00411   assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
00412 
00413   hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
00414 
00415   /* Disable the FMPSMBUS Peripheral Clock */
00416   __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
00417 
00418 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
00419   if (hfmpsmbus->MspDeInitCallback == NULL)
00420   {
00421     hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit; /* Legacy weak MspDeInit  */
00422   }
00423 
00424   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00425   hfmpsmbus->MspDeInitCallback(hfmpsmbus);
00426 #else
00427   /* DeInit the low level hardware: GPIO, CLOCK, NVIC */
00428   HAL_FMPSMBUS_MspDeInit(hfmpsmbus);
00429 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
00430 
00431   hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
00432   hfmpsmbus->PreviousState =  HAL_FMPSMBUS_STATE_RESET;
00433   hfmpsmbus->State = HAL_FMPSMBUS_STATE_RESET;
00434 
00435   /* Release Lock */
00436   __HAL_UNLOCK(hfmpsmbus);
00437 
00438   return HAL_OK;
00439 }
00440 
00441 /**
00442   * @brief Initialize the FMPSMBUS MSP.
00443   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00444   *                the configuration information for the specified FMPSMBUS.
00445   * @retval None
00446   */
00447 __weak void HAL_FMPSMBUS_MspInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
00448 {
00449   /* Prevent unused argument(s) compilation warning */
00450   UNUSED(hfmpsmbus);
00451 
00452   /* NOTE : This function should not be modified, when the callback is needed,
00453             the HAL_FMPSMBUS_MspInit could be implemented in the user file
00454    */
00455 }
00456 
00457 /**
00458   * @brief DeInitialize the FMPSMBUS MSP.
00459   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00460   *                the configuration information for the specified FMPSMBUS.
00461   * @retval None
00462   */
00463 __weak void HAL_FMPSMBUS_MspDeInit(FMPSMBUS_HandleTypeDef *hfmpsmbus)
00464 {
00465   /* Prevent unused argument(s) compilation warning */
00466   UNUSED(hfmpsmbus);
00467 
00468   /* NOTE : This function should not be modified, when the callback is needed,
00469             the HAL_FMPSMBUS_MspDeInit could be implemented in the user file
00470    */
00471 }
00472 
00473 /**
00474   * @brief  Configure Analog noise filter.
00475   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00476   *                the configuration information for the specified FMPSMBUS.
00477   * @param  AnalogFilter This parameter can be one of the following values:
00478   *         @arg @ref FMPSMBUS_ANALOGFILTER_ENABLE
00479   *         @arg @ref FMPSMBUS_ANALOGFILTER_DISABLE
00480   * @retval HAL status
00481   */
00482 HAL_StatusTypeDef HAL_FMPSMBUS_ConfigAnalogFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t AnalogFilter)
00483 {
00484   /* Check the parameters */
00485   assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
00486   assert_param(IS_FMPSMBUS_ANALOG_FILTER(AnalogFilter));
00487 
00488   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
00489   {
00490     /* Process Locked */
00491     __HAL_LOCK(hfmpsmbus);
00492 
00493     hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
00494 
00495     /* Disable the selected FMPSMBUS peripheral */
00496     __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
00497 
00498     /* Reset ANOFF bit */
00499     hfmpsmbus->Instance->CR1 &= ~(FMPI2C_CR1_ANFOFF);
00500 
00501     /* Set analog filter bit*/
00502     hfmpsmbus->Instance->CR1 |= AnalogFilter;
00503 
00504     __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
00505 
00506     hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
00507 
00508     /* Process Unlocked */
00509     __HAL_UNLOCK(hfmpsmbus);
00510 
00511     return HAL_OK;
00512   }
00513   else
00514   {
00515     return HAL_BUSY;
00516   }
00517 }
00518 
00519 /**
00520   * @brief  Configure Digital noise filter.
00521   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00522   *                the configuration information for the specified FMPSMBUS.
00523   * @param  DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F.
00524   * @retval HAL status
00525   */
00526 HAL_StatusTypeDef HAL_FMPSMBUS_ConfigDigitalFilter(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t DigitalFilter)
00527 {
00528   uint32_t tmpreg;
00529 
00530   /* Check the parameters */
00531   assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
00532   assert_param(IS_FMPSMBUS_DIGITAL_FILTER(DigitalFilter));
00533 
00534   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
00535   {
00536     /* Process Locked */
00537     __HAL_LOCK(hfmpsmbus);
00538 
00539     hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
00540 
00541     /* Disable the selected FMPSMBUS peripheral */
00542     __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
00543 
00544     /* Get the old register value */
00545     tmpreg = hfmpsmbus->Instance->CR1;
00546 
00547     /* Reset FMPI2C DNF bits [11:8] */
00548     tmpreg &= ~(FMPI2C_CR1_DNF);
00549 
00550     /* Set FMPI2Cx DNF coefficient */
00551     tmpreg |= DigitalFilter << FMPI2C_CR1_DNF_Pos;
00552 
00553     /* Store the new register value */
00554     hfmpsmbus->Instance->CR1 = tmpreg;
00555 
00556     __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
00557 
00558     hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
00559 
00560     /* Process Unlocked */
00561     __HAL_UNLOCK(hfmpsmbus);
00562 
00563     return HAL_OK;
00564   }
00565   else
00566   {
00567     return HAL_BUSY;
00568   }
00569 }
00570 
00571 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
00572 /**
00573   * @brief  Register a User FMPSMBUS Callback
00574   *         To be used instead of the weak predefined callback
00575   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00576   *                the configuration information for the specified FMPSMBUS.
00577   * @param  CallbackID ID of the callback to be registered
00578   *         This parameter can be one of the following values:
00579   *          @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00580   *          @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00581   *          @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00582   *          @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00583   *          @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00584   *          @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
00585   *          @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
00586   *          @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00587   * @param  pCallback pointer to the Callback function
00588   * @retval HAL status
00589   */
00590 HAL_StatusTypeDef HAL_FMPSMBUS_RegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
00591                                                 HAL_FMPSMBUS_CallbackIDTypeDef CallbackID,
00592                                                 pFMPSMBUS_CallbackTypeDef pCallback)
00593 {
00594   HAL_StatusTypeDef status = HAL_OK;
00595 
00596   if (pCallback == NULL)
00597   {
00598     /* Update the error code */
00599     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00600 
00601     return HAL_ERROR;
00602   }
00603 
00604   /* Process locked */
00605   __HAL_LOCK(hfmpsmbus);
00606 
00607   if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
00608   {
00609     switch (CallbackID)
00610     {
00611       case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
00612         hfmpsmbus->MasterTxCpltCallback = pCallback;
00613         break;
00614 
00615       case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
00616         hfmpsmbus->MasterRxCpltCallback = pCallback;
00617         break;
00618 
00619       case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
00620         hfmpsmbus->SlaveTxCpltCallback = pCallback;
00621         break;
00622 
00623       case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
00624         hfmpsmbus->SlaveRxCpltCallback = pCallback;
00625         break;
00626 
00627       case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
00628         hfmpsmbus->ListenCpltCallback = pCallback;
00629         break;
00630 
00631       case HAL_FMPSMBUS_ERROR_CB_ID :
00632         hfmpsmbus->ErrorCallback = pCallback;
00633         break;
00634 
00635       case HAL_FMPSMBUS_MSPINIT_CB_ID :
00636         hfmpsmbus->MspInitCallback = pCallback;
00637         break;
00638 
00639       case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
00640         hfmpsmbus->MspDeInitCallback = pCallback;
00641         break;
00642 
00643       default :
00644         /* Update the error code */
00645         hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00646 
00647         /* Return error status */
00648         status =  HAL_ERROR;
00649         break;
00650     }
00651   }
00652   else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
00653   {
00654     switch (CallbackID)
00655     {
00656       case HAL_FMPSMBUS_MSPINIT_CB_ID :
00657         hfmpsmbus->MspInitCallback = pCallback;
00658         break;
00659 
00660       case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
00661         hfmpsmbus->MspDeInitCallback = pCallback;
00662         break;
00663 
00664       default :
00665         /* Update the error code */
00666         hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00667 
00668         /* Return error status */
00669         status =  HAL_ERROR;
00670         break;
00671     }
00672   }
00673   else
00674   {
00675     /* Update the error code */
00676     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00677 
00678     /* Return error status */
00679     status =  HAL_ERROR;
00680   }
00681 
00682   /* Release Lock */
00683   __HAL_UNLOCK(hfmpsmbus);
00684   return status;
00685 }
00686 
00687 /**
00688   * @brief  Unregister an FMPSMBUS Callback
00689   *         FMPSMBUS callback is redirected to the weak predefined callback
00690   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00691   *                the configuration information for the specified FMPSMBUS.
00692   * @param  CallbackID ID of the callback to be unregistered
00693   *         This parameter can be one of the following values:
00694   *         This parameter can be one of the following values:
00695   *          @arg @ref HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID
00696   *          @arg @ref HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID
00697   *          @arg @ref HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID
00698   *          @arg @ref HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID
00699   *          @arg @ref HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID Listen Complete callback ID
00700   *          @arg @ref HAL_FMPSMBUS_ERROR_CB_ID Error callback ID
00701   *          @arg @ref HAL_FMPSMBUS_MSPINIT_CB_ID MspInit callback ID
00702   *          @arg @ref HAL_FMPSMBUS_MSPDEINIT_CB_ID MspDeInit callback ID
00703   * @retval HAL status
00704   */
00705 HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
00706                                                   HAL_FMPSMBUS_CallbackIDTypeDef CallbackID)
00707 {
00708   HAL_StatusTypeDef status = HAL_OK;
00709 
00710   /* Process locked */
00711   __HAL_LOCK(hfmpsmbus);
00712 
00713   if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
00714   {
00715     switch (CallbackID)
00716     {
00717       case HAL_FMPSMBUS_MASTER_TX_COMPLETE_CB_ID :
00718         hfmpsmbus->MasterTxCpltCallback = HAL_FMPSMBUS_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */
00719         break;
00720 
00721       case HAL_FMPSMBUS_MASTER_RX_COMPLETE_CB_ID :
00722         hfmpsmbus->MasterRxCpltCallback = HAL_FMPSMBUS_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */
00723         break;
00724 
00725       case HAL_FMPSMBUS_SLAVE_TX_COMPLETE_CB_ID :
00726         hfmpsmbus->SlaveTxCpltCallback = HAL_FMPSMBUS_SlaveTxCpltCallback;   /* Legacy weak SlaveTxCpltCallback  */
00727         break;
00728 
00729       case HAL_FMPSMBUS_SLAVE_RX_COMPLETE_CB_ID :
00730         hfmpsmbus->SlaveRxCpltCallback = HAL_FMPSMBUS_SlaveRxCpltCallback;   /* Legacy weak SlaveRxCpltCallback  */
00731         break;
00732 
00733       case HAL_FMPSMBUS_LISTEN_COMPLETE_CB_ID :
00734         hfmpsmbus->ListenCpltCallback = HAL_FMPSMBUS_ListenCpltCallback;     /* Legacy weak ListenCpltCallback   */
00735         break;
00736 
00737       case HAL_FMPSMBUS_ERROR_CB_ID :
00738         hfmpsmbus->ErrorCallback = HAL_FMPSMBUS_ErrorCallback;               /* Legacy weak ErrorCallback        */
00739         break;
00740 
00741       case HAL_FMPSMBUS_MSPINIT_CB_ID :
00742         hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit;                   /* Legacy weak MspInit              */
00743         break;
00744 
00745       case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
00746         hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00747         break;
00748 
00749       default :
00750         /* Update the error code */
00751         hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00752 
00753         /* Return error status */
00754         status =  HAL_ERROR;
00755         break;
00756     }
00757   }
00758   else if (HAL_FMPSMBUS_STATE_RESET == hfmpsmbus->State)
00759   {
00760     switch (CallbackID)
00761     {
00762       case HAL_FMPSMBUS_MSPINIT_CB_ID :
00763         hfmpsmbus->MspInitCallback = HAL_FMPSMBUS_MspInit;                   /* Legacy weak MspInit              */
00764         break;
00765 
00766       case HAL_FMPSMBUS_MSPDEINIT_CB_ID :
00767         hfmpsmbus->MspDeInitCallback = HAL_FMPSMBUS_MspDeInit;               /* Legacy weak MspDeInit            */
00768         break;
00769 
00770       default :
00771         /* Update the error code */
00772         hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00773 
00774         /* Return error status */
00775         status =  HAL_ERROR;
00776         break;
00777     }
00778   }
00779   else
00780   {
00781     /* Update the error code */
00782     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00783 
00784     /* Return error status */
00785     status =  HAL_ERROR;
00786   }
00787 
00788   /* Release Lock */
00789   __HAL_UNLOCK(hfmpsmbus);
00790   return status;
00791 }
00792 
00793 /**
00794   * @brief  Register the Slave Address Match FMPSMBUS Callback
00795   *         To be used instead of the weak HAL_FMPSMBUS_AddrCallback() predefined callback
00796   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00797   *                the configuration information for the specified FMPSMBUS.
00798   * @param  pCallback pointer to the Address Match Callback function
00799   * @retval HAL status
00800   */
00801 HAL_StatusTypeDef HAL_FMPSMBUS_RegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus,
00802                                                     pFMPSMBUS_AddrCallbackTypeDef pCallback)
00803 {
00804   HAL_StatusTypeDef status = HAL_OK;
00805 
00806   if (pCallback == NULL)
00807   {
00808     /* Update the error code */
00809     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00810 
00811     return HAL_ERROR;
00812   }
00813   /* Process locked */
00814   __HAL_LOCK(hfmpsmbus);
00815 
00816   if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
00817   {
00818     hfmpsmbus->AddrCallback = pCallback;
00819   }
00820   else
00821   {
00822     /* Update the error code */
00823     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00824 
00825     /* Return error status */
00826     status =  HAL_ERROR;
00827   }
00828 
00829   /* Release Lock */
00830   __HAL_UNLOCK(hfmpsmbus);
00831   return status;
00832 }
00833 
00834 /**
00835   * @brief  UnRegister the Slave Address Match FMPSMBUS Callback
00836   *         Info Ready FMPSMBUS Callback is redirected to the weak HAL_FMPSMBUS_AddrCallback() predefined callback
00837   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00838   *                the configuration information for the specified FMPSMBUS.
00839   * @retval HAL status
00840   */
00841 HAL_StatusTypeDef HAL_FMPSMBUS_UnRegisterAddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
00842 {
00843   HAL_StatusTypeDef status = HAL_OK;
00844 
00845   /* Process locked */
00846   __HAL_LOCK(hfmpsmbus);
00847 
00848   if (HAL_FMPSMBUS_STATE_READY == hfmpsmbus->State)
00849   {
00850     hfmpsmbus->AddrCallback = HAL_FMPSMBUS_AddrCallback; /* Legacy weak AddrCallback  */
00851   }
00852   else
00853   {
00854     /* Update the error code */
00855     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_INVALID_CALLBACK;
00856 
00857     /* Return error status */
00858     status =  HAL_ERROR;
00859   }
00860 
00861   /* Release Lock */
00862   __HAL_UNLOCK(hfmpsmbus);
00863   return status;
00864 }
00865 
00866 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
00867 
00868 /**
00869   * @}
00870   */
00871 
00872 /** @defgroup FMPSMBUS_Exported_Functions_Group2 Input and Output operation functions
00873   *  @brief   Data transfers functions
00874   *
00875 @verbatim
00876  ===============================================================================
00877                       ##### IO operation functions #####
00878  ===============================================================================
00879     [..]
00880     This subsection provides a set of functions allowing to manage the FMPSMBUS data
00881     transfers.
00882 
00883     (#) Blocking mode function to check if device is ready for usage is :
00884         (++) HAL_FMPSMBUS_IsDeviceReady()
00885 
00886     (#) There is only one mode of transfer:
00887        (++) Non-Blocking mode : The communication is performed using Interrupts.
00888             These functions return the status of the transfer startup.
00889             The end of the data processing will be indicated through the
00890             dedicated FMPSMBUS IRQ when using Interrupt mode.
00891 
00892     (#) Non-Blocking mode functions with Interrupt are :
00893         (++) HAL_FMPSMBUS_Master_Transmit_IT()
00894         (++) HAL_FMPSMBUS_Master_Receive_IT()
00895         (++) HAL_FMPSMBUS_Slave_Transmit_IT()
00896         (++) HAL_FMPSMBUS_Slave_Receive_IT()
00897         (++) HAL_FMPSMBUS_EnableListen_IT() or alias HAL_FMPSMBUS_EnableListen_IT()
00898         (++) HAL_FMPSMBUS_DisableListen_IT()
00899         (++) HAL_FMPSMBUS_EnableAlert_IT()
00900         (++) HAL_FMPSMBUS_DisableAlert_IT()
00901 
00902     (#) A set of Transfer Complete Callbacks are provided in non-Blocking mode:
00903         (++) HAL_FMPSMBUS_MasterTxCpltCallback()
00904         (++) HAL_FMPSMBUS_MasterRxCpltCallback()
00905         (++) HAL_FMPSMBUS_SlaveTxCpltCallback()
00906         (++) HAL_FMPSMBUS_SlaveRxCpltCallback()
00907         (++) HAL_FMPSMBUS_AddrCallback()
00908         (++) HAL_FMPSMBUS_ListenCpltCallback()
00909         (++) HAL_FMPSMBUS_ErrorCallback()
00910 
00911 @endverbatim
00912   * @{
00913   */
00914 
00915 /**
00916   * @brief  Transmit in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
00917   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
00918   *                the configuration information for the specified FMPSMBUS.
00919   * @param  DevAddress Target device address: The device 7 bits address value
00920   *         in datasheet must be shifted to the left before calling the interface
00921   * @param  pData Pointer to data buffer
00922   * @param  Size Amount of data to be sent
00923   * @param  XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
00924   * @retval HAL status
00925   */
00926 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress,
00927                                                   uint8_t *pData, uint16_t Size, uint32_t XferOptions)
00928 {
00929   uint32_t tmp;
00930 
00931   /* Check the parameters */
00932   assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
00933 
00934   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
00935   {
00936     /* Process Locked */
00937     __HAL_LOCK(hfmpsmbus);
00938 
00939     hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
00940     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
00941     /* Prepare transfer parameters */
00942     hfmpsmbus->pBuffPtr = pData;
00943     hfmpsmbus->XferCount = Size;
00944     hfmpsmbus->XferOptions = XferOptions;
00945 
00946     /* In case of Quick command, remove autoend mode */
00947     /* Manage the stop generation by software */
00948     if (hfmpsmbus->pBuffPtr == NULL)
00949     {
00950       hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
00951     }
00952 
00953     if (Size > MAX_NBYTE_SIZE)
00954     {
00955       hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
00956     }
00957     else
00958     {
00959       hfmpsmbus->XferSize = Size;
00960     }
00961 
00962     /* Send Slave Address */
00963     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
00964     if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
00965     {
00966       FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
00967                            FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
00968                            FMPSMBUS_GENERATE_START_WRITE);
00969     }
00970     else
00971     {
00972       /* If transfer direction not change, do not generate Restart Condition */
00973       /* Mean Previous state is same as current state */
00974 
00975       /* Store current volatile XferOptions, misra rule */
00976       tmp = hfmpsmbus->XferOptions;
00977 
00978       if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) && \
00979           (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
00980       {
00981         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
00982                                 FMPSMBUS_NO_STARTSTOP);
00983       }
00984       /* Else transfer direction change, so generate Restart with new transfer direction */
00985       else
00986       {
00987         /* Convert OTHER_xxx XferOptions if any */
00988         FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
00989 
00990         /* Handle Transfer */
00991         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
00992                              hfmpsmbus->XferOptions,
00993                              FMPSMBUS_GENERATE_START_WRITE);
00994       }
00995 
00996       /* If PEC mode is enable, size to transmit manage by SW part should be Size-1 byte, corresponding to PEC byte */
00997       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
00998       if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
00999       {
01000         hfmpsmbus->XferSize--;
01001         hfmpsmbus->XferCount--;
01002       }
01003     }
01004 
01005     /* Process Unlocked */
01006     __HAL_UNLOCK(hfmpsmbus);
01007 
01008     /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
01009               to avoid the risk of FMPSMBUS interrupt handle execution before current
01010               process unlock */
01011     FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
01012 
01013     return HAL_OK;
01014   }
01015   else
01016   {
01017     return HAL_BUSY;
01018   }
01019 }
01020 
01021 /**
01022   * @brief  Receive in master/host FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
01023   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01024   *                the configuration information for the specified FMPSMBUS.
01025   * @param  DevAddress Target device address: The device 7 bits address value
01026   *         in datasheet must be shifted to the left before calling the interface
01027   * @param  pData Pointer to data buffer
01028   * @param  Size Amount of data to be sent
01029   * @param  XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
01030   * @retval HAL status
01031   */
01032 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint8_t *pData,
01033                                               uint16_t Size, uint32_t XferOptions)
01034 {
01035   uint32_t tmp;
01036 
01037   /* Check the parameters */
01038   assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01039 
01040   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
01041   {
01042     /* Process Locked */
01043     __HAL_LOCK(hfmpsmbus);
01044 
01045     hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
01046     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
01047 
01048     /* Prepare transfer parameters */
01049     hfmpsmbus->pBuffPtr = pData;
01050     hfmpsmbus->XferCount = Size;
01051     hfmpsmbus->XferOptions = XferOptions;
01052 
01053     /* In case of Quick command, remove autoend mode */
01054     /* Manage the stop generation by software */
01055     if (hfmpsmbus->pBuffPtr == NULL)
01056     {
01057       hfmpsmbus->XferOptions &= ~FMPSMBUS_AUTOEND_MODE;
01058     }
01059 
01060     if (Size > MAX_NBYTE_SIZE)
01061     {
01062       hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
01063     }
01064     else
01065     {
01066       hfmpsmbus->XferSize = Size;
01067     }
01068 
01069     /* Send Slave Address */
01070     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
01071     if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
01072     {
01073       FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
01074                            FMPSMBUS_RELOAD_MODE  | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
01075                            FMPSMBUS_GENERATE_START_READ);
01076     }
01077     else
01078     {
01079       /* If transfer direction not change, do not generate Restart Condition */
01080       /* Mean Previous state is same as current state */
01081 
01082       /* Store current volatile XferOptions, Misra rule */
01083       tmp = hfmpsmbus->XferOptions;
01084 
01085       if ((hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) && \
01086           (IS_FMPSMBUS_TRANSFER_OTHER_OPTIONS_REQUEST(tmp) == 0))
01087       {
01088         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
01089                                 FMPSMBUS_NO_STARTSTOP);
01090       }
01091       /* Else transfer direction change, so generate Restart with new transfer direction */
01092       else
01093       {
01094         /* Convert OTHER_xxx XferOptions if any */
01095         FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
01096 
01097         /* Handle Transfer */
01098         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize,
01099                              hfmpsmbus->XferOptions,
01100                              FMPSMBUS_GENERATE_START_READ);
01101       }
01102     }
01103 
01104     /* Process Unlocked */
01105     __HAL_UNLOCK(hfmpsmbus);
01106 
01107     /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
01108               to avoid the risk of FMPSMBUS interrupt handle execution before current
01109               process unlock */
01110     FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
01111 
01112     return HAL_OK;
01113   }
01114   else
01115   {
01116     return HAL_BUSY;
01117   }
01118 }
01119 
01120 /**
01121   * @brief  Abort a master/host FMPSMBUS process communication with Interrupt.
01122   * @note   This abort can be called only if state is ready
01123   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01124   *                the configuration information for the specified FMPSMBUS.
01125   * @param  DevAddress Target device address: The device 7 bits address value
01126   *         in datasheet must be shifted to the left before calling the interface
01127   * @retval HAL status
01128   */
01129 HAL_StatusTypeDef HAL_FMPSMBUS_Master_Abort_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress)
01130 {
01131   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
01132   {
01133     /* Process Locked */
01134     __HAL_LOCK(hfmpsmbus);
01135 
01136     /* Keep the same state as previous */
01137     /* to perform as well the call of the corresponding end of transfer callback */
01138     if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
01139     {
01140       hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_TX;
01141     }
01142     else if (hfmpsmbus->PreviousState == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
01143     {
01144       hfmpsmbus->State = HAL_FMPSMBUS_STATE_MASTER_BUSY_RX;
01145     }
01146     else
01147     {
01148       /* Wrong usage of abort function */
01149       /* This function should be used only in case of abort monitored by master device */
01150       return HAL_ERROR;
01151     }
01152     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
01153 
01154     /* Set NBYTES to 1 to generate a dummy read on FMPSMBUS peripheral */
01155     /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */
01156     FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, 1, FMPSMBUS_AUTOEND_MODE, FMPSMBUS_NO_STARTSTOP);
01157 
01158     /* Process Unlocked */
01159     __HAL_UNLOCK(hfmpsmbus);
01160 
01161     /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
01162               to avoid the risk of FMPSMBUS interrupt handle execution before current
01163               process unlock */
01164     if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
01165     {
01166       FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
01167     }
01168     else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
01169     {
01170       FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
01171     }
01172     else
01173     {
01174       /* Nothing to do */
01175     }
01176 
01177     return HAL_OK;
01178   }
01179   else
01180   {
01181     return HAL_BUSY;
01182   }
01183 }
01184 
01185 /**
01186   * @brief  Transmit in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
01187   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01188   *                the configuration information for the specified FMPSMBUS.
01189   * @param  pData Pointer to data buffer
01190   * @param  Size Amount of data to be sent
01191   * @param  XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
01192   * @retval HAL status
01193   */
01194 HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Transmit_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
01195                                               uint32_t XferOptions)
01196 {
01197   /* Check the parameters */
01198   assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01199 
01200   if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
01201   {
01202     if ((pData == NULL) || (Size == 0UL))
01203     {
01204       hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
01205       return HAL_ERROR;
01206     }
01207 
01208     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
01209     FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_TX);
01210 
01211     /* Process Locked */
01212     __HAL_LOCK(hfmpsmbus);
01213 
01214     hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX | HAL_FMPSMBUS_STATE_LISTEN);
01215     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
01216 
01217     /* Set SBC bit to manage Acknowledge at each bit */
01218     hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
01219 
01220     /* Enable Address Acknowledge */
01221     hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01222 
01223     /* Prepare transfer parameters */
01224     hfmpsmbus->pBuffPtr = pData;
01225     hfmpsmbus->XferCount = Size;
01226     hfmpsmbus->XferOptions = XferOptions;
01227 
01228     /* Convert OTHER_xxx XferOptions if any */
01229     FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
01230 
01231     if (Size > MAX_NBYTE_SIZE)
01232     {
01233       hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
01234     }
01235     else
01236     {
01237       hfmpsmbus->XferSize = Size;
01238     }
01239 
01240     /* Set NBYTES to write and reload if size > MAX_NBYTE_SIZE and generate RESTART */
01241     if ((hfmpsmbus->XferSize < hfmpsmbus->XferCount) && (hfmpsmbus->XferSize == MAX_NBYTE_SIZE))
01242     {
01243       FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize,
01244                            FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
01245                            FMPSMBUS_NO_STARTSTOP);
01246     }
01247     else
01248     {
01249       /* Set NBYTE to transmit */
01250       FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
01251                               FMPSMBUS_NO_STARTSTOP);
01252 
01253       /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
01254       /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
01255       if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
01256       {
01257         hfmpsmbus->XferSize--;
01258         hfmpsmbus->XferCount--;
01259       }
01260     }
01261 
01262     /* Clear ADDR flag after prepare the transfer parameters */
01263     /* This action will generate an acknowledge to the HOST */
01264     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
01265 
01266     /* Process Unlocked */
01267     __HAL_UNLOCK(hfmpsmbus);
01268 
01269     /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
01270               to avoid the risk of FMPSMBUS interrupt handle execution before current
01271               process unlock */
01272     /* REnable ADDR interrupt */
01273     FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX | FMPSMBUS_IT_ADDR);
01274 
01275     return HAL_OK;
01276   }
01277   else
01278   {
01279     return HAL_BUSY;
01280   }
01281 }
01282 
01283 /**
01284   * @brief  Receive in slave/device FMPSMBUS mode an amount of data in non-blocking mode with Interrupt.
01285   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01286   *                the configuration information for the specified FMPSMBUS.
01287   * @param  pData Pointer to data buffer
01288   * @param  Size Amount of data to be sent
01289   * @param  XferOptions Options of Transfer, value of @ref FMPSMBUS_XferOptions_definition
01290   * @retval HAL status
01291   */
01292 HAL_StatusTypeDef HAL_FMPSMBUS_Slave_Receive_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t *pData, uint16_t Size,
01293                                              uint32_t XferOptions)
01294 {
01295   /* Check the parameters */
01296   assert_param(IS_FMPSMBUS_TRANSFER_OPTIONS_REQUEST(XferOptions));
01297 
01298   if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
01299   {
01300     if ((pData == NULL) || (Size == 0UL))
01301     {
01302       hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_INVALID_PARAM;
01303       return HAL_ERROR;
01304     }
01305 
01306     /* Disable Interrupts, to prevent preemption during treatment in case of multicall */
01307     FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR | FMPSMBUS_IT_RX);
01308 
01309     /* Process Locked */
01310     __HAL_LOCK(hfmpsmbus);
01311 
01312     hfmpsmbus->State = (HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX | HAL_FMPSMBUS_STATE_LISTEN);
01313     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
01314 
01315     /* Set SBC bit to manage Acknowledge at each bit */
01316     hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_SBC;
01317 
01318     /* Enable Address Acknowledge */
01319     hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
01320 
01321     /* Prepare transfer parameters */
01322     hfmpsmbus->pBuffPtr = pData;
01323     hfmpsmbus->XferSize = Size;
01324     hfmpsmbus->XferCount = Size;
01325     hfmpsmbus->XferOptions = XferOptions;
01326 
01327     /* Convert OTHER_xxx XferOptions if any */
01328     FMPSMBUS_ConvertOtherXferOptions(hfmpsmbus);
01329 
01330     /* Set NBYTE to receive */
01331     /* If XferSize equal "1", or XferSize equal "2" with PEC requested (mean 1 data byte + 1 PEC byte */
01332     /* no need to set RELOAD bit mode, a ACK will be automatically generated in that case */
01333     /* else need to set RELOAD bit mode to generate an automatic ACK at each byte Received */
01334     /* This RELOAD bit will be reset for last BYTE to be receive in FMPSMBUS_Slave_ISR */
01335     if (((FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL) && (hfmpsmbus->XferSize == 2U)) || (hfmpsmbus->XferSize == 1U))
01336     {
01337       FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
01338                               FMPSMBUS_NO_STARTSTOP);
01339     }
01340     else
01341     {
01342       FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions | FMPSMBUS_RELOAD_MODE, FMPSMBUS_NO_STARTSTOP);
01343     }
01344 
01345     /* Clear ADDR flag after prepare the transfer parameters */
01346     /* This action will generate an acknowledge to the HOST */
01347     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
01348 
01349     /* Process Unlocked */
01350     __HAL_UNLOCK(hfmpsmbus);
01351 
01352     /* Note : The FMPSMBUS interrupts must be enabled after unlocking current process
01353               to avoid the risk of FMPSMBUS interrupt handle execution before current
01354               process unlock */
01355     /* REnable ADDR interrupt */
01356     FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_ADDR);
01357 
01358     return HAL_OK;
01359   }
01360   else
01361   {
01362     return HAL_BUSY;
01363   }
01364 }
01365 
01366 /**
01367   * @brief  Enable the Address listen mode with Interrupt.
01368   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01369   *                the configuration information for the specified FMPSMBUS.
01370   * @retval HAL status
01371   */
01372 HAL_StatusTypeDef HAL_FMPSMBUS_EnableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01373 {
01374   hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
01375 
01376   /* Enable the Address Match interrupt */
01377   FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
01378 
01379   return HAL_OK;
01380 }
01381 
01382 /**
01383   * @brief  Disable the Address listen mode with Interrupt.
01384   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01385   *                the configuration information for the specified FMPSMBUS.
01386   * @retval HAL status
01387   */
01388 HAL_StatusTypeDef HAL_FMPSMBUS_DisableListen_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01389 {
01390   /* Disable Address listen mode only if a transfer is not ongoing */
01391   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_LISTEN)
01392   {
01393     hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01394 
01395     /* Disable the Address Match interrupt */
01396     FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
01397 
01398     return HAL_OK;
01399   }
01400   else
01401   {
01402     return HAL_BUSY;
01403   }
01404 }
01405 
01406 /**
01407   * @brief  Enable the FMPSMBUS alert mode with Interrupt.
01408   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01409   *                the configuration information for the specified FMPSMBUSx peripheral.
01410   * @retval HAL status
01411   */
01412 HAL_StatusTypeDef HAL_FMPSMBUS_EnableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01413 {
01414   /* Enable SMBus alert */
01415   hfmpsmbus->Instance->CR1 |= FMPI2C_CR1_ALERTEN;
01416 
01417   /* Clear ALERT flag */
01418   __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
01419 
01420   /* Enable Alert Interrupt */
01421   FMPSMBUS_Enable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
01422 
01423   return HAL_OK;
01424 }
01425 /**
01426   * @brief  Disable the FMPSMBUS alert mode with Interrupt.
01427   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01428   *                the configuration information for the specified FMPSMBUSx peripheral.
01429   * @retval HAL status
01430   */
01431 HAL_StatusTypeDef HAL_FMPSMBUS_DisableAlert_IT(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01432 {
01433   /* Enable SMBus alert */
01434   hfmpsmbus->Instance->CR1 &= ~FMPI2C_CR1_ALERTEN;
01435 
01436   /* Disable Alert Interrupt */
01437   FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ALERT);
01438 
01439   return HAL_OK;
01440 }
01441 
01442 /**
01443   * @brief  Check if target device is ready for communication.
01444   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01445   *                the configuration information for the specified FMPSMBUS.
01446   * @param  DevAddress Target device address: The device 7 bits address value
01447   *         in datasheet must be shifted to the left before calling the interface
01448   * @param  Trials Number of trials
01449   * @param  Timeout Timeout duration
01450   * @retval HAL status
01451   */
01452 HAL_StatusTypeDef HAL_FMPSMBUS_IsDeviceReady(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint16_t DevAddress, uint32_t Trials,
01453                                           uint32_t Timeout)
01454 {
01455   uint32_t tickstart;
01456 
01457   __IO uint32_t FMPSMBUS_Trials = 0UL;
01458 
01459   FlagStatus tmp1;
01460   FlagStatus tmp2;
01461 
01462   if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_READY)
01463   {
01464     if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BUSY) != RESET)
01465     {
01466       return HAL_BUSY;
01467     }
01468 
01469     /* Process Locked */
01470     __HAL_LOCK(hfmpsmbus);
01471 
01472     hfmpsmbus->State = HAL_FMPSMBUS_STATE_BUSY;
01473     hfmpsmbus->ErrorCode = HAL_FMPSMBUS_ERROR_NONE;
01474 
01475     do
01476     {
01477       /* Generate Start */
01478       hfmpsmbus->Instance->CR2 = FMPSMBUS_GENERATE_START(hfmpsmbus->Init.AddressingMode, DevAddress);
01479 
01480       /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
01481       /* Wait until STOPF flag is set or a NACK flag is set*/
01482       tickstart = HAL_GetTick();
01483 
01484       tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01485       tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
01486 
01487       while ((tmp1 == RESET) && (tmp2 == RESET))
01488       {
01489         if (Timeout != HAL_MAX_DELAY)
01490         {
01491           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
01492           {
01493             /* Device is ready */
01494             hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01495 
01496             /* Update FMPSMBUS error code */
01497             hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
01498 
01499             /* Process Unlocked */
01500             __HAL_UNLOCK(hfmpsmbus);
01501             return HAL_ERROR;
01502           }
01503         }
01504 
01505         tmp1 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01506         tmp2 = __HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
01507       }
01508 
01509       /* Check if the NACKF flag has not been set */
01510       if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF) == RESET)
01511       {
01512         /* Wait until STOPF flag is reset */
01513         if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01514         {
01515           return HAL_ERROR;
01516         }
01517 
01518         /* Clear STOP Flag */
01519         __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01520 
01521         /* Device is ready */
01522         hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01523 
01524         /* Process Unlocked */
01525         __HAL_UNLOCK(hfmpsmbus);
01526 
01527         return HAL_OK;
01528       }
01529       else
01530       {
01531         /* Wait until STOPF flag is reset */
01532         if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01533         {
01534           return HAL_ERROR;
01535         }
01536 
01537         /* Clear NACK Flag */
01538         __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
01539 
01540         /* Clear STOP Flag, auto generated with autoend*/
01541         __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01542       }
01543 
01544       /* Check if the maximum allowed number of trials has been reached */
01545       if (FMPSMBUS_Trials == Trials)
01546       {
01547         /* Generate Stop */
01548         hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
01549 
01550         /* Wait until STOPF flag is reset */
01551         if (FMPSMBUS_WaitOnFlagUntilTimeout(hfmpsmbus, FMPSMBUS_FLAG_STOPF, RESET, Timeout) != HAL_OK)
01552         {
01553           return HAL_ERROR;
01554         }
01555 
01556         /* Clear STOP Flag */
01557         __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01558       }
01559 
01560       /* Increment Trials */
01561       FMPSMBUS_Trials++;
01562     } while (FMPSMBUS_Trials < Trials);
01563 
01564     hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01565 
01566     /* Update FMPSMBUS error code */
01567     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
01568 
01569     /* Process Unlocked */
01570     __HAL_UNLOCK(hfmpsmbus);
01571 
01572     return HAL_ERROR;
01573   }
01574   else
01575   {
01576     return HAL_BUSY;
01577   }
01578 }
01579 /**
01580   * @}
01581   */
01582 
01583 /** @defgroup FMPSMBUS_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
01584   * @{
01585   */
01586 
01587 /**
01588   * @brief  Handle FMPSMBUS event interrupt request.
01589   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01590   *                the configuration information for the specified FMPSMBUS.
01591   * @retval None
01592   */
01593 void HAL_FMPSMBUS_EV_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01594 {
01595   /* Use a local variable to store the current ISR flags */
01596   /* This action will avoid a wrong treatment due to ISR flags change during interrupt handler */
01597   uint32_t tmpisrvalue = READ_REG(hfmpsmbus->Instance->ISR);
01598   uint32_t tmpcr1value = READ_REG(hfmpsmbus->Instance->CR1);
01599 
01600   /* FMPSMBUS in mode Transmitter ---------------------------------------------------*/
01601   if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
01602                                             FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI)) != RESET) &&
01603       ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TXIS) != RESET) ||
01604        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
01605        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
01606        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
01607        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
01608   {
01609     /* Slave mode selected */
01610     if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
01611     {
01612       (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
01613     }
01614     /* Master mode selected */
01615     else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_TX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
01616     {
01617       (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
01618     }
01619     else
01620     {
01621       /* Nothing to do */
01622     }
01623   }
01624 
01625   /* FMPSMBUS in mode Receiver ----------------------------------------------------*/
01626   if ((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, (FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI |
01627                                             FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI)) != RESET) &&
01628       ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_RXNE) != RESET) ||
01629        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TCR) != RESET) ||
01630        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_TC) != RESET) ||
01631        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
01632        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
01633   {
01634     /* Slave mode selected */
01635     if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
01636     {
01637       (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
01638     }
01639     /* Master mode selected */
01640     else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_MASTER_BUSY_RX) == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
01641     {
01642       (void)FMPSMBUS_Master_ISR(hfmpsmbus, tmpisrvalue);
01643     }
01644     else
01645     {
01646       /* Nothing to do */
01647     }
01648   }
01649 
01650   /* FMPSMBUS in mode Listener Only --------------------------------------------------*/
01651   if (((FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_ADDRI) != RESET) ||
01652        (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_STOPI) != RESET) ||
01653        (FMPSMBUS_CHECK_IT_SOURCE(tmpcr1value, FMPSMBUS_IT_NACKI) != RESET)) &&
01654       ((FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_ADDR) != RESET) ||
01655        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_STOPF) != RESET) ||
01656        (FMPSMBUS_CHECK_FLAG(tmpisrvalue, FMPSMBUS_FLAG_AF) != RESET)))
01657   {
01658     if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
01659     {
01660       (void)FMPSMBUS_Slave_ISR(hfmpsmbus, tmpisrvalue);
01661     }
01662   }
01663 }
01664 
01665 /**
01666   * @brief  Handle FMPSMBUS error interrupt request.
01667   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01668   *                the configuration information for the specified FMPSMBUS.
01669   * @retval None
01670   */
01671 void HAL_FMPSMBUS_ER_IRQHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01672 {
01673   FMPSMBUS_ITErrorHandler(hfmpsmbus);
01674 }
01675 
01676 /**
01677   * @brief  Master Tx Transfer completed callback.
01678   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01679   *                the configuration information for the specified FMPSMBUS.
01680   * @retval None
01681   */
01682 __weak void HAL_FMPSMBUS_MasterTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01683 {
01684   /* Prevent unused argument(s) compilation warning */
01685   UNUSED(hfmpsmbus);
01686 
01687   /* NOTE : This function should not be modified, when the callback is needed,
01688             the HAL_FMPSMBUS_MasterTxCpltCallback() could be implemented in the user file
01689    */
01690 }
01691 
01692 /**
01693   * @brief  Master Rx Transfer completed callback.
01694   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01695   *                the configuration information for the specified FMPSMBUS.
01696   * @retval None
01697   */
01698 __weak void HAL_FMPSMBUS_MasterRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01699 {
01700   /* Prevent unused argument(s) compilation warning */
01701   UNUSED(hfmpsmbus);
01702 
01703   /* NOTE : This function should not be modified, when the callback is needed,
01704             the HAL_FMPSMBUS_MasterRxCpltCallback() could be implemented in the user file
01705    */
01706 }
01707 
01708 /** @brief  Slave Tx Transfer completed callback.
01709   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01710   *                the configuration information for the specified FMPSMBUS.
01711   * @retval None
01712   */
01713 __weak void HAL_FMPSMBUS_SlaveTxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01714 {
01715   /* Prevent unused argument(s) compilation warning */
01716   UNUSED(hfmpsmbus);
01717 
01718   /* NOTE : This function should not be modified, when the callback is needed,
01719             the HAL_FMPSMBUS_SlaveTxCpltCallback() could be implemented in the user file
01720    */
01721 }
01722 
01723 /**
01724   * @brief  Slave Rx Transfer completed callback.
01725   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01726   *                the configuration information for the specified FMPSMBUS.
01727   * @retval None
01728   */
01729 __weak void HAL_FMPSMBUS_SlaveRxCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01730 {
01731   /* Prevent unused argument(s) compilation warning */
01732   UNUSED(hfmpsmbus);
01733 
01734   /* NOTE : This function should not be modified, when the callback is needed,
01735             the HAL_FMPSMBUS_SlaveRxCpltCallback() could be implemented in the user file
01736    */
01737 }
01738 
01739 /**
01740   * @brief  Slave Address Match callback.
01741   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01742   *                the configuration information for the specified FMPSMBUS.
01743   * @param  TransferDirection Master request Transfer Direction (Write/Read)
01744   * @param  AddrMatchCode Address Match Code
01745   * @retval None
01746   */
01747 __weak void HAL_FMPSMBUS_AddrCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint8_t TransferDirection,
01748                                       uint16_t AddrMatchCode)
01749 {
01750   /* Prevent unused argument(s) compilation warning */
01751   UNUSED(hfmpsmbus);
01752   UNUSED(TransferDirection);
01753   UNUSED(AddrMatchCode);
01754 
01755   /* NOTE : This function should not be modified, when the callback is needed,
01756             the HAL_FMPSMBUS_AddrCallback() could be implemented in the user file
01757    */
01758 }
01759 
01760 /**
01761   * @brief  Listen Complete callback.
01762   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01763   *                the configuration information for the specified FMPSMBUS.
01764   * @retval None
01765   */
01766 __weak void HAL_FMPSMBUS_ListenCpltCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01767 {
01768   /* Prevent unused argument(s) compilation warning */
01769   UNUSED(hfmpsmbus);
01770 
01771   /* NOTE : This function should not be modified, when the callback is needed,
01772             the HAL_FMPSMBUS_ListenCpltCallback() could be implemented in the user file
01773    */
01774 }
01775 
01776 /**
01777   * @brief  FMPSMBUS error callback.
01778   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01779   *                the configuration information for the specified FMPSMBUS.
01780   * @retval None
01781   */
01782 __weak void HAL_FMPSMBUS_ErrorCallback(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01783 {
01784   /* Prevent unused argument(s) compilation warning */
01785   UNUSED(hfmpsmbus);
01786 
01787   /* NOTE : This function should not be modified, when the callback is needed,
01788             the HAL_FMPSMBUS_ErrorCallback() could be implemented in the user file
01789    */
01790 }
01791 
01792 /**
01793   * @}
01794   */
01795 
01796 /** @defgroup FMPSMBUS_Exported_Functions_Group3 Peripheral State and Errors functions
01797   *  @brief   Peripheral State and Errors functions
01798   *
01799 @verbatim
01800  ===============================================================================
01801             ##### Peripheral State and Errors functions #####
01802  ===============================================================================
01803     [..]
01804     This subsection permits to get in run-time the status of the peripheral
01805     and the data flow.
01806 
01807 @endverbatim
01808   * @{
01809   */
01810 
01811 /**
01812   * @brief  Return the FMPSMBUS handle state.
01813   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01814   *                the configuration information for the specified FMPSMBUS.
01815   * @retval HAL state
01816   */
01817 uint32_t HAL_FMPSMBUS_GetState(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01818 {
01819   /* Return FMPSMBUS handle state */
01820   return hfmpsmbus->State;
01821 }
01822 
01823 /**
01824   * @brief  Return the FMPSMBUS error code.
01825   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01826   *              the configuration information for the specified FMPSMBUS.
01827   * @retval FMPSMBUS Error Code
01828   */
01829 uint32_t HAL_FMPSMBUS_GetError(FMPSMBUS_HandleTypeDef *hfmpsmbus)
01830 {
01831   return hfmpsmbus->ErrorCode;
01832 }
01833 
01834 /**
01835   * @}
01836   */
01837 
01838 /**
01839   * @}
01840   */
01841 
01842 /** @addtogroup FMPSMBUS_Private_Functions FMPSMBUS Private Functions
01843   *  @brief   Data transfers Private functions
01844   * @{
01845   */
01846 
01847 /**
01848   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Master Mode.
01849   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
01850   *                the configuration information for the specified FMPSMBUS.
01851   * @param  StatusFlags Value of Interrupt Flags.
01852   * @retval HAL status
01853   */
01854 static HAL_StatusTypeDef FMPSMBUS_Master_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
01855 {
01856   uint16_t DevAddress;
01857 
01858   /* Process Locked */
01859   __HAL_LOCK(hfmpsmbus);
01860 
01861   if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
01862   {
01863     /* Clear NACK Flag */
01864     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
01865 
01866     /* Set corresponding Error Code */
01867     /* No need to generate STOP, it is automatically done */
01868     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
01869 
01870     /* Process Unlocked */
01871     __HAL_UNLOCK(hfmpsmbus);
01872 
01873     /* Call the Error callback to inform upper layer */
01874 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
01875     hfmpsmbus->ErrorCallback(hfmpsmbus);
01876 #else
01877     HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
01878 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
01879   }
01880   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
01881   {
01882     /* Check and treat errors if errors occurs during STOP process */
01883     FMPSMBUS_ITErrorHandler(hfmpsmbus);
01884 
01885     /* Call the corresponding callback to inform upper layer of End of Transfer */
01886     if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
01887     {
01888       /* Disable Interrupt */
01889       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
01890 
01891       /* Clear STOP Flag */
01892       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01893 
01894       /* Clear Configuration Register 2 */
01895       FMPSMBUS_RESET_CR2(hfmpsmbus);
01896 
01897       /* Flush remaining data in Fifo register in case of error occurs before TXEmpty */
01898       /* Disable the selected FMPSMBUS peripheral */
01899       __HAL_FMPSMBUS_DISABLE(hfmpsmbus);
01900 
01901       hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
01902       hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01903 
01904       /* Process Unlocked */
01905       __HAL_UNLOCK(hfmpsmbus);
01906 
01907       /* Re-enable the selected FMPSMBUS peripheral */
01908       __HAL_FMPSMBUS_ENABLE(hfmpsmbus);
01909 
01910       /* Call the corresponding callback to inform upper layer of End of Transfer */
01911 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
01912       hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
01913 #else
01914       HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
01915 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
01916     }
01917     else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
01918     {
01919       /* Store Last receive data if any */
01920       if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
01921       {
01922         /* Read data from RXDR */
01923         *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
01924 
01925         /* Increment Buffer pointer */
01926         hfmpsmbus->pBuffPtr++;
01927 
01928         if ((hfmpsmbus->XferSize > 0U))
01929         {
01930           hfmpsmbus->XferSize--;
01931           hfmpsmbus->XferCount--;
01932         }
01933       }
01934 
01935       /* Disable Interrupt */
01936       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
01937 
01938       /* Clear STOP Flag */
01939       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
01940 
01941       /* Clear Configuration Register 2 */
01942       FMPSMBUS_RESET_CR2(hfmpsmbus);
01943 
01944       hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
01945       hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
01946 
01947       /* Process Unlocked */
01948       __HAL_UNLOCK(hfmpsmbus);
01949 
01950       /* Call the corresponding callback to inform upper layer of End of Transfer */
01951 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
01952       hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
01953 #else
01954       HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
01955 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
01956     }
01957     else
01958     {
01959       /* Nothing to do */
01960     }
01961   }
01962   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET)
01963   {
01964     /* Read data from RXDR */
01965     *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
01966 
01967     /* Increment Buffer pointer */
01968     hfmpsmbus->pBuffPtr++;
01969 
01970     /* Increment Size counter */
01971     hfmpsmbus->XferSize--;
01972     hfmpsmbus->XferCount--;
01973   }
01974   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
01975   {
01976     /* Write data to TXDR */
01977     hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
01978 
01979     /* Increment Buffer pointer */
01980     hfmpsmbus->pBuffPtr++;
01981 
01982     /* Increment Size counter */
01983     hfmpsmbus->XferSize--;
01984     hfmpsmbus->XferCount--;
01985   }
01986   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET)
01987   {
01988     if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
01989     {
01990       DevAddress = (uint16_t)(hfmpsmbus->Instance->CR2 & FMPI2C_CR2_SADD);
01991 
01992       if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
01993       {
01994         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, MAX_NBYTE_SIZE,
01995                              (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
01996                              FMPSMBUS_NO_STARTSTOP);
01997         hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
01998       }
01999       else
02000       {
02001         hfmpsmbus->XferSize = hfmpsmbus->XferCount;
02002         FMPSMBUS_TransferConfig(hfmpsmbus, DevAddress, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
02003                                 FMPSMBUS_NO_STARTSTOP);
02004         /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
02005         /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
02006         if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
02007         {
02008           hfmpsmbus->XferSize--;
02009           hfmpsmbus->XferCount--;
02010         }
02011       }
02012     }
02013     else if ((hfmpsmbus->XferCount == 0U) && (hfmpsmbus->XferSize == 0U))
02014     {
02015       /* Call TxCpltCallback() if no stop mode is set */
02016       if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
02017       {
02018         /* Call the corresponding callback to inform upper layer of End of Transfer */
02019         if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
02020         {
02021           /* Disable Interrupt */
02022           FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
02023           hfmpsmbus->PreviousState = hfmpsmbus->State;
02024           hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02025 
02026           /* Process Unlocked */
02027           __HAL_UNLOCK(hfmpsmbus);
02028 
02029           /* Call the corresponding callback to inform upper layer of End of Transfer */
02030 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02031           hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
02032 #else
02033           HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
02034 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02035         }
02036         else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
02037         {
02038           FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
02039           hfmpsmbus->PreviousState = hfmpsmbus->State;
02040           hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02041 
02042           /* Process Unlocked */
02043           __HAL_UNLOCK(hfmpsmbus);
02044 
02045           /* Call the corresponding callback to inform upper layer of End of Transfer */
02046 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02047           hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
02048 #else
02049           HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
02050 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02051         }
02052         else
02053         {
02054           /* Nothing to do */
02055         }
02056       }
02057     }
02058     else
02059     {
02060       /* Nothing to do */
02061     }
02062   }
02063   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TC) != RESET)
02064   {
02065     if (hfmpsmbus->XferCount == 0U)
02066     {
02067       /* Specific use case for Quick command */
02068       if (hfmpsmbus->pBuffPtr == NULL)
02069       {
02070         /* Generate a Stop command */
02071         hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_STOP;
02072       }
02073       /* Call TxCpltCallback() if no stop mode is set */
02074       else if (FMPSMBUS_GET_STOP_MODE(hfmpsmbus) != FMPSMBUS_AUTOEND_MODE)
02075       {
02076         /* No Generate Stop, to permit restart mode */
02077         /* The stop will be done at the end of transfer, when FMPSMBUS_AUTOEND_MODE enable */
02078 
02079         /* Call the corresponding callback to inform upper layer of End of Transfer */
02080         if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_TX)
02081         {
02082           /* Disable Interrupt */
02083           FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
02084           hfmpsmbus->PreviousState = hfmpsmbus->State;
02085           hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02086 
02087           /* Process Unlocked */
02088           __HAL_UNLOCK(hfmpsmbus);
02089 
02090           /* Call the corresponding callback to inform upper layer of End of Transfer */
02091 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02092           hfmpsmbus->MasterTxCpltCallback(hfmpsmbus);
02093 #else
02094           HAL_FMPSMBUS_MasterTxCpltCallback(hfmpsmbus);
02095 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02096         }
02097         else if (hfmpsmbus->State == HAL_FMPSMBUS_STATE_MASTER_BUSY_RX)
02098         {
02099           FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
02100           hfmpsmbus->PreviousState = hfmpsmbus->State;
02101           hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02102 
02103           /* Process Unlocked */
02104           __HAL_UNLOCK(hfmpsmbus);
02105 
02106           /* Call the corresponding callback to inform upper layer of End of Transfer */
02107 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02108           hfmpsmbus->MasterRxCpltCallback(hfmpsmbus);
02109 #else
02110           HAL_FMPSMBUS_MasterRxCpltCallback(hfmpsmbus);
02111 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02112         }
02113         else
02114         {
02115           /* Nothing to do */
02116         }
02117       }
02118       else
02119       {
02120         /* Nothing to do */
02121       }
02122     }
02123   }
02124   else
02125   {
02126     /* Nothing to do */
02127   }
02128 
02129   /* Process Unlocked */
02130   __HAL_UNLOCK(hfmpsmbus);
02131 
02132   return HAL_OK;
02133 }
02134 /**
02135   * @brief  Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode.
02136   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
02137   *                the configuration information for the specified FMPSMBUS.
02138   * @param  StatusFlags Value of Interrupt Flags.
02139   * @retval HAL status
02140   */
02141 static HAL_StatusTypeDef FMPSMBUS_Slave_ISR(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t StatusFlags)
02142 {
02143   uint8_t TransferDirection;
02144   uint16_t SlaveAddrCode;
02145 
02146   /* Process Locked */
02147   __HAL_LOCK(hfmpsmbus);
02148 
02149   if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_AF) != RESET)
02150   {
02151     /* Check that FMPSMBUS transfer finished */
02152     /* if yes, normal usecase, a NACK is sent by the HOST when Transfer is finished */
02153     /* Mean XferCount == 0*/
02154     /* So clear Flag NACKF only */
02155     if (hfmpsmbus->XferCount == 0U)
02156     {
02157       /* Clear NACK Flag */
02158       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
02159 
02160       /* Process Unlocked */
02161       __HAL_UNLOCK(hfmpsmbus);
02162     }
02163     else
02164     {
02165       /* if no, error usecase, a Non-Acknowledge of last Data is generated by the HOST*/
02166       /* Clear NACK Flag */
02167       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_AF);
02168 
02169       /* Set HAL State to "Idle" State, mean to LISTEN state */
02170       /* So reset Slave Busy state */
02171       hfmpsmbus->PreviousState = hfmpsmbus->State;
02172       hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
02173       hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
02174 
02175       /* Disable RX/TX Interrupts, keep only ADDR Interrupt */
02176       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
02177 
02178       /* Set ErrorCode corresponding to a Non-Acknowledge */
02179       hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ACKF;
02180 
02181       /* Process Unlocked */
02182       __HAL_UNLOCK(hfmpsmbus);
02183 
02184       /* Call the Error callback to inform upper layer */
02185 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02186       hfmpsmbus->ErrorCallback(hfmpsmbus);
02187 #else
02188       HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
02189 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02190     }
02191   }
02192   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_ADDR) != RESET)
02193   {
02194     TransferDirection = (uint8_t)(FMPSMBUS_GET_DIR(hfmpsmbus));
02195     SlaveAddrCode = (uint16_t)(FMPSMBUS_GET_ADDR_MATCH(hfmpsmbus));
02196 
02197     /* Disable ADDR interrupt to prevent multiple ADDRInterrupt*/
02198     /* Other ADDRInterrupt will be treat in next Listen usecase */
02199     __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, FMPSMBUS_IT_ADDRI);
02200 
02201     /* Process Unlocked */
02202     __HAL_UNLOCK(hfmpsmbus);
02203 
02204     /* Call Slave Addr callback */
02205 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02206     hfmpsmbus->AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
02207 #else
02208     HAL_FMPSMBUS_AddrCallback(hfmpsmbus, TransferDirection, SlaveAddrCode);
02209 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02210   }
02211   else if ((FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_RXNE) != RESET) ||
02212            (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TCR) != RESET))
02213   {
02214     if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX)
02215     {
02216       /* Read data from RXDR */
02217       *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
02218 
02219       /* Increment Buffer pointer */
02220       hfmpsmbus->pBuffPtr++;
02221 
02222       hfmpsmbus->XferSize--;
02223       hfmpsmbus->XferCount--;
02224 
02225       if (hfmpsmbus->XferCount == 1U)
02226       {
02227         /* Receive last Byte, can be PEC byte in case of PEC BYTE enabled */
02228         /* or only the last Byte of Transfer */
02229         /* So reset the RELOAD bit mode */
02230         hfmpsmbus->XferOptions &= ~FMPSMBUS_RELOAD_MODE;
02231         FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1, hfmpsmbus->XferOptions, FMPSMBUS_NO_STARTSTOP);
02232       }
02233       else if (hfmpsmbus->XferCount == 0U)
02234       {
02235         /* Last Byte is received, disable Interrupt */
02236         FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX);
02237 
02238         /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX, keep only HAL_FMPSMBUS_STATE_LISTEN */
02239         hfmpsmbus->PreviousState = hfmpsmbus->State;
02240         hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX);
02241 
02242         /* Process Unlocked */
02243         __HAL_UNLOCK(hfmpsmbus);
02244 
02245         /* Call the corresponding callback to inform upper layer of End of Transfer */
02246 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02247         hfmpsmbus->SlaveRxCpltCallback(hfmpsmbus);
02248 #else
02249         HAL_FMPSMBUS_SlaveRxCpltCallback(hfmpsmbus);
02250 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02251       }
02252       else
02253       {
02254         /* Set Reload for next Bytes */
02255         FMPSMBUS_TransferConfig(hfmpsmbus, 0, 1,
02256                              FMPSMBUS_RELOAD_MODE  | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE),
02257                              FMPSMBUS_NO_STARTSTOP);
02258 
02259         /* Ack last Byte Read */
02260         hfmpsmbus->Instance->CR2 &= ~FMPI2C_CR2_NACK;
02261       }
02262     }
02263     else if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
02264     {
02265       if ((hfmpsmbus->XferCount != 0U) && (hfmpsmbus->XferSize == 0U))
02266       {
02267         if (hfmpsmbus->XferCount > MAX_NBYTE_SIZE)
02268         {
02269           FMPSMBUS_TransferConfig(hfmpsmbus, 0, MAX_NBYTE_SIZE,
02270                                (FMPSMBUS_RELOAD_MODE | (hfmpsmbus->XferOptions & FMPSMBUS_SENDPEC_MODE)),
02271                                FMPSMBUS_NO_STARTSTOP);
02272           hfmpsmbus->XferSize = MAX_NBYTE_SIZE;
02273         }
02274         else
02275         {
02276           hfmpsmbus->XferSize = hfmpsmbus->XferCount;
02277           FMPSMBUS_TransferConfig(hfmpsmbus, 0, (uint8_t)hfmpsmbus->XferSize, hfmpsmbus->XferOptions,
02278                                   FMPSMBUS_NO_STARTSTOP);
02279           /* If PEC mode is enable, size to transmit should be Size-1 byte, corresponding to PEC byte */
02280           /* PEC byte is automatically sent by HW block, no need to manage it in Transmit process */
02281           if (FMPSMBUS_GET_PEC_MODE(hfmpsmbus) != 0UL)
02282           {
02283             hfmpsmbus->XferSize--;
02284             hfmpsmbus->XferCount--;
02285           }
02286         }
02287       }
02288     }
02289     else
02290     {
02291       /* Nothing to do */
02292     }
02293   }
02294   else if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_TXIS) != RESET)
02295   {
02296     /* Write data to TXDR only if XferCount not reach "0" */
02297     /* A TXIS flag can be set, during STOP treatment      */
02298     /* Check if all Data have already been sent */
02299     /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */
02300     if (hfmpsmbus->XferCount > 0U)
02301     {
02302       /* Write data to TXDR */
02303       hfmpsmbus->Instance->TXDR = *hfmpsmbus->pBuffPtr;
02304 
02305       /* Increment Buffer pointer */
02306       hfmpsmbus->pBuffPtr++;
02307 
02308       hfmpsmbus->XferCount--;
02309       hfmpsmbus->XferSize--;
02310     }
02311 
02312     if (hfmpsmbus->XferCount == 0U)
02313     {
02314       /* Last Byte is Transmitted */
02315       /* Remove HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX, keep only HAL_FMPSMBUS_STATE_LISTEN */
02316       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_TX);
02317       hfmpsmbus->PreviousState = hfmpsmbus->State;
02318       hfmpsmbus->State &= ~((uint32_t)HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX);
02319 
02320       /* Process Unlocked */
02321       __HAL_UNLOCK(hfmpsmbus);
02322 
02323       /* Call the corresponding callback to inform upper layer of End of Transfer */
02324 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02325       hfmpsmbus->SlaveTxCpltCallback(hfmpsmbus);
02326 #else
02327       HAL_FMPSMBUS_SlaveTxCpltCallback(hfmpsmbus);
02328 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02329     }
02330   }
02331   else
02332   {
02333     /* Nothing to do */
02334   }
02335 
02336   /* Check if STOPF is set */
02337   if (FMPSMBUS_CHECK_FLAG(StatusFlags, FMPSMBUS_FLAG_STOPF) != RESET)
02338   {
02339     if ((hfmpsmbus->State & HAL_FMPSMBUS_STATE_LISTEN) == HAL_FMPSMBUS_STATE_LISTEN)
02340     {
02341       /* Store Last receive data if any */
02342       if (__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, FMPSMBUS_FLAG_RXNE) != RESET)
02343       {
02344         /* Read data from RXDR */
02345         *hfmpsmbus->pBuffPtr = (uint8_t)(hfmpsmbus->Instance->RXDR);
02346 
02347         /* Increment Buffer pointer */
02348         hfmpsmbus->pBuffPtr++;
02349 
02350         if ((hfmpsmbus->XferSize > 0U))
02351         {
02352           hfmpsmbus->XferSize--;
02353           hfmpsmbus->XferCount--;
02354         }
02355       }
02356 
02357       /* Disable RX and TX Interrupts */
02358       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_RX | FMPSMBUS_IT_TX);
02359 
02360       /* Disable ADDR Interrupt */
02361       FMPSMBUS_Disable_IRQ(hfmpsmbus, FMPSMBUS_IT_ADDR);
02362 
02363       /* Disable Address Acknowledge */
02364       hfmpsmbus->Instance->CR2 |= FMPI2C_CR2_NACK;
02365 
02366       /* Clear Configuration Register 2 */
02367       FMPSMBUS_RESET_CR2(hfmpsmbus);
02368 
02369       /* Clear STOP Flag */
02370       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_STOPF);
02371 
02372       /* Clear ADDR flag */
02373       __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ADDR);
02374 
02375       hfmpsmbus->XferOptions = 0;
02376       hfmpsmbus->PreviousState = hfmpsmbus->State;
02377       hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02378 
02379       /* Process Unlocked */
02380       __HAL_UNLOCK(hfmpsmbus);
02381 
02382       /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */
02383 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02384       hfmpsmbus->ListenCpltCallback(hfmpsmbus);
02385 #else
02386       HAL_FMPSMBUS_ListenCpltCallback(hfmpsmbus);
02387 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02388     }
02389   }
02390 
02391   /* Process Unlocked */
02392   __HAL_UNLOCK(hfmpsmbus);
02393 
02394   return HAL_OK;
02395 }
02396 /**
02397   * @brief  Manage the enabling of Interrupts.
02398   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
02399   *                the configuration information for the specified FMPSMBUS.
02400   * @param  InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
02401   * @retval HAL status
02402   */
02403 static void FMPSMBUS_Enable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
02404 {
02405   uint32_t tmpisr = 0UL;
02406 
02407   if ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT)
02408   {
02409     /* Enable ERR interrupt */
02410     tmpisr |= FMPSMBUS_IT_ERRI;
02411   }
02412 
02413   if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
02414   {
02415     /* Enable ADDR, STOP interrupt */
02416     tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_ERRI;
02417   }
02418 
02419   if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
02420   {
02421     /* Enable ERR, TC, STOP, NACK, RXI interrupt */
02422     tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_TXI;
02423   }
02424 
02425   if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
02426   {
02427     /* Enable ERR, TC, STOP, NACK, TXI interrupt */
02428     tmpisr |= FMPSMBUS_IT_ERRI | FMPSMBUS_IT_TCI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI | FMPSMBUS_IT_RXI;
02429   }
02430 
02431   /* Enable interrupts only at the end */
02432   /* to avoid the risk of FMPSMBUS interrupt handle execution before */
02433   /* all interrupts requested done */
02434   __HAL_FMPSMBUS_ENABLE_IT(hfmpsmbus, tmpisr);
02435 }
02436 /**
02437   * @brief  Manage the disabling of Interrupts.
02438   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
02439   *                the configuration information for the specified FMPSMBUS.
02440   * @param  InterruptRequest Value of @ref FMPSMBUS_Interrupt_configuration_definition.
02441   * @retval HAL status
02442   */
02443 static void FMPSMBUS_Disable_IRQ(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t InterruptRequest)
02444 {
02445   uint32_t tmpisr = 0UL;
02446   uint32_t tmpstate = hfmpsmbus->State;
02447 
02448   if ((tmpstate == HAL_FMPSMBUS_STATE_READY) && ((InterruptRequest & FMPSMBUS_IT_ALERT) == FMPSMBUS_IT_ALERT))
02449   {
02450     /* Disable ERR interrupt */
02451     tmpisr |= FMPSMBUS_IT_ERRI;
02452   }
02453 
02454   if ((InterruptRequest & FMPSMBUS_IT_TX) == FMPSMBUS_IT_TX)
02455   {
02456     /* Disable TC, STOP, NACK and TXI interrupt */
02457     tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_TXI;
02458 
02459     if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
02460         && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
02461     {
02462       /* Disable ERR interrupt */
02463       tmpisr |= FMPSMBUS_IT_ERRI;
02464     }
02465 
02466     if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
02467     {
02468       /* Disable STOP and NACK interrupt */
02469       tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
02470     }
02471   }
02472 
02473   if ((InterruptRequest & FMPSMBUS_IT_RX) == FMPSMBUS_IT_RX)
02474   {
02475     /* Disable TC, STOP, NACK and RXI interrupt */
02476     tmpisr |= FMPSMBUS_IT_TCI | FMPSMBUS_IT_RXI;
02477 
02478     if ((FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
02479         && ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN))
02480     {
02481       /* Disable ERR interrupt */
02482       tmpisr |= FMPSMBUS_IT_ERRI;
02483     }
02484 
02485     if ((tmpstate & HAL_FMPSMBUS_STATE_LISTEN) != HAL_FMPSMBUS_STATE_LISTEN)
02486     {
02487       /* Disable STOP and NACK interrupt */
02488       tmpisr |= FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
02489     }
02490   }
02491 
02492   if ((InterruptRequest & FMPSMBUS_IT_ADDR) == FMPSMBUS_IT_ADDR)
02493   {
02494     /* Disable ADDR, STOP and NACK interrupt */
02495     tmpisr |= FMPSMBUS_IT_ADDRI | FMPSMBUS_IT_STOPI | FMPSMBUS_IT_NACKI;
02496 
02497     if (FMPSMBUS_GET_ALERT_ENABLED(hfmpsmbus) == 0UL)
02498     {
02499       /* Disable ERR interrupt */
02500       tmpisr |= FMPSMBUS_IT_ERRI;
02501     }
02502   }
02503 
02504   /* Disable interrupts only at the end */
02505   /* to avoid a breaking situation like at "t" time */
02506   /* all disable interrupts request are not done */
02507   __HAL_FMPSMBUS_DISABLE_IT(hfmpsmbus, tmpisr);
02508 }
02509 
02510 /**
02511   * @brief  FMPSMBUS interrupts error handler.
02512   * @param  hfmpsmbus FMPSMBUS handle.
02513   * @retval None
02514   */
02515 static void FMPSMBUS_ITErrorHandler(FMPSMBUS_HandleTypeDef *hfmpsmbus)
02516 {
02517   uint32_t itflags   = READ_REG(hfmpsmbus->Instance->ISR);
02518   uint32_t itsources = READ_REG(hfmpsmbus->Instance->CR1);
02519   uint32_t tmpstate;
02520   uint32_t tmperror;
02521 
02522   /* FMPSMBUS Bus error interrupt occurred ------------------------------------*/
02523   if (((itflags & FMPSMBUS_FLAG_BERR) == FMPSMBUS_FLAG_BERR) && \
02524       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02525   {
02526     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BERR;
02527 
02528     /* Clear BERR flag */
02529     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_BERR);
02530   }
02531 
02532   /* FMPSMBUS Over-Run/Under-Run interrupt occurred ----------------------------------------*/
02533   if (((itflags & FMPSMBUS_FLAG_OVR) == FMPSMBUS_FLAG_OVR) && \
02534       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02535   {
02536     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_OVR;
02537 
02538     /* Clear OVR flag */
02539     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_OVR);
02540   }
02541 
02542   /* FMPSMBUS Arbitration Loss error interrupt occurred ------------------------------------*/
02543   if (((itflags & FMPSMBUS_FLAG_ARLO) == FMPSMBUS_FLAG_ARLO) && \
02544       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02545   {
02546     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ARLO;
02547 
02548     /* Clear ARLO flag */
02549     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ARLO);
02550   }
02551 
02552   /* FMPSMBUS Timeout error interrupt occurred ---------------------------------------------*/
02553   if (((itflags & FMPSMBUS_FLAG_TIMEOUT) == FMPSMBUS_FLAG_TIMEOUT) && \
02554       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02555   {
02556     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_BUSTIMEOUT;
02557 
02558     /* Clear TIMEOUT flag */
02559     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_TIMEOUT);
02560   }
02561 
02562   /* FMPSMBUS Alert error interrupt occurred -----------------------------------------------*/
02563   if (((itflags & FMPSMBUS_FLAG_ALERT) == FMPSMBUS_FLAG_ALERT) && \
02564       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02565   {
02566     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_ALERT;
02567 
02568     /* Clear ALERT flag */
02569     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_ALERT);
02570   }
02571 
02572   /* FMPSMBUS Packet Error Check error interrupt occurred ----------------------------------*/
02573   if (((itflags & FMPSMBUS_FLAG_PECERR) == FMPSMBUS_FLAG_PECERR) && \
02574       ((itsources & FMPSMBUS_IT_ERRI) == FMPSMBUS_IT_ERRI))
02575   {
02576     hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_PECERR;
02577 
02578     /* Clear PEC error flag */
02579     __HAL_FMPSMBUS_CLEAR_FLAG(hfmpsmbus, FMPSMBUS_FLAG_PECERR);
02580   }
02581 
02582   /* Store current volatile hfmpsmbus->State, misra rule */
02583   tmperror = hfmpsmbus->ErrorCode;
02584 
02585   /* Call the Error Callback in case of Error detected */
02586   if ((tmperror != HAL_FMPSMBUS_ERROR_NONE) && (tmperror != HAL_FMPSMBUS_ERROR_ACKF))
02587   {
02588     /* Do not Reset the HAL state in case of ALERT error */
02589     if ((tmperror & HAL_FMPSMBUS_ERROR_ALERT) != HAL_FMPSMBUS_ERROR_ALERT)
02590     {
02591       /* Store current volatile hfmpsmbus->State, misra rule */
02592       tmpstate = hfmpsmbus->State;
02593 
02594       if (((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_TX)
02595           || ((tmpstate & HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX) == HAL_FMPSMBUS_STATE_SLAVE_BUSY_RX))
02596       {
02597         /* Reset only HAL_FMPSMBUS_STATE_SLAVE_BUSY_XX */
02598         /* keep HAL_FMPSMBUS_STATE_LISTEN if set */
02599         hfmpsmbus->PreviousState = HAL_FMPSMBUS_STATE_READY;
02600         hfmpsmbus->State = HAL_FMPSMBUS_STATE_LISTEN;
02601       }
02602     }
02603 
02604     /* Call the Error callback to inform upper layer */
02605 #if (USE_HAL_FMPSMBUS_REGISTER_CALLBACKS == 1)
02606     hfmpsmbus->ErrorCallback(hfmpsmbus);
02607 #else
02608     HAL_FMPSMBUS_ErrorCallback(hfmpsmbus);
02609 #endif /* USE_HAL_FMPSMBUS_REGISTER_CALLBACKS */
02610   }
02611 }
02612 
02613 /**
02614   * @brief  Handle FMPSMBUS Communication Timeout.
02615   * @param  hfmpsmbus Pointer to a FMPSMBUS_HandleTypeDef structure that contains
02616   *                the configuration information for the specified FMPSMBUS.
02617   * @param  Flag Specifies the FMPSMBUS flag to check.
02618   * @param  Status The new Flag status (SET or RESET).
02619   * @param  Timeout Timeout duration
02620   * @retval HAL status
02621   */
02622 static HAL_StatusTypeDef FMPSMBUS_WaitOnFlagUntilTimeout(FMPSMBUS_HandleTypeDef *hfmpsmbus, uint32_t Flag,
02623                                                          FlagStatus Status, uint32_t Timeout)
02624 {
02625   uint32_t tickstart = HAL_GetTick();
02626 
02627   /* Wait until flag is set */
02628   while ((FlagStatus)(__HAL_FMPSMBUS_GET_FLAG(hfmpsmbus, Flag)) == Status)
02629   {
02630     /* Check for the Timeout */
02631     if (Timeout != HAL_MAX_DELAY)
02632     {
02633       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0UL))
02634       {
02635         hfmpsmbus->PreviousState = hfmpsmbus->State;
02636         hfmpsmbus->State = HAL_FMPSMBUS_STATE_READY;
02637 
02638         /* Update FMPSMBUS error code */
02639         hfmpsmbus->ErrorCode |= HAL_FMPSMBUS_ERROR_HALTIMEOUT;
02640 
02641         /* Process Unlocked */
02642         __HAL_UNLOCK(hfmpsmbus);
02643 
02644         return HAL_ERROR;
02645       }
02646     }
02647   }
02648 
02649   return HAL_OK;
02650 }
02651 
02652 /**
02653   * @brief  Handle FMPSMBUSx communication when starting transfer or during transfer (TC or TCR flag are set).
02654   * @param  hfmpsmbus FMPSMBUS handle.
02655   * @param  DevAddress specifies the slave address to be programmed.
02656   * @param  Size specifies the number of bytes to be programmed.
02657   *   This parameter must be a value between 0 and 255.
02658   * @param  Mode New state of the FMPSMBUS START condition generation.
02659   *   This parameter can be one or a combination  of the following values:
02660   *     @arg @ref FMPSMBUS_RELOAD_MODE Enable Reload mode.
02661   *     @arg @ref FMPSMBUS_AUTOEND_MODE Enable Automatic end mode.
02662   *     @arg @ref FMPSMBUS_SOFTEND_MODE Enable Software end mode and Reload mode.
02663   *     @arg @ref FMPSMBUS_SENDPEC_MODE Enable Packet Error Calculation mode.
02664   * @param  Request New state of the FMPSMBUS START condition generation.
02665   *   This parameter can be one of the following values:
02666   *     @arg @ref FMPSMBUS_NO_STARTSTOP Don't Generate stop and start condition.
02667   *     @arg @ref FMPSMBUS_GENERATE_STOP Generate stop condition (Size should be set to 0).
02668   *     @arg @ref FMPSMBUS_GENERATE_START_READ Generate Restart for read request.
02669   *     @arg @ref FMPSMBUS_GENERATE_START_WRITE Generate Restart for write request.
02670   * @retval None
02671   */
02672 static void FMPSMBUS_TransferConfig(FMPSMBUS_HandleTypeDef *hfmpsmbus,  uint16_t DevAddress, uint8_t Size,
02673                                     uint32_t Mode, uint32_t Request)
02674 {
02675   /* Check the parameters */
02676   assert_param(IS_FMPSMBUS_ALL_INSTANCE(hfmpsmbus->Instance));
02677   assert_param(IS_FMPSMBUS_TRANSFER_MODE(Mode));
02678   assert_param(IS_FMPSMBUS_TRANSFER_REQUEST(Request));
02679 
02680   /* update CR2 register */
02681   MODIFY_REG(hfmpsmbus->Instance->CR2,
02682              ((FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | \
02683                (FMPI2C_CR2_RD_WRN & (uint32_t)(Request >> (31UL - FMPI2C_CR2_RD_WRN_Pos))) | \
02684                FMPI2C_CR2_START | FMPI2C_CR2_STOP | FMPI2C_CR2_PECBYTE)), \
02685              (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | \
02686                         (((uint32_t)Size << FMPI2C_CR2_NBYTES_Pos) & FMPI2C_CR2_NBYTES) | \
02687                         (uint32_t)Mode | (uint32_t)Request));
02688 }
02689 
02690 /**
02691   * @brief  Convert FMPSMBUSx OTHER_xxx XferOptions to functional XferOptions.
02692   * @param  hfmpsmbus FMPSMBUS handle.
02693   * @retval None
02694   */
02695 static void FMPSMBUS_ConvertOtherXferOptions(FMPSMBUS_HandleTypeDef *hfmpsmbus)
02696 {
02697   /* if user set XferOptions to FMPSMBUS_OTHER_FRAME_NO_PEC   */
02698   /* it request implicitly to generate a restart condition */
02699   /* set XferOptions to FMPSMBUS_FIRST_FRAME                  */
02700   if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_NO_PEC)
02701   {
02702     hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME;
02703   }
02704   /* else if user set XferOptions to FMPSMBUS_OTHER_FRAME_WITH_PEC */
02705   /* it request implicitly to generate a restart condition      */
02706   /* set XferOptions to FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE  */
02707   else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_FRAME_WITH_PEC)
02708   {
02709     hfmpsmbus->XferOptions = FMPSMBUS_FIRST_FRAME | FMPSMBUS_SENDPEC_MODE;
02710   }
02711   /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC */
02712   /* it request implicitly to generate a restart condition             */
02713   /* then generate a stop condition at the end of transfer             */
02714   /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC              */
02715   else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_NO_PEC)
02716   {
02717     hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_NO_PEC;
02718   }
02719   /* else if user set XferOptions to FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC */
02720   /* it request implicitly to generate a restart condition               */
02721   /* then generate a stop condition at the end of transfer               */
02722   /* set XferOptions to FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC              */
02723   else if (hfmpsmbus->XferOptions == FMPSMBUS_OTHER_AND_LAST_FRAME_WITH_PEC)
02724   {
02725     hfmpsmbus->XferOptions = FMPSMBUS_FIRST_AND_LAST_FRAME_WITH_PEC;
02726   }
02727   else
02728   {
02729     /* Nothing to do */
02730   }
02731 }
02732 /**
02733   * @}
02734   */
02735 
02736 #endif /* FMPI2C_CR1_PE */
02737 #endif /* HAL_FMPSMBUS_MODULE_ENABLED */
02738 /**
02739   * @}
02740   */
02741 
02742 /**
02743   * @}
02744   */
02745 
02746 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/