This is an automated email from Gerrit.

Thomas Søhus (t...@ceepro.dk) just uploaded a new patch set to Gerrit, which 
you can find at http://openocd.zylin.com/4654

-- gerrit

commit 1f88add583a2171eb41dfe15313e5c6fb3045446
Author: Thomas Søhus <t...@ceepro.dk>
Date:   Thu Aug 16 14:04:45 2018 +0200

    Added support for STM32L4X option bytes writing.
    
    Enables the programming of Write protection lock bits.
    
    Change-Id: I86358c7eb1285c3c0baac1564e46da8ced5fd025
    Signed-off-by: Thomas Søhus <t...@ceepro.dk>

diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 4fb7e03..0e931e6 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -57,8 +57,8 @@
 #define STM32_FLASH_CR      0x40022014
 #define STM32_FLASH_OPTR    0x40022020
 #define STM32_FLASH_WRP1AR  0x4002202c
-#define STM32_FLASH_WRP2AR  0x40022030
-#define STM32_FLASH_WRP1BR  0x4002204c
+#define STM32_FLASH_WRP1BR  0x40022030
+#define STM32_FLASH_WRP2AR  0x4002204c
 #define STM32_FLASH_WRP2BR  0x40022050
 
 /* FLASH_CR register bits */
@@ -70,8 +70,10 @@
 #define FLASH_CR_BKER  (1 << 11)
 #define FLASH_MER2     (1 << 15)
 #define FLASH_STRT     (1 << 16)
+#define FLASH_OPTSTRT  (1 << 17)
 #define FLASH_EOPIE    (1 << 24)
 #define FLASH_ERRIE    (1 << 25)
+#define FLASH_OBLLAUNCH (1 << 27)
 #define FLASH_OPTLOCK  (1 << 30)
 #define FLASH_LOCK     (1 << 31)
 
