This is an automated email from Gerrit.

Alex Lennon ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/4642

-- gerrit

commit 6f70e5152adbce23952d2c07086d85c1ad2a501f
Author: Alex J Lennon <[email protected]>
Date:   Tue Aug 7 11:14:58 2018 +0100

    flash/nor/stm32l4x: implement locking and unlocking
    
    This enables us to lock to STM32L4 level 1.
    An unlock causes a mass erase
    
    Change-Id: Iebf26f7095786998d887a53ce884abb3bef25472
    Signed-off-by: Alex J Lennon <[email protected]>

diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 4fb7e03..f452bc6 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -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;
@@ -284,24 +286,28 @@ static int stm32l4_read_options(struct flash_bank *bank)
        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_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;
 
@@ -322,10 +328,58 @@ static int stm32l4_write_options(struct flash_bank *bank)
        (void) optiondata;
        (void) stm32l4_info;
 
+       stm32l4_unlock_reg(target);
+
        int retval = stm32l4_unlock_option_reg(target);
        if (retval != ERROR_OK)
                return retval;
-       /* FIXME: Implement Option writing!*/
+
+       optiondata = (((uint32_t)stm32l4_info->option_bytes.user_options) << 8);
+       optiondata += ((uint32_t)stm32l4_info->option_bytes.RDP);
+
+       retval = target_write_u32(target, STM32_FLASH_OPTR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = ((uint32_t)stm32l4_info->option_bytes.wpr1a_end << 16);
+       optiondata += ((uint32_t)stm32l4_info->option_bytes.wpr1a_start);
+       retval = target_write_u32(target, STM32_FLASH_WRP1AR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = ((uint32_t)stm32l4_info->option_bytes.wpr2a_end << 16);
+       optiondata += ((uint32_t)stm32l4_info->option_bytes.wpr2a_start);
+       retval = target_write_u32(target, STM32_FLASH_WRP2AR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = ((uint32_t)stm32l4_info->option_bytes.wpr1b_end << 16);
+       optiondata += ((uint32_t)stm32l4_info->option_bytes.wpr1b_start);
+       retval = target_write_u32(target, STM32_FLASH_WRP1BR, optiondata);
+       if (retval != ERROR_OK)
+               return retval;
+
+       optiondata = ((uint32_t)stm32l4_info->option_bytes.wpr2b_end << 16);
+       optiondata += ((uint32_t)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;
+
+       /* Force reset to reload options registers */
+       retval = target_write_u32(target,
+                       stm32l4_get_flash_reg(bank, STM32_FLASH_CR), 
FLASH_OBLLAUNCH);
+       if (retval != ERROR_OK)
+               return retval;
+
        return ERROR_OK;
 }
 
@@ -649,10 +703,10 @@ static int stm32l4_probe(struct flash_bank *bank)
                return retval;
 
        /* only devices with < 1024 kiB may be set to single bank dual banks */
-       if ((flash_size_in_kb == 1024) || !(options & OPT_DUALBANK))
+       if ((flash_size_in_kb == 1024) || !(options & (1<<OPT_DUALBANK)))
                stm32l4_info->option_bytes.bank_b_start = 256;
        else
-               stm32l4_info->option_bytes.bank_b_start = flash_size_in_kb << 9;
+               stm32l4_info->option_bytes.bank_b_start = flash_size_in_kb >> 2;
 
        /* did we assign flash size? */
        assert((flash_size_in_kb != 0xffff) && flash_size_in_kb);
@@ -774,7 +828,7 @@ COMMAND_HANDLER(stm32l4_handle_lock_command)
                return ERROR_OK;
        }
 
-       /* set readout protection */
+       /* set readout protection level 1 */
        stm32l4_info->option_bytes.RDP = 0;
 
        if (stm32l4_write_options(bank) != ERROR_OK) {

-- 

------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to