stm32: update option bytes for stm32xl family
authorSpencer Oliver <ntfreak@users.sourceforge.net>
Thu, 23 Dec 2010 12:04:53 +0000 (12:04 +0000)
committerSpencer Oliver <ntfreak@users.sourceforge.net>
Thu, 23 Dec 2010 12:11:16 +0000 (12:11 +0000)
add supoort for xl family boot bank option.
The option byte handling will be cleaned up in a later patch.

Signed-off-by: Spencer Oliver <ntfreak@users.sourceforge.net>
src/flash/nor/stm32x.c

index 6393aa40f426c4ec55276f8eb2190a9ccb30d8b5..70624b2e512e0de576c602ae85ebe74930673c38 100644 (file)
 #define OPT_RDWDGSW            2
 #define OPT_RDRSTSTOP  3
 #define OPT_RDRSTSTDBY 4
+#define OPT_BFB2               5       /* dual flash bank only */
 
 /* register unlock keys */
 
 #define KEY1                   0x45670123
 #define KEY2                   0xCDEF89AB
 
+/* we use an offset to access the second bank on dual flash devices
+ * strangely the protection of the second bank is done on the bank0 reg's */
+
+#define FLASH_OFFSET_B0        0x00
+#define FLASH_OFFSET_B1 0x40
+
 struct stm32x_options
 {
        uint16_t RDP;
@@ -96,9 +103,10 @@ struct stm32x_flash_bank
        int ppage_size;
        int probed;
 
+       bool has_dual_banks;
        /* used to access dual flash bank stm32xl
-        * 0x00 will address sector 0 flash
-        * 0x40 will address sector 1 flash */
+        * 0x00 will address bank 0 flash
+        * 0x40 will address bank 1 flash */
        int register_offset;
 };
 
@@ -121,7 +129,8 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
 
        stm32x_info->write_algorithm = NULL;
        stm32x_info->probed = 0;
-       stm32x_info->register_offset = 0x00;
+       stm32x_info->has_dual_banks = false;
+       stm32x_info->register_offset = FLASH_OFFSET_B0;
 
        return ERROR_OK;
 }
@@ -185,6 +194,21 @@ static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)
        return retval;
 }
 
+int stm32x_check_operation_supported(struct flash_bank *bank)
+{
+       struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
+
+       /* if we have a dual flash bank device then
+        * we need to perform option byte stuff on bank0 only */
+       if (stm32x_info->register_offset != FLASH_OFFSET_B0)
+       {
+               LOG_ERROR("Option Byte Operation's must use bank0");
+               return ERROR_FLASH_OPERATION_FAILED;
+       }
+
+       return ERROR_OK;
+}
+
 static int stm32x_read_options(struct flash_bank *bank)
 {
        uint32_t optiondata;
@@ -368,9 +392,13 @@ static int stm32x_protect_check(struct flash_bank *bank)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       int retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        /* medium density - each bit refers to a 4bank protection
         * high density - each bit refers to a 2bank protection */
-       int retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
+       retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
        if (retval != ERROR_OK)
                return retval;
 
@@ -495,6 +523,10 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       int retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        if ((first % stm32x_info->ppage_size) != 0)
        {
                LOG_WARNING("aligned start protect sector to a %d sector boundary",
@@ -512,7 +544,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
 
        /* medium density - each bit refers to a 4bank protection
         * high density - each bit refers to a 2bank protection */
-       int retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
+       retval = target_read_u32(target, STM32_FLASH_WRPR, &protection);
        if (retval != ERROR_OK)
                return retval;
 
@@ -813,7 +845,7 @@ static int stm32x_probe(struct flash_bank *bank)
        int page_size;
 
        stm32x_info->probed = 0;
-       stm32x_info->register_offset = 0x00;
+       stm32x_info->register_offset = FLASH_OFFSET_B0;
 
        /* read stm32 device id register */
        int retval = target_read_u32(target, 0xE0042000, &device_id);
@@ -911,6 +943,7 @@ static int stm32x_probe(struct flash_bank *bank)
                 * 2 pages for a protection area */
                page_size = 2048;
                stm32x_info->ppage_size = 2;
+               stm32x_info->has_dual_banks = true;
 
                /* check for early silicon */
                if (num_pages == 0xffff)
@@ -930,7 +963,7 @@ static int stm32x_probe(struct flash_bank *bank)
                {
                        num_pages -= 512;
                        /* bank1 also uses a register offset */
-                       stm32x_info->register_offset = 0x40;
+                       stm32x_info->register_offset = FLASH_OFFSET_B1;
                }
        }
        else
@@ -1154,6 +1187,10 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (stm32x_erase_options(bank) != ERROR_OK)
        {
                command_print(CMD_CTX, "stm32x failed to erase options");
@@ -1200,6 +1237,10 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        if (stm32x_erase_options(bank) != ERROR_OK)
        {
                command_print(CMD_CTX, "stm32x failed to unlock device");
@@ -1246,6 +1287,10 @@ COMMAND_HANDLER(stm32x_handle_options_read_command)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        retval = target_read_u32(target, STM32_FLASH_OBR, &optionbyte);
        if (retval != ERROR_OK)
                return retval;
@@ -1274,6 +1319,14 @@ COMMAND_HANDLER(stm32x_handle_options_read_command)
        else
                command_print(CMD_CTX, "Standby: Reset generated");
 
+       if (stm32x_info->has_dual_banks)
+       {
+               if (buf_get_u32((uint8_t*)&optionbyte, OPT_BFB2, 1))
+                       command_print(CMD_CTX, "Boot: Bank 0");
+               else
+                       command_print(CMD_CTX, "Boot: Bank 1");
+       }
+
        return ERROR_OK;
 }
 
@@ -1285,7 +1338,8 @@ COMMAND_HANDLER(stm32x_handle_options_write_command)
 
        if (CMD_ARGC < 4)
        {
-               command_print(CMD_CTX, "stm32x options_write <bank> <SWWDG | HWWDG> <RSTSTNDBY | NORSTSTNDBY> <RSTSTOP | NORSTSTOP>");
+               command_print(CMD_CTX, "stm32x options_write <bank> <SWWDG | HWWDG> "
+                               "<RSTSTNDBY | NORSTSTNDBY> <RSTSTOP | NORSTSTOP> <BOOT0 | BOOT1>");
                return ERROR_OK;
        }
 
@@ -1304,6 +1358,10 @@ COMMAND_HANDLER(stm32x_handle_options_write_command)
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       retval = stm32x_check_operation_supported(bank);
+       if (ERROR_OK != retval)
+               return retval;
+
        /* REVISIT: ignores some options which we will display...
         * and doesn't insist on the specified syntax.
         */
@@ -1338,6 +1396,19 @@ COMMAND_HANDLER(stm32x_handle_options_write_command)
                optionbyte &= ~(1 << 2);
        }
 
+       if (CMD_ARGC > 4 && stm32x_info->has_dual_banks)
+       {
+               /* OPT_BFB2 */
+               if (strcmp(CMD_ARGV[4], "BOOT0") == 0)
+               {
+                       optionbyte |= (1 << 3);
+               }
+               else
+               {
+                       optionbyte &= ~(1 << 3);
+               }
+       }
+
        if (stm32x_erase_options(bank) != ERROR_OK)
        {
                command_print(CMD_CTX, "stm32x failed to erase options");

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)