diff --git a/stmhal/flash.c b/stmhal/flash.c index aa75a54a86..29de8b8daa 100644 --- a/stmhal/flash.c +++ b/stmhal/flash.c @@ -30,105 +30,102 @@ #include "mpconfigport.h" #include "py/misc.h" -#if defined(MCU_SERIES_F7) +typedef struct { + uint32_t base_address; + uint32_t sector_size; + uint32_t sector_count; +} flash_layout_t; + +#if defined(MCU_SERIES_F4) + +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(MCU_SERIES_F7) // FLASH_FLAG_PGSERR (Programming Sequence Error) was renamed to // FLASH_FLAG_ERSERR (Erasing Sequence Error) in STM32F7 #define FLASH_FLAG_PGSERR FLASH_FLAG_ERSERR -/* Base address of the Flash sectors */ -#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 32 Kbytes */ -#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08008000) /* Base @ of Sector 1, 32 Kbytes */ -#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08010000) /* Base @ of Sector 2, 32 Kbytes */ -#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08018000) /* Base @ of Sector 3, 32 Kbytes */ -#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08020000) /* Base @ of Sector 4, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08040000) /* Base @ of Sector 5, 256 Kbytes */ -#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08080000) /* Base @ of Sector 6, 256 Kbytes */ -#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080C0000) /* Base @ of Sector 7, 256 Kbytes */ -#define ADDR_FLASH_END ((uint32_t)0x08100000) /* 1 Mbytes total */ - -#else - -/* Base address of the Flash sectors */ -#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */ -#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */ -#if !defined(FLASH_SECTOR_8) -#define ADDR_FLASH_END ((uint32_t)0x08080000) /* 512 Kbytes total */ -#else -#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */ -#if !defined(FLASH_SECTOR_12) -#define ADDR_FLASH_END ((uint32_t)0x08100000) /* 1 Mbytes total */ -#else -#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base @ of Sector 12, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08104000) /* Base @ of Sector 13, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08108000) /* Base @ of Sector 14, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x0810C000) /* Base @ of Sector 15, 16 Kbytes */ -#define ADDR_FLASH_SECTOR_16 ((uint32_t)0x08110000) /* Base @ of Sector 16, 64 Kbytes */ -#define ADDR_FLASH_SECTOR_17 ((uint32_t)0x08120000) /* Base @ of Sector 17, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_18 ((uint32_t)0x08140000) /* Base @ of Sector 18, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_19 ((uint32_t)0x08160000) /* Base @ of Sector 19, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_20 ((uint32_t)0x08180000) /* Base @ of Sector 20, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_21 ((uint32_t)0x081A0000) /* Base @ of Sector 21, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_22 ((uint32_t)0x081C0000) /* Base @ of Sector 22, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_23 ((uint32_t)0x081E0000) /* Base @ of Sector 23, 128 Kbytes */ -#define ADDR_FLASH_END ((uint32_t)0x08200000) /* 2 Mbytes total */ -#endif -#endif - -#endif // MCU_SERIES_F7 - -static const uint32_t flash_info_table[] = { - ADDR_FLASH_SECTOR_0, FLASH_SECTOR_0, - ADDR_FLASH_SECTOR_1, FLASH_SECTOR_1, - ADDR_FLASH_SECTOR_2, FLASH_SECTOR_2, - ADDR_FLASH_SECTOR_3, FLASH_SECTOR_3, - ADDR_FLASH_SECTOR_4, FLASH_SECTOR_4, - ADDR_FLASH_SECTOR_5, FLASH_SECTOR_5, - ADDR_FLASH_SECTOR_6, FLASH_SECTOR_6, - ADDR_FLASH_SECTOR_7, FLASH_SECTOR_7, - #if defined(FLASH_SECTOR_8) - ADDR_FLASH_SECTOR_8, FLASH_SECTOR_8, - ADDR_FLASH_SECTOR_9, FLASH_SECTOR_9, - ADDR_FLASH_SECTOR_10, FLASH_SECTOR_10, - ADDR_FLASH_SECTOR_11, FLASH_SECTOR_11, - #endif - #if defined(FLASH_SECTOR_12) - ADDR_FLASH_SECTOR_12, FLASH_SECTOR_12, - ADDR_FLASH_SECTOR_13, FLASH_SECTOR_13, - ADDR_FLASH_SECTOR_14, FLASH_SECTOR_14, - ADDR_FLASH_SECTOR_15, FLASH_SECTOR_15, - ADDR_FLASH_SECTOR_16, FLASH_SECTOR_16, - ADDR_FLASH_SECTOR_17, FLASH_SECTOR_17, - ADDR_FLASH_SECTOR_18, FLASH_SECTOR_18, - ADDR_FLASH_SECTOR_19, FLASH_SECTOR_19, - ADDR_FLASH_SECTOR_20, FLASH_SECTOR_20, - ADDR_FLASH_SECTOR_21, FLASH_SECTOR_21, - ADDR_FLASH_SECTOR_22, FLASH_SECTOR_22, - ADDR_FLASH_SECTOR_23, FLASH_SECTOR_23, - #endif - ADDR_FLASH_END, 0, +static const flash_layout_t flash_layout[] = { + { 0x08000000, 0x08000, 4 }, + { 0x08020000, 0x20000, 1 }, + { 0x08040000, 0x40000, 3 }, }; +#elif defined(MCU_SERIES_L4) + +static const flash_layout_t flash_layout[] = { + { (uint32_t)FLASH_BASE, (uint32_t)FLASH_PAGE_SIZE, 512 }, +}; + +#else +#error Unsupported processor +#endif + +#if defined(MCU_SERIES_L4) + +// get the bank of a given flash address +static uint32_t get_bank(uint32_t addr) { + if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 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; + } + } +} + +// get the page of a given flash address +static uint32_t get_page(uint32_t addr) { + if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) { + // bank 1 + return (addr - FLASH_BASE) / FLASH_PAGE_SIZE; + } else { + // bank 2 + return (addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE; + } +} + +#endif + uint32_t flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) { - if (addr >= flash_info_table[0]) { - for (int i = 0; i < MP_ARRAY_SIZE(flash_info_table) - 2; i += 2) { - if (addr < flash_info_table[i + 2]) { - if (start_addr != NULL) { - *start_addr = flash_info_table[i]; + 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) { + if (start_addr != NULL) { + *start_addr = flash_layout[i].base_address + + j * flash_layout[i].sector_size; + } + if (size != NULL) { + *size = flash_layout[i].sector_size; + } + return sector_index; } - if (size != NULL) { - *size = flash_info_table[i + 2] - flash_info_table[i]; - } - return flash_info_table[i + 1]; + ++sector_index; } } } @@ -144,16 +141,30 @@ void flash_erase(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) // unlock HAL_FLASH_Unlock(); + FLASH_EraseInitTypeDef EraseInitStruct; + + #if defined(MCU_SERIES_L4) + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); + + // erase the sector(s) + // The sector returned by flash_get_sector_info can not be used + // as the flash has on each bank 0/1 pages 0..255 + EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; + EraseInitStruct.Banks = get_bank(flash_dest); + EraseInitStruct.Page = get_page(flash_dest); + EraseInitStruct.NbPages = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;; + #else // Clear pending flags (if any) __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); // 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 EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL); EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1; + #endif + uint32_t SectorError = 0; if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) { // error occurred during sector erase @@ -192,6 +203,31 @@ void flash_erase_it(uint32_t flash_dest, const uint32_t *src, uint32_t num_word3 */ void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) { + #if defined(MCU_SERIES_L4) + + // program the flash uint64 by uint64 + for (int i = 0; i < num_word32 / 2; i++) { + uint64_t val = *(uint64_t*)src; + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) { + // error occurred during flash write + HAL_FLASH_Lock(); // lock the flash + return; + } + flash_dest += 8; + src += 2; + } + if ((num_word32 & 0x01) == 1) { + uint64_t val = *(uint64_t*)flash_dest; + val = (val & 0xffffffff00000000uL) | (*src); + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, flash_dest, val) != HAL_OK) { + // error occurred during flash write + HAL_FLASH_Lock(); // lock the flash + return; + } + } + + #else + // program the flash word by word for (int i = 0; i < num_word32; i++) { if (HAL_FLASH_Program(TYPEPROGRAM_WORD, flash_dest, *src) != HAL_OK) { @@ -203,6 +239,8 @@ void flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) src += 1; } + #endif + // lock the flash HAL_FLASH_Lock(); } diff --git a/stmhal/storage.c b/stmhal/storage.c index dd1e3e2852..0c91fa0848 100644 --- a/stmhal/storage.c +++ b/stmhal/storage.c @@ -84,6 +84,14 @@ STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k #define FLASH_MEM_SEG1_START_ADDR (0x08008000) // sector 1 #define FLASH_MEM_SEG1_NUM_BLOCKS (192) // sectors 1,2,3: 32k+32k+32=96k +#elif defined(STM32L476xx) + +// The STM32L476 doesn't have CCRAM, so we use the 32K SRAM2 for this. +#define CACHE_MEM_START_ADDR (0x10000000) // SRAM2 data RAM, 32k +#define FLASH_SECTOR_SIZE_MAX (0x00800) // 2k max +#define FLASH_MEM_SEG1_START_ADDR (0x08000800) // sector 1 +#define FLASH_MEM_SEG1_NUM_BLOCKS (252) // 1 Block=512 Bytes Reserve 126 kBytes + #else #error "no storage support for this MCU" #endif