To achieve that we need to avoid using FLASH_REG_BASE_B0, and use
bank registers instead:
For dual bank devices, each option register is mapped in 2 addresses
at the same offset from flash_bank_reg_base.
This is true for OPTCR, OPTKEYR, OPTSR_CUR/PRG, OPTCCR according to
RM0433 Rev6 (refer to section 3.9: FLASH registers)
In stm32x_write_options, according to RM0433 Rev6, after OBL launch we
should wait for OPTSR_CUR.BSY bit instead of FLASH_SR.QW
Change-Id: Ie24a91f069d03c9233797390fc2e925c737dad90
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: http://openocd.zylin.com/5291
Tested-by: jenkins
Reviewed-by: Christopher Head <chead@zaber.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
#define OPT_LOCK (1 << 0)
#define OPT_START (1 << 1)
#define OPT_LOCK (1 << 0)
#define OPT_START (1 << 1)
+/* FLASH_OPTSR register bits */
+#define OPT_BSY (1 << 0)
+
/* register unlock keys */
#define KEY1 0x45670123
#define KEY2 0xCDEF89AB
/* register unlock keys */
#define KEY1 0x45670123
#define KEY2 0xCDEF89AB
uint32_t ctrl;
struct target *target = bank->target;
uint32_t ctrl;
struct target *target = bank->target;
- int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl);
+ int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
return ERROR_OK;
/* unlock option registers */
return ERROR_OK;
/* unlock option registers */
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY1);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY1);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY2);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY2);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
- retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl);
+ retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
struct target *target = bank->target;
/* read current option bytes */
struct target *target = bank->target;
/* read current option bytes */
- int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_CUR, &optiondata);
+ int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &optiondata);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24;
/* program options */
optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24;
/* program options */
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_PRG, optiondata);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_PRG), optiondata);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
optiondata = 0x40000000;
/* Remove OPT error flag before programming */
optiondata = 0x40000000;
/* Remove OPT error flag before programming */
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCCR, optiondata);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCCR), optiondata);
if (retval != ERROR_OK)
return retval;
/* start programming cycle */
if (retval != ERROR_OK)
return retval;
/* start programming cycle */
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_START);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_START);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
int timeout = FLASH_ERASE_TIMEOUT;
for (;;) {
uint32_t status;
int timeout = FLASH_ERASE_TIMEOUT;
for (;;) {
uint32_t status;
- retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_SR, &status);
+ retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &status);
if (retval != ERROR_OK) {
if (retval != ERROR_OK) {
- LOG_INFO("stm32x_write_options: wait_flash_op_queue : error");
+ LOG_INFO("stm32x_write_options: failed to read FLASH_OPTSR_CUR");
- if ((status & FLASH_QW) == 0)
+ if ((status & OPT_BSY) == 0)
break;
if (timeout-- <= 0) {
break;
if (timeout-- <= 0) {
- LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status);
+ LOG_INFO("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status);
return ERROR_FAIL;
}
alive_sleep(1);
}
/* relock option registers */
return ERROR_FAIL;
}
alive_sleep(1);
}
/* relock option registers */
- retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_LOCK);
+ retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_LOCK);
if (retval != ERROR_OK)
return retval;
if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
target = bank->target;
stm32x_info = bank->driver_priv;
target = bank->target;
- /* if we have a dual flash bank device then
- * we need to perform option byte lock on bank0 only */
- if (stm32x_info->flash_base != FLASH_REG_BASE_B0) {
- LOG_ERROR("Option Byte Lock Operation must use bank0");
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
bank->driver->name);
return ERROR_OK;
}
bank->driver->name);
return ERROR_OK;
}
+
+ LOG_WARNING("locking the entire flash device");
+
/* set readout protection */
stm32x_info->option_bytes.RDP = 0;
/* set readout protection */
stm32x_info->option_bytes.RDP = 0;
stm32x_info = bank->driver_priv;
target = bank->target;
stm32x_info = bank->driver_priv;
target = bank->target;
- /* if we have a dual flash bank device then
- * we need to perform option byte unlock on bank0 only */
- if (stm32x_info->flash_base != FLASH_REG_BASE_B0) {
- LOG_ERROR("Option Byte Unlock Operation must use bank0");
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
+ LOG_WARNING("unlocking the entire flash device");
+
/* clear readout protection option byte
* this will also force a device unlock if set */
stm32x_info->option_bytes.RDP = 0xAA;
/* clear readout protection option byte
* this will also force a device unlock if set */
stm32x_info->option_bytes.RDP = 0xAA;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)