diff options
author | Leo C | 2014-10-14 22:38:56 +0200 |
---|---|---|
committer | Leo C | 2014-10-14 22:38:56 +0200 |
commit | cd5ee5442821f283f6661befb24b885d944e4c5e (patch) | |
tree | 44deae1ded16c5e818e461e7d07c25ebbe116c9b /avr/cmd_boot.c | |
parent | 41d36f28612cb6c49cf0260236f3b834549883be (diff) | |
download | z180-stamp-cd5ee5442821f283f6661befb24b885d944e4c5e.zip |
pin command: pin groups work nowhexrel-3
Diffstat (limited to 'avr/cmd_boot.c')
-rw-r--r-- | avr/cmd_boot.c | 163 |
1 files changed, 123 insertions, 40 deletions
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; } |