I2C Byte Transfer Order

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

  • I've not run across such a device. Memory chips are the prime example of ones that take a two-byte address, unless, of course, you want to rely on auto-increment, send the address once and skip it thereafter. Advanced sensors and modules may have lots of registers, but all I can think of manage with less than 256.

    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:
    PUB ReadPage(devSel, address, dataPtr, byteCount)
    
    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.
  • I've not run across such a device. Memory chips are the prime example of ones that take a two-byte address, unless, of course, you want to rely on auto-increment, send the address once and skip it thereafter. Advanced sensors and modules may have lots of registers, but all I can think of manage with less than 256.

    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:
    PUB ReadPage(devSel, address, dataPtr, byteCount)
    
    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.
  • Tracy AllenTracy Allen Posts: 6,393
    edited 2018-12-21 - 02:01:53
    Oh, right! I do use the sht31 and forgot about its 16 bit command.

    My method for that reads,
    i2c.ReadPage(device_ID, HOLD_MEDIUM | i2c#BIGADRS, @temp1, -6)  ' 
      ' -6 puts bytes in array in swapped order.   temp1:(rhcrc, rh0, rh1, tccrc) temp2:(tc0, tc1,0,0)
    
    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:
    degC :=  temp2 * 100 ** 11468975 - 4500    ' xxx.xx    raw * 175/65535 - 45. returns degC to 100ths
      rh := (temp1<<8>>16) ** 65536000           ' xxx.x     raw * 100 / 65535, shifts clear out the checksums, data to tenths.
    
  • TamiDukeTamiDuke Posts: 1
    edited 2019-01-24 - 22:30:36
    Hello...the Slaves are not sending data whenever they feel like it, they are responding to the Wire.requestFrom() from the Master. So the Master controls the I2C bus.
    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.

    PCB実装
  • Another weird one is the MAX1161x series. 12 bit 2/4/8 channel differential SAR ADCs. The command is two bytes, but what they call the configuration byte and the setup byte are distinguished by a low or high in bit 7. They can be sent in either order, or only one byte, or no bytes to repeat the existing configuration. The command with internal clocking is followed by clock stretch, and then the conversion results msb first in a burst from the selected channels.
Sign In or Register to comment.