i2ctransfer(8)

πŸ“¦
version 4.4 Β· 2 versions
, in alpine 3.24, arch rolling, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu questing, ubuntu resolute, ubuntu stonking

✨ i2ctransfer(8) β€” the manual, but make it a vibe ✨

okay so bestie, welcome to i2ctransfer from the System Manager's Manual section of your system. this one is a little bit feral and a lot powerful, so sit down, grab a snack πŸ“, and let's get into it.


πŸŽ€ NAME πŸŽ€

i2ctransfer β€” send user-defined I2C messages in one transfer


🌸 SYNOPSIS 🌸

i2ctransfer [-a] [-b] [-f] [-v] [-y] i2cbus desc [data] [desc [data]]
...
i2ctransfer -h
i2ctransfer -V

πŸ¦‹ DESCRIPTION πŸ¦‹

so i2ctransfer is the program that lets you build your own I2C messages and yeet them all out as one single transfer. iconic behavior honestly. for read messages, the contents of the received buffers get printed to stdout β€” one line per read message. periodt.

now, real talk, because this part is important: there is a difference between a transfer and a message. a transfer can be made of multiple messages, and it starts with a START condition and ends with a STOP condition, exactly like the I2C specification describes. the messages inside that transfer are glued together with the REPEATED START condition, which the spec also talks about. iykyk.

and why would you even want multiple messages in one transfer? so glad you asked πŸ’…:

  • some devices keep their internal state across a REPEATED START but reset them after a STOP. so yeah, that matters.
  • you cannot get interrupted during one transfer β€” but it can totally happen between transfers. interruption could come at the hardware level from another I2C master chilling on the bus, or at the software level from another I2C user whose transfer got scheduled right between yours. rude, honestly.

this program helps you create proper transfers for your needs. no cap. 🫢


πŸ’… OPTIONS πŸ’…

  • -a β€” allow using addresses between 0x00 - 0x07 and 0x78 - 0x7f. not recommended. like, at all.
  • -b β€” print data from read messages as binary data. disables -v (verbose). super useful for piping into a pretty printing tool like hexdump, or for redirecting into a file so you can analyze it later. lowkey the move.
  • -f β€” force access to the device even if it is already busy. by default, i2ctransfer will refuse to touch a device that's already under the control of a kernel driver. using this flag is dangerous β€” it can seriously confuse the kernel driver in question. it can also cause i2ctransfer to silently write to the wrong register. so use at your own risk and only if you know what you're doing. fr fr.
  • -h β€” display the help and exit. cute, quick, no drama.
  • -v β€” enable verbose output. it prints infos about all messages sent, i.e. not only for read messages but also for write messages. main character energy for your terminal.
  • -V β€” display the version and exit.
  • -y β€” disable interactive mode. by default, i2ctransfer waits for a confirmation from you before messing with the I2C bus. with this flag it just does the thing immediately. mainly meant to be used in scripts. (scripts don't have time to vibe check you.)

🌈 ARGUMENTS 🌈

the first parameter, i2cbus, is the number or name of the I2C bus you wanna use. that number should correspond to one of the busses listed by i2cdetect -l.

the next parameter is one or multiple desc blocks. the number of blocks is limited by the Linux Kernel and defined by I2C_RDWR_IOCTL_MAX_MSGS (42 as of v4.10). and yes, it's 42, the universe said so.

desc blocks are composed like this:

{r|w}<length_of_message>[@address]
  • {r|w} β€” specifies if the message is read or write.
  • <length_of_message> β€” specifies the number of bytes read or written in this message. it's parsed as an unsigned 16 bit integer, but heads up: the Linux Kernel applies an additional upper limit (8192 as of v4.10). for read messages to targets which support SMBus Block transactions, it can also be '?' β€” then the target will determine the length. she decides. πŸ’…
  • [@address] β€” specifies the 7-bit address of the chip to be accessed for this message, and it's an integer. if omitted, it reuses the previous address. normally, addresses outside the range of 0x08-0x77 and addresses with a kernel driver attached to them will be blocked. this can be overridden with -a (all) or -f (force). be very careful when using these! and also: 10-bit addresses are currently not supported at all. nope. not even a little. πŸ’€

if the I2C message is a write, then a data block with the data to be written follows. it consists of <length_of_message> bytes which can be marked with the usual prefixes for hexadecimal, octal, etc. to make it easier to create larger data blocks, the data byte can have a suffix:

  • = β€” keep value constant until end of message (i.e. 0= means 0, 0, 0, ...)
  • + β€” increase value by 1 until end of message (i.e. 0+ means 0, 1, 2, ...)
  • - β€” decrease value by 1 until end of message (i.e. 0xff- means 0xff, 0xfe, 0xfd, ...)
  • p β€” use value as seed for an 8 bit pseudo random sequence (i.e. 0p means 0x00, 0x50, 0xb0, ...)

🌟 EXAMPLES 🌟

on bus 0, from an EEPROM at address 0x50, read 8 byte from offset 0x64 (first message writes one byte to set the memory pointer to 0x64, second message reads from the same chip):

# i2ctransfer 0 w1@0x50 0x64 r8

for the same EEPROM, at offset 0x42 write 0xff 0xfe ... 0xf0 (one write message; first byte sets the memory pointer to 0x42, 0xff is the first data byte, all following data bytes are decreased by one):

# i2ctransfer 0 w17@0x50 0x42 0xff-

⚠️ WARNING ⚠️

i2ctransfer can be extremely dangerous if used improperly. it can confuse your I2C bus, cause data loss, or have more serious side effects. writing to a serial EEPROM on a memory DIMM (chip addresses between 0x50 and 0x57) may DESTROY your memory, leaving your system unbootable! be extremely careful using this program. i am so serious bestie. 🫢

πŸ› BUGS πŸ›

to report bugs or send fixes, please write to the Linux I2C mailing list <linux-i2c@vger.kernel.org> with Cc to the current maintainer: Jean Delvare <jdelvare@suse.de>.


πŸ‘‘ AUTHORS πŸ‘‘

Wolfram Sang, based on i2cget by Jean Delvare

this manual page was originally written by Wolfram Sang based on the manual for i2cset by David Z Maze <dmaze@debian.org>.


πŸ”— SEE ALSO πŸ”—

i2cdetect(8), i2cdump(8), i2cget(8), i2cset(8)


and that's the whole page, bestie πŸŽ€ this one lives in the System Manager's Manual section, and this version is dated May 2022. go forth, build your transfers, and please don't nuke your DIMM. mwah πŸ’–βœ¨