I2C Byte Transfer Order
apcountryman
Posts: 33
As part of writing a general I2C support library I've taken a survey of a variety of I2C devices to look for consistency/inconsistency in the order that bytes that make up a multibyte register / register address / command are transferred. During this survey I've found that there is no consistency in the byte transfer order of multibyte registers (unless the device claims SMBus compatibility in which case they are always transferred least significant byte first). In fact some devices from the same manufacturer are not consistent with each other. However, with multibyte register addresses / commands all devices I looked at during my survey transferred the most significant byte of the register address / command first. Has anyone here come across any I2C devices where a multibyte register address / command was not transferred most significant byte first?
Comments
What non-memory two-byte examples do you thinking of?
AFAIK, the i2c specification does not put any restrictions on how the data bytes after the device ID are implemented. It doesn't even talk about "register addresses". Those are just data as far as the spec is concerned. (ref: NXP
I2C-bus specification and user manual). Manufacturers certainly do take creative license. All sorts of tricks, occasionally traps. (Granted SMB is a higher level protocol)
In my own i2c code, similar to other versions, the readpage method looks like this: I pass address as a long, so that a value of -1 skips sending and goes right into the data, otherwise if bit 31 is set , it sends a two-byte address msb first, otherwise it sends a one-byte address.
For the byteCount, if it is a positive number, it brings in the data in the order received into the array at dataPtr. But if it is negative, it reverses the endedness. So an device that returns a word value msb first can be requested with bytecount=-2, so the lsb ends where it should in the small-endian framework of the Prop.
The only non-memory device that I came across during my survey that takes a 16-bit register address / command (a command in this case) is the Sensirion SHT31-DIS temperature/humidity sensor. Commands are issued most significant byte first just like memory device register addresses are.
Thanks for providing your read page interface.
In my case, the library is being written in C++. The supported register addressing modes are non-addressed, 8-bit addressed, and 16-bit addressed. Single register, register block, and functor controlled read and write operations are supported for both 8-bit and 16-bit registers. With 16-bit registers a tag is used to control the byte transfer order. Unless/until I come across a device that works differently, 16-bit addresses will only be transferred most significant byte first. If a device is truly exotic the above abstractions don't have to be used.
My method for that reads, The constant HOLD_MEDIUM selects a 4ms conversion time with 0.15% resolution, using the clock hold mechanism, and #BIGADRS, is NEGX, or'd with the address to call out two byte addressing. The method then does math on longs temp1 and temp2:
service men fail to handle the I2C bus effectively due to the poor material used in them.
The Wire.write() can send a number of bytes. The second parameter is the number of bytes. If the second parameter is omitted, only one byte is send, but just one byte is boring.