STM32G474xx HAL用户手册
stm32g4xx_hal_smbus.c
转到该文件文档。
00001 /**
00002   ******************************************************************************
00003   * @file    stm32g4xx_hal_smbus.c
00004   * @author  MCD Application Team
00005   * @brief   SMBUS HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the System Management Bus (SMBus) peripheral,
00008   *          based on I2C principles of operation :
00009   *           + Initialization and de-initialization functions
00010   *           + IO operation functions
00011   *           + Peripheral State and Errors functions
00012   *
00013   ******************************************************************************
00014   * @attention
00015   *
00016   * Copyright (c) 2019 STMicroelectronics.
00017   * All rights reserved.
00018   *
00019   * This software is licensed under terms that can be found in the LICENSE file
00020   * in the root directory of this software component.
00021   * If no LICENSE file comes with this software, it is provided AS-IS.
00022   *
00023   ******************************************************************************
00024   @verbatim
00025   ==============================================================================
00026                         ##### How to use this driver #####
00027   ==============================================================================
00028     [..]
00029     The SMBUS HAL driver can be used as follows:
00030 
00031     (#) Declare a SMBUS_HandleTypeDef handle structure, for example:
00032         SMBUS_HandleTypeDef  hsmbus;
00033 
00034     (#)Initialize the SMBUS low level resources by implementing the HAL_SMBUS_MspInit() API:
00035         (##) Enable the SMBUSx interface clock
00036         (##) SMBUS pins configuration
00037             (+++) Enable the clock for the SMBUS GPIOs
00038             (+++) Configure SMBUS pins as alternate function open-drain
00039         (##) NVIC configuration if you need to use interrupt process
00040             (+++) Configure the SMBUSx interrupt priority
00041             (+++) Enable the NVIC SMBUS IRQ Channel
00042 
00043     (#) Configure the Communication Clock Timing, Bus Timeout, Own Address1, Master Addressing mode,
00044         Dual Addressing mode, Own Address2, Own Address2 Mask, General call, Nostretch mode,
00045         Peripheral mode and Packet Error Check mode in the hsmbus Init structure.
00046 
00047     (#) Initialize the SMBUS registers by calling the HAL_SMBUS_Init() API:
00048         (++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00049              by calling the customized HAL_SMBUS_MspInit(&hsmbus) API.
00050 
00051     (#) To check if target device is ready for communication, use the function HAL_SMBUS_IsDeviceReady()
00052 
00053     (#) For SMBUS IO operations, only one mode of operations is available within this driver
00055 
00055     *** Interrupt mode IO operation ***
00056     ===================================
00057     [..]
00058       (+) Transmit in master/host SMBUS mode an amount of data in non-blocking mode
00059           using HAL_SMBUS_Master_Transmit_IT()
00060       (++) At transmission end of transfer HAL_SMBUS_MasterTxCpltCallback() is executed and users can
00061            add their own code by customization of function pointer HAL_SMBUS_MasterTxCpltCallback()
00062       (+) Receive in master/host SMBUS mode an amount of data in non-blocking mode
00063           using HAL_SMBUS_Master_Receive_IT()
00064       (++) At reception end of transfer HAL_SMBUS_MasterRxCpltCallback() is executed and users can
00065            add their own code by customization of function pointer HAL_SMBUS_MasterRxCpltCallback()
00066       (+) Abort a master/host SMBUS process communication with Interrupt using HAL_SMBUS_Master_Abort_IT()
00067       (++) The associated previous transfer callback is called at the end of abort process
00068       (++) mean HAL_SMBUS_MasterTxCpltCallback() in case of previous state was master transmit
00069       (++) mean HAL_SMBUS_MasterRxCpltCallback() in case of previous state was master receive
00070       (+) Enable/disable the Address listen mode in slave/device or host/slave SMBUS mode
00071            using HAL_SMBUS_EnableListen_IT() HAL_SMBUS_DisableListen_IT()
00072       (++) When address slave/device SMBUS match, HAL_SMBUS_AddrCallback() is executed and users can
00073            add their own code to check the Address Match Code and the transmission direction
00074            request by master/host (Write/Read).
00075       (++) At Listen mode end HAL_SMBUS_ListenCpltCallback() is executed and users can
00076            add their own code by customization of function pointer HAL_SMBUS_ListenCpltCallback()
00077       (+) Transmit in slave/device SMBUS mode an amount of data in non-blocking mode
00078           using HAL_SMBUS_Slave_Transmit_IT()
00079       (++) At transmission end of transfer HAL_SMBUS_SlaveTxCpltCallback() is executed and users can
00080            add their own code by customization of function pointer HAL_SMBUS_SlaveTxCpltCallback()
00081       (+) Receive in slave/device SMBUS mode an amount of data in non-blocking mode
00082           using HAL_SMBUS_Slave_Receive_IT()
00083       (++) At reception end of transfer HAL_SMBUS_SlaveRxCpltCallback() is executed and users can
00084            add their own code by customization of function pointer HAL_SMBUS_SlaveRxCpltCallback()
00085       (+) Enable/Disable the SMBUS alert mode using
00086           HAL_SMBUS_EnableAlert_IT() or HAL_SMBUS_DisableAlert_IT()
00087       (++) When SMBUS Alert is generated HAL_SMBUS_ErrorCallback() is executed and users can
00088            add their own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00089            to check the Alert Error Code using function HAL_SMBUS_GetError()
00090       (+) Get HAL state machine or error values using HAL_SMBUS_GetState() or HAL_SMBUS_GetError()
00091       (+) In case of transfer Error, HAL_SMBUS_ErrorCallback() function is executed and users can
00092            add their own code by customization of function pointer HAL_SMBUS_ErrorCallback()
00093            to check the Error Code using function HAL_SMBUS_GetError()
00094 
00095      *** SMBUS HAL driver macros list ***
00096      ==================================
00097      [..]
00098        Below the list of most used macros in SMBUS HAL driver.
00099 
00100       (+) __HAL_SMBUS_ENABLE:      Enable the SMBUS peripheral
00101       (+) __HAL_SMBUS_DISABLE:     Disable the SMBUS peripheral
00102       (+) __HAL_SMBUS_GET_FLAG:    Check whether the specified SMBUS flag is set or not
00103       (+) __HAL_SMBUS_CLEAR_FLAG:  Clear the specified SMBUS pending flag
00104       (+) __HAL_SMBUS_ENABLE_IT:   Enable the specified SMBUS interrupt
00105       (+) __HAL_SMBUS_DISABLE_IT:  Disable the specified SMBUS interrupt
00106 
00107      *** Callback registration ***
00108      =============================================
00109     [..]
00110      The compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS when set to 1
00111      allows the user to configure dynamically the driver callbacks.
00112      Use Functions HAL_SMBUS_RegisterCallback() or HAL_SMBUS_RegisterAddrCallback()
00113      to register an interrupt callback.
00114     [..]
00115      Function HAL_SMBUS_RegisterCallback() allows to register following callbacks:
00116        (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
00117        (+) MasterRxCpltCallback : callback for Master reception end of transfer.
00118        (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
00119        (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
00120        (+) ListenCpltCallback   : callback for end of listen mode.
00121        (+) ErrorCallback        : callback for error detection.
00122        (+) MspInitCallback      : callback for Msp Init.
00123        (+) MspDeInitCallback    : callback for Msp DeInit.
00124      This function takes as parameters the HAL peripheral handle, the Callback ID
00125      and a pointer to the user callback function.
00126     [..]
00127      For specific callback AddrCallback use dedicated register callbacks : HAL_SMBUS_RegisterAddrCallback.
00128     [..]
00129      Use function HAL_SMBUS_UnRegisterCallback to reset a callback to the default
00130      weak function.
00131      HAL_SMBUS_UnRegisterCallback takes as parameters the HAL peripheral handle,
     and the Callback ID.
     This function allows to reset following callbacks:
       (+) MasterTxCpltCallback : callback for Master transmission end of transfer.
       (+) MasterRxCpltCallback : callback for Master reception end of transfer.
       (+) SlaveTxCpltCallback  : callback for Slave transmission end of transfer.
       (+) SlaveRxCpltCallback  : callback for Slave reception end of transfer.
       (+) ListenCpltCallback   : callback for end of listen mode.
       (+) ErrorCallback        : callback for error detection.
       (+) MspInitCallback      : callback for Msp Init.
       (+) MspDeInitCallback    : callback for Msp DeInit.
    [..]
     For callback AddrCallback use dedicated register callbacks : HAL_SMBUS_UnRegisterAddrCallback.
    [..]
     By default, after the HAL_SMBUS_Init() and when the state is HAL_I2C_STATE_RESET
     all callbacks are set to the corresponding weak functions:
     examples HAL_SMBUS_MasterTxCpltCallback(), HAL_SMBUS_MasterRxCpltCallback().
     Exception done for MspInit and MspDeInit functions that are
     reset to the legacy weak functions in the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit() only when
     these callbacks are null (not registered beforehand).
     If MspInit or MspDeInit are not null, the HAL_SMBUS_Init()/ HAL_SMBUS_DeInit()
     keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
    [..]
     Callbacks can be registered/unregistered in HAL_I2C_STATE_READY state only.
     Exception done MspInit/MspDeInit functions that can be registered/unregistered
     in HAL_I2C_STATE_READY or HAL_I2C_STATE_RESET state,
     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
     Then, the user first registers the MspInit/MspDeInit user callbacks
     using HAL_SMBUS_RegisterCallback() before calling HAL_SMBUS_DeInit()
     or HAL_SMBUS_Init() function.
    [..]
     When the compilation flag USE_HAL_SMBUS_REGISTER_CALLBACKS is set to 0 or
     not defined, the callback registration feature is not available and all callbacks
     are set to the corresponding weak functions.

     [..]
       (@) You can refer to the SMBUS HAL driver header file for more useful macros

  @endverbatim
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal.h"

/** @addtogroup STM32G4xx_HAL_Driver
  * @{
  */

