Mercurial > ~darius > hgwebdir.cgi > avr
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; }