stm32f1: Fix handling of option byte write. Write needs to happend on erased option bytes.
This commit is contained in:
parent
15e529a43a
commit
086f3565f0
|
@ -324,10 +324,12 @@ static bool stm32f1_option_erase(target *t)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value)
|
static bool stm32f1_option_write_erased(target *t, uint32_t addr, uint16_t value)
|
||||||
{
|
{
|
||||||
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||||
|
|
||||||
|
if (value == 0xffff)
|
||||||
|
return true;
|
||||||
/* Erase option bytes instruction */
|
/* Erase option bytes instruction */
|
||||||
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_OPTPG | FLASH_CR_OPTWRE);
|
adiv5_ap_mem_write(ap, FLASH_CR, FLASH_CR_OPTPG | FLASH_CR_OPTWRE);
|
||||||
adiv5_ap_mem_write_halfword(ap, addr, value);
|
adiv5_ap_mem_write_halfword(ap, addr, value);
|
||||||
|
@ -338,6 +340,36 @@ static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool stm32f1_option_write(target *t, uint32_t addr, uint16_t value)
|
||||||
|
{
|
||||||
|
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||||
|
uint16_t opt_val[8];
|
||||||
|
int i, index;
|
||||||
|
|
||||||
|
index = (addr - FLASH_OBP_RDP) / 2;
|
||||||
|
if ((index < 0) || (index > 7))
|
||||||
|
return false;
|
||||||
|
/* Retrieve old values */
|
||||||
|
for (i = 0; i < 16; i = i +4) {
|
||||||
|
uint32_t val = adiv5_ap_mem_read(ap, FLASH_OBP_RDP + i);
|
||||||
|
opt_val[i/2] = val & 0xffff;
|
||||||
|
opt_val[i/2 +1] = val >> 16;
|
||||||
|
}
|
||||||
|
if (opt_val[index] == value)
|
||||||
|
return true;
|
||||||
|
/* Check for erased value */
|
||||||
|
if (opt_val[index] != 0xffff)
|
||||||
|
if (!(stm32f1_option_erase(t)))
|
||||||
|
return false;
|
||||||
|
opt_val[index] = value;
|
||||||
|
/* Write changed values*/
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
if (!(stm32f1_option_write_erased
|
||||||
|
(t, FLASH_OBP_RDP + i*2,opt_val[i])))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
|
static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint32_t addr, val;
|
uint32_t addr, val;
|
||||||
|
@ -353,14 +385,14 @@ static bool stm32f1_cmd_option(target *t, int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
default: flash_obp_rdp_key = FLASH_OBP_RDP_KEY;
|
default: flash_obp_rdp_key = FLASH_OBP_RDP_KEY;
|
||||||
}
|
}
|
||||||
rdprt = (adiv5_ap_mem_read(ap, FLASH_OBR) & FLASH_OBR_RDPRT);
|
rdprt = (adiv5_ap_mem_read(ap, FLASH_OBR) & FLASH_OBR_RDPRT);
|
||||||
stm32f1_flash_unlock(ap);
|
stm32f1_flash_unlock(ap);
|
||||||
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY1);
|
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY1);
|
||||||
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY2);
|
adiv5_ap_mem_write(ap, FLASH_OPTKEYR, KEY2);
|
||||||
|
|
||||||
if ((argc == 2) && !strcmp(argv[1], "erase")) {
|
if ((argc == 2) && !strcmp(argv[1], "erase")) {
|
||||||
stm32f1_option_erase(t);
|
stm32f1_option_erase(t);
|
||||||
stm32f1_option_write(t, FLASH_OBP_RDP, flash_obp_rdp_key);
|
stm32f1_option_write_erased(t, FLASH_OBP_RDP, flash_obp_rdp_key);
|
||||||
} else if (rdprt) {
|
} else if (rdprt) {
|
||||||
gdb_out("Device is Read Protected\n");
|
gdb_out("Device is Read Protected\n");
|
||||||
gdb_out("Use \"monitor option erase\" to unprotect, erasing device\n");
|
gdb_out("Use \"monitor option erase\" to unprotect, erasing device\n");
|
||||||
|
|
Loading…
Reference in New Issue