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
This commit is contained in:
Arnim Läuger 2017-05-16 16:50:36 +02:00 committed by Marcel Stör
parent 447fcd397d
commit 4e4dfc1d88
10 changed files with 48 additions and 124 deletions

View File

@ -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

View File

@ -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");

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 <serial-port-of-ESP8266> erase_flash`
- Modules with flash chips larger than 4&nbsp;MByte (e.g. WeMos D1 mini pro) need to be manually configured to at least 1&nbsp;MByte: Firmware image and SDK init data occupy the first MByte, while the remaining 7/15&nbsp;MByte of the flash are used for SPIFFS:
`esptool.py --port <serial-port-of-ESP8266> write_flash -fm <mode> -fs 8m 0x00000 <nodemcu-firmware>.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.

View File

@ -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));