Subversion Repositories FuelGauge

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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