diff --git a/boards.txt b/boards.txt index deb930479..30ce8c51b 100644 --- a/boards.txt +++ b/boards.txt @@ -577,78 +577,7 @@ esp210.menu.FlashSize.4M1M.build.spiffs_pagesize=256 # ############################################################## -d1.name=WeMos D1 - -d1.upload.tool=esptool -d1.upload.speed=460800 -d1.upload.resetmethod=nodemcu -d1.upload.maximum_size=1044464 -d1.upload.maximum_data_size=81920 -d1.upload.wait_for_upload_port=true -d1.serial.disableDTR=true -d1.serial.disableRTS=true - -d1.build.mcu=esp8266 -d1.build.f_cpu=80000000L -d1.build.board=ESP8266_ESP12 -d1.build.core=esp8266 -d1.build.variant=d1 -d1.build.flash_mode=dio -d1.build.flash_size=4M -d1.build.flash_freq=40 - -d1.menu.CpuFrequency.80=80 MHz -d1.menu.CpuFrequency.80.build.f_cpu=80000000L -d1.menu.CpuFrequency.160=160 MHz -d1.menu.CpuFrequency.160.build.f_cpu=160000000L - -d1.menu.UploadTool.esptool=Serial -d1.menu.UploadTool.esptool.upload.tool=esptool -d1.menu.UploadTool.esptool.upload.verbose=-vv - -d1.menu.UploadTool.espota=OTA -d1.menu.UploadTool.espota.upload.tool=espota - -d1.menu.UploadSpeed.921600=921600 -d1.menu.UploadSpeed.921600.upload.speed=921600 -d1.menu.UploadSpeed.115200=115200 -d1.menu.UploadSpeed.115200.upload.speed=115200 -d1.menu.UploadSpeed.9600=9600 -d1.menu.UploadSpeed.9600.upload.speed=9600 -d1.menu.UploadSpeed.57600=57600 -d1.menu.UploadSpeed.57600.upload.speed=57600 -d1.menu.UploadSpeed.256000.windows=256000 -d1.menu.UploadSpeed.256000.upload.speed=256000 -d1.menu.UploadSpeed.230400.linux=230400 -d1.menu.UploadSpeed.230400.macosx=230400 -d1.menu.UploadSpeed.230400.macosx=230400 -d1.menu.UploadSpeed.230400.upload.speed=230400 -d1.menu.UploadSpeed.460800.linux=460800 -d1.menu.UploadSpeed.460800.macosx=460800 -d1.menu.UploadSpeed.460800.upload.speed=460800 -d1.menu.UploadSpeed.512000.windows=512000 -d1.menu.UploadSpeed.512000.upload.speed=512000 - - -d1.menu.FlashSize.4M3M=4M (3M SPIFFS) -d1.menu.FlashSize.4M3M.build.flash_size=4M -d1.menu.FlashSize.4M3M.build.flash_ld=eagle.flash.4m.ld -d1.menu.FlashSize.4M3M.build.spiffs_start=0x100000 -d1.menu.FlashSize.4M3M.build.spiffs_end=0x3FB000 -d1.menu.FlashSize.4M3M.build.spiffs_blocksize=8192 -d1.menu.FlashSize.4M3M.build.spiffs_pagesize=256 - -d1.menu.FlashSize.4M1M=4M (1M SPIFFS) -d1.menu.FlashSize.4M1M.build.flash_size=4M -d1.menu.FlashSize.4M1M.build.flash_ld=eagle.flash.4m1m.ld -d1.menu.FlashSize.4M1M.build.spiffs_start=0x300000 -d1.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000 -d1.menu.FlashSize.4M1M.build.spiffs_blocksize=8192 -d1.menu.FlashSize.4M1M.build.spiffs_pagesize=256 - - -############################################################## -d1_mini.name=WeMos D1 mini +d1_mini.name=WeMos D1 R2 & mini d1_mini.upload.tool=esptool d1_mini.upload.speed=460800 @@ -719,6 +648,78 @@ d1_mini.menu.FlashSize.4M1M.build.spiffs_pagesize=256 ############################################################## +d1.name=WeMos D1(Retired) + +d1.upload.tool=esptool +d1.upload.speed=460800 +d1.upload.resetmethod=nodemcu +d1.upload.maximum_size=1044464 +d1.upload.maximum_data_size=81920 +d1.upload.wait_for_upload_port=true +d1.serial.disableDTR=true +d1.serial.disableRTS=true + +d1.build.mcu=esp8266 +d1.build.f_cpu=80000000L +d1.build.board=ESP8266_ESP12 +d1.build.core=esp8266 +d1.build.variant=d1 +d1.build.flash_mode=dio +d1.build.flash_size=4M +d1.build.flash_freq=40 + +d1.menu.CpuFrequency.80=80 MHz +d1.menu.CpuFrequency.80.build.f_cpu=80000000L +d1.menu.CpuFrequency.160=160 MHz +d1.menu.CpuFrequency.160.build.f_cpu=160000000L + +d1.menu.UploadTool.esptool=Serial +d1.menu.UploadTool.esptool.upload.tool=esptool +d1.menu.UploadTool.esptool.upload.verbose=-vv + +d1.menu.UploadTool.espota=OTA +d1.menu.UploadTool.espota.upload.tool=espota + +d1.menu.UploadSpeed.921600=921600 +d1.menu.UploadSpeed.921600.upload.speed=921600 +d1.menu.UploadSpeed.115200=115200 +d1.menu.UploadSpeed.115200.upload.speed=115200 +d1.menu.UploadSpeed.9600=9600 +d1.menu.UploadSpeed.9600.upload.speed=9600 +d1.menu.UploadSpeed.57600=57600 +d1.menu.UploadSpeed.57600.upload.speed=57600 +d1.menu.UploadSpeed.256000.windows=256000 +d1.menu.UploadSpeed.256000.upload.speed=256000 +d1.menu.UploadSpeed.230400.linux=230400 +d1.menu.UploadSpeed.230400.macosx=230400 +d1.menu.UploadSpeed.230400.macosx=230400 +d1.menu.UploadSpeed.230400.upload.speed=230400 +d1.menu.UploadSpeed.460800.linux=460800 +d1.menu.UploadSpeed.460800.macosx=460800 +d1.menu.UploadSpeed.460800.upload.speed=460800 +d1.menu.UploadSpeed.512000.windows=512000 +d1.menu.UploadSpeed.512000.upload.speed=512000 + + +d1.menu.FlashSize.4M3M=4M (3M SPIFFS) +d1.menu.FlashSize.4M3M.build.flash_size=4M +d1.menu.FlashSize.4M3M.build.flash_ld=eagle.flash.4m.ld +d1.menu.FlashSize.4M3M.build.spiffs_start=0x100000 +d1.menu.FlashSize.4M3M.build.spiffs_end=0x3FB000 +d1.menu.FlashSize.4M3M.build.spiffs_blocksize=8192 +d1.menu.FlashSize.4M3M.build.spiffs_pagesize=256 + +d1.menu.FlashSize.4M1M=4M (1M SPIFFS) +d1.menu.FlashSize.4M1M.build.flash_size=4M +d1.menu.FlashSize.4M1M.build.flash_ld=eagle.flash.4m1m.ld +d1.menu.FlashSize.4M1M.build.spiffs_start=0x300000 +d1.menu.FlashSize.4M1M.build.spiffs_end=0x3FB000 +d1.menu.FlashSize.4M1M.build.spiffs_blocksize=8192 +d1.menu.FlashSize.4M1M.build.spiffs_pagesize=256 + + +############################################################## + espino.name=ESPino espino.upload.tool=esptool @@ -810,7 +811,7 @@ wifinfo.serial.disableDTR=true wifinfo.serial.disableRTS=true wifinfo.build.mcu=esp8266 -wifinfo.build.f_cpu=80000000L +wifinfo.build.f_cpu=160000000L wifinfo.build.core=esp8266 wifinfo.build.variant=wifinfo wifinfo.build.flash_mode=qio diff --git a/cores/esp8266/StreamString.cpp b/cores/esp8266/StreamString.cpp index 9aace2b47..7ebf11d0e 100644 --- a/cores/esp8266/StreamString.cpp +++ b/cores/esp8266/StreamString.cpp @@ -23,16 +23,14 @@ #include #include "StreamString.h" -size_t StreamString::write(const uint8_t *buffer, size_t size) { - if(reserve(length() + size + 1)) { - for(size_t i = 0; i < size; i++) { - if(write(*buffer)) { - buffer++; - } else { - return i; - } +size_t StreamString::write(const uint8_t *data, size_t size) { + if(size && data) { + if(reserve(length() + size + 1)) { + memcpy((void *) (buffer + len), (const void *) data, size); + len += size; + *(buffer + len) = 0x00; // add null for string end + return size; } - } return 0; } diff --git a/cores/esp8266/cont.h b/cores/esp8266/cont.h index 4fe742f44..46daad100 100644 --- a/cores/esp8266/cont.h +++ b/cores/esp8266/cont.h @@ -60,6 +60,10 @@ void cont_yield(cont_t*); // return 1 if guard bytes were overwritten. int cont_check(cont_t* cont); +// Go through stack and check how many bytes are most probably still unchanged +// and thus weren't used by the user code. i.e. that stack space is free. (high water mark) +int cont_get_free_stack(cont_t* cont); + // Check if yield() may be called. Returns true if we are running inside // continuation stack bool cont_can_yield(cont_t* cont); diff --git a/cores/esp8266/cont_util.c b/cores/esp8266/cont_util.c index 2a29e7eac..52a79e34e 100644 --- a/cores/esp8266/cont_util.c +++ b/cores/esp8266/cont_util.c @@ -30,6 +30,12 @@ void ICACHE_RAM_ATTR cont_init(cont_t* cont) { cont->stack_guard2 = CONT_STACKGUARD; cont->stack_end = cont->stack + (sizeof(cont->stack) / 4); cont->struct_start = (unsigned*) cont; + + // fill stack with magic values to check high water mark + for(int pos = 0; pos < sizeof(cont->stack) / 4; pos++) + { + cont->stack[pos] = CONT_STACKGUARD; + } } int ICACHE_RAM_ATTR cont_check(cont_t* cont) { @@ -38,6 +44,19 @@ int ICACHE_RAM_ATTR cont_check(cont_t* cont) { return 0; } +int ICACHE_RAM_ATTR cont_get_free_stack(cont_t* cont) { + uint32_t *head = cont->stack; + int freeWords = 0; + + while(*head == CONT_STACKGUARD) + { + head++; + freeWords++; + } + + return freeWords * 4; +} + bool ICACHE_RAM_ATTR cont_can_yield(cont_t* cont) { return !ETS_INTR_WITHINISR() && cont->pc_ret != 0 && cont->pc_yield == 0; diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index 77b9c2ea2..d68346634 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -66,11 +66,11 @@ public: bool rename(const char* pathFrom, const char* pathTo) override { if (!isSpiffsFilenameValid(pathFrom)) { - DEBUGV("SPIFFSImpl::rename: invalid pathFrom=`%s`\r\n", path); + DEBUGV("SPIFFSImpl::rename: invalid pathFrom=`%s`\r\n", pathFrom); return false; } if (!isSpiffsFilenameValid(pathTo)) { - DEBUGV("SPIFFSImpl::rename: invalid pathTo=`%s` \r\n", path); + DEBUGV("SPIFFSImpl::rename: invalid pathTo=`%s` \r\n", pathTo); return false; } auto rc = SPIFFS_rename(&_fs, pathFrom, pathTo); diff --git a/doc/platformio.md b/doc/platformio.md index 197091a7d..1bec79c34 100644 --- a/doc/platformio.md +++ b/doc/platformio.md @@ -71,5 +71,8 @@ platformio run --target upload - [IDE Integration](http://docs.platformio.org/en/latest/ide.html) (Atom, CLion, Eclipse, Qt Creator, Sublime Text, VIM, Visual Studio) - [Project Examples](http://docs.platformio.org/en/latest/platforms/espressif.html#examples) -## Demo of OTA update -[![PlatformIO and OTA firmware uploading to Espressif ESP8266 ESP-01](http://img.youtube.com/vi/W8wWjvQ8ZQs/0.jpg)](http://www.youtube.com/watch?v=W8wWjvQ8ZQs "PlatformIO and OTA firmware uploading to Espressif ESP8266 ESP-01") +## Demo of Over-the-Air (OTA) ESP8266 programming using PlatformIO + +http://www.penninkhof.com/2015/12/1610-over-the-air-esp8266-programming-using-platformio/ + +[![Over-the-Air ESP8266 programming using PlatformIO](http://img.youtube.com/vi/lXchL3hpDO4/0.jpg)](http://www.youtube.com/watch?v=lXchL3hpDO4 "Over-the-Air ESP8266 programming using PlatformIO") diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index 5cddaf616..36545fcbb 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -50,6 +50,7 @@ HTTPClient::HTTPClient() { _returnCode = 0; _size = -1; _canReuse = false; + _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; } @@ -252,6 +253,17 @@ void HTTPClient::setAuthorization(const char * auth) { } } +/** + * set the timeout for the TCP connection + * @param timeout unsigned int + */ +void HTTPClient::setTimeout(uint16_t timeout) { + _tcpTimeout = timeout; + if(connected()) { + _tcp->setTimeout(timeout); + } +} + /** * send a GET request * @return http code @@ -354,16 +366,25 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) { if(buff) { // read all data from stream and send it to server - while(connected() && stream->available() && (len > 0 || len == -1)) { + while(connected() && (stream->available() > -1) && (len > 0 || len == -1)) { // get available data size size_t s = stream->available(); + if(len) { + s = ((s > len) ? len : s); + } + if(s) { int c = stream->readBytes(buff, ((s > buff_size) ? buff_size : s)); // write it to Stream - bytesWritten += _tcp->write((const uint8_t *) buff, c); + int w = _tcp->write((const uint8_t *) buff, c); + bytesWritten += w; + if(w != c) { + DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] short write asked for %d but got %d\n", c, w); + break; + } if(len > 0) { len -= c; @@ -378,7 +399,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) { free(buff); if(size && (int) size != bytesWritten) { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, _size); + DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!"); return HTTPC_ERROR_SEND_PAYLOAD_FAILED; } else { @@ -386,7 +407,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) { } } else { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] too less ram! need " HTTP_TCP_BUFFER_SIZE); + DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); return HTTPC_ERROR_TOO_LESS_RAM; } @@ -470,7 +491,12 @@ int HTTPClient::writeToStream(Stream * stream) { int c = _tcp->readBytes(buff, ((size > buff_size) ? buff_size : size)); // write it to Stream - bytesWritten += stream->write(buff, c); + int w = stream->write(buff, c); + bytesWritten += w; + if(w != c) { + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d\n", c, w); + break; + } if(len > 0) { len -= c; @@ -491,7 +517,7 @@ int HTTPClient::writeToStream(Stream * stream) { } } else { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] too less ram! need " HTTP_TCP_BUFFER_SIZE); + DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); return HTTPC_ERROR_TOO_LESS_RAM; } @@ -659,7 +685,7 @@ bool HTTPClient::connect(void) { } // set Timeout for readBytesUntil and readStringUntil - _tcp->setTimeout(HTTPCLIENT_TCP_TIMEOUT); + _tcp->setTimeout(_tcpTimeout); #ifdef ESP8266 _tcp->setNoDelay(true); diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index 74a27af5d..43c6b19ac 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -31,7 +31,7 @@ #define DEBUG_HTTPCLIENT(...) #endif -#define HTTPCLIENT_TCP_TIMEOUT (1000) +#define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (1000) /// HTTP client errors #define HTTPC_ERROR_CONNECTION_REFUSED (-1) @@ -127,6 +127,7 @@ class HTTPClient { void setUserAgent(const char * userAgent); void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); + void setTimeout(uint16_t timeout); /// request handling int GET(); @@ -170,7 +171,7 @@ class HTTPClient { String _host; uint16_t _port; bool _reuse; - + uint16_t _tcpTimeout; String _url; bool _https; diff --git a/libraries/ESP8266WebServer/src/detail/RequestHandler.h b/libraries/ESP8266WebServer/src/detail/RequestHandler.h index 5a998bfbd..b8ec03890 100644 --- a/libraries/ESP8266WebServer/src/detail/RequestHandler.h +++ b/libraries/ESP8266WebServer/src/detail/RequestHandler.h @@ -3,6 +3,7 @@ class RequestHandler { public: + virtual ~RequestHandler() { } virtual bool canHandle(HTTPMethod method, String uri) { return false; } virtual bool canUpload(String uri) { return false; } virtual bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) { return false; } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 25544f858..a95bd1f7d 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -897,6 +897,43 @@ void ESP8266WiFiClass::_smartConfigCallback(uint32_t st, void* result) } } + +//-------------------------------------------------------------- + +/** + * set Sleep mode + * @param type sleep_type_t + * @return bool + */ +bool ESP8266WiFiClass::setSleepMode(WiFiSleepType_t type) { + return wifi_set_sleep_type((sleep_type_t)type); +} + +/** + * get Sleep mode + * @return sleep_type_t + */ +WiFiSleepType_t ESP8266WiFiClass::getSleepMode() { + return (WiFiSleepType_t)wifi_get_sleep_type(); +} + +/** + * set phy Mode + * @param mode phy_mode_t + * @return bool + */ +bool ESP8266WiFiClass::setPhyMode(WiFiPhyMode_t mode) { + return wifi_set_phy_mode((phy_mode_t)mode); +} + +/** + * get phy Mode + * @return phy_mode_t + */ +WiFiPhyMode_t ESP8266WiFiClass::getPhyMode() { + return (WiFiPhyMode_t)wifi_get_phy_mode(); +} + //-------------------------------------------------------------- void ESP8266WiFiClass::_eventCallback(void* arg) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 2623b2fb6..5a7fe54c1 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -36,8 +36,21 @@ extern "C" { #define WIFI_SCAN_RUNNING (-1) #define WIFI_SCAN_FAILED (-2) + +// Note: +// this enums need to be in sync with the SDK! + enum WiFiMode { WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 }; +typedef enum { + WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3 +} WiFiPhyMode_t; + +typedef enum { + WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 2, WIFI_MODEM_SLEEP = 3 +} WiFiSleepType_t; + + class ESP8266WiFiClass { public: @@ -375,6 +388,32 @@ public: friend class WiFiClient; friend class WiFiServer; + /** + * set Sleep mode + * @param type WiFiPhyMode_t + * @return bool + */ + bool setSleepMode(WiFiSleepType_t type); + + /** + * get Sleep mode + * @return sleep_type_t + */ + WiFiSleepType_t getSleepMode(); + + /** + * set phy Mode + * @param mode phy_mode_t + * @return bool + */ + bool setPhyMode(WiFiPhyMode_t mode); + + /** + * get phy Mode + * @return phy_mode_t + */ + WiFiPhyMode_t getPhyMode(); + protected: void _mode(WiFiMode); static void _scanDone(void* result, int status); diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 4299ddb8f..484a23fc0 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -493,8 +493,9 @@ extern "C" void* ax_port_malloc(size_t size, const char* file, int line) { DEBUG_TLS_MEM_PRINT("%s:%d malloc %d failed, left %d\r\n", file, line, size, ESP.getFreeHeap()); panic(); } - if (size >= 1024) + if (size >= 1024) { DEBUG_TLS_MEM_PRINT("%s:%d malloc %d, left %d\r\n", file, line, size, ESP.getFreeHeap()); + } return result; } @@ -510,8 +511,9 @@ extern "C" void* ax_port_realloc(void* ptr, size_t size, const char* file, int l DEBUG_TLS_MEM_PRINT("%s:%d realloc %d failed, left %d\r\n", file, line, size, ESP.getFreeHeap()); panic(); } - if (size >= 1024) + if (size >= 1024) { DEBUG_TLS_MEM_PRINT("%s:%d realloc %d, left %d\r\n", file, line, size, ESP.getFreeHeap()); + } return result; } @@ -519,6 +521,7 @@ extern "C" void ax_port_free(void* ptr) { free(ptr); uint32_t *p = (uint32_t*) ptr; size_t size = p[-3]; - if (size >= 1024) + if (size >= 1024) { DEBUG_TLS_MEM_PRINT("free %d, left %d\r\n", p[-3], ESP.getFreeHeap()); + } } diff --git a/libraries/GDBStub/src/internal/gdbstub.c b/libraries/GDBStub/src/internal/gdbstub.c index e3d010787..7ca195ea7 100644 --- a/libraries/GDBStub/src/internal/gdbstub.c +++ b/libraries/GDBStub/src/internal/gdbstub.c @@ -299,7 +299,7 @@ static void ATTR_GDBFN sendReason() { } else if (gdbstub_savedRegs.reason&0x80) { //We stopped because of an exception. Convert exception code to a signal number and send it. i=gdbstub_savedRegs.reason&0x7f; - if (i