From a75521bfe037d327065dd9efbdffc3b3ddafad45 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 22 May 2015 10:46:56 +0200 Subject: [PATCH 01/23] add __attribute__ format to Print::printf compiler now gives warnings by miss usage of printf --- cores/esp8266/Print.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/Print.h b/cores/esp8266/Print.h index 7366174f5a..a0df267c1f 100644 --- a/cores/esp8266/Print.h +++ b/cores/esp8266/Print.h @@ -63,7 +63,7 @@ class Print { return write((const uint8_t *) buffer, size); } - size_t printf(const char * format, ...); + size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3))); size_t print(const __FlashStringHelper *); size_t print(const String &); size_t print(const char[]); From d5f4819ff0c380071cc42993a379c757fdc811f2 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 24 May 2015 18:09:14 +0200 Subject: [PATCH 02/23] add link to arduinoWebSockets --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 373b645a4d..d62d1defab 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ Libraries that don't rely on low-level access to AVR registers should work well. - [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266. - [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266. - [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)). +- [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) - WebSocket Server and Client compatible with esp8266 (RFC6455) #### Upload via serial port #### Pick the correct serial port. From e74142d42d165fadab26a019b62f7e3a268fa213 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 00:15:38 +0200 Subject: [PATCH 03/23] add 2 compiler options from last SDK --- platform.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.txt b/platform.txt index e76b838ca2..571b18d501 100644 --- a/platform.txt +++ b/platform.txt @@ -16,7 +16,7 @@ compiler.sdk.path={runtime.platform.path}/tools/sdk/ compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" compiler.c.cmd=xtensa-lx106-elf-gcc -compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=c99 +compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -ffunction-sections -fdata-sections -MMD -std=c99 compiler.S.cmd=xtensa-lx106-elf-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD @@ -26,7 +26,7 @@ compiler.c.elf.cmd=xtensa-lx106-elf-gcc compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig compiler.cpp.cmd=xtensa-lx106-elf-g++ -compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD +compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -ffunction-sections -fdata-sections -std=c++11 -MMD compiler.as.cmd=xtensa-lx106-elf-as From 023e8fdf00511e345f0639e2ff4ad307c90927de Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 00:41:22 +0200 Subject: [PATCH 04/23] remove new flags again. they are usless. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -ffunction-sections -fdata-sections Place each function or data item into its own section in the output file if the target supports arbitrary sections. The name of the function or the name of the data item determines the section’s name in the output file. Use these options on systems where the linker can perform optimizations to improve locality of reference in the instruction space. Most systems using the ELF object format and SPARC processors running Solaris 2 have linkers with such optimizations. AIX may have these optimizations in the future. Only use these options when there are significant benefits from doing so. When you specify these options, the assembler and linker will create larger object and executable files and will also be slower. You will not be able to use gprof on all systems if you specify this option and you may have problems with debugging if you specify both this option and ‘-g’. --- platform.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform.txt b/platform.txt index 571b18d501..e76b838ca2 100644 --- a/platform.txt +++ b/platform.txt @@ -16,7 +16,7 @@ compiler.sdk.path={runtime.platform.path}/tools/sdk/ compiler.cpreprocessor.flags=-D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ "-I{compiler.sdk.path}/include" compiler.c.cmd=xtensa-lx106-elf-gcc -compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -ffunction-sections -fdata-sections -MMD -std=c99 +compiler.c.flags=-c -Os -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -falign-functions=4 -MMD -std=c99 compiler.S.cmd=xtensa-lx106-elf-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD @@ -26,7 +26,7 @@ compiler.c.elf.cmd=xtensa-lx106-elf-gcc compiler.c.elf.libs=-lm -lgcc -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp -lsmartconfig compiler.cpp.cmd=xtensa-lx106-elf-g++ -compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -ffunction-sections -fdata-sections -std=c++11 -MMD +compiler.cpp.flags=-c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -falign-functions=4 -std=c++11 -MMD compiler.as.cmd=xtensa-lx106-elf-as From 5a86c20f1e57509f80667908c7217e111208ad5a Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 09:46:34 +0200 Subject: [PATCH 05/23] add rssi function of new SDK 1.1.0 fix warning in hexdump and ESP8266WiFiMulti --- cores/esp8266/debug.cpp | 4 ++-- libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 5 +++++ libraries/ESP8266WiFi/src/ESP8266WiFi.h | 7 +++---- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cores/esp8266/debug.cpp b/cores/esp8266/debug.cpp index 68d3a6b82a..478fe7392d 100644 --- a/cores/esp8266/debug.cpp +++ b/cores/esp8266/debug.cpp @@ -22,10 +22,10 @@ #include "debug.h" void ICACHE_RAM_ATTR hexdump(uint8_t *mem, uint32_t len, uint8_t cols) { - os_printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", mem, len, len); + os_printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (size_t)mem, len, len); for(uint32_t i = 0; i < len; i++) { if(i % cols == 0) { - os_printf("\n[0x%08X] 0x%08X: ", mem, i); + os_printf("\n[0x%08X] 0x%08X: ", (size_t)mem, i); yield(); } os_printf("%02X ", *mem); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 31b4df1eb3..009cb69ef1 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -255,6 +255,11 @@ int32_t ESP8266WiFiClass::channel(void) { return wifi_get_channel(); } + +int32_t ESP8266WiFiClass::RSSI(void) { + return wifi_station_get_rssi(); +} + extern "C" { typedef STAILQ_HEAD(, bss_info) bss_info_head_t; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 386938c53f..5eb5c9b0fd 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -163,13 +163,12 @@ class ESP8266WiFiClass int32_t channel(void); /* - * Return the current network RSSI. Note: this is just a stub, there is no way to - * get the RSSI in the Espressif SDK yet. + * Return the current network RSSI. * - * return: RSSI value (currently 0) + * return: RSSI value */ - int32_t RSSI() { return 0; } + int32_t RSSI(); /* * Start scan WiFi networks available diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index e0a7ddeb22..e32f426f20 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -93,7 +93,7 @@ wl_status_t ESP8266WiFiMulti::run(void) { DEBUG_WIFI_MULTI(" "); } - DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan, rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*'); + DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*'); delay(0); } } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 9a412ebb19..3f2692a508 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -32,7 +32,7 @@ #undef max #include -//#define DEBUG_WIFI_MULTI(...) os_printf( __VA_ARGS__ ) +#define DEBUG_WIFI_MULTI(...) Serial1.printf( __VA_ARGS__ ) #ifndef DEBUG_WIFI_MULTI #define DEBUG_WIFI_MULTI(...) From 1d2b85ec0e41a1e23479a6a2dcd5346dc46b9fdc Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 09:49:15 +0200 Subject: [PATCH 06/23] disable DEBUG_WIFI_MULTI define --- libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 3f2692a508..63c180c313 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h @@ -32,7 +32,7 @@ #undef max #include -#define DEBUG_WIFI_MULTI(...) Serial1.printf( __VA_ARGS__ ) +//#define DEBUG_WIFI_MULTI(...) Serial1.printf( __VA_ARGS__ ) #ifndef DEBUG_WIFI_MULTI #define DEBUG_WIFI_MULTI(...) From dc52cf82c5f828e0846f652f45204e5b103f9474 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 11:15:29 +0200 Subject: [PATCH 07/23] read the rst reason from the SDK if stored. add String getResetInfo(void); and struct rst_info * getResetInfoPtr(void); --- cores/esp8266/Esp.cpp | 15 +++++++++++++++ cores/esp8266/Esp.h | 3 +++ cores/esp8266/core_esp8266_main.cpp | 11 +++++++++++ tools/sdk/include/user_interface.h | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 2a90355195..627fdcf2c8 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -22,6 +22,8 @@ extern "C" { #include "user_interface.h" + +extern struct rst_info resetInfo; } //extern "C" void ets_wdt_init(uint32_t val); @@ -279,3 +281,16 @@ uint32_t EspClass::getFlashChipSizeByChipId(void) { return 0; } } + +String EspClass::getResetInfo(void) { + if(resetInfo.reason != 0) { + char buff[150]; + sprintf(&buff[0], "Fatal exception:%d flag:%d epc1:0x%08x epc2:0x%08x epc3:0x%08x excvaddr:0x%08x depc:0x%08x", resetInfo.exccause, resetInfo.reason, resetInfo.epc1, resetInfo.epc2, resetInfo.epc3, resetInfo.excvaddr, resetInfo.depc); + return String(buff); + } + return String("flag: 0"); +} + +struct rst_info * EspClass::getResetInfoPtr(void) { + return &resetInfo; +} diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index 5e356459e1..ccefa0c5f7 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -98,6 +98,9 @@ class EspClass { FlashMode_t getFlashChipMode(void); uint32_t getFlashChipSizeByChipId(void); + String getResetInfo(void); + struct rst_info * getResetInfoPtr(void); + inline uint32_t getCycleCount(void); }; diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 34e436c880..16902b15cb 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -34,6 +34,8 @@ extern "C" { #define LOOP_TASK_PRIORITY 0 #define LOOP_QUEUE_SIZE 1 +struct rst_info resetInfo; + int atexit(void (*func)()) { return 0; } @@ -124,6 +126,15 @@ void user_rf_pre_init() { extern "C" { void user_init(void) { + uart_div_modify(0, UART_CLK_FREQ / (74480)); + + system_rtc_mem_read(0, &resetInfo, sizeof(struct rst_info)); + if(resetInfo.reason == WDT_RST_FLAG || resetInfo.reason == EXCEPTION_RST_FLAG) { + os_printf("Last Reset:\n - flag=%d\n - Fatal exception (%d):\n - epc1=0x%08x,epc2=0x%08x,epc3=0x%08x,excvaddr=0x%08x,depc=0x%08x\n", resetInfo.reason, resetInfo.exccause, resetInfo.epc1, resetInfo.epc2, resetInfo.epc3, resetInfo.excvaddr, resetInfo.depc); + } + struct rst_info info = { 0 }; + system_rtc_mem_write(0, &info, sizeof(struct rst_info)); + uart_div_modify(0, UART_CLK_FREQ / (115200)); init(); diff --git a/tools/sdk/include/user_interface.h b/tools/sdk/include/user_interface.h index 7f593e0eb7..7c4706dc4d 100644 --- a/tools/sdk/include/user_interface.h +++ b/tools/sdk/include/user_interface.h @@ -30,7 +30,7 @@ enum rst_reason { DEEP_SLEEP_AWAKE_FLAG = 4 }; -struct rst_info{ +struct rst_info { uint32 reason; uint32 exccause; uint32 epc1; From 5852c484ca2784aca640b10f937ab1a7fdc0ccb0 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 12:29:26 +0200 Subject: [PATCH 08/23] add ESP.eraseESPconfig() to erase the ESP SDK configuration (including wifi) improve WiFiMulti --- cores/esp8266/Esp.cpp | 22 +++++++++++++++++++ cores/esp8266/Esp.h | 2 ++ .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 627fdcf2c8..bf012afd5b 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -294,3 +294,25 @@ String EspClass::getResetInfo(void) { struct rst_info * EspClass::getResetInfoPtr(void) { return &resetInfo; } + +bool EspClass::eraseESPconfig(void) { + bool ret = true; + size_t cfgAddr = (ESP.getFlashChipSize() - 0x3000); + size_t cfgSize = (8*1024); + + noInterrupts(); + while(cfgSize) { + + if(spi_flash_erase_sector((cfgAddr / SPI_FLASH_SEC_SIZE)) != SPI_FLASH_RESULT_OK) { + ret = false; + } + + cfgSize -= SPI_FLASH_SEC_SIZE; + cfgAddr += SPI_FLASH_SEC_SIZE; + } + interrupts(); + + return ret; +} + + diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index ccefa0c5f7..9411dc5f0c 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -101,6 +101,8 @@ class EspClass { String getResetInfo(void); struct rst_info * getResetInfoPtr(void); + bool eraseESPconfig(void); + inline uint32_t getCycleCount(void); }; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index e32f426f20..7161c399c1 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -47,6 +47,10 @@ wl_status_t ESP8266WiFiMulti::run(void) { uint8 bestBSSID[6]; int32_t bestChannel; + DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n"); + WiFi.disconnect(); + + DEBUG_WIFI_MULTI("[WIFI] start scan\n"); // WiFi.scanNetworks will return the number of networks found int8_t n = WiFi.scanNetworks(); From 5a19cc24bf8cbddc4563da9fb4f843ea0dd2ec28 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 13:13:05 +0200 Subject: [PATCH 09/23] correct addr --- cores/esp8266/Esp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index bf012afd5b..946a8b3754 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -297,7 +297,7 @@ struct rst_info * EspClass::getResetInfoPtr(void) { bool EspClass::eraseESPconfig(void) { bool ret = true; - size_t cfgAddr = (ESP.getFlashChipSize() - 0x3000); + size_t cfgAddr = (ESP.getFlashChipSize() - 0x4000); size_t cfgSize = (8*1024); noInterrupts(); From 72ab7cd41cdf64013351daa409ce939d4d2bad08 Mon Sep 17 00:00:00 2001 From: moeur Date: Tue, 26 May 2015 07:55:56 -0700 Subject: [PATCH 10/23] Update NTPClient.ino Instead of hardwiring the IP address of one server into the program, look-up an IP address from the host name. This way you get a random server from the pool each time. --- libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino b/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino index 4a9771b5fd..a3fdaf49c3 100644 --- a/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino +++ b/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino @@ -27,7 +27,11 @@ char pass[] = "********"; // your network password unsigned int localPort = 2390; // local port to listen for UDP packets -IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server +/* Don't hardwire the IP address or we won't get the benefits of the pool. + * Lookup the IP address for the host name instead */ +//IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server +IPAddress timeServerIP; // time.nist.gov NTP server address +const char* ntpServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message @@ -65,6 +69,9 @@ void setup() void loop() { + //get a random server from the pool + WiFi.hostByName(ntpServerName, timeServerIP); + sendNTPpacket(timeServer); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); From 4dbb73b11cee8c45d4098284f28f41f5ea091cb8 Mon Sep 17 00:00:00 2001 From: Todd Treece Date: Wed, 27 May 2015 10:56:40 -0400 Subject: [PATCH 11/23] adds adafruit huzzah to boards.txt & adds adafruit variant --- boards.txt | 42 +++++++++++++++++++ variants/adafruit/pins_arduino.h | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 variants/adafruit/pins_arduino.h diff --git a/boards.txt b/boards.txt index fdf37d5700..3aca00ae97 100644 --- a/boards.txt +++ b/boards.txt @@ -282,6 +282,48 @@ nodemcuv2.menu.UploadSpeed.512000.upload.speed=512000 nodemcuv2.menu.UploadSpeed.921600=921600 nodemcuv2.menu.UploadSpeed.921600.upload.speed=921600 +############################################################## +huzzah.name=Adafruit HUZZAH ESP8266 + +huzzah.upload.tool=esptool +huzzah.upload.speed=115200 +huzzah.upload.resetmethod=ck +huzzah.upload.maximum_size=983040 +huzzah.upload.maximum_data_size=81920 +huzzah.upload.wait_for_upload_port=true +huzzah.serial.disableDTR=true +huzzah.serial.disableRTS=true + +huzzah.build.mcu=esp8266 +huzzah.build.f_cpu=80000000L +huzzah.build.board=ESP8266_ESP12 +huzzah.build.core=esp8266 +huzzah.build.variant=adafruit +huzzah.build.flash_mode=qio +huzzah.build.flash_size=4M +huzzah.build.flash_freq=40 +huzzah.build.flash_ld=eagle.flash.4m.ld +huzzah.build.spiffs_start=0x100000 +huzzah.build.spiffs_end=0x3FB000 +huzzah.build.spiffs_pagesize=256 +huzzah.build.spiffs_blocksize=8192 + +huzzah.menu.CpuFrequency.80=80 MHz +huzzah.menu.CpuFrequency.80.build.f_cpu=80000000L +huzzah.menu.CpuFrequency.160=160 MHz +huzzah.menu.CpuFrequency.160.build.f_cpu=160000000L + +huzzah.menu.UploadSpeed.115200=115200 +huzzah.menu.UploadSpeed.115200.upload.speed=115200 +huzzah.menu.UploadSpeed.9600=9600 +huzzah.menu.UploadSpeed.9600.upload.speed=9600 +huzzah.menu.UploadSpeed.57600=57600 +huzzah.menu.UploadSpeed.57600.upload.speed=57600 +huzzah.menu.UploadSpeed.256000=256000 +huzzah.menu.UploadSpeed.256000.upload.speed=256000 +huzzah.menu.UploadSpeed.921600=921600 +huzzah.menu.UploadSpeed.921600.upload.speed=921600 + ############################################################## # wifio.name=Wifio # diff --git a/variants/adafruit/pins_arduino.h b/variants/adafruit/pins_arduino.h new file mode 100644 index 0000000000..aeb20d43be --- /dev/null +++ b/variants/adafruit/pins_arduino.h @@ -0,0 +1,70 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + Modified for ESP8266 platform by Ivan Grokhotkov, 2014-2015. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#define EXTERNAL_NUM_INTERRUPTS 16 +#define NUM_DIGITAL_PINS 17 +#define NUM_ANALOG_INPUTS 1 + +#define analogInputToDigitalPin(p) ((p > 0)?NOT_A_PIN:0) +#define digitalPinToInterrupt(p) (((p) < EXTERNAL_NUM_INTERRUPTS)?p:NOT_A_PIN) +#define digitalPinHasPWM(p) (((p) < NUM_DIGITAL_PINS)?p:NOT_A_PIN) + +static const uint8_t SDA = 4; +static const uint8_t SCL = 5; + +static const uint8_t SS = 15; +static const uint8_t MOSI = 13; +static const uint8_t MISO = 12; +static const uint8_t SCK = 14; + +static const uint8_t BUILTIN_LED = 0; + +static const uint8_t A0 = 17; + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE_OPEN Serial + +#endif /* Pins_Arduino_h */ + From 883278ae4e142279405be90987762f9bb18aa38f Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 17:15:49 +0200 Subject: [PATCH 12/23] apply patch 1 for SDK v1.1.0 espressif: Here is a patch based on SDK_v1.1.0 resolved issues below: 1. SDK 1.1.0 may boot fail if SPI Flash speed is 80MHz. 2. Memory Leak in libssl when SSL connection fail. 3. Update smartconfig, please using it with the latest Espressif APP https://github.com/EspressifApp Sorry for the inconvenience. --- tools/sdk/changelog.txt | 10 ++++++++++ tools/sdk/lib/libmain.a | Bin 146208 -> 146112 bytes tools/sdk/lib/libsmartconfig.a | Bin 93140 -> 104942 bytes tools/sdk/lib/libssl.a | Bin 165002 -> 165086 bytes tools/sdk/version | 2 +- 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/sdk/changelog.txt b/tools/sdk/changelog.txt index ad750024a6..b3faa0773b 100644 --- a/tools/sdk/changelog.txt +++ b/tools/sdk/changelog.txt @@ -1,3 +1,13 @@ +esp_iot_sdk_v1.1.0_15_05_27_p1 Release Note +------------------------------------------- + +Here is a patch based on SDK_v1.1.0 resolved issues below: +1. SDK 1.1.0 may boot fail if SPI Flash speed is 80MHz. +2. Memory Leak in libssl when SSL connection fail. +3. Update smartconfig, please using it with the latest Espressif APP https://github.com/EspressifApp + +Sorry for the inconvenience. + esp_iot_sdk_v1.1.0_15_05_22 Release Note ---------------------------------------- Resolved Issues(Bugs below are eligible for Bug Bounty Program): diff --git a/tools/sdk/lib/libmain.a b/tools/sdk/lib/libmain.a index 5f1e03f7d37be301fe24eb25749ba1893ba5ed03..ec7bb4cdfa337bd5a668c5a87eea694b2af67a16 100644 GIT binary patch delta 6309 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 delta 6470 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 FzX4=2Mj`+J diff --git a/tools/sdk/lib/libsmartconfig.a b/tools/sdk/lib/libsmartconfig.a index fc2795df3bf4d06d42c9b0c2e97ba350163f6a13..b8feefc989de12f3a70d90b3956837667ea5e0a0 100644 GIT binary patch literal 104942 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∨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 Z={OiGMg758DavtqhH2{x#!6BBe*wM&A+G=c diff --git a/tools/sdk/lib/libssl.a b/tools/sdk/lib/libssl.a index 825f74db21fe688002cf09698d19b8e9feab9ecf..d68dc61bb1937a3ac4ba8476e61732d68d5e67c3 100644 GIT binary patch delta 27485 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

NjB(cB1o`LGOG~vjYL6j)4+j! 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 mT$UJ7^1fh2T delta 27522 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 diff --git a/tools/sdk/version b/tools/sdk/version index 9084fa2f71..a64d2ed43c 100644 --- a/tools/sdk/version +++ b/tools/sdk/version @@ -1 +1 @@ -1.1.0 +1.1.0_15_05_27_p1 \ No newline at end of file From c415ebe8b42dff7da390d905482da780b0bf79fd Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 17:31:45 +0200 Subject: [PATCH 13/23] add function to get the MAC / BSSID as String --- libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 41 +++++++++++++++++++++++ libraries/ESP8266WiFi/src/ESP8266WiFi.h | 23 +++++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 009cb69ef1..0f97e48a1b 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -203,12 +203,32 @@ uint8_t* ESP8266WiFiClass::macAddress(uint8_t* mac) return mac; } +String ESP8266WiFiClass::macAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = {0}; + wifi_get_macaddr(STATION_IF, mac); + + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + uint8_t* ESP8266WiFiClass::softAPmacAddress(uint8_t* mac) { wifi_get_macaddr(SOFTAP_IF, mac); return mac; } +String ESP8266WiFiClass::softAPmacAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = {0}; + wifi_get_macaddr(SOFTAP_IF, mac); + + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + IPAddress ESP8266WiFiClass::localIP() { struct ip_info ip; @@ -251,6 +271,16 @@ uint8_t* ESP8266WiFiClass::BSSID(void) return reinterpret_cast(conf.bssid); } +String ESP8266WiFiClass::BSSIDstr(void) +{ + static struct station_config conf; + char mac[18] = {0}; + wifi_station_get_config(&conf); + sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]); + return String(mac); +} + + int32_t ESP8266WiFiClass::channel(void) { return wifi_get_channel(); } @@ -358,6 +388,17 @@ uint8_t * ESP8266WiFiClass::BSSID(uint8_t i) return it->bssid; } +String ESP8266WiFiClass::BSSIDstr(uint8_t i) +{ + char mac[18] = {0}; + struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); + if (!it) + return String(""); + + sprintf(mac,"%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]); + return String(mac); +} + int32_t ESP8266WiFiClass::channel(uint8_t i) { struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 5eb5c9b0fd..0d6def8b3d 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -103,16 +103,19 @@ class ESP8266WiFiClass * Get the station interface MAC address. * * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * return: String */ uint8_t* macAddress(uint8_t* mac); + String macAddress(void); /* * Get the softAP interface MAC address. * * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + * return: String */ uint8_t* softAPmacAddress(uint8_t* mac); - + String softAPmacAddress(void); /* * Get the station interface IP address. * @@ -151,10 +154,17 @@ class ESP8266WiFiClass /* * Return the current bssid / mac associated with the network if configured * - * return: bssid string + * return: bssid uint8_t * */ uint8_t * BSSID(void); + /* + * Return the current bssid / mac associated with the network if configured + * + * return: bssid string + */ + String BSSIDstr(void); + /* * Return the current channel associated with the network * @@ -208,10 +218,17 @@ class ESP8266WiFiClass /** * return MAC / BSSID of scanned wifi * @param networkItem specify from which network item want to get the information - * @return uint8_t * to MAC / BSSID of scanned wifi + * @return uint8_t * MAC / BSSID of scanned wifi */ uint8_t * BSSID(uint8_t networkItem); + /** + * return MAC / BSSID of scanned wifi + * @param networkItem specify from which network item want to get the information + * @return String MAC / BSSID of scanned wifi + */ + String BSSIDstr(uint8_t networkItem); + /** * return channel of scanned wifi * @param networkItem specify from which network item want to get the information From 1d0a923292d3934084ef861aaab606912829f00e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 18:50:11 +0200 Subject: [PATCH 14/23] add missing include #include "ets_sys.h" --- cores/esp8266/core_esp8266_timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index bfdd3692cf..048f6fa876 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -21,6 +21,7 @@ #include "wiring_private.h" #include "pins_arduino.h" #include "c_types.h" +#include "ets_sys.h" void (*timer1_user_cb)(void); From f18bb28813581330e6cac65ef7bb09f8e121fc8b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 18:58:09 +0200 Subject: [PATCH 15/23] fix bug #343 add __attribute__ to printf functions for better compiler warning handling. remove ICACHE_FLASH_ATTR, all cpp files are automatic in FLASH (ld script) --- cores/esp8266/Arduino.h | 3 +- cores/esp8266/pgmspace.cpp | 58 ++++++++++++------------- cores/esp8266/pgmspace.h | 18 ++++---- libraries/ESP8266WiFi/src/ESP8266WiFi.h | 1 + tools/sdk/include/ets_sys.h | 4 +- 5 files changed, 43 insertions(+), 41 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 89dbff873f..9d3f18ed9e 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -35,7 +35,6 @@ extern "C" { #include "stdlib_noniso.h" #include "binary.h" -#include "pgmspace.h" #include "esp8266_peri.h" #include "twi.h" @@ -205,6 +204,8 @@ void loop(void); #ifdef __cplusplus +#include "pgmspace.h" + #include "WCharacter.h" #include "WString.h" diff --git a/cores/esp8266/pgmspace.cpp b/cores/esp8266/pgmspace.cpp index 84af6264b3..c2b5781f1f 100644 --- a/cores/esp8266/pgmspace.cpp +++ b/cores/esp8266/pgmspace.cpp @@ -1,32 +1,32 @@ /* -pgmspace.cpp - string functions that support PROGMEM -Copyright (c) 2015 Michael C. Miller. All right reserved. + pgmspace.cpp - string functions that support PROGMEM + Copyright (c) 2015 Michael C. Miller. All right reserved. -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include #include "pgmspace.h" -size_t ICACHE_FLASH_ATTR strnlen_P(const char* s, size_t size) { +size_t strnlen_P(const char* s, size_t size) { const char* cp; for (cp = s; size != 0 && pgm_read_byte(cp) != '\0'; cp++, size--); - return (size_t)(cp - s); + return (size_t) (cp - s); } -void* ICACHE_FLASH_ATTR memcpy_P(void* dest, const void* src, size_t count) { +void* memcpy_P(void* dest, const void* src, size_t count) { const uint8_t* read = reinterpret_cast(src); uint8_t* write = reinterpret_cast(dest); @@ -39,7 +39,7 @@ void* ICACHE_FLASH_ATTR memcpy_P(void* dest, const void* src, size_t count) { return dest; } -char* ICACHE_FLASH_ATTR strncpy_P(char* dest, const char* src, size_t size) { +char* strncpy_P(char* dest, const char* src, size_t size) { const char* read = src; char* write = dest; char ch = '.'; @@ -48,19 +48,19 @@ char* ICACHE_FLASH_ATTR strncpy_P(char* dest, const char* src, size_t size) { ch = pgm_read_byte(read++); *write++ = ch; size--; - } + } return dest; } -char* ICACHE_FLASH_ATTR strncat_P(char* dest, const char* src, size_t size) { +char* strncat_P(char* dest, const char* src, size_t size) { char* write = dest; while (*write != '\0') { write++; } - + const char* read = src; char ch = '.'; @@ -80,7 +80,7 @@ char* ICACHE_FLASH_ATTR strncat_P(char* dest, const char* src, size_t size) { return dest; } -int ICACHE_FLASH_ATTR strncmp_P(const char* str1, const char* str2P, size_t size) { +int strncmp_P(const char* str1, const char* str2P, size_t size) { int result = 0; while (size > 0) @@ -99,7 +99,7 @@ int ICACHE_FLASH_ATTR strncmp_P(const char* str1, const char* str2P, size_t size return result; } -int ICACHE_FLASH_ATTR strncasecmp_P(const char* str1, const char* str2P, size_t size) { +int strncasecmp_P(const char* str1, const char* str2P, size_t size) { int result = 0; while (size > 0) @@ -118,7 +118,7 @@ int ICACHE_FLASH_ATTR strncasecmp_P(const char* str1, const char* str2P, size_t return result; } -int ICACHE_FLASH_ATTR printf_P(const char* formatP, ...) { +int printf_P(const char* formatP, ...) { int ret; va_list arglist; va_start(arglist, formatP); @@ -129,13 +129,13 @@ int ICACHE_FLASH_ATTR printf_P(const char* formatP, ...) { ret = os_printf(format, arglist); - delete [] format; + delete[] format; va_end(arglist); return ret; } -int ICACHE_FLASH_ATTR snprintf_P(char* str, size_t strSize, const char* formatP, ...) { +int snprintf_P(char* str, size_t strSize, const char* formatP, ...) { int ret; va_list arglist; va_start(arglist, formatP); @@ -146,7 +146,7 @@ int ICACHE_FLASH_ATTR snprintf_P(char* str, size_t strSize, const char* formatP, return ret; } -int ICACHE_FLASH_ATTR vsnprintf_P(char* str, size_t strSize, const char* formatP, va_list ap) { +int vsnprintf_P(char* str, size_t strSize, const char* formatP, va_list ap) { int ret; size_t fmtLen = strlen_P(formatP); @@ -155,7 +155,7 @@ int ICACHE_FLASH_ATTR vsnprintf_P(char* str, size_t strSize, const char* formatP ret = ets_vsnprintf(str, strSize, format, ap); - delete [] format; + delete[] format; return ret; -} \ No newline at end of file +} diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index 695f2a50b9..e6db10fbda 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -32,26 +32,26 @@ typedef uint32_t prog_uint32_t; #define SIZE_IRRELEVANT 0x7fffffff -extern void* memcpy_P(void* dest, const void* src, size_t count); +void* memcpy_P(void* dest, const void* src, size_t count); -extern char* strncpy_P(char* dest, const char* src, size_t size); +char* strncpy_P(char* dest, const char* src, size_t size); #define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT) -extern char* strncat_P(char* dest, const char* src, size_t size); +char* strncat_P(char* dest, const char* src, size_t size); #define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT) -extern int strncmp_P(const char* str1, const char* str2P, size_t size); +int strncmp_P(const char* str1, const char* str2P, size_t size); #define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT) -extern int strncasecmp_P(const char* str1, const char* str2P, size_t size); +int strncasecmp_P(const char* str1, const char* str2P, size_t size); #define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT) -extern size_t strnlen_P(const char *s, size_t size); +size_t strnlen_P(const char *s, size_t size); #define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT) -extern int printf_P(const char *formatP, ...); -extern int snprintf_P(char *str, size_t strSize, const char *formatP, ...); -extern int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap); +int printf_P(const char *formatP, ...) __attribute__ ((format (printf, 1, 2))); +int snprintf_P(char *str, size_t strSize, const char *formatP, ...) __attribute__ ((format (printf, 3, 4))); +int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap) __attribute__ ((format (printf, 3, 0))); // flash memory must be read using 32 bit aligned addresses else a processor // exception will be triggered diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 0d6def8b3d..64563ad7e9 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -116,6 +116,7 @@ class ESP8266WiFiClass */ uint8_t* softAPmacAddress(uint8_t* mac); String softAPmacAddress(void); + /* * Get the station interface IP address. * diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index 7908699bb5..389918be4d 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -118,7 +118,7 @@ void ets_isr_unmask(int intr); void ets_isr_attach(int intr, int_handler_t handler, void *arg); void ets_intr_lock(); void ets_intr_unlock(); -int ets_vsnprintf(char * s, size_t n, const char * format, va_list arg); -int ets_vprintf(const char * format, va_list arg); +int ets_vsnprintf(char * s, size_t n, const char * format, va_list arg) __attribute__ ((format (printf, 3, 0))); +int ets_vprintf(const char * format, va_list arg) __attribute__ ((format (printf, 1, 0))); #endif /* _ETS_SYS_H */ From 4ad7f3bf0701fb56a266e9c9a0109faa5c8823bc Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:11 -0700 Subject: [PATCH 16/23] Revert "Fixed timer bug and cleaned up" This reverts commit cff57490feae778b68740e0ef878d4521ae4eb2b. --- cores/esp8266/Arduino.h | 4 ++-- cores/esp8266/Esp.h | 16 ++++++++++++++++ cores/esp8266/core_esp8266_timer.c | 10 ++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index dcaa47b09e..7ebc77b791 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -114,8 +114,8 @@ void timer1_write(uint32_t ticks); //maximum ticks 8388607 // it is auto-disabled when the compare value matches CCOUNT // it is auto-enabled when the compare value changes #define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;}))) -#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory") +#define timer0_read() (ESP.getCycleCompare0()) +#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) void timer0_isr_init(void); void timer0_attachInterrupt(void(*userFunc)(void)); diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index fc52371965..c887c89e92 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -99,6 +99,8 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); + inline uint32_t getCycleCompare0(void); + inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) @@ -108,6 +110,20 @@ uint32_t EspClass::getCycleCount(void) return ccount; } +// this returns a value in the range of (0 - 2^32) +uint32_t EspClass::getCycleCompare0(void) +{ + uint32_t count; + __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); + return count; +} + +// this takes a value in the range of (0 - 2^32) +void EspClass::setCycleCompare0(uint32_t count) +{ + __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); +} + extern EspClass ESP; #endif //ESP_H diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index b9b2f1256a..979ab0bfc1 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -22,9 +22,7 @@ #include "pins_arduino.h" #include "c_types.h" -typedef void(*_timercallback)(void); - -static volatile _timercallback timer1_user_cb = NULL; +void (*timer1_user_cb)(void); void timer1_isr_handler(void *para){ if((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable @@ -62,7 +60,7 @@ void timer1_disable(){ T1I = 0; } -static volatile _timercallback timer0_user_cb = NULL; +void(*timer0_user_cb)(void); void timer0_isr_handler(void *para){ if (timer0_user_cb) { @@ -75,11 +73,11 @@ void timer0_isr_init(){ } void timer0_attachInterrupt(void(*userFunc)(void)) { - timer0_user_cb = userFunc; + timer1_user_cb = userFunc; ETS_CCOMPARE0_ENABLE(); } void timer0_detachInterrupt() { - timer0_user_cb = NULL; + timer1_user_cb = NULL; ETS_CCOMPARE0_DISABLE(); } \ No newline at end of file From 897a61e84fe5ca9828331bba5c0df7b30a8ed84f Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:50 -0700 Subject: [PATCH 17/23] Revert "ETS_INTR_ENABLED & ETS_INT_PENDING as inline" This reverts commit 9560c67aa86659bd9f8210f807706e35b85ae9be. --- tools/sdk/include/ets_sys.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index e11e619708..3cdb51d2af 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -73,14 +73,12 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Fri, 29 May 2015 08:37:13 -0700 Subject: [PATCH 18/23] Revert "Expose Chip CCompare0 timer" This reverts commit 17b29fc437b8334c4d0089a7e576cc386687f361. --- cores/esp8266/Arduino.h | 18 ++---------------- cores/esp8266/Esp.h | 18 +----------------- cores/esp8266/core_esp8266_timer.c | 22 ---------------------- tools/sdk/include/ets_sys.h | 22 ---------------------- 4 files changed, 3 insertions(+), 77 deletions(-) diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 7ebc77b791..89dbff873f 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -107,20 +107,6 @@ void timer1_attachInterrupt(void (*userFunc)(void)); void timer1_detachInterrupt(void); void timer1_write(uint32_t ticks); //maximum ticks 8388607 -// timer0 is a special CPU timer that has very high resolution but with -// limited control. -// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter -// it does not support divide, type, or reload flags -// it is auto-disabled when the compare value matches CCOUNT -// it is auto-enabled when the compare value changes -#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM))) -#define timer0_read() (ESP.getCycleCompare0()) -#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) - -void timer0_isr_init(void); -void timer0_attachInterrupt(void(*userFunc)(void)); -void timer0_detachInterrupt(void); - // undefine stdlib's abs if encountered #ifdef abs #undef abs @@ -140,13 +126,13 @@ void ets_intr_unlock(); // level 15 will disable ALL interrupts, // level 0 will disable most software interrupts // -#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)) +#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) "; esync; isync; dsync" : "=a" (state)) #define xt_enable_interrupts(state) __asm__ __volatile__("wsr %0,ps; esync" :: "a" (state) : "memory") extern uint32_t interruptsState; #define interrupts() xt_enable_interrupts(interruptsState) -#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState)) +#define noInterrupts() __asm__ __volatile__("rsil %0,15; esync; isync; dsync" : "=a" (interruptsState)) #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index c887c89e92..5e356459e1 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -99,31 +99,15 @@ class EspClass { uint32_t getFlashChipSizeByChipId(void); inline uint32_t getCycleCount(void); - inline uint32_t getCycleCompare0(void); - inline void setCycleCompare0(uint32_t count); }; uint32_t EspClass::getCycleCount(void) { uint32_t ccount; - __asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount)); + __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); return ccount; } -// this returns a value in the range of (0 - 2^32) -uint32_t EspClass::getCycleCompare0(void) -{ - uint32_t count; - __asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count)); - return count; -} - -// this takes a value in the range of (0 - 2^32) -void EspClass::setCycleCompare0(uint32_t count) -{ - __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory"); -} - extern EspClass ESP; #endif //ESP_H diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index 979ab0bfc1..bfdd3692cf 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -59,25 +59,3 @@ void timer1_disable(){ T1C = 0; T1I = 0; } - -void(*timer0_user_cb)(void); - -void timer0_isr_handler(void *para){ - if (timer0_user_cb) { - timer0_user_cb(); - } -} - -void timer0_isr_init(){ - ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL); -} - -void timer0_attachInterrupt(void(*userFunc)(void)) { - timer1_user_cb = userFunc; - ETS_CCOMPARE0_ENABLE(); -} - -void timer0_detachInterrupt() { - timer1_user_cb = NULL; - ETS_CCOMPARE0_DISABLE(); -} \ No newline at end of file diff --git a/tools/sdk/include/ets_sys.h b/tools/sdk/include/ets_sys.h index 3cdb51d2af..7908699bb5 100644 --- a/tools/sdk/include/ets_sys.h +++ b/tools/sdk/include/ets_sys.h @@ -43,7 +43,6 @@ typedef void (*int_handler_t)(void*); #define ETS_GPIO_INUM 4 #define ETS_UART_INUM 5 #define ETS_UART1_INUM 5 -#define ETS_CCOMPARE0_INUM 6 #define ETS_FRC_TIMER1_INUM 9 /* use edge*/ #define ETS_INTR_LOCK() \ @@ -52,9 +51,6 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_UNLOCK() \ ets_intr_unlock() -#define ETS_CCOMPARE0_INTR_ATTACH(func, arg) \ - ets_isr_attach(ETS_CCOMPARE0_INUM, (int_handler_t)(func), (void *)(arg)) - #define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \ ets_isr_attach(ETS_FRC_TIMER1_INUM, (int_handler_t)(func), (void *)(arg)) @@ -73,18 +69,6 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Fri, 29 May 2015 08:57:00 -0700 Subject: [PATCH 19/23] strtok fix public strtok_r implementation --- cores/esp8266/libc_replacements.c | 83 ++++++++++++++++--------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/cores/esp8266/libc_replacements.c b/cores/esp8266/libc_replacements.c index 519ea233ae..39ee925a43 100644 --- a/cores/esp8266/libc_replacements.c +++ b/cores/esp8266/libc_replacements.c @@ -169,60 +169,65 @@ char* ICACHE_FLASH_ATTR strncat(char * dest, const char * src, size_t n) { return dest; } +char* ICACHE_FLASH_ATTR strtok_r(char* s, const char* delim, char** last) { + const char* spanp; + char* tok; + char c; + char sc; + + if (s == NULL && (s = *last) == NULL) { + return (NULL); + } -char* ICACHE_FLASH_ATTR strtok_r(char * str, const char * delimiters, char ** temp) { - static char * ret = NULL; - char * start = NULL; - char * end = NULL; - uint32_t size = 0; - if(str == NULL) { - if(temp == NULL) { - return NULL; + // Skip (span) leading delimiters + // +cont: + c = *s++; + for (spanp = delim; (sc = *spanp++) != 0;) { + if (c == sc) { + goto cont; } - start = *temp; - } else { - start = str; } - if(start == NULL) { - return NULL; + // check for no delimiters left + // + if (c == '\0') { + *last = NULL; + return (NULL); } - if(delimiters == NULL) { - return NULL; - } + tok = s - 1; - end = start; - while(1) { - for(uint16_t i = 0; i < strlen(delimiters); i++) { - if(*end == *(delimiters + i)) { - break; + // Scan token + // Note that delim must have one NUL; we stop if we see that, too. + // + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) { + s = NULL; + } + else { + s[-1] = '\0'; + } + *last = s; + return (tok); } - } - end++; - if(*end == 0x00) { - break; - } - } - *temp = end; - - if(ret != NULL) { - free(ret); + } while (sc != 0); } - size = (end - start); - ret = (char *) malloc(size); - strncpy(ret, start, size); - return ret; + // NOTREACHED EVER } -char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) { - static char * ret = NULL; - ret = strtok_r(str, delimiters, &ret); - return ret; +char* ICACHE_FLASH_ATTR strtok(char* s, const char* delim) { + static char* last; + + return (strtok_r(s, delim, &last)); } int ICACHE_FLASH_ATTR strcasecmp(const char * str1, const char * str2) { From 48e0d44860f338af6106988ffc296982c43c5bdf Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:27:03 +0300 Subject: [PATCH 20/23] Add eboot --- bootloaders/eboot/LICENSE | 26 +++ bootloaders/eboot/Makefile | 50 ++++++ bootloaders/eboot/eboot.c | 86 +++++++++ bootloaders/eboot/eboot.elf | Bin 0 -> 6358 bytes bootloaders/eboot/eboot.h | 41 +++++ bootloaders/eboot/eboot.ld | 176 ++++++++++++++++++ bootloaders/eboot/rom.ld | 344 ++++++++++++++++++++++++++++++++++++ 7 files changed, 723 insertions(+) create mode 100644 bootloaders/eboot/LICENSE create mode 100644 bootloaders/eboot/Makefile create mode 100644 bootloaders/eboot/eboot.c create mode 100755 bootloaders/eboot/eboot.elf create mode 100644 bootloaders/eboot/eboot.h create mode 100644 bootloaders/eboot/eboot.ld create mode 100755 bootloaders/eboot/rom.ld diff --git a/bootloaders/eboot/LICENSE b/bootloaders/eboot/LICENSE new file mode 100644 index 0000000000..d81a07e401 --- /dev/null +++ b/bootloaders/eboot/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2015 Ivan Grokhotkov +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. The name of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +Authors: Ivan Grokhotkov diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile new file mode 100644 index 0000000000..4ecc252f0b --- /dev/null +++ b/bootloaders/eboot/Makefile @@ -0,0 +1,50 @@ +XTENSA_TOOCHAIN ?= + +BIN_DIR := ./ +TARGET_DIR := ./ + +TARGET_OBJ_FILES := \ + eboot_debug.o \ + +TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) + +CC := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-gcc +CXX := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-g++ +AR := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-ar +LD := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-gcc +OBJDUMP := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-objdump + + +CFLAGS += -std=gnu99 + +CFLAGS += -O0 -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals + +LDFLAGS += -nostdlib -Wl,--no-check-sections -umain + +LD_SCRIPT := -Teboot.ld + +APP_OUT:= eboot.elf +APP_AR := eboot.a +APP_FW := eboot.bin + +all: $(APP_FW) + +$(APP_AR): $(TARGET_OBJ_PATHS) + $(AR) cru $@ $^ + + +$(APP_OUT): $(APP_AR) + $(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group -Wl,--whole-archive $(APP_AR) -Wl,--end-group -o $@ + +$(APP_FW): $(APP_OUT) + $(ESPTOOL) -vvv -eo $(APP_OUT) -bo $@ -bs .text -bs .data -bs .rodata -bc -ec || true + + +clean: + rm -f *.o + rm -f $(APP_AR) + rm -f $(APP_OUT) + + +.PHONY: all clean default + diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c new file mode 100644 index 0000000000..e39375d2d2 --- /dev/null +++ b/bootloaders/eboot/eboot.c @@ -0,0 +1,86 @@ +/* Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + * This file is part of eboot bootloader. + * + * Redistribution and use is permitted according to the conditions of the + * 3-clause BSD license to be found in the LICENSE file. + */ + + +#include +#include +#include +#include "eboot.h" +extern void* flashchip; + +#define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0); + + +int load_app_from_flash_raw(const uint32_t flash_addr) +{ + image_header_t image_header; + uint32_t pos = flash_addr + APP_START_OFFSET; + + if (SPIRead(pos, &image_header, sizeof(image_header))) { + return 1; + } + pos += sizeof(image_header); + + + for (uint32_t section_index = 0; + section_index < image_header.num_segments; + ++section_index) + { + section_header_t section_header = {0}; + if (SPIRead(pos, §ion_header, sizeof(section_header))) { + return 2; + } + pos += sizeof(section_header); + + const uint32_t address = section_header.address; + + bool load = false; + + if (address < 0x40000000) { + load = true; + } + + if (address >= 0x40100000 && address < 0x40108000) { + load = true; + } + + if (address >= 0x60000000) { + load = true; + } + + if (!load) { + pos += section_header.size; + continue; + } + + if (SPIRead(pos, (void*)address, section_header.size)) + return 3; + + pos += section_header.size; + } + + register uint32_t sp asm("a1") = 0x3ffffff0; + register uint32_t pc asm("a3") = image_header.entry; + __asm__ __volatile__ ("jx a3"); + + return 0; +} + + +void main() +{ + int res = load_app_from_flash_raw(0); + if (res) { + ets_putc('\n'); + ets_putc('#'); + ets_putc('0' + res); + ets_putc('\n'); + SWRST; + } + + while(true){} +} diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf new file mode 100755 index 0000000000000000000000000000000000000000..e2c2c492d82177cfcb34f38dcf2cced7242f48b3 GIT binary patch literal 6358 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 :dport0_0_phdr + + .dport0.literal : ALIGN(4) + { + _dport0_literal_start = ABSOLUTE(.); + *(.dport0.literal) + *(.dport.literal) + _dport0_literal_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .dport0.data : ALIGN(4) + { + _dport0_data_start = ABSOLUTE(.); + *(.dport0.data) + *(.dport.data) + _dport0_data_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .data : ALIGN(4) + { + _heap_start = ABSOLUTE(.); +/* _stack_sentry = ALIGN(0x8); */ + } >dram0_0_seg :dram0_0_bss_phdr +/* __stack = 0x3ffc8000; */ + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.entry.text) + *(.init.literal) + *(.init) + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + . = ALIGN (8); + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + . = ALIGN (8); + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + /* C++ constructor and destructor tables, properly ordered: */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); /* this table MUST be 4-byte aligned */ + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >iram1_0_seg :iram1_0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >iram1_0_seg :iram1_0_phdr + + .irom0.text : ALIGN(4) + { + _irom0_text_start = ABSOLUTE(.); + *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) + _irom0_text_end = ABSOLUTE(.); + } >irom0_0_seg :irom0_0_phdr +} + +/* get ROM code address */ +INCLUDE "rom.ld" diff --git a/bootloaders/eboot/rom.ld b/bootloaders/eboot/rom.ld new file mode 100755 index 0000000000..c5c1b65223 --- /dev/null +++ b/bootloaders/eboot/rom.ld @@ -0,0 +1,344 @@ +PROVIDE ( Cache_Read_Disable = 0x400047f0 ); +PROVIDE ( Cache_Read_Enable = 0x40004678 ); +PROVIDE ( FilePacketSendReqMsgProc = 0x400035a0 ); +PROVIDE ( FlashDwnLdParamCfgMsgProc = 0x4000368c ); +PROVIDE ( FlashDwnLdStartMsgProc = 0x40003538 ); +PROVIDE ( FlashDwnLdStopReqMsgProc = 0x40003658 ); +PROVIDE ( GetUartDevice = 0x40003f4c ); +PROVIDE ( MD5Final = 0x40009900 ); +PROVIDE ( MD5Init = 0x40009818 ); +PROVIDE ( MD5Update = 0x40009834 ); +PROVIDE ( MemDwnLdStartMsgProc = 0x400036c4 ); +PROVIDE ( MemDwnLdStopReqMsgProc = 0x4000377c ); +PROVIDE ( MemPacketSendReqMsgProc = 0x400036f0 ); +PROVIDE ( RcvMsg = 0x40003eac ); +PROVIDE ( SHA1Final = 0x4000b648 ); +PROVIDE ( SHA1Init = 0x4000b584 ); +PROVIDE ( SHA1Transform = 0x4000a364 ); +PROVIDE ( SHA1Update = 0x4000b5a8 ); +PROVIDE ( Wait_SPI_Idle = 0x4000448c ); +PROVIDE ( SPIEraseArea = 0x40004b44 ); +PROVIDE ( SPIEraseBlock = 0x400049b4 ); +PROVIDE ( SPIEraseChip = 0x40004984 ); +PROVIDE ( SPIEraseSector = 0x40004a00 ); +PROVIDE ( SPILock = 0x400048a8 ); +PROVIDE ( SPIParamCfg = 0x40004c2c ); +PROVIDE ( SPIRead = 0x40004b1c ); +PROVIDE ( SPIReadModeCnfig = 0x400048ec ); +PROVIDE ( SPIUnlock = 0x40004878 ); +PROVIDE ( SPIWrite = 0x40004a4c ); +PROVIDE ( SelectSpiFunction = 0x40003f58 ); +PROVIDE ( SendMsg = 0x40003cf4 ); +PROVIDE ( UartConnCheck = 0x40003230 ); +PROVIDE ( UartConnectProc = 0x400037a0 ); +PROVIDE ( UartDwnLdProc = 0x40003368 ); +PROVIDE ( UartGetCmdLn = 0x40003ef4 ); +PROVIDE ( UartRegReadProc = 0x4000381c ); +PROVIDE ( UartRegWriteProc = 0x400037ac ); +PROVIDE ( UartRxString = 0x40003c30 ); +PROVIDE ( Uart_Init = 0x40003a14 ); +PROVIDE ( _DebugExceptionVector = 0x40000010 ); +PROVIDE ( _DoubleExceptionVector = 0x40000070 ); +PROVIDE ( _KernelExceptionVector = 0x40000030 ); +PROVIDE ( _NMIExceptionVector = 0x40000020 ); +PROVIDE ( _ResetHandler = 0x400000a4 ); +PROVIDE ( _ResetVector = 0x40000080 ); +PROVIDE ( _UserExceptionVector = 0x40000050 ); +PROVIDE ( __adddf3 = 0x4000c538 ); +PROVIDE ( __addsf3 = 0x4000c180 ); +PROVIDE ( __divdf3 = 0x4000cb94 ); +PROVIDE ( __divdi3 = 0x4000ce60 ); +PROVIDE ( __divsi3 = 0x4000dc88 ); +PROVIDE ( __extendsfdf2 = 0x4000cdfc ); +PROVIDE ( __fixdfsi = 0x4000ccb8 ); +PROVIDE ( __fixunsdfsi = 0x4000cd00 ); +PROVIDE ( __fixunssfsi = 0x4000c4c4 ); +PROVIDE ( __floatsidf = 0x4000e2f0 ); +PROVIDE ( __floatsisf = 0x4000e2ac ); +PROVIDE ( __floatunsidf = 0x4000e2e8 ); +PROVIDE ( __floatunsisf = 0x4000e2a4 ); +PROVIDE ( __muldf3 = 0x4000c8f0 ); +PROVIDE ( __muldi3 = 0x40000650 ); +PROVIDE ( __mulsf3 = 0x4000c3dc ); +PROVIDE ( __subdf3 = 0x4000c688 ); +PROVIDE ( __subsf3 = 0x4000c268 ); +PROVIDE ( __truncdfsf2 = 0x4000cd5c ); +PROVIDE ( __udivdi3 = 0x4000d310 ); +PROVIDE ( __udivsi3 = 0x4000e21c ); +PROVIDE ( __umoddi3 = 0x4000d770 ); +PROVIDE ( __umodsi3 = 0x4000e268 ); +PROVIDE ( __umulsidi3 = 0x4000dcf0 ); +PROVIDE ( _rom_store = 0x4000e388 ); +PROVIDE ( _rom_store_table = 0x4000e328 ); +PROVIDE ( _start = 0x4000042c ); +PROVIDE ( _xtos_alloca_handler = 0x4000dbe0 ); +PROVIDE ( _xtos_c_wrapper_handler = 0x40000598 ); +PROVIDE ( _xtos_cause3_handler = 0x40000590 ); +PROVIDE ( _xtos_ints_off = 0x4000bda4 ); +PROVIDE ( _xtos_ints_on = 0x4000bd84 ); +PROVIDE ( _xtos_l1int_handler = 0x4000048c ); +PROVIDE ( _xtos_p_none = 0x4000dbf8 ); +PROVIDE ( _xtos_restore_intlevel = 0x4000056c ); +PROVIDE ( _xtos_return_from_exc = 0x4000dc54 ); +PROVIDE ( _xtos_set_exception_handler = 0x40000454 ); +PROVIDE ( _xtos_set_interrupt_handler = 0x4000bd70 ); +PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bd28 ); +PROVIDE ( _xtos_set_intlevel = 0x4000dbfc ); +PROVIDE ( _xtos_set_min_intlevel = 0x4000dc18 ); +PROVIDE ( _xtos_set_vpri = 0x40000574 ); +PROVIDE ( _xtos_syscall_handler = 0x4000dbe4 ); +PROVIDE ( _xtos_unhandled_exception = 0x4000dc44 ); +PROVIDE ( _xtos_unhandled_interrupt = 0x4000dc3c ); +PROVIDE ( aes_decrypt = 0x400092d4 ); +PROVIDE ( aes_decrypt_deinit = 0x400092e4 ); +PROVIDE ( aes_decrypt_init = 0x40008ea4 ); +PROVIDE ( aes_unwrap = 0x40009410 ); +PROVIDE ( base64_decode = 0x40009648 ); +PROVIDE ( base64_encode = 0x400094fc ); +PROVIDE ( bzero = 0x4000de84 ); +PROVIDE ( cmd_parse = 0x40000814 ); +PROVIDE ( conv_str_decimal = 0x40000b24 ); +PROVIDE ( conv_str_hex = 0x40000cb8 ); +PROVIDE ( convert_para_str = 0x40000a60 ); +PROVIDE ( dtm_get_intr_mask = 0x400026d0 ); +PROVIDE ( dtm_params_init = 0x4000269c ); +PROVIDE ( dtm_set_intr_mask = 0x400026c8 ); +PROVIDE ( dtm_set_params = 0x400026dc ); +PROVIDE ( eprintf = 0x40001d14 ); +PROVIDE ( eprintf_init_buf = 0x40001cb8 ); +PROVIDE ( eprintf_to_host = 0x40001d48 ); +PROVIDE ( est_get_printf_buf_remain_len = 0x40002494 ); +PROVIDE ( est_reset_printf_buf_len = 0x4000249c ); +PROVIDE ( ets_bzero = 0x40002ae8 ); +PROVIDE ( ets_char2xdigit = 0x40002b74 ); +PROVIDE ( ets_delay_us = 0x40002ecc ); +PROVIDE ( ets_enter_sleep = 0x400027b8 ); +PROVIDE ( ets_external_printf = 0x40002578 ); +PROVIDE ( ets_get_cpu_frequency = 0x40002f0c ); +PROVIDE ( ets_getc = 0x40002bcc ); +PROVIDE ( ets_install_external_printf = 0x40002450 ); +PROVIDE ( ets_install_putc1 = 0x4000242c ); +PROVIDE ( ets_install_putc2 = 0x4000248c ); +PROVIDE ( ets_install_uart_printf = 0x40002438 ); +PROVIDE ( ets_intr_lock = 0x40000f74 ); +PROVIDE ( ets_intr_unlock = 0x40000f80 ); +PROVIDE ( ets_isr_attach = 0x40000f88 ); +PROVIDE ( ets_isr_mask = 0x40000f98 ); +PROVIDE ( ets_isr_unmask = 0x40000fa8 ); +PROVIDE ( ets_memcmp = 0x400018d4 ); +PROVIDE ( ets_memcpy = 0x400018b4 ); +PROVIDE ( ets_memmove = 0x400018c4 ); +PROVIDE ( ets_memset = 0x400018a4 ); +PROVIDE ( ets_post = 0x40000e24 ); +PROVIDE ( ets_printf = 0x400024cc ); +PROVIDE ( ets_putc = 0x40002be8 ); +PROVIDE ( ets_rtc_int_register = 0x40002a40 ); +PROVIDE ( ets_run = 0x40000e04 ); +PROVIDE ( ets_set_idle_cb = 0x40000dc0 ); +PROVIDE ( ets_set_user_start = 0x40000fbc ); +PROVIDE ( ets_str2macaddr = 0x40002af8 ); +PROVIDE ( ets_strcmp = 0x40002aa8 ); +PROVIDE ( ets_strcpy = 0x40002a88 ); +PROVIDE ( ets_strlen = 0x40002ac8 ); +PROVIDE ( ets_strncmp = 0x40002ab8 ); +PROVIDE ( ets_strncpy = 0x40002a98 ); +PROVIDE ( ets_strstr = 0x40002ad8 ); +PROVIDE ( ets_task = 0x40000dd0 ); +PROVIDE ( ets_timer_arm = 0x40002cc4 ); +PROVIDE ( ets_timer_disarm = 0x40002d40 ); +PROVIDE ( ets_timer_done = 0x40002d80 ); +PROVIDE ( ets_timer_handler_isr = 0x40002da8 ); +PROVIDE ( ets_timer_init = 0x40002e68 ); +PROVIDE ( ets_timer_setfn = 0x40002c48 ); +PROVIDE ( ets_uart_printf = 0x40002544 ); +PROVIDE ( ets_update_cpu_frequency = 0x40002f04 ); +PROVIDE ( ets_vprintf = 0x40001f00 ); +PROVIDE ( ets_wdt_disable = 0x400030f0 ); +PROVIDE ( ets_wdt_enable = 0x40002fa0 ); +PROVIDE ( ets_wdt_get_mode = 0x40002f34 ); +PROVIDE ( ets_wdt_init = 0x40003170 ); +PROVIDE ( ets_wdt_restore = 0x40003158 ); +PROVIDE ( ets_write_char = 0x40001da0 ); +PROVIDE ( get_first_seg = 0x4000091c ); +PROVIDE ( gpio_init = 0x40004c50 ); +PROVIDE ( gpio_input_get = 0x40004cf0 ); +PROVIDE ( gpio_intr_ack = 0x40004dcc ); +PROVIDE ( gpio_intr_handler_register = 0x40004e28 ); +PROVIDE ( gpio_intr_pending = 0x40004d88 ); +PROVIDE ( gpio_intr_test = 0x40004efc ); +PROVIDE ( gpio_output_set = 0x40004cd0 ); +PROVIDE ( gpio_pin_intr_state_set = 0x40004d90 ); +PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 ); +PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 ); +PROVIDE ( gpio_register_get = 0x40004d5c ); +PROVIDE ( gpio_register_set = 0x40004d04 ); +PROVIDE ( hmac_md5 = 0x4000a2cc ); +PROVIDE ( hmac_md5_vector = 0x4000a160 ); +PROVIDE ( hmac_sha1 = 0x4000ba28 ); +PROVIDE ( hmac_sha1_vector = 0x4000b8b4 ); +PROVIDE ( lldesc_build_chain = 0x40004f40 ); +PROVIDE ( lldesc_num2link = 0x40005050 ); +PROVIDE ( lldesc_set_owner = 0x4000507c ); +PROVIDE ( main = 0x40000fec ); +PROVIDE ( md5_vector = 0x400097ac ); +PROVIDE ( mem_calloc = 0x40001c2c ); +PROVIDE ( mem_free = 0x400019e0 ); +PROVIDE ( mem_init = 0x40001998 ); +PROVIDE ( mem_malloc = 0x40001b40 ); +PROVIDE ( mem_realloc = 0x40001c6c ); +PROVIDE ( mem_trim = 0x40001a14 ); +PROVIDE ( mem_zalloc = 0x40001c58 ); +PROVIDE ( memcmp = 0x4000dea8 ); +PROVIDE ( memcpy = 0x4000df48 ); +PROVIDE ( memmove = 0x4000e04c ); +PROVIDE ( memset = 0x4000e190 ); +PROVIDE ( multofup = 0x400031c0 ); +PROVIDE ( pbkdf2_sha1 = 0x4000b840 ); +PROVIDE ( phy_get_romfuncs = 0x40006b08 ); +PROVIDE ( rand = 0x40000600 ); +PROVIDE ( rc4_skip = 0x4000dd68 ); +PROVIDE ( recv_packet = 0x40003d08 ); +PROVIDE ( remove_head_space = 0x40000a04 ); +PROVIDE ( rijndaelKeySetupDec = 0x40008dd0 ); +PROVIDE ( rijndaelKeySetupEnc = 0x40009300 ); +PROVIDE ( rom_abs_temp = 0x400060c0 ); +PROVIDE ( rom_ana_inf_gating_en = 0x40006b10 ); +PROVIDE ( rom_cal_tos_v50 = 0x40007a28 ); +PROVIDE ( rom_chip_50_set_channel = 0x40006f84 ); +PROVIDE ( rom_chip_v5_disable_cca = 0x400060d0 ); +PROVIDE ( rom_chip_v5_enable_cca = 0x400060ec ); +PROVIDE ( rom_chip_v5_rx_init = 0x4000711c ); +PROVIDE ( rom_chip_v5_sense_backoff = 0x4000610c ); +PROVIDE ( rom_chip_v5_tx_init = 0x4000718c ); +PROVIDE ( rom_dc_iq_est = 0x4000615c ); +PROVIDE ( rom_en_pwdet = 0x400061b8 ); +PROVIDE ( rom_get_bb_atten = 0x40006238 ); +PROVIDE ( rom_get_corr_power = 0x40006260 ); +PROVIDE ( rom_get_fm_sar_dout = 0x400062dc ); +PROVIDE ( rom_get_noisefloor = 0x40006394 ); +PROVIDE ( rom_get_power_db = 0x400063b0 ); +PROVIDE ( rom_i2c_readReg = 0x40007268 ); +PROVIDE ( rom_i2c_readReg_Mask = 0x4000729c ); +PROVIDE ( rom_i2c_writeReg = 0x400072d8 ); +PROVIDE ( rom_i2c_writeReg_Mask = 0x4000730c ); +PROVIDE ( rom_iq_est_disable = 0x40006400 ); +PROVIDE ( rom_iq_est_enable = 0x40006430 ); +PROVIDE ( rom_linear_to_db = 0x40006484 ); +PROVIDE ( rom_mhz2ieee = 0x400065a4 ); +PROVIDE ( rom_pbus_dco___SA2 = 0x40007bf0 ); +PROVIDE ( rom_pbus_debugmode = 0x4000737c ); +PROVIDE ( rom_pbus_enter_debugmode = 0x40007410 ); +PROVIDE ( rom_pbus_exit_debugmode = 0x40007448 ); +PROVIDE ( rom_pbus_force_test = 0x4000747c ); +PROVIDE ( rom_pbus_rd = 0x400074d8 ); +PROVIDE ( rom_pbus_set_rxgain = 0x4000754c ); +PROVIDE ( rom_pbus_set_txgain = 0x40007610 ); +PROVIDE ( rom_pbus_workmode = 0x40007648 ); +PROVIDE ( rom_pbus_xpd_rx_off = 0x40007688 ); +PROVIDE ( rom_pbus_xpd_rx_on = 0x400076cc ); +PROVIDE ( rom_pbus_xpd_tx_off = 0x400076fc ); +PROVIDE ( rom_pbus_xpd_tx_on = 0x40007740 ); +PROVIDE ( rom_pbus_xpd_tx_on__low_gain = 0x400077a0 ); +PROVIDE ( rom_phy_reset_req = 0x40007804 ); +PROVIDE ( rom_restart_cal = 0x4000781c ); +PROVIDE ( rom_rfcal_pwrctrl = 0x40007eb4 ); +PROVIDE ( rom_rfcal_rxiq = 0x4000804c ); +PROVIDE ( rom_rfcal_rxiq_set_reg = 0x40008264 ); +PROVIDE ( rom_rfcal_txcap = 0x40008388 ); +PROVIDE ( rom_rfcal_txiq = 0x40008610 ); +PROVIDE ( rom_rfcal_txiq_cover = 0x400088b8 ); +PROVIDE ( rom_rfcal_txiq_set_reg = 0x40008a70 ); +PROVIDE ( rom_rfpll_reset = 0x40007868 ); +PROVIDE ( rom_rfpll_set_freq = 0x40007968 ); +PROVIDE ( rom_rxiq_cover_mg_mp = 0x40008b6c ); +PROVIDE ( rom_rxiq_get_mis = 0x40006628 ); +PROVIDE ( rom_sar_init = 0x40006738 ); +PROVIDE ( rom_set_ana_inf_tx_scale = 0x4000678c ); +PROVIDE ( rom_set_channel_freq = 0x40006c50 ); +PROVIDE ( rom_set_loopback_gain = 0x400067c8 ); +PROVIDE ( rom_set_noise_floor = 0x40006830 ); +PROVIDE ( rom_set_rxclk_en = 0x40006550 ); +PROVIDE ( rom_set_txbb_atten = 0x40008c6c ); +PROVIDE ( rom_set_txclk_en = 0x4000650c ); +PROVIDE ( rom_set_txiq_cal = 0x40008d34 ); +PROVIDE ( rom_start_noisefloor = 0x40006874 ); +PROVIDE ( rom_start_tx_tone = 0x400068b4 ); +PROVIDE ( rom_stop_tx_tone = 0x4000698c ); +PROVIDE ( rom_tx_mac_disable = 0x40006a98 ); +PROVIDE ( rom_tx_mac_enable = 0x40006ad4 ); +PROVIDE ( rom_txtone_linear_pwr = 0x40006a1c ); +PROVIDE ( rom_write_rfpll_sdm = 0x400078dc ); +PROVIDE ( roundup2 = 0x400031b4 ); +PROVIDE ( rtc_enter_sleep = 0x40002870 ); +PROVIDE ( rtc_get_reset_reason = 0x400025e0 ); +PROVIDE ( rtc_intr_handler = 0x400029ec ); +PROVIDE ( rtc_set_sleep_mode = 0x40002668 ); +PROVIDE ( save_rxbcn_mactime = 0x400027a4 ); +PROVIDE ( save_tsf_us = 0x400027ac ); +PROVIDE ( send_packet = 0x40003c80 ); +PROVIDE ( sha1_prf = 0x4000ba48 ); +PROVIDE ( sha1_vector = 0x4000a2ec ); +PROVIDE ( sip_alloc_to_host_evt = 0x40005180 ); +PROVIDE ( sip_get_ptr = 0x400058a8 ); +PROVIDE ( sip_get_state = 0x40005668 ); +PROVIDE ( sip_init_attach = 0x4000567c ); +PROVIDE ( sip_install_rx_ctrl_cb = 0x4000544c ); +PROVIDE ( sip_install_rx_data_cb = 0x4000545c ); +PROVIDE ( sip_post = 0x400050fc ); +PROVIDE ( sip_post_init = 0x400056c4 ); +PROVIDE ( sip_reclaim_from_host_cmd = 0x4000534c ); +PROVIDE ( sip_reclaim_tx_data_pkt = 0x400052c0 ); +PROVIDE ( sip_send = 0x40005808 ); +PROVIDE ( sip_to_host_chain_append = 0x40005864 ); +PROVIDE ( sip_to_host_evt_send_done = 0x40005234 ); +PROVIDE ( slc_add_credits = 0x400060ac ); +PROVIDE ( slc_enable = 0x40005d90 ); +PROVIDE ( slc_from_host_chain_fetch = 0x40005f24 ); +PROVIDE ( slc_from_host_chain_recycle = 0x40005e94 ); +PROVIDE ( slc_init_attach = 0x40005c50 ); +PROVIDE ( slc_init_credit = 0x4000608c ); +PROVIDE ( slc_pause_from_host = 0x40006014 ); +PROVIDE ( slc_reattach = 0x40005c1c ); +PROVIDE ( slc_resume_from_host = 0x4000603c ); +PROVIDE ( slc_select_tohost_gpio = 0x40005dc0 ); +PROVIDE ( slc_select_tohost_gpio_mode = 0x40005db8 ); +PROVIDE ( slc_send_to_host_chain = 0x40005de4 ); +PROVIDE ( slc_set_host_io_max_window = 0x40006068 ); +PROVIDE ( slc_to_host_chain_recycle = 0x40005f10 ); +PROVIDE ( software_reset = 0x4000264c ); +PROVIDE ( spi_flash_attach = 0x40004644 ); +PROVIDE ( srand = 0x400005f0 ); +PROVIDE ( strcmp = 0x4000bdc8 ); +PROVIDE ( strcpy = 0x4000bec8 ); +PROVIDE ( strlen = 0x4000bf4c ); +PROVIDE ( strncmp = 0x4000bfa8 ); +PROVIDE ( strncpy = 0x4000c0a0 ); +PROVIDE ( strstr = 0x4000e1e0 ); +PROVIDE ( timer_insert = 0x40002c64 ); +PROVIDE ( uartAttach = 0x4000383c ); +PROVIDE ( uart_baudrate_detect = 0x40003924 ); +PROVIDE ( uart_buff_switch = 0x400038a4 ); +PROVIDE ( uart_div_modify = 0x400039d8 ); +PROVIDE ( uart_rx_intr_handler = 0x40003bbc ); +PROVIDE ( uart_rx_one_char = 0x40003b8c ); +PROVIDE ( uart_rx_one_char_block = 0x40003b64 ); +PROVIDE ( uart_rx_readbuff = 0x40003ec8 ); +PROVIDE ( uart_tx_one_char = 0x40003b30 ); +PROVIDE ( wepkey_128 = 0x4000bc40 ); +PROVIDE ( wepkey_64 = 0x4000bb3c ); +PROVIDE ( xthal_bcopy = 0x40000688 ); +PROVIDE ( xthal_copy123 = 0x4000074c ); +PROVIDE ( xthal_get_ccompare = 0x4000dd4c ); +PROVIDE ( xthal_get_ccount = 0x4000dd38 ); +PROVIDE ( xthal_get_interrupt = 0x4000dd58 ); +PROVIDE ( xthal_get_intread = 0x4000dd58 ); +PROVIDE ( xthal_memcpy = 0x400006c4 ); +PROVIDE ( xthal_set_ccompare = 0x4000dd40 ); +PROVIDE ( xthal_set_intclear = 0x4000dd60 ); +PROVIDE ( xthal_spill_registers_into_stack_nw = 0x4000e320 ); +PROVIDE ( xthal_window_spill = 0x4000e324 ); +PROVIDE ( xthal_window_spill_nw = 0x4000e320 ); + +PROVIDE ( Te0 = 0x3fffccf0 ); +PROVIDE ( UartDev = 0x3fffde10 ); +PROVIDE ( flashchip = 0x3fffc714); From de28edb82fd7abf19a917d5a14260b94ab67ceec Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:35:31 +0300 Subject: [PATCH 21/23] Fix eboot makefile --- bootloaders/eboot/Makefile | 2 +- bootloaders/eboot/eboot.elf | Bin 6358 -> 5209 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile index 4ecc252f0b..32e325f34b 100644 --- a/bootloaders/eboot/Makefile +++ b/bootloaders/eboot/Makefile @@ -4,7 +4,7 @@ BIN_DIR := ./ TARGET_DIR := ./ TARGET_OBJ_FILES := \ - eboot_debug.o \ + eboot.o \ TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index e2c2c492d82177cfcb34f38dcf2cced7242f48b3..b2381a4098690e025f33c25290a14715934882fe 100755 GIT binary patch literal 5209 zcmb_fZ){sv6~FgA+p%LOcAXVkwOd>#B{tN5;)N*6F$+t4WOnsh6C;Pu&lNlfkc zy!W1)7J*WsO+rwq3KAg1kV--96A0+UA8A4@68!*`IuHmZ#@G-a5Fpe}LRx{%{LcGh zzc?P^16R8D{JrO#d+xdS-M2BfaFlb-+$OM(F`{A*V#Nu-SNk!Dj7_iv^RpC-vWO-B zl{=ve(p>8Q7x`PUB13P$Aa%cEo9rJEF!X37YqeTatyZ+y+K3f_OZPzUJ;92skDY_~ z@}EDzit$@FL-!xN@itFiO!D{J$ZzwA@Z7ytI+}{U zbUk^kpZ}PQ9w_ja2&SURpXB+E2#s9lKOng8#n$+Z*3AT)8DZn!Yvm^rzzZc7Xtfx% z25N+Q1UT~C5*hy_i*Pn-Nf{f(-u(@@5B0+ai#{K~Wqwug(cTS2+j>-MOKrWxHoZI8 zRGN#Ce;p(LH5h&9xV$qs;iMg)fCqBTX-W9r^;v9=6qwgg*lIRbuCe zy^kUlHqVAASUzU^TL^uZyr(xU@5dpD&}@+ly8s60Q1TDE+sB{p*A>LGK#M@E;Zf}C zD02O)r?$O*9^l1npr%SD>bXNijli$Dyku8Y8S`z2Qx}-Wjmv)mTS$5 z!kALhG&5T!w>C-z$qciCLy}#yu4v{LC_*vLMIjVsH1=WSp_qjSFp41>eGWfpNu!q3 zZ;d1sLcTVKhe$^ZL5c&(10o|v05;qFHcoSS2w8xA^3Fqp7zNAYInpN!;s((UhWka_ zZ&~6Y!nxzw#szR(OCd{YuZE)IA)7-{aL1eLK@9C;WDna>)8vXIHyYB4uGOWLnry5| zy1dS$8SDeI>AHsWDypepVun&StC}jUDRM>89l25cgo63XGhJfIWKGqmuBu8UQC^dE zCRZvrE(SB!G~G+-7NnsvQY)rxYF9a}t;m`zM%C$oh_re4$3)v{cx8NgL7 zV=5QTjH92aRZT^gNwk{CoXjUO*!;t*YV)zj5}6e!SJhfoRWd70)mnwY6w{CzO|#5$ zXADI*a@AE`JHMux=d}yDhOT`at2J_p(U>e8JeZU9O0%kJIjp3zF6)XbC~I{W%~1(b zO39d2gj*Jdgw*A#%G73EGL+Ria%wPIP{JCvB&5Tp^w=3AjI29(r*txeWIkGeW!eRp zU#*tgC*j!a?4d-;d#n=U*+M>>PuuCl!-la0I?f|IYn?P{UR}}HnWZ^tdS>b5!kOhc zX<>eO?)3D+(&2pn^vwL>ae5x%5Lur*2hw~xSOCnIvhgwCbTym+pX9jb*aGkYz$7}| z#Q+wcaJou}-}LYacln#ZcRD)X1dhwn(ti;+-9saOluLl7Zo@SfqpD=tic)H>;$X;i#U-kg zT}L37O1g5PP3f|_if@S{q(XIZSY=sM8PyBR+Bag>wsg_VqUed4MZGpCtpBO)ffgkM z*S@ux^me6Bo7?Q$9Pc48JZ$R?dd^h>boKCT+@kjlWb0+mL>E2OrDwvxZ$0*0z2jYa z3x38DJ@lUL(yKx5YpxNGjJ^uQ&ZAQsz~kfhU3x^S=w7|QplbKg1gDXV`Z~JxesTC= zyiq3|oB-)idlucriJpZX9R#!0euOMeOUnkT+*gO2Y@CIKva zcL;IzgZ$H(^2YZj=-iu~^$a5RVbA;n)>`gOkr|pl1KR8V1j#SI)0RIC+WNnA^d-Fc0l$nO#y#!)TnpuO>Z7PR}5Lh|c0-;=+apuPTn(KY{%UGjUDyt6(5N5pF{2|DM= zXOWIjdw)4Q20CHcu=h(QxhJ3PCxBEk3<+PSnj$G`g-La#UY8qESuW!VXPUayRGWrU zk?OK>o=NzYOuUQUx+#@pLtzqq+iV?6+c0I_>^!6-#rpP1x>k`*+18^FY&A(byDZI} zot-eJSlhBSNuG>26MEQJ|7#+!g&qHfUB=stK*=t*uA-rk{sTxtGVlNZ literal 6358 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 Date: Fri, 29 May 2015 19:37:31 +0300 Subject: [PATCH 22/23] Update flash layout to use eboot --- boards.txt | 22 +++++++++++----------- platform.txt | 6 +++--- tools/sdk/ld/eagle.flash.16m.ld | 4 ++-- tools/sdk/ld/eagle.flash.1m128.ld | 4 ++-- tools/sdk/ld/eagle.flash.1m256.ld | 4 ++-- tools/sdk/ld/eagle.flash.1m512.ld | 4 ++-- tools/sdk/ld/eagle.flash.1m64.ld | 4 ++-- tools/sdk/ld/eagle.flash.2m.ld | 4 ++-- tools/sdk/ld/eagle.flash.4m.ld | 4 ++-- tools/sdk/ld/eagle.flash.512k.ld | 4 ++-- tools/sdk/ld/eagle.flash.8m.ld | 4 ++-- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/boards.txt b/boards.txt index fdf37d5700..d3c3d28061 100644 --- a/boards.txt +++ b/boards.txt @@ -9,7 +9,7 @@ generic.name=Generic ESP8266 Module generic.upload.tool=esptool generic.upload.speed=115200 generic.upload.resetmethod=ck -generic.upload.maximum_size=372736 +generic.upload.maximum_size=434160 generic.upload.maximum_data_size=81920 generic.upload.wait_for_upload_port=true generic.serial.disableDTR=true @@ -59,31 +59,31 @@ generic.menu.FlashSize.512K.build.flash_ld=eagle.flash.512k.ld generic.menu.FlashSize.512K.build.spiffs_start=0x6B000 generic.menu.FlashSize.512K.build.spiffs_end=0x7B000 generic.menu.FlashSize.512K.build.spiffs_blocksize=4096 -generic.menu.FlashSize.512K.upload.maximum_size=372736 +generic.menu.FlashSize.512K.upload.maximum_size=434160 generic.menu.FlashSize.1M512=1M (512K SPIFFS) generic.menu.FlashSize.1M512.build.flash_size=1M generic.menu.FlashSize.1M512.build.flash_ld=eagle.flash.1m512.ld -generic.menu.FlashSize.1M512.build.spiffs_start=0x6B000 +generic.menu.FlashSize.1M512.build.spiffs_start=0x7B000 generic.menu.FlashSize.1M512.build.spiffs_end=0xFB000 generic.menu.FlashSize.1M512.build.spiffs_blocksize=8192 -generic.menu.FlashSize.1M512.upload.maximum_size=438272 +generic.menu.FlashSize.1M512.upload.maximum_size=499696 generic.menu.FlashSize.1M256=1M (256K SPIFFS) generic.menu.FlashSize.1M256.build.flash_size=1M generic.menu.FlashSize.1M256.build.flash_ld=eagle.flash.1m256.ld -generic.menu.FlashSize.1M256.build.spiffs_start=0xAB000 +generic.menu.FlashSize.1M256.build.spiffs_start=0xBB000 generic.menu.FlashSize.1M256.build.spiffs_end=0xFB000 generic.menu.FlashSize.1M256.build.spiffs_blocksize=4096 -generic.menu.FlashSize.1M256.upload.maximum_size=700416 +generic.menu.FlashSize.1M256.upload.maximum_size=761840 generic.menu.FlashSize.1M128=1M (128K SPIFFS) generic.menu.FlashSize.1M128.build.flash_size=1M generic.menu.FlashSize.1M128.build.flash_ld=eagle.flash.1m128.ld -generic.menu.FlashSize.1M128.build.spiffs_start=0xCB000 +generic.menu.FlashSize.1M128.build.spiffs_start=0xDB000 generic.menu.FlashSize.1M128.build.spiffs_end=0xFB000 generic.menu.FlashSize.1M128.build.spiffs_blocksize=4096 -generic.menu.FlashSize.1M128.upload.maximum_size=831488 +generic.menu.FlashSize.1M128.upload.maximum_size=892912 generic.menu.FlashSize.1M64=1M (64K SPIFFS) generic.menu.FlashSize.1M64.build.flash_size=1M @@ -91,7 +91,7 @@ generic.menu.FlashSize.1M64.build.flash_ld=eagle.flash.1m64.ld generic.menu.FlashSize.1M64.build.spiffs_start=0xEB000 generic.menu.FlashSize.1M64.build.spiffs_end=0xFB000 generic.menu.FlashSize.1M64.build.spiffs_blocksize=4096 -generic.menu.FlashSize.1M64.upload.maximum_size=897024 +generic.menu.FlashSize.1M64.upload.maximum_size=958448 generic.menu.FlashSize.2M=2M (1M SPIFFS) generic.menu.FlashSize.2M.build.flash_size=2M @@ -99,7 +99,7 @@ generic.menu.FlashSize.2M.build.flash_ld=eagle.flash.2m.ld generic.menu.FlashSize.2M.build.spiffs_start=0x100000 generic.menu.FlashSize.2M.build.spiffs_end=0x1FB000 generic.menu.FlashSize.2M.build.spiffs_blocksize=8192 -generic.menu.FlashSize.2M.upload.maximum_size=983040 +generic.menu.FlashSize.2M.upload.maximum_size=1044464 generic.menu.FlashSize.4M=4M (3M SPIFFS) generic.menu.FlashSize.4M.build.flash_size=4M @@ -107,7 +107,7 @@ generic.menu.FlashSize.4M.build.flash_ld=eagle.flash.4m.ld generic.menu.FlashSize.4M.build.spiffs_start=0x100000 generic.menu.FlashSize.4M.build.spiffs_end=0x3FB000 generic.menu.FlashSize.4M.build.spiffs_blocksize=8192 -generic.menu.FlashSize.4M.upload.maximum_size=983040 +generic.menu.FlashSize.4M.upload.maximum_size=1044464 # disabled because espressif's bootloader refuses to write above 4M # generic.menu.FlashSize.8M=8M (7M SPIFFS) diff --git a/platform.txt b/platform.txt index e76b838ca2..f0796310b0 100644 --- a/platform.txt +++ b/platform.txt @@ -74,11 +74,11 @@ recipe.objcopy.eep.pattern= ## Create hex #recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" -recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{build.path}/{build.project_name}.elf" -bo "{build.path}/{build.project_name}_00000.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bs .data -bs .rodata -bc -ec -eo "{build.path}/{build.project_name}.elf" -es .irom0.text "{build.path}/{build.project_name}_10000.bin" -ec +recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{runtime.platform.path}/bootloaders/eboot/eboot.elf" -bo "{build.path}/{build.project_name}.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bp 4096 -ec -eo "{build.path}/{build.project_name}.elf" -bs .irom0.text -bs .text -bs .data -bs .rodata -bc -ec ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=^(?:\.irom0\.text|)\s+([0-9]+).* +recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|\.bss|)\s+([0-9]+).* recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).* #recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* @@ -91,4 +91,4 @@ tools.esptool.path={runtime.platform.path}/tools tools.esptool.upload.protocol=esp tools.esptool.upload.params.verbose=-vv tools.esptool.upload.params.quiet= -tools.esptool.upload.pattern="{path}/{cmd}" {upload.verbose} -cd {upload.resetmethod} -cb {upload.speed} -cp "{serial.port}" -ca 0x00000 -cf "{build.path}/{build.project_name}_00000.bin" -ca 0x10000 -cf "{build.path}/{build.project_name}_10000.bin" +tools.esptool.upload.pattern="{path}/{cmd}" {upload.verbose} -cd {upload.resetmethod} -cb {upload.speed} -cp "{serial.port}" -ca 0x00000 -cf "{build.path}/{build.project_name}.bin" diff --git a/tools/sdk/ld/eagle.flash.16m.ld b/tools/sdk/ld/eagle.flash.16m.ld index d6112f9735..d968c14299 100644 --- a/tools/sdk/ld/eagle.flash.16m.ld +++ b/tools/sdk/ld/eagle.flash.16m.ld @@ -1,5 +1,5 @@ /* Flash Split for 16M chips */ -/* irom0 940KB */ +/* sketch 1019KB */ /* eeprom 20KB */ /* spiffs 15MB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xEB000 + irom0_0_seg : org = 0x40201010, len = 0xfeff0 } PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.1m128.ld b/tools/sdk/ld/eagle.flash.1m128.ld index d7d4a94235..12a70ed15a 100644 --- a/tools/sdk/ld/eagle.flash.1m128.ld +++ b/tools/sdk/ld/eagle.flash.1m128.ld @@ -1,5 +1,5 @@ /* Flash Split for 1M chips */ -/* irom0 812KB */ +/* sketch 871KB */ /* spiffs 128KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xCB000 + irom0_0_seg : org = 0x40201010, len = 0xd9ff0 } PROVIDE ( _SPIFFS_start = 0x402DB000 ); diff --git a/tools/sdk/ld/eagle.flash.1m256.ld b/tools/sdk/ld/eagle.flash.1m256.ld index b75be04f3a..0f97d179c4 100644 --- a/tools/sdk/ld/eagle.flash.1m256.ld +++ b/tools/sdk/ld/eagle.flash.1m256.ld @@ -1,5 +1,5 @@ /* Flash Split for 1M chips */ -/* irom0 684KB */ +/* sketch 743KB */ /* spiffs 256KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xAB000 + irom0_0_seg : org = 0x40201010, len = 0xb9ff0 } PROVIDE ( _SPIFFS_start = 0x402BB000 ); diff --git a/tools/sdk/ld/eagle.flash.1m512.ld b/tools/sdk/ld/eagle.flash.1m512.ld index 1bc7148b1c..89350c44ec 100644 --- a/tools/sdk/ld/eagle.flash.1m512.ld +++ b/tools/sdk/ld/eagle.flash.1m512.ld @@ -1,5 +1,5 @@ /* Flash Split for 1M chips */ -/* irom0 428KB */ +/* sketch 487KB */ /* spiffs 512KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0x6B000 + irom0_0_seg : org = 0x40201010, len = 0x79ff0 } PROVIDE ( _SPIFFS_start = 0x4027B000 ); diff --git a/tools/sdk/ld/eagle.flash.1m64.ld b/tools/sdk/ld/eagle.flash.1m64.ld index aa553ba559..73fa6e51b6 100644 --- a/tools/sdk/ld/eagle.flash.1m64.ld +++ b/tools/sdk/ld/eagle.flash.1m64.ld @@ -1,5 +1,5 @@ /* Flash Split for 1M chips */ -/* irom0 876KB */ +/* sketch 935KB */ /* spiffs 64KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xDB000 + irom0_0_seg : org = 0x40201010, len = 0xe9ff0 } PROVIDE ( _SPIFFS_start = 0x402EB000 ); diff --git a/tools/sdk/ld/eagle.flash.2m.ld b/tools/sdk/ld/eagle.flash.2m.ld index 95c045a379..0753f5ead2 100644 --- a/tools/sdk/ld/eagle.flash.2m.ld +++ b/tools/sdk/ld/eagle.flash.2m.ld @@ -1,5 +1,5 @@ /* Flash Split for 2M chips */ -/* irom0 960KB */ +/* sketch 1019KB */ /* spiffs 1004KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xF0000 + irom0_0_seg : org = 0x40201010, len = 0xfeff0 } PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.4m.ld b/tools/sdk/ld/eagle.flash.4m.ld index 1239033f39..04aa3a8f46 100644 --- a/tools/sdk/ld/eagle.flash.4m.ld +++ b/tools/sdk/ld/eagle.flash.4m.ld @@ -1,5 +1,5 @@ /* Flash Split for 4M chips */ -/* irom0 960KB */ +/* sketch 1019KB */ /* spiffs 3052KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xF0000 + irom0_0_seg : org = 0x40201010, len = 0xfeff0 } PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.512k.ld b/tools/sdk/ld/eagle.flash.512k.ld index ea6f37bedd..5d01d32597 100644 --- a/tools/sdk/ld/eagle.flash.512k.ld +++ b/tools/sdk/ld/eagle.flash.512k.ld @@ -1,5 +1,5 @@ /* Flash Split for 512K chips */ -/* irom0 364KB */ +/* sketch 423KB */ /* spiffs 64KB */ /* eeprom 20KB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0x5B000 + irom0_0_seg : org = 0x40201010, len = 0x69ff0 } PROVIDE ( _SPIFFS_start = 0x4026B000 ); diff --git a/tools/sdk/ld/eagle.flash.8m.ld b/tools/sdk/ld/eagle.flash.8m.ld index 166e44f91a..18c5f7d99a 100644 --- a/tools/sdk/ld/eagle.flash.8m.ld +++ b/tools/sdk/ld/eagle.flash.8m.ld @@ -1,5 +1,5 @@ /* Flash Split for 8M chips */ -/* irom0 940KB */ +/* sketch 1019KB */ /* eeprom 20KB */ /* spiffs 7MB */ @@ -8,7 +8,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0xEB000 + irom0_0_seg : org = 0x40201010, len = 0xfeff0 } PROVIDE ( _SPIFFS_start = 0x40300000 ); From 5465f709d1abbaad45c1076abc407ae951c861d1 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:57:03 +0300 Subject: [PATCH 23/23] Fix max sketch sizes for branded boards --- boards.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boards.txt b/boards.txt index 5d9f468a81..bfc910a2b0 100644 --- a/boards.txt +++ b/boards.txt @@ -134,7 +134,7 @@ modwifi.name=Olimex MOD-WIFI-ESP8266(-DEV) modwifi.upload.tool=esptool modwifi.upload.speed=115200 modwifi.upload.resetmethod=ck -modwifi.upload.maximum_size=983040 +modwifi.upload.maximum_size=1044464 modwifi.upload.maximum_data_size=81920 modwifi.upload.wait_for_upload_port=true modwifi.serial.disableDTR=true @@ -186,7 +186,7 @@ nodemcu.name=NodeMCU 0.9 (ESP-12 Module) nodemcu.upload.tool=esptool nodemcu.upload.speed=115200 nodemcu.upload.resetmethod=ck -nodemcu.upload.maximum_size=983040 +nodemcu.upload.maximum_size=1044464 nodemcu.upload.maximum_data_size=81920 nodemcu.upload.wait_for_upload_port=true nodemcu.serial.disableDTR=true @@ -237,7 +237,7 @@ nodemcuv2.name=NodeMCU 1.0 (ESP-12E Module) nodemcuv2.upload.tool=esptool nodemcuv2.upload.speed=115200 nodemcuv2.upload.resetmethod=ck -nodemcuv2.upload.maximum_size=983040 +nodemcuv2.upload.maximum_size=1044464 nodemcuv2.upload.maximum_data_size=81920 nodemcuv2.upload.wait_for_upload_port=true nodemcuv2.serial.disableDTR=true @@ -288,7 +288,7 @@ huzzah.name=Adafruit HUZZAH ESP8266 huzzah.upload.tool=esptool huzzah.upload.speed=115200 huzzah.upload.resetmethod=ck -huzzah.upload.maximum_size=983040 +huzzah.upload.maximum_size=1044464 huzzah.upload.maximum_data_size=81920 huzzah.upload.wait_for_upload_port=true huzzah.serial.disableDTR=true