diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 7e06e0058..10c6ebd44 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -219,14 +219,12 @@ void loop(void); void yield(void); void optimistic_yield(uint32_t interval_us); -// Get the bit location within the hardware port of the given virtual pin. -// This comes from the pins_*.c file for the active board configuration. #define digitalPinToPort(pin) (0) #define digitalPinToBitMask(pin) (1UL << (pin)) #define digitalPinToTimer(pin) (0) -#define portOutputRegister(port) ((volatile uint32_t*) GPO) -#define portInputRegister(port) ((volatile uint32_t*) GPI) -#define portModeRegister(port) ((volatile uint32_t*) GPE) +#define portOutputRegister(port) ((volatile uint32_t*) &GPO) +#define portInputRegister(port) ((volatile uint32_t*) &GPI) +#define portModeRegister(port) ((volatile uint32_t*) &GPE) #define NOT_A_PIN -1 #define NOT_A_PORT -1 diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 2e93f8aee..78108bee7 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -617,18 +617,15 @@ size_t HardwareSerial::write(uint8_t c) { size_t room = uart_get_tx_fifo_room(_uart); if(room > 0 && _tx_buffer->empty()) { uart_transmit_char(_uart, c); - if(room < 10) { - uart_arm_tx_interrupt(_uart); - } return 1; } while(_tx_buffer->room() == 0) { yield(); - uart_arm_tx_interrupt(_uart); } _tx_buffer->write(c); + uart_arm_tx_interrupt(_uart); return 1; } diff --git a/cores/esp8266/Updater.h b/cores/esp8266/Updater.h index b9f1b3d06..a25cb081b 100644 --- a/cores/esp8266/Updater.h +++ b/cores/esp8266/Updater.h @@ -26,7 +26,7 @@ class UpdaterClass { Call this to check the space needed for the update Will return false if there is not enough space */ - bool begin(size_t size, int = U_FLASH); + bool begin(size_t size, int command = U_FLASH); /* Writes a buffer to the flash and increments the address diff --git a/cores/esp8266/abi.cpp b/cores/esp8266/abi.cpp index b38f16453..ff865d9ca 100644 --- a/cores/esp8266/abi.cpp +++ b/cores/esp8266/abi.cpp @@ -68,6 +68,10 @@ void __throw_length_error(char const*) { void __throw_bad_alloc() { panic(); } + +void __throw_logic_error(const char* str) { + panic(); +} } // TODO: rebuild windows toolchain to make this unnecessary: diff --git a/cores/esp8266/cbuf.h b/cores/esp8266/cbuf.h index fee98a94b..087e7200b 100644 --- a/cores/esp8266/cbuf.h +++ b/cores/esp8266/cbuf.h @@ -42,9 +42,6 @@ class cbuf { if(_end >= _begin) { return _size - (_end - _begin) - 1; } - if(_begin == _end) { - return _size; - } return _begin - _end - 1; } @@ -62,7 +59,7 @@ class cbuf { if(getSize() == 0) return -1; char result = *_begin; - if(++_begin == _bufend) _begin = _buf; + _begin = wrap_if_bufend(_begin + 1); return static_cast(result); } @@ -78,8 +75,7 @@ class cbuf { dst += top_size; } memcpy(dst, _begin, size_to_read); - _begin += size_to_read; - if(_begin == _bufend) _begin = _buf; + _begin = wrap_if_bufend(_begin + size_to_read); return size_read; } @@ -87,7 +83,7 @@ class cbuf { if(room() == 0) return 0; *_end = c; - if(++_end == _bufend) _end = _buf; + _end = wrap_if_bufend(_end + 1); return 1; } @@ -103,8 +99,7 @@ class cbuf { src += top_size; } memcpy(_end, src, size_to_write); - _end += size_to_write; - if(_end == _bufend) _end = _buf; + _end = wrap_if_bufend(_end + size_to_write); return size_written; } @@ -114,6 +109,10 @@ class cbuf { } private: + inline char* wrap_if_bufend(char* ptr) { + return (ptr == _bufend) ? _buf : ptr; + } + size_t _size; char* _buf; char* _bufend; diff --git a/cores/esp8266/esp8266_peri.h b/cores/esp8266/esp8266_peri.h index 64c1f30b5..4fd057009 100644 --- a/cores/esp8266/esp8266_peri.h +++ b/cores/esp8266/esp8266_peri.h @@ -494,7 +494,7 @@ extern uint8_t esp8266_gpioToFn[16]; //SPI Phase Length Locations #define SPILCOMMAND 28 //4 bit in SPIxU2 default 7 (8bit) -#define SPILADDR 16 //6 bit in SPIxU1 default:23 (24bit) +#define SPILADDR 26 //6 bit in SPIxU1 default:23 (24bit) #define SPILDUMMY 0 //8 bit in SPIxU1 default:0 (0 cycles) #define SPILMISO 8 //9 bit in SPIxU1 default:0 (1bit) #define SPILMOSI 17 //9 bit in SPIxU1 default:0 (1bit) diff --git a/cores/esp8266/pgmspace.h b/cores/esp8266/pgmspace.h index 4ee599557..c9e83fa05 100644 --- a/cores/esp8266/pgmspace.h +++ b/cores/esp8266/pgmspace.h @@ -78,7 +78,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut (__extension__({ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \ - const uint32_t* __addr32 = reinterpret_cast(reinterpret_cast(__local)-__offset); \ + const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local)-__offset); \ uint8_t __result = ((*__addr32) >> (__offset * 8)); \ __result; \ })) @@ -87,7 +87,7 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut (__extension__({ \ PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \ ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \ - const uint32_t* __addr32 = reinterpret_cast(reinterpret_cast(__local) - __offset); \ + const uint32_t* __addr32 = (const uint32_t*)((const uint8_t*)(__local) - __offset); \ uint16_t __result = ((*__addr32) >> (__offset * 8)); \ __result; \ })) diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index 978e2ea0d..f1689cbfe 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -410,6 +410,17 @@ protected: FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode) { int mode = getSpiffsMode(openMode, accessMode); int fd = SPIFFS_open(&_fs, path, mode, 0); + if (fd < 0 && _fs.err_code == SPIFFS_ERR_DELETED && (openMode & OM_CREATE)) { + DEBUGV("SPIFFSImpl::open: fd=%d path=`%s` openMode=%d accessMode=%d err=%d, trying to remove\r\n", + fd, path, openMode, accessMode, _fs.err_code); + auto rc = SPIFFS_remove(&_fs, path); + if (rc != SPIFFS_OK) { + DEBUGV("SPIFFSImpl::open: SPIFFS_ERR_DELETED, but failed to remove path=`%s` openMode=%d accessMode=%d err=%d\r\n", + path, openMode, accessMode, _fs.err_code); + return FileImplPtr(); + } + fd = SPIFFS_open(&_fs, path, mode, 0); + } if (fd < 0) { DEBUGV("SPIFFSImpl::open: fd=%d path=`%s` openMode=%d accessMode=%d err=%d\r\n", fd, path, openMode, accessMode, _fs.err_code); diff --git a/doc/eclipse/makefile.init b/doc/eclipse/makefile.init new file mode 100644 index 000000000..76438d62c --- /dev/null +++ b/doc/eclipse/makefile.init @@ -0,0 +1,39 @@ +vecho := @echo +Q := @ + +PROJECT_NAME=project_name + +OTA_IP=192.168.254.100 +OTA_PORT=8266 + +SERIAL_PORT=COM3 +SERIAL_BAUD=230400 + +ARDUINO_BASE = D:/Coding/avr/Programme/arduino-nightly +ESP8266_BASE = $(ARDUINO_BASE)/hardware/esp8266com/esp8266 +ESP8266_TOOLS = $(ESP8266_BASE)/tools +XTENSA_TOOLS_ROOT = $(ESP8266_TOOLS)/xtensa-lx106-elf/bin + +PYTHON_BIN = python +ESPTOOL_PY_BIN = $(ESP8266_TOOLS)/esptool.py +ESPOTA_PY_BIN = $(ESP8266_TOOLS)/espota.py +ESPTOOL_BIN = $(ESP8266_TOOLS)/esptool/esptool.exe + +ota: + $(vecho) ota... + $(PYTHON_BIN) $(ESPOTA_PY_BIN) -i $(OTA_IP) -p $(OTA_PORT) --auth= -f ./$(PROJECT_NAME).bin + +ota_spiffs: + $(vecho) ota spiffs... + $(PYTHON_BIN) $(ESPOTA_PY_BIN) -i $(OTA_IP) -p $(OTA_PORT) --auth= -s -f ./$(PROJECT_NAME)_spiffs.bin + +erase_flash: + $(vecho) "Erase Flash" + $(PYTHON_BIN) $(ESPTOOL_PY_BIN) -p $(SERIAL_PORT) -b $(SERIAL_BAUD) erase_flash + +dumpmem: + $(vecho) "Read Flash need some time..." + $(PYTHON_BIN) $(ESPTOOL_PY_BIN) -p $(SERIAL_PORT) -b $(SERIAL_BAUD) read_flash 0 4194304 dump.bin + +objdump: + "$(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objdump" -S $(PROJECT_NAME).elf > $(PROJECT_NAME).dobj diff --git a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino index 7ffc78acd..eb7c02eff 100644 --- a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino +++ b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino @@ -71,7 +71,14 @@ void loop() { client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); - delay(10); + int timeout = millis() + 5000; + while (client.available() == 0) { + if (timeout - millis() < 0) { + Serial.println(">>> Client Timeout !"); + client.stop(); + return; + } + } // Read all the lines of the reply from server and print them to Serial while(client.available()){ diff --git a/libraries/ESP8266WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino b/libraries/ESP8266WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino new file mode 100644 index 000000000..accb37bf8 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino @@ -0,0 +1,68 @@ +/* + * This sketch sends a message to a TCP server + * + */ + +#include +#include + +ESP8266WiFiMulti WiFiMulti; + +void setup() { + Serial.begin(115200); + delay(10); + + // We start by connecting to a WiFi network + WiFiMulti.addAP("SSID", "passpasspass"); + + Serial.println(); + Serial.println(); + Serial.print("Wait for WiFi... "); + + while(WiFiMulti.run() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + delay(500); +} + + +void loop() { + const uint16_t port = 80; + const char * host = "192.168.1.1"; // ip or dns + + + + Serial.print("connecting to "); + Serial.println(host); + + // Use WiFiClient class to create TCP connections + WiFiClient client; + + if (!client.connect(host, port)) { + Serial.println("connection failed"); + Serial.println("wait 5 sec..."); + delay(5000); + return; + } + + // This will send the request to the server + client.print("Send this data to server"); + + //read back one line from server + String line = client.readStringUntil('\r'); + client.println(line); + + Serial.println("closing connection"); + client.stop(); + + Serial.println("wait 5 sec..."); + delay(5000); +} + diff --git a/libraries/ESP8266WiFi/src/include/UdpContext.h b/libraries/ESP8266WiFi/src/include/UdpContext.h index d9347fd34..708007036 100644 --- a/libraries/ESP8266WiFi/src/include/UdpContext.h +++ b/libraries/ESP8266WiFi/src/include/UdpContext.h @@ -1,9 +1,9 @@ -/* +/* UdpContext.h - UDP connection handling on top of lwIP Copyright (c) 2014 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 @@ -206,10 +206,10 @@ public: size_t max_size = _rx_buf->len - _rx_buf_offset; size = (size < max_size) ? size : max_size; DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset); - - os_memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, size); + + memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, size); _consume(size); - + return size; } @@ -236,7 +236,7 @@ public: { _reserve(_tx_buf_offset + size); } - + size_t left_to_copy = size; while(left_to_copy) { @@ -249,7 +249,7 @@ public: continue; } size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur; - os_memcpy(reinterpret_cast(_tx_buf_cur->payload) + used_cur, data, will_copy); + memcpy(reinterpret_cast(_tx_buf_cur->payload) + used_cur, data, will_copy); _tx_buf_offset += will_copy; left_to_copy -= will_copy; data += will_copy; @@ -259,18 +259,20 @@ public: void send(ip_addr_t* addr = 0, uint16_t port = 0) { - size_t orig_size = _tx_buf_head->tot_len; - size_t data_size = _tx_buf_offset; - size_t size_adjustment = orig_size - data_size; - for (pbuf* p = _tx_buf_head; p; p = p->next) - { - p->tot_len -= size_adjustment; - if (!p->next) - { - p->len = p->tot_len; - } + pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM); + uint8_t* dst = reinterpret_cast(tx_copy->payload); + for (pbuf* p = _tx_buf_head; p; p = p->next) { + size_t will_copy = (data_size < p->len) ? data_size : p->len; + memcpy(dst, p->payload, will_copy); + dst += will_copy; + data_size -= will_copy; } + pbuf_free(_tx_buf_head); + _tx_buf_head = 0; + _tx_buf_cur = 0; + _tx_buf_offset = 0; + if (!addr) { addr = &_dest_addr; @@ -282,30 +284,16 @@ public: _pcb->ttl = _multicast_ttl; } - udp_sendto(_pcb, _tx_buf_head, addr, port); - + udp_sendto(_pcb, tx_copy, addr, port); _pcb->ttl = old_ttl; - - for (pbuf* p = _tx_buf_head; p; p = p->next) - { - p->tot_len += size_adjustment; - if (!p->next) - { - p->len = p->tot_len; - } - } - - pbuf_free(_tx_buf_head); - _tx_buf_head = 0; - _tx_buf_cur = 0; - _tx_buf_offset = 0; + pbuf_free(tx_copy); } private: void _reserve(size_t size) { - const size_t pbuf_unit_size = 512; + const size_t pbuf_unit_size = 128; if (!_tx_buf_head) { _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); @@ -357,7 +345,7 @@ private: } - static void _s_recv(void *arg, + static void _s_recv(void *arg, udp_pcb *upcb, pbuf *p, ip_addr_t *addr, u16_t port) { diff --git a/tests/FSWrapper/FSWrapper.ino b/tests/FSWrapper/FSWrapper.ino index b152093d5..099065f4f 100644 --- a/tests/FSWrapper/FSWrapper.ino +++ b/tests/FSWrapper/FSWrapper.ino @@ -139,7 +139,15 @@ void setup() { fail("some files left after format"); } } - + { + File tmp = SPIFFS.open("/tmp.txt", "w"); + } + { + File tmp = SPIFFS.open("/tmp.txt", "w"); + if (!tmp) { + fail("failed to re-open empty file"); + } + } Serial.println("success"); }