kopia lustrzana https://github.com/stlink-org/stlink
Merge pull request #843 from daveystruijk/stm32f4-option-bytes
Allow reading/writing option bytes to STM32F446 devicespull/851/head
commit
290182654b
|
@ -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"
|
||||
|
|
88
src/common.c
88
src/common.c
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) &&
|
||||
|
|
Ładowanie…
Reference in New Issue