3
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Do you have the manpages for those calls? \$\endgroup\$ – XTL Dec 4 '10 at 9:44
  • \$\begingroup\$ Unfortunately not. All I have is the header file for the DLL, which is where I copied the above from. \$\endgroup\$ – Jack Dec 4 '10 at 12:17
  • \$\begingroup\$ Can you elaborate on 'doesn't seem to work'? What errors are you getting? \$\endgroup\$ – Adam Lawrence Nov 27 '12 at 12:54
2
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

thats very interesting I never noticed that PC/104 had a SMbus and I2C interface!! thanks :) I have always used off the shelf cards but I degres.....

I would suggest that you monitor the lines with a scope that has I2C interpretation and connect and see what happens with the equivalent write commands. This may give you a better idea of what the commands are actually doing. Follow this with connecting a microcontroller and some simple code to read and write stuff on the i2c as a slave device and then try the read commands again.

By knowing what you are putting on the bus with the microcontroller and monitoring communication with the scope, it will make it easier to try to figure out the API.

I know the above will take some time to set up, but when you have it will simplify all further testing and debugging on the PC104 computer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy