summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--avr/Tupfile2
-rw-r--r--avr/cmd_boot.c163
-rw-r--r--avr/command_tbl.c12
-rw-r--r--avr/getopt-min.c2
-rw-r--r--avr/main.c2
-rw-r--r--avr/pin.c2
-rw-r--r--include/pin.h2
7 files changed, 134 insertions, 51 deletions
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] [<pins>]\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 <pins> 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 <pins> ts|i[n]|p[ullup]\n"
" - config pins as input/tristate or input with pullup\n"
- "pin pins value[K|M][Hz]\n"
+ "pin <pins> 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"
+ "<pins> 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);