Skip to content

Commit

Permalink
Set SWDCLK and fix jtag_reset bug (#534)
Browse files Browse the repository at this point in the history
* - Fixed bug where stlink_jtag_reset in stlink_open_usb() was never being called because the STLINK version was being checked before it had been initialized
- Added support for stlink_set_swdclk() to adjust the SWD clock speed.  For example, to set at 4Mhz, 1.8Mhz, 900Khz, etc similar to in the official ST-LINK utility.  NOTE: The default when STLINK is powered appears to be 1.8Mhz (looked at scope traces) but it retains whatever was set before.

* Fixed tab->space
  • Loading branch information
jkhax0r authored and xor-gate committed Dec 30, 2016
1 parent ecc31f7 commit c441824
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 2 deletions.
19 changes: 19 additions & 0 deletions include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ extern "C" {
#define STLINK_JTAG_READDEBUG_32BIT 0x36
#define STLINK_JTAG_DRIVE_NRST 0x3c

#define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43

/* cortex core ids */
// TODO clean this up...
#define STM32VL_CORE_ID 0x1ba01477
Expand All @@ -57,6 +59,22 @@ extern "C" {
#define STM32_FLASH_BASE 0x08000000
#define STM32_SRAM_BASE 0x20000000

// Baud rate divisors for SWDCLK
#define STLINK_SWDCLK_4MHZ_DIVISOR 0
#define STLINK_SWDCLK_1P8MHZ_DIVISOR 1
#define STLINK_SWDCLK_1P2MHZ_DIVISOR 2
#define STLINK_SWDCLK_950KHZ_DIVISOR 3
#define STLINK_SWDCLK_480KHZ_DIVISOR 7
#define STLINK_SWDCLK_240KHZ_DIVISOR 15
#define STLINK_SWDCLK_125KHZ_DIVISOR 31
#define STLINK_SWDCLK_100KHZ_DIVISOR 40
#define STLINK_SWDCLK_50KHZ_DIVISOR 79
#define STLINK_SWDCLK_25KHZ_DIVISOR 158
#define STLINK_SWDCLK_15KHZ_DIVISOR 265
#define STLINK_SWDCLK_5KHZ_DIVISOR 798



/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/
#define C_BUF_LEN 32

Expand Down Expand Up @@ -177,6 +195,7 @@ typedef struct flash_loader {
int stlink_current_mode(stlink_t *sl);
int stlink_force_debug(stlink_t *sl);
int stlink_target_voltage(stlink_t *sl);
int stlink_set_swdclk(stlink_t *sl, uint16_t divisor);

int stlink_erase_flash_mass(stlink_t* sl);
int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, uint32_t length, uint8_t eraseonly);
Expand Down
1 change: 1 addition & 0 deletions include/stlink/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
int (*current_mode) (stlink_t * stl);
int (*force_debug) (stlink_t *sl);
int32_t (*target_voltage) (stlink_t *sl);
int (*set_swdclk) (stlink_t * stl, uint16_t divisor);
} stlink_backend_t;

#endif /* STLINK_BACKEND_H_ */
5 changes: 5 additions & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,11 @@ int stlink_run(stlink_t *sl) {
return sl->backend->run(sl);
}

int stlink_set_swdclk(stlink_t *sl, uint16_t divisor) {
DLOG("*** set_swdclk ***\n");
return sl->backend->set_swdclk(sl, divisor);
}

int stlink_status(stlink_t *sl) {
int ret;

Expand Down
40 changes: 38 additions & 2 deletions src/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,36 @@ int _stlink_usb_run(stlink_t* sl) {
return 0;
}


int _stlink_usb_set_swdclk(stlink_t* sl, uint16_t clk_divisor) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const data = sl->q_buf;
unsigned char* const cmd = sl->c_buf;
ssize_t size;
int rep_len = 2;
int i;

// clock speed only supported by stlink/v2 and for firmware >= 22
if (sl->version.stlink_v >= 2 && sl->version.jtag_v >= 22) {
i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len);

cmd[i++] = STLINK_DEBUG_COMMAND;
cmd[i++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ;
cmd[i++] = clk_divisor & 0xFF;
cmd[i++] = (clk_divisor >> 8) & 0xFF;

size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len);
if (size == -1) {
printf("[!] send_recv STLINK_DEBUG_APIV2_SWD_SET_FREQ\n");
return (int) size;
}

return 0;
} else {
return -1;
}
}

int _stlink_usb_exit_debug_mode(stlink_t *sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const cmd = sl->c_buf;
Expand Down Expand Up @@ -724,7 +754,8 @@ static stlink_backend_t _stlink_usb_backend = {
_stlink_usb_step,
_stlink_usb_current_mode,
_stlink_usb_force_debug,
_stlink_usb_target_voltage
_stlink_usb_target_voltage,
_stlink_usb_set_swdclk
};

stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16])
Expand Down Expand Up @@ -878,16 +909,21 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
stlink_enter_swd_mode(sl);
}

// Initialize stlink version (sl->version)
stlink_version(sl);

if (reset) {
if( sl->version.stlink_v > 1 ) stlink_jtag_reset(sl, 2);
stlink_reset(sl);
usleep(10000);
}

stlink_version(sl);
ret = stlink_load_device_params(sl);

// Set the stlink clock speed (default is 1800kHz)
stlink_set_swdclk(sl, STLINK_SWDCLK_1P8MHZ_DIVISOR);

on_libusb_error:
if (ret == -1) {
stlink_close(sl);
Expand Down

0 comments on commit c441824

Please sign in to comment.