stm32l1/Cat.3: Devices have only one bank.
[openocd.git] / src / flash / nor / stm32lx.c
index 22830e60bc814687f46ddfb91c73b99a1591f3b4..11d853228440131bb2818ca6884810d307cb0543 100644 (file)
@@ -103,6 +103,8 @@ static int stm32lx_lock_program_memory(struct flash_bank *bank);
 static int stm32lx_enable_write_half_page(struct flash_bank *bank);
 static int stm32lx_erase_sector(struct flash_bank *bank, int sector);
 static int stm32lx_wait_until_bsy_clear(struct flash_bank *bank);
+static int stm32lx_lock(struct flash_bank *bank);
+static int stm32lx_unlock(struct flash_bank *bank);
 static int stm32lx_mass_erase(struct flash_bank *bank);
 static int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int timeout);
 
@@ -208,8 +210,7 @@ static const struct stm32lx_part_info stm32lx_parts[] = {
                .page_size                      = 256,
                .pages_per_sector       = 16,
                .max_flash_size_kb      = 256,
-               .first_bank_size_kb     = 192,
-               .has_dual_banks         = true,
+               .has_dual_banks         = false,
                .flash_base                     = 0x40023C00,
                .fsize_base                     = 0x1FF800CC,
        },
@@ -332,6 +333,46 @@ COMMAND_HANDLER(stm32lx_handle_mass_erase_command)
        return retval;
 }
 
+COMMAND_HANDLER(stm32lx_handle_lock_command)
+{
+       if (CMD_ARGC < 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank;
+       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       retval = stm32lx_lock(bank);
+
+       if (retval == ERROR_OK)
+               command_print(CMD_CTX, "STM32Lx locked, takes effect after power cycle.");
+       else
+               command_print(CMD_CTX, "STM32Lx lock failed");
+
+       return retval;
+}
+
+COMMAND_HANDLER(stm32lx_handle_unlock_command)
+{
+       if (CMD_ARGC < 1)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct flash_bank *bank;
+       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+       if (ERROR_OK != retval)
+               return retval;
+
+       retval = stm32lx_unlock(bank);
+
+       if (retval == ERROR_OK)
+               command_print(CMD_CTX, "STM32Lx unlocked, takes effect after power cycle.");
+       else
+               command_print(CMD_CTX, "STM32Lx unlock failed");
+
+       return retval;
+}
+
 static int stm32lx_protect_check(struct flash_bank *bank)
 {
        int retval;
@@ -945,6 +986,20 @@ static const struct command_registration stm32lx_exec_command_handlers[] = {
                .usage = "bank_id",
                .help = "Erase entire flash device. including available EEPROM",
        },
+       {
+               .name = "lock",
+               .handler = stm32lx_handle_lock_command,
+               .mode = COMMAND_EXEC,
+               .usage = "bank_id",
+               .help = "Increase the readout protection to Level 1.",
+       },
+       {
+               .name = "unlock",
+               .handler = stm32lx_handle_unlock_command,
+               .mode = COMMAND_EXEC,
+               .usage = "bank_id",
+               .help = "Lower the readout protection from Level 1 to 0.",
+       },
        COMMAND_REGISTRATION_DONE
 };
 
@@ -1278,33 +1333,37 @@ static int stm32lx_obl_launch(struct flash_bank *bank)
        return tries ? ERROR_OK : ERROR_FAIL;
 }
 
-static int stm32lx_mass_erase(struct flash_bank *bank)
+static int stm32lx_lock(struct flash_bank *bank)
 {
        int retval;
        struct target *target = bank->target;
-       struct stm32lx_flash_bank *stm32lx_info = NULL;
-       uint32_t reg32;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       stm32lx_info = bank->driver_priv;
-
        retval = stm32lx_unlock_options_bytes(bank);
        if (retval != ERROR_OK)
                return retval;
 
-       /* mass erase flash memory */
        /* set the RDP protection level to 1 */
        retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR1);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32lx_obl_launch(bank);
-       if (retval != ERROR_OK)
-               return retval;
+       return ERROR_OK;
+}
+
+static int stm32lx_unlock(struct flash_bank *bank)
+{
+       int retval;
+       struct target *target = bank->target;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
 
        retval = stm32lx_unlock_options_bytes(bank);
        if (retval != ERROR_OK)
@@ -1319,6 +1378,35 @@ static int stm32lx_mass_erase(struct flash_bank *bank)
        if (retval != ERROR_OK)
                return retval;
 
+       return ERROR_OK;
+}
+
+static int stm32lx_mass_erase(struct flash_bank *bank)
+{
+       int retval;
+       struct target *target = bank->target;
+       struct stm32lx_flash_bank *stm32lx_info = NULL;
+       uint32_t reg32;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       stm32lx_info = bank->driver_priv;
+
+       retval = stm32lx_lock(bank);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = stm32lx_obl_launch(bank);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = stm32lx_unlock(bank);
+       if (retval != ERROR_OK)
+               return retval;
+
        retval = stm32lx_obl_launch(bank);
        if (retval != ERROR_OK)
                return retval;

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)