summaryrefslogtreecommitdiff
path: root/avr/cmd_boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'avr/cmd_boot.c')
-rw-r--r--avr/cmd_boot.c163
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;
}