From 4e4dfc1d888997904bbc881bb62e2f74a70d68e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Tue, 16 May 2017 16:50:36 +0200 Subject: [PATCH] Align 8 MB & 16 MB flash sizes with SDK 2.1.0. (#1968) * align 8MB and 16MB auto flash support with sdk 2.1.0 * remove SAFE_API * fix flash size mismatch detection logic --- app/include/user_config.h | 1 - app/modules/adc.c | 6 +-- app/modules/node.c | 8 ---- app/platform/cpu_esp8266.h | 10 ----- app/platform/flash_api.c | 62 +++++--------------------- app/platform/flash_api.h | 17 +------ app/spiffs/spiffs.c | 10 +---- app/user/user_main.c | 47 ++++++++++--------- docs/en/flash.md | 6 +-- sdk-overrides/include/user_interface.h | 5 --- 10 files changed, 48 insertions(+), 124 deletions(-) diff --git a/app/include/user_config.h b/app/include/user_config.h index 03745f93..393da734 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -8,7 +8,6 @@ // #define FLASH_8M // #define FLASH_16M #define FLASH_AUTOSIZE -#define FLASH_SAFE_API // This adds the asserts in LUA. It also adds some useful extras to the // node module. This is all silent in normal operation and so can be enabled diff --git a/app/modules/adc.c b/app/modules/adc.c index 3ccd90aa..83904bbe 100644 --- a/app/modules/adc.c +++ b/app/modules/adc.c @@ -34,7 +34,7 @@ static int adc_init107( lua_State *L ) // Note 32bit alignment so we can safely cast to uint32 for the flash api char init_data[SPI_FLASH_SEC_SIZE] __attribute__((aligned(4))); - if (SPI_FLASH_RESULT_OK != flash_safe_read ( + if (SPI_FLASH_RESULT_OK != flash_read ( init_sector * SPI_FLASH_SEC_SIZE, (uint32 *)init_data, sizeof(init_data))) return luaL_error(L, "flash read error"); @@ -48,10 +48,10 @@ static int adc_init107( lua_State *L ) // Nope, it differs, we need to rewrite it init_data[107] = byte107; - if (SPI_FLASH_RESULT_OK != flash_safe_erase_sector (init_sector)) + if (SPI_FLASH_RESULT_OK != flash_erase (init_sector)) return luaL_error(L, "flash erase error"); - if (SPI_FLASH_RESULT_OK != flash_safe_write ( + if (SPI_FLASH_RESULT_OK != flash_write ( init_sector * SPI_FLASH_SEC_SIZE, (uint32 *)init_data, sizeof(init_data))) return luaL_error(L, "flash write error"); diff --git a/app/modules/node.c b/app/modules/node.c index 1bfcc12b..8302ec8c 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -112,11 +112,7 @@ static int node_info( lua_State* L ) lua_pushinteger(L, NODE_VERSION_REVISION); lua_pushinteger(L, system_get_chip_id()); // chip id lua_pushinteger(L, spi_flash_get_id()); // flash id -#if defined(FLASH_SAFE_API) - lua_pushinteger(L, flash_safe_get_size_byte() / 1024); // flash size in KB -#else lua_pushinteger(L, flash_rom_get_size_byte() / 1024); // flash size in KB -#endif // defined(FLASH_SAFE_API) lua_pushinteger(L, flash_rom_get_mode()); lua_pushinteger(L, flash_rom_get_speed()); return 8; @@ -154,11 +150,7 @@ static int node_flashsize( lua_State* L ) { flash_rom_set_size_byte(luaL_checkinteger(L, 1)); } -#if defined(FLASH_SAFE_API) - uint32_t sz = flash_safe_get_size_byte(); -#else uint32_t sz = flash_rom_get_size_byte(); -#endif // defined(FLASH_SAFE_API) lua_pushinteger( L, sz ); return 1; } diff --git a/app/platform/cpu_esp8266.h b/app/platform/cpu_esp8266.h index b763d9cd..eb6d3406 100644 --- a/app/platform/cpu_esp8266.h +++ b/app/platform/cpu_esp8266.h @@ -32,11 +32,7 @@ #elif defined(FLASH_16M) #define FLASH_SEC_NUM 0x1000 #elif defined(FLASH_AUTOSIZE) -#if defined(FLASH_SAFE_API) -#define FLASH_SEC_NUM (flash_safe_get_sec_num()) -#else #define FLASH_SEC_NUM (flash_rom_get_sec_num()) -#endif // defined(FLASH_SAFE_API) #else #define FLASH_SEC_NUM 0x80 #endif @@ -55,15 +51,9 @@ // SpiFlashOpResult spi_flash_erase_sector(uint16 sec); // SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size); // SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size); -#if defined(FLASH_SAFE_API) -#define flash_write flash_safe_write -#define flash_erase flash_safe_erase_sector -#define flash_read flash_safe_read -#else #define flash_write spi_flash_write #define flash_erase spi_flash_erase_sector #define flash_read spi_flash_read -#endif // defined(FLASH_SAFE_API) #define CACHE_FLASH_CTRL_REG 0x3ff0000c #define CACHE_FLASH_ACTIVE 0x00000100 diff --git a/app/platform/flash_api.c b/app/platform/flash_api.c index bee2149c..05f12390 100644 --- a/app/platform/flash_api.c +++ b/app/platform/flash_api.c @@ -10,73 +10,35 @@ uint32_t flash_detect_size_byte(void) { + // enable operations on whole physical flash, SDK might have restricted + // the flash size already + extern SpiFlashChip * flashchip; + uint32 orig_chip_size = flashchip->chip_size; + flashchip->chip_size = FLASH_SIZE_16MBYTE; + #define FLASH_BUFFER_SIZE_DETECT 32 uint32_t dummy_size = FLASH_SIZE_256KBYTE; uint8_t data_orig[FLASH_BUFFER_SIZE_DETECT] ICACHE_STORE_ATTR = {0}; uint8_t data_new[FLASH_BUFFER_SIZE_DETECT] ICACHE_STORE_ATTR = {0}; - if (SPI_FLASH_RESULT_OK == flash_safe_read(0, (uint32 *)data_orig, FLASH_BUFFER_SIZE_DETECT)) + if (SPI_FLASH_RESULT_OK == flash_read(0, (uint32 *)data_orig, FLASH_BUFFER_SIZE_DETECT)) { dummy_size = FLASH_SIZE_256KBYTE; while ((dummy_size < FLASH_SIZE_16MBYTE) && - (SPI_FLASH_RESULT_OK == flash_safe_read(dummy_size, (uint32 *)data_new, FLASH_BUFFER_SIZE_DETECT)) && + (SPI_FLASH_RESULT_OK == flash_read(dummy_size, (uint32 *)data_new, FLASH_BUFFER_SIZE_DETECT)) && (0 != os_memcmp(data_orig, data_new, FLASH_BUFFER_SIZE_DETECT)) ) { dummy_size *= 2; } }; + + // revert temporary setting + flashchip->chip_size = orig_chip_size; + return dummy_size; #undef FLASH_BUFFER_SIZE_DETECT } -uint32_t flash_safe_get_size_byte(void) -{ - static uint32_t flash_size = 0; - if (flash_size == 0) - { - flash_size = flash_detect_size_byte(); -#if !defined(FLASH_SAFE_API) - // clip maximum flash size to 4MByte if "SAFE API" is not used - if (flash_size > FLASH_SIZE_4MBYTE) { - flash_size = FLASH_SIZE_4MBYTE; - } -#endif - } - return flash_size; -} - -uint16_t flash_safe_get_sec_num(void) -{ - return (flash_safe_get_size_byte() / (SPI_FLASH_SEC_SIZE)); -} - -SpiFlashOpResult flash_safe_read(uint32 src_addr, uint32 *des_addr, uint32 size) -{ - SpiFlashOpResult result = SPI_FLASH_RESULT_ERR; - FLASH_SAFEMODE_ENTER(); - result = spi_flash_read(src_addr, (uint32 *) des_addr, size); - FLASH_SAFEMODE_LEAVE(); - return result; -} - -SpiFlashOpResult flash_safe_write(uint32 des_addr, uint32 *src_addr, uint32 size) -{ - SpiFlashOpResult result = SPI_FLASH_RESULT_ERR; - FLASH_SAFEMODE_ENTER(); - result = spi_flash_write(des_addr, src_addr, size); - FLASH_SAFEMODE_LEAVE(); - return result; -} - -SpiFlashOpResult flash_safe_erase_sector(uint16 sec) -{ - SpiFlashOpResult result = SPI_FLASH_RESULT_ERR; - FLASH_SAFEMODE_ENTER(); - result = spi_flash_erase_sector(sec); - FLASH_SAFEMODE_LEAVE(); - return result; -} - SPIFlashInfo flash_rom_getinfo(void) { volatile SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR; diff --git a/app/platform/flash_api.h b/app/platform/flash_api.h index 7ea697fc..b0fb16be 100644 --- a/app/platform/flash_api.h +++ b/app/platform/flash_api.h @@ -20,16 +20,6 @@ #define FLASH_SIZE_8MBYTE (FLASH_SIZE_64MBIT / 8) #define FLASH_SIZE_16MBYTE (FLASH_SIZE_128MBIT/ 8) -#define FLASH_SAFEMODE_ENTER() \ -do { \ - extern SpiFlashChip * flashchip; \ - flashchip->chip_size = FLASH_SIZE_16MBYTE - - -#define FLASH_SAFEMODE_LEAVE() \ - flashchip->chip_size = flash_rom_get_size_byte(); \ -} while(0) - /****************************************************************************** * ROM Function definition * Note: It is unsafe to use ROM function, but it may efficient. @@ -89,15 +79,10 @@ typedef struct uint32_t segment_size; } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo; -uint32_t flash_detect_size_byte(void); -uint32_t flash_safe_get_size_byte(void); -uint16_t flash_safe_get_sec_num(void); -SpiFlashOpResult flash_safe_read(uint32 src_addr, uint32 *des_addr, uint32 size); -SpiFlashOpResult flash_safe_write(uint32 des_addr, uint32 *src_addr, uint32 size); -SpiFlashOpResult flash_safe_erase_sector(uint16 sec); SPIFlashInfo flash_rom_getinfo(void); uint8_t flash_rom_get_size_type(void); uint32_t flash_rom_get_size_byte(void); +uint32_t flash_detect_size_byte(void); bool flash_rom_set_size_type(uint8_t); bool flash_rom_set_size_byte(uint32_t); uint16_t flash_rom_get_sec_num(void); diff --git a/app/spiffs/spiffs.c b/app/spiffs/spiffs.c index 6090489b..08d0dfb5 100644 --- a/app/spiffs/spiffs.c +++ b/app/spiffs/spiffs.c @@ -53,14 +53,8 @@ static bool myspiffs_set_location(spiffs_config *cfg, int align, int offset, int #ifdef SPIFFS_FIXED_LOCATION cfg->phys_addr = (SPIFFS_FIXED_LOCATION + block_size - 1) & ~(block_size-1); #else - if (flash_safe_get_size_byte() <= FLASH_SIZE_4MBYTE) { - // 256kByte - 4MByte modules: SPIFFS partition starts right after firmware image - cfg->phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL ) + offset; - cfg->phys_addr = (cfg->phys_addr + align - 1) & ~(align - 1); - } else { - // > 4MByte modules: SPIFFS partition starts after SDK data - cfg->phys_addr = flash_rom_get_size_byte(); - } + cfg->phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL ) + offset; + cfg->phys_addr = (cfg->phys_addr + align - 1) & ~(align - 1); #endif #ifdef SPIFFS_SIZE_1M_BOUNDARY cfg->phys_size = ((0x100000 - (SYS_PARAM_SEC_NUM * INTERNAL_FLASH_SECTOR_SIZE) - ( ( u32_t )cfg->phys_addr )) & ~(block_size - 1)) & 0xfffff; diff --git a/app/user/user_main.c b/app/user/user_main.c index 7af00ecc..95a1ab96 100644 --- a/app/user/user_main.c +++ b/app/user/user_main.c @@ -72,9 +72,24 @@ void TEXT_SECTION_ATTR user_start_trampoline (void) * is deliberately quite terse and not as readable as one might like. */ SPIFlashInfo sfi; + + // enable operations on >4MB flash chip + extern SpiFlashChip * flashchip; + uint32 orig_chip_size = flashchip->chip_size; + flashchip->chip_size = FLASH_SIZE_16MBYTE; + SPIRead (0, (uint32_t *)(&sfi), sizeof (sfi)); // Cache read not enabled yet, safe to use - if (sfi.size < 2) // Compensate for out-of-order 4mbit vs 2mbit values - sfi.size ^= 1; + // handle all size entries + switch (sfi.size) { + case 0: sfi.size = 1; break; // SIZE_4MBIT + case 1: sfi.size = 0; break; // SIZE_2MBIT + case 5: sfi.size = 3; break; // SIZE_16MBIT_8M_8M + case 6: // fall-through + case 7: sfi.size = 4; break; // SIZE_32MBIT_8M_8M, SIZE_32MBIT_16M_16M + case 8: sfi.size = 5; break; // SIZE_64MBIT + case 9: sfi.size = 6; break; // SIZE_128MBIT + default: break; + } uint32_t flash_end_addr = (256 * 1024) << sfi.size; uint32_t init_data_hdr = 0xffffffff; uint32_t init_data_addr = flash_end_addr - 4 * SPI_FLASH_SEC_SIZE; @@ -85,6 +100,9 @@ void TEXT_SECTION_ATTR user_start_trampoline (void) SPIWrite (init_data_addr, init_data, 4 * (init_data_end - init_data)); } + // revert temporary setting + flashchip->chip_size = orig_chip_size; + call_user_start (); } @@ -122,21 +140,10 @@ void nodemcu_init(void) return; } - if( flash_safe_get_size_byte() <= FLASH_SIZE_4MBYTE ) { - if( flash_safe_get_size_byte() != flash_rom_get_size_byte() ) { - NODE_ERR("Self adjust flash size.\n"); - // Fit hardware real flash size. - flash_rom_set_size_byte(flash_safe_get_size_byte()); - - system_restart (); - // Don't post the start_lua task, we're about to reboot... - return; - } - } else if( (flash_rom_get_size_byte() < FLASH_SIZE_1MBYTE) || - (flash_rom_get_size_byte() > FLASH_SIZE_4MBYTE) ) { - NODE_ERR("Locking flash size for SDK to 1MByte.\n"); - // SDK/ROM can't handle flash size > 4MByte, ensure a minimum of 1MByte for firmware image - flash_rom_set_size_byte(FLASH_SIZE_1MBYTE); + if( flash_detect_size_byte() != flash_rom_get_size_byte() ) { + NODE_ERR("Self adjust flash size.\n"); + // Fit hardware real flash size. + flash_rom_set_size_byte(flash_detect_size_byte()); system_restart (); // Don't post the start_lua task, we're about to reboot... @@ -190,7 +197,7 @@ void user_rf_pre_init(void) uint32 user_rf_cal_sector_set(void) { - enum ext_flash_size_map size_map = system_get_flash_size_map(); + enum flash_size_map size_map = system_get_flash_size_map(); uint32 rf_cal_sec = 0; switch (size_map) { @@ -213,11 +220,11 @@ user_rf_cal_sector_set(void) rf_cal_sec = 1024 - 5; break; - case FLASH_SIZE_64M_MAP: + case FLASH_SIZE_64M_MAP_1024_1024: rf_cal_sec = 2048 - 5; break; - case FLASH_SIZE_128M_MAP: + case FLASH_SIZE_128M_MAP_1024_1024: rf_cal_sec = 4096 - 5; break; diff --git a/docs/en/flash.md b/docs/en/flash.md index b33bbcd7..255ce7ca 100644 --- a/docs/en/flash.md +++ b/docs/en/flash.md @@ -32,8 +32,6 @@ Run the following command to flash an *aggregated* binary as is produced for exa - esptool.py is under heavy development. It's advised you run the latest version (check with `esptool.py version`). Since this documentation may not have been able to keep up refer to the [esptool flash modes documentation](https://github.com/themadinventor/esptool#flash-modes) for current options and parameters. - In some uncommon cases, the [SDK init data](#sdk-init-data) may be invalid and NodeMCU may fail to boot. The easiest solution is to fully erase the chip before flashing: `esptool.py --port erase_flash` -- Modules with flash chips larger than 4 MByte (e.g. WeMos D1 mini pro) need to be manually configured to at least 1 MByte: Firmware image and SDK init data occupy the first MByte, while the remaining 7/15 MByte of the flash are used for SPIFFS: -`esptool.py --port write_flash -fm -fs 8m 0x00000 .bin` ### NodeMCU Flasher > A firmware Flash tool for NodeMCU...We are working on next version and will use QT framework. It will be cross platform and open-source. @@ -102,12 +100,14 @@ Espressif refers to this area as "System Param" and it resides in the last four The default init data is provided as part of the SDK in the file `esp_init_data_default.bin`. NodeMCU will automatically flash this file to the right place on first boot if the sector appears to be empty. -If you need to customize init data then first download the [Espressif SDK 2.0.0](https://espressif.com/sites/default/files/sdks/esp8266_nonos_sdk_v2.0.0_16_08_10.zip) and extract `esp_init_data_default.bin`. Then flash that file just like you'd flash the firmware. The correct address for the init data depends on the capacity of the flash chip. +If you need to customize init data then first download the [Espressif SDK 2.1.0](https://github.com/espressif/ESP8266_NONOS_SDK/archive/v2.1.0.zip) and extract `esp_init_data_default.bin`. Then flash that file just like you'd flash the firmware. The correct address for the init data depends on the capacity of the flash chip. - `0x7c000` for 512 kB, modules like most ESP-01, -03, -07 etc. - `0xfc000` for 1 MB, modules like ESP8285, PSF-A85, some ESP-01, -03 etc. - `0x1fc000` for 2 MB - `0x3fc000` for 4 MB, modules like ESP-12E, NodeMCU devkit 1.0, WeMos D1 mini +- `0x7fc000` for 8 MB +- `0xffc000` for 16 MB, modules like WeMos D1 mini pro See "4.1 Non-FOTA Flash Map" and "6.3 RF Initialization Configuration" of the [ESP8266 Getting Started Guide](https://espressif.com/en/support/explore/get-started/esp8266/getting-started-guide) for details on init data addresses and customization. diff --git a/sdk-overrides/include/user_interface.h b/sdk-overrides/include/user_interface.h index b0297512..200ee6df 100644 --- a/sdk-overrides/include/user_interface.h +++ b/sdk-overrides/include/user_interface.h @@ -6,11 +6,6 @@ bool wifi_softap_deauth(uint8 mac[6]); uint8 get_fpm_auto_sleep_flag(void); -enum ext_flash_size_map { - FLASH_SIZE_64M_MAP = 8, - FLASH_SIZE_128M_MAP = 9 -}; - //force sleep API #define FPM_SLEEP_MAX_TIME 268435455 //0xFFFFFFF void wifi_fpm_set_wakeup_cb(void (*fpm_wakeup_cb_func)(void));