From: Leo C Date: Tue, 14 Oct 2014 20:38:56 +0000 (+0200) Subject: pin command: pin groups work now X-Git-Tag: hexrel-3 X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/commitdiff_plain/cd5ee5442821f283f6661befb24b885d944e4c5e pin command: pin groups work now --- diff --git a/avr/Tupfile b/avr/Tupfile index cbceff8..1300a4a 100644 --- a/avr/Tupfile +++ b/avr/Tupfile @@ -1,6 +1,6 @@ include_rules -PROG = stamp-test +PROG = stamp-monitor SRC = main.c SRC += cli.c cli_readline.c command.c command_tbl.c SRC += cmd_help.c cmd_echo.c cmd_date.c cmd_mem.c cmd_boot.c diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 285dd65..26855f1 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -278,6 +278,7 @@ static void print_blanks(uint_fast8_t count) } static const FLASH char * const FLASH pinconf_str[] = { + FSTR("?"), FSTR("Input"), FSTR("Pullup"), FSTR("Output"), @@ -327,25 +328,74 @@ int print_pin(int pin, int multi) return 0; } +int pinarg_insert(int pin, int count, int pinarg[]) +{ + int pos; -/* - * TODO: - pin groups - * - error if pin "config clock" on pins without clock - * - stat for single pin (group) - */ - -command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + if (pin < 0 || pin >= PIN_MAX) + return -1; + + for (pos = 0; pos < count; pos++) { + if (pin == pinarg[pos]) + return 0; + if (pin < pinarg[pos]) + break; + } + for (int i = count-1; i == pos ; i--) + pinarg[i+1] = pinarg[i]; + pinarg[pos] = pin; + + return 1; +} + +int pinarg_get(char * arg, int pinarg[]) { - int opt, pin; - unsigned long value; + int count = 0; char *endp; + int pin1, pin2, rc; + + while (1) { + pin1 = (int) strtoul(arg, &endp, 10); + if (endp != arg && *endp == '-') { + arg = endp+1; + pin2 = (int) strtoul(arg, &endp, 10); + if (pin1 < pin2) + for (; pin1 < pin2; pin1++) + if ((rc = pinarg_insert(pin1, count, pinarg)) >= 0) + count += rc; + else + return 0; + else + return 0; + } + if (endp != arg && pin1 >= 0) { + if ((*endp == ',' || *endp == '\0') && + (rc = pinarg_insert(pin1, count, pinarg)) >= 0) { + count += rc; + if (*endp == '\0') + return count; + } else + return 0; + } else + return 0; + + arg = endp+1; + } +} + + +command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ char printheader = 1; + int pinarg[PIN_MAX]; + int pinargc; (void) cmdtp; (void) flag; /* reset getopt() */ optind = 1; + int opt; while ((opt = getopt(argc, argv, PSTR("s"))) != -1) { switch (opt) { case 's': @@ -356,45 +406,59 @@ command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } } -// if ((argc - optind) % 2 != 0) -// return CMD_RET_USAGE; - - debug("argc: %d, optind: %d\n", argc, optind); + /* remaining arguments */ + argc -= optind; + + if (argc == 0) + /* print cofig of all pins */ + for (pinargc = 0; pinargc < PIN_MAX; pinargc++) + pinarg[pinargc] = pinargc; + else { + /* get first arg */ + pinargc = pinarg_get(argv[optind++], pinarg); + if (pinargc == 0) + return CMD_RET_USAGE; + else + argc--; + } - switch (argc - optind) { - case 0: - if (printheader) - printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n" - "-----------------------------------------\n")); - for (pin = 0; pin < PIN_MAX; pin++) - print_pin(pin, 1); - - return CMD_RET_SUCCESS; - break; - case 1: - pin = strtol(argv[optind], &endp, 10); - print_pin(pin, 0); + if (argc == 0) { + /* no more args, print config */ + if (pinargc == 1) + print_pin(pinarg[0], 0); + else { + if (printheader) + printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n" + "-----------------------------------------\n")); + for (int i = 0; i < pinargc; i++) + print_pin(pinarg[i], 1); + } return CMD_RET_SUCCESS; - break; } - while (optind < argc ) { + /* arguments must be in pairs: pins conf */ + if (argc % 2 != 1) + return CMD_RET_USAGE; + + while (argc > 0) { + char *endp; + pinmode_t mode = NONE; + int level = 0; + unsigned long value = 0; uint8_t hz_flag = 0; - pin = strtol(argv[optind++], &endp, 10); - switch (toupper(argv[optind][0])) { - case 'L': case 'H': - pin_write(pin, toupper(argv[optind][0]) == 'H'); - pin_config(pin, OUTPUT); + level = 1; + case 'L': + mode = OUTPUT; break; case 'P': - pin_config(pin, INPUT_PULLUP); + mode = INPUT_PULLUP; break; case 'I': case 'T': - pin_config(pin, INPUT); + mode = INPUT; break; default: @@ -429,19 +493,38 @@ command_ret_t do_pin(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } value = F_CPU/value; } + mode = OUTPUT_TIMER; + } - debug("** setting pin '%d' to '%lu'\n", pin, value); - if (pin_clockdiv_set(pin, value) < 0) { - printf_P(PSTR("Setting pin %d to %lu failed.\n"), - pin, value); + if (mode == NONE) + return CMD_RET_USAGE; + + for (int i = 0; i < pinargc; i++) { + switch (mode) { + case OUTPUT: + pin_write(pinarg[i], level); + /* fall thru */ + case INPUT: + case INPUT_PULLUP: + pin_config(pinarg[i], mode); + break; + case OUTPUT_TIMER: + if (pin_clockdiv_set(pinarg[i], value) < 0) { + printf_P(PSTR("Setting pin %d to %lu failed.\n"), + pinarg[i], value); + } + break; + default: + break; } } optind++; + pinargc = pinarg_get(argv[optind++], pinarg); + argc -= 2; } - return CMD_RET_SUCCESS; } diff --git a/avr/command_tbl.c b/avr/command_tbl.c index 71e70ea..e8af931 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -148,20 +148,20 @@ CMD_TBL_ITEM( CMD_TBL_ITEM( pin, CONFIG_SYS_MAXARGS, 0, do_pin, - "Set or get pin state", - "[-s][pins]\n" + "Set or query pin state", + "[-s] []\n" " - print cofiguration and state or frequency of pins\n" " print all pins, if argument is omitted\n" - "pin pins [h[igh]]|[l[ow]]\n" + "pin h[igh]|l[ow]\n" " - config pins as output and set to level high or low\n" - "pin pins [ts]|[i[n]]|[p[ullup]]\n" + "pin ts|i[n]|p[ullup]\n" " - config pins as input/tristate or input with pullup\n" - "pin pins value[K|M][Hz]\n" + "pin value[K|M][Hz]\n" " - output a clock on pins\n" " value is system clock divider or frequency, if 'Hz' is appended\n" " divider is rounded down to next possible value (depends on pin)\n" "\n" - "pins is a comma separated list of numbers or ranges, i.e. \"0,9,3-6\"\n" + " is a comma separated list of numbers or ranges, i.e. \"0,9,3-6\"\n" ), CMD_TBL_ITEM( diff --git a/avr/getopt-min.c b/avr/getopt-min.c index 778258d..571c14f 100644 --- a/avr/getopt-min.c +++ b/avr/getopt-min.c @@ -39,7 +39,7 @@ getopt( /* returns letter, '?', EOF */ || argv[optind][0] != '-' /* no more options */ || argv[optind][1] == '\0' /* not option; stdin */ ) - return EOF; + return -1; } c = argv[optind][sp]; /* option letter */ diff --git a/avr/main.c b/avr/main.c index 0470fea..e7ebd5d 100644 --- a/avr/main.c +++ b/avr/main.c @@ -228,7 +228,7 @@ int main(void) i2c_init(CONFIG_SYS_I2C_CLOCK); #endif - printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n")); + printf_P(PSTR("\nATMEGA1281+Z8S180 Stamp Monitor\n\n")); main_loop(); diff --git a/avr/pin.c b/avr/pin.c index 8a9f000..14896b3 100644 --- a/avr/pin.c +++ b/avr/pin.c @@ -12,7 +12,7 @@ Pin Name Port Timer Mode max div max div min f [Hz] 0 PG5 OC0B PWM (2**8)*1024 262144 70.31 1 PG4 2 CLK2 PB4 OC2A Toggle (2**8)*1024*2 524288 35.16 -3 CLOCK PB5 OC1A PWM (2**16)*1024 67108864 0.2746 +3 ZCLK PB5 OC1A PWM (2**16)*1024 67108864 0.2746 4 PB6 OC1B PWM (2**16)*1024 67108864 0.2746 5 PB7 OC0A Toggle (2**8)*1024*2 524288 35.16 6 PG3 diff --git a/include/pin.h b/include/pin.h index e673b56..5b37587 100644 --- a/include/pin.h +++ b/include/pin.h @@ -4,7 +4,7 @@ /* Number of user configurable I/O pins */ #define PIN_MAX 11 -typedef enum {INPUT, INPUT_PULLUP, OUTPUT, OUTPUT_TIMER} pinmode_t; +typedef enum {NONE, INPUT, INPUT_PULLUP, OUTPUT, OUTPUT_TIMER} pinmode_t; int pin_config(int pin, pinmode_t mode); pinmode_t pin_config_get(int pin);