/** @defgroup SMBUS SMBUS
  * @brief SMBUS HAL module driver
  * @{
  */

#ifdef HAL_SMBUS_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup SMBUS_Private_Define SMBUS Private Constants
  * @{
  */
*/
00191 #define TIMING_CLEAR_MASK   (0xF0FFFFFFUL)     /*!< SMBUS TIMING clear register Mask */
00192 #define HAL_TIMEOUT_ADDR    (10000U)           /*!< 10 s  */
00193 #define HAL_TIMEOUT_BUSY    (25U)              /*!< 25 ms */
00194 #define HAL_TIMEOUT_DIR     (25U)              /*!< 25 ms */
00195 #define HAL_TIMEOUT_RXNE    (25U)              /*!< 25 ms */
00196 #define HAL_TIMEOUT_STOPF   (25U)              /*!< 25 ms */
00197 #define HAL_TIMEOUT_TC      (25U)              /*!< 25 ms */
00198 #define HAL_TIMEOUT_TCR     (25U)              /*!< 25 ms */
00199 #define HAL_TIMEOUT_TXIS    (25U)              /*!< 25 ms */
00200 #define MAX_NBYTE_SIZE      255U
/**
  * @}
  */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @addtogroup SMBUS_Private_Functions SMBUS Private Functions
  * @{
  */
/* Private functions to handle flags during polling transfer */
static HAL_StatusTypeDef SMBUS_WaitOnFlagUntilTimeout(SMBUS_HandleTypeDef *hsmbus, uint32_t Flag,
                                                       FlagStatus Status, uint32_t Timeout);

/* Private functions for SMBUS transfer IRQ handler */
static HAL_StatusTypeDef SMBUS_Master_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
static HAL_StatusTypeDef SMBUS_Slave_ISR(SMBUS_HandleTypeDef *hsmbus, uint32_t StatusFlags);
static void SMBUS_ITErrorHandler(SMBUS_HandleTypeDef *hsmbus);

/* Private functions to centralize the enable/disable of Interrupts */
static void SMBUS_Enable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);
static void SMBUS_Disable_IRQ(SMBUS_HandleTypeDef *hsmbus, uint32_t InterruptRequest);

/* Private function to flush TXDR register */
static void