From 76a73c7f8a42d05f43a767310cd29e414ed7fa6b Mon Sep 17 00:00:00 2001 From: Pablotis Date: Sat, 16 May 2015 11:11:42 +0200 Subject: [PATCH 01/77] Readme changes --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bf6cba3b36..0143944eb0 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ Also note that multicast doesn't work on softAP interface. WiFiServer, WiFiClient, and WiFiUDP behave mostly the same way as with WiFi shield library. Four samples are provided for this library. +You can see more commands here: [http://www.arduino.cc/en/Reference/WiFi](http://www.arduino.cc/en/Reference/WiFi) #### Ticker #### @@ -137,7 +138,7 @@ Setting the Clock polarity (CPOL) is not supported, yet (SPI_MODE2 and SPI_MODE3 #### ESP-specific APIs #### -APIs related to deep sleep and watchdog timer are available in the ```ESP``` object. +APIs related to deep sleep and watchdog timer are available in the ```ESP``` object, only available in Alpha version. ```ESP.deepSleep(microseconds, mode)``` will put the chip into deep sleep. ```mode``` is one of ```WAKE_RF_DEFAULT```, ```WAKE_RFCAL```, ```WAKE_NO_RFCAL```, ```WAKE_RF_DISABLED```. (GPIO16 needs to be tied to RST to wake from deepSleep.) From 87ebf84f46475dfed6f396fddccc45becc97fa69 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 22 May 2015 10:46:56 +0200 Subject: [PATCH 02/77] add __attribute__ format to Print::printf compiler now gives warnings by miss usage of printf --- hardware/esp8266com/esp8266/cores/esp8266/Print.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Print.h b/hardware/esp8266com/esp8266/cores/esp8266/Print.h index 7366174f5a..a0df267c1f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Print.h +++ b/hardware/esp8266com/esp8266/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 06caa7f1991cc369eec5afcdea0f6f52d1acb92f Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sat, 23 May 2015 12:48:56 +0300 Subject: [PATCH 03/77] Update SDK to 1.1.0 (#306) --- hardware/esp8266com/esp8266/changes.md | 2 + .../cores/esp8266/core_esp8266_main.cpp | 6 + .../esp8266/cores/esp8266/spiffs/spiffs.h | 1 - .../esp8266/tools/sdk/changelog.txt | 103 ++++++++- .../esp8266/tools/sdk/include/eagle_soc.h | 4 +- .../esp8266/tools/sdk/include/espconn.h | 210 +++++++++--------- .../esp8266/tools/sdk/include/osapi.h | 3 + .../esp8266/tools/sdk/include/smartconfig.h | 6 +- .../esp8266/tools/sdk/include/sntp.h | 6 +- .../tools/sdk/include/user_interface.h | 30 ++- .../esp8266/tools/sdk/lib/libjson.a | Bin 12714 -> 12714 bytes .../esp8266/tools/sdk/lib/liblwip.a | Bin 299544 -> 301976 bytes .../esp8266/tools/sdk/lib/libmain.a | Bin 109456 -> 146208 bytes .../esp8266/tools/sdk/lib/libnet80211.a | Bin 186022 -> 187862 bytes .../esp8266com/esp8266/tools/sdk/lib/libphy.a | Bin 145068 -> 147470 bytes .../esp8266com/esp8266/tools/sdk/lib/libpp.a | Bin 180144 -> 183274 bytes .../esp8266/tools/sdk/lib/libsmartconfig.a | Bin 93184 -> 93140 bytes .../esp8266com/esp8266/tools/sdk/lib/libssl.a | Bin 164570 -> 165002 bytes .../esp8266/tools/sdk/lib/libupgrade.a | Bin 16212 -> 16990 bytes .../esp8266com/esp8266/tools/sdk/lib/libwpa.a | Bin 124464 -> 124712 bytes hardware/esp8266com/esp8266/tools/sdk/version | 2 +- 21 files changed, 250 insertions(+), 123 deletions(-) mode change 100755 => 100644 hardware/esp8266com/esp8266/tools/sdk/include/sntp.h mode change 100755 => 100644 hardware/esp8266com/esp8266/tools/sdk/lib/libjson.a mode change 100755 => 100644 hardware/esp8266com/esp8266/tools/sdk/lib/libupgrade.a diff --git a/hardware/esp8266com/esp8266/changes.md b/hardware/esp8266com/esp8266/changes.md index 32fabfd53f..22da473e83 100644 --- a/hardware/esp8266com/esp8266/changes.md +++ b/hardware/esp8266com/esp8266/changes.md @@ -15,6 +15,8 @@ ### Tools +- SDK updated to 1.1.0 (#306) + ## 1.6.4-673-g8cd3697 May 22, 2015 diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp index d45165443c..34e436c880 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp @@ -116,6 +116,12 @@ void init_done() { esp_schedule(); } +extern "C" { +void user_rf_pre_init() { + +} +} + extern "C" { void user_init(void) { uart_div_modify(0, UART_CLK_FREQ / (115200)); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs.h b/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs.h index 7df7ae0496..3765604365 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/spiffs/spiffs.h @@ -511,7 +511,6 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); #endif #endif -#include "spiffs_esp8266.h" #ifdef __cplusplus } diff --git a/hardware/esp8266com/esp8266/tools/sdk/changelog.txt b/hardware/esp8266com/esp8266/tools/sdk/changelog.txt index 86bb16cee0..ad750024a6 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/changelog.txt +++ b/hardware/esp8266com/esp8266/tools/sdk/changelog.txt @@ -1,3 +1,102 @@ +esp_iot_sdk_v1.1.0_15_05_22 Release Note +---------------------------------------- +Resolved Issues(Bugs below are eligible for Bug Bounty Program): +1.Predictable TLS random values leads to insecure connections [projectgus] +2.Connection problem in softAP+station mode.[智捷通] +3.Low heap cause of reset when connect using SSL. [TuanPM] +4.Smart config issue [bigbear] + +Document "2C_ESP8266__Programming Guide" updates: +1.Update Demo code of rtc timer in appendix, and rtc timer will return to zero after deep-sleep wake up. [andrew] +2.Add "3.espconn callback" in appendix to introduce espconn callbacks and the pointer may be different in different callback.[nagverma] +3.Add RF description in “2.Overview”,if RF is disabled,ESP8266 station and soft-AP are both disabled.[yiaiguo] +4.Revise name of API "wifi_softap_set_dhcps_offer_option" [ryan] + +Optimization: +1.Solving the problem that some Wi-Fi events may be missing during test. +2.UART Wi-Fi passthrough of UDP maybe change to oneway. [orgmar] +3.Optimized FOTA to make upgrade faster +4.ESP8266 soft-AP can connected to 8 stations at most, softap_config.max_connection default is 4 +5.ESP8266 station will connect to the stronger WiFi signal, if there are several APs sharing the same SSID.[stefan] +6.Add 1024KB+1024KB flash map which need boot_v1.4+, more details in document "2A-ESP8266_IOT_SDK_User_Manual" +7.Optimized PWM driver +8.Revised structure mdns_info to support 10 groups of text data. +9.Add user_rf_pre_init in user_main.c, user can set configuration of RF in it. + +Added APIs: +1.sntp_set_timezone: set SNTP time zone. +2.espconn_dns_setserver : set default DNS server +3.system_uart_de_swap : disable UART0 swap +4.system_get_flash_size_map: get flash size and flash map +5.system_phy_set_max_tpw : set maximum RF TX power +6.system_phy_set_tpw_via_vdd33 :set RF TX power according to VDD33 +7.system_phy_set_rfoption : set RF option +8.wifi_station_get_rssi:get rssi of AP which ESP8266 station connected to   +9.wifi_softap_get_station_num :get number count of stations connected to ESP8266 soft-AP + +AT_v0.24 Release Note: +Note: For AT firmware to support FOTA, flash size need to be 1024KB or more than that. +Optimization: +1.Disable data echo of command "AT+CIPSEND" +2.Optimized "AT+CWJAP?" to get channel and rssi +3.ESP8266 station IP can only be got and inquiried after ESP8266 station connected to AP + +Added AT command: +1.AT+RFPOWER :set maximum RF TX power +2.AT+RFVDD : set RF TX power according to VDD33 + + +自从乐鑫信息科技于 2015-03-20 启动 Bug 赏金计划以来,我们收到了一些重要问题反馈及建议,感谢世界各地的开发者对 ESP8266的关注,推动我们的软件更进一步,技术支持团队也得到迅速地成长。我们将在如下发布日志中点名感谢您的帮助。 + +esp_iot_sdk_v1.1.0_15_05_22 Release Note +修正问题(符合乐鑫 Bug 赏金计划): +1.随机值的生成可以被预测,完善随机数的产生机制 [projectgus] +2.softAP+station 模式下,可能连接 ESP8266 soft-AP 失败 [智捷通] +3.内存不足导致 SSL 连接时重启. [TuanPM] +4.Smart config 相关问题 [bigbear] + +文档 "2C_ESP8266__Programming Guide" 更新: +1.更新附录中的 RTC 示例代码,RTC 时钟会因 deep-sleep 清零. [andrew] +2.附录新增 "3.espconn callback"介绍 espconn callbacks,不同的 espconn callback 中 espconn 结构体指针可能不同.[nagverma] +3.“2.概述”中增加 RF 设置的说明,如果不打开 RF ,ESP8266 station 和 soft-AP 均失效。[yiaiguo] +4.修正 API 名称 "wifi_softap_set_dhcps_offer_option" [ryan] + +优化: +1.解决特定测试环境下某些 Wi-Fi events 可能缺失的问题。 +2.UDP 透传可能变成单向传输的相关问题 [orgmar] +3.优化 FOTA 的底层实现,加快升级速度 +4.ESP8266 soft-AP 最多可连接 8 个 station, 默认最大连接个数为 4 +5.当多个 AP 的 SSID password相同时,ESP8266 station 默认连接信号最强的 AP。[stefan] +6.更新 boot_v1.4+ 及编译文件,支持 1024KB+1024KB flash map , flash map 的详细介绍见文档 "2A-ESP8266_IOT_SDK_User_Manual" +7.优化 PWM driver +8.优化 structure mdns_info 支持 10 组 text data. +9.在 user_main.c 中新增 user_rf_pre_init , 用户可在 user_rf_pre_init 中调用 system_phy_set_rfoption 配置 RF 初始化. + +新增 APIs: +1.sntp_set_timezone: SNTP 设置时区 +2.espconn_dns_setserver : 设置默认 DNS server +3.system_uart_de_swap : 取消 UART0 转换 +4.system_get_flash_size_map: 查询 flash size 和 flash map +5.system_phy_set_max_tpw : 设置 RF TX power 最大值 +6.system_phy_set_tpw_via_vdd33 :根据 VDD33 设置 RF TX power +7.system_phy_set_rfoption : 设置 RF +8.wifi_station_get_rssi:查询 ESP8266 station 连接的 AP 的信号强度   +9.wifi_softap_get_station_num :查询连接到 ESP8266 soft-AP 的 station 数目 + +AT_v0.24 Release Note: +注意:运行 AT 固件,支持云端升级,请使用 1024KB 或以上容量的 flash + +优化: +1."AT+CIPSEND" 发送数据时,数据不回显 +2.优化"AT+CWJAP?" 可获得信道和信号强度 +3.必须在 ESP8266 station 连接到 AP 后,才能查询到 ESP8266 station IP + +新增 AT command: +1.AT+RFPOWER :设置 RF TX power 最大值 +2.AT+RFVDD : 根据 VDD33 设置 RF TX power + +Thanks for your interest in ESP8266 ! + esp_iot_sdk_v1.0.1_15_05_04_p1 ------------------------------------------- Here is a patch for station+softAP issue that users may have, based on SDK_v1.0.1, @@ -18,7 +117,7 @@ Optimization: 1. Optimized IOT_Espressif_EspTouch.APK (apply for access from Espressif) for improved compatibility. [???] 2. TCP server can not open again immediately with the same port [624908539] 3. Update UART driver for parity bit value may be incorrect [1062583993] -4. Add define of �ICACHE_RODATA_ATTR� for Symbol 'ICACHE_RODATA_ATTR' could not be resolved. [???] +4. Add define of “ICACHE_RODATA_ATTR” for Symbol 'ICACHE_RODATA_ATTR' could not be resolved. [???] 5. Add API wifi_softap_dhcps_set_offer_option to enable/disable ESP8266 softAP DHCP server default gateway. [xyz769] 6. AT register_uart_rx_intr may enter callback twice. [???] 7.optimize document that WPA password length range : 8 ~ 64 bytes [785057041] @@ -75,7 +174,7 @@ Fix bugs: 4.UDP broadcast issue in WEP Optimize: -1.Add more details about measure ADC & VDD3P3 in appendix of document�2C-SDK-Espressif IoT SDK Programming Guide�[BBP#15 reporter (DarkByte)] +1.Add more details about measure ADC & VDD3P3 in appendix of document“2C-SDK-Espressif IoT SDK Programming Guide”[BBP#15 reporter (DarkByte)] 2.Can not do any WiFi related operation if WiFi mode is in NULL_MODE [BBP#23 reporter (hao.wang)] 3.start_ip and end_ip won't change through API wifi_softap_set_dhcps_lease [BBP#37 reporter (glb)] 4.AT get into busy state [BBP#35 reporter (tommy_hk)] diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/eagle_soc.h b/hardware/esp8266com/esp8266/tools/sdk/include/eagle_soc.h index 59214159e4..71e32dc2e1 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/eagle_soc.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/eagle_soc.h @@ -184,9 +184,9 @@ #define PERIPHS_IO_MUX_FUNC 0x13 #define PERIPHS_IO_MUX_FUNC_S 4 #define PERIPHS_IO_MUX_PULLUP BIT7 -#define PERIPHS_IO_MUX_PULLDWN BIT6 +#define PERIPHS_IO_MUX_PULLUP2 BIT6 #define PERIPHS_IO_MUX_SLEEP_PULLUP BIT3 -#define PERIPHS_IO_MUX_SLEEP_PULLDWN BIT2 +#define PERIPHS_IO_MUX_SLEEP_PULLUP2 BIT2 #define PERIPHS_IO_MUX_SLEEP_OE BIT1 #define PERIPHS_IO_MUX_OE BIT0 diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/espconn.h b/hardware/esp8266com/esp8266/tools/sdk/include/espconn.h index eaf23bbecb..a85c823928 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/espconn.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/espconn.h @@ -126,9 +126,8 @@ struct mdns_info { char *server_name; uint16 server_port; unsigned long ipAddr; - char *txt_data; + char *txt_data[10]; }; - /****************************************************************************** * FunctionName : espconn_connect * Description : The function given as the connect @@ -174,19 +173,6 @@ sint8 espconn_accept(struct espconn *espconn); sint8 espconn_create(struct espconn *espconn); -/****************************************************************************** - * FunctionName : espconn_sent - * Description : sent data for client or server - * Parameters : espconn -- espconn to set for client or server - * psent -- data to send - * length -- length of data to send - * Returns : none -*******************************************************************************/ - -sint8 espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length); - -/***** Connetion Settings *******/ - /****************************************************************************** * FunctionName : espconn_tcp_get_max_con * Description : get the number of simulatenously active TCP connections @@ -218,7 +204,7 @@ sint8 espconn_tcp_get_max_con_allow(struct espconn *espconn); * FunctionName : espconn_tcp_set_max_con_allow * Description : set the count of simulatenously active connections on the server * Parameters : espconn -- espconn to set the count - * num -- support the connection number + * num -- support the connection number * Returns : result *******************************************************************************/ @@ -228,7 +214,7 @@ sint8 espconn_tcp_set_max_con_allow(struct espconn *espconn, uint8 num); * FunctionName : espconn_regist_time * Description : used to specify the time that should be called when don't recv data * Parameters : espconn -- the espconn used to the connection - * interval -- the timer when don't recv data + * interval -- the timer when don't recv data * Returns : none *******************************************************************************/ @@ -248,69 +234,12 @@ sint8 espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_in * FunctionName : espconn_get_packet_info * Description : get the packet info with host * Parameters : espconn -- the espconn used to disconnect the connection - * infoarg -- the packet info + * infoarg -- the packet info * Returns : the errur code *******************************************************************************/ sint8 espconn_get_packet_info(struct espconn *espconn, struct espconn_packet* infoarg); -/****************************************************************************** - * FunctionName : espconn_port - * Description : access port value for client so that we don't end up bouncing - * all connections at the same time . - * Parameters : none - * Returns : access port value -*******************************************************************************/ - -uint32 espconn_port(void); - -/****************************************************************************** - * FunctionName : espconn_set_opt - * Description : access port value for client so that we don't end up bouncing - * all connections at the same time . - * Parameters : espconn -- the espconn used to set the connection - * opt -- the option to set - * Returns : access port value -*******************************************************************************/ - -sint8 espconn_set_opt(struct espconn *espconn, uint8 opt); - -/****************************************************************************** - * FunctionName : espconn_clear_opt - * Description : clear the option for connections so that we don't end up bouncing - * all connections at the same time . - * Parameters : espconn -- the espconn used to set the connection - * opt -- the option for clear - * Returns : the result -*******************************************************************************/ - -sint8 espconn_clear_opt(struct espconn *espconn, uint8 opt); - -/****************************************************************************** - * FunctionName : espconn_set_keepalive - * Description : access level value for connection so that we set the value for - * keep alive - * Parameters : espconn -- the espconn used to set the connection - * level -- the connection's level - * value -- the value of time(s) - * Returns : access port value -*******************************************************************************/ - -sint8 espconn_set_keepalive(struct espconn *espconn, uint8 level, void* optarg); - -/****************************************************************************** - * FunctionName : espconn_get_keepalive - * Description : access level value for connection so that we get the value for - * keep alive - * Parameters : espconn -- the espconn used to get the connection - * level -- the connection's level - * Returns : access keep alive value -*******************************************************************************/ - -sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg); - -/***** CALLBACKS *******/ - /****************************************************************************** * FunctionName : espconn_regist_sentcb * Description : Used to specify the function that should be called when data @@ -324,9 +253,9 @@ sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg); sint8 espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_cb); /****************************************************************************** - * FunctionName : espconn_regist_write_finish + * FunctionName : espconn_regist_sentcb * Description : Used to specify the function that should be called when data - * has been successfully written to the send buffer + * has been successfully delivered to the remote host. * Parameters : espconn -- espconn to set the sent callback * sent_cb -- sent callback function to call for this espconn * when data is successfully sent @@ -335,6 +264,17 @@ sint8 espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callback sent_ sint8 espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn); +/****************************************************************************** + * FunctionName : espconn_sent + * Description : sent data for client or server + * Parameters : espconn -- espconn to set for client or server + * psent -- data to send + * length -- length of data to send + * Returns : none +*******************************************************************************/ + +sint8 espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length); + /****************************************************************************** * FunctionName : espconn_regist_connectcb * Description : used to specify the function that should be called when @@ -378,7 +318,59 @@ sint8 espconn_regist_reconcb(struct espconn *espconn, espconn_reconnect_callback sint8 espconn_regist_disconcb(struct espconn *espconn, espconn_connect_callback discon_cb); -/***** DNS *******/ +/****************************************************************************** + * FunctionName : espconn_port + * Description : access port value for client so that we don't end up bouncing + * all connections at the same time . + * Parameters : none + * Returns : access port value +*******************************************************************************/ + +uint32 espconn_port(void); + +/****************************************************************************** + * FunctionName : espconn_set_opt + * Description : access port value for client so that we don't end up bouncing + * all connections at the same time . + * Parameters : none + * Returns : access port value +*******************************************************************************/ + +sint8 espconn_set_opt(struct espconn *espconn, uint8 opt); + +/****************************************************************************** + * FunctionName : espconn_clear_opt + * Description : clear the option for connections so that we don't end up bouncing + * all connections at the same time . + * Parameters : espconn -- the espconn used to set the connection + * opt -- the option for clear + * Returns : the result +*******************************************************************************/ + +sint8 espconn_clear_opt(struct espconn *espconn, uint8 opt); + +/****************************************************************************** + * FunctionName : espconn_set_keepalive + * Description : access level value for connection so that we set the value for + * keep alive + * Parameters : espconn -- the espconn used to set the connection + * level -- the connection's level + * value -- the value of time(s) + * Returns : access port value +*******************************************************************************/ + +sint8 espconn_set_keepalive(struct espconn *espconn, uint8 level, void* optarg); + +/****************************************************************************** + * FunctionName : espconn_get_keepalive + * Description : access level value for connection so that we get the value for + * keep alive + * Parameters : espconn -- the espconn used to get the connection + * level -- the connection's level + * Returns : access keep alive value +*******************************************************************************/ + +sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *optarg); /****************************************************************************** * TypedefName : dns_found_callback @@ -413,8 +405,6 @@ typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *ca err_t espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t *addr, dns_found_callback found); -/***** SSL *******/ - /****************************************************************************** * FunctionName : espconn_encry_connect * Description : The function given as connection @@ -437,7 +427,7 @@ sint8 espconn_secure_disconnect(struct espconn *espconn); * FunctionName : espconn_encry_sent * Description : sent data for client or server * Parameters : espconn -- espconn to set for client or server - * psent -- data to send + * psent -- data to send * length -- length of data to send * Returns : none *******************************************************************************/ @@ -448,8 +438,8 @@ sint8 espconn_secure_sent(struct espconn *espconn, uint8 *psent, uint16 length); * FunctionName : espconn_secure_set_size * Description : set the buffer size for client or server * Parameters : level -- set for client or server - * 1: client,2:server,3:client and server - * size -- buffer size + * 1: client,2:server,3:client and server + * size -- buffer size * Returns : true or false *******************************************************************************/ @@ -459,7 +449,7 @@ bool espconn_secure_set_size(uint8 level, uint16 size); * FunctionName : espconn_secure_get_size * Description : get buffer size for client or server * Parameters : level -- set for client or server - * 1: client,2:server,3:client and server + * 1: client,2:server,3:client and server * Returns : buffer size for client or server *******************************************************************************/ @@ -474,31 +464,11 @@ sint16 espconn_secure_get_size(uint8 level); sint8 espconn_secure_accept(struct espconn *espconn); -/***** TCP RX HOLD *******/ - -/****************************************************************************** - * FunctionName : espconn_recv_hold - * Description : hold tcp receive - * Parameters : espconn -- espconn to hold - * Returns : none -*******************************************************************************/ -sint8 espconn_recv_hold(struct espconn *pespconn); - -/****************************************************************************** - * FunctionName : espconn_recv_unhold - * Description : unhold tcp receive - * Parameters : espconn -- espconn to unhold - * Returns : none -*******************************************************************************/ -sint8 espconn_recv_unhold(struct espconn *pespconn); - -/***** IGMP *******/ - /****************************************************************************** * FunctionName : espconn_igmp_join * Description : join a multicast group * Parameters : host_ip -- the ip address of udp server - * multicast_ip -- multicast ip given by user + * multicast_ip -- multicast ip given by user * Returns : none *******************************************************************************/ sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip); @@ -507,18 +477,32 @@ sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip); * FunctionName : espconn_igmp_leave * Description : leave a multicast group * Parameters : host_ip -- the ip address of udp server - * multicast_ip -- multicast ip given by user + * multicast_ip -- multicast ip given by user * Returns : none *******************************************************************************/ sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip); -/***** mDNS *******/ +/****************************************************************************** + * FunctionName : espconn_recv_hold + * Description : hold tcp receive + * Parameters : espconn -- espconn to hold + * Returns : none +*******************************************************************************/ +sint8 espconn_recv_hold(struct espconn *pespconn); + +/****************************************************************************** + * FunctionName : espconn_recv_unhold + * Description : unhold tcp receive + * Parameters : espconn -- espconn to unhold + * Returns : none +*******************************************************************************/ +sint8 espconn_recv_unhold(struct espconn *pespconn); /****************************************************************************** * FunctionName : espconn_mdns_init * Description : register a device with mdns * Parameters : ipAddr -- the ip address of device - * hostname -- the hostname of device + * hostname -- the hostname of device * Returns : none *******************************************************************************/ @@ -594,5 +578,15 @@ void espconn_mdns_disable(void); * Returns : none *******************************************************************************/ void espconn_mdns_enable(void); +/****************************************************************************** + * FunctionName : espconn_dns_setserver + * Description : Initialize one of the DNS servers. + * Parameters : numdns -- the index of the DNS server to set must + * be < DNS_MAX_SERVERS = 2 + * dnsserver -- IP address of the DNS server to set + * Returns : none +*******************************************************************************/ +void espconn_dns_setserver(char numdns, ip_addr_t *dnsserver); + #endif diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/osapi.h b/hardware/esp8266com/esp8266/tools/sdk/include/osapi.h index 11e03803fa..404efb8556 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/osapi.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/osapi.h @@ -54,5 +54,8 @@ extern int os_printf_plus(const char * format, ...) __attribute__ ((format (prin #define os_printf os_printf_plus #endif +unsigned long os_random(void); +int os_get_random(unsigned char *buf, size_t len); + #endif diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/smartconfig.h b/hardware/esp8266com/esp8266/tools/sdk/include/smartconfig.h index 22b04ff1b3..4035ad39da 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/smartconfig.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/smartconfig.h @@ -6,13 +6,10 @@ #ifndef __SMARTCONFIG_H__ #define __SMARTCONFIG_H__ -typedef void (*sc_callback_t)(void *data); - typedef enum { SC_STATUS_WAIT = 0, SC_STATUS_FIND_CHANNEL, SC_STATUS_GETTING_SSID_PSWD, - SC_STATUS_GOT_SSID_PSWD, SC_STATUS_LINK, SC_STATUS_LINK_OVER, } sc_status; @@ -22,7 +19,8 @@ typedef enum { SC_TYPE_AIRKISS, } sc_type; -sc_status smartconfig_get_status(void); +typedef void (*sc_callback_t)(sc_status status, void *pdata); + const char *smartconfig_get_version(void); bool smartconfig_start(sc_type type, sc_callback_t cb, ...); bool smartconfig_stop(void); diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/sntp.h b/hardware/esp8266com/esp8266/tools/sdk/include/sntp.h old mode 100755 new mode 100644 index 2d2749a341..6cdb337e31 --- a/hardware/esp8266com/esp8266/tools/sdk/include/sntp.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/sntp.h @@ -8,13 +8,17 @@ #include "ip_addr.h" #endif /** - * get the seconds since Jan 01, 1970, 00:00 (GMT) + * get the seconds since Jan 01, 1970, 00:00 (GMT + 8) */ uint32 sntp_get_current_timestamp(); /** * get real time (GTM + 8 time zone) */ char* sntp_get_real_time(long t); +/** + * SNTP set time_zone (default GMT + 8) + */ +bool sntp_set_timezone(sint8 timezone); /** * Initialize this module. * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC). diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h b/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h index 1fa01edd99..7f593e0eb7 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h @@ -25,11 +25,13 @@ enum rst_reason { DEFAULT_RST_FLAG = 0, WDT_RST_FLAG = 1, - EXP_RST_FLAG = 2 + EXCEPTION_RST_FLAG = 2, + SOFT_RST_FLAG = 3, + DEEP_SLEEP_AWAKE_FLAG = 4 }; struct rst_info{ - uint32 flag; + uint32 reason; uint32 exccause; uint32 epc1; uint32 epc2; @@ -87,6 +89,7 @@ bool system_rtc_mem_read(uint8 src_addr, void *des_addr, uint16 load_size); bool system_rtc_mem_write(uint8 des_addr, const void *src_addr, uint16 save_size); void system_uart_swap(void); +void system_uart_de_swap(void); uint16 system_adc_read(void); uint16 system_get_vdd33(void); @@ -110,6 +113,22 @@ bool system_restart_enhance(uint8 bin_type, uint32 bin_addr); bool system_update_cpu_freq(uint8 freq); uint8 system_get_cpu_freq(void); +enum flash_size_map { + FLASH_SIZE_4M_MAP_256_256 = 0, + FLASH_SIZE_2M, + FLASH_SIZE_8M_MAP_512_512, + FLASH_SIZE_16M_MAP_512_512, + FLASH_SIZE_32M_MAP_512_512, + FLASH_SIZE_16M_MAP_1024_1024, + FLASH_SIZE_32M_MAP_1024_1024 +}; + +enum flash_size_map system_get_flash_size_map(void); + +void system_phy_set_max_tpw(uint8 max_tpw); +void system_phy_set_tpw_via_vdd33(uint16 vdd33); +void system_phy_set_rfoption(uint8 option); + #define NULL_MODE 0x00 #define STATION_MODE 0x01 #define SOFTAP_MODE 0x02 @@ -169,6 +188,8 @@ bool wifi_station_set_config_current(struct station_config *config); bool wifi_station_connect(void); bool wifi_station_disconnect(void); +sint8 wifi_station_get_rssi(void); + struct scan_config { uint8 *ssid; // Note: ssid == NULL, don't filter ssid. uint8 *bssid; // Note: bssid == NULL, don't filter bssid. @@ -202,6 +223,7 @@ uint8 wifi_station_get_connect_status(void); uint8 wifi_station_get_current_ap_id(void); bool wifi_station_ap_change(uint8 current_ap_id); bool wifi_station_ap_number_set(uint8 ap_number); +uint8 wifi_station_get_ap_info(struct station_config config[]); bool wifi_station_dhcpc_start(void); bool wifi_station_dhcpc_stop(void); @@ -241,15 +263,15 @@ enum dhcps_offer_option{ OFFER_END }; +uint8 wifi_softap_get_station_num(void); struct station_info * wifi_softap_get_station_info(void); void wifi_softap_free_station_info(void); -uint8 wifi_station_get_ap_info(struct station_config config[]); bool wifi_softap_dhcps_start(void); bool wifi_softap_dhcps_stop(void); bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please); enum dhcp_status wifi_softap_dhcps_status(void); -bool wifi_softap_dhcps_set_offer_option(uint8 level, void* optarg); +bool wifi_softap_set_dhcps_offer_option(uint8 level, void* optarg); #define STATION_IF 0x00 #define SOFTAP_IF 0x01 diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libjson.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libjson.a old mode 100755 new mode 100644 index cc7c69abda3c8f260da0cb8cdcfff842bd2440a2..5a889af733dd8c09d9c6c853c61f4476066ed97d GIT binary patch delta 51 tcmZ3LyefHu6o;{qk)?@|srg1FE+#l<@&ReF&0b7-l5mmD2c%z#0sw7E4mkh- delta 51 tcmZ3LyefHu6o-+eg_)_5rNKreE+#l<@&ReF&0b7-l5mmD2c%z#0swE)4o(07 diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/liblwip.a b/hardware/esp8266com/esp8266/tools/sdk/lib/liblwip.a index d3c356dcea2ced111f77ce3ae5263792c3cd2754..b4304413a9288330397e5b155ebc9500905ba97a 100644 GIT binary patch delta 55026 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 delta 52623 zcmcG%349ery8nH;PZ9z-fdpaz*^&?-K!5~MQG*5q1VsegP*D~EVFr=SaT%Ng5xqE~ zA_u48x&ecZ3n~guaNIyqVZ;Ro9T>sE9q%9m4k{{o-ru*+Q`ndL-uM2O&s!gw`qrN3=>H`p$M@=$5lY51ip9KEu~>QS z|Ni#tF|pWxvn9ib)q7&Gqqp}~#bW>eZ^{3qLcHb$vH$Jus@XB`f83J)jZtb!%=@3V zmk-4}ws+V6&)W}`F)y{4WXO-mut_t!C_q}`Fnq+C$pVOrtpIw~YvuDp< zy;6n6oxEA8ughopH@%C>UR0v z64_f~-SYb+61@f#dY!!sMkKl=YEp@E??8HeEY>a2vrW-WZ_2M}pXh(npHsJYY@hea z8-y=U^nc~G)N>u%S7yIXc&5S|1&L-iy^42SHeTzOZ+eB$<=J@IYFBHTHXJZ zM^f7=PiQb;lB)O0%c;U{=jQ*X#Hs1sS`Qs?QO3IHru$;*qeVH^NBfWT(JPlIeb@&V z(%fb@DFuCir#=`-=<;m5?E2LE-IkU&-LQLe^%ui;^lezW%P)Q>Z&Tfe2hzo(@^W`} zjJ2(Kxomw~Z-45c?(MxjsV&{Bliz0Nu4?Gbf9{sTE$f!tv;5t3Y-z!=r6o%XyXAkh zrMypLZ(CTE{63!dmyjCw@y_b&ZOy1>ReNt`$a^#N6N%psI5oDZdVAkJ!*ffUZYas$ zUzRAp=A&$XS$g27Y43&fie)c$I(b2U<5xdStB(syhGsgS4#yRxp6*e9R8L)3_3Tkf z-|Dnil_=)g&_aHTyjZNY{GIYk72&y;or@rl{C?Iz~uWpyMMexU+M- zS+Ks|&ssC5W?puZgr5Ez(=Zn6A+FPQhqzq+3TKcc%{pwiQ%Um+VR{a0~wv)>o7hh-Y( zQ>-4t(SS@ZYAQlTy%gaxx?AirdMc6tb{YLGqPyKdK8K~>rOc_&oobcK=OJ1sN5Qbm z=j~)9!tF;gIwYMgC8K=$O^(Fy+4AYFiz7OGzUfbhk2T&Lv2n)-`EQfnNj6Ce_(1`B zj7+oD=h|%{H>UsPD7e6w#ITO7uyUnhUrgHe5qmdYU=Np=eSc>oU7S3U(fKYyhKy!7 z62tAqRP@&oo7oW?_zbgoIbyR>Tq2!(J`rDHHm5Za$mOd17y;MfL1Mav)?9VOD8ubc zzdfSE4NSjFTx|Sk#0GZxuZ`&NM3o;Fc5Hz_E>|1eS3Z@vL_Em&_hL09)L)O-!`Y_4 z9noQS6Zw1?(P3BV@xZ?qQfr1!H5oXB2YkDoMW6#sd6+1c9kfO=&;Hv4imSE zM8MgpuLtxMdfax-*VVlI?huul}>MzbFxMliuT zZH;XLLIL5$Mn3Ifn&k$w&SH0*^bouLb(5D|*~6TLbsX-a6<`pf5>v!D3V?n2=u?Y= zsv`f9pkSLnK9x9gm^U?b>6z_wT2!hYZGwH<{4)RXqTqwAUPpg_QLwMh>zKVvy|O;2 ze#dK{Q!!YhgcscYu3zSjNew=$Q_i3>W3hV@!3R?O!|j7N-%)~t9hF(|;f-GV?5r+2 zrq_IV)*rm4T!9``4VtP4zm$I{k$Uj#H~nq-sb3AfxO$f-$sFg+e;gG)d{j7RP2o8z zYvy$`XHB@08TG8mS4|y##Z|LLPo6e<=7d?XsS{>Ro(PS;dRnUVwPwMwXLyZL-G=8e zj*QX1_AJNVI$S-vM{b)&KF4oIcuRygMVL|3*>BTz$g^wIZk_9%9a~&I9S_p(ShIHc z7C$*dd$UNhg5L69GG=n{xp9sB{^~Jom?&_)hik6!4V!F;km{i$-gDSzD6I?N>9cbT41~k3XM4} zN{u_p-)uZe`iI7hzK4u|l%J!)g-l0E&ogG|ooqZ@z7C6+r{e+FSzA#&b^V1mdj%

HYr(V)s!{3#c-01aMbKsI+`)b3L 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 diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libmain.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libmain.a index 265466dc110b467c732a066884fc2013f49074ef..5f1e03f7d37be301fe24eb25749ba1893ba5ed03 100644 GIT binary patch literal 146208 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

J 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
)S-a` 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 b;Ru%*V;I2?bqv$VT^%mj`bdhab@TrPi?oka delta 48165 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⁢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 a8Er5*-PgyGyZT&0_V>i5r2c`_#{Ua>-S12Q diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libpp.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libpp.a index d28457b1e721833487e8ae6328f2707fc577bfac..c2e844b54c7b23c107f7bdf74debbbe02ae5a066 100644 GIT binary patch delta 48198 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 eDRE#pJWmC`;w0AZD delta 45717 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 diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libsmartconfig.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libsmartconfig.a index 39bfe39d2fc132584c7b28a2ac80bfafcf095c5c..fc2795df3bf4d06d42c9b0c2e97ba350163f6a13 100644 GIT binary patch literal 93140 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 Z={OiGMg758DavtqhH2{x#!6BBe*wM&A+G=c literal 93184 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

ewi0#uA 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 Tr{uY)r60zCQ9XuXXp?SJ*(p3$_6 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 A9RL6T delta 6108 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 bE_+$lE$yS8sW*=o^+gawlGfE`eAGVy6qmN^ diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libupgrade.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libupgrade.a old mode 100755 new mode 100644 index 39eb41a5443efc20279742d9f5f602a5223853df..6eaebbd309ce78fe2d237ecde3e35e83df9f4ef0 GIT binary patch literal 16990 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 diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libwpa.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libwpa.a index c3d04200d949b8c87b5a9f2727ecd59400ed2bf6..39de3f00132b334091fac1cae2b2b319780180d4 100644 GIT binary patch delta 3568 zcma);e^6A{702&+`-8=O$nJuupzB*!kRL0ss~{$g1FMxxuvO4tn^9mXKh{psAf#d@ z=_2(HXJRPwoIYYRsnRB)mbNs@WHtT>Yf=LlVoc*SWUwu^aY{{1NozZpYF^LTcbBqG z+InZs-p~EM@4NTzdH0=pgJW_1m*Top1FJlqwW~cvZb>STsLlPABzN(eqKGWj&SQ*y zow2y7*huMMOgi}gqi_Rb_r}H!7GPgJ%DynFank#V>w}DaL4eN1?jr&W()#~*v~Oc@ zztLCAfTI8Cf8rc&qiwWW;F%hkz@oT;`wYVZ7;em(BfBUCFYZ_z55~<|KGmYN$EN#_W-8ag|w*T;o zD2!Og9aHX^Qkq;!nDz>+SvXu@X@s=KswY%)<{_3a$kU5q#puKM3C04>=ds7lM)WtZk9w{kQ#0XO#BmrnPdS?)5rZcB zBL-a{zJWpS3-K)sYUCr1E^r%Jk3pWhOb#cWl)q&eg1hnoOOo8N&0^RT&seb>PIDUE zz*w2wVs%2hd~MqbLza#)iyXE(4F_?RMY3;+(@>0>U#?i^G(L}-ALIvY>B4cnTy4uV z^y0osWLWAnjN>j^?HiJ` zBgr23@2_cUXp5XrIY*ZvpV%G>G@~n-roh&Xk&L^iY*N;vI%S=7%J>=1qz!W>?}wZz zv6GxB;nz7+0&jAr#Qsxbf!&Y~EJzC;-{6PT);3?wuHB7$^7iCM%9wj~%uCbpSdT8| zvt@*0$q%_0kw6G%i5(qFE`lE)D*g1TQFg`LGtA z4*Bz8`4X5>o-K!kP#b!&93FDbn&~xrwH-dmj!{BlAEd;-tD%y9crrQ0rCU?HR!%f! z!(_;C4sHW1R@C!Q>^#f9PulUkOyp{S+;lzwr-@zKKS>BFDDNEP|b$!c}$6kjL z+iM=(vCPVOnXN+OclBaM<%ZXkf!ATRyv3qdCehHda9&{Wg3lWMy*jc<@L2?xJquH* zuS!pJOsHPT?w(NBUi0dWFr^MNR_U@=X4rinsFem|?W2V8iZ_3%4Bcozra0+^s-%O%w@rnZ-fOei~DCs;F664Ni(0v?xLtcNS)5Sf_P=dvI8 zmD-ylJhJGJY4ADextz1T#n;LmE`2<}7`f8J8J@9%Bj;4Hz9;+Xp3>#;7Rf6CXM$6z z$7we)kIv{R%|-QLv0_N|>fMzFw&o-IK!f8I70!}9ON2AjZ#4?c@pBbU)8K-`DmW~* z@Ro#W-$~V9lv4D0de|kt0YSRzeo4&|%hx}%6$beXzn~r+o^XLTycz~*X#7M~z7d9& z(B&{ZD;S<)_?m_4-h_`KKujeq8DHlv7)Cu2{Z+&Mb& zm$=?ENB484wTOB7%w+rKnA(vgyqQeB$PXgZhTaeT?ILsmye~VfPGh$Xw-m3O9D#Jf zVo)xPK&GJytK3HUJxh`zj)Db#rYs$W6^5NyhaQfoJ4hW;nn`^T)l;%HH%S>lRgjh_ z=SOjhomj>?WuMInhm?f3(RT<-l#zV0r7BPUPL)MoS5+c+RY}VEFM}oY+1v1KFi_sM zDo>0-Q^xnPzC;^Uw;$azK8It!0`I^w=nXmEfmcAec?p&*Zr$J7*3evorK4@vp4~M~ zd)jJtJzmq=(59H)g-wCOmL+cp1juFr(5m*Hgyq+EulNd6_fqc}(L#aPjRM48RmRAH2Q1!SP10s4bn!g;zHomGK=3pk-11CHgkQFJj*rDPVOO%*v$2h z$djRYzR5kL5u3R_MV?Ijex|mcn@A)!XKFWpkLy%H{z5mFX~fZN-678k%`=~S zNFz3r9{K;cKy;#1ZepkrM<*)aI-M2#ie^B?5?e9XNh3CM-9#QNd(_Ifhcsd{*F_u$ zAX_tS<|Yz}&0M$8L^+zLntMniHgmn1^mNVBjSP7jpW%Meh|OF-N}l|PXFj{gO(b3n SEgpx`m`|F8q5TsOn)h$0$f}V5 delta 3278 zcma);4Qx}_702&+e$RHWliCg>5C`)d=bO+t9tqAWR_tYvK}3TElyy-)P)L)hfs}Y# zkdT}OA+?o2MNj3m6EHw!OHsre%=(x_hmBU2&}1`=N@NWbD!QeDc7d^qNn5>h@@~HN z$(4@p@BZKae!TPEy?*__HAP2EujfR3)&8o=uT@sbvR9@u_g9uH{8cNbWVv|(V{98^ zrt$fa6=qEC`TtSrXY5~NZJ0&a##h+CMI+AjB=Kn(WB(yQ=x0w9&in`iXa0YWA0`<* zX`C2mK+$iTjSIMt{}mtEYZ-hrFJc3*4`Nk@7EvfKS5BCUl&Hz144Hi9=|`oU*_a($ zV&0Q6s~nTFV$rNWrp+j^WAYd2@OkXO)5FGDv9WTceWs;Mbz1wSX`Ukbsw=D1W&;$% zh;lP)nPPjcp%x#mHRVjRbK ziu2F0rb2z9Q>6DLHepa-4TG*z--{Te6JN%l_m?<{K?Qv|Qw<3lbm2n`k@MK$QxH(P z9)3@m%sB^R%7cfQ${M>(x{bZ+l~Jb$(iQubB55<=VifmZGZk;HO%e@^EmkTXc_c5+ zmalZ?dZb*`{JO(oGj2xR56Z7{^I)?ATZ^PRT%uP=U+R(e;?Ucbz}GXCq~mSH`g{X? zQ?Vb(v{P=L#c(i*ZN)mO9DTkfV^??6?v|acyE++F%CiQilC$mING}=|;+l?Q-Hrh^ z{J}y=C7m>43)f#lhIIVFqF|7RG-3h+b+Ec@rh~S#2gK5uri#sM z?a)bBG`oMaGyU-T!Wj##LtM4W@71?UTzmCB_!~f)y6+55=tKwFw`c6YsgPuB-Xgb* zrQ$LRwf$p5S;+&qLyqDH71vW%5kBUPYuKgm06u9%UnMiO1)VstY7?!Ir^6TR_O(^|IP+?nV1GJO0K*_fp5f%ovu)8 z1>gwqUdrcjnVHXE^aYlqT5H|(%T!RT2uWGlfBpq7pXQ1%zZY6{g5xY z?cWgGHb-zI;@el@oZiY;Bzrdp43 z`T(A@=LLO5R%P&!Q(BGZQ=fA6kq6qeN%CunhKU?~lS+sO;X;9p2H|)E#aKckJ5P^y02?Q%6@*_l_{zxg*@s zM%2{O+PZsA^ZQ-u!0(`LV;3d@@GqXqOT^1{ZYSoGw-QrIu{0Ae)tM4H?MdQ2f?I7& zLiQ3wD!(R4M!*s$UZx&QLQX+1@;Pc-^lJmeE}f5aeL@>e!q1>H15-f<=9{RyIUhkT z;!OT$IKPct!?_>%JDh3!HqKGxZqBrZA8@8e^kenTHOP*9%q3d>=bVR-zv8@r?iz!Z zHG(?5lf;yPb)3mVuNdi+r3h!rWFKeB@P5ve`6D`KOr`h~ztE)}{XN_hBCa`;U&o2S zqvxxf>!cA|xPF5?`MPHl_mDIVk=RnGcizW! z+Szxh1AS*;Ily(&h%H=yhwHTaC+7HLTqliq+J9fb`KJd>aMOJ>5l@>YxK63R$C)0@ zBu(Ja7c|Lr(uk+C^@u!0y5}+XkVb4Fo$mkfoPk6fn4T?Z#M1-iaGlkKD=65UhHJ){v^xK3X@9Z;&90^CF*v4!iKNYB$fVPtq(=bvytX~Y(;_mHPt a_nhV)(oSpkF$m0lD$xJ0)-?|27yJ`E%ZFJ2 diff --git a/hardware/esp8266com/esp8266/tools/sdk/version b/hardware/esp8266com/esp8266/tools/sdk/version index fd9c79de5f..9084fa2f71 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/version +++ b/hardware/esp8266com/esp8266/tools/sdk/version @@ -1 +1 @@ -1.0.1_15_05_04_p1 \ No newline at end of file +1.1.0 From 921a4761390343857bfb0fdee083cf8454fd3403 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Sat, 23 May 2015 17:06:47 +0100 Subject: [PATCH 04/77] Added support for NodeMCU dev kit v2 --- hardware/esp8266com/esp8266/boards.txt | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index 0177228e00..d3fdcc2516 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/boards.txt @@ -215,6 +215,54 @@ nodemcu.menu.UploadSpeed.512000.upload.speed=512000 nodemcu.menu.UploadSpeed.921600=921600 nodemcu.menu.UploadSpeed.921600.upload.speed=921600 +############################################################## +nodemcuv2.name=NodeMCU Dev Kit 2.0 (ESP8266 ESP-12E Module) + +nodemcuv2.upload.tool=esptool +nodemcuv2.upload.speed=115200 +nodemcuv2.upload.resetmethod=ck +nodemcuv2.upload.maximum_size=4194304 +nodemcuv2.upload.wait_for_upload_port=true +nodemcuv2.serial.disableDTR=true +nodemcuv2.serial.disableRTS=true + +nodemcuv2.build.mcu=esp8266 +nodemcuv2.build.f_cpu=80000000L +nodemcuv2.build.board=ESP8266_ESP12 +nodemcuv2.build.core=esp8266 +nodemcuv2.build.variant=nodemcu +nodemcuv2.build.flash_mode=dio +nodemcuv2.build.flash_size=4M +nodemcuv2.build.flash_freq=40 + +nodemcuv2.menu.CpuFrequency.80=80 MHz +nodemcuv2.menu.CpuFrequency.80.build.f_cpu=80000000L +nodemcuv2.menu.CpuFrequency.160=160 MHz +nodemcuv2.menu.CpuFrequency.160.build.f_cpu=160000000L + +nodemcuv2.menu.UploadSpeed.115200=115200 +nodemcuv2.menu.UploadSpeed.115200.upload.speed=115200 +nodemcuv2.menu.UploadSpeed.9600=9600 +nodemcuv2.menu.UploadSpeed.9600.upload.speed=9600 +nodemcuv2.menu.UploadSpeed.57600=57600 +nodemcuv2.menu.UploadSpeed.57600.upload.speed=57600 +nodemcuv2.menu.UploadSpeed.256000.windows=256000 +nodemcuv2.menu.UploadSpeed.256000.upload.speed=256000 +nodemcuv2.menu.UploadSpeed.230400.linux=230400 +nodemcuv2.menu.UploadSpeed.230400.macosx=230400 +nodemcuv2.menu.UploadSpeed.230400.macosx=230400 +nodemcuv2.menu.UploadSpeed.230400.upload.speed=230400 +nodemcuv2.menu.UploadSpeed.460800.linux=460800 +nodemcuv2.menu.UploadSpeed.460800.macosx=460800 +nodemcuv2.menu.UploadSpeed.460800.upload.speed=460800 +nodemcuv2.menu.UploadSpeed.512000.windows=512000 +nodemcuv2.menu.UploadSpeed.512000.upload.speed=512000 +nodemcuv2.menu.UploadSpeed.921600=921600 +nodemcuv2.menu.UploadSpeed.921600.upload.speed=921600 + +nodemcuv2.menu.FlashSize.4M=4M +nodemcuv2.menu.FlashSize.4M.build.flash_size=4M + ############################################################## # wifio.name=Wifio # From 25b9494162161f275f3c78320059d6daba8724ad Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 24 May 2015 15:35:18 +0300 Subject: [PATCH 05/77] Fix build --- .../esp8266com/esp8266/cores/esp8266/Esp.cpp | 4 ++- .../esp8266/core_esp8266_wiring_digital.c | 2 ++ .../esp8266/cores/esp8266/esp8266_peri.h | 2 +- .../libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 29 ++++++++++++------- .../libraries/ESP8266WiFi/src/ESP8266WiFi.h | 3 +- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 67e6a41af5..2a90355195 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp @@ -27,7 +27,9 @@ extern "C" { //extern "C" void ets_wdt_init(uint32_t val); extern "C" void ets_wdt_enable(void); extern "C" void ets_wdt_disable(void); -extern "C" void wdt_feed(void); +extern "C" void wdt_feed(void) { + +} /** * User-defined Literals diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c index 54c2b557b1..57702f4695 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c @@ -25,6 +25,8 @@ #include "eagle_soc.h" #include "ets_sys.h" +uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10}; + extern void __pinMode(uint8_t pin, uint8_t mode) { if(pin < 16){ if(mode == SPECIAL){ diff --git a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h index d3841740b6..e2998cf540 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h @@ -68,7 +68,7 @@ #define GPCD 2 //DRIVER 0:normal,1:open drain #define GPCS 0 //SOURCE 0:GPIO_DATA,1:SigmaDelta -static uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10}; +extern uint8_t esp8266_gpioToFn[16]; #define GPF(p) ESP8266_REG(0x800 + esp8266_gpioToFn[(p & 0xF)]) #define GPMUX ESP8266_REG(0x800) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 5a3db61432..31b4df1eb3 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -468,9 +468,10 @@ void ESP8266WiFiClass::beginSmartConfig() } _smartConfigStarted = true; + _smartConfigDone = false; //SC_TYPE_ESPTOUCH use ESPTOUCH for smartconfig, or use SC_TYPE_AIRKISS for AIRKISS - smartconfig_start(SC_TYPE_ESPTOUCH, &ESP8266WiFiClass::_smartConfigDone); + smartconfig_start(SC_TYPE_ESPTOUCH, reinterpret_cast(&ESP8266WiFiClass::_smartConfigCallback), 1); } void ESP8266WiFiClass::stopSmartConfig() @@ -482,22 +483,30 @@ void ESP8266WiFiClass::stopSmartConfig() _smartConfigStarted = false; } -bool ESP8266WiFiClass::smartConfigDone(){ +bool ESP8266WiFiClass::smartConfigDone() +{ if (!_smartConfigStarted) return false; - return smartconfig_get_status() == SC_STATUS_LINK_OVER; + return _smartConfigDone; } -void ESP8266WiFiClass::_smartConfigDone(void* result) +void ESP8266WiFiClass::_smartConfigCallback(uint32_t st, void* result) { - station_config* sta_conf = reinterpret_cast(result); - - wifi_station_set_config(sta_conf); - wifi_station_disconnect(); - wifi_station_connect(); -} + sc_status status = (sc_status) st; + if (status == SC_STATUS_LINK) { + station_config* sta_conf = reinterpret_cast(result); + + wifi_station_set_config(sta_conf); + wifi_station_disconnect(); + wifi_station_connect(); + WiFi._smartConfigDone = true; + } + else if (status == SC_STATUS_LINK_OVER) { + WiFi.stopSmartConfig(); + } +} void ESP8266WiFiClass::printDiag(Print& p) { diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 1a3a7b3668..386938c53f 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -287,8 +287,9 @@ class ESP8266WiFiClass protected: static void _scanDone(void* result, int status); void * _getScanInfoByIndex(int i); - static void _smartConfigDone(void* result); + static void _smartConfigCallback(uint32_t status, void* result); bool _smartConfigStarted = false; + bool _smartConfigDone = false; bool _useApMode; bool _useClientMode; From 775e9d4f9852ea2d5a3ced1575cf083f6d5bbd93 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 24 May 2015 16:12:31 +0300 Subject: [PATCH 06/77] Better sketch size reporting (#314) --- hardware/esp8266com/esp8266/boards.txt | 16 +++++++++++++++- hardware/esp8266com/esp8266/platform.txt | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index 0177228e00..3aba3feecf 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/boards.txt @@ -9,7 +9,8 @@ generic.name=Generic ESP8266 Module generic.upload.tool=esptool generic.upload.speed=115200 generic.upload.resetmethod=ck -generic.upload.maximum_size=524288 +generic.upload.maximum_size=372736 +generic.upload.maximum_data_size=81920 generic.upload.wait_for_upload_port=true generic.serial.disableDTR=true generic.serial.disableRTS=true @@ -58,42 +59,55 @@ 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.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_end=0xFB000 generic.menu.FlashSize.1M512.build.spiffs_blocksize=8192 +generic.menu.FlashSize.1M512.upload.maximum_size=438272 + 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_end=0xFB000 generic.menu.FlashSize.1M256.build.spiffs_blocksize=4096 +generic.menu.FlashSize.1M256.upload.maximum_size=700416 + 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_end=0xFB000 generic.menu.FlashSize.1M128.build.spiffs_blocksize=4096 +generic.menu.FlashSize.1M128.upload.maximum_size=831488 + generic.menu.FlashSize.1M64=1M (64K SPIFFS) generic.menu.FlashSize.1M64.build.flash_size=1M 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.2M=2M (1M SPIFFS) generic.menu.FlashSize.2M.build.flash_size=2M 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.4M=4M (3M SPIFFS) generic.menu.FlashSize.4M.build.flash_size=4M 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 # disabled because espressif's bootloader refuses to write above 4M # generic.menu.FlashSize.8M=8M (7M SPIFFS) diff --git a/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index c2cfa053e5..e76b838ca2 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/platform.txt @@ -78,8 +78,8 @@ recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=^(?:\.text|\.data|\.rodata|\.irom0\.text|)\s+([0-9]+).* -#recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* +recipe.size.regex=^(?:\.irom0\.text|)\s+([0-9]+).* +recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).* #recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* # ------------------------------ From 843ff86568693216aafc95c231fdcd58d54f83fc Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 24 May 2015 18:09:14 +0200 Subject: [PATCH 07/77] 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 2bb9f596f42d2049bdaa708876b37c41504a3657 Mon Sep 17 00:00:00 2001 From: Testato Date: Sun, 24 May 2015 19:02:16 +0200 Subject: [PATCH 08/77] Update build_board_manager_package.sh added all boards present in the core, so it is visible on Board Manager also before install the core. --- build/build_board_manager_package.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build/build_board_manager_package.sh b/build/build_board_manager_package.sh index dbccd99996..0868e887de 100755 --- a/build/build_board_manager_package.sh +++ b/build/build_board_manager_package.sh @@ -52,8 +52,15 @@ cat << EOF > package_esp8266com_index.json "help":{ "online":"http://esp8266.com" }, - "boards":[ { + "boards":[ + { "name":"Generic ESP8266 Module" + }, + { + "name":"Olimex MOD-WIFI-ESP8266(-DEV)" + }, + { + "name":"NodeMCU (ESP8266 ESP-12 Module)" } ], "toolsDependencies":[ { From fdaf126d31448759314b893c56375ab0c4b2300a Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 24 May 2015 22:07:33 +0300 Subject: [PATCH 09/77] Fix max upload size for modwifi and nodemcu (#314) --- hardware/esp8266com/esp8266/boards.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index 3aba3feecf..3588d09e2c 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/boards.txt @@ -134,7 +134,8 @@ modwifi.name=Olimex MOD-WIFI-ESP8266(-DEV) modwifi.upload.tool=esptool modwifi.upload.speed=115200 modwifi.upload.resetmethod=ck -modwifi.upload.maximum_size=2097152 +modwifi.upload.maximum_size=983040 +modwifi.upload.maximum_data_size=81920 modwifi.upload.wait_for_upload_port=true modwifi.serial.disableDTR=true modwifi.serial.disableRTS=true @@ -185,7 +186,8 @@ nodemcu.name=NodeMCU (ESP8266 ESP-12 Module) nodemcu.upload.tool=esptool nodemcu.upload.speed=115200 nodemcu.upload.resetmethod=ck -nodemcu.upload.maximum_size=4194304 +nodemcu.upload.maximum_size=983040 +nodemcu.upload.maximum_data_size=81920 nodemcu.upload.wait_for_upload_port=true nodemcu.serial.disableDTR=true nodemcu.serial.disableRTS=true From a38585c01473ed8b1b9bf0cd202390fcf5cc107b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 24 May 2015 22:20:02 +0300 Subject: [PATCH 10/77] Proper naming of NodeMCU boards, flash map update #292 --- hardware/esp8266com/esp8266/boards.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index 6b09be6772..fdf37d5700 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/boards.txt @@ -181,7 +181,7 @@ modwifi.menu.UploadSpeed.921600=921600 modwifi.menu.UploadSpeed.921600.upload.speed=921600 ############################################################## -nodemcu.name=NodeMCU (ESP8266 ESP-12 Module) +nodemcu.name=NodeMCU 0.9 (ESP-12 Module) nodemcu.upload.tool=esptool nodemcu.upload.speed=115200 @@ -232,12 +232,13 @@ nodemcu.menu.UploadSpeed.921600=921600 nodemcu.menu.UploadSpeed.921600.upload.speed=921600 ############################################################## -nodemcuv2.name=NodeMCU Dev Kit 2.0 (ESP8266 ESP-12E Module) +nodemcuv2.name=NodeMCU 1.0 (ESP-12E Module) nodemcuv2.upload.tool=esptool nodemcuv2.upload.speed=115200 nodemcuv2.upload.resetmethod=ck -nodemcuv2.upload.maximum_size=4194304 +nodemcuv2.upload.maximum_size=983040 +nodemcuv2.upload.maximum_data_size=81920 nodemcuv2.upload.wait_for_upload_port=true nodemcuv2.serial.disableDTR=true nodemcuv2.serial.disableRTS=true @@ -250,6 +251,11 @@ nodemcuv2.build.variant=nodemcu nodemcuv2.build.flash_mode=dio nodemcuv2.build.flash_size=4M nodemcuv2.build.flash_freq=40 +nodemcuv2.build.flash_ld=eagle.flash.4m.ld +nodemcuv2.build.spiffs_start=0x100000 +nodemcuv2.build.spiffs_end=0x3FB000 +nodemcuv2.build.spiffs_pagesize=256 +nodemcuv2.build.spiffs_blocksize=8192 nodemcuv2.menu.CpuFrequency.80=80 MHz nodemcuv2.menu.CpuFrequency.80.build.f_cpu=80000000L @@ -275,9 +281,6 @@ nodemcuv2.menu.UploadSpeed.512000.windows=512000 nodemcuv2.menu.UploadSpeed.512000.upload.speed=512000 nodemcuv2.menu.UploadSpeed.921600=921600 nodemcuv2.menu.UploadSpeed.921600.upload.speed=921600 - -nodemcuv2.menu.FlashSize.4M=4M -nodemcuv2.menu.FlashSize.4M.build.flash_size=4M ############################################################## # wifio.name=Wifio From 00604f35dec937ed53541900a66792d31ab181a4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 24 May 2015 23:15:05 +0300 Subject: [PATCH 11/77] Add API to set the beginning of local ports range for WiFiClient --- .../esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp | 6 ++++++ .../esp8266/libraries/ESP8266WiFi/src/WiFiClient.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp index 534c7fa895..056d5bb654 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -40,6 +40,8 @@ extern "C" #include "include/ClientContext.h" #include "c_types.h" +uint16_t WiFiClient::_localPort = 0; + ICACHE_FLASH_ATTR WiFiClient::WiFiClient() : _client(0) { @@ -93,6 +95,10 @@ int ICACHE_FLASH_ATTR WiFiClient::connect(IPAddress ip, uint16_t port) if (!pcb) return 0; + if (_localPort > 0) { + pcb->local_port = _localPort++; + } + ip_addr_t addr; addr.addr = ip; tcp_arg(pcb, this); diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h index f4063cbbaf..a15cb1b68d 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h @@ -61,6 +61,7 @@ class WiFiClient : public Client { uint16_t remotePort(); bool getNoDelay(); void setNoDelay(bool nodelay); + static void setLocalPortStart(uint16_t port) { _localPort = port; } template size_t write(T &src){ uint8_t obuf[1460]; @@ -97,6 +98,7 @@ class WiFiClient : public Client { void _err(int8_t err); ClientContext* _client; + static uint16_t _localPort; }; From 92147999b997e7e167ab0365cc98d1f2e99824c7 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 25 May 2015 00:32:45 +0300 Subject: [PATCH 12/77] Update linker script for SDK 1.1.0 Exception vectors have moved into .text. --- .../tools/sdk/ld/eagle.app.v6.common.ld | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld index 986b441ffa..a411c33914 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld +++ b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld @@ -13,6 +13,11 @@ PHDRS /* Default entry point: */ ENTRY(call_user_start) +EXTERN(_DebugExceptionVector) +EXTERN(_DoubleExceptionVector) +EXTERN(_KernelExceptionVector) +EXTERN(_NMIExceptionVector) +EXTERN(_UserExceptionVector) PROVIDE(_memmap_vecbase_reset = 0x40000000); /* Various memory-map dependent cache attribute settings: */ _memmap_cacheattr_wb_base = 0x00000110; @@ -158,6 +163,30 @@ SECTIONS { _stext = .; _text_start = ABSOLUTE(.); + *(.UserEnter.text) + . = ALIGN(16); + *(.DebugExceptionVector.text) + . = ALIGN(16); + *(.NMIExceptionVector.text) + . = ALIGN(16); + *(.KernelExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.UserExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.DoubleExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN (16); *(.entry.text) *(.init.literal) *(.init) From 49c25b9c1b38458b2e9508e4540519caaf052e04 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 25 May 2015 00:42:41 +0300 Subject: [PATCH 13/77] Add NodeMCU 1.0 board to package json --- build/build_board_manager_package.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/build_board_manager_package.sh b/build/build_board_manager_package.sh index 0868e887de..d4d598bd05 100755 --- a/build/build_board_manager_package.sh +++ b/build/build_board_manager_package.sh @@ -60,8 +60,12 @@ cat << EOF > package_esp8266com_index.json "name":"Olimex MOD-WIFI-ESP8266(-DEV)" }, { - "name":"NodeMCU (ESP8266 ESP-12 Module)" + "name":"NodeMCU 0.9 (ESP-12 Module)" + }, + { + "name":"NodeMCU 1.0 (ESP-12E Module)" } + ], "toolsDependencies":[ { "packager":"esp8266", From f9ecdaa0aa071c064055d648cd064e9a54afaf34 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 00:15:38 +0200 Subject: [PATCH 14/77] add 2 compiler options from last SDK --- hardware/esp8266com/esp8266/platform.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index e76b838ca2..571b18d501 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/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 ecfd5c4593c11c9f5bd735a13361f5a2a04419f0 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 00:41:22 +0200 Subject: [PATCH 15/77] 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’. --- hardware/esp8266com/esp8266/platform.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index 571b18d501..e76b838ca2 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/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 17b29fc437b8334c4d0089a7e576cc386687f361 Mon Sep 17 00:00:00 2001 From: Makuna Date: Sun, 24 May 2015 19:21:47 -0700 Subject: [PATCH 16/77] Expose Chip CCompare0 timer --- .../esp8266/cores/esp8266/Arduino.h | 18 +++++++++++++-- .../esp8266com/esp8266/cores/esp8266/Esp.h | 18 ++++++++++++++- .../cores/esp8266/core_esp8266_timer.c | 22 +++++++++++++++++++ .../esp8266/tools/sdk/include/ets_sys.h | 22 +++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 89dbff873f..7ebc77b791 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -107,6 +107,20 @@ 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 @@ -126,13 +140,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) "; esync; isync; dsync" : "=a" (state)) +#define xt_disable_interrupts(state, level) __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=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; esync; isync; dsync" : "=a" (interruptsState)) +#define noInterrupts() __asm__ __volatile__("rsil %0,15" : "=a" (interruptsState)) #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index 5e356459e1..c887c89e92 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,15 +99,31 @@ 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__("rsr %0,ccount":"=a" (ccount)); + __asm__ __volatile__("esync; 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/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index bfdd3692cf..979ab0bfc1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -59,3 +59,25 @@ 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/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 7908699bb5..3cdb51d2af 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -43,6 +43,7 @@ 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() \ @@ -51,6 +52,9 @@ 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)) @@ -69,6 +73,18 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Sun, 24 May 2015 19:22:29 -0700 Subject: [PATCH 17/77] ETS_INTR_ENABLED & ETS_INT_PENDING as inline --- hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 3cdb51d2af..e11e619708 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -73,12 +73,14 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_DISABLE(inum) \ ets_isr_mask((1< Date: Mon, 25 May 2015 09:46:34 +0200 Subject: [PATCH 18/77] add rssi function of new SDK 1.1.0 fix warning in hexdump and ESP8266WiFiMulti --- hardware/esp8266com/esp8266/cores/esp8266/debug.cpp | 4 ++-- .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 5 +++++ .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h | 7 +++---- .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 2 +- .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/debug.cpp b/hardware/esp8266com/esp8266/cores/esp8266/debug.cpp index 68d3a6b82a..478fe7392d 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/debug.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 31b4df1eb3..009cb69ef1 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 386938c53f..5eb5c9b0fd 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index e0a7ddeb22..e32f426f20 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 9a412ebb19..3f2692a508 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/hardware/esp8266com/esp8266/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 143e78c8261bd3d0b92d056419c0d242e14ed596 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 09:49:15 +0200 Subject: [PATCH 19/77] disable DEBUG_WIFI_MULTI define --- .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h index 3f2692a508..63c180c313 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.h +++ b/hardware/esp8266com/esp8266/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 ebca28b1106225356e238ac1506dc13824effe9c Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 11:15:29 +0200 Subject: [PATCH 20/77] read the rst reason from the SDK if stored. add String getResetInfo(void); and struct rst_info * getResetInfoPtr(void); --- hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp | 15 +++++++++++++++ hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 3 +++ .../esp8266/cores/esp8266/core_esp8266_main.cpp | 11 +++++++++++ .../esp8266/tools/sdk/include/user_interface.h | 2 +- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 2a90355195..627fdcf2c8 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index 5e356459e1..ccefa0c5f7 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp index 34e436c880..16902b15cb 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h b/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h index 7f593e0eb7..7c4706dc4d 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/user_interface.h +++ b/hardware/esp8266com/esp8266/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 51e919d0a5ff35f60e079f42bd10a8068dd46a2f Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 12:29:26 +0200 Subject: [PATCH 21/77] add ESP.eraseESPconfig() to erase the ESP SDK configuration (including wifi) improve WiFiMulti --- .../esp8266com/esp8266/cores/esp8266/Esp.cpp | 22 +++++++++++++++++++ .../esp8266com/esp8266/cores/esp8266/Esp.h | 2 ++ .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 627fdcf2c8..bf012afd5b 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index ccefa0c5f7..9411dc5f0c 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index e32f426f20..7161c399c1 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/hardware/esp8266com/esp8266/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 105a0b8c458a666039e009d8468530261ebd7e09 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 25 May 2015 13:13:05 +0200 Subject: [PATCH 22/77] correct addr --- hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index bf012afd5b..946a8b3754 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/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 cff57490feae778b68740e0ef878d4521ae4eb2b Mon Sep 17 00:00:00 2001 From: Makuna Date: Mon, 25 May 2015 12:24:39 -0700 Subject: [PATCH 23/77] Fixed timer bug and cleaned up Decided to not expose compare timer in ESP object to minimize the exposure surface Fixed incorrect timer callback being used and initialized timer callbacks --- .../esp8266com/esp8266/cores/esp8266/Arduino.h | 4 ++-- hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 16 ---------------- .../esp8266/cores/esp8266/core_esp8266_timer.c | 10 ++++++---- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 7ebc77b791..dcaa47b09e 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/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() (ESP.getCycleCompare0()) -#define timer0_write(ticks) (ESP.setCycleCompare0(ticks)) +#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") void timer0_isr_init(void); void timer0_attachInterrupt(void(*userFunc)(void)); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index c887c89e92..fc52371965 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -99,8 +99,6 @@ 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) @@ -110,20 +108,6 @@ 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/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 979ab0bfc1..b9b2f1256a 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -22,7 +22,9 @@ #include "pins_arduino.h" #include "c_types.h" -void (*timer1_user_cb)(void); +typedef void(*_timercallback)(void); + +static volatile _timercallback timer1_user_cb = NULL; void timer1_isr_handler(void *para){ if((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable @@ -60,7 +62,7 @@ void timer1_disable(){ T1I = 0; } -void(*timer0_user_cb)(void); +static volatile _timercallback timer0_user_cb = NULL; void timer0_isr_handler(void *para){ if (timer0_user_cb) { @@ -73,11 +75,11 @@ void timer0_isr_init(){ } void timer0_attachInterrupt(void(*userFunc)(void)) { - timer1_user_cb = userFunc; + timer0_user_cb = userFunc; ETS_CCOMPARE0_ENABLE(); } void timer0_detachInterrupt() { - timer1_user_cb = NULL; + timer0_user_cb = NULL; ETS_CCOMPARE0_DISABLE(); } \ No newline at end of file From 0ac84df8542f4059c2717c67f56611107fecbeb0 Mon Sep 17 00:00:00 2001 From: moeur Date: Tue, 26 May 2015 07:55:56 -0700 Subject: [PATCH 24/77] 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. --- .../ESP8266WiFi/examples/NTPClient/NTPClient.ino | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino index 4a9771b5fd..a3fdaf49c3 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino +++ b/hardware/esp8266com/esp8266/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 d988e6c8a562f1cba840faef5973d239247a2874 Mon Sep 17 00:00:00 2001 From: Toshik Date: Wed, 27 May 2015 17:52:30 +0300 Subject: [PATCH 25/77] Fix windows build --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index 20bac52d48..83405f0c49 100644 --- a/build/build.xml +++ b/build/build.xml @@ -891,7 +891,7 @@ - + From 94d39579ec76d7c6609624ddbba3a4f383ec9c62 Mon Sep 17 00:00:00 2001 From: Todd Treece Date: Wed, 27 May 2015 10:55:48 -0400 Subject: [PATCH 26/77] adds adafruit huzzah to board manager package --- build/build_board_manager_package.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/build_board_manager_package.sh b/build/build_board_manager_package.sh index d4d598bd05..d0cdc5ce46 100755 --- a/build/build_board_manager_package.sh +++ b/build/build_board_manager_package.sh @@ -64,8 +64,10 @@ cat << EOF > package_esp8266com_index.json }, { "name":"NodeMCU 1.0 (ESP-12E Module)" + }, + { + "name":"Adafruit HUZZAH ESP8266 (ESP-12)" } - ], "toolsDependencies":[ { "packager":"esp8266", From 83f0a700dff18a958db89c3de5684f8846fbeb97 Mon Sep 17 00:00:00 2001 From: Todd Treece Date: Wed, 27 May 2015 10:56:40 -0400 Subject: [PATCH 27/77] adds adafruit huzzah to boards.txt & adds adafruit variant --- hardware/esp8266com/esp8266/boards.txt | 42 +++++++++++ .../esp8266/variants/adafruit/pins_arduino.h | 70 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 hardware/esp8266com/esp8266/variants/adafruit/pins_arduino.h diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index fdf37d5700..3aca00ae97 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/variants/adafruit/pins_arduino.h b/hardware/esp8266com/esp8266/variants/adafruit/pins_arduino.h new file mode 100644 index 0000000000..aeb20d43be --- /dev/null +++ b/hardware/esp8266com/esp8266/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 937fb0d6103bc48f93b10ececc8aeba118a0bc9e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 17:15:49 +0200 Subject: [PATCH 28/77] 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. --- .../esp8266/tools/sdk/changelog.txt | 10 ++++++++++ .../esp8266/tools/sdk/lib/libmain.a | Bin 146208 -> 146112 bytes .../esp8266/tools/sdk/lib/libsmartconfig.a | Bin 93140 -> 104942 bytes .../esp8266com/esp8266/tools/sdk/lib/libssl.a | Bin 165002 -> 165086 bytes hardware/esp8266com/esp8266/tools/sdk/version | 2 +- 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/tools/sdk/changelog.txt b/hardware/esp8266com/esp8266/tools/sdk/changelog.txt index ad750024a6..b3faa0773b 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/changelog.txt +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/lib/libmain.a b/hardware/esp8266com/esp8266/tools/sdk/lib/libmain.a index 5f1e03f7d37be301fe24eb25749ba1893ba5ed03..ec7bb4cdfa337bd5a668c5a87eea694b2af67a16 100644 GIT binary patch delta 6309 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 delta 6470 zcmchbdvsLA9mi*GvLVUcjhhhIfGg}KApzWlJU|{L50Ljm7L-a`5P~rR0tSqT5Zx6~ zC@2z!x*#9{p+3q>mSbo^ns9=ENDFGMwu(wQr`B2umY0g${=WDAuB@r;>0ivr?0n`s z-+A0SGxyF-(&0}0K(VzcH0Bc+LQ~eeJ#a~dxVyI{#pz! z5*lKUN&?b3L)MoWWQRzgv6k*e5{FJFpnNw1Nugoqf15svv<_t4rcp{yN7 z5+fp%$7Z$(X!5PtbDlR7RJkWH>|B}AboK-Pk@UY6Htjc3WQkM0XEX}o)QJ9IQZ~^$ zCKVCA4e}l!I&RY2M85}>IGqdSF_889>934nnmh`@|FTh%CXbk9uNX})8vYlJF5WKv zQUYOl&{UhR{Wfhff=+n=LeN=QZ#WZWqm}V0XQs1_d>uJQvmy5Zvg;#qFQD*Qqj$nb zTIbfii{%~&C9VPWk@D>H?6(``ZV2)j!~cxY=o3ZRi+hP=f&t;|#jO@yY+43&Y+%Tp zraC1sq}7ub<;$ou$0hRa^aNdnj~mpQ++sGI7IZnb8&676LNsWb5p>B7DDW>Z3Ktmt z7Z_t|4Y|%#=9~QmHjH`LC@8pqE(2FX1Ks6A`gnmC;PzW=krWSP)^L+c#u_^`$+RM0Q9)r( zQP`(%aY5gnv1fd9wKnv873-3O=uGKATBFI7Mq=%A@*QCmNz%&`h4`9yA;rFQDJhh0 zqIfH@lX-NUKAt$2^;%*CGz)%^Qq(<1Jehe6bx(h$e&;m~i;34V;%;I$n;sy(fq5Zu zD)UpsF6K4F2yZVtC=fLqKPbVjUfUZAaS6+M$6+p5U{ zrz5kw5LeXfK#n6s7h4m3b%t!Mwg%j?S-l>}cXX#aGguWq+gj~>JaHwhst1)TnD6M6 zPQx+fkwLfSE>m{}^W--5L@-}|sJ4+Ir5)Xa+*(d_?<8Ib+;)A;b93Ft`#sdKW>q~r$v5li~M6P^2=J}SGUN&@cn#-*!F!v z>{b6L>hAxth3cl&YX=OolPW3h=r3!b-rgcVAvUvka6nyO7oD7t~*-6yhmL!FottEm_-%OJ`BLC|yM*V4ZbboD8Y`r5^fy zuXI)_mP$RuG3vH5PrETz<7c?Ki?+*Vl#W%8mU-y+*|H)zQXMJlo{e?56GelpDn7EJ zM`&PukZNC^C(Bj;^8AuTWR`bWMl4i$yTw@8lFSG%(XOz0a~#*lwv^wkg-2jW6bDlK z&oK`r-oiYRcqj9C;uv#?_%-G`h)*z2AU?@FnK%XGr+g*x&CFAYyIC9-Gbn>c4@}j> zRm?TS4>Lbb=`!Ydq%UW#C9Y$R5U*lhM7*AP3GpwPF{$q`uOLoIqNf5n#(d_`%>iRB zyECsN?#qnntYXIG;ZX(uOT>S){ghs2uBWs$O$0o+@wv>Hka5fdvk0(OV8RS8V_p~>_gMLa6tG@u z)jf@N$}Ij1d!T`J)<1)%-13}b4>YjO`X$zT)4u%z{{EK#YfBHCA~HG`oP}wCWlG@n z2@R~Xejc8#mM4=v(7-zDm*Kh9@^oSkG_cNkF9)xAY`Stb;T$lM8SndX%s2;JL8Ak$ zMp1_K2o0>WUctI~KA>_r$nwu%U62OWp;P~2E*H=znux@4A}SBIDnG$GG_cNkGCVh0 zo+x{ufpylMah@jjKm&(u6W%3qh}F;$HbDdHtmA5Bq2>7#d!T`J)=#mHQ&1NCLoNT` zS%(JJEj=u}FyXX8;S!smfpyk>@bDEI?12Wh?}U#YC7D61om}|opn;GFo$}DYI_sU` z8IJo;VGx@jg7x8+K7w_e<8EWdIWB<8BPB3P#a zgvG4m@VS+uy)8dw9U9o)mOJ6$t#y_?(7^VVyU04;0K1cD{oAWIiJ$f)3b4H}(^o@`Li}UBR4h?MiY5p5w8f;y0cQ!!-+ly-`vEA`__CN#M9pBA5 zj^X#k@tinb!HiS#YLn@ft5`{>ESW#QRq5KcvDM>qeewDC=VfNupXb|iHBT(1u6rsA zvC_3#rd>$i?w;7h9eYdd+8xe#5_|V7@|hp=^|6XGYh~WVMEWZ4lAa>pDt2Z(nIJ|b z_`foGr_+^!~`&v8WPD<(@laXv?$QYX%PRO5NKN%@XbRBMQNba!8H%Pz`)A>Z)< zJx>cvZ8B-A)ojvI=r#pZdXP^37u>E-=;I(jH7OCP(T!cT8y!9ANpPQe#CKh$`x>Fr zG%8Jrouk5;X=Nf!-ubjTrnMLW8{IWW_(JRiNZ@S6i>Oad`3~@)8hFJS~ojJ&bU6$@#g4zqG zEu~)?Vto~|G{oA2l$t|?Kts&l@iBopMkq8!`u*P{JlS%DE_pVVYn;@=nKaIw6p>Dl z)|We>na7%iPMgwPv+XHW6tPaXQAEJ{wd=#*OnKY?Ch>+B zv?=U=BWxxQI!8nMiLti8hln-iBg7q;|4NL2&cN+eXo{y>2IWx8OI6x17ZSq-y$><% z6_ZP}XvnMOsn<8%pkiIU4UZ(q8>B3WKAk9YQnph6HPmdHl2bj=>ayD@c|DqZ`TT*hKs9A#?x9b5#E(Z~8|8>9P^WLrNbVGYF$;SjAU#Z6w#`Fu*JMlU4E5$0TCqak1;fpJ0fp8=C` zp*R&l$E`(^U^k^`5{$V##Jro*kD2#SdYXA3r9;UJe58^ofF@Z+~>Y|^u%$T{&lHNxsz=ZGP0xXbbW-OdPGh?wB z%&Anl6-CsQlx8twX>?=8lEJ{?L1(uxV__mlq-t2`#)igZ+2gzC6uplYyHjO@J5@Vv zzjN?EVo!8bd#$V?)JFRxG5+<_KypV%ykZ#-cf4k7pqJQE`;FH?jSX%UU!h@R53OU; FzX4=2Mj`+J diff --git a/hardware/esp8266com/esp8266/tools/sdk/lib/libsmartconfig.a b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/lib/libssl.a b/hardware/esp8266com/esp8266/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 zcmbWA33yf2z4rG$gb+9)&@k?d_G9rAvcgzPGL@3WERN^@&e{;NM--|7L

kT&qA?uQ=|9QQqCAFeVsRN*5qsE%%6G9>|o<{iAhac&6_@Z+T^LTrq7)pOq)4x z&NcIdZ zf==0G7bn_hdUZOOt?d!E&9p8rN`IW&5(KSx7aZu>svuR_v#f8bYENQOzp!>-pVPu+ zwdIM-o?v~i>XVk$hlj9M7m5A>)f9zq6Dma}nu!;#zA$rP`6=1Do5PNo|0qwUKVn1cqs^6NL26H8 z_5M9U`HPvF)KmL%?z1&^1#1^?&#gXCP+zsY{pvXt zpXBj&E#ed&!+Q-`OFRSAYKa`i8dkrKPD;4&79p z7+624boIO~O@bwP!Tl>wsA<->bJshZ^bjY@Wp6<3kR0W8r67Nx2Imq6?Bl{In)XD zpRPz1O!z#nx`TH386;hE1s&EtpIqC%e!}Tr{NYHhy2J3F@@IXnVpA@4;=^ML!Yvr% zzY|NU3sVDTmQLz8s&dq@*26yRuq7{8^2gk&k~=#VbQm0_E>0!7hmRH31P`7VKALIK zwc9C6Hs$UsPUQb8_t!;VR{SIvKH%zi`9r_I{IYI~U&`e_bZke1XekJ@i=GQxrQhz; zJbbz0>5@H7o=dcTxM{^lx$qNGAMD^?JJD^h@WxaBvt7aXh37BZQdK^rs&3T6E2`5WG0HYFz4tH*x;MHiqbr}2eXx%m{`#WvRsF-kwS{|{ z{2>g^D;huJlyKpm!G$9Z)juT0gF^Zz{j< zxT4Bbv&wNNJl%0neSA;8o2b0H)#lRhbt+x)YA!qw!7I5`%Tz(*_=0dB@$N;-4h&9d zf6`6E-H~w8j=l>&%ufb`3u{s=8 zHg{Ip%#M>fjH;<=T3?okk41IKsMO$aRF`vK&DEC$@nJ{>m1C>6m-N{+v?eI1DBW6K zc(`)SlC8=P-fsboa%{zuW5EdT(!`r#+(p$m~6W2a9J!-dBuc=zz z_J3@*`X==9is&ebsion+rdT54>(d zYxu(VQR3EV^Aw#O9fRm_ENK>uE8O~ePR&(KDsHf9Qm#EccIDdnh}yB}=>e%7i!P1o zv8l|dD;`5C4_~F6iWhQ&3nvz)rj2eD?ux2X*!0`E{C9JUboN?iZs>kSv&9p0)g6al zoY~TSMRTQymNnYiEz{WJ?4o_Sfm3(P+i_Vgn8)LpmxP6c)n&>n;A`|MM04)t#+de9n2Pl_Qt`FK+Va zA^WwfTeo%9DRtrC_$JqVJ!62o$>(a*sqQ9!tT3u{^k;wcw>&u1B0jxc3bQ4bB*t%C zQgc<9*j}XL(>nX7rD3un{EWl8Cy@$Pzc{LApAU6~CgLYnO<~_Px&Sgmd$+BMA5DdQ z{%$8bzW=_uxvrQsbNcN0nbo!JGoSRX%lxW$dFI;MDH}hj9gs+ut16pA-7g9sNCbfz zpdirGvOvK!g~bZ>pb7dbJgAMs6t2--TCQ+Pvmh9#@FtnrzPx$tKcaAu;=8naoTM$f zf@>9)=@5|LDuv|=FD(k%2eSk{rFKy0mONFcEc0ByTvWYKbt{n4SDPEPo-R%)T&s12 zSfxbVASQeCDdN_~*NR!#CHQ28c<%9ZxUK1rf2F679UCg~hBl0siAwZMd{yuuF=v-d zM~mATUoK{$V7R+NJhyr}%&w!~@9FWmNb7;Ag4b(9r3{T)|0M2e2|g0Lf;nj{6b2KL zwm^)Zv^8Q{*tJ^wiQ5~G6T72$k=W%q?KDML$jn_0WJ-Ukn=~^0iC8B*%5>c^fA;$$ z6DOs)D)1kXeyRBzqDw5!6Rxnd-}ZE#gDg>5;s!BgZSy>^J97Iy9j3n8$#itdiX*{Y zzGT`{9i!gT$@CJj%jmme7BYZ`DpW?nV;+C*d0@RCMxJK&@FFdIipq})802k$iIQo( zpr`R{vCC*71}$U+S1P2UcYC_K2ich|(np%7neIt!#he{B6pK$X?j?5T z`wY(ylMeq`Vs;uH<#}M|Y4AK3nkUUhB5DAl#IzVJ=&tn$tJNY%?;@>H>t^u`g%nmP zqbs-@iL?;Frz^xW)zhaLlczWxH9us!z%#+_YH##(*Nl<)G3hOpjD}a|5`Pq9Bkl8^ALb6i^MR*F zZLrD@$f#DkJH$-0*>x>c2=1YfOjmh2TxU9sI17H)ppz%ht}CTc@cEoyEqGv^!6?u4 z#fqF@k(r(era}~azo)~l8Gh2!-4ld@=?@K1Its4hIiQ7tVVZpOL1Nv~>8OB-o(XpM z^qt~LnW@CDJrC?|#iu0Qk; zT8xbfP4N7%D{PUc!|oyXV^4R_*D$RD=y!~^0z&PU+kuF z=oHTnlMa2b*j>o=o(GQZe@th4rgJ(Vv#Vk_Dg1$&$>rBm%-eGz6)_;b5SM2SO`Dn;H`8*`6gKX{5 zP`$pQFck?87H7&^R_0Iau17$5ru^pinelZ6`TJG$=RxMuy2`}MC7DHaRf)>d%$j|z zGrz4XZu+7ctPPp)?v|Oi6x*p13o>8Sb#B_IK3GGxq%mxn88EasfA`snw#cqo5mqK% zJSj70XjT4EwIJnr*~60ZJ5;G@ZIangR+}krRh-$sv>`L+{?jwJ)i20?^Ng@KdyD>* zuanq+2U!S?;tWJr7CYgn2ou0ix>d>A#7;Yg&-Er}AkBd(| zF8I8QBZxl&!Xc z&ru`lJhMEW2HTONGwAkgy&h4{{{U>2UI$zLYn;yhAIZ}O%jmGjhdie9?+SQcURS^l z*b3P0>DxSgi^o^NRtesS+PlQOM7shGs#0NT=HS`&XU2z#Gtc7U9+CGLP>y=Gyz%m}~M&Q(REB= z7bqNJ%r!jPm}~nx#@8u)(wOW2C9P=^573?Ts%_vMfENUGZkUgamnrLO~%}vdyTnk-!tYtVX*Fc((2Am2bWufTmDG0nm}W15R6jcG<+GREIq z?G2go4$xps_kNwnn?3HVo^M$~=byefeRC4iXe~CTF}v58M(#0V{D1H`PmLjI(Tk1A z?|Nf;%^8oMF{TmSleP%0Yo1zRGNOl@GNuJS!I+l$Ok+B%V~y!GU*z%I#!;)TJ|%h5 z+BY}upa;fC<1`UEo|t$%Y&GVw@r>~-@u$Xf#Cb}Cf4=wxW1c)yjd>z98sDujW6V=a z`w*o)OQEvd*zuh1Vfqm55wEjaT3N$`1}9BF(R3Q5e#U%hV~zGu;SgiKx*b;fP(4c) zI&*l?;H2rJVm%%3Y3_(NhOMych*$zNIBEK4iifD@^B8-j&9*s7K{< zX=j>_HZ#;k=n^mR5(HwG;QOYd!Ol+~-g$m#9yHi_GNyCn?l8Vb;TEmYQRf-;fo(v9 z-C_UKblP~HNgT$`T3Z?* zzA;b1U0&J?O-F-W+G(DDx96V`={o+1L|lUXp6NT57!7uw>rLkq?GKDOP5 z>kYJqeCE`0hHXHDlcoJUo`^-R41qU10@ydc^ts!aQhj5?$p7 zzp@Q?*WJ9JT+5M4}og zuh+%y6ufQB;6z(-SQ8g^*mN{FX?iFhX&Du1ZoENBii~%PJ7}9#IvupL4T!L-bvdS9 zabcazg9ax}?`JyKN*DZggc?jogWZw4*mOotrbMjcPvlzLz_1H(_MlN=+L!`}qca>+ zO<{I;mzs_SyB%0%I*0ww#*CH-%>>cmrFKvUw08X0zxao}dED$^Y0n^c7=YQ99{0qflZJhu6 zrlY~hNZ0vagvrk3XJ$f!-MPF8PoFrW0%go$M1zy27n@GOOYt)(t);E$XmHZ>a&(^m zj94urf%VY_SOPTI_1%`^=^AG`)I4agYqnS7=^T5;ngEc_~fLvB(02bB(!T ziL;lC4{bN*1@#5vT?$$8FbcLxYd9b-_;u6K;H2rR@z_qj8++0LA`!QjYcN?y^t0F$ zpuw(#x(?5&abay#DJp>mCry6<&%oGovU$+pr0MIUZ&Y@njWE-CnP7K8jW?ZPxea7` zTAb-z)6w9h=?hKgRsIqD*15gWbTl~XOVa*7Xd8Gx|CzBo!7q#%$9vf0M?797cDLnL z)6rmeTdu}at_-!jZXPr^?HZGJYy-WZ0-bZ$Le+^mylAj%pi+43LOa_$Xt2A`it%)b z3qH?0Xs~r&(!n=u0|Sd?T3x2oO-F-Wrfu<5#+fcK4;t(ms}6XqvAWqjXs|mf<#@Vs z{I#q$6C&(xr!JVPV$TESL4#c{=wZ_tF|F3>F5bsYM}ytP+Y?WDoaZxXGa){M$u_)b zI;Uf|IP4K8DA3msP6rz79@#~v^Vy}XF(aw_No$YhPNt*5JhG$x?`9i#PWLqCIsFES ztz|sbbTrttj0f@9<9M)n&|vqN9%DL{y9lK0U4(YC+SZF#L?D~oAOlO$)dHmJnqy6t_8xUdFciV}nXIxl!^Ps_Q?@u$G zR&t2(XoYnikMKOZ$g_K#=Qq)5{}G9}j^%DlQSDSeON<7)%I(L~BhKhY=0StqHF1aO z3{Jm+|K!;J6VuVsL|pgi9^1eu_dyc$j1$~vIvVWu{!!D}``;Tga(;-kC&y`DH60Ch zWxW~eX$^%3!8>MxL#ws`E8 zK8s;^GD18HlWmwNMqi}x3S&MdcF^h)&oUhic4@zFI!C2k?EFhiM}s3j_uq2cK!QIS zGrazQ*fqn?nT`g#W_UfGa%G}rzj@H$WO*b92Tf;K|9xXVTz(*q`u~jCAF&OL&3|sp z5d4?Md>P#!c1>@Y;v69~*fqV6;OP_>TxlLO*fqTaP1pQ@bTHf^d{#ZrnA$DW>N*Rr znT`g#zQQ6r)>k-W9yHiBw>RNABd*YA=0Ss#XK?(r~CWIslE69PXg<=|JrmkIPSOW!o$-u&UBl3&|udf+2CHubGYpCry9b^KZs)UGk%*qrt8Zu?3Iyl$sUC*BKg|bl-orVY0@j%uHyo zYgqb=UFY+B^Ps`5^Ld%+Oi&r9)%B9EG#w3gz2x*DOm*=d&ovVooHTu*>CA4a)9S9? zTTMrU-Nic$&(Ju}ADagaPMXfvFcED0`Bh=K@rjvFH6N{)4wfD2h`JHmT^_&T@nMe{ zq;mcOwV+{>%=UTpnfvCuA6;$SGXIl~-tVzCzPMsXwI6@t*Mr7*@lB=8!fhvbLU!+W z!z(vUY7_QpV(O;l?Ze*|dX`P!tPbDkYC=|9+id#Q_^{d6EVo?}E^6zgA=|4qt(YIy zx@`Hi*e0o~z9y`=E?oIFp*|fhYvyIN=^snN9qqqX_+Rb`pDgk%zt|8CI?-A96U!HXZ!64Gl|2kHMP8b_P~yCL#8~L#~kxiS!I4f;>!KaG}Au%Dbx!e=3d#I z{qN_(9(|+VHC5JJXFqgF#lLN;thp)vMTve$aBMofO*X$j@u#pT+_tI7?(p7Zny<d>T1?KAy@z3BR~wTj z%sUHtKAQdgJK@OmR!N*ol0D@mgPs1gr^8Nv&eLJ1zu@URjVT`1B^MR{mRQ%=gs9*T zy#%n!=o3$e-NF2qr(@<~rGS(;x*D=uMO$XcAg>}bqbp%P8iSd61%2|#B-v=aoX>DX_t9vZ}ZZ+ z=8Lo&q)$@*jar-YO_;+=!6yJ(3bevBOXz2MI?Q(Tk)H0_MGCk;I=3AKEEBt{pQH|d8 zHo%=s=dr~?rtT3&rd_17_hfpySWmAgpV6Kl?rQpMF`L$E{hsGZ6JcDL4H<6(>=HjF zcGtmgJdb;pQXxLUG$;=$)In{H^H+$=rIG(oG5ZOR5v!Svr{+&ngd@y`tHmtrG0b&` zKF`zL!<&LvO6O=bYTf90V0V4+Rpd6y=OR7uzh(S8z6r2U*zdH#?eX8m?vQ>WX2Iin z3lvLlj3ci4QObZ@(fI=#LiKIS;ps4 z8!Z$7_fSZt3q2h!H+{9I!_4l%|B$EC<%v3H?9C2Ej-9_^Ikiw26PHw{C~*%@hh4MH zv|kqd@W~1(Y@V2>5PYqevja0}iF%0B!R?B$kQjDX{svEnxrIpFOdT|LntF=eA?+h( zAs^V~)8Oea&vx>eDbA<;CvuHvf}Lrpr^8%~jaqN>bl6>J>pUHH7w=C!9cJGs_ldN( z!F4^uYPDR_>tvv?JUy9QMlEpZ<0P%o-_r}$7LZ? z*WbnThV(0?;TdD|!|;qX#skx=;+g7s;BL~W+)^=}ba;&z8@#cluKVijn2*)bb*J%7 zHfo_9*zNc`o(?pAMSP%hy7|uCvb$7D!hR?O?6vffLdx ztgo292Ry*j2a4T}H;7rtA9k16%t+UD$Oa;WWb|#ZyH0)(nc{8k4TQ=qlgm4(EOC6QlJ%X=^E!cZv)H;BEbYt zhr5}6y{E&j3AxeJZxY8xUd@x(9rz!4o?z3bpNFr9`fBp(7vcHgkFvdwhMk+%4bs_x)x`RsK^!)}TGmu1%-4XeTnvda|UY>oZNupB;SNrcx?kjm|c3+dk-WFf|yHeTBd5PYe z^p8o6ZIb4ybl*33>fy`zVBw+cbe`glAJMsTAKUZPOLKl+QTP=I3$HYe=SXvYUh-W& z+zR6C)`CR$w3}GnQ-yy=D`O=;P`KFmHid3tE)#b%TJi8RmG_MKs`IJwzZ6c;0m3sz z;rqs)E9|O*(d!lVj5!_Mn0$6%1GW5-@hpXR8-J{jF9&$oD>o%^zW4;4HuR6gyye4n z3da}^Q^*TEIxqF}jAtoq?tZGm8+%GE2c}YmypY2yrSlRFuM!V4-Y34yn3wUaG4Iw7 z8jn@@nx}t9r-pnuMIRb(PYc%REr|^eDm-BPfx;1bmq4GRaJk1%c>J<4FK2UfZ{p|0 zYlAVbHcx6r-=*+eT{rLyT}uoQMWckg=kO}RhNEI$MPOb9s*Jhd7;-|Ns_;&a*L(bT zV_rAfsnx;H+dwyuha2n7ARX{q225PtKle<%)F*a{`x`ToG|tm!dA!);TRpzVlD&wfayp4rA<&DMd&c} zP;1DB*$M|6*DE~Vc%s5Z#&~#+HJ=VHZZEE!v0#_FfG3|Mn{9)FzvwDqw7h_U1marooNuJj*%r;YaTS% zO`Wg9!@IVYpP2^@PMSUpj}9`+M)RO;^ndm8XEu~ap6I6-)cO-?FIxh5pT}>(d@I(% z!?&y==1Qd_EdvNOaOYU>XF3B2XBd|=>*W@UFgUQxW8!4Q$9@JE!me>f|7AKF?1oqQ zmvQj(cv)}EAj73v!>Ty#M$^&Yv>Q^Lf{8w&7WaD%G}uiXnudqoj+Upz6ov-7={S2$ zXB6XYxJ&H6O6*P(&pgsfO9w>Uc{;@&evDR>X>~uxI^A?M*!?bu2PPRYiqYUPar9dh zGOFRYt=JvK>5;DM50QvFjNghj1i=jozwL1cu{(?lOh<#=QM}o73SDdbs6u|eK_z~p z@IK?M3LkX8^0=%=*iA^BWcn0^R~R!YvOudll`Bj~ z6KmFkT4t8JYywEOo>XCx$=YTB7o)VjKWGI&|o*OhhddaeIl0G=0Ss#rZY|7or3F|seCd*ydIOaZapzs0w#^)L4#dJ zt4-H9O;D@V`5!hN4R-$icr5>|=IPH*uZg&V2V$~@s@AbOwtU3kubDWpO{f zMuU^4GkxC`JWe`0g9fKv!AHG}rkM#1b{Wkwox!C*t1GzCbTruc^YBzhbqj76Q!pBA z<))(_4!Dfgnu#A1z%HYon$8GU!d?X!Hfv|hC|IR2qgO+W8P%GoH5?dM;`^qf!O4N~ z^%q=ZH&$*x4qrq-k-F7i)84uiN%-)X` zyCeFJ>1eP!TK(-U@bski-_7S{tZ$HQU~q7#F=KrUF1j{VSz4=33U72@Q68@C(x!^(@yKT16i=9SwFn(8gY@8TDl4s8lH2M%tm){-10c z5MehpuAk{c6}m~~jCv9$qcIA%lTm$K>EWiM!Aa9EHJy=E(z{ChG^O)TgyGO9Yy-og z457M<$j#?QgWW~6Q%qV$Mgy%dQ>^nnE`s~Vl{?9Fo{GJUFXEqGSU_QC#istY0S!)? zz7Wr_*fY*NXmHZ>Nv8AlW|}dRlE3NkBJ#28X`b}xdj=vAcOBe>$y!4JH1)XhW>Q?x-}H&a4JzGIPEewZ7e$QR|HH zPZcuh7!RD%>W=6-)6v$Y^~YUM58DPtyf+#1ndx!k=M=JyOyOd!F4JwMqrooEGSBl@ z^Ps_awEubo@=R};2@Q4`9WkA6T^+=(;4e%^gPp(J^SFQW0}XbbF3fs&=e}GU*fWU% z?9P3y>5Sh;bHPuGFS@~|Gk!nXxQovHB_1z=&A-HS<_Bbsd9?rc9gApwqc|K97r+<* z6+(lPrWcsb*#Ak!jQ7_WGfaQAF=PC5j2U+So-t$mOiYe`^+IHoZD1__9%Cj8-0$&k zjTz&A+4voW2R#0#F|(X<#(Yl9i@x5)Uwl)>jQ6KYEW)^cYh%XjI~cPE6~;^`*uoLA zHsDOt(O`F8&o`Y(1Xma{A7q9xWBlKVIUO)@V1aFbmm4!dfEnzX8XYY^F&z!&-;iS- zz;-;=0{+rGXs~M;-#0x^pBXWBxxXml3g6jEz)+*$Z2!#HhFuSDTIoCr$q`y1kaKGtVOm ze`d^KUnF)%=r^XL!D)Ahc4Im{F6@Yz&|udeEabzg-A=7wRrFMa*GxHxYFrhqM4WyaiuX+8?H9quW+96s|vqo%rpo0HJB+Bi%rLKt1(j>ZZ{^MtnnI! z{~58)Kl38)wGGU9xX==@{gP%zmdWy}}(B4fVf zw=`xRMR((&3U^b0t_zmlrlY~`2n{!#xf$mhcT>2Zv}xOeD{KQI?DpUdOy-$m9yHi_ zR+xT3;hn}z;8^YPLGrPS?!Qe(OA~QdT;Wk; zCW0_Y#GQgKO-F-u3UvIn^sqq=W`guKCevtkhE5H$F=m*~42+q^OuAU6HM}UwCRl4a z8k{u!W7EG-_?aHiNCr3(N^>`m~UL1Sk&YH07-bM%m4rY diff --git a/hardware/esp8266com/esp8266/tools/sdk/version b/hardware/esp8266com/esp8266/tools/sdk/version index 9084fa2f71..a64d2ed43c 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/version +++ b/hardware/esp8266com/esp8266/tools/sdk/version @@ -1 +1 @@ -1.1.0 +1.1.0_15_05_27_p1 \ No newline at end of file From 877aa5aad7d5b5af7fad6db23c71d672e8a4d775 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 17:31:45 +0200 Subject: [PATCH 29/77] 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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 009cb69ef1..0f97e48a1b 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 5eb5c9b0fd..0d6def8b3d 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/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 bba12477db056743d757270ffd62406498fa488c Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 18:50:11 +0200 Subject: [PATCH 30/77] add missing include #include "ets_sys.h" --- hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index bfdd3692cf..048f6fa876 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/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 936669e234e997b1d0406af004d1ac56b900d4fb Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 28 May 2015 18:58:09 +0200 Subject: [PATCH 31/77] 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) --- .../esp8266/cores/esp8266/Arduino.h | 3 +- .../esp8266/cores/esp8266/pgmspace.cpp | 58 +++++++++---------- .../esp8266/cores/esp8266/pgmspace.h | 18 +++--- .../libraries/ESP8266WiFi/src/ESP8266WiFi.h | 1 + .../esp8266/tools/sdk/include/ets_sys.h | 4 +- 5 files changed, 43 insertions(+), 41 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 89dbff873f..9d3f18ed9e 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp index 84af6264b3..c2b5781f1f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.cpp +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h index 695f2a50b9..e6db10fbda 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 0d6def8b3d..64563ad7e9 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 7908699bb5..389918be4d 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/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 7647df15dbe525d2c1a48cc93e2247d77d02d8d0 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:11 -0700 Subject: [PATCH 32/77] Revert "Fixed timer bug and cleaned up" This reverts commit cff57490feae778b68740e0ef878d4521ae4eb2b. --- .../esp8266com/esp8266/cores/esp8266/Arduino.h | 4 ++-- hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 16 ++++++++++++++++ .../esp8266/cores/esp8266/core_esp8266_timer.c | 10 ++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index dcaa47b09e..7ebc77b791 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index fc52371965..c887c89e92 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index b9b2f1256a..979ab0bfc1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/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 a5a7872d2f150b0b34ee099c415db3c619a01603 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 08:36:50 -0700 Subject: [PATCH 33/77] Revert "ETS_INTR_ENABLED & ETS_INT_PENDING as inline" This reverts commit 9560c67aa86659bd9f8210f807706e35b85ae9be. --- hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index e11e619708..3cdb51d2af 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/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 34/77] Revert "Expose Chip CCompare0 timer" This reverts commit 17b29fc437b8334c4d0089a7e576cc386687f361. --- .../esp8266/cores/esp8266/Arduino.h | 18 ++------------- .../esp8266com/esp8266/cores/esp8266/Esp.h | 18 +-------------- .../cores/esp8266/core_esp8266_timer.c | 22 ------------------- .../esp8266/tools/sdk/include/ets_sys.h | 22 ------------------- 4 files changed, 3 insertions(+), 77 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 7ebc77b791..89dbff873f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index c887c89e92..5e356459e1 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 979ab0bfc1..bfdd3692cf 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 3cdb51d2af..7908699bb5 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/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 35/77] strtok fix public strtok_r implementation --- .../esp8266/cores/esp8266/libc_replacements.c | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c b/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c index 519ea233ae..39ee925a43 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c +++ b/hardware/esp8266com/esp8266/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 8ebdcfac72bdfa20d525fed4c095f6c7c54e8acf Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:27:03 +0300 Subject: [PATCH 36/77] Add eboot --- .../esp8266/bootloaders/eboot/LICENSE | 26 ++ .../esp8266/bootloaders/eboot/Makefile | 50 +++ .../esp8266/bootloaders/eboot/eboot.c | 86 +++++ .../esp8266/bootloaders/eboot/eboot.elf | Bin 0 -> 6358 bytes .../esp8266/bootloaders/eboot/eboot.h | 41 +++ .../esp8266/bootloaders/eboot/eboot.ld | 176 +++++++++ .../esp8266/bootloaders/eboot/rom.ld | 344 ++++++++++++++++++ 7 files changed, 723 insertions(+) create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/LICENSE create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/Makefile create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c create mode 100755 hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/eboot.ld create mode 100755 hardware/esp8266com/esp8266/bootloaders/eboot/rom.ld diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/LICENSE b/hardware/esp8266com/esp8266/bootloaders/eboot/LICENSE new file mode 100644 index 0000000000..d81a07e401 --- /dev/null +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile new file mode 100644 index 0000000000..4ecc252f0b --- /dev/null +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c new file mode 100644 index 0000000000..e39375d2d2 --- /dev/null +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/bootloaders/eboot/rom.ld b/hardware/esp8266com/esp8266/bootloaders/eboot/rom.ld new file mode 100755 index 0000000000..c5c1b65223 --- /dev/null +++ b/hardware/esp8266com/esp8266/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 a4d8a3b84339c9f4165ea82b2f8e1619010058a8 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:33:15 +0300 Subject: [PATCH 37/77] Update esptool to 0.4.5 --- build/build.xml | 30 ++++++++++---------- build/linux/esptool-0.4.4-linux64.tar.gz.sha | 1 - build/linux/esptool-0.4.5-linux64.tar.gz.sha | 1 + build/macosx/esptool-0.4.4-osx.tar.gz.sha | 1 - build/macosx/esptool-0.4.5-osx.tar.gz.sha | 1 + build/windows/esptool-0.4.4-win32.zip.sha | 1 - build/windows/esptool-0.4.5-win32.zip.sha | 1 + 7 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 build/linux/esptool-0.4.4-linux64.tar.gz.sha create mode 100644 build/linux/esptool-0.4.5-linux64.tar.gz.sha delete mode 100644 build/macosx/esptool-0.4.4-osx.tar.gz.sha create mode 100644 build/macosx/esptool-0.4.5-osx.tar.gz.sha delete mode 100644 build/windows/esptool-0.4.4-win32.zip.sha create mode 100644 build/windows/esptool-0.4.5-win32.zip.sha diff --git a/build/build.xml b/build/build.xml index 20bac52d48..5afc34cb61 100644 --- a/build/build.xml +++ b/build/build.xml @@ -398,13 +398,13 @@ - - - + + + - - + + @@ -673,13 +673,13 @@ - - - + + + - - + + @@ -928,13 +928,13 @@ - - - + + + - - + + diff --git a/build/linux/esptool-0.4.4-linux64.tar.gz.sha b/build/linux/esptool-0.4.4-linux64.tar.gz.sha deleted file mode 100644 index 18f5fabdd9..0000000000 --- a/build/linux/esptool-0.4.4-linux64.tar.gz.sha +++ /dev/null @@ -1 +0,0 @@ -65e4b3c4a26e7960536f8f2a19c5d65a13fe8025 diff --git a/build/linux/esptool-0.4.5-linux64.tar.gz.sha b/build/linux/esptool-0.4.5-linux64.tar.gz.sha new file mode 100644 index 0000000000..d380907b57 --- /dev/null +++ b/build/linux/esptool-0.4.5-linux64.tar.gz.sha @@ -0,0 +1 @@ +ef9940f7b690f346739b54e4df46d0fbd37f0e12 diff --git a/build/macosx/esptool-0.4.4-osx.tar.gz.sha b/build/macosx/esptool-0.4.4-osx.tar.gz.sha deleted file mode 100644 index 0cf3a3d4a3..0000000000 --- a/build/macosx/esptool-0.4.4-osx.tar.gz.sha +++ /dev/null @@ -1 +0,0 @@ -26c53e32887b0c41dab861df93a60d1688e7762b diff --git a/build/macosx/esptool-0.4.5-osx.tar.gz.sha b/build/macosx/esptool-0.4.5-osx.tar.gz.sha new file mode 100644 index 0000000000..534ff18d54 --- /dev/null +++ b/build/macosx/esptool-0.4.5-osx.tar.gz.sha @@ -0,0 +1 @@ +702be33406745b31904a40b28cf6ebb87173e4c8 diff --git a/build/windows/esptool-0.4.4-win32.zip.sha b/build/windows/esptool-0.4.4-win32.zip.sha deleted file mode 100644 index 9fea4d2e5f..0000000000 --- a/build/windows/esptool-0.4.4-win32.zip.sha +++ /dev/null @@ -1 +0,0 @@ -2d1beb3fb3af8b16bca15b7cd6f61aec10cc52cb diff --git a/build/windows/esptool-0.4.5-win32.zip.sha b/build/windows/esptool-0.4.5-win32.zip.sha new file mode 100644 index 0000000000..e37cc5b2ac --- /dev/null +++ b/build/windows/esptool-0.4.5-win32.zip.sha @@ -0,0 +1 @@ +7c6b0049e016889a85dc0c7e01282ef0ce36d1f3 From 9980066e3cd0b78e6b1d1afa38a34ccb3ca76477 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:35:31 +0300 Subject: [PATCH 38/77] Fix eboot makefile --- .../esp8266/bootloaders/eboot/Makefile | 2 +- .../esp8266/bootloaders/eboot/eboot.elf | Bin 6358 -> 5209 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile index 4ecc252f0b..32e325f34b 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf b/hardware/esp8266com/esp8266/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 39/77] Update flash layout to use eboot --- hardware/esp8266com/esp8266/boards.txt | 22 +++++++++---------- hardware/esp8266com/esp8266/platform.txt | 6 ++--- .../esp8266/tools/sdk/ld/eagle.flash.16m.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.1m128.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.1m256.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.1m512.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.1m64.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.2m.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.4m.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.512k.ld | 4 ++-- .../esp8266/tools/sdk/ld/eagle.flash.8m.ld | 4 ++-- 11 files changed, 32 insertions(+), 32 deletions(-) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index fdf37d5700..d3c3d28061 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index e76b838ca2..f0796310b0 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.16m.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.16m.ld index d6112f9735..d968c14299 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.16m.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m128.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m128.ld index d7d4a94235..12a70ed15a 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m128.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m256.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m256.ld index b75be04f3a..0f97d179c4 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m256.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m512.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m512.ld index 1bc7148b1c..89350c44ec 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m512.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m64.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m64.ld index aa553ba559..73fa6e51b6 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.1m64.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.2m.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.2m.ld index 95c045a379..0753f5ead2 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.2m.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.4m.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.4m.ld index 1239033f39..04aa3a8f46 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.4m.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.512k.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.512k.ld index ea6f37bedd..5d01d32597 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.512k.ld +++ b/hardware/esp8266com/esp8266/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/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.8m.ld b/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.8m.ld index 166e44f91a..18c5f7d99a 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.flash.8m.ld +++ b/hardware/esp8266com/esp8266/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 d50aa4396060c1458ea8f95683050bfed2f4a6d6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 19:57:03 +0300 Subject: [PATCH 40/77] Fix max sketch sizes for branded boards --- hardware/esp8266com/esp8266/boards.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hardware/esp8266com/esp8266/boards.txt b/hardware/esp8266com/esp8266/boards.txt index 5d9f468a81..bfc910a2b0 100644 --- a/hardware/esp8266com/esp8266/boards.txt +++ b/hardware/esp8266com/esp8266/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 From 579dbb7cd2ed02dcc6b3ac9270f77dd86dae2d01 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 20:37:32 +0300 Subject: [PATCH 41/77] Fix linker errors --- .../esp8266/cores/esp8266/core_esp8266_wiring_pwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c index b175f6e553..c74f76bc3f 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c @@ -81,8 +81,8 @@ void prep_pwm_steps(){ } ETS_FRC1_INTR_DISABLE(); pwm_steps_len = pwm_temp_steps_len; - os_memcpy(pwm_steps, pwm_temp_steps, (pwm_temp_steps_len + 1) * 2); - os_memcpy(pwm_steps_mask, pwm_temp_masks, pwm_temp_steps_len * 4); + ets_memcpy(pwm_steps, pwm_temp_steps, (pwm_temp_steps_len + 1) * 2); + ets_memcpy(pwm_steps_mask, pwm_temp_masks, pwm_temp_steps_len * 4); pwm_multiplier = F_CPU/(PWMRANGE * pwm_freq); ETS_FRC1_INTR_ENABLE(); } From db0b8be7f17fed7933049932dbade9ea72ed3734 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 20:40:18 +0300 Subject: [PATCH 42/77] Improve I2C waveforms --- .../esp8266/cores/esp8266/core_esp8266_si2c.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c index cff2809d3c..1593bb8597 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c @@ -44,16 +44,16 @@ static unsigned char twi_sda, twi_scl; void twi_setClock(unsigned int freq){ #if F_CPU == FCPU80 - if(freq <= 100000) twi_dcount = 18;//about 100KHz + if(freq <= 100000) twi_dcount = 19;//about 100KHz else if(freq <= 200000) twi_dcount = 8;//about 200KHz - else if(freq <= 300000) twi_dcount = 4;//about 300KHz - else if(freq <= 400000) twi_dcount = 2;//about 370KHz + else if(freq <= 300000) twi_dcount = 3;//about 300KHz + else if(freq <= 400000) twi_dcount = 1;//about 370KHz else twi_dcount = 1;//about 450KHz #else if(freq <= 100000) twi_dcount = 32;//about 100KHz - else if(freq <= 200000) twi_dcount = 16;//about 200KHz + else if(freq <= 200000) twi_dcount = 14;//about 200KHz else if(freq <= 300000) twi_dcount = 8;//about 300KHz - else if(freq <= 400000) twi_dcount = 4;//about 370KHz + else if(freq <= 400000) twi_dcount = 5;//about 370KHz else twi_dcount = 2;//about 450KHz #endif } @@ -109,7 +109,7 @@ static bool twi_write_bit(bool bit) { twi_delay(twi_dcount+1); SCL_HIGH(); while (SCL_READ() == 0 && (i++) < TWI_CLOCK_STRETCH);// Clock stretching (up to 100us) - twi_delay(twi_dcount+1); + twi_delay(twi_dcount); return true; } @@ -117,7 +117,7 @@ static bool twi_read_bit(void) { unsigned int i = 0; SCL_LOW(); SDA_HIGH(); - twi_delay(twi_dcount+1); + twi_delay(twi_dcount+2); SCL_HIGH(); while (SCL_READ() == 0 && (i++) < TWI_CLOCK_STRETCH);// Clock stretching (up to 100us) bool bit = SDA_READ(); From f5e2deb63f7e64c2a4b6c9359abc47cbf26b27a4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 21:17:11 +0300 Subject: [PATCH 43/77] Add staging board manager package (#324) --- build/build_board_manager_package.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/build/build_board_manager_package.sh b/build/build_board_manager_package.sh index d0cdc5ce46..28559ec445 100755 --- a/build/build_board_manager_package.sh +++ b/build/build_board_manager_package.sh @@ -1,4 +1,8 @@ #!/bin/bash +# +# for platform in windows linux macosx; do pushd $platform; ls -l esptool-*; shasum -a 256 esptool-*; popd; done; +# +# ver=`git describe --tags` outdir=esp8266-$ver @@ -23,9 +27,14 @@ size=`/bin/ls -l $outdir.zip | awk '{print $5}'` echo Size: $size echo SHA-256: $sha -if [ ! -z "$do_upload" ]; then +if [ "$upload" == "prod" ]; then remote="http://arduino.esp8266.com" + path="" +elif [ "$upload" == "stag" ]; then + remote="http://arduino.esp8266.com" + path="staging/" else + upload="" remote="http://localhost:8000" fi @@ -45,7 +54,7 @@ cat << EOF > package_esp8266com_index.json "architecture":"esp8266", "version":"$ver", "category":"ESP8266", - "url":"$remote/$outdir.zip", + "url":"$remote/$path/$outdir.zip", "archiveFileName":"$outdir.zip", "checksum":"SHA-256:$sha", "size":"$size", @@ -153,9 +162,9 @@ cat << EOF > package_esp8266com_index.json } EOF -if [ ! -z "$do_upload" ]; then - scp $outdir.zip dl:apps/download_files/download/ - scp package_esp8266com_index.json dl:apps/download_files/download +if [ ! -z "$upload" ]; then + scp $outdir.zip dl:apps/download_files/download/$path + scp package_esp8266com_index.json dl:apps/download_files/download/$path else python -m SimpleHTTPServer fi From 69e9f2ed43178efb295a2252035c55bd03f17aa3 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 21:18:09 +0300 Subject: [PATCH 44/77] Update board manager package to use esptool 0.4.5 Note: linux32 package not updated yet --- build/build_board_manager_package.sh | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/build/build_board_manager_package.sh b/build/build_board_manager_package.sh index 28559ec445..4b02fc90b4 100755 --- a/build/build_board_manager_package.sh +++ b/build/build_board_manager_package.sh @@ -81,7 +81,7 @@ cat << EOF > package_esp8266com_index.json "toolsDependencies":[ { "packager":"esp8266", "name":"esptool", - "version":"0.4.4" + "version":"0.4.5" }, { "packager":"esp8266", @@ -92,33 +92,33 @@ cat << EOF > package_esp8266com_index.json "tools": [ { "name":"esptool", - "version":"0.4.4", + "version":"0.4.5", "systems": [ { "host":"i686-mingw32", - "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.4/esptool-0.4.4-win32.zip", - "archiveFileName":"esptool-0.4.4-win32.zip", - "checksum":"SHA-256:bc52165c847b194d8f079add982eae1c4b4466784bff8c8494241de602a003b3", - "size":"17262" + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.5/esptool-0.4.5-win32.zip", + "archiveFileName":"esptool-0.4.5-win32.zip", + "checksum":"SHA-256:1b0a7d254e74942d820a09281aa5dc2af1c8314ae5ee1a5abb0653d0580e531b", + "size":"17408" }, { "host":"x86_64-apple-darwin", - "url":"http://arduino.esp8266.com/esptool-0.4.4-5-g744c44d-osx.tar.gz", - "archiveFileName":"esptool-0.4.4-5-g744c44d-osx.tar.gz", - "checksum":"SHA-256:d8bc920e046fcc668b31cda63ac5553b4c07a6db12bfd0abc9005fc94628afcb", - "size":"12133" + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.5/esptool-0.4.5-osx.tar.gz", + "archiveFileName":"esptool-0.4.5-osx.tar.gz", + "checksum":"SHA-256:924d31c64f4bb9f748e70806dafbabb15e5eb80afcdde33715f3ec884be1652d", + "size":"11359" }, { "host":"x86_64-pc-linux-gnu", - "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.4/esptool-0.4.4-linux64.tar.gz", - "archiveFileName":"esptool-0.4.4-linux64.tar.gz", - "checksum":"SHA-256:beedf89db0bdce0bf6034232d86edebcfed0966ff1501545aca9cfbba1f92593", - "size":"12513" + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.5/esptool-0.4.5-linux64.tar.gz", + "archiveFileName":"esptool-0.4.5-linux64.tar.gz", + "checksum":"SHA-256:4ce799e13fbd89f8a8f08a08db77dc3b1362c4486306fe1b3801dee80cfa3203", + "size":"12789" }, { "host":"i686-pc-linux-gnu", - "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.4/esptool-0.4.4-linux32.tar.gz", - "archiveFileName":"esptool-0.4.4-linux32.tar.gz", + "url":"https://github.com/igrr/esptool-ck/releases/download/0.4.5/esptool-0.4.5-linux32.tar.gz", + "archiveFileName":"esptool-0.4.5-linux32.tar.gz", "checksum":"SHA-256:4aa81b97a470641771cf371e5d470ac92d3b177adbe8263c4aae66e607b67755", "size":"12044" } From a19402414fe7c40c1ff234ddd60091c27d4f6821 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 29 May 2015 21:26:23 +0300 Subject: [PATCH 45/77] Add wakeup pullup and pulldown pin modes --- hardware/esp8266com/esp8266/cores/esp8266/Arduino.h | 2 ++ .../cores/esp8266/core_esp8266_wiring_digital.c | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 9d3f18ed9e..ff5d4c4cde 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -51,6 +51,8 @@ void yield(void); #define INPUT_PULLDOWN 0x04 #define OUTPUT 0x01 #define OUTPUT_OPEN_DRAIN 0x03 +#define WAKEUP_PULLUP 0x05 +#define WAKEUP_PULLDOWN 0x07 #define SPECIAL 0xF8 //defaults to the usable BUSes uart0rx/tx uart1tx and hspi #define FUNCTION_0 0x08 #define FUNCTION_1 0x18 diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c index 57702f4695..d86829ff71 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_digital.c @@ -53,6 +53,16 @@ extern void __pinMode(uint8_t pin, uint8_t mode) { } else if(mode == INPUT_PULLDOWN) { GPF(pin) |= (1 << GPFPD); // Enable Pulldown } + } else if(mode == WAKEUP_PULLUP || mode == WAKEUP_PULLDOWN){ + GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO + GPEC = (1 << pin); //Disable + if(mode == WAKEUP_PULLUP) { + GPF(pin) |= (1 << GPFPU); // Enable Pullup + GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED) + } else { + GPF(pin) |= (1 << GPFPD); // Enable Pulldown + GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED) + } } } else if(pin == 16){ GPF16 = GP16FFS(GPFFS_GPIO(pin));//Set mode to GPIO From 54e7ecd4142dd2569bba5d5f5e1c46f4b0f89c44 Mon Sep 17 00:00:00 2001 From: Makuna Date: Fri, 29 May 2015 13:30:15 -0700 Subject: [PATCH 46/77] Timer0 and Servo library support This exposes the Timer0 This provides a Servo library support compatible with Arduino Servo library but only supports the two timers the esp8266 has available --- .../esp8266/cores/esp8266/Arduino.h | 18 +- .../cores/esp8266/core_esp8266_timer.c | 51 +++- .../libraries/Servo/examples/Sweep/Sweep.ino | 39 +++ .../esp8266/libraries/Servo/keywords.txt | 24 ++ .../libraries/Servo/library.properties | 9 + .../esp8266/libraries/Servo/src/Servo.h | 93 +++++++ .../libraries/Servo/src/esp8266/Servo.cpp | 249 ++++++++++++++++++ .../libraries/Servo/src/esp8266/ServoTimers.h | 227 ++++++++++++++++ .../esp8266/tools/sdk/include/ets_sys.h | 24 ++ 9 files changed, 727 insertions(+), 7 deletions(-) create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/examples/Sweep/Sweep.ino create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/keywords.txt create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/library.properties create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/src/Servo.h create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/Servo.cpp create mode 100644 hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/ServoTimers.h diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 9d3f18ed9e..6d8dc1eb5c 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -99,13 +99,29 @@ void yield(void); #define timer1_enabled() ((T1C & (1 << TCTE)) != 0) #define timer1_interrupted() ((T1C & (1 << TCIS)) != 0) +typedef void(*timercallback)(void); + void timer1_isr_init(void); void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload); void timer1_disable(void); -void timer1_attachInterrupt(void (*userFunc)(void)); +void timer1_attachInterrupt(timercallback userFunc); 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() ((__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") + +void timer0_isr_init(void); +void timer0_attachInterrupt(timercallback userFunc); +void timer0_detachInterrupt(void); + // undefine stdlib's abs if encountered #ifdef abs #undef abs diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 048f6fa876..08b971c58c 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -20,22 +20,33 @@ */ #include "wiring_private.h" #include "pins_arduino.h" +#ifdef __cplusplus +extern "C" { +#endif + #include "c_types.h" #include "ets_sys.h" -void (*timer1_user_cb)(void); +#ifdef __cplusplus +} +#endif + +/ ------------------------------------------------------------------ - +// timer 1 + +static volatile timercallback timer1_user_cb = NULL; void timer1_isr_handler(void *para){ - if((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable + if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable T1I = 0; - if(timer1_user_cb) timer1_user_cb(); + if (timer1_user_cb) timer1_user_cb(); } void timer1_isr_init(){ ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL); } -void timer1_attachInterrupt(void (*userFunc)(void)) { +void timer1_attachInterrupt(timercallback userFunc) { timer1_user_cb = userFunc; ETS_FRC1_INTR_ENABLE(); } @@ -52,11 +63,39 @@ void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload){ } void timer1_write(uint32_t ticks){ - T1L = ((ticks) & 0x7FFFFF); - if((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable + T1L = ((ticks)& 0x7FFFFF); + if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable } void timer1_disable(){ T1C = 0; T1I = 0; } + +//------------------------------------------------------------------- +// timer 0 + +static volatile timercallback timer0_user_cb = NULL; + +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(timercallback userFunc) { + timer0_user_cb = userFunc; + ETS_CCOMPARE0_ENABLE(); +} + +void timer0_detachInterrupt() { + timer0_user_cb = NULL; + ETS_CCOMPARE0_DISABLE(); +} + + + diff --git a/hardware/esp8266com/esp8266/libraries/Servo/examples/Sweep/Sweep.ino b/hardware/esp8266com/esp8266/libraries/Servo/examples/Sweep/Sweep.ino new file mode 100644 index 0000000000..fe4e343cef --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/examples/Sweep/Sweep.ino @@ -0,0 +1,39 @@ +/* Sweep + by BARRAGAN + This example code is in the public domain. + + modified 28 May 2015 + by Michael C. Miller + modified 8 Nov 2013 + by Scott Fitzgerald + + http://arduino.cc/en/Tutorial/Sweep +*/ + +#include + +Servo myservo; // create servo object to control a servo + // twelve servo objects can be created on most boards + + +void setup() +{ + myservo.attach(2); // attaches the servo on GIO2 to the servo object +} + +void loop() +{ + int pos; + + for(pos = 0; pos <= 180; pos += 1) // goes from 0 degrees to 180 degrees + { // in steps of 1 degree + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } + for(pos = 180; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees + { + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } +} + diff --git a/hardware/esp8266com/esp8266/libraries/Servo/keywords.txt b/hardware/esp8266com/esp8266/libraries/Servo/keywords.txt new file mode 100644 index 0000000000..0a7ca1e3d8 --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map Servo +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Servo KEYWORD1 Servo + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +attach KEYWORD2 +detach KEYWORD2 +write KEYWORD2 +read KEYWORD2 +attached KEYWORD2 +writeMicroseconds KEYWORD2 +readMicroseconds KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/hardware/esp8266com/esp8266/libraries/Servo/library.properties b/hardware/esp8266com/esp8266/libraries/Servo/library.properties new file mode 100644 index 0000000000..28b1eedf71 --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/library.properties @@ -0,0 +1,9 @@ +name=Servo +version=1.0.2 +author=Michael C. Miller +maintainer=GitHub/esp8266/arduino +sentence=Allows Esp8266 boards to control a variety of servo motors. +paragraph=This library can control a great number of servos.
It makes careful use of timers: the library can control 12 servos using only 1 timer.
+category=Device Control +url=http://arduino.cc/en/Reference/Servo +architectures=esp8266 diff --git a/hardware/esp8266com/esp8266/libraries/Servo/src/Servo.h b/hardware/esp8266com/esp8266/libraries/Servo/src/Servo.h new file mode 100644 index 0000000000..10cfd32835 --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/src/Servo.h @@ -0,0 +1,93 @@ +/* + Servo.h - Interrupt driven Servo library for Esp8266 using timers + 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 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 + */ + + +// A servo is activated by creating an instance of the Servo class passing +// the desired pin to the attach() method. +// The servos are pulsed in the background using the value most recently +// written using the write() method. +// +// This library uses time0 and timer1. +// Note that timer0 may be repurposed when the first servo is attached. +// +// Timers are seized as needed in groups of 12 servos - 24 servos use two +// timers, there are only two timers for the esp8266 so the support stops here +// The sequence used to sieze timers is defined in timers.h +// +// The methods are: +// +// Servo - Class for manipulating servo motors connected to Arduino pins. +// +// attach(pin ) - Attaches a servo motor to an i/o pin. +// attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds +// default min is 544, max is 2400 +// +// write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) +// writeMicroseconds() - Sets the servo pulse width in microseconds +// read() - Gets the last written servo pulse width as an angle between 0 and 180. +// readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) +// attached() - Returns true if there is a servo attached. +// detach() - Stops an attached servos from pulsing its i/o pin. + + +#ifndef Servo_h +#define Servo_h + +#include + +// the following are in us (microseconds) +// +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo +#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached +#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds + +// NOTE: to maintain a strict refresh interval the user needs to not exceede 8 servos +#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer +#define MAX_SERVOS (ServoTimerSequence_COUNT * SERVOS_PER_TIMER) + +#if defined(ESP8266) + +#include "esp8266/ServoTimers.h" + +#else + +#error "This library only supports esp8266 boards." + +#endif + +class Servo +{ +public: + Servo(); + uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure + uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. + void detach(); + void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds + void writeMicroseconds(int value); // Write pulse width in microseconds + int read(); // returns current pulse width as an angle between 0 and 180 degrees + int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) + bool attached(); // return true if this servo is attached, otherwise false +private: + uint8_t _servoIndex; // index into the channel data for this servo + uint16_t _minUs; + uint16_t _maxUs; +}; + +#endif diff --git a/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/Servo.cpp b/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/Servo.cpp new file mode 100644 index 0000000000..bbc7bb26ff --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/Servo.cpp @@ -0,0 +1,249 @@ +/* + 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 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 + */ + +#if defined(ESP8266) + +#include +#include + + +#define INVALID_SERVO 255 // flag indicating an invalid servo index + +const uint32_t c_CycleCompensation = 4; // compensation us to trim adjust for digitalWrite delays + +struct ServoInfo { + uint8_t pin : 6; // a pin number from 0 to 63 + uint8_t isActive : 1; // true if this channel is enabled, pin not pulsed if false +}; + +struct ServoState { + ServoInfo info; + volatile uint16_t usPulse; +}; + +#if !defined (SERVO_EXCLUDE_TIMER0) +ServoTimer0 s_servoTimer0; +#endif + +#if !defined (SERVO_EXCLUDE_TIMER1) +ServoTimer1 s_servoTimer1; +#endif + +static ServoState s_servos[MAX_SERVOS]; // static array of servo structures + +static uint8_t s_servoCount = 0; // the total number of attached s_servos + + +// inconvenience macros +#define SERVO_INDEX_TO_TIMER(servoIndex) ((ServoTimerSequence)(servoIndex / SERVOS_PER_TIMER)) // returns the timer controlling this servo +#define SERVO_INDEX(timerId, channel) ((timerId * SERVOS_PER_TIMER) + channel) // macro to access servo index by timer and channel + +//------------------------------------------------------------------------------ +// Interrupt handler template method that takes a class that implements +// a standard set of methods for the timer abstraction +//------------------------------------------------------------------------------ +template void Servo_Handler(T* timer) +{ + noInterrupts(); + + uint8_t servoIndex; + + // clear interrupt + timer->ResetInterrupt(); + + if (timer->isEndOfCycle()) { + timer->StartCycle(); + } + else { + servoIndex = SERVO_INDEX(timer->timerId(), timer->getCurrentChannel()); + if (servoIndex < s_servoCount && s_servos[servoIndex].info.isActive) { + // pulse this channel low if activated + digitalWrite(s_servos[servoIndex].info.pin, LOW); + } + timer->nextChannel(); + } + + servoIndex = SERVO_INDEX(timer->timerId(), timer->getCurrentChannel()); + + if (servoIndex < s_servoCount && timer->getCurrentChannel() < SERVOS_PER_TIMER) { + timer->SetPulseCompare(timer->usToTicks(s_servos[servoIndex].usPulse) - c_CycleCompensation); + + if (s_servos[servoIndex].info.isActive) { // check if activated + digitalWrite(s_servos[servoIndex].info.pin, HIGH); // its an active channel so pulse it high + } + } + else { + // finished all channels so wait for the refresh period to expire before starting over + // allow a few ticks to ensure the next match is not missed + uint32_t refreshCompare = timer->usToTicks(REFRESH_INTERVAL); + if ((timer->GetCycleCount() + c_CycleCompensation * 2) < refreshCompare) { + timer->SetCycleCompare(refreshCompare - c_CycleCompensation); + } + else { + // at least REFRESH_INTERVAL has elapsed + timer->SetCycleCompare(timer->GetCycleCount() + c_CycleCompensation * 2); + } + + timer->setEndOfCycle(); + } + + interrupts(); +} + +static void initISR(ServoTimerSequence timerId) +{ +#if !defined (SERVO_EXCLUDE_TIMER0) + if (timerId == ServoTimerSequence_Timer0) + s_servoTimer0.InitInterrupt([]() {Servo_Handler(&s_servoTimer0); }); +#endif +#if !defined (SERVO_EXCLUDE_TIMER1) + if (timerId == ServoTimerSequence_Timer1) + s_servoTimer1.InitInterrupt([]() {Servo_Handler(&s_servoTimer1); }); +#endif +} + +static void finISR(ServoTimerSequence timerId) +{ +#if !defined (SERVO_EXCLUDE_TIMER0) + if (timerId == ServoTimerSequence_Timer0) + s_servoTimer0.StopInterrupt(); +#endif +#if !defined (SERVO_EXCLUDE_TIMER1) + if (timerId == ServoTimerSequence_Timer1) + s_servoTimer1.StopInterrupt(); +#endif +} + +// returns true if any servo is active on this timer +static boolean isTimerActive(ServoTimerSequence timerId) +{ + for (uint8_t channel = 0; channel < SERVOS_PER_TIMER; channel++) { + if (s_servos[SERVO_INDEX(timerId, channel)].info.isActive) { + return true; + } + } + return false; +} + +//------------------------------------------------------------------- +// Servo class methods + +Servo::Servo() +{ + if (s_servoCount < MAX_SERVOS) { + // assign a servo index to this instance + _servoIndex = s_servoCount++; + // store default values + s_servos[_servoIndex].usPulse = DEFAULT_PULSE_WIDTH; + } + else { + _servoIndex = INVALID_SERVO; // too many servos + } +} + +uint8_t Servo::attach(int pin) +{ + return attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +uint8_t Servo::attach(int pin, int minUs, int maxUs) +{ + ServoTimerSequence timerId; + + Serial.print("_servoIndex "); + Serial.println(_servoIndex); + + if (_servoIndex < MAX_SERVOS) { + pinMode(pin, OUTPUT); // set servo pin to output + digitalWrite(pin, LOW); + s_servos[_servoIndex].info.pin = pin; + + // keep the min and max within 200-3000 us, these are extreme + // ranges and should support extreme servos while maintaining + // reasonable ranges + _maxUs = max(250, min(3000, maxUs)); + _minUs = max(200, min(_maxUs, minUs)); + + // initialize the timerId if it has not already been initialized + timerId = SERVO_INDEX_TO_TIMER(_servoIndex); + if (!isTimerActive(timerId)) { + initISR(timerId); + } + s_servos[_servoIndex].info.isActive = true; // this must be set after the check for isTimerActive + } + return _servoIndex; +} + +void Servo::detach() +{ + ServoTimerSequence timerId; + + s_servos[_servoIndex].info.isActive = false; + timerId = SERVO_INDEX_TO_TIMER(_servoIndex); + if (!isTimerActive(timerId)) { + finISR(timerId); + } +} + +void Servo::write(int value) +{ + // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + if (value < MIN_PULSE_WIDTH) { + // assumed to be 0-180 degrees servo + value = max(0, min(180, value)); + value = map(value, 0, 180, _minUs, _maxUs); + } + writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) +{ + // ensure channel is valid + if ((_servoIndex < MAX_SERVOS)) { + // ensure pulse width is valid + value = max(_minUs, min(_maxUs, value)); + + s_servos[_servoIndex].usPulse = value; + } +} + +int Servo::read() // return the value as degrees +{ + return map(readMicroseconds(), _minUs, _maxUs, 0, 180); +} + +int Servo::readMicroseconds() +{ + unsigned int pulsewidth; + if (_servoIndex != INVALID_SERVO) { + pulsewidth = s_servos[_servoIndex].usPulse; + } + else { + pulsewidth = 0; + } + + return pulsewidth; +} + +bool Servo::attached() +{ + return s_servos[_servoIndex].info.isActive; +} + +#endif + diff --git a/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/ServoTimers.h b/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/ServoTimers.h new file mode 100644 index 0000000000..56ee18671b --- /dev/null +++ b/hardware/esp8266com/esp8266/libraries/Servo/src/esp8266/ServoTimers.h @@ -0,0 +1,227 @@ +/* + 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 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 + */ + +// +// Defines for timer abstractions used with Servo library +// +// ServoTimerSequence enumerates the sequence that the timers should be allocated +// ServoTimerSequence_COUNT indicates how many timers are available. +// +enum ServoTimerSequence { + +#if !defined (SERVO_EXCLUDE_TIMER0) + ServoTimerSequence_Timer0, +#endif + +#if !defined (SERVO_EXCLUDE_TIMER1) + ServoTimerSequence_Timer1, +#endif + + ServoTimerSequence_COUNT +}; + + +#if !defined (SERVO_EXCLUDE_TIMER0) + +struct ServoTimer0 +{ +public: + ServoTimer0() + { + setEndOfCycle(); + } + + + uint32_t usToTicks(uint32_t us) const + { + return (clockCyclesPerMicrosecond() * us); // converts microseconds to tick + } + uint32_t ticksToUs(uint32_t ticks) const + { + return (ticks / clockCyclesPerMicrosecond()); // converts from ticks back to microseconds + } + + void InitInterrupt(timercallback handler) + { + timer0_isr_init(); + timer0_attachInterrupt(handler); + } + + void ResetInterrupt() {}; // timer0 doesn't have a clear interrupt + + void StopInterrupt() + { + timer0_detachInterrupt(); + } + + void SetPulseCompare(uint32_t value) + { + timer0_write(ESP.getCycleCount() + value); + } + + void SetCycleCompare(uint32_t value) + { + timer0_write(_cycleStart + value); + } + + uint32_t GetCycleCount() const + { + return ESP.getCycleCount() - _cycleStart; + } + + + void StartCycle() + { + _cycleStart = ESP.getCycleCount(); + _currentChannel = 0; + } + + int8_t getCurrentChannel() const + { + return _currentChannel; + } + + void nextChannel() + { + _currentChannel++; + } + + void setEndOfCycle() + { + _currentChannel = -1; + } + + bool isEndOfCycle() const + { + return (_currentChannel == -1); + } + + ServoTimerSequence timerId() const + { + return ServoTimerSequence_Timer0; + } + +private: + volatile uint32_t _cycleStart; + volatile int8_t _currentChannel; +}; + +#endif + + +#if !defined (SERVO_EXCLUDE_TIMER1) + +struct ServoTimer1 +{ +public: + ServoTimer1() + { + setEndOfCycle(); + } + + + uint32_t usToTicks(uint32_t us) const + { + return (clockCyclesPerMicrosecond() / 16 * us); // converts microseconds to tick + } + uint32_t ticksToUs(uint32_t ticks) const + { + return (ticks / clockCyclesPerMicrosecond() * 16); // converts from ticks back to microseconds + } + + void InitInterrupt(timercallback handler) + { + timer1_isr_init(); + timer1_attachInterrupt(handler); + timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); + timer1_write(usToTicks(REFRESH_INTERVAL)); + } + + void ResetInterrupt() {}; // timer1 doesn't have a clear interrupt + + void StopInterrupt() + { + timer1_detachInterrupt(); + } + + void SetPulseCompare(uint32_t value) + { + _cycleTicks += value; + timer1_write(value); + } + + void SetCycleCompare(uint32_t value) + { + if (value <= _cycleTicks) + { + value = 1; + } + else + { + value -= _cycleTicks; + } + timer1_write(value); + } + + uint32_t GetCycleCount() const + { + return _cycleTicks; + } + + + void StartCycle() + { + _cycleTicks = 0; + _currentChannel = 0; + } + + int8_t getCurrentChannel() const + { + return _currentChannel; + } + + void nextChannel() + { + _currentChannel++; + } + + void setEndOfCycle() + { + _currentChannel = -1; + } + + bool isEndOfCycle() const + { + return (_currentChannel == -1); + } + + ServoTimerSequence timerId() const + { + return ServoTimerSequence_Timer1; + } + +private: + volatile uint32_t _cycleTicks; + volatile int8_t _currentChannel; +}; + +#endif + + + + diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index 389918be4d..ad1a4c7be6 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -43,6 +43,7 @@ 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() \ @@ -51,6 +52,23 @@ typedef void (*int_handler_t)(void*); #define ETS_INTR_UNLOCK() \ ets_intr_unlock() +inline uint32_t ETS_INTR_ENABLED(void) +{ + uint32_t enabled; + __asm__ __volatile__("esync; rsr %0,intenable":"=a" (enabled)); + return enabled; +} + +inline uint32_t ETS_INTR_PENDING(void) +{ + uint32_t pending; + __asm__ __volatile__("esync; rsr %0,interrupt":"=a" (pending)); + return pending; +} + +#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)) @@ -78,6 +96,12 @@ typedef void (*int_handler_t)(void*); #define ETS_UART_INTR_DISABLE() \ ETS_INTR_DISABLE(ETS_UART_INUM) +#define ETS_CCOMPARE0_ENABLE() \ + ETS_INTR_ENABLE(ETS_CCOMPARE0_INUM) + +#define ETS_CCOMPARE0_DISABLE() \ + ETS_INTR_DISABLE(ETS_CCOMPARE0_INUM) + #define ETS_FRC1_INTR_ENABLE() \ ETS_INTR_ENABLE(ETS_FRC_TIMER1_INUM) From c66919e36fd717d21aff52d7bc84df248bc61002 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sat, 30 May 2015 15:10:56 +0300 Subject: [PATCH 47/77] add higher I2C freqs for 160MHz core clock --- .../esp8266/cores/esp8266/core_esp8266_si2c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c index 1593bb8597..d825c4445b 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_si2c.c @@ -47,14 +47,16 @@ void twi_setClock(unsigned int freq){ if(freq <= 100000) twi_dcount = 19;//about 100KHz else if(freq <= 200000) twi_dcount = 8;//about 200KHz else if(freq <= 300000) twi_dcount = 3;//about 300KHz - else if(freq <= 400000) twi_dcount = 1;//about 370KHz - else twi_dcount = 1;//about 450KHz + else if(freq <= 400000) twi_dcount = 1;//about 400KHz + else twi_dcount = 1;//about 400KHz #else if(freq <= 100000) twi_dcount = 32;//about 100KHz else if(freq <= 200000) twi_dcount = 14;//about 200KHz else if(freq <= 300000) twi_dcount = 8;//about 300KHz - else if(freq <= 400000) twi_dcount = 5;//about 370KHz - else twi_dcount = 2;//about 450KHz + else if(freq <= 400000) twi_dcount = 5;//about 400KHz + else if(freq <= 500000) twi_dcount = 3;//about 500KHz + else if(freq <= 600000) twi_dcount = 2;//about 600KHz + else twi_dcount = 1;//about 700KHz #endif } From 790606adb2488f7a01e9a2077aa5be7e1a57605e Mon Sep 17 00:00:00 2001 From: Wietse van Buitenen Date: Sun, 31 May 2015 13:02:13 +0200 Subject: [PATCH 48/77] Use correct variable for sendNTPpacket --- .../libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino index a3fdaf49c3..4176c511b2 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino @@ -72,7 +72,7 @@ void loop() //get a random server from the pool WiFi.hostByName(ntpServerName, timeServerIP); - sendNTPpacket(timeServer); // send an NTP packet to a time server + sendNTPpacket(timeServerIP); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); From 219be7d4c3141d6f8974a0dba257c8e8f479a907 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 1 Jun 2015 02:08:48 +0300 Subject: [PATCH 49/77] reading eboot commands via RTC, flash erase/copy --- .../esp8266/bootloaders/eboot/Makefile | 3 +- .../esp8266/bootloaders/eboot/eboot.c | 94 +++++++++++++++++- .../esp8266/bootloaders/eboot/eboot.elf | Bin 5209 -> 11738 bytes .../esp8266/bootloaders/eboot/eboot.h | 3 + .../esp8266/bootloaders/eboot/eboot_command.c | 47 +++++++++ .../esp8266/bootloaders/eboot/eboot_command.h | 29 ++++++ 6 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile index 32e325f34b..8aaac9cabb 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile @@ -5,6 +5,7 @@ TARGET_DIR := ./ TARGET_OBJ_FILES := \ eboot.o \ + eboot_command.o \ TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) @@ -17,7 +18,7 @@ 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 +CFLAGS += -Os -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 diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c index e39375d2d2..86a27eff04 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c @@ -10,6 +10,7 @@ #include #include #include "eboot.h" +#include "eboot_command.h" extern void* flashchip; #define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0); @@ -71,9 +72,100 @@ int load_app_from_flash_raw(const uint32_t flash_addr) } + +int erase(const uint32_t start, const uint32_t size) +{ + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { + return 1; + } + + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + uint32_t current_sector = start / FLASH_SECTOR_SIZE; + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; + const uint32_t end = current_sector + sector_count; + + for (; current_sector < end && (current_sector & (sectors_per_block-1)); + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 2; + } + } + + for (;current_sector + sectors_per_block <= end; + current_sector += sectors_per_block, + sector_count -= sectors_per_block) { + if (SPIEraseBlock(current_sector / sectors_per_block)) { + return 3; + } + } + + for (; current_sector < end; + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 4; + } + } + + return 0; +} + +int copy_raw(const uint32_t src_addr, + const uint32_t dst_addr, + const uint32_t size) +{ + // require regions to be aligned + if (src_addr & 0xfff != 0 || + dst_addr & 0xfff != 0) { + return 1; + } + + if (erase(dst_addr, size)) { + return 2; + } + + const uint32_t buffer_size = 4096; + uint8_t buffer[buffer_size]; + + const uint32_t end = src_addr + size; + uint32_t saddr = src_addr; + uint32_t daddr = dst_addr; + uint32_t left = size; + while (saddr < end) { + uint32_t will_copy = (left < buffer_size) ? left : buffer_size; + if (SPIRead(saddr, buffer, will_copy)) { + return 3; + } + if (SPIWrite(daddr, buffer, will_copy)) { + return 4; + } + saddr += will_copy; + daddr += will_copy; + left -= will_copy; + } + + return 0; +} + + + void main() { - int res = load_app_from_flash_raw(0); + int res; + struct eboot_command cmd; + + eboot_command_read(&cmd); + + if (cmd.action == ACTION_COPY_RAW) { + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); + if (res == 0) { + cmd.action = ACTION_LOAD_APP; + } + } + + if (cmd.action == ACTION_LOAD_APP) { + res = load_app_from_flash_raw(0); + } + if (res) { ets_putc('\n'); ets_putc('#'); diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf index b2381a4098690e025f33c25290a14715934882fe..b7908dfd67b803008b425ac3b0d07ce5d7dd279b 100755 GIT binary patch literal 11738 zcmb_i3v^t?d7im@ceN|69;>x%89%g=t;jak!^Q=f+E|h;V;O^uBtK|vmX)-YWTahr zcjX5aNVs4i7_i}_JmN%#Q%+9^%?Xf}a0r_bMDOl_~xH~{(olf+`Bv6yl%CWQs~PN*9&syZ;Kk1pgvWB!X?BK5fW}O zPXt7P(!Ze_OsLtG_a8<7X;Fi~U5fsByKURFe-8YGF6z8R)Qr8D9#)8>>2$hm=2fC0 zT?l@yX!t>kXb`}x11)mI4UmqUxmYwjJL{M!ioyRXJvxHA_}FW29lCqbX~Tb8#p^|{ zKI(hw?5&^el<%jH3USid)Zr=rdHQ$$1*hNl?+=RV{N>Vr+gW)wAb(E4xsMuuny#03 zpI$qs@xRkmKgcgXoo+mxUNEO>iSe=_)a<$n=);^}#T1*i8LLiiVY+`_-?WtW(d zu8_W}6;B*-iPezL^gdPXfAi4sN6*~)>CWO~b@^kW_}JL1<-SEHjkf}4rN21mT%`PX z`sj(q1wVQ1RO5f1LJ!q``A@Wee&37}|MC2^qoF069{XZH!*+CTqkK{MxcFqjJ12_% z=Y?|?{y7RyH37eD%x|oA34eu$el6aQR{kdMqT}Un2F}RhV@2>lz=zjfee|tE49aQ4 z_f%a)=y&p@%Rf8kogLM#2I<*-ROk1uxT{t^$liNaoNH1tzkJBz@2owwZ^!8!CvLd&=)AJ3Cj7|6Ei*OwEr+(c;Q6hab zB-R*pOG2oZ8mm7{uU+XcJrqxSa)l62!^_({j*Ntc-Oqa5BfIMc22x`cfrF3LO47prxG#wcl`pAg5ZvQ;(U1UWV@|Pk;WGj4Kv^8CRT^efi zwZ&MlZpW(Y%&RIcyZ?h~zx#Z;-k|*BY#`Z-O*AIST4b6V*K~ldI)`F(U6Z@8in1uJ?ew6{LkNQdoja4}|x) z?q%DB7F6_nR@Crt23u!(K_4&(y3cL;z~mQ>NK_%*ytwD2SkqR)L8&k!@&KlwnCLtC z=W*{rn|jnUZT|b~+)28Ow9C^^x;)BKxW2^(6}Nza zy~+gQO3aYRWz_|79*da_)-*u<6%fl{B}zR5<>5{! z@}EH=gCuzse2hYtFfPWSErkQ|q>##T8zhCv0U=ki1J2;WfleV;k$VQWdJL?Fm4FZZ z%Gs2^g1fjBMZsPavVzeu4s8f9Kyn_t`~|2$57`AhU_S#DydASX&yA-b1XEkuREm--Y^046{(qwv1C=QC+LnjsW4Yx2jZ(0S*U?43paVO} zGSQav39{X|1FH$Xh3uWUr!9klCn^6n3OP)BuYt1MzLl^sYHO(7$3e}2lYu0S{3Y3? zWVeyMjqGNyMRgzoFcdgOPxe#(SC9vv$B3B7&%hvuu3_Qf;F!b{P;G+BAx30G$pOgY z=$rD7WxI|=?m8&xdMPJ$0`|mIQq!Mjj}Pj-Ode);g^4I8?ZcG-eFw;kI{T54N4U~l zhsJK1(TGjyGU!gj+)PU46NKImc9saXKsyK{kAp?;@^TTp))qZyi45-?5&Sb-cG8v& z)rpc0TV^#A!KvW)!_-F>hMkMql@M~ul`I8uBYGzq0W7-+K9~jcWC7ZQq98(wQX71^ zS@sYC`2=w8D1a#QAy%fJLPpaTGNEQ6g&fI5Q;spyyIG;&lYWFp)-PbU3eg>gwZ{pmGjcczb%-X~aYfCn) zEm>{yt~aQ6s~ytJWCdug$3H@ri|YOS;uV`=%)wEF_>GHyZKLYC>rusmFkaazX8Nd6SYru+tk zEWZL}sGutee=Amk=0YlA)MOR?xeV;o8$eV+$1%>KbS-B~;6r$`6J62)F5*IyeHRf> zXtESCAS(-kd9H#P1skUYWYIJXd9KLIyCTo!#j2btTm_fs{b^oH5J|G-1(*RrnU_bo zgxr�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 diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h index b77f8f45a6..973c616a80 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h @@ -14,6 +14,9 @@ int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); int SPIWrite(uint32_t addr, void *src, size_t size); + +#define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 #define APP_START_OFFSET 0x1000 typedef struct { diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c new file mode 100644 index 0000000000..1e9cbed2cf --- /dev/null +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c @@ -0,0 +1,47 @@ +#include "eboot_command.h" + +uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length) +{ + uint32_t i; + bool bit; + uint8_t c; + + while (length--) { + c = *data++; + for (i = 0x80; i > 0; i >>= 1) { + bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + } + return crc; +} + +uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) +{ + return crc_update(0xffffffff, (const uint8_t*) cmd, + offsetof(struct eboot_command, crc32)); +} + +void eboot_command_read(struct eboot_command* cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + uint32_t* dst = (uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + dst[i] = RTC_MEM[i]; + } + + uint32_t crc32 = eboot_command_calculate_crc32(cmd); + if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC || + cmd->crc32 != crc32) { + + cmd->action = ACTION_LOAD_APP; + cmd->args[0] = 0; + } +} + diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h new file mode 100644 index 0000000000..aa0fc11bbd --- /dev/null +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h @@ -0,0 +1,29 @@ +#ifndef EBOOT_COMMAND_H +#define EBOOT_COMMAND_H + +#include +#include +#include + +#define RTC_MEM ((volatile uint32_t*)0x60001200) + +enum action_t { + ACTION_COPY_RAW = 0x00000001, + ACTION_LOAD_APP = 0xffffffff +}; + +#define EBOOT_MAGIC 0xeb001000 +#define EBOOT_MAGIC_MASK 0xfffff000 + +struct eboot_command { + uint32_t magic; + enum action_t action; + uint32_t args[29]; + uint32_t crc32; +}; + + +void eboot_command_read(struct eboot_command* cmd); + + +#endif //EBOOT_COMMAND_H From 5dbc9ef8b1ba021712b6d50f39629937b9df6991 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 1 Jun 2015 02:09:46 +0300 Subject: [PATCH 50/77] Remove .bss from sketch size calculation --- hardware/esp8266com/esp8266/platform.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/platform.txt b/hardware/esp8266com/esp8266/platform.txt index f0796310b0..2695115c28 100644 --- a/hardware/esp8266com/esp8266/platform.txt +++ b/hardware/esp8266com/esp8266/platform.txt @@ -78,7 +78,7 @@ recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|\.bss|)\s+([0-9]+).* +recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|)\s+([0-9]+).* recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).* #recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* From 5b13b9527fdd99fa12bd8fc387f73cba84adf54d Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 1 Jun 2015 03:05:34 +0300 Subject: [PATCH 51/77] Fix missing slash --- .../esp8266/cores/esp8266/core_esp8266_timer.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c index 08b971c58c..819c5f9901 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_timer.c @@ -20,18 +20,11 @@ */ #include "wiring_private.h" #include "pins_arduino.h" -#ifdef __cplusplus -extern "C" { -#endif #include "c_types.h" #include "ets_sys.h" -#ifdef __cplusplus -} -#endif - -/ ------------------------------------------------------------------ - +// ------------------------------------------------------------------ - // timer 1 static volatile timercallback timer1_user_cb = NULL; From ae055f9cb3ab8684a3e71266c569c5984168e084 Mon Sep 17 00:00:00 2001 From: John Doe Date: Mon, 1 Jun 2015 03:27:21 +0300 Subject: [PATCH 52/77] add RTC registers --- docs/rgisters_dump.txt | 18 +++++++++--------- .../esp8266/cores/esp8266/esp8266_peri.h | 11 +++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/rgisters_dump.txt b/docs/rgisters_dump.txt index 957a9e1305..8143dba63a 100644 --- a/docs/rgisters_dump.txt +++ b/docs/rgisters_dump.txt @@ -547,21 +547,21 @@ | 10987654321098765432109876543210 | | | | ===========|==================================|============|============|======| 0x60000700 | 00000000000110011100000001101010 | 0x0019C06A | 1687658 | Àj | -0x60000704 | 00000000001111100011111111111111 | 0x003E3FFF | 4079615 | >?ÿ | +0x60000704 | 00000000001111100011111111111111 | 0x003E3FFF | 4079615 | >?ÿ | RTCSV 0x60000708 | 00000000001000000000000000000000 | 0x00200000 | 2097152 | | 0x6000070C | 00000000000000011110000000101000 | 0x0001E028 | 122920 | à( | 0x60000710 | 11111110000000000000000000000000 | 0xFE000000 | 4261412864 | þ | 0x60000714 | 00000000000000000000000000000010 | 0x00000002 | 2 | | 0x60000718 | 00000000000000000000100000001000 | 0x00000808 | 2056 | | -0x6000071C | 00000000010100001010011111000011 | 0x0050A7C3 | 5285827 | P§Ã | -0x60000720 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000724 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000728 | 00000000000000000000000000000101 | 0x00000005 | 5 | | +0x6000071C | 00000000010100001010011111000011 | 0x0050A7C3 | 5285827 | P§Ã | RTCCV +0x60000720 | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCIS +0x60000724 | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCIC +0x60000728 | 00000000000000000000000000000101 | 0x00000005 | 5 | | RTCIE 0x6000072C | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000730 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000734 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000738 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x6000073C | 00000000000000000000000000000000 | 0x00000000 | 0 | | +0x60000730 | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCS0 +0x60000734 | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCS1 +0x60000738 | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCS2 +0x6000073C | 00000000000000000000000000000000 | 0x00000000 | 0 | | RTCS3 0x60000740 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x60000744 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x60000748 | 00100000001100000010000000100000 | 0x20302020 | 540024864 | 0 | diff --git a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h index e2998cf540..f6be56756d 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h @@ -148,6 +148,17 @@ extern uint8_t esp8266_gpioToFn[16]; #define TCPD 2 //Prescale Devider (2bit) 0:1(12.5ns/tick), 1:16(0.2us/tick), 2/3:256(3.2us/tick) #define TCIT 0 //Interrupt Type 0:edge, 1:level +//RTC Registers +#define RTCMEM(i) ESP8266_REG(0x1100 + (((i) & 0xFF) * 4)) //RTC RAM 768 bytes, 192 registers +#define RTCSV ESP8266_REG(0x704) //RTC SLEEP COUNTER Target Value +#define RTCCV ESP8266_REG(0x71C) //RTC SLEEP COUNTER Value +#define RTCIS ESP8266_REG(0x720) //RTC INT Status +#define RTCIC ESP8266_REG(0x724) //RTC INT Clear +#define RTCIE ESP8266_REG(0x728) //RTC INT Enable +#define RTCS0 ESP8266_REG(0x730) //RTC SCRATCH 0 +#define RTCS1 ESP8266_REG(0x734) //RTC SCRATCH 1 +#define RTCS2 ESP8266_REG(0x738) //RTC SCRATCH 2 +#define RTCS3 ESP8266_REG(0x73C) //RTC SCRATCH 3 //UART SWAP Register #define USWAP ESP8266_DREG(0x28) From 93e6be1919cfcf541d4325392b6f053b691a91f6 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 1 Jun 2015 13:33:56 +0300 Subject: [PATCH 53/77] Fix uboot startup --- .../esp8266/bootloaders/eboot/Makefile | 2 +- .../esp8266/bootloaders/eboot/eboot.c | 2 +- .../esp8266/bootloaders/eboot/eboot.elf | Bin 11738 -> 9816 bytes .../esp8266/bootloaders/eboot/eboot.ld | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile index 8aaac9cabb..cd9e141431 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile @@ -18,7 +18,7 @@ OBJDUMP := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-objdump CFLAGS += -std=gnu99 -CFLAGS += -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals +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 diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c index 86a27eff04..b3193e299a 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c @@ -150,7 +150,7 @@ int copy_raw(const uint32_t src_addr, void main() { - int res; + int res = 9; struct eboot_command cmd; eboot_command_read(&cmd); diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf index b7908dfd67b803008b425ac3b0d07ce5d7dd279b..0637a05253c2b3f61f91954695e5fd4b116cadc6 100755 GIT binary patch literal 9816 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 literal 11738 zcmb_i3v^t?d7im@ceN|69;>x%89%g=t;jak!^Q=f+E|h;V;O^uBtK|vmX)-YWTahr zcjX5aNVs4i7_i}_JmN%#Q%+9^%?Xf}a0r_bMDOl_~xH~{(olf+`Bv6yl%CWQs~PN*9&syZ;Kk1pgvWB!X?BK5fW}O zPXt7P(!Ze_OsLtG_a8<7X;Fi~U5fsByKURFe-8YGF6z8R)Qr8D9#)8>>2$hm=2fC0 zT?l@yX!t>kXb`}x11)mI4UmqUxmYwjJL{M!ioyRXJvxHA_}FW29lCqbX~Tb8#p^|{ zKI(hw?5&^el<%jH3USid)Zr=rdHQ$$1*hNl?+=RV{N>Vr+gW)wAb(E4xsMuuny#03 zpI$qs@xRkmKgcgXoo+mxUNEO>iSe=_)a<$n=);^}#T1*i8LLiiVY+`_-?WtW(d zu8_W}6;B*-iPezL^gdPXfAi4sN6*~)>CWO~b@^kW_}JL1<-SEHjkf}4rN21mT%`PX z`sj(q1wVQ1RO5f1LJ!q``A@Wee&37}|MC2^qoF069{XZH!*+CTqkK{MxcFqjJ12_% z=Y?|?{y7RyH37eD%x|oA34eu$el6aQR{kdMqT}Un2F}RhV@2>lz=zjfee|tE49aQ4 z_f%a)=y&p@%Rf8kogLM#2I<*-ROk1uxT{t^$liNaoNH1tzkJBz@2owwZ^!8!CvLd&=)AJ3Cj7|6Ei*OwEr+(c;Q6hab zB-R*pOG2oZ8mm7{uU+XcJrqxSa)l62!^_({j*Ntc-Oqa5BfIMc22x`cfrF3LO47prxG#wcl`pAg5ZvQ;(U1UWV@|Pk;WGj4Kv^8CRT^efi zwZ&MlZpW(Y%&RIcyZ?h~zx#Z;-k|*BY#`Z-O*AIST4b6V*K~ldI)`F(U6Z@8in1uJ?ew6{LkNQdoja4}|x) z?q%DB7F6_nR@Crt23u!(K_4&(y3cL;z~mQ>NK_%*ytwD2SkqR)L8&k!@&KlwnCLtC z=W*{rn|jnUZT|b~+)28Ow9C^^x;)BKxW2^(6}Nza zy~+gQO3aYRWz_|79*da_)-*u<6%fl{B}zR5<>5{! z@}EH=gCuzse2hYtFfPWSErkQ|q>##T8zhCv0U=ki1J2;WfleV;k$VQWdJL?Fm4FZZ z%Gs2^g1fjBMZsPavVzeu4s8f9Kyn_t`~|2$57`AhU_S#DydASX&yA-b1XEkuREm--Y^046{(qwv1C=QC+LnjsW4Yx2jZ(0S*U?43paVO} zGSQav39{X|1FH$Xh3uWUr!9klCn^6n3OP)BuYt1MzLl^sYHO(7$3e}2lYu0S{3Y3? zWVeyMjqGNyMRgzoFcdgOPxe#(SC9vv$B3B7&%hvuu3_Qf;F!b{P;G+BAx30G$pOgY z=$rD7WxI|=?m8&xdMPJ$0`|mIQq!Mjj}Pj-Ode);g^4I8?ZcG-eFw;kI{T54N4U~l zhsJK1(TGjyGU!gj+)PU46NKImc9saXKsyK{kAp?;@^TTp))qZyi45-?5&Sb-cG8v& z)rpc0TV^#A!KvW)!_-F>hMkMql@M~ul`I8uBYGzq0W7-+K9~jcWC7ZQq98(wQX71^ zS@sYC`2=w8D1a#QAy%fJLPpaTGNEQ6g&fI5Q;spyyIG;&lYWFp)-PbU3eg>gwZ{pmGjcczb%-X~aYfCn) zEm>{yt~aQ6s~ytJWCdug$3H@ri|YOS;uV`=%)wEF_>GHyZKLYC>rusmFkaazX8Nd6SYru+tk zEWZL}sGutee=Amk=0YlA)MOR?xeV;o8$eV+$1%>KbS-B~;6r$`6J62)F5*IyeHRf> zXtESCAS(-kd9H#P1skUYWYIJXd9KLIyCTo!#j2btTm_fs{b^oH5J|G-1(*RrnU_bo zgxr�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 z Date: Mon, 1 Jun 2015 15:50:51 +0300 Subject: [PATCH 54/77] Update README.md Update travis link [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b6c1bf224..008ddcd3e6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Arduino-compatible IDE with ESP8266 support =========================================== -![Linux build status](http://img.shields.io/travis/igrr/Arduino.svg) +[![Linux build status](http://img.shields.io/travis/igrr/Arduino.svg)](https://travis-ci.org/igrr/Arduino) [![Donate](http://img.shields.io/paypal/donate.png?color=yellow)](https://www.paypal.com/webscr?cmd=_s-xclick&hosted_button_id=4M56YCWV6PX66) This project brings support for ESP8266 chip to the Arduino environment. ESP8266WiFi library bundled with this project has the same interface as the WiFi Shield library, making it easy to re-use existing code and libraries. From a6e8697ae15cfcb2f4767412c94645a57b183229 Mon Sep 17 00:00:00 2001 From: John Doe Date: Tue, 2 Jun 2015 00:11:20 +0300 Subject: [PATCH 55/77] register and clock changes --- docs/rgisters_dump.txt | 17 ++-- .../esp8266/cores/esp8266/HardwareSerial.cpp | 6 +- .../cores/esp8266/core_esp8266_wiring_pwm.c | 2 +- .../esp8266/cores/esp8266/esp8266_peri.h | 79 ++++++++++++------- .../esp8266com/esp8266/libraries/SPI/SPI.cpp | 6 +- .../esp8266com/esp8266/libraries/SPI/SPI.h | 2 - .../esp8266/tools/sdk/include/ets_sys.h | 4 +- 7 files changed, 67 insertions(+), 49 deletions(-) diff --git a/docs/rgisters_dump.txt b/docs/rgisters_dump.txt index 8143dba63a..0039ac8b93 100644 --- a/docs/rgisters_dump.txt +++ b/docs/rgisters_dump.txt @@ -5,14 +5,14 @@ 0x3FF00000 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00004 | 00000000000000000000000000000101 | 0x00000005 | 5 | | TEIE 0x3FF00008 | 00000000000000000000100000001111 | 0x0000080F | 2063 | . | -0x3FF0000C | 00000100000000000000000100000010 | 0x04000102 | 67109122 | | +0x3FF0000C | 00000100000000000000000100000010 | 0x04000102 | 67109122 | | SPIRDY 0x3FF00010 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x3FF00014 | 00000000000000000000000000000000 | 0x00000000 | 0 | | +0x3FF00014 | 00000000000000000000000000000000 | 0x00000000 | 0 | | CPU2X 0x3FF00018 | 11111111111111110000000011111111 | 0xFFFF00FF | 4294902015 | .. . | 0x3FF0001C | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00020 | 00000000000000000000000000010000 | 0x00000010 | 16 | . | SPIIR 0x3FF00024 | 00000000000000000000000000011010 | 0x0000001A | 26 | . | -0x3FF00028 | 00000000000000000000000000000000 | 0x00000000 | 0 | | USWAP +0x3FF00028 | 00000000000000000000000000000000 | 0x00000000 | 0 | | IOSWAP 0x3FF0002C | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00030 | 00000000000000000100000001000000 | 0x00004040 | 16448 | @@ | 0x3FF00034 | 00000000000000000000000000000000 | 0x00000000 | 0 | | @@ -22,9 +22,9 @@ 0x3FF00044 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00048 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF0004C | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x3FF00050 | 10011101111011100000000000000000 | 0x9DEE0000 | 2649620480 | .. | -0x3FF00054 | 00000010000000001001110011000010 | 0x02009CC2 | 33594562 | .. | -0x3FF00058 | 00000000000000001010000000000000 | 0x0000A000 | 40960 | . | +0x3FF00050 | 10011101111011100000000000000000 | 0x9DEE0000 | 2649620480 | .. | MAC0 +0x3FF00054 | 00000010000000001001110011000010 | 0x02009CC2 | 33594562 | .. | MAC1 +0x3FF00058 | 00000000000000001010000000000000 | 0x0000A000 | 40960 | . | CHIPID 0x3FF0005C | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00060 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x3FF00064 | 00000000000000000000000000000000 | 0x00000000 | 0 | | @@ -687,14 +687,13 @@ 0x60000908 | 00000000000000000000000000001011 | 0x0000000B | 11 | | 0x6000090C | 00000000000000111001000001110010 | 0x00039072 | 233586 | r | 0x60000910 | 00000000000000000000000000000000 | 0x00000000 | 0 | | -0x60000914 | 00000000000000000000000000000000 | 0x00000000 | 0 | | WDTRST +0x60000914 | 00000000000000000000000000000000 | 0x00000000 | 0 | | WDTFEED 0x60000918 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x6000091C | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x60000920 | 00000000000000000000000000111001 | 0x00000039 | 57 | 9 | 0x60000924 | 00000000000000000000000000001011 | 0x0000000B | 11 | | 0x60000928 | 00000000000000000000000000001011 | 0x0000000B | 11 | | -0x6000092C | 00000111100111110000110111101010 | 0x079F0DEA | 127864298 |Ÿ -ê| +0x6000092C | 00000111100111110000110111101010 | 0x079F0DEA | 127864298 | Ÿê | 0x60000930 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x60000934 | 00000000000000000000000000000000 | 0x00000000 | 0 | | 0x60000938 | 00000000000000000000000000000000 | 0x00000000 | 0 | | diff --git a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp index ac56919ca7..970b16c50a 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/HardwareSerial.cpp @@ -262,7 +262,7 @@ void uart_set_baudrate(uart_t* uart, int baud_rate) { if(uart == 0) return; uart->baud_rate = baud_rate; - USD(uart->uart_nr) = (80000000UL / uart->baud_rate); + USD(uart->uart_nr) = (ESP8266_CLOCK / uart->baud_rate); } int uart_get_baudrate(uart_t* uart) { @@ -359,7 +359,7 @@ void uart_swap(uart_t* uart) { if(uart->txPin == 1 && uart->rxPin == 3) { pinMode(15, FUNCTION_4); //TX pinMode(13, FUNCTION_4); //RX - USWAP |= (1 << USWAP0); + IOSWAP |= (1 << IOSWAPU0); pinMode(1, INPUT); //TX pinMode(3, INPUT); //RX uart->rxPin = 13; @@ -367,7 +367,7 @@ void uart_swap(uart_t* uart) { } else { pinMode(1, SPECIAL); //TX pinMode(3, SPECIAL); //RX - USWAP &= ~(1 << USWAP0); + IOSWAP &= ~(1 << IOSWAPU0); pinMode(15, INPUT); //TX pinMode(13, INPUT); //RX uart->rxPin = 3; diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c index c74f76bc3f..7a70f5d276 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c @@ -83,7 +83,7 @@ void prep_pwm_steps(){ pwm_steps_len = pwm_temp_steps_len; ets_memcpy(pwm_steps, pwm_temp_steps, (pwm_temp_steps_len + 1) * 2); ets_memcpy(pwm_steps_mask, pwm_temp_masks, pwm_temp_steps_len * 4); - pwm_multiplier = F_CPU/(PWMRANGE * pwm_freq); + pwm_multiplier = ESP8266_CLOCK/(PWMRANGE * pwm_freq); ETS_FRC1_INTR_ENABLE(); } diff --git a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h index f6be56756d..d7723c3ad4 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h @@ -25,6 +25,15 @@ #define ESP8266_REG(addr) *((volatile uint32_t *)(0x60000000+(addr))) #define ESP8266_DREG(addr) *((volatile uint32_t *)(0x3FF00000+(addr))) +#define ESP8266_CLOCK 80000000UL + +//CPU Register +#define CPU2X ESP8266_DREG(0x14) //when bit 0 is set, F_CPU = 160MHz + +//OTP Registers +#define MAC0 ESP8266_DREG(0x50) +#define MAC1 ESP8266_DREG(0x54) +#define CHIPID ESP8266_DREG(0x58) //GPIO (0-15) Control Registers #define GPO ESP8266_REG(0x300) //GPIO_OUT R/W (Output Level) @@ -149,20 +158,26 @@ extern uint8_t esp8266_gpioToFn[16]; #define TCIT 0 //Interrupt Type 0:edge, 1:level //RTC Registers -#define RTCMEM(i) ESP8266_REG(0x1100 + (((i) & 0xFF) * 4)) //RTC RAM 768 bytes, 192 registers #define RTCSV ESP8266_REG(0x704) //RTC SLEEP COUNTER Target Value #define RTCCV ESP8266_REG(0x71C) //RTC SLEEP COUNTER Value #define RTCIS ESP8266_REG(0x720) //RTC INT Status #define RTCIC ESP8266_REG(0x724) //RTC INT Clear #define RTCIE ESP8266_REG(0x728) //RTC INT Enable -#define RTCS0 ESP8266_REG(0x730) //RTC SCRATCH 0 -#define RTCS1 ESP8266_REG(0x734) //RTC SCRATCH 1 -#define RTCS2 ESP8266_REG(0x738) //RTC SCRATCH 2 -#define RTCS3 ESP8266_REG(0x73C) //RTC SCRATCH 3 -//UART SWAP Register -#define USWAP ESP8266_DREG(0x28) -#define USWAP0 2 //BIT 2 swaps UART 0 +//IO SWAP Register +#define IOSWAP ESP8266_DREG(0x28) +#define IOSWAPU 0 //Swaps UART +#define IOSWAPS 1 //Swaps SPI +#define IOSWAPU0 2 //Swaps UART 0 pins (u0rxd <-> u0cts), (u0txd <-> u0rts) +#define IOSWAPU1 3 //Swaps UART 1 pins (u1rxd <-> u1cts), (u1txd <-> u1rts) +#define IOSWAPHS 5 //Sets HSPI with higher prio +#define IOSWAP2HS 6 //Sets Two SPI Masters on HSPI +#define IOSWAP2CS 7 //Sets Two SPI Masters on CSPI + +//UART INT Status +#define UIS ESP8266_DREG(0x20020) +#define UIS0 0 +#define UIS1 2 //UART 0 Registers #define U0F ESP8266_REG(0x000) //UART FIFO @@ -227,9 +242,9 @@ extern uint8_t esp8266_gpioToFn[16]; #define UIFF 0 //RX FIFO Full //UART STATUS Registers Bits -#define USTX 31 //TX PIN Level -#define USRTS 30 //RTS PIN Level -#define USDTR 39 //DTR PIN Level +#define USTX 31 //TX PIN Level +#define USRTS 30 //RTS PIN Level +#define USDTR 39 //DTR PIN Level #define USTXC 16 //TX FIFO COUNT (8bit) #define USRXD 15 //RX PIN Level #define USCTS 14 //CTS PIN Level @@ -237,35 +252,39 @@ extern uint8_t esp8266_gpioToFn[16]; #define USRXC 0 //RX FIFO COUNT (8bit) //UART CONF0 Registers Bits -#define UCDTRI 24 //Invert DTR -#define UCRTSI 23 //Invert RTS -#define UCTXI 22 //Invert TX -#define UCDSRI 21 //Invert DSR -#define UCCTSI 20 //Invert CTS -#define UCRXI 19 //Invert RX +#define UCDTRI 24 //Invert DTR +#define UCRTSI 23 //Invert RTS +#define UCTXI 22 //Invert TX +#define UCDSRI 21 //Invert DSR +#define UCCTSI 20 //Invert CTS +#define UCRXI 19 //Invert RX #define UCTXRST 18 //Reset TX FIFO #define UCRXRST 17 //Reset RX FIFO #define UCTXHFE 15 //TX Harware Flow Enable -#define UCLBE 14 //LoopBack Enable -#define UCBRK 8 //Send Break on the TX line +#define UCLBE 14 //LoopBack Enable +#define UCBRK 8 //Send Break on the TX line #define UCSWDTR 7 //Set this bit to assert DTR #define UCSWRTS 6 //Set this bit to assert RTS -#define UCSBN 4 //StopBits Count (2bit) 0:disable, 1:1bit, 2:1.5bit, 3:2bit -#define UCBN 2 //DataBits Count (2bin) 0:5bit, 1:6bit, 2:7bit, 3:8bit -#define UCPAE 1 //Parity Enable -#define UCPA 0 //Parity 0:even, 1:odd +#define UCSBN 4 //StopBits Count (2bit) 0:disable, 1:1bit, 2:1.5bit, 3:2bit +#define UCBN 2 //DataBits Count (2bin) 0:5bit, 1:6bit, 2:7bit, 3:8bit +#define UCPAE 1 //Parity Enable +#define UCPA 0 //Parity 0:even, 1:odd //UART CONF1 Registers Bits -#define UCTOE 31 //RX TimeOut Enable -#define UCTOT 24 //RX TimeOut Treshold (7bit) +#define UCTOE 31 //RX TimeOut Enable +#define UCTOT 24 //RX TimeOut Treshold (7bit) #define UCRXHFE 23 //RX Harware Flow Enable #define UCRXHFT 16 //RX Harware Flow Treshold (7bit) -#define UCFET 8 //TX FIFO Empty Treshold (7bit) -#define UCFFT 0 //RX FIFO Full Treshold (7bit) +#define UCFET 8 //TX FIFO Empty Treshold (7bit) +#define UCFFT 0 //RX FIFO Full Treshold (7bit) + +//WDT Feed (the dog) Register +#define WDTFEED ESP8266_REG(0x914) +#define WDT_FEED() (WDTFEED = 0x73) -//WDT Register used for UART -#define WDTRST ESP8266_REG(0x914) -#define WDT_RESET() (WDTRST = 0x73) +//SPI_READY +#define SPIRDY ESP8266_DREG(0x0C) +#define SPIBUSY 9 //wait SPI idle //SPI0 Registers (SPI0 is used for the flash) #define SPI0CMD ESP8266_REG(0x200) diff --git a/hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp b/hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp index 7d52528ef1..4e73021220 100644 --- a/hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp +++ b/hardware/esp8266com/esp8266/libraries/SPI/SPI.cpp @@ -121,14 +121,14 @@ void SPIClass::setBitOrder(uint8_t bitOrder) { * @return */ static uint32_t ClkRegToFreq(spiClk_t * reg) { - return (SPI_MAX_SPEED / ((reg->regPre + 1) * (reg->regN + 1))); + return (ESP8266_CLOCK / ((reg->regPre + 1) * (reg->regN + 1))); } void SPIClass::setFrequency(uint32_t freq) { static uint32_t lastSetFrequency = 0; static uint32_t lastSetRegister = 0; - if(freq >= SPI_MAX_SPEED) { + if(freq >= ESP8266_CLOCK) { setClockDivider(0x80000000); return; } @@ -164,7 +164,7 @@ void SPIClass::setFrequency(uint32_t freq) { reg.regN = calN; while(calPreVari++ <= 1) { // test different variants for Pre (we calculate in int so we miss the decimals, testing is the easyest and fastest way) - calPre = (((SPI_MAX_SPEED / (reg.regN + 1)) / freq) - 1) + calPreVari; + calPre = (((ESP8266_CLOCK / (reg.regN + 1)) / freq) - 1) + calPreVari; if(calPre > 0x1FFF) { reg.regPre = 0x1FFF; // 8191 } else if(calPre <= 0) { diff --git a/hardware/esp8266com/esp8266/libraries/SPI/SPI.h b/hardware/esp8266com/esp8266/libraries/SPI/SPI.h index 68d2a3dc6c..e67b5b0d58 100644 --- a/hardware/esp8266com/esp8266/libraries/SPI/SPI.h +++ b/hardware/esp8266com/esp8266/libraries/SPI/SPI.h @@ -45,8 +45,6 @@ #define SPI_CLOCK_DIV64 0x04fc1001 //250 KHz #endif -#define SPI_MAX_SPEED (80000000L) - const uint8_t SPI_MODE0 = 0x00; ///< CPOL: 0 CPHA: 0 const uint8_t SPI_MODE1 = 0x01; ///< CPOL: 0 CPHA: 1 const uint8_t SPI_MODE2 = 0x10; ///< CPOL: 1 CPHA: 0 diff --git a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h index ad1a4c7be6..8b118b3416 100644 --- a/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h +++ b/hardware/esp8266com/esp8266/tools/sdk/include/ets_sys.h @@ -39,11 +39,13 @@ typedef struct _ETSTIMER_ { typedef void (*int_handler_t)(void*); -#define ETS_SPI_INUM 2 +#define ETS_SPI_INUM 2 #define ETS_GPIO_INUM 4 #define ETS_UART_INUM 5 #define ETS_UART1_INUM 5 #define ETS_CCOMPARE0_INUM 6 +#define ETS_SOFT_INUM 7 +#define ETS_WDT_INUM 8 #define ETS_FRC_TIMER1_INUM 9 /* use edge*/ #define ETS_INTR_LOCK() \ From 2f157b80e63e66c123cb08f6d167076d6315d561 Mon Sep 17 00:00:00 2001 From: John Doe Date: Tue, 2 Jun 2015 01:11:08 +0300 Subject: [PATCH 56/77] add PWM Range control setting freq to 50, range to 20000 and writing between 700 and 2200 gives servo control for example --- hardware/esp8266com/esp8266/cores/esp8266/Arduino.h | 1 + .../esp8266/cores/esp8266/core_esp8266_wiring_pwm.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h index 3f67fdaead..138aea96b5 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Arduino.h @@ -188,6 +188,7 @@ int analogRead(uint8_t); void analogReference(uint8_t mode); void analogWrite(uint8_t, int); void analogWriteFreq(uint32_t freq); +void analogWriteRange(uint32_t range); unsigned long millis(void); unsigned long micros(void); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c index 7a70f5d276..d102f93d65 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring_pwm.c @@ -27,6 +27,7 @@ uint32_t pwm_mask = 0; uint16_t pwm_values[17] = {0,}; uint32_t pwm_freq = 1000; +uint32_t pwm_range = PWMRANGE; uint32_t pwm_multiplier = 0; uint16_t pwm_steps[17]; @@ -71,7 +72,7 @@ void prep_pwm_steps(){ for(i=0; i<17; i++){ if((pwm_mask & (1 << i)) != 0 && pwm_values[i] != 0) pwm_temp_steps[pwm_temp_steps_len++] = pwm_values[i]; } - pwm_temp_steps[pwm_temp_steps_len++] = PWMRANGE; + pwm_temp_steps[pwm_temp_steps_len++] = pwm_range; pwm_temp_steps_len = pwm_sort_array(pwm_temp_steps, pwm_temp_steps_len) - 1; for(i=0; i Date: Tue, 2 Jun 2015 01:13:15 +0300 Subject: [PATCH 57/77] spi clock does not depend on cpu clock --- hardware/esp8266com/esp8266/libraries/SPI/SPI.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/SPI/SPI.h b/hardware/esp8266com/esp8266/libraries/SPI/SPI.h index e67b5b0d58..141f30ef4b 100644 --- a/hardware/esp8266com/esp8266/libraries/SPI/SPI.h +++ b/hardware/esp8266com/esp8266/libraries/SPI/SPI.h @@ -28,7 +28,6 @@ // This defines are not representing the real Divider of the ESP8266 // the Defines match to an AVR Arduino on 16MHz for better compatibility -#if F_CPU == 80000000L #define SPI_CLOCK_DIV2 0x00101001 //8 MHz #define SPI_CLOCK_DIV4 0x00241001 //4 MHz #define SPI_CLOCK_DIV8 0x004c1001 //2 MHz @@ -36,14 +35,6 @@ #define SPI_CLOCK_DIV32 0x013c1001 //500 KHz #define SPI_CLOCK_DIV64 0x027c1001 //250 KHz #define SPI_CLOCK_DIV128 0x04fc1001 //125 KHz -#else -#define SPI_CLOCK_DIV2 0x00241001 //8 MHz -#define SPI_CLOCK_DIV4 0x004c1001 //4 MHz -#define SPI_CLOCK_DIV8 0x009c1001 //2 MHz -#define SPI_CLOCK_DIV16 0x013c1001 //1 MHz -#define SPI_CLOCK_DIV32 0x027c1001 //500 KHz -#define SPI_CLOCK_DIV64 0x04fc1001 //250 KHz -#endif const uint8_t SPI_MODE0 = 0x00; ///< CPOL: 0 CPHA: 0 const uint8_t SPI_MODE1 = 0x01; ///< CPOL: 0 CPHA: 1 From 7c67eca226e712b62c5ab0ee419141e36eeee9d7 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Tue, 2 Jun 2015 23:47:42 +0200 Subject: [PATCH 58/77] add images --- docs/ESP_improved_stability.png | Bin 0 -> 18458 bytes docs/ESP_min.png | Bin 0 -> 6617 bytes docs/ESP_to_serial.png | Bin 0 -> 30183 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/ESP_improved_stability.png create mode 100644 docs/ESP_min.png create mode 100644 docs/ESP_to_serial.png diff --git a/docs/ESP_improved_stability.png b/docs/ESP_improved_stability.png new file mode 100644 index 0000000000000000000000000000000000000000..74a7e01eeb22c808ca1e171367e09857fbeb8af4 GIT binary patch literal 18458 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 literal 0 HcmV?d00001 diff --git a/docs/ESP_min.png b/docs/ESP_min.png new file mode 100644 index 0000000000000000000000000000000000000000..59dc10c15aa4516fb5fc9f61c81ef51a68bd0881 GIT binary patch literal 6617 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

lwoHhj((xZhdXqF2z54lGm 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 Date: Tue, 2 Jun 2015 23:55:29 +0200 Subject: [PATCH 59/77] add new schematics to README.md --- README.md | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 008ddcd3e6..b2404b0b24 100644 --- a/README.md +++ b/README.md @@ -221,26 +221,43 @@ ESPxx Hardware - Reset is also named RSBT or REST (adding PullUp improves the stability of the Module) - GPIO2 is alternative TX for the boot loader mode -ESP01 example: - -![ESP01 connect](https://raw.githubusercontent.com/Links2004/Arduino/esp8266/docs/ESP01_connect.jpg) +###### esp to Serial +![ESP to Serial](https://raw.githubusercontent.com/Links2004/Arduino/esp8266/docs/ESP_to_serial.png) #### Minimal hardware Setup for Bootloading only #### ESPxx Hardware -| PIN | Resistor | Serial Adapter | -| ------------- | -------- | -------------- | -| VCC | | VCC (3.3V) | -| GND | | GND | -| TX or GPIO2 | | RX | -| RX | | TX | -| GPIO0 | | GND | +| PIN | Resistor | Serial Adapter | +| ------------- | -------- | --------------- | +| VCC | | VCC (3.3V) | +| GND | | GND | +| TX or GPIO2 | | RX | +| RX | | TX | +| GPIO0 | | GND | | Reset | | RTS* | -| GPIO15 | PullDown | | -| CH_PD | PullUp | | +| GPIO15 | PullDown | | +| CH_PD | PullUp | | * Note - if no RTS is used a manual power toggle is needed + +#### Minimal hardware Setup for running only #### + +ESPxx Hardware + +| PIN | Resistor | Power supply | +| ------------- | -------- | --------------- | +| VCC | | VCC (3.3V) | +| GND | | GND | +| GPIO0 | PullUp | | +| GPIO15 | PullDown | | +| CH_PD | PullUp | | + +###### minimal +![ESP min](https://raw.githubusercontent.com/Links2004/Arduino/esp8266/docs/ESP_min.png) + +###### improved stability +![ESP improved stability](https://raw.githubusercontent.com/Links2004/Arduino/esp8266/docs/ESP_improved_stability.png) ### Issues and support ### From 2af8acd9b22e1256ee6683b67eb0731e2b343d13 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 3 Jun 2015 00:16:12 +0200 Subject: [PATCH 60/77] add current note fix image --- README.md | 7 +++++++ docs/ESP_to_serial.png | Bin 30183 -> 21830 bytes 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index b2404b0b24..a916b8f3ae 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,13 @@ Libraries that don't rely on low-level access to AVR registers should work well. Pick the correct serial port. You need to put ESP8266 into bootloader mode before uploading code. +#### Power Supply #### + +For stable use of the ESP8266 a power supply with 3V3 and >= 250mA is required. + +* Note + - using Power from USB to Serial is may unstable, they not deliver enough current. + #### Minimal hardware Setup for Bootloading and usage #### ESPxx Hardware diff --git a/docs/ESP_to_serial.png b/docs/ESP_to_serial.png index 2d09ce076063dfb39e01679a5c29f8008bc3547e..9dd116be74c84a9cb42269a8f74468498e254e29 100644 GIT binary patch literal 21830 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

kVi_ic1}aBBqC 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

lwoHhj((xZhdXqF2z54lGm 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 Date: Tue, 2 Jun 2015 15:59:22 -0700 Subject: [PATCH 61/77] Include Servo Library in Readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 008ddcd3e6..d3af79de9e 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,11 @@ Allows the sketch to respond to multicast DNS queries for domain names like "foo Currently the library only works on STA interface, AP interface is not supported. See attached example and library README file for details. +#### Servor #### + +This library exposes the ability to control RC(hobby) servo motors. It will support upto 24 servos on any available output pin. By defualt the first 12 servos will use Timer0 and currently this will not interfere with any other support. Servos counts above 12 will use Timer1 and features that use it will be effected. +While many RC servo motors will accept the 3.3v IO data pin from a esp8266, most will not be able to run off 3.3v and will require another power source that matches their specifications. Make sure to connect the grounds between the esp8266 and the servo motor power supply. + #### Other libraries (not included with the IDE) Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work: From 41cc6d72fec01d9d347daa3cf8281a4d086dcab4 Mon Sep 17 00:00:00 2001 From: Makuna Date: Tue, 2 Jun 2015 16:00:51 -0700 Subject: [PATCH 62/77] edits --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d3af79de9e..8928e14c88 100644 --- a/README.md +++ b/README.md @@ -184,9 +184,9 @@ Allows the sketch to respond to multicast DNS queries for domain names like "foo Currently the library only works on STA interface, AP interface is not supported. See attached example and library README file for details. -#### Servor #### +#### Servo #### -This library exposes the ability to control RC(hobby) servo motors. It will support upto 24 servos on any available output pin. By defualt the first 12 servos will use Timer0 and currently this will not interfere with any other support. Servos counts above 12 will use Timer1 and features that use it will be effected. +This library exposes the ability to control RC (hobby) servo motors. It will support upto 24 servos on any available output pin. By defualt the first 12 servos will use Timer0 and currently this will not interfere with any other support. Servo counts above 12 will use Timer1 and features that use it will be effected. While many RC servo motors will accept the 3.3v IO data pin from a esp8266, most will not be able to run off 3.3v and will require another power source that matches their specifications. Make sure to connect the grounds between the esp8266 and the servo motor power supply. #### Other libraries (not included with the IDE) From 9dcc5a19b2226068dc62a2992458397461c9f1ff Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 3 Jun 2015 15:10:35 +0200 Subject: [PATCH 63/77] improve mode handling for ESP8266WiFiClass::scanNetworks and ESP8266WiFiClass::beginSmartConfig --- .../libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 0f97e48a1b..84bb134ea3 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -333,10 +333,14 @@ void ESP8266WiFiClass::_scanDone(void* result, int status) int8_t ESP8266WiFiClass::scanNetworks() { - if ((wifi_get_opmode() & 1) == 0)//1 and 3 have STA enabled - { + if(_useApMode) { + // turn on AP+STA mode mode(WIFI_AP_STA); + } else { + // turn on STA mode + mode(WIFI_STA); } + int status = wifi_station_get_connect_status(); if (status != STATION_GOT_IP && status != STATION_IDLE) { @@ -508,9 +512,12 @@ void ESP8266WiFiClass::beginSmartConfig() if (_smartConfigStarted) return; - if ((wifi_get_opmode() & 1) == 0)//1 and 3 have STA enabled - { + if(_useApMode) { + // turn on AP+STA mode mode(WIFI_AP_STA); + } else { + // turn on STA mode + mode(WIFI_STA); } _smartConfigStarted = true; From 2aab78ade9098be4e4ec13ef31938f022698765b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 3 Jun 2015 15:40:11 +0200 Subject: [PATCH 64/77] fix ILI9341 (define for SPI speed was deleted?) --- libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp b/libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp index 05d376aed9..2af27e83e6 100644 --- a/libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp +++ b/libraries/Adafruit_ILI9341/Adafruit_ILI9341.cpp @@ -264,7 +264,7 @@ uint16_t Adafruit_ILI9341::getWidth(void){ #ifdef SPI_HAS_TRANSACTION #ifdef ESP8266 -SPISettings spiSettings = SPISettings(SPI_MAX_SPEED, MSBFIRST, SPI_MODE0); +SPISettings spiSettings = SPISettings(ESP8266_CLOCK, MSBFIRST, SPI_MODE0); #else SPISettings spiSettings = SPISettings(8000000, MSBFIRST, SPI_MODE0); #endif From be738f229d3a645518c0f2bcbf3bb31965e84e09 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 3 Jun 2015 15:40:43 +0200 Subject: [PATCH 65/77] only call wifi_set_opmode when really needed --- .../esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 84bb134ea3..11a1c11ee8 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -45,6 +45,9 @@ ESP8266WiFiClass::ESP8266WiFiClass() void ESP8266WiFiClass::mode(WiFiMode m) { + if(wifi_get_opmode() == (uint8)m) { + return; + } ETS_UART_INTR_DISABLE(); wifi_set_opmode(m); ETS_UART_INTR_ENABLE(); From cf773e4c0fda5c3c68c8fd75506027a3b2a94a29 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 3 Jun 2015 19:32:44 +0200 Subject: [PATCH 66/77] add some infos to Serial Adapter --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index a916b8f3ae..84d2f7ccb0 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,21 @@ For stable use of the ESP8266 a power supply with 3V3 and >= 250mA is required. * Note - using Power from USB to Serial is may unstable, they not deliver enough current. +#### Serial Adapter #### + +There are many different USB to Serial adapters / boards. + +* Note + - for full upload management you need RTS and DTR + - the chip need to have 3V3 TTL (5V may damage the chip) + - not all board have all pins of the ICs as breakout (check before order) + - CTS and DSR are not useful for upload (they are Inputs) + +* Working ICs + - FT232RL + - CP2102 + - may others (drop a comment) + #### Minimal hardware Setup for Bootloading and usage #### ESPxx Hardware From 149f619d9735815a120d96b22b5eb106d871bd22 Mon Sep 17 00:00:00 2001 From: John Doe Date: Wed, 3 Jun 2015 22:23:19 +0300 Subject: [PATCH 67/77] double --- hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h index d7723c3ad4..996185ddc9 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/esp8266_peri.h @@ -284,7 +284,7 @@ extern uint8_t esp8266_gpioToFn[16]; //SPI_READY #define SPIRDY ESP8266_DREG(0x0C) -#define SPIBUSY 9 //wait SPI idle +#define SPI_BUSY 9 //wait SPI idle //SPI0 Registers (SPI0 is used for the flash) #define SPI0CMD ESP8266_REG(0x200) From 58f42fe44fc6efeeba7fa864f5861ec033910e2d Mon Sep 17 00:00:00 2001 From: chad cormier roussel Date: Wed, 3 Jun 2015 15:29:25 -0400 Subject: [PATCH 68/77] Add function overload to config to include DNS Disable DHCP if using static IP With dhcp disabled, I noticed about 50% less conncection time --- .../libraries/ESP8266WiFi/src/ESP8266WiFi.cpp | 26 ++++++++++++++++++- .../libraries/ESP8266WiFi/src/ESP8266WiFi.h | 13 ++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp index 0f97e48a1b..2ba6eda66f 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp @@ -40,6 +40,7 @@ extern "C" void esp_yield(); ESP8266WiFiClass::ESP8266WiFiClass() : _useApMode(false) , _useClientMode(false) +, _useStaticIp(false) { } @@ -100,7 +101,8 @@ int ESP8266WiFiClass::begin(const char* ssid, const char *passphrase, int32_t ch wifi_set_channel(channel); } - wifi_station_dhcpc_start(); + if(!_useStaticIp) + wifi_station_dhcpc_start(); return status(); } @@ -112,6 +114,8 @@ uint8_t ESP8266WiFiClass::waitForConnectResult(){ return status(); } + +// You will have to set the DNS-Server manually later since this will not enable DHCP void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet) { struct ip_info info; @@ -121,6 +125,26 @@ void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress s wifi_station_dhcpc_stop(); wifi_set_ip_info(STATION_IF, &info); + + _useStaticIp = true; +} + +void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns) +{ + struct ip_info info; + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + + wifi_station_dhcpc_stop(); + wifi_set_ip_info(STATION_IF, &info); + + // Set DNS-Server + ip_addr_t d; + d.addr = static_cast(dns); + dns_setserver(0,&d); + + _useStaticIp = true; } int ESP8266WiFiClass::disconnect() diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 64563ad7e9..5591343ab8 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -75,7 +75,6 @@ class ESP8266WiFiClass */ void softAP(const char* ssid, const char* passphrase, int channel = 1); - /* Change Ip configuration settings disabling the dhcp client * * param local_ip: Static ip configuration @@ -84,6 +83,15 @@ class ESP8266WiFiClass */ void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet); + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param gateway: Static gateway configuration + * param subnet: Static Subnet mask + * param dns: Defined DNS + */ + void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns); + /* Configure access point * * param local_ip: access point IP @@ -310,7 +318,8 @@ class ESP8266WiFiClass bool _useApMode; bool _useClientMode; - + bool _useStaticIp; + static size_t _scanCount; static void* _scanResult; From d0315a33e8f0d3d0e854d851e1fecb3b900ba3d3 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 5 Jun 2015 11:48:02 +0200 Subject: [PATCH 69/77] fix #386 --- .../ESP8266WiFi/src/ESP8266WiFiMulti.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp index 7161c399c1..91f03bbc0d 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp @@ -72,7 +72,6 @@ wl_status_t ESP8266WiFiMulti::run(void) { WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan); - bool known = false; for(uint32_t x = 0; x < APlist.size(); x++) { WifiAPlist_t entry = APlist[x]; @@ -152,7 +151,17 @@ bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) { WifiAPlist_t newAP; - newAP.ssid = (char*) malloc(strlen(ssid)); + if(!ssid || strlen(ssid) > 31) { + // fail SSID to long or missing! + return false; + } + + if(passphrase && strlen(passphrase) > 63) { + // fail passphrase to long! + return false; + } + + newAP.ssid = (char*) malloc((strlen(ssid) + 1)); if(!newAP.ssid) { return false; @@ -161,16 +170,14 @@ bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) { strcpy(newAP.ssid, ssid); if(passphrase && *passphrase != 0x00) { - newAP.passphrase = (char*) malloc(strlen(passphrase)); - } - - if(!newAP.passphrase) { - free(newAP.ssid); - return false; + newAP.passphrase = (char*) malloc((strlen(passphrase) + 1)); + if(!newAP.passphrase) { + free(newAP.ssid); + return false; + } + strcpy(newAP.passphrase, passphrase); } - strcpy(newAP.passphrase, passphrase); - APlist.push_back(newAP); return true; } From fa6917fb13f41e771d15d0c2a95f6529db7dd670 Mon Sep 17 00:00:00 2001 From: Dario Di Maio Date: Thu, 4 Jun 2015 16:51:52 +0200 Subject: [PATCH 70/77] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 174b078edd..1004502e13 100644 --- a/README.md +++ b/README.md @@ -193,14 +193,15 @@ While many RC servo motors will accept the 3.3v IO data pin from a esp8266, most Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work: +- [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) - WebSocket Server and Client compatible with esp8266 (RFC6455) - [aREST](https://github.com/marcoschwartz/aREST) REST API handler library. -- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy. -- [DHT11](https://github.com/adafruit/DHT-sensor-library) - initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);``` +- [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) - initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);``` - [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. -- [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) +- [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB. #### Upload via serial port #### Pick the correct serial port. From 45c27c6686abad021ca184d1f20dc0f9505da788 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 5 Jun 2015 08:04:10 +0300 Subject: [PATCH 71/77] Fix typo --- .../esp8266com/esp8266/bootloaders/eboot/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile index cd9e141431..1364ac0d00 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile @@ -1,4 +1,4 @@ -XTENSA_TOOCHAIN ?= +XTENSA_TOOLCHAIN ?= BIN_DIR := ./ TARGET_DIR := ./ @@ -9,11 +9,11 @@ TARGET_OBJ_FILES := \ 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 +CC := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc +CXX := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-g++ +AR := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-ar +LD := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc +OBJDUMP := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-objdump CFLAGS += -std=gnu99 From 1b8cbe7fc544c3ac5a5ddf9c7177e4a0ec390f35 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 5 Jun 2015 08:08:53 +0300 Subject: [PATCH 72/77] Clean up eboot --- .../esp8266/bootloaders/eboot/Makefile | 1 + .../esp8266/bootloaders/eboot/eboot.c | 57 +++++------------- .../esp8266/bootloaders/eboot/eboot.elf | Bin 9816 -> 11233 bytes .../esp8266/bootloaders/eboot/eboot_command.c | 26 ++++++-- .../esp8266/bootloaders/eboot/eboot_command.h | 5 +- .../esp8266/bootloaders/eboot/flash.c | 42 +++++++++++++ .../bootloaders/eboot/{eboot.h => flash.h} | 9 ++- 7 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 hardware/esp8266com/esp8266/bootloaders/eboot/flash.c rename hardware/esp8266com/esp8266/bootloaders/eboot/{eboot.h => flash.h} (90%) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile index 1364ac0d00..0872ee35f5 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/Makefile @@ -6,6 +6,7 @@ TARGET_DIR := ./ TARGET_OBJ_FILES := \ eboot.o \ eboot_command.o \ + flash.o \ TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c index b3193e299a..0b74fcdf07 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c @@ -9,9 +9,8 @@ #include #include #include -#include "eboot.h" +#include "flash.h" #include "eboot_command.h" -extern void* flashchip; #define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0); @@ -73,53 +72,21 @@ int load_app_from_flash_raw(const uint32_t flash_addr) -int erase(const uint32_t start, const uint32_t size) -{ - if (start & (FLASH_SECTOR_SIZE - 1) != 0) { - return 1; - } - - const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; - uint32_t current_sector = start / FLASH_SECTOR_SIZE; - uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; - const uint32_t end = current_sector + sector_count; - - for (; current_sector < end && (current_sector & (sectors_per_block-1)); - ++current_sector, --sector_count) { - if (SPIEraseSector(current_sector)) { - return 2; - } - } - - for (;current_sector + sectors_per_block <= end; - current_sector += sectors_per_block, - sector_count -= sectors_per_block) { - if (SPIEraseBlock(current_sector / sectors_per_block)) { - return 3; - } - } - - for (; current_sector < end; - ++current_sector, --sector_count) { - if (SPIEraseSector(current_sector)) { - return 4; - } - } - - return 0; -} - int copy_raw(const uint32_t src_addr, const uint32_t dst_addr, const uint32_t size) { + ets_putc('\n'); + ets_putc('c'); + ets_putc('p'); + ets_putc('\n'); // require regions to be aligned if (src_addr & 0xfff != 0 || dst_addr & 0xfff != 0) { return 1; } - if (erase(dst_addr, size)) { + if (SPIEraseAreaEx(dst_addr, size)) { return 2; } @@ -153,17 +120,25 @@ void main() int res = 9; struct eboot_command cmd; - eboot_command_read(&cmd); + if (eboot_command_read(&cmd)) { + cmd.action = ACTION_LOAD_APP; + cmd.args[0] = 0; + ets_putc('e'); + } else { + ets_putc('@'); + } + eboot_command_clear(); if (cmd.action == ACTION_COPY_RAW) { res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); if (res == 0) { cmd.action = ACTION_LOAD_APP; + cmd.args[0] = cmd.args[1]; } } if (cmd.action == ACTION_LOAD_APP) { - res = load_app_from_flash_raw(0); + res = load_app_from_flash_raw(cmd.args[0]); } if (res) { diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.elf index 0637a05253c2b3f61f91954695e5fd4b116cadc6..97e25c14616a9f6e768711b46c6cafa6f62df21e 100755 GIT binary patch literal 11233 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 diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c index 1e9cbed2cf..648039e48a 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.c @@ -28,7 +28,7 @@ uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) offsetof(struct eboot_command, crc32)); } -void eboot_command_read(struct eboot_command* cmd) +int eboot_command_read(struct eboot_command* cmd) { const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); uint32_t* dst = (uint32_t *) cmd; @@ -39,9 +39,27 @@ void eboot_command_read(struct eboot_command* cmd) uint32_t crc32 = eboot_command_calculate_crc32(cmd); if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC || cmd->crc32 != crc32) { - - cmd->action = ACTION_LOAD_APP; - cmd->args[0] = 0; + return 1; } + + return 0; +} + +void eboot_command_write(struct eboot_command* cmd) +{ + cmd->magic = EBOOT_MAGIC; + cmd->crc32 = eboot_command_calculate_crc32(cmd); + + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + const uint32_t* src = (const uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + RTC_MEM[i] = src[i]; + } +} + +void eboot_command_clear() +{ + RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; + RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; } diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h index aa0fc11bbd..cf40c135de 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h @@ -23,7 +23,8 @@ struct eboot_command { }; -void eboot_command_read(struct eboot_command* cmd); - +int eboot_command_read(struct eboot_command* cmd); +void eboot_command_write(struct eboot_command* cmd); +void eboot_command_clear(); #endif //EBOOT_COMMAND_H diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c new file mode 100644 index 0000000000..6f95a472d5 --- /dev/null +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "flash.h" + + +int SPIEraseAreaEx(const uint32_t start, const uint32_t size) +{ + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { + return 1; + } + + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + uint32_t current_sector = start / FLASH_SECTOR_SIZE; + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; + const uint32_t end = current_sector + sector_count; + + for (; current_sector < end && (current_sector & (sectors_per_block-1)); + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 2; + } + } + + for (;current_sector + sectors_per_block <= end; + current_sector += sectors_per_block, + sector_count -= sectors_per_block) { + if (SPIEraseBlock(current_sector / sectors_per_block)) { + return 3; + } + } + + for (; current_sector < end; + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 4; + } + } + + return 0; +} + diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.h similarity index 90% rename from hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h rename to hardware/esp8266com/esp8266/bootloaders/eboot/flash.h index 973c616a80..ea8b65c1fa 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.h @@ -5,15 +5,14 @@ * 3-clause BSD license to be found in the LICENSE file. */ -#ifndef EBOOT_H -#define EBOOT_H - +#ifndef FLASH_H +#define FLASH_H int SPIEraseBlock(uint32_t block); int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); int SPIWrite(uint32_t addr, void *src, size_t size); - +int SPIEraseAreaEx(const uint32_t start, const uint32_t size); #define FLASH_SECTOR_SIZE 0x1000 #define FLASH_BLOCK_SIZE 0x10000 @@ -41,4 +40,4 @@ typedef struct { -#endif //EBOOT_H +#endif //FLASH_H From 4e3455b2169beea47d791dd9dc3f8839961bd92e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 5 Jun 2015 08:19:47 +0300 Subject: [PATCH 73/77] rename EspClass::eraseESPconfig to eraseConfig --- hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp | 2 +- hardware/esp8266com/esp8266/cores/esp8266/Esp.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 946a8b3754..419cb889ad 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp @@ -295,7 +295,7 @@ struct rst_info * EspClass::getResetInfoPtr(void) { return &resetInfo; } -bool EspClass::eraseESPconfig(void) { +bool EspClass::eraseConfig(void) { bool ret = true; size_t cfgAddr = (ESP.getFlashChipSize() - 0x4000); size_t cfgSize = (8*1024); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index 9411dc5f0c..ecb80da077 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -101,7 +101,7 @@ class EspClass { String getResetInfo(void); struct rst_info * getResetInfoPtr(void); - bool eraseESPconfig(void); + bool eraseConfig(void); inline uint32_t getCycleCount(void); }; From 28b4e0b24f8003232b5c96e58aa8787aca45cdf4 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 5 Jun 2015 08:29:15 +0300 Subject: [PATCH 74/77] Add some headers --- .../esp8266com/esp8266/bootloaders/eboot/eboot_command.h | 7 +++++++ hardware/esp8266com/esp8266/bootloaders/eboot/flash.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h index cf40c135de..ba9c889a2c 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/eboot_command.h @@ -1,3 +1,10 @@ +/* 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. + */ + #ifndef EBOOT_COMMAND_H #define EBOOT_COMMAND_H diff --git a/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c index 6f95a472d5..f90e25b347 100644 --- a/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c +++ b/hardware/esp8266com/esp8266/bootloaders/eboot/flash.c @@ -1,3 +1,10 @@ +/* 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 From 004078262e2ca8ba92e6af99bea53d1af2519578 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 5 Jun 2015 13:48:00 +0300 Subject: [PATCH 75/77] Add function to update sketch from Stream --- .../esp8266com/esp8266/cores/esp8266/Esp.cpp | 125 ++++++++++++++++++ .../esp8266com/esp8266/cores/esp8266/Esp.h | 48 ++++--- .../esp8266/core_esp8266_eboot_command.c | 88 ++++++++++++ .../cores/esp8266/core_esp8266_flash_utils.c | 64 +++++++++ .../esp8266/cores/esp8266/eboot_command.h | 36 +++++ .../esp8266/cores/esp8266/flash_utils.h | 63 +++++++++ 6 files changed, 402 insertions(+), 22 deletions(-) create mode 100644 hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_eboot_command.c create mode 100644 hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_flash_utils.c create mode 100644 hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h create mode 100644 hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp index 419cb889ad..73367683af 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp @@ -19,6 +19,9 @@ */ #include "Arduino.h" +#include "flash_utils.h" +#include "eboot_command.h" +#include extern "C" { #include "user_interface.h" @@ -26,6 +29,9 @@ extern "C" { extern struct rst_info resetInfo; } + +// #define DEBUG_SERIAL Serial + //extern "C" void ets_wdt_init(uint32_t val); extern "C" void ets_wdt_enable(void); extern "C" void ets_wdt_disable(void); @@ -315,4 +321,123 @@ bool EspClass::eraseConfig(void) { return ret; } +uint32_t EspClass::getSketchSize() { + static uint32_t result = 0; + if (result) + return result; + + image_header_t image_header; + uint32_t pos = APP_START_OFFSET; + if (spi_flash_read(pos, (uint32_t*) &image_header, sizeof(image_header))) { + return 0; + } + pos += sizeof(image_header); +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.printf("num_segments=%u\r\n", image_header.num_segments); +#endif + for (uint32_t section_index = 0; + section_index < image_header.num_segments; + ++section_index) + { + section_header_t section_header = {0}; + if (spi_flash_read(pos, (uint32_t*) §ion_header, sizeof(section_header))) { + return 0; + } + pos += sizeof(section_header); + pos += section_header.size; +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.printf("section=%u size=%u pos=%u\r\n", section_index, section_header.size, pos); +#endif + } + result = pos; + return result; +} + +extern "C" uint32_t _SPIFFS_start; + +uint32_t EspClass::getFreeSketchSpace() { + + uint32_t usedSize = getSketchSize(); + // round one sector up + uint32_t freeSpaceStart = (usedSize + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + uint32_t freeSpaceEnd = (uint32_t)&_SPIFFS_start - 0x40200000; + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.printf("usedSize=%u freeSpaceStart=%u freeSpaceEnd=%u\r\n", usedSize, freeSpaceStart, freeSpaceEnd); +#endif + return freeSpaceEnd - freeSpaceStart; +} + +bool EspClass::updateSketch(Stream& in, uint32_t size) { + + if (size > getFreeSketchSpace()) + return false; + + uint32_t usedSize = getSketchSize(); + uint32_t freeSpaceStart = (usedSize + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + uint32_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.printf("erase @0x%x size=0x%x\r\n", freeSpaceStart, roundedSize); +#endif + + noInterrupts(); + int rc = SPIEraseAreaEx(freeSpaceStart, roundedSize); + interrupts(); + if (rc) + return false; + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("erase done"); +#endif + + uint32_t addr = freeSpaceStart; + uint32_t left = size; + + const uint32_t bufferSize = FLASH_SECTOR_SIZE; + std::unique_ptr buffer(new uint8_t[bufferSize]); + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("writing"); +#endif + while (left > 0) { + size_t willRead = (left < bufferSize) ? left : bufferSize; + size_t rd = in.readBytes(buffer.get(), willRead); + if (rd != willRead) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("stream read failed"); +#endif + return false; + } + + noInterrupts(); + rc = SPIWrite(addr, buffer.get(), willRead); + interrupts(); + if (rc) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("write failed"); +#endif + return false; + } + + addr += willRead; + left -= willRead; +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print("."); +#endif + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("\r\nrestarting"); +#endif + eboot_command ebcmd; + ebcmd.action = ACTION_COPY_RAW; + ebcmd.args[0] = freeSpaceStart; + ebcmd.args[1] = 0x00000; + ebcmd.args[2] = size; + eboot_command_write(&ebcmd); + + ESP.restart(); + return true; // never happens +} diff --git a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h index ecb80da077..2b58b79d1c 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/Esp.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/Esp.h @@ -69,44 +69,48 @@ class EspClass { // note: setting the timeout value is not implemented at the moment void wdtEnable(WDTO_t timeout_ms = WDTO_0MS); - void wdtDisable(void); - void wdtFeed(void); + void wdtDisable(); + void wdtFeed(); void deepSleep(uint32_t time_us, WakeMode mode = WAKE_RF_DEFAULT); - void reset(void); - void restart(void); + void reset(); + void restart(); - uint16_t getVcc(void); - uint32_t getFreeHeap(void); + uint16_t getVcc(); + uint32_t getFreeHeap(); - uint32_t getChipId(void); + uint32_t getChipId(); - const char * getSdkVersion(void); + const char * getSdkVersion(); - uint8_t getBootVersion(void); - uint8_t getBootMode(void); + uint8_t getBootVersion(); + uint8_t getBootMode(); - uint8_t getCpuFreqMHz(void); + uint8_t getCpuFreqMHz(); - uint32_t getFlashChipId(void); + uint32_t getFlashChipId(); //gets the actual chip size based on the flash id - uint32_t getFlashChipRealSize(void); + uint32_t getFlashChipRealSize(); //gets the size of the flash as set by the compiler - uint32_t getFlashChipSize(void); - uint32_t getFlashChipSpeed(void); - FlashMode_t getFlashChipMode(void); - uint32_t getFlashChipSizeByChipId(void); + uint32_t getFlashChipSize(); + uint32_t getFlashChipSpeed(); + FlashMode_t getFlashChipMode(); + uint32_t getFlashChipSizeByChipId(); - String getResetInfo(void); - struct rst_info * getResetInfoPtr(void); + uint32_t getSketchSize(); + uint32_t getFreeSketchSpace(); + bool updateSketch(Stream& in, uint32_t size); - bool eraseConfig(void); + String getResetInfo(); + struct rst_info * getResetInfoPtr(); - inline uint32_t getCycleCount(void); + bool eraseConfig(); + + inline uint32_t getCycleCount(); }; -uint32_t EspClass::getCycleCount(void) +uint32_t EspClass::getCycleCount() { uint32_t ccount; __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_eboot_command.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_eboot_command.c new file mode 100644 index 0000000000..60c92bf189 --- /dev/null +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_eboot_command.c @@ -0,0 +1,88 @@ +/* + core_esp8266_eboot_command.c - interface to the eboot bootloader + + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "eboot_command.h" + +uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length) +{ + uint32_t i; + bool bit; + uint8_t c; + + while (length--) { + c = *data++; + for (i = 0x80; i > 0; i >>= 1) { + bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + } + return crc; +} + +uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) +{ + return crc_update(0xffffffff, (const uint8_t*) cmd, + offsetof(struct eboot_command, crc32)); +} + +int eboot_command_read(struct eboot_command* cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + uint32_t* dst = (uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + dst[i] = RTC_MEM[i]; + } + + uint32_t crc32 = eboot_command_calculate_crc32(cmd); + if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC || + cmd->crc32 != crc32) { + return 1; + } + + return 0; +} + +void eboot_command_write(struct eboot_command* cmd) +{ + cmd->magic = EBOOT_MAGIC; + cmd->crc32 = eboot_command_calculate_crc32(cmd); + + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + const uint32_t* src = (const uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + RTC_MEM[i] = src[i]; + } +} + +void eboot_command_clear() +{ + RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; + RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; +} + diff --git a/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_flash_utils.c b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_flash_utils.c new file mode 100644 index 0000000000..6f8a34f41c --- /dev/null +++ b/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_flash_utils.c @@ -0,0 +1,64 @@ +/* + core_esp8266_flash_utils.c - flash and binary image helpers + + Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include +#include +#include "flash_utils.h" + + +int SPIEraseAreaEx(const uint32_t start, const uint32_t size) +{ + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { + return 1; + } + + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + uint32_t current_sector = start / FLASH_SECTOR_SIZE; + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; + const uint32_t end = current_sector + sector_count; + + for (; current_sector < end && (current_sector & (sectors_per_block-1)); + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 2; + } + } + + for (;current_sector + sectors_per_block <= end; + current_sector += sectors_per_block, + sector_count -= sectors_per_block) { + if (SPIEraseBlock(current_sector / sectors_per_block)) { + return 3; + } + } + + for (; current_sector < end; + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 4; + } + } + + return 0; +} + diff --git a/hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h b/hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h new file mode 100644 index 0000000000..3d854afba3 --- /dev/null +++ b/hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h @@ -0,0 +1,36 @@ +#ifndef EBOOT_COMMAND_H +#define EBOOT_COMMAND_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTC_MEM ((volatile uint32_t*)0x60001200) + +enum action_t { + ACTION_COPY_RAW = 0x00000001, + ACTION_LOAD_APP = 0xffffffff +}; + +#define EBOOT_MAGIC 0xeb001000 +#define EBOOT_MAGIC_MASK 0xfffff000 + +struct eboot_command { + uint32_t magic; + enum action_t action; + uint32_t args[29]; + uint32_t crc32; +}; + + +int eboot_command_read(struct eboot_command* cmd); +void eboot_command_write(struct eboot_command* cmd); +void eboot_command_clear(); + +#ifdef __cplusplus +} +#endif + +#endif //EBOOT_COMMAND_H diff --git a/hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h b/hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h new file mode 100644 index 0000000000..4e5f2120b1 --- /dev/null +++ b/hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h @@ -0,0 +1,63 @@ +/* + flash_utils.h - Flash access function and data structures + Copyright (c) 2015 Ivan Grokhotkov. 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 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 +*/ + + +#ifndef FLASH_UTILS_H +#define FLASH_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + +int SPIEraseBlock(uint32_t block); +int SPIEraseSector(uint32_t sector); +int SPIRead(uint32_t addr, void *dest, size_t size); +int SPIWrite(uint32_t addr, void *src, size_t size); +int SPIEraseAreaEx(const uint32_t start, const uint32_t size); + +#define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 +#define APP_START_OFFSET 0x1000 + +typedef struct { + unsigned char magic; + unsigned char num_segments; + + /* SPI Flash Interface (0 = QIO, 1 = QOUT, 2 = DIO, 0x3 = DOUT) */ + unsigned char flash_mode; + + /* High four bits: 0 = 512K, 1 = 256K, 2 = 1M, 3 = 2M, 4 = 4M, + Low four bits: 0 = 40MHz, 1= 26MHz, 2 = 20MHz, 0xf = 80MHz */ + unsigned char flash_size_freq; + + uint32_t entry; +} image_header_t; + + +typedef struct { + uint32_t address; + uint32_t size; +} section_header_t; + +#ifdef __cplusplus +} +#endif + + +#endif //FLASH_UTILS_H From b364bcb9dea9e8bc3463e4d187f014fdedff5eab Mon Sep 17 00:00:00 2001 From: Dario Di Maio Date: Thu, 4 Jun 2015 16:51:52 +0200 Subject: [PATCH 76/77] Remove unnecessary ICACHE_FLASH_ATTR --- .../libraries/ESP8266WiFi/src/WiFiClient.cpp | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp index 056d5bb654..727e64fc1a 100644 --- a/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp +++ b/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp @@ -42,30 +42,30 @@ extern "C" uint16_t WiFiClient::_localPort = 0; -ICACHE_FLASH_ATTR WiFiClient::WiFiClient() +WiFiClient::WiFiClient() : _client(0) { } -ICACHE_FLASH_ATTR WiFiClient::WiFiClient(ClientContext* client) : _client(client) +WiFiClient::WiFiClient(ClientContext* client) : _client(client) { _client->ref(); } -ICACHE_FLASH_ATTR WiFiClient::~WiFiClient() +WiFiClient::~WiFiClient() { if (_client) _client->unref(); } -ICACHE_FLASH_ATTR WiFiClient::WiFiClient(const WiFiClient& other) +WiFiClient::WiFiClient(const WiFiClient& other) { _client = other._client; if (_client) _client->ref(); } -WiFiClient& ICACHE_FLASH_ATTR WiFiClient::operator=(const WiFiClient& other) +WiFiClient& WiFiClient::operator=(const WiFiClient& other) { if (_client) _client->unref(); @@ -76,7 +76,7 @@ WiFiClient& ICACHE_FLASH_ATTR WiFiClient::operator=(const WiFiClient& other) } -int ICACHE_FLASH_ATTR WiFiClient::connect(const char* host, uint16_t port) +int WiFiClient::connect(const char* host, uint16_t port) { IPAddress remote_addr; if (WiFi.hostByName(host, remote_addr)) @@ -86,7 +86,7 @@ int ICACHE_FLASH_ATTR WiFiClient::connect(const char* host, uint16_t port) return 0; } -int ICACHE_FLASH_ATTR WiFiClient::connect(IPAddress ip, uint16_t port) +int WiFiClient::connect(IPAddress ip, uint16_t port) { if (_client) stop(); @@ -114,7 +114,7 @@ int ICACHE_FLASH_ATTR WiFiClient::connect(IPAddress ip, uint16_t port) return 0; } -int8_t ICACHE_FLASH_ATTR WiFiClient::_connected(void* pcb, int8_t err) +int8_t WiFiClient::_connected(void* pcb, int8_t err) { tcp_pcb* tpcb = reinterpret_cast(pcb); _client = new ClientContext(tpcb, 0, 0); @@ -123,31 +123,31 @@ int8_t ICACHE_FLASH_ATTR WiFiClient::_connected(void* pcb, int8_t err) return ERR_OK; } -void ICACHE_FLASH_ATTR WiFiClient::_err(int8_t err) +void WiFiClient::_err(int8_t err) { DEBUGV(":err %d\r\n", err); esp_schedule(); } -void ICACHE_FLASH_ATTR WiFiClient::setNoDelay(bool nodelay) { +void WiFiClient::setNoDelay(bool nodelay) { if (!_client) return; _client->setNoDelay(nodelay); } -bool ICACHE_FLASH_ATTR WiFiClient::getNoDelay() { +bool WiFiClient::getNoDelay() { if (!_client) return false; return _client->getNoDelay(); } -size_t ICACHE_FLASH_ATTR WiFiClient::write(uint8_t b) +size_t WiFiClient::write(uint8_t b) { return write(&b, 1); } -size_t ICACHE_FLASH_ATTR WiFiClient::write(const uint8_t *buf, size_t size) +size_t WiFiClient::write(const uint8_t *buf, size_t size) { if (!_client || !size) { @@ -159,7 +159,7 @@ size_t ICACHE_FLASH_ATTR WiFiClient::write(const uint8_t *buf, size_t size) extern "C" uint32_t esp_micros_at_task_start(); -int ICACHE_FLASH_ATTR WiFiClient::available() +int WiFiClient::available() { static uint32_t lastPollTime = 0; if (!_client) @@ -174,7 +174,7 @@ int ICACHE_FLASH_ATTR WiFiClient::available() return result; } -int ICACHE_FLASH_ATTR WiFiClient::read() +int WiFiClient::read() { if (!available()) return -1; @@ -183,12 +183,12 @@ int ICACHE_FLASH_ATTR WiFiClient::read() } -int ICACHE_FLASH_ATTR WiFiClient::read(uint8_t* buf, size_t size) +int WiFiClient::read(uint8_t* buf, size_t size) { return (int) _client->read(reinterpret_cast(buf), size); } -int ICACHE_FLASH_ATTR WiFiClient::peek() +int WiFiClient::peek() { if (!available()) return -1; @@ -196,13 +196,13 @@ int ICACHE_FLASH_ATTR WiFiClient::peek() return _client->peek(); } -void ICACHE_FLASH_ATTR WiFiClient::flush() +void WiFiClient::flush() { if (_client) _client->flush(); } -void ICACHE_FLASH_ATTR WiFiClient::stop() +void WiFiClient::stop() { if (!_client) return; @@ -211,7 +211,7 @@ void ICACHE_FLASH_ATTR WiFiClient::stop() _client = 0; } -uint8_t ICACHE_FLASH_ATTR WiFiClient::connected() +uint8_t WiFiClient::connected() { if (!_client) return 0; @@ -219,14 +219,14 @@ uint8_t ICACHE_FLASH_ATTR WiFiClient::connected() return _client->state() == ESTABLISHED || available(); } -uint8_t ICACHE_FLASH_ATTR WiFiClient::status() +uint8_t WiFiClient::status() { if (!_client) return CLOSED; return _client->state(); } -ICACHE_FLASH_ATTR WiFiClient::operator bool() + WiFiClient::operator bool() { return _client != 0; } @@ -247,12 +247,12 @@ uint16_t WiFiClient::remotePort() return _client->getRemotePort(); } -int8_t ICACHE_FLASH_ATTR WiFiClient::_s_connected(void* arg, void* tpcb, int8_t err) +int8_t WiFiClient::_s_connected(void* arg, void* tpcb, int8_t err) { return reinterpret_cast(arg)->_connected(tpcb, err); } -void ICACHE_FLASH_ATTR WiFiClient::_s_err(void* arg, int8_t err) +void WiFiClient::_s_err(void* arg, int8_t err) { reinterpret_cast(arg)->_err(err); } From d1142f769908a748f2e14ac2a2b3d277ca9d65b3 Mon Sep 17 00:00:00 2001 From: Tony DiCola Date: Mon, 8 Jun 2015 11:11:56 -0700 Subject: [PATCH 77/77] Wrap all pgmspace.h declarations with extern C to prevent issue with linking. --- hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h index e6db10fbda..c24dd240e7 100644 --- a/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h +++ b/hardware/esp8266com/esp8266/cores/esp8266/pgmspace.h @@ -8,9 +8,6 @@ extern "C" { #include #include "ets_sys.h" #include "osapi.h" -#ifdef __cplusplus -} -#endif #define PROGMEM ICACHE_RODATA_ATTR #define PGM_P const char * @@ -90,4 +87,8 @@ int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap) __at #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) +#ifdef __cplusplus // End extern "C" wrapper. +} +#endif + #endif //__PGMSPACE_H_