summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
Diffstat (limited to 'avr')
-rw-r--r--avr/cmd_boot.c6
-rw-r--r--avr/cmd_cpu.c286
-rw-r--r--avr/command_tbl.c14
-rw-r--r--avr/z80-if.c11
4 files changed, 307 insertions, 10 deletions
diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c
index 2159608..f4a6183 100644
--- a/avr/cmd_boot.c
+++ b/avr/cmd_boot.c
@@ -259,18 +259,18 @@ command_ret_t do_go(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc,
return CMD_RET_USAGE;
addr = eval_arg(argv[1], NULL);
if (addr >= (1UL<<16)) {
- printf_P(PSTR("## Startaddress 0x%05lx too high.\n"
+ printf_P(PSTR("Invalid startaddress: 0x%05lx\n"
" (Out of logical address space (0x00000-0x0ffff))\n"),
addr);
return CMD_RET_FAILURE;
}
if (z80_bus_state() & ZST_RUNNING) {
- printf_P(PSTR("## CPU already running!\n"));
+ printf_P(PSTR("CPU already running!\n"));
return CMD_RET_FAILURE;
}
- printf_P(PSTR("## Starting application at 0x%04lx ...\n"), addr);
+ printf_P(PSTR("Starting application at 0x%04lx ...\n"), addr);
if (addr != 0) {
uint8_t tmp[3];
diff --git a/avr/cmd_cpu.c b/avr/cmd_cpu.c
index de627c6..1b1982c 100644
--- a/avr/cmd_cpu.c
+++ b/avr/cmd_cpu.c
@@ -11,8 +11,9 @@
#include "z80-if.h"
#include "con-utils.h"
//#include "env.h"
-//#include "eval_arg.h"
-//#include "getopt-min.h"
+#include "eval_arg.h"
+#include "timer.h"
+#include "getopt-min.h"
//#include "debug.h"
/* hack to get Z180 loadfile into flash memory */
@@ -88,3 +89,284 @@ donot:
return CMD_RET_SUCCESS;
}
+
+/*
+ * delay for <count> ms...
+ */
+static void test_delay(uint32_t count)
+{
+ uint32_t ts = get_timer(0);
+
+ while (get_timer(ts) < count);
+}
+
+command_ret_t do_cpu_test(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
+{
+
+ uint32_t pulsewidth = 10; /* ms */
+
+ /* reset getopt() */
+ optind = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("t:"))) != -1) {
+ switch (opt) {
+ case 't':
+ pulsewidth = eval_arg(optarg, NULL);
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ if ((z80_bus_state() & ZST_ACQUIRED) != RESET)
+ cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
+
+ clear_ctrlc(); /* forget any previous Control C */
+ do {
+ z80_bus_cmd(Request);
+ test_delay(pulsewidth);
+ z80_bus_cmd(Release);
+ test_delay(pulsewidth);
+ } while (!(had_ctrlc() || ctrlc()));
+
+ return CMD_RET_SUCCESS;
+}
+
+#if 0
+command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, int flag UNUSED, int argc, char * const argv[])
+{
+ bool silent = false;
+ bool write_env = false;
+ bool load_loop = true;
+ uint8_t lcycles = 18;
+ uint16_t timeout = 1000;
+
+ uint8_t eicrb_save;
+ uint8_t eimsk_save;
+ uint8_t mem_save[cpuinfo_length];
+
+ /* reset getopt() */
+ optind = 0;
+
+ int opt;
+ while ((opt = getopt(argc, argv, PSTR("swnc:t:"))) != -1) {
+ switch (opt) {
+ case 's':
+ silent = true;
+ break;
+ case 'w':
+ write_env = true;
+ break;
+ case 'n':
+ load_loop = false;
+ break;
+ case 'c':
+ lcycles = eval_arg(optarg, NULL);
+ break;
+ case 't':
+ lcycles = eval_arg(optarg, NULL);
+ break;
+ default: /* '?' */
+ return CMD_RET_USAGE;
+ }
+ }
+
+ if (z80_bus_state() & ZST_RUNNING) {
+ if (!silent)
+ printf_P(PSTR("Frequency measuring failed. CPU allready running!\n"));
+ return CMD_RET_FAILURE;
+ }
+
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ /* Save state and disable INT6 */
+ eimsk_save = EIMSK;
+ EIMSK &= ~_BV(INT6);
+ /* Save state and set INT6 for falling edge */
+ eicrb_save = EICRB;
+ EICRB = (eicrb_save & ~(0b11 << ISC60)) | (0b10 << ISC60);
+ }
+
+ z80_bus_cmd(Request);
+ if (load_loop) {
+ z80_read_block(mem_save, 0, cpuinfo_length);
+ z80_load_mem(0, cpuinfo,
+ &cpuinfo_sections,
+ cpuinfo_address,
+ cpuinfo_length_of_sections);
+ }
+ z80_bus_cmd(Run);
+ z80_bus_cmd(Release);
+
+ uint32_t cpu_freq = z80_measure_phi(lcycles, true, timeout);
+
+ z80_bus_cmd(Reset);
+ z80_bus_cmd(Request);
+ if (load_loop)
+ z80_write_block(mem_save, 0, cpuinfo_length);
+ z80_bus_cmd(Release);
+
+ ATOMIC_BLOCK(ATOMIC_FORCEON) {
+ /* Restore INT6 */
+ eicrb_save = EICRB;
+ EICRB = (EICRB & ~(0b11 << ISC60)) | (eicrb_save & (0b11 << ISC60));
+ if ((eimsk_save & _BV(INT6)) != 0)
+ EIMSK |= _BV(INT6);
+ /* Reset pending int */
+ EIFR = _BV(INTF6);
+ }
+
+ if (!silent) {
+ if (cpu_freq != 0)
+ printf_P(PSTR("%luHz\n"), cpu_freq);
+ else
+ printf_P(PSTR("No CPU clock or input frequency to low!\n"));
+ }
+
+ if (write_env) {
+ if (setenv_ulong(PSTR(ENV_CPU_FREQ), cpu_freq)) {
+ if (!silent)
+ printf_P(PSTR("'SETENV (%S, %lu)' failed!\n"), PSTR(ENV_CPU_FREQ), cpu_freq);
+ return CMD_RET_FAILURE;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+#endif
+
+/*
+ * command table for fat subcommands
+ */
+
+cmd_tbl_t cmd_tbl_cpu[] = {
+CMD_TBL_ITEM(
+ chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpuchk,
+ "Check CPU",
+ ""
+),
+CMD_TBL_ITEM(
+ test, CONFIG_SYS_MAXARGS, 1, do_cpu_test,
+ "Do bus request/release cycles",
+ "[-t pulsewidth]"
+),
+#if 0
+CMD_TBL_ITEM(
+ freq, CONFIG_SYS_MAXARGS, 1, do_cpu_freq,
+ "Measure cpu frequency",
+ "[-swn] [-c loopcycles]\n"
+ " -s Supress output (silent)\n"
+ " -w Write result to environment variable '"ENV_CPU_FREQ"'"
+),
+#endif
+CMD_TBL_ITEM(
+ help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help,
+ "Print sub command description/usage",
+ "\n"
+ " - print brief description of all sub commands\n"
+ "fat help command ...\n"
+ " - print detailed usage of sub cmd 'command'"
+),
+
+/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
+ {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help,
+ NULL,
+#ifdef CONFIG_SYS_LONGHELP
+ FSTR(""),
+#endif /* CONFIG_SYS_LONGHELP */
+ NULL,
+#ifdef CONFIG_AUTO_COMPLETE
+ NULL,
+#endif
+},
+/* Mark end of table */
+CMD_TBL_END(cmd_tbl_cpu)
+};
+
+
+command_ret_t do_cpu(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
+{
+ //puts_P(PSTR("Huch?"));
+
+ return CMD_RET_USAGE;
+}
+
+
+#if 0
+/*
+ * Z180 Single Step Functions
+ *
+ */
+
+
+#define P_RUN PORTG
+#define RUN 1
+#define DDR_RUN DDRG
+#define P_STEP PORTG
+#define STEP 0
+#define DDR_STEP DDRG
+#define P_WAIT PORTG
+#define WAIT 2
+#define DDR_WAIT DDRG
+/* All three signals are on the same Port (PortG) */
+#define PORT_SS PORTG
+#define DDR_SS DDRG
+#define PIN_SS PING
+
+static bool ss_available;
+
+int single_step_setup(void)
+{
+ ss_available = false;
+
+#if 0
+ if (z80_bus_state() & ZST_RUNNING ||
+ !(z80_bus_cmd(Request) & ZST_ACQUIRED))
+ return -1;
+#endif
+
+ /* STEP, RUN output, WAIT input */
+
+ PORT_SS |= _BV(RUN) | _BV(STEP);
+ DDR_SS |= _BV(RUN) | _BV(STEP);
+ DDR_SS &= ~_BV(WAIT);
+
+ /* RUN high, MREQ pulse --> WAIT should be low */
+ z80_mreq_pulse();
+
+ if ((PIN_SS & _BV(WAIT)) == 0) {
+
+ /* RUN high, STEP pulse --> WAIT should be high */
+ PIN_SS = _BV(STEP);
+ PIN_SS = _BV(STEP);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* RUN high, MREQ pulse --> WAIT should be low */
+ z80_mreq_pulse();
+ if ((PIN_SS & _BV(WAIT)) == 0) {
+
+ /* RUN low --> WAIT should be high */
+ PIN_SS = _BV(RUN);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* RUN low, STEP pulse --> WAIT should be high */
+ PIN_SS = _BV(STEP);
+ PIN_SS = _BV(STEP);
+ if ((PIN_SS & _BV(WAIT)) != 0) {
+
+ /* all tests passed */
+ ss_available = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (!ss_available) {
+ DDR_SS &= ~(_BV(STEP) | _BV(RUN));
+ PORT_SS |= _BV(RUN) | _BV(STEP);
+ }
+
+ return ss_available ? 0 : -1;
+}
+#endif
diff --git a/avr/command_tbl.c b/avr/command_tbl.c
index 9968dc0..4ed37b7 100644
--- a/avr/command_tbl.c
+++ b/avr/command_tbl.c
@@ -24,6 +24,15 @@
cmd_tbl_t cmd_tbl[] = {
+CMD_TBL_ITEM_TOP(
+ xx, CONFIG_SYS_MAXARGS, 0, do_cpu,
+ "experimental commands",
+ "<subcommand> args ...\n"
+ "xx help\n",
+ cmd_tbl_cpu
+),
+
+
CMD_TBL_ITEM(
date, 2, 1, do_date,
"get/set date & time",
@@ -127,11 +136,6 @@ CMD_TBL_ITEM_TOP(
),
CMD_TBL_ITEM(
- chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpuchk,
- "Check CPU",
- ""
-),
-CMD_TBL_ITEM(
loadf, 1, 0, do_loadf,
"load srec_cat prepared image from controller flash",
""
diff --git a/avr/z80-if.c b/avr/z80-if.c
index 9452ad1..5d88842 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -145,6 +145,15 @@ void z80_bus_request_or_exit(void)
static zstate_t zstate;
static volatile uint8_t timer; /* used for bus timeout */
+#if 0
+static volatile uint16_t req_cycles_ovl;
+
+ISR(TIMER4_COMPB_vect)
+{
+ req_cycles_ovl++;
+}
+#endif
+
/*---------------------------------------------------------*/
/* 10Hz timer interrupt generated by OC5A */
/*---------------------------------------------------------*/
@@ -352,6 +361,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
z80_dbus_set_in();
z80_addrbus_set_in();
z80_reset_active();
+ _delay_us(10);
Z80_O_BUSREQ = 1;
timer = BUS_TO;
while (Z80_I_BUSACK == 0 && timer)
@@ -400,6 +410,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd)
z80_dbus_set_in();
z80_addrbus_set_in();
z80_reset_active();
+ _delay_us(10);
Z80_O_BUSREQ = 1;
timer = BUS_TO;
while (Z80_I_BUSACK == 0 && timer)