From 8517494b239d652ea9a24457faa13f88f55979b9 Mon Sep 17 00:00:00 2001 From: Guo Wenxue <guowenxue@gmail.com> Date: Sun, 29 Dec 2024 14:45:29 +0800 Subject: [PATCH] Update infrared code to support two channels --- modules/sht20.c | 273 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 173 insertions(+), 100 deletions(-) diff --git a/modules/sht20.c b/modules/sht20.c index c3aa745..f549369 100644 --- a/modules/sht20.c +++ b/modules/sht20.c @@ -10,7 +10,7 @@ * ChangeLog: 1, Release initial version on "10/08/23 17:52:00" * * Pin connection: - * STH20 Module Raspberry Pi Board + * SHT20 Raspberry Pi 40Pin * VCC <-----> #Pin1(3.3V) * SDA <-----> #Pin3(SDA, BCM GPIO2) * SCL <-----> #Pin5(SCL, BCM GPIO3) @@ -20,6 +20,7 @@ * dtoverlay=i2c1,pins_2_3 * ********************************************************************************/ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -53,22 +54,26 @@ MODE_RDWR, /* I2C device API use read()/write() */ }; -typedef struct sht2x_s +typedef struct i2c_s { - char *dev; /* SHT20 connect I2C device, /dev/i2c-N */ - int addr; /* SHT20 7-bits slave address */ + char *dev; /* I2C master device, /dev/i2c-N */ + int addr; /* 7-bits slave address */ int fd; /* File description */ int mode; /* I2C device API use read/write or ioctl mode */ -} sht2x_t; +} i2c_t; -int sht2x_init(sht2x_t *sht2x); -int sht2x_get_serialnumber(sht2x_t *sht2x, uint8_t *serialnumber, int size); -int sht2x_get_temp_humidity(sht2x_t *sht2x, float *temp, float *rh); +int sht2x_softreset(i2c_t *i2c); +int sht2x_get_serialnumber(i2c_t *i2c, uint8_t *serialnumber, int size); +int sht2x_get_temp_humidity(i2c_t *i2c, float *temp, float *rh); + +int i2c_init(i2c_t *i2c, int mode, char *i2cdev, int addr); +int i2c_write(i2c_t *i2c, uint8_t *data, int len); +int i2c_read(i2c_t *i2c, uint8_t *buf, int size); +void i2c_term(i2c_t *i2c); static inline void msleep(unsigned long ms); -static inline void dump_buf(const char *prompt, uint8_t *buf, int size); -static int i2c_write(sht2x_t *sht2x, uint8_t *data, int len); -static int i2c_read(sht2x_t *sht2x, uint8_t *buf, int size); +void print_buf(const char *prompt, uint8_t *buf, int size); +void dump_buf(const char *prompt, char *buffer, size_t length); static inline void banner(const char *progname) { @@ -94,11 +99,13 @@ int main(int argc, char **argv) { + char *dev="/dev/i2c-1"; + char *progname=NULL; + int mode = MODE_IOCTL; int rv; float temp, rh; uint8_t serialnumber[8]; - char *progname=NULL; - sht2x_t sht2x; + i2c_t i2c; struct option long_options[] = { {"device", required_argument, NULL, 'd'}, @@ -110,21 +117,17 @@ progname = basename(argv[0]); - memset(&sht2x, 0, sizeof(sht2x)); - sht2x.addr = SHT2X_CHIPADDR; - sht2x.dev = "/dev/i2c-1"; - /* Parser the command line parameters */ while ((rv = getopt_long(argc, argv, "d:m:vh", long_options, NULL)) != -1) { switch (rv) { case 'd': /* Set I2C device path: /dev/i2c-1 */ - sht2x.dev = optarg; + dev = optarg; break; case 'm': /* Set I2C API mode: 0,1 */ - sht2x.mode = atoi(optarg) ? MODE_RDWR : MODE_IOCTL; + mode = atoi(optarg) ? MODE_RDWR : MODE_IOCTL; break; case 'v': /* Get software version */ @@ -140,19 +143,25 @@ } } - if( sht2x_init(&sht2x) < 0 ) + if( i2c_init(&i2c, mode, dev, SHT2X_CHIPADDR) < 0 ) + { + printf("I2C master device initial failed.\n"); + return 1; + } + + if( sht2x_softreset(&i2c) < 0 ) { printf("SHT2x initialize failure, maybe device not present!\n"); return 1; } - if( sht2x_get_serialnumber(&sht2x, serialnumber, 8) < 0) + if( sht2x_get_serialnumber(&i2c, serialnumber, 8) < 0) { printf("SHT2x get serial number failure\n"); return 3; } - if( sht2x_get_temp_humidity(&sht2x, &temp, &rh) < 0 ) + if( sht2x_get_temp_humidity(&i2c, &temp, &rh) < 0 ) { printf("SHT2x get get temperature and relative humidity failure\n"); return 3; @@ -160,14 +169,16 @@ printf("Temperature=%lf ℃ relative humidity=%lf.\n", temp, rh); - close(sht2x.fd); + i2c_term(&i2c); + + return 0; } -int sht2x_softreset(sht2x_t *sht2x) +int sht2x_softreset(i2c_t *i2c) { uint8_t buf[1]; - if( !sht2x || sht2x->fd<0 ) + if( !i2c || i2c->fd<0 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; @@ -175,7 +186,7 @@ /* software reset SHT2x */ buf[0] = SOFTRESET; - if( i2c_write(sht2x, buf, 1) < 0 ) + if( i2c_write(i2c, buf, 1) < 0 ) { return -2; } @@ -185,35 +196,11 @@ return 0; } -int sht2x_init(sht2x_t *sht2x) -{ - if( (sht2x->fd=open(sht2x->dev, O_RDWR)) < 0) - { - printf("i2c device open failed: %s\n", strerror(errno)); - return -1; - } - - if( MODE_RDWR == sht2x->mode ) - { - /* set I2C mode and SHT2x slave address */ - ioctl(sht2x->fd, I2C_TENBIT, 0); /* Not 10-bit but 7-bit mode */ - ioctl(sht2x->fd, I2C_SLAVE, SHT2X_CHIPADDR); /* set SHT2x slave address 0x40*/ - } - - if( sht2x_softreset(sht2x) < 0 ) - { - printf("SHT2x softreset failure\n"); - return -2; - } - - return 0; -} - -int sht2x_get_temp_humidity(sht2x_t *sht2x, float *temp, float *rh) +int sht2x_get_temp_humidity(i2c_t *i2c, float *temp, float *rh) { uint8_t buf[4]; - if( !sht2x || !temp || !rh || sht2x->fd<0 ) + if( !i2c || !temp || !rh || i2c->fd<0 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; @@ -222,35 +209,35 @@ /* send trigger temperature measure command and read the data */ memset(buf, 0, sizeof(buf)); buf[0]=TRIGGER_TEMPERATURE_NO_HOLD; - i2c_write(sht2x, buf, 1); + i2c_write(i2c, buf, 1); msleep(85); /* datasheet: typ=66, max=85 */ memset(buf, 0, sizeof(buf)); - i2c_read(sht2x, buf, 3); - dump_buf("Temperature sample data: ", buf, 3); + i2c_read(i2c, buf, 3); + print_buf("Temperature sample data: ", buf, 3); *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85; /* send trigger humidity measure command and read the data */ memset(buf, 0, sizeof(buf)); buf[0] = TRIGGER_HUMIDITY_NO_HOLD; - i2c_write(sht2x, buf, 1); + i2c_write(i2c, buf, 1); msleep(29); /* datasheet: typ=22, max=29 */ memset(buf, 0, sizeof(buf)); - i2c_read(sht2x, buf, 3); - dump_buf("Relative humidity sample data: ", buf, 3); + i2c_read(i2c, buf, 3); + print_buf("Relative humidity sample data: ", buf, 3); *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6; return 0; } -int sht2x_get_serialnumber(sht2x_t *sht2x, uint8_t *serialnumber, int size) +int sht2x_get_serialnumber(i2c_t *i2c, uint8_t *serialnumber, int size) { uint8_t buf[4]={0x0}; - if( !sht2x || sht2x->fd<0 || !serialnumber || size!=8 ) + if( !i2c || i2c->fd<0 || !serialnumber || size!=8 ) { printf("%s line [%d] %s() get invalid input arguments\n", __FILE__, __LINE__, __func__ ); return -1; @@ -260,10 +247,10 @@ memset(buf, 0, sizeof(buf)); buf[0] = 0xfa; /* command for readout on-chip memory */ buf[1] = 0x0f; /* on-chip memory address */ - i2c_write(sht2x, buf, 2); + i2c_write(i2c, buf, 2); memset(buf, 0, sizeof(buf)); - i2c_read(sht2x, buf, 4); + i2c_read(i2c, buf, 4); if( !buf[0] && !buf[1] && !buf[2] && !buf[3] ) { @@ -280,24 +267,65 @@ memset(buf, 0, sizeof(buf) ); buf[0]=0xfc; /* command for readout on-chip memory */ buf[1]=0xc9; /* on-chip memory address */ - i2c_write(sht2x, buf, 2); + i2c_write(i2c, buf, 2); memset(buf, 0, sizeof(buf) ); - i2c_read(sht2x, buf, 4); + i2c_read(i2c, buf, 4); serialnumber[1]=buf[0]; /* Read SNC_1 */ serialnumber[0]=buf[1]; /* Read SNC_0 */ serialnumber[7]=buf[2]; /* Read SNA_1 */ serialnumber[6]=buf[3]; /* Read SNA_0 */ - dump_buf("SHT2x Serial number: ", serialnumber, 8); + print_buf("SHT2x Serial number: ", serialnumber, 8); return 0; } -static int i2c_write(sht2x_t *sht2x, uint8_t *data, int len) +/*+----------------------+ + *| I2C API functions | + *+----------------------+*/ + +int i2c_init(i2c_t *i2c, int mode, char *i2cdev, int addr) { - struct i2c_rdwr_ioctl_data i2cdata; + if( !i2c || !i2cdev || !addr ) + return -1; + + memset(i2c, 0, sizeof(*i2c)); + i2c->addr = addr; + i2c->dev = i2cdev; + i2c->mode = mode; + + if( (i2c->fd=open(i2cdev, O_RDWR)) < 0) + { + printf("open i2c device %s failed: %s\n", i2cdev, strerror(errno)); + return -1; + } + + if( MODE_RDWR == i2c->mode ) + { + /* set I2C mode and SHT2x slave address */ + ioctl(i2c->fd, I2C_TENBIT, 0); /* Not 10-bit but 7-bit mode */ + ioctl(i2c->fd, I2C_SLAVE, i2c->addr); /* set SHT2x slave address */ + } + + return 0; +} + +void i2c_term(i2c_t *i2c) +{ + if( !i2c ) + return; + + if( i2c->fd > 0) + close(i2c->fd); + + return ; +} + +int i2c_write(i2c_t *i2c, uint8_t *data, int len) +{ + struct i2c_rdwr_ioctl_data tr; int rv = 0; if( !data || len<= 0) @@ -307,35 +335,35 @@ } /* I2C device program API: read()/write() */ - if( MODE_RDWR == sht2x->mode ) + if( MODE_RDWR == i2c->mode ) { - write(sht2x->fd, data, len); + write(i2c->fd, data, len); return 0; } /* I2C device program API: ioctl() */ - i2cdata.nmsgs = 1; - i2cdata.msgs = malloc( sizeof(struct i2c_msg)*i2cdata.nmsgs ); - if ( !i2cdata.msgs ) + tr.nmsgs = 1; + tr.msgs = malloc( sizeof(struct i2c_msg)*tr.nmsgs ); + if ( !tr.msgs ) { printf("%s() msgs malloc failed!\n", __func__); return -2; } - i2cdata.msgs[0].addr = sht2x->addr; - i2cdata.msgs[0].flags = 0; //write - i2cdata.msgs[0].len = len; - i2cdata.msgs[0].buf = malloc(len); - if( !i2cdata.msgs[0].buf ) + tr.msgs[0].addr = i2c->addr; + tr.msgs[0].flags = 0; //write + tr.msgs[0].len = len; + tr.msgs[0].buf = malloc(len); + if( !tr.msgs[0].buf ) { printf("%s() msgs malloc failed!\n", __func__); rv = -3; goto cleanup; } - memcpy(i2cdata.msgs[0].buf, data, len); + memcpy(tr.msgs[0].buf, data, len); - if( ioctl(sht2x->fd, I2C_RDWR, &i2cdata)<0 ) + if( ioctl(i2c->fd, I2C_RDWR, &tr)<0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); rv = -4; @@ -343,18 +371,18 @@ } cleanup: - if( i2cdata.msgs[0].buf ) - free(i2cdata.msgs[0].buf); + if( tr.msgs[0].buf ) + free(tr.msgs[0].buf); - if( i2cdata.msgs ) - free(i2cdata.msgs); + if( tr.msgs ) + free(tr.msgs); return rv; } -static int i2c_read(sht2x_t *sht2x, uint8_t *buf, int size) +int i2c_read(i2c_t *i2c, uint8_t *buf, int size) { - struct i2c_rdwr_ioctl_data i2cdata; + struct i2c_rdwr_ioctl_data tr; int rv = 0; if( !buf || size<= 0) @@ -364,40 +392,40 @@ } /* I2C device program API: read()/write() */ - if( MODE_RDWR == sht2x->mode ) + if( MODE_RDWR == i2c->mode ) { - read(sht2x->fd, buf, size); + read(i2c->fd, buf, size); return 0; } /* I2C device program API: ioctl() */ - i2cdata.nmsgs = 1; - i2cdata.msgs = malloc( sizeof(struct i2c_msg)*i2cdata.nmsgs ); - if ( !i2cdata.msgs ) + tr.nmsgs = 1; + tr.msgs = malloc( sizeof(struct i2c_msg)*tr.nmsgs ); + if ( !tr.msgs ) { printf("%s() msgs malloc failed!\n", __func__); return -2; } - i2cdata.msgs[0].addr = sht2x->addr; - i2cdata.msgs[0].flags = I2C_M_RD; //read - i2cdata.msgs[0].len = size; - i2cdata.msgs[0].buf = buf; + tr.msgs[0].addr = i2c->addr; + tr.msgs[0].flags = I2C_M_RD; //read + tr.msgs[0].len = size; + tr.msgs[0].buf = buf; memset(buf, 0, size); - if( ioctl(sht2x->fd, I2C_RDWR, &i2cdata)<0 ) + if( ioctl(i2c->fd, I2C_RDWR, &tr)<0 ) { printf("%s() ioctl failure: %s\n", __func__, strerror(errno)); rv = -4; } - free( i2cdata.msgs ); + free( tr.msgs ); return rv; } -/*+----------------+ - *| Misc functions | - *+----------------+*/ +/*+----------------------+ + *| Misc functions | + *+----------------------+*/ static inline void msleep(unsigned long ms) { @@ -418,7 +446,7 @@ nanosleep(&cSleep, 0); } -static inline void dump_buf(const char *prompt, uint8_t *buf, int size) +void print_buf(const char *prompt, uint8_t *buf, int size) { int i; @@ -440,3 +468,48 @@ return ; } + +void dump_buf(const char *prompt, char *buffer, size_t length) +{ + size_t i, j; + + if (prompt) + { + printf("%s\n", prompt); + } + + for (i = 0; i < length; i += 16) + { + printf("%08zx: ", i); + + for (j = 0; j < 16; j++) + { + if (i + j < length) + { + printf("%02x ", buffer[i + j]); + } + else + { + printf(" "); + } + } + + printf(" "); + + for (j = 0; j < 16; j++) + { + if (i + j < length) + { + unsigned char c = buffer[i + j]; + printf("%c", (c >= 32 && c <= 126) ? c : '.'); + } + else + { + printf(" "); + } + } + + printf("\n"); + } +} + -- Gitblit v1.9.1