diff tempctrl.c @ 51:cb184206344d

Rejig command parsing and assume the compiler isn't dumb (eg it can reuse stack variables).
author darius@Inchoate
date Wed, 29 Oct 2008 16:09:55 +1030
parents a13e0ccc1d2d
children 58f1ec46bff6
line wrap: on
line diff
--- a/tempctrl.c	Wed Oct 29 16:06:42 2008 +1030
+++ b/tempctrl.c	Wed Oct 29 16:09:55 2008 +1030
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 #include <avr/interrupt.h>
 #include <avr/pgmspace.h>
 #include <avr/eeprom.h>
@@ -418,93 +419,113 @@
 tempctrl_cmd(char *buf) {
     char	cmd[6];
     int16_t	data;
-    int		i;
-
-    i = sscanf_P(buf, PSTR("tc %5s %d"), cmd, &data);
-
-    if (i == 1) {
-	if (!strcasecmp_P(cmd, PSTR("help"))) {
-	    printf_P(PSTR(
-			 "tc help	  This help\r\n"
-			 "tc save	  Save settings to EEPROM\r\n"
-			 "tc load	  Load or default settings from EEPROM\r\n"
-			 "tc dflt	  Load defaults from flash\r\n"
-			 "tc list	  List current settings\r\n"
-			 "tc mode [achin] Change control mode, must be one of\r\n"
-			 "                 a	Auto\r\n"
-			 "		   c	Always cool\r\n"
-			 "                 h	Always heat\r\n"
-			 " 		   i	Always idle\r\n"
-			 "		   n	Like idle but don't log anything\r\n"
-			 "\r\n"
-			 "tc X Y	  Set X to Y where X is one of\r\n"
-			 "   		   targ	Target temperature\r\n"
-			 "   		   hys	Hysteresis range\r\n"
-			 "		   mhov	Minimum heat overshoot\r\n"
-			 "		   mcov	Minimum cool overshoot\r\n"
-			 "		   mcon	Minimum cool on time\r\n"
-			 "		   mcoff	Minimum cool off time\r\n"
-			 "		   mhin	Minimum heat on time\r\n"
-			 "		   mhoff	Minimum heat off time\r\n"
-			 "		  Times are in seconds\r\n"
-			 "		  Temperatures are in hundredths of degrees Celcius\r\n"
-			 ));
-	    return;
-	}
+    uint8_t 	ROM[8];
+    
+    if (sscanf_P(buf, PSTR("tc %5s"), cmd, &data) == 0) {
+	printf_P(PSTR("Unable to parse tc subcommand\r\n"));
+	return;
+    }
+	
+    if (!strcasecmp_P(cmd, PSTR("help"))) {
+	printf_P(PSTR(
+		     "tc help         This help\r\n"
+		     "tc save         Save settings to EEPROM\r\n"
+		     "tc load         Load or default settings from EEPROM\r\n"
+		     "tc dflt         Load defaults from flash\r\n"
+		     "tc list         List current settings\r\n"
+		     "tc mode [achin] Change control mode, must be one of\r\n"
+		     "                 a    Auto\r\n"
+		     "                 c    Always cool\r\n"
+		     "                 h    Always heat\r\n"
+		     "                 i    Always idle\r\n"
+		     "                 n    Like idle but don't log anything\r\n"
+		     "tc X Y          Set X to Y where X is one of\r\n"
+		     "                 targ Target temperature\r\n"
+		     "                 hys  Hysteresis range\r\n"
+		     "                 mhov Minimum heat overshoot\r\n"
+		     "                 mcov Minimum cool overshoot\r\n"
+		     "                 mcon Minimum cool on time\r\n"
+		     "                 mcoff        Minimum cool off time\r\n"
+		     "                 mhin Minimum heat on time\r\n"
+		     "                 mhoff        Minimum heat off time\r\n"
+		     "tc A B          Set temperature sensor ID\r\n"
+		     "                 Where A is ferm, frg or amb\r\n"
+		     "                 and B is of the form xx:xx:xx:xx:xx:xx:xx:xx\r\n"
+		     "\r\n"
+		     "                Times are in seconds\r\n"
+		     "                Temperatures are in hundredths of degrees Celcius\r\n"
+		     ));
+	return;
+    }
 	
-	if (!strcasecmp_P(cmd, PSTR("save"))) {
-	    tempctrl_write_settings();
-	    return;
-	}
-	if (!strcasecmp_P(cmd, PSTR("load"))) {
-	    tempctrl_load_or_init_settings();
-	    return;
+    if (!strcasecmp_P(cmd, PSTR("save"))) {
+	tempctrl_write_settings();
+	return;
+    }
+    if (!strcasecmp_P(cmd, PSTR("load"))) {
+	tempctrl_load_or_init_settings();
+	return;
+    }
+    if (!strcasecmp_P(cmd, PSTR("dflt"))) {
+	tempctrl_default_settings();
+	return;
+    }
+    if (!strcasecmp_P(cmd, PSTR("list"))) {
+	printf_P(PSTR("Fermenter ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
+		      "Fridge ROM ID    %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
+		      "Ambient ROM ID   %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
+		      "Mode - %c, Target - %d, Hystersis - %d\r\n"
+		      "Min heat overshoot - %d, Min cool overshoot - %d\r\n"
+		      "Min cool on time - %d, Min cool off time - %d\r\n"
+		      "Min heat on time - %d, Min heat off time - %d\r\n"),
+		 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], 
+		 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], 
+		 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], 
+		 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], 
+		 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], 
+		 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], 
+		 settings.mode, settings.target_temp, settings.hysteresis,
+		 settings.minheatovershoot, settings.mincoolovershoot,
+		 settings.mincoolontime, settings.minheatontime,
+		 settings.minheatontime, settings.minheatofftime);
+	return;
+    }
+    if (!strcasecmp_P(cmd, PSTR("mode"))) {
+	switch (buf[8]) {
+	    case TC_MODE_AUTO:
+	    case TC_MODE_HEAT:
+	    case TC_MODE_COOL:
+	    case TC_MODE_IDLE:
+	    case TC_MODE_NOTHING:
+		settings.mode = buf[8];
+		break;
+		    
+	    default:
+		printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]);
+		break;
 	}
