DUDS
Distributed Update of Data from Something
duds::hardware::interface::Smbus Class Referenceabstract

An interface for communication with a SMBus device. More...

#include <Smbus.hpp>

Inheritance diagram for duds::hardware::interface::Smbus:
Collaboration diagram for duds::hardware::interface::Smbus:

Classes

struct  NoPec
 Use with constructors to specify that Packet Error Checking (PEC) will not be used. More...
 
struct  UsePec
 Use with constructors to explicitly specify that Packet Error Checking (PEC) be used. More...
 

Public Member Functions

virtual ~Smbus ()=0
 
virtual int address () const =0
 Returns the address of the device that this object will attempt to communicate with. More...
 
virtual std::uint16_t call (std::uint8_t cmd, std::uint16_t word)=0
 Does a process call operation. More...
 
virtual void call (std::uint8_t cmd, const std::vector< std::uint8_t > &out, std::vector< std::uint8_t > &in)=0
 Does a block process call operation. More...
 
virtual int receive (std::uint8_t cmd, std::uint8_t *in, const int maxlen)=0
 Sends a command byte, then reads a block of data from the device. More...
 
virtual void receive (std::uint8_t cmd, std::vector< std::uint8_t > &in)=0
 Sends a command byte, then reads a block of data from the device. More...
 
virtual std::uint8_t receiveByte ()=0
 Read a single byte from the device without sending a command/register byte first. More...
 
virtual std::uint8_t receiveByte (std::uint8_t cmd)=0
 Sends a command byte, then reads a single byte from the device. More...
 
virtual std::uint16_t receiveWord (std::uint8_t cmd)=0
 Sends a command byte, then reads a word, two bytes, from the device. More...
 
std::uint16_t receiveWordBe (std::uint8_t cmd)
 Sends a command byte, then reads a big-endian word from the device. More...
 
virtual void transmit (std::uint8_t cmd, const std::uint8_t *out, const int len)=0
 Sends a command byte and a block of data to the device. More...
 
void transmit (std::uint8_t cmd, const std::vector< std::uint8_t > &out)
 Sends a command byte and a block of data to the device. More...
 
virtual void transmitBool (bool out)=0
 Sends a single bit to the device. More...
 
virtual void transmitByte (std::uint8_t byte)=0
 Sends a single byte to the device. More...
 
virtual void transmitByte (std::uint8_t cmd, std::uint8_t byte)=0
 Sends a command byte and a data byte to the device. More...
 
virtual void transmitWord (std::uint8_t cmd, std::uint16_t word)=0
 Sends a command byte and a data word to the device. More...
 
void transmitWordBe (std::uint8_t cmd, std::uint16_t word)
 Sends a command byte and a big-endian data word to the device. More...
 

Detailed Description

An interface for communication with a SMBus device.

This is intended to communicate with a single device. Use one for each device, even if they use the same bus. As a result, implementations need not be thread-safe since it makes little sense to attempt multiple communications with the same device. However, the bus should be handled in a thread-safe manner; multiple simultaneous attempts to use the same bus to communicate with different devices should work.

Some I2C devices communicate in a manner that allows them to be handled as SMBus devices. Such devices should use Smbus instead of I2c to take advantage of the easier-to-use interface of Smbus. The Linux kernel documentation implies that SMBus master hardware exists, so favoring the use of Smbus may also increase compatibility without requiring the use of a software master using GPIOs.

Whenever possible, use Packet Error Checking (PEC) with communications. It will help prevent bad data on the bus from causing trouble by noticing the bad data and generating an error. It is not part of the I2C specification, so it should be disabled for use with SMBus-like I2C devices.

All word, two byte, std::uint16_t data is in host endianness. The SMBus protocol specifies that words are sent in little endian order. This must work on both little and big endian hosts. To assist in dealing with devices that are not SMBus compliant and use big-endian data, the receiveWordBe() and transmitWordBe() functions will do an endianness conversion on the data. They allow the code to use host endianness while communicating with big-endian data.

There isn't a matching access object because SMBus is specified in such a way that it shouldn't be required.

Todo:
Add ability to query SMBus master's capabilities.
Author
Jeff Jackowski

Definition at line 56 of file Smbus.hpp.

Constructor & Destructor Documentation

◆ ~Smbus()

duds::hardware::interface::Smbus::~Smbus ( )
pure virtual

Definition at line 14 of file Smbus.cpp.

Member Function Documentation

◆ address()

virtual int duds::hardware::interface::Smbus::address ( ) const
pure virtual

Returns the address of the device that this object will attempt to communicate with.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by transmit().

◆ call() [1/2]

virtual std::uint16_t duds::hardware::interface::Smbus::call ( std::uint8_t  cmd,
std::uint16_t  word 
)
pure virtual

Does a process call operation.

Sends a command byte and a word to the device, then receives a word.

Parameters
cmdThe command or register byte.
wordThe word to send.
Returns
The word received from the device.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by transmit().

◆ call() [2/2]

virtual void duds::hardware::interface::Smbus::call ( std::uint8_t  cmd,
const std::vector< std::uint8_t > &  out,
std::vector< std::uint8_t > &  in 
)
pure virtual

Does a block process call operation.

Sends a command byte and block of data to the device, then receives a block of data.

Parameters
cmdThe command or register byte.
outThe data block to send. It must not have more than 32 bytes.
inThe data block received from the device.
Exceptions
SmbusErrorMessageLengthA request was made to send a block of more than 32 bytes.
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

◆ receive() [1/2]

