From 371b100cb08289f7507c5fb2b245ebc63c403411 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 12 Oct 2011 01:45:28 +0000 Subject: [PATCH] Fix stm32l readmem32. As noted, the usb transfer only has a 1 byte length, but it also has a different mode to enter. Tidied up and removed more duplicate and hard coded code, tried to add some notes on where the magic came from. No idea where the chip ids came from, I can't find them in the datasheets anywhere. --- gdbserver/gdb-server.c | 21 +++++++++--------- src/stlink-common.c | 15 ++++++++----- src/stlink-common.h | 14 +++++++++--- src/stlink-usb.c | 49 +++++++++++++++++------------------------- src/stlink-usb.h | 2 ++ src/test_usb.c | 10 +++++---- 6 files changed, 59 insertions(+), 52 deletions(-) diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 2520c30..77d7562 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -36,18 +36,22 @@ struct chip_params { uint32_t bootrom_base, bootrom_size; } const devices[] = { { 0x412, "Low-density device", - 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, + 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063 { 0x410, "Medium-density device", - 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, + 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063 { 0x414, "High-density device", - 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, + 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063 + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) + { 0x416, "EnergyLite device", + 0x2000, 0x100, 0x4000, 0x1ff00000, 0x1000 }, { 0x418, "Connectivity line device", 0x40000, 0x800, 0x10000, 0x1fffb000, 0x4800 }, { 0x420, "Medium-density value line device", 0x20000, 0x400, 0x2000, 0x1ffff000, 0x800 }, { 0x428, "High-density value line device", 0x80000, 0x800, 0x8000, 0x1ffff000, 0x800 }, - { 0x430, "XL-density device", + { 0x430, "XL-density device", // pm0068 0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 }, { 0 } }; @@ -69,12 +73,7 @@ int main(int argc, char** argv) { if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); - uint32_t chip_id; - - stlink_read_mem32(sl, 0xE0042000, 4); - chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) | - (sl->q_buf[3] << 24); - + uint32_t chip_id = stlink_chip_id(sl); printf("Chip ID is %08x.\n", chip_id); const struct chip_params* params = NULL; @@ -99,7 +98,7 @@ int main(int argc, char** argv) { uint32_t flash_size; - stlink_read_mem32(sl, 0x1FFFF7E0, 4); + stlink_read_mem32(sl, 0x1FFFF7E0, 4); // FIXME - that's never going to work! flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); printf("Flash size is %d KiB.\n", flash_size); diff --git a/src/stlink-common.c b/src/stlink-common.c index e3d6631..a317007 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -285,6 +285,13 @@ void stlink_core_id(stlink_t *sl) { DD(sl, "core_id = 0x%08x\n", sl->core_id); } +uint16_t stlink_chip_id(stlink_t *sl) { + stlink_read_mem32(sl, 0xE0042000, 4); + uint32_t chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) | + (sl->q_buf[3] << 24); + return chip_id; +} + void stlink_reset(stlink_t *sl) { D(sl, "\n*** stlink_reset ***\n"); sl->backend->reset(sl); @@ -404,18 +411,16 @@ void stlink_step(stlink_t *sl) { } int stlink_current_mode(stlink_t *sl) { - D(sl, "\n*** stlink_current_mode ***\n"); int mode = sl->backend->current_mode(sl); - stlink_print_data(sl); switch (mode) { case STLINK_DEV_DFU_MODE: - DD(sl, "stlink mode: dfu\n"); + DD(sl, "stlink current mode: dfu\n"); return mode; case STLINK_DEV_DEBUG_MODE: - DD(sl, "stlink mode: debug (jtag or swd)\n"); + DD(sl, "stlink current mode: debug (jtag or swd)\n"); return mode; case STLINK_DEV_MASS_MODE: - DD(sl, "stlink mode: mass\n"); + DD(sl, "stlink current mode: mass\n"); return mode; } DD(sl, "stlink mode: unknown!\n"); diff --git a/src/stlink-common.h b/src/stlink-common.h index b77a899..a716f4d 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -38,6 +38,7 @@ extern "C" { #define STLINK_DEBUG_COMMAND 0xF2 #define STLINK_DFU_COMMAND 0xF3 #define STLINK_DFU_EXIT 0x07 + // enter dfu could be 0x08? // STLINK_GET_CURRENT_MODE #define STLINK_DEV_DFU_MODE 0x00 @@ -65,6 +66,10 @@ extern "C" { #define STLINK_DEBUG_WRITEDEBUGREG 0x0f #define STLINK_DEBUG_ENTER_SWD 0xa3 #define STLINK_DEBUG_ENTER_JTAG 0x00 + + // TODO - possible poor names... +#define STLINK_SWD_ENTER 0x30 +#define STLINK_SWD_READCOREID 0x32 // TBD typedef struct { uint32_t r[16]; @@ -109,12 +114,12 @@ extern "C" { void (*reset) (stlink_t * stl); void (*run) (stlink_t * stl); void (*status) (stlink_t * stl); - void (*version) (stlink_t * stl); + void (*version) (stlink_t *sl); void (*read_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len); void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len); - void (*read_all_regs) (stlink_t *sl, reg* regp); - void (*read_reg) (stlink_t *sl, int r_idx, reg* regp); + void (*read_all_regs) (stlink_t *sl, reg * regp); + void (*read_reg) (stlink_t *sl, int r_idx, reg * regp); void (*write_reg) (stlink_t *sl, uint32_t reg, int idx); void (*step) (stlink_t * stl); int (*current_mode) (stlink_t * stl); @@ -189,6 +194,9 @@ extern "C" { int stlink_erase_flash_mass(stlink_t* sl); int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length); + + // PUBLIC + uint16_t stlink_chip_id(stlink_t *sl); // privates, publics, the rest.... // TODO sort what is private, and what is not diff --git a/src/stlink-usb.c b/src/stlink-usb.c index e30a980..90d5913 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -145,7 +146,7 @@ static int is_stlink_device(libusb_device * dev) { return 1; } -void _stlink_usb_version(stlink_t * sl) { +void _stlink_usb_version(stlink_t *sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const buf = sl->q_buf; ssize_t size; @@ -154,7 +155,7 @@ void _stlink_usb_version(stlink_t * sl) { buf[0] = STLINK_GET_VERSION; buf[1] = 0x80; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -181,26 +182,17 @@ void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { int _stlink_usb_current_mode(stlink_t * sl) { - int mode = -1; - struct stlink_libusb * const slu = sl->backend_data; unsigned char* const buf = sl->q_buf; ssize_t size; - memset(buf, 0, sizeof (sl->q_buf)); - buf[0] = STLINK_GET_CURRENT_MODE; - - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return -1; } - - /* mode = (int)read_uint16(buf, 0); */ - mode = (int) buf[0]; - DD(sl, "mode == 0x%x\n", mode); - return mode; + return sl->q_buf[0]; } void _stlink_usb_core_id(stlink_t * sl) { @@ -212,7 +204,7 @@ void _stlink_usb_core_id(stlink_t * sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_READCOREID; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -231,7 +223,7 @@ void _stlink_usb_status(stlink_t * sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_GETSTATUS; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -246,7 +238,7 @@ void _stlink_usb_status(stlink_t * sl) { } -void _stlink_enter_swd_mode(stlink_t * sl) { +void _stlink_usb_enter_swd_mode(stlink_t * sl) { struct stlink_libusb * const slu = sl->backend_data; unsigned char* const buf = sl->q_buf; ssize_t size; @@ -254,15 +246,14 @@ void _stlink_enter_swd_mode(stlink_t * sl) { memset(buf, 0, sizeof (sl->q_buf)); buf[0] = STLINK_DEBUG_COMMAND; - buf[1] = 0x30; /* needed byte */ - buf[2] = STLINK_DEBUG_ENTER_JTAG; + buf[1] = STLINK_SWD_ENTER; + buf[2] = STLINK_DEBUG_ENTER_SWD; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; } - } void _stlink_usb_exit_dfu_mode(stlink_t* sl) { @@ -290,7 +281,7 @@ void _stlink_usb_reset(stlink_t * sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_RESETSYS; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -307,7 +298,7 @@ void _stlink_usb_step(stlink_t* sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_STEPCORE; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -323,7 +314,7 @@ void _stlink_usb_run(stlink_t* sl) { buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_RUNCORE; - size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -353,18 +344,18 @@ void _stlink_usb_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { ssize_t size; /* assume len < sizeof(sl->q_buf) */ + assert(len < sizeof(sl->q_buf)); // makes a compiler warning? always true? memset(buf, 0, sizeof (sl->q_buf)); buf[0] = STLINK_DEBUG_COMMAND; buf[1] = STLINK_DEBUG_READMEM_32BIT; write_uint32(buf + 2, addr); - write_uint16(buf + 6, len); -#if 0 /* windows usb logs show only one byte is used for length ... */ + // Presumably, this is because usb transfers can't be 16 bits worth of bytes long... + assert (len < 256); buf[6] = (uint8_t) len; -#endif - size = send_recv(slu, buf, 0x10, buf, sizeof (sl->q_buf)); + size = send_recv(slu, buf, STLINK_CMD_SIZE, buf, sizeof (sl->q_buf)); if (size == -1) { printf("[!] send_recv\n"); return; @@ -394,8 +385,8 @@ void _stlink_usb_write_reg(stlink_t *sl, uint32_t reg, int idx) { stlink_backend_t _stlink_usb_backend = { _stlink_usb_close, _stlink_usb_exit_debug_mode, - _stlink_enter_swd_mode, - NULL, + _stlink_usb_enter_swd_mode, + NULL, // no enter_jtag_mode here... _stlink_usb_exit_dfu_mode, _stlink_usb_core_id, _stlink_usb_reset, diff --git a/src/stlink-usb.h b/src/stlink-usb.h index 4b8b46b..4ed655b 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -14,6 +14,8 @@ extern "C" { #include #include "stlink-common.h" + +#define STLINK_CMD_SIZE 16 #if defined(CONFIG_USE_LIBUSB) struct stlink_libusb { diff --git a/src/test_usb.c b/src/test_usb.c index 1ffd47b..0c4232f 100644 --- a/src/test_usb.c +++ b/src/test_usb.c @@ -9,6 +9,8 @@ int main(int ac, char** av) { if (sl != NULL) { printf("-- version\n"); stlink_version(sl); + + printf("mode before doing anything: %d\n", stlink_current_mode(sl)); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { printf("-- exit_dfu_mode\n"); @@ -18,11 +20,11 @@ int main(int ac, char** av) { printf("-- enter_swd_mode\n"); stlink_enter_swd_mode(sl); - printf("-- current_mode\n"); - stlink_current_mode(sl); + printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl)); - /* printf("-- core_id\n"); */ - /* stlink_core_id(sl); */ + printf("-- chip id: %#x\n", stlink_chip_id(sl)); + printf("-- core_id\n"); + stlink_core_id(sl); printf("-- read_sram\n"); static const uint32_t sram_base = 0x8000000; -- 2.30.2