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.c299
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;
+}
+