Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Adjust the JTAG/SWD frequency via cmdline option #953

Merged
merged 3 commits into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ The size may be followed by an optional "k" or "m" to multiply the given value b
When flashing a file, a checksum is calculated for the binary file, both in md5 and the sum algorithm.
The latter is also used by the official ST-Link utility tool from STMicroelectronics as described in the document: [`UM0892 - User manual - STM32 ST-LINK utility software description`](https://www.st.com/resource/en/user_manual/cd00262073-stm32-stlink-utility-software-description-stmicroelectronics.pdf).

#### --freq=n[k][m]

(since v1.6.1)

You can specify the frequency of SWD/JTAG interface, to override the default 1800KHz configuration. This option accpets decimal only (5K or 1.8M). `Hz` is left out in this option. Valid frequencies are `5K, 15K, 25K, 50K, 100K, 125K, 240K, 480K, 950K, 1200K(1.2M), 1800K(1.8M), 4000K(4M)`

#### --opt

(since v1.6.1, optional; enabled by default from v1.0.0 to v1.6.0)

You can enable the optimization to skip flashing empty (0x00 or 0xff) bytes at the end of binary file. May cause some garbage data left after a flash.

## Solutions to common problems
### a) STLINK/v1 driver: Issue with Kernel Extension (kext) (macOS 10.11 and later only)
Expand Down
4 changes: 3 additions & 1 deletion include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,16 @@ typedef struct flash_loader {

// transport layer verboseness: 0 for no debug info, 10 for lots
int verbose;
int opt;
int opt; // set by main() in tools/flash.c, empty tail bytes drop optimization
uint32_t core_id; // set by stlink_core_id(), result from STLINK_DEBUGREADCOREID
uint32_t chip_id; // set by stlink_load_device_params(), used to identify flash and sram
int core_stat; // set by stlink_status(), values STLINK_CORE_xxxxx

char serial[STLINK_SERIAL_MAX_SIZE];
int serial_size;

int freq; // set by stlink_open_usb(), values: STLINK_SWDCLK_xxx_DIVISOR

enum stlink_flash_type flash_type; // stlink_chipid_params.flash_type, set by stlink_load_device_params(), values: STLINK_FLASH_TYPE_xxx
bool has_dual_bank;

Expand Down
5 changes: 3 additions & 2 deletions include/stlink/tools/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ struct flash_opts
enum flash_area area;
uint32_t val;
size_t flash_size; /* --flash=n[k][m] */
int opt;
int opt; /* enable empty tail data drop optimization */
int freq; /* --freq=n[k][m] frequency of JTAG/SWD */
};

#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define FLASH_OPTS_INITIALIZER {0, { 0 }, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

int flash_get_opts(struct flash_opts* o, int ac, char** av);

Expand Down
4 changes: 2 additions & 2 deletions src/st-util/gdb-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ static void cleanup(int signum) {
static stlink_t* do_connect(st_state_t *st) {
stlink_t *sl = NULL;
if (serial_specified) {
sl = stlink_open_usb(st->logging_level, st->reset, serialnumber);
sl = stlink_open_usb(st->logging_level, st->reset, serialnumber, 0);
} else {
sl = stlink_open_usb(st->logging_level, st->reset, NULL);
sl = stlink_open_usb(st->logging_level, st->reset, NULL, 0);
}
return sl;
}
Expand Down
2 changes: 1 addition & 1 deletion src/stlink-gui/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ static void connect_button_cb (GtkWidget *widget, gpointer data) {
/* try version 1 then version 2 */
gui->sl = stlink_v1_open(0, 1);
if (gui->sl == NULL)
gui->sl = stlink_open_usb(0, 1, NULL);
gui->sl = stlink_open_usb(0, 1, NULL, 0);
if (gui->sl == NULL) {
stlink_gui_set_info_error_message (gui, "Failed to connect to STLink.");
return;
Expand Down
8 changes: 4 additions & 4 deletions src/tools/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ static void cleanup(int signum) {

static void usage(void)
{
puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] {read|write} <path> [addr] [size]");
puts("command line: ./st-flash [--debug] [--serial <serial>] erase");
puts("command line: ./st-flash [--debug] [--serial <serial>] reset");
puts("command line: ./st-flash [--debug] [--reset] [--opt] [--serial <serial>] [--format <format>] [--flash=<fsize>] [--freq=<Hz>] {read|write} <path> [addr] [size]");
puts("command line: ./st-flash [--debug] [--freq=<Hz>] [--serial <serial>] erase");
puts("command line: ./st-flash [--debug] [--freq=<Hz>] [--serial <serial>] reset");
Nightwalker-87 marked this conversation as resolved.
Show resolved Hide resolved
puts(" <addr>, <serial> and <size>: Use hex format.");
puts(" <fsize>: Use decimal, octal or hex (prefix 0xXXX) format, optionally followed by k=KB, or m=MB (eg. --flash=128k)");
puts(" <format>: Can be 'binary' (default) or 'ihex', although <addr> must be specified for binary format only.");
Expand All @@ -56,7 +56,7 @@ int main(int ac, char** av)

printf("st-flash %s\n", STLINK_VERSION);

sl = stlink_open_usb(o.log_level, 1, (char *)o.serial);
sl = stlink_open_usb(o.log_level, 1, (char *)o.serial, o.freq);

if (sl == NULL) {
return -1;
Expand Down
50 changes: 50 additions & 0 deletions src/tools/flash_opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,56 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) {
return -1;

}
else if (strcmp(av[0], "--freq") == 0 || starts_with(av[0], "--freq=")) {
const char* freq;
if (strcmp(av[0], "--freq") == 0) {
ac--;
av++;
if (ac < 1) return -1;
freq = av[0];
}
else {
freq = av[0] + strlen("--freq=");
}
if (strcmp(freq, "5K") == 0 || strcmp(freq, "5k") == 0) {
o->freq = 5;
}
else if (strcmp(freq, "15K") == 0 || strcmp(freq, "15k") == 0) {
o->freq = 15;
}
else if (strcmp(freq, "25K") == 0 || strcmp(freq, "25k") == 0) {
o->freq = 25;
}
else if (strcmp(freq, "50K") == 0 || strcmp(freq, "50k") == 0) {
o->freq = 50;
}
else if (strcmp(freq, "100K") == 0 || strcmp(freq, "100k") == 0) {
o->freq = 100;
}
else if (strcmp(freq, "125K") == 0 || strcmp(freq, "125k") == 0) {
o->freq = 125;
}
else if (strcmp(freq, "240K") == 0 || strcmp(freq, "240k") == 0) {
o->freq = 240;
}
else if (strcmp(freq, "480K") == 0 || strcmp(freq, "480k") == 0) {
o->freq = 480;
}
else if (strcmp(freq, "950K") == 0 || strcmp(freq, "950k") == 0) {
o->freq = 950;
}
else if (strcmp(freq, "1200K") == 0 || strcmp(freq, "1200k") == 0 || strcmp(freq, "1.2M") == 0 || strcmp(freq, "1.2m") == 0) {
o->freq = 1200;
}
else if (strcmp(freq, "1800K") == 0 || strcmp(freq, "1800k") == 0 || strcmp(freq, "1.8M") == 0 || strcmp(freq, "1.8m") == 0) {
o->freq = 1800;
}
else if (strcmp(freq, "4000K") == 0 || strcmp(freq, "4000k") == 0 || strcmp(freq, "4M") == 0 || strcmp(freq, "4m") == 0) {
o->freq = 4000;
}
else
return -1;
}
else if (strcmp(av[0], "--format") == 0 || starts_with(av[0], "--format=")) {
const char * format;
if (strcmp(av[0], "--format") == 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static stlink_t *stlink_open_first(void)
stlink_t* sl = NULL;
sl = stlink_v1_open(0, 1);
if (sl == NULL)
sl = stlink_open_usb(0, 1, NULL);
sl = stlink_open_usb(0, 1, NULL, 0);

return sl;
}
Expand Down
47 changes: 44 additions & 3 deletions src/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ static stlink_backend_t _stlink_usb_backend = {
_stlink_usb_set_swdclk
};

stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE])
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq)
{
stlink_t* sl = NULL;
struct stlink_libusb* slu = NULL;
Expand Down Expand Up @@ -1041,10 +1041,51 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[ST
stlink_exit_dfu_mode(sl);
}


sl->freq = freq;
// set the speed before entering the mode
// as the chip discovery phase should be done at this speed too
// Set the stlink clock speed (default is 1800kHz)
stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR);
DLOG("JTAG/SWD freq set to %d\n", freq);
switch (freq) {
case 5:
stlink_set_swdclk(sl, STLINK_SWDCLK_5KHZ_DIVISOR);
break;
case 15:
stlink_set_swdclk(sl, STLINK_SWDCLK_15KHZ_DIVISOR);
break;
case 25:
stlink_set_swdclk(sl, STLINK_SWDCLK_25KHZ_DIVISOR);
break;
case 50:
stlink_set_swdclk(sl, STLINK_SWDCLK_50KHZ_DIVISOR);
break;
case 100:
stlink_set_swdclk(sl, STLINK_SWDCLK_100KHZ_DIVISOR);
break;
case 125:
stlink_set_swdclk(sl, STLINK_SWDCLK_125KHZ_DIVISOR);
break;
case 240:
stlink_set_swdclk(sl, STLINK_SWDCLK_240KHZ_DIVISOR);
break;
case 480:
stlink_set_swdclk(sl, STLINK_SWDCLK_480KHZ_DIVISOR);
break;
case 950:
stlink_set_swdclk(sl, STLINK_SWDCLK_950KHZ_DIVISOR);
break;
case 1200:
stlink_set_swdclk(sl, STLINK_SWDCLK_1P2MHZ_DIVISOR);
break;
case 0: case 1800:
stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR);
break;
case 4000:
stlink_set_swdclk(sl, STLINK_SWDCLK_4MHZ_DIVISOR);
break;
}


if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
stlink_enter_swd_mode(sl);
Expand Down Expand Up @@ -1147,7 +1188,7 @@ static size_t stlink_probe_usb_devs(libusb_device **devs, stlink_t **sldevs[]) {
continue;
}

stlink_t *sl = stlink_open_usb(0, 1, serial);
stlink_t *sl = stlink_open_usb(0, 1, serial, 0);
if (!sl) {
ELOG("Failed to open USB device %#06x:%#06x\n", desc.idVendor, desc.idProduct);
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ extern "C" {
* @retval NULL Error while opening the stlink
* @retval !NULL Stlink found and ready to use
*/
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE]);
stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[STLINK_SERIAL_MAX_SIZE], int freq);
size_t stlink_probe_usb(stlink_t **stdevs[]);
void stlink_probe_usb_free(stlink_t **stdevs[], size_t size);

Expand Down
55 changes: 55 additions & 0 deletions tests/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static bool execute_test(const struct Test * test) {
ret &= (opts.size == test->opts.size);
ret &= (opts.reset == test->opts.reset);
ret &= (opts.log_level == test->opts.log_level);
ret &= (opts.freq == test->opts.freq);
ret &= (opts.format == test->opts.format);
}

Expand All @@ -83,6 +84,7 @@ static struct Test tests[] = {
.size = 0x1000,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset write test.bin 0x80000000", 0,
Expand All @@ -93,6 +95,51 @@ static struct Test tests[] = {
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --freq 5k --reset write test.bin 0x80000000", 0,
{ .cmd = FLASH_CMD_WRITE,
.serial = { 0 },
.filename = "test.bin",
.addr = 0x80000000,
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 5,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --freq 15K --reset write test.bin 0x80000000", 0,
{ .cmd = FLASH_CMD_WRITE,
.serial = { 0 },
.filename = "test.bin",
.addr = 0x80000000,
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 15,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --freq=5k --reset write test.bin 0x80000000", 0,
{ .cmd = FLASH_CMD_WRITE,
.serial = { 0 },
.filename = "test.bin",
.addr = 0x80000000,
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 5,
.format = FLASH_FORMAT_BINARY }
},
Nightwalker-87 marked this conversation as resolved.
Show resolved Hide resolved
{ "--debug --freq=6k --reset write test.bin 0x80000000", -1,
{ .cmd = FLASH_CMD_WRITE,
.serial = { 0 },
.filename = "test.bin",
.addr = 0x80000000,
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 6,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset read test.bin 0x80000000 1000", 0,
Expand All @@ -103,6 +150,7 @@ static struct Test tests[] = {
.size = 1000,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset read test.bin 0x80000000 1k", 0,
Expand All @@ -113,6 +161,7 @@ static struct Test tests[] = {
.size = 1024,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset read test.bin 0x80000000 1M", 0,
Expand All @@ -123,6 +172,7 @@ static struct Test tests[] = {
.size = 1048576,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset write test.bin 0x80000000", 0,
Expand All @@ -133,6 +183,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "erase", 0,
Expand All @@ -143,6 +194,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 0,
.log_level = STND_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--debug --reset --format=ihex write test.hex", 0,
Expand All @@ -153,6 +205,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 1,
.log_level = DEBUG_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_IHEX }
},
{ "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER },
Expand All @@ -167,6 +220,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 0,
.log_level = STND_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
{ "--serial=A1020304 erase", 0,
Expand All @@ -177,6 +231,7 @@ static struct Test tests[] = {
.size = 0,
.reset = 0,
.log_level = STND_LOG_LEVEL,
.freq = 0,
.format = FLASH_FORMAT_BINARY }
},
};
Expand Down
2 changes: 1 addition & 1 deletion tests/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int main(int ac, char** av) {
stlink_t* sl;
struct stlink_reg regs;

sl = stlink_open_usb(10, 1, NULL);
sl = stlink_open_usb(10, 1, NULL, 0);
if (sl != NULL) {
printf("-- version\n");
stlink_version(sl);
Expand Down