#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <getopt.h>
// Digilent SDK
#include <dpcdecl.h>
}
-bool scan(HIF hif)
+bool jtag_scan(HIF hif)
{
assert(hif != hifInvalid);
// -----------------------------------------------------------------------------
-int main(int argc, char **argv)
+void usage(void)
{
- (void)argc;
- (void)argv;
+ fprintf(stderr,
+ "JTAG debugger for CPU0 on Digilent Nexys2\n"
+ "\n"
+ "Usage: jtag [options]\n"
+ "\nConnection options:\n"
+ " -p, --part <name> Specify device (default: \"Nexys2\")\n"
+ " -P, --port <portnum> JTAG port number (default: 0)\n"
+ "\nOperation options:\n"
+ " -S, --scan Perform a scan of the JTAG chain\n"
+ " -s, --step <steps> Step the CPU\n"
+ " -h, --halt Leave the CPU in a halted state\n"
+ " (default if --step provided)\n"
+ " -r, --run Leave the CPU in a running state\n"
+ " -d, --dump Dump CPU state\n"
+ "\nOutput options:\n"
+ " -v, --verbose Verbose output; -v -v for more\n"
+ " -q, --quell Quell progress output; -q -q for less\n"
+ " -?, --help Display this message\n"
+ "\n"
+ );
+}
- // Requested settings
- char *device = "Nexys2";
- int32_t port = 0;
+
+int main(int argc, char **argv)
+{
+ // Parsed options with defaults
+ int verbose = 0;
+ int quell = 0;
+ char *part = "Nexys2";
+ int port = 0;
+ bool scan = false;
+ bool halt = false;
+ bool run = false;
+ int steps = 0;
+ bool dump = false;
+
+ // Options
+ int opt;
+ int option_idx = 0;
+ struct option longopts[] = {
+ // Output options
+ {"help", no_argument, NULL, '?'},
+ {"quell", no_argument, NULL, 'q'},
+ {"verbose", no_argument, NULL, 'v'},
+
+ // Connection options
+ {"part", required_argument, NULL, 'p'},
+ {"port", required_argument, NULL, 'P'},
+
+ // Operation options
+ {"scan", no_argument, NULL, 'S'},
+ {"step", required_argument, NULL, 's'},
+ {"halt", no_argument, NULL, 'h'},
+ {"run", no_argument, NULL, 'r'},
+ {"dump", no_argument, NULL, 'd'},
+ };
// Port handle and properties
HIF hif = hifInvalid;
// -------------------------------------------------------------
+ while ((opt = getopt_long(argc, argv, "?qvSp:P:Ss:hrd", longopts, &option_idx)) != -1)
+ {
+ switch (opt)
+ {
+ case '?': usage(); exit(0); break;
+ case 'q': quell++; break;
+ case 'v': verbose++; break;
+
+ case 'p': part = optarg; break;
+ case 'P': port = strtol(optarg, NULL, 0); break;
+
+ case 'S': scan = true; break;
+ case 's': steps += strtol(optarg, NULL, 0); break;
+ case 'h': halt = true; break;
+ case 'r': run = true; break;
+ case 'd': dump = true; break;
+
+ default:
+ fprintf(stderr, "Invalid option -%c\n\n", opt);
+ usage();
+ exit(1);
+ break;
+ }
+ }
+
+ // -------------------------------------------------------------
+
EC_FALSE(DjtgGetVersion(version));
- printf("DJTG version: %s\n", version);
+ if (verbose) printf("DJTG version: %s\n", version);
- EC_FALSE(DmgrOpen(&hif, device));
- printf("Opened device \"%s\"\n", device);
+ EC_FALSE(DmgrOpen(&hif, part));
+ if (verbose) printf("Opened device \"%s\"\n", part);
EC_FALSE(DjtgGetPortCount(hif, &port_count));
- printf("Port count: %" PRIi32 "\n", port_count);
- for (int32_t i = 0; i < port_count; i++)
+ if (verbose)
{
- uint32_t port_properties = 0;
- EC_FALSE(DjtgGetPortProperties(hif, i, &port_properties));
- printf("Port %" PRIi32 " properties: 0x%08" PRIx32 "\n", i, port_properties);
- printf(" %c JtgSetSpeed\n", port_properties & dprpJtgSetSpeed ? 'y' : 'n');
- printf(" %c JtgSetPinState\n", port_properties & dprpJtgSetPinState ? 'y' : 'n');
- printf(" %c JtgWait\n", port_properties & dprpJtgWait ? 'y' : 'n');
- printf(" %c JtgBatch\n", port_properties & dprpJtgBatch ? 'y' : 'n');
- printf(" %c JtgSetAuxReset\n", port_properties & dprpJtgSetAuxReset ? 'y' : 'n');
- printf(" %c JtgSetGetGpio\n", port_properties & dprpJtgSetGetGpio ? 'y' : 'n');
-
- if (port_properties & dprpJtgBatch)
+ printf("Port count: %" PRIi32 "\n", port_count);
+ for (int32_t i = 0; i < port_count; i++)
{
- uint32_t batch_properties = 0;
- EC_FALSE(DjtgGetBatchProperties(hif, i, &batch_properties));
- printf(" Batch properties:\n");
- printf(" %c WaitUs\n", batch_properties & djbpWaitUs ? 'y' : 'n');
- printf(" %c SetAuxReset\n", batch_properties & djbpSetAuxReset ? 'y' : 'n');
- printf(" %c SetGetGpio\n", batch_properties & djbpSetGetGpio ? 'y' : 'n');
+ uint32_t port_properties = 0;
+ EC_FALSE(DjtgGetPortProperties(hif, i, &port_properties));
+ printf("Port %" PRIi32 " properties: 0x%08" PRIx32 "\n", i, port_properties);
+ printf(" %c JtgSetSpeed\n", port_properties & dprpJtgSetSpeed ? 'y' : 'n');
+ printf(" %c JtgSetPinState\n", port_properties & dprpJtgSetPinState ? 'y' : 'n');
+ printf(" %c JtgWait\n", port_properties & dprpJtgWait ? 'y' : 'n');
+ printf(" %c JtgBatch\n", port_properties & dprpJtgBatch ? 'y' : 'n');
+ printf(" %c JtgSetAuxReset\n", port_properties & dprpJtgSetAuxReset ? 'y' : 'n');
+ printf(" %c JtgSetGetGpio\n", port_properties & dprpJtgSetGetGpio ? 'y' : 'n');
+
+ if (port_properties & dprpJtgBatch)
+ {
+ uint32_t batch_properties = 0;
+ EC_FALSE(DjtgGetBatchProperties(hif, i, &batch_properties));
+ printf(" Batch properties:\n");
+ printf(" %c WaitUs\n", batch_properties & djbpWaitUs ? 'y' : 'n');
+ printf(" %c SetAuxReset\n", batch_properties & djbpSetAuxReset ? 'y' : 'n');
+ printf(" %c SetGetGpio\n", batch_properties & djbpSetGetGpio ? 'y' : 'n');
+ }
}
}
}
EC_FALSE(DjtgEnableEx(hif, port));
- printf("Opened JTAG port %" PRIi32 "\n", port);
+ if (verbose) printf("Opened JTAG port %" PRIi32 "\n", port);
EC_FALSE(DjtgGetSpeed(hif, &speed));
- printf("Port speed: %" PRIi32 " Hz\n", speed);
+ if (verbose) printf("Port speed: %" PRIi32 " Hz\n", speed);
// -------------------------------------------------------------
// Perform a scan to see what's on the chain
- //EC_FALSE(scan(hif));
- printf("\n\n");
+ if (scan) EC_FALSE(jtag_scan(hif));
- EC_FALSE(cpu_halt(hif));
- EC_FALSE(cpu_state(hif));
- for (size_t i = 0; i < 20; i++)
+ if (steps > 0)
{
- EC_FALSE(cpu_step(hif));
- EC_FALSE(cpu_state(hif));
+ EC_FALSE(cpu_halt(hif));
+ for (size_t i = 0; i < 20; i++)
+ {
+ EC_FALSE(cpu_step(hif));
+ EC_FALSE(cpu_state(hif));
+ }
}
+ if (halt) EC_FALSE(cpu_halt(hif));
+ if (dump) EC_FALSE(cpu_state(hif));
+ if (run) EC_FALSE(cpu_run(hif));
+
// -------------------------------------------------------------
// Close JTAG session