diff options
author | Leo C | 2014-10-14 12:53:48 +0200 |
---|---|---|
committer | Leo C | 2014-10-14 12:53:48 +0200 |
commit | 41d36f28612cb6c49cf0260236f3b834549883be (patch) | |
tree | a9c8c4e81d1cff76a8473498d2a9a71c76216450 /avr/cmd_boot.c | |
parent | 04a63b0d5660f1c0c0b7e8123e4f56d188e52a5d (diff) | |
download | z180-stamp-41d36f28612cb6c49cf0260236f3b834549883be.zip |
pin command, add user configurable i/o pins
Diffstat (limited to 'avr/cmd_boot.c')
-rw-r--r-- | avr/cmd_boot.c | 299 |
1 files changed, 285 insertions, 14 deletions
diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 58c4f56..285dd65 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -4,11 +4,16 @@ */ #include "common.h" #include <stdlib.h> +#include <limits.h> +#include <ctype.h> #include <util/delay.h> #include <avr/pgmspace.h> #include "command.h" +#include "getopt-min.h" #include "z80-if.h" +#include "pin.h" +#include "debug.h" /* ugly hack to get Z180 loadfile into flash memory */ #define const const FLASH @@ -32,7 +37,7 @@ static void z80_load_mem(void) z80_bus_cmd(Request); z80_write_block((const FLASH unsigned char *) &hdrom[sec_base], /* src */ - hdrom_address[sec], /* dest */ + hdrom_address[sec], /* dest */ hdrom_length_of_sections[sec]); /* len */ z80_bus_cmd(Release); sec_base+=hdrom_length_of_sections[sec]; @@ -143,25 +148,47 @@ command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv return CMD_RET_SUCCESS; } - +#if 0 command_ret_t do_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - uint32_t freq; + long freq; + char *endp; (void) cmdtp; (void) flag; - + if (argc == 2) { - freq = strtoul(argv[1], NULL, 10); - if (freq == 0) { - printf_P(PSTR("CPU clock cannot be 0\n")); - return CMD_RET_USAGE; + if (toupper(argv[1][0]) == 'L') + freq = 0; + else if (toupper(argv[1][0]) == 'H') + freq = LONG_MAX; + else { + freq = strtol(argv[1], &endp, 10); + switch (*endp) { + case 'M': + freq *= 1000; + case 'K': + freq *= 1000; + endp++; + case '\0': + if (*endp == '\0') + break; + default: + printf_P(PSTR("invalid value\n")); + return CMD_RET_USAGE; + } + + if (freq == 0) { + printf_P(PSTR("CPU clock cannot be 0\n")); + return CMD_RET_USAGE; + } + + +/* if (freq > (long) F_CPU / 2) { + printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2); + return CMD_RET_USAGE; + } +*/ } - - if (freq > F_CPU / 2) { - printf_P(PSTR("Max CPU clock freq. is: %luHz\n"), F_CPU/2); - return CMD_RET_USAGE; - } - if (z80_clock_set(freq) < 0) { printf_P(PSTR("Setting CPU clock freq. to %luHz failed.\n"), freq); @@ -174,3 +201,247 @@ command_ret_t do_clock(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_SUCCESS; } +command_ret_t do_clock2(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + long value; + char *endp; + uint8_t div_flag = 0; + + (void) cmdtp; (void) flag; + + if (argc >= 2) { + if (argv[1][0] == '-' && argv[1][1] == 'd') { + div_flag = 1; + argc--; + argv++; + } + } + + if (argc == 2) { + if (toupper(argv[1][0]) == 'L') + value = 0; + else if (toupper(argv[1][0]) == 'H') + value = LONG_MAX; + else { + value = strtol(argv[1], &endp, 10); + switch (*endp) { + case 'M': + value *= 1000; + case 'K': + value *= 1000; + endp++; + case '\0': + if (*endp == '\0') + break; + default: + printf_P(PSTR("invalid value\n")); + return CMD_RET_USAGE; + } + + if (value == 0) { + printf_P(PSTR("clk2 cannot be 0\n")); + return CMD_RET_USAGE; + } + + if (div_flag) { + if (value > 256*1024L) { + printf_P(PSTR("Max clk2 divider is: %lu\n"), 256*1024L); + return CMD_RET_USAGE; + } + } else { + if (value > (long) F_CPU / 2) { + printf_P(PSTR("Max clk2 freq. is: %luHz\n"), F_CPU/2); + return CMD_RET_USAGE; + } + } + } + if (div_flag ? z80_clock2_divset(value) : z80_clock2_set(value) < 0) { + printf_P(PSTR("Setting clk2 freq. to %luHz failed.\n"), + value); + } + } + + printf_P(PSTR("clk2: %luHz\n"), z80_clock2_get()); + + + return CMD_RET_SUCCESS; +} +#endif + +// {INPUT, INPUT_PULLUP, OUTPUT, OUTPUT_TIMER} pinmode_t; + + +static void print_blanks(uint_fast8_t count) +{ + while(count--) + putchar(' '); +} + +static const FLASH char * const FLASH pinconf_str[] = { + FSTR("Input"), + FSTR("Pullup"), + FSTR("Output"), + FSTR("Clock"), + }; + +static const FLASH char * const FLASH pinlevel_str[] = { + FSTR("Low"), + FSTR("High"), + FSTR(""), + }; + +int print_pin(int pin, int multi) +{ + int pinconf; + const FLASH char *levelp; + long div; + + pinconf = pin_config_get(pin); + if (pinconf == OUTPUT_TIMER) { + div = pin_clockdiv_get(pin); + levelp = pinlevel_str[2]; + } else + levelp = pinlevel_str[pin_read(pin)]; + + if (multi) { + printf_P(PSTR("%3d "), pin); + my_puts_P(pinconf_str[pinconf]); + print_blanks(8 - strlen_P(pinconf_str[pinconf])); + my_puts_P(levelp); + print_blanks(6 - strlen_P(levelp)); + if (pinconf == OUTPUT_TIMER) + printf_P(PSTR("%7ld %8ld"), + div, F_CPU/div); + } else { + printf_P(PSTR("Pin %d: "), pin); + my_puts_P(pinconf_str[pinconf]); + printf_P(PSTR(", ")); + my_puts_P(levelp); + + if (pinconf == OUTPUT_TIMER) + printf_P(PSTR("divide by %ld (%ldHz)"), + div, F_CPU/div); + } + printf_P(PSTR("\n")); + + return 0; +} + + +/* + * 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[]) +{ + int opt, pin; + unsigned long value; + char *endp; + char printheader = 1; + + (void) cmdtp; (void) flag; + + /* reset getopt() */ + optind = 1; + + while ((opt = getopt(argc, argv, PSTR("s"))) != -1) { + switch (opt) { + case 's': + printheader = 0; + break; + default: /* '?' */ + return CMD_RET_USAGE; + } + } + +// if ((argc - optind) % 2 != 0) +// return CMD_RET_USAGE; + + debug("argc: %d, optind: %d\n", argc, optind); + + 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); + return CMD_RET_SUCCESS; + break; + } + + while (optind < argc ) { + 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); + break; + case 'P': + pin_config(pin, INPUT_PULLUP); + break; + case 'I': + case 'T': + pin_config(pin, INPUT); + break; + + default: + value = strtoul(argv[optind], &endp, 10); + switch (*endp) { + case 'M': + value *= 1000; + case 'K': + value *= 1000; + endp++; + } + + if (*endp && strcmp_P(endp, PSTR("Hz")) == 0) { + hz_flag = 1; + endp += 2; + } + + if (*endp != '\0') { + printf_P(PSTR("invalid parameter: '%s'\n"), argv[optind]); + return CMD_RET_USAGE; + } + + if (value == 0) { + printf_P(PSTR("invalid value: %lu \n")); + return CMD_RET_USAGE; + } + + if (hz_flag) { + if (value > F_CPU / 2) { + printf_P(PSTR("Max frequency is: %luHz\n"), F_CPU/2); + return CMD_RET_USAGE; + } + value = F_CPU/value; + } + + + 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); + } + } + + optind++; + } + + + return CMD_RET_SUCCESS; +} + |