virtual int duds::hardware::interface::Smbus::receive ( std::uint8_t  cmd,
std::uint8_t *  in,
const int  maxlen 
)
pure virtual

Sends a command byte, then reads a block of data from the device.

Parameters
cmdThe command or register byte.
inThe input buffer.
maxlenThe maximum amount of data to write into in.
Returns
The number of bytes received from the device.
Exceptions
SmbusErrorMessageLengthThe buffer in could not hold all the received data.
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by receiveWordBe().

◆ receive() [2/2]

virtual void duds::hardware::interface::Smbus::receive ( std::uint8_t  cmd,
std::vector< std::uint8_t > &  in 
)
pure virtual

Sends a command byte, then reads a block of data from the device.

Parameters
cmdThe command or register byte.
inThe input vector. Upon success, the vector will be resized to match the received data.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

◆ receiveByte() [1/2]

virtual std::uint8_t duds::hardware::interface::Smbus::receiveByte ( )
pure virtual

Read a single byte from the device without sending a command/register byte first.

Returns
The byte from the device.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by duds::hardware::devices::instruments::MCP9808::MCP9808().

◆ receiveByte() [2/2]

virtual std::uint8_t duds::hardware::interface::Smbus::receiveByte ( std::uint8_t  cmd)
pure virtual

Sends a command byte, then reads a single byte from the device.

Parameters
cmdThe command or register byte.
Returns
The byte from the device.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

◆ receiveWord()

virtual std::uint16_t duds::hardware::interface::Smbus::receiveWord ( std::uint8_t  cmd)
pure virtual

Sends a command byte, then reads a word, two bytes, from the device.

Parameters
cmdThe command or register byte.
Returns
The word from the device.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by receiveWordBe().

◆ receiveWordBe()

std::uint16_t duds::hardware::interface::Smbus::receiveWordBe ( std::uint8_t  cmd)
inline

Sends a command byte, then reads a big-endian word from the device.

Parameters
cmdThe command or register byte.
Returns
The word from the device in host endianness.
Note
This function is only useful for devices that are not actually SMBus compliant. Some I2C devices that can be used as SMBus devices may use big-endian data.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Definition at line 146 of file Smbus.hpp.

Referenced by duds::hardware::devices::instruments::MCP9808::MCP9808().

◆ transmit() [1/2]

virtual void duds::hardware::interface::Smbus::transmit ( std::uint8_t  cmd,
const std::uint8_t *  out,
const int  len 
)
pure virtual

Sends a command byte and a block of data to the device.

Parameters
cmdThe command or register byte.
outThe data to send.
lenThe number of bytes in the buffer out to send. It must be between 1 and 32, inclusive.
Exceptions
SmbusErrorMessageLengthA request was made to send a block of less than 1 or more than 32 bytes.
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by transmit(), and transmitWordBe().

◆ transmit() [2/2]

void duds::hardware::interface::Smbus::transmit ( std::uint8_t  cmd,
const std::vector< std::uint8_t > &  out 
)
inline

Sends a command byte and a block of data to the device.

Parameters
cmdThe command or register byte.
outThe data to send. It must have between 1 and 32 bytes, inclusive.
Exceptions
SmbusErrorMessageLengthA request was made to send a block of less than 1 or more than 32 bytes.
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Definition at line 330 of file Smbus.hpp.

◆ transmitBool()

virtual void duds::hardware::interface::Smbus::transmitBool ( bool  out)
pure virtual

Sends a single bit to the device.

Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by receiveWordBe().

◆ transmitByte() [1/2]

virtual void duds::hardware::interface::Smbus::transmitByte ( std::uint8_t  byte)
pure virtual

Sends a single byte to the device.

Parameters
byteThe byte to send.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by receiveWordBe().

◆ transmitByte() [2/2]

virtual void duds::hardware::interface::Smbus::transmitByte ( std::uint8_t  cmd,
std::uint8_t  byte 
)
pure virtual

Sends a command byte and a data byte to the device.

Parameters
cmdThe command or register byte.
byteThe data byte to send.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

◆ transmitWord()

virtual void duds::hardware::interface::Smbus::transmitWord ( std::uint8_t  cmd,
std::uint16_t  word 
)
pure virtual

Sends a command byte and a data word to the device.

Parameters
cmdThe command or register byte.
wordThe data word to send.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Implemented in duds::hardware::interface::linux::DevSmbus.

Referenced by receiveWordBe(), and transmitWordBe().

◆ transmitWordBe()

void duds::hardware::interface::Smbus::transmitWordBe ( std::uint8_t  cmd,
std::uint16_t  word 
)
inline

Sends a command byte and a big-endian data word to the device.

Parameters
cmdThe command or register byte.
wordThe data word to send in host endianness.
Note
This function is only useful for devices that are not actually SMBus compliant. Some I2C devices that can be used as SMBus devices may use big-endian data.
Exceptions
SmbusErrorPecThe PEC checksum was not valid for the data.
SmbusErrorBusyThe bus was in use for an inordinate length of time. This is not caused by scheduling on the same host computer.
SmbusErrorNoDeviceThe device did not respond to its address.
SmbusErrorUnsupportedThis operation is unsupported by the master.
SmbusErrorProtocolData from the device does not conform to the SMBus protocol.
SmbusErrorTimeoutThe operation took too long resulting in a bus timeout.
SmbusErrorA general error that doesn't fit one of the other exceptions.

Definition at line 281 of file Smbus.hpp.

Referenced by duds::hardware::devices::instruments::INA219::INA219().


The documentation for this class was generated from the following files: