/* * Copyright 2020, Jérôme Duval, jerome.duval@gmail.com. * Distributed under the terms of the MIT license. */ #include #include #include #include #include #include #include #include #include #include "i2c.h" static struct option const kLongOptions[] = { {"help", no_argument, 0, 'h'}, {NULL} }; extern const char *__progname; static const char *kProgramName = __progname; void usage(int returnValue) { fprintf(stderr, "Usage: %s \n", kProgramName); exit(returnValue); } static int scan_bus(const char *path) { int err = EXIT_SUCCESS; FileDescriptorCloser fd(open(path, O_RDONLY)); if (!fd.IsSet()) { fprintf(stderr, "%s: Could not access path: %s\n", kProgramName, strerror(errno)); return EXIT_FAILURE; } setbuf(stdout, NULL); printf("Scanning I2C bus: %s\n", path); printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); for (int i = 0; i < 128; i+=16) { printf("%02x: ", i); for (int j = 0; j < 16; j++) { uint16 addr = i + j; uint8 cmd = 0; uint8 data = 0; i2c_ioctl_exec exec; exec.addr = addr; exec.op = I2C_OP_READ_STOP; exec.cmdBuffer = &cmd; exec.cmdLength = sizeof(cmd); exec.buffer = &data; exec.bufferLength = sizeof(data); if (ioctl(fd.Get(), I2CEXEC, &exec, sizeof(exec)) == 0) printf("%02x ", addr); else printf("-- "); } printf("\n"); } return err; } int main(int argc, char** argv) { int c; while ((c = getopt_long(argc, argv, "h", kLongOptions, NULL)) != -1) { switch (c) { case 0: break; case 'h': usage(0); break; default: usage(1); break; } } if (argc - optind < 1) usage(1); const char* path = argv[optind++]; exit(scan_bus(path)); }