diff options
Diffstat (limited to 'avr')
-rw-r--r-- | avr/cli.c | 1 | ||||
-rw-r--r-- | avr/cli_readline.c | 4 | ||||
-rw-r--r-- | avr/cmd_boot.c | 20 | ||||
-rw-r--r-- | avr/cmd_cpu.c | 671 | ||||
-rw-r--r-- | avr/cmd_fat.c | 1 | ||||
-rw-r--r-- | avr/cmd_gpio.c | 4 | ||||
-rw-r--r-- | avr/cmd_loadcpm3.c | 2 | ||||
-rw-r--r-- | avr/cmd_loadihex.c | 1 | ||||
-rw-r--r-- | avr/cmd_misc.c | 2 | ||||
-rw-r--r-- | avr/cmd_sd.c | 1 | ||||
-rw-r--r-- | avr/command.c | 1 | ||||
-rw-r--r-- | avr/con-utils.c | 1 | ||||
-rw-r--r-- | avr/debug.c | 3 | ||||
-rw-r--r-- | avr/env.c | 4 | ||||
-rw-r--r-- | avr/eval_arg.c | 1 | ||||
-rw-r--r-- | avr/getopt-min.c | 1 | ||||
-rw-r--r-- | avr/gpio.c | 1 | ||||
-rw-r--r-- | avr/i2c.c | 1 | ||||
-rw-r--r-- | avr/main.c | 1 | ||||
-rw-r--r-- | avr/mmc.c | 7 | ||||
-rw-r--r-- | avr/print-utils.c | 2 | ||||
-rw-r--r-- | avr/z180-serv.c | 47 | ||||
-rw-r--r-- | avr/z80-if.c | 105 |
23 files changed, 313 insertions, 569 deletions
@@ -13,7 +13,6 @@ #include "cli.h" #include "command.h" -#include <ctype.h> #include "config.h" #include "debug.h" diff --git a/avr/cli_readline.c b/avr/cli_readline.c index 0ed8f67..81f68df 100644 --- a/avr/cli_readline.c +++ b/avr/cli_readline.c @@ -13,10 +13,6 @@ #include "cli_readline.h" #include "common.h" -#include <string.h> -#include <stdio.h> -#include <stdbool.h> -#include <ctype.h> #include "config.h" #include "con-utils.h" diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c index 036a041..6b98496 100644 --- a/avr/cmd_boot.c +++ b/avr/cmd_boot.c @@ -11,7 +11,6 @@ * Misc boot support */ #include "cmd_boot.h" -#include <ctype.h> #include <util/atomic.h> #include "cli_readline.h" /* console_buffer[] */ @@ -275,28 +274,24 @@ command_ret_t do_go(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, } if (z80_bus_state() & ZST_RUNNING) { - printf_P(PSTR("CPU already running!\n")); - return CMD_RET_FAILURE; + cmd_error(CMD_RET_FAILURE, ERUNNING, NULL); } printf_P(PSTR("Starting application at 0x%04lx ...\n"), addr); if (addr != 0) { - uint8_t tmp[3]; +// uint8_t tmp[3]; - z80_bus_cmd(Request); - z80_read_block (tmp, 0, 3); + z80_bus_request_or_exit(); +// z80_read_block (tmp, 0, 3); z80_write(0, 0xc3); z80_write(1, addr); z80_write(2, (addr >> 8)); + z80_bus_cmd(Release); + _delay_ms(100); z80_bus_cmd(Run); - _delay_us(10); - z80_bus_cmd(M_Cycle); - _delay_us(10); - z80_bus_cmd(M_Cycle); - _delay_us(10); - z80_write_block(tmp, 0, 3); +// z80_write_block(tmp, 0, 3); } else { if (!hold) z80_bus_cmd(Request); @@ -383,6 +378,7 @@ command_ret_t do_console(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int case 2: my_puts_P(PSTR("\n" "------------------------------------------------\n")); + /* FALL TROUGH */ case 1: state = 0; switch (toupper(ch)) { diff --git a/avr/cmd_cpu.c b/avr/cmd_cpu.c index e5158fd..af9ded4 100644 --- a/avr/cmd_cpu.c +++ b/avr/cmd_cpu.c @@ -5,7 +5,6 @@ */ #include "cmd_cpu.h" -//#include <ctype.h> #include <util/atomic.h> #include "z80-if.h" @@ -21,6 +20,10 @@ #include "../z180/cpuinfo.h" #undef const +#define DEBUG_CPU 1 /* set to 1 to debug */ + +#define debug_cpu(fmt, args...) \ + debug_cond(DEBUG_CPU, fmt, ##args) /* * delay for <count> ms... @@ -32,429 +35,174 @@ static void test_delay(uint32_t count) while (get_timer(ts) <= count); } -uint32_t z80_measure_phi(uint_fast8_t cycles) -{ - uint16_t ref_stop; - uint16_t ref_ovfl; - uint8_t x_ovfl; - uint8_t eimsk_save,eicrb_save; - uint32_t x_freq; - +static const FLASH char * const FLASH cpu_strings[] = { + FSTR("Unknown"), + FSTR("8080"), + FSTR("8085"), + FSTR("Z80"), + FSTR("x180"), + FSTR("HD64180"), + FSTR("Z80180"), + FSTR("Z80S180"), +}; - 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); - } +#define O_SILENT (1<<0) +#define O_WENV (1<<1) +#define O_LOAD_LOOP (1<<2) +#define O_UNLOAD_LOOP (1<<3) - PRR1 &= ~_BV(PRTIM3); - TCCR3A = 0; - TCCR3B = 0b000<<CS30; /* stop counter */ - TCNT3 = 0; - x_ovfl = 0; - TIFR3 = _BV(TOV3); - ref_ovfl = 0; +static const FLASH char * const FLASH opt_strings[] = { + FSTR("swnu"), /* Options for chkcpu */ + FSTR("swnuc:"), /* Oprions for cpufreq */ +}; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Reset pending int */ - EIFR = _BV(INTF6); - /* Wait for falling edge */ - while ((EIFR & _BV(INTF6)) == 0) - ; - TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */ - OCR4B = TCNT4; - TIFR4 = _BV(OCF4B); /* clear compare match flag */ - } - while (ref_ovfl < 60) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - ref_ovfl++; - } - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } - } - } +static const FLASH char * const FLASH env_names[] = { + FSTR(ENV_CPU), /* Env var for chkcpu result */ + FSTR(ENV_CPU_FREQ), /* Env var for cpufreq result */ +}; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - EIFR = _BV(INTF6); - for (;;) { - if (EIFR & _BV(INTF6)) { - TCCR3B = 0b000<<CS30; /* stop counter */ - ref_stop = TCNT4; - break; - } - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - ref_ovfl++; - } - } - } +command_ret_t do_cpu_freq_chk(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) +{ + uint_fast8_t options = O_LOAD_LOOP | O_UNLOAD_LOOP; + uint_fast8_t cputype = 0; + uint32_t cpu_freq = 0; + uint_fast8_t lcycles = 0; + uint_fast8_t freq_cmd = 0; +// uint16_t timeout = 1000; + uint8_t eimsk_save; + ERRNUM err = ESUCCESS; - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } + if (argv[0][0] == 'f') + freq_cmd = 1; - ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Restore INT6 */ - EICRB = eicrb_save; - if ((eimsk_save & _BV(INT6)) != 0) - EIMSK |= _BV(INT6); - /* Reset pending int */ - EIFR = _BV(INTF6); + int opt; + while ((opt = getopt(argc, argv, opt_strings[freq_cmd])) != -1) { + switch (opt) { + case 's': + options |= O_SILENT; + break; + case 'w': + options |= O_WENV; + break; + case 'n': + options &= ~O_LOAD_LOOP; + break; + case 'u': + options &= ~O_UNLOAD_LOOP; + break; + case 'c': + lcycles = eval_arg(optarg, NULL); + break; +// case 't': +// timeout = eval_arg(optarg, NULL); +// break; + default: /* '?' */ + return CMD_RET_USAGE; + } } + if (argc - optind != 0) + return CMD_RET_USAGE; - uint32_t ref_cnt = (ref_stop - OCR4B) + ((uint32_t)ref_ovfl << 16); - uint32_t x_cnt = TCNT3 + ((uint32_t) x_ovfl << 16); - uint64_t x_tmp = (uint64_t) 100000 * (x_cnt * cycles); - - debug("TCNT3: %6u, ref_cnt: %9lu\n", TCNT3, ref_cnt); - debug("x_tmp: %lu %lu\n", (uint32_t) (x_tmp >> 32), (uint32_t) (x_tmp & 0xffffffff)); - - x_tmp = (x_tmp * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU) + (ref_cnt / 2)) / ref_cnt; - - debug("x_tmp: %lu %lu\n", (uint32_t) (x_tmp >> 32), (uint32_t) (x_tmp & 0xffffffff)); + if (z80_bus_state() & ZST_RUNNING) + cmd_error(CMD_RET_FAILURE, ERUNNING, NULL); - /* round to 5 decimal digits */ - int_fast8_t sc = 5; - while (x_tmp >= 100000) { - x_tmp = (x_tmp + 5)/10; - sc--; - } - x_freq = x_tmp; - while (sc < 0) { - x_freq *= 10; - sc++; + uint8_t *mem_save = NULL; + if (options & O_LOAD_LOOP) { + mem_save = (uint8_t *) malloc(cpuinfo_length); + if (mem_save == NULL) + cmd_error(CMD_RET_FAILURE, ENOMEM, NULL); + z80_bus_cmd(Request); + z80_read_block(mem_save, 0, cpuinfo_length); + z80_load_mem(0, cpuinfo, &cpuinfo_sections, cpuinfo_address, + cpuinfo_length_of_sections); + z80_bus_cmd(Release); } - x_freq += (uint32_t) sc << 28; - - - /* Stop Timer */ - TCCR3B = 0; - PRR1 |= _BV(PRTIM3); - - return x_freq; -} - -#if 0 -float z80_measure_phi(uint_fast8_t cycles, uint16_t wait_ms) -{ - uint16_t ref_stop; - uint16_t ref_ovfl; - uint8_t x_ovfl; - uint8_t eimsk_save,eicrb_save; - float x_freq; - + /* Save state and disable INT5/INT6 */ 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); + EIMSK &= ~_BV(INT5); } + EIFR = _BV(INTF5); /* Reset pending int */ - PRR1 &= ~_BV(PRTIM3); - TCCR3A = 0; - TCCR3B = 0b000<<CS30; /* stop counter */ - TCNT3 = 0; - x_ovfl = 0; - TIFR3 = _BV(TOV3); - ref_ovfl = 0; + z80_bus_cmd(Run); - ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Reset pending int */ - EIFR = _BV(INTF6); - /* Wait for falling edge */ - while ((EIFR & _BV(INTF6)) == 0) - ; - TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */ - OCR4B = TCNT4; - TIFR4 = _BV(OCF4B); /* clear compare match flag */ - } - while (ref_ovfl < 60) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - ref_ovfl++; - } - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } + clear_ctrlc(); /* forget any previous Control C */ + /* Wait for falling edge */ + do { + /* check for ctrl-c to abort... */ + if (had_ctrlc() || ctrlc()) { + err = EINTR; + break; } - } + } while ((EIFR & _BV(INTF5)) == 0); - ATOMIC_BLOCK(ATOMIC_FORCEON) { - EIFR = _BV(INTF6); - for (;;) { - if (EIFR & _BV(INTF6)) { - TCCR3B = 0b000<<CS30; /* stop counter */ - ref_stop = TCNT4; - break; - } - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - ref_ovfl++; - } + if (freq_cmd) { + if (lcycles == 0) { + z80_bus_cmd(Request); + if (z80_read(3) == 0xFF) + lcycles = z80_read(5); + z80_bus_cmd(Release); } + if (!err) + cpu_freq = z80_measure_phi(lcycles); } + z80_bus_cmd(Reset); - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } - + /* Restore INT5/INT6 */ ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Restore INT6 */ - EICRB = eicrb_save; + if ((eimsk_save & _BV(INT5)) != 0) + EIMSK |= _BV(INT5); if ((eimsk_save & _BV(INT6)) != 0) EIMSK |= _BV(INT6); /* Reset pending int */ + EIFR = _BV(INTF5); EIFR = _BV(INTF6); } + Stat &= ~S_MSG_PENDING; + Stat &= ~S_CON_PENDING; - uint32_t ref_cnt = (ref_stop - OCR4B) + ((uint32_t)ref_ovfl << 16); - - uint32_t x_cnt = TCNT3 + ((uint32_t) x_ovfl << 16); - x_freq = x_cnt * cycles; - - x_freq = (x_freq * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU)) / ref_cnt; - - debug("TCNT3: %6u, ref_cnt: %9lu\n", TCNT3, ref_cnt); -#if 0 - debug("ref_start: %6u, ref_stop: %6u, ref_ovfl: %4u, ref_cnt: %9lu\n" - " TCNT3: %6u, x_cnt: %6lu, xfreq: %f\n", - OCR4B, ref_stop, ref_ovfl, ref_cnt, - TCNT3, x_cnt, x_freq); -#endif - - - /* Stop Timer */ - TCCR3B = 0; - PRR1 |= _BV(PRTIM3); - - return x_freq; -} -#endif - -#if 0 -int32_t z80_measure_phi(uint_fast8_t cycles, uint16_t wait_ms) -{ - uint16_t ref_stop; - uint16_t ref_ovfl; - uint8_t x_ovfl; - uint32_t x_freq; - uint8_t eimsk_save,eicrb_save; - - - 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); - } - - PRR1 &= ~_BV(PRTIM3); - TCCR3A = 0; - TCCR3B = 0b000<<CS30; /* stop counter */ - TCNT3 = 0; - x_ovfl = 0; - TIFR3 = _BV(TOV3); - ref_ovfl = 0; - - ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Reset pending int */ - EIFR = _BV(INTF6); - /* Wait for falling edge */ - while ((EIFR & _BV(INTF6)) == 0) - ; - OCR4B = TCNT4; - TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */ - TIFR4 = _BV(OCF4B); /* clear compare match flag */ - } - while (ref_ovfl < 60) { - ATOMIC_BLOCK(ATOMIC_FORCEON) { - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - ref_ovfl++; - } - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } - } - } - - ATOMIC_BLOCK(ATOMIC_FORCEON) { - EIFR = _BV(INTF6); - for (;;) { - if (EIFR & _BV(INTF6)) { - ref_stop = TCNT4; - TCCR3B = 0b000<<CS30; /* stop counter */ - break; - } - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - if (ref_ovfl) - ref_ovfl++; - } - } - } - -#if 0 - ATOMIC_BLOCK(ATOMIC_FORCEON) { - EIFR = _BV(INTF6); - for (;;) { - if (EIFR & _BV(INTF6)) - break; - if (TIFR4 & _BV(OCF4B)) { - if (EIFR & _BV(INTF6)) - break; - TIFR4 = _BV(OCF4B); - if (EIFR & _BV(INTF6)) - break; - ref_ovfl++; - if (EIFR & _BV(INTF6)) - break; - if (ref_ovfl == 0) - break; - } - } - ref_stop = TCNT4; - TCCR3B = 0b000<<CS30; /* stop counter */ - if ((TIFR4 & _BV(OCF4B)) != 0) { - TIFR4 = _BV(OCF4B); - if (ref_ovfl) - ref_ovfl++; - } - } -#endif - if ((TIFR3 & _BV(TOV3)) != 0) { - TIFR3 = _BV(TOV3); - x_ovfl++; - } - - if (ref_ovfl == 0) - x_freq = 0xFFFFFFFE; - else - { - uint32_t ref_cnt = (ref_stop - OCR4B) + ((uint32_t)ref_ovfl << 16); - - x_freq = TCNT3 + ((uint32_t) x_ovfl << 16); - uint32_t x_cnt = x_freq; - x_freq *= cycles; - - x_freq = ((uint64_t) x_freq * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU) + (ref_cnt / 2))/ ref_cnt; - - debug("ref_start: %6u, ref_stop: %6u, ref_ovfl: %4u, ref_cnt: %9lu\n" - " TCNT3: %6u, x_cnt: %6lu, xfreq: %9lu\n", - OCR4B, ref_stop, ref_ovfl, ref_cnt, - TCNT3, x_cnt, x_freq); - - /* round to 5 decimal digits */ - uint_fast8_t sc = 0; - while (x_freq >= 100000UL) { - x_freq = (x_freq + 5)/10; - ++sc; - } - while (sc--) - x_freq *= 10; + if (freq_cmd == 0) { + z80_bus_cmd(Request); + if (z80_read(3) == 0xFF) + cputype = z80_read(4); + z80_bus_cmd(Release); } - /* Stop Timer */ - TCCR3B = 0; - PRR1 |= _BV(PRTIM3); - - ATOMIC_BLOCK(ATOMIC_FORCEON) { - /* Restore INT6 */ -#if 0 /* wtf? */ - eicrb_save = EICRB; - EICRB = (EICRB & ~(0b11 << ISC60)) | (eicrb_save & (0b11 << ISC60)); -#endif - EICRB = eicrb_save; - if ((eimsk_save & _BV(INT6)) != 0) - EIMSK |= _BV(INT6); - /* Reset pending int */ - EIFR = _BV(INTF6); + if ((mem_save != NULL) && options & O_UNLOAD_LOOP) { + z80_bus_cmd(Request); + z80_write_block(mem_save, 0, cpuinfo_length); + z80_bus_cmd(Release); } + free(mem_save); - return (int32_t) x_freq; -} -#endif - -static const FLASH char * const FLASH cpu_strings[] = { - FSTR("Unknown CPU"), - FSTR("8080"), - FSTR("8085"), - FSTR("Z80"), - FSTR("x180"), - FSTR("HD64180"), - FSTR("Z80180"), - FSTR("Z80S180"), -}; + if (err) + cmd_error(CMD_RET_FAILURE, err, NULL); -command_ret_t do_cpuchk(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED) -{ - uint_fast8_t cputype = 0; - ERRNUM err = ESUCCESS; - uint8_t ram_save[cpuinfo_length]; + char result_str[11]; - if (z80_bus_state() & ZST_RUNNING) { - err = ERUNNING; + if (freq_cmd) { + ultoa(cpu_freq, result_str, 10); } else { - z80_bus_request_or_exit(); - z80_read_block(ram_save, 0, cpuinfo_length); - z80_load_mem(0, cpuinfo, - &cpuinfo_sections, - cpuinfo_address, - cpuinfo_length_of_sections); - z80_bus_cmd(Release); - - if (argv[1] && (argv[1][0] == 'n')) - goto donot; + if (cputype >= ARRAY_SIZE(cpu_strings)) + cputype = 0; + strcpy_P(result_str, cpu_strings[cputype]); + } - z80_bus_cmd(Run); + if (!(options & O_SILENT)) + printf_P(PSTR("%s\n"), result_str); - clear_ctrlc(); /* forget any previous Control C */ - uint_fast8_t done = 0; - while (done != 0xFF) { - _delay_ms(8); - /* check for ctrl-c to abort... */ - if (had_ctrlc() || ctrlc()) { - err = EINTR; - break; + if (options & O_WENV) { + if (setenv(env_names[freq_cmd], result_str)) { + if (!(options & O_SILENT)) { + printf_P(PSTR("'setenv %S %s' failed!\n"), env_names[freq_cmd], result_str); + //cmd_error(CMD_RET_FAILURE, ENOMEM, PSTR("'setenv (%S, %s)' failed"), env_names[freq_cmd], result_str); } - z80_bus_cmd(Request); - done = z80_read(3); - if (done == 0xFF) - cputype = z80_read(4); - z80_bus_cmd(Release); + return CMD_RET_FAILURE; } - z80_bus_cmd(Reset); - z80_bus_cmd(Request); -// z80_write_block(ram_save, 0, cpuinfo_length); - z80_bus_cmd(Release); } -donot: - - if (err) - cmd_error(CMD_RET_FAILURE, err, NULL); - - if (cputype >= ARRAY_SIZE(cpu_strings)) - cputype = 0; - printf_P(PSTR("Detected CPU: %S\n"), cpu_strings[cputype]); - return CMD_RET_SUCCESS; } @@ -569,135 +317,33 @@ command_ret_t do_busack_test(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, return CMD_RET_SUCCESS; } -static const FLASH uint8_t loop_code[] = { -/* 0000 */ 0x00, /* nop */ -/* 0001 */ 0xAF, /* xor a */ -/* 0005 */ 0xD3,0x32, /* out (032h),a ;DCNTL */ -/* 0002 */ 0xD3,0x36, /* out (036h),a ;RCR */ -/* */ /* */ -/* 0006 */ 0xD3,0x40, /* out (040H),a ;Ready */ -/* */ /* */ -/* */ /* ;Z80 Z180(0W) Z180(MaxW) */ -/* 0008 */ /* loop: ;-------------------------- */ -/* 0008 */ 0xDB,0x50, /* in a,(050h) ;11 10 +3*3 19 */ -/* 000A */ 0xC3,0x08,0x00 /* jp loop ;10 9 +3*3 18 */ - /* ;-------------------------- */ - /* ;21 19 37 */ -}; - -command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) -{ - -#define O_SILENT (1<<0) -#define O_WENV (1<<1) -#define O_LOAD_LOOP (1<<2) -#define O_UNLOAD_LOOP (1<<3) - - uint_fast8_t options = O_LOAD_LOOP | O_UNLOAD_LOOP; - uint_fast8_t lcycles = 19; - uint16_t timeout = 1000; - - uint8_t mem_save[ARRAY_SIZE(loop_code)]; - - int opt; - while ((opt = getopt(argc, argv, PSTR("swnuc:t:"))) != -1) { - switch (opt) { - case 's': - options |= O_SILENT; - break; - case 'w': - options |= O_WENV; - break; - case 'n': - options &= ~O_LOAD_LOOP; - break; - case 'u': - options &= ~O_UNLOAD_LOOP; - break; - case 'c': - lcycles = eval_arg(optarg, NULL); - break; - case 't': - timeout = eval_arg(optarg, NULL); - break; - default: /* '?' */ - return CMD_RET_USAGE; - } - } - if (argc - optind != 0) - return CMD_RET_USAGE; - - if (z80_bus_state() & ZST_RUNNING) { - if (!(options & O_SILENT)) - printf_P(PSTR("Frequency measuring failed. CPU allready running!\n")); - return CMD_RET_FAILURE; - } - - - z80_bus_cmd(Request); - if (options & O_LOAD_LOOP) { - z80_read_block(mem_save, 0, ARRAY_SIZE(loop_code)); - z80_write_block_P(loop_code, 0, ARRAY_SIZE(loop_code)); - } - Stat &= ~S_IO_0X40; /* Reset pending int */ - z80_bus_cmd(Release); - z80_bus_cmd(Run); - - clear_ctrlc(); /* forget any previous Control C */ - ERRNUM err = 0; - - /* Wait for falling edge */ - do { - /* check for ctrl-c to abort... */ - if (had_ctrlc() || ctrlc()) { - err = EINTR; - break; - } - } while ((Stat & S_IO_0X40) == 0); - - uint32_t cpu_freq = 0; - if (!err) - cpu_freq = z80_measure_phi(lcycles); - - z80_bus_cmd(Reset); - if (options & O_UNLOAD_LOOP) { - z80_bus_cmd(Request); - z80_write_block(mem_save, 0, ARRAY_SIZE(loop_code)); - z80_bus_cmd(Release); - } - if (err) - cmd_error(CMD_RET_FAILURE, err, NULL); - - if (!(options & O_SILENT)) { - printf_P(PSTR("%lu %3u\n"), cpu_freq & 0x0fffffff, cpu_freq >> 28); - -// printf_P(PSTR("%f%S\n"), cpu_freq, cpu_freq < 0 ? PSTR("") : PSTR("Hz")); -// if (cpu_freq != 0) -// else -// printf_P(PSTR("No CPU clock or input frequency to low!\n")); - } -#if 0 - if (options & O_WENV) { - if (setenv_ulong(PSTR(ENV_CPU_FREQ), cpu_freq)) { - if (!(options & O_SILENT)) - printf_P(PSTR("'SETENV (%S, %lu)' failed!\n"), PSTR(ENV_CPU_FREQ), cpu_freq); - return CMD_RET_FAILURE; - } - } -#endif - return CMD_RET_SUCCESS; -} - /* - * command table for fat subcommands + * command table for subcommands */ - cmd_tbl_t cmd_tbl_cpu[] = { CMD_TBL_ITEM( - chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpuchk, - "Check CPU", - "" + freq, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpu_freq_chk, + "Measure cpu frequency", +// "[-swnu] [-c loopcycles] [-t timeout]\n" + "[-swnu] [-c loopcycles]\n" + " -s Be silent\n" + " -w Write result to environment variable '"ENV_CPU_FREQ"'\n" + " -n Don't load code snippet. \n" + " -u Don't unload. Leave code snippet in ram.\n" + " -c Overwrite cycles per lopp for in \"l: a,(50h)/jp l\" loop." +// " -t Timeout (ms)\n" +), +CMD_TBL_ITEM( + chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT|CTBL_SUBCMDAUTO, do_cpu_freq_chk, + "Check/Identify CPU", +// "[-swnu] [-c loopcycles] [-t timeout]\n" + "[-swnu] [-c loopcycles]\n" + " -s Be silent\n" + " -w Write result to environment variable '"ENV_CPU"'\n" + " -n Don't load code snippet. \n" + " -u Don't unload. Leave code snippet in ram." +// " -t Timeout (ms)\n" ), CMD_TBL_ITEM( buscmd, CONFIG_SYS_MAXARGS, CTBL_RPT, do_bus_test, @@ -705,22 +351,15 @@ CMD_TBL_ITEM( "" ), CMD_TBL_ITEM( - test, CONFIG_SYS_MAXARGS, 1, do_cpu_test, + test, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpu_test, "Do bus request/release cycles", "[-t pulsewidth]" ), CMD_TBL_ITEM( - busack, 2, 1, do_busack_test, + busack, 2, CTBL_RPT, do_busack_test, "Get time from /Reset high to /BUSACK low", "" ), -CMD_TBL_ITEM( - freq, CONFIG_SYS_MAXARGS, 1, do_cpu_freq, - "Measure cpu frequency", - "[-qwn] [-c loopcycles] [-t timeout]\n" - " -q Be quiet\n" -// " -w Write result to environment variable '"ENV_CPU_FREQ"'" -), CMD_TBL_ITEM( help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help, @@ -732,7 +371,7 @@ CMD_TBL_ITEM( ), /* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */ - {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help, + {FSTR("?"), CONFIG_SYS_MAXARGS, CTBL_RPT, do_help, NULL, #ifdef CONFIG_SYS_LONGHELP FSTR(""), diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index fdd05b4..8477fc2 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -9,7 +9,6 @@ */ #include "cmd_fat.h" -#include <ctype.h> #include <time.h> uint32_t fat_time(const struct tm * timeptr); diff --git a/avr/cmd_gpio.c b/avr/cmd_gpio.c index 549654f..16c2202 100644 --- a/avr/cmd_gpio.c +++ b/avr/cmd_gpio.c @@ -5,8 +5,6 @@ */ #include "cmd_gpio.h" -#include <ctype.h> - #include "print-utils.h" #include "getopt-min.h" #include "env.h" @@ -247,6 +245,7 @@ command_ret_t do_gpio(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int arg switch (toupper(argv[optind][0])) { case 'H': level = 1; + /* FALL TROUGH */ case 'L': mode = OUTPUT; break; @@ -263,6 +262,7 @@ command_ret_t do_gpio(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int arg switch (*endp) { case 'M': value *= 1000; + /* FALL TROUGH */ case 'K': value *= 1000; endp++; diff --git a/avr/cmd_loadcpm3.c b/avr/cmd_loadcpm3.c index ee336da..425d1fd 100644 --- a/avr/cmd_loadcpm3.c +++ b/avr/cmd_loadcpm3.c @@ -9,7 +9,6 @@ */ #include "cmd_loadcpm3.h" -#include <ctype.h> #include "env.h" #include "ff.h" @@ -17,7 +16,6 @@ #include "con-utils.h" #include "z80-if.h" #include "debug.h" -#include "errnum.h" #define RS 128 /* CP/M record size */ diff --git a/avr/cmd_loadihex.c b/avr/cmd_loadihex.c index a7c9238..19cd29b 100644 --- a/avr/cmd_loadihex.c +++ b/avr/cmd_loadihex.c @@ -5,7 +5,6 @@ */ #include "cmd_loadihex.h" -#include <ctype.h> #include "con-utils.h" #include "z80-if.h" diff --git a/avr/cmd_misc.c b/avr/cmd_misc.c index ad913e8..63a510c 100644 --- a/avr/cmd_misc.c +++ b/avr/cmd_misc.c @@ -104,7 +104,7 @@ command_ret_t do_time(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int arg sec = (elapsed_ms / 1000) % 60; ms = elapsed_ms % 1000; - printf_P(PSTR("\ntime: %lum%u.%03us\n"), min, sec, ms); + printf_P(PSTR("\ntime: %lum %u.%03us\n"), min, sec, ms); return retval; } diff --git a/avr/cmd_sd.c b/avr/cmd_sd.c index 344a197..440bfd4 100644 --- a/avr/cmd_sd.c +++ b/avr/cmd_sd.c @@ -7,7 +7,6 @@ #include "cmd_sd.h" #include "diskio.h" -#include "ff.h" #include "eval_arg.h" #include "print-utils.h" #include "z80-if.h" diff --git a/avr/command.c b/avr/command.c index 8eb5bb7..8a4ca02 100644 --- a/avr/command.c +++ b/avr/command.c @@ -13,7 +13,6 @@ #include "command.h" #include "common.h" -#include <ctype.h> #include <setjmp.h> #include "config.h" diff --git a/avr/con-utils.c b/avr/con-utils.c index 4a96771..5ea19fd 100644 --- a/avr/con-utils.c +++ b/avr/con-utils.c @@ -5,7 +5,6 @@ */ #include "common.h" -#include <string.h> #include <avr/wdt.h> #include "config.h" diff --git a/avr/debug.c b/avr/debug.c index 89ef4b1..ea21583 100644 --- a/avr/debug.c +++ b/avr/debug.c @@ -6,9 +6,6 @@ #include "debug.h" #include "common.h" -#include <stdlib.h> /* __malloc_margin */ -#include <string.h> -#include <ctype.h> #include <avr/eeprom.h> #include "command.h" @@ -63,6 +63,7 @@ char env_get_char(uint_fast16_t index) switch (env_valid) { case 2: off += CONFIG_ENV_SIZE; + /* FALL TROUGH */ case 1: ret = (char) eeprom_read_byte((const uint8_t *)off + index + offsetof(env_t, data)); @@ -562,7 +563,7 @@ command_ret_t _do_env_set(uint_fast8_t flag UNUSED, int argc, char * const argv[ * @param varvalue Value to set it to * @return 0 if ok, 1 on error */ -static + int setenv(const MEMX char *varname, const char *varvalue) { int rc; @@ -718,7 +719,6 @@ command_ret_t do_env_print(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, while (optind < argc) { int len = env_print(argv[optind], mode); if (len < 0) { - printf_P(PSTR("## Error: \"%s\" not defined\n"), argv[optind]); rc = CMD_RET_FAILURE; } optind++; diff --git a/avr/eval_arg.c b/avr/eval_arg.c index fd8b067..deb601f 100644 --- a/avr/eval_arg.c +++ b/avr/eval_arg.c @@ -6,7 +6,6 @@ #include "eval_arg.h" #include "command.h" /* jump_buf */ -#include <ctype.h> #include <setjmp.h> #include "print-utils.h" diff --git a/avr/getopt-min.c b/avr/getopt-min.c index 401beed..4e67a9b 100644 --- a/avr/getopt-min.c +++ b/avr/getopt-min.c @@ -11,7 +11,6 @@ /* $Id: getopt.c,v 1.2 1992/12/07 11:12:52 nickc Exp $ */ #include "common.h" /* definition of FLASH */ -#include <string.h> int optind; /* next argv[] index */ char *optarg; /* option parameter if any */ @@ -148,6 +148,7 @@ int gpio_config(int pin, gpiomode_t mode) break; case OUTPUT: gpio_timer_off(pinlist[pin].timer); + /* FALL TROUGH */ case OUTPUT_TIMER: ATOMIC_BLOCK(ATOMIC_FORCEON) { p->ddr |= bit; @@ -10,7 +10,6 @@ #include "common.h" #include <avr/interrupt.h> -#include <string.h> #include "config.h" #include "timer.h" @@ -85,7 +85,6 @@ void print_reset_reason(void) ISR(INT5_vect) { Stat |= S_MSG_PENDING; - Stat |= S_IO_0X40; } ISR(INT6_vect) @@ -6,7 +6,6 @@ /*-----------------------------------------------------------------------*/ #include "common.h" -#include <stdbool.h> #include <util/atomic.h> #include "timer.h" #include "spi.h" @@ -293,7 +292,6 @@ UINT btr /* Byte count (must be multiple of 4) */ /* Send a data packet to MMC */ /*-----------------------------------------------------------------------*/ -#if _USE_WRITE static int xmit_datablock ( const BYTE *buff, /* 512 byte data block to be transmitted */ @@ -323,7 +321,6 @@ int xmit_datablock ( spi_wait(); return 1; } -#endif /* _USE_WRITE */ /*-----------------------------------------------------------------------*/ /* Send a command packet to MMC */ @@ -585,7 +582,6 @@ DRESULT disk_read ( /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -#if _USE_WRITE DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0) */ const BYTE *buff, /* Pointer to the data to be written */ @@ -631,13 +627,11 @@ DRESULT disk_write ( return count ? RES_ERROR : RES_OK; } -#endif /* _USE_WRITE */ /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ -#if _USE_IOCTL DRESULT disk_ioctl ( BYTE drv, /* Physical drive nmuber (0) */ BYTE cmd, /* Control code */ @@ -749,7 +743,6 @@ DRESULT disk_ioctl ( return res; } -#endif /* _USE_IOCTL */ /*-----------------------------------------------------------------------*/ /* Device Timer Interrupt Procedure (Platform dependent) */ diff --git a/avr/print-utils.c b/avr/print-utils.c index 15f69f8..ea3b5cf 100644 --- a/avr/print-utils.c +++ b/avr/print-utils.c @@ -6,8 +6,6 @@ #include "common.h" #include <stdint.h> -#include <stdio.h> -#include <ctype.h> #include "con-utils.h" #include "print-utils.h" diff --git a/avr/z180-serv.c b/avr/z180-serv.c index f99a11e..6973908 100644 --- a/avr/z180-serv.c +++ b/avr/z180-serv.c @@ -6,9 +6,6 @@ #include "z180-serv.h" #include "common.h" -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> #include <util/atomic.h> #include "config.h" @@ -109,6 +106,45 @@ void do_msg_get_timer(uint8_t subf, int len, uint8_t * msg) /* ---------------------------------------------------------------------------*/ +/* measure f_cpu */ +void do_msg_m_fcpu(uint8_t subf, int len UNUSED, uint8_t * msg) +{ + uint32_t freq; + uint8_t eimsk_save; + + /* Save state and disable INT5/INT6 */ + ATOMIC_BLOCK(ATOMIC_FORCEON) { + eimsk_save = EIMSK; + EIMSK &= ~_BV(INT6); + EIMSK &= ~_BV(INT5); + } + EIFR = _BV(INTF5); /* Reset pending int */ + z80_bus_cmd(Request); + z80_write(0x3f, 0xff); + z80_bus_cmd(Release); + + freq = z80_measure_phi(*msg); + + z80_bus_cmd(Request); + z80_write(0x3f, 0xff); + z80_bus_cmd(Release); + + /* Restore INT5/INT6 */ + ATOMIC_BLOCK(ATOMIC_FORCEON) { + if ((eimsk_save & _BV(INT5)) != 0) + EIMSK |= _BV(INT5); + if ((eimsk_save & _BV(INT6)) != 0) + EIMSK |= _BV(INT6); + /* Reset pending int */ + EIFR = _BV(INTF5); + EIFR = _BV(INTF6); + } + + msg_xmit(4, subf, sizeof(freq), (uint8_t *) &freq); +} + +/* ---------------------------------------------------------------------------*/ + #define CPM_DAY_OFFSET ((1978-1900) * 365 + 19) /* 19 leap years */ /* @@ -625,6 +661,9 @@ const FLASH struct msg_item z80_messages[] = { 3, 2, 3, /* 2: get, 3: set time and date */ do_msg_get_set_time}, + { 4, + 1, 1, + do_msg_m_fcpu}, { 0xff, /* end mark */ 0, 0, 0}, @@ -632,8 +671,6 @@ const FLASH struct msg_item z80_messages[] = }; - - void do_message(int len, uint8_t *msg) { uint8_t fct, sub_fct; diff --git a/avr/z80-if.c b/avr/z80-if.c index 9865208..f36466c 100644 --- a/avr/z80-if.c +++ b/avr/z80-if.c @@ -163,7 +163,6 @@ ISR(TIMER4_COMPB_vect) ISR(TIMER5_COMPA_vect) { - uint8_t i = timer; if (i) @@ -402,7 +401,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd) Z80_I_RST = 1; /* Toggle RESET --> inactive */ OCR4B = TCNT4; TIFR4 = _BV(OCF4B); /* Clear compare match flag */ -/*test*/ TIMSK4 &= ~_BV(OCIE4A); /* Disable Output Compare A interrupt */ +// TIMSK4 &= ~_BV(OCIE4A); /* Disable Output Compare A interrupt */ } TIMSK4 |= _BV(OCIE4B); /* Enable compare match interrupt */ @@ -414,7 +413,7 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd) ovl_cnt = busack_cycles_ovl; ifr = TIFR4; TIMSK4 &= ~_BV(OCIE4B); /* Disable compare match interrupt */ -/*test*/ TIMSK4 |= _BV(OCIE4A); /* Enable Output Compare A interrupt */ +// TIMSK4 |= _BV(OCIE4A); /* Enable Output Compare A interrupt */ } if (Z80_I_BUSACK == 0) { if ((ifr & _BV(OCF4B)) && !(tcnt & (1<<15))) @@ -518,6 +517,106 @@ zstate_t z80_bus_cmd(bus_cmd_t cmd) return zstate; } +/*--------------------------------------------------------------------------*/ + +#define DEBUG_FREQ 0 /* set to 1 to debug */ + +#define debug_cpu(fmt, args...) \ + debug_cond(DEBUG_FREQ, fmt, ##args) + +#if 0 +static +char * ulltoa (uint64_t val, char *s) +{ + char *p = s; + + while (val >= 10) { + *p++ = (val % 10) + '0'; + val = val / 10; + } + *p++ = val + '0'; + *p = '\0'; + + return strrev(s); +} +#endif + +uint32_t z80_measure_phi(uint_fast8_t cycles) +{ + uint16_t ref_stop; + uint16_t ref_ovfl; + uint8_t x_ovfl; + uint32_t x_freq; + + + PRR1 &= ~_BV(PRTIM3); + TCCR3A = 0; + TCCR3B = 0b000<<CS30; /* stop counter */ + TCNT3 = 0; + x_ovfl = 0; + TIFR3 = _BV(TOV3); + ref_ovfl = 0; + + ATOMIC_BLOCK(ATOMIC_FORCEON) { + EIFR = _BV(INTF6); /* Reset pending int */ + while ((EIFR & _BV(INTF6)) == 0) /* Wait for falling edge */ + ; + OCR4B = TCNT4; + TCCR3B = 0b110<<CS30; /* Count falling edges on T3 (==INT6) */ + TIFR4 = _BV(OCF4B); /* clear compare match flag */ + + while (ref_ovfl < 60) { + if ((TIFR4 & _BV(OCF4B)) != 0) { + TIFR4 = _BV(OCF4B); + ++ref_ovfl; + } + if ((TIFR3 & _BV(TOV3)) != 0) { + TIFR3 = _BV(TOV3); + ++x_ovfl; + } + } + + EIFR = _BV(INTF6); + for (;;) { + if (EIFR & _BV(INTF6)) { + TCCR3B = 0b000<<CS30; /* stop counter */ + ref_stop = TCNT4; + break; + } + if ((TIFR4 & _BV(OCF4B)) != 0) { + TIFR4 = _BV(OCF4B); + ++ref_ovfl; + } + } + } + + if ((TIFR3 & _BV(TOV3)) != 0) { + TIFR3 = _BV(TOV3); + x_ovfl++; + } + + uint32_t ref_cnt = (ref_stop - OCR4B) + ((uint32_t)ref_ovfl << 16); + uint32_t x_cnt = TCNT3 + ((uint32_t) x_ovfl << 16); + uint64_t x_tmp = (uint64_t) 100000 * (x_cnt * cycles); + + /* Stop Timer */ + TCCR3B = 0; + PRR1 |= _BV(PRTIM3); + + debug_cpu("\nx_ovfl: %6u, TCNT3: %6u, cycles: %3u\n", x_ovfl, TCNT3, cycles); + debug_cpu("ref_ovfl: %6u, ref_...: %6u\n", ref_ovfl, ref_stop-OCR4B); + debug_cpu("x_cnt: %9lu, ref_cnt: %9lu\n", x_cnt, ref_cnt); + + x_tmp = (x_tmp * getenv_ulong(PSTR(ENV_FMON), 10, F_CPU) + (ref_cnt / 2)) / ref_cnt; + + /* round to 5 decimal digits */ + int_fast8_t sc = 5; + for ( ; sc > 0 || x_tmp >= 100000; sc--) x_tmp = (x_tmp + 5)/10; + x_freq = x_tmp; + for ( ; sc < 0; sc++) x_freq *= 10; + + return x_freq; +} /*--------------------------------------------------------------------------*/ |