-	if (!strcasecmp_P(cmd, PSTR("dflt"))) {
-	    tempctrl_default_settings();
-	    return;
+	return;
+    }
+    if (!strcasecmp_P(cmd, PSTR("ferm")) ||
+	!strcasecmp_P(cmd, PSTR("frg")) ||
+	!strcasecmp_P(cmd, PSTR("amb"))) {
+
+	if (sscanf_P((char *)cmd, PSTR("tc %5s %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), cmd,
+		     &ROM[0], &ROM[1], &ROM[2], &ROM[3],
+		     &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 9) {
+	    printf_P(PSTR("Unable to parse ROM ID\r\n"));
+	} else {
+	    if (!strcasecmp_P(cmd, PSTR("ferm")))
+		memcpy(settings.fermenter_ROM, ROM, sizeof(ROM));
+	    if (!strcasecmp_P(cmd, PSTR("frg")))
+		memcpy(settings.fridge_ROM, ROM, sizeof(ROM));
+	    if (!strcasecmp_P(cmd, PSTR("amb")))
+		memcpy(settings.ambient_ROM, ROM, sizeof(ROM));
 	}
-	if (!strcasecmp_P(cmd, PSTR("list"))) {
-	    printf_P(PSTR("Fermenter ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
-			  "Fridge ROM ID    %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
-			  "Ambient ROM ID   %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n"
-			  "Mode - %c, Target - %d, Hystersis - %d\r\n"
-			  "Min heat overshoot - %d, Min cool overshoot - %d\r\n"
-			  "Min cool on time - %d, Min cool off time - %d\r\n"
-			  "Min heat on time - %d, Min heat off time - %d\r\n"),
-		     settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], 
-		     settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], 
-		     settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], 
-		     settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], 
-		     settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], 
-		     settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], 
-		     settings.mode, settings.target_temp, settings.hysteresis,
-		     settings.minheatovershoot, settings.mincoolovershoot,
-		     settings.mincoolontime, settings.minheatontime,
-		     settings.minheatontime, settings.minheatofftime);
-	    return;
-	}
-	if (!strcasecmp_P(cmd, PSTR("mode"))) {
-	    switch (buf[8]) {
-		case TC_MODE_AUTO:
-		case TC_MODE_HEAT:
-		case TC_MODE_COOL:
-		case TC_MODE_IDLE:
-		case TC_MODE_NOTHING:
-		    settings.mode = buf[8];
-		    break;
-		    
-		default:
-		    printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]);
-		    break;
-	    }
-	    return;
-	}
-	
     }
     
-    if (i != 2) {
-	printf_P(PSTR("Unable to parse command\r\n"));
+    if (sscanf_P(buf, PSTR("tc %5s %d"), cmd, &data) != 2) {
+	printf_P(PSTR("Unable to parse tc subcommand & value\r\n"));
 	return;
     }