Mercurial > ~darius > hgwebdir.cgi > sprink
diff sprink.c @ 5:951277329ee6
Use splitargv instead of rolling our own.
Fix WDT tripping continuously on self reset (disable WDT on startup).
Pretty up startup message.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sun, 15 Feb 2015 16:16:54 +1030 |
parents | 1188042ddc2f |
children | 78983502a4e9 |
line wrap: on
line diff
--- a/sprink.c Tue Jan 27 23:40:50 2015 +1030 +++ b/sprink.c Sun Feb 15 16:16:54 2015 +1030 @@ -36,12 +36,15 @@ #include <util/delay.h> #include <avr/wdt.h> +#include "1wire.h" #include "bitstring.h" #include "cons.h" #include "ds1307.h" -#include "1wire.h" +#include "splitargv.h" #include "water.h" +#define MAXARGS 10 + /* ** Fuse bits should be set as follows ** @@ -90,18 +93,20 @@ /* Disable interrupts while we frob stuff */ cli(); + /* Disable watchdog in case it was previously on */ + wdt_disable(); + /* Init UART */ cons_init(); - + + printf_P(PSTR("\r\n\r\n===============\r\n")); + /* Init TWI etc */ ds1307_init(); /* Set up the one wire stuff */ OWInit(); - - /* Init water control state machine */ - water_init(); - + /* Analogue input is PA0:7 */ DDRA = 0x00; PORTA = 0x00; @@ -111,7 +116,7 @@ * datasheet says this is already 0 at * power on.. */ #endif - + /* PB0 Used for 1-wire bus * PB4:7 Used for relay board */ DDRB = 0xf0; @@ -125,9 +130,7 @@ DDRD = 0x03; PORTD = 0x03; - printf_P(PSTR("\r\n\r\n===============\r\n" - "Inited!\r\n\r\n")); - + fputs_P(PSTR("Reset cause: "), stdout); if ((mcucsr & _BV(PORF)) == _BV(PORF)) printf_P(PSTR("Power on\r\n")); @@ -148,23 +151,24 @@ /* Ready to go! */ sei(); + /* Init water control state machine */ + water_init(); + /* * Enable the watchdog with the largest prescaler. Will cause a * watchdog reset after approximately 2 s @ Vcc = 5 V - * - * Gets reset in the loop below and in the tempctrl.c timer IRQ */ wdt_enable(WDTO_2S); printf_P(PSTR("> ")); cmd.state = 0; - + /* Wait for user input or an "interrupt" */ while (1) { wdt_reset(); water_update(); - + if (cmd.state == 255) { process_cmd(); printf_P(PSTR("> ")); @@ -176,12 +180,21 @@ void process_cmd(void) { + int argc; + char *argv[MAXARGS]; + /* User just pressed enter */ if (cmd.len == 0) return; - - if (!strcasecmp_P((char *)cmd.buf, PSTR("?")) || - !strcasecmp_P((char *)cmd.buf, PSTR("help"))) { + + /* Split buffer into argv/argc (and de-volatilise) */ + splitargv((char *)cmd.buf, 0, argv, MAXARGS, &argc); + + if (argc == 0) + return; + + if (!strcasecmp_P(argv[0], PSTR("?")) || + !strcasecmp_P(argv[0], PSTR("help"))) { puts_P(PSTR("help This help\r\n" "wa all dly time Water all regions for time minutes after dly minutes\r\n" "gc Get time of day\r\n" @@ -199,47 +212,20 @@ "wc byte Write byte to 1-wire bus\r\n" "zz Reset micro\r\n")); return; - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wa"), 2)) { - water_cmd((char *)cmd.buf); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("gc"), 2)) { - ds1307_printnow(PSTR(""), PSTR("\r\n")); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sc"), 2)) { - if (cmd.len < 17) { - printf_P(PSTR("Invalid TOD\r\n")); - } else { - if (ds1307_settod((char *)cmd.buf + 3) != 1) - printf_P(PSTR("Unable to set TOD\r\n")); - } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("in"), 2)) { - uint8_t inp; - - switch (tolower(cmd.buf[3])) { - case 'a': - inp = PINA; - break; - - case 'b': - inp = PINB; - break; - - case 'c': - inp = PINC; - break; - - case 'd': - inp = PIND; - break; - - default: - printf_P(PSTR("Unknown port\r\n")); - return; - } - printf_P(PSTR("PORT %c <= 0x%02x\r\n"), toupper(cmd.buf[3]), inp); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("an"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("wa"))) { + water_cmd(argc - 1, argv + 1); + } else if (!strcasecmp_P(argv[0], PSTR("an"))) { uint16_t res; int pin; - - if (sscanf_P((char *)cmd.buf, PSTR("an %d"), &pin) != 1) { + char *eptr; + + if (argc != 2) { + printf_P(PSTR("Bad usage\r\n")); + return; + } + + pin = strtol(argv[1], &eptr, 0); + if (eptr == argv[1]) { printf_P(PSTR("Unable to parse\r\n")); return; } @@ -250,7 +236,7 @@ /* Select desired pin, use AVREF */ ADMUX = _BV(pin); - + /* Enable ADC, start conversion, set divisor to 64 * (8e6 / 64 => 125kHz (max is 200kHz) */ @@ -264,51 +250,54 @@ /* Disable ADC */ ADCSRA = 0; - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("ou"), 2)) { - char port; + } else if (!strcasecmp_P(argv[0], PSTR("ou"))) { int val; - - if (sscanf_P((char *)cmd.buf, PSTR("ou %c %x"), &port, &val) != 2) { - printf_P(PSTR("Unable to parse\r\n")); + char *eptr; + + if (argc != 3) { + printf_P(PSTR("Bad usage\r\n")); return; } - - switch (port) { + + val = strtol(argv[2], &eptr, 0); + if (eptr == argv[2]) { + printf_P(PSTR("Unable to parse val\r\n")); + return; + } + + switch (argv[1][0]) { case 'a': PORTA = val & 0xff; break; - + case 'b': PORTB = val & 0xff; break; - + case 'c': PORTC = val & 0xff; break; - + case 'd': PORTD = val & 0xff; break; - + default: printf_P(PSTR("Unknown port\r\n")); return; } - printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(port), val); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("dd"), 2)) { - char port; + printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(argv[1][0]), val); + } else if (!strcasecmp_P(argv[0], PSTR("dd"))) { uint8_t val; - int num; - - num = sscanf_P((char *)cmd.buf, PSTR("dd %c %x"), &port, &val); - - if (num != 1 && num != 2) { - printf_P(PSTR("Unable to parse dd arguments\r\n")); + char *eptr; + + if (argc != 2 && argc != 3) { + printf_P(PSTR("Bad usage\r\n")); return; } - - if (num == 1) { - switch (port) { + + if (argc == 1) { + switch (argv[1][0]) { case 'a': DDRA = val; break; @@ -320,79 +309,80 @@ case 'c': DDRC = val; break; - + case 'd': DDRD = val; break; - + default: printf_P(PSTR("Unknown port\r\n")); return; } - printf_P(PSTR("DDR%c => 0x%02x\r\n"), toupper(port), val); + printf_P(PSTR("DDR%c => 0x%02x\r\n"), toupper(argv[1][0]), val); } else { - switch (port) { + val = strtol(argv[2], &eptr, 0); + if (eptr == argv[2]) { + printf_P(PSTR("Unable to parse val\r\n")); + return; + } + + switch (argv[1][0]) { case 'a': DDRA = val & 0xff; break; - + case 'b': DDRB = val & 0xff; break; - + case 'c': DDRC = val & 0xff; break; - + case 'd': DDRD = val & 0xff; break; - + default: printf_P(PSTR("Unknown port\r\n")); return; } - printf_P(PSTR("DDR%c <= 0x%02x\r\n"), toupper(port), val); + printf_P(PSTR("DDR%c <= 0x%02x\r\n"), toupper(argv[1][0]), val); } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("zz"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("zz"))) { cli(); wdt_enable(WDTO_15MS); for (;;) ; - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("sr"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("sr"))) { uint8_t ROM[8]; int8_t i; - - memset(ROM, 0, 8); i = OWFirst(ROM, 1, 0); do { switch (i) { case OW_NOMODULES: + return; + case OW_FOUND: + for (i = 0; i < 8; i++) + printf_P(PSTR("%02x%S"), ROM[i], i == 7 ? PSTR("\r\n") : PSTR(":")); break; - + case OW_BADWIRE: case OW_NOPRESENCE: case OW_BADCRC: default: printf_P(PSTR("Err %d\r\n"), i); - break; + return; } - - if (i != OW_FOUND) - break; - - for (i = 0; i < 8; i++) - printf_P(PSTR("%02x%S"), ROM[i], i == 7 ? PSTR("\r\n") : PSTR(":")); - i = OWNext(ROM, 1, 0); } while (1); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("te"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("te"))) { uint8_t ROM[8]; int16_t t; - - if (sscanf_P((char *)cmd.buf, PSTR("te %hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), + + if (sscanf_P(argv[1], PSTR("%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx"), &ROM[0], &ROM[1], &ROM[2], &ROM[3], &ROM[4], &ROM[5], &ROM[6], &ROM[7]) != 8) { printf_P(PSTR("Unable to parse ROM ID\r\n")); @@ -417,26 +407,28 @@ printf_P(PSTR("%d.%02d\r\n"), GETWHOLE(t), GETFRAC(t)); break; } - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("re"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("re"))) { printf_P(PSTR("Reset = %d\r\n"), OWTouchReset()); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rb"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("rb"))) { printf_P(PSTR("Read %d\r\n"), OWReadBit()); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("rc"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("rc"))) { printf_P(PSTR("Read 0x%02x\r\n"), OWReadByte()); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wb"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("wb"))) { uint8_t d; - + if (sscanf_P((char *)cmd.buf, PSTR("wb %hhu"), &d) != 1) { printf_P(PSTR("Can't parse bit\r\n")); return; } OWWriteBit(d); printf_P(PSTR("Wrote %d\r\n"), d); - } else if (!strncasecmp_P((char *)cmd.buf, PSTR("wc"), 2)) { + } else if (!strcasecmp_P(argv[0], PSTR("wc"))) { uint8_t d; - - if (sscanf_P((char *)cmd.buf, PSTR("wc %hhx"), &d) != 1) { - printf_P(PSTR("Can't parse byte\r\n")); + char *eptr; + + d = strtol(argv[1], &eptr, 16); + if (eptr == argv[1]) { + printf_P(PSTR("Unable to parse byte\r\n")); return; } @@ -446,4 +438,3 @@ printf_P(PSTR("Unknown command, help for a list\r\n")); } } -