]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/cmd_boot.c
pin command: pin groups work now
[z180-stamp.git] / avr / cmd_boot.c
index 285dd6520088b6f596e8fdd2d9bf60b628dd0a2d..26855f1e6099e7858f0c6a8136417f22d198e5e6 100644 (file)
@@ -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;
 }