Skip to content

Commit

Permalink
Merge pull request #843 from daveystruijk/stm32f4-option-bytes
Browse files Browse the repository at this point in the history
Allow reading/writing option bytes to STM32F446 devices
  • Loading branch information
texane committed Oct 28, 2019
2 parents 393e942 + 0948cd1 commit 2901826
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/stlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ typedef struct flash_loader {
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);
int stlink_read_option_bytes_f4(stlink_t *sl, uint32_t* option_byte);

#include "stlink/sg.h"
#include "stlink/usb.h"
Expand Down
88 changes: 87 additions & 1 deletion src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@
#define FLASH_F4_SR (FLASH_F4_REGS_ADDR + 0x0c)
#define FLASH_F4_CR (FLASH_F4_REGS_ADDR + 0x10)
#define FLASH_F4_OPT_CR (FLASH_F4_REGS_ADDR + 0x14)
#define FLASH_F4_OPT_LOCK_BIT (1u << 0)
#define FLASH_F4_CR_STRT 16
#define FLASH_F4_CR_LOCK 31
#define FLASH_F4_CR_SER 1
Expand Down Expand Up @@ -2711,6 +2712,56 @@ static int stlink_write_option_bytes_f2(stlink_t *sl, uint32_t option_byte) {
return 0;
}

/**
* Write option bytes
* @param sl
* @param option_byte value to write
* @return 0 on success, -ve on failure.
*/
static int stlink_write_option_bytes_f4(stlink_t *sl, uint32_t option_byte) {
uint32_t val;

stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
if (val & FLASH_F4_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_F4_OPT_KEYR, 0x08192A3B);
stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F);

stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
if (val & FLASH_F4_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_F4_OPT_CR, &val);
WLOG("option bytes CR = %x\n",val);

stlink_write_debug32(sl, FLASH_F4_OPT_CR, option_byte & 0x0FFFFFFC);

stlink_write_debug32(sl, FLASH_F4_OPT_CR, (option_byte & 0x0FFFFFFC)|0x00000002);


stlink_read_debug32(sl, FLASH_F4_SR, &val);
WLOG("wait BSY flag to be 0\n");

while(val & 0x00010000){
stlink_read_debug32(sl, FLASH_F4_SR, &val);
}
WLOG("BSY flag is 0\n");

stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
WLOG("option bytes CR = %x\n",val);
WLOG("Option flash re-lock\n");
stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001);

DLOG("STM32 F4 option bytes are written\n");

return 0;
}

/**
* Read option bytes
* @param sl
Expand Down Expand Up @@ -2744,6 +2795,39 @@ int stlink_read_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_f4(stlink_t *sl, uint32_t* option_byte) {
uint32_t val;

stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
if (val & FLASH_F4_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_F4_OPT_KEYR, 0x08192A3B);
stlink_write_debug32(sl, FLASH_F4_OPT_KEYR, 0x4C5D6E7F);

stlink_read_debug32(sl, FLASH_F4_OPT_CR, &val);
if (val & FLASH_F4_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_F4_OPT_CR, option_byte);
WLOG("option bytes CR = %x\n",option_byte);

WLOG("Option flash re-lock\n");
stlink_write_debug32(sl, FLASH_F4_OPT_CR, val | 0x00000001);

return 0;
}

/**
* Write option bytes
* @param sl
Expand Down Expand Up @@ -2803,10 +2887,12 @@ int stlink_fwrite_option_bytes_32bit(stlink_t *sl, uint32_t val) {

if(sl->chip_id == STLINK_CHIPID_STM32_F2){
return stlink_write_option_bytes_f2(sl, val);
}else if(sl->chip_id == STLINK_CHIPID_STM32_F446){
return stlink_write_option_bytes_f4(sl, val);
}
else
{
ELOG("Option bytes writing is currently only supported for the STM32F2, STM32G0 and STM32L0\n");
ELOG("Option bytes writing is currently only supported for the STM32F2, STM32F4, STM32G0 and STM32L0\n");
return -1;
}
}
6 changes: 5 additions & 1 deletion src/tools/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,12 @@ int main(int ac, char** av)
uint32_t option_byte = 0;
err = stlink_read_option_bytes_f2(sl,&option_byte);
printf("%x\n",option_byte);
}else if(sl->chip_id == STLINK_CHIPID_STM32_F446){
uint32_t option_byte = 0;
err = stlink_read_option_bytes_f4(sl,&option_byte);
printf("%x\n",option_byte);
}else{
printf("This format is available for STM32F2 Only\n");
printf("This format is available for STM32F2 and STM32F4 Only\n");
}
}else{
if ((o.addr >= sl->flash_base) && (o.size == 0) &&
Expand Down

0 comments on commit 2901826

Please sign in to comment.