thermferm/one-wire.c

changeset 660
a28ef4d9afa4
parent 659
bfab45f4d5cd
child 661
8c1e7a52e24f
--- a/thermferm/one-wire.c	Wed Apr 03 19:33:38 2024 +0200
+++ b/thermferm/one-wire.c	Fri Apr 05 16:19:39 2024 +0200
@@ -28,12 +28,14 @@
 #include "futil.h"
 #include "xutil.h"
 
+#define	W1_TEMP_RESOLUTION	12
+
 
 extern sys_config	Config;
-extern int		my_shutdown;
 extern pthread_mutex_t	mutexes[5];
 
 int			my_one_wire_state = 0;
+int			my_one_wire_shutdown = 0;
 w1_list			*w1_devices = NULL;
 
 
@@ -66,17 +68,17 @@
     ScanNew,
     ScanDel,
     Read2413,
-    Reading,
+    ReadTemp,
     Missing
 SM_NAMES
     (char *)"ScanNew",
     (char *)"ScanDel",
     (char *)"Read2413",
-    (char *)"Reading",
+    (char *)"ReadTemp",
     (char *)"Missing"
 SM_EDECL
 
-    int			found, i, rc;
+    int			found, i, rc, value, conv_time;
     FILE		*fp;
     devices_list	*device;
     w1_list		*dev_w1, *n_w1, *cur_w1 = NULL;
@@ -87,7 +89,7 @@
 
 SM_STATE(ScanNew)
 
-    if (my_shutdown) {
+    if (my_one_wire_shutdown) {
 	SM_SUCCESS;
     }
 
@@ -122,9 +124,9 @@
 			pthread_mutex_unlock(&mutexes[LOCK_ONE_WIRE]);
 			for (device = Config.devices; device; device = device->next) {
 			    if (strcmp(dev_w1->address, device->address) == 0) {
-				pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
+//				pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
 				device->present = DEVPRESENT_YES;
-				pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
+//				pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
 			    }
 			}
 		    }
@@ -139,7 +141,8 @@
 		strncpy(n_w1->family, buffer, 2);
 		n_w1->family[2] = '\0';
 		n_w1->present = DEVPRESENT_YES;
-		n_w1->subdevices = (strcmp(w1type, (char *)"3a") == 0) ? 2:1;
+		n_w1->value = (strcmp(w1type, (char *)"3a") == 0) ? 3:-1;
+//		n_w1->subdevices = (strcmp(w1type, (char *)"3a") == 0) ? 2:1;
 		n_w1->timestamp = time(NULL);
 
 		pthread_mutex_lock(&mutexes[LOCK_ONE_WIRE]);
@@ -165,7 +168,7 @@
 
 SM_STATE(ScanDel)
 
-    if (my_shutdown) {
+    if (my_one_wire_shutdown) {
 	SM_SUCCESS;
     }
 
@@ -192,19 +195,21 @@
 		}
 	    }
 	}
+	free(devfile);
+	devfile = NULL;
     }
 
     SM_PROCEED(Read2413);
 
 SM_STATE(Read2413)
 
