Путь: Toys/Other, команды версии: Ver.4 Ver.9 Комментарии в файле i2ctools.c : Команд: 4 i2cdetect
i2cdump
i2cget
i2cset
Исходный текст в файле i2ctools.c #define FOR_i2cdetect #define TT this.i2ctools #include "toys.h" #include <linux/i2c.h> #include <linux/i2c-dev.h> printf_format static void confirm(const char *fmt, ...) { va_list va; if (FLAG(y)) return; va_start(va, fmt); vfprintf(stderr, fmt, va); va_end(va); if (!yesno(1)) error_exit("Exiting"); } static int i2c_open(int bus, int slave, int chip) { int fd; snprintf(toybuf, sizeof(toybuf), "/dev/i2c-%d", bus); fd = xopen(toybuf, O_RDONLY); if (slave) xioctl(fd, slave, (void *)(long)chip); return fd; } static unsigned long i2c_get_funcs(int bus) { int fd = i2c_open(bus, 0, 0); unsigned long result; xioctl(fd, I2C_FUNCS, &result); close(fd); return result; } static int i2c_read_byte(int fd, int addr, int *byte) { union i2c_smbus_data data; struct i2c_smbus_ioctl_data ioctl_data = { .read_write = I2C_SMBUS_READ, .size = I2C_SMBUS_BYTE_DATA, .command = addr, .data = &data }; memset(&data, 0, sizeof(data)); if (ioctl(fd, I2C_SMBUS, &ioctl_data)==-1) return -1; *byte = data.byte; return 0; } static int i2c_quick_write(int fd, int addr) { struct i2c_smbus_ioctl_data ioctl_data = { .read_write = I2C_SMBUS_QUICK, .size = 0, .command = addr }; return ioctl(fd, I2C_SMBUS, &ioctl_data); } static void i2cdetect_dash_F(int bus) { struct { int mask; const char *name; } funcs[] = { {I2C_FUNC_I2C, "I2C"}, {I2C_FUNC_SMBUS_QUICK, "SMBus Quick Command"}, {I2C_FUNC_SMBUS_WRITE_BYTE, "SMBus Send Byte"}, {I2C_FUNC_SMBUS_READ_BYTE, "SMBus Receive Byte"}, {I2C_FUNC_SMBUS_WRITE_BYTE_DATA, "SMBus Write Byte"}, {I2C_FUNC_SMBUS_READ_BYTE_DATA, "SMBus Read Byte"}, {I2C_FUNC_SMBUS_WRITE_WORD_DATA, "SMBus Write Word"}, {I2C_FUNC_SMBUS_READ_WORD_DATA, "SMBus Read Word"}, {I2C_FUNC_SMBUS_PROC_CALL, "SMBus Process Call"}, {I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, "SMBus Write Block"}, {I2C_FUNC_SMBUS_READ_BLOCK_DATA, "SMBus Read Block"}, {I2C_FUNC_SMBUS_BLOCK_PROC_CALL, "SMBus Block Process Call"}, {I2C_FUNC_SMBUS_PEC, "SMBus PEC"}, {I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, "I2C Write Block"}, {I2C_FUNC_SMBUS_READ_I2C_BLOCK, "I2C Read Block"}, }; unsigned long sup = i2c_get_funcs(bus); int i; printf("Functionalities implemented by %s:\n", toybuf); for (i = 0; i < ARRAY_LEN(funcs); ++i) printf("%-32s %s\n", funcs[i].name, (sup & funcs[i].mask) ? "yes" : "no"); } static int i2cdetect_dash_l(struct dirtree *node) { int suffix_len = strlen("/name"); int bus; char *fname, *p; unsigned long funcs; if (!node->parent) return DIRTREE_RECURSE; // Skip the directory itself. if (sscanf(node->name, "i2c-%d", &bus)!=1) return 0; funcs = i2c_get_funcs(bus); fname = dirtree_path(node, &suffix_len); strcat(fname, "/name"); xreadfile(fname, toybuf, sizeof(toybuf)); free(fname); if ((p = strchr(toybuf, '\n'))) *p = 0; // "i2c-1 i2c Synopsys DesignWare I2C adapter I2C adapter" printf("%s\t%-10s\t%-32s\t%s\n", node->name, (funcs & I2C_FUNC_I2C) ? "i2c" : "?", toybuf, (funcs & I2C_FUNC_I2C) ? "I2C Adapter" : "?"); return 0; } void i2cdetect_main(void) { if (FLAG(l)) { if (toys.optc) error_exit("-l doesn't take arguments"); dirtree_flagread("/sys/class/i2c-dev", DIRTREE_SHUTUP, i2cdetect_dash_l); } else if (FLAG(F)) { if (toys.optc != 1) error_exit("-F BUS"); i2cdetect_dash_F(atolx_range(*toys.optargs, 0, INT_MAX)); } else { int bus, first = 0x03, last = 0x77, fd, row, addr, byte; if (FLAG(a)) { first = 0x00; last = 0x7f; } if (toys.optc!=1 && toys.optc!=3) help_exit("Needs 1 or 3 arguments"); bus = atolx_range(*toys.optargs, 0, INT_MAX); if (toys.optc==3) { first = atolx_range(toys.optargs[1], 0, 0x7f); last = atolx_range(toys.optargs[2], 0, 0x7f); if (first > last) error_exit("first > last"); } confirm("Probe chips 0x%02x-0x%02x on bus %d?", first, last, bus); fd = i2c_open(bus, 0, 0); printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); for (row = 0; row <= 0x70; row += 16) { xprintf("%02x:", row & 0xf0); for (addr = row; addr<row+16; ++addr) { if (addr<first || addr>last) printf(" "); else { if (ioctl(fd, I2C_SLAVE, addr) == -1) { if (errno == EBUSY) { xprintf(" UU"); continue; } perror_exit("ioctl(I2C_SLAVE)"); } if ((FLAG(r) ? i2c_read_byte(fd, addr, &byte) : i2c_quick_write(fd, addr)) == -1) xprintf(" --"); else xprintf(" %02x", addr); } } putchar('\n'); } close(fd); } } #define FOR_i2cdump #include "generated/flags.h" void i2cdump_main(void) { int bus = atolx_range(toys.optargs[0], 0, INT_MAX); int chip = atolx_range(toys.optargs[1], 0, 0x7f); int fd, row, addr, byte; confirm("Dump chip 0x%02x on bus %d?", chip, bus); fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip); printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef\n"); for (row = 0; row<=0xf0; row += 16) { xprintf("%02x:", row & 0xf0); for (addr = row; addr<row+16; ++addr) { if (!i2c_read_byte(fd, addr, &byte)) printf(" %02x", byte); else { printf(" XX"); byte = 'X'; } toybuf[addr-row] = isprint(byte) ? byte : (byte ? '?' : '.'); } printf(" %16.16s\n", toybuf); } close(fd); } #define FOR_i2cget #include "generated/flags.h" void i2cget_main(void) { int bus = atolx_range(toys.optargs[0], 0, INT_MAX); int chip = atolx_range(toys.optargs[1], 0, 0x7f); int addr = atolx_range(toys.optargs[2], 0, 0xff); int fd, byte; confirm("Read register 0x%02x from chip 0x%02x on bus %d?", addr, chip, bus); fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip); if (i2c_read_byte(fd, addr, &byte)==-1) perror_exit("i2c_read_byte"); printf("0x%02x\n", byte); close(fd); } #define FOR_i2cset #include "generated/flags.h" void i2cset_main(void) { int bus = atolx_range(toys.optargs[0], 0, INT_MAX); int chip = atolx_range(toys.optargs[1], 0, 0x7f); int addr = atolx_range(toys.optargs[2], 0, 0xff); char *mode = toys.optargs[toys.optc-1]; int fd, i; struct i2c_smbus_ioctl_data ioctl_data; union i2c_smbus_data data; memset(&data, 0, sizeof(data)); if (strlen(mode)!=1) help_exit("mode too long"); if (*mode=='b' && toys.optc==5) { ioctl_data.size = I2C_SMBUS_BYTE_DATA; data.byte = atolx_range(toys.optargs[3], 0, 0xff); } else if (*mode=='w' && toys.optc==5) { ioctl_data.size = I2C_SMBUS_WORD_DATA; data.word = atolx_range(toys.optargs[3], 0, 0xffff); } else if (*mode=='i' && toys.optc>=5) { if (toys.optc-4>I2C_SMBUS_BLOCK_MAX) error_exit("too much data"); ioctl_data.size = I2C_SMBUS_I2C_BLOCK_DATA; for (i = 0; i<toys.optc-4; ++i) data.block[i+1] = atolx_range(toys.optargs[3+i], 0, 0xff); data.block[0] = toys.optc-4; } else help_exit("syntax error"); confirm("Write register 0x%02x from chip 0x%02x on bus %d?", addr, chip, bus); fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip); ioctl_data.read_write = I2C_SMBUS_WRITE; ioctl_data.command = addr; ioctl_data.data = &data; xioctl(fd, I2C_SMBUS, &ioctl_data); close(fd); } |