@@ -110,7 +112,7 @@
 struct stm32l4_options {
        uint8_t RDP;
        uint16_t bank_b_start;
-       uint8_t user_options;
+       uint32_t user_options;
        uint8_t wpr1a_start;
        uint8_t wpr1a_end;
        uint8_t wpr1b_start;
@@ -278,30 +280,34 @@ static int stm32l4_read_options(struct flash_bank *bank)
        if (retval != ERROR_OK)
                return retval;
 
-       stm32l4_info->option_bytes.user_options = (optiondata >> 8) & 0x3ffff;
+       stm32l4_info->option_bytes.user_options = (optiondata >> 8) & 0xffffff;
        stm32l4_info->option_bytes.RDP = optiondata & 0xff;
 
        retval = target_read_u32(target, STM32_FLASH_WRP1AR, &optiondata);
        if (retval != ERROR_OK)
                return retval;
+
        stm32l4_info->option_bytes.wpr1a_start =  optiondata         & 0xff;
        stm32l4_info->option_bytes.wpr1a_end   = (optiondata >> 16)  & 0xff;
 
-       retval = target_read_u32(target, STM32_FLASH_WRP2AR, &optiondata);
-       if (retval != ERROR_OK)
-               return retval;
-       stm32l4_info->option_bytes.wpr2a_start =  optiondata         & 0xff;
-       stm32l4_info->option_bytes.wpr2a_end   = (optiondata >> 16)  & 0xff;
-
        retval = target_read_u32(target, STM32_FLASH_WRP1BR, &optiondata);
        if (retval != ERROR_OK)
                return retval;
+
        stm32l4_info->option_bytes.wpr1b_start =  optiondata         & 0xff;
        stm32l4_info->option_bytes.wpr1b_end   = (optiondata >> 16)  & 0xff;
 
+       retval = target_read_u32(target, STM32_FLASH_WRP2AR, &optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       stm32l4_info->option_bytes.wpr2a_start =  optiondata         & 0xff;
+       stm32l4_info->option_bytes.wpr2a_end   = (optiondata >> 16)  & 0xff;
+
        retval = target_read_u32(target, STM32_FLASH_WRP2BR, &optiondata);
        if (retval != ERROR_OK)
                return retval;
+
        stm32l4_info->option_bytes.wpr2b_start =  optiondata         & 0xff;
        stm32l4_info->option_bytes.wpr2b_end   = (optiondata >> 16)  & 0xff;
 
@@ -319,13 +325,53 @@ static int stm32l4_write_options(struct flash_bank *bank)
 
        stm32l4_info = bank->driver_priv;
 
-       (void) optiondata;
-       (void) stm32l4_info;
+       int retval = stm32l4_unlock_reg(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = stm32l4_unlock_option_reg(target);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = (stm32l4_info->option_bytes.user_options << 8) | 
stm32l4_info->option_bytes.RDP;
+       retval = target_write_u32(target, STM32_FLASH_OPTR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
 
-       int retval = stm32l4_unlock_option_reg(target);
+       optiondata = (stm32l4_info->option_bytes.wpr1a_end << 16) | 
stm32l4_info->option_bytes.wpr1a_start;
+       retval = target_write_u32(target, STM32_FLASH_WRP1AR, optiondata);
        if (retval != ERROR_OK)
                return retval;
-       /* FIXME: Implement Option writing!*/
+
+       optiondata = (stm32l4_info->option_bytes.wpr1b_end << 16) | 
stm32l4_info->option_bytes.wpr1b_start;
+       retval = target_write_u32(target, STM32_FLASH_WRP1BR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = (stm32l4_info->option_bytes.wpr2a_end << 16) | 
stm32l4_info->option_bytes.wpr2a_start;
+       retval = target_write_u32(target, STM32_FLASH_WRP2AR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = (stm32l4_info->option_bytes.wpr2b_end << 16) | 
stm32l4_info->option_bytes.wpr2b_start;
+       retval = target_write_u32(target, STM32_FLASH_WRP2BR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, stm32l4_get_flash_reg(bank, 
STM32_FLASH_CR), FLASH_OPTSTRT);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_u32(target, stm32l4_get_flash_reg(bank, 
STM32_FLASH_CR), FLASH_OBLLAUNCH);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_INFO("Wrote option bytes");
+
        return ERROR_OK;
 }
 
@@ -441,8 +487,14 @@ static int stm32l4_protect(struct flash_bank *bank, int 
set, int first, int last
                return retval;
        }
 
-       (void)stm32l4_info;
-       /* FIXME: Write First and last in a valid WRPxx_start/end combo*/
+       if (set == 1) {
+               stm32l4_info->option_bytes.wpr1a_start = first & 0xff;
+               stm32l4_info->option_bytes.wpr1a_end   = last & 0xff;
+       } else {
+               stm32l4_info->option_bytes.wpr1a_start = 0xff;
+               stm32l4_info->option_bytes.wpr1a_end   = 0x00;
+       }
+
        retval = stm32l4_write_options(bank);
        if (retval != ERROR_OK)
                return retval;
@@ -774,15 +826,18 @@ COMMAND_HANDLER(stm32l4_handle_lock_command)
                return ERROR_OK;
        }
 
-       /* set readout protection */
-       stm32l4_info->option_bytes.RDP = 0;
+       /* set write protection */
+       stm32l4_info->option_bytes.wpr1a_start = 0x00;
+       stm32l4_info->option_bytes.wpr1a_end = 0xff;
 
        if (stm32l4_write_options(bank) != ERROR_OK) {
                command_print(CMD_CTX, "%s failed to lock device", 
bank->driver->name);
                return ERROR_OK;
        }
 
-       command_print(CMD_CTX, "%s locked", bank->driver->name);
+       command_print(CMD_CTX, "%s locked.\n"
+                       "INFO: a reset or power cycle is required "
+                       "for the new settings to take effect.", 
bank->driver->name);
 
        return ERROR_OK;
 }
@@ -813,9 +868,11 @@ COMMAND_HANDLER(stm32l4_handle_unlock_command)
                return ERROR_OK;
        }
 
-       /* clear readout protection and complementary option bytes
+       /* clear read and write protection and complementary option bytes
         * this will also force a device unlock if set */
        stm32l4_info->option_bytes.RDP = 0xAA;
+       stm32l4_info->option_bytes.wpr1a_start = 0xff;
+       stm32l4_info->option_bytes.wpr1a_end = 0x00;
 
        if (stm32l4_write_options(bank) != ERROR_OK) {
                command_print(CMD_CTX, "%s failed to unlock device",

-- 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to