-    if (my_shutdown) {
+    if (my_one_wire_shutdown) {
 	SM_SUCCESS;
     }
 
     for (dev_w1 = w1_devices; dev_w1; dev_w1 = dev_w1->next) {
 	if (strcmp(dev_w1->family, "3a") == 0) {
-	    syslog(LOG_NOTICE, "ds2413 %s", dev_w1->address);
+//	    syslog(LOG_NOTICE, "ds2413 %s", dev_w1->address);
 	    for (i = 0; i < 2; i++) {
 		for (device = Config.devices; device; device = device->next) {
 		    if ((strcmp(dev_w1->address, device->address) == 0) && (device->subdevice == i) && (device->direction == DEVDIR_IN_BIN)) {
@@ -216,7 +221,7 @@
 			    state = (unsigned int)rc;
 			    output = ((state & 0x02) >> 1) + ((state & 0x08) >> 2);		/* Both latch states	*/
 			    if ((i == 0) && ((state & 0x02) == 0)) {				/* Fix A side		*/
-				syslog(LOG_NOTICE, "One-wire device %s-%d out %04x -> %04x", dev_w1->address, i, output, output | 0x01);
+				syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x01);
 				output |= 0x01;
 				write_w1(device->address, (char *)"output", output);
 				mDelay(10);
@@ -224,7 +229,7 @@
 				    state = (unsigned int)rc;
 			    }
 			    if ((i == 1) && ((state & 0x08) == 0)) {				/* Fix B side		*/
-				syslog(LOG_NOTICE, "One-wire device %s-%d out %04x -> %04x", dev_w1->address, i, output, output | 0x02);
+				syslog(LOG_NOTICE, "One-wire device %s-%d out %02x -> %02x", dev_w1->address, i, output, output | 0x02);
 				output |= 0x02;
 				write_w1(device->address, (char *)"output", output);
 				mDelay(10);
@@ -232,16 +237,19 @@
 				    state = (unsigned int)rc;
 			    }
 
-			    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
+			    dev_w1->value = ((state & 0x04) >> 1) + (state & 0x01);
+			    syslog(LOG_NOTICE, "One-wire device %s-%d in %02x value %d", dev_w1->address, i, state, dev_w1->value);
+
+//			    pthread_mutex_lock(&mutexes[LOCK_DEVICES]);
 			    /*
 			     * Read PIOA or PIOB pin state bits
 			     */
 			    if (device->subdevice == 0)
-				device->value = (rc & 0x01) ? 0 : 1;
+				device->value = (state & 0x01) ? 0 : 1;
 			    else if (device->subdevice == 1)
-				device->value = (rc & 0x04) ? 0 : 1;
+				device->value = (state & 0x04) ? 0 : 1;
 			    device->timestamp = time(NULL);
-			    pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
+//			    pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
 			}
 			mDelay(20);
 		    }
@@ -250,11 +258,11 @@
 	}
     }
 
-    SM_PROCEED(Reading);
+    SM_PROCEED(ReadTemp);
 
-SM_STATE(Reading)
+SM_STATE(ReadTemp)
 
-    if (my_shutdown) {
+    if (my_one_wire_shutdown) {
 	SM_SUCCESS;
     }
 
@@ -265,17 +273,80 @@
 
 	if ((strcmp(cur_w1->family, (char *)"10") == 0) || (strcmp(cur_w1->family, (char *)"22") == 0) || (strcmp(cur_w1->family, (char *)"28") == 0) ||
 	    (strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0)) {
-	    syslog(LOG_NOTICE, "Reading %s", cur_w1->address);
-	    sleep(1);
+//	    syslog(LOG_NOTICE, "Reading %s", cur_w1->address);
+	    /*
+	     * 1. Read sensor resolution. This is a present check too.
+	     * 2. Fix resolution if wrong.
+	     * 3. Read conversion time.
+	     * 4. Open temperature for read.
+	     * 5. Wait conversion time.
+	     * 6. Read temperature.
+	     */
+	    devfile = xstrcpy((char *)"/sys/bus/w1/devices/");
+	    devfile = xstrcat(devfile, cur_w1->address);
+	    devfile = xstrcat(devfile, (char *)"/resolution");
+	    if ((fp = fopen(devfile, "r+"))) {
+		if ((fgets(buffer, 25, fp))) {
+		     sscanf(buffer, "%d", &value);
+		     if (value != W1_TEMP_RESOLUTION) {
+			syslog(LOG_NOTICE, "One-wire device %s set resolution from %d to %d", cur_w1->address, value, W1_TEMP_RESOLUTION);
+			fseek(fp, 0L, SEEK_SET);
+			sprintf(buffer, "%d", W1_TEMP_RESOLUTION);
+			fputs(buffer, fp);
+		     }
+		}
+		fclose(fp);
+		free(devfile);
+
+		conv_time = 760;
+		devfile = xstrcpy((char *)"/sys/bus/w1/devices/");
+		devfile = xstrcat(devfile, cur_w1->address);
+		devfile = xstrcat(devfile, (char *)"/conv_time");
+		if ((fp = fopen(devfile, "r"))) {
+		    if ((fgets(buffer, 25, fp))) {
+			sscanf(buffer, "%d", &conv_time);
+		    }
+		    fclose(fp);
+		}
+		free(devfile);
+
+		devfile = xstrcpy((char *)"/sys/bus/w1/devices/");
+		devfile = xstrcat(devfile, cur_w1->address);
+		devfile = xstrcat(devfile, (char *)"/temperature");
+		if ((fp = fopen(devfile, "r"))) {
+		    syslog(LOG_NOTICE, "One-wire device %s temperature is open, delay %d", cur_w1->address, conv_time);
+		    mDelay(conv_time);
+		    if ((fgets(buffer, 25, fp))) {
+			sscanf(buffer, "%d", &value);
+			syslog(LOG_NOTICE, "One-wire device %s temperature read %d", cur_w1->address, value);
+			cur_w1->value = value;		/* devices.c will pick this up */
+		    } else {
+			syslog(LOG_NOTICE, "One-wire device %s temperature read error", cur_w1->address);
+		    }
+		    fclose(fp);
+		}
+
+	    } else {
+		syslog(LOG_NOTICE, "One-wire device %s open: %s", cur_w1->address, strerror(errno));
+	    }
+	    free(devfile);
+	    devfile = NULL;
 	}
 
-	if (cur_w1->next != NULL) {
-	    cur_w1 = cur_w1->next;
-	} else {
-	    cur_w1 = w1_devices;
+	for (;;) {
+	    if (cur_w1->next != NULL) {
+	    	cur_w1 = cur_w1->next;
+	    } else {
+	    	cur_w1 = w1_devices;
+	    }
+	    if ((strcmp(cur_w1->family, (char *)"10") == 0) || (strcmp(cur_w1->family, (char *)"22") == 0) || (strcmp(cur_w1->family, (char *)"28") == 0) ||
+		(strcmp(cur_w1->family, (char *)"3b") == 0) || (strcmp(cur_w1->family, (char *)"42") == 0))
+		break;
 	}
+	syslog(LOG_NOTICE, "One-wire device %s next sensor %s", cur_w1->address, cur_w1->family);
 
     } else {
+	syslog(LOG_NOTICE, "cur_w1 == NULL");
     	sleep(1);
     }
 
@@ -283,7 +354,7 @@
 
 SM_STATE(Missing)
 
-    if (my_shutdown) {
+    if (my_one_wire_shutdown) {
 	SM_SUCCESS;
     }
 

mercurial