diff --git a/README.md b/README.md index 4af1e524e6..f2c45e50cd 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,6 @@ toggle power). - analogWrite (PWM). ESP8266 has only one hardware PWM source. It is not yet clear how to use it with analogWrite API. Software PWM is also an option, but apparently it causes issues with WiFi connectivity. - pulseIn - I2C slave mode -- Serial modes other than 8n1 - WiFi.RSSI. SDK doesn't seem to have an API to get RSSI for the current network. So far the only way to obtain RSSI is to disconnect, perform a scan, and get the RSSI value from there. - Upload sketches via WiFi. Conceptually and technically simple, but need to figure out how to provide the best UX for this feature. diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 19c25e8995..3060ba1858 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -82,6 +82,18 @@ void yield(void); #define degrees(rad) ((rad)*RAD_TO_DEG) #define sq(x) ((x)*(x)) +#define kHz (1000L) +#define MHz (1000L*kHz) +#define GHz (1000L*MHz) + +#define kBit (1024L) +#define MBit (1024L*kBit) +#define GBit (1024L*MBit) + +#define kB (1024L) +#define MB (1024L*kB) +#define GB (1024L*MB) + void ets_intr_lock(); void ets_intr_unlock(); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 3d70d61fe1..5362da4da3 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp @@ -108,3 +108,70 @@ uint8_t EspClass::getCPUfreqMHz(void) { return system_get_cpu_freq(); } + + +uint32_t EspClass::getFlashChipId(void) +{ + return spi_flash_get_id(); +} + +uint32_t EspClass::getFlashChipSize(void) +{ + uint32_t data; + uint8_t * bytes = (uint8_t *) &data; + // read first 4 byte (magic byte + flash config) + if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) { + switch((bytes[3] & 0xF0) >> 4) { + case 0x0: // 4 Mbit (512KB) + return (512 * kB); + case 0x1: // 2 MBit (256KB) + return (256 * kB); + case 0x2: // 8 MBit (1MB) + return (1 * MB); + case 0x3: // 16 MBit (2MB) + return (2 * MB); + case 0x4: // 32 MBit (4MB) + return (4 * MB); + default: // fail? + return 0; + } + } + return 0; +} + +uint32_t EspClass::getFlashChipSpeed(void) +{ + uint32_t data; + uint8_t * bytes = (uint8_t *) &data; + // read first 4 byte (magic byte + flash config) + if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) { + switch(bytes[3] & 0x0F) { + case 0x0: // 40 MHz + return (40 * MHz); + case 0x1: // 26 MHz + return (26 * MHz); + case 0x2: // 20 MHz + return (20 * MHz); + case 0xF: // 80 MHz + return (80 * MHz); + default: // fail? + return 0; + } + } + return 0; +} + +FlashMode_t EspClass::getFlashChipMode(void) +{ + FlashMode_t mode = FM_FAILD; + uint32_t data; + uint8_t * bytes = (uint8_t *) &data; + // read first 4 byte (magic byte + flash config) + if(spi_flash_read(0x0000, &data, 4) == SPI_FLASH_RESULT_OK) { + mode = (FlashMode_t) bytes[2]; + if(mode > FM_DOUT) { + mode = FM_FAILD; + } + } + return mode; +} diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index f4d6b652b1..97a614c716 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -49,6 +49,14 @@ enum WakeMode { WAKE_RF_DISABLED = 4 // disable RF after deep-sleep wake up, just like modem sleep, there will be the smallest current. }; +typedef enum { + FM_QIO = 0x00, + FM_QOUT = 0x01, + FM_DIO = 0x02, + FM_DOUT = 0x03, + FM_FAILD = 0xFF +} FlashMode_t; + class EspClass { public: EspClass(); @@ -70,6 +78,7 @@ class EspClass { uint32_t getChipId(void); + const char * getSDKversion(void); uint8_t getBootVersion(void); @@ -77,6 +86,11 @@ class EspClass { uint8_t getCPUfreqMHz(void); + uint32_t getFlashChipId(void); + uint32_t getFlashChipSize(void); + uint32_t getFlashChipSpeed(void); + FlashMode_t getFlashChipMode(void); + }; extern EspClass ESP; diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 8fdf22cf40..cb97c6f9a9 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -27,6 +27,7 @@ extern "C" { #include "osapi.h" #include "mem.h" #include "user_interface.h" +#include "smartconfig.h" #include "lwip/opt.h" #include "lwip/err.h" #include "lwip/dns.h" @@ -375,6 +376,45 @@ int ESP8266WiFiClass::hostByName(const char* aHostname, IPAddress& aResult) return (aResult != 0) ? 1 : 0; } +void ESP8266WiFiClass::beginSmartConfig() +{ + if (_smartConfigStarted) + return; + + WiFi.mode(WIFI_STA); + + _smartConfigStarted = true; + + //SC_TYPE_ESPTOUCH use ESPTOUCH for smartconfig, or use SC_TYPE_AIRKISS for AIRKISS + smartconfig_start(SC_TYPE_ESPTOUCH, &ESP8266WiFiClass::_smartConfigDone); +} + +void ESP8266WiFiClass::stopSmartConfig() +{ + if (!_smartConfigStarted) + return; + + smartconfig_stop(); + _smartConfigStarted = false; +} + +bool ESP8266WiFiClass::smartConfigDone(){ + if (!_smartConfigStarted) + return false; + + return smartconfig_get_status() == SC_STATUS_LINK_OVER; +} + +void ESP8266WiFiClass::_smartConfigDone(void* result) +{ + station_config* sta_conf = reinterpret_cast(result); + + wifi_station_set_config(sta_conf); + wifi_station_disconnect(); + wifi_station_connect(); +} + + void ESP8266WiFiClass::printDiag(Print& p) { const char* modes[] = {"NULL", "STA", "AP", "STA+AP"}; diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index ff7b39bba8..46d6b64afb 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -211,12 +211,29 @@ class ESP8266WiFiClass */ void printDiag(Print& dest); + /* + * Start SmartConfig + * + */ + void beginSmartConfig(); + + /* + * Query SmartConfig status, to decide when stop config + * + */ + bool smartConfigDone(); + + void stopSmartConfig(); + friend class WiFiClient; friend class WiFiServer; protected: static void _scanDone(void* result, int status); void * _getScanInfoByIndex(int i); + static void _smartConfigDone(void* result); + bool _smartConfigStarted = false; + static size_t _scanCount; static void* _scanResult; diff --git a/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index 0b5b090da1..fe99019fed 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/platform.txt @@ -23,7 +23,7 @@ compiler.S.flags=-c -g -x assembler-with-cpp -MMD compiler.c.elf.ldscript=eagle.app.v6.ld compiler.c.elf.flags=-nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-T{compiler.c.elf.ldscript}" compiler.c.elf.cmd=xtensa-lx106-elf-gcc -compiler.c.elf.libs=-lgcc -lm -lhal -lphy -lnet80211 -llwip -lwpa -lmain -lpp +compiler.c.elf.libs=-lgcc -lm -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 -std=c++11 -MMD diff --git a/hardware/tools/esp8266/sdk/ld/eagle.app.v6.ld b/hardware/tools/esp8266/sdk/ld/eagle.app.v6.ld index e290c93a20..74c3d2f2a2 100644 --- a/hardware/tools/esp8266/sdk/ld/eagle.app.v6.ld +++ b/hardware/tools/esp8266/sdk/ld/eagle.app.v6.ld @@ -154,6 +154,7 @@ SECTIONS *core_esp8266_*.o(.literal*, .text*) *.cpp.o(.literal*, .text*) *libm.a:(.literal .text .literal.* .text.*) + *libsmartconfig.a:(.literal .text .literal.* .text.*) *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) _irom0_text_end = ABSOLUTE(.); } >irom0_0_seg :irom0_0_phdr