From d973d6f8e12b16c3cdd84e63e19b61187424f4ce Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Thu, 14 Mar 2024 10:06:12 +0800
Subject: [PATCH] Add AT24C EEPROM code

---
 modules/sht20.c |  300 ++++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 200 insertions(+), 100 deletions(-)

diff --git a/modules/sht20.c b/modules/sht20.c
index c3aa745..477adc6 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 *buf, size_t len);
 
 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,75 @@
 
     return ;
 }
+
+#define LINELEN 81
+#define CHARS_PER_LINE 16
+static char *print_char =
+"                "
+"                "
+" !\"#$%&'()*+,-./"
+"0123456789:;<=>?"
+"@ABCDEFGHIJKLMNO"
+"PQRSTUVWXYZ[\\]^_"
+"`abcdefghijklmno"
+"pqrstuvwxyz{|}~ "
+"                "
+"                "
+" ???????????????"
+"????????????????"
+"????????????????"
+"????????????????"
+"????????????????"
+"????????????????";
+
+void dump_buf(const char *prompt, char *buf, size_t len)
+{
+    int rc;
+    int idx;
+    char prn[LINELEN];
+    char lit[CHARS_PER_LINE + 2];
+    char hc[4];
+    short line_done = 1;
+
+    if( prompt )
+        printf("%s", prompt);
+
+    rc = len;
+    idx = 0;
+    lit[CHARS_PER_LINE] = '\0';
+
+    while (rc > 0)
+    {
+        if (line_done)
+            snprintf(prn, LINELEN, "%08X: ", idx);
+
+        do
+        {
+            unsigned char c = buf[idx];
+            snprintf(hc, 4, "%02X ", c);
+            strncat(prn, hc, LINELEN);
+
+            lit[idx % CHARS_PER_LINE] = print_char[c];
+        }
+        while (--rc > 0 && (++idx % CHARS_PER_LINE != 0));
+
+        line_done = (idx % CHARS_PER_LINE) == 0;
+        if (line_done)
+        {
+            printf("%s  %s\r\n", prn, lit);
+        }
+    }
+
+    if (!line_done)
+    {
+        int ldx = idx % CHARS_PER_LINE;
+        lit[ldx++] = print_char[(int)buf[idx]];
+        lit[ldx] = '\0';
+
+        while ((++idx % CHARS_PER_LINE) != 0)
+            strncat(prn, "   ", sizeof(prn)-strlen(prn));
+
+        printf("%s  %s\r\n", prn, lit);
+
+    }
+}

--
Gitblit v1.9.1