From 3b443dc1c8690ee4b45f477cd83165dca700e60a Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 9 Jul 2014 22:31:11 -0700 Subject: [PATCH] Reindent all source files The indentation of various st-link source files is highly inconsistent. Reindent all source files to 4 space indentions for consistency. I went with 4 space indentations, as it was the most common style. --- flash/main.c | 340 +++---- flashloaders/stm32f0.s | 46 +- flashloaders/stm32f4.s | 26 +- flashloaders/stm32lx.s | 51 +- gdbserver/gdb-remote.c | 248 +++-- gdbserver/gdb-server.c | 1944 ++++++++++++++++++++-------------------- gui/stlink-gui.c | 1332 +++++++++++++-------------- gui/stlink-gui.h | 102 +-- mingw/mingw.c | 198 ++-- src/mmap.c | 28 +- src/mmap.h | 4 +- src/st-info.c | 118 +-- src/st-term.c | 352 ++++---- src/stlink-common.c | 538 +++++------ src/stlink-common.h | 335 ++++--- src/stlink-sg.c | 363 ++++---- src/stlink-sg.h | 10 +- src/stlink-usb.c | 104 +-- src/stlink-usb.h | 6 +- src/test_sg.c | 288 +++--- src/test_usb.c | 10 +- src/uglylogging.c | 52 +- src/uglylogging.h | 4 +- 23 files changed, 3247 insertions(+), 3252 deletions(-) diff --git a/flash/main.c b/flash/main.c index d550eee..8f5b351 100644 --- a/flash/main.c +++ b/flash/main.c @@ -12,12 +12,12 @@ enum st_cmds {DO_WRITE = 0, DO_READ = 1, DO_ERASE = 2}; struct opts { - enum st_cmds cmd; - const char* devname; - const char* filename; - stm32_addr_t addr; - size_t size; - int reset; + enum st_cmds cmd; + const char* devname; + const char* filename; + stm32_addr_t addr; + size_t size; + int reset; }; static void usage(void) @@ -31,183 +31,183 @@ static void usage(void) static int get_opts(struct opts* o, int ac, char** av) { - /* stlinkv1 command line: ./flash {read|write} /dev/sgX path addr */ - /* stlinkv2 command line: ./flash {read|write} path addr */ - - unsigned int i = 0; - - if (ac < 1) return -1; - - if (strcmp(av[0], "--reset") == 0) - { - o->reset = 1; - ac--; - av++; - } - else - { - o->reset = 0; - } - - if (ac < 1) return -1; - - /* stlinkv2 */ - o->devname = NULL; - - if (strcmp(av[0], "erase") == 0) - { - o->cmd = DO_ERASE; - - /* stlinkv1 mode */ - if (ac == 2) + /* stlinkv1 command line: ./flash {read|write} /dev/sgX path addr */ + /* stlinkv2 command line: ./flash {read|write} path addr */ + + unsigned int i = 0; + + if (ac < 1) return -1; + + if (strcmp(av[0], "--reset") == 0) + { + o->reset = 1; + ac--; + av++; + } + else { - o->devname = av[1]; - i = 1; + o->reset = 0; } - } - else { - if (ac < 3) return -1; - if (strcmp(av[0], "read") == 0) - { - o->cmd = DO_READ; - - /* stlinkv1 mode */ - if (ac == 5) - { - o->devname = av[1]; - i = 1; - } - if (ac > 3) - o->size = strtoul(av[i + 3], NULL, 16); - } - else if (strcmp(av[0], "write") == 0) - { - o->cmd = DO_WRITE; - - /* stlinkv1 mode */ - if (ac == 4) - { - o->devname = av[1]; - i = 1; - } - } - else - { - return -1; - } - } - - o->filename = av[i + 1]; - o->addr = strtoul(av[i + 2], NULL, 16); - - return 0; -} + + if (ac < 1) return -1; + + /* stlinkv2 */ + o->devname = NULL; + + if (strcmp(av[0], "erase") == 0) + { + o->cmd = DO_ERASE; + + /* stlinkv1 mode */ + if (ac == 2) + { + o->devname = av[1]; + i = 1; + } + } + else { + if (ac < 3) return -1; + if (strcmp(av[0], "read") == 0) + { + o->cmd = DO_READ; + + /* stlinkv1 mode */ + if (ac == 5) + { + o->devname = av[1]; + i = 1; + } + if (ac > 3) + o->size = strtoul(av[i + 3], NULL, 16); + } + else if (strcmp(av[0], "write") == 0) + { + o->cmd = DO_WRITE; + + /* stlinkv1 mode */ + if (ac == 4) + { + o->devname = av[1]; + i = 1; + } + } + else + { + return -1; + } + } + + o->filename = av[i + 1]; + o->addr = strtoul(av[i + 2], NULL, 16); + + return 0; +} int main(int ac, char** av) { - stlink_t* sl = NULL; - struct opts o; - int err = -1; - - o.size = 0; - if (get_opts(&o, ac - 1, av + 1) == -1) - { - printf("invalid command line\n"); - usage(); - goto on_error; - } - - if (o.devname != NULL) /* stlinkv1 */ - { - sl = stlink_v1_open(50, 1); - if (sl == NULL) goto on_error; - sl->verbose = 50; - } - else /* stlinkv2 */ - { - sl = stlink_open_usb(50, 1); - if (sl == NULL) goto on_error; - sl->verbose = 50; - } - - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(sl); - - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); - - if (o.reset) - stlink_reset(sl); - -// Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 - if (sl->chip_id == STM32_CHIPID_F4) - { - memset(sl->q_buf,0,4); - for (int i=0;i<8;i++) { - stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); - stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); - stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); - } - } - if (o.cmd == DO_WRITE) /* write */ - { - if ((o.addr >= sl->flash_base) && - (o.addr < sl->flash_base + sl->flash_size)) { - err = stlink_fwrite_flash(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; - } + stlink_t* sl = NULL; + struct opts o; + int err = -1; + + o.size = 0; + if (get_opts(&o, ac - 1, av + 1) == -1) + { + printf("invalid command line\n"); + usage(); + goto on_error; } - else if ((o.addr >= sl->sram_base) && - (o.addr < sl->sram_base + sl->sram_size)) { - err = stlink_fwrite_sram(sl, o.filename, o.addr); - if (err == -1) - { - printf("stlink_sram_flash() == -1\n"); - goto on_error; - } - } - } else if (o.cmd == DO_ERASE) - { - err = stlink_erase_flash_mass(sl); - if (err == -1) + + if (o.devname != NULL) /* stlinkv1 */ { - printf("stlink_fwrite_flash() == -1\n"); - goto on_error; + sl = stlink_v1_open(50, 1); + if (sl == NULL) goto on_error; + sl->verbose = 50; } - } - else /* read */ - { - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)) - o.size = sl->flash_size; - else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)) - o.size = sl->sram_size; - err = stlink_fread(sl, o.filename, o.addr, o.size); - if (err == -1) + else /* stlinkv2 */ { - printf("stlink_fread() == -1\n"); - goto on_error; + sl = stlink_open_usb(50, 1); + if (sl == NULL) goto on_error; + sl->verbose = 50; } - } - if (o.reset) - stlink_reset(sl); + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); - /* success */ - err = 0; + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); - on_error: - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + if (o.reset) + stlink_reset(sl); + + // Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 + if (sl->chip_id == STM32_CHIPID_F4) + { + memset(sl->q_buf,0,4); + for (int i=0;i<8;i++) { + stlink_write_mem32(sl,0x40026000+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x10+0x18*i,4); + stlink_write_mem32(sl,0x40026000+0x24+0x18*i,4); + stlink_write_mem32(sl,0x40026400+0x24+0x18*i,4); + } + } + if (o.cmd == DO_WRITE) /* write */ + { + if ((o.addr >= sl->flash_base) && + (o.addr < sl->flash_base + sl->flash_size)) { + err = stlink_fwrite_flash(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else if ((o.addr >= sl->sram_base) && + (o.addr < sl->sram_base + sl->sram_size)) { + err = stlink_fwrite_sram(sl, o.filename, o.addr); + if (err == -1) + { + printf("stlink_sram_flash() == -1\n"); + goto on_error; + } + } + } else if (o.cmd == DO_ERASE) + { + err = stlink_erase_flash_mass(sl); + if (err == -1) + { + printf("stlink_fwrite_flash() == -1\n"); + goto on_error; + } + } + else /* read */ + { + if ((o.addr >= sl->flash_base) && (o.size == 0) && + (o.addr < sl->flash_base + sl->flash_size)) + o.size = sl->flash_size; + else if ((o.addr >= sl->sram_base) && (o.size == 0) && + (o.addr < sl->sram_base + sl->sram_size)) + o.size = sl->sram_size; + err = stlink_fread(sl, o.filename, o.addr, o.size); + if (err == -1) + { + printf("stlink_fread() == -1\n"); + goto on_error; + } + } + + if (o.reset) + stlink_reset(sl); + + /* success */ + err = 0; + +on_error: + if (sl != NULL) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } - return err; + return err; } diff --git a/flashloaders/stm32f0.s b/flashloaders/stm32f0.s index f35fe40..fe12f90 100644 --- a/flashloaders/stm32f0.s +++ b/flashloaders/stm32f0.s @@ -1,32 +1,32 @@ /* Adopted from STM AN4065 stm32f0xx_flash.c:FLASH_ProgramWord */ -write: - ldr r4, STM32_FLASH_BASE - mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ - mov r6, #4 /* PGERR */ +write: + ldr r4, STM32_FLASH_BASE + mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ + mov r6, #4 /* PGERR */ write_half_word: - ldr r3, [r4, #16] /* FLASH->CR */ - orr r3, r5 - str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ - ldrh r3, [r0] /* r3 = *sram */ - strh r3, [r1] /* *flash = r3 */ + ldr r3, [r4, #16] /* FLASH->CR */ + orr r3, r5 + str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ + ldrh r3, [r0] /* r3 = *sram */ + strh r3, [r1] /* *flash = r3 */ busy: - ldr r3, [r4, #12] /* FLASH->SR */ - tst r3, r5 /* FLASH_SR_BUSY */ - beq busy + ldr r3, [r4, #12] /* FLASH->SR */ + tst r3, r5 /* FLASH_SR_BUSY */ + beq busy - tst r3, r6 /* PGERR */ - bne exit + tst r3, r6 /* PGERR */ + bne exit - add r0, r0, #2 /* sram += 2 */ - add r1, r1, #2 /* flash += 2 */ - sub r2, r2, #0x01 /* count-- */ - cmp r2, #0 - bne write_half_word + add r0, r0, #2 /* sram += 2 */ + add r1, r1, #2 /* flash += 2 */ + sub r2, r2, #0x01 /* count-- */ + cmp r2, #0 + bne write_half_word exit: - ldr r3, [r4, #16] /* FLASH->CR */ - bic r3, r5 - str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ - bkpt #0x00 + ldr r3, [r4, #16] /* FLASH->CR */ + bic r3, r5 + str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ + bkpt #0x00 STM32_FLASH_BASE: .word 0x40022000 diff --git a/flashloaders/stm32f4.s b/flashloaders/stm32f4.s index 6cad730..21f5a8f 100644 --- a/flashloaders/stm32f4.s +++ b/flashloaders/stm32f4.s @@ -8,23 +8,23 @@ @ r4 = temp start: - ldr r3, flash_base + ldr r3, flash_base next: - cbz r2, done - ldr r4, [r0] - str r4, [r1] + cbz r2, done + ldr r4, [r0] + str r4, [r1] wait: - ldrh r4, [r3, #0x0e] - tst.w r4, #1 - bne wait - - add r0, #4 - add r1, #4 - sub r2, #1 - b next + ldrh r4, [r3, #0x0e] + tst.w r4, #1 + bne wait + + add r0, #4 + add r1, #4 + sub r2, #1 + b next done: - bkpt + bkpt .align 2 diff --git a/flashloaders/stm32lx.s b/flashloaders/stm32lx.s index 6e8ccb0..799d134 100644 --- a/flashloaders/stm32lx.s +++ b/flashloaders/stm32lx.s @@ -26,38 +26,37 @@ // Build : arm-eabi-gcc -c stm32lx.S - .text - .syntax unified - .cpu cortex-m3 - .thumb - .thumb_func - .global write + .text + .syntax unified + .cpu cortex-m3 + .thumb + .thumb_func + .global write /* - r0 - destination address - r1 - source address - r2 - count + r0 - destination address + r1 - source address + r2 - count */ - // Set 0 to r3 - movs r3, #0 - // Go to compare - b.n test_done + // 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 + // 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 + // Compare r3 and r2 + cmp r3, r2 + // Loop if not zero + bcc.n write_word + // Set breakpoint to exit + bkpt #0x00 diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index edf5338..a9eef33 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -1,10 +1,8 @@ -/* -*- tab-width:8 -*- */ - /* - Copyright (C) 2011 Peter Zotov - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ + * Copyright (C) 2011 Peter Zotov + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ #include #include @@ -20,141 +18,141 @@ static const char hex[] = "0123456789abcdef"; int gdb_send_packet(int fd, char* data) { - int length = strlen(data) + 5; - char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ - - memset(packet, 0, length); - - packet[0] = '$'; - - uint8_t cksum = 0; - for(unsigned int i = 0; i < strlen(data); i++) { - packet[i + 1] = data[i]; - cksum += data[i]; - } - - packet[length - 4] = '#'; - packet[length - 3] = hex[cksum >> 4]; - packet[length - 2] = hex[cksum & 0xf]; - - while(1) { - if(write(fd, packet, length) != length) { - free(packet); - return -2; - } - - char ack; - if(read(fd, &ack, 1) != 1) { - free(packet); - return -2; - } - - if(ack == '+') { - free(packet); - return 0; - } - } + int length = strlen(data) + 5; + char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */ + + memset(packet, 0, length); + + packet[0] = '$'; + + uint8_t cksum = 0; + for(unsigned int i = 0; i < strlen(data); i++) { + packet[i + 1] = data[i]; + cksum += data[i]; + } + + packet[length - 4] = '#'; + packet[length - 3] = hex[cksum >> 4]; + packet[length - 2] = hex[cksum & 0xf]; + + while(1) { + if(write(fd, packet, length) != length) { + free(packet); + return -2; + } + + char ack; + if(read(fd, &ack, 1) != 1) { + free(packet); + return -2; + } + + if(ack == '+') { + free(packet); + return 0; + } + } } #define ALLOC_STEP 1024 int gdb_recv_packet(int fd, char** buffer) { - unsigned packet_size = ALLOC_STEP + 1, packet_idx = 0; - uint8_t cksum = 0; - char recv_cksum[3] = {0}; - char* packet_buffer = malloc(packet_size); - unsigned state; + unsigned packet_size = ALLOC_STEP + 1, packet_idx = 0; + uint8_t cksum = 0; + char recv_cksum[3] = {0}; + char* packet_buffer = malloc(packet_size); + unsigned state; start: - state = 0; - /* - * 0: waiting $ - * 1: data, waiting # - * 2: cksum 1 - * 3: cksum 2 - * 4: fin - */ - - char c; - while(state != 4) { - if(read(fd, &c, 1) != 1) { - return -2; - } - - switch(state) { - case 0: - if(c != '$') { - // ignore - } else { - state = 1; - } - break; - - case 1: - if(c == '#') { - state = 2; - } else { - packet_buffer[packet_idx++] = c; - cksum += c; - - if(packet_idx == packet_size) { - packet_size += ALLOC_STEP; - packet_buffer = realloc(packet_buffer, packet_size); - } - } - break; - - case 2: - recv_cksum[0] = c; - state = 3; - break; - - case 3: - recv_cksum[1] = c; - state = 4; - break; - } - } - - uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); - if(recv_cksum_int != cksum) { - char nack = '-'; - if(write(fd, &nack, 1) != 1) { - return -2; - } - - goto start; - } else { - char ack = '+'; - if(write(fd, &ack, 1) != 1) { - return -2; - } - } - - packet_buffer[packet_idx] = 0; - *buffer = packet_buffer; - - return packet_idx; + state = 0; + /* + * 0: waiting $ + * 1: data, waiting # + * 2: cksum 1 + * 3: cksum 2 + * 4: fin + */ + + char c; + while(state != 4) { + if(read(fd, &c, 1) != 1) { + return -2; + } + + switch(state) { + case 0: + if(c != '$') { + // ignore + } else { + state = 1; + } + break; + + case 1: + if(c == '#') { + state = 2; + } else { + packet_buffer[packet_idx++] = c; + cksum += c; + + if(packet_idx == packet_size) { + packet_size += ALLOC_STEP; + packet_buffer = realloc(packet_buffer, packet_size); + } + } + break; + + case 2: + recv_cksum[0] = c; + state = 3; + break; + + case 3: + recv_cksum[1] = c; + state = 4; + break; + } + } + + uint8_t recv_cksum_int = strtoul(recv_cksum, NULL, 16); + if(recv_cksum_int != cksum) { + char nack = '-'; + if(write(fd, &nack, 1) != 1) { + return -2; + } + + goto start; + } else { + char ack = '+'; + if(write(fd, &ack, 1) != 1) { + return -2; + } + } + + packet_buffer[packet_idx] = 0; + *buffer = packet_buffer; + + return packet_idx; } // Here we skip any characters which are not \x03, GDB interrupt. // As we use the mode with ACK, in a (very unlikely) situation of a packet // lost because of this skipping, it will be resent anyway. int gdb_check_for_interrupt(int fd) { - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLIN; + struct pollfd pfd; + pfd.fd = fd; + pfd.events = POLLIN; - if(poll(&pfd, 1, 0) != 0) { - char c; + if(poll(&pfd, 1, 0) != 0) { + char c; - if(read(fd, &c, 1) != 1) - return -2; + if(read(fd, &c, 1) != 1) + return -2; - if(c == '\x03') // ^C - return 1; - } + if(c == '\x03') // ^C + return 1; + } - return 0; + return 0; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index a3ed335..71ab440 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -1,10 +1,9 @@ -/* -*- tab-width:8 -*- */ #define DEBUG 0 /* - Copyright (C) 2011 Peter Zotov - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. -*/ + * Copyright (C) 2011 Peter Zotov + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ #include #include @@ -75,31 +74,31 @@ int parse_options(int argc, char** argv, st_state_t *st) { {"verbose", optional_argument, NULL, 'v'}, {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, - {"listen_port", required_argument, NULL, 'p'}, - {"multi", optional_argument, NULL, 'm'}, - {"no-reset", optional_argument, NULL, 'n'}, + {"listen_port", required_argument, NULL, 'p'}, + {"multi", optional_argument, NULL, 'm'}, + {"no-reset", optional_argument, NULL, 'n'}, {0, 0, 0, 0}, }; - 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\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" - " -p 4242, --listen_port=1234\n" - "\t\t\tSet the gdb server listen port. " - "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" - " -m, --multi\n" - "\t\t\tSet gdb server to extended mode.\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 :.\n" - "\n" - ; + 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\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" + " -p 4242, --listen_port=1234\n" + "\t\t\tSet the gdb server listen port. " + "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + " -m, --multi\n" + "\t\t\tSet gdb server to extended mode.\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 :.\n" + "\n" + ; int option_index = 0; @@ -107,50 +106,50 @@ int parse_options(int argc, char** argv, st_state_t *st) { int q; 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"); - printf("option %s", long_options[option_index].name); - if (optarg) { - printf(" with arg %s", optarg); - } - printf("\n"); - break; - case 'h': - printf(help_str, argv[0]); - exit(EXIT_SUCCESS); - break; - case 'v': - if (optarg) { - st->logging_level = atoi(optarg); - } else { - st->logging_level = DEFAULT_LOGGING_LEVEL; - } - break; - case '1': - st->stlink_version = 1; - break; - case 's': - sscanf(optarg, "%i", &q); - if (q < 0 || q > 2) { - fprintf(stderr, "stlink version %d unknown!\n", q); - exit(EXIT_FAILURE); - } - st->stlink_version = q; - break; - case 'p': - sscanf(optarg, "%i", &q); - if (q < 0) { - fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); - exit(EXIT_FAILURE); - } - st->listen_port = q; - break; - case 'm': - st->persistent = 1; - break; - case 'n': - st->reset = 0; - break; + case 0: + printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + if (optarg) { + st->logging_level = atoi(optarg); + } else { + st->logging_level = DEFAULT_LOGGING_LEVEL; + } + break; + case '1': + st->stlink_version = 1; + break; + case 's': + sscanf(optarg, "%i", &q); + if (q < 0 || q > 2) { + fprintf(stderr, "stlink version %d unknown!\n", q); + exit(EXIT_FAILURE); + } + st->stlink_version = q; + break; + case 'p': + sscanf(optarg, "%i", &q); + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + st->listen_port = q; + break; + case 'm': + st->persistent = 1; + break; + case 'n': + st->reset = 0; + break; } } @@ -165,27 +164,27 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { - int32_t voltage; - - stlink_t *sl = NULL; - - st_state_t state; - memset(&state, 0, sizeof(state)); - // set defaults... - state.stlink_version = 2; - state.logging_level = DEFAULT_LOGGING_LEVEL; - state.listen_port = DEFAULT_GDB_LISTEN_PORT; - state.reset = 1; /* By default, reset board */ - parse_options(argc, argv, &state); - switch (state.stlink_version) { - case 2: - sl = stlink_open_usb(state.logging_level, 0); - if(sl == NULL) return 1; - break; - case 1: - sl = stlink_v1_open(state.logging_level, 0); - if(sl == NULL) return 1; - break; + int32_t voltage; + + stlink_t *sl = NULL; + + st_state_t state; + memset(&state, 0, sizeof(state)); + // set defaults... + state.stlink_version = 2; + state.logging_level = DEFAULT_LOGGING_LEVEL; + state.listen_port = DEFAULT_GDB_LISTEN_PORT; + state.reset = 1; /* By default, reset board */ + parse_options(argc, argv, &state); + switch (state.stlink_version) { + case 2: + sl = stlink_open_usb(state.logging_level, 0); + if(sl == NULL) return 1; + break; + case 1: + sl = stlink_v1_open(state.logging_level, 0); + if(sl == NULL) return 1; + break; } connected_stlink = sl; @@ -193,44 +192,44 @@ int main(int argc, char** argv) { signal(SIGTERM, &cleanup); if (state.reset) { - stlink_reset(sl); + stlink_reset(sl); } - printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); - voltage = stlink_target_voltage(sl); - if (voltage != -1) { - printf("Target voltage is %d mV.\n", voltage); - } + voltage = stlink_target_voltage(sl); + if (voltage != -1) { + printf("Target voltage is %d mV.\n", voltage); + } - sl->verbose=0; + sl->verbose=0; - current_memory_map = make_memory_map(sl); + current_memory_map = make_memory_map(sl); #ifdef __MINGW32__ - WSADATA wsadata; - if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { - goto winsock_error; - } + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) { + goto winsock_error; + } #endif - do { - serve(sl, &state); + do { + serve(sl, &state); - /* Continue */ - stlink_run(sl); - } while (state.persistent); + /* Continue */ + stlink_run(sl); + } while (state.persistent); #ifdef __MINGW32__ winsock_error: - WSACleanup(); + WSACleanup(); #endif - /* Switch back to mass storage mode before closing. */ - stlink_exit_debug_mode(sl); - stlink_close(sl); + /* Switch back to mass storage mode before closing. */ + stlink_exit_debug_mode(sl); + stlink_close(sl); - return 0; + return 0; } static const char* const target_description_F4 = @@ -299,59 +298,59 @@ static const char* const target_description_F4 = ""; static const char* const memory_map_template_F4 = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // ccm ram - " " // sram - " " //Sectors 0..3 - " 0x4000" //16kB - " " - " " //Sector 4 - " 0x10000" //64kB - " " - " " //Sectors 5..11 - " 0x20000" //128kB - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // ccm ram + " " // sram + " " //Sectors 0..3 + " 0x4000" //16kB + " " + " " //Sector 4 + " 0x10000" //64kB + " " + " " //Sectors 5..11 + " 0x20000" //128kB + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; static const char* const memory_map_template = - "" - "" - "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%zx" - " " - " " // peripheral regs - " " // cortex regs - " " // bootrom - " " // option byte area - ""; + "" + "" + "" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%zx" + " " + " " // peripheral regs + " " // cortex regs + " " // bootrom + " " // option byte area + ""; char* make_memory_map(stlink_t *sl) { - /* This will be freed in serve() */ - char* map = malloc(4096); - map[0] = '\0'; + /* This will be freed in serve() */ + char* map = malloc(4096); + map[0] = '\0'; - if(sl->chip_id==STM32_CHIPID_F4) { - strcpy(map, memory_map_template_F4); + if(sl->chip_id==STM32_CHIPID_F4) { + strcpy(map, memory_map_template_F4); } else { snprintf(map, 4096, memory_map_template, - sl->flash_size, - sl->sram_size, - sl->flash_size, sl->flash_pgsz, - sl->sys_base, sl->sys_size); + sl->flash_size, + sl->sram_size, + sl->flash_size, sl->flash_pgsz, + sl->sys_base, sl->sys_size); } - return map; + return map; } @@ -375,101 +374,101 @@ char* make_memory_map(stlink_t *sl) { enum watchfun { WATCHDISABLED = 0, WATCHREAD = 5, WATCHWRITE = 6, WATCHACCESS = 7 }; struct code_hw_watchpoint { - stm32_addr_t addr; - uint8_t mask; - enum watchfun fun; + stm32_addr_t addr; + uint8_t mask; + enum watchfun fun; }; struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { - #if DEBUG - printf("init watchpoints\n"); - #endif - - // set trcena in debug command to turn on dwt unit - stlink_write_debug32(sl, 0xE000EDFC, - stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); - - // make sure all watchpoints are cleared - for(int i = 0; i < DATA_WATCH_NUM; i++) { - data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); - } +#if DEBUG + printf("init watchpoints\n"); +#endif + + // set trcena in debug command to turn on dwt unit + stlink_write_debug32(sl, 0xE000EDFC, + stlink_read_debug32(sl, 0xE000EDFC) | (1<<24)); + + // make sure all watchpoints are cleared + for(int i = 0; i < DATA_WATCH_NUM; i++) { + data_watches[i].fun = WATCHDISABLED; + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + } } static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { - int i = 0; - uint32_t mask; - - // computer mask - // find a free watchpoint - // configure - - mask = -1; - i = len; - while(i) { - i >>= 1; - mask++; - } - - if((mask != (uint32_t)-1) && (mask < 16)) { - for(i = 0; i < DATA_WATCH_NUM; i++) { - // is this an empty slot ? - if(data_watches[i].fun == WATCHDISABLED) { - #if DEBUG - printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); - #endif - - data_watches[i].fun = wf; - data_watches[i].addr = addr; - data_watches[i].mask = mask; - - // insert comparator address - stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); - - // insert mask - stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); - - // insert function - stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); - - // just to make sure the matched bit is clear ! - stlink_read_debug32(sl, 0xE0001028 + i * 16); - return 0; - } - } - } - - #if DEBUG - printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); - #endif - return -1; + int i = 0; + uint32_t mask; + + // computer mask + // find a free watchpoint + // configure + + mask = -1; + i = len; + while(i) { + i >>= 1; + mask++; + } + + if((mask != (uint32_t)-1) && (mask < 16)) { + for(i = 0; i < DATA_WATCH_NUM; i++) { + // is this an empty slot ? + if(data_watches[i].fun == WATCHDISABLED) { +#if DEBUG + printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); +#endif + + data_watches[i].fun = wf; + data_watches[i].addr = addr; + data_watches[i].mask = mask; + + // insert comparator address + stlink_write_debug32(sl, 0xE0001020 + i * 16, addr); + + // insert mask + stlink_write_debug32(sl, 0xE0001024 + i * 16, mask); + + // insert function + stlink_write_debug32(sl, 0xE0001028 + i * 16, wf); + + // just to make sure the matched bit is clear ! + stlink_read_debug32(sl, 0xE0001028 + i * 16); + return 0; + } + } + } + +#if DEBUG + printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); +#endif + return -1; } static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) { - int i; + int i; - for(i = 0 ; i < DATA_WATCH_NUM; i++) { - if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { - #if DEBUG - printf("delete watchpoint %d addr %x\n", i, addr); - #endif + for(i = 0 ; i < DATA_WATCH_NUM; i++) { + if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { +#if DEBUG + printf("delete watchpoint %d addr %x\n", i, addr); +#endif - data_watches[i].fun = WATCHDISABLED; - stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); + data_watches[i].fun = WATCHDISABLED; + stlink_write_debug32(sl, 0xe0001028 + i * 16, 0); - return 0; - } - } + return 0; + } + } - #if DEBUG - printf("failure: delete watchpoint addr %x\n", addr); - #endif +#if DEBUG + printf("failure: delete watchpoint addr %x\n", addr); +#endif - return -1; + return -1; } #define CODE_BREAK_NUM 6 @@ -478,814 +477,813 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) #define CODE_BREAK_HIGH 0x02 struct code_hw_breakpoint { - stm32_addr_t addr; - int type; + stm32_addr_t addr; + int type; }; struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; 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*/); - unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); - if (((val & 3) != 1) || + memset(sl->q_buf, 0, 4); + stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); + 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); - } - + 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; - stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); - } + for(int i = 0; i < CODE_BREAK_NUM; i++) { + code_breaks[i].type = 0; + stlink_write_debug32(sl, CM3_REG_FP_COMP0 + i * 4, 0); + } } static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { - stm32_addr_t fpb_addr = addr & ~0x3; - int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; - - if(addr & 1) { - fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr); - return -1; - } - - int id = -1; - for(int i = 0; i < CODE_BREAK_NUM; i++) { - if(fpb_addr == code_breaks[i].addr || - (set && code_breaks[i].type == 0)) { - id = i; - break; - } - } - - if(id == -1) { - if(set) return -1; // Free slot not found - else return 0; // Breakpoint is already removed - } - - struct code_hw_breakpoint* brk = &code_breaks[id]; - - brk->addr = fpb_addr; - - if(set) brk->type |= type; - else brk->type &= ~type; - - if(brk->type == 0) { - #if DEBUG - printf("clearing hw break %d\n", id); - #endif - - stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); - } else { - uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - - #if DEBUG - printf("setting hw break %d at %08x (%d)\n", - id, brk->addr, brk->type); - printf("reg %08x \n", - mask); - #endif - - stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); - } - - return 0; + stm32_addr_t fpb_addr = addr & ~0x3; + int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW; + + if(addr & 1) { + fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr); + return -1; + } + + int id = -1; + for(int i = 0; i < CODE_BREAK_NUM; i++) { + if(fpb_addr == code_breaks[i].addr || + (set && code_breaks[i].type == 0)) { + id = i; + break; + } + } + + if(id == -1) { + if(set) return -1; // Free slot not found + else return 0; // Breakpoint is already removed + } + + struct code_hw_breakpoint* brk = &code_breaks[id]; + + brk->addr = fpb_addr; + + if(set) brk->type |= type; + else brk->type &= ~type; + + if(brk->type == 0) { +#if DEBUG + printf("clearing hw break %d\n", id); +#endif + + stlink_write_debug32(sl, 0xe0002008 + id * 4, 0); + } else { + uint32_t mask = (brk->addr) | 1 | (brk->type << 30); + +#if DEBUG + printf("setting hw break %d at %08x (%d)\n", + id, brk->addr, brk->type); + printf("reg %08x \n", + mask); +#endif + + stlink_write_debug32(sl, 0xe0002008 + id * 4, mask); + } + + return 0; } struct flash_block { - stm32_addr_t addr; - unsigned length; - uint8_t* data; + stm32_addr_t addr; + unsigned length; + uint8_t* data; - struct flash_block* next; + struct flash_block* next; }; static struct flash_block* flash_root; static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { - if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { - fprintf(stderr, "flash_add_block: incorrect bounds\n"); - return -1; - } + if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) { + fprintf(stderr, "flash_add_block: incorrect bounds\n"); + return -1; + } - stlink_calculate_pagesize(sl, addr); - if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { - fprintf(stderr, "flash_add_block: unaligned block\n"); - return -1; - } + stlink_calculate_pagesize(sl, addr); + if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) { + fprintf(stderr, "flash_add_block: unaligned block\n"); + return -1; + } - struct flash_block* new = malloc(sizeof(struct flash_block)); - new->next = flash_root; + struct flash_block* new = malloc(sizeof(struct flash_block)); + new->next = flash_root; - new->addr = addr; - new->length = length; - new->data = calloc(length, 1); + new->addr = addr; + new->length = length; + new->data = calloc(length, 1); - flash_root = new; + flash_root = new; - return 0; + return 0; } static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { - unsigned int fit_blocks = 0, fit_length = 0; - - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - /* Block: ------X------Y-------- - * Data: a-----b - * a--b - * a-----------b - * Block intersects with data, if: - * a < Y && b > x - */ - - unsigned X = fb->addr, Y = fb->addr + fb->length; - unsigned a = addr, b = addr + length; - if(a < Y && b > X) { - // from start of the block - unsigned start = (a > X ? a : X) - X; - unsigned end = (b > Y ? Y : b) - X; - - memcpy(fb->data + start, data, end - start); - - fit_blocks++; - fit_length += end - start; - } - } - - if(fit_blocks == 0) { - fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length); - return -1; - } - - if(fit_length != length) { - fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n", - addr, length, fit_length); - fprintf(stderr, "(this is not an error, just a GDB glitch)\n"); - } - - return 0; + unsigned int fit_blocks = 0, fit_length = 0; + + for(struct flash_block* fb = flash_root; fb; fb = fb->next) { + /* Block: ------X------Y-------- + * Data: a-----b + * a--b + * a-----------b + * Block intersects with data, if: + * a < Y && b > x + */ + + unsigned X = fb->addr, Y = fb->addr + fb->length; + unsigned a = addr, b = addr + length; + if(a < Y && b > X) { + // from start of the block + unsigned start = (a > X ? a : X) - X; + unsigned end = (b > Y ? Y : b) - X; + + memcpy(fb->data + start, data, end - start); + + fit_blocks++; + fit_length += end - start; + } + } + + if(fit_blocks == 0) { + fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length); + return -1; + } + + if(fit_length != length) { + fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n", + addr, length, fit_length); + fprintf(stderr, "(this is not an error, just a GDB glitch)\n"); + } + + return 0; } static int flash_go(stlink_t *sl) { - int error = -1; + int error = -1; - // Some kinds of clock settings do not allow writing to flash. - stlink_reset(sl); + // Some kinds of clock settings do not allow writing to flash. + stlink_reset(sl); - for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - #if DEBUG - printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); - #endif + for(struct flash_block* fb = flash_root; fb; fb = fb->next) { +#if DEBUG + printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); +#endif - unsigned length = fb->length; - for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { + unsigned length = fb->length; + for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) { - //Update FLASH_PAGE - stlink_calculate_pagesize(sl, page); + //Update FLASH_PAGE + stlink_calculate_pagesize(sl, page); - #if DEBUG - printf("flash_do: page %08x\n", page); - #endif +#if DEBUG + printf("flash_do: page %08x\n", page); +#endif - if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), - length > FLASH_PAGE ? FLASH_PAGE : length) < 0) - goto error; - } - } + if(stlink_write_flash(sl, page, fb->data + (page - fb->addr), + length > FLASH_PAGE ? FLASH_PAGE : length) < 0) + goto error; + } + } - stlink_reset(sl); + stlink_reset(sl); - error = 0; + error = 0; error: - for(struct flash_block* fb = flash_root, *next; fb; fb = next) { - next = fb->next; - free(fb->data); - free(fb); - } + for(struct flash_block* fb = flash_root, *next; fb; fb = next) { + next = fb->next; + free(fb->data); + free(fb); + } - flash_root = NULL; + flash_root = NULL; - return error; + return error; } int serve(stlink_t *sl, st_state_t *st) { - int sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock < 0) { - perror("socket"); - return 1; - } - - unsigned int val = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); - - struct sockaddr_in serv_addr; - memset(&serv_addr,0,sizeof(struct sockaddr_in)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(st->listen_port); - - if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { - perror("bind"); - return 1; - } - - if(listen(sock, 5) < 0) { - perror("listen"); - return 1; - } - - printf("Listening at *:%d...\n", st->listen_port); - - int client = accept(sock, NULL, NULL); - //signal (SIGINT, SIG_DFL); - if(client < 0) { - perror("accept"); - return 1; - } - - close(sock); - - stlink_force_debug(sl); - if (st->reset) { - stlink_reset(sl); + int sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) { + perror("socket"); + return 1; + } + + unsigned int val = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + + struct sockaddr_in serv_addr; + memset(&serv_addr,0,sizeof(struct sockaddr_in)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(st->listen_port); + + if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("bind"); + return 1; + } + + if(listen(sock, 5) < 0) { + perror("listen"); + return 1; + } + + printf("Listening at *:%d...\n", st->listen_port); + + int client = accept(sock, NULL, NULL); + //signal (SIGINT, SIG_DFL); + if(client < 0) { + perror("accept"); + return 1; + } + + close(sock); + + stlink_force_debug(sl); + if (st->reset) { + stlink_reset(sl); } - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - printf("GDB connected.\n"); - - /* - * To allow resetting the chip from GDB it is required to - * emulate attaching and detaching to target. - */ - unsigned int attached = 1; - - while(1) { - char* packet; - - int status = gdb_recv_packet(client, &packet); - if(status < 0) { - fprintf(stderr, "cannot recv: %d\n", status); - return 1; - } - - #if DEBUG - printf("recv: %s\n", packet); - #endif - - char* reply = NULL; - reg regp; - - switch(packet[0]) { - case 'q': { - if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { - reply = strdup(""); - break; - } - - char *separator = strstr(packet, ":"), *params = ""; - if(separator == NULL) { - separator = packet + strlen(packet); - } else { - params = separator + 1; - } - - unsigned queryNameLength = (separator - &packet[1]); - char* queryName = calloc(queryNameLength + 1, 1); - strncpy(queryName, &packet[1], queryNameLength); - - #if DEBUG - printf("query: %s;%s\n", queryName, params); - #endif - - if(!strcmp(queryName, "Supported")) { - if(sl->chip_id==STM32_CHIPID_F4) { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + printf("GDB connected.\n"); + + /* + * To allow resetting the chip from GDB it is required to + * emulate attaching and detaching to target. + */ + unsigned int attached = 1; + + while(1) { + char* packet; + + int status = gdb_recv_packet(client, &packet); + if(status < 0) { + fprintf(stderr, "cannot recv: %d\n", status); + return 1; + } + +#if DEBUG + printf("recv: %s\n", packet); +#endif + + char* reply = NULL; + reg regp; + + switch(packet[0]) { + case 'q': { + if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') { + reply = strdup(""); + break; } - else { - reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + + char *separator = strstr(packet, ":"), *params = ""; + if(separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; } - } else if(!strcmp(queryName, "Xfer")) { - char *type, *op, *__s_addr, *s_length; - char *tok = params; - char *annex __attribute__((unused)); - - type = strsep(&tok, ":"); - op = strsep(&tok, ":"); - annex = strsep(&tok, ":"); - __s_addr = strsep(&tok, ","); - s_length = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); - - #if DEBUG - printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", - type, op, annex, addr, length); - #endif - - const char* data = NULL; - - if(!strcmp(type, "memory-map") && !strcmp(op, "read")) - data = current_memory_map; - - if(!strcmp(type, "features") && !strcmp(op, "read")) - data = target_description_F4; - - if(data) { - unsigned data_length = strlen(data); - if(addr + length > data_length) - length = data_length - addr; - - if(length == 0) { - reply = strdup("l"); - } else { - reply = calloc(length + 2, 1); - reply[0] = 'm'; - strncpy(&reply[1], data, length); - } - } - } else if(!strncmp(queryName, "Rcmd,",4)) { - // Rcmd uses the wrong separator - char *separator = strstr(packet, ","), *params = ""; - if(separator == NULL) { - separator = packet + strlen(packet); - } else { - params = separator + 1; - } - - - if (!strncmp(params,"726573756d65",12)) {// resume + + unsigned queryNameLength = (separator - &packet[1]); + char* queryName = calloc(queryNameLength + 1, 1); + strncpy(queryName, &packet[1], queryNameLength); + +#if DEBUG + printf("query: %s;%s\n", queryName, params); +#endif + + if(!strcmp(queryName, "Supported")) { + if(sl->chip_id==STM32_CHIPID_F4) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + } + else { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + } + } else if(!strcmp(queryName, "Xfer")) { + char *type, *op, *__s_addr, *s_length; + char *tok = params; + char *annex __attribute__((unused)); + + type = strsep(&tok, ":"); + op = strsep(&tok, ":"); + annex = strsep(&tok, ":"); + __s_addr = strsep(&tok, ","); + s_length = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16), + length = strtoul(s_length, NULL, 16); + +#if DEBUG + printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", + type, op, annex, addr, length); +#endif + + const char* data = NULL; + + if(!strcmp(type, "memory-map") && !strcmp(op, "read")) + data = current_memory_map; + + if(!strcmp(type, "features") && !strcmp(op, "read")) + data = target_description_F4; + + if(data) { + unsigned data_length = strlen(data); + if(addr + length > data_length) + length = data_length - addr; + + if(length == 0) { + reply = strdup("l"); + } else { + reply = calloc(length + 2, 1); + reply[0] = 'm'; + strncpy(&reply[1], data, length); + } + } + } else if(!strncmp(queryName, "Rcmd,",4)) { + // Rcmd uses the wrong separator + char *separator = strstr(packet, ","), *params = ""; + if(separator == NULL) { + separator = packet + strlen(packet); + } else { + params = separator + 1; + } + + + if (!strncmp(params,"726573756d65",12)) {// resume #if DEBUG - printf("Rcmd: resume\n"); + printf("Rcmd: resume\n"); #endif - stlink_run(sl); + stlink_run(sl); + + reply = strdup("OK"); + } else if (!strncmp(params,"68616c74",8)) { //halt + reply = strdup("OK"); - reply = strdup("OK"); - } else if (!strncmp(params,"68616c74",8)) { //halt - reply = strdup("OK"); + stlink_force_debug(sl); - stlink_force_debug(sl); +#if DEBUG + printf("Rcmd: halt\n"); +#endif + } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset + reply = strdup("OK"); + + stlink_jtag_reset(sl, 1); + stlink_jtag_reset(sl, 0); + stlink_force_debug(sl); #if DEBUG - printf("Rcmd: halt\n"); + printf("Rcmd: jtag_reset\n"); #endif - } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset - reply = strdup("OK"); + } else if (!strncmp(params,"7265736574",10)) { //reset + reply = strdup("OK"); - stlink_jtag_reset(sl, 1); - stlink_jtag_reset(sl, 0); - stlink_force_debug(sl); + stlink_force_debug(sl); + stlink_reset(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); #if DEBUG - printf("Rcmd: jtag_reset\n"); + printf("Rcmd: reset\n"); +#endif + } else { +#if DEBUG + printf("Rcmd: %s\n", params); #endif - } else if (!strncmp(params,"7265736574",10)) { //reset - reply = strdup("OK"); - stlink_force_debug(sl); - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); + } + + } + + if(reply == NULL) + reply = strdup(""); + + free(queryName); + + break; + } + + case 'v': { + char *params = NULL; + char *cmdName = strtok_r(packet, ":;", ¶ms); + + cmdName++; // vCommand -> Command + + if(!strcmp(cmdName, "FlashErase")) { + char *__s_addr, *s_length; + char *tok = params; + + __s_addr = strsep(&tok, ","); + s_length = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16), + length = strtoul(s_length, NULL, 16); #if DEBUG - printf("Rcmd: reset\n"); + printf("FlashErase: addr:%08x,len:%04x\n", + addr, length); #endif - } else { + + if(flash_add_block(addr, length, sl) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "FlashWrite")) { + char *__s_addr, *data; + char *tok = params; + + __s_addr = strsep(&tok, ":"); + data = tok; + + unsigned addr = strtoul(__s_addr, NULL, 16); + unsigned data_length = status - (data - packet); + + // Length of decoded data cannot be more than + // encoded, as escapes are removed. + // Additional byte is reserved for alignment fix. + uint8_t *decoded = calloc(data_length + 1, 1); + unsigned dec_index = 0; + for(unsigned int i = 0; i < data_length; i++) { + if(data[i] == 0x7d) { + i++; + decoded[dec_index++] = data[i] ^ 0x20; + } else { + decoded[dec_index++] = data[i]; + } + } + + // Fix alignment + if(dec_index % 2 != 0) + dec_index++; + #if DEBUG - printf("Rcmd: %s\n", params); + printf("binary packet %d -> %d\n", data_length, dec_index); #endif - } - - } - - if(reply == NULL) - reply = strdup(""); - - free(queryName); - - break; - } - - case 'v': { - char *params = NULL; - char *cmdName = strtok_r(packet, ":;", ¶ms); - - cmdName++; // vCommand -> Command - - if(!strcmp(cmdName, "FlashErase")) { - char *__s_addr, *s_length; - char *tok = params; - - __s_addr = strsep(&tok, ","); - s_length = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16), - length = strtoul(s_length, NULL, 16); - - #if DEBUG - printf("FlashErase: addr:%08x,len:%04x\n", - addr, length); - #endif - - if(flash_add_block(addr, length, sl) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "FlashWrite")) { - char *__s_addr, *data; - char *tok = params; - - __s_addr = strsep(&tok, ":"); - data = tok; - - unsigned addr = strtoul(__s_addr, NULL, 16); - unsigned data_length = status - (data - packet); - - // Length of decoded data cannot be more than - // encoded, as escapes are removed. - // Additional byte is reserved for alignment fix. - uint8_t *decoded = calloc(data_length + 1, 1); - unsigned dec_index = 0; - for(unsigned int i = 0; i < data_length; i++) { - if(data[i] == 0x7d) { - i++; - decoded[dec_index++] = data[i] ^ 0x20; - } else { - decoded[dec_index++] = data[i]; - } - } - - // Fix alignment - if(dec_index % 2 != 0) - dec_index++; - - #if DEBUG - printf("binary packet %d -> %d\n", data_length, dec_index); - #endif - - if(flash_populate(addr, decoded, dec_index) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "FlashDone")) { - if(flash_go(sl) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - } else if(!strcmp(cmdName, "Kill")) { - attached = 0; - - reply = strdup("OK"); - } - - if(reply == NULL) - reply = strdup(""); - - break; - } - - case 'c': - stlink_run(sl); - - while(1) { - int status = gdb_check_for_interrupt(client); - if(status < 0) { - fprintf(stderr, "cannot check for int: %d\n", status); - return 1; - } - - if(status == 1) { - stlink_force_debug(sl); - break; - } - - stlink_status(sl); - if(sl->core_stat == STLINK_CORE_HALTED) { - break; - } - - usleep(100000); - } - - reply = strdup("S05"); // TRAP - break; - - case 's': - stlink_step(sl); - - reply = strdup("S05"); // TRAP - break; - - case '?': - if(attached) { - reply = strdup("S05"); // TRAP - } else { - /* Stub shall reply OK if not attached. */ - reply = strdup("OK"); - } - break; - - case 'g': - stlink_read_all_regs(sl, ®p); - - reply = calloc(8 * 16 + 1, 1); - for(int i = 0; i < 16; i++) - sprintf(&reply[i * 8], "%08x", htonl(regp.r[i])); - - break; - - case 'p': { - unsigned id = strtoul(&packet[1], NULL, 16); - unsigned myreg = 0xDEADDEAD; - - if(id < 16) { - stlink_read_reg(sl, id, ®p); - myreg = htonl(regp.r[id]); - } else if(id == 0x19) { - stlink_read_reg(sl, 16, ®p); - myreg = htonl(regp.xpsr); - } else if(id == 0x1A) { - stlink_read_reg(sl, 17, ®p); - myreg = htonl(regp.main_sp); - } else if(id == 0x1B) { - stlink_read_reg(sl, 18, ®p); - myreg = htonl(regp.process_sp); - } else if(id == 0x1C) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.control); - } else if(id == 0x1D) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.faultmask); - } else if(id == 0x1E) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.basepri); - } else if(id == 0x1F) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.primask); - } else if(id >= 0x20 && id < 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.s[id-0x20]); - } else if(id == 0x40) { - stlink_read_unsupported_reg(sl, id, ®p); - myreg = htonl(regp.fpscr); - } else { - reply = strdup("E00"); - } - - reply = calloc(8 + 1, 1); - sprintf(reply, "%08x", myreg); - - break; - } - - case 'P': { - char* s_reg = &packet[1]; - char* s_value = strstr(&packet[1], "=") + 1; - - unsigned reg = strtoul(s_reg, NULL, 16); - unsigned value = strtoul(s_value, NULL, 16); - - if(reg < 16) { - stlink_write_reg(sl, ntohl(value), reg); - } else if(reg == 0x19) { - stlink_write_reg(sl, ntohl(value), 16); - } else if(reg == 0x1A) { - stlink_write_reg(sl, ntohl(value), 17); - } else if(reg == 0x1B) { - stlink_write_reg(sl, ntohl(value), 18); - } else if(reg == 0x1C) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1D) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1E) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x1F) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg >= 0x20 && reg < 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else if(reg == 0x40) { - stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); - } else { - reply = strdup("E00"); - } - - if(!reply) { - reply = strdup("OK"); - } - - break; - } - - case 'G': - for(int i = 0; i < 16; i++) { - char str[9] = {0}; - strncpy(str, &packet[1 + i * 8], 8); - uint32_t reg = strtoul(str, NULL, 16); - stlink_write_reg(sl, ntohl(reg), i); - } - - reply = strdup("OK"); - break; - - case 'm': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; - - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); - - unsigned adj_start = start % 4; - unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - - stlink_read_mem32(sl, start - adj_start, count_rnd); - - reply = calloc(count * 2 + 1, 1); - for(unsigned int i = 0; i < count; i++) { - reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; - reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; - } - - break; - } - - case 'M': { - char* s_start = &packet[1]; - char* s_count = strstr(&packet[1], ",") + 1; - char* hexdata = strstr(packet, ":") + 1; - - stm32_addr_t start = strtoul(s_start, NULL, 16); - unsigned count = strtoul(s_count, NULL, 16); - - if(start % 4) { - unsigned align_count = 4 - start % 4; - if (align_count > count) align_count = count; - for(unsigned int i = 0; i < align_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem8(sl, start, align_count); - start += align_count; - count -= align_count; - hexdata += 2*align_count; - } - - if(count - count % 4) { - unsigned aligned_count = count - count % 4; - - for(unsigned int i = 0; i < aligned_count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem32(sl, start, aligned_count); - count -= aligned_count; - start += aligned_count; - hexdata += 2*aligned_count; - } - - if(count) { - for(unsigned int i = 0; i < count; i ++) { - char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; - uint8_t byte = strtoul(hex, NULL, 16); - sl->q_buf[i] = byte; - } - stlink_write_mem8(sl, start, count); - } - reply = strdup("OK"); - break; - } - - case 'Z': { - char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); - stm32_addr_t len = strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': - if(update_code_breakpoint(sl, addr, 1) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - } - break; - - case '2': // insert write watchpoint - case '3': // insert read watchpoint - case '4': // insert access watchpoint - { - enum watchfun wf; - if(packet[1] == '2') { - wf = WATCHWRITE; - } else if(packet[1] == '3') { - wf = WATCHREAD; - } else { - wf = WATCHACCESS; - } - - if(add_data_watchpoint(sl, wf, addr, len) < 0) { + if(flash_populate(addr, decoded, dec_index) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "FlashDone")) { + if(flash_go(sl) < 0) { reply = strdup("E00"); } else { reply = strdup("OK"); + } + } else if(!strcmp(cmdName, "Kill")) { + attached = 0; + + reply = strdup("OK"); + } + + if(reply == NULL) + reply = strdup(""); + + break; + } + + case 'c': + stlink_run(sl); + + while(1) { + int status = gdb_check_for_interrupt(client); + if(status < 0) { + fprintf(stderr, "cannot check for int: %d\n", status); + return 1; + } + + if(status == 1) { + stlink_force_debug(sl); + break; + } + + stlink_status(sl); + if(sl->core_stat == STLINK_CORE_HALTED) { + break; + } + + usleep(100000); + } + + reply = strdup("S05"); // TRAP + break; + + case 's': + stlink_step(sl); + + reply = strdup("S05"); // TRAP + break; + + case '?': + if(attached) { + reply = strdup("S05"); // TRAP + } else { + /* Stub shall reply OK if not attached. */ + reply = strdup("OK"); + } + break; + + case 'g': + stlink_read_all_regs(sl, ®p); + + reply = calloc(8 * 16 + 1, 1); + for(int i = 0; i < 16; i++) + sprintf(&reply[i * 8], "%08x", htonl(regp.r[i])); + + break; + + case 'p': { + unsigned id = strtoul(&packet[1], NULL, 16); + unsigned myreg = 0xDEADDEAD; + + if(id < 16) { + stlink_read_reg(sl, id, ®p); + myreg = htonl(regp.r[id]); + } else if(id == 0x19) { + stlink_read_reg(sl, 16, ®p); + myreg = htonl(regp.xpsr); + } else if(id == 0x1A) { + stlink_read_reg(sl, 17, ®p); + myreg = htonl(regp.main_sp); + } else if(id == 0x1B) { + stlink_read_reg(sl, 18, ®p); + myreg = htonl(regp.process_sp); + } else if(id == 0x1C) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.control); + } else if(id == 0x1D) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.faultmask); + } else if(id == 0x1E) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.basepri); + } else if(id == 0x1F) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.primask); + } else if(id >= 0x20 && id < 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.s[id-0x20]); + } else if(id == 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.fpscr); + } else { + reply = strdup("E00"); + } + + reply = calloc(8 + 1, 1); + sprintf(reply, "%08x", myreg); + + break; + } + + case 'P': { + char* s_reg = &packet[1]; + char* s_value = strstr(&packet[1], "=") + 1; + + unsigned reg = strtoul(s_reg, NULL, 16); + unsigned value = strtoul(s_value, NULL, 16); + + if(reg < 16) { + stlink_write_reg(sl, ntohl(value), reg); + } else if(reg == 0x19) { + stlink_write_reg(sl, ntohl(value), 16); + } else if(reg == 0x1A) { + stlink_write_reg(sl, ntohl(value), 17); + } else if(reg == 0x1B) { + stlink_write_reg(sl, ntohl(value), 18); + } else if(reg == 0x1C) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1D) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1E) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1F) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg >= 0x20 && reg < 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else { + reply = strdup("E00"); + } + + if(!reply) { + reply = strdup("OK"); + } + + break; + } + + case 'G': + for(int i = 0; i < 16; i++) { + char str[9] = {0}; + strncpy(str, &packet[1 + i * 8], 8); + uint32_t reg = strtoul(str, NULL, 16); + stlink_write_reg(sl, ntohl(reg), i); + } + + reply = strdup("OK"); + break; + + case 'm': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + + stm32_addr_t start = strtoul(s_start, NULL, 16); + unsigned count = strtoul(s_count, NULL, 16); + + unsigned adj_start = start % 4; + unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; + + stlink_read_mem32(sl, start - adj_start, count_rnd); + + reply = calloc(count * 2 + 1, 1); + for(unsigned int i = 0; i < count; i++) { + reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; + reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; + } + + break; + } + + case 'M': { + char* s_start = &packet[1]; + char* s_count = strstr(&packet[1], ",") + 1; + char* hexdata = strstr(packet, ":") + 1; + + stm32_addr_t start = strtoul(s_start, NULL, 16); + unsigned count = strtoul(s_count, NULL, 16); + + if(start % 4) { + unsigned align_count = 4 - start % 4; + if (align_count > count) align_count = count; + for(unsigned int i = 0; i < align_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, align_count); + start += align_count; + count -= align_count; + hexdata += 2*align_count; + } + + if(count - count % 4) { + unsigned aligned_count = count - count % 4; + + for(unsigned int i = 0; i < aligned_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem32(sl, start, aligned_count); + count -= aligned_count; + start += aligned_count; + hexdata += 2*aligned_count; + } + + if(count) { + for(unsigned int i = 0; i < count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, count); + } + reply = strdup("OK"); + break; + } + + case 'Z': { + char *endptr; + stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); + stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': + if(update_code_breakpoint(sl, addr, 1) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + } break; + + case '2': // insert write watchpoint + case '3': // insert read watchpoint + case '4': { // insert access watchpoint + enum watchfun wf; + if(packet[1] == '2') { + wf = WATCHWRITE; + } else if(packet[1] == '3') { + wf = WATCHREAD; + } else { + wf = WATCHACCESS; + } + + if(add_data_watchpoint(sl, wf, addr, len) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } } - } - - default: - reply = strdup(""); - } - break; - } - case 'z': { - char *endptr; - stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); - //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); - - switch (packet[1]) { - case '1': // remove breakpoint - update_code_breakpoint(sl, addr, 0); - reply = strdup("OK"); - break; - - case '2' : // remove write watchpoint - case '3' : // remove read watchpoint - case '4' : // remove access watchpoint - if(delete_data_watchpoint(sl, addr) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - break; - } - - default: - reply = strdup(""); - } - break; - } - - case '!': { - /* - * Enter extended mode which allows restarting. - * We do support that always. - */ - - /* - * Also, set to persistent mode - * to allow GDB disconnect. - */ - st->persistent = 1; - - reply = strdup("OK"); - - break; - } - - case 'R': { - /* Reset the core. */ - - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); - - attached = 1; - - reply = strdup("OK"); - - break; - } - - default: - reply = strdup(""); - } - - if(reply) { - #if DEBUG - printf("send: %s\n", reply); - #endif - - int result = gdb_send_packet(client, reply); - if(result != 0) { - fprintf(stderr, "cannot send: %d\n", result); - free(reply); - free(packet); - return 1; - } - - free(reply); - } - - free(packet); - } - - return 0; + + default: + reply = strdup(""); + } + break; + } + case 'z': { + char *endptr; + stm32_addr_t addr = strtoul(&packet[3], &endptr, 16); + //stm32_addr_t len = strtoul(&endptr[1], NULL, 16); + + switch (packet[1]) { + case '1': // remove breakpoint + update_code_breakpoint(sl, addr, 0); + reply = strdup("OK"); + break; + + case '2' : // remove write watchpoint + case '3' : // remove read watchpoint + case '4' : // remove access watchpoint + if(delete_data_watchpoint(sl, addr) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } + + default: + reply = strdup(""); + } + break; + } + + case '!': { + /* + * Enter extended mode which allows restarting. + * We do support that always. + */ + + /* + * Also, set to persistent mode + * to allow GDB disconnect. + */ + st->persistent = 1; + + reply = strdup("OK"); + + break; + } + + case 'R': { + /* Reset the core. */ + + stlink_reset(sl); + init_code_breakpoints(sl); + init_data_watchpoints(sl); + + attached = 1; + + reply = strdup("OK"); + + break; + } + + default: + reply = strdup(""); + } + + if(reply) { +#if DEBUG + printf("send: %s\n", reply); +#endif + + int result = gdb_send_packet(client, reply); + if(result != 0) { + fprintf(stderr, "cannot send: %d\n", result); + free(reply); + free(packet); + return 1; + } + + free(reply); + } + + free(packet); + } + + return 0; } diff --git a/gui/stlink-gui.c b/gui/stlink-gui.c index 3646c3a..f60e92d 100644 --- a/gui/stlink-gui.c +++ b/gui/stlink-gui.c @@ -17,117 +17,117 @@ G_DEFINE_TYPE (STlinkGUI, stlink_gui, G_TYPE_OBJECT); static void stlink_gui_dispose (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); + G_OBJECT_CLASS (stlink_gui_parent_class)->dispose (gobject); } static void stlink_gui_finalize (GObject *gobject) { - G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); + G_OBJECT_CLASS (stlink_gui_parent_class)->finalize (gobject); } static void stlink_gui_class_init (STlinkGUIClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = stlink_gui_dispose; - gobject_class->finalize = stlink_gui_finalize; + gobject_class->dispose = stlink_gui_dispose; + gobject_class->finalize = stlink_gui_finalize; } static void stlink_gui_init (STlinkGUI *self) { - self->sl = NULL; - self->filename = NULL; + self->sl = NULL; + self->filename = NULL; - self->progress.activity_mode = FALSE; - self->progress.fraction = 0; + self->progress.activity_mode = FALSE; + self->progress.fraction = 0; - self->flash_mem.memory = NULL; - self->flash_mem.size = 0; - self->flash_mem.base = 0; + self->flash_mem.memory = NULL; + self->flash_mem.size = 0; + self->flash_mem.base = 0; - self->file_mem.memory = NULL; - self->file_mem.size = 0; - self->file_mem.base = 0; + self->file_mem.memory = NULL; + self->file_mem.size = 0; + self->file_mem.base = 0; } static gboolean set_info_error_message_idle (STlinkGUI *gui) { - if (gui->error_message != NULL) { - gchar *markup; + if (gui->error_message != NULL) { + gchar *markup; - markup = g_markup_printf_escaped ("%s", gui->error_message); - gtk_label_set_markup (gui->infolabel, markup); - gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); - gtk_widget_show (GTK_WIDGET (gui->infobar)); + markup = g_markup_printf_escaped ("%s", gui->error_message); + gtk_label_set_markup (gui->infolabel, markup); + gtk_info_bar_set_message_type (gui->infobar, GTK_MESSAGE_ERROR); + gtk_widget_show (GTK_WIDGET (gui->infobar)); - g_free (markup); - g_free (gui->error_message); - gui->error_message = NULL; - } - return FALSE; + g_free (markup); + g_free (gui->error_message); + gui->error_message = NULL; + } + return FALSE; } static void stlink_gui_set_info_error_message (STlinkGUI *gui, const gchar *message) { - gui->error_message = g_strdup (message); - g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); + gui->error_message = g_strdup (message); + g_idle_add ((GSourceFunc) set_info_error_message_idle, gui); } static void stlink_gui_set_sensitivity (STlinkGUI *gui, gboolean sensitivity) { - gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); + gtk_widget_set_sensitive (GTK_WIDGET (gui->open_button), sensitivity); - if (sensitivity && gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); + if (sensitivity && gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), sensitivity); - if (sensitivity && !gui->sl) - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); + if (sensitivity && !gui->sl) + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), sensitivity); - if (sensitivity && gui->sl && gui->filename) - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); + if (sensitivity && gui->sl && gui->filename) + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), sensitivity); } static void mem_view_init_headers (GtkTreeView *view) { - GtkCellRenderer *renderer; - gint i; - - g_return_if_fail (view != NULL); - - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, - -1, - "Address", - renderer, - "text", - 0, /* column */ - NULL); - for (i = 0; i < 4; i++) { - gchar *label; - - label = g_strdup_printf ("%X", i * 4); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (view, - -1, - label, - renderer, - "text", - (i + 1), /* column */ - NULL); - g_free (label); - } - - for (i = 0; i < 5; i++) { - GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); - gtk_tree_view_column_set_expand (column, TRUE); - } + GtkCellRenderer *renderer; + gint i; + + g_return_if_fail (view != NULL); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + "Address", + renderer, + "text", + 0, /* column */ + NULL); + for (i = 0; i < 4; i++) { + gchar *label; + + label = g_strdup_printf ("%X", i * 4); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (view, + -1, + label, + renderer, + "text", + (i + 1), /* column */ + NULL); + g_free (label); + } + + for (i = 0; i < 5; i++) { + GtkTreeViewColumn *column = gtk_tree_view_get_column (view, i); + gtk_tree_view_column_set_expand (column, TRUE); + } } static void @@ -136,11 +136,11 @@ mem_view_add_as_hex (GtkListStore *store, gint column, guint32 value) { - gchar *hex_str; + gchar *hex_str; - hex_str = g_strdup_printf ("0x%08X", value); - gtk_list_store_set (store, iter, column, hex_str, -1); - g_free (hex_str); + hex_str = g_strdup_printf ("0x%08X", value); + gtk_list_store_set (store, iter, column, hex_str, -1); + g_free (hex_str); } static void @@ -150,194 +150,194 @@ mem_view_add_buffer (GtkListStore *store, guchar *buffer, gint len) { - guint32 *word; - gint i, step; - gint column = 0; + guint32 *word; + gint i, step; + gint column = 0; - step = sizeof (*word); + step = sizeof (*word); - for (i = 0; i < len; i += step) { - word = (guint *) &buffer[i]; + for (i = 0; i < len; i += step) { + word = (guint *) &buffer[i]; - if (column == 0) { - /* new row */ - gtk_list_store_append (store, iter); + if (column == 0) { + /* new row */ + gtk_list_store_append (store, iter); - /* add address */ - mem_view_add_as_hex (store, iter, column, (address + i)); - } - mem_view_add_as_hex (store, iter, (column + 1), *word); - column = (column + 1) % step; - } + /* add address */ + mem_view_add_as_hex (store, iter, column, (address + i)); + } + mem_view_add_as_hex (store, iter, (column + 1), *word); + column = (column + 1) % step; + } } static guint32 hexstr_to_guint32 (const gchar *str, GError **err) { - guint32 val; - gchar *end_ptr; + guint32 val; + gchar *end_ptr; - val = strtoul (str, &end_ptr, 16); - if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 1, - "Invalid hexstring"); - return LONG_MAX; - } - if (end_ptr == str) { - g_set_error (err, - g_quark_from_string ("hextou32"), - 2, - "Invalid hexstring"); - return LONG_MAX; - } - return val; + val = strtoul (str, &end_ptr, 16); + if ((errno == ERANGE && val == LONG_MAX) || (errno != 0 && val == 0)) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 1, + "Invalid hexstring"); + return LONG_MAX; + } + if (end_ptr == str) { + g_set_error (err, + g_quark_from_string ("hextou32"), + 2, + "Invalid hexstring"); + return LONG_MAX; + } + return val; } static void stlink_gui_update_mem_view (STlinkGUI *gui, struct mem_t *mem, GtkTreeView *view) { - GtkListStore *store; - GtkTreeIter iter; + GtkListStore *store; + GtkTreeIter iter; - store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); + store = GTK_LIST_STORE (gtk_tree_view_get_model (view)); - mem_view_add_buffer (store, - &iter, - mem->base, - mem->memory, - mem->size); + mem_view_add_buffer (store, + &iter, + mem->base, + mem->memory, + mem->size); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_fraction (gui->progress.bar, 0); - stlink_gui_set_sensitivity (gui, TRUE); + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_fraction (gui->progress.bar, 0); + stlink_gui_set_sensitivity (gui, TRUE); } static gboolean stlink_gui_update_devmem_view (STlinkGUI *gui) { - stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); - return FALSE; + stlink_gui_update_mem_view (gui, &gui->flash_mem, gui->devmem_treeview); + return FALSE; } static void stlink_gui_populate_devmem_view (STlinkGUI *gui) { - guint off; - stm32_addr_t addr; - - g_return_if_fail (gui != NULL); - g_return_if_fail (gui->sl != NULL); - - addr = gui->sl->flash_base; - - if (gui->flash_mem.memory) { - g_free (gui->flash_mem.memory); - } - gui->flash_mem.memory = g_malloc (gui->sl->flash_size); - gui->flash_mem.size = gui->sl->flash_size; - gui->flash_mem.base = gui->sl->flash_base; - - for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > gui->sl->flash_size) { - n_read = gui->sl->flash_size - off; - - /* align if needed */ - if (n_read & 3) { - n_read = (n_read + 4) & ~(3); - } - } - /* reads to sl->q_buf */ - stlink_read_mem32(gui->sl, addr + off, n_read); - if (gui->sl->q_len < 0) { - stlink_gui_set_info_error_message (gui, "Failed to read memory"); - g_free (gui->flash_mem.memory); - gui->flash_mem.memory = NULL; - return; - } - memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; - } - g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); + guint off; + stm32_addr_t addr; + + g_return_if_fail (gui != NULL); + g_return_if_fail (gui->sl != NULL); + + addr = gui->sl->flash_base; + + if (gui->flash_mem.memory) { + g_free (gui->flash_mem.memory); + } + gui->flash_mem.memory = g_malloc (gui->sl->flash_size); + gui->flash_mem.size = gui->sl->flash_size; + gui->flash_mem.base = gui->sl->flash_base; + + for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->sl->flash_size) { + n_read = gui->sl->flash_size - off; + + /* align if needed */ + if (n_read & 3) { + n_read = (n_read + 4) & ~(3); + } + } + /* reads to sl->q_buf */ + stlink_read_mem32(gui->sl, addr + off, n_read); + if (gui->sl->q_len < 0) { + stlink_gui_set_info_error_message (gui, "Failed to read memory"); + g_free (gui->flash_mem.memory); + gui->flash_mem.memory = NULL; + return; + } + memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); } static gboolean stlink_gui_update_filemem_view (STlinkGUI *gui) { - gchar *basename; + gchar *basename; - basename = g_path_get_basename (gui->filename); - gtk_notebook_set_tab_label_text (gui->notebook, - GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), - basename); - g_free (basename); + basename = g_path_get_basename (gui->filename); + gtk_notebook_set_tab_label_text (gui->notebook, + GTK_WIDGET (gtk_notebook_get_nth_page (gui->notebook, 1)), + basename); + g_free (basename); - stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); + stlink_gui_update_mem_view (gui, &gui->file_mem, gui->filemem_treeview); - return FALSE; + return FALSE; } static gpointer stlink_gui_populate_filemem_view (STlinkGUI *gui) { - guchar buffer[MEM_READ_SIZE]; - GFile *file; - GFileInfo *file_info; - GInputStream *input_stream; - gint off; - GError *err = NULL; - - g_return_val_if_fail (gui != NULL, NULL); - g_return_val_if_fail (gui->filename != NULL, NULL); - - file = g_file_new_for_path (gui->filename); - input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out; - } - - file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), - G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - if (gui->file_mem.memory) { - g_free (gui->file_mem.memory); - } - gui->file_mem.size = g_file_info_get_size (file_info); - gui->file_mem.memory = g_malloc (gui->file_mem.size); - - for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { - guint n_read = MEM_READ_SIZE; - - if (off + MEM_READ_SIZE > gui->file_mem.size) { - n_read = gui->file_mem.size - off; - } - - if (g_input_stream_read (G_INPUT_STREAM (input_stream), - &buffer, n_read, NULL, &err) == -1) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - goto out_input; - } - memcpy (gui->file_mem.memory + off, buffer, n_read); - gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; - } - g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); - - out_input: - g_object_unref (input_stream); - out: - g_object_unref (file); - return NULL; + guchar buffer[MEM_READ_SIZE]; + GFile *file; + GFileInfo *file_info; + GInputStream *input_stream; + gint off; + GError *err = NULL; + + g_return_val_if_fail (gui != NULL, NULL); + g_return_val_if_fail (gui->filename != NULL, NULL); + + file = g_file_new_for_path (gui->filename); + input_stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out; + } + + file_info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (input_stream), + G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + if (gui->file_mem.memory) { + g_free (gui->file_mem.memory); + } + gui->file_mem.size = g_file_info_get_size (file_info); + gui->file_mem.memory = g_malloc (gui->file_mem.size); + + for (off = 0; off < gui->file_mem.size; off += MEM_READ_SIZE) { + guint n_read = MEM_READ_SIZE; + + if (off + MEM_READ_SIZE > gui->file_mem.size) { + n_read = gui->file_mem.size - off; + } + + if (g_input_stream_read (G_INPUT_STREAM (input_stream), + &buffer, n_read, NULL, &err) == -1) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + goto out_input; + } + memcpy (gui->file_mem.memory + off, buffer, n_read); + gui->progress.fraction = (gdouble) (off + n_read) / gui->file_mem.size; + } + g_idle_add ((GSourceFunc) stlink_gui_update_filemem_view, gui); + +out_input: + g_object_unref (input_stream); +out: + g_object_unref (file); + return NULL; } static void mem_jmp (GtkTreeView *view, @@ -346,362 +346,362 @@ static void mem_jmp (GtkTreeView *view, gsize size, GError **err) { - GtkTreeModel *model; - guint32 jmp_addr; - GtkTreeIter iter; - - jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); - if (err && *err) { - return; - } - - if (jmp_addr < base_addr || jmp_addr > base_addr + size) { - g_set_error (err, - g_quark_from_string ("mem_jmp"), - 1, - "Invalid address"); - return; - } - - model = gtk_tree_view_get_model (view); - if (!model) { - return; - } - - if (gtk_tree_model_get_iter_first (model, &iter)) { - do { - guint32 addr; - GValue value = G_VALUE_INIT; - GError *err = NULL; - - gtk_tree_model_get_value (model, &iter, 0, &value); - if (G_VALUE_HOLDS_STRING (&value)) { - addr = hexstr_to_guint32 (g_value_get_string (&value), &err); - if (!err) { - if (addr == (jmp_addr & 0xFFFFFFF0)) { - GtkTreeSelection *selection; - GtkTreePath *path; - - selection = gtk_tree_view_get_selection (view); - path = gtk_tree_model_get_path (model, &iter); - - gtk_tree_selection_select_iter (selection, &iter); - gtk_tree_view_scroll_to_cell (view, - path, - NULL, - TRUE, - 0.0, - 0.0); - gtk_tree_path_free (path); - } - } - } - g_value_unset (&value); - } while (gtk_tree_model_iter_next (model, &iter)); - } + GtkTreeModel *model; + guint32 jmp_addr; + GtkTreeIter iter; + + jmp_addr = hexstr_to_guint32 (gtk_entry_get_text (entry), err); + if (err && *err) { + return; + } + + if (jmp_addr < base_addr || jmp_addr > base_addr + size) { + g_set_error (err, + g_quark_from_string ("mem_jmp"), + 1, + "Invalid address"); + return; + } + + model = gtk_tree_view_get_model (view); + if (!model) { + return; + } + + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + guint32 addr; + GValue value = G_VALUE_INIT; + GError *err = NULL; + + gtk_tree_model_get_value (model, &iter, 0, &value); + if (G_VALUE_HOLDS_STRING (&value)) { + addr = hexstr_to_guint32 (g_value_get_string (&value), &err); + if (!err) { + if (addr == (jmp_addr & 0xFFFFFFF0)) { + GtkTreeSelection *selection; + GtkTreePath *path; + + selection = gtk_tree_view_get_selection (view); + path = gtk_tree_model_get_path (model, &iter); + + gtk_tree_selection_select_iter (selection, &iter); + gtk_tree_view_scroll_to_cell (view, + path, + NULL, + TRUE, + 0.0, + 0.0); + gtk_tree_path_free (path); + } + } + } + g_value_unset (&value); + } while (gtk_tree_model_iter_next (model, &iter)); + } } static void devmem_jmp_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - GError *err = NULL; + STlinkGUI *gui; + GError *err = NULL; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - mem_jmp (gui->devmem_treeview, - gui->devmem_jmp_entry, - gui->sl->flash_base, - gui->sl->flash_size, - &err); + mem_jmp (gui->devmem_treeview, + gui->devmem_jmp_entry, + gui->sl->flash_base, + gui->sl->flash_size, + &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - } + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } } static void filemem_jmp_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - GError *err = NULL; + STlinkGUI *gui; + GError *err = NULL; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - g_return_if_fail (gui->filename != NULL); + g_return_if_fail (gui->filename != NULL); - mem_jmp (gui->filemem_treeview, - gui->filemem_jmp_entry, - 0, - gui->file_mem.size, - &err); + mem_jmp (gui->filemem_treeview, + gui->filemem_jmp_entry, + 0, + gui->file_mem.size, + &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - g_error_free (err); - } + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + g_error_free (err); + } } static gchar * dev_format_chip_id (guint32 chip_id) { - gint i; + gint i; - for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { - if (chip_id == devices[i].chip_id) { - return g_strdup (devices[i].description); - } - } - return g_strdup_printf ("0x%x", chip_id); + for (i = 0; i < sizeof (devices) / sizeof (devices[0]); i++) { + if (chip_id == devices[i].chip_id) { + return g_strdup (devices[i].description); + } + } + return g_strdup_printf ("0x%x", chip_id); } static gchar * dev_format_mem_size (gsize flash_size) { - return g_strdup_printf ("%u kB", flash_size / 1024); + return g_strdup_printf ("%u kB", flash_size / 1024); } static void stlink_gui_set_connected (STlinkGUI *gui) { - gchar *tmp_str; - GtkListStore *store; - GtkTreeIter iter; + gchar *tmp_str; + GtkListStore *store; + GtkTreeIter iter; - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Connected"); + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Connected"); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->devmem_box), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), FALSE); - if (gui->filename) { - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); - } + if (gui->filename) { + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), TRUE); + } - tmp_str = dev_format_chip_id (gui->sl->chip_id); - gtk_label_set_text (gui->chip_id_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_chip_id (gui->sl->chip_id); + gtk_label_set_text (gui->chip_id_label, tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); - gtk_label_set_text (gui->core_id_label, tmp_str); - g_free (tmp_str); + tmp_str = g_strdup_printf ("0x%x", gui->sl->core_id); + gtk_label_set_text (gui->core_id_label, tmp_str); + g_free (tmp_str); - tmp_str = dev_format_mem_size (gui->sl->flash_size); - gtk_label_set_text (gui->flash_size_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size (gui->sl->flash_size); + gtk_label_set_text (gui->flash_size_label, tmp_str); + g_free (tmp_str); - tmp_str = dev_format_mem_size (gui->sl->sram_size); - gtk_label_set_text (gui->ram_size_label, tmp_str); - g_free (tmp_str); + tmp_str = dev_format_mem_size (gui->sl->sram_size); + gtk_label_set_text (gui->ram_size_label, tmp_str); + g_free (tmp_str); - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); - gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); - g_free (tmp_str); + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->devmem_jmp_entry, tmp_str); + gtk_editable_set_editable (GTK_EDITABLE (gui->devmem_jmp_entry), TRUE); + g_free (tmp_str); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_DEVMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading memory"); - g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); + g_thread_new ("devmem", (GThreadFunc) stlink_gui_populate_devmem_view, gui); } static void connect_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - gint i; + STlinkGUI *gui; + gint i; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (gui->sl != NULL) - return; + if (gui->sl != NULL) + return; - /* try version 1 then version 2 */ - gui->sl = stlink_v1_open(0, 1); - if (gui->sl == NULL) { - gui->sl = stlink_open_usb(0, 1); - } - if (gui->sl == NULL) { - stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; - } + /* try version 1 then version 2 */ + gui->sl = stlink_v1_open(0, 1); + if (gui->sl == NULL) { + gui->sl = stlink_open_usb(0, 1); + } + if (gui->sl == NULL) { + stlink_gui_set_info_error_message (gui, "Failed to connect to STLink."); return; + } - /* code below taken from flash/main.c, refactoring might be in order */ - if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(gui->sl); + /* code below taken from flash/main.c, refactoring might be in order */ + if (stlink_current_mode(gui->sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(gui->sl); - if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(gui->sl); + if (stlink_current_mode(gui->sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(gui->sl); - /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ - if (gui->sl->chip_id == STM32_CHIPID_F4) { - memset(gui->sl->q_buf, 0, 4); - for (i = 0; i < 8; i++) { - stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); - stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); - } - } - stlink_gui_set_connected (gui); + /* Disable DMA - Set All DMA CCR Registers to zero. - AKS 1/7/2013 */ + if (gui->sl->chip_id == STM32_CHIPID_F4) { + memset(gui->sl->q_buf, 0, 4); + for (i = 0; i < 8; i++) { + stlink_write_mem32(gui->sl, 0x40026000 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x10 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026000 + 0x24 + 0x18 * i, 4); + stlink_write_mem32(gui->sl, 0x40026400 + 0x24 + 0x18 * i, 4); + } + } + stlink_gui_set_connected (gui); } static void stlink_gui_set_disconnected (STlinkGUI *gui) { - gtk_statusbar_push (gui->statusbar, - gtk_statusbar_get_context_id (gui->statusbar, "conn"), - "Disconnected"); + gtk_statusbar_push (gui->statusbar, + gtk_statusbar_get_context_id (gui->statusbar, "conn"), + "Disconnected"); - gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->device_frame), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->flash_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->disconnect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (gui->connect_button), TRUE); } static void disconnect_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (gui->sl != NULL) { - stlink_exit_debug_mode(gui->sl); - stlink_close(gui->sl); - gui->sl = NULL; - } - stlink_gui_set_disconnected (gui); + if (gui->sl != NULL) { + stlink_exit_debug_mode(gui->sl); + stlink_close(gui->sl); + gui->sl = NULL; + } + stlink_gui_set_disconnected (gui); } static void stlink_gui_open_file (STlinkGUI *gui) { - GtkWidget *dialog; - GtkListStore *store; - GtkTreeIter iter; + GtkWidget *dialog; + GtkListStore *store; + GtkTreeIter iter; - dialog = gtk_file_chooser_dialog_new ("Open file", - gui->window, - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); + dialog = gtk_file_chooser_dialog_new ("Open file", + gui->window, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - gui->filename = - gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + gui->filename = + gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->filemem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); - } - gtk_widget_destroy (dialog); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + } + gtk_widget_destroy (dialog); } static void open_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - stlink_gui_open_file (gui); + stlink_gui_open_file (gui); } static gboolean stlink_gui_write_flash_update (STlinkGUI *gui) { - stlink_gui_set_sensitivity (gui, TRUE); - gui->progress.activity_mode = FALSE; - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + stlink_gui_set_sensitivity (gui, TRUE); + gui->progress.activity_mode = FALSE; + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - return FALSE; + return FALSE; } static void stlink_gui_write_flash (STlinkGUI *gui) { - g_return_if_fail (gui->sl != NULL); - g_return_if_fail (gui->filename != NULL); + g_return_if_fail (gui->sl != NULL); + g_return_if_fail (gui->filename != NULL); - if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { - stlink_gui_set_info_error_message (gui, "Failed to write to flash"); - } + if (stlink_fwrite_flash(gui->sl, gui->filename, gui->sl->flash_base) < 0) { + stlink_gui_set_info_error_message (gui, "Failed to write to flash"); + } - g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); + g_idle_add ((GSourceFunc) stlink_gui_write_flash_update, gui); } static void flash_button_cb (GtkWidget *widget, gpointer data) { - STlinkGUI *gui; - gchar *tmp_str; - guint32 address; - gint result; - GError *err = NULL; - - gui = STLINK_GUI (data); - g_return_if_fail (gui->sl != NULL); - - if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { - tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); - gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); - g_free (tmp_str); - } - - result = gtk_dialog_run (gui->flash_dialog); - if (result == GTK_RESPONSE_OK) { - address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), - &err); - if (err) { - stlink_gui_set_info_error_message (gui, err->message); - } else { - if (address > gui->sl->flash_base + gui->sl->flash_size || - address < gui->sl->flash_base) { - stlink_gui_set_info_error_message (gui, "Invalid address"); - } - else if (address + gui->file_mem.size > - gui->sl->flash_base + gui->sl->flash_size) { - stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); - } else { - stlink_gui_set_sensitivity (gui, FALSE); - gtk_progress_bar_set_text (gui->progress.bar, - "Writing to flash"); - gui->progress.activity_mode = TRUE; - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - g_thread_new ("flash", - (GThreadFunc) stlink_gui_write_flash, gui); - } - } - } + STlinkGUI *gui; + gchar *tmp_str; + guint32 address; + gint result; + GError *err = NULL; + + gui = STLINK_GUI (data); + g_return_if_fail (gui->sl != NULL); + + if (!g_strcmp0 (gtk_entry_get_text (gui->flash_dialog_entry), "")) { + tmp_str = g_strdup_printf ("0x%08X", gui->sl->flash_base); + gtk_entry_set_text (gui->flash_dialog_entry, tmp_str); + g_free (tmp_str); + } + + result = gtk_dialog_run (gui->flash_dialog); + if (result == GTK_RESPONSE_OK) { + address = hexstr_to_guint32 (gtk_entry_get_text (gui->flash_dialog_entry), + &err); + if (err) { + stlink_gui_set_info_error_message (gui, err->message); + } else { + if (address > gui->sl->flash_base + gui->sl->flash_size || + address < gui->sl->flash_base) { + stlink_gui_set_info_error_message (gui, "Invalid address"); + } + else if (address + gui->file_mem.size > + gui->sl->flash_base + gui->sl->flash_size) { + stlink_gui_set_info_error_message (gui, "Binary overwrites flash"); + } else { + stlink_gui_set_sensitivity (gui, FALSE); + gtk_progress_bar_set_text (gui->progress.bar, + "Writing to flash"); + gui->progress.activity_mode = TRUE; + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + g_thread_new ("flash", + (GThreadFunc) stlink_gui_write_flash, gui); + } + } + } } static gboolean progress_pulse_timeout (STlinkGUI *gui) { - if (gui->progress.activity_mode) { - gtk_progress_bar_pulse (gui->progress.bar); - } else { - gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); - } - return TRUE; + if (gui->progress.activity_mode) { + gtk_progress_bar_pulse (gui->progress.bar); + } else { + gtk_progress_bar_set_fraction (gui->progress.bar, gui->progress.fraction); + } + return TRUE; } static void @@ -710,15 +710,15 @@ notebook_switch_page_cb (GtkNotebook *notebook, guint page_num, gpointer data) { - STlinkGUI *gui; + STlinkGUI *gui; - gui = STLINK_GUI (data); + gui = STLINK_GUI (data); - if (page_num == 1) { - if (gui->filename == NULL) { - stlink_gui_open_file (gui); - } - } + if (page_num == 1) { + if (gui->filename == NULL) { + stlink_gui_open_file (gui); + } + } } static void @@ -731,225 +731,225 @@ dnd_received_cb (GtkWidget *widget, guint time, gpointer data) { - GFile *file_uri; - gchar **file_list; - const guchar *file_data; - STlinkGUI *gui = STLINK_GUI (data); - GtkListStore *store; - GtkTreeIter iter; + GFile *file_uri; + gchar **file_list; + const guchar *file_data; + STlinkGUI *gui = STLINK_GUI (data); + GtkListStore *store; + GtkTreeIter iter; - if (selection_data != NULL && - gtk_selection_data_get_length (selection_data) > 0) { - switch (target_type) { - case TARGET_FILENAME: + if (selection_data != NULL && + gtk_selection_data_get_length (selection_data) > 0) { + switch (target_type) { + case TARGET_FILENAME: - if (gui->filename) { - g_free (gui->filename); - } + if (gui->filename) { + g_free (gui->filename); + } - file_data = gtk_selection_data_get_data (selection_data); - file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); + file_data = gtk_selection_data_get_data (selection_data); + file_list = g_strsplit ((gchar *)file_data, "\r\n", 0); - file_uri = g_file_new_for_uri (file_list[0]); - gui->filename = g_file_get_path (file_uri); + file_uri = g_file_new_for_uri (file_list[0]); + gui->filename = g_file_get_path (file_uri); - g_strfreev (file_list); - g_object_unref (file_uri); + g_strfreev (file_list); + g_object_unref (file_uri); - store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); - if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { - gtk_list_store_clear (store); - } + store = GTK_LIST_STORE (gtk_tree_view_get_model (gui->devmem_treeview)); + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) { + gtk_list_store_clear (store); + } - stlink_gui_set_sensitivity (gui, FALSE); - gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); - gtk_widget_show (GTK_WIDGET (gui->progress.bar)); - gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); - g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); - break; - } - } - gtk_drag_finish (context, - TRUE, - gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, - time); + stlink_gui_set_sensitivity (gui, FALSE); + gtk_notebook_set_current_page (gui->notebook, PAGE_FILEMEM); + gtk_widget_show (GTK_WIDGET (gui->progress.bar)); + gtk_progress_bar_set_text (gui->progress.bar, "Reading file"); + g_thread_new ("file", (GThreadFunc) stlink_gui_populate_filemem_view, gui); + break; + } + } + gtk_drag_finish (context, + TRUE, + gdk_drag_context_get_suggested_action (context) == GDK_ACTION_MOVE, + time); } void stlink_gui_init_dnd (STlinkGUI *gui) { - GtkTargetEntry target_list[] = { - { "text/uri-list", 0, TARGET_FILENAME }, - }; + GtkTargetEntry target_list[] = { + { "text/uri-list", 0, TARGET_FILENAME }, + }; - gtk_drag_dest_set (GTK_WIDGET (gui->window), - GTK_DEST_DEFAULT_ALL, - target_list, - G_N_ELEMENTS (target_list), - GDK_ACTION_COPY); + gtk_drag_dest_set (GTK_WIDGET (gui->window), + GTK_DEST_DEFAULT_ALL, + target_list, + G_N_ELEMENTS (target_list), + GDK_ACTION_COPY); - g_signal_connect (gui->window, "drag-data-received", - G_CALLBACK (dnd_received_cb), gui); + g_signal_connect (gui->window, "drag-data-received", + G_CALLBACK (dnd_received_cb), gui); } static void stlink_gui_build_ui (STlinkGUI *gui) { - GtkBuilder *builder; - GtkListStore *devmem_store; - GtkListStore *filemem_store; - gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; - - if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { - ui_file = "stlink-gui.ui"; - } - builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { - g_printerr ("Failed to load UI file: %s\n", ui_file); - exit (1); - } - - gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); - g_signal_connect (G_OBJECT (gui->window), "destroy", - G_CALLBACK (gtk_main_quit), NULL); - - /* set up toolutton clicked callbacks */ - gui->open_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); - g_signal_connect (G_OBJECT (gui->open_button), "clicked", - G_CALLBACK (open_button_cb), gui); - - gui->connect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); - g_signal_connect (G_OBJECT (gui->connect_button), "clicked", - G_CALLBACK (connect_button_cb), gui); - - gui->disconnect_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); - g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", - G_CALLBACK (disconnect_button_cb), gui); - - gui->flash_button = - GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); - g_signal_connect (G_OBJECT (gui->flash_button), "clicked", - G_CALLBACK (flash_button_cb), gui); - - gui->devmem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); - gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); - mem_view_init_headers (gui->devmem_treeview); - devmem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); - g_object_unref (devmem_store); - - gui->filemem_treeview = - GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); - gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); - mem_view_init_headers (gui->filemem_treeview); - filemem_store = gtk_list_store_new (5, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); - gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); - g_object_unref (filemem_store); - - gui->core_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); - - gui->chip_id_label = - GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); - - gui->flash_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); - - gui->ram_size_label = - GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); - - gui->device_frame = - GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); - - gui->notebook = - GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); - g_signal_connect (gui->notebook, "switch-page", - G_CALLBACK (notebook_switch_page_cb), gui); - - gui->devmem_box = - GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); - - gui->filemem_box = - GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); - - gui->devmem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); - g_signal_connect (gui->devmem_jmp_entry, "activate", - G_CALLBACK (devmem_jmp_cb), gui); - - gui->filemem_jmp_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); - g_signal_connect (gui->filemem_jmp_entry, "activate", - G_CALLBACK (filemem_jmp_cb), gui); - gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); - - gui->progress.bar = - GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); - gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); - gui->progress.timer = g_timeout_add (100, - (GSourceFunc) progress_pulse_timeout, - gui); - - gui->statusbar = - GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); - - gui->infobar = - GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); - gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); - gui->infolabel = GTK_LABEL (gtk_label_new ("")); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), - GTK_WIDGET (gui->infolabel)); - g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); - - /* flash dialog */ - gui->flash_dialog = - GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); - g_signal_connect_swapped (gui->flash_dialog, "response", - G_CALLBACK (gtk_widget_hide), gui->flash_dialog); - - gui->flash_dialog_ok = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); - - gui->flash_dialog_cancel = - GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); - - gui->flash_dialog_entry = - GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); - - /* make it so */ - gtk_widget_show_all (GTK_WIDGET (gui->window)); - gtk_widget_hide (GTK_WIDGET (gui->infobar)); - gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); - - stlink_gui_set_disconnected (gui); + GtkBuilder *builder; + GtkListStore *devmem_store; + GtkListStore *filemem_store; + gchar *ui_file = STLINK_UI_DIR "/stlink-gui.ui"; + + if (!g_file_test (ui_file, G_FILE_TEST_EXISTS)) { + ui_file = "stlink-gui.ui"; + } + builder = gtk_builder_new (); + if (!gtk_builder_add_from_file (builder, ui_file, NULL)) { + g_printerr ("Failed to load UI file: %s\n", ui_file); + exit (1); + } + + gui->window = GTK_WINDOW (gtk_builder_get_object (builder, "window")); + g_signal_connect (G_OBJECT (gui->window), "destroy", + G_CALLBACK (gtk_main_quit), NULL); + + /* set up toolutton clicked callbacks */ + gui->open_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "open_button")); + g_signal_connect (G_OBJECT (gui->open_button), "clicked", + G_CALLBACK (open_button_cb), gui); + + gui->connect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "connect_button")); + g_signal_connect (G_OBJECT (gui->connect_button), "clicked", + G_CALLBACK (connect_button_cb), gui); + + gui->disconnect_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "disconnect_button")); + g_signal_connect (G_OBJECT (gui->disconnect_button), "clicked", + G_CALLBACK (disconnect_button_cb), gui); + + gui->flash_button = + GTK_TOOL_BUTTON (gtk_builder_get_object (builder, "flash_button")); + g_signal_connect (G_OBJECT (gui->flash_button), "clicked", + G_CALLBACK (flash_button_cb), gui); + + gui->devmem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "devmem_treeview")); + gtk_tree_view_set_rules_hint (gui->devmem_treeview, TRUE); + mem_view_init_headers (gui->devmem_treeview); + devmem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->devmem_treeview, GTK_TREE_MODEL (devmem_store)); + g_object_unref (devmem_store); + + gui->filemem_treeview = + GTK_TREE_VIEW (gtk_builder_get_object (builder, "filemem_treeview")); + gtk_tree_view_set_rules_hint (gui->filemem_treeview, TRUE); + mem_view_init_headers (gui->filemem_treeview); + filemem_store = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING); + gtk_tree_view_set_model (gui->filemem_treeview, GTK_TREE_MODEL (filemem_store)); + g_object_unref (filemem_store); + + gui->core_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "core_id_value")); + + gui->chip_id_label = + GTK_LABEL (gtk_builder_get_object (builder, "chip_id_value")); + + gui->flash_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "flash_size_value")); + + gui->ram_size_label = + GTK_LABEL (gtk_builder_get_object (builder, "ram_size_value")); + + gui->device_frame = + GTK_FRAME (gtk_builder_get_object (builder, "device_frame")); + + gui->notebook = + GTK_NOTEBOOK (gtk_builder_get_object (builder, "mem_notebook")); + g_signal_connect (gui->notebook, "switch-page", + G_CALLBACK (notebook_switch_page_cb), gui); + + gui->devmem_box = + GTK_BOX (gtk_builder_get_object (builder, "devmem_box")); + + gui->filemem_box = + GTK_BOX (gtk_builder_get_object (builder, "filemem_box")); + + gui->devmem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "devmem_jmp_entry")); + g_signal_connect (gui->devmem_jmp_entry, "activate", + G_CALLBACK (devmem_jmp_cb), gui); + + gui->filemem_jmp_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "filemem_jmp_entry")); + g_signal_connect (gui->filemem_jmp_entry, "activate", + G_CALLBACK (filemem_jmp_cb), gui); + gtk_editable_set_editable (GTK_EDITABLE (gui->filemem_jmp_entry), TRUE); + + gui->progress.bar = + GTK_PROGRESS_BAR (gtk_builder_get_object (builder, "progressbar")); + gtk_progress_bar_set_show_text (gui->progress.bar, TRUE); + gui->progress.timer = g_timeout_add (100, + (GSourceFunc) progress_pulse_timeout, + gui); + + gui->statusbar = + GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + + gui->infobar = + GTK_INFO_BAR (gtk_builder_get_object (builder, "infobar")); + gtk_info_bar_add_button (gui->infobar, GTK_STOCK_OK, GTK_RESPONSE_OK); + gui->infolabel = GTK_LABEL (gtk_label_new ("")); + gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (gui->infobar)), + GTK_WIDGET (gui->infolabel)); + g_signal_connect (gui->infobar, "response", G_CALLBACK (gtk_widget_hide), NULL); + + /* flash dialog */ + gui->flash_dialog = + GTK_DIALOG (gtk_builder_get_object (builder, "flash_dialog")); + g_signal_connect_swapped (gui->flash_dialog, "response", + G_CALLBACK (gtk_widget_hide), gui->flash_dialog); + + gui->flash_dialog_ok = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_ok_button")); + + gui->flash_dialog_cancel = + GTK_BUTTON (gtk_builder_get_object (builder, "flash_dialog_cancel_button")); + + gui->flash_dialog_entry = + GTK_ENTRY (gtk_builder_get_object (builder, "flash_dialog_entry")); + + /* make it so */ + gtk_widget_show_all (GTK_WIDGET (gui->window)); + gtk_widget_hide (GTK_WIDGET (gui->infobar)); + gtk_widget_hide (GTK_WIDGET (gui->progress.bar)); + + stlink_gui_set_disconnected (gui); } int main (int argc, char **argv) { - STlinkGUI *gui; + STlinkGUI *gui; - gtk_init (&argc, &argv); + gtk_init (&argc, &argv); - gui = g_object_new (STLINK_TYPE_GUI, NULL); - stlink_gui_build_ui (gui); - stlink_gui_init_dnd (gui); + gui = g_object_new (STLINK_TYPE_GUI, NULL); + stlink_gui_build_ui (gui); + stlink_gui_init_dnd (gui); - gtk_main (); + gtk_main (); - return 0; + return 0; } diff --git a/gui/stlink-gui.h b/gui/stlink-gui.h index a91c869..0c90648 100644 --- a/gui/stlink-gui.h +++ b/gui/stlink-gui.h @@ -17,75 +17,75 @@ typedef struct _STlinkGUIClass STlinkGUIClass; typedef struct _STlinkGUIPrivate STlinkGUIPrivate; enum stlink_gui_pages_t { - PAGE_DEVMEM, - PAGE_FILEMEM + PAGE_DEVMEM, + PAGE_FILEMEM }; enum stlink_gui_dnd_targets_t { - TARGET_FILENAME, - TARGET_ROOTWIN + TARGET_FILENAME, + TARGET_ROOTWIN }; struct progress_t { - GtkProgressBar *bar; - guint timer; - gboolean activity_mode; - gdouble fraction; + GtkProgressBar *bar; + guint timer; + gboolean activity_mode; + gdouble fraction; }; struct mem_t { - guchar *memory; - gsize size; - guint32 base; + guchar *memory; + gsize size; + guint32 base; }; struct _STlinkGUI { - GObject parent_instance; - - /*< private >*/ - GtkWindow *window; - GtkTreeView *devmem_treeview; - GtkTreeView *filemem_treeview; - GtkSpinner *spinner; - GtkStatusbar *statusbar; - GtkInfoBar *infobar; - GtkLabel *infolabel; - GtkNotebook *notebook; - GtkFrame *device_frame; - GtkLabel *chip_id_label; - GtkLabel *core_id_label; - GtkLabel *flash_size_label; - GtkLabel *ram_size_label; - GtkBox *devmem_box; - GtkEntry *devmem_jmp_entry; - GtkBox *filemem_box; - GtkEntry *filemem_jmp_entry; - GtkToolButton *connect_button; - GtkToolButton *disconnect_button; - GtkToolButton *flash_button; - GtkToolButton *open_button; - - /* flash dialog */ - GtkDialog *flash_dialog; - GtkButton *flash_dialog_ok; - GtkButton *flash_dialog_cancel; - GtkEntry *flash_dialog_entry; - - struct progress_t progress; - struct mem_t flash_mem; - struct mem_t file_mem; - - gchar *error_message; - gchar *filename; - stlink_t *sl; + GObject parent_instance; + + /*< private >*/ + GtkWindow *window; + GtkTreeView *devmem_treeview; + GtkTreeView *filemem_treeview; + GtkSpinner *spinner; + GtkStatusbar *statusbar; + GtkInfoBar *infobar; + GtkLabel *infolabel; + GtkNotebook *notebook; + GtkFrame *device_frame; + GtkLabel *chip_id_label; + GtkLabel *core_id_label; + GtkLabel *flash_size_label; + GtkLabel *ram_size_label; + GtkBox *devmem_box; + GtkEntry *devmem_jmp_entry; + GtkBox *filemem_box; + GtkEntry *filemem_jmp_entry; + GtkToolButton *connect_button; + GtkToolButton *disconnect_button; + GtkToolButton *flash_button; + GtkToolButton *open_button; + + /* flash dialog */ + GtkDialog *flash_dialog; + GtkButton *flash_dialog_ok; + GtkButton *flash_dialog_cancel; + GtkEntry *flash_dialog_entry; + + struct progress_t progress; + struct mem_t flash_mem; + struct mem_t file_mem; + + gchar *error_message; + gchar *filename; + stlink_t *sl; }; struct _STlinkGUIClass { - GObjectClass parent_class; + GObjectClass parent_class; - /* class members */ + /* class members */ }; GType stlink_gui_get_type (void); diff --git a/mingw/mingw.c b/mingw/mingw.c index 493dcba..266a87c 100644 --- a/mingw/mingw.c +++ b/mingw/mingw.c @@ -22,30 +22,30 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) FD_ZERO(&ofds); FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { - fds[i].revents = 0; - if(fds[i].events & (POLLIN|POLLPRI)) { - ip = &ifds; - FD_SET(fds[i].fd, ip); - } - if(fds[i].events & POLLOUT) { - op = &ofds; - FD_SET(fds[i].fd, op); - } - FD_SET(fds[i].fd, &efds); + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); } /* Set up the timeval structure for the timeout parameter */ if(timo < 0) { - toptr = 0; + toptr = 0; } else { - toptr = &timeout; - timeout.tv_sec = timo / 1000; - timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; } #ifdef DEBUG_POLL printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", - (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); #endif rc = select(0, ip, op, &efds, toptr); #ifdef DEBUG_POLL @@ -53,23 +53,23 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) #endif if(rc <= 0) - return rc; + return rc; if(rc > 0) { for ( i = 0; i < nfds; ++i) { int fd = fds[i].fd; - if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) - fds[i].revents |= POLLIN; - if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) - fds[i].revents |= POLLOUT; - if(FD_ISSET(fd, &efds)) - /* Some error was detected ... should be some way to know. */ - fds[i].revents |= POLLHUP; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) + /* Some error was detected ... should be some way to know. */ + fds[i].revents |= POLLHUP; #ifdef DEBUG_POLL - printf("%d %d %d revent = %x\n", - FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), - fds[i].revents - ); + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); #endif } } @@ -79,14 +79,14 @@ static void set_connect_errno(int winsock_err) { switch(winsock_err) { - case WSAEINVAL: - case WSAEALREADY: - case WSAEWOULDBLOCK: - errno = EINPROGRESS; - break; - default: - errno = winsock_err; - break; + case WSAEINVAL: + case WSAEALREADY: + case WSAEWOULDBLOCK: + errno = EINPROGRESS; + break; + default: + errno = winsock_err; + break; } } @@ -94,12 +94,12 @@ static void set_socket_errno(int winsock_err) { switch(winsock_err) { - case WSAEWOULDBLOCK: - errno = EAGAIN; - break; - default: - errno = winsock_err; - break; + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + default: + errno = winsock_err; + break; } } /* @@ -192,75 +192,75 @@ ssize_t win32_read_socket(SOCKET fd, void *buf, int n) char * win32_strtok_r(char *s, const char *delim, char **lasts) { - register char *spanp; - register int c, sc; - char *tok; + register char *spanp; + register int c, sc; + char *tok; - if (s == NULL && (s = *lasts) == NULL) - return (NULL); + if (s == NULL && (s = *lasts) == NULL) + return (NULL); - /* - * Skip (span) leading delimiters (s += strspn(s, delim), sort of). - */ + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ cont: - c = *s++; - for (spanp = (char *)delim; (sc = *spanp++) != 0;) { - if (c == sc) - goto cont; - } + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } - if (c == 0) { /* no non-delimiter characters */ - *lasts = NULL; - return (NULL); - } - tok = s - 1; + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; - /* - * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). - * Note that delim must have one NUL; we stop if we see that, too. - */ - for (;;) { - c = *s++; - spanp = (char *)delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *lasts = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ } char *win32_strsep (char **stringp, const char *delim) { - register char *s; - register const char *spanp; - register int c, sc; - char *tok; + register char *s; + register const char *spanp; + register int c, sc; + char *tok; - if ((s = *stringp) == NULL) - return (NULL); - for (tok = s;;) { - c = *s++; - spanp = delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringp = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ } #endif diff --git a/src/mmap.c b/src/mmap.c index 9c631da..c5794da 100644 --- a/src/mmap.c +++ b/src/mmap.c @@ -7,27 +7,27 @@ void *mmap (void *addr, size_t len, int prot, int flags, int fd, long long offset) { - void *buf; - ssize_t count; + void *buf; + ssize_t count; - if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; + if ( addr || fd == -1 || (prot & PROT_WRITE)) return MAP_FAILED; - buf = malloc(len); - if ( NULL == buf ) return MAP_FAILED; + buf = malloc(len); + if ( NULL == buf ) return MAP_FAILED; - if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; + if (lseek(fd,offset,SEEK_SET) != offset) return MAP_FAILED; - count = read(fd, buf, len); + count = read(fd, buf, len); - if (count != len) { - free (buf); - return MAP_FAILED; - } + if (count != len) { + free (buf); + return MAP_FAILED; + } - return buf; + return buf; } int munmap (void *addr, size_t len) { - free (addr); - return 0; + free (addr); + return 0; } diff --git a/src/mmap.h b/src/mmap.h index bff766c..71de819 100644 --- a/src/mmap.h +++ b/src/mmap.h @@ -19,8 +19,8 @@ extern "C" { #endif -void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); -int munmap(void *addr, size_t len); + void *mmap(void *addr, size_t len, int prot, int flags, int fd, long long offset); + int munmap(void *addr, size_t len); #ifdef __cplusplus } diff --git a/src/st-info.c b/src/st-info.c index 28f3fb8..6fe2f8d 100644 --- a/src/st-info.c +++ b/src/st-info.c @@ -11,79 +11,79 @@ static void usage(void) { - puts("st-info --flash"); - puts("st-info --sram"); - puts("st-info --descr"); - puts("st-info --pagesize"); - puts("st-info --chipid"); + puts("st-info --flash"); + puts("st-info --sram"); + puts("st-info --descr"); + puts("st-info --pagesize"); + puts("st-info --chipid"); } static int print_data(stlink_t* sl, char** av) { - int ret = 0; - if (strcmp(av[1], "--flash") == 0) - printf("0x%zx\n", sl->flash_size); - else if (strcmp(av[1], "--sram") == 0) - printf("0x%zx\n", sl->sram_size); - else if (strcmp(av[1], "--pagesize") == 0) - printf("0x%zx\n", sl->flash_pgsz); - else if (strcmp(av[1], "--chipid") == 0) - printf("0x%.4x\n", sl->chip_id); - else if (strcmp(av[1], "--descr")==0) { - const chip_params_t *params = NULL; - for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { - if(devices[i].chip_id == sl->chip_id) { - params = &devices[i]; - break; - } - } - if (params == NULL) { - return -1; - } - printf("%s\n", params->description); - } - return ret; -} + int ret = 0; + if (strcmp(av[1], "--flash") == 0) + printf("0x%zx\n", sl->flash_size); + else if (strcmp(av[1], "--sram") == 0) + printf("0x%zx\n", sl->sram_size); + else if (strcmp(av[1], "--pagesize") == 0) + printf("0x%zx\n", sl->flash_pgsz); + else if (strcmp(av[1], "--chipid") == 0) + printf("0x%.4x\n", sl->chip_id); + else if (strcmp(av[1], "--descr")==0) { + const chip_params_t *params = NULL; + for (size_t i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { + if(devices[i].chip_id == sl->chip_id) { + params = &devices[i]; + break; + } + } + if (params == NULL) { + return -1; + } + printf("%s\n", params->description); + } + return ret; +} -stlink_t* open_sl(void) +stlink_t* open_sl(void) { - stlink_t* sl; - sl = stlink_v1_open(0, 1); - if (sl == NULL) - sl = stlink_open_usb(0, 1); - return sl; + stlink_t* sl; + sl = stlink_v1_open(0, 1); + if (sl == NULL) + sl = stlink_open_usb(0, 1); + return sl; } int main(int ac, char** av) { - stlink_t* sl = NULL; - int err = -1; - if (ac < 2) { - usage(); - return -1; - } + stlink_t* sl = NULL; + int err = -1; + if (ac < 2) { + usage(); + return -1; + } + + sl = open_sl(); + + if (sl == NULL) { + return -1; + } + sl->verbose=0; + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) + stlink_exit_dfu_mode(sl); - sl = open_sl(); - - if (sl == NULL) { - return -1; - } - sl->verbose=0; - if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) - stlink_exit_dfu_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) + stlink_enter_swd_mode(sl); - if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); + err = print_data(sl, av); - err = print_data(sl, av); - - if (sl != NULL) - { - stlink_exit_debug_mode(sl); - stlink_close(sl); - } + if (sl != NULL) + { + stlink_exit_debug_mode(sl); + stlink_close(sl); + } - return err; + return err; } diff --git a/src/st-term.c b/src/st-term.c index 6881f62..8350cff 100644 --- a/src/st-term.c +++ b/src/st-term.c @@ -13,225 +13,225 @@ #define STLINKY_MAGIC 0xDEADF00D -#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ - | buf[1] << 8 \ - | buf[2] << 16 \ - | buf[3] << 24)) +#define READ_UINT32_LE(buf) ((uint32_t) ( buf[0] \ + | buf[1] << 8 \ + | buf[2] << 16 \ + | buf[3] << 24)) static stlink_t* sl; sigset_t sig_mask; struct stlinky { - stlink_t *sl; - uint32_t off; - size_t bufsize; + stlink_t *sl; + uint32_t off; + size_t bufsize; }; void nonblock(int state); static void cleanup(int signal __attribute__((unused))) { - if (sl) { - /* Switch back to mass storage mode before closing. */ - stlink_run(sl); - stlink_exit_debug_mode(sl); - stlink_close(sl); - } - - printf("\n"); - nonblock(0); - exit(1); + if (sl) { + /* Switch back to mass storage mode before closing. */ + stlink_run(sl); + stlink_exit_debug_mode(sl); + stlink_close(sl); + } + + printf("\n"); + nonblock(0); + exit(1); } void sig_init() { - sigemptyset(&sig_mask); - sigaddset(&sig_mask, SIGINT); - sigaddset(&sig_mask, SIGTERM); - signal(SIGINT, &cleanup); - signal(SIGTERM, &cleanup); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); + sigemptyset(&sig_mask); + sigaddset(&sig_mask, SIGINT); + sigaddset(&sig_mask, SIGTERM); + signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); } void sig_process() { - sigset_t pending; - sigpending(&pending); - if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { - sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); - sigsuspend(&pending); - sigprocmask(SIG_BLOCK, &sig_mask, NULL); - } + sigset_t pending; + sigpending(&pending); + if (sigismember(&pending, SIGINT) || sigismember(&pending, SIGTERM)) { + sigprocmask(SIG_UNBLOCK, &sig_mask, NULL); + sigsuspend(&pending); + sigprocmask(SIG_BLOCK, &sig_mask, NULL); + } } /* Detects stlinky in RAM, returns handler */ struct stlinky* stlinky_detect(stlink_t* sl) { - static const uint32_t sram_base = 0x20000000; - struct stlinky* st = malloc(sizeof(struct stlinky)); - int multiple=0; - st->sl = sl; - printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); - uint32_t off; - for (off = 0; off < sl->sram_size; off += 4) { - if (off % 1024 == 0) sig_process(); - stlink_read_mem32(sl, sram_base + off, 4); - if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) - { - if (multiple > 0) printf("WARNING: another "); - printf("stlinky detected at 0x%x\n", sram_base + off); - st->off = sram_base + off; - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu \n", st->bufsize); - multiple++; - } - } - if (multiple > 0) { - if (multiple > 1) { - printf("Using last stlinky structure detected\n"); - } - return st; - } - return NULL; + static const uint32_t sram_base = 0x20000000; + struct stlinky* st = malloc(sizeof(struct stlinky)); + int multiple=0; + st->sl = sl; + printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); + uint32_t off; + for (off = 0; off < sl->sram_size; off += 4) { + if (off % 1024 == 0) sig_process(); + stlink_read_mem32(sl, sram_base + off, 4); + if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) + { + if (multiple > 0) printf("WARNING: another "); + printf("stlinky detected at 0x%x\n", sram_base + off); + st->off = sram_base + off; + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu \n", st->bufsize); + multiple++; + } + } + if (multiple > 0) { + if (multiple > 1) { + printf("Using last stlinky structure detected\n"); + } + return st; + } + return NULL; } int stlinky_canrx(struct stlinky *st) { - stlink_read_mem32(st->sl, st->off+4, 4); - unsigned char tx = (unsigned char) st->sl->q_buf[1]; - return (int) tx; + stlink_read_mem32(st->sl, st->off+4, 4); + unsigned char tx = (unsigned char) st->sl->q_buf[1]; + return (int) tx; } size_t stlinky_rx(struct stlinky *st, char* buffer) { - unsigned char tx = 0; - while(tx == 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - tx = (unsigned char) st->sl->q_buf[1]; - } - size_t rs = tx + (4 - (tx % 4)); /* voodoo */ - stlink_read_mem32(st->sl, st->off+8, rs); - memcpy(buffer, st->sl->q_buf, (size_t) tx); - *st->sl->q_buf=0x0; - stlink_write_mem8(st->sl, st->off+5, 1); - return (size_t) tx; + unsigned char tx = 0; + while(tx == 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + tx = (unsigned char) st->sl->q_buf[1]; + } + size_t rs = tx + (4 - (tx % 4)); /* voodoo */ + stlink_read_mem32(st->sl, st->off+8, rs); + memcpy(buffer, st->sl->q_buf, (size_t) tx); + *st->sl->q_buf=0x0; + stlink_write_mem8(st->sl, st->off+5, 1); + return (size_t) tx; } size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz) { - unsigned char rx = 1; - while(rx != 0) { - stlink_read_mem32(st->sl, st->off+4, 4); - rx = (unsigned char) st->sl->q_buf[2]; - } - memcpy(st->sl->q_buf, buffer, sz); - size_t rs = sz + (4 - (sz % 4)); /* voodoo */ - stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); - *st->sl->q_buf=(unsigned char) sz; - stlink_write_mem8(st->sl, st->off+6, 1); - return (size_t) rx; + unsigned char rx = 1; + while(rx != 0) { + stlink_read_mem32(st->sl, st->off+4, 4); + rx = (unsigned char) st->sl->q_buf[2]; + } + memcpy(st->sl->q_buf, buffer, sz); + size_t rs = sz + (4 - (sz % 4)); /* voodoo */ + stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); + *st->sl->q_buf=(unsigned char) sz; + stlink_write_mem8(st->sl, st->off+6, 1); + return (size_t) rx; } int kbhit() { - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); + struct timeval tv; + fd_set fds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&fds); + FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 + select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); + return FD_ISSET(STDIN_FILENO, &fds); } void nonblock(int state) { - struct termios ttystate; - - //get the terminal state - tcgetattr(STDIN_FILENO, &ttystate); - - if (state==1) - { - //turn off canonical mode - ttystate.c_lflag &= ~ICANON; - ttystate.c_lflag &= ~ECHO; - //minimum of number input read. - ttystate.c_cc[VMIN] = 1; - } - else if (state==0) - { - //turn on canonical mode - ttystate.c_lflag |= ICANON | ECHO; - } - //set the terminal attributes. - tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); + struct termios ttystate; + + //get the terminal state + tcgetattr(STDIN_FILENO, &ttystate); + + if (state==1) + { + //turn off canonical mode + ttystate.c_lflag &= ~ICANON; + ttystate.c_lflag &= ~ECHO; + //minimum of number input read. + ttystate.c_cc[VMIN] = 1; + } + else if (state==0) + { + //turn on canonical mode + ttystate.c_lflag |= ICANON | ECHO; + } + //set the terminal attributes. + tcsetattr(STDIN_FILENO, TCSANOW, &ttystate); } int main(int ac, char** av) { - struct stlinky *st=NULL; - - sig_init(); - - sl = stlink_open_usb(10, 1); - if (sl != NULL) { - printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); - stlink_version(sl); - stlink_enter_swd_mode(sl); - printf("chip id: %#x\n", sl->chip_id); - printf("core_id: %#x\n", sl->core_id); - - cortex_m3_cpuid_t cpuid; - stlink_cpu_id(sl, &cpuid); - printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); - printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); - - stlink_reset(sl); - stlink_force_debug(sl); - stlink_run(sl); - stlink_status(sl); - - /* wait for device to boot */ - /* TODO: Make timeout adjustable via command line */ - sleep(1); - - if(ac == 1){ - st = stlinky_detect(sl); - }else if(ac == 2){ - st = malloc(sizeof(struct stlinky)); - st->sl = sl; - st->off = (int)strtol(av[1], NULL, 16); - printf("using stlinky at 0x%x\n", st->off); - stlink_read_mem32(sl, st->off + 4, 4); - st->bufsize = (size_t) *(unsigned char*) sl->q_buf; - printf("stlinky buffer size 0x%zu \n", st->bufsize); - }else{ - cleanup(0); - } - if (st == NULL) - { - printf("stlinky magic not found in sram :(\n"); - cleanup(0); - } - char* rxbuf = malloc(st->bufsize); - char* txbuf = malloc(st->bufsize); - size_t tmp; - nonblock(1); - int fd = fileno(stdin); - int saved_flags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); - printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); - while(1) { - sig_process(); - if (stlinky_canrx(st)) { - tmp = stlinky_rx(st, rxbuf); - fwrite(rxbuf,tmp,1,stdout); - fflush(stdout); - } - if (kbhit()) { - tmp = read(fd, txbuf, st->bufsize); - stlinky_tx(st,txbuf,tmp); - } - } - } - return 0; + struct stlinky *st=NULL; + + sig_init(); + + sl = stlink_open_usb(10, 1); + if (sl != NULL) { + printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); + stlink_version(sl); + stlink_enter_swd_mode(sl); + printf("chip id: %#x\n", sl->chip_id); + printf("core_id: %#x\n", sl->core_id); + + cortex_m3_cpuid_t cpuid; + stlink_cpu_id(sl, &cpuid); + printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); + printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); + + stlink_reset(sl); + stlink_force_debug(sl); + stlink_run(sl); + stlink_status(sl); + + /* wait for device to boot */ + /* TODO: Make timeout adjustable via command line */ + sleep(1); + + if(ac == 1){ + st = stlinky_detect(sl); + }else if(ac == 2){ + st = malloc(sizeof(struct stlinky)); + st->sl = sl; + st->off = (int)strtol(av[1], NULL, 16); + printf("using stlinky at 0x%x\n", st->off); + stlink_read_mem32(sl, st->off + 4, 4); + st->bufsize = (size_t) *(unsigned char*) sl->q_buf; + printf("stlinky buffer size 0x%zu \n", st->bufsize); + }else{ + cleanup(0); + } + if (st == NULL) + { + printf("stlinky magic not found in sram :(\n"); + cleanup(0); + } + char* rxbuf = malloc(st->bufsize); + char* txbuf = malloc(st->bufsize); + size_t tmp; + nonblock(1); + int fd = fileno(stdin); + int saved_flags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); + printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); + while(1) { + sig_process(); + if (stlinky_canrx(st)) { + tmp = stlinky_rx(st, rxbuf); + fwrite(rxbuf,tmp,1,stdout); + fflush(stdout); + } + if (kbhit()) { + tmp = read(fd, txbuf, st->bufsize); + stlinky_tx(st,txbuf,tmp); + } + } + } + return 0; } diff --git a/src/stlink-common.c b/src/stlink-common.c index 545434b..ce1306b 100644 --- a/src/stlink-common.c +++ b/src/stlink-common.c @@ -144,7 +144,7 @@ static inline uint32_t read_flash_obr(stlink_t *sl) { 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) ||(sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_CR); else res = stlink_read_debug32(sl, FLASH_CR); @@ -157,7 +157,7 @@ static inline uint32_t read_flash_cr(stlink_t *sl) { 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) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (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 return read_flash_cr(sl) & (1 << FLASH_CR_LOCK); @@ -168,13 +168,13 @@ static void unlock_flash(stlink_t *sl) { 2 key values are written to the FLASH_KEYR register. 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) || (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); + (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); } else { - stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); + stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY1); stlink_write_debug32(sl, FLASH_KEYR, FLASH_KEY2); } @@ -196,9 +196,9 @@ static int unlock_flash_if(stlink_t *sl) { static void lock_flash(stlink_t *sl) { 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); + (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); } else { /* write to 1 only. reset by hw at unlock sequence */ const uint32_t n = read_flash_cr(sl) | (1 << FLASH_CR_LOCK); @@ -209,10 +209,10 @@ static void lock_flash(stlink_t *sl) { static void set_flash_cr_pg(stlink_t *sl) { 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); - stlink_write_debug32(sl, FLASH_F4_CR, x); + (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); + stlink_write_debug32(sl, FLASH_F4_CR, x); } else { const uint32_t n = 1 << FLASH_CR_PG; stlink_write_debug32(sl, FLASH_CR, n); @@ -222,8 +222,8 @@ static void set_flash_cr_pg(stlink_t *sl) { 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) || (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); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + stlink_write_debug32(sl, FLASH_F4_CR, n); else stlink_write_debug32(sl, FLASH_CR, n); } @@ -240,33 +240,33 @@ static void __attribute__((unused)) clear_flash_cr_per(stlink_t *sl) { static void set_flash_cr_mer(stlink_t *sl) { 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)) + (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)); + stlink_read_debug32(sl, FLASH_F4_CR) | (1 << FLASH_CR_MER)); else stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_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) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (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)); + stlink_read_debug32(sl, FLASH_F4_CR) & ~(1 << FLASH_CR_MER)); else stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) & ~(1 << FLASH_CR_MER)); + stlink_read_debug32(sl, FLASH_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) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + (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); stlink_write_debug32(sl, FLASH_F4_CR, x); } else { stlink_write_debug32(sl, FLASH_CR, - stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); + stlink_read_debug32(sl, FLASH_CR) | (1 << FLASH_CR_STRT) ); } } @@ -277,7 +277,7 @@ static inline uint32_t read_flash_acr(stlink_t *sl) { 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) || (sl->chip_id == STM32_CHIPID_F4_DE) || - (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) res = stlink_read_debug32(sl, FLASH_F4_SR); else res = stlink_read_debug32(sl, FLASH_SR); @@ -287,7 +287,7 @@ static inline uint32_t read_flash_sr(stlink_t *sl) { static inline unsigned int is_flash_busy(stlink_t *sl) { 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)) + (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 return read_flash_sr(sl) & (1 << FLASH_SR_BSY); @@ -464,7 +464,7 @@ int stlink_load_device_params(stlink_t *sl) { flash_size = flash_size & 0xffff; if ((sl->chip_id == STM32_CHIPID_L1_MEDIUM || sl->chip_id == STM32_CHIPID_L1_MEDIUM_PLUS) && ( flash_size == 0 )) { - sl->flash_size = 128 * 1024; + sl->flash_size = 128 * 1024; } else if ((sl->chip_id & 0xFFF) == STM32_CHIPID_L1_HIGH) { // 0 is 384k and 1 is 256k if ( flash_size == 0 ) { @@ -483,8 +483,8 @@ int stlink_load_device_params(stlink_t *sl) { ILOG("Device connected is: %s, id %#x\n", params->description, chip_id); // TODO make note of variable page size here..... ILOG("SRAM size: %#x bytes (%d KiB), Flash: %#x bytes (%d KiB) in pages of %zd bytes\n", - sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, - sl->flash_pgsz); + sl->sram_size, sl->sram_size / 1024, sl->flash_size, sl->flash_size / 1024, + sl->flash_pgsz); return 0; } @@ -557,11 +557,11 @@ int stlink_target_voltage(stlink_t *sl) { DLOG("*** reading target voltage\n"); if (sl->backend->target_voltage != NULL) { voltage = sl->backend->target_voltage(sl); - if (voltage != -1) { + if (voltage != -1) { DLOG("target voltage = %ldmV\n", voltage); - } else { + } else { DLOG("error reading target voltage\n"); - } + } } else { DLOG("reading voltage not supported by backend\n"); } @@ -691,15 +691,15 @@ void stlink_step(stlink_t *sl) { int stlink_current_mode(stlink_t *sl) { int mode = sl->backend->current_mode(sl); switch (mode) { - case STLINK_DEV_DFU_MODE: - DLOG("stlink current mode: dfu\n"); - return mode; - case STLINK_DEV_DEBUG_MODE: - DLOG("stlink current mode: debug (jtag or swd)\n"); - return mode; - case STLINK_DEV_MASS_MODE: - DLOG("stlink current mode: mass\n"); - return mode; + case STLINK_DEV_DFU_MODE: + DLOG("stlink current mode: dfu\n"); + return mode; + case STLINK_DEV_DEBUG_MODE: + DLOG("stlink current mode: debug (jtag or swd)\n"); + return mode; + case STLINK_DEV_MASS_MODE: + DLOG("stlink current mode: mass\n"); + return mode; } DLOG("stlink mode: unknown!\n"); return STLINK_DEV_UNKNOWN_MODE; @@ -750,17 +750,17 @@ void stlink_core_stat(stlink_t *sl) { return; switch (sl->q_buf[0]) { - case STLINK_CORE_RUNNING: - sl->core_stat = STLINK_CORE_RUNNING; - DLOG(" core status: running\n"); - return; - case STLINK_CORE_HALTED: - sl->core_stat = STLINK_CORE_HALTED; - DLOG(" core status: halted\n"); - return; - default: - sl->core_stat = STLINK_CORE_STAT_UNKNOWN; - fprintf(stderr, " core status: unknown\n"); + case STLINK_CORE_RUNNING: + sl->core_stat = STLINK_CORE_RUNNING; + DLOG(" core status: running\n"); + return; + case STLINK_CORE_HALTED: + sl->core_stat = STLINK_CORE_HALTED; + DLOG(" core status: halted\n"); + return; + default: + sl->core_stat = STLINK_CORE_STAT_UNKNOWN; + fprintf(stderr, " core status: unknown\n"); } } @@ -773,11 +773,11 @@ void stlink_print_data(stlink_t * sl) { for (int i = 0; i < sl->q_len; i++) { if (i % 16 == 0) { /* - if (sl->q_data_dir == Q_DATA_OUT) - fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); - else - fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); - */ + if (sl->q_data_dir == Q_DATA_OUT) + fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i); + else + fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i); + */ } fprintf(stdout, " %02x", (unsigned int) sl->q_buf[i]); } @@ -931,7 +931,7 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) 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 || sl->chip_id == STM32_CHIPID_L152_RE) ? 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) { @@ -940,32 +940,32 @@ int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) } if (size <1) - size = sl->flash_size; + size = sl->flash_size; if (size > sl->flash_size) - size = sl->flash_size; + size = sl->flash_size; /* do the copy by 1k blocks */ for (off = 0; off < size; off += 1024) { size_t read_size = 1024; - size_t rounded_size; - size_t index; + size_t rounded_size; + size_t index; if ((off + read_size) > size) - read_size = size - off; + read_size = size - off; /* round size if needed */ - rounded_size = read_size; + rounded_size = read_size; if (rounded_size & 3) - rounded_size = (rounded_size + 4) & ~(3); + rounded_size = (rounded_size + 4) & ~(3); stlink_read_mem32(sl, addr + off, rounded_size); - for(index = 0; index < read_size; index ++) { - if (sl->q_buf[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; - } + for(index = 0; index < read_size; index ++) { + if (sl->q_buf[index] == erased_pattern) + num_empty ++; + else + num_empty = 0; + } if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) { fprintf(stderr, "write() != read_size\n"); goto on_error; @@ -1013,14 +1013,14 @@ uint32_t calculate_F4_sectornum(uint32_t flashaddr){ } uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ - 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; - else if(sector<5) sl->flash_pgsz=0x10000; - else sl->flash_pgsz=0x20000; - } - return (sl->flash_pgsz); + 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; + else if(sector<5) sl->flash_pgsz=0x10000; + else sl->flash_pgsz=0x20000; + } + return (sl->flash_pgsz); } /** @@ -1032,144 +1032,144 @@ uint32_t stlink_calculate_pagesize(stlink_t *sl, uint32_t flashaddr){ 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) || (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); + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); - /* unlock if locked */ - unlock_flash_if(sl); + /* unlock if locked */ + unlock_flash_if(sl); - /* select the page to erase */ - // calculate the actual page from the address - uint32_t sector=calculate_F4_sectornum(flashaddr); + /* select the page to erase */ + // calculate the actual page from the address + uint32_t sector=calculate_F4_sectornum(flashaddr); - fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); - write_flash_cr_snb(sl, sector); + fprintf(stderr, "EraseFlash - Sector:0x%x Size:0x%x\n", sector, stlink_calculate_pagesize(sl, flashaddr)); + write_flash_cr_snb(sl, sector); - /* start erase operation */ - set_flash_cr_strt(sl); + /* start erase operation */ + set_flash_cr_strt(sl); - /* wait for completion */ - wait_flash_busy(sl); + /* wait for completion */ + wait_flash_busy(sl); - /* relock the flash */ - //todo: fails to program if this is in - lock_flash(sl); + /* relock the flash */ + //todo: fails to program if this is in + lock_flash(sl); #if DEBUG_FLASH - fprintf(stdout, "Erase Final CR:0x%x\n", read_flash_cr(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_L152_RE) { + } 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_L152_RE) { - uint32_t val; + uint32_t val; - /* check if the locks are set */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if((val & (1<<0))||(val & (1<<1))) { - /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - - /* check pecr.pelock is cleared */ + /* check if the locks are set */ val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) { - WLOG("pecr.pelock not clear (%#x)\n", val); - return -1; - } + if((val & (1<<0))||(val & (1<<1))) { + /* disable pecr protection */ + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + /* check pecr.pelock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 0)) { + WLOG("pecr.pelock not clear (%#x)\n", val); + return -1; + } - /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) { - WLOG("pecr.prglock not clear (%#x)\n", val); - return -1; + /* unlock program memory */ + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + + /* check pecr.prglock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 1)) { + WLOG("pecr.prglock not clear (%#x)\n", val); + return -1; + } } - } - /* unused: unlock the option byte block */ + /* unused: unlock the option byte block */ #if 0 - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); - stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0xfbead9c8); + stlink_write_debug32(sl, STM32L_FLASH_OPTKEYR, 0x24252627); - /* check pecr.optlock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 2)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return -1; - } + /* check pecr.optlock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 2)) { + fprintf(stderr, "pecr.prglock not clear\n"); + return -1; + } #endif - /* set pecr.{erase,prog} */ - val |= (1 << 9) | (1 << 3); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + /* set pecr.{erase,prog} */ + val |= (1 << 9) | (1 << 3); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); #if 0 /* fix_to_be_confirmed */ - /* wait for sr.busy to be cleared - MP: Test shows that busy bit is not set here. Perhaps, PM0062 is - wrong and we do not need to wait here for clearing the busy bit. - TEXANE: ok, if experience says so and it works for you, we comment - it. If someone has a problem, please drop an email. - */ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - ; + /* wait for sr.busy to be cleared + * MP: Test shows that busy bit is not set here. Perhaps, PM0062 is + * wrong and we do not need to wait here for clearing the busy bit. + * TEXANE: ok, if experience says so and it works for you, we comment + * it. If someone has a problem, please drop an email. + */ + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + ; #endif /* fix_to_be_confirmed */ - /* write 0 to the first word of the page to be erased */ - stlink_write_debug32(sl, flashaddr, 0); - - /* MP: It is better to wait for clearing the busy bit after issuing - page erase command, even though PM0062 recommends to wait before it. - Test shows that a few iterations is performed in the following loop - before busy bit is cleared.*/ - while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) - ; - - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); - } else if (sl->core_id == STM32VL_CORE_ID - || sl->core_id == STM32F0_CORE_ID - || sl->chip_id == STM32_CHIPID_F3 - || sl->chip_id == STM32_CHIPID_F37x) { - /* wait for ongoing op to finish */ - wait_flash_busy(sl); + /* write 0 to the first word of the page to be erased */ + stlink_write_debug32(sl, flashaddr, 0); + + /* MP: It is better to wait for clearing the busy bit after issuing + page erase command, even though PM0062 recommends to wait before it. + Test shows that a few iterations is performed in the following loop + before busy bit is cleared.*/ + while ((stlink_read_debug32(sl, STM32L_FLASH_SR) & (1 << 0)) != 0) + ; + + /* reset lock bits */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + } else if (sl->core_id == STM32VL_CORE_ID + || sl->core_id == STM32F0_CORE_ID + || sl->chip_id == STM32_CHIPID_F3 + || sl->chip_id == STM32_CHIPID_F37x) { + /* wait for ongoing op to finish */ + wait_flash_busy(sl); - /* unlock if locked */ - unlock_flash_if(sl); + /* unlock if locked */ + unlock_flash_if(sl); - /* set the page erase bit */ - set_flash_cr_per(sl); + /* set the page erase bit */ + set_flash_cr_per(sl); - /* select the page to erase */ - write_flash_ar(sl, flashaddr); + /* select the page to erase */ + write_flash_ar(sl, flashaddr); - /* start erase operation, reset by hw with bsy bit */ - set_flash_cr_strt(sl); + /* start erase operation, reset by hw with bsy bit */ + set_flash_cr_strt(sl); - /* wait for completion */ - wait_flash_busy(sl); + /* wait for completion */ + wait_flash_busy(sl); - /* relock the flash */ - lock_flash(sl); - } else { - WLOG("unknown coreid %x, page erase failed\n", sl->core_id); - return -1; - } + /* relock the flash */ + lock_flash(sl); + } else { + WLOG("unknown coreid %x, page erase failed\n", sl->core_id); + return -1; + } - /* todo: verify the erased page */ + /* todo: verify the erased page */ - return 0; + return 0; } 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_L152_RE) { + || 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++) { @@ -1266,13 +1266,13 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE 0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */ 0x04, 0x26, // mov r6, #4 /* PGERR */ - // write_half_word: + // write_half_word: 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ 0x2B, 0x43, // orr r3, r5 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */ 0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */ 0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */ - // busy: + // busy: 0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */ 0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */ 0xFC, 0xD0, // beq busy @@ -1285,7 +1285,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */ 0x00, 0x2A, // cmp r2, #0 0xF0, 0xD1, // bne write_half_word - // exit: + // exit: 0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */ 0xAB, 0x43, // bic r3, r5 0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */ @@ -1300,7 +1300,7 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { r1, input, source addr r2, input, word count r3, output, word count - */ + */ 0x00, 0x23, 0x04, 0xe0, @@ -1340,14 +1340,14 @@ int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size) { 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 || sl->chip_id == STM32_CHIPID_L152_RE ) { /* 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 || (sl->chip_id == STM32_CHIPID_F4_DE) || - sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD){ + 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_CAN || sl->chip_id == STM32_CHIPID_F0_SMALL) { @@ -1473,7 +1473,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t size_t off; flash_loader_t fl; ILOG("Attempting to write %d (%#x) bytes to stm32 address: %u (%#x)\n", - len, len, addr, addr); + len, len, addr, addr); /* check addr range is inside the flash */ stlink_calculate_pagesize(sl, addr); if (addr < sl->flash_base) { @@ -1507,17 +1507,17 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return -1; } fprintf(stdout,"\rFlash page at addr: 0x%08lx erased", - (unsigned long)addr + off); + (unsigned long)addr + off); fflush(stdout); page_count++; } fprintf(stdout,"\n"); ILOG("Finished erasing %d pages of %d (%#x) bytes\n", - page_count, sl->flash_pgsz, sl->flash_pgsz); + page_count, sl->flash_pgsz, sl->flash_pgsz); 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 */ + (sl->chip_id == STM32_CHIPID_F4_LP) || (sl->chip_id == STM32_CHIPID_F4_HD)) { + /* todo: check write operation */ ILOG("Starting Flash write for F2/F4\n"); /* flash loader initialization */ @@ -1526,15 +1526,15 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t return -1; } - /* First unlock the cr */ - unlock_flash_if(sl); + /* First unlock the cr */ + unlock_flash_if(sl); - /* TODO: Check that Voltage range is 2.7 - 3.6 V */ - /* set parallelisim to 32 bit*/ - write_flash_cr_psiz(sl, 2); + /* TODO: Check that Voltage range is 2.7 - 3.6 V */ + /* set parallelisim to 32 bit*/ + write_flash_cr_psiz(sl, 2); - /* set programming mode */ - set_flash_cr_pg(sl); + /* set programming mode */ + set_flash_cr_pg(sl); for(off = 0; off < len;) { size_t size = len - off > 0x8000 ? 0x8000 : len - off; @@ -1551,8 +1551,8 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t #if 0 #define PROGRESS_CHUNK_SIZE 0x1000 - /* write a word in program memory */ - for (off = 0; off < len; off += sizeof(uint32_t)) { + /* write a word in program memory */ + for (off = 0; off < len; off += sizeof(uint32_t)) { uint32_t data; if (sl->verbose >= 1) { if ((off & (PROGRESS_CHUNK_SIZE - 1)) == 0) { @@ -1569,65 +1569,65 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t stlink_write_debug32(sl, addr + off, data); /* wait for sr.busy to be cleared */ - wait_flash_busy(sl); + wait_flash_busy(sl); - } + } #endif - /* Relock flash */ - lock_flash(sl); + /* Relock flash */ + lock_flash(sl); #if 0 /* todo: debug mode */ - fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); + fprintf(stdout, "Final CR:0x%x\n", read_flash_cr(sl)); #endif } //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_L152_RE ) { - /* use fast word write. todo: half page. */ - uint32_t val; + || sl->chip_id == STM32_CHIPID_L1_HIGH || sl->chip_id == STM32_CHIPID_L152_RE ) { + /* use fast word write. todo: half page. */ + uint32_t val; #if 0 /* todo: check write operation */ - uint32_t nwrites = sl->flash_pgsz; + uint32_t nwrites = sl->flash_pgsz; - redo_write: +redo_write: #endif /* todo: check write operation */ - /* disable pecr protection */ - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); - stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); - - /* check pecr.pelock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 0)) { - fprintf(stderr, "pecr.pelock not clear\n"); - return -1; - } - - /* unlock program memory */ - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); - stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); - - /* check pecr.prglock is cleared */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR); - if (val & (1 << 1)) { - fprintf(stderr, "pecr.prglock not clear\n"); - return -1; - } - off = 0; + /* disable pecr protection */ + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x89abcdef); + stlink_write_debug32(sl, STM32L_FLASH_PEKEYR, 0x02030405); + + /* check pecr.pelock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 0)) { + fprintf(stderr, "pecr.pelock not clear\n"); + return -1; + } + + /* unlock program memory */ + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x8c9daebf); + stlink_write_debug32(sl, STM32L_FLASH_PRGKEYR, 0x13141516); + + /* check pecr.prglock is cleared */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR); + if (val & (1 << 1)) { + fprintf(stderr, "pecr.prglock not clear\n"); + return -1; + } + off = 0; if (len > L1_WRITE_BLOCK_SIZE) { if (stm32l1_write_half_pages(sl, addr, base, len/L1_WRITE_BLOCK_SIZE) == -1) { - /* This may happen on a blank device! */ + /* This may happen on a blank device! */ WLOG("\nwrite_half_pages failed == -1\n"); - } else { - off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; - } - } + } else { + off = (len /L1_WRITE_BLOCK_SIZE)*L1_WRITE_BLOCK_SIZE; + } + } - /* write remainingword in program memory */ - for ( ; off < len; off += sizeof(uint32_t)) { + /* write remainingword in program memory */ + for ( ; off < len; off += sizeof(uint32_t)) { uint32_t data; if (off > 254) fprintf(stdout, "\r"); @@ -1683,12 +1683,12 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t ++nwrites; #endif /* todo: check redo write operation */ - } + } fprintf(stdout, "\n"); - /* reset lock bits */ - val = stlink_read_debug32(sl, STM32L_FLASH_PECR) - | (1 << 0) | (1 << 1) | (1 << 2); - stlink_write_debug32(sl, STM32L_FLASH_PECR, val); + /* reset lock bits */ + val = stlink_read_debug32(sl, STM32L_FLASH_PECR) + | (1 << 0) | (1 << 1) | (1 << 2); + stlink_write_debug32(sl, STM32L_FLASH_PECR, val); } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { ILOG("Starting Flash write for VL/F0 core id\n"); /* flash loader initialization */ @@ -1715,7 +1715,7 @@ int stlink_write_flash(stlink_t *sl, stm32_addr_t addr, uint8_t* base, uint32_t if (sl->verbose >= 1) { /* show progress. writing procedure is slow and previous errors are misleading */ - fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); + fprintf(stdout, "\r%3u/%lu pages written", write_block_count++, (unsigned long)len/sl->flash_pgsz); fflush(stdout); } } @@ -1740,23 +1740,23 @@ int stlink_fwrite_flash(stlink_t *sl, const char* path, stm32_addr_t addr) { 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 || sl->chip_id == STM32_CHIPID_L152_RE )?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"); return -1; } for(index = 0; index < mf.len; index ++) { - if (mf.base[index] == erased_pattern) - num_empty ++; - else - num_empty = 0; + if (mf.base[index] == erased_pattern) + num_empty ++; + else + num_empty = 0; } /* Round down to words */ num_empty -= (num_empty & 3); if(num_empty != 0) { - ILOG("Ignoring %d bytes of 0x%02x at end of file\n", num_empty, erased_pattern); - mf.len -= 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); /* set stack*/ @@ -1781,7 +1781,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } 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_L152_RE ) { + || 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; @@ -1805,7 +1805,7 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons stlink_write_reg(sl, fl->loader_addr, 15); /* pc register */ } 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) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { size_t count = size / sizeof(uint32_t); if (size % sizeof(uint32_t)) ++count; @@ -1839,27 +1839,27 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons /* 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_L152_RE ) { + || 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; + size_t count = size / sizeof(uint32_t); + if (size % sizeof(uint32_t)) ++count; - stlink_read_reg(sl, 3, &rr); - if (rr.r[3] != count) { - fprintf(stderr, "write error, count == %u\n", rr.r[3]); - return -1; - } + stlink_read_reg(sl, 3, &rr); + if (rr.r[3] != count) { + fprintf(stderr, "write error, count == %u\n", rr.r[3]); + return -1; + } } else if (sl->core_id == STM32VL_CORE_ID || sl->core_id == STM32F0_CORE_ID || sl->chip_id == STM32_CHIPID_F3 || sl->chip_id == STM32_CHIPID_F37x) { - stlink_read_reg(sl, 2, &rr); - if (rr.r[2] != 0) { - fprintf(stderr, "write error, count == %u\n", rr.r[2]); - return -1; - } + stlink_read_reg(sl, 2, &rr); + if (rr.r[2] != 0) { + fprintf(stderr, "write error, count == %u\n", rr.r[2]); + return -1; + } } 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) { + sl->chip_id == STM32_CHIPID_F4_LP || sl->chip_id == STM32_CHIPID_F4_HD) { stlink_read_reg(sl, 2, &rr); if (rr.r[2] != 0) { @@ -1869,8 +1869,8 @@ int run_flash_loader(stlink_t *sl, flash_loader_t* fl, stm32_addr_t target, cons } else { - fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); - return -1; + fprintf(stderr, "unknown coreid 0x%x, can't check written byte count\n", sl->core_id); + return -1; } diff --git a/src/stlink-common.h b/src/stlink-common.h index 1bedbf4..898b2a5 100644 --- a/src/stlink-common.h +++ b/src/stlink-common.h @@ -7,7 +7,7 @@ */ #ifndef STLINK_COMMON_H -#define STLINK_COMMON_H +#define STLINK_COMMON_H #ifdef __cplusplus extern "C" { @@ -77,12 +77,12 @@ extern "C" { #define STLINK_JTAG_DRIVE_NRST 0x3c #define STLINK_JTAG_DRIVE_NRST 0x3c -// cortex m3 technical reference manual + // cortex m3 technical reference manual #define CM3_REG_CPUID 0xE000ED00 #define CM3_REG_FP_CTRL 0xE0002000 #define CM3_REG_FP_COMP0 0xE0002008 -/* cortex core ids */ + /* cortex core ids */ // TODO clean this up... #define STM32VL_CORE_ID 0x1ba01477 #define STM32L_CORE_ID 0x2ba01477 @@ -93,11 +93,11 @@ extern "C" { #define CORE_M3_R2 0x4BA00477 #define CORE_M4_R0 0x2BA01477 -/* - * Chip IDs are explained in the appropriate programming manual for the - * DBGMCU_IDCODE register (0xE0042000) - */ -// stm32 chipids, only lower 12 bits.. + /* + * Chip IDs are explained in the appropriate programming manual for the + * DBGMCU_IDCODE register (0xE0042000) + */ + // stm32 chipids, only lower 12 bits.. #define STM32_CHIPID_F1_MEDIUM 0x410 #define STM32_CHIPID_F2 0x411 #define STM32_CHIPID_F1_LOW 0x412 @@ -132,252 +132,252 @@ extern "C" { #define STM32_CHIPID_F0_CAN 0x448 -/* - * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" - * and some that are called "High". 0x427 is assigned to the other "Medium- - * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and - * 0x436 HIGH. - */ + /* + * 0x436 is actually assigned to some L1 chips that are called "Medium-Plus" + * and some that are called "High". 0x427 is assigned to the other "Medium- + * plus" chips. To make it a bit simpler we just call 427 MEDIUM_PLUS and + * 0x436 HIGH. + */ -// Constant STM32 memory map figures + // Constant STM32 memory map figures #define STM32_FLASH_BASE 0x08000000 #define STM32_SRAM_BASE 0x20000000 -/* Cortex™-M3 Technical Reference Manual */ -/* Debug Halting Control and Status Register */ + /* Cortex™-M3 Technical Reference Manual */ + /* Debug Halting Control and Status Register */ #define DHCSR 0xe000edf0 #define DCRSR 0xe000edf4 #define DCRDR 0xe000edf8 #define DBGKEY 0xa05f0000 -/* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ + /* Enough space to hold both a V2 command or a V1 command packaged as generic scsi*/ #define C_BUF_LEN 32 typedef struct chip_params_ { - uint32_t chip_id; - char* description; + uint32_t chip_id; + char* description; uint32_t flash_size_reg; - uint32_t flash_pagesize; - uint32_t sram_size; - uint32_t bootrom_base, bootrom_size; + uint32_t flash_pagesize; + 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[] = { + // 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 2, PM0063 .chip_id = STM32_CHIPID_F1_MEDIUM, .description = "F1 Medium-density device", .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x5000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .flash_pagesize = 0x400, + .sram_size = 0x5000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { // table 1, PM0059 .chip_id = STM32_CHIPID_F2, - .description = "F2 device", - .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ - .flash_pagesize = 0x20000, - .sram_size = 0x20000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F2 device", + .flash_size_reg = 0x1fff7a22, /* As in RM0033 Rev 5*/ + .flash_pagesize = 0x20000, + .sram_size = 0x20000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { // PM0063 .chip_id = STM32_CHIPID_F1_LOW, - .description = "F1 Low-density device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2800, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 Low-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2800, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F4, - .description = "F4 device", - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F4 device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F4_HD, - .description = "F42x and F43x device", - .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ - .flash_pagesize = 0x4000, - .sram_size = 0x30000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F42x and F43x device", + .flash_size_reg = 0x1FFF7A22, /* As in rm0090 since Rev 2*/ + .flash_pagesize = 0x4000, + .sram_size = 0x30000, + .bootrom_base = 0x1fff0000, + .bootrom_size = 0x7800 }, { .chip_id = STM32_CHIPID_F4_LP, - .description = "F4 device (low power)", - .flash_size_reg = 0x1FFF7A22, - .flash_pagesize = 0x4000, - .sram_size = 0x10000, - .bootrom_base = 0x1fff0000, - .bootrom_size = 0x7800 + .description = "F4 device (low power)", + .flash_size_reg = 0x1FFF7A22, + .flash_pagesize = 0x4000, + .sram_size = 0x10000, + .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 + .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", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 High-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This ignores the EEPROM! (and uses the page erase size, - // not the sector write protection...) + // This ignores the EEPROM! (and uses the page erase size, + // not the sector write protection...) .chip_id = STM32_CHIPID_L1_MEDIUM, - .description = "L1 Med-density device", - .flash_size_reg = 0x1ff8004c, - .flash_pagesize = 0x100, - .sram_size = 0x4000, - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 Med-density device", + .flash_size_reg = 0x1ff8004c, + .flash_pagesize = 0x100, + .sram_size = 0x4000, + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_L1_MEDIUM_PLUS, - .description = "L1 Medium-Plus-density device", - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 Medium-Plus-density device", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0x8000,/*Not completely clear if there are some with 48K*/ + .bootrom_base = 0x1ff00000, + .bootrom_size = 0x1000 }, { .chip_id = STM32_CHIPID_L1_HIGH, - .description = "L1 High-density device", - .flash_size_reg = 0x1ff800cc, - .flash_pagesize = 0x100, - .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ - .bootrom_base = 0x1ff00000, - .bootrom_size = 0x1000 + .description = "L1 High-density device", + .flash_size_reg = 0x1ff800cc, + .flash_pagesize = 0x100, + .sram_size = 0xC000, /*Not completely clear if there are some with 32K*/ + .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 + .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", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x10000, - .bootrom_base = 0x1fffb000, - .bootrom_size = 0x4800 + .description = "F1 Connectivity line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x10000, + .bootrom_base = 0x1fffb000, + .bootrom_size = 0x4800 }, { .chip_id = STM32_CHIPID_F1_VL_MEDIUM, - .description = "F1 Medium-density Value Line device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x400, - .sram_size = 0x2000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 Medium-density Value Line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x400, + .sram_size = 0x2000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This is STK32F303VCT6 device from STM32 F3 Discovery board. - // Support based on DM00043574.pdf (RM0316) document. + // This is STK32F303VCT6 device from STM32 F3 Discovery board. + // Support based on DM00043574.pdf (RM0316) document. .chip_id = STM32_CHIPID_F3, - .description = "F3 device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { - // This is STK32F373VCT6 device from STM32 F373 eval board - // Support based on 303 above (37x and 30x have same memory map) + // This is STK32F373VCT6 device from STM32 F373 eval board + // Support based on 303 above (37x and 30x have same memory map) .chip_id = STM32_CHIPID_F37x, - .description = "F3 device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F3 device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F1_VL_HIGH, - .description = "F1 High-density value line device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x8000, - .bootrom_base = 0x1ffff000, - .bootrom_size = 0x800 + .description = "F1 High-density value line device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x8000, + .bootrom_base = 0x1ffff000, + .bootrom_size = 0x800 }, { .chip_id = STM32_CHIPID_F1_XL, - .description = "F1 XL-density device", - .flash_size_reg = 0x1ffff7e0, - .flash_pagesize = 0x800, - .sram_size = 0x18000, - .bootrom_base = 0x1fffe000, - .bootrom_size = 0x1800 + .description = "F1 XL-density device", + .flash_size_reg = 0x1ffff7e0, + .flash_pagesize = 0x800, + .sram_size = 0x18000, + .bootrom_base = 0x1fffe000, + .bootrom_size = 0x1800 }, - { - //Use this as an example for mapping future chips: - //RM0091 document was used to find these paramaters + { + //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 + .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 .chip_id = STM32_CHIPID_F0, - .description = "F0 device", - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .description = "F0 device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x2000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "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 .chip_id = STM32_CHIPID_F0_SMALL, - .description = "F0 small device", - .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) - .flash_pagesize = 0x400, // Page sizes listed in Table 4 - .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 - .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 - .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 + .description = "F0 small device", + .flash_size_reg = 0x1ffff7cc, // "Flash size data register" (pg735) + .flash_pagesize = 0x400, // Page sizes listed in Table 4 + .sram_size = 0x1000, // "SRAM" byte size in hex from Table 2 + .bootrom_base = 0x1fffec00, // "System memory" starting address from Table 2 + .bootrom_size = 0xC00 // "System memory" byte size in hex from Table 2 }, { - // STM32F30x + // STM32F30x .chip_id = STM32_CHIPID_F3_SMALL, - .description = "F3 small device", - .flash_size_reg = 0x1ffff7cc, - .flash_pagesize = 0x800, - .sram_size = 0xa000, - .bootrom_base = 0x1fffd800, - .bootrom_size = 0x2000 + .description = "F3 small device", + .flash_size_reg = 0x1ffff7cc, + .flash_pagesize = 0x800, + .sram_size = 0xa000, + .bootrom_base = 0x1fffd800, + .bootrom_size = 0x2000 }, - }; + }; typedef struct { @@ -566,4 +566,3 @@ static const chip_params_t devices[] = { #endif #endif /* STLINK_COMMON_H */ - diff --git a/src/stlink-sg.c b/src/stlink-sg.c index 53e93cc..1aefe61 100644 --- a/src/stlink-sg.c +++ b/src/stlink-sg.c @@ -1,77 +1,77 @@ /* - Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. - - A linux stlink access demo. The purpose of this file is to mitigate the usual - "reinventing the wheel" force by incompatible licenses and give you an idea, - how to access the stlink device. That doesn't mean you should be a free-loader - and not contribute your improvements to this code. - - Author: Martin Capitanio - The stlink related constants kindly provided by Oliver Spencer (OpenOCD) - for use in a GPL compatible license. - - Tested compatibility: linux, gcc >= 4.3.3 - - The communication is based on standard USB mass storage device - BOT (Bulk Only Transfer) - - Endpoint 1: BULK_IN, 64 bytes max - - Endpoint 2: BULK_OUT, 64 bytes max - - All CBW transfers are ordered with the LSB (byte 0) first (little endian). - Any command must be answered before sending the next command. - Each USB transfer must complete in less than 1s. - - SB Device Class Definition for Mass Storage Devices: - www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf - - dt - Data Transfer (IN/OUT) - CBW - Command Block Wrapper - CSW - Command Status Wrapper - RFU - Reserved for Future Use - - Originally, this driver used scsi pass through commands, which required the - usb-storage module to be loaded, providing the /dev/sgX links. The USB mass - storage implementation on the STLinkv1 is however terribly broken, and it can - take many minutes for the kernel to give up. - - However, in Nov 2011, the scsi pass through was replaced by raw libusb, so - instead of having to let usb-storage struggle with the device, and also greatly - limiting the portability of the driver, you can now tell usb-storage to simply - ignore this device completely. - - usb-storage.quirks - http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/kernel-parameters.txt - Each entry has the form VID:PID:Flags where VID and PID are Vendor and Product - ID values (4-digit hex numbers) and Flags is a set of characters, each corresponding - to a common usb-storage quirk flag as follows: - - a = SANE_SENSE (collect more than 18 bytes of sense data); - b = BAD_SENSE (don't collect more than 18 bytes of sense data); - c = FIX_CAPACITY (decrease the reported device capacity by one sector); - h = CAPACITY_HEURISTICS (decrease the reported device capacity by one sector if the number is odd); - i = IGNORE_DEVICE (don't bind to this device); - l = NOT_LOCKABLE (don't try to lock and unlock ejectable media); - m = MAX_SECTORS_64 (don't transfer more than 64 sectors = 32 KB at a time); - o = CAPACITY_OK (accept the capacity reported by the device); - r = IGNORE_RESIDUE (the device reports bogus residue values); - s = SINGLE_LUN (the device has only one Logical Unit); - w = NO_WP_DETECT (don't test whether the medium is write-protected). - - Example: quirks=0419:aaf5:rl,0421:0433:rc - http://permalink.gmane.org/gmane.linux.usb.general/35053 - - For the stlinkv1, you just want the following - - modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i - - Equivalently, you can add a line saying - - options usb-storage quirks=483:3744:i - - to your /etc/modprobe.conf or /etc/modprobe.d/local.conf (or add the "quirks=..." - part to an existing options line for usb-storage). + * Copyright (c) 2010 "Capt'ns Missing Link" Authors. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + * + * A linux stlink access demo. The purpose of this file is to mitigate the usual + * "reinventing the wheel" force by incompatible licenses and give you an idea, + * how to access the stlink device. That doesn't mean you should be a free-loader + * and not contribute your improvements to this code. + * + * Author: Martin Capitanio + * The stlink related constants kindly provided by Oliver Spencer (OpenOCD) + * for use in a GPL compatible license. + * + * Tested compatibility: linux, gcc >= 4.3.3 + * + * The communication is based on standard USB mass storage device + * BOT (Bulk Only Transfer) + * - Endpoint 1: BULK_IN, 64 bytes max + * - Endpoint 2: BULK_OUT, 64 bytes max + * + * All CBW transfers are ordered with the LSB (byte 0) first (little endian). + * Any command must be answered before sending the next command. + * Each USB transfer must complete in less than 1s. + * + * SB Device Class Definition for Mass Storage Devices: + * www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf + * + * dt - Data Transfer (IN/OUT) + * CBW - Command Block Wrapper + * CSW - Command Status Wrapper + * RFU - Reserved for Future Use + * + * Originally, this driver used scsi pass through commands, which required the + * usb-storage module to be loaded, providing the /dev/sgX links. The USB mass + * storage implementation on the STLinkv1 is however terribly broken, and it can + * take many minutes for the kernel to give up. + * + * However, in Nov 2011, the scsi pass through was replaced by raw libusb, so + * instead of having to let usb-storage struggle with the device, and also greatly + * limiting the portability of the driver, you can now tell usb-storage to simply + * ignore this device completely. + * + * usb-storage.quirks + * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=Documentation/kernel-parameters.txt + * Each entry has the form VID:PID:Flags where VID and PID are Vendor and Product + * ID values (4-digit hex numbers) and Flags is a set of characters, each corresponding + * to a common usb-storage quirk flag as follows: + * + * a = SANE_SENSE (collect more than 18 bytes of sense data); + * b = BAD_SENSE (don't collect more than 18 bytes of sense data); + * c = FIX_CAPACITY (decrease the reported device capacity by one sector); + * h = CAPACITY_HEURISTICS (decrease the reported device capacity by one sector if the number is odd); + * i = IGNORE_DEVICE (don't bind to this device); + * l = NOT_LOCKABLE (don't try to lock and unlock ejectable media); + * m = MAX_SECTORS_64 (don't transfer more than 64 sectors = 32 KB at a time); + * o = CAPACITY_OK (accept the capacity reported by the device); + * r = IGNORE_RESIDUE (the device reports bogus residue values); + * s = SINGLE_LUN (the device has only one Logical Unit); + * w = NO_WP_DETECT (don't test whether the medium is write-protected). + * + * Example: quirks=0419:aaf5:rl,0421:0433:rc + * http://permalink.gmane.org/gmane.linux.usb.general/35053 + * + * For the stlinkv1, you just want the following + * + * modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i + * + * Equivalently, you can add a line saying + * + * options usb-storage quirks=483:3744:i + * + * to your /etc/modprobe.conf or /etc/modprobe.d/local.conf (or add the "quirks=..." + * part to an existing options line for usb-storage). */ @@ -108,7 +108,8 @@ static void clear_cdb(struct stlink_libsg *sl) { /** * Close and free any _backend_ related information... * @param sl - */void _stlink_sg_close(stlink_t *sl) { + */ +void _stlink_sg_close(stlink_t *sl) { if (sl) { struct stlink_libsg *slsg = sl->backend_data; libusb_close(slsg->usb_handle); @@ -126,7 +127,7 @@ static int get_usb_mass_storage_status(libusb_device_handle *handle, uint8_t end int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint, (unsigned char *)&csw, sizeof(csw), - &transferred, SG_TIMEOUT_MSEC); + &transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint); } @@ -175,11 +176,11 @@ static int dump_CDB_command(uint8_t *cdb, uint8_t cdb_len) { * @param lun * @param flags * @param expected_rx_size - * @return + * @return */ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out, - uint8_t *cdb, uint8_t cdb_length, - uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { + uint8_t *cdb, uint8_t cdb_length, + uint8_t lun, uint8_t flags, uint32_t expected_rx_size) { DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size); dump_CDB_command(cdb, cdb_length); @@ -211,13 +212,13 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint // Now the actual CDB request assert(cdb_length <= CDB_SL); memcpy(&(c_buf[i]), cdb, cdb_length); - + int sending_length = STLINK_SG_SIZE; - + // send.... do { ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length, - &real_transferred, SG_TIMEOUT_MSEC); + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } @@ -237,7 +238,7 @@ int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint * @param endpoint_in * @param endpoint_out */ -static void + static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out) { DLOG("Fetching sense...\n"); @@ -248,7 +249,7 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou cdb[0] = REQUEST_SENSE; cdb[4] = REQUEST_SENSE_LENGTH; uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0, - LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); + LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH); if (tag == 0) { WLOG("refusing to send request sense with tag 0\n"); return; @@ -259,7 +260,7 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense), - &transferred, SG_TIMEOUT_MSEC); + &transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_in); } @@ -289,20 +290,20 @@ get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_ou * Just send a buffer on an endpoint, no questions asked. * Handles repeats, and time outs. Also handles reading status reports and sense * @param handle libusb device * - * @param endpoint_out sends - * @param endpoint_in used to read status reports back in + * @param endpoint_out sends + * @param endpoint_in used to read status reports back in * @param cbuf what to send * @param length how much to send * @return number of bytes actually sent, or -1 for failures. */ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, - unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { + unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) { int ret; int real_transferred; int try = 0; do { ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length, - &real_transferred, SG_TIMEOUT_MSEC); + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(handle, endpoint_out); } @@ -312,7 +313,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, WLOG("sending failed: %d\n", ret); return -1; } - + // now, swallow up the status, so that things behave nicely... uint32_t received_tag; // -ve is for my errors, 0 is good, +ve is libusb sense status bytes @@ -328,7 +329,7 @@ int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out, get_sense(handle, endpoint_in, endpoint_out); return -1; } - + return real_transferred; } @@ -338,10 +339,10 @@ int stlink_q(stlink_t *sl) { //uint8_t cdb_len = 6; // FIXME varies!!! uint8_t cdb_len = 10; // FIXME varies!!! uint8_t lun = 0; // always zero... - uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, - sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); - - + uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, + sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len); + + // now wait for our response... // length copied from stlink-usb... int rx_length = sl->q_len; @@ -350,8 +351,8 @@ int stlink_q(stlink_t *sl) { int ret; if (rx_length > 0) { do { - ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, - &real_transferred, SG_TIMEOUT_MSEC); + ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, + &real_transferred, SG_TIMEOUT_MSEC); if (ret == LIBUSB_ERROR_PIPE) { libusb_clear_halt(sg->usb_handle, sg->ep_req); } @@ -401,14 +402,14 @@ void stlink_stat(stlink_t *stl, char *txt) { stlink_print_data(stl); switch (stl->q_buf[0]) { - case STLINK_OK: - DLOG(" %s: ok\n", txt); - return; - case STLINK_FALSE: - DLOG(" %s: false\n", txt); - return; - default: - DLOG(" %s: unknown\n", txt); + case STLINK_OK: + DLOG(" %s: ok\n", txt); + return; + case STLINK_FALSE: + DLOG(" %s: false\n", txt); + return; + default: + DLOG(" %s: unknown\n", txt); } } @@ -471,48 +472,48 @@ void _stlink_sg_exit_dfu_mode(stlink_t *sl) { sl->q_len = 0; // ?? stlink_q(sl); /* - [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code - [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK - [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00 - [135121.844584] end_request: I/O error, dev sdb, sector 4096 - [135121.844590] Buffer I/O error on device sdb, logical block 512 - [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7 - [135130.274551] usb 6-1: device firmware changed - [135130.274618] usb 6-1: USB disconnect, address 7 - [135130.275186] VFS: busy inodes on changed media or resized disk sdb - [135130.275424] VFS: busy inodes on changed media or resized disk sdb - [135130.286758] VFS: busy inodes on changed media or resized disk sdb - [135130.292796] VFS: busy inodes on changed media or resized disk sdb - [135130.301481] VFS: busy inodes on changed media or resized disk sdb - [135130.304316] VFS: busy inodes on changed media or resized disk sdb - [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8 - [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1 - [135130.629492] scsi20 : usb-storage 6-1:1.0 - [135131.625600] scsi 20:0:0:0: Direct-Access STM32 PQ: 0 ANSI: 0 - [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0 - [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB) - [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.640609] sdb: - [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled - [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through - [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk - [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE - [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] - [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range - [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 - [135131.671570] end_request: I/O error, dev sdb, sector 63872 - [135131.671575] Buffer I/O error on device sdb, logical block 7984 - [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE - [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] - [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range - [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 - [135131.678551] end_request: I/O error, dev sdb, sector 63872 - ... - [135131.853565] end_request: I/O error, dev sdb, sector 4096 - */ + [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code + [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK + [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00 + [135121.844584] end_request: I/O error, dev sdb, sector 4096 + [135121.844590] Buffer I/O error on device sdb, logical block 512 + [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7 + [135130.274551] usb 6-1: device firmware changed + [135130.274618] usb 6-1: USB disconnect, address 7 + [135130.275186] VFS: busy inodes on changed media or resized disk sdb + [135130.275424] VFS: busy inodes on changed media or resized disk sdb + [135130.286758] VFS: busy inodes on changed media or resized disk sdb + [135130.292796] VFS: busy inodes on changed media or resized disk sdb + [135130.301481] VFS: busy inodes on changed media or resized disk sdb + [135130.304316] VFS: busy inodes on changed media or resized disk sdb + [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8 + [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1 + [135130.629492] scsi20 : usb-storage 6-1:1.0 + [135131.625600] scsi 20:0:0:0: Direct-Access STM32 PQ: 0 ANSI: 0 + [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0 + [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB) + [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.640609] sdb: + [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled + [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through + [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk + [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] + [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range + [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 + [135131.671570] end_request: I/O error, dev sdb, sector 63872 + [135131.671575] Buffer I/O error on device sdb, logical block 7984 + [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE + [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current] + [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range + [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00 + [135131.678551] end_request: I/O error, dev sdb, sector 63872 + ... + [135131.853565] end_request: I/O error, dev sdb, sector 4096 + */ } void _stlink_sg_core_id(stlink_t *sl) { @@ -586,7 +587,7 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) { stlink_print_data(sl); // TODO - most of this should be re-extracted up.... - + // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71 | 72-75 | 76-79 | 80-83 // r0 | r1 | ... | r15 | xpsr | main_sp | process_sp | rw | rw2 for (int i = 0; i < 16; i++) { @@ -630,23 +631,23 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 16: - regp->xpsr = r; - break; - case 17: - regp->main_sp = r; - break; - case 18: - regp->process_sp = r; - break; - case 19: - regp->rw = r; //XXX ?(primask, basemask etc.) - break; - case 20: - regp->rw2 = r; //XXX ?(primask, basemask etc.) - break; - default: - regp->r[r_idx] = r; + case 16: + regp->xpsr = r; + break; + case 17: + regp->main_sp = r; + break; + case 18: + regp->process_sp = r; + break; + case 19: + regp->rw = r; //XXX ?(primask, basemask etc.) + break; + case 20: + regp->rw2 = r; //XXX ?(primask, basemask etc.) + break; + default: + regp->r[r_idx] = r; } } @@ -883,7 +884,7 @@ stlink_backend_t _stlink_sg_backend = { }; static stlink_t* stlink_open(const int verbose) { - + stlink_t *sl = malloc(sizeof (stlink_t)); memset(sl, 0, sizeof(stlink_t)); struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg)); @@ -891,16 +892,16 @@ static stlink_t* stlink_open(const int verbose) { WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n"); return NULL; } - + if (libusb_init(&(slsg->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); free(sl); free(slsg); return NULL; } - + libusb_set_debug(slsg->libusb_ctx, 3); - + slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID); if (slsg->usb_handle == NULL) { WLOG("Failed to find an stlink v1 by VID:PID\n"); @@ -910,10 +911,10 @@ static stlink_t* stlink_open(const int verbose) { free(slsg); return NULL; } - - // TODO + + // TODO // Could read the interface config descriptor, and assert lots of the assumptions - + // assumption: numInterfaces is always 1... if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) { int r = libusb_detach_kernel_driver(slsg->usb_handle, 0); @@ -939,7 +940,7 @@ static stlink_t* stlink_open(const int verbose) { return NULL; } - + // assumption: bConfigurationValue is always 1 if (config != 1) { WLOG("Your stlink got into a real weird configuration, trying to fix it!\n"); @@ -967,9 +968,9 @@ static stlink_t* stlink_open(const int verbose) { // assumption: endpoint config is fixed mang. really. slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; - + DLOG("Successfully opened stlinkv1 by libusb :)\n"); - + sl->verbose = verbose; sl->backend_data = slsg; sl->backend = &_stlink_sg_backend; @@ -991,15 +992,15 @@ stlink_t* stlink_v1_open_inner(const int verbose) { stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } DLOG("Reading current mode...\n"); switch (stlink_current_mode(sl)) { case STLINK_DEV_MASS_MODE: - return sl; + return sl; case STLINK_DEV_DEBUG_MODE: // TODO go to mass? return sl; @@ -1010,12 +1011,12 @@ stlink_t* stlink_v1_open_inner(const int verbose) { DLOG("Attempting to exit DFU mode\n"); _stlink_sg_exit_dfu_mode(sl); - + // re-query device info (and retest) stlink_version(sl); if ((sl->version.st_vid != USB_ST_VID) || (sl->version.stlink_pid != USB_STLINK_PID)) { - ugly_log(UERROR, LOG_TAG, - "WTF? successfully opened, but unable to read version details. BROKEN!\n"); + ugly_log(UERROR, LOG_TAG, + "WTF? successfully opened, but unable to read version details. BROKEN!\n"); return NULL; } @@ -1029,7 +1030,7 @@ stlink_t* stlink_v1_open(const int verbose, int reset) { return NULL; } // by now, it _must_ be fully open and in a useful mode.... - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); /* Now we are ready to read the parameters */ if (reset) { stlink_reset(sl); diff --git a/src/stlink-sg.h b/src/stlink-sg.h index f8871db..7c02028 100644 --- a/src/stlink-sg.h +++ b/src/stlink-sg.h @@ -1,4 +1,4 @@ -/* +/* * File: stlink-sg.h * Author: karl * @@ -11,11 +11,11 @@ #ifdef __cplusplus extern "C" { #endif - + #include #include "stlink-common.h" - - // device access + + // device access #define RDWR 0 #define RO 1 #define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec @@ -46,7 +46,7 @@ extern "C" { libusb_device_handle *usb_handle; unsigned ep_rep; unsigned ep_req; - + int sg_fd; int do_scsi_pt_err; diff --git a/src/stlink-usb.c b/src/stlink-usb.c index 8e910bc..23ff191 100644 --- a/src/stlink-usb.c +++ b/src/stlink-usb.c @@ -16,17 +16,17 @@ #define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args) #define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args) -/* code from bsd timersub.h +/* code from bsd timersub.h http://www.gnu-darwin.org/www001/src/ports/net/libevnet/work/libevnet-0.3.8/libnostd/bsd/sys/time/timersub.h.html */ #if !defined timersub #define timersub(a, b, r) do { \ - (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((r)->tv_usec < 0) { \ - --(r)->tv_sec; \ - (r)->tv_usec += 1000000; \ - } \ + (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((r)->tv_usec < 0) { \ + --(r)->tv_sec; \ + (r)->tv_usec += 1000000; \ + } \ } while (0) #endif @@ -135,14 +135,14 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, if (rxsize != 0) { /* read the response */ - + libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle, - handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0); - + handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0); + if (submit_wait(handle, handle->rep_trans)) return -1; res = handle->rep_trans->actual_length; } - + if ((handle->protocoll == 1) && terminate) { /* Read the SG reply */ unsigned char sg_buf[13]; @@ -237,7 +237,7 @@ uint32_t _stlink_usb_read_debug32(stlink_t *sl, uint32_t addr) { unsigned char* const cmd = sl->c_buf; ssize_t size; const int rep_len = 8; - + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_READDEBUG_32BIT; @@ -256,7 +256,7 @@ void _stlink_usb_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) { unsigned char* const cmd = sl->c_buf; ssize_t size; const int rep_len = 2; - + int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_JTAG_WRITEDEBUG_32BIT; @@ -306,7 +306,7 @@ int _stlink_usb_current_mode(stlink_t * sl) { ssize_t size; int rep_len = 2; int i = fill_command(sl, SG_DXFER_FROM_DEV, rep_len); - + cmd[i++] = STLINK_GET_CURRENT_MODE; size = send_recv(slu, 1, cmd, slu->cmd_len, data, rep_len); if (size == -1) { @@ -582,7 +582,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) { stlink_print_data(sl); r = read_uint32(sl->q_buf, 0); DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); - + switch (r_idx) { case 16: regp->xpsr = r; @@ -620,18 +620,18 @@ void _stlink_usb_read_unsupported_reg(stlink_t *sl, int r_idx, reg *regp) { DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r); switch (r_idx) { - case 0x14: - regp->primask = (uint8_t) (r & 0xFF); - regp->basepri = (uint8_t) ((r>>8) & 0xFF); - regp->faultmask = (uint8_t) ((r>>16) & 0xFF); - regp->control = (uint8_t) ((r>>24) & 0xFF); - break; - case 0x21: - regp->fpscr = r; - break; - default: - regp->s[r_idx - 0x40] = r; - break; + case 0x14: + regp->primask = (uint8_t) (r & 0xFF); + regp->basepri = (uint8_t) ((r>>8) & 0xFF); + regp->faultmask = (uint8_t) ((r>>16) & 0xFF); + regp->control = (uint8_t) ((r>>24) & 0xFF); + break; + case 0x21: + regp->fpscr = r; + break; + default: + regp->s[r_idx - 0x40] = r; + break; } } @@ -653,18 +653,18 @@ void _stlink_usb_write_unsupported_reg(stlink_t *sl, uint32_t val, int r_idx, re val = (uint8_t) (val>>24); switch (r_idx) { - case 0x1C: /* control */ - val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1D: /* faultmask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); - break; - case 0x1E: /* basepri */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); - break; - case 0x1F: /* primask */ - val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); - break; + case 0x1C: /* control */ + val = (((uint32_t) val) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1D: /* faultmask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) val) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) regp->primask); + break; + case 0x1E: /* basepri */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) val) << 8) | ((uint32_t) regp->primask); + break; + case 0x1F: /* primask */ + val = (((uint32_t) regp->control) << 24) | (((uint32_t) regp->faultmask) << 16) | (((uint32_t) regp->basepri) << 8) | ((uint32_t) val); + break; } r_idx = 0x14; @@ -750,20 +750,20 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { ugly_init(verbose); sl->backend = &_stlink_usb_backend; sl->backend_data = slu; - + sl->core_stat = STLINK_CORE_STAT_UNKNOWN; if (libusb_init(&(slu->libusb_ctx))) { WLOG("failed to init libusb context, wrong version of libraries?\n"); goto on_error; } - + libusb_device **list; int cnt = libusb_get_device_list(slu->libusb_ctx, &list); struct libusb_device_descriptor desc; int devBus =0; int devAddr=0; - + char *device = getenv("STLINK_DEVICE"); if (device) { char *c = strchr(device,':'); @@ -788,7 +788,7 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { break; } } - + if (cnt < 0) { WLOG ("Couldn't find %s ST-Link/V2 devices\n",(devBus && devAddr)?"matched":"any"); goto on_error; @@ -799,13 +799,13 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { goto on_error; } } - + libusb_free_device_list(list, 1); - + if (libusb_kernel_driver_active(slu->usb_handle, 0) == 1) { int r; - + r = libusb_detach_kernel_driver(slu->usb_handle, 0); if (r<0) { WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r)); @@ -848,9 +848,9 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { // TODO - could use the scanning techniq from stm8 code here... slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN; if (desc.idProduct == USB_STLINK_NUCLEO_PID) { - slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_req = 1 /* ep req */ | LIBUSB_ENDPOINT_OUT; } else { - slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; + slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT; } slu->sg_transfer_idx = 0; @@ -860,12 +860,12 @@ stlink_t* stlink_open_usb(const int verbose, int reset) { /* success */ if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { - ILOG("-- exit_dfu_mode\n"); - stlink_exit_dfu_mode(sl); + ILOG("-- exit_dfu_mode\n"); + stlink_exit_dfu_mode(sl); } if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { - stlink_enter_swd_mode(sl); + stlink_enter_swd_mode(sl); } if (reset) { @@ -891,7 +891,7 @@ on_libusb_error: on_error: if( slu->libusb_ctx) - libusb_exit(slu->libusb_ctx); + libusb_exit(slu->libusb_ctx); if (sl != NULL) free(sl); if (slu != NULL) free(slu); return 0; diff --git a/src/stlink-usb.h b/src/stlink-usb.h index f433193..58b60e4 100644 --- a/src/stlink-usb.h +++ b/src/stlink-usb.h @@ -1,4 +1,4 @@ -/* +/* * File: stlink-usb.h * Author: karl * @@ -14,7 +14,7 @@ extern "C" { #include #include "stlink-common.h" - + #define STLINK_SG_SIZE 31 #define STLINK_CMD_SIZE 16 @@ -29,7 +29,7 @@ extern "C" { unsigned int sg_transfer_idx; unsigned int cmd_len; }; - + stlink_t* stlink_open_usb(const int verbose, int reset); diff --git a/src/test_sg.c b/src/test_sg.c index bc16a1c..dea6ffb 100644 --- a/src/test_sg.c +++ b/src/test_sg.c @@ -33,196 +33,196 @@ static void __attribute__((unused)) mark_buf(stlink_t *sl) { int main(int argc, char *argv[]) { - /* Avoid unused parameter warning */ - (void)argv; - // set scpi lib debug level: 0 for no debug info, 10 for lots - - switch (argc) { - case 1: - fputs( - "\nUsage: stlink-access-test [anything at all] ...\n" - "\n*** Notice: The stlink firmware violates the USB standard.\n" - "*** Because we just use libusb, we can just tell the kernel's\n" - "*** driver to simply ignore the device...\n" - "*** Unplug the stlink and execute once as root:\n" - "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", - stderr); - return EXIT_FAILURE; - default: + /* Avoid unused parameter warning */ + (void)argv; + // set scpi lib debug level: 0 for no debug info, 10 for lots + + switch (argc) { + case 1: + fputs( + "\nUsage: stlink-access-test [anything at all] ...\n" + "\n*** Notice: The stlink firmware violates the USB standard.\n" + "*** Because we just use libusb, we can just tell the kernel's\n" + "*** driver to simply ignore the device...\n" + "*** Unplug the stlink and execute once as root:\n" + "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", + stderr); + return EXIT_FAILURE; + default: break; - } - - stlink_t *sl = stlink_v1_open(99, 1); - if (sl == NULL) - return EXIT_FAILURE; - - // we are in mass mode, go to swd - stlink_enter_swd_mode(sl); - stlink_current_mode(sl); - stlink_core_id(sl); - //---------------------------------------------------------------------- - - stlink_status(sl); - //stlink_force_debug(sl); - stlink_reset(sl); - stlink_status(sl); - // core system control block - stlink_read_mem32(sl, 0xe000ed00, 4); - DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); - // no MPU - stlink_read_mem32(sl, 0xe000ed90, 4); - DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); + } + + stlink_t *sl = stlink_v1_open(99, 1); + if (sl == NULL) + return EXIT_FAILURE; + + // we are in mass mode, go to swd + stlink_enter_swd_mode(sl); + stlink_current_mode(sl); + stlink_core_id(sl); + //---------------------------------------------------------------------- + + stlink_status(sl); + //stlink_force_debug(sl); + stlink_reset(sl); + stlink_status(sl); + // core system control block + stlink_read_mem32(sl, 0xe000ed00, 4); + DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); + // no MPU + stlink_read_mem32(sl, 0xe000ed90, 4); + DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); #if 0 - stlink_read_mem32(sl, 0xe000edf0, 4); - DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); + stlink_read_mem32(sl, 0xe000edf0, 4); + DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); - stlink_read_mem32(sl, 0x4001100c, 4); - DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); + stlink_read_mem32(sl, 0x4001100c, 4); + DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif #if 0 - // happy new year 2011: let blink all the leds - // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" + // happy new year 2011: let blink all the leds + // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" #define GPIOC 0x40011000 // port C #define GPIOC_CRH (GPIOC + 0x04) // port configuration register high #define GPIOC_ODR (GPIOC + 0x0c) // port output data register #define LED_BLUE (1<<8) // pin 8 #define LED_GREEN (1<<9) // pin 9 - stlink_read_mem32(sl, GPIOC_CRH, 4); - uint32_t io_conf = read_uint32(sl->q_buf, 0); - DLOG("GPIOC_CRH = 0x%08x\n", io_conf); - - // set: general purpose output push-pull, output mode, max speed 10 MHz. - write_uint32(sl->q_buf, 0x44444411); - stlink_write_mem32(sl, GPIOC_CRH, 4); - - memset(sl->q_buf, 0, sizeof(sl->q_buf)); - for (int i = 0; i < 100; i++) { - write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); - stlink_write_mem32(sl, GPIOC_ODR, 4); - /* stlink_read_mem32(sl, 0x4001100c, 4); */ - /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ - usleep(100 * 1000); - - memset(sl->q_buf, 0, sizeof(sl->q_buf)); - stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo + stlink_read_mem32(sl, GPIOC_CRH, 4); + uint32_t io_conf = read_uint32(sl->q_buf, 0); + DLOG("GPIOC_CRH = 0x%08x\n", io_conf); + + // set: general purpose output push-pull, output mode, max speed 10 MHz. + write_uint32(sl->q_buf, 0x44444411); + stlink_write_mem32(sl, GPIOC_CRH, 4); + + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + for (int i = 0; i < 100; i++) { + write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); + stlink_write_mem32(sl, GPIOC_ODR, 4); + /* stlink_read_mem32(sl, 0x4001100c, 4); */ + /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ usleep(100 * 1000); - } - write_uint32(sl->q_buf, io_conf); // set old state + + memset(sl->q_buf, 0, sizeof(sl->q_buf)); + stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo + usleep(100 * 1000); + } + write_uint32(sl->q_buf, io_conf); // set old state #endif #if 0 - // TODO rtfm: stlink doesn't have flash write routines - // writing to the flash area confuses the fw for the next read access - - //stlink_read_mem32(sl, 0, 1024*6); - // flash 0x08000000 128kB - fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); - stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB - clear_buf(sl); - stlink_read_mem32(sl, 0x08000c00, 5); - stlink_read_mem32(sl, 0x08000c00, 4); - mark_buf(sl); - stlink_write_mem32(sl, 0x08000c00, 4); - stlink_read_mem32(sl, 0x08000c00, 256); - stlink_read_mem32(sl, 0x08000c00, 256); + // TODO rtfm: stlink doesn't have flash write routines + // writing to the flash area confuses the fw for the next read access + + //stlink_read_mem32(sl, 0, 1024*6); + // flash 0x08000000 128kB + fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); + stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB + clear_buf(sl); + stlink_read_mem32(sl, 0x08000c00, 5); + stlink_read_mem32(sl, 0x08000c00, 4); + mark_buf(sl); + stlink_write_mem32(sl, 0x08000c00, 4); + stlink_read_mem32(sl, 0x08000c00, 256); + stlink_read_mem32(sl, 0x08000c00, 256); #endif #if 0 - // sram 0x20000000 8kB - fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); + // sram 0x20000000 8kB + fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); - //stlink_write_mem8(sl, 0x20000000, 16); + //stlink_write_mem8(sl, 0x20000000, 16); - //stlink_write_mem8(sl, 0x20000000, 1); - //stlink_write_mem8(sl, 0x20000001, 1); - stlink_write_mem8(sl, 0x2000000b, 3); - stlink_read_mem32(sl, 0x20000000, 16); + //stlink_write_mem8(sl, 0x20000000, 1); + //stlink_write_mem8(sl, 0x20000001, 1); + stlink_write_mem8(sl, 0x2000000b, 3); + stlink_read_mem32(sl, 0x20000000, 16); #endif #if 0 - // a not aligned mem32 access doesn't work indeed - fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); + // a not aligned mem32 access doesn't work indeed + fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 1); - stlink_read_mem32(sl, 0x20000000, 16); - mark_buf(sl); - stlink_write_mem32(sl, 0x20000001, 1); - stlink_read_mem32(sl, 0x20000000, 16); - mark_buf(sl); - stlink_write_mem32(sl, 0x2000000b, 3); - stlink_read_mem32(sl, 0x20000000, 16); - - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 17); - stlink_read_mem32(sl, 0x20000000, 32); + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 1); + stlink_read_mem32(sl, 0x20000000, 16); + mark_buf(sl); + stlink_write_mem32(sl, 0x20000001, 1); + stlink_read_mem32(sl, 0x20000000, 16); + mark_buf(sl); + stlink_write_mem32(sl, 0x2000000b, 3); + stlink_read_mem32(sl, 0x20000000, 16); + + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 17); + stlink_read_mem32(sl, 0x20000000, 32); #endif #if 0 - // sram 0x20000000 8kB - fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); + // sram 0x20000000 8kB + fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); - mark_buf(sl); - stlink_write_mem8(sl, 0x20000000, 64); - stlink_read_mem32(sl, 0x20000000, 64); - - mark_buf(sl); - stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB - stlink_read_mem32(sl, 0x20000000, 1024 * 6); - stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); + mark_buf(sl); + stlink_write_mem8(sl, 0x20000000, 64); + stlink_read_mem32(sl, 0x20000000, 64); + + mark_buf(sl); + stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB + stlink_read_mem32(sl, 0x20000000, 1024 * 6); + stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif #if 1 reg regs; - stlink_read_all_regs(sl, ®s); - stlink_step(sl); - fputs("++++++++++ write r0 = 0x12345678\n", stderr); - stlink_write_reg(sl, 0x12345678, 0); - stlink_read_reg(sl, 0, ®s); - stlink_read_all_regs(sl, ®s); + stlink_read_all_regs(sl, ®s); + stlink_step(sl); + fputs("++++++++++ write r0 = 0x12345678\n", stderr); + stlink_write_reg(sl, 0x12345678, 0); + stlink_read_reg(sl, 0, ®s); + stlink_read_all_regs(sl, ®s); #endif #if 0 - stlink_run(sl); - stlink_status(sl); + stlink_run(sl); + stlink_status(sl); - stlink_force_debug(sl); - stlink_status(sl); + stlink_force_debug(sl); + stlink_status(sl); #endif #if 0 /* read the system bootloader */ - fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); - stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); + fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); + stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif #if 0 /* read the flash memory */ - fputs("\n+++++++ read flash memory\n\n", stderr); - /* mark_buf(sl); */ - stlink_read_mem32(sl, 0x08000000, 4); + fputs("\n+++++++ read flash memory\n\n", stderr); + /* mark_buf(sl); */ + stlink_read_mem32(sl, 0x08000000, 4); #endif #if 0 /* flash programming */ - fputs("\n+++++++ program flash memory\n\n", stderr); - stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); + fputs("\n+++++++ program flash memory\n\n", stderr); + stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif #if 0 /* check file contents */ - fputs("\n+++++++ check flash memory\n\n", stderr); - { - const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); - printf("_____ stlink_fcheck_flash() == %d\n", res); - } + fputs("\n+++++++ check flash memory\n\n", stderr); + { + const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); + printf("_____ stlink_fcheck_flash() == %d\n", res); + } #endif #if 0 - fputs("\n+++++++ sram write and execute\n\n", stderr); - stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); - stlink_run_at(sl, sl->sram_base); + fputs("\n+++++++ sram write and execute\n\n", stderr); + stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); + stlink_run_at(sl, sl->sram_base); #endif #if 0 - stlink_run(sl); - stlink_status(sl); - //---------------------------------------------------------------------- - // back to mass mode, just in case ... - stlink_exit_debug_mode(sl); - stlink_current_mode(sl); - stlink_close(sl); + stlink_run(sl); + stlink_status(sl); + //---------------------------------------------------------------------- + // back to mass mode, just in case ... + stlink_exit_debug_mode(sl); + stlink_current_mode(sl); + stlink_close(sl); #endif - //fflush(stderr); fflush(stdout); - return EXIT_SUCCESS; + //fflush(stderr); fflush(stdout); + return EXIT_SUCCESS; } diff --git a/src/test_usb.c b/src/test_usb.c index 5e8806d..eb8e54c 100644 --- a/src/test_usb.c +++ b/src/test_usb.c @@ -14,7 +14,7 @@ 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) { @@ -43,7 +43,7 @@ int main(int ac, char** av) { printf("FP_CTRL\n"); stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4); - + // no idea what reg this is.. */ // stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... @@ -58,7 +58,7 @@ int main(int ac, char** av) { stlink_write_mem32(sl,0x200000ac, 4); stlink_read_mem32(sl, 0x200000a8, 4); stlink_read_mem32(sl, 0x200000ac, 4); - + /* Test 8 bit write */ write_uint32(sl->q_buf,0x01234567); stlink_write_mem8(sl,0x200001a8,3); @@ -79,8 +79,8 @@ int main(int ac, char** av) { stlink_write_reg(sl, 0x12345678, 15); for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); - - + + stlink_read_all_regs(sl, ®s); printf("-- status\n"); diff --git a/src/uglylogging.c b/src/uglylogging.c index c6d07f8..a04ab33 100644 --- a/src/uglylogging.c +++ b/src/uglylogging.c @@ -1,7 +1,7 @@ -/* - * UglyLogging. Slow, yet another wheel reinvented, but enough to make the +/* + * UglyLogging. Slow, yet another wheel reinvented, but enough to make the * rest of our code pretty enough. - * + * */ #include @@ -30,29 +30,29 @@ int ugly_log(int level, const char *tag, const char *format, ...) { tt = localtime(&mytt); fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec); switch (level) { - case UDEBUG: - fprintf(stderr, "DEBUG %s: ", tag); - break; - case UINFO: - fprintf(stderr, "INFO %s: ", tag); - break; - case UWARN: - fprintf(stderr, "WARN %s: ", tag); - break; - case UERROR: - fprintf(stderr, "ERROR %s: ", tag); - break; - case UFATAL: - fprintf(stderr, "FATAL %s: ", tag); - vfprintf(stderr, format, args); - exit(EXIT_FAILURE); - // NEVER GETS HERE!!! - break; - default: - fprintf(stderr, "%d %s: ", level, tag); - break; + case UDEBUG: + fprintf(stderr, "DEBUG %s: ", tag); + break; + case UINFO: + fprintf(stderr, "INFO %s: ", tag); + break; + case UWARN: + fprintf(stderr, "WARN %s: ", tag); + break; + case UERROR: + fprintf(stderr, "ERROR %s: ", tag); + break; + case UFATAL: + fprintf(stderr, "FATAL %s: ", tag); + vfprintf(stderr, format, args); + exit(EXIT_FAILURE); + // NEVER GETS HERE!!! + break; + default: + fprintf(stderr, "%d %s: ", level, tag); + break; } - vfprintf(stderr, format, args); + vfprintf(stderr, format, args); va_end(args); return 1; -} \ No newline at end of file +} diff --git a/src/uglylogging.h b/src/uglylogging.h index fa34d46..5122820 100644 --- a/src/uglylogging.h +++ b/src/uglylogging.h @@ -1,4 +1,4 @@ -/* +/* * Ugly, low performance, configurable level, logging "framework" */ @@ -8,7 +8,7 @@ #ifdef __cplusplus extern "C" { #endif - + #define UDEBUG 90 #define UINFO 50 #define UWARN 30 -- 2.30.2