drivers: flash: stm32l5: use write-block-size when writing
STM32L5 have a write block size of 8, but STM32U5 and STM32H5 have a write block size of 16. Convert write_dword() and flash_stm32_write_range() to write write-block-size data at a time. Fixes #60724 Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
This commit is contained in:
parent
199486546a
commit
4c9e42925e
1 changed files with 25 additions and 11 deletions
|
@ -155,13 +155,15 @@ bool flash_stm32_valid_range(const struct device *dev, off_t offset,
|
|||
return flash_stm32_range_exists(dev, offset, len);
|
||||
}
|
||||
|
||||
static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
||||
static int write_nwords(const struct device *dev, off_t offset, const uint32_t *buff, size_t n)
|
||||
{
|
||||
FLASH_TypeDef *regs = FLASH_STM32_REGS(dev);
|
||||
volatile uint32_t *flash = (uint32_t *)(offset
|
||||
+ CONFIG_FLASH_BASE_ADDRESS);
|
||||
bool full_zero = true;
|
||||
uint32_t tmp;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
/* if the non-secure control register is locked,do not fail silently */
|
||||
if (regs->NSCR & FLASH_STM32_NSLOCK) {
|
||||
|
@ -175,16 +177,26 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Check if this double word is erased and value isn't 0.
|
||||
/* Check if this double/quad word is erased and value isn't 0.
|
||||
*
|
||||
* It is allowed to write only zeros over an already written dword
|
||||
* It is allowed to write only zeros over an already written dword / qword
|
||||
* See 6.3.7 in STM32L5 reference manual.
|
||||
* See 7.3.7 in STM32U5 reference manual.
|
||||
* See 7.3.5 in STM32H5 reference manual.
|
||||
*/
|
||||
if ((flash[0] != 0xFFFFFFFFUL ||
|
||||
flash[1] != 0xFFFFFFFFUL) && val != 0UL) {
|
||||
LOG_ERR("Word at offs %ld not erased", (long)offset);
|
||||
return -EIO;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (buff[i] != 0) {
|
||||
full_zero = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!full_zero) {
|
||||
for (i = 0; i < n; i++) {
|
||||
if (flash[i] != 0xFFFFFFFFUL) {
|
||||
LOG_ERR("Word at offs %ld not erased", (long)(offset + i));
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the NSPG bit */
|
||||
|
@ -194,8 +206,9 @@ static int write_dword(const struct device *dev, off_t offset, uint64_t val)
|
|||
tmp = regs->NSCR;
|
||||
|
||||
/* Perform the data write operation at the desired memory address */
|
||||
flash[0] = (uint32_t)val;
|
||||
flash[1] = (uint32_t)(val >> 32);
|
||||
for (i = 0; i < n; i++) {
|
||||
flash[i] = buff[i];
|
||||
}
|
||||
|
||||
/* Wait until the NSBSY bit is cleared */
|
||||
rc = flash_stm32_wait_flash_idle(dev);
|
||||
|
@ -343,8 +356,9 @@ int flash_stm32_write_range(const struct device *dev, unsigned int offset,
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i += 8, offset += 8) {
|
||||
rc = write_dword(dev, offset, ((const uint64_t *) data)[i>>3]);
|
||||
for (i = 0; i < len; i += FLASH_STM32_WRITE_BLOCK_SIZE) {
|
||||
rc = write_nwords(dev, offset + i, ((const uint32_t *) data + (i>>2)),
|
||||
FLASH_STM32_WRITE_BLOCK_SIZE / 4);
|
||||
if (rc < 0) {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue