From 92888956f34f312c6ea2e6b7d91c8822f25b73b6 Mon Sep 17 00:00:00 2001 From: Martin Pittermann Date: Thu, 21 May 2020 13:06:02 +0200 Subject: [PATCH 1/3] add jtag frequency option --- README.md | 1 + src/main.cpp | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ccfe318..09cbb5c 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,7 @@ openFPGALoader -- a program to flash cyclone10 LP FPGA Gowin and ECP5 devices) -o, --offset=OFFSET start offset in EEPROM -r, --reset reset FPGA after operations + -s, --speed=SPEED jtag frequency (Hz) -v, --verbose Produce verbose output -?, --help Give this help list --usage Give a short usage message diff --git a/src/main.cpp b/src/main.cpp index 13945b6..7f7e4e7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ struct arguments { string bit_file; string device; string cable; + string speed; string board; bool list_cables; bool list_boards; @@ -64,6 +65,7 @@ static char args_doc[] = "BIT_FILE"; static error_t parse_opt(int key, char *arg, struct argp_state *state); static struct argp_option options[] = { {"cable", 'c', "CABLE", 0, "jtag interface"}, + {"speed", 's', "SPEED", 0, "jtag frequency (Hz)"}, {"list-cables", LIST_CABLE, 0, 0, "list all supported cables"}, {"board", 'b', "BOARD", 0, "board name, may be used instead of cable"}, {"list-boards", LIST_BOARD, 0, 0, "list all supported boards"}, @@ -91,7 +93,7 @@ int main(int argc, char **argv) jtag_pins_conf_t *pins_config = NULL; /* command line args. */ - struct arguments args = {false, false, false, 0, "", "-", "-", "-", + struct arguments args = {false, false, false, 0, "", "-", "-", "6M", "-", false, false, false, false, true, false}; /* parse arguments */ argp_parse(&argp, argc, argv, 0, 0, &args); @@ -127,12 +129,39 @@ int main(int argc, char **argv) } cable = select_cable->second; + uint32_t speed; + try { + size_t end; + float speed_base = stof(args.speed, &end); + if (end == args.speed.size()) { + speed = (uint32_t)speed_base; + } else if (end == (args.speed.size() - 1)) { + switch (args.speed.back()) { + case 'k': case 'K': + speed = (uint32_t)(1e3 * speed_base); + break; + case 'm': case 'M': + speed = (uint32_t)(1e6 * speed_base); + break; + default: + cerr << "error : speed: invaild postfix \"" << args.speed.back() << "\"" << endl; + return EXIT_FAILURE; + } + } else { + cerr << "error : speed: invaild postfix \"" << args.speed.substr(end) << "\"" << endl; + return EXIT_FAILURE; + } + } catch (...) { + cerr << "error : speed: invaild format" << endl; + return EXIT_FAILURE; + } + /* jtag base */ Jtag *jtag; if (args.device == "-") - jtag = new Jtag(cable, pins_config, 6000000, false); + jtag = new Jtag(cable, pins_config, speed, false); else - jtag = new Jtag(cable, pins_config, args.device, 6000000, false); + jtag = new Jtag(cable, pins_config, args.device, speed, false); /* chain detection */ vector listDev; @@ -235,6 +264,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) case 'b': arguments->board = arg; break; + case 's': + arguments->speed = arg; + break; case ARGP_KEY_ARG: arguments->bit_file = arg; break; From e93034db692876d7b34b8e3c6e19350f9d1e1f98 Mon Sep 17 00:00:00 2001 From: Martin Pittermann Date: Mon, 25 May 2020 10:31:37 +0200 Subject: [PATCH 2/3] clean up --freq parser --- src/main.cpp | 80 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7f7e4e7..3cf5cbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,7 @@ struct arguments { string bit_file; string device; string cable; - string speed; + uint32_t freq; string board; bool list_cables; bool list_boards; @@ -57,6 +57,7 @@ struct arguments { #define LIST_BOARD 2 #define LIST_FPGA 3 #define DETECT 4 +#define FREQUENCY 5 const char *argp_program_version = "openFPGALoader 1.0"; const char *argp_program_bug_address = ""; @@ -65,7 +66,7 @@ static char args_doc[] = "BIT_FILE"; static error_t parse_opt(int key, char *arg, struct argp_state *state); static struct argp_option options[] = { {"cable", 'c', "CABLE", 0, "jtag interface"}, - {"speed", 's', "SPEED", 0, "jtag frequency (Hz)"}, + {"freq", FREQUENCY, "FREQ", 0, "jtag frequency (Hz)"}, {"list-cables", LIST_CABLE, 0, 0, "list all supported cables"}, {"board", 'b', "BOARD", 0, "board name, may be used instead of cable"}, {"list-boards", LIST_BOARD, 0, 0, "list all supported boards"}, @@ -93,7 +94,7 @@ int main(int argc, char **argv) jtag_pins_conf_t *pins_config = NULL; /* command line args. */ - struct arguments args = {false, false, false, 0, "", "-", "-", "6M", "-", + struct arguments args = {false, false, false, 0, "", "-", "-", 6000000, "-", false, false, false, false, true, false}; /* parse arguments */ argp_parse(&argp, argc, argv, 0, 0, &args); @@ -129,39 +130,12 @@ int main(int argc, char **argv) } cable = select_cable->second; - uint32_t speed; - try { - size_t end; - float speed_base = stof(args.speed, &end); - if (end == args.speed.size()) { - speed = (uint32_t)speed_base; - } else if (end == (args.speed.size() - 1)) { - switch (args.speed.back()) { - case 'k': case 'K': - speed = (uint32_t)(1e3 * speed_base); - break; - case 'm': case 'M': - speed = (uint32_t)(1e6 * speed_base); - break; - default: - cerr << "error : speed: invaild postfix \"" << args.speed.back() << "\"" << endl; - return EXIT_FAILURE; - } - } else { - cerr << "error : speed: invaild postfix \"" << args.speed.substr(end) << "\"" << endl; - return EXIT_FAILURE; - } - } catch (...) { - cerr << "error : speed: invaild format" << endl; - return EXIT_FAILURE; - } - /* jtag base */ Jtag *jtag; if (args.device == "-") - jtag = new Jtag(cable, pins_config, speed, false); + jtag = new Jtag(cable, pins_config, args.freq, false); else - jtag = new Jtag(cable, pins_config, args.device, speed, false); + jtag = new Jtag(cable, pins_config, args.device, args.freq, false); /* chain detection */ vector listDev; @@ -231,6 +205,35 @@ int main(int argc, char **argv) delete(jtag); } +// parse double from string in enginerring notation +// can deal with postfixes k and m, add more when required +static error_t parse_eng(string arg, double *dst) { + try { + size_t end; + double base = stod(arg, &end); + if (end == arg.size()) { + *dst = base; + return 0; + } else if (end == (arg.size() - 1)) { + switch (arg.back()) { + case 'k': case 'K': + *dst = (uint32_t)(1e3 * base); + return 0; + case 'm': case 'M': + *dst = (uint32_t)(1e6 * base); + return 0; + default: + return EINVAL; + } + } else { + return EINVAL; + } + } catch (...) { + cerr << "error : speed: invaild format" << endl; + return EINVAL; + } +} + /* arguments parser */ static error_t parse_opt(int key, char *arg, struct argp_state *state) { @@ -264,8 +267,17 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) case 'b': arguments->board = arg; break; - case 's': - arguments->speed = arg; + case FREQUENCY: + double freq; + if (parse_eng(string(arg), &freq)) { + cerr << "Error: invalid format for --freq" << endl; + exit(1); + } + if (freq < 1) { + cerr << "Error: --freq must be positive" << endl; + exit(1); + } + arguments->freq = freq; break; case ARGP_KEY_ARG: arguments->bit_file = arg; From c6385e5a50e0fda62a2fc976b32bff7d4447ad63 Mon Sep 17 00:00:00 2001 From: Martin Pittermann Date: Mon, 25 May 2020 23:18:42 +0200 Subject: [PATCH 3/3] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 09cbb5c..5e63654 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ openFPGALoader -- a program to flash cyclone10 LP FPGA -c, --cable=CABLE jtag interface -d, --device=DEVICE device to use (/dev/ttyUSBx) --detect detect FPGA + --freq=FREQ jtag frequency (Hz) -f, --write-flash write bitstream in flash (default: false, only for Gowin and ECP5 devices) --list-boards list all supported boards @@ -104,7 +105,6 @@ openFPGALoader -- a program to flash cyclone10 LP FPGA Gowin and ECP5 devices) -o, --offset=OFFSET start offset in EEPROM -r, --reset reset FPGA after operations - -s, --speed=SPEED jtag frequency (Hz) -v, --verbose Produce verbose output -?, --help Give this help list --usage Give a short usage message