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: Paul Fertser <fercerpav@gmail.com> Reviewed-on: http://openocd.zylin.com/2490 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
This commit is contained in:
parent
c9639ae2ac
commit
cd72808889
|
@ -95,8 +95,8 @@
|
|||
/* option bytes */
|
||||
#define OPTION_BYTES_ADDRESS 0x1FF80000
|
||||
|
||||
#define OPTION_BYTE_0_PR1 0x015500AA
|
||||
#define OPTION_BYTE_0_PR0 0x01FF0011
|
||||
#define OPTION_BYTE_0_PR1 0xFFFF0000
|
||||
#define OPTION_BYTE_0_PR0 0xFF5500AA
|
||||
|
||||
static int stm32lx_unlock_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)
|
|||
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)
|
||||
{
|
||||
int retval;
|
||||
|
@ -1240,18 +1260,33 @@ static int stm32lx_mass_erase(struct flash_bank *bank)
|
|||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* mass erase flash memory, write 0x015500AA option byte address 0*/
|
||||
/* pass the RDP privilege to 1 */
|
||||
/* 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;
|
||||
|
||||
/* 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);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
/* the mass erase occur when the privilege go back to 0 */
|
||||
retval = stm32lx_wait_status_busy(bank, 30000);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = stm32lx_obl_launch(bank);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
retval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, ®32);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
|
Loading…
Reference in New Issue