Quell compiler warning.
--- /dev/null
+# stm32 nucleo boards, with onboard st/linkv2-1
+# ie, STM32F0, STM32F4.
+# STM32VL has st/linkv1, which is quite different
+
+SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", \
+ MODE:="0666", \
+ SYMLINK+="stlinkv2-1_%n"
+
+# If you share your linux system with other users, or just don't like the
+# idea of write permission for everybody, you can replace MODE:="0666" with
+# OWNER:="yourusername" to create the device owned by you, or with
+# GROUP:="somegroupname" and mange access using standard unix groups.
--- /dev/null
+from dandev37:
+
+Here's a step by step from a clean install to successfully setup MinGW and build
+libusb-1.0 and stlink for MS Windows. Hopefully this helps someone.
+
+1. Install MinGW and MSYS to C:\MinGW with the graphical installer from
+http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download
+and add these packages:
+mingw32-base
+mingw-developer-toolkit
+
+2. Add C:\MinGW\bin to your path.
+Note: a user reports she had to use c:\MinGW\msys\1.0\bin
+
+3. Create the C:\MinGW\msys\1.0\etc\fstab file to mount C:\MinGW as /mingw as per
+http://www.mingw.org/wiki/MSYS:
+
+#Win32_Path Mount_Point
+c:/mingw /mingw
+
+4. Download these three glib, pkg-config, pkg-config-dev archives and extract
+contents to C:\MinGW
+http://win32builder.gnome.org/packages/3.6/glib_2.34.3-1_win32.zip
+http://win32builder.gnome.org/packages/3.6/pkg-config_0.28-1_win32.zip
+http://win32builder.gnome.org/packages/3.6/pkg-config-dev_0.28-1_win32.zip
+
+5. Download latest libusb-1.0 source from
+https://github.com/libusb/libusb (newer repo, includes USB 3.0 hub support)
+OR the old git://git.libusb.org/libusb.git (original repo, NO USB 3.0 support)
+and build (prefix as per http://www.mingw.org/wiki/MSYS)
+
+./autogen.sh
+./configure --prefix=/mingw
+make
+make install
+
+6. Repeat for stlink source from https://github.com/texane/stlink
+
+./autogen.sh
+./configure --prefix=/mingw
+make
+make install
+
+7. Enjoy the fruits of the stlink developers.
./st-util - usage:
- -h, --help Print this help
- -vXX, --verbose=XX specify a specific verbosity level (0..99)
- -v, --verbose specify generally verbose logging
+ -h, --help Print this help
+ -vXX, --verbose=XX Specify a specific verbosity level (0..99)
+ -v, --verbose Specify generally verbose logging
-s X, --stlink_version=X
- Choose what version of stlink to use, (defaults to 2)
- -1, --stlinkv1 Force stlink version 1
+ Choose what version of stlink to use, (defaults to 2)
+ -1, --stlinkv1 Force stlink version 1
-p 4242, --listen_port=1234
- Set the gdb server listen port. (default port: 4242)
+ Set the gdb server listen port. (default port: 4242)
+ -m, --multi
+ Set gdb server to extended mode.
+ st-util will continue listening for connections after disconnect.
+ -n, --no-reset
+ Do not reset board on connection.
+
+The STLINKv2 device to use can be specified in the environment
+variable STLINK_DEVICE on the format <USB_BUS>:<USB_ADDR>.
Then, in your project directory, someting like this...
(remember, you need to run an _ARM_ gdb, not an x86 gdb)
{
o->reset = 0;
}
+
+ if (ac < 1) return -1;
/* stlinkv2 */
o->devname = NULL;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2010 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * Copyright (C) 2011 Øyvind Harboe *
+ * oyvind.harboe@zylin.com *
+ * *
+ * Copyright (C) 2011 Clement Burin des Roziers *
+ * clement.burin-des-roziers@hikob.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+// Build : arm-eabi-gcc -c stm32lx.S
+ .text
+ .syntax unified
+ .cpu cortex-m3
+ .thumb
+ .thumb_func
+ .global write
+
+/*
+ r0 - destination address
+ r1 - source address
+ r2 - count
+*/
+
+ // Set 0 to r3
+ movs r3, #0
+ // Go to compare
+ b.n test_done
+
+write_word:
+ // Load one word from address in r0, increment by 4
+ ldr.w ip, [r1], #4
+ // Store the word to address in r1, increment by 4
+ str.w ip, [r0], #4
+ // Increment r3
+ adds r3, #1
+
+test_done:
+ // Compare r3 and r2
+ cmp r3, r2
+ // Loop if not zero
+ bcc.n write_word
+
+ // Set breakpoint to exit
+ bkpt #0x00
+
typedef struct _st_state_t {
// things from command line, bleh
int stlink_version;
- // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars
- char devicename[100];
int logging_level;
- int listen_port;
+ int listen_port;
int persistent;
int reset;
} st_state_t;
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", optional_argument, NULL, 'v'},
- {"device", required_argument, NULL, 'd'},
{"stlink_version", required_argument, NULL, 's'},
{"stlinkv1", no_argument, NULL, '1'},
{"listen_port", required_argument, NULL, 'p'},
};
const char * help_str = "%s - usage:\n\n"
" -h, --help\t\tPrint this help\n"
- " -vXX, --verbose=XX\tspecify a specific verbosity level (0..99)\n"
- " -v, --verbose\tspecify generally verbose logging\n"
- " -d <device>, --device=/dev/stlink2_1\n"
- "\t\t\tWhere is your stlink device connected?\n"
+ " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n"
+ " -v, --verbose\t\tSpecify generally verbose logging\n"
" -s X, --stlink_version=X\n"
"\t\t\tChoose what version of stlink to use, (defaults to 2)\n"
" -1, --stlinkv1\tForce stlink version 1\n"
"\t\t\tst-util will continue listening for connections after disconnect.\n"
" -n, --no-reset\n"
"\t\t\tDo not reset board on connection.\n"
+ "\n"
+ "The STLINKv2 device to use can be specified in the environment\n"
+ "variable STLINK_DEVICE on the format <USB_BUS>:<USB_ADDR>.\n"
+ "\n"
;
int option_index = 0;
int c;
int q;
- while ((c = getopt_long(argc, argv, "hv::d:s:1p:mn", long_options, &option_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) {
switch (c) {
case 0:
printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n");
} else {
st->logging_level = DEFAULT_LOGGING_LEVEL;
}
- break;
- case 'd':
- if (strlen(optarg) > sizeof (st->devicename)) {
- fprintf(stderr, "device name too long: %zd\n", strlen(optarg));
- } else {
- strcpy(st->devicename, optarg);
- }
break;
case '1':
st->stlink_version = 1;
}
#define CODE_BREAK_NUM 6
+#define CODE_LIT_NUM 2
#define CODE_BREAK_LOW 0x01
#define CODE_BREAK_HIGH 0x02
static void init_code_breakpoints(stlink_t *sl) {
memset(sl->q_buf, 0, 4);
stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/);
- printf("KARL - should read back as 0x03, not 60 02 00 00\n");
- stlink_read_debug32(sl, CM3_REG_FP_CTRL);
+ unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL);
+ if (((val & 3) != 1) ||
+ ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) ||
+ (((val >> 8) & 0xf) != CODE_LIT_NUM)){
+ fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val,
+ ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1);
+ }
+
for(int i = 0; i < CODE_BREAK_NUM; i++) {
code_breaks[i].type = 0;
}
int main(int ac, char** av) {
- struct stlinky *st;
+ struct stlinky *st=NULL;
sig_init();
static inline uint32_t read_flash_cr(stlink_t *sl) {
uint32_t res;
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||(sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
res = stlink_read_debug32(sl, FLASH_F4_CR);
else
static inline unsigned int is_flash_locked(stlink_t *sl) {
/* return non zero for true */
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
return read_flash_cr(sl) & (1 << FLASH_F4_CR_LOCK);
else
an invalid sequence results in a definitive lock of
the FPEC block until next reset.
*/
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY1);
stlink_write_debug32(sl, FLASH_F4_KEYR, FLASH_KEY2);
}
static void lock_flash(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
const uint32_t n = read_flash_cr(sl) | (1 << FLASH_F4_CR_LOCK);
stlink_write_debug32(sl, FLASH_F4_CR, n);
static void set_flash_cr_pg(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
uint32_t x = read_flash_cr(sl);
x |= (1 << FLASH_CR_PG);
static void __attribute__((unused)) clear_flash_cr_pg(stlink_t *sl) {
const uint32_t n = read_flash_cr(sl) & ~(1 << FLASH_CR_PG);
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
stlink_write_debug32(sl, FLASH_F4_CR, n);
else
}
static void set_flash_cr_mer(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
stlink_write_debug32(sl, FLASH_F4_CR,
stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER));
}
static void __attribute__((unused)) clear_flash_cr_mer(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
stlink_write_debug32(sl, FLASH_F4_CR,
stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER));
}
static void set_flash_cr_strt(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
uint32_t x = read_flash_cr(sl);
x |= (1 << FLASH_F4_CR_STRT);
static inline uint32_t read_flash_sr(stlink_t *sl) {
uint32_t res;
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
res = stlink_read_debug32(sl, FLASH_F4_SR);
else
}
static inline unsigned int is_flash_busy(stlink_t *sl) {
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD))
return read_flash_sr(sl) & (1 << FLASH_F4_SR_BSY);
else
size_t off;
int num_empty = 0;
unsigned char erased_pattern = (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH) ? 0:0xff;
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) ? 0:0xff;
const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700);
if (fd == -1) {
}
uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
uint32_t sector=calculate_F4_sectornum(flashaddr);
if (sector<4) sl->flash_pgsz=0x4000;
*/
int stlink_erase_flash_page(stlink_t *sl, stm32_addr_t flashaddr)
{
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
/* wait for ongoing op to finish */
wait_flash_busy(sl);
fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(sl));
#endif
} else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH) {
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) {
uint32_t val;
int stlink_erase_flash_mass(stlink_t *sl) {
if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH) {
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE) {
/* erase each page */
int i = 0, num_pages = sl->flash_size/sl->flash_pgsz;
for (i = 0; i < num_pages; i++) {
size_t loader_size;
if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH ) { /* stm32l */
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { /* stm32l */
loader_code = loader_code_stm32l;
loader_size = sizeof(loader_code_stm32l);
} else if (sl->core_id == STM32VL_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) {
loader_code = loader_code_stm32vl;
loader_size = sizeof(loader_code_stm32vl);
- } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 ||
+ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){
loader_code = loader_code_stm32f4;
loader_size = sizeof(loader_code_stm32f4);
- } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_SMALL) {
+ } else if (sl->chip_id == STM32_CHIPID_F0 || sl->chip_id == STM32_CHIPID_F0_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) {
loader_code = loader_code_stm32f0;
loader_size = sizeof(loader_code_stm32f0);
} else {
ILOG("Finished erasing %d pages of %d (%#x) bytes\n",
page_count, sl->flash_pgsz, sl->flash_pgsz);
- if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) ||
+ if ((sl->chip_id == STM32_CHIPID_F2) || (sl->chip_id == STM32_CHIPID_F4) || (sl->chip_id == STM32_CHIPID_F4_DE) ||
(sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) {
/* todo: check write operation */
} //STM32F4END
else if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH ) {
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) {
/* use fast word write. todo: half page. */
uint32_t val;
int err;
unsigned int num_empty = 0, index;
unsigned char erased_pattern =(sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH )?0:0xff;
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE )?0:0xff;
mapped_file_t mf = MAPPED_FILE_INITIALIZER;
if (map_file(&mf, path) == -1) {
ELOG("map_file() == -1\n");
else
num_empty = 0;
}
+ /* Round down to words */
+ num_empty -= (num_empty & 3);
if(num_empty != 0) {
- ILOG("Ignoring %d bytes of Zeros at end of file\n",num_empty);
+ ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern);
mf.len -= num_empty;
}
err = stlink_write_flash(sl, addr, mf.base, mf.len);
}
if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH ) {
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) {
size_t count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t)) ++count;
stlink_write_reg(sl, 0, 3); /* flash bank 0 (input) */
stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */
- } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 ||
+ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) {
size_t count = size / sizeof(uint32_t);
/* check written byte count */
if (sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS
- || sl->chip_id == STM32_CHIPID_L1_HIGH ) {
+ || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) {
size_t count = size / sizeof(uint32_t);
if (size % sizeof(uint32_t)) ++count;
return -1;
}
- } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 ||
+ } else if (sl->chip_id == STM32_CHIPID_F2 || sl->chip_id == STM32_CHIPID_F4 || (sl->chip_id == STM32_CHIPID_F4_DE) ||
sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) {
stlink_read_reg(sl, 2, &rr);
-/*
+/*
* File: stlink-common.h
* Bulk import from stlink-hw.h
- *
+ *
* This should contain all the common top level stlink interfaces, regardless
* of how the backend does the work....
*/
#define USB_ST_VID 0x0483
#define USB_STLINK_PID 0x3744
#define USB_STLINK_32L_PID 0x3748
+#define USB_STLINK_NUCLEO_PID 0x374b
// STLINK_DEBUG_RESETSYS, etc:
#define STLINK_OK 0x80
#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
#define STM32_CHIPID_F4 0x413
#define STM32_CHIPID_F4_HD 0x419
#define STM32_CHIPID_F4_LP 0x423
+#define STM32_CHIPID_F4_DE 0x433
#define STM32_CHIPID_F1_HIGH 0x414
#define STM32_CHIPID_L1_MEDIUM 0x416
#define STM32_CHIPID_L1_MEDIUM_PLUS 0x427
* 0x436 HIGH.
*/
#define STM32_CHIPID_L1_HIGH 0x436
+#define STM32_CHIPID_L152_RE 0x437
#define STM32_CHIPID_F1_CONN 0x418
#define STM32_CHIPID_F1_VL_MEDIUM 0x420
#define STM32_CHIPID_F1_VL_HIGH 0x428
#define STM32_CHIPID_F1_XL 0x430
#define STM32_CHIPID_F0 0x440
#define STM32_CHIPID_F0_SMALL 0x444
+#define STM32_CHIPID_F0_CAN 0x448
// Constant STM32 memory map figures
#define STM32_FLASH_BASE 0x08000000
uint32_t sram_size;
uint32_t bootrom_base, bootrom_size;
} chip_params_t;
-
-
+
+
// These maps are from a combination of the Programming Manuals, and
// also the Reference manuals. (flash size reg is normally in ref man)
static const chip_params_t devices[] = {
{ // table 1, PM0059
.chip_id = STM32_CHIPID_F2,
.description = "F2 device",
- .flash_size_reg = 0x1ff7a22, /* RM0033 sind Rev 4*/
+ .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/
.flash_pagesize = 0x20000,
.sram_size = 0x20000,
.bootrom_base = 0x1fff0000,
.bootrom_base = 0x1fff0000,
.bootrom_size = 0x7800
},
+ {
+ .chip_id = STM32_CHIPID_F4_DE,
+ .description = "F4 device (Dynamic Efficency)",
+ .flash_size_reg = 0x1FFF7A22,
+ .flash_pagesize = 0x4000,
+ .sram_size = 0x18000,
+ .bootrom_base = 0x1fff0000,
+ .bootrom_size = 0x7800
+ },
{
.chip_id = STM32_CHIPID_F1_HIGH,
.description = "F1 High-density device",
.bootrom_base = 0x1ff00000,
.bootrom_size = 0x1000
},
-
+ {
+ .chip_id = STM32_CHIPID_L152_RE,
+ .description = "L152RE",
+ .flash_size_reg = 0x1ff800cc,
+ .flash_pagesize = 0x100,
+ .sram_size = 0x14000, /*Not completely clear if there are some with 32K*/
+ .bootrom_base = 0x1ff00000,
+ .bootrom_size = 0x1000
+ },
{
.chip_id = STM32_CHIPID_F1_CONN,
.description = "F1 Connectivity line device",
.bootrom_base = 0x1fffe000,
.bootrom_size = 0x1800
},
+ {
+ //Use this as an example for mapping future chips:
+ //RM0091 document was used to find these paramaters
+ .chip_id = STM32_CHIPID_F0_CAN,
+ .description = "F07x device",
+ .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735)
+ .flash_pagesize = 0x800, // Page sizes listed in Table 4
+ .sram_size = 0x4000, // "SRAM" byte size in hex from Table 2
+ .bootrom_base = 0x1fffC800, // "System memory" starting address from Table 2
+ .bootrom_size = 0x3000 // "System memory" byte size in hex from Table 2
+ },
{
//Use this as an example for mapping future chips:
//RM0091 document was used to find these paramaters
},
};
-
+
typedef struct {
uint32_t r[16];
uint32_t s[32];
} reg;
typedef uint32_t stm32_addr_t;
-
+
typedef struct _cortex_m3_cpuid_ {
uint16_t implementer_id;
uint16_t variant;
#define STM32L_SRAM_SIZE (16 * 1024)
stm32_addr_t sram_base;
size_t sram_size;
-
+
// bootloader
stm32_addr_t sys_base;
size_t sys_size;
int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr);
int stlink_fwrite_sram(stlink_t *sl, const char* path, stm32_addr_t addr);
int stlink_verify_write_flash(stlink_t *sl, stm32_addr_t address, uint8_t *data, uint32_t length);
-
+
// PUBLIC
uint32_t stlink_chip_id(stlink_t *sl);
void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid);
#include "stlink-sg.h"
-#include "stlink-usb.h"
+#include "stlink-usb.h"
(handle->rep_trans, handle->usb_handle,
handle->ep_rep, sg_buf, 13, NULL, NULL, 0);
res = submit_wait(handle, handle->rep_trans);
- /* The STLink doesn't seem to evaluate the sequence number */
+ /* The STLink doesn't seem to evaluate the sequence number */
handle->sg_transfer_idx++;
if (res ) return -1;
}
char *device = getenv("STLINK_DEVICE");
if (device) {
- char *c = strchr(device,':');
- if (c==NULL) {
- WLOG("STLINK_DEVICE must be <USB_BUS>:<USB_ADDR> format\n");
- goto on_error;
- }
- devBus=atoi(device);
- *c++=0;
- devAddr=atoi(c);
- ILOG("bus %03d dev %03d\n",devBus, devAddr);
+ char *c = strchr(device,':');
+ if (c==NULL) {
+ WLOG("STLINK_DEVICE must be <USB_BUS>:<USB_ADDR> format\n");
+ goto on_error;
+ }
+ devBus=atoi(device);
+ *c++=0;
+ devAddr=atoi(c);
+ ILOG("bus %03d dev %03d\n",devBus, devAddr);
}
while (cnt){
- cnt--;
+ cnt--;
libusb_get_device_descriptor( list[cnt], &desc );
if (desc.idVendor!=USB_ST_VID) continue;
if (devBus && devAddr)
if ((libusb_get_bus_number(list[cnt])!=devBus) || (libusb_get_device_address(list[cnt])!=devAddr)) continue;
- if (desc.idProduct == USB_STLINK_32L_PID) break;
+ if ( (desc.idProduct == USB_STLINK_32L_PID) || (desc.idProduct == USB_STLINK_NUCLEO_PID) ) break;
if (desc.idProduct == USB_STLINK_PID) {
slu->protocoll = 1;
break;
}
if (cnt < 0) {
- WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any");
- goto on_error;
+ WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any");
+ goto on_error;
} else {
- if( libusb_open(list[cnt], &slu->usb_handle) !=0){
- WLOG("Couldn't open ST-Link/V2 device %03d:%03d\n",libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt]));
- goto on_error;
- }
+ int error = libusb_open(list[cnt], &slu->usb_handle);
+ if( error !=0 ) {
+ WLOG("Error %d opening ST-Link/V2 device %03d:%03d\n", error, libusb_get_bus_number(list[cnt]), libusb_get_device_address(list[cnt]));
+ goto on_error;
+ }
}
libusb_free_device_list(list, 1);
WLOG("libusb_alloc_transfer failed\n");
goto on_libusb_error;
}
+
// TODO - could use the scanning techniq from stm8 code here...
slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
- slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
+ if (desc.idProduct == USB_STLINK_NUCLEO_PID) {
+ slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT;
+ } else {
+ slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
+ }
slu->sg_transfer_idx = 0;
// TODO - never used at the moment, always CMD_SIZE