From 4d3ef20f2996b9bea20fa0dc471fe5765f687e34 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 10 Jul 2015 18:28:04 -0700 Subject: [PATCH 1/3] Issue fixes https://github.com/esp8266/Arduino/issues/475 https://github.com/esp8266/Arduino/issues/484 --- README.md | 4 +- .../cores/esp8266/core_esp8266_noniso.c | 39 ++++++++++++------- .../esp8266/cores/esp8266/pgmspace.cpp | 11 ++++++ .../esp8266/cores/esp8266/pgmspace.h | 3 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 64ab428924..201d0f250e 100644 --- a/README.md +++ b/README.md @@ -213,8 +213,8 @@ Libraries that don't rely on low-level access to AVR registers should work well. - [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)). - [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git) - [DHT11](https://github.com/adafruit/DHT-sensor-library) - Download latest v1.1.0 library and no changes are necessary. Older versions should initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);``` -- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel libray, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager). -- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266. +- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel library, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager). +- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266. Use the "NeoPixelAnimator" branch for esp8266 to get HSL color support and more. - [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy. - [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266. - [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB. diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c index eddac25a5c..40fe5e6dd4 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c @@ -149,49 +149,58 @@ char* ultoa(unsigned long value, char* result, int base) { char * dtostrf(double number, signed char width, unsigned char prec, char *s) { - if(isnan(number)) { + if (isnan(number)) { strcpy(s, "nan"); return s; } - if(isinf(number)) { + if (isinf(number)) { strcpy(s, "inf"); return s; } - if(number > 4294967040.0 || number < -4294967040.0) { + if (number > 4294967040.0 || number < -4294967040.0) { strcpy(s, "ovf"); return s; } + char* out = s; + int signInt_Part = 1; + // Handle negative numbers - if(number < 0.0) { - *out = '-'; - ++out; + if (number < 0.0) { + signInt_Part = -1; number = -number; } + // calc left over digits + if (prec > 0) + { + width -= (prec + 1); + } + // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; - for(uint8_t i = 0; i < prec; ++i) + for (uint8_t i = 0; i < prec; ++i) rounding /= 10.0; number += rounding; // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long) number; - double remainder = number - (double) int_part; - out += sprintf(out, "%ld", int_part); + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + out += sprintf(out, "%*ld", width, int_part * signInt_Part); // Print the decimal point, but only if there are digits beyond - if(prec > 0) { + if (prec > 0) { *out = '.'; ++out; - } - for (unsigned char decShift = prec; decShift > 0; decShift--) { - remainder *= 10.0; + + for (unsigned char decShift = prec; decShift > 0; decShift--) { + remainder *= 10.0; + } + sprintf(out, "%0*d", prec, (int)remainder); } - sprintf(out, "%0*d", prec, (int)remainder); return s; } diff --git a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp index c2b5781f1f..b91dd59128 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp @@ -135,6 +135,17 @@ int printf_P(const char* formatP, ...) { return ret; } +int sprintf_P(char* str, const char* formatP, ...) { + int ret; + va_list arglist; + va_start(arglist, formatP); + + ret = vsnprintf_P(str, SIZE_IRRELEVANT, formatP, arglist); + + va_end(arglist); + return ret; +} + int snprintf_P(char* str, size_t strSize, const char* formatP, ...) { int ret; va_list arglist; diff --git a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h index e6db10fbda..7669058be3 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h @@ -50,7 +50,8 @@ size_t strnlen_P(const char *s, size_t size); #define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT) 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 sprintf_P(char *str, const char *formatP, ...) __attribute__((format(printf, 2, 3))); +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 From f54cf376929efce2338b7f7b42a1a01fee8f6f15 Mon Sep 17 00:00:00 2001 From: Makuna Date: Sun, 12 Jul 2015 12:39:14 -0700 Subject: [PATCH 2/3] Yield in available() to reduce resets --- .../esp8266/cores/esp8266/HardwareSerial.cpp | 21 +++++++++++++------ .../libraries/ESP8266WiFi/src/WiFiUdp.cpp | 11 +++++++--- .../esp8266/libraries/Wire/Wire.cpp | 10 ++++++++- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp index e77fe3ef43..5d051cbe52 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp @@ -39,6 +39,8 @@ extern "C" { #include "HardwareSerial.h" +extern "C" uint32_t esp_micros_at_task_start(); + #define UART_TX_FIFO_SIZE 0x80 struct uart_ { @@ -552,13 +554,20 @@ bool HardwareSerial::isRxEnabled(void) { } int HardwareSerial::available(void) { - if(_uart == 0) - return 0; - if(_uart->rxEnabled) { - return static_cast(_rx_buffer->getSize()); - } else { - return 0; + int isAvailable; + + if (_uart != NULL && _uart->rxEnabled) { + isAvailable = static_cast(_rx_buffer->getSize()); + } + else { + isAvailable = 0; + } + + if (!isAvailable && (micros() - esp_micros_at_task_start()) > 10000) { + yield(); } + + return isAvailable; } int HardwareSerial::peek(void) { diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp index 80b005556b..697aeaec09 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiUdp.cpp @@ -40,6 +40,7 @@ extern "C" #include "lwip/mem.h" #include "include/UdpContext.h" +extern "C" uint32_t esp_micros_at_task_start(); template<> WiFiUDP* SList::_s_first = 0; @@ -116,9 +117,13 @@ uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, ui /* return number of bytes available in the current packet, will return zero if parsePacket hasn't been called yet */ int WiFiUDP::available() { - if (!_ctx) - return 0; - return static_cast(_ctx->getSize()); + int isAvailable = (_ctx != NULL) ? static_cast(_ctx->getSize()) : 0 + + if (!isAvailable && (micros() - esp_micros_at_task_start()) > 10000) { + yield(); + } + + return isAvailable; } /* Release any resources being used by this WiFiUDP instance */ diff --git a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp index 7591592032..a24e60f19c 100644 --- a/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp +++ b/hardware/esp8266com/esp8266/libraries/Wire/Wire.cpp @@ -30,6 +30,8 @@ extern "C" { #include "twi.h" #include "Wire.h" +extern "C" uint32_t esp_micros_at_task_start(); + // Initialize Class Variables ////////////////////////////////////////////////// uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; @@ -161,7 +163,13 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity){ } int TwoWire::available(void){ - return rxBufferLength - rxBufferIndex; + int isAvailable = rxBufferLength - rxBufferIndex; + + if (!isAvailable && (micros() - esp_micros_at_task_start()) > 10000) { + yield(); + } + + return isAvailable; } int TwoWire::read(void){ From 422ed5291c9816bba1a0fc1bf45140a85555c922 Mon Sep 17 00:00:00 2001 From: Makuna Date: Sun, 12 Jul 2015 12:44:56 -0700 Subject: [PATCH 3/3] Revert "Issue fixes" This reverts commit 4d3ef20f2996b9bea20fa0dc471fe5765f687e34. --- README.md | 4 +- .../cores/esp8266/core_esp8266_noniso.c | 39 +++++++------------ .../esp8266/cores/esp8266/pgmspace.cpp | 11 ------ .../esp8266/cores/esp8266/pgmspace.h | 3 +- 4 files changed, 18 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 201d0f250e..64ab428924 100644 --- a/README.md +++ b/README.md @@ -213,8 +213,8 @@ Libraries that don't rely on low-level access to AVR registers should work well. - [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)). - [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git) - [DHT11](https://github.com/adafruit/DHT-sensor-library) - Download latest v1.1.0 library and no changes are necessary. Older versions should initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);``` -- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel library, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager). -- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266. Use the "NeoPixelAnimator" branch for esp8266 to get HSL color support and more. +- [NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) - Adafruit's NeoPixel libray, now with support for the ESP8266 (use version 1.0.2 or higher from Arduino's library manager). +- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266. - [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy. - [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266. - [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB. diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c index 40fe5e6dd4..eddac25a5c 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_noniso.c @@ -149,58 +149,49 @@ char* ultoa(unsigned long value, char* result, int base) { char * dtostrf(double number, signed char width, unsigned char prec, char *s) { - if (isnan(number)) { + if(isnan(number)) { strcpy(s, "nan"); return s; } - if (isinf(number)) { + if(isinf(number)) { strcpy(s, "inf"); return s; } - if (number > 4294967040.0 || number < -4294967040.0) { + if(number > 4294967040.0 || number < -4294967040.0) { strcpy(s, "ovf"); return s; } - char* out = s; - int signInt_Part = 1; - // Handle negative numbers - if (number < 0.0) { - signInt_Part = -1; + if(number < 0.0) { + *out = '-'; + ++out; number = -number; } - // calc left over digits - if (prec > 0) - { - width -= (prec + 1); - } - // Round correctly so that print(1.999, 2) prints as "2.00" double rounding = 0.5; - for (uint8_t i = 0; i < prec; ++i) + for(uint8_t i = 0; i < prec; ++i) rounding /= 10.0; number += rounding; // Extract the integer part of the number and print it - unsigned long int_part = (unsigned long)number; - double remainder = number - (double)int_part; - out += sprintf(out, "%*ld", width, int_part * signInt_Part); + unsigned long int_part = (unsigned long) number; + double remainder = number - (double) int_part; + out += sprintf(out, "%ld", int_part); // Print the decimal point, but only if there are digits beyond - if (prec > 0) { + if(prec > 0) { *out = '.'; ++out; + } - - for (unsigned char decShift = prec; decShift > 0; decShift--) { - remainder *= 10.0; - } - sprintf(out, "%0*d", prec, (int)remainder); + for (unsigned char decShift = prec; decShift > 0; decShift--) { + remainder *= 10.0; } + sprintf(out, "%0*d", prec, (int)remainder); return s; } diff --git a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp index b91dd59128..c2b5781f1f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp @@ -135,17 +135,6 @@ int printf_P(const char* formatP, ...) { return ret; } -int sprintf_P(char* str, const char* formatP, ...) { - int ret; - va_list arglist; - va_start(arglist, formatP); - - ret = vsnprintf_P(str, SIZE_IRRELEVANT, formatP, arglist); - - va_end(arglist); - return ret; -} - int snprintf_P(char* str, size_t strSize, const char* formatP, ...) { int ret; va_list arglist; diff --git a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h index 7669058be3..e6db10fbda 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h @@ -50,8 +50,7 @@ size_t strnlen_P(const char *s, size_t size); #define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT) int printf_P(const char *formatP, ...) __attribute__ ((format (printf, 1, 2))); -int sprintf_P(char *str, const char *formatP, ...) __attribute__((format(printf, 2, 3))); -int snprintf_P(char *str, size_t strSize, const char *formatP, ...) __attribute__((format(printf, 3, 4))); +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