From 3a02ddd44e0952bd80254628e9db9d6a43ba9825 Mon Sep 17 00:00:00 2001 From: Gergő J. Miklós Date: Thu, 15 Oct 2020 04:29:19 +0200 Subject: i2c SMBUS function get --- Makefile | 6 +-- src/deftypes.h | 1 - src/main.c | 151 +++++++++++++++++++++++++++++++++++---------------------- 3 files changed, 96 insertions(+), 62 deletions(-) diff --git a/Makefile b/Makefile index 05a9a5b..255d599 100644 --- a/Makefile +++ b/Makefile @@ -11,13 +11,13 @@ dir: mkdir -p build/ armhf: - $(ACC) $(CFLAGS) $(VFLAGS) src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors-armhf + $(ACC) $(CFLAGS) $(VFLAGS) src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors-armhf -li2c x86: - $(CC) $(CFLAGS) $(VFLAGS) src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors + $(CC) $(CFLAGS) $(VFLAGS) src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors -li2c geode: - $(CC) $(CFLAGS) $(VFLAGS) -m32 -march=geode src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors + $(CC) $(CFLAGS) $(VFLAGS) -m32 -march=geode src/hmc5883.c src/hih61xx.c src/lm75.c src/main.c -o build/i2sensors -li2c copy: scp -r build/i2sensors-armhf root@cb2:/tmp/i2sensors diff --git a/src/deftypes.h b/src/deftypes.h index c53cd57..af9b3e4 100644 --- a/src/deftypes.h +++ b/src/deftypes.h @@ -18,7 +18,6 @@ #define uchar __u_char - #define ulong __u_long diff --git a/src/main.c b/src/main.c index 8414892..10ca27b 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,7 @@ #include #include +#include #include #include "deftypes.h" @@ -30,11 +31,22 @@ // extern void hih61xx_print_help(void); // extern void hih61xx_read_all(const char *opts); // extern void hih61xx_read_one(const char *opts); + +// >> i2sensor () +// >> i2sensor read_all 0 lm75 4f 1,-1.0;2,+0.2;3,+10;4,-2 +// read_all, list_all, +// ...read_all..., +// read_one..., +// ...read_reg_hex... , +// ...read_reg_dec... , +// ...set_param... , +// ...set_reg... , + - -uint16 devicef; //# Bus-Device file -uchar temp[256]; +__int16_t devicef; //# Bus-Device file +long addr=0, funcs=0; +//__uint8_t temp[256]; void (*print_all)(void) = NULL; void (*read_all)(const uchar *opts) = NULL; void (*read_one)(const uchar *opts) = NULL; @@ -51,6 +63,7 @@ void print_help(void) { " read_one -- read the selected parameters from device\n" " read_repeat -- read measurements continously\n" " conf_set -- set the configuration register\n" + " get_info -- List I2C driver functions\n" "\n" "Usage:\n" " i2sensors read_all
\n" @@ -64,10 +77,12 @@ void print_help(void) { printf ("Version: v%1.2f, build: [%s] (gcc %s) \n\n",VERSION,_BUILD_TIME_,__VERSION__); } +/* void bus_err(int ern){ printf("I2C communication(rd) error. errno: %d\n",errno); //fprintf (stderr, "Internal error %d at %s, line %d. (function: %s/%s)\n", ern, __FILE__, __LINE__, __func__, __FUNCTION__); } +*/ uchar *xchg_data (uchar *buf, uint16 wrlen, uint16 waitlen, uint16 rdlen){ //# [buf] = 32 byte @@ -81,11 +96,12 @@ uchar *xchg_data (uchar *buf, uint16 wrlen, uint16 waitlen, uint16 rdlen){ //perror("I2C communication(rd) error."); fprintf (stderr, "I2C read error: [NO: %d, MSG: %s] at %s, line %d. (function: %s)\n", errno, strerror(errno), __FILE__, __LINE__, __func__); } - return buf; + return buf; } -void preinit(const uchar *dev_type){ + +void preinit(const char *dev_type){ if(!strcmp("lm75", (char *)dev_type)){ print_all = lm75_print_all; @@ -111,86 +127,105 @@ void preinit(const uchar *dev_type){ -int main(int argc, char *argv[]) -{ - -// >> i2sensor () -// >> i2sensor read_all 0 lm75 4f 1,-1.0;2,+0.2;3,+10;4,-2 -// read_all, list_all, -// ...read_all..., -// read_one..., -// ...read_reg_hex... , -// ...read_reg_dec... , -// ...set_param... , -// ...set_reg... , - +int main( int argc, char *argv[] ){ - if(4 < argc && argc < 10) //Minimum 5 arguments should be passed. - { + if( (argc == 3 && !strcmp("get_info", argv[1])) || (4 < argc && argc < 10)){ //Minimal 5 arguments should be passed. (or get_info is called) - char filename[32]; - int i; - preinit((uchar *)argv[3]); - - for( i = 0; i < strlen(argv[2]); i++){ //# Test on bus address, for error detection. + char filename[256]; + int i, file1; + +/* for( i = 0; i < strlen(argv[2]); i++){ //# Test on bus address, for error detection. if(!isdigit(argv[2][i])){ printf("\n\tThe BUS Address must be an integer!\n\n"); - print_help(); - exit (EXIT_FAILURE); + exit(EXIT_FAILURE); } } - snprintf(filename, 31, "/dev/i2c-%s", argv[2]); - devicef = open(filename, O_RDWR); //# Open the i2c bus - +*/ + snprintf(filename, 256, "/dev/i2c-%s", argv[2]); + devicef = open(filename, O_RDWR); //# Open the i2c bus if (devicef < 0){ printf("\n\tCan't open i2c BUS. Have you any permission?\n\n"); - print_help(); - exit (EXIT_FAILURE); + exit(EXIT_FAILURE); } + if (ioctl(devicef, I2C_FUNCS, &funcs) < 0) { //Get i2c device features + fprintf (stderr, "\n\tAdapter function error [ERR: %d, MSG: %s] at %s, line %d. \n", errno, strerror(errno), __FILE__, __LINE__); + exit(EXIT_FAILURE); + } - if(argv[4][0]=='0' && argv[4][1]=='x'){ //# Hexadecimal representetion of device address - long addr = (int)strtol(argv[4], NULL, 0); //# strtol() is working with hex-string correctly + if( argc > 5 ){ //If not get_info was called + if(argv[4][0]=='0' && argv[4][1]=='x'){ //# Hexadecimal representetion of device address - if (ioctl(devicef, I2C_SLAVE, addr) < 0){ //# Seeking/Opening the device on the Bus - printf("\n\tCan't open i2c DEVICE, errno: %d\n\n",errno); - print_help(); - exit (EXIT_FAILURE); + addr = (int)strtol(argv[4], NULL, 0); //# strtol() is working with hex-string correctly + + if (ioctl(devicef, I2C_SLAVE, addr) < 0){ //# Seeking/Opening the device on the Bus + //printf("\n\tCan't open i2c DEVICE, errno: %d\n\n",errno); + fprintf (stderr, "\n\tCan't open i2c DEVICE! [ERR: %d, MSG: %s] at %s, line %d. \n", errno, strerror(errno), __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + } else { + printf("\n\tThe DEVICE address must be a hexadecimal number\n\n"); + exit(EXIT_FAILURE); } - } else { - printf("\n\tThe DEVICE address must be a hexadecimal number\n\n"); - print_help(); - exit (EXIT_FAILURE); + preinit((char *)argv[3]); //Initialization of subcommands } - - if(!strcmp("print_all",argv[1]) && print_all != NULL){ //# Gets the device's help message. + if (!strcmp("print_all",argv[1]) && print_all != NULL){ //# Gets the device's help message. print_all(); - } - else if(!strcmp("read_all",argv[1]) && read_all != NULL){ //# Pulls all readable registers data from device + + } else if (!strcmp("read_all",argv[1]) && read_all != NULL){ //# Pulls all readable registers data from device // read_all(argv[5]); read_all(NULL); - } - else if(!strcmp("read_one",argv[1]) && read_one != NULL && argc > 5) //# Prints out the selected register - { + + } else if (!strcmp("read_one",argv[1]) && read_one != NULL && argc > 5) { //# Prints out the selected register read_one((uchar*)argv[5]); - } - else if(!strcmp("conf_set",argv[1]) && conf_set != NULL && argc > 5) //# Prints out the selected register - { + + } else if (!strcmp("conf_set",argv[1]) && conf_set != NULL && argc > 5){ //# Prints out the selected register conf_set((uchar*)argv[5]); - } - else //# No other option - { + + } else if ( !strcmp("get_info", argv[1]) ){ + + snprintf(filename, 256, "/sys/class/i2c-dev/i2c-%s/name", argv[2]); + file1 = open(filename, O_RDONLY); + i = read(file1, filename, 256 ); + if(i > 0) { filename[i-1] = '\0'; } + close(file1); + + printf("\n Functions, supported by the [%s] adapter:\n\n", filename); + + printf("\tI2C_FUNC_I2C -- "); + if (funcs & I2C_FUNC_I2C){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_BYTE -- "); + if (funcs & I2C_FUNC_SMBUS_BYTE){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_BYTE_DATA -- "); + if (funcs & I2C_FUNC_SMBUS_BYTE_DATA){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_WORD_DATA -- "); + if (funcs & I2C_FUNC_SMBUS_WORD_DATA){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_BLOCK_DATA -- "); + if (funcs & I2C_FUNC_SMBUS_BLOCK_DATA){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_I2C_BLOCK -- "); + if (funcs & I2C_FUNC_SMBUS_I2C_BLOCK){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_SMBUS_EMUL -- "); + if (funcs & I2C_FUNC_SMBUS_EMUL){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_NOSTART -- "); + if (funcs & I2C_FUNC_NOSTART){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_10BIT_ADDR -- "); + if (funcs & I2C_FUNC_10BIT_ADDR){ printf("YES\n"); } else { printf("NO\n"); } + printf("\tI2C_FUNC_PROTOCOL_MANGLING -- "); + if (funcs & I2C_FUNC_PROTOCOL_MANGLING){ printf(" YES\n"); } else { printf("NO\n"); } + + printf("\n\tMore info in Linux Kernel Documentation: i2c/functionality.rst\n\n"); + + + } else { //# No other option print_help(); } close(devicef); - } - else - { + } else { print_help(); } return 0; -- cgit v1.2.3