X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstm32l4x.c;h=c8055cd9ca473fdd2e99475d4ce97a5a08a03d0f;hp=3d1537756074466676a9bd6fde6e4cd0d32ddae5;hb=e7e681ac2b66b9eb585b7dfb8eed6c5bd2efefa9;hpb=251eb035fc72c8fe6348fa21d8c8d8faa9902988 diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 3d15377560..c8055cd9ca 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -106,7 +106,7 @@ #define FLASH_PROGERR (1 << 3) /* Programming error */ #define FLASH_OPERR (1 << 1) /* Operation error */ #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 */ #define KEY1 0x45670123 @@ -278,6 +278,10 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) return ERROR_FAIL; /* Checkme: What better error to use?*/ bank->driver_priv = stm32l4_info; + /* The flash write must be aligned to a double word (8-bytes) boundary. + * Ask the flash infrastructure to ensure required alignment */ + bank->write_start_alignment = bank->write_end_alignment = 8; + stm32l4_info->probed = 0; return ERROR_OK; @@ -573,7 +577,7 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last return ret; } -/* Count is in halfwords */ +/* Count is in double-words */ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -626,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[2], "r2", 32, PARAM_OUT); /* target address */ 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[1].value, 0, 32, source->address + source->size); 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); - retval = target_run_flash_async_algorithm(target, buffer, count, 2, + retval = target_run_flash_async_algorithm(target, buffer, count, 8, 0, NULL, 5, reg_params, source->address, source->size, @@ -672,45 +676,31 @@ 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, uint32_t offset, uint32_t count) { - int retval; + int retval, retval2; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - if (offset & 0x7) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", - offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (count & 0x7) { - LOG_WARNING("Padding %d bytes to keep 8-byte write size", - count & 7); - count = (count + 7) & ~7; - /* This pads the write chunk with random bytes by overrunning the - * write buffer. Padding with the erased pattern 0xff is purely - * cosmetical, as 8-byte flash words are ECC secured and the first - * write will program the ECC bits. A second write would need - * to reprogramm these ECC bits. - * But this can only be done after erase! - */ - } + /* The flash write must be aligned to a double word (8-bytes) boundary. + * The flash infrastructure ensures it, do just a security check */ + assert(offset % 8 == 0); + assert(count % 8 == 0); retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; - /* Only full double words (8-byte) can be programmed*/ - 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) { - LOG_WARNING("block write failed"); + LOG_ERROR("block write failed"); return retval; } - - LOG_WARNING("block write succeeded"); - return stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); + return retval2; } static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id)