aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George2020-06-18 17:27:52 +1000
committerDamien George2020-06-22 14:18:15 +1000
commita8778c8dc8849dfba14fb17ba148e4d0f78f0467 (patch)
treeb0720c00832ce13a867730a182cd52a2f0290913
parent736daebfc8c7dce2fab10ee311519034d702c8b6 (diff)
stm32/mboot: Use flash routines from main stm32 code rather than custom.
The flash functions in ports/stm32/flash.c are almost identical to those in ports/stm32/mboot/main.c, so remove the duplicated code in mboot and use instead the main stm32 code. This also allows supporting other MCU series. Signed-off-by: Damien George <damien@micropython.org>
-rwxr-xr-xports/stm32/mboot/Makefile3
-rw-r--r--ports/stm32/mboot/main.c162
-rw-r--r--ports/stm32/mboot/mphalport.h5
3 files changed, 25 insertions, 145 deletions
diff --git a/ports/stm32/mboot/Makefile b/ports/stm32/mboot/Makefile
index 43aae2a67..a5db1666d 100755
--- a/ports/stm32/mboot/Makefile
+++ b/ports/stm32/mboot/Makefile
@@ -99,9 +99,10 @@ SRC_C = \
drivers/bus/softspi.c \
drivers/bus/softqspi.c \
drivers/memory/spiflash.c \
+ ports/stm32/flash.c \
+ ports/stm32/flashbdev.c \
ports/stm32/i2cslave.c \
ports/stm32/qspi.c \
- ports/stm32/flashbdev.c \
ports/stm32/spibdev.c \
ports/stm32/usbd_conf.c \
$(wildcard $(BOARD_DIR)/*.c)
diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c
index 4ae575f3d..c53920ccf 100644
--- a/ports/stm32/mboot/main.c
+++ b/ports/stm32/mboot/main.c
@@ -31,6 +31,7 @@
#include "extmod/crypto-algorithms/sha256.c"
#include "usbd_core.h"
#include "storage.h"
+#include "flash.h"
#include "i2cslave.h"
#include "mboot.h"
#include "dfu.h"
@@ -500,115 +501,26 @@ static int usrbtn_state(void) {
#define MBOOT_SPIFLASH2_LAYOUT ""
#endif
-typedef struct {
- uint32_t base_address;
- uint32_t sector_size;
- uint32_t sector_count;
-} flash_layout_t;
-
-#if defined(STM32F7)
-// FLASH_FLAG_PGSERR (Programming Sequence Error) was renamed to
-// FLASH_FLAG_ERSERR (Erasing Sequence Error) in STM32F7
-#define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR
-#endif
-
#if defined(STM32F4) \
|| defined(STM32F722xx) \
|| defined(STM32F723xx) \
|| defined(STM32F732xx) \
|| defined(STM32F733xx)
-
#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
-
-static const flash_layout_t flash_layout[] = {
- { 0x08000000, 0x04000, 4 },
- { 0x08010000, 0x10000, 1 },
- { 0x08020000, 0x20000, 3 },
- #if defined(FLASH_SECTOR_8)
- { 0x08080000, 0x20000, 4 },
- #endif
- #if defined(FLASH_SECTOR_12)
- { 0x08100000, 0x04000, 4 },
- { 0x08110000, 0x10000, 1 },
- { 0x08120000, 0x20000, 7 },
- #endif
-};
-
#elif defined(STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx)
-
#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/04*032Kg,01*128Kg,07*256Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
-
-// This is for dual-bank mode disabled
-static const flash_layout_t flash_layout[] = {
- { 0x08000000, 0x08000, 4 },
- { 0x08020000, 0x20000, 1 },
- { 0x08040000, 0x40000, 7 },
-};
-
#elif defined(STM32H743xx)
-
#define FLASH_LAYOUT_STR "@Internal Flash /0x08000000/16*128Kg" MBOOT_SPIFLASH_LAYOUT MBOOT_SPIFLASH2_LAYOUT
-
-static const flash_layout_t flash_layout[] = {
- { 0x08000000, 0x20000, 16 },
-};
-
-#endif
-
-static inline bool flash_is_valid_addr(uint32_t addr) {
- uint8_t last = MP_ARRAY_SIZE(flash_layout) - 1;
- uint32_t end_of_flash = flash_layout[last].base_address +
- flash_layout[last].sector_count * flash_layout[last].sector_size;
- return flash_layout[0].base_address <= addr && addr < end_of_flash;
-}
-
-static uint32_t flash_get_sector_index(uint32_t addr, uint32_t *sector_size) {
- if (addr >= flash_layout[0].base_address) {
- uint32_t sector_index = 0;
- for (int i = 0; i < MP_ARRAY_SIZE(flash_layout); ++i) {
- for (int j = 0; j < flash_layout[i].sector_count; ++j) {
- uint32_t sector_start_next = flash_layout[i].base_address
- + (j + 1) * flash_layout[i].sector_size;
- if (addr < sector_start_next) {
- *sector_size = flash_layout[i].sector_size;
- return sector_index;
- }
- ++sector_index;
- }
- }
- }
- return 0;
-}
-
-#if defined(STM32H7)
-// get the bank of a given flash address
-static uint32_t get_bank(uint32_t addr) {
- if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) {
- // no bank swap
- if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
- return FLASH_BANK_1;
- } else {
- return FLASH_BANK_2;
- }
- } else {
- // bank swap
- if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) {
- return FLASH_BANK_2;
- } else {
- return FLASH_BANK_1;
- }
- }
-}
#endif
-static int flash_mass_erase(void) {
+static int mboot_flash_mass_erase(void) {
// TODO
return -1;
}
-static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
+static int mboot_flash_page_erase(uint32_t addr, uint32_t *next_addr) {
uint32_t sector_size = 0;
- uint32_t sector = flash_get_sector_index(addr, &sector_size);
+ uint32_t sector = flash_get_sector_info(addr, NULL, &sector_size);
if (sector == 0) {
// Don't allow to erase the sector with this bootloader in it
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
@@ -618,30 +530,10 @@ static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
*next_addr = addr + sector_size;
- HAL_FLASH_Unlock();
-
- // Clear pending flags (if any)
- #if defined(STM32H7)
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
- #else
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
- FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
- #endif
-
- // erase the sector(s)
- FLASH_EraseInitTypeDef EraseInitStruct;
- EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
- EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
- #if defined(STM32H7)
- EraseInitStruct.Banks = get_bank(addr);
- #endif
- EraseInitStruct.Sector = sector;
- EraseInitStruct.NbSectors = 1;
-
- uint32_t SectorError = 0;
- if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
- // error occurred during sector erase
- return -1;
+ // Erase the flash page.
+ int ret = flash_erase(addr, sector_size / sizeof(uint32_t));
+ if (ret != 0) {
+ return ret;
}
// Check the erase set bits to 1, at least for the first 256 bytes
@@ -654,8 +546,9 @@ static int flash_page_erase(uint32_t addr, uint32_t *next_addr) {
return 0;
}
-static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
- if (addr >= flash_layout[0].base_address && addr < flash_layout[0].base_address + flash_layout[0].sector_size) {
+static int mboot_flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
+ uint32_t sector = flash_get_sector_info(addr, NULL, NULL);
+ if (sector == 0) {
// Don't allow to write the sector with this bootloader in it
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
dfu_context.error = MBOOT_ERROR_STR_OVERWRITE_BOOTLOADER_IDX;
@@ -664,32 +557,13 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
const uint32_t *src = (const uint32_t*)src8;
size_t num_word32 = (len + 3) / 4;
- HAL_FLASH_Unlock();
- #if defined(STM32H7)
-
- // program the flash 256 bits at a time
- for (int i = 0; i < num_word32 / 8; ++i) {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, (uint64_t)(uint32_t)src) != HAL_OK) {
- return - 1;
- }
- addr += 32;
- src += 8;
+ // Write the data to flash.
+ int ret = flash_write(addr, src, num_word32);
+ if (ret != 0) {
+ return ret;
}
- #else
-
- // program the flash word by word
- for (size_t i = 0; i < num_word32; i++) {
- if (HAL_FLASH_Program(TYPEPROGRAM_WORD, addr, *src) != HAL_OK) {
- return -1;
- }
- addr += 4;
- src += 1;
- }
-
- #endif
-
// TODO verify data
return 0;
@@ -700,7 +574,7 @@ static int flash_write(uint32_t addr, const uint8_t *src8, size_t len) {
static int do_mass_erase(void) {
// TODO
- return flash_mass_erase();
+ return mboot_flash_mass_erase();
}
#if defined(MBOOT_SPIFLASH_ADDR) || defined(MBOOT_SPIFLASH2_ADDR)
@@ -735,7 +609,7 @@ int do_page_erase(uint32_t addr, uint32_t *next_addr) {
} else
#endif
{
- ret = flash_page_erase(addr, next_addr);
+ ret = mboot_flash_page_erase(addr, next_addr);
}
led0_state((ret == 0) ? LED0_STATE_SLOW_FLASH : LED0_STATE_SLOW_INVERTED_FLASH);
@@ -775,7 +649,7 @@ int do_write(uint32_t addr, const uint8_t *src8, size_t len) {
} else
#endif
if (flash_is_valid_addr(addr)) {
- ret = flash_write(addr, src8, len);
+ ret = mboot_flash_write(addr, src8, len);
} else {
dfu_context.status = DFU_STATUS_ERROR_ADDRESS;
dfu_context.error = MBOOT_ERROR_STR_INVALID_ADDRESS_IDX;
diff --git a/ports/stm32/mboot/mphalport.h b/ports/stm32/mboot/mphalport.h
index 0c8cb91a6..56d18a9b0 100644
--- a/ports/stm32/mboot/mphalport.h
+++ b/ports/stm32/mboot/mphalport.h
@@ -28,6 +28,11 @@
#include "genhdr/pins.h"
+// For simplicity just convert all HAL errors to one errno.
+static inline int mp_hal_status_to_neg_errno(HAL_StatusTypeDef status) {
+ return status == HAL_OK ? 0 : -1;
+}
+
#define mp_hal_delay_us_fast(us) mp_hal_delay_us(us)
#define MP_HAL_PIN_MODE_INPUT (0)