Mercurial > ~darius > hgwebdir.cgi > tempctrl
comparison 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 |
comparison
equal
deleted
inserted
replaced
50:a13e0ccc1d2d | 51:cb184206344d |
---|---|
27 */ | 27 */ |
28 | 28 |
29 #include <stdio.h> | 29 #include <stdio.h> |
30 #include <stdint.h> | 30 #include <stdint.h> |
31 #include <stdlib.h> | 31 #include <stdlib.h> |
32 #include <string.h> | |
32 #include <avr/interrupt.h> | 33 #include <avr/interrupt.h> |
33 #include <avr/pgmspace.h> | 34 #include <avr/pgmspace.h> |
34 #include <avr/eeprom.h> | 35 #include <avr/eeprom.h> |
35 #include <avr/wdt.h> | 36 #include <avr/wdt.h> |
36 #include <util/crc16.h> | 37 #include <util/crc16.h> |
416 */ | 417 */ |
417 void | 418 void |
418 tempctrl_cmd(char *buf) { | 419 tempctrl_cmd(char *buf) { |
419 char cmd[6]; | 420 char cmd[6]; |
420 int16_t data; | 421 int16_t data; |
421 int i; | 422 uint8_t ROM[8]; |
422 | 423 |
423 i = sscanf_P(buf, PSTR("tc %5s %d"), cmd, &data); | 424 if (sscanf_P(buf, PSTR("tc %5s"), cmd, &data) == 0) { |
424 | 425 printf_P(PSTR("Unable to parse tc subcommand\r\n")); |
425 if (i == 1) { | 426 return; |
426 if (!strcasecmp_P(cmd, PSTR("help"))) { | 427 } |
427 printf_P(PSTR( | 428 |
428 "tc help This help\r\n" | 429 if (!strcasecmp_P(cmd, PSTR("help"))) { |
429 "tc save Save settings to EEPROM\r\n" | 430 printf_P(PSTR( |
430 "tc load Load or default settings from EEPROM\r\n" | 431 "tc help This help\r\n" |
431 "tc dflt Load defaults from flash\r\n" | 432 "tc save Save settings to EEPROM\r\n" |
432 "tc list List current settings\r\n" | 433 "tc load Load or default settings from EEPROM\r\n" |
433 "tc mode [achin] Change control mode, must be one of\r\n" | 434 "tc dflt Load defaults from flash\r\n" |
434 " a Auto\r\n" | 435 "tc list List current settings\r\n" |
435 " c Always cool\r\n" | 436 "tc mode [achin] Change control mode, must be one of\r\n" |
436 " h Always heat\r\n" | 437 " a Auto\r\n" |
437 " i Always idle\r\n" | 438 " c Always cool\r\n" |
438 " n Like idle but don't log anything\r\n" | 439 " h Always heat\r\n" |
439 "\r\n" | 440 " i Always idle\r\n" |
440 "tc X Y Set X to Y where X is one of\r\n" | 441 " n Like idle but don't log anything\r\n" |
441 " targ Target temperature\r\n" | 442 "tc X Y Set X to Y where X is one of\r\n" |
442 " hys Hysteresis range\r\n" | 443 " targ Target temperature\r\n" |
443 " mhov Minimum heat overshoot\r\n" | 444 " hys Hysteresis range\r\n" |
444 " mcov Minimum cool overshoot\r\n" | 445 " mhov Minimum heat overshoot\r\n" |
445 " mcon Minimum cool on time\r\n" | 446 " mcov Minimum cool overshoot\r\n" |
446 " mcoff Minimum cool off time\r\n" | 447 " mcon Minimum cool on time\r\n" |
447 " mhin Minimum heat on time\r\n" | 448 " mcoff Minimum cool off time\r\n" |
448 " mhoff Minimum heat off time\r\n" | 449 " mhin Minimum heat on time\r\n" |
449 " Times are in seconds\r\n" | 450 " mhoff Minimum heat off time\r\n" |
450 " Temperatures are in hundredths of degrees Celcius\r\n" | 451 "tc A B Set temperature sensor ID\r\n" |
451 )); | 452 " Where A is ferm, frg or amb\r\n" |
452 return; | 453 " and B is of the form xx:xx:xx:xx:xx:xx:xx:xx\r\n" |
454 "\r\n" | |
455 " Times are in seconds\r\n" | |
456 " Temperatures are in hundredths of degrees Celcius\r\n" | |
457 )); | |
458 return; | |
459 } | |
460 | |
461 if (!strcasecmp_P(cmd, PSTR("save"))) { | |
462 tempctrl_write_settings(); | |
463 return; | |
464 } | |
465 if (!strcasecmp_P(cmd, PSTR("load"))) { | |
466 tempctrl_load_or_init_settings(); | |
467 return; | |
468 } | |
469 if (!strcasecmp_P(cmd, PSTR("dflt"))) { | |
470 tempctrl_default_settings(); | |
471 return; | |
472 } | |
473 if (!strcasecmp_P(cmd, PSTR("list"))) { | |
474 printf_P(PSTR("Fermenter ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
475 "Fridge ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
476 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
477 "Mode - %c, Target - %d, Hystersis - %d\r\n" | |
478 "Min heat overshoot - %d, Min cool overshoot - %d\r\n" | |
479 "Min cool on time - %d, Min cool off time - %d\r\n" | |
480 "Min heat on time - %d, Min heat off time - %d\r\n"), | |
481 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], | |
482 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], | |
483 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], | |
484 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], | |
485 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], | |
486 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], | |
487 settings.mode, settings.target_temp, settings.hysteresis, | |
488 settings.minheatovershoot, settings.mincoolovershoot, | |
489 settings.mincoolontime, settings.minheatontime, | |
490 settings.minheatontime, settings.minheatofftime); | |
491 return; | |
492 } | |
493 if (!strcasecmp_P(cmd, PSTR("mode"))) { | |
494 switch (buf[8]) { | |
495 case TC_MODE_AUTO: | |
496 case TC_MODE_HEAT: | |
497 case TC_MODE_COOL: | |
498 case TC_MODE_IDLE: | |
499 case TC_MODE_NOTHING: | |
500 settings.mode = buf[8]; | |
501 break; | |
502 | |
503 default: | |
504 printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]); | |
505 break; | |
453 } | 506 } |
454 | 507 return; |
455 if (!strcasecmp_P(cmd, PSTR("save"))) { | 508 } |
456 tempctrl_write_settings(); | 509 if (!strcasecmp_P(cmd, PSTR("ferm")) || |
457 return; | 510 !strcasecmp_P(cmd, PSTR("frg")) || |
511 !strcasecmp_P(cmd, PSTR("amb"))) { | |
512 | |
513 if (sscanf_P((char *)cmd, PSTR("tc %5s %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), cmd, | |
514 &ROM[0], &ROM[1], &ROM[2], &ROM[3], | |
515 &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 9) { | |
516 printf_P(PSTR("Unable to parse ROM ID\r\n")); | |
517 } else { | |
518 if (!strcasecmp_P(cmd, PSTR("ferm"))) | |
519 memcpy(settings.fermenter_ROM, ROM, sizeof(ROM)); | |
520 if (!strcasecmp_P(cmd, PSTR("frg"))) | |
521 memcpy(settings.fridge_ROM, ROM, sizeof(ROM)); | |
522 if (!strcasecmp_P(cmd, PSTR("amb"))) | |
523 memcpy(settings.ambient_ROM, ROM, sizeof(ROM)); | |
458 } | 524 } |
459 if (!strcasecmp_P(cmd, PSTR("load"))) { | 525 } |
460 tempctrl_load_or_init_settings(); | 526 |
461 return; | 527 if (sscanf_P(buf, PSTR("tc %5s %d"), cmd, &data) != 2) { |
462 } | 528 printf_P(PSTR("Unable to parse tc subcommand & value\r\n")); |
463 if (!strcasecmp_P(cmd, PSTR("dflt"))) { | |
464 tempctrl_default_settings(); | |
465 return; | |
466 } | |
467 if (!strcasecmp_P(cmd, PSTR("list"))) { | |
468 printf_P(PSTR("Fermenter ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
469 "Fridge ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
470 "Ambient ROM ID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\r\n" | |
471 "Mode - %c, Target - %d, Hystersis - %d\r\n" | |
472 "Min heat overshoot - %d, Min cool overshoot - %d\r\n" | |
473 "Min cool on time - %d, Min cool off time - %d\r\n" | |
474 "Min heat on time - %d, Min heat off time - %d\r\n"), | |
475 settings.fermenter_ROM[0], settings.fermenter_ROM[1], settings.fermenter_ROM[2], settings.fermenter_ROM[3], | |
476 settings.fermenter_ROM[4], settings.fermenter_ROM[5], settings.fermenter_ROM[6], settings.fermenter_ROM[7], | |
477 settings.fridge_ROM[0], settings.fridge_ROM[1], settings.fridge_ROM[2], settings.fridge_ROM[3], | |
478 settings.fridge_ROM[4], settings.fridge_ROM[5], settings.fridge_ROM[6], settings.fridge_ROM[7], | |
479 settings.ambient_ROM[0], settings.ambient_ROM[1], settings.ambient_ROM[2], settings.ambient_ROM[3], | |
480 settings.ambient_ROM[4], settings.ambient_ROM[5], settings.ambient_ROM[6], settings.ambient_ROM[7], | |
481 settings.mode, settings.target_temp, settings.hysteresis, | |
482 settings.minheatovershoot, settings.mincoolovershoot, | |
483 settings.mincoolontime, settings.minheatontime, | |
484 settings.minheatontime, settings.minheatofftime); | |
485 return; | |
486 } | |
487 if (!strcasecmp_P(cmd, PSTR("mode"))) { | |
488 switch (buf[8]) { | |
489 case TC_MODE_AUTO: | |
490 case TC_MODE_HEAT: | |
491 case TC_MODE_COOL: | |
492 case TC_MODE_IDLE: | |
493 case TC_MODE_NOTHING: | |
494 settings.mode = buf[8]; | |
495 break; | |
496 | |
497 default: | |
498 printf_P(PSTR("Unknown mode character '%c'\r\n"), buf[8]); | |
499 break; | |
500 } | |
501 return; | |
502 } | |
503 | |
504 } | |
505 | |
506 if (i != 2) { | |
507 printf_P(PSTR("Unable to parse command\r\n")); | |
508 return; | 529 return; |
509 } | 530 } |
510 | 531 |
511 if (!strcasecmp_P(cmd, PSTR("targ"))) { | 532 if (!strcasecmp_P(cmd, PSTR("targ"))) { |
512 settings.target_temp = data; | 533 settings.target_temp = data; |