diff --git a/app/include/user_config.h b/app/include/user_config.h index 5f04a616..fd3228d4 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -12,12 +12,6 @@ #define FLASH_AUTOSIZE #define FLASH_SAFE_API -// Byte 107 of esp_init_data_default, only one of these 3 can be picked -#define ESP_INIT_DATA_ENABLE_READVDD33 -//#define ESP_INIT_DATA_ENABLE_READADC -//#define ESP_INIT_DATA_FIXED_VDD33_VALUE 33 -// - // 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 // without any harm (except for the code size increase and slight slowdown) diff --git a/app/modules/adc.c b/app/modules/adc.c index 15bf7de9..06068cd8 100644 --- a/app/modules/adc.c +++ b/app/modules/adc.c @@ -24,10 +24,49 @@ static int adc_readvdd33( lua_State* L ) return 1; } +// Lua: adc.force_init_mode(x) +static int adc_init107( lua_State *L ) +{ + uint8_t byte107 = luaL_checkinteger (L, 1); + + uint32 init_sector = flash_safe_get_sec_num () - 4; + + // 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 ( + init_sector * SPI_FLASH_SEC_SIZE, + (uint32 *)init_data, sizeof(init_data))) + return luaL_error(L, "flash read error"); + + // If it's already the correct value, we don't need to force it + if (init_data[107] == byte107) + { + lua_pushboolean (L, false); + return 1; + } + + // Nope, it differs, we need to rewrite it + init_data[107] = byte107; + if (SPI_FLASH_RESULT_OK != flash_safe_erase_sector (init_sector)) + return luaL_error(L, "flash erase error"); + + if (SPI_FLASH_RESULT_OK != flash_safe_write ( + init_sector * SPI_FLASH_SEC_SIZE, + (uint32 *)init_data, sizeof(init_data))) + return luaL_error(L, "flash write error"); + + lua_pushboolean (L, true); + return 1; +} + // Module function map static const LUA_REG_TYPE adc_map[] = { { LSTRKEY( "read" ), LFUNCVAL( adc_sample ) }, - { LSTRKEY( "readvdd33" ), LFUNCVAL( adc_readvdd33) }, + { LSTRKEY( "readvdd33" ), LFUNCVAL( adc_readvdd33 ) }, + { LSTRKEY( "force_init_mode" ), LFUNCVAL( adc_init107 ) }, + { LSTRKEY( "INIT_ADC" ), LNUMVAL( 0x00 ) }, + { LSTRKEY( "INIT_VDD33" ),LNUMVAL( 0xff ) }, { LNILKEY, LNILVAL } }; diff --git a/app/modules/node.c b/app/modules/node.c index b8419c06..251fb4c0 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -521,8 +521,6 @@ static int node_bootreason (lua_State *L) // Lua: restore() static int node_restore (lua_State *L) { - flash_init_data_default(); - flash_init_data_blank(); system_restore(); return 0; } diff --git a/app/platform/flash_api.c b/app/platform/flash_api.c index e23111ad..cb9ddac1 100644 --- a/app/platform/flash_api.c +++ b/app/platform/flash_api.c @@ -8,28 +8,6 @@ #include "spi_flash.h" #include "c_stdio.h" -#if defined(ESP_INIT_DATA_ENABLE_READVDD33) -# define INIT_107 0xff -#elif defined(ESP_INIT_DATA_ENABLE_READADC) -# define INIT_107 0x00 -#elif defined(ESP_INIT_DATA_FIXED_VDD33_VALUE) -# define INIT_107 ESP_INIT_DATA_FIXED_VDD33_VALUE -#else -# define INIT_107 0xff -#endif - -static const uint8_t flash_init_data[128] = -{ - 0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02, 0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05, - 0x04, 0xFE, 0xFD, 0xFF, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xE0, 0xE1, 0x0A, 0xFF, 0xFF, 0xF8, 0x00, - 0xF8, 0xF8, 0x52, 0x4E, 0x4A, 0x44, 0x40, 0x38, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE1, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, INIT_107, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - uint32_t flash_detect_size_byte(void) { #define FLASH_BUFFER_SIZE_DETECT 32 @@ -323,59 +301,6 @@ bool flash_rom_set_speed(uint32_t speed) return true; } -bool flash_init_data_default(void) -{ - /* Can't copy directly from flash (which is where the default data lives) - * due to it being unmapped during the write, so bounce via ram buffer. */ - uint8_t init_data[128]; - os_memcpy (init_data, flash_init_data, 128); - - // FLASH SEC - 4 - // Dangerous, here are dinosaur infested!!!!! - // Reboot required!!! - // It will init system data to default! - bool result = false; -#if defined(FLASH_SAFE_API) - if (SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_safe_get_sec_num() - 4))) - { - if (SPI_FLASH_RESULT_OK == flash_safe_write((flash_safe_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)init_data, 128)) - { - result = true; - } - } -#else - if (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_rom_get_sec_num() - 4))) - { - if (SPI_FLASH_RESULT_OK == spi_flash_write((flash_rom_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)init_data, 128)) - { - result = true; - } - } -#endif // defined(FLASH_SAFE_API) - return result; -} - -bool flash_init_data_blank(void) -{ - // FLASH SEC - 2 - // Dangerous, here are dinosaur infested!!!!! - // Reboot required!!! - // It will init system config to blank! - bool result = false; -#if defined(FLASH_SAFE_API) - if ((SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_safe_get_sec_num() - 2))) && - (SPI_FLASH_RESULT_OK == flash_safe_erase_sector((flash_safe_get_sec_num() - 1)))) -#else - if ((SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_rom_get_sec_num() - 2))) && - (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_rom_get_sec_num() - 1)))) -#endif // defined(FLASH_SAFE_API) - { - result = true; - } - - return result ; -} - uint8_t byte_of_aligned_array(const uint8_t *aligned_array, uint32_t index) { if ( (((uint32_t)aligned_array) % 4) != 0 ) diff --git a/app/platform/flash_api.h b/app/platform/flash_api.h index 32475361..0ce1d163 100644 --- a/app/platform/flash_api.h +++ b/app/platform/flash_api.h @@ -100,9 +100,6 @@ bool flash_rom_set_size_byte(uint32_t); uint16_t flash_rom_get_sec_num(void); uint8_t flash_rom_get_mode(void); uint32_t flash_rom_get_speed(void); -bool flash_init_data_written(void); -bool flash_init_data_default(void); -bool flash_init_data_blank(void); uint8_t byte_of_aligned_array(const uint8_t* aligned_array, uint32_t index); uint16_t word_of_aligned_array(const uint16_t *aligned_array, uint32_t index); // uint8_t flash_rom_get_checksum(void); diff --git a/app/user/user_main.c b/app/user/user_main.c index c4b9d367..aa6fdb93 100644 --- a/app/user/user_main.c +++ b/app/user/user_main.c @@ -33,13 +33,6 @@ static os_event_t *taskQueue; -/* Important: no_init_data CAN NOT be left as zero initialised, as that - * initialisation will happen after user_start_trampoline, but before - * the user_init, thus clobbering our state! - */ -static uint8_t no_init_data = 0xff; - - /* Note: the trampoline *must* be explicitly put into the .text segment, since * by the time it is invoked the irom has not yet been mapped. This naturally * also goes for anything the trampoline itself calls. @@ -55,29 +48,6 @@ void TEXT_SECTION_ATTR user_start_trampoline (void) rtctime_early_startup (); #endif - - /* Minimal early detection of missing esp_init_data. - * If it is missing, the SDK will write its own and thus we'd end up - * using that unless the flash size field is incorrect. This then leads - * to different esp_init_data being used depending on whether the user - * flashed with the right flash size or not (and the better option would - * be to flash with an *incorrect* flash size, counter-intuitively). - * To avoid that mess, we read out the flash size and do a test for - * esp_init_data based on that size. If it's missing, flag for later. - * If the flash size was incorrect, we'll end up fixing it all up - * anyway, so this ends up solving the conundrum. Only remaining issue - * is lack of spare code bytes in iram, so this is deliberately quite - * terse and not as readable as one might like. - */ - SPIFlashInfo sfi; - 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; - uint32_t flash_end_addr = (256 * 1024) << sfi.size; - uint32_t init_data_hdr = 0xffffffff; - SPIRead (flash_end_addr - 4 * SPI_FLASH_SEC_SIZE, &init_data_hdr, sizeof (init_data_hdr)); - no_init_data = (init_data_hdr == 0xffffffff); - call_user_start (); } @@ -119,8 +89,6 @@ void nodemcu_init(void) NODE_ERR("Self adjust flash size.\n"); // Fit hardware real flash size. flash_rom_set_size_byte(flash_safe_get_size_byte()); - // Write out init data at real location. - no_init_data = true; if( !fs_format() ) { @@ -131,20 +99,15 @@ void nodemcu_init(void) NODE_ERR( "format done.\n" ); } fs_unmount(); // mounted by format. + + // Reboot to get SDK to use (or write) init data at new location + system_restart (); + + // Don't post the start_lua task, we're about to reboot... + return; } #endif // defined(FLASH_SAFE_API) - if (no_init_data) - { - NODE_ERR("Restore init data.\n"); - // Flash init data at FLASHSIZE - 0x04000 Byte. - flash_init_data_default(); - // Flash blank data at FLASHSIZE - 0x02000 Byte. - flash_init_data_blank(); - // Reboot to make the new data come into effect - system_restart (); - } - #if defined ( BUILD_SPIFFS ) fs_mount(); // test_spiffs(); diff --git a/docs/en/modules/adc.md b/docs/en/modules/adc.md index 3906b703..b05b6850 100644 --- a/docs/en/modules/adc.md +++ b/docs/en/modules/adc.md @@ -1,13 +1,41 @@ # ADC Module | Since | Origin / Contributor | Maintainer | Source | | :----- | :-------------------- | :---------- | :------ | -| 2014-12-24 | [Zeroday](https://github.com/funshine) | [Zeroday](https://github.com/funshine) | [adc.c](../../../app/modules/adc.c)| +| 2014-12-24 | [Zeroday](https://github.com/funshine) | [jmattsson](https://github.com/jmattsson) | [adc.c](../../../app/modules/adc.c)| The ADC module provides access to the in-built ADC. -On the ESP8266 there is only a single-channel, which is multiplexed with the battery voltage. Depending on the setting in the "esp init data" (byte 107) one can either use the ADC to read an external voltage, or to read the system voltage, but not both. +On the ESP8266 there is only a single-channel, which is multiplexed with the battery voltage. Depending on the setting in the "esp init data" (byte 107) one can either use the ADC to read an external voltage, or to read the system voltage (vdd33), but not both. -The default setting in the NodeMCU firmware can be controlled via user_config.h at compile time, by defining one of ESP_INIT_DATA_ENABLE_READVDD33, ESP_INIT_DATA_ENABLE_READADC or ESP_INIT_DATA_FIXED_VDD33_VALUE. To change the setting at a later date, use Espressif's flash download tool to create a new init data block. +Which mode to use the ADC in can be configured via the `adc.force_init_mode()` function. Note that after switching from one to the other a system restart is required before the change takes effect. + +## adc.force_init_mode() + +Checks and if necessary reconfigures the ADC mode setting in the ESP init data block. + +####Syntax +`adc.force_init_mode(mode_value)` + +####Parameters +`mode_value` One of `adc.INIT_ADC` or `adc.INIT_VDD33`. + +####Returns +True if the function had to change the mode, false if the mode was already configured. On a true return the ESP needs to be restarted for the change to take effect. + +####Example +```lua +-- in you init.lua: +if adc.force_init_mode(adc.INIT_VDD33) +then + node.restart() + return -- don't bother continuing, the restart is scheduled +end + +print("System voltage (mV):", adc.readvdd33(0)) +``` + +####See also +[`node.restart()`](node.md#noderestart) ## adc.read() @@ -22,6 +50,8 @@ Samples the ADC. ####Returns the sampled value (number) +If the ESP8266 has been configured to use the ADC for reading the system voltage, this function will always return 65535. This is a hardware and/or SDK limitation. + ####Example ```lua val = adc.read(0) diff --git a/docs/en/modules/node.md b/docs/en/modules/node.md index 2a37fc2a..ebafaccb 100644 --- a/docs/en/modules/node.md +++ b/docs/en/modules/node.md @@ -315,9 +315,7 @@ none ## node.restore() -Restores system configuration to defaults. Erases all stored WiFi settings, and resets the "esp init data" to the defaults. This function is intended as a last-resort without having to reflash the ESP altogether. - -This also uses the SDK function `system_restore()`, which doesn't document precisely what it erases/restores. +Restores system configuration to defaults using the SDK function `system_restore()`, which doesn't document precisely what it erases/restores. #### Syntax `node.restore()`