From 2756c6d19c92223fe70d2a09490d41f6300f7a2b Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Sun, 14 Jun 2015 18:32:38 +0200 Subject: [PATCH 001/134] Fix ram_end value typo for 0x641 devices Thanks to keirfraser1 for reporting. "The current value 0x00005000 is clearly a typo, should be 0x20005000. Without this fix I am unable to write to the memory of a STM32F103C8 device." https://code.google.com/p/stm32flash/issues/detail?id=73 Signed-off-by: Tormod Volden --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 399cd9d..2c1b80d 100644 --- a/dev_table.c +++ b/dev_table.c @@ -63,7 +63,7 @@ const stm32_dev_t devices[] = { {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x00005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, {0x0} From 81a9e59c0fc8d6f77eacf82326bd12c67057630f Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Sun, 14 Jun 2015 19:02:52 +0200 Subject: [PATCH 002/134] Moved to stm32flash.sf.net - updated links Signed-off-by: Tormod Volden --- main.c | 2 +- stm32flash.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 5105d21..cbfad12 100644 --- a/main.c +++ b/main.c @@ -121,7 +121,7 @@ int main(int argc, char* argv[]) { FILE *diag = stdout; fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://stm32flash.googlecode.com/\n\n"); + fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); if (parse_options(argc, argv) != 0) goto close; diff --git a/stm32flash.1 b/stm32flash.1 index d37292f..24ac77c 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -343,7 +343,7 @@ Man page and extension to STM32W and I2C are written by .IR "Antonio Borneo " . Please report any bugs at the project homepage -http://stm32flash.googlecode.com . +http://stm32flash.sourceforge.net . .SH SEE ALSO .BR "srec_cat" "(1)," " srec_intel" "(5)," " srec_motorola" "(5)." From 4ac0566f188f39eace0223d966d349cd2f2c5895 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 7 Oct 2014 11:59:12 +0800 Subject: [PATCH 003/134] TX frame length: fix min value The minimum value for TX frame length is determined by command "write memory". It requires: - one byte for data length; - four bytes as minimum amount of data (length multiple of 4 bytes); - one byte for checksum; so total 6 bytes. Signed-off-by: Antonio Borneo --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index cbfad12..492690d 100644 --- a/main.c +++ b/main.c @@ -644,9 +644,9 @@ int parse_options(int argc, char *argv[]) if (port_opts.tx_frame_max == 0) port_opts.tx_frame_max = STM32_MAX_TX_FRAME; if (port_opts.rx_frame_max < 20 - || port_opts.tx_frame_max < 5) { + || port_opts.tx_frame_max < 6) { fprintf(stderr, "ERROR: current code cannot work with small frames.\n"); - fprintf(stderr, "min(RX) = 20, min(TX) = 5\n"); + fprintf(stderr, "min(RX) = 20, min(TX) = 6\n"); return 1; } if (port_opts.rx_frame_max > STM32_MAX_RX_FRAME) { From 1716be24e3901f8f6d39a0cb17f9c1c1f5e55e8b Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 29 Sep 2015 22:42:28 +0200 Subject: [PATCH 004/134] Add STM32F446xx and STM32F411xx to device table RAM and system memory range taken from AN2606 DocID13801 Rev 22 ROM and option byte range taken from data sheet (Memory Map): STM32F446xx DocID027107 Rev 4 STM32F411xx DocID026289 Rev 4 Signed-off-by: Tormod Volden --- dev_table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev_table.c b/dev_table.c index 2c1b80d..6bf5dc0 100644 --- a/dev_table.c +++ b/dev_table.c @@ -54,6 +54,8 @@ const stm32_dev_t devices[] = { {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, + {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, /* L0 */ {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, /* L1 */ From fb52b4d80613b19b28ab82ba9fa415378d00fb9a Mon Sep 17 00:00:00 2001 From: Seth LaForge Date: Fri, 9 Oct 2015 00:18:27 +0200 Subject: [PATCH 005/134] Fix incorrect enum comparisons stm32_get_ack_timeout returns STM32_ERR_NACK, not STM32_NACK. Thanks also to Yuriy C. and Ilia Sergachev for providing patches. Signed-off-by: Tormod Volden --- stm32.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stm32.c b/stm32.c index 74047d2..b20feed 100644 --- a/stm32.c +++ b/stm32.c @@ -604,7 +604,7 @@ stm32_err_t stm32_wunprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; s_err = stm32_get_ack_timeout(stm, STM32_WUNPROT_TIMEOUT); - if (s_err == STM32_NACK) { + if (s_err == STM32_ERR_NACK) { fprintf(stderr, "Error: Failed to WRITE UNPROTECT\n"); return STM32_ERR_UNKNOWN; } @@ -631,7 +631,7 @@ stm32_err_t stm32_wprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; s_err = stm32_get_ack_timeout(stm, STM32_WPROT_TIMEOUT); - if (s_err == STM32_NACK) { + if (s_err == STM32_ERR_NACK) { fprintf(stderr, "Error: Failed to WRITE PROTECT\n"); return STM32_ERR_UNKNOWN; } @@ -658,7 +658,7 @@ stm32_err_t stm32_runprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err == STM32_NACK) { + if (s_err == STM32_ERR_NACK) { fprintf(stderr, "Error: Failed to READOUT UNPROTECT\n"); return STM32_ERR_UNKNOWN; } @@ -685,7 +685,7 @@ stm32_err_t stm32_readprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; s_err = stm32_get_ack_timeout(stm, STM32_RPROT_TIMEOUT); - if (s_err == STM32_NACK) { + if (s_err == STM32_ERR_NACK) { fprintf(stderr, "Error: Failed to READOUT PROTECT\n"); return STM32_ERR_UNKNOWN; } From dd7e2b8c55a751b2d5440cda305e3ebcc7b404e9 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 22 Jun 2015 19:35:28 +0800 Subject: [PATCH 006/134] main: collaps few variables in a single enum main() implements only one actions at a time (or read or write or ...). We were using few variables to flag which action to take. Also, we had incomplete tests to avoid the command line to list two or more actions. Replace variables with a single enum and enforce the tests on the command line. Signed-off-by: Antonio Borneo --- main.c | 111 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 36 deletions(-) diff --git a/main.c b/main.c index 492690d..83b7517 100644 --- a/main.c +++ b/main.c @@ -55,13 +55,19 @@ struct port_options port_opts = { .rx_frame_max = STM32_MAX_RX_FRAME, .tx_frame_max = STM32_MAX_TX_FRAME, }; -int rd = 0; -int wr = 0; -int wu = 0; -int rp = 0; -int ur = 0; -int eraseOnly = 0; -int crc = 0; + +enum actions { + ACT_NONE, + ACT_READ, + ACT_WRITE, + ACT_WRITE_UNPROTECT, + ACT_READ_PROTECT, + ACT_READ_UNPROTECT, + ACT_ERASE_ONLY, + ACT_CRC +}; + +enum actions action = ACT_NONE; int npages = 0; int spage = 0; int no_erase = 0; @@ -81,6 +87,36 @@ uint32_t readwrite_len = 0; int parse_options(int argc, char *argv[]); void show_help(char *name); +static const char *action2str(enum actions act) +{ + switch (act) { + case ACT_READ: + return "memory read"; + case ACT_WRITE: + return "memory write"; + case ACT_WRITE_UNPROTECT: + return "write unprotect"; + case ACT_READ_PROTECT: + return "read protect"; + case ACT_READ_UNPROTECT: + return "read unprotect"; + case ACT_ERASE_ONLY: + return "flash erase"; + case ACT_CRC: + return "memory crc"; + default: + return ""; + }; +} + +static void err_multi_action(enum actions new) +{ + fprintf(stderr, + "ERROR: Invalid options !\n" + "\tCan't execute \"%s\" and \"%s\" at the same time.\n", + action2str(action), action2str(new)); +} + static int is_addr_in_ram(uint32_t addr) { return addr >= stm->dev->ram_start && addr < stm->dev->ram_end; @@ -125,11 +161,11 @@ int main(int argc, char* argv[]) { if (parse_options(argc, argv) != 0) goto close; - if (rd && filename[0] == '-') { + if ((action == ACT_READ) && filename[0] == '-') { diag = stderr; } - if (wr) { + if (action == ACT_WRITE) { /* first try hex */ if (!force_binary) { parser = &PARSER_HEX; @@ -260,7 +296,7 @@ int main(int argc, char* argv[]) { num_pages = 0xff; /* mass erase */ } - if (rd) { + if (action == ACT_READ) { unsigned int max_len = port_opts.rx_frame_max; fprintf(diag, "Memory read\n"); @@ -300,19 +336,19 @@ int main(int argc, char* argv[]) { fprintf(diag, "Done.\n"); ret = 0; goto close; - } else if (rp) { + } else if (action == ACT_READ_PROTECT) { fprintf(stdout, "Read-Protecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; stm32_readprot_memory(stm); fprintf(stdout, "Done.\n"); - } else if (ur) { + } else if (action == ACT_READ_UNPROTECT) { fprintf(stdout, "Read-UnProtecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; stm32_runprot_memory(stm); fprintf(stdout, "Done.\n"); - } else if (eraseOnly) { + } else if (action == ACT_ERASE_ONLY) { ret = 0; fprintf(stdout, "Erasing flash\n"); @@ -330,14 +366,14 @@ int main(int argc, char* argv[]) { ret = 1; goto close; } - } else if (wu) { + } else if (action == ACT_WRITE_UNPROTECT) { fprintf(diag, "Write-unprotecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; stm32_wunprot_memory(stm); fprintf(diag, "Done.\n"); - } else if (wr) { + } else if (action == ACT_WRITE) { fprintf(diag, "Write to memory\n"); off_t offset = 0; @@ -450,7 +486,7 @@ int main(int argc, char* argv[]) { fprintf(diag, "Done.\n"); ret = 0; goto close; - } else if (crc) { + } else if (action == ACT_CRC) { uint32_t crc_val = 0; fprintf(diag, "CRC computation\n"); @@ -533,12 +569,11 @@ int parse_options(int argc, char *argv[]) case 'r': case 'w': - rd = rd || c == 'r'; - wr = wr || c == 'w'; - if (rd && wr) { - fprintf(stderr, "ERROR: Invalid options, can't read & write at the same time\n"); + if (action != ACT_NONE) { + err_multi_action((c == 'r') ? ACT_READ : ACT_WRITE); return 1; } + action = (c == 'r') ? ACT_READ : ACT_WRITE; filename = optarg; if (filename[0] == '-') { force_binary = 1; @@ -558,37 +593,37 @@ int parse_options(int argc, char *argv[]) no_erase = 1; break; case 'u': - wu = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't write unprotect and read/write at the same time\n"); + if (action != ACT_NONE) { + err_multi_action(ACT_WRITE_UNPROTECT); return 1; } + action = ACT_WRITE_UNPROTECT; break; case 'j': - rp = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read protect and read/write at the same time\n"); + if (action != ACT_NONE) { + err_multi_action(ACT_READ_PROTECT); return 1; } + action = ACT_READ_PROTECT; break; case 'k': - ur = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't read unprotect and read/write at the same time\n"); + if (action != ACT_NONE) { + err_multi_action(ACT_READ_UNPROTECT); return 1; } + action = ACT_READ_UNPROTECT; break; case 'o': - eraseOnly = 1; - if (rd || wr) { - fprintf(stderr, "ERROR: Invalid options, can't erase-only and read/write at the same time\n"); + if (action != ACT_NONE) { + err_multi_action(ACT_ERASE_ONLY); return 1; } - break; - + action = ACT_ERASE_ONLY; + break; + case 'v': verify = 1; break; @@ -679,7 +714,11 @@ int parse_options(int argc, char *argv[]) break; case 'C': - crc = 1; + if (action != ACT_NONE) { + err_multi_action(ACT_CRC); + return 1; + } + action = ACT_CRC; break; } } @@ -699,7 +738,7 @@ int parse_options(int argc, char *argv[]) return 1; } - if (!wr && verify) { + if ((action != ACT_WRITE) && verify) { fprintf(stderr, "ERROR: Invalid usage, -v is only valid when writing\n"); show_help(argv[0]); return 1; From 5376181d18e8d61e693f2427b2f28d68852154f4 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 24 Jun 2015 23:36:01 +0800 Subject: [PATCH 007/134] man page: remove STM32[W], update for i2c, fix typos Now there are STM32 suffixes L, F, W and probably other to come. Rewrite as STM32 instead of STM32[W] if there is no need to highlight it. Minor update for i2c: - add mention to i2c application note - describe the command line parameter for i2c device Fix few typos. Signed-off-by: Antonio Borneo --- stm32flash.1 | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/stm32flash.1 b/stm32flash.1 index 24ac77c..58e3900 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -1,6 +1,6 @@ -.TH STM32FLASH 1 "2013\-11\-03" STM32FLASH "User command" +.TH STM32FLASH 1 "2015\-11\-25" STM32FLASH "User command" .SH NAME -stm32flash \- flashing utility for STM32 and STM32W through UART or I2C +stm32flash \- flashing utility for STM32 through UART or I2C .SH SYNOPSIS .B stm32flash .RB [ \-cfhjkouvCR ] @@ -34,14 +34,16 @@ stm32flash \- flashing utility for STM32 and STM32W through UART or I2C .SH DESCRIPTION .B stm32flash -reads or writes the flash memory of STM32 and STM32W. +reads or writes the flash memory of STM32. -It requires the STM32[W] to embed a bootloader compliant with ST -application note AN3155. +It requires the STM32 to embed a bootloader compliant with ST +application note AN3155 or AN4221. .B stm32flash uses the serial port .I tty_device -to interact with the bootloader of STM32[W]. +or the i2c port +.I i2c_device +to interact with the bootloader of STM32. .SH OPTIONS .TP @@ -55,7 +57,7 @@ This option is mandatory for I2C interface. Specify baud rate speed of .IR tty_device . Please notice that the ST bootloader can automatically detect the baud rate, -as explaned in chapter 2 of AN3155. +as explained in chapter 2 of AN3155. This option could be required together with option .B "\-c" or if following interaction with bootloader is expected. @@ -68,7 +70,7 @@ Specify the format of UART data. .I mode is a three characters long string where each character specifies, in this strict order, character size, parity and stop bits. -The only values currenly used are +The only values currently used are .I 8e1 for standard STM32 bootloader and .I 8n1 @@ -78,27 +80,27 @@ Default is .TP .BI "\-r" " filename" -Specify to read the STM32[W] flash and write its content in +Specify to read the STM32 flash and write its content in .I filename in raw binary format (see below .BR "FORMAT CONVERSION" ). .TP .BI "\-w" " filename" -Specify to write the STM32[W] flash with the content of +Specify to write the STM32 flash with the content of .IR filename . File format can be either raw binary or intel hex (see below .BR "FORMAT CONVERSION" ). The file format is automatically detected. To by\-pass format detection and force binary mode (e.g. to -write an intel hex content in STM32[W] flash), use +write an intel hex content in STM32 flash), use .B \-f option. .TP .B \-u -Specify to disable write\-protection from STM32[W] flash. -The STM32[W] will be reset after this operation. +Specify to disable write\-protection from STM32 flash. +The STM32 will be reset after this operation. .TP .B \-j @@ -167,9 +169,9 @@ existing connection. This is useful if the reset fails. .TP .BI "\-i" " GPIO_string" -Specify the GPIO sequences on the host to force STM32[W] to enter and +Specify the GPIO sequences on the host to force STM32 to enter and exit bootloader mode. GPIO can either be real GPIO connected from host to -STM32[W] beside the UART connection, or UART's modem signals used as +STM32 beside the UART connection, or UART's modem signals used as GPIO. (See below .B BOOTLOADER GPIO SEQUENCE for the format of @@ -255,7 +257,7 @@ The corresponding string for .I GPIO_string is "4,\-5,\-3,3". -To exit from bootloade and run the application program, the sequence is: +To exit from bootloader and run the application program, the sequence is: put GPIO_4="low"; then send reset pulse. The corresponding string for .I GPIO_string From a326c4513211b25c8f2ffcc5ead3c28d522751d8 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 25 Jun 2015 13:59:23 +0800 Subject: [PATCH 008/134] dev_table: fix ID=0x440 (STM32F030x8/F05xxx) Change name to "STM32F030x8/F05xxx" as in AN2606 rev 22 (June 2015). Fix RAM start address as in AN2606. Fix OPT end address as in RM0091 Rev 6 and RM0360 Rev 3. Both address changes verified on board STM32F0308-DISCO MB1134-A. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 6bf5dc0..58e0b1d 100644 --- a/dev_table.c +++ b/dev_table.c @@ -27,7 +27,7 @@ */ const stm32_dev_t devices[] = { /* F0 */ - {0x440, "STM32F051xx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, + {0x440, "STM32F030x8/F05xxx", 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, From cd9a0dbfc5ca744b06f09e86eea799923cd1defb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 25 Jun 2015 15:54:16 +0800 Subject: [PATCH 009/134] dev_table: Add device 0x442 "STM32F030xC/F09xxx" Data and name taken from: - AN2606 Rev 22 - RM0091 Rev 7 - RM0360 Rev 3 Tested on board Nucleo F091RC Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 58e0b1d..eb2cd01 100644 --- a/dev_table.c +++ b/dev_table.c @@ -28,6 +28,7 @@ const stm32_dev_t devices[] = { /* F0 */ {0x440, "STM32F030x8/F05xxx", 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, + {0x442, "STM32F030xC/F09xxx", 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, From 04d49117de6f1c4bc7b341e8d812206d3118e7dc Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Jun 2015 11:40:33 +0800 Subject: [PATCH 010/134] dev_table: fix ID=0x444 (STM32F03xx4/6) Change name as in AN2606 rev 22. Fix RAM start and end addresses, as in AN2606 rev 22. Fix Flash end address, as in RM0091 rev 7 and in RM0360 rev3. Fix opt bytes end address, as in RM0091 rev 7 and in RM0360 rev3. Addresses has been tested on device STM32F031K6 on custom board. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index eb2cd01..9ff6c67 100644 --- a/dev_table.c +++ b/dev_table.c @@ -29,7 +29,7 @@ const stm32_dev_t devices[] = { /* F0 */ {0x440, "STM32F030x8/F05xxx", 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, {0x442, "STM32F030xC/F09xxx", 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - {0x444, "STM32F030/F031" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80B, 0x1FFFEC00, 0x1FFFF800}, + {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, /* F1 */ From d1d5f2661a7bbc3d4a1063d9cb480c3364a411b2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Jun 2015 14:29:09 +0800 Subject: [PATCH 011/134] dev_table: fix ID=0x411 (STM32F2xxxx) Change name as in AN2606 rev 22. Fix system memory end address as in RM0033 rev 7. Address change above checked on STM32F207 device on custom board. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 9ff6c67..a7bb858 100644 --- a/dev_table.c +++ b/dev_table.c @@ -43,7 +43,7 @@ const stm32_dev_t devices[] = { /* Note that F2 and F4 devices have sectors of different page sizes and only the first sectors (of one page size) are included here */ /* F2 */ - {0x411, "STM32F2xx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, + {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F3 */ {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, From c7e55123b7f39a2844d9cb14aaba8c1dcde1d618 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Jun 2015 14:46:12 +0800 Subject: [PATCH 012/134] dev_table: change copyright date Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index a7bb858..c401d03 100644 --- a/dev_table.c +++ b/dev_table.c @@ -1,7 +1,7 @@ /* stm32flash - Open Source ST STM32 flash program for *nix Copyright (C) 2010 Geoffrey McRae - Copyright (C) 2014 Antonio Borneo + Copyright (C) 2014-2015 Antonio Borneo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License From 6b10279ee6b0f12e7b303e7b17f33f5f89368c6c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Jun 2015 15:02:03 +0800 Subject: [PATCH 013/134] dev_table: increase space for device names Just increase indentation, no value has been modified in this commit. Signed-off-by: Antonio Borneo --- dev_table.c | 64 ++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/dev_table.c b/dev_table.c index c401d03..608167e 100644 --- a/dev_table.c +++ b/dev_table.c @@ -27,47 +27,47 @@ */ const stm32_dev_t devices[] = { /* F0 */ - {0x440, "STM32F030x8/F05xxx", 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x442, "STM32F030xC/F09xxx", 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, + {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, + {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, + {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, + {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, /* Note that F2 and F4 devices have sectors of different page sizes and only the first sectors (of one page size) are included here */ /* F2 */ - {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, + {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, - {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, - {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, + {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, + {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, + {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, + {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, + {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, {0x0} }; From 4c73ac95ae452bc728e5d9f2d3a7807ffde90472 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 26 Jun 2015 15:07:56 +0800 Subject: [PATCH 014/134] dev_table: change F0 and F1 device name, as in AN2606 rev 22 Signed-off-by: Antonio Borneo --- dev_table.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dev_table.c b/dev_table.c index 608167e..e5b7896 100644 --- a/dev_table.c +++ b/dev_table.c @@ -30,16 +30,16 @@ const stm32_dev_t devices[] = { {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F042xx" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F072xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, + {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, /* F1 */ - {0x412, "Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "Connectivity line" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, + {0x412, "STM32F10xxx Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x410, "STM32F10xxx Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x414, "STM32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x420, "STM32F10xxx Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, + {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, /* Note that F2 and F4 devices have sectors of different page sizes and only the first sectors (of one page size) are included here */ /* F2 */ From 0cbba16432b36864011620060cda59485b1ab2e0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 17:27:42 +0800 Subject: [PATCH 015/134] dev_table: change name of F3 devices as in AN2606 rev 22 No other parameters has been changed in this commit Signed-off-by: Antonio Borneo --- dev_table.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_table.c b/dev_table.c index e5b7896..2dbd4ce 100644 --- a/dev_table.c +++ b/dev_table.c @@ -45,10 +45,10 @@ const stm32_dev_t devices[] = { /* F2 */ {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F3 */ - {0x432, "STM32F373/8" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "F302xB/303xB/358" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F302x4(6/8)" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "F303x4/334/328" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ From c67e6d0c029de2d2feeb17b72144060499df809c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 17:37:16 +0800 Subject: [PATCH 016/134] dev_table: fix RAM end for 0x422 (STM32F302xB(C)/F303xB(C)/F358xx) As reported in: - RM0316 rev 5 - RM0365 rev 4 these devices have only 40 Kbyte of RAM. Some of them (F303xC, F358xx) have additional 8 Kbyte of CCM RAM, but it is placed at addresses not contiguous with main RAM. Let's keep CCM RAM out of the table. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 2dbd4ce..44938ea 100644 --- a/dev_table.c +++ b/dev_table.c @@ -46,7 +46,7 @@ const stm32_dev_t devices[] = { {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F3 */ {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ From da5fe9e328699d972b762703fd9efbca8498ffe9 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 17:46:05 +0800 Subject: [PATCH 017/134] dev_table: fix flash end for 0x439 (STM32F301xx/F302x4(6/8)/F318xx) As reported in: - RM0365 rev 4 - RM0366 rev 2 - STM on line device selector these devices have 64 Kbyte max of flash. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 44938ea..9aca455 100644 --- a/dev_table.c +++ b/dev_table.c @@ -47,7 +47,7 @@ const stm32_dev_t devices[] = { /* F3 */ {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, From ef6d94dab11aa45cface9826153469b38c982ce2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 17:49:41 +0800 Subject: [PATCH 018/134] dev_table: fix flash end for 0x438 (STM32F303x4(6/8)/F334xx/F328xx) As reported in: - RM0316 rev 5 - RM0364 rev 1 - STM on line device selector these devices have 64 Kbyte max of flash. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 9aca455..38a1d07 100644 --- a/dev_table.c +++ b/dev_table.c @@ -48,7 +48,7 @@ const stm32_dev_t devices[] = { {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ From 2c8c31ffc157f3437372aefcfa3cbc4ecdf7b0d1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 17:52:03 +0800 Subject: [PATCH 019/134] dev_table: add device 0x446 (STM32F302xD(E)/F303xD(E)/F398xx) Data taken from: - AN2606 rev 22 - RM0316 rev 5 - RM0365 rev 4 Not verified on real HW. Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 38a1d07..67238de 100644 --- a/dev_table.c +++ b/dev_table.c @@ -49,6 +49,7 @@ const stm32_dev_t devices[] = { {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ From 1892313cc6031eb839ce82eb152e3e4ca05254d6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 21:51:15 +0800 Subject: [PATCH 020/134] dev_table: fix names for F4 as in AN2606 rev 22 Remove comment, since new name covers what comment reports Signed-off-by: Antonio Borneo --- dev_table.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dev_table.c b/dev_table.c index 67238de..31f1ae9 100644 --- a/dev_table.c +++ b/dev_table.c @@ -51,9 +51,8 @@ const stm32_dev_t devices[] = { {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ - {0x413, "STM32F40/1" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, - /* 0x419 is also used for STM32F429/39 but with other bootloader ID... */ - {0x419, "STM32F427/37" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x413, "STM32F40xxx/41xxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, + {0x419, "STM32F42xxx/43xxx" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, From fc9009952aa0232fcc6e6a6d666060698f7d8ba3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 21:55:52 +0800 Subject: [PATCH 021/134] dev_table: fix address for 0x413 (STM32F40xxx/41xxx) Accordingly to AN2606 rev 22, different version of bootloader use different amount of RAM. Let's play safe and define a RAM start that is compatible with all the bootloaders. Also, fix the end of system memory as reported in AN2606 and RM0090 rev 9. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 31f1ae9..d8f148b 100644 --- a/dev_table.c +++ b/dev_table.c @@ -51,7 +51,7 @@ const stm32_dev_t devices[] = { {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ - {0x413, "STM32F40xxx/41xxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77DF}, + {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x419, "STM32F42xxx/43xxx" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, From f718953966ef0b0d2be4157a487a4463f4604eb0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 22:03:12 +0800 Subject: [PATCH 022/134] dev_table: fix addresses for 0x419 (STM32F42xxx/43xxx) Fix start RAM as in AN2606 rev 22. Fix flash end address as in RM0090 rev 9. Fix end address for system memory. For RM0090 rev 9 there are two banks of option bytes - 0x1FFFC000 ~ 0x1FFFC00F - 0x1FFEC000 ~ 0x1FFEC00F For the moment, let's put a range that includes both. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index d8f148b..9bbc7e8 100644 --- a/dev_table.c +++ b/dev_table.c @@ -52,7 +52,7 @@ const stm32_dev_t devices[] = { {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x419, "STM32F42xxx/43xxx" , 0x20002000, 0x20030000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 4, 16384, 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, From 79c699c7eead033c205f4524fc684992aed49ce0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 22:11:00 +0800 Subject: [PATCH 023/134] dev_table: fix addresses for 0x423 (STM32F401xB(C)) Fix end of flash address as in RM0368 rev 4. Fix end of system memory. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 9bbc7e8..cabc5c5 100644 --- a/dev_table.c +++ b/dev_table.c @@ -53,7 +53,7 @@ const stm32_dev_t devices[] = { /* F4 */ {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 4, 16384, 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, From ca22f83234b695f4eec7f6fec52386e5d3ed28f2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 22:13:12 +0800 Subject: [PATCH 024/134] dev_table: fix addresses for 0x433 (STM32F401xD(E)) Fix end of flash address as in RM0368 rev 4. Fix end of system memory. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index cabc5c5..80f9a3a 100644 --- a/dev_table.c +++ b/dev_table.c @@ -54,7 +54,7 @@ const stm32_dev_t devices[] = { {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 4, 16384, 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF77FF}, + {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, /* L0 */ From b71dbc1910500ab61988767abe07ad839fd6c85b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 23:56:18 +0800 Subject: [PATCH 025/134] dev_table: fix addresses for 0x431 (STM32F411xx) Fix end of option bytes as in AN2606 rev 22. Fix end of system memory as in RM0383 rev 1. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 80f9a3a..f1c1774 100644 --- a/dev_table.c +++ b/dev_table.c @@ -55,7 +55,7 @@ const stm32_dev_t devices[] = { {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 4, 16384, 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC007, 0x1FFF0000, 0x1FFF7A10}, + {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, /* L0 */ {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, From bad59c0a972ef6380b0dddbf4c4dc6edd931d59a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 26 Nov 2015 00:03:07 +0800 Subject: [PATCH 026/134] dev_table: fix addresses for 0x421 (STM32F446xx) Fix end of flash as in RM0390 rev 1. Fix end of system memory as in RM0390 rev 1. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index f1c1774..df74d21 100644 --- a/dev_table.c +++ b/dev_table.c @@ -56,7 +56,7 @@ const stm32_dev_t devices[] = { {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08200000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7A10}, + {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* L0 */ {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, /* L1 */ From 35752084b6778b82de0d2e988b7a8e75ff93decd Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Jun 2015 22:41:03 +0800 Subject: [PATCH 027/134] dev_table: add new device 0x449 (STM32F74xxx/75xxx) Adapt comment explaining variable page size. Data from: - AN2606 rev 22 - RM0385 rev 1 Signed-off-by: Antonio Borneo --- dev_table.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index df74d21..76392f4 100644 --- a/dev_table.c +++ b/dev_table.c @@ -40,7 +40,7 @@ const stm32_dev_t devices[] = { {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2 and F4 devices have sectors of different page sizes + /* Note that F2, F4 and F7 devices have sectors of different page sizes and only the first sectors (of one page size) are included here */ /* F2 */ {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, @@ -57,6 +57,8 @@ const stm32_dev_t devices[] = { {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + /* F7 */ + {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 4, 32768, 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, /* L1 */ From 86e1524cdf2f08575fe374c1b30e7fc52fcfc04c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 11:29:25 +0800 Subject: [PATCH 028/134] dev_table: fix names for L0 as in AN2606 rev 22 Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 76392f4..bacb64e 100644 --- a/dev_table.c +++ b/dev_table.c @@ -60,7 +60,7 @@ const stm32_dev_t devices[] = { /* F7 */ {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 4, 32768, 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ - {0x417, "L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, /* L1 */ {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, From 2a09ae61acebc579a3942b4edbd9b3bfccb8e221 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 13:09:35 +0800 Subject: [PATCH 029/134] dev_table: fix opt byte address for L0 Accordingly to RM0367 rev 3, RM0376 rev 2, RM0377 rev 2 the option byte area is 32 bytes wide. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index bacb64e..e377a6e 100644 --- a/dev_table.c +++ b/dev_table.c @@ -60,7 +60,7 @@ const stm32_dev_t devices[] = { /* F7 */ {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 4, 32768, 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ - {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, /* L1 */ {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, From 90d36e602402dd4f5ac8a830f49a767123788efb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 13:20:57 +0800 Subject: [PATCH 030/134] dev_table: fix names for L1 as in AN2606 rev 22 Signed-off-by: Antonio Borneo --- dev_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev_table.c b/dev_table.c index e377a6e..60e614d 100644 --- a/dev_table.c +++ b/dev_table.c @@ -62,11 +62,11 @@ const stm32_dev_t devices[] = { /* L0 */ {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, /* L1 */ - {0x416, "L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, + {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, From 932442e2aee2e050c6ee16d2670bf120184f4ac5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 13:23:05 +0800 Subject: [PATCH 031/134] dev_table: fix flash size for 0x427 (STM32L1xxxC) Data from RM0038 rev 12 Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 60e614d..f7a2b3a 100644 --- a/dev_table.c +++ b/dev_table.c @@ -64,7 +64,7 @@ const stm32_dev_t devices[] = { /* L1 */ {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ From 6b60d09c944df0aa0b2e1b40296e45449a8d6cdb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 13:24:35 +0800 Subject: [PATCH 032/134] dev_table: fix flash size for 0x437 (STM32L1xxxE) Data from RM0038 rev 12 Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index f7a2b3a..e6086a7 100644 --- a/dev_table.c +++ b/dev_table.c @@ -66,7 +66,7 @@ const stm32_dev_t devices[] = { {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, From 31e5fa8601a2743043304f6f97b88f049aa047ae Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 14:37:08 +0800 Subject: [PATCH 033/134] dev_table: fix opt byte area for F1 devices From RM0038 rev 12, F1 devices have one or two opt byte area each 32 bytes wide. For devices with two opt byte area, use a address range that covers both. Signed-off-by: Antonio Borneo --- dev_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev_table.c b/dev_table.c index e6086a7..55d5b0f 100644 --- a/dev_table.c +++ b/dev_table.c @@ -62,11 +62,11 @@ const stm32_dev_t devices[] = { /* L0 */ {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, /* L1 */ - {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF01000}, - {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8000F, 0x1FF00000, 0x1FF02000}, - {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, - {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, 256, 0x1ff80000, 0x1ff8000F, 0x1FF00000, 0x1FF02000}, + {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, + {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, From 487db8f7ab926caabf4e8415a0b735471961ba3a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 14:56:32 +0800 Subject: [PATCH 034/134] dev_table: Add new device 0x415 (STM32L476xx/486xx) Data from: - AN2606 rev 22 - RM0351 rev 1 There are two opt byte areas. Use an address range that covers both. Signed-off-by: Antonio Borneo --- dev_table.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev_table.c b/dev_table.c index 55d5b0f..41816ae 100644 --- a/dev_table.c +++ b/dev_table.c @@ -67,6 +67,8 @@ const stm32_dev_t devices[] = { {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, + /* L4 */ + {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, 2048, 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, From f5480bf262c12bd68fdf3ebe5f5f70048debea88 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 15:13:48 +0800 Subject: [PATCH 035/134] dev_table: fix data for STM32W Data from PM0073 rev 5 Signed-off-by: Antonio Borneo --- dev_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_table.c b/dev_table.c index 41816ae..24db4e8 100644 --- a/dev_table.c +++ b/dev_table.c @@ -71,7 +71,7 @@ const stm32_dev_t devices[] = { {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, 2048, 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 1, 1024, 0, 0, 0, 0}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 1, 2048, 0, 0, 0, 0}, + {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, + {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, 2048, 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, {0x0} }; From 91a76008544c0a4d8e6fc10da67a07c65c3c7a5e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 18:46:09 +0800 Subject: [PATCH 036/134] dev_table: add header description for table fields Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 24db4e8..69b5e11 100644 --- a/dev_table.c +++ b/dev_table.c @@ -26,6 +26,7 @@ * Note that the option bytes upper range is inclusive! */ const stm32_dev_t devices[] = { + /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range */ /* F0 */ {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, From 7d4d16337883fdfd206494315e75272d1bfffd54 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 28 Jun 2015 23:51:38 +0800 Subject: [PATCH 037/134] dev_table: Use array for page size of flash Some devices like F2, F4 and F7 have flash split in pages having different size. Replace the scalar number fl_ps with a zero terminated array. Change type of fl_ps to accommodate the size of big pages. Specify 1 page per sector for F2, F4 and F7. Modify the code to use the first element of fl_ps array in place of the scalar number. This patch does not change the overall behavior of the code. Signed-off-by: Antonio Borneo --- dev_table.c | 104 +++++++++++++++++++++++++++++++++------------------- main.c | 12 +++--- stm32.h | 2 +- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/dev_table.c b/dev_table.c index 69b5e11..8986454 100644 --- a/dev_table.c +++ b/dev_table.c @@ -20,59 +20,87 @@ #include "stm32.h" +#define SZ_128 0x00000080 +#define SZ_256 0x00000100 +#define SZ_1K 0x00000400 +#define SZ_2K 0x00000800 +#define SZ_16K 0x00004000 +#define SZ_32K 0x00008000 +#define SZ_64K 0x00010000 +#define SZ_128K 0x00020000 +#define SZ_256K 0x00040000 + +/* + * Page-size for page-by-page flash erase. + * Arrays are zero terminated; last non-zero value is automatically repeated + */ + +/* fixed size pages */ +static uint32_t p_128[] = { SZ_128, 0 }; +static uint32_t p_256[] = { SZ_256, 0 }; +static uint32_t p_1k[] = { SZ_1K, 0 }; +static uint32_t p_2k[] = { SZ_2K, 0 }; +/* F2 and F4 page size */ +static uint32_t f2f4[] = { SZ_16K, SZ_16K, SZ_16K, SZ_16K, SZ_64K, SZ_128K, 0 }; +/* F4 dual bank page size */ +static uint32_t f4db[] = { + SZ_16K, SZ_16K, SZ_16K, SZ_16K, SZ_64K, SZ_128K, SZ_128K, SZ_128K, + SZ_16K, SZ_16K, SZ_16K, SZ_16K, SZ_64K, SZ_128K, 0 +}; +/* F7 page size */ +static uint32_t f7[] = { SZ_32K, SZ_32K, SZ_32K, SZ_32K, SZ_128K, SZ_256K, 0 }; + /* * Device table, corresponds to the "Bootloader device-dependant parameters" * table in ST document AN2606. * Note that the option bytes upper range is inclusive! */ const stm32_dev_t devices[] = { - /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range */ + /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range */ /* F0 */ - {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, + {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, + {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, /* F1 */ - {0x412, "STM32F10xxx Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "STM32F10xxx Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "STM32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "STM32F10xxx Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, - /* Note that F2, F4 and F7 devices have sectors of different page sizes - and only the first sectors (of one page size) are included here */ + {0x412, "STM32F10xxx Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x410, "STM32F10xxx Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x414, "STM32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x420, "STM32F10xxx Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, + {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, /* F2 */ - {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F3 */ - {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, 2048, 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, /* F4 */ - {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 4, 16384, 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 4, 16384, 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F7 */ - {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 4, 32768, 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, + {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ - {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, 128, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, /* L1 */ - {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, 256, 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, - {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, - {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, 256, 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, + {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, + {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, /* L4 */ - {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, 2048, 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000}, + {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000}, /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, 1024, 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, 1024, 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, 2048, 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, + {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, + {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, + {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, p_2k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, {0x0} }; diff --git a/main.c b/main.c index 83b7517..2fe64c6 100644 --- a/main.c +++ b/main.c @@ -132,7 +132,7 @@ static int flash_addr_to_page_floor(uint32_t addr) if (!is_addr_in_flash(addr)) return 0; - return (addr - stm->dev->fl_start) / stm->dev->fl_ps; + return (addr - stm->dev->fl_start) / stm->dev->fl_ps[0]; } static int flash_addr_to_page_ceil(uint32_t addr) @@ -140,13 +140,13 @@ static int flash_addr_to_page_ceil(uint32_t addr) if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) return 0; - return (addr + stm->dev->fl_ps - 1 - stm->dev->fl_start) - / stm->dev->fl_ps; + return (addr + stm->dev->fl_ps[0] - 1 - stm->dev->fl_start) + / stm->dev->fl_ps[0]; } static uint32_t flash_page_to_addr(int page) { - return stm->dev->fl_start + page * stm->dev->fl_ps; + return stm->dev->fl_start + page * stm->dev->fl_ps[0]; } int main(int argc, char* argv[]) { @@ -230,7 +230,7 @@ int main(int argc, char* argv[]) { } fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps); + fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps[0]); fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); @@ -395,7 +395,7 @@ int main(int argc, char* argv[]) { // TODO: It is possible to write to non-page boundaries, by reading out flash // from partial pages and combining with the input data - // if ((start % stm->dev->fl_ps) != 0 || (end % stm->dev->fl_ps) != 0) { + // if ((start % stm->dev->fl_ps[i]) != 0 || (end % stm->dev->fl_ps[i]) != 0) { // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); // goto close; // } diff --git a/stm32.h b/stm32.h index 1688fcb..3b7eab7 100644 --- a/stm32.h +++ b/stm32.h @@ -55,7 +55,7 @@ struct stm32_dev { uint32_t ram_start, ram_end; uint32_t fl_start, fl_end; uint16_t fl_pps; // pages per sector - uint16_t fl_ps; // page size + uint32_t *fl_ps; // page size uint32_t opt_start, opt_end; uint32_t mem_start, mem_end; }; From 7d25156cae1255ee4af0c589a0ad9a48b84d1942 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 17:30:21 +0800 Subject: [PATCH 038/134] main: use variable page size information Now dev_table provides arrays of page size for every device. Let's use such info in the code. Signed-off-by: Antonio Borneo --- main.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 2fe64c6..e0cc332 100644 --- a/main.c +++ b/main.c @@ -127,26 +127,68 @@ static int is_addr_in_flash(uint32_t addr) return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; } +/* returns the page that contains address "addr" */ static int flash_addr_to_page_floor(uint32_t addr) { + int page; + uint32_t *psize; + if (!is_addr_in_flash(addr)) return 0; - return (addr - stm->dev->fl_start) / stm->dev->fl_ps[0]; + page = 0; + addr -= stm->dev->fl_start; + psize = stm->dev->fl_ps; + + while (addr >= psize[0]) { + addr -= psize[0]; + page++; + if (psize[1]) + psize++; + } + + return page; } +/* returns the first page whose start addr is >= "addr" */ static int flash_addr_to_page_ceil(uint32_t addr) { + int page; + uint32_t *psize; + if (!(addr >= stm->dev->fl_start && addr <= stm->dev->fl_end)) return 0; - return (addr + stm->dev->fl_ps[0] - 1 - stm->dev->fl_start) - / stm->dev->fl_ps[0]; + page = 0; + addr -= stm->dev->fl_start; + psize = stm->dev->fl_ps; + + while (addr >= psize[0]) { + addr -= psize[0]; + page++; + if (psize[1]) + psize++; + } + + return addr ? page + 1 : page; } +/* returns the lower address of flash page "page" */ static uint32_t flash_page_to_addr(int page) { - return stm->dev->fl_start + page * stm->dev->fl_ps[0]; + int i; + uint32_t addr, *psize; + + addr = stm->dev->fl_start; + psize = stm->dev->fl_ps; + + for (i = 0; i < page; i++) { + addr += psize[0]; + if (psize[1]) + psize++; + } + + return addr; } int main(int argc, char* argv[]) { From e8fd730511b6323201f8dfcb05dc081979fb9bf2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 21:36:36 +0800 Subject: [PATCH 039/134] TODO: Remove need for variable page size support Variable page size is now supported. Signed-off-by: Antonio Borneo --- TODO | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO b/TODO index 41df614..09a1776 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,4 @@ -stm32: -- Add support for variable page size - AUTHORS: - Add contributors from Geoffrey's commits From 7f4dd6609eee4a44b8ffdbe2086f974bf89ea5f7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 19:26:05 +0800 Subject: [PATCH 040/134] dev_table: Add new device 0x458 (STM32F410xx) Data from: - AN2606 rev 23 - RM0401 rev 2 Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 8986454..23edaa6 100644 --- a/dev_table.c +++ b/dev_table.c @@ -84,6 +84,7 @@ const stm32_dev_t devices[] = { {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F7 */ From c17be3283185e92118deb2bef69df73a71d0f1f0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 19:42:49 +0800 Subject: [PATCH 041/134] dev_table: Add new device 0x434 (STM32F469xx) Data from: - AN2606 rev 23 - RM0386 rev 2 Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 23edaa6..90389bb 100644 --- a/dev_table.c +++ b/dev_table.c @@ -87,6 +87,7 @@ const stm32_dev_t devices[] = { {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, /* F7 */ {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ From 73bbeed58fad4c120cd669945f7ad2d1c70cc3ca Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 20:20:45 +0800 Subject: [PATCH 042/134] dev_table: Add new device 0x425 (STM32L031xx/041xx) Data from: - AN2606 rev 23 - RM0377 rev 4 Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 90389bb..c706464 100644 --- a/dev_table.c +++ b/dev_table.c @@ -91,6 +91,7 @@ const stm32_dev_t devices[] = { /* F7 */ {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, /* L0 */ + {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, /* L1 */ {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, From 5071254f81156977c0220b6b8a2076143d5a010e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 25 Nov 2015 20:59:05 +0800 Subject: [PATCH 043/134] dev_table: Add new device 0x447 (STM32L07xxx/08xxx) Data from: - AN2606 rev 23 - RM0367 rev 3 - RM0376 rev 2 - RM0377 rev 4 Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index c706464..28e003a 100644 --- a/dev_table.c +++ b/dev_table.c @@ -93,6 +93,7 @@ const stm32_dev_t devices[] = { /* L0 */ {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, + {0x447, "STM32L07xxx/08xxx" , 0x20001400, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, /* L1 */ {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, From af505946fa200009490f63254faba1c89c64302e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 26 Nov 2015 16:50:00 +0800 Subject: [PATCH 044/134] main: fix device summary log Device summary only prints the size of first sector. For devices with constant page size, sector size is also constant. More complex output message would be required for device with variable page size. Signed-off-by: Antonio Borneo --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index e0cc332..59989d6 100644 --- a/main.c +++ b/main.c @@ -272,7 +272,7 @@ int main(int argc, char* argv[]) { } fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (sector size: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps[0]); + fprintf(diag, "- Flash : %dKiB (size first sector: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps[0]); fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); From 345ce82df36780f552f5109f6c4b77b584b0c446 Mon Sep 17 00:00:00 2001 From: Johan Hellman Date: Fri, 4 Dec 2015 09:26:42 +0100 Subject: [PATCH 045/134] Support tristated GPIOs Restore direction of GPIOs after flash. Restore exported state of GPIOs after flash. https://sourceforge.net/p/stm32flash/tickets/79/ Signed-off-by: Johan Hellman --- init.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/init.c b/init.c index 77a571b..12998de 100644 --- a/init.c +++ b/init.c @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -35,8 +36,36 @@ struct gpio_list { struct gpio_list *next; int gpio; + int input; /* 1 if direction of gpio should be changed back to input. */ + int exported; /* 0 if gpio should be unexported. */ }; +static int read_from(const char *filename, char *buf, size_t len) +{ + int fd, ret; + ssize_t n = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open file \"%s\"\n", filename); + return 0; + } + + do { + ret = read(fd, buf + n, len - n); + if (ret < 0) { + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + continue; /* try again */ + fprintf(stderr, "Error reading in file \"%s\"\n", filename); + close(fd); + return 0; + } + n += ret; + } while (n < len && ret); + + close(fd); + return n; +} static int write_to(const char *filename, const char *value) { @@ -68,11 +97,14 @@ static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) { char num[16]; /* sized to carry MAX_INT */ char file[48]; /* sized to carry longest filename */ + char dir; struct stat buf; struct gpio_list *new; int ret; + int exported = 1; + int input = 0; - sprintf(file, "/sys/class/gpio/gpio%d/direction", n); + sprintf(file, "/sys/class/gpio/gpio%d/value", n); ret = stat(file, &buf); if (ret) { /* file miss, GPIO not exported yet */ @@ -85,12 +117,25 @@ static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) fprintf(stderr, "GPIO %d not available\n", n); return 0; } + exported = 0; + } + + sprintf(file, "/sys/class/gpio/gpio%d/direction", n); + ret = stat(file, &buf); + if (!ret) + if (read_from(file, &dir, sizeof(dir))) + if (dir == 'i') + input = 1; + + if (exported == 0 || input == 1) { new = (struct gpio_list *)malloc(sizeof(struct gpio_list)); if (new == NULL) { fprintf(stderr, "Out of memory\n"); return 0; } new->gpio = n; + new->exported = exported; + new->input = input; new->next = *gpio_to_release; *gpio_to_release = new; } @@ -99,12 +144,20 @@ static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) } #endif -static int release_gpio(int n) +static int release_gpio(int n, int input, int exported) { char num[16]; /* sized to carry MAX_INT */ + char file[48]; /* sized to carry longest filename */ sprintf(num, "%d", n); - return write_to("/sys/class/gpio/unexport", num); + if (input) { + sprintf(file, "/sys/class/gpio/gpio%d/direction", n); + write_to(file, "in"); + } + if (!exported) + write_to("/sys/class/gpio/unexport", num); + + return 1; } static int gpio_sequence(struct port_interface *port, const char *s, size_t l) @@ -163,7 +216,7 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) } while (gpio_to_release) { - release_gpio(gpio_to_release->gpio); + release_gpio(gpio_to_release->gpio, gpio_to_release->input, gpio_to_release->exported); to_free = gpio_to_release; gpio_to_release = gpio_to_release->next; free(to_free); From 4df8f50e375e81f01daec0d16219a22eece46cf6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 16 Jan 2016 17:43:51 +0800 Subject: [PATCH 046/134] dev_table: fix device 0x447 RAM start address AN2606 rev 25 updates RAM start address Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 28e003a..a2c1685 100644 --- a/dev_table.c +++ b/dev_table.c @@ -93,7 +93,7 @@ const stm32_dev_t devices[] = { /* L0 */ {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x447, "STM32L07xxx/08xxx" , 0x20001400, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, + {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, /* L1 */ {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, From 84077b10d8077cf3b8d6e2d55208b3d73f42b3d1 Mon Sep 17 00:00:00 2001 From: Matthias Weisser Date: Sat, 16 Jan 2016 22:52:31 +0800 Subject: [PATCH 047/134] serial_w32: fix memory leak detected by cppcheck Ticket #80 https://sourceforge.net/p/stm32flash/tickets/80/ Signed-off-by: Matthias Weisser Signed-off-by: Antonio Borneo --- serial_w32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/serial_w32.c b/serial_w32.c index ceac3a3..c3bf42e 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -67,6 +67,7 @@ static serial_t *serial_open(const char *device) if (h->fd == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) fprintf(stderr, "File not found: %s\n", device); + free(h); return NULL; } From 801c93e9720118d605d478c29b888780c95685ed Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Mon, 11 Jan 2016 18:44:02 +0100 Subject: [PATCH 048/134] hex parser: Ignore address field of extended linear address records. In practice the address field should be zero anyway, but I guess this is a little bit safer. Signed-off-by: Antonio Borneo --- parsers/hex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsers/hex.c b/parsers/hex.c index 3baf856..541700e 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -105,7 +105,7 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { /* extended linear address record */ case 4: - base = address; + base = 0; break; } From ddcc9ba9952b2435faef928ee13efa3f4af00fda Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Mon, 11 Jan 2016 19:57:44 +0100 Subject: [PATCH 049/134] hex parser: Fill gaps caused by address records with 0xff. This removes the inconsistency of values used to fill gaps in IHEX files. Signed-off-by: Antonio Borneo --- parsers/hex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parsers/hex.c b/parsers/hex.c index 541700e..0ba84f8 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -168,11 +168,11 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { return PARSER_ERR_INVALID_FILE; } - /* if there is a gap, enlarge and fill with zeros */ + /* if there is a gap, enlarge and fill with 0xff */ unsigned int len = base - st->base; if (len > st->data_len) { st->data = realloc(st->data, len); - memset(&st->data[st->data_len], 0, len - st->data_len); + memset(&st->data[st->data_len], 0xff, len - st->data_len); st->data_len = len; } break; From 228134881f98b75f30948c50b767bd6f45931ba1 Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Mon, 11 Jan 2016 20:25:30 +0100 Subject: [PATCH 050/134] hex parser: Fix handling of address records. This replaces a bogus byte swap with the correct bit shift. It also promotes hex_t::base to a 32 bit type, making the gap detection arithmetic work properly. Signed-off-by: Antonio Borneo --- parsers/hex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parsers/hex.c b/parsers/hex.c index 0ba84f8..2910603 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -32,7 +32,7 @@ typedef struct { size_t data_len, offset; uint8_t *data; - uint8_t base; + uint32_t base; } hex_t; void* hex_init() { @@ -152,8 +152,8 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { return PARSER_ERR_OK; /* address record */ + case 4: base = base << 12; case 2: base = base << 4; - case 4: base = be_u32(base); /* Reset last_address since our base changed */ last_address = 0; From e9812a1dc7269ec4b2f69ade2387ec2eff5ea342 Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Mon, 11 Jan 2016 20:29:09 +0100 Subject: [PATCH 051/134] hex parser: Only assign program's base address if no data was stored yet. If there are any data records before the first address record, then the program's base address must be zero (which is the default value). This fixes a problem that will likely never manifest with STM32 chips, but it makes the code a little more readable. Signed-off-by: Antonio Borneo --- parsers/hex.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/parsers/hex.c b/parsers/hex.c index 2910603..1c92ea4 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -157,7 +157,12 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { /* Reset last_address since our base changed */ last_address = 0; - if (st->base == 0) { + /* Only assign the program's base address once, and only + * do so if we haven't seen any data records yet. + * If there are any data records before address records, + * the program's base address must be zero. + */ + if (st->base == 0 && st->data_len == 0) { st->base = base; break; } From de298597310d30bafd30e5a27d2865bd9cfb627e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 17 Jan 2016 19:30:45 +0800 Subject: [PATCH 052/134] Makefile: force make to enter in subfolder Currently a change in source files in "parsers" folder does not trigger re-compiling. Fixed by adding a empty target "force". Signed-off-by: Antonio Borneo --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0328d55..e3a019e 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ all: stm32flash serial_platform.o: serial_posix.c serial_w32.c -parsers/parsers.a: +parsers/parsers.a: force cd parsers && $(MAKE) parsers.a stm32flash: $(OBJS) $(LIBOBJS) @@ -35,4 +35,6 @@ install: all $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1 $(INSTALL) -m 644 stm32flash.1 $(DESTDIR)$(PREFIX)/share/man/man1 -.PHONY: all clean install +force: + +.PHONY: all clean install force From e006a1ffd9abae86724010877f326074e8a840a8 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 16 Jan 2016 19:54:38 +0800 Subject: [PATCH 053/134] stm32: enlarge container for page number 8 bits are not enough to carry 16 bits page number. Switch to 32 bits to include a magic number for "mass erase". Check that page number is in 16 bits range. Use a macro for the magic number for "mass erase" and use a value out of page range. Signed-off-by: Antonio Borneo --- main.c | 8 ++++---- stm32.c | 15 ++++++++------- stm32.h | 7 +++++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index 59989d6..c89008a 100644 --- a/main.c +++ b/main.c @@ -308,14 +308,14 @@ int main(int argc, char* argv[]) { first_page = flash_addr_to_page_floor(start); if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ + num_pages = STM32_MASS_ERASE; else num_pages = flash_addr_to_page_ceil(end) - first_page; } else if (!spage && !npages) { start = stm->dev->fl_start; end = stm->dev->fl_end; first_page = 0; - num_pages = 0xff; /* mass erase */ + num_pages = STM32_MASS_ERASE; } else { first_page = spage; start = flash_page_to_addr(first_page); @@ -335,7 +335,7 @@ int main(int argc, char* argv[]) { } if (!first_page && end == stm->dev->fl_end) - num_pages = 0xff; /* mass erase */ + num_pages = STM32_MASS_ERASE; } if (action == ACT_READ) { @@ -394,7 +394,7 @@ int main(int argc, char* argv[]) { ret = 0; fprintf(stdout, "Erasing flash\n"); - if (num_pages != 0xff && + if (num_pages != STM32_MASS_ERASE && (start != flash_page_to_addr(first_page) || end != flash_page_to_addr(first_page + num_pages))) { fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); diff --git a/stm32.c b/stm32.c index b20feed..25eceed 100644 --- a/stm32.c +++ b/stm32.c @@ -698,13 +698,14 @@ stm32_err_t stm32_readprot_memory(const stm32_t *stm) return STM32_ERR_OK; } -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) +stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t pages) { struct port_interface *port = stm->port; stm32_err_t s_err; port_err_t p_err; - if (!pages) + if (!pages || spage > STM32_MAX_PAGES || + ((pages != STM32_MASS_ERASE) && ((spage + pages) > STM32_MAX_PAGES))) return STM32_ERR_OK; if (stm->cmd->er == STM32_CMD_ERR) { @@ -725,10 +726,10 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ /* So if someone has not overridden the default, but uses one of these chips, take it out of */ /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == 0xFF) + if (stm->pid == 0x416 && pages == STM32_MASS_ERASE) pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - if (pages == 0xFF) { + if (pages == STM32_MASS_ERASE) { uint8_t buf[3]; /* 0xFFFF the magic number for mass erase */ @@ -750,7 +751,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) return STM32_ERR_OK; } - uint16_t pg_num; + uint32_t pg_num; uint8_t pg_byte; uint8_t cs = 0; uint8_t *buf; @@ -797,7 +798,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) } /* And now the regular erase (0x43) for all other chips */ - if (pages == 0xFF) { + if (pages == STM32_MASS_ERASE) { s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { if (port->flags & PORT_STRETCH_W) @@ -807,7 +808,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, uint8_t pages) return STM32_ERR_OK; } else { uint8_t cs = 0; - uint8_t pg_num; + uint32_t pg_num; uint8_t *buf; int i = 0; diff --git a/stm32.h b/stm32.h index 3b7eab7..a0a7a73 100644 --- a/stm32.h +++ b/stm32.h @@ -27,6 +27,9 @@ #define STM32_MAX_RX_FRAME 256 /* cmd read memory */ #define STM32_MAX_TX_FRAME (1 + 256 + 1) /* cmd write memory */ +#define STM32_MAX_PAGES 0x0000ffff +#define STM32_MASS_ERASE 0x00100000 /* > 2 x max_pages */ + typedef enum { STM32_ERR_OK = 0, STM32_ERR_UNKNOWN, /* Generic error */ @@ -68,8 +71,8 @@ stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, const uint8_t data[], unsigned int len); stm32_err_t stm32_wunprot_memory(const stm32_t *stm); stm32_err_t stm32_wprot_memory(const stm32_t *stm); -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint8_t spage, - uint8_t pages); +stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, + uint32_t pages); stm32_err_t stm32_go(const stm32_t *stm, uint32_t address); stm32_err_t stm32_reset_device(const stm32_t *stm); stm32_err_t stm32_readprot_memory(const stm32_t *stm); From c5d7354c2e4e6668f3420767512367c8cb0fced6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 00:33:56 +0800 Subject: [PATCH 054/134] stm32: move mass-erase in separate function Behaviour is same as before with one exception: - (stm->pid == 0x416) is now checked for every value of stm->cmd->er. This is required to extend the check to other devices that do not support mass erase. Signed-off-by: Antonio Borneo --- stm32.c | 93 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/stm32.c b/stm32.c index 25eceed..b2436a2 100644 --- a/stm32.c +++ b/stm32.c @@ -698,6 +698,47 @@ stm32_err_t stm32_readprot_memory(const stm32_t *stm) return STM32_ERR_OK; } +static stm32_err_t stm32_mass_erase(const stm32_t *stm) +{ + struct port_interface *port = stm->port; + stm32_err_t s_err; + uint8_t buf[3]; + + if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { + fprintf(stderr, "Can't initiate chip mass erase!\n"); + return STM32_ERR_UNKNOWN; + } + + /* regular erase (0x43) */ + if (stm->cmd->er == STM32_CMD_ER) { + s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); + if (s_err != STM32_ERR_OK) { + if (port->flags & PORT_STRETCH_W) + stm32_warn_stretching("mass erase"); + return STM32_ERR_UNKNOWN; + } + return STM32_ERR_OK; + } + + /* extended erase */ + buf[0] = 0xFF; /* 0xFFFF the magic number for mass erase */ + buf[1] = 0xFF; + buf[2] = 0x00; /* checksum */ + if (port->write(port, buf, 3) != PORT_ERR_OK) { + fprintf(stderr, "Mass erase error.\n"); + return STM32_ERR_UNKNOWN; + } + s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); + if (port->flags & PORT_STRETCH_W + && stm->cmd->er != STM32_CMD_EE_NS) + stm32_warn_stretching("mass erase"); + return STM32_ERR_UNKNOWN; + } + return STM32_ERR_OK; +} + stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t pages) { struct port_interface *port = stm->port; @@ -713,6 +754,19 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page return STM32_ERR_NO_CMD; } + if (pages == STM32_MASS_ERASE) { + /* + * Not all chips using Extended Erase support mass erase. + * Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range + * So if someone has not overridden the default, but uses one of these chips, take it out of + * mass erase mode, so it will be done page by page. This maximum might not be correct either! + */ + if (stm->pid != 0x416) + return stm32_mass_erase(stm); + + pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ + } + if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { fprintf(stderr, "Can't initiate chip erase!\n"); return STM32_ERR_UNKNOWN; @@ -722,35 +776,6 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ if (stm->cmd->er != STM32_CMD_ER) { - /* Not all chips using Extended Erase support mass erase */ - /* Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range */ - /* So if someone has not overridden the default, but uses one of these chips, take it out of */ - /* mass erase mode, so it will be done page by page. This maximum might not be correct either! */ - if (stm->pid == 0x416 && pages == STM32_MASS_ERASE) - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - - if (pages == STM32_MASS_ERASE) { - uint8_t buf[3]; - - /* 0xFFFF the magic number for mass erase */ - buf[0] = 0xFF; - buf[1] = 0xFF; - buf[2] = 0x00; /* checksum */ - if (port->write(port, buf, 3) != PORT_ERR_OK) { - fprintf(stderr, "Mass erase error.\n"); - return STM32_ERR_UNKNOWN; - } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } - uint32_t pg_num; uint8_t pg_byte; uint8_t cs = 0; @@ -798,15 +823,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page } /* And now the regular erase (0x43) for all other chips */ - if (pages == STM32_MASS_ERASE) { - s_err = stm32_send_command_timeout(stm, 0xFF, STM32_MASSERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - return STM32_ERR_OK; - } else { + { uint8_t cs = 0; uint32_t pg_num; uint8_t *buf; From 666dde2ebd2d9e1fd6ded6e3b5a8061e60915bba Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 02:25:17 +0800 Subject: [PATCH 055/134] stm32: move page-by-page-erase in separate function Signed-off-by: Antonio Borneo --- stm32.c | 159 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 79 insertions(+), 80 deletions(-) diff --git a/stm32.c b/stm32.c index b2436a2..df81621 100644 --- a/stm32.c +++ b/stm32.c @@ -739,96 +739,27 @@ static stm32_err_t stm32_mass_erase(const stm32_t *stm) return STM32_ERR_OK; } -stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t pages) +static stm32_err_t stm32_pages_erase(const stm32_t *stm, uint32_t spage, uint32_t pages) { struct port_interface *port = stm->port; stm32_err_t s_err; port_err_t p_err; - - if (!pages || spage > STM32_MAX_PAGES || - ((pages != STM32_MASS_ERASE) && ((spage + pages) > STM32_MAX_PAGES))) - return STM32_ERR_OK; - - if (stm->cmd->er == STM32_CMD_ERR) { - fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); - return STM32_ERR_NO_CMD; - } - - if (pages == STM32_MASS_ERASE) { - /* - * Not all chips using Extended Erase support mass erase. - * Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range - * So if someone has not overridden the default, but uses one of these chips, take it out of - * mass erase mode, so it will be done page by page. This maximum might not be correct either! - */ - if (stm->pid != 0x416) - return stm32_mass_erase(stm); - - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - } - - if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { - fprintf(stderr, "Can't initiate chip erase!\n"); - return STM32_ERR_UNKNOWN; - } + uint32_t pg_num; + uint8_t pg_byte; + uint8_t cs = 0; + uint8_t *buf; + int i = 0; /* The erase command reported by the bootloader is either 0x43, 0x44 or 0x45 */ /* 0x44 is Extended Erase, a 2 byte based protocol and needs to be handled differently. */ /* 0x45 is clock no-stretching version of Extended Erase for I2C port. */ - if (stm->cmd->er != STM32_CMD_ER) { - uint32_t pg_num; - uint8_t pg_byte; - uint8_t cs = 0; - uint8_t *buf; - int i = 0; - - buf = malloc(2 + 2 * pages + 1); - if (!buf) - return STM32_ERR_UNKNOWN; - - /* Number of pages to be erased - 1, two bytes, MSB first */ - pg_byte = (pages - 1) >> 8; - buf[i++] = pg_byte; - cs ^= pg_byte; - pg_byte = (pages - 1) & 0xFF; - buf[i++] = pg_byte; - cs ^= pg_byte; - - for (pg_num = spage; pg_num < spage + pages; pg_num++) { - pg_byte = pg_num >> 8; - cs ^= pg_byte; - buf[i++] = pg_byte; - pg_byte = pg_num & 0xFF; - cs ^= pg_byte; - buf[i++] = pg_byte; - } - buf[i++] = cs; - p_err = port->write(port, buf, i); - free(buf); - if (p_err != PORT_ERR_OK) { - fprintf(stderr, "Page-by-page erase error.\n"); - return STM32_ERR_UNKNOWN; - } - - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("erase"); - return STM32_ERR_UNKNOWN; - } - - return STM32_ERR_OK; + if (stm32_send_command(stm, stm->cmd->er) != STM32_ERR_OK) { + fprintf(stderr, "Can't initiate chip mass erase!\n"); + return STM32_ERR_UNKNOWN; } - /* And now the regular erase (0x43) for all other chips */ - { - uint8_t cs = 0; - uint32_t pg_num; - uint8_t *buf; - int i = 0; - + /* regular erase (0x43) */ + if (stm->cmd->er == STM32_CMD_ER) { buf = malloc(1 + pages + 1); if (!buf) return STM32_ERR_UNKNOWN; @@ -854,6 +785,74 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page } return STM32_ERR_OK; } + + /* extended erase */ + buf = malloc(2 + 2 * pages + 1); + if (!buf) + return STM32_ERR_UNKNOWN; + + /* Number of pages to be erased - 1, two bytes, MSB first */ + pg_byte = (pages - 1) >> 8; + buf[i++] = pg_byte; + cs ^= pg_byte; + pg_byte = (pages - 1) & 0xFF; + buf[i++] = pg_byte; + cs ^= pg_byte; + + for (pg_num = spage; pg_num < spage + pages; pg_num++) { + pg_byte = pg_num >> 8; + cs ^= pg_byte; + buf[i++] = pg_byte; + pg_byte = pg_num & 0xFF; + cs ^= pg_byte; + buf[i++] = pg_byte; + } + buf[i++] = cs; + p_err = port->write(port, buf, i); + free(buf); + if (p_err != PORT_ERR_OK) { + fprintf(stderr, "Page-by-page erase error.\n"); + return STM32_ERR_UNKNOWN; + } + + s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); + if (port->flags & PORT_STRETCH_W + && stm->cmd->er != STM32_CMD_EE_NS) + stm32_warn_stretching("erase"); + return STM32_ERR_UNKNOWN; + } + + return STM32_ERR_OK; +} + +stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t pages) +{ + if (!pages || spage > STM32_MAX_PAGES || + ((pages != STM32_MASS_ERASE) && ((spage + pages) > STM32_MAX_PAGES))) + return STM32_ERR_OK; + + if (stm->cmd->er == STM32_CMD_ERR) { + fprintf(stderr, "Error: ERASE command not implemented in bootloader.\n"); + return STM32_ERR_NO_CMD; + } + + if (pages == STM32_MASS_ERASE) { + /* + * Not all chips using Extended Erase support mass erase. + * Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range + * So if someone has not overridden the default, but uses one of these chips, take it out of + * mass erase mode, so it will be done page by page. This maximum might not be correct either! + */ + if (stm->pid != 0x416) + return stm32_mass_erase(stm); + + pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ + + } + + return stm32_pages_erase(stm, spage, pages); } static stm32_err_t stm32_run_raw_code(const stm32_t *stm, From cdfcc5ef13e2a464142eb48f5fa7ac054d910790 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 01:00:01 +0800 Subject: [PATCH 056/134] stm32: limit number of pages in a single erase operation 512 pages seams the max limit Signed-off-by: Antonio Borneo --- stm32.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/stm32.c b/stm32.c index df81621..d15e188 100644 --- a/stm32.c +++ b/stm32.c @@ -829,6 +829,9 @@ static stm32_err_t stm32_pages_erase(const stm32_t *stm, uint32_t spage, uint32_ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t pages) { + uint32_t n; + stm32_err_t s_err; + if (!pages || spage > STM32_MAX_PAGES || ((pages != STM32_MASS_ERASE) && ((spage + pages) > STM32_MAX_PAGES))) return STM32_ERR_OK; @@ -852,7 +855,19 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page } - return stm32_pages_erase(stm, spage, pages); + /* + * Some device, like STM32L152, cannot erase more than 512 pages in + * one command. Split the call. + */ + while (pages) { + n = (pages <= 512) ? pages : 512; + s_err = stm32_pages_erase(stm, spage, n); + if (s_err != STM32_ERR_OK) + return s_err; + spage += n; + pages -= n; + } + return STM32_ERR_OK; } static stm32_err_t stm32_run_raw_code(const stm32_t *stm, From 73ccb038f255b9eb36add716cb9dd4f96202f446 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 01:21:36 +0800 Subject: [PATCH 057/134] dev_table: add flags column Signed-off-by: Antonio Borneo --- dev_table.c | 80 ++++++++++++++++++++++++++--------------------------- stm32.h | 1 + 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/dev_table.c b/dev_table.c index a2c1685..84e9f2b 100644 --- a/dev_table.c +++ b/dev_table.c @@ -56,55 +56,55 @@ static uint32_t f7[] = { SZ_32K, SZ_32K, SZ_32K, SZ_32K, SZ_128K, SZ_256K, 0 * Note that the option bytes upper range is inclusive! */ const stm32_dev_t devices[] = { - /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range */ + /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range Flags */ /* F0 */ - {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, - {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800}, - {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800}, - {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800}, + {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, + {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, + {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800, 0}, + {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, /* F1 */ - {0x412, "STM32F10xxx Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x410, "STM32F10xxx Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x414, "STM32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x420, "STM32F10xxx Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800}, - {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800}, + {0x412, "STM32F10xxx Low-density" , 0x20000200, 0x20002800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x410, "STM32F10xxx Medium-density" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x414, "STM32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x420, "STM32F10xxx Medium-density VL" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x428, "STM32F10xxx High-density VL" , 0x20000200, 0x20008000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x418, "STM32F105xx/F107xx" , 0x20001000, 0x20010000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFB000, 0x1FFFF800, 0}, + {0x430, "STM32F10xxx XL-density" , 0x20000800, 0x20018000, 0x08000000, 0x08100000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFE000, 0x1FFFF800, 0}, /* F2 */ - {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x411, "STM32F2xxxx" , 0x20002000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, /* F3 */ - {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, - {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800}, + {0x432, "STM32F373xx/F378xx" , 0x20001400, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, 0}, + {0x422, "STM32F302xB(C)/F303xB(C)/F358xx" , 0x20001400, 0x2000A000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, 0}, + {0x439, "STM32F301xx/F302x4(6/8)/F318xx" , 0x20001800, 0x20004000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, 0}, + {0x438, "STM32F303x4(6/8)/F334xx/F328xx" , 0x20001800, 0x20003000, 0x08000000, 0x08010000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, 0}, + {0x446, "STM32F302xD(E)/F303xD(E)/F398xx" , 0x20001800, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, 0}, /* F4 */ - {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, - {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800}, + {0x413, "STM32F40xxx/41xxx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x419, "STM32F42xxx/43xxx" , 0x20003000, 0x20030000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x423, "STM32F401xB(C)" , 0x20003000, 0x20010000, 0x08000000, 0x08040000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, /* F7 */ - {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0}, + {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, /* L0 */ - {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, + {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, /* L1 */ - {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000}, - {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000}, - {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, - {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000}, + {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, + {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, /* L4 */ - {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000}, + {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ - {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800}, - {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, - {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, p_2k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800}, + {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, + {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, p_2k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, {0x0} }; diff --git a/stm32.h b/stm32.h index a0a7a73..6e56e28 100644 --- a/stm32.h +++ b/stm32.h @@ -61,6 +61,7 @@ struct stm32_dev { uint32_t *fl_ps; // page size uint32_t opt_start, opt_end; uint32_t mem_start, mem_end; + uint32_t flags; }; stm32_t *stm32_init(struct port_interface *port, const char init); From f6e546e4e8b81599d93d73421f02387c7e4f09ad Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 01:24:54 +0800 Subject: [PATCH 058/134] dev_table: mark STM32L1xxx6(8/B) for not supporting mass-erase Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- stm32.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 84e9f2b..379bdb1 100644 --- a/dev_table.c +++ b/dev_table.c @@ -95,7 +95,7 @@ const stm32_dev_t devices[] = { {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, /* L1 */ - {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, diff --git a/stm32.h b/stm32.h index 6e56e28..20aced0 100644 --- a/stm32.h +++ b/stm32.h @@ -37,6 +37,10 @@ typedef enum { STM32_ERR_NO_CMD, /* Command not available in bootloader */ } stm32_err_t; +typedef enum { + F_NO_ME = 1 << 0, /* Mass-Erase not supported */ +} flags_t; + typedef struct stm32 stm32_t; typedef struct stm32_cmd stm32_cmd_t; typedef struct stm32_dev stm32_dev_t; From d87614e307933dc609298c65341ff9b9dc259794 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 02:30:08 +0800 Subject: [PATCH 059/134] stm32: use device flags instead of hardcoded pid Detect devices that do not support "mass erase" through the flags, instead of through their pid. Signed-off-by: Antonio Borneo --- stm32.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/stm32.c b/stm32.c index d15e188..c146657 100644 --- a/stm32.c +++ b/stm32.c @@ -843,16 +843,19 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page if (pages == STM32_MASS_ERASE) { /* - * Not all chips using Extended Erase support mass erase. - * Currently known as not supporting mass erase is the Ultra Low Power STM32L15xx range - * So if someone has not overridden the default, but uses one of these chips, take it out of - * mass erase mode, so it will be done page by page. This maximum might not be correct either! + * Not all chips support mass erase. + * Mass erase can be obtained executing a "readout protect" + * followed by "readout un-protect". This method is not + * suggested because can hang the target if a debug SWD/JTAG + * is connected. When the target enters in "readout + * protection" mode it will consider the debug connection as + * a tentative of intrusion and will hang. + * Erasing the flash page-by-page is the safer way to go. */ - if (stm->pid != 0x416) + if (!(stm->dev->flags & F_NO_ME)) return stm32_mass_erase(stm); pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ - } /* From 4690cc33460b860d361e629bab0cc9ff376812cb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 25 Jan 2016 23:56:13 +0800 Subject: [PATCH 060/134] main: export flash_addr_to_page_ceil() Remove static attribute only. We need a header file for it! Signed-off-by: Antonio Borneo --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index c89008a..82dd0b4 100644 --- a/main.c +++ b/main.c @@ -151,7 +151,7 @@ static int flash_addr_to_page_floor(uint32_t addr) } /* returns the first page whose start addr is >= "addr" */ -static int flash_addr_to_page_ceil(uint32_t addr) +int flash_addr_to_page_ceil(uint32_t addr) { int page; uint32_t *psize; From 3eadfa5a0e4efd222dc1db2be2333d9d67e70add Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 02:09:44 +0800 Subject: [PATCH 061/134] stm32: use generic upper limit page Use the address of end of flash to compute the upper limit instead of a hardcoded value. Signed-off-by: Antonio Borneo --- stm32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stm32.c b/stm32.c index c146657..f8402db 100644 --- a/stm32.c +++ b/stm32.c @@ -97,6 +97,8 @@ static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); extern const stm32_dev_t devices[]; +int flash_addr_to_page_ceil(uint32_t addr); + static void stm32_warn_stretching(const char *f) { fprintf(stderr, "Attention !!!\n"); @@ -855,7 +857,7 @@ stm32_err_t stm32_erase_memory(const stm32_t *stm, uint32_t spage, uint32_t page if (!(stm->dev->flags & F_NO_ME)) return stm32_mass_erase(stm); - pages = 0xF8; /* works for the STM32L152RB with 128Kb flash */ + pages = flash_addr_to_page_ceil(stm->dev->fl_end); } /* From da61dcc1ca4b61ce42060860a0b7fdbc0335adc6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 02:05:38 +0800 Subject: [PATCH 062/134] dev_table: mark STM32L1xxxE for not supporting mass-erase Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 379bdb1..8b12db2 100644 --- a/dev_table.c +++ b/dev_table.c @@ -99,7 +99,7 @@ const stm32_dev_t devices[] = { {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, - {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, + {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ From a20e8f851d7dab1b3544f9c293988e0363416563 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 12:20:37 +0800 Subject: [PATCH 063/134] stm32: change macro name Erase is done page-by-page, not sector-by-sector. Signed-off-by: Antonio Borneo --- stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stm32.c b/stm32.c index f8402db..3f6ff62 100644 --- a/stm32.c +++ b/stm32.c @@ -57,7 +57,7 @@ #define STM32_RESYNC_TIMEOUT 35 /* seconds */ #define STM32_MASSERASE_TIMEOUT 35 /* seconds */ -#define STM32_SECTERASE_TIMEOUT 5 /* seconds */ +#define STM32_PAGEERASE_TIMEOUT 5 /* seconds */ #define STM32_BLKWRITE_TIMEOUT 1 /* seconds */ #define STM32_WUNPROT_TIMEOUT 1 /* seconds */ #define STM32_WPROT_TIMEOUT 1 /* seconds */ @@ -817,7 +817,7 @@ static stm32_err_t stm32_pages_erase(const stm32_t *stm, uint32_t spage, uint32_ return STM32_ERR_UNKNOWN; } - s_err = stm32_get_ack_timeout(stm, pages * STM32_SECTERASE_TIMEOUT); + s_err = stm32_get_ack_timeout(stm, pages * STM32_PAGEERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); if (port->flags & PORT_STRETCH_W From 2b75e644f8c7d5ed28ba070fa3cc11643a982e0a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 26 Jan 2016 12:25:11 +0800 Subject: [PATCH 064/134] stm32: fix timeout during page-by-page erase Signed-off-by: Antonio Borneo --- stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm32.c b/stm32.c index 3f6ff62..91f5cd0 100644 --- a/stm32.c +++ b/stm32.c @@ -779,7 +779,7 @@ static stm32_err_t stm32_pages_erase(const stm32_t *stm, uint32_t spage, uint32_ fprintf(stderr, "Erase failed.\n"); return STM32_ERR_UNKNOWN; } - s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); + s_err = stm32_get_ack_timeout(stm, pages * STM32_PAGEERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { if (port->flags & PORT_STRETCH_W) stm32_warn_stretching("erase"); From ed59692774e5b936463edec501c700c7b78b4f75 Mon Sep 17 00:00:00 2001 From: Tilman Sauerbeck Date: Thu, 21 Jan 2016 19:13:06 +0100 Subject: [PATCH 065/134] Skip empty pages when writing to flash (issue #24) When writing to flash, write data by pages. For each page, check if it has previously been erased, and if so, skip writing it if the page's new desired data contains 0xff bytes only. https://sourceforge.net/p/stm32flash/tickets/24/ Signed-off-by: Tormod Volden --- main.c | 179 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 133 insertions(+), 46 deletions(-) diff --git a/main.c b/main.c index 82dd0b4..445ab56 100644 --- a/main.c +++ b/main.c @@ -191,12 +191,44 @@ static uint32_t flash_page_to_addr(int page) return addr; } +/* returns the size of flash page "page" */ +static uint32_t flash_page_size(int page) +{ + uint32_t *psize; + + psize = stm->dev->fl_ps; + + while (page && psize[1]) { + psize++; + page--; + } + + return psize[0]; +} + +/* returns 1 if the given buffer only contains 0xff bytes. + * + * Yes, this could be optimized to compare 4 bytes at once for example + * (NB: alignment!), but this function isn't a bottleneck anyway... + */ +static int buffer_is_0xff_only(uint8_t *buffer, uint32_t len) +{ + uint32_t i; + + for (i = 0; i < len; i++) + if (buffer[i] != 0xff) + return 0; + + return 1; +} + int main(int argc, char* argv[]) { struct port_interface *port = NULL; int ret = 1; stm32_err_t s_err; parser_err_t perr; FILE *diag = stdout; + uint8_t *page_data = NULL; fprintf(diag, "stm32flash " VERSION "\n\n"); fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); @@ -422,6 +454,7 @@ int main(int argc, char* argv[]) { ssize_t r; unsigned int size; unsigned int max_wlen, max_rlen; + uint32_t allocated_page_len = 0; max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ max_wlen &= ~3; /* 32 bit aligned */ @@ -456,14 +489,43 @@ int main(int argc, char* argv[]) { fflush(diag); addr = start; while(addr < end && offset < size) { + int page_number; + uint32_t page_size, page_len; + + /* Find out the page number that we are going to + * program next along with its size. + */ + page_number = flash_addr_to_page_floor(addr); + page_size = flash_page_size(page_number); + uint32_t left = end - addr; - len = max_wlen > left ? left : max_wlen; - len = len > size - offset ? size - offset : len; - if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) + /* page_len will hold the actual number of bytes to program + * in this page. This should only be different from page_size + * when we reach the end of the data to program. + */ + page_len = page_size > left ? left : page_size; + page_len = page_len > size - offset ? size - offset : page_len; + + /* Prepare a buffer to hold the data that will be written to + * this page. Note that we only allocate a new buffer if the + * one that we used previously is too small. + */ + if (!page_data || page_len > allocated_page_len) { + free(page_data); + page_data = malloc(page_len); + allocated_page_len = page_len; + } + + if (!page_data) { + fprintf(stderr, "Failed to allocate %u bytes.\n", page_len); goto close; + } - if (len == 0) { + if (parser->read(p_st, page_data, &page_len) != PARSER_ERR_OK) + goto close; + + if (page_len == 0) { if (filename[0] == '-') { break; } else { @@ -471,58 +533,80 @@ int main(int argc, char* argv[]) { goto close; } } - - again: - s_err = stm32_write_memory(stm, addr, buffer, len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; + + /* If this page has already been erased, we can + * skip programming if the new data is all 0xff. + */ + if (!no_erase && num_pages > page_number) { + if (buffer_is_0xff_only(page_data, page_len)) { + addr += page_len; + offset += page_len; + continue; + } } - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); - goto close; - } - offset += rlen; + uint32_t left_in_page = page_len; + uint32_t block_offset = 0; + + /* Now program the page's data in the chunk size that was + * previously chosen. + */ + while (left_in_page > 0) { + len = max_wlen > left_in_page ? left_in_page : max_wlen; + +again: + s_err = stm32_write_memory(stm, addr, &page_data[block_offset], len); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); + goto close; } - for(r = 0; r < len; ++r) - if (buffer[r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - buffer [r], - compare[r] - ); + if (verify) { + uint8_t compare[len]; + unsigned int offset, rlen; + + offset = 0; + while (offset < len) { + rlen = len - offset; + rlen = rlen < max_rlen ? rlen : max_rlen; + s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); goto close; } - ++failed; - goto again; + offset += rlen; } - failed = 0; - } - - addr += len; - offset += len; + for(r = 0; r < len; ++r) + if (page_data[block_offset + r] != compare[r]) { + if (failed == retry) { + fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", + (uint32_t)(addr + r), + page_data[block_offset + r], + compare[r] + ); + goto close; + } + ++failed; + goto again; + } - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); + failed = 0; + } + addr += len; + offset += len; + left_in_page -= len; + block_offset += len; + + fprintf(diag, + "\rWrote %saddress 0x%08x (%.2f%%) ", + verify ? "and verified " : "", + addr, + (100.0f / size) * offset + ); + fflush(diag); + } } fprintf(diag, "Done.\n"); @@ -546,6 +630,9 @@ int main(int argc, char* argv[]) { ret = 0; close: + free(page_data); + page_data = NULL; + if (stm && exec_flag && ret == 0) { if (execute == 0) execute = stm->dev->fl_start; From 240b5fb41ed1d6a3c262b9b119959937935eaf8f Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Fri, 4 Dec 2015 22:01:50 +0100 Subject: [PATCH 066/134] Do not require 4-byte-aligned data length We will pad the data instead. Fixes issues with sparse hex files. Thanks to smal.r for the suggestion. https://sourceforge.net/p/stm32flash/tickets/62/ Signed-off-by: Tormod Volden --- stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stm32.c b/stm32.c index 91f5cd0..d4d4ce5 100644 --- a/stm32.c +++ b/stm32.c @@ -542,8 +542,8 @@ stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, } /* must be 32bit aligned */ - if (address & 0x3 || len & 0x3) { - fprintf(stderr, "Error: WRITE address and length must be 4 byte aligned\n"); + if (address & 0x3) { + fprintf(stderr, "Error: WRITE address must be 4 byte aligned\n"); return STM32_ERR_UNKNOWN; } From 66b42e2871ea6324088b9200de1d257b2184cdb5 Mon Sep 17 00:00:00 2001 From: matys4877 Date: Wed, 11 Feb 2015 12:26:15 +0100 Subject: [PATCH 067/134] serial_w32: Allow COMxx port names Earlier we could connect only to ports COM1-COM9. When connecting to COM10 and greater we needed to use \\.\COM10 form. Now COM10 and greater is working. https://sourceforge.net/p/stm32flash/tickets/73/ Signed-off-by: Tormod Volden --- serial_w32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/serial_w32.c b/serial_w32.c index c3bf42e..47d2675 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -187,8 +187,7 @@ static port_err_t serial_w32_open(struct port_interface *port, serial_t *h; /* 1. check device name match */ - if (!(strlen(ops->device) == 4 - && !strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) + if (!(!strncmp(ops->device, "COM", 3) && isdigit(ops->device[3])) && !(!strncmp(ops->device, "\\\\.\\COM", strlen("\\\\.\\COM")) && isdigit(ops->device[strlen("\\\\.\\COM")]))) return PORT_ERR_NODEV; From 7c2f20bb9a10f71c1b8f7760e3888e58a949b3fc Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Mon, 25 Jan 2016 00:12:55 +0100 Subject: [PATCH 068/134] serial_posix: Do not check device filename We should not assume the device name is /dev/tty* or anything we can think of. Instead use isatty() after opening the device, and for maximum flexibility, only warn if it fails. https://sourceforge.net/p/stm32flash/tickets/75/ Signed-off-by: Tormod Volden --- serial_posix.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/serial_posix.c b/serial_posix.c index 30b5ff8..ec6694f 100644 --- a/serial_posix.c +++ b/serial_posix.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "serial.h" #include "port.h" @@ -198,30 +199,12 @@ static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, return PORT_ERR_OK; } -static int startswith(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} - -static int is_tty(const char *path) { - char resolved[PATH_MAX]; - - if(!realpath(path, resolved)) return 0; - - if(startswith(resolved, "/dev/tty")) return 1; - - return 0; -} - static port_err_t serial_posix_open(struct port_interface *port, struct port_options *ops) { serial_t *h; - /* 1. check device name match */ - if (!is_tty(ops->device)) - return PORT_ERR_NODEV; - - /* 2. check options */ + /* 1. check options */ if (ops->baudRate == SERIAL_BAUD_INVALID) return PORT_ERR_UNKNOWN; if (serial_get_bits(ops->serial_mode) == SERIAL_BITS_INVALID) @@ -231,11 +214,15 @@ static port_err_t serial_posix_open(struct port_interface *port, if (serial_get_stopbit(ops->serial_mode) == SERIAL_STOPBIT_INVALID) return PORT_ERR_UNKNOWN; - /* 3. open it */ + /* 2. open it */ h = serial_open(ops->device); if (h == NULL) return PORT_ERR_UNKNOWN; + /* 3. check for tty (but only warn) */ + if (!isatty(h->fd)) + fprintf(stderr, "Warning: Not a tty: %s\n", ops->device); + /* 4. set options */ if (serial_setup(h, ops->baudRate, serial_get_bits(ops->serial_mode), From e26cc7949e7a07c939ce96d173e035bddae117d5 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Wed, 27 Jan 2016 08:46:35 +0100 Subject: [PATCH 069/134] Revert "Skip empty pages when writing to flash (issue #24)" This reverts commit ed59692774e5b936463edec501c700c7b78b4f75. On EEPROM devices the value in "flash" after erase is 0x00 and not 0xFF as on NOR-FLASH devices. --- main.c | 179 +++++++++++++++------------------------------------------ 1 file changed, 46 insertions(+), 133 deletions(-) diff --git a/main.c b/main.c index 445ab56..82dd0b4 100644 --- a/main.c +++ b/main.c @@ -191,44 +191,12 @@ static uint32_t flash_page_to_addr(int page) return addr; } -/* returns the size of flash page "page" */ -static uint32_t flash_page_size(int page) -{ - uint32_t *psize; - - psize = stm->dev->fl_ps; - - while (page && psize[1]) { - psize++; - page--; - } - - return psize[0]; -} - -/* returns 1 if the given buffer only contains 0xff bytes. - * - * Yes, this could be optimized to compare 4 bytes at once for example - * (NB: alignment!), but this function isn't a bottleneck anyway... - */ -static int buffer_is_0xff_only(uint8_t *buffer, uint32_t len) -{ - uint32_t i; - - for (i = 0; i < len; i++) - if (buffer[i] != 0xff) - return 0; - - return 1; -} - int main(int argc, char* argv[]) { struct port_interface *port = NULL; int ret = 1; stm32_err_t s_err; parser_err_t perr; FILE *diag = stdout; - uint8_t *page_data = NULL; fprintf(diag, "stm32flash " VERSION "\n\n"); fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); @@ -454,7 +422,6 @@ int main(int argc, char* argv[]) { ssize_t r; unsigned int size; unsigned int max_wlen, max_rlen; - uint32_t allocated_page_len = 0; max_wlen = port_opts.tx_frame_max - 2; /* skip len and crc */ max_wlen &= ~3; /* 32 bit aligned */ @@ -489,43 +456,14 @@ int main(int argc, char* argv[]) { fflush(diag); addr = start; while(addr < end && offset < size) { - int page_number; - uint32_t page_size, page_len; - - /* Find out the page number that we are going to - * program next along with its size. - */ - page_number = flash_addr_to_page_floor(addr); - page_size = flash_page_size(page_number); - uint32_t left = end - addr; + len = max_wlen > left ? left : max_wlen; + len = len > size - offset ? size - offset : len; - /* page_len will hold the actual number of bytes to program - * in this page. This should only be different from page_size - * when we reach the end of the data to program. - */ - page_len = page_size > left ? left : page_size; - page_len = page_len > size - offset ? size - offset : page_len; - - /* Prepare a buffer to hold the data that will be written to - * this page. Note that we only allocate a new buffer if the - * one that we used previously is too small. - */ - if (!page_data || page_len > allocated_page_len) { - free(page_data); - page_data = malloc(page_len); - allocated_page_len = page_len; - } - - if (!page_data) { - fprintf(stderr, "Failed to allocate %u bytes.\n", page_len); + if (parser->read(p_st, buffer, &len) != PARSER_ERR_OK) goto close; - } - if (parser->read(p_st, page_data, &page_len) != PARSER_ERR_OK) - goto close; - - if (page_len == 0) { + if (len == 0) { if (filename[0] == '-') { break; } else { @@ -533,80 +471,58 @@ int main(int argc, char* argv[]) { goto close; } } - - /* If this page has already been erased, we can - * skip programming if the new data is all 0xff. - */ - if (!no_erase && num_pages > page_number) { - if (buffer_is_0xff_only(page_data, page_len)) { - addr += page_len; - offset += page_len; - continue; - } + + again: + s_err = stm32_write_memory(stm, addr, buffer, len); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); + goto close; } - uint32_t left_in_page = page_len; - uint32_t block_offset = 0; - - /* Now program the page's data in the chunk size that was - * previously chosen. - */ - while (left_in_page > 0) { - len = max_wlen > left_in_page ? left_in_page : max_wlen; - -again: - s_err = stm32_write_memory(stm, addr, &page_data[block_offset], len); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to write memory at address 0x%08x\n", addr); - goto close; + if (verify) { + uint8_t compare[len]; + unsigned int offset, rlen; + + offset = 0; + while (offset < len) { + rlen = len - offset; + rlen = rlen < max_rlen ? rlen : max_rlen; + s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); + goto close; + } + offset += rlen; } - if (verify) { - uint8_t compare[len]; - unsigned int offset, rlen; - - offset = 0; - while (offset < len) { - rlen = len - offset; - rlen = rlen < max_rlen ? rlen : max_rlen; - s_err = stm32_read_memory(stm, addr + offset, compare + offset, rlen); - if (s_err != STM32_ERR_OK) { - fprintf(stderr, "Failed to read memory at address 0x%08x\n", addr + offset); + for(r = 0; r < len; ++r) + if (buffer[r] != compare[r]) { + if (failed == retry) { + fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", + (uint32_t)(addr + r), + buffer [r], + compare[r] + ); goto close; } - offset += rlen; + ++failed; + goto again; } - for(r = 0; r < len; ++r) - if (page_data[block_offset + r] != compare[r]) { - if (failed == retry) { - fprintf(stderr, "Failed to verify at address 0x%08x, expected 0x%02x and found 0x%02x\n", - (uint32_t)(addr + r), - page_data[block_offset + r], - compare[r] - ); - goto close; - } - ++failed; - goto again; - } + failed = 0; + } - failed = 0; - } + addr += len; + offset += len; + + fprintf(diag, + "\rWrote %saddress 0x%08x (%.2f%%) ", + verify ? "and verified " : "", + addr, + (100.0f / size) * offset + ); + fflush(diag); - addr += len; - offset += len; - left_in_page -= len; - block_offset += len; - - fprintf(diag, - "\rWrote %saddress 0x%08x (%.2f%%) ", - verify ? "and verified " : "", - addr, - (100.0f / size) * offset - ); - fflush(diag); - } } fprintf(diag, "Done.\n"); @@ -630,9 +546,6 @@ int main(int argc, char* argv[]) { ret = 0; close: - free(page_data); - page_data = NULL; - if (stm && exec_flag && ret == 0) { if (execute == 0) execute = stm->dev->fl_start; From 23e658374cb15dd22039e3028081da90a114b109 Mon Sep 17 00:00:00 2001 From: Ernst Schwab Date: Mon, 1 Feb 2016 23:16:33 +0100 Subject: [PATCH 070/134] Use Thumb mode jump address for GO command As discussed in the ST forums [1], the bootloader requires an odd (Thumb mode) address for the GO command. If an even address is used, the Cortex M does something like a software reset, but this is not generated by the write to AICR in stm_reset_code, but by an exception due to the even address which is not compatible with Thumb mode. ARM specifies 'Hard Fault' for this case: http://infocenter.arm.com/help/ index.jsp?topic=/com.arm.doc.dui0497a/BABDCDHA.html [1] https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/System%20boot%20mode%20and%20Go%20command%20STM32f103rbt6 Signed-off-by: Ernst Schwab --- stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm32.c b/stm32.c index d4d4ce5..a3b6edb 100644 --- a/stm32.c +++ b/stm32.c @@ -880,7 +880,7 @@ static stm32_err_t stm32_run_raw_code(const stm32_t *stm, const uint8_t *code, uint32_t code_size) { uint32_t stack_le = le_u32(0x20002000); - uint32_t code_address_le = le_u32(target_address + 8); + uint32_t code_address_le = le_u32(target_address + 8 + 1); // thumb mode address (!) uint32_t length = code_size + 8; uint8_t *mem, *pos; uint32_t address, w; From 35b263e9e93fa21e0fc121d5567129de72eef3bd Mon Sep 17 00:00:00 2001 From: Ernst Schwab Date: Mon, 1 Feb 2016 23:46:18 +0100 Subject: [PATCH 071/134] Use OBL_LAUNCH reset instead of SYSRESETREQ on STM32F030xC On some devices, when programming an initially blank device, -R will reenter the bootloader unless the OBL_LAUNCH bit in FLASH_CR is set. Refer to RM0360, section 2.5 "Empty Check". The STM32F030xC device is marked in the device table to use the OBL_LAUNCH reset. Signed-off-by: Ernst Schwab --- dev_table.c | 2 +- stm32.c | 29 ++++++++++++++++++++++++++++- stm32.h | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) mode change 100644 => 100755 dev_table.c diff --git a/dev_table.c b/dev_table.c old mode 100644 new mode 100755 index 8b12db2..f4ada72 --- a/dev_table.c +++ b/dev_table.c @@ -59,7 +59,7 @@ const stm32_dev_t devices[] = { /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range Flags */ /* F0 */ {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, - {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, F_OBLL}, {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800, 0}, {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, diff --git a/stm32.c b/stm32.c index a3b6edb..1b0362d 100644 --- a/stm32.c +++ b/stm32.c @@ -95,6 +95,28 @@ static const uint8_t stm_reset_code[] = { static const uint32_t stm_reset_code_length = sizeof(stm_reset_code); +/* RM0360, Empty check + * On STM32F070x6 and STM32F030xC devices only, internal empty check flag is + * implemented to allow easy programming of the virgin devices by the boot loader. This flag is + * used when BOOT0 pin is defining Main Flash memory as the target boot space. When the + * flag is set, the device is considered as empty and System memory (boot loader) is selected + * instead of the Main Flash as a boot space to allow user to program the Flash memory. + * This flag is updated only during Option bytes loading: it is set when the content of the + * address 0x08000 0000 is read as 0xFFFF FFFF, otherwise it is cleared. It means a power + * on or setting of OBL_LAUNCH bit in FLASH_CR register is needed to clear this flag after + * programming of a virgin device to execute user code after System reset. + */ +static const uint8_t stm_obl_launch_code[] = { + 0x01, 0x49, // ldr r1, [pc, #4] ; () + 0x02, 0x4A, // ldr r2, [pc, #8] ; () + 0x0A, 0x60, // str r2, [r1, #0] + 0xfe, 0xe7, // endless: b endless + 0x10, 0x20, 0x02, 0x40, // address: FLASH_CR = 40022010 + 0x00, 0x20, 0x00, 0x00 // value: OBL_LAUNCH = 00002000 +}; + +static const uint32_t stm_obl_launch_code_length = sizeof(stm_obl_launch_code); + extern const stm32_dev_t devices[]; int flash_addr_to_page_ceil(uint32_t addr); @@ -947,7 +969,12 @@ stm32_err_t stm32_reset_device(const stm32_t *stm) { uint32_t target_address = stm->dev->ram_start; - return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); + if (stm->dev->flags & F_OBLL) { + /* set the OBL_LAUNCH bit to reset device (see RM0360, 2.5) */ + return stm32_run_raw_code(stm, target_address, stm_obl_launch_code, stm_obl_launch_code_length); + } else { + return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); + } } stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, diff --git a/stm32.h b/stm32.h index 20aced0..0e0035b 100644 --- a/stm32.h +++ b/stm32.h @@ -39,6 +39,7 @@ typedef enum { typedef enum { F_NO_ME = 1 << 0, /* Mass-Erase not supported */ + F_OBLL = 1 << 1, /* OBL_LAUNCH required */ } flags_t; typedef struct stm32 stm32_t; From 098cdc91d2136e3144d7c7a854803b77e80ae745 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Wed, 27 Jan 2016 22:29:04 +0100 Subject: [PATCH 072/134] Update author list --- AUTHORS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/AUTHORS b/AUTHORS index d096f22..7894bb9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,3 +17,11 @@ Armin van der Togt Brian Silverman Georg Hofmann Luis Rodrigues +Jeff Epler +Alexander O. Anisimov +Seth LaForge +Johan Hellman +Matthias Weisser +Tilman Sauerbeck +Mateusz Spychała +Ernst Schwab From ee32be940e8b6c5f07951edb12e9136474b2a758 Mon Sep 17 00:00:00 2001 From: Ernst Schwab Date: Sat, 6 Feb 2016 18:51:54 +0100 Subject: [PATCH 073/134] serial_w32: Improved interface initialization When using the -i DTR / RTS options, stm32flash failed if another application (terminal program etc.) left DTR / RTS in the DTR_CONTROL_HANDSHAKE / RTS_CONTROL_HANDSHAKE mode. Extend the DCB initialization to additionally init fDtrControl, fDsrSensitivity, fTXContinueOnXoff, fErrorChar and fRtsControl. The DCB length field is now initialized before calling GetCommState. Signed-off-by: Ernst Schwab --- serial_w32.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/serial_w32.c b/serial_w32.c index 47d2675..0bcce93 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -77,6 +77,9 @@ static serial_t *serial_open(const char *device) SetCommMask(h->fd, EV_ERR); /* Notify us of error events */ + /* DCBlength should be initialized before calling GetCommState */ + h->oldtio.DCBlength = sizeof(DCB); + h->newtio.DCBlength = sizeof(DCB); GetCommState(h->fd, &h->oldtio); /* Retrieve port parameters */ GetCommState(h->fd, &h->newtio); /* Retrieve port parameters */ @@ -162,10 +165,15 @@ static port_err_t serial_setup(serial_t *h, /* reset the settings */ h->newtio.fOutxCtsFlow = FALSE; h->newtio.fOutxDsrFlow = FALSE; + h->newtio.fDtrControl = DTR_CONTROL_DISABLE; + h->newtio.fDsrSensitivity = FALSE; + h->newtio.fTXContinueOnXoff = FALSE; h->newtio.fOutX = FALSE; h->newtio.fInX = FALSE; - h->newtio.fNull = 0; - h->newtio.fAbortOnError = 0; + h->newtio.fErrorChar = FALSE; + h->newtio.fNull = FALSE; + h->newtio.fRtsControl = RTS_CONTROL_DISABLE; + h->newtio.fAbortOnError = FALSE; /* set the settings */ serial_flush(h); From d834257acb35a528dec946c85e6133b3a656431f Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Mon, 8 Feb 2016 19:28:17 +0100 Subject: [PATCH 074/134] init.c: Don't build write_to() on non-Linux It is only used by the Linux-only drive_gpio() and otherwise breaks on MinGW. https://sourceforge.net/p/stm32flash/tickets/85/ Signed-off-by: Tormod Volden --- init.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/init.c b/init.c index 12998de..e763256 100644 --- a/init.c +++ b/init.c @@ -40,6 +40,32 @@ struct gpio_list { int exported; /* 0 if gpio should be unexported. */ }; +static int write_to(const char *filename, const char *value) +{ + int fd, ret; + + fd = open(filename, O_WRONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open file \"%s\"\n", filename); + return 0; + } + ret = write(fd, value, strlen(value)); + if (ret < 0) { + fprintf(stderr, "Error writing in file \"%s\"\n", filename); + close(fd); + return 0; + } + close(fd); + return 1; +} + +#if !defined(__linux__) +static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) +{ + fprintf(stderr, "GPIO control only available in Linux\n"); + return 0; +} +#else static int read_from(const char *filename, char *buf, size_t len) { int fd, ret; @@ -67,32 +93,6 @@ static int read_from(const char *filename, char *buf, size_t len) return n; } -static int write_to(const char *filename, const char *value) -{ - int fd, ret; - - fd = open(filename, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open file \"%s\"\n", filename); - return 0; - } - ret = write(fd, value, strlen(value)); - if (ret < 0) { - fprintf(stderr, "Error writing in file \"%s\"\n", filename); - close(fd); - return 0; - } - close(fd); - return 1; -} - -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) { char num[16]; /* sized to carry MAX_INT */ From 1a1f0d9c0bc4193e13415d9d735b4f0752ba651b Mon Sep 17 00:00:00 2001 From: Ernst Schwab Date: Tue, 2 Feb 2016 00:09:08 +0100 Subject: [PATCH 075/134] Allow software reset generation combined with init string The stm32_reset_device() software reset generation function is only called if the -R option is specified. However, if an initialization string (-i) was added, stm32_reset_device() was not called, and gpio_bl_exit() was used instead, even if it didn't contain an exit string. This change will instead allow the combination of a GPIO initialization sequence and a software reset, as long as there is no exit sequence. Also an empty exit sequence will prevent the software reset. Examples: -R -i rts:-rts init string, exit string, no sw reset -R -i rts: init string, empty exit string, no sw reset -R -i rts init string, no exit string, sw reset Signed-off-by: Ernst Schwab --- init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.c b/init.c index e763256..2e72385 100644 --- a/init.c +++ b/init.c @@ -263,7 +263,7 @@ int init_bl_entry(struct port_interface *port, const char *seq) int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) { - if (seq) + if (seq && strchr(seq, ':')) return gpio_bl_exit(port, seq); if (stm32_reset_device(stm) != STM32_ERR_OK) From 295284ee2706e7cdb069d275493f5a5ea08f47e8 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 9 Feb 2016 01:15:01 +0100 Subject: [PATCH 076/134] man page: Describe dependence on -R for -i exit sequences Also add -R to the -i examples. Signed-off-by: Tormod Volden --- stm32flash.1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/stm32flash.1 b/stm32flash.1 index 58e3900..9bc532a 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -228,6 +228,7 @@ GPIO_string = [entry sequence][:[exit sequence]] .P sequence = [\-]n[,sequence] .RE +.PD .P In the above sequences, negative numbers correspond to GPIO at "low" level; numbers without sign correspond to GPIO at "high" level. @@ -239,6 +240,9 @@ after BREAK the UART is returned in normal "non\-break" mode. Note: the string "\-brk" has no effect and is ignored. .PD +.P +Note that the exit sequence is only executed if -R is specified. If -R is specified, but no exit sequence, a software-triggered reset will be performed. + .PD 0 As example, let's suppose the following connection between host and STM32: .IP \(bu 2 @@ -263,7 +267,7 @@ The corresponding string for .I GPIO_string is "\-4,\-3,3". -The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". +The complete command line flag is "\-R \-i 4,\-5,\-3,3:\-4,\-3,3". STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then STM32W will enter in bootloader mode; if PA5 is "high" it will execute the @@ -273,7 +277,7 @@ As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. The command: .PD 0 .RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 +stm32flash \-R \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 .RE provides: .IP \(bu 2 @@ -323,7 +327,7 @@ entry sequence: RTS=low, DTR=low, DTR=high exit sequence: RTS=high, DTR=low, DTR=high .P .RS -stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 +stm32flash \-R \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 .PD .RE From 52b7f79c7cd581d0f5c73b008f5d9fab0e61f1e3 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 9 Feb 2016 17:13:10 +0100 Subject: [PATCH 077/134] Add INSTALL file with build instructions Signed-off-by: Tormod Volden --- INSTALL | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 INSTALL diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..16dcc41 --- /dev/null +++ b/INSTALL @@ -0,0 +1,16 @@ + +Building stm32flash + +A set of static makefiles is provided that should work on most operating +systems with a standard build environment, for instance GNU make and gcc. + +1. Build executable + + make + +2. Install executable and manual page (optional) + + make install + + The install location base can be set with the PREFIX flag (default + is /usr/local), e.g. make install PREFIX=/opt From 8b48701fc319acd3692eb3fb88c2e8adca2dfaa2 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 9 Feb 2016 17:20:31 +0100 Subject: [PATCH 078/134] Update copyright years Signed-off-by: Tormod Volden --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 82dd0b4..1ad3a3f 100644 --- a/main.c +++ b/main.c @@ -2,8 +2,8 @@ stm32flash - Open Source ST STM32 flash program for *nix Copyright 2010 Geoffrey McRae Copyright 2011 Steve Markgraf - Copyright 2012 Tormod Volden - Copyright 2013 Antonio Borneo + Copyright 2012-2016 Tormod Volden + Copyright 2013-2016 Antonio Borneo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License From 2c8100c3309f8a5f919086fee888f2a8d409f02e Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Wed, 10 Feb 2016 17:56:19 +0100 Subject: [PATCH 079/134] Add -R to built-in help text -i example Signed-off-by: Tormod Volden --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 1ad3a3f..7424ae6 100644 --- a/main.c +++ b/main.c @@ -841,7 +841,7 @@ void show_help(char *name) { " GPIO sequence:\n" " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -i -3,-2,2:3,-2,2 /dev/ttyS0\n", + " %s -R -i -3,-2,2:3,-2,2 /dev/ttyS0\n", name, name, name, From 0231aab55846c0ab578c6d351e80d6beb574311f Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Wed, 10 Feb 2016 17:59:02 +0100 Subject: [PATCH 080/134] man page: Remove non-man formatting macro Detected by Debian "lintian" check. Signed-off-by: Tormod Volden --- stm32flash.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stm32flash.1 b/stm32flash.1 index 9bc532a..ca7acb7 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -29,7 +29,7 @@ stm32flash \- flashing utility for STM32 through UART or I2C .RB [ \-i .IR GPIO_string ] .RI [ tty_device -.R | +| .IR i2c_device ] .SH DESCRIPTION From 1f934ae86babdeea47afdfae1d856d5fd5da6c53 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Wed, 10 Feb 2016 20:56:23 +0100 Subject: [PATCH 081/134] Release 0.5 Signed-off-by: Tormod Volden --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 7424ae6..dd11b7f 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ #include "parsers/binary.h" #include "parsers/hex.h" -#define VERSION "0.4" +#define VERSION "0.5" /* device globals */ stm32_t *stm = NULL; From 5361ed8259c9db5cf306c7cf5194af06732cb130 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 11 Dec 2015 15:46:03 +0100 Subject: [PATCH 082/134] Fix for device 0x442: System memory start address RM0091(rev.8.): page 50: STM32F0xx memory boundary addresses (continued) also RM0360 (rev.3) : page 39: STM32F0x0 memory boundary addresses (continued) 0x1FFFC800 -> 0x1FFFD800 Signed-off-by: Amir Hammad --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index f4ada72..50fb64e 100755 --- a/dev_table.c +++ b/dev_table.c @@ -59,7 +59,7 @@ const stm32_dev_t devices[] = { /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range Flags */ /* F0 */ {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, - {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, F_OBLL}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, F_OBLL}, {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800, 0}, {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, From 2381ce3c53a172d19b6450e6005abdb7be0295d4 Mon Sep 17 00:00:00 2001 From: Luc Hondareyte Date: Fri, 6 May 2016 13:35:13 +0200 Subject: [PATCH 083/134] Fix parity setting/checking on *BSD and MacOSX The flag INPCK was set to newtio.c_cflag but it should be set to newtio.c_iflag. http://pubs.opengroup.org/onlinepubs/009695399/basedefs/termios.h.html https://sourceforge.net/p/stm32flash/tickets/89/ https://sourceforge.net/p/stm32flash/tickets/68/ --- serial_posix.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/serial_posix.c b/serial_posix.c index ec6694f..1683b85 100644 --- a/serial_posix.c +++ b/serial_posix.c @@ -129,8 +129,8 @@ static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, switch (parity) { case SERIAL_PARITY_NONE: port_parity = 0; break; - case SERIAL_PARITY_EVEN: port_parity = INPCK | PARENB; break; - case SERIAL_PARITY_ODD: port_parity = INPCK | PARENB | PARODD; break; + case SERIAL_PARITY_EVEN: port_parity = PARENB; break; + case SERIAL_PARITY_ODD: port_parity = PARENB | PARODD; break; default: return PORT_ERR_UNKNOWN; @@ -174,6 +174,8 @@ static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, port_stop | CLOCAL | CREAD; + if ( port_parity != 0 ) + h->newtio.c_iflag |= INPCK; h->newtio.c_cc[VMIN] = 0; h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ From 8c4aa650bffaf98e96d1b6065ab6e76c43150d8a Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Fri, 6 May 2016 16:04:13 +0200 Subject: [PATCH 084/134] dev_table: Mark 0x417, 0x429, 0x427 for no mass-erase These have been reported to not support mass-erase: STM32L151xx-A -> chip ID 0x429 STM32L152RCT -> chip ID 0x427 STM32L051xx -> chip ID 0x417 Thanks to Dieter Deppenaffe for reporting. https://sourceforge.net/p/stm32flash/tickets/87/ Signed-off-by: Tormod Volden --- dev_table.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev_table.c b/dev_table.c index 50fb64e..7e1c53c 100755 --- a/dev_table.c +++ b/dev_table.c @@ -92,12 +92,12 @@ const stm32_dev_t devices[] = { {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, /* L0 */ {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, - {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, + {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, /* L1 */ {0x416, "STM32L1xxx6(8/B)" , 0x20000800, 0x20004000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, - {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, - {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, + {0x429, "STM32L1xxx6(8/B)A" , 0x20001000, 0x20008000, 0x08000000, 0x08020000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, + {0x427, "STM32L1xxxC" , 0x20001000, 0x20008000, 0x08000000, 0x08040000, 16, p_256 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, F_NO_ME}, {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ From d581ce8f8d78a497a1e305e8c759cf75c41ed262 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Tue, 28 Jun 2016 21:25:36 +0300 Subject: [PATCH 085/134] Put Linux specific GPIO code under conditional compile --- init.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/init.c b/init.c index 2e72385..95909cc 100644 --- a/init.c +++ b/init.c @@ -40,6 +40,7 @@ struct gpio_list { int exported; /* 0 if gpio should be unexported. */ }; +#if defined(__linux__) static int write_to(const char *filename, const char *value) { int fd, ret; @@ -59,13 +60,6 @@ static int write_to(const char *filename, const char *value) return 1; } -#if !defined(__linux__) -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) -{ - fprintf(stderr, "GPIO control only available in Linux\n"); - return 0; -} -#else static int read_from(const char *filename, char *buf, size_t len) { int fd, ret; @@ -142,7 +136,6 @@ static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) return write_to(file, level ? "high" : "low"); } -#endif static int release_gpio(int n, int input, int exported) { @@ -159,10 +152,20 @@ static int release_gpio(int n, int input, int exported) return 1; } +#else +static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) +{ + fprintf(stderr, "GPIO control only available in Linux\n"); + return 0; +} +#endif static int gpio_sequence(struct port_interface *port, const char *s, size_t l) { - struct gpio_list *gpio_to_release = NULL, *to_free; + struct gpio_list *gpio_to_release = NULL; +#if defined(__linux__) + struct gpio_list *to_free; +#endif int ret, level, gpio; ret = 1; @@ -214,13 +217,14 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) ret = drive_gpio(gpio, level, &gpio_to_release); usleep(100000); } - +#if defined(__linux__) while (gpio_to_release) { release_gpio(gpio_to_release->gpio, gpio_to_release->input, gpio_to_release->exported); to_free = gpio_to_release; gpio_to_release = gpio_to_release->next; free(to_free); } +#endif usleep(500000); return ret; } From 7a7b4c91d68109daf990ca88528b4b0bc1e31e98 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Wed, 29 Jun 2016 17:02:41 +0300 Subject: [PATCH 086/134] Always run GPIO exit sequence if present [Tormod: Update man page accordingly] Signed-off-by: Tormod Volden --- init.c | 2 +- init.h | 1 + main.c | 4 ++++ stm32flash.1 | 11 +++++++---- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/init.c b/init.c index 95909cc..ee67f13 100644 --- a/init.c +++ b/init.c @@ -243,7 +243,7 @@ static int gpio_bl_entry(struct port_interface *port, const char *seq) return gpio_sequence(port, seq, s - seq); } -static int gpio_bl_exit(struct port_interface *port, const char *seq) +int gpio_bl_exit(struct port_interface *port, const char *seq) { char *s; diff --git a/init.h b/init.h index 6075b51..26992ac 100644 --- a/init.h +++ b/init.h @@ -27,5 +27,6 @@ int init_bl_entry(struct port_interface *port, const char *seq); int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq); +int gpio_bl_exit(struct port_interface *port, const char *seq); #endif diff --git a/main.c b/main.c index dd11b7f..0de5771 100644 --- a/main.c +++ b/main.c @@ -565,6 +565,10 @@ int main(int argc, char* argv[]) { if (init_bl_exit(stm, port, gpio_seq)) fprintf(diag, "done.\n"); else fprintf(diag, "failed.\n"); + } else { + /* Always run exit sequence if present */ + if (gpio_seq && strchr(gpio_seq, ':')) + return gpio_bl_exit(port, gpio_seq); } if (p_st ) parser->close(p_st); diff --git a/stm32flash.1 b/stm32flash.1 index ca7acb7..a521c78 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -241,7 +241,10 @@ Note: the string "\-brk" has no effect and is ignored. .PD .P -Note that the exit sequence is only executed if -R is specified. If -R is specified, but no exit sequence, a software-triggered reset will be performed. +Note that since version 0.6, an exit sequence will always be executed if +specified, regardless of the -R option, to ensure the signals are reset. +If -R is specified, but no exit sequence, a software-triggered reset will +be performed. .PD 0 As example, let's suppose the following connection between host and STM32: @@ -267,7 +270,7 @@ The corresponding string for .I GPIO_string is "\-4,\-3,3". -The complete command line flag is "\-R \-i 4,\-5,\-3,3:\-4,\-3,3". +The complete command line flag is "\-i 4,\-5,\-3,3:\-4,\-3,3". STM32W uses pad PA5 to select boot mode; if during reset PA5 is "low" then STM32W will enter in bootloader mode; if PA5 is "high" it will execute the @@ -277,7 +280,7 @@ As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. The command: .PD 0 .RS -stm32flash \-R \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 +stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 .RE provides: .IP \(bu 2 @@ -327,7 +330,7 @@ entry sequence: RTS=low, DTR=low, DTR=high exit sequence: RTS=high, DTR=low, DTR=high .P .RS -stm32flash \-R \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 +stm32flash \-i \-rts,\-dtr,dtr:rts,\-dtr,dtr /dev/ttyS0 .PD .RE From 3772e9547410116142338190b77b4ceb62c4f577 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 15:54:16 +0300 Subject: [PATCH 087/134] Fix return code in case of flash failure --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 0de5771..b7b8a0e 100644 --- a/main.c +++ b/main.c @@ -568,7 +568,7 @@ int main(int argc, char* argv[]) { } else { /* Always run exit sequence if present */ if (gpio_seq && strchr(gpio_seq, ':')) - return gpio_bl_exit(port, gpio_seq); + ret = gpio_bl_exit(port, gpio_seq) || ret; } if (p_st ) parser->close(p_st); From 26854ef307d3af982cfaba57a5b3d89ed931f329 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Wed, 29 Jun 2016 20:00:47 +0300 Subject: [PATCH 088/134] Fix return value in case of successful protect/unprotect operation --- main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index b7b8a0e..9637da5 100644 --- a/main.c +++ b/main.c @@ -382,13 +382,15 @@ int main(int argc, char* argv[]) { fprintf(stdout, "Read-Protecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - stm32_readprot_memory(stm); + if(stm32_readprot_memory(stm) == STM32_ERR_OK) + ret = 0; fprintf(stdout, "Done.\n"); } else if (action == ACT_READ_UNPROTECT) { fprintf(stdout, "Read-UnProtecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - stm32_runprot_memory(stm); + if(stm32_runprot_memory(stm) == STM32_ERR_OK) + ret = 0; fprintf(stdout, "Done.\n"); } else if (action == ACT_ERASE_ONLY) { ret = 0; @@ -412,7 +414,8 @@ int main(int argc, char* argv[]) { fprintf(diag, "Write-unprotecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - stm32_wunprot_memory(stm); + if(stm32_wunprot_memory(stm) == STM32_ERR_OK) + ret = 0; fprintf(diag, "Done.\n"); } else if (action == ACT_WRITE) { From 0242da6b9d686fe1c276b28621979511999ba670 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Wed, 29 Jun 2016 20:02:44 +0300 Subject: [PATCH 089/134] Ensure correct precedence of bit and logic comparisons --- stm32.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/stm32.c b/stm32.c index 1b0362d..32b1d1c 100644 --- a/stm32.c +++ b/stm32.c @@ -606,7 +606,7 @@ stm32_err_t stm32_write_memory(const stm32_t *stm, uint32_t address, s_err = stm32_get_ack_timeout(stm, STM32_BLKWRITE_TIMEOUT); if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->wm != STM32_CMD_WM_NS) stm32_warn_stretching("write"); return STM32_ERR_UNKNOWN; @@ -633,7 +633,7 @@ stm32_err_t stm32_wunprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; } if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->uw != STM32_CMD_UW_NS) stm32_warn_stretching("WRITE UNPROTECT"); return STM32_ERR_UNKNOWN; @@ -660,7 +660,7 @@ stm32_err_t stm32_wprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; } if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->wp != STM32_CMD_WP_NS) stm32_warn_stretching("WRITE PROTECT"); return STM32_ERR_UNKNOWN; @@ -687,7 +687,7 @@ stm32_err_t stm32_runprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; } if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->ur != STM32_CMD_UR_NS) stm32_warn_stretching("READOUT UNPROTECT"); return STM32_ERR_UNKNOWN; @@ -714,7 +714,7 @@ stm32_err_t stm32_readprot_memory(const stm32_t *stm) return STM32_ERR_UNKNOWN; } if (s_err != STM32_ERR_OK) { - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->rp != STM32_CMD_RP_NS) stm32_warn_stretching("READOUT PROTECT"); return STM32_ERR_UNKNOWN; @@ -755,7 +755,7 @@ static stm32_err_t stm32_mass_erase(const stm32_t *stm) s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->er != STM32_CMD_EE_NS) stm32_warn_stretching("mass erase"); return STM32_ERR_UNKNOWN; @@ -842,7 +842,7 @@ static stm32_err_t stm32_pages_erase(const stm32_t *stm, uint32_t spage, uint32_ s_err = stm32_get_ack_timeout(stm, pages * STM32_PAGEERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { fprintf(stderr, "Page-by-page erase failed. Check the maximum pages your device supports.\n"); - if (port->flags & PORT_STRETCH_W + if ((port->flags & PORT_STRETCH_W) && stm->cmd->er != STM32_CMD_EE_NS) stm32_warn_stretching("erase"); return STM32_ERR_UNKNOWN; @@ -983,7 +983,7 @@ stm32_err_t stm32_crc_memory(const stm32_t *stm, uint32_t address, struct port_interface *port = stm->port; uint8_t buf[5]; - if (address & 0x3 || length & 0x3) { + if ((address & 0x3) || (length & 0x3)) { fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); return STM32_ERR_UNKNOWN; } @@ -1076,7 +1076,7 @@ stm32_err_t stm32_crc_wrapper(const stm32_t *stm, uint32_t address, uint8_t buf[256]; uint32_t start, total_len, len, current_crc; - if (address & 0x3 || length & 0x3) { + if ((address & 0x3) || (length & 0x3)) { fprintf(stderr, "Start and end addresses must be 4 byte aligned\n"); return STM32_ERR_UNKNOWN; } From d202bd046c21c79e14ce566413f077626d31873b Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 12:58:35 +0300 Subject: [PATCH 090/134] Make termios timeout settable via TERMIOS_TIMEOUT_MS define --- serial_posix.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/serial_posix.c b/serial_posix.c index 1683b85..6fa58aa 100644 --- a/serial_posix.c +++ b/serial_posix.c @@ -31,6 +31,12 @@ #include "serial.h" #include "port.h" +#ifndef TERMIOS_TIMEOUT_MS +#define TERMIOS_TIMEOUT_MS 500 +#endif + +#define TERMIOS_TIMEOUT ((TERMIOS_TIMEOUT_MS)/100) + struct serial { int fd; struct termios oldtio; @@ -178,7 +184,7 @@ static port_err_t serial_setup(serial_t *h, const serial_baud_t baud, h->newtio.c_iflag |= INPCK; h->newtio.c_cc[VMIN] = 0; - h->newtio.c_cc[VTIME] = 5; /* in units of 0.1 s */ + h->newtio.c_cc[VTIME] = TERMIOS_TIMEOUT; /* in units of 0.1 s */ /* set the settings */ serial_flush(h); From efeab97a7c7128a6a8b4fc242b3e40e93c72bc07 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Mon, 17 Apr 2017 14:47:01 +0200 Subject: [PATCH 091/134] Allow extra delay or no delay at all in GPIO sequences There was already a 100 ms delay between each GPIO activation. By specifiying an empty GPIO (just the comma) extra delays can now be introduced. By using '&' instead of comma between GPIOs, no delay at all will take place between the GPIO activations. [Tormod: rework documentation] Signed-off-by: Tormod Volden --- init.c | 60 ++++++++++++++++++++++++++++++++++++++++------------ main.c | 25 +++++++++++++++++----- stm32flash.1 | 33 ++++++++++++++++++++++++----- 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/init.c b/init.c index ee67f13..933d1b7 100644 --- a/init.c +++ b/init.c @@ -167,9 +167,17 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) struct gpio_list *to_free; #endif int ret, level, gpio; + int sleep_time = 0; + int delimiter = 0; + const char *sig_str = NULL; + fprintf(stdout, "\nGPIO sequence start\n"); ret = 1; while (ret == 1 && *s && l > 0) { + sig_str = NULL; + sleep_time = 0; + delimiter = 0; + if (*s == '-') { level = 0; s++; @@ -184,38 +192,64 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) l--; } } else if (!strncmp(s, "rts", 3)) { + sig_str = s; gpio = -GPIO_RTS; s += 3; l -= 3; } else if (!strncmp(s, "dtr", 3)) { + sig_str = s; gpio = -GPIO_DTR; s += 3; l -= 3; } else if (!strncmp(s, "brk", 3)) { + sig_str = s; gpio = -GPIO_BRK; s += 3; l -= 3; - } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; - break; - } - - if (*s && (l > 0)) { + } else if (*s && (l > 0)) { + delimiter = 1; + /* The ',' delimiter adds a 100 ms delay between signal toggles. + * i.e -rts,dtr will reset rts, wait 100 ms, set dtr. + * + * The '&' delimiter adds no delay between signal toggles. + * i.e -rts&dtr will reset rts and immediately set dtr. + * + * Example: -rts&dtr,,,rts,-dtr will reset rts and set dtr + * without delay, then wait 300 ms, set rts, wait 100 ms, reset dtr. + */ if (*s == ',') { s++; l--; + sleep_time = 100000; + } else if (*s == '&') { + s++; + l--; } else { fprintf(stderr, "Character \'%c\' is not a separator\n", *s); ret = 0; break; } + } else { + fprintf(stderr, "Character \'%c\' is not a digit\n", *s); + ret = 0; + break; + } + + if (!delimiter) { /* actual gpio/port signal driving */ + if (gpio < 0) { + gpio = -gpio; + fprintf(stdout, " setting port signal %.3s to %i\n", sig_str, level); + ret = (port->gpio(port, gpio, level) == PORT_ERR_OK); + } else { + fprintf(stdout, " setting gpio %i to %i\n", gpio, level); + ret = drive_gpio(gpio, level, &gpio_to_release); + } + } + + if (sleep_time) { + fprintf(stdout, " delay %i us\n", sleep_time); + usleep(sleep_time); } - if (gpio < 0) - ret = (port->gpio(port, -gpio, level) == PORT_ERR_OK); - else - ret = drive_gpio(gpio, level, &gpio_to_release); - usleep(100000); } #if defined(__linux__) while (gpio_to_release) { @@ -225,7 +259,7 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) free(to_free); } #endif - usleep(500000); + fprintf(stdout, "GPIO sequence end\n\n"); return ret; } diff --git a/main.c b/main.c index 9637da5..f1b040f 100644 --- a/main.c +++ b/main.c @@ -822,10 +822,20 @@ void show_help(char *name) { " -c Resume the connection (don't send initial INIT)\n" " *Baud rate must be kept the same as the first init*\n" " This is useful if the reset fails\n" + " -R Reset device at exit.\n" " -i GPIO_string GPIO sequence to enter/exit bootloader mode\n" " GPIO_string=[entry_seq][:[exit_seq]]\n" - " sequence=[-]n[,sequence]\n" - " -R Reset device at exit.\n" + " sequence=[[-]signal]&|,[sequence]\n" + "\n" + "GPIO sequence:\n" + " The following signals can appear in a sequence:\n" + " Integer number representing GPIO pin\n" + " 'dtr', 'rts' or 'brk' representing serial port signal\n" + " The sequence can use the following delimiters:\n" + " ',' adds 100 ms delay between signals\n" + " '&' adds no delay between signals\n" + " The following modifiers can be prepended to a signal:\n" + " '-' reset signal (low) instead of setting it (high)\n" "\n" "Examples:\n" " Get device information:\n" @@ -846,9 +856,14 @@ void show_help(char *name) { " %s -g 0x0 /dev/ttyS0\n" "\n" " GPIO sequence:\n" - " - entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high\n" - " - exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high\n" - " %s -R -i -3,-2,2:3,-2,2 /dev/ttyS0\n", + " - entry sequence: GPIO_3=low, GPIO_2=low, 100ms delay, GPIO_2=high\n" + " - exit sequence: GPIO_3=high, GPIO_2=low, 300ms delay, GPIO_2=high\n" + " %s -i '-3&-2,2:3&-2,,,2' /dev/ttyS0\n" + " GPIO sequence adding delay after port opening:\n" + " - entry sequence: delay 500ms\n" + " - exit sequence: rts=high, dtr=low, 300ms delay, GPIO_2=high\n" + " %s -R -i ',,,,,:rts&-dtr,,,2' /dev/ttyS0\n", + name, name, name, name, diff --git a/stm32flash.1 b/stm32flash.1 index a521c78..6870ae0 100644 --- a/stm32flash.1 +++ b/stm32flash.1 @@ -226,7 +226,7 @@ The format of .RS GPIO_string = [entry sequence][:[exit sequence]] .P -sequence = [\-]n[,sequence] +sequence = [[\-]signal]&|,[sequence] .RE .PD .P @@ -239,7 +239,15 @@ The string "brk" forces the UART to send a BREAK sequence on TX line; after BREAK the UART is returned in normal "non\-break" mode. Note: the string "\-brk" has no effect and is ignored. .PD - +.P +The ',' delimiter adds 100 ms of delay between signal toggles, whereas +the '&' delimiter adds no delay. +An empty signal, thus repeated ',' delimiters, can be used to insert larger +delays in multiples of 100 ms. +E.g. "rts,,,,\-dtr" will set RTS, then wait 400 ms, then reset DTR. +"rts&\-dtr" will set RTS and reset DTR without delay. You can use ',' delimiters +alone to simply add a delay between opening port and starting to flash. +.DP .P Note that since version 0.6, an exit sequence will always be executed if specified, regardless of the -R option, to ensure the signals are reset. @@ -280,15 +288,30 @@ As example, supposing GPIO_3 connected to PA5 and GPIO_2 to STM32W's reset. The command: .PD 0 .RS -stm32flash \-i \-3,\-2,2:3,\-2,2 /dev/ttyS0 +stm32flash \-i '\-3&\-2,2:3&\-2,,,2' /dev/ttyS0 .RE provides: .IP \(bu 2 -entry sequence: GPIO_3=low, GPIO_2=low, GPIO_2=high +entry sequence: GPIO_3=low, GPIO_2=low, 100 ms delay, GPIO_2=high .IP \(bu 2 -exit sequence: GPIO_3=high, GPIO_2=low, GPIO_2=high +exit sequence: GPIO_3=high, GPIO_2=low, 300 ms delay, GPIO_2=high .PD + +GPIO sequence to bring delays on start after port opening. +The command: +.PD 0 +.RS +stm32flash \-i ',,,,,:rts&\-dtr,,,2' /dev/ttyS0\n", +.RE +provides: +.IP \(bu 2 +entry sequence: delay 500 ms +.IP \(bu 2 +exit sequence: RTS=high, DTR=low, 300 ms delay, GPIO_2=high +.PD + + .SH EXAMPLES Get device information: .RS From de7332e6c56aad30335880e00ecc7e674f7368be Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 15:47:13 +0300 Subject: [PATCH 092/134] Fix return code from GPIO bootloader entry sequence --- init.c | 15 +++++++-------- main.c | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/init.c b/init.c index 933d1b7..161b700 100644 --- a/init.c +++ b/init.c @@ -166,14 +166,13 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) #if defined(__linux__) struct gpio_list *to_free; #endif - int ret, level, gpio; + int ret = 0, level, gpio; int sleep_time = 0; int delimiter = 0; const char *sig_str = NULL; fprintf(stdout, "\nGPIO sequence start\n"); - ret = 1; - while (ret == 1 && *s && l > 0) { + while (ret == 0 && *s && l > 0) { sig_str = NULL; sleep_time = 0; delimiter = 0; @@ -226,12 +225,12 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) l--; } else { fprintf(stderr, "Character \'%c\' is not a separator\n", *s); - ret = 0; + ret = 1; break; } } else { fprintf(stderr, "Character \'%c\' is not a digit\n", *s); - ret = 0; + ret = 1; break; } @@ -239,10 +238,10 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) if (gpio < 0) { gpio = -gpio; fprintf(stdout, " setting port signal %.3s to %i\n", sig_str, level); - ret = (port->gpio(port, gpio, level) == PORT_ERR_OK); + ret = (port->gpio(port, gpio, level) != PORT_ERR_OK); } else { fprintf(stdout, " setting gpio %i to %i\n", gpio, level); - ret = drive_gpio(gpio, level, &gpio_to_release); + ret = (drive_gpio(gpio, level, &gpio_to_release) != 1); } } @@ -296,7 +295,7 @@ int init_bl_entry(struct port_interface *port, const char *seq) if (seq) return gpio_bl_entry(port, seq); - return 1; + return 0; } int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) diff --git a/main.c b/main.c index f1b040f..7987f2a 100644 --- a/main.c +++ b/main.c @@ -259,7 +259,7 @@ int main(int argc, char* argv[]) { } fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq) == 0) + if (init_flag && init_bl_entry(port, gpio_seq)) goto close; stm = stm32_init(port, init_flag); if (!stm) From ee7c963ce4e68064e971016ea4111ef30cc4a118 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 16:22:51 +0300 Subject: [PATCH 093/134] Fix return code from GPIO bootloader exit sequence --- init.c | 4 +--- main.c | 10 ++++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/init.c b/init.c index 161b700..fcff677 100644 --- a/init.c +++ b/init.c @@ -303,7 +303,5 @@ int init_bl_exit(stm32_t *stm, struct port_interface *port, const char *seq) if (seq && strchr(seq, ':')) return gpio_bl_exit(port, seq); - if (stm32_reset_device(stm) != STM32_ERR_OK) - return 0; - return 1; + return stm32_reset_device(stm); } diff --git a/main.c b/main.c index 7987f2a..8a61cce 100644 --- a/main.c +++ b/main.c @@ -563,11 +563,13 @@ int main(int argc, char* argv[]) { } if (stm && reset_flag) { - fprintf(diag, "\nResetting device... "); + fprintf(diag, "\nResetting device... \n"); fflush(diag); - if (init_bl_exit(stm, port, gpio_seq)) - fprintf(diag, "done.\n"); - else fprintf(diag, "failed.\n"); + if (init_bl_exit(stm, port, gpio_seq)) { + ret = 1; + fprintf(diag, "Reset failed.\n"); + } else + fprintf(diag, "Reset done.\n"); } else { /* Always run exit sequence if present */ if (gpio_seq && strchr(gpio_seq, ':')) From a285a095262b22bb767ef31403e5f054e019afd8 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 17:41:24 +0300 Subject: [PATCH 094/134] Flush port after boot GPIO sequence Also avoid segfault if no port found. --- i2c.c | 7 +++++++ main.c | 5 ++++- port.h | 1 + serial_posix.c | 13 +++++++++++++ serial_w32.c | 13 +++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/i2c.c b/i2c.c index 10e6bb1..fd15b7a 100644 --- a/i2c.c +++ b/i2c.c @@ -194,11 +194,18 @@ static struct varlen_cmd i2c_cmd_get_reply[] = { { /* sentinel */ } }; +static port_err_t i2c_flush(struct port_interface *port) +{ + /* We shouldn't need to flush I2C */ + return PORT_ERR_OK; +} + struct port_interface port_i2c = { .name = "i2c", .flags = PORT_STRETCH_W, .open = i2c_open, .close = i2c_close, + .flush = i2c_flush, .read = i2c_read, .write = i2c_write, .gpio = i2c_gpio, diff --git a/main.c b/main.c index 8a61cce..0a19fd0 100644 --- a/main.c +++ b/main.c @@ -261,6 +261,9 @@ int main(int argc, char* argv[]) { fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); if (init_flag && init_bl_entry(port, gpio_seq)) goto close; + + port->flush(port); + stm = stm32_init(port, init_flag); if (!stm) goto close; @@ -570,7 +573,7 @@ int main(int argc, char* argv[]) { fprintf(diag, "Reset failed.\n"); } else fprintf(diag, "Reset done.\n"); - } else { + } else if (port) { /* Always run exit sequence if present */ if (gpio_seq && strchr(gpio_seq, ':')) ret = gpio_bl_exit(port, gpio_seq) || ret; diff --git a/port.h b/port.h index 290f034..4e728d7 100644 --- a/port.h +++ b/port.h @@ -62,6 +62,7 @@ struct port_interface { unsigned flags; port_err_t (*open)(struct port_interface *port, struct port_options *ops); port_err_t (*close)(struct port_interface *port); + port_err_t (*flush)(struct port_interface *port); port_err_t (*read)(struct port_interface *port, void *buf, size_t nbyte); port_err_t (*write)(struct port_interface *port, void *buf, size_t nbyte); port_err_t (*gpio)(struct port_interface *port, serial_gpio_t n, int level); diff --git a/serial_posix.c b/serial_posix.c index 6fa58aa..0e999b1 100644 --- a/serial_posix.c +++ b/serial_posix.c @@ -352,11 +352,24 @@ static const char *serial_posix_get_cfg_str(struct port_interface *port) return h ? h->setup_str : "INVALID"; } +static port_err_t serial_posix_flush(struct port_interface *port) +{ + serial_t *h; + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + serial_flush(h); + + return PORT_ERR_OK; +} + struct port_interface port_serial = { .name = "serial_posix", .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, .open = serial_posix_open, .close = serial_posix_close, + .flush = serial_posix_flush, .read = serial_posix_read, .write = serial_posix_write, .gpio = serial_posix_gpio, diff --git a/serial_w32.c b/serial_w32.c index 0bcce93..b53a055 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -337,11 +337,24 @@ static const char *serial_w32_get_cfg_str(struct port_interface *port) return h ? h->setup_str : "INVALID"; } +static port_err_t serial_w32_flush(struct port_interface *port) +{ + serial_t *h; + h = (serial_t *)port->private; + if (h == NULL) + return PORT_ERR_UNKNOWN; + + serial_flush(h); + + return PORT_ERR_OK; +} + struct port_interface port_serial = { .name = "serial_w32", .flags = PORT_BYTE | PORT_GVR_ETX | PORT_CMD_INIT | PORT_RETRY, .open = serial_w32_open, .close = serial_w32_close, + .flush = serial_w32_flush, .read = serial_w32_read, .write = serial_w32_write, .gpio = serial_w32_gpio, From d5df420e988515d8b854c4302299a7e06b0c0f54 Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Thu, 30 Jun 2016 17:56:54 +0300 Subject: [PATCH 095/134] Add message and fix return code on failed boot entry sequence --- main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 0a19fd0..3c9663d 100644 --- a/main.c +++ b/main.c @@ -259,8 +259,11 @@ int main(int argc, char* argv[]) { } fprintf(diag, "Interface %s: %s\n", port->name, port->get_cfg_str(port)); - if (init_flag && init_bl_entry(port, gpio_seq)) + if (init_flag && init_bl_entry(port, gpio_seq)){ + ret = 1; + fprintf(stderr, "Failed to send boot enter sequence\n"); goto close; + } port->flush(port); From 7b5b33a9e90addcae0fc31bdea85a52284c23bfd Mon Sep 17 00:00:00 2001 From: Roman Savrulin Date: Mon, 4 Jul 2016 15:24:18 +0300 Subject: [PATCH 096/134] Verbose error message on GPIO signal change failure --- init.c | 7 +++++-- utils.c | 7 +++++++ utils.h | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/init.c b/init.c index fcff677..488e21e 100644 --- a/init.c +++ b/init.c @@ -32,6 +32,7 @@ #include "serial.h" #include "stm32.h" #include "port.h" +#include "utils.h" struct gpio_list { struct gpio_list *next; @@ -237,11 +238,13 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) if (!delimiter) { /* actual gpio/port signal driving */ if (gpio < 0) { gpio = -gpio; - fprintf(stdout, " setting port signal %.3s to %i\n", sig_str, level); + fprintf(stdout, " setting port signal %.3s to %i... ", sig_str, level); ret = (port->gpio(port, gpio, level) != PORT_ERR_OK); + printStatus(stdout, ret); } else { - fprintf(stdout, " setting gpio %i to %i\n", gpio, level); + fprintf(stdout, " setting gpio %i to %i... ", gpio, level); ret = (drive_gpio(gpio, level, &gpio_to_release) != 1); + printStatus(stdout, ret); } } diff --git a/utils.c b/utils.c index 271bb3e..4bfba17 100644 --- a/utils.c +++ b/utils.c @@ -43,3 +43,10 @@ uint32_t le_u32(const uint32_t v) { ((v & 0x000000FF) << 24); return v; } + +void printStatus(FILE *fd, int condition){ + if(condition) + fprintf(fd, "Error!\n"); + else + fprintf(fd, "OK\n"); +} diff --git a/utils.h b/utils.h index a8d37d2..07395d3 100644 --- a/utils.h +++ b/utils.h @@ -22,9 +22,12 @@ #define _H_UTILS #include +#include char cpu_le(); uint32_t be_u32(const uint32_t v); uint32_t le_u32(const uint32_t v); +void printStatus(FILE *fd, int condition); + #endif From 3daa90ea5ed951751a15166601fd95ee6b951beb Mon Sep 17 00:00:00 2001 From: Mickael GARDET Date: Thu, 1 Sep 2016 17:10:14 +0200 Subject: [PATCH 097/134] Print message on failing read/write protect/unprotect [Tormod: The original patch also fixed invalid application exit status but this was taken care of in Roman's patch series.] Signed-off-by: Tormod Volden --- main.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index 3c9663d..d306f57 100644 --- a/main.c +++ b/main.c @@ -388,16 +388,24 @@ int main(int argc, char* argv[]) { fprintf(stdout, "Read-Protecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - if(stm32_readprot_memory(stm) == STM32_ERR_OK) - ret = 0; + s_err = stm32_readprot_memory(stm); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to read-protect flash\n"); + goto close; + } fprintf(stdout, "Done.\n"); + ret = 0; } else if (action == ACT_READ_UNPROTECT) { fprintf(stdout, "Read-UnProtecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - if(stm32_runprot_memory(stm) == STM32_ERR_OK) - ret = 0; + s_err = stm32_runprot_memory(stm); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to read-unprotect flash\n"); + goto close; + } fprintf(stdout, "Done.\n"); + ret = 0; } else if (action == ACT_ERASE_ONLY) { ret = 0; fprintf(stdout, "Erasing flash\n"); @@ -416,14 +424,18 @@ int main(int argc, char* argv[]) { ret = 1; goto close; } + ret = 0; } else if (action == ACT_WRITE_UNPROTECT) { fprintf(diag, "Write-unprotecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; - if(stm32_wunprot_memory(stm) == STM32_ERR_OK) - ret = 0; + s_err = stm32_wunprot_memory(stm); + if (s_err != STM32_ERR_OK) { + fprintf(stderr, "Failed to write-unprotect flash\n"); + goto close; + } fprintf(diag, "Done.\n"); - + ret = 0; } else if (action == ACT_WRITE) { fprintf(diag, "Write to memory\n"); From 8aa685c996d1382c6db480e6ed46b05ece82957d Mon Sep 17 00:00:00 2001 From: Mickael GARDET Date: Thu, 1 Sep 2016 17:10:53 +0200 Subject: [PATCH 098/134] Add ctrl-C signal handler Will close ports before quitting. --- main.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index d306f57..c266fe6 100644 --- a/main.c +++ b/main.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "init.h" #include "utils.h" @@ -38,13 +39,17 @@ #include "parsers/binary.h" #include "parsers/hex.h" +#if defined(__WIN32__) || defined(__CYGWIN__) +#include +#endif + #define VERSION "0.5" /* device globals */ stm32_t *stm = NULL; - void *p_st = NULL; parser_t *parser = NULL; +struct port_interface *port = NULL; /* settings */ struct port_options port_opts = { @@ -191,8 +196,27 @@ static uint32_t flash_page_to_addr(int page) return addr; } + +#if defined(__WIN32__) || defined(__CYGWIN__) +BOOL CtrlHandler( DWORD fdwCtrlType ) +{ + printf("\nCaught signal %lu\n",fdwCtrlType); + if (p_st && parser ) parser->close(p_st); + if (stm ) stm32_close (stm); + if (port) port->close(port); + exit(1); +} +#else +void sighandler(int s){ + printf("\nCaught signal %d\n",s); + if (p_st && parser ) parser->close(p_st); + if (stm ) stm32_close (stm); + if (port) port->close(port); + exit(1); +} +#endif + int main(int argc, char* argv[]) { - struct port_interface *port = NULL; int ret = 1; stm32_err_t s_err; parser_err_t perr; @@ -203,6 +227,18 @@ int main(int argc, char* argv[]) { if (parse_options(argc, argv) != 0) goto close; +#if defined(__WIN32__) || defined(__CYGWIN__) + SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); +#else + struct sigaction sigIntHandler; + + sigIntHandler.sa_handler = sighandler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + + sigaction(SIGINT, &sigIntHandler, NULL); +#endif + if ((action == ACT_READ) && filename[0] == '-') { diag = stderr; } @@ -461,7 +497,7 @@ int main(int argc, char* argv[]) { // if ((start % stm->dev->fl_ps[i]) != 0 || (end % stm->dev->fl_ps[i]) != 0) { // fprintf(stderr, "Specified start & length are invalid (must be page aligned)\n"); // goto close; - // } + // } // TODO: If writes are not page aligned, we should probably read out existing flash // contents first, so it can be preserved and combined with new data @@ -492,7 +528,7 @@ int main(int argc, char* argv[]) { goto close; } } - + again: s_err = stm32_write_memory(stm, addr, buffer, len); if (s_err != STM32_ERR_OK) { From 1f10b4e3364de54f108bc42e4f789893afd44c9a Mon Sep 17 00:00:00 2001 From: Mickael GARDET Date: Thu, 1 Sep 2016 17:12:03 +0200 Subject: [PATCH 099/134] Serial POSIX: Check if tty is already opened by another stm32flash --- serial_posix.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/serial_posix.c b/serial_posix.c index 0e999b1..00625b8 100644 --- a/serial_posix.c +++ b/serial_posix.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "serial.h" #include "port.h" @@ -53,6 +54,13 @@ static serial_t *serial_open(const char *device) free(h); return NULL; } + + if(lockf(h->fd,F_TLOCK,0) != 0) + { + fprintf(stderr, "Error: %s is already open\n", device); + free(h); + return NULL; + } fcntl(h->fd, F_SETFL, 0); tcgetattr(h->fd, &h->oldtio); @@ -70,6 +78,7 @@ static void serial_close(serial_t *h) { serial_flush(h); tcsetattr(h->fd, TCSANOW, &h->oldtio); + lockf(h->fd, F_ULOCK, 0); close(h->fd); free(h); } From 033aaa8c9ef76163dd74d22fd88c2910dab4cec9 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Fri, 22 Jul 2016 12:27:16 +0200 Subject: [PATCH 100/134] Report RAM and flash size as maximal values https://sourceforge.net/p/stm32flash/tickets/56/ Signed-off-by: Tormod Volden --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index c266fe6..32eb9da 100644 --- a/main.c +++ b/main.c @@ -313,8 +313,8 @@ int main(int argc, char* argv[]) { fprintf(diag, "Option 2 : 0x%02x\n", stm->option2); } fprintf(diag, "Device ID : 0x%04x (%s)\n", stm->pid, stm->dev->name); - fprintf(diag, "- RAM : %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); - fprintf(diag, "- Flash : %dKiB (size first sector: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps[0]); + fprintf(diag, "- RAM : Up to %dKiB (%db reserved by bootloader)\n", (stm->dev->ram_end - 0x20000000) / 1024, stm->dev->ram_start - 0x20000000); + fprintf(diag, "- Flash : Up to %dKiB (size first sector: %dx%d)\n", (stm->dev->fl_end - stm->dev->fl_start ) / 1024, stm->dev->fl_pps, stm->dev->fl_ps[0]); fprintf(diag, "- Option RAM : %db\n", stm->dev->opt_end - stm->dev->opt_start + 1); fprintf(diag, "- System RAM : %dKiB\n", (stm->dev->mem_end - stm->dev->mem_start) / 1024); From 7683db86c4cc5a4add6e343f55764b55a7caefa1 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Fri, 22 Jul 2016 12:29:18 +0200 Subject: [PATCH 101/134] Allow specifying more than 255 pages to erase https://sourceforge.net/p/stm32flash/tickets/91/ Signed-off-by: Tormod Volden --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index 32eb9da..470f9f5 100644 --- a/main.c +++ b/main.c @@ -690,7 +690,7 @@ int parse_options(int argc, char *argv[]) return 1; } npages = strtoul(optarg, NULL, 0); - if (npages > 0xFF || npages < 0) { + if (npages > STM32_MAX_PAGES || npages < 0) { fprintf(stderr, "ERROR: You need to specify a page count between 0 and 255"); return 1; } From a1b2fe4dd5d9a6252da0f1dc1591d8610f66ea5c Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Mon, 17 Apr 2017 18:23:05 +0200 Subject: [PATCH 102/134] Improve validation of GPIO sequence Signed-off-by: Tormod Volden --- init.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/init.c b/init.c index 488e21e..43f51e7 100644 --- a/init.c +++ b/init.c @@ -161,7 +161,7 @@ static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) } #endif -static int gpio_sequence(struct port_interface *port, const char *s, size_t l) +static int gpio_sequence(struct port_interface *port, const char *seq, size_t len_seq) { struct gpio_list *gpio_to_release = NULL; #if defined(__linux__) @@ -171,6 +171,8 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) int sleep_time = 0; int delimiter = 0; const char *sig_str = NULL; + const char *s = seq; + size_t l = len_seq; fprintf(stdout, "\nGPIO sequence start\n"); while (ret == 0 && *s && l > 0) { @@ -191,17 +193,17 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) s++; l--; } - } else if (!strncmp(s, "rts", 3)) { + } else if (l >= 3 && !strncmp(s, "rts", 3)) { sig_str = s; gpio = -GPIO_RTS; s += 3; l -= 3; - } else if (!strncmp(s, "dtr", 3)) { + } else if (l >= 3 && !strncmp(s, "dtr", 3)) { sig_str = s; gpio = -GPIO_DTR; s += 3; l -= 3; - } else if (!strncmp(s, "brk", 3)) { + } else if (l >= 3 && !strncmp(s, "brk", 3)) { sig_str = s; gpio = -GPIO_BRK; s += 3; @@ -225,12 +227,13 @@ static int gpio_sequence(struct port_interface *port, const char *s, size_t l) s++; l--; } else { - fprintf(stderr, "Character \'%c\' is not a separator\n", *s); + fprintf(stderr, "Character \'%c\' is not a valid signal or separator\n", *s); ret = 1; break; } } else { - fprintf(stderr, "Character \'%c\' is not a digit\n", *s); + /* E.g. modifier without signal */ + fprintf(stderr, "Invalid sequence %.*s\n", (int) len_seq, seq); ret = 1; break; } From cc97bcafffca55cd4679eb94e45c007710fc0d2a Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 18 Apr 2017 00:17:21 +0200 Subject: [PATCH 103/134] Treat filenames starting with hyphen correctly In places we were a bit sloppy with the file name check and names only starting with '-' would be interpreted as the magic "-" filename for stdin/stdout. Signed-off-by: Tormod Volden --- main.c | 10 ++++++---- parsers/binary.c | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 470f9f5..6905959 100644 --- a/main.c +++ b/main.c @@ -81,6 +81,7 @@ int retry = 10; char exec_flag = 0; uint32_t execute = 0; char init_flag = 1; +int use_stdinout = 0; char force_binary = 0; char reset_flag = 0; char *filename; @@ -239,7 +240,7 @@ int main(int argc, char* argv[]) { sigaction(SIGINT, &sigIntHandler, NULL); #endif - if ((action == ACT_READ) && filename[0] == '-') { + if (action == ACT_READ && use_stdinout) { diag = stderr; } @@ -487,7 +488,7 @@ int main(int argc, char* argv[]) { max_rlen = max_rlen < max_wlen ? max_rlen : max_wlen; /* Assume data from stdin is whole device */ - if (filename[0] == '-' && filename[1] == '\0') + if (use_stdinout) size = end - start; else size = parser->size(p_st); @@ -521,7 +522,7 @@ int main(int argc, char* argv[]) { goto close; if (len == 0) { - if (filename[0] == '-') { + if (use_stdinout) { break; } else { fprintf(stderr, "Failed to read input file\n"); @@ -680,7 +681,8 @@ int parse_options(int argc, char *argv[]) } action = (c == 'r') ? ACT_READ : ACT_WRITE; filename = optarg; - if (filename[0] == '-') { + if (filename[0] == '-' && filename[1] == '\0') { + use_stdinout = 1; force_binary = 1; } break; diff --git a/parsers/binary.c b/parsers/binary.c index f491952..13a7dcd 100644 --- a/parsers/binary.c +++ b/parsers/binary.c @@ -39,7 +39,7 @@ void* binary_init() { parser_err_t binary_open(void *storage, const char *filename, const char write) { binary_t *st = storage; if (write) { - if (filename[0] == '-') + if (filename[0] == '-' && filename[1] == '\0') st->fd = 1; else st->fd = open( @@ -57,7 +57,7 @@ parser_err_t binary_open(void *storage, const char *filename, const char write) ); st->stat.st_size = 0; } else { - if (filename[0] == '-') { + if (filename[0] == '-' && filename[1] == '\0') { st->fd = 0; } else { if (stat(filename, &st->stat) != 0) From 3a07489490f0770a6f8ed9035ea388bd77fdefa6 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 18 Apr 2017 00:20:48 +0200 Subject: [PATCH 104/134] Don't always print banner to stdout If we are going to write binary output to stdout we don't want to prepend it with the banner. This will cause option parsing error messages to be printed before any banner, which is a pity but hard to avoid. Signed-off-by: Tormod Volden --- main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 6905959..7ff8290 100644 --- a/main.c +++ b/main.c @@ -223,11 +223,16 @@ int main(int argc, char* argv[]) { parser_err_t perr; FILE *diag = stdout; - fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); if (parse_options(argc, argv) != 0) goto close; + if (action == ACT_READ && use_stdinout) { + diag = stderr; + } + + fprintf(diag, "stm32flash " VERSION "\n\n"); + fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); + #if defined(__WIN32__) || defined(__CYGWIN__) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); #else @@ -240,10 +245,6 @@ int main(int argc, char* argv[]) { sigaction(SIGINT, &sigIntHandler, NULL); #endif - if (action == ACT_READ && use_stdinout) { - diag = stderr; - } - if (action == ACT_WRITE) { /* first try hex */ if (!force_binary) { From 843c6f5d1a4a8ff7b4d5dbb43bc985cd577c723a Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 18 Apr 2017 00:29:25 +0200 Subject: [PATCH 105/134] Don't write diagnostics messages to stdout unconditionally Signed-off-by: Tormod Volden --- init.c | 16 +++++++++------- main.c | 17 +++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/init.c b/init.c index 43f51e7..5e3e5b2 100644 --- a/init.c +++ b/init.c @@ -34,6 +34,8 @@ #include "port.h" #include "utils.h" +extern FILE *diag; + struct gpio_list { struct gpio_list *next; int gpio; @@ -174,7 +176,7 @@ static int gpio_sequence(struct port_interface *port, const char *seq, size_t le const char *s = seq; size_t l = len_seq; - fprintf(stdout, "\nGPIO sequence start\n"); + fprintf(diag, "\nGPIO sequence start\n"); while (ret == 0 && *s && l > 0) { sig_str = NULL; sleep_time = 0; @@ -241,18 +243,18 @@ static int gpio_sequence(struct port_interface *port, const char *seq, size_t le if (!delimiter) { /* actual gpio/port signal driving */ if (gpio < 0) { gpio = -gpio; - fprintf(stdout, " setting port signal %.3s to %i... ", sig_str, level); + fprintf(diag, " setting port signal %.3s to %i... ", sig_str, level); ret = (port->gpio(port, gpio, level) != PORT_ERR_OK); - printStatus(stdout, ret); + printStatus(diag, ret); } else { - fprintf(stdout, " setting gpio %i to %i... ", gpio, level); + fprintf(diag, " setting gpio %i to %i... ", gpio, level); ret = (drive_gpio(gpio, level, &gpio_to_release) != 1); - printStatus(stdout, ret); + printStatus(diag, ret); } } if (sleep_time) { - fprintf(stdout, " delay %i us\n", sleep_time); + fprintf(diag, " delay %i us\n", sleep_time); usleep(sleep_time); } } @@ -264,7 +266,7 @@ static int gpio_sequence(struct port_interface *port, const char *seq, size_t le free(to_free); } #endif - fprintf(stdout, "GPIO sequence end\n\n"); + fprintf(diag, "GPIO sequence end\n\n"); return ret; } diff --git a/main.c b/main.c index 7ff8290..4fe4396 100644 --- a/main.c +++ b/main.c @@ -83,6 +83,7 @@ uint32_t execute = 0; char init_flag = 1; int use_stdinout = 0; char force_binary = 0; +FILE *diag; char reset_flag = 0; char *filename; char *gpio_seq = NULL; @@ -201,7 +202,7 @@ static uint32_t flash_page_to_addr(int page) #if defined(__WIN32__) || defined(__CYGWIN__) BOOL CtrlHandler( DWORD fdwCtrlType ) { - printf("\nCaught signal %lu\n",fdwCtrlType); + fprintf(stderr, "\nCaught signal %lu\n",fdwCtrlType); if (p_st && parser ) parser->close(p_st); if (stm ) stm32_close (stm); if (port) port->close(port); @@ -209,7 +210,7 @@ BOOL CtrlHandler( DWORD fdwCtrlType ) } #else void sighandler(int s){ - printf("\nCaught signal %d\n",s); + fprintf(stderr, "\nCaught signal %d\n",s); if (p_st && parser ) parser->close(p_st); if (stm ) stm32_close (stm); if (port) port->close(port); @@ -221,7 +222,7 @@ int main(int argc, char* argv[]) { int ret = 1; stm32_err_t s_err; parser_err_t perr; - FILE *diag = stdout; + diag = stdout; if (parse_options(argc, argv) != 0) goto close; @@ -423,7 +424,7 @@ int main(int argc, char* argv[]) { ret = 0; goto close; } else if (action == ACT_READ_PROTECT) { - fprintf(stdout, "Read-Protecting flash\n"); + fprintf(diag, "Read-Protecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; s_err = stm32_readprot_memory(stm); @@ -431,10 +432,10 @@ int main(int argc, char* argv[]) { fprintf(stderr, "Failed to read-protect flash\n"); goto close; } - fprintf(stdout, "Done.\n"); + fprintf(diag, "Done.\n"); ret = 0; } else if (action == ACT_READ_UNPROTECT) { - fprintf(stdout, "Read-UnProtecting flash\n"); + fprintf(diag, "Read-UnProtecting flash\n"); /* the device automatically performs a reset after the sending the ACK */ reset_flag = 0; s_err = stm32_runprot_memory(stm); @@ -442,11 +443,11 @@ int main(int argc, char* argv[]) { fprintf(stderr, "Failed to read-unprotect flash\n"); goto close; } - fprintf(stdout, "Done.\n"); + fprintf(diag, "Done.\n"); ret = 0; } else if (action == ACT_ERASE_ONLY) { ret = 0; - fprintf(stdout, "Erasing flash\n"); + fprintf(diag, "Erasing flash\n"); if (num_pages != STM32_MASS_ERASE && (start != flash_page_to_addr(first_page) From 671561e55282d300718cda1051bf50a4ce364a5e Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 18 Apr 2017 21:22:23 +0200 Subject: [PATCH 106/134] Allow read/write to full option byte area and system memory Set the end address to the end of the memory area in question. Specifying shorter length is possible using -S address:length Note that some hardware only let you read from the beginning of the option byte area (or write the complete area in one operation). Thanks to Edvar Klakken for reporting and Maurits van der Hoorn for suggesting and testing an initial patch. https://sourceforge.net/p/stm32flash/tickets/93/ Signed-off-by: Tormod Volden --- main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/main.c b/main.c index 4fe4396..d2e5812 100644 --- a/main.c +++ b/main.c @@ -134,6 +134,17 @@ static int is_addr_in_flash(uint32_t addr) return addr >= stm->dev->fl_start && addr < stm->dev->fl_end; } +static int is_addr_in_opt_bytes(uint32_t addr) +{ + /* option bytes upper range is inclusive in our device table */ + return addr >= stm->dev->opt_start && addr <= stm->dev->opt_end; +} + +static int is_addr_in_sysmem(uint32_t addr) +{ + return addr >= stm->dev->mem_start && addr < stm->dev->mem_end; +} + /* returns the page that contains address "addr" */ static int flash_addr_to_page_floor(uint32_t addr) { @@ -344,6 +355,10 @@ int main(int argc, char* argv[]) { no_erase = 1; if (is_addr_in_ram(start)) end = stm->dev->ram_end; + else if (is_addr_in_opt_bytes(start)) + end = stm->dev->opt_end + 1; + else if (is_addr_in_sysmem(start)) + end = stm->dev->mem_end; else end = start + sizeof(uint32_t); } From 6b6b6e5f5c2870a8ea9bc69d9073a8b6b12165ef Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Tue, 18 Apr 2017 21:47:30 +0200 Subject: [PATCH 107/134] Let user decide length for unknown memory areas As before use a safe default of 4 bytes if the user doesn't specify a length. We have no idea if more bytes can be accessed. https://sourceforge.net/p/stm32flash/tickets/93/ Signed-off-by: Tormod Volden --- main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index d2e5812..f0d33ae 100644 --- a/main.c +++ b/main.c @@ -359,8 +359,13 @@ int main(int argc, char* argv[]) { end = stm->dev->opt_end + 1; else if (is_addr_in_sysmem(start)) end = stm->dev->mem_end; - else - end = start + sizeof(uint32_t); + else { + /* Unknown territory */ + if (readwrite_len) + end = start + readwrite_len; + else + end = start + sizeof(uint32_t); + } } if (readwrite_len && (end > start + readwrite_len)) From 27626f59d446656dbf7ca4c6a14406a36a197696 Mon Sep 17 00:00:00 2001 From: Mickael GARDET Date: Thu, 1 Sep 2016 17:09:40 +0200 Subject: [PATCH 108/134] Add autotools support For now we'll keep the hand-crafted Makefile anyway to keep dependencies to a minimum. --- Makefile.am | 39 +++++++++++++++++++++++++++++++++++++++ configure.ac | 33 +++++++++++++++++++++++++++++++++ parsers/Makefile.am | 11 +++++++++++ 3 files changed, 83 insertions(+) create mode 100644 Makefile.am create mode 100644 configure.ac create mode 100644 parsers/Makefile.am diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..c877c7b --- /dev/null +++ b/Makefile.am @@ -0,0 +1,39 @@ + +SUBDIRS = parsers + +bin_PROGRAMS = stm32flash + +AUTOMAKE_OPTIONS = subdir-objects + + +stm32flash_SOURCES = \ + dev_table.c \ + i2c.c \ + init.c \ + main.c \ + port.c \ + serial_common.c \ + serial_platform.c\ + stm32.c \ + utils.c + +stm32flash_LDADD = ${top_builddir}/parsers/parsers.la + +stm32flash_CFLAGS = \ + -g3 \ + -Os \ + -Wall \ + -Wextra \ + -I$(srcdir)/parsers + + +stm32flash_LDFLAGS = \ + -Wall \ + -g3 \ + -Wextra + +all: + + +.PHONY: all +.SILENT: all diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..c05a9e0 --- /dev/null +++ b/configure.ac @@ -0,0 +1,33 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.68]) +AC_INIT([stm32flash], [0.5], []) + +# Checks for programs. +AM_INIT_AUTOMAKE([foreign -Wall]) +AC_PROG_CC +AM_PROG_CC_C_O +AM_PROG_AR +AM_PROG_AS +LT_INIT +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. + +# Checks for libraries. + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. + + +AC_CONFIG_FILES( + [ + Makefile + parsers/Makefile + ]) + +AC_OUTPUT diff --git a/parsers/Makefile.am b/parsers/Makefile.am new file mode 100644 index 0000000..033d49b --- /dev/null +++ b/parsers/Makefile.am @@ -0,0 +1,11 @@ +noinst_LTLIBRARIES = parsers.la + + +parsers_la_SOURCES = binary.c hex.c + +parsers_la_CXXFLAGS = -Wall -g + + +parsers_la_LDFLAGS = -module -avoid-version + + From 2783493f8cb25d61b0a143114b908002cf05aa21 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 27 Apr 2017 16:58:28 +0200 Subject: [PATCH 109/134] Add some more F4/F7/L4 devices Tested on Nucleo-F769ZI and checked against AN2606 Rev.30. Signed-off-by: Uwe Bonnes --- dev_table.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 7e1c53c..e939517 100755 --- a/dev_table.c +++ b/dev_table.c @@ -86,10 +86,14 @@ const stm32_dev_t devices[] = { {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x441, "STM32F412xx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x463, "STM32F413xx" , 0x20003000, 0x20050000, 0x08000000, 0x08180000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, /* F7 */ + {0x452, "STM32F72xxx/73xxx" , 0x20004000, 0x20040000, 0x08000000, 0x08080000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, + {0x451, "STM32F76xxx/77xxx" , 0x20004000, 0x20080000, 0x08000000, 0x08200000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, /* L0 */ {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, @@ -101,7 +105,9 @@ const stm32_dev_t devices[] = { {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ - {0x415, "STM32L476xx/486xx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x461, "STM32L496xx/4A6xx" , 0x20003100, 0x20040000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, From bc0876ddf54e8b69ba606c090a62861e68a4a323 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 5 Aug 2017 20:44:21 +0200 Subject: [PATCH 110/134] dev_table: fix RAM size for STM32F412xx Accordingly to RM0402 and datasheet, the device has 256k of RAM. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index e939517..be68b1e 100755 --- a/dev_table.c +++ b/dev_table.c @@ -86,7 +86,7 @@ const stm32_dev_t devices[] = { {0x433, "STM32F401xD(E)" , 0x20003000, 0x20018000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, - {0x441, "STM32F412xx" , 0x20003000, 0x20020000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x441, "STM32F412xx" , 0x20003000, 0x20040000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x463, "STM32F413xx" , 0x20003000, 0x20050000, 0x08000000, 0x08180000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, From 8a0d423c93209b34371bb6682bb3a2ca3eaa719a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 5 Aug 2017 21:20:22 +0200 Subject: [PATCH 111/134] dev_table: F4: reorder and align names with AN2606 rev 31 Align device names with AN2606 rev 31. Also, reorder them to match the list in AN2606. This would make easier to keep the table in sync with the document. Signed-off-by: Antonio Borneo --- dev_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_table.c b/dev_table.c index be68b1e..f89e808 100755 --- a/dev_table.c +++ b/dev_table.c @@ -87,9 +87,9 @@ const stm32_dev_t devices[] = { {0x458, "STM32F410xx" , 0x20003000, 0x20008000, 0x08000000, 0x08020000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x431, "STM32F411xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x441, "STM32F412xx" , 0x20003000, 0x20040000, 0x08000000, 0x08100000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, - {0x463, "STM32F413xx" , 0x20003000, 0x20050000, 0x08000000, 0x08180000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x421, "STM32F446xx" , 0x20003000, 0x20020000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, - {0x434, "STM32F469xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x434, "STM32F469xx/479xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, + {0x463, "STM32F413xx/423xx" , 0x20003000, 0x20050000, 0x08000000, 0x08180000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, /* F7 */ {0x452, "STM32F72xxx/73xxx" , 0x20004000, 0x20040000, 0x08000000, 0x08080000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, From cc70634f05a1fcc2ddf634d23ed8a9b7421dccee Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 00:49:13 +0200 Subject: [PATCH 112/134] dev_table: F0: reorder with AN2606 rev 31 Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index f89e808..afd1114 100755 --- a/dev_table.c +++ b/dev_table.c @@ -59,8 +59,8 @@ const stm32_dev_t devices[] = { /* ID "name" SRAM-address-range FLASH-address-range PPS PSize Option-byte-addr-range System-mem-addr-range Flags */ /* F0 */ {0x440, "STM32F030x8/F05xxx" , 0x20000800, 0x20002000, 0x08000000, 0x08010000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, - {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, F_OBLL}, {0x444, "STM32F03xx4/6" , 0x20000800, 0x20001000, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFEC00, 0x1FFFF800, 0}, + {0x442, "STM32F030xC/F09xxx" , 0x20001800, 0x20008000, 0x08000000, 0x08040000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFD800, 0x1FFFF800, F_OBLL}, {0x445, "STM32F04xxx/F070x6" , 0x20001800, 0x20001800, 0x08000000, 0x08008000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC400, 0x1FFFF800, 0}, {0x448, "STM32F070xB/F071xx/F72xx" , 0x20001800, 0x20004000, 0x08000000, 0x08020000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFC800, 0x1FFFF800, 0}, /* F1 */ From 76da7c4fcc328d8eb0ea92a6f73fb927600901be Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 01:07:17 +0200 Subject: [PATCH 113/134] dev_table: L4: reorder with AN2606 rev 31 Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index afd1114..77ddd14 100755 --- a/dev_table.c +++ b/dev_table.c @@ -105,8 +105,8 @@ const stm32_dev_t devices[] = { {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ - {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, {0x461, "STM32L496xx/4A6xx" , 0x20003100, 0x20040000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, From e2a4f65bf36ad4bb4358f0e3a9ddb3e3092137a0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 21:00:31 +0200 Subject: [PATCH 114/134] dev_table: fix option byte end address for STM32L43xxx/44xxx Checked against RM0394 rev 3 http://www.st.com/resource/en/reference_manual/dm00151940.pdf Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index 77ddd14..8e51d99 100755 --- a/dev_table.c +++ b/dev_table.c @@ -105,7 +105,7 @@ const stm32_dev_t devices[] = { {0x436, "STM32L1xxxD" , 0x20001000, 0x2000C000, 0x08000000, 0x08060000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, 0}, {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ - {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, 0}, {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, {0x461, "STM32L496xx/4A6xx" , 0x20003100, 0x20040000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ From 0c846695c6aa58334147e386cc8254bc9b816abf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 21:41:59 +0200 Subject: [PATCH 115/134] dev_table: add STM32L45xxx/46xxx Checked against RM0394 rev 3 http://www.st.com/resource/en/reference_manual/dm00151940.pdf and AN2606 rev 31. Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 8e51d99..d707850 100755 --- a/dev_table.c +++ b/dev_table.c @@ -106,6 +106,7 @@ const stm32_dev_t devices[] = { {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x462, "STM32L45xxx/46xxx" , 0x20003100, 0x20020000, 0x08000000, 0x08080000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, 0}, {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, {0x461, "STM32L496xx/4A6xx" , 0x20003100, 0x20040000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ From 12bfd33d384d4a26c0a4753dce6fadef2f057ff9 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 22:14:48 +0200 Subject: [PATCH 116/134] dev_table: fix flash layout of STM32F72xxx/73xxx Accordingly to RM0431 rev 1 http://www.st.com/resource/en/reference_manual/dm00305990.pdf the flash layout of STM32F72xxx/73xxx is the same as f2f4. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_table.c b/dev_table.c index d707850..cda071b 100755 --- a/dev_table.c +++ b/dev_table.c @@ -91,7 +91,7 @@ const stm32_dev_t devices[] = { {0x434, "STM32F469xx/479xx" , 0x20003000, 0x20060000, 0x08000000, 0x08200000, 1, f4db , 0x1FFEC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, {0x463, "STM32F413xx/423xx" , 0x20003000, 0x20050000, 0x08000000, 0x08180000, 1, f2f4 , 0x1FFFC000, 0x1FFFC00F, 0x1FFF0000, 0x1FFF7800, 0}, /* F7 */ - {0x452, "STM32F72xxx/73xxx" , 0x20004000, 0x20040000, 0x08000000, 0x08080000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, + {0x452, "STM32F72xxx/73xxx" , 0x20004000, 0x20040000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x451, "STM32F76xxx/77xxx" , 0x20004000, 0x20080000, 0x08000000, 0x08200000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, /* L0 */ From 59d08c22afb2d7dfa51ba853b4ce4da1d6ce639c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 23:18:37 +0200 Subject: [PATCH 117/134] dev_table: add device family H7 Based on AN2606 rev 31 and RM0433 rev 2 http://www.st.com/resource/en/reference_manual/dm00314099.pdf Actually device STM32H74xxx/75xxx has two RAM areas. The second one 0x24034000-0x24080000 is not reported here. The option bytes are not memory mapped, so not accessible. Signed-off-by: Antonio Borneo --- dev_table.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dev_table.c b/dev_table.c index cda071b..9312c1f 100755 --- a/dev_table.c +++ b/dev_table.c @@ -36,10 +36,11 @@ */ /* fixed size pages */ -static uint32_t p_128[] = { SZ_128, 0 }; -static uint32_t p_256[] = { SZ_256, 0 }; -static uint32_t p_1k[] = { SZ_1K, 0 }; -static uint32_t p_2k[] = { SZ_2K, 0 }; +static uint32_t p_128[] = { SZ_128, 0 }; +static uint32_t p_256[] = { SZ_256, 0 }; +static uint32_t p_1k[] = { SZ_1K, 0 }; +static uint32_t p_2k[] = { SZ_2K, 0 }; +static uint32_t p_128k[] = { SZ_128K, 0 }; /* F2 and F4 page size */ static uint32_t f2f4[] = { SZ_16K, SZ_16K, SZ_16K, SZ_16K, SZ_64K, SZ_128K, 0 }; /* F4 dual bank page size */ @@ -94,6 +95,8 @@ const stm32_dev_t devices[] = { {0x452, "STM32F72xxx/73xxx" , 0x20004000, 0x20040000, 0x08000000, 0x08080000, 1, f2f4 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x449, "STM32F74xxx/75xxx" , 0x20004000, 0x20050000, 0x08000000, 0x08100000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, {0x451, "STM32F76xxx/77xxx" , 0x20004000, 0x20080000, 0x08000000, 0x08200000, 1, f7 , 0x1FFF0000, 0x1FFF001F, 0x1FF00000, 0x1FF0EDC0, 0}, + /* H7 */ + {0x450, "STM32H74xxx/75xxx" , 0x20004100, 0x20020000, 0x08000000, 0x08200000, 1, p_128k, 0 , 0 , 0x1FF00000, 0x1FF1E800, 0}, /* L0 */ {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, From acf15a2be46a671405d177c81356cfde70ca2464 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 6 Aug 2017 23:45:27 +0200 Subject: [PATCH 118/134] dev_table: add device STM32L01xxx/02xxx Based on AN2606 rev 31 and RM0377 rev 7 http://www.st.com/resource/en/reference_manual/dm00108282.pdf RAM start and end address are set to the same value (end-of-RAM) because no RAM is accessible from bootloader. Signed-off-by: Antonio Borneo --- dev_table.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_table.c b/dev_table.c index 9312c1f..f552982 100755 --- a/dev_table.c +++ b/dev_table.c @@ -98,6 +98,7 @@ const stm32_dev_t devices[] = { /* H7 */ {0x450, "STM32H74xxx/75xxx" , 0x20004100, 0x20020000, 0x08000000, 0x08200000, 1, p_128k, 0 , 0 , 0x1FF00000, 0x1FF1E800, 0}, /* L0 */ + {0x457, "STM32L01xxx/02xxx" , 0x20000800, 0x20000800, 0x08000000, 0x08004000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x425, "STM32L031xx/041xx" , 0x20001000, 0x20002000, 0x08000000, 0x08008000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, 0}, {0x417, "STM32L05xxx/06xxx" , 0x20001000, 0x20002000, 0x08000000, 0x08010000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF01000, F_NO_ME}, {0x447, "STM32L07xxx/08xxx" , 0x20002000, 0x20005000, 0x08000000, 0x08030000, 32, p_128 , 0x1FF80000, 0x1FF8001F, 0x1FF00000, 0x1FF02000, 0}, From c4293d39d6e2f8e41ce8d8040df49654d5f34715 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 7 Aug 2017 01:12:47 +0200 Subject: [PATCH 119/134] Flip PEMPTY bit before SW reset on STM32L452 Somehow similar to commit 35b263e9e93f ("Use OBL_LAUNCH reset instead of SYSRESETREQ on STM32F030xC"). Also device STM32L452 reenters in bootloader after reset if its flash was empty at power-on. Check RM0394 at chapter 2.6. Before SW reset, check bit PEMPTY of FLASH_SR register and the first word in flash; if they do not match then flip PEMPTY by writing "1" into it. Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- stm32.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stm32.h | 5 +++-- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/dev_table.c b/dev_table.c index f552982..de21824 100755 --- a/dev_table.c +++ b/dev_table.c @@ -110,7 +110,7 @@ const stm32_dev_t devices[] = { {0x437, "STM32L1xxxE" , 0x20001000, 0x20014000, 0x08000000, 0x08080000, 16, p_256 , 0x1FF80000, 0x1FF8009F, 0x1FF00000, 0x1FF02000, F_NO_ME}, /* L4 */ {0x435, "STM32L43xxx/44xxx" , 0x20003100, 0x2000C000, 0x08000000, 0x08040000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, 0}, - {0x462, "STM32L45xxx/46xxx" , 0x20003100, 0x20020000, 0x08000000, 0x08080000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, 0}, + {0x462, "STM32L45xxx/46xxx" , 0x20003100, 0x20020000, 0x08000000, 0x08080000, 1, p_2k , 0x1FFF7800, 0x1FFF780F, 0x1FFF0000, 0x1FFF7000, F_PEMPTY}, {0x415, "STM32L47xxx/48xxx" , 0x20003100, 0x20018000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, {0x461, "STM32L496xx/4A6xx" , 0x20003100, 0x20040000, 0x08000000, 0x08100000, 1, p_2k , 0x1FFF7800, 0x1FFFF80F, 0x1FFF0000, 0x1FFF7000, 0}, /* These are not (yet) in AN2606: */ diff --git a/stm32.c b/stm32.c index 32b1d1c..781961c 100644 --- a/stm32.c +++ b/stm32.c @@ -117,6 +117,59 @@ static const uint8_t stm_obl_launch_code[] = { static const uint32_t stm_obl_launch_code_length = sizeof(stm_obl_launch_code); +/* RM0394, Empty check + * On STM32L452 (and possibly all STM32L45xxx/46xxx) internal empty check flag is + * implemented to allow easy programming of the virgin devices by the boot loader. This flag is + * used when BOOT0 pin is defining Main Flash memory as the target boot space. When the + * flag is set, the device is considered as empty and System memory (boot loader) is selected + * instead of the Main Flash as a boot space to allow user to program the Flash memory. + * This flag is updated only during Option bytes loading: it is set when the content of the + * address 0x08000 0000 is read as 0xFFFF FFFF, otherwise it is cleared. It means a power + * on or setting of OBL_LAUNCH bit in FLASH_CR register or a toggle of PEMPTY bit in FLASH_SR + * register is needed to clear this flag after after programming of a virgin device to execute + * user code after System reset. + * In STM32L45xxx/46xxx the register FLASH_CR could be locked and a special SW sequence is + * required for unlocking it. If a previous unsuccessful unlock has happened, a reset is + * required before the unlock. Due to such complications, toggling the PEMPTY bit in FLASH_SR + * seams the most reasonable choice. + * The code below check first word in flash and flag PEMPTY. If they do not match, then it + * toggles PEMPTY. At last, it resets. + */ + +static const uint8_t stm_pempty_launch_code[] = { + 0x08, 0x48, // ldr r0, [pc, #32] ; () + 0x00, 0x68, // ldr r0, [r0, #0] + 0x01, 0x30, // adds r0, #1 + 0x41, 0x1e, // subs r1, r0, #1 + 0x88, 0x41, // sbcs r0, r1 + + 0x07, 0x49, // ldr r1, [pc, #28] ; () + 0x07, 0x4a, // ldr r2, [pc, #28] ; () + 0x0b, 0x68, // ldr r3, [r1, #0] + 0x13, 0x40, // ands r3, r2 + 0x5c, 0x1e, // subs r4, r3, #1 + 0xa3, 0x41, // sbcs r3, r4 + + 0x98, 0x42, // cmp r0, r3 + 0x00, 0xd1, // bne.n skip1 + + 0x0a, 0x60, // str r2, [r1, #0] + + 0x04, 0x48, // skip1: ldr r0, [pc, #16] ; () + 0x05, 0x49, // ldr r1, [pc, #16] ; () + 0x01, 0x60, // str r1, [r0, #0] + + 0xfe, 0xe7, // endless: b.n endless + + 0x00, 0x00, 0x00, 0x08, // .word 0x08000000 + 0x10, 0x20, 0x02, 0x40, // .word 0x40022010 + 0x00, 0x00, 0x02, 0x00, // .word 0x00020000 + 0x0c, 0xed, 0x00, 0xe0, // .word 0xe000ed0c = NVIC AIRCR register address + 0x04, 0x00, 0xfa, 0x05 // .word 0x05fa0004 = VECTKEY | SYSRESETREQ +}; + +static const uint32_t stm_pempty_launch_code_length = sizeof(stm_pempty_launch_code); + extern const stm32_dev_t devices[]; int flash_addr_to_page_ceil(uint32_t addr); @@ -972,6 +1025,9 @@ stm32_err_t stm32_reset_device(const stm32_t *stm) if (stm->dev->flags & F_OBLL) { /* set the OBL_LAUNCH bit to reset device (see RM0360, 2.5) */ return stm32_run_raw_code(stm, target_address, stm_obl_launch_code, stm_obl_launch_code_length); + } else if (stm->dev->flags & F_PEMPTY) { + /* clear the PEMPTY bit to reset the device (see RM0394) */ + return stm32_run_raw_code(stm, target_address, stm_pempty_launch_code, stm_pempty_launch_code_length); } else { return stm32_run_raw_code(stm, target_address, stm_reset_code, stm_reset_code_length); } diff --git a/stm32.h b/stm32.h index 0e0035b..eb9e79e 100644 --- a/stm32.h +++ b/stm32.h @@ -38,8 +38,9 @@ typedef enum { } stm32_err_t; typedef enum { - F_NO_ME = 1 << 0, /* Mass-Erase not supported */ - F_OBLL = 1 << 1, /* OBL_LAUNCH required */ + F_NO_ME = 1 << 0, /* Mass-Erase not supported */ + F_OBLL = 1 << 1, /* OBL_LAUNCH required */ + F_PEMPTY = 1 << 2, /* clear PEMPTY bit required */ } flags_t; typedef struct stm32 stm32_t; From 2e09c51ad5184adea4218f9d9f7bd91683629316 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 7 Aug 2017 01:23:11 +0200 Subject: [PATCH 120/134] Fix indentation warning from GCC 7.1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properly adjust indentation to avoid warning from new GCC. This fixes: stm32.c: In function ‘stm32_mass_erase’: stm32.c:793:2: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation] if ((port->flags & PORT_STRETCH_W) ^~ stm32.c:796:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’ return STM32_ERR_UNKNOWN; ^~~~~~ Signed-off-by: Antonio Borneo --- stm32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stm32.c b/stm32.c index 781961c..96c0e81 100644 --- a/stm32.c +++ b/stm32.c @@ -808,9 +808,9 @@ static stm32_err_t stm32_mass_erase(const stm32_t *stm) s_err = stm32_get_ack_timeout(stm, STM32_MASSERASE_TIMEOUT); if (s_err != STM32_ERR_OK) { fprintf(stderr, "Mass erase failed. Try specifying the number of pages to be erased.\n"); - if ((port->flags & PORT_STRETCH_W) - && stm->cmd->er != STM32_CMD_EE_NS) - stm32_warn_stretching("mass erase"); + if ((port->flags & PORT_STRETCH_W) + && stm->cmd->er != STM32_CMD_EE_NS) + stm32_warn_stretching("mass erase"); return STM32_ERR_UNKNOWN; } return STM32_ERR_OK; From 68cc278ecdd456b4f59d4599bd44f8898175be69 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 17 Oct 2017 14:47:39 +0200 Subject: [PATCH 121/134] Fix dev_table for Android compilation Android uses clang for compiling stm32flash, enabling extra warning. The last "empty" element of the table must be full or empty, otherwise it will rise error: error: missing field 'name' initializer [-Werror,-Wmissing-field-initializers] Signed-off-by: Antonio Borneo --- dev_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 dev_table.c diff --git a/dev_table.c b/dev_table.c old mode 100755 new mode 100644 index de21824..5cdb515 --- a/dev_table.c +++ b/dev_table.c @@ -117,5 +117,5 @@ const stm32_dev_t devices[] = { {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, p_2k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, - {0x0} + { /* sentinel */ } }; From 475da89cdf632aa26a76df970da2547d1afce4c7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 17 Oct 2017 15:08:47 +0200 Subject: [PATCH 122/134] Fix signed/unsigned comparison Compiling under Android fails because of comparison between signed and unsigned integers. Fix all the cases prompted by the compiler. Signed-off-by: Antonio Borneo --- i2c.c | 4 ++-- init.c | 2 +- parsers/binary.c | 12 ++++++++---- parsers/hex.c | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/i2c.c b/i2c.c index fd15b7a..56a5393 100644 --- a/i2c.c +++ b/i2c.c @@ -149,7 +149,7 @@ static port_err_t i2c_read(struct port_interface *port, void *buf, if (h == NULL) return PORT_ERR_UNKNOWN; ret = read(h->fd, buf, nbyte); - if (ret != nbyte) + if (ret != (int)nbyte) return PORT_ERR_UNKNOWN; return PORT_ERR_OK; } @@ -164,7 +164,7 @@ static port_err_t i2c_write(struct port_interface *port, void *buf, if (h == NULL) return PORT_ERR_UNKNOWN; ret = write(h->fd, buf, nbyte); - if (ret != nbyte) + if (ret != (int)nbyte) return PORT_ERR_UNKNOWN; return PORT_ERR_OK; } diff --git a/init.c b/init.c index 5e3e5b2..5f2d855 100644 --- a/init.c +++ b/init.c @@ -66,7 +66,7 @@ static int write_to(const char *filename, const char *value) static int read_from(const char *filename, char *buf, size_t len) { int fd, ret; - ssize_t n = 0; + size_t n = 0; fd = open(filename, O_RDONLY); if (fd < 0) { diff --git a/parsers/binary.c b/parsers/binary.c index 13a7dcd..a1a30b4 100644 --- a/parsers/binary.c +++ b/parsers/binary.c @@ -92,11 +92,13 @@ unsigned int binary_size(void *storage) { parser_err_t binary_read(void *storage, void *data, unsigned int *len) { binary_t *st = storage; unsigned int left = *len; + unsigned char *d = data; + if (st->write) return PARSER_ERR_WRONLY; ssize_t r; while(left > 0) { - r = read(st->fd, data, left); + r = read(st->fd, d, left); /* If there is no data to read at all, return OK, but with zero read */ if (r == 0 && left == *len) { *len = 0; @@ -104,7 +106,7 @@ parser_err_t binary_read(void *storage, void *data, unsigned int *len) { } if (r <= 0) return PARSER_ERR_SYSTEM; left -= r; - data += r; + d += r; } *len = *len - left; @@ -113,16 +115,18 @@ parser_err_t binary_read(void *storage, void *data, unsigned int *len) { parser_err_t binary_write(void *storage, void *data, unsigned int len) { binary_t *st = storage; + unsigned char *d = data; + if (!st->write) return PARSER_ERR_RDONLY; ssize_t r; while(len > 0) { - r = write(st->fd, data, len); + r = write(st->fd, d, len); if (r < 1) return PARSER_ERR_SYSTEM; st->stat.st_size += r; len -= r; - data += r; + d += r; } return PARSER_ERR_OK; diff --git a/parsers/hex.c b/parsers/hex.c index 1c92ea4..8c4ba71 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -45,9 +45,9 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { return PARSER_ERR_RDONLY; } else { char mark; - int i, fd; + int fd; uint8_t checksum; - unsigned int c; + unsigned int c, i; uint32_t base = 0; unsigned int last_address = 0x0; From 4957909bdb12391d28f663468b9d5e77c6ab66ea Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 17 Oct 2017 15:14:44 +0200 Subject: [PATCH 123/134] Fix compile warning for unused parameters Compiling under Android fails for few parameter of functions not used in the function body. Fix it by adding a compiler specific include file and adding, currently for GCC only, an attribute macro to declare function parameters as "unused". Signed-off-by: Antonio Borneo --- compiler.h | 38 ++++++++++++++++++++++++++++++++++++++ i2c.c | 12 +++++++----- parsers/hex.c | 3 ++- 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 0000000..57e83ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + stm32flash - Open Source ST STM32 flash program for *nix + Copyright (C) 2017 Antonio Borneo + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef _H_COMPILER +#define _H_COMPILER + +#if defined(__GNUC__) +#undef __unused +#undef __maybe_unused +#define __unused __attribute__ ((unused)) +#define __maybe_unused __attribute__ ((unused)) +#endif + +#ifndef __unused +#define __unused +#endif + +#ifndef __maybe_unused +#define __maybe_unused +#endif + +#endif /* _H_COMPILER */ diff --git a/i2c.c b/i2c.c index 56a5393..bb99545 100644 --- a/i2c.c +++ b/i2c.c @@ -28,14 +28,15 @@ #include #include +#include "compiler.h" #include "serial.h" #include "port.h" #if !defined(__linux__) -static port_err_t i2c_open(struct port_interface *port, - struct port_options *ops) +static port_err_t i2c_open(struct port_interface __unused *port, + struct port_options __unused *ops) { return PORT_ERR_NODEV; } @@ -169,8 +170,9 @@ static port_err_t i2c_write(struct port_interface *port, void *buf, return PORT_ERR_OK; } -static port_err_t i2c_gpio(struct port_interface *port, serial_gpio_t n, - int level) +static port_err_t i2c_gpio(struct port_interface __unused *port, + serial_gpio_t __unused n, + int __unused level) { return PORT_ERR_OK; } @@ -194,7 +196,7 @@ static struct varlen_cmd i2c_cmd_get_reply[] = { { /* sentinel */ } }; -static port_err_t i2c_flush(struct port_interface *port) +static port_err_t i2c_flush(struct port_interface __unused *port) { /* We shouldn't need to flush I2C */ return PORT_ERR_OK; diff --git a/parsers/hex.c b/parsers/hex.c index 8c4ba71..86c9e27 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -27,6 +27,7 @@ #include #include "hex.h" +#include "../compiler.h" #include "../utils.h" typedef struct { @@ -213,7 +214,7 @@ parser_err_t hex_read(void *storage, void *data, unsigned int *len) { return PARSER_ERR_OK; } -parser_err_t hex_write(void *storage, void *data, unsigned int len) { +parser_err_t hex_write(void __unused *storage, void __unused *data, unsigned int __unused len) { return PARSER_ERR_RDONLY; } From 12f06e31f6819183e034d75e3bbcc634eff32d0a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 20 Oct 2017 14:36:37 +0200 Subject: [PATCH 124/134] Fix warning for unused parameters with mingw-gcc Compile with command make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar or make CC=i686-w64-mingw32-gcc AR=i686-w64-mingw32-ar Signed-off-by: Antonio Borneo --- init.c | 5 ++++- serial_w32.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/init.c b/init.c index 5f2d855..3177607 100644 --- a/init.c +++ b/init.c @@ -28,6 +28,8 @@ #include #include #include + +#include "compiler.h" #include "init.h" #include "serial.h" #include "stm32.h" @@ -156,7 +158,8 @@ static int release_gpio(int n, int input, int exported) return 1; } #else -static int drive_gpio(int n, int level, struct gpio_list **gpio_to_release) +static int drive_gpio(int __unused n, int __unused level, + struct gpio_list __unused **gpio_to_release) { fprintf(stderr, "GPIO control only available in Linux\n"); return 0; diff --git a/serial_w32.c b/serial_w32.c index b53a055..1662da1 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -27,6 +27,7 @@ #include #include +#include "compiler.h" #include "serial.h" #include "port.h" @@ -88,7 +89,7 @@ static serial_t *serial_open(const char *device) return h; } -static void serial_flush(const serial_t *h) +static void serial_flush(const serial_t __unused *h) { /* We shouldn't need to flush in non-overlapping (blocking) mode */ /* tcflush(h->fd, TCIFLUSH); */ From d302abfc9af3226ad7f31b0a97f0cd3bb0a14f81 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 20 Oct 2017 14:37:56 +0200 Subject: [PATCH 125/134] Add comment on switch fall-through New gcc check for switch fall-through. Adding the comment removes the warning and documents the fall-through case. Signed-off-by: Antonio Borneo --- parsers/hex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/parsers/hex.c b/parsers/hex.c index 86c9e27..b3eaddf 100644 --- a/parsers/hex.c +++ b/parsers/hex.c @@ -154,6 +154,7 @@ parser_err_t hex_open(void *storage, const char *filename, const char write) { /* address record */ case 4: base = base << 12; + /* fall-through */ case 2: base = base << 4; /* Reset last_address since our base changed */ last_address = 0; From 74bfe1abbe410d24613f51f6cf4101fb4f5bbcfe Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 20 Oct 2017 14:50:02 +0200 Subject: [PATCH 126/134] serial_w32: remove always false if-then Variable r is defined as DWORD in ReadFile API, so it is an unsigned value. Condition (r < 0) is always false and can be removed. Signed-off-by: Antonio Borneo --- serial_w32.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/serial_w32.c b/serial_w32.c index 1662da1..97f7f24 100644 --- a/serial_w32.c +++ b/serial_w32.c @@ -258,8 +258,6 @@ static port_err_t serial_w32_read(struct port_interface *port, void *buf, ReadFile(h->fd, pos, nbyte, &r, NULL); if (r == 0) return PORT_ERR_TIMEDOUT; - if (r < 0) - return PORT_ERR_UNKNOWN; nbyte -= r; pos += r; From ee5b009ae86a6fab29fb4bed7eecf7a0c90b0d56 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 20 Oct 2017 15:14:19 +0200 Subject: [PATCH 127/134] Fix comparison between signed and unsigned integer Change type to the signed variables, since they only assumes unsigned values. Signed-off-by: Antonio Borneo --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index f0d33ae..a45521c 100644 --- a/main.c +++ b/main.c @@ -498,8 +498,8 @@ int main(int argc, char* argv[]) { } else if (action == ACT_WRITE) { fprintf(diag, "Write to memory\n"); - off_t offset = 0; - ssize_t r; + unsigned int offset = 0; + unsigned int r; unsigned int size; unsigned int max_wlen, max_rlen; From 5ad1f87f741a0b75ff91f61f3282d06cfbfa4413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Fri, 16 Mar 2018 14:07:25 -0300 Subject: [PATCH 128/134] Makefile: Check if CC and AR are defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index e3a019e..81a5344 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ PREFIX = /usr/local CFLAGS += -Wall -g +ifndef CC + $(error CC is not defined) +endif + +ifndef AR + $(error AR is not defined) +endif + INSTALL = install OBJS = dev_table.o \ From 7f0647b7cafae19ff715e6b0ee2e3bc8092d2c48 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 9 Aug 2018 22:20:00 +0200 Subject: [PATCH 129/134] Create README.md --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6a90e4 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# stm32flash +Open source flash program for STM32 using the ST serial bootloader + +Forked from https://sourceforge.net/projects/stm32flash + +Since: +``` +Author: Patrick José Pereira 2018-03-16 18:07:25 +Committer: Tormod Volden 2018-04-17 00:18:23 +Follows: v0.5 +Precedes: + + Makefile: Check if CC and AR are defined + + Signed-off-by: Patrick José Pereira +``` From fa3b6697798d49857151f2b8ac751d8cf4625fb1 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 9 Aug 2018 22:21:41 +0200 Subject: [PATCH 130/134] Update LICENSE --- LICENSE | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. From 65b5ad15a4c6258f1c8d0d407dd88b9971761b3c Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Sat, 11 Aug 2018 16:00:34 +0200 Subject: [PATCH 131/134] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6a90e4..2c2b401 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Open source flash program for STM32 using the ST serial bootloader Forked from https://sourceforge.net/projects/stm32flash -Since: +Branch **[master](https://github.com/stm32duino/stm32flash/tree/master)** sync from: ``` Author: Patrick José Pereira 2018-03-16 18:07:25 Committer: Tormod Volden 2018-04-17 00:18:23 @@ -14,3 +14,7 @@ Precedes: Signed-off-by: Patrick José Pereira ``` + +Branch: **[Arduino_STM32](https://github.com/stm32duino/stm32flash/tree/Arduino_STM32)** +includes the stm32flash sources modified and provided by Roger Clark (@rogerclarkmelbourne) +with [rogerclarkmelbourne/Arduino_STM32](https://github.com/rogerclarkmelbourne/Arduino_STM32) From 3df2c7870fa3b3e52802efc94e950e06734d6b0e Mon Sep 17 00:00:00 2001 From: "Frederic.Pillon" Date: Mon, 13 Aug 2018 14:04:25 +0200 Subject: [PATCH 132/134] Update HOWTO Add tips to cross compile for linux 32 bits from linux 64 bits host Signed-off-by: Frederic.Pillon --- HOWTO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/HOWTO b/HOWTO index d8f32eb..4c466c7 100644 --- a/HOWTO +++ b/HOWTO @@ -33,3 +33,7 @@ Cross compile on Linux host for Windows target with MinGW: ===================================================================== I'm using a 64 bit Arch Linux machines, and I usually run: make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar + +Cross compile on Linux 64 bits host for linux 32 bits target: +===================================================================== + make CFLAGS=-m32 LDFLAGS=-m32 From d8c265f4b17861213cfb183a8fb656291215da97 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Thu, 20 Sep 2018 22:31:51 +0200 Subject: [PATCH 133/134] Changed printed message to indicate this is a version built for STM32duino Signed-off-by: Frederic Pillon --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index a45521c..b5a2b46 100644 --- a/main.c +++ b/main.c @@ -43,7 +43,7 @@ #include #endif -#define VERSION "0.5" +#define VERSION "STM32duino_0.5.1" /* device globals */ stm32_t *stm = NULL; @@ -243,7 +243,7 @@ int main(int argc, char* argv[]) { } fprintf(diag, "stm32flash " VERSION "\n\n"); - fprintf(diag, "http://stm32flash.sourceforge.net/\n\n"); + fprintf(diag, "https://github.com/stm32duino/stm32flash\n\n"); #if defined(__WIN32__) || defined(__CYGWIN__) SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ); From 8bc5ceb3d802c2c9b80453317825ef5ebd78009e Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Fri, 28 Jun 2019 11:15:23 +0200 Subject: [PATCH 134/134] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2c2b401..53541a4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# Since release [1.6.0](https://github.com/stm32duino/Arduino_Core_STM32/releases/tag/1.6.0) of the STM32 core, STM32CubeProgrammer is used to flash and replaced this tool. + # stm32flash Open source flash program for STM32 using the ST serial bootloader