flash/nor/stm32l4x: fix minor errors in flash write/async algo
Fix comment of tested errors in asm src. List all relevant errors in FLASH_ERROR mask: FLASH_PROGERR was missing and any trial to re-program already programmed double word ended up in the error bit held uncleared and flash write permanetly repeating the error message until reset. Lock the bank also after unsuccesfull write_block run. Set async target algo block size to size of double word. Remove warning in case of write_block success. In case of error use LOG_ERROR instead of warning. Change-Id: Ibf6d5e306a4c2eaa43de67d636b4902c737f02f3 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/5360 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
This commit is contained in:
parent
c2cb4e40b8
commit
e7e681ac2b
|
@ -71,7 +71,7 @@ busy:
|
||||||
ldr r6, [r4, #STM32_FLASH_SR_OFFSET]
|
ldr r6, [r4, #STM32_FLASH_SR_OFFSET]
|
||||||
tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */
|
tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */
|
||||||
bne busy /* wait more... */
|
bne busy /* wait more... */
|
||||||
tst r6, #0xfa /* PGSERR | PGPERR | PGAERR | WRPERR | PROGERR*/
|
tst r6, #0xfa /* PGSERR | SIZERR | PGAERR | WRPERR | PROGERR | OPERR */
|
||||||
bne error /* fail... */
|
bne error /* fail... */
|
||||||
|
|
||||||
cmp r5, r1 /* wrap rp at end of buffer */
|
cmp r5, r1 /* wrap rp at end of buffer */
|
||||||
|
|
|
@ -106,7 +106,7 @@
|
||||||
#define FLASH_PROGERR (1 << 3) /* Programming error */
|
#define FLASH_PROGERR (1 << 3) /* Programming error */
|
||||||
#define FLASH_OPERR (1 << 1) /* Operation error */
|
#define FLASH_OPERR (1 << 1) /* Operation error */
|
||||||
#define FLASH_EOP (1 << 0) /* End of operation */
|
#define FLASH_EOP (1 << 0) /* End of operation */
|
||||||
#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGSERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR)
|
#define FLASH_ERROR (FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR)
|
||||||
|
|
||||||
/* register unlock keys */
|
/* register unlock keys */
|
||||||
#define KEY1 0x45670123
|
#define KEY1 0x45670123
|
||||||
|
@ -577,7 +577,7 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count is in halfwords */
|
/* Count is in double-words */
|
||||||
static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
|
static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
|
||||||
uint32_t offset, uint32_t count)
|
uint32_t offset, uint32_t count)
|
||||||
{
|
{
|
||||||
|
@ -630,15 +630,15 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
|
||||||
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */
|
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */
|
||||||
init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */
|
init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */
|
||||||
init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (double word-64bit) */
|
init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (double word-64bit) */
|
||||||
init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash base */
|
init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash regs base */
|
||||||
|
|
||||||
buf_set_u32(reg_params[0].value, 0, 32, source->address);
|
buf_set_u32(reg_params[0].value, 0, 32, source->address);
|
||||||
buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
|
buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
|
||||||
buf_set_u32(reg_params[2].value, 0, 32, address);
|
buf_set_u32(reg_params[2].value, 0, 32, address);
|
||||||
buf_set_u32(reg_params[3].value, 0, 32, count / 4);
|
buf_set_u32(reg_params[3].value, 0, 32, count);
|
||||||
buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base);
|
buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base);
|
||||||
|
|
||||||
retval = target_run_flash_async_algorithm(target, buffer, count, 2,
|
retval = target_run_flash_async_algorithm(target, buffer, count, 8,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
5, reg_params,
|
5, reg_params,
|
||||||
source->address, source->size,
|
source->address, source->size,
|
||||||
|
@ -676,7 +676,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
|
||||||
static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
|
static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||||
uint32_t offset, uint32_t count)
|
uint32_t offset, uint32_t count)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval, retval2;
|
||||||
|
|
||||||
if (bank->target->state != TARGET_HALTED) {
|
if (bank->target->state != TARGET_HALTED) {
|
||||||
LOG_ERROR("Target not halted");
|
LOG_ERROR("Target not halted");
|
||||||
|
@ -692,14 +692,15 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||||
if (retval != ERROR_OK)
|
if (retval != ERROR_OK)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
retval = stm32l4_write_block(bank, buffer, offset, count / 2);
|
retval = stm32l4_write_block(bank, buffer, offset, count / 8);
|
||||||
|
|
||||||
|
retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK);
|
||||||
|
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_WARNING("block write failed");
|
LOG_ERROR("block write failed");
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
return retval2;
|
||||||
LOG_WARNING("block write succeeded");
|
|
||||||
return stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id)
|
static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id)
|
||||||
|
|
Loading…
Reference in New Issue