Skip to content

Commit d3fe0a0

Browse files
committed
stm32/flash: Fix writing final words to flash on H5 and H7 MCUs.
The calculations `num_word32 / 4` and `num_word32 / 8` were rounding down the number of words to program to flash, and therefore possibly truncating the data (eg mboot could miss writing the final few words of the firmware). That's fixed in this commit by adding extra logic to program any remaining words. And the logic for H5 and H7 is combined. Signed-off-by: Damien George <[email protected]>
1 parent 64f28dc commit d3fe0a0

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

Diff for: ports/stm32/flash.c

+29-18
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include <string.h>
2728
#include "py/mpconfig.h"
2829
#include "py/misc.h"
2930
#include "py/mphal.h"
@@ -450,28 +451,38 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
450451
#endif
451452
}
452453

453-
#elif defined(STM32H5)
454+
#elif defined(STM32H5) || defined(STM32H7)
454455

455-
// program the flash 128 bits (4 words) at a time
456-
for (int i = 0; i < num_word32 / 4; i++) {
457-
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, flash_dest, (uint64_t)(uint32_t)src);
458-
if (status != HAL_OK) {
459-
break;
460-
}
461-
flash_dest += 16;
462-
src += 4;
463-
}
456+
#if defined(STM32H5)
457+
static const unsigned int WORD32_PER_FLASHWORD = 4;
458+
static const unsigned int PROGRAM_TYPE = FLASH_TYPEPROGRAM_QUADWORD;
459+
#else
460+
static const unsigned int WORD32_PER_FLASHWORD = FLASH_NB_32BITWORD_IN_FLASHWORD;
461+
static const unsigned int PROGRAM_TYPE = FLASH_TYPEPROGRAM_FLASHWORD;
462+
#endif
464463

465-
#elif defined(STM32H7)
464+
if (flash_dest % (WORD32_PER_FLASHWORD * sizeof(uint32_t))) {
465+
// The flash_dest address is not aligned correctly.
466+
status = HAL_ERROR;
467+
} else {
468+
// Program the flash WORD32_PER_FLASHWORD words at a time.
469+
for (int i = 0; i < num_word32 / WORD32_PER_FLASHWORD; i++) {
470+
status = HAL_FLASH_Program(PROGRAM_TYPE, flash_dest, (uint32_t)src);
471+
if (status != HAL_OK) {
472+
break;
473+
}
474+
flash_dest += WORD32_PER_FLASHWORD * sizeof(uint32_t);
475+
src += WORD32_PER_FLASHWORD;
476+
}
466477

467-
// program the flash 256 bits at a time
468-
for (int i = 0; i < num_word32 / 8; i++) {
469-
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, flash_dest, (uint64_t)(uint32_t)src);
470-
if (status != HAL_OK) {
471-
break;
478+
// Program any remaining words from src.
479+
// Additional bytes beyond that are programmed to 0xff.
480+
if (num_word32 % WORD32_PER_FLASHWORD) {
481+
uint32_t buf[WORD32_PER_FLASHWORD];
482+
memset(buf, 0xff, sizeof(buf));
483+
memcpy(buf, src, (num_word32 % WORD32_PER_FLASHWORD) * sizeof(uint32_t));
484+
status = HAL_FLASH_Program(PROGRAM_TYPE, flash_dest, (uint32_t)buf);
472485
}
473-
flash_dest += 32;
474-
src += 8;
475486
}
476487

477488
#else

0 commit comments

Comments
 (0)