text: //*****************************************************************************
  //
  // smbus.h - Prototypes for the SMBus driver.
  //
  // Copyright (c) 2010-2020 Texas Instruments Incorporated.  All rights reserved.
  // Software License Agreement
  // 
  // Texas Instruments (TI) is supplying this software for use solely and
  // exclusively on TI's microcontroller products. The software is owned by
  // TI and/or its suppliers, and is protected under applicable copyright
  // laws. You may not combine this software with "viral" open-source
  // software in order to form a larger program.
  // 
  // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  // DAMAGES, FOR ANY REASON WHATSOEVER.
  // 
  // This is part of revision 2.2.0.295 of the Tiva Utility Library.
  //
  //*****************************************************************************
  
  #ifndef __SMBUS_H__
  #define __SMBUS_H__
  
  //*****************************************************************************
  //
  // If building with a C++ compiler, make all of the definitions in this header
  // have a C binding.
  //
  //*****************************************************************************
  #ifdef __cplusplus
  extern "C"
  {
  #endif
  
  //*****************************************************************************
  //
  //! \addtogroup smbus_api
  //! @{
  //
  //*****************************************************************************
  
  //*****************************************************************************
  //
  //! This structure holds the SMBus Unique Device ID (UDID).  For detailed
  //! information, please refer to the SMBus Specification.
  //
  //*****************************************************************************
  typedef struct
  {
      //
      //! Device capabilities field.  This 8-bit field reports generic SMBus
      //! capabilities such as address type for ARP.
      //
      uint8_t ui8DeviceCapabilities;
  
      //
      //! Version Revision field.  This 8-bit field reports UDID revision
      //! information as well as some vendor-specific things such as silicon
      //! revision.
      //
      uint8_t ui8Version;
  
      //
      //! Vendor ID.  This 16-bit field contains the manufacturer's ID as
      //! assigned by the SBS Implementers' Forum of the PCI SIG.
      //
      uint16_t ui16VendorID;
  
      //
      //! Device ID.  This 16-bit field contains the device ID assigned by the
      //! device manufacturer.
      //
      uint16_t ui16DeviceID;
  
      //
      //! Interface.  This 16-bit field identifies the protocol layer interfaces
      //! supported over the SMBus connection.
      //
      uint16_t ui16Interface;
  
      //
      //! Subsystem Vendor ID.  This 16-bit field holds additional information
      //! that may be derived from the vendor ID or other information.
      //
      uint16_t ui16SubSystemVendorID;
  
      //
      //! Subsystem Device ID.  This 16-bit field holds additional information
      //! that may be derived from the device ID or other information.
      //
      uint16_t ui16SubSystemDeviceID;
  
      //
      //! Vendor-specific ID.  This 32-bit field contains a unique number that
      //! can be assigned per device by the manufacturer.
      //
      uint32_t ui32VendorSpecificID;
  }
  tSMBusUDID;
  
  //*****************************************************************************
  //
  //! This structure contains the state of a single instance of an SMBus module.
  //! Master and slave instances require unique configuration structures.
  //
  //*****************************************************************************
  typedef struct
  {
      //
      //! The SMBus Unique Device ID (UDID) for this SMBus instance.  If
      //! operating as a host, master-only, or on a bus that does not use Address
      //! Resolution Protocol (ARP), this is not required.  This member can be
      //! set via a direct structure access or using the SMBusSlaveInit
      //! function.  For detailed information about the UDID, refer to the SMBus
      //! spec.
      //
      tSMBusUDID *pUDID;
  
      //
      //! The base address of the I2C master peripheral.  This member can be set
      //! via a direct structure access or using the SMBusMasterInit or
      //! SMBusSlaveInit functions.
      //
      uint32_t ui32I2CBase;
  
      //
      //! The address of the data buffer used for transmit operations.  For
      //! master operations, this member is set by the SMBusMasterxxxx functions
      //! that pass a buffer pointer (for example, SMBusMasterBlockWrite).  For
      //! slave operations, this member can be set via direct structure access or
      //! using the SMBusSlaveTxBufferSet function.
      //
      uint8_t *pui8TxBuffer;
  
      //
      //! The address of the data buffer used for receive operations.  For master
      //! operations, this member is set by the SMBusMasterxxxx functions that
      //! pass a buffer pointer (for example, SMBusMasterBlockRead).  For slave
      //! operations, this member can be set via direct structure access or using
      //! the SMBusSlaveRxBufferSet function.
      //
      uint8_t *pui8RxBuffer;
  
      //
      //! The amount of data to transmit from pui8TxBuffer.  For master
      //! operations this member is set by the SMBusMasterxxxx functions either
      //! via an input argument (example SMBusMasterByteWordWrite) or explicitly
      //! (example SMBusMasterSendByte).  In master mode, this member should not
      //! be accessed or modified by the application.  For slave operations, this
      //! member can be set via direct structure access of using the
      //! SMBusSlaveTxBufferSet function.
      //
      uint8_t ui8TxSize;
  
      //
      //! The current index in the transmit buffer.  This member should not be
      //! accessed or modified by the application.
      //
      uint8_t ui8TxIndex;
  
      //
      //! The amount of data to receive into pui8RxBuffer.  For master
      //! operations, this member is set by the SMBusMasterxxxx functions either
      //! via an input argument (example SMBusMasterByteWordRead), explicitly
      //! (example SMBusMasterReceiveByte), or by the slave (example
      //! SMBusMasterBlockRead).  In master mode, this member should not be
      //! accessed or modified by the application.  For slave operations, this
      //! member can be set via direct structure access of using the
      //! SMBusSlaveRxBufferSet function.
      //
      uint8_t ui8RxSize;
  
      //
      //! The current index in the receive buffer.  This member should not be
      //! accessed or modified by the application.
      //
      uint8_t ui8RxIndex;
  
      //
      //! The active slave address of the I2C peripheral on the device.
      //! When using dual address in slave mode, the active address is store
      //! here.  In master mode, this member is not used.  This member is updated
      //! as requests come in from the master.
      //
      uint8_t ui8OwnSlaveAddress;
  
      //
      //! The address of the targeted slave device.  In master mode, this member
      //! is set by the ui8TargetSlaveAddress argument in the SMBusMasterxxxx
      //! transfer functions.  In slave mode, it is not used.  This member should
      //! not be modified by the application.
      //
      uint8_t ui8TargetSlaveAddress;
  
      //
      //! The last used command.  In master mode, this member is set by the
      //! ui8Command argument in the SMBusMasterxxxx transfer functions.  In
      //! slave mode, the first received byte will always be considered the
      //! command.  This member should not be modified by the application.
      //
      uint8_t ui8CurrentCommand;
  
      //
      //! The running CRC calculation used for transfers that require Packet
      //! Error Checking (PEC).  This member is updated by the SMBus software and
      //! should not be modified by the application.
      //
      uint8_t ui8CalculatedCRC;
  
      //
      //! The received CRC calculation used for transfers that require Packet
      //! Error Checking (PEC).  This member is updated by the SMBus software and
      //! should not be modified by the application.
      //
      uint8_t ui8ReceivedCRC;
  
      //
      //! The current state of the SMBusMasterISRProcess state machine.  This
      //! member should not be accessed or modified by the application.
      //
      uint8_t ui8MasterState;
  
      //
      //! The current state of the SMBusSlaveISRProcess state machine.  This
      //! member should not be accessed or modified by the application.
      //
      uint8_t ui8SlaveState;
  
      //
      //! Flags used for various items in the SMBus state machines for different
      //! transaction types and status.
      //!
      //! FLAG_PEC can be modified via the SMBusPECEnable or SMBusPECDisable
      //! functions or via direct structure access.
      //!
      //! FLAG_BLOCK_TRANSFER can be set via the SMBusSlaveBlockTransferEnable
      //! function and is cleared automatically by the SMBusSlaveTransferInit
      //! function or manually using the SMBusSlaveBlockTransferDisable function.
      //!
      //! FLAG_RAW_I2C can be modified via the SMBusSlaveI2CEnable or
      //! SMBusSlaveI2CDisable functions or via direct structure access.
      //!
      //! FLAG_TRANSFER_IN_PROGRESS should not be modified by the application,
      //! but can be read via the SMBusStatusGet function.
      //!
      //! FLAG_PROCESS_CALL can be set via the SMBusSlaveProcessCallEnable
      //! function and is cleared automatically by the SMBusSlaveTransferInit
      //! function or manually using the SMBusSlaveProcessCallDisable function.
      //!
      //! FLAG_ADDRESS_RESOLVED is only used by an SMBus Slave that supports ARP.
      //! This flag can be modified via the SMBusSlaveARPFlagARSet function and
      //! read via SMBusSlaveARPFlagARGet.  It can also be modified by direct
      //! structure access.
      //!
      //! FLAG_ADDRESS_VALID is only used by an SMBus Slave that supports ARP.
      //! This flag can be modified via the SMBusSlaveARPFlagAVSet function and
      //! read via SMBusSlaveARPFlagAVGet.  It can also be modified by direct
      //! structure access.
      //!
      //! FLAG_ARP is used to indicate that ARP is currently active.  This flag
      //! is not used by the SMBus stack and can (optionally) be used by the
      //! application to keep track of the ARP session.
      //
      uint16_t ui16Flags;
  }
  tSMBus;
  
  //*****************************************************************************
  //
  // ! Return codes.
  //
  //*****************************************************************************
  typedef enum
  {
      SMBUS_OK = 0,               // General "OK" return code
      SMBUS_TIMEOUT,              // Master detected bus timeout from slave
      SMBUS_PERIPHERAL_BUSY,      // The I2C peripheral is currently in use
      SMBUS_BUS_BUSY,             // The I2C bus is currently in use
      SMBUS_ARB_LOST,             // Bus arbitration was lost (master mode)
      SMBUS_ADDR_ACK_ERROR,       // In master mode, the address was NAK'd
      SMBUS_DATA_ACK_ERROR,       // Data transfer was NAK'd by receiver
      SMBUS_PEC_ERROR,            // PEC mismatch occurred
      SMBUS_DATA_SIZE_ERROR,      // Data size error has occurred
      SMBUS_MASTER_ERROR,         // Error occurred in the master ISR
      SMBUS_SLAVE_ERROR,          // Error occurred in the slave ISR
      SMBUS_SLAVE_QCMD_0,         // Slave transaction is Quick Command with
                                  // data value 0.
      SMBUS_SLAVE_QCMD_1,         // Slave transaction is Quick Command with
                                  // data value 1.
      SMBUS_SLAVE_FIRST_BYTE,     // The first byte has been received
      SMBUS_SLAVE_ADDR_PRIMARY,   // Primary address was detected
      SMBUS_SLAVE_ADDR_SECONDARY, // Secondary address was detected
      SMBUS_TRANSFER_IN_PROGRESS, // A transfer is currently in progress
      SMBUS_TRANSFER_COMPLETE,    // The last active transfer is complete
      SMBUS_SLAVE_NOT_READY,      // A slave transmit has been requested, but is
                                  // not ready (TX buffer not set).
      SMBUS_FIFO_ERROR,           // A master receive operation did not receive
                                  // enough data from the slave.
  }
  tSMBusStatus;
  
  //*****************************************************************************
  //
  // Close the Doxygen group.
  //! @}
  //
  //*****************************************************************************
  
  //*****************************************************************************
  //
  // ARP Commands
  //
  //*****************************************************************************
  #define SMBUS_CMD_PREPARE_TO_ARP            0x01
  #define SMBUS_CMD_ARP_RESET_DEVICE          0x02
  #define SMBUS_CMD_ARP_GET_UDID              0x03
  #define SMBUS_CMD_ARP_ASSIGN_ADDRESS        0x04
  
  //*****************************************************************************
  //
  // Fixed addresses defined by the SMBus specification.
  //
  //*****************************************************************************
  #define SMBUS_ADR_HOST                      0x08
  #define SMBUS_ADR_SMART_BATTERY_CHARGER     0x09
  #define SMBUS_ADR_SMART_BATTERY_SELECTOR    0x0A
  #define SMBUS_ADR_SMART_BATTERY             0x0B
  #define SMBUS_ADR_DEFAULT_DEVICE            0x61
  
  //*****************************************************************************
  //
  // API Function prototypes
  //
  //*****************************************************************************
  extern void SMBusPECEnable(tSMBus *psSMBus);
  extern void SMBusPECDisable(tSMBus *psSMBus);
  extern void SMBusARPEnable(tSMBus *psSMBus);
  extern void SMBusARPDisable(tSMBus *psSMBus);
  extern tSMBusStatus SMBusStatusGet(tSMBus *psSMBus);
  extern void SMBusARPUDIDPacketEncode(tSMBusUDID *pUDID,
                                       uint8_t ui8Address,
                                       uint8_t *pui8Data);
  extern void SMBusARPUDIDPacketDecode(tSMBusUDID *pUDID,
                                       uint8_t *pui8Address,
                                       uint8_t *pui8Data);
  extern uint8_t SMBusRxPacketSizeGet(tSMBus *psSMBus);
  extern void SMBusUDIDDataGet(tSMBus *psSMBus, tSMBusUDID *pUDID);
  extern tSMBusStatus SMBusMasterQuickCommand(tSMBus *psSMBus,
                                              uint8_t ui8TargetAddress,
                                              bool bData);
  extern tSMBusStatus SMBusMasterByteSend(tSMBus *psSMBus,
                                          uint8_t ui8TargetAddress,
                                          uint8_t ui8Data);
  extern tSMBusStatus SMBusMasterByteReceive(tSMBus *psSMBus,
                                             uint8_t ui8TargetAddress,
                                             uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterByteWordWrite(tSMBus *psSMBus,
                                               uint8_t ui8TargetAddress,
                                               uint8_t ui8Command,
                                               uint8_t *pui8Data,
                                               uint8_t ui8Size);
  extern tSMBusStatus SMBusMasterBlockWrite(tSMBus *psSMBus,
                                            uint8_t ui8TargetAddress,
                                            uint8_t ui8Command,
                                            uint8_t *pui8Data,
                                            uint8_t ui8Size);
  extern tSMBusStatus SMBusMasterByteWordRead(tSMBus *psSMBus,
                                              uint8_t ui8TargetAddress,
                                              uint8_t ui8Command,
                                              uint8_t *pui8Data,
                                              uint8_t ui8Size);
  extern tSMBusStatus SMBusMasterBlockRead(tSMBus *psSMBus,
                                           uint8_t ui8TargetAddress,
                                           uint8_t ui8Command,
                                           uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterProcessCall(tSMBus *psSMBus,
                                             uint8_t ui8TargetAddress,
                                             uint8_t ui8Command,
                                             uint8_t *pui8TxData,
                                             uint8_t *pui8RxData);
  extern tSMBusStatus SMBusMasterBlockProcessCall(tSMBus *psSMBus,
                                                  uint8_t ui8TargetAddress,
                                                  uint8_t ui8Command,
                                                  uint8_t *pui8TxData,
                                                  uint8_t ui8TxSize,
                                                  uint8_t *pui8RxData);
  extern tSMBusStatus SMBusMasterHostNotify(tSMBus *psSMBus,
                                            uint8_t ui8OwnSlaveAddress,
                                            uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterI2CWrite(tSMBus *psSMBus,
                                          uint8_t ui8TargetAddress,
                                          uint8_t *pui8Data,
                                          uint8_t ui8Size);
  extern tSMBusStatus SMBusMasterI2CRead(tSMBus *psSMBus,
                                         uint8_t ui8TargetAddress,
                                         uint8_t *pui8Data,
                                         uint8_t ui8Size);
  extern tSMBusStatus SMBusMasterI2CWriteRead(tSMBus *psSMBus,
                                              uint8_t ui8TargetAddress,
                                              uint8_t *pui8TxData,
                                              uint8_t ui8TxSize,
                                              uint8_t *pui8RxData,
                                              uint8_t ui8RxSize);
  extern tSMBusStatus SMBusMasterARPGetUDIDGen(tSMBus *psSMBus,
                                               uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterARPGetUDIDDir(tSMBus *psSMBus,
                                               uint8_t ui8TargetAddress,
                                               uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterARPResetDeviceGen(tSMBus *psSMBus);
  extern tSMBusStatus SMBusMasterARPResetDeviceDir(tSMBus *psSMBus,
                                                   uint8_t ui8TargetAddress);
  extern tSMBusStatus SMBusMasterARPAssignAddress(tSMBus *psSMBus,
                                                  uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterARPNotifyMaster(tSMBus *psSMBus,
                                                 uint8_t *pui8Data);
  extern tSMBusStatus SMBusMasterARPPrepareToARP(tSMBus *psSMBus);
  extern tSMBusStatus SMBusMasterIntProcess(tSMBus *psSMBus);
  extern void SMBusMasterIntEnable(tSMBus *psSMBus);
  extern void SMBusMasterInit(tSMBus *psSMBus, uint32_t ui32I2CBase,
                              uint32_t ui32SMBusClock);
  extern void SMBusSlaveTxBufferSet(tSMBus *psSMBus, uint8_t *pui8Data,
                                    uint8_t ui8Size);
  extern void SMBusSlaveRxBufferSet(tSMBus *psSMBus, uint8_t *pui8Data,
                                    uint8_t ui8Size);
  extern uint8_t SMBusSlaveCommandGet(tSMBus *psSMBus);
  extern void SMBusSlaveProcessCallEnable(tSMBus *psSMBus);
  extern void SMBusSlaveProcessCallDisable(tSMBus *psSMBus);
  extern void SMBusSlaveBlockTransferEnable(tSMBus *psSMBus);
  extern void SMBusSlaveBlockTransferDisable(tSMBus *psSMBus);
  extern void SMBusSlaveI2CEnable(tSMBus *psSMBus);
  extern void SMBusSlaveI2CDisable(tSMBus *psSMBus);
  extern void SMBusSlaveARPFlagARSet(tSMBus *psSMBus, bool bValue);
  extern bool SMBusSlaveARPFlagARGet(tSMBus *psSMBus);
  extern void SMBusSlaveARPFlagAVSet(tSMBus *psSMBus, bool bValue);
  extern bool SMBusSlaveARPFlagAVGet(tSMBus *psSMBus);
  extern void SMBusSlaveTransferInit(tSMBus *psSMBus);
  extern tSMBusStatus SMBusSlaveIntProcess(tSMBus *psSMBus);
  extern tSMBusStatus SMBusSlaveDataSend(tSMBus *psSMBus);
  extern void SMBusSlaveACKSend(tSMBus *psSMBus, bool bACK);
  extern void SMBusSlaveManualACKEnable(tSMBus *psSMBus);
  extern void SMBusSlaveManualACKDisable(tSMBus *psSMBus);
  extern bool SMBusSlaveManualACKStatusGet(tSMBus *psSMBus);
  extern tSMBusStatus SMBusSlaveIntAddressGet(tSMBus *psSMBus);
  extern void SMBusSlaveIntEnable(tSMBus *psSMBus);
  extern void SMBusSlaveUDIDSet(tSMBus *psSMBus, tSMBusUDID *pUDID);
  extern void SMBusSlaveAddressSet(tSMBus *psSMBus, uint8_t ui8AddressNum,
                                   uint8_t ui8SlaveAddress);
  extern void SMBusSlaveInit(tSMBus *psSMBus, uint32_t ui32I2CBase);
  
  //*****************************************************************************
  //
  // Mark the end of the C bindings section for C++ compilers.
  //
  //*****************************************************************************
  #ifdef __cplusplus
  }
  #endif
  
  #endif // __SMBUS_H__
  