summaryrefslogtreecommitdiff
path: root/avr
diff options
context:
space:
mode:
Diffstat (limited to 'avr')
-rw-r--r--avr/cli.c1
-rw-r--r--avr/cli_readline.c4
-rw-r--r--avr/cmd_boot.c20
-rw-r--r--avr/cmd_cpu.c671
-rw-r--r--avr/cmd_fat.c1
-rw-r--r--avr/cmd_gpio.c4
-rw-r--r--avr/cmd_loadcpm3.c2
-rw-r--r--avr/cmd_loadihex.c1
-rw-r--r--avr/cmd_misc.c2
-rw-r--r--avr/cmd_sd.c1
-rw-r--r--avr/command.c1
-rw-r--r--avr/con-utils.c1
-rw-r--r--avr/debug.c3
-rw-r--r--avr/env.c4
-rw-r--r--avr/eval_arg.c1
-rw-r--r--avr/getopt-min.c1
-rw-r--r--avr/gpio.c1
-rw-r--r--avr/i2c.c1
-rw-r--r--avr/main.c1
-rw-r--r--avr/mmc.c7
-rw-r--r--avr/print-utils.c2
-rw-r--r--avr/z180-serv.c47
-rw-r--r--avr/z80-if.c105
23 files changed, 313 insertions, 569 deletions
diff --git a/avr/cli.c b/avr/cli.c
index 7c45251..3e711b3 100644
--- a/avr/cli.c
+++ b/avr/cli.c
@@ -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"
diff --git a/avr/env.c b/avr/env.c
index 671d1c4..f167859 100644
--- a/avr/env.c
+++ b/avr/env.c
@@ -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 */
diff --git a/avr/gpio.c b/avr/gpio.c
index 73e9c39..6f73cee 100644
--- a/avr/gpio.c
+++ b/avr/gpio.c
@@ -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;
diff --git a/avr/i2c.c b/avr/i2c.c
index ae2f8da..a0a12c8 100644
--- a/avr/i2c.c
+++ b/avr/i2c.c
@@ -10,7 +10,6 @@
#include "common.h"
#include <avr/interrupt.h>
-#include <string.h>
#include "config.h"
#include "timer.h"
diff --git a/avr/main.c b/avr/main.c
index 6fd29a8..09df64b 100644
--- a/avr/main.c
+++ b/avr/main.c
@@ -85,7 +85,6 @@ void print_reset_reason(void)
ISR(INT5_vect)
{
Stat |= S_MSG_PENDING;
- Stat |= S_IO_0X40;
}
ISR(INT6_vect)
diff --git a/avr/mmc.c b/avr/mmc.c
index d45cdf5..e1a51fe 100644
--- a/avr/mmc.c
+++ b/avr/mmc.c
@@ -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;
+}
/*--------------------------------------------------------------------------*/