Set SWDCLK and fix jtag_reset bug (#534)

* - 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
pull/538/head
jkhax0r 2016-12-30 05:00:27 -06:00 zatwierdzone przez Jerry Jacobs
rodzic ecc31f764d
commit c44182465a
4 zmienionych plików z 63 dodań i 2 usunięć

Wyświetl plik

@ -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
@ -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
@ -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);

Wyświetl plik

@ -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_ */

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;
@ -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])
@ -878,6 +909,9 @@ 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);
@ -885,9 +919,11 @@ stlink_t *stlink_open_usb(enum ugly_loglevel verbose, bool reset, char serial[16
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);