diff --git a/include/stlink.h b/include/stlink.h index 50f86c1..0715166 100644 --- a/include/stlink.h +++ b/include/stlink.h @@ -222,6 +222,7 @@ typedef struct flash_loader { int write_loader_to_sram(stlink_t *sl, stm32_addr_t* addr, size_t* size); int stlink_fread(stlink_t* sl, const char* path, bool is_ihex, stm32_addr_t addr, size_t size); int stlink_load_device_params(stlink_t *sl); + int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte); #include "stlink/sg.h" #include "stlink/usb.h" diff --git a/src/common.c b/src/common.c index bf1aba6..207be3d 100644 --- a/src/common.c +++ b/src/common.c @@ -2709,6 +2709,39 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) { return 0; } +/** + * Read option bytes + * @param sl + * @param option_byte value to write + * @return 0 on success, -ve on failure. + */ +int stlink_read_option_bytes_f2(stlink_t *sl, uint32_t* option_byte) { + uint32_t val; + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + WLOG("Unlocking option flash\n"); + //Unlock the FLASH_OPT_CR register (FLASH Programming manual page 15) + //https://www.st.com/resource/en/programming_manual/cd00233952.pdf + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x08192A3B); + stlink_write_debug32(sl, FLASH_F2_OPT_KEYR, 0x4C5D6E7F); + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, &val); + if (val & FLASH_F2_OPT_LOCK_BIT) { + ELOG("Option flash unlock failed! System reset required to be able to unlock it again!\n"); + return -1; + } + } + + stlink_read_debug32(sl, FLASH_F2_OPT_CR, option_byte); + WLOG("option bytes CR = %x\n",option_byte); + + WLOG("Option flash re-lock\n"); + stlink_write_debug32(sl, FLASH_F2_OPT_CR, val | 0x00000001); + + return 0; +} + /** * Write option bytes * @param sl diff --git a/src/tools/flash.c b/src/tools/flash.c index 91fa1c6..8bdddc5 100644 --- a/src/tools/flash.c +++ b/src/tools/flash.c @@ -39,6 +39,7 @@ static void usage(void) puts(" Format may be 'binary' (default) or 'ihex', although must be specified for binary format only."); puts(" ./st-flash [--version]"); puts("example write option byte: ./st-flash --debug --reset --area=option write 0xXXXXXXXX"); + puts("example read option byte: ./st-flash --debug --reset --area=option read > option_byte"); } int main(int ac, char** av) @@ -208,13 +209,25 @@ int main(int ac, char** av) } else /* read */ { - if ((o.addr >= sl->flash_base) && (o.size == 0) && - (o.addr < sl->flash_base + sl->flash_size)) + if(o.area == FLASH_OPTION_BYTES){ + if(sl->chip_id == STLINK_CHIPID_STM32_F2){ + uint32_t option_byte = 0; + err = stlink_read_option_bytes_f2(sl,&option_byte); + printf("%x\n",option_byte); + }else{ + printf("This format is available for STM32F2 Only\n"); + } + } + else if ((o.addr >= sl->flash_base) && (o.size == 0) && + (o.addr < sl->flash_base + sl->flash_size)){ o.size = sl->flash_size; + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + } else if ((o.addr >= sl->sram_base) && (o.size == 0) && - (o.addr < sl->sram_base + sl->sram_size)) + (o.addr < sl->sram_base + sl->sram_size)){ o.size = sl->sram_size; - err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + err = stlink_fread(sl, o.filename, o.format == FLASH_FORMAT_IHEX, o.addr, o.size); + } if (err == -1) { printf("stlink_fread() == -1\n"); diff --git a/src/tools/flash_opts.c b/src/tools/flash_opts.c index ab066de..3f74ac0 100644 --- a/src/tools/flash_opts.c +++ b/src/tools/flash_opts.c @@ -172,6 +172,7 @@ int flash_get_opts(struct flash_opts* o, int ac, char** av) break; case FLASH_CMD_READ: // expect filename, addr and size + if((o->area == FLASH_OPTION_BYTES) &&(ac == 0)) break; if (ac != 3) return -1; o->filename = av[0];