From 51dd0948df5ed53b11cab4e909e19ee7cee363c5 Mon Sep 17 00:00:00 2001 From: Leo C Date: Sat, 8 Sep 2018 20:37:23 +0200 Subject: [PATCH] new debug command: xx test. get freq command from single step branch. --- avr/cmd_boot.c | 6 +- avr/cmd_cpu.c | 286 +++++++++++++++++++++++++++++++++++++++++++++- avr/command_tbl.c | 14 ++- avr/z80-if.c | 11 ++ include/cmd_cpu.h | 4 +- 5 files changed, 310 insertions(+), 11 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 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", + " args ...\n" + "xx help\n", + cmd_tbl_cpu +), + + CMD_TBL_ITEM( date, 2, 1, do_date, "get/set date & time", @@ -126,11 +135,6 @@ CMD_TBL_ITEM_TOP( cmd_tbl_env ), -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) diff --git a/include/cmd_cpu.h b/include/cmd_cpu.h index d590468..f6f1fb9 100644 --- a/include/cmd_cpu.h +++ b/include/cmd_cpu.h @@ -9,6 +9,8 @@ #include "command.h" -command_ret_t do_cpuchk(cmd_tbl_t *, uint_fast8_t, int, char * const []); +extern cmd_tbl_t cmd_tbl_cpu[]; + +command_ret_t do_cpu(cmd_tbl_t *, uint_fast8_t, int, char * const []); #endif /* CMD_CPU_H */ -- 2.39.2