Electronic – Using I2C Devices on SMBus interface

i2c

I'm developing on a PC/104 stack which aparently has an I2C interface. However, on further investigation it is actually an SMBus interface but says the two are interchangable up to 400kHz.
However, the only way I can access it is through a DLL provided by the vendor. The DLL only has SMBus specific commands but reading up on SMBus I can see that the read_byte functionality seems to be the same as that for I2C.

The DLL shows the interface for read_byte as:

//
// Call this function to reads a byte on the SMBus. This function
// requires the proper values to be setup in the SMB_REQUEST structure.
// This call is valid after a successful OPEN call has been made.
//
// Parameters: handle - Handle to open SMBus API
//      request - input SMB_REQUEST structure 
//
// Returns: 0=SUCCESS, non-zero = FAIL
//
SMBUS_API int SmBusReadByte( SMBUS_HANDLE handle, SMB_REQUEST *request );

….defining the SMB_REQUEST struct as

typedef struct _SMB_REQUEST
{
 unsigned char Address;
 unsigned char Command;
 unsigned char BlockLength;
 unsigned char Data[SMB_MAX_DATA_SIZE];
} SMB_REQUEST;

Relating this to I2C I'm thinking that:
Address is the address of the I2C device
Command is the register to read from
BlockLength the amount of bytes to read
Data is the memory buffer used to give back the result.

However, using it like this doesn't seem to work. There is also a SmReceiveReadByte() function with the same interface so I'm not sure whether I'm supposed to be using that or this funcion.
There is also a SmBusReadWord() function with the same interface so that leads me to beleive that I have the wrong idea about BlockLength above. What else could it be?
I'm probably not using this correctly at all.
Would anyone be able to shed some light on this for me?

Thanks

Best Answer

If you take some time and poke around Wikipedia you'll find a page describing the differences between I2C and SMBus; the one that's probably getting you is the packet checksumming or PEC; this is not required for I2C transfers but SMBus devices want it. It's not difficult to calculate and append to the transfer, so you might want to start there.

Obviously if you have a logic analyzer it'd be prudent to throw that on first and see if that really is what's causing your troubles before going to the effort of writing the code. :-) You can also probably lift the PEC generation code from the linux kernel, as it has I2C and SMBus drivers and the places like the Linux Cross Reference are excellent at helping you find out where the code you're interested is hiding.

Good luck!