]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/cmd_cpu.c
ew debug command: xx busack: Measure time RESET to BUSACK
[z180-stamp.git] / avr / cmd_cpu.c
CommitLineData
226d3221
L
1/*
2 * (C) Copyright 2018 Leo C. <erbl259-lmu@yahoo.de>
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7#include "cmd_cpu.h"
8//#include <ctype.h>
9//#include <util/atomic.h>
10
11#include "z80-if.h"
12#include "con-utils.h"
13//#include "env.h"
51dd0948
L
14#include "eval_arg.h"
15#include "timer.h"
16#include "getopt-min.h"
226d3221
L
17//#include "debug.h"
18
19/* hack to get Z180 loadfile into flash memory */
20#define const const FLASH
21#include "../z180/cpuinfo.h"
22#undef const
23
24
25static const FLASH char * const FLASH cpu_strings[] = {
26 FSTR("Unknown CPU"),
27 FSTR("8080"),
28 FSTR("8085"),
29 FSTR("Z80"),
30 FSTR("x180"),
31 FSTR("HD64180"),
32 FSTR("Z80180"),
33 FSTR("Z80S180"),
34};
35
36command_ret_t do_cpuchk(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
37{
38 uint8_t done = 0;
39 uint8_t cputype;
40 ERRNUM err = ESUCCESS;
41 uint8_t ram_save[cpuinfo_length];
42
43 if (z80_bus_state() & ZST_RUNNING) {
44 err = ERUNNING;
45 } else {
46 z80_bus_request_or_exit();
47 z80_read_block(ram_save, 0, cpuinfo_length);
48 z80_load_mem(0, cpuinfo,
49 &cpuinfo_sections,
50 cpuinfo_address,
51 cpuinfo_length_of_sections);
52 z80_bus_cmd(Release);
53
54 if (argv[1] && (argv[1][0] == 'n'))
55 goto donot;
56
57 z80_bus_cmd(Run);
58
59 clear_ctrlc(); /* forget any previous Control C */
60 while (done != 0xFF) {
61 _delay_ms(8);
62 /* check for ctrl-c to abort... */
63 if (had_ctrlc() || ctrlc()) {
64 err = EINTR;
65 break;
66 }
67 z80_bus_cmd(Request);
68 done = z80_read(3);
69 if (done == 0xFF)
70 cputype = z80_read(4);
71 z80_bus_cmd(Release);
72 }
73 z80_bus_cmd(Reset);
74 z80_bus_cmd(Request);
75// z80_write_block(ram_save, 0, cpuinfo_length);
76 z80_bus_cmd(Release);
77 }
78
79donot:
80
81 if (err)
82 cmd_error(CMD_RET_FAILURE, err, NULL);
83
84 if (done == 0xFF) {
85 if (cputype >= ARRAY_SIZE(cpu_strings))
86 cputype = 0;
87 printf_P(PSTR("Detected CPU: %S\n"), cpu_strings[cputype]);
88 }
89
90 return CMD_RET_SUCCESS;
91}
51dd0948
L
92
93/*
94 * delay for <count> ms...
95 */
96static void test_delay(uint32_t count)
97{
98 uint32_t ts = get_timer(0);
99
d66348b4 100 while (get_timer(ts) <= count);
51dd0948
L
101}
102
103command_ret_t do_cpu_test(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[])
104{
105
106 uint32_t pulsewidth = 10; /* ms */
107
108 /* reset getopt() */
109 optind = 0;
110
111 int opt;
112 while ((opt = getopt(argc, argv, PSTR("t:"))) != -1) {
113 switch (opt) {
114 case 't':
115 pulsewidth = eval_arg(optarg, NULL);
116 break;
117 default: /* '?' */
118 return CMD_RET_USAGE;
119 }
120 }
121
122 if ((z80_bus_state() & ZST_ACQUIRED) != RESET)
123 cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
124
125 clear_ctrlc(); /* forget any previous Control C */
126 do {
127 z80_bus_cmd(Request);
128 test_delay(pulsewidth);
129 z80_bus_cmd(Release);
130 test_delay(pulsewidth);
131 } while (!(had_ctrlc() || ctrlc()));
132
133 return CMD_RET_SUCCESS;
134}
135
d66348b4
L
136command_ret_t do_busack_test(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
137{
138
139 if ((z80_bus_state() & ZST_ACQUIRED) != RESET)
140 cmd_error(CMD_RET_FAILURE, ERUNNING, NULL);
141
142 z80_bus_cmd(Request);
143 uint32_t result = z80_get_busreq_cycles();
144 test_delay(20);
145 z80_bus_cmd(Release);
146
147#if 0
148 long div;
149
150 pinconf = gpio_config_get(pin);
151 if (pinconf == OUTPUT_TIMER) {
152 div = gpio_clockdiv_get(pin);
153#endif
154
155
156 printf_P(PSTR("cycles: %lu, time: %luus\n"), result, (uint32_t) (result * 1000000LL / F_CPU));
157
158 return CMD_RET_SUCCESS;
159}
160
51dd0948
L
161#if 0
162command_ret_t do_cpu_freq(cmd_tbl_t *cmdtp UNUSED, int flag UNUSED, int argc, char * const argv[])
163{
164 bool silent = false;
165 bool write_env = false;
166 bool load_loop = true;
167 uint8_t lcycles = 18;
168 uint16_t timeout = 1000;
169
170 uint8_t eicrb_save;
171 uint8_t eimsk_save;
172 uint8_t mem_save[cpuinfo_length];
173
174 /* reset getopt() */
175 optind = 0;
176
177 int opt;
178 while ((opt = getopt(argc, argv, PSTR("swnc:t:"))) != -1) {
179 switch (opt) {
180 case 's':
181 silent = true;
182 break;
183 case 'w':
184 write_env = true;
185 break;
186 case 'n':
187 load_loop = false;
188 break;
189 case 'c':
190 lcycles = eval_arg(optarg, NULL);
191 break;
192 case 't':
193 lcycles = eval_arg(optarg, NULL);
194 break;
195 default: /* '?' */
196 return CMD_RET_USAGE;
197 }
198 }
199
200 if (z80_bus_state() & ZST_RUNNING) {
201 if (!silent)
202 printf_P(PSTR("Frequency measuring failed. CPU allready running!\n"));
203 return CMD_RET_FAILURE;
204 }
205
206 ATOMIC_BLOCK(ATOMIC_FORCEON) {
207 /* Save state and disable INT6 */
208 eimsk_save = EIMSK;
209 EIMSK &= ~_BV(INT6);
210 /* Save state and set INT6 for falling edge */
211 eicrb_save = EICRB;
212 EICRB = (eicrb_save & ~(0b11 << ISC60)) | (0b10 << ISC60);
213 }
214
215 z80_bus_cmd(Request);
216 if (load_loop) {
217 z80_read_block(mem_save, 0, cpuinfo_length);
218 z80_load_mem(0, cpuinfo,
219 &cpuinfo_sections,
220 cpuinfo_address,
221 cpuinfo_length_of_sections);
222 }
223 z80_bus_cmd(Run);
224 z80_bus_cmd(Release);
225
226 uint32_t cpu_freq = z80_measure_phi(lcycles, true, timeout);
227
228 z80_bus_cmd(Reset);
229 z80_bus_cmd(Request);
230 if (load_loop)
231 z80_write_block(mem_save, 0, cpuinfo_length);
232 z80_bus_cmd(Release);
233
234 ATOMIC_BLOCK(ATOMIC_FORCEON) {
235 /* Restore INT6 */
236 eicrb_save = EICRB;
237 EICRB = (EICRB & ~(0b11 << ISC60)) | (eicrb_save & (0b11 << ISC60));
238 if ((eimsk_save & _BV(INT6)) != 0)
239 EIMSK |= _BV(INT6);
240 /* Reset pending int */
241 EIFR = _BV(INTF6);
242 }
243
244 if (!silent) {
245 if (cpu_freq != 0)
246 printf_P(PSTR("%luHz\n"), cpu_freq);
247 else
248 printf_P(PSTR("No CPU clock or input frequency to low!\n"));
249 }
250
251 if (write_env) {
252 if (setenv_ulong(PSTR(ENV_CPU_FREQ), cpu_freq)) {
253 if (!silent)
254 printf_P(PSTR("'SETENV (%S, %lu)' failed!\n"), PSTR(ENV_CPU_FREQ), cpu_freq);
255 return CMD_RET_FAILURE;
256 }
257 }
258
259 return CMD_RET_SUCCESS;
260}
261#endif
262
263/*
264 * command table for fat subcommands
265 */
266
267cmd_tbl_t cmd_tbl_cpu[] = {
268CMD_TBL_ITEM(
269 chkcpu, CONFIG_SYS_MAXARGS, CTBL_RPT, do_cpuchk,
270 "Check CPU",
271 ""
272),
273CMD_TBL_ITEM(
274 test, CONFIG_SYS_MAXARGS, 1, do_cpu_test,
275 "Do bus request/release cycles",
276 "[-t pulsewidth]"
277),
d66348b4
L
278CMD_TBL_ITEM(
279 busack, 2, 1, do_busack_test,
280 "Get time from /Reset high to /BUSACK low",
281 ""
282),
51dd0948
L
283#if 0
284CMD_TBL_ITEM(
285 freq, CONFIG_SYS_MAXARGS, 1, do_cpu_freq,
286 "Measure cpu frequency",
287 "[-swn] [-c loopcycles]\n"
288 " -s Supress output (silent)\n"
289 " -w Write result to environment variable '"ENV_CPU_FREQ"'"
290),
291#endif
292CMD_TBL_ITEM(
293 help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help,
294 "Print sub command description/usage",
295 "\n"
296 " - print brief description of all sub commands\n"
297 "fat help command ...\n"
298 " - print detailed usage of sub cmd 'command'"
299),
300
301/* This does not use the CMD_TBL_ITEM macro as ? can't be used in symbol names */
302 {FSTR("?"), CONFIG_SYS_MAXARGS, 1, do_help,
303 NULL,
304#ifdef CONFIG_SYS_LONGHELP
305 FSTR(""),
306#endif /* CONFIG_SYS_LONGHELP */
307 NULL,
308#ifdef CONFIG_AUTO_COMPLETE
309 NULL,
310#endif
311},
312/* Mark end of table */
313CMD_TBL_END(cmd_tbl_cpu)
314};
315
316
317command_ret_t do_cpu(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc UNUSED, char * const argv[] UNUSED)
318{
319 //puts_P(PSTR("Huch?"));
320
321 return CMD_RET_USAGE;
322}
323
324
325#if 0
326/*
327 * Z180 Single Step Functions
328 *
329 */
330
331
332#define P_RUN PORTG
333#define RUN 1
334#define DDR_RUN DDRG
335#define P_STEP PORTG
336#define STEP 0
337#define DDR_STEP DDRG
338#define P_WAIT PORTG
339#define WAIT 2
340#define DDR_WAIT DDRG
341/* All three signals are on the same Port (PortG) */
342#define PORT_SS PORTG
343#define DDR_SS DDRG
344#define PIN_SS PING
345
346static bool ss_available;
347
348int single_step_setup(void)
349{
350 ss_available = false;
351
352#if 0
353 if (z80_bus_state() & ZST_RUNNING ||
354 !(z80_bus_cmd(Request) & ZST_ACQUIRED))
355 return -1;
356#endif
357
358 /* STEP, RUN output, WAIT input */
359
360 PORT_SS |= _BV(RUN) | _BV(STEP);
361 DDR_SS |= _BV(RUN) | _BV(STEP);
362 DDR_SS &= ~_BV(WAIT);
363
364 /* RUN high, MREQ pulse --> WAIT should be low */
365 z80_mreq_pulse();
366
367 if ((PIN_SS & _BV(WAIT)) == 0) {
368
369 /* RUN high, STEP pulse --> WAIT should be high */
370 PIN_SS = _BV(STEP);
371 PIN_SS = _BV(STEP);
372 if ((PIN_SS & _BV(WAIT)) != 0) {
373
374 /* RUN high, MREQ pulse --> WAIT should be low */
375 z80_mreq_pulse();
376 if ((PIN_SS & _BV(WAIT)) == 0) {
377
378 /* RUN low --> WAIT should be high */
379 PIN_SS = _BV(RUN);
380 if ((PIN_SS & _BV(WAIT)) != 0) {
381
382 /* RUN low, STEP pulse --> WAIT should be high */
383 PIN_SS = _BV(STEP);
384 PIN_SS = _BV(STEP);
385 if ((PIN_SS & _BV(WAIT)) != 0) {
386
387 /* all tests passed */
388 ss_available = true;
389 }
390 }
391 }
392 }
393 }
394
395 if (!ss_available) {
396 DDR_SS &= ~(_BV(STEP) | _BV(RUN));
397 PORT_SS |= _BV(RUN) | _BV(STEP);
398 }
399
400 return ss_available ? 0 : -1;
401}
402#endif