Skip to content
Snippets Groups Projects
Commit cd728088 authored by Paul Fertser's avatar Paul Fertser Committed by Spencer Oliver
Browse files

flash/nor/stm32l: fix mass erase

Topaz reports on http://sourceforge.net/p/openocd/tickets/87/

 that
protection level constants are mixed up. This leads to device ending
up in protection level 1 after mass erase.

Additional work is required to actually put the device in RDP Level 1
and then back to Level 0, as Option bootloader launch is a special
kind of full target reset.

To be able to flash properly after mass_erase a "reset init" is needed
(it's anyway recommended to always perform it before any flash
operation).

Change-Id: I9a838909458039bb0114d3019723bf134fa4d7c9
Signed-off-by: default avatarPaul Fertser <fercerpav@gmail.com>
Reviewed-on: http://openocd.zylin.com/2490


Tested-by: jenkins
Reviewed-by: default avatarSpencer Oliver <spen@spen-soft.co.uk>
parent c9639ae2
Branches
No related tags found
No related merge requests found
...@@ -95,8 +95,8 @@ ...@@ -95,8 +95,8 @@
/* option bytes */ /* option bytes */
#define OPTION_BYTES_ADDRESS 0x1FF80000 #define OPTION_BYTES_ADDRESS 0x1FF80000
#define OPTION_BYTE_0_PR1 0x015500AA #define OPTION_BYTE_0_PR1 0xFFFF0000
#define OPTION_BYTE_0_PR0 0x01FF0011 #define OPTION_BYTE_0_PR0 0xFF5500AA
static int stm32lx_unlock_program_memory(struct flash_bank *bank); static int stm32lx_unlock_program_memory(struct flash_bank *bank);
static int stm32lx_lock_program_memory(struct flash_bank *bank); static int stm32lx_lock_program_memory(struct flash_bank *bank);
...@@ -1222,6 +1222,26 @@ static int stm32lx_wait_status_busy(struct flash_bank *bank, int timeout) ...@@ -1222,6 +1222,26 @@ static int stm32lx_wait_status_busy(struct flash_bank *bank, int timeout)
return retval; return retval;
} }
static int stm32lx_obl_launch(struct flash_bank *bank)
{
struct target *target = bank->target;
struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
int retval;
/* This will fail as the target gets immediately rebooted */
target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,
FLASH_PECR__OBL_LAUNCH);
size_t tries = 10;
do {
target_halt(target);
retval = target_poll(target);
} while (--tries > 0 &&
(retval != ERROR_OK || target->state != TARGET_HALTED));
return tries ? ERROR_OK : ERROR_FAIL;
}
static int stm32lx_mass_erase(struct flash_bank *bank) static int stm32lx_mass_erase(struct flash_bank *bank)
{ {
int retval; int retval;
...@@ -1240,18 +1260,33 @@ static int stm32lx_mass_erase(struct flash_bank *bank) ...@@ -1240,18 +1260,33 @@ static int stm32lx_mass_erase(struct flash_bank *bank)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
/* mass erase flash memory, write 0x015500AA option byte address 0*/ /* mass erase flash memory */
/* pass the RDP privilege to 1 */ /* set the RDP protection level to 1 */
retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR1); retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR1);
if (retval != ERROR_OK)
return retval;
/* restore the RDP privilege to 0 */ retval = stm32lx_obl_launch(bank);
if (retval != ERROR_OK)
return retval;
retval = stm32lx_unlock_options_bytes(bank);
if (retval != ERROR_OK)
return retval;
/* set the RDP protection level to 0 */
retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR0); retval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR0);
if (retval != ERROR_OK)
return retval;
/* the mass erase occur when the privilege go back to 0 */
retval = stm32lx_wait_status_busy(bank, 30000); retval = stm32lx_wait_status_busy(bank, 30000);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = stm32lx_obl_launch(bank);
if (retval != ERROR_OK)
return retval;
retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, &reg32); retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, &reg32);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment