commit
e8bd066fe9
|
@ -59,7 +59,7 @@ static bool cmd_target_power(target *t, int argc, const char **argv);
|
||||||
#ifdef PLATFORM_HAS_TRACESWO
|
#ifdef PLATFORM_HAS_TRACESWO
|
||||||
static bool cmd_traceswo(target *t, int argc, const char **argv);
|
static bool cmd_traceswo(target *t, int argc, const char **argv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PLATFORM_HAS_DEBUG
|
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
||||||
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
|
static bool cmd_debug_bmp(target *t, int argc, const char **argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ const struct command_s cmd_list[] = {
|
||||||
#ifdef PLATFORM_HAS_TRACESWO
|
#ifdef PLATFORM_HAS_TRACESWO
|
||||||
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture [(baudrate) for async swo]" },
|
{"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture [(baudrate) for async swo]" },
|
||||||
#endif
|
#endif
|
||||||
#ifdef PLATFORM_HAS_DEBUG
|
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
||||||
{"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"},
|
{"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"},
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
|
@ -124,7 +124,12 @@ int command_process(target *t, char *cmd)
|
||||||
|
|
||||||
bool cmd_version(void)
|
bool cmd_version(void)
|
||||||
{
|
{
|
||||||
|
#if defined PC_HOSTED
|
||||||
|
gdb_outf("Black Magic Probe, PC-Hosted for " PLATFORM_IDENT
|
||||||
|
", Version " FIRMWARE_VERSION "\n");
|
||||||
|
#else
|
||||||
gdb_outf("Black Magic Probe (Firmware " FIRMWARE_VERSION ") (Hardware Version %d)\n", platform_hwversion());
|
gdb_outf("Black Magic Probe (Firmware " FIRMWARE_VERSION ") (Hardware Version %d)\n", platform_hwversion());
|
||||||
|
#endif
|
||||||
gdb_out("Copyright (C) 2015 Black Sphere Technologies Ltd.\n");
|
gdb_out("Copyright (C) 2015 Black Sphere Technologies Ltd.\n");
|
||||||
gdb_out("License GPLv3+: GNU GPL version 3 or later "
|
gdb_out("License GPLv3+: GNU GPL version 3 or later "
|
||||||
"<http://gnu.org/licenses/gpl.html>\n\n");
|
"<http://gnu.org/licenses/gpl.html>\n\n");
|
||||||
|
@ -344,7 +349,7 @@ static bool cmd_traceswo(target *t, int argc, const char **argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PLATFORM_HAS_DEBUG
|
#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED)
|
||||||
static bool cmd_debug_bmp(target *t, int argc, const char **argv)
|
static bool cmd_debug_bmp(target *t, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
(void)t;
|
(void)t;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#define PLATFORM_HAS_DEBUG
|
#define PLATFORM_HAS_DEBUG
|
||||||
|
|
||||||
|
#define PLATFORM_IDENT "FTDI/MPSSE"
|
||||||
#define SET_RUN_STATE(state)
|
#define SET_RUN_STATE(state)
|
||||||
#define SET_IDLE_STATE(state)
|
#define SET_IDLE_STATE(state)
|
||||||
#define SET_ERROR_STATE(state)
|
#define SET_ERROR_STATE(state)
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#define PLATFORM_HAS_DEBUG
|
#define PLATFORM_HAS_DEBUG
|
||||||
|
|
||||||
|
#define PLATFORM_IDENT "StlinkV2/3"
|
||||||
#define SET_RUN_STATE(state)
|
#define SET_RUN_STATE(state)
|
||||||
#define SET_IDLE_STATE(state)
|
#define SET_IDLE_STATE(state)
|
||||||
//#define SET_ERROR_STATE(state)
|
//#define SET_ERROR_STATE(state)
|
||||||
|
|
|
@ -800,10 +800,23 @@ void stlink_init(int argc, char **argv)
|
||||||
Stlink.req_trans = libusb_alloc_transfer(0);
|
Stlink.req_trans = libusb_alloc_transfer(0);
|
||||||
Stlink.rep_trans = libusb_alloc_transfer(0);
|
Stlink.rep_trans = libusb_alloc_transfer(0);
|
||||||
stlink_version();
|
stlink_version();
|
||||||
if (Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) {
|
if ((Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) ||
|
||||||
DEBUG("Please update Firmware\n");
|
(Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3)) {
|
||||||
|
/* Maybe the adapter is in some strange state. Try to reset */
|
||||||
|
int result = libusb_reset_device(Stlink.handle);
|
||||||
|
DEBUG("Trying reset\n");
|
||||||
|
if (result == LIBUSB_ERROR_BUSY) { /* Try again */
|
||||||
|
platform_delay(50);
|
||||||
|
result = libusb_reset_device(Stlink.handle);
|
||||||
|
}
|
||||||
|
if (result != LIBUSB_SUCCESS) {
|
||||||
|
DEBUG("libusb_reset_device failed\n");
|
||||||
goto error_1;
|
goto error_1;
|
||||||
} else if (Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3) {
|
}
|
||||||
|
stlink_version();
|
||||||
|
}
|
||||||
|
if ((Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) ||
|
||||||
|
(Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3)) {
|
||||||
DEBUG("Please update Firmware\n");
|
DEBUG("Please update Firmware\n");
|
||||||
goto error_1;
|
goto error_1;
|
||||||
}
|
}
|
||||||
|
@ -1095,6 +1108,7 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
size_t read_len = len;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
char *CMD;
|
char *CMD;
|
||||||
if (src & 1 || len & 1) {
|
if (src & 1 || len & 1) {
|
||||||
|
@ -1104,6 +1118,8 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||||
DEBUG(" Too large!\n");
|
DEBUG(" Too large!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (len == 1)
|
||||||
|
read_len ++; /* Fix read length as in openocd*/
|
||||||
} else if (src & 3 || len & 3) {
|
} else if (src & 3 || len & 3) {
|
||||||
CMD = "READMEM_16BIT";
|
CMD = "READMEM_16BIT";
|
||||||
type = STLINK_DEBUG_APIV2_READMEM_16BIT;
|
type = STLINK_DEBUG_APIV2_READMEM_16BIT;
|
||||||
|
@ -1120,7 +1136,7 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len)
|
||||||
src & 0xff, (src >> 8) & 0xff, (src >> 16) & 0xff,
|
src & 0xff, (src >> 8) & 0xff, (src >> 16) & 0xff,
|
||||||
(src >> 24) & 0xff,
|
(src >> 24) & 0xff,
|
||||||
len & 0xff, len >> 8, ap->apsel};
|
len & 0xff, len >> 8, ap->apsel};
|
||||||
int res = read_retry(cmd, 16, dest, len);
|
int res = read_retry(cmd, 16, dest, read_len);
|
||||||
if (res == STLINK_ERROR_OK) {
|
if (res == STLINK_ERROR_OK) {
|
||||||
uint8_t *p = (uint8_t*)dest;
|
uint8_t *p = (uint8_t*)dest;
|
||||||
for (size_t i = 0; i < len ; i++) {
|
for (size_t i = 0; i < len ; i++) {
|
||||||
|
@ -1197,37 +1213,40 @@ void stlink_writemem32(ADIv5_AP_t *ap, uint32_t addr, size_t len,
|
||||||
write_retry(cmd, 16, (void*)buffer, len);
|
write_retry(cmd, 16, (void*)buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stlink_regs_read(void *data)
|
void stlink_regs_read(ADIv5_AP_t *ap, void *data)
|
||||||
{
|
{
|
||||||
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READALLREGS};
|
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READALLREGS,
|
||||||
|
ap->apsel};
|
||||||
uint8_t res[88];
|
uint8_t res[88];
|
||||||
DEBUG_STLINK("Read all core registers\n");
|
DEBUG_STLINK("AP %d: Read all core registers\n", ap->apsel);
|
||||||
send_recv(cmd, 16, res, 88);
|
send_recv(cmd, 16, res, 88);
|
||||||
stlink_usb_error_check(res, true);
|
stlink_usb_error_check(res, true);
|
||||||
memcpy(data, res + 4, 84);
|
memcpy(data, res + 4, 84);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t stlink_reg_read(int num)
|
uint32_t stlink_reg_read(ADIv5_AP_t *ap, int num)
|
||||||
{
|
{
|
||||||
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READREG, num};
|
uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READREG, num,
|
||||||
|
ap->apsel};
|
||||||
uint8_t res[8];
|
uint8_t res[8];
|
||||||
send_recv(cmd, 16, res, 8);
|
send_recv(cmd, 16, res, 8);
|
||||||
stlink_usb_error_check(res, true);
|
stlink_usb_error_check(res, true);
|
||||||
uint32_t ret = res[0] | res[1] << 8 | res[2] << 16 | res[3] << 24;
|
uint32_t ret = res[0] | res[1] << 8 | res[2] << 16 | res[3] << 24;
|
||||||
DEBUG_STLINK("Read reg %02" PRId32 " val 0x%08" PRIx32 "\n", num, ret);
|
DEBUG_STLINK("AP %d: Read reg %02" PRId32 " val 0x%08" PRIx32 "\n",
|
||||||
|
ap->apsel, num, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stlink_reg_write(int num, uint32_t val)
|
void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val)
|
||||||
{
|
{
|
||||||
uint8_t cmd[16] = {
|
uint8_t cmd[16] = {
|
||||||
STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_WRITEREG, num,
|
STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_WRITEREG, num,
|
||||||
val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff,
|
val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff,
|
||||||
(val >> 24) & 0xff
|
(val >> 24) & 0xff, ap->apsel};
|
||||||
};
|
|
||||||
uint8_t res[2];
|
uint8_t res[2];
|
||||||
send_recv(cmd, 16, res, 2);
|
send_recv(cmd, 16, res, 2);
|
||||||
DEBUG_STLINK("Write reg %02" PRId32 " val 0x%08" PRIx32 "\n", num, val);
|
DEBUG_STLINK("AP %d: Write reg %02" PRId32 " val 0x%08" PRIx32 "\n",
|
||||||
|
ap->apsel, num, val);
|
||||||
stlink_usb_error_check(res, true);
|
stlink_usb_error_check(res, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,9 @@ void stlink_dp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||||
int stlink_open_ap(uint8_t ap);
|
int stlink_open_ap(uint8_t ap);
|
||||||
void stlink_close_ap(uint8_t ap);
|
void stlink_close_ap(uint8_t ap);
|
||||||
int stlink_usb_get_rw_status(void);
|
int stlink_usb_get_rw_status(void);
|
||||||
void stlink_regs_read(void *data);
|
void stlink_regs_read(ADIv5_AP_t *ap, void *data);
|
||||||
uint32_t stlink_reg_read(int idx);
|
uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx);
|
||||||
void stlink_reg_write(int num, uint32_t val);
|
void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val);
|
||||||
extern int debug_level;
|
extern int debug_level;
|
||||||
# define DEBUG_STLINK if (debug_level > 0) printf
|
# define DEBUG_STLINK if (debug_level > 0) printf
|
||||||
# define DEBUG_USB if (debug_level > 1) printf
|
# define DEBUG_USB if (debug_level > 1) printf
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Blackmagic for ST -Link Adapters
|
||||||
|
|
||||||
|
For STlinkV3 and StlinkV2/1, as found on all Nucleo and recent Discovery
|
||||||
|
boards, use the pc-stlinkv2 branch, running on the PC and with original,
|
||||||
|
recent ST firmware.
|
||||||
|
|
||||||
|
Only if you have a Stlinkv2 with STM32F103C8 versus the STM32F103CB on V2/1
|
||||||
|
and you want to rewire and use the UART, consider reflashing the the Stlink
|
||||||
|
firmware.
|
||||||
|
|
||||||
|
## Versions
|
||||||
|
|
||||||
|
### [Standalone ST-LINKV2
|
||||||
|
](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/st-link-v2.html)
|
||||||
|
Accessible connectors for JTAG/SWD (20-pin) and SWIM.
|
||||||
|
ST-LINKV2/ISOL).
|
||||||
|
### ST-LINKV2 clones aka "baite"
|
||||||
|
JTAG/SWD/SWIM are on a 10-pin connector. CPU SWD pins are accessible on the
|
||||||
|
board.
|
||||||
|
### SWIM-only ST-LINK adapters on STM8 Discovery boards
|
||||||
|
JTAG and target SWIM pins are accessible on connector (footprints). They are handled in the swlink branch.
|
||||||
|
### SWIM-only ST-LINK adapters on STM8 Nucleo-Stm8 boards
|
||||||
|
As only a SWIM connector is accessible, they are not usefull as BMP target.
|
||||||
|
### [SWD only ST-LINK adapter
|
||||||
|
](https://www.st.com/content/ccc/resource/technical/document/technical_note/group0/30/c8/1d/0f/15/62/46/ef/DM00290229/files/DM00290229.pdf/jcr:content/translations/en.DM00290229.pdf)
|
||||||
|
SWD, SWO and Reset are accessible on a 6-pin connector row.
|
||||||
|
Jumper allow to route SWD to on-board target or off-board.
|
||||||
|
Newer variants have UART TX/RX accessible on a connector
|
||||||
|
According to on-board target variant, some signals have open (resistor) jumper between debugger and target.
|
||||||
|
Newer variants have transistor for USB reenumeration
|
||||||
|
Newer variants may switch onboard target power.
|
||||||
|
Newer Variants may have level shifters for some signals to onboard target.
|
||||||
|
#### ST-Link/V1
|
||||||
|
CDCACM USART pins are not accessible. MCO output is used for LED.
|
||||||
|
#### ST-Link/V2 and ST-Link/V2-A
|
||||||
|
CDCACM USART pins are not accessible. MCO is connected to on board target.
|
||||||
|
#### ST-Link/V2-1 and ST-Link/V2-B
|
||||||
|
### [STLINK-V3SET
|
||||||
|
](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/stlink-v3set.html)
|
||||||
|
|
||||||
|
## BMP version detection and handling
|
||||||
|
All stlink variants
|
||||||
|
PC13/14 open -> Standalone ST-LINKV2 or baite, some STM32 Disco w/o accessible
|
||||||
|
UART RX/TX
|
||||||
|
|
||||||
|
PC13 low -> SWIM internal connection
|
||||||
|
|
|
@ -450,16 +450,16 @@ enum { DB_DHCSR, DB_DCRSR, DB_DCRDR, DB_DEMCR };
|
||||||
static void cortexm_regs_read(target *t, void *data)
|
static void cortexm_regs_read(target *t, void *data)
|
||||||
{
|
{
|
||||||
uint32_t *regs = data;
|
uint32_t *regs = data;
|
||||||
|
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||||
#if defined(STLINKV2)
|
#if defined(STLINKV2)
|
||||||
extern void stlink_regs_read(void *data);
|
extern void stlink_regs_read(ADIv5_AP_t *ap, void *data);
|
||||||
extern uint32_t stlink_reg_read(int idx);
|
extern uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx);
|
||||||
stlink_regs_read(data);
|
stlink_regs_read(ap, data);
|
||||||
regs += sizeof(regnum_cortex_m);
|
regs += sizeof(regnum_cortex_m);
|
||||||
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
||||||
for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++)
|
for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++)
|
||||||
*regs++ = stlink_reg_read(regnum_cortex_mf[t]);
|
*regs++ = stlink_reg_read(ap, regnum_cortex_mf[t]);
|
||||||
#else
|
#else
|
||||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* FIXME: Describe what's really going on here */
|
/* FIXME: Describe what's really going on here */
|
||||||
|
@ -491,19 +491,19 @@ static void cortexm_regs_read(target *t, void *data)
|
||||||
static void cortexm_regs_write(target *t, const void *data)
|
static void cortexm_regs_write(target *t, const void *data)
|
||||||
{
|
{
|
||||||
const uint32_t *regs = data;
|
const uint32_t *regs = data;
|
||||||
|
ADIv5_AP_t *ap = cortexm_ap(t);
|
||||||
#if defined(STLINKV2)
|
#if defined(STLINKV2)
|
||||||
extern void stlink_reg_write(int num, uint32_t val);
|
extern void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val);
|
||||||
for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) {
|
for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) {
|
||||||
stlink_reg_write(regnum_cortex_m[z], *regs);
|
stlink_reg_write(ap, regnum_cortex_m[z], *regs);
|
||||||
regs++;
|
regs++;
|
||||||
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
||||||
for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) {
|
for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) {
|
||||||
stlink_reg_write(regnum_cortex_mf[z], *regs);
|
stlink_reg_write(ap, regnum_cortex_mf[z], *regs);
|
||||||
regs++;
|
regs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
ADIv5_AP_t *ap = cortexm_ap(t);
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/* FIXME: Describe what's really going on here */
|
/* FIXME: Describe what's really going on here */
|
||||||
|
|
Loading…
Reference in New Issue