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.
pull/248/head
Michael Pratt 2014-07-09 22:31:11 -07:00
rodzic 2a4466ec4e
commit 3b443dc1c8
23 zmienionych plików z 3079 dodań i 3084 usunięć

Wyświetl plik

@ -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 <size> */
/* stlinkv2 command line: ./flash {read|write} path addr <size> */
/* stlinkv1 command line: ./flash {read|write} /dev/sgX path addr <size> */
/* stlinkv2 command line: ./flash {read|write} path addr <size> */
unsigned int i = 0;
unsigned int i = 0;
if (ac < 1) return -1;
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)
if (strcmp(av[0], "--reset") == 0)
{
o->devname = av[1];
i = 1;
o->reset = 1;
ac--;
av++;
}
else
{
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);
if (ac < 1) return -1;
return 0;
}
/* 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;
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;
}
}
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)
o.size = 0;
if (get_opts(&o, ac - 1, av + 1) == -1)
{
printf("stlink_fwrite_flash() == -1\n");
goto on_error;
printf("invalid command line\n");
usage();
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)
if (o.devname != NULL) /* stlinkv1 */
{
printf("stlink_fread() == -1\n");
goto on_error;
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 (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);
return err;
// 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;
}

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -1,10 +1,8 @@
/* -*- tab-width:8 -*- */
/*
Copyright (C) 2011 Peter Zotov <whitequark@whitequark.org>
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 <whitequark@whitequark.org>
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
#include <stdio.h>
#include <string.h>
@ -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) */
int length = strlen(data) + 5;
char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */
memset(packet, 0, length);
memset(packet, 0, length);
packet[0] = '$';
packet[0] = '$';
uint8_t cksum = 0;
for(unsigned int i = 0; i < strlen(data); i++) {
packet[i + 1] = data[i];
cksum += data[i];
}
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];
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;
}
while(1) {
if(write(fd, packet, length) != length) {
free(packet);
return -2;
}
char ack;
if(read(fd, &ack, 1) != 1) {
free(packet);
return -2;
}
char ack;
if(read(fd, &ack, 1) != 1) {
free(packet);
return -2;
}
if(ack == '+') {
free(packet);
return 0;
}
}
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
*/
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;
}
char c;
while(state != 4) {
if(read(fd, &c, 1) != 1) {
return -2;
}
switch(state) {
case 0:
if(c != '$') {
// ignore
} else {
state = 1;
}
break;
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;
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;
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 2:
recv_cksum[0] = c;
state = 3;
break;
case 3:
recv_cksum[1] = c;
state = 4;
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;
}
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;
}
}
goto start;
} else {
char ack = '+';
if(write(fd, &ack, 1) != 1) {
return -2;
}
}
packet_buffer[packet_idx] = 0;
*buffer = packet_buffer;
packet_buffer[packet_idx] = 0;
*buffer = packet_buffer;
return packet_idx;
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;
}

Plik diff jest za duży Load Diff

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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;
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;
/*< 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;
/* 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;
struct progress_t progress;
struct mem_t flash_mem;
struct mem_t file_mem;
gchar *error_message;
gchar *filename;
stlink_t *sl;
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);

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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 (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
stlink_enter_swd_mode(sl);
if (sl == NULL) {
return -1;
}
sl->verbose=0;
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE)
stlink_exit_dfu_mode(sl);
err = print_data(sl, av);
if (sl != NULL)
{
stlink_exit_debug_mode(sl);
stlink_close(sl);
}
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
stlink_enter_swd_mode(sl);
return err;
err = print_data(sl, av);
if (sl != NULL)
{
stlink_exit_debug_mode(sl);
stlink_close(sl);
}
return err;
}

Wyświetl plik

@ -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);
}
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);
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;
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &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);
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();
struct stlinky *st=NULL;
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);
sig_init();
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);
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);
stlink_reset(sl);
stlink_force_debug(sl);
stlink_run(sl);
stlink_status(sl);
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);
/* wait for device to boot */
/* TODO: Make timeout adjustable via command line */
sleep(1);
stlink_reset(sl);
stlink_force_debug(sl);
stlink_run(sl);
stlink_status(sl);
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;
/* 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;
}

Wyświetl plik

@ -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);
/* 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;
}
/* 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;
}
}
/* 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);
/* 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)
;
/* 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);
/* 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);
/* 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;
}
/* 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);
/* 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;
/* 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;
}

Wyświetl plik

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

Wyświetl plik

@ -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 <m@capitanio.org>
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 <m@capitanio.org>
* 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);

Wyświetl plik

@ -1,4 +1,4 @@
/*
/*
* File: stlink-sg.h
* Author: karl
*
@ -11,11 +11,11 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <libusb.h>
#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;

Wyświetl plik

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

Wyświetl plik

@ -1,4 +1,4 @@
/*
/*
* File: stlink-usb.h
* Author: karl
*
@ -14,7 +14,7 @@ extern "C" {
#include <libusb.h>
#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);

Wyświetl plik

@ -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
/* 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:
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_t *sl = stlink_v1_open(99, 1);
if (sl == NULL)
return EXIT_FAILURE;
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));
// 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);
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);
// 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
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
// 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);
//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, 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, 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_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_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, &regs);
stlink_step(sl);
fputs("++++++++++ write r0 = 0x12345678\n", stderr);
stlink_write_reg(sl, 0x12345678, 0);
stlink_read_reg(sl, 0, &regs);
stlink_read_all_regs(sl, &regs);
stlink_read_all_regs(sl, &regs);
stlink_step(sl);
fputs("++++++++++ write r0 = 0x12345678\n", stderr);
stlink_write_reg(sl, 0x12345678, 0);
stlink_read_reg(sl, 0, &regs);
stlink_read_all_regs(sl, &regs);
#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;
}

Wyświetl plik

@ -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, &regs);
stlink_read_all_regs(sl, &regs);
printf("-- status\n");

Wyświetl plik

@ -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 <stddef.h>
@ -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;
}
}

Wyświetl plik

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