diff --git a/Makefile b/Makefile index 4138886..702fc8d 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ ESPBAUD ?= 460800 # --------------- chipset configuration --------------- -# Pick your flash size: "512KB", "1MB", or "4MB" +# Pick your flash size: "512KB", "1MB", "2MB" or "4MB" FLASH_SIZE ?= 4MB # The pin assignments below are used when the settings in flash are invalid, they @@ -135,13 +135,12 @@ YUI_COMPRESSOR ?= yuicompressor-2.4.8.jar HTML_PATH = $(abspath ./html)/ WIFI_PATH = $(HTML_PATH)wifi/ -ESP_FLASH_MAX ?= 503808 # max bin file - ifeq ("$(FLASH_SIZE)","512KB") # Winbond 25Q40 512KB flash, typ for esp-01 thru esp-11 ESP_SPI_SIZE ?= 0 # 0->512KB (256KB+256KB) ESP_FLASH_MODE ?= 0 # 0->QIO ESP_FLASH_FREQ_DIV ?= 0 # 0->40Mhz +ESP_FLASH_MAX ?= 241664 # max bin file for 512KB flash: 236KB ET_FS ?= 4m # 4Mbit flash size in esptool flash command ET_FF ?= 40m # 40Mhz flash speed in esptool flash command ET_BLANK ?= 0x7E000 # where to flash blank.bin to erase wireless settings @@ -151,6 +150,7 @@ else ifeq ("$(FLASH_SIZE)","1MB") ESP_SPI_SIZE ?= 2 # 2->1MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80MHz +ESP_FLASH_MAX ?= 503808 # max bin file for 1MB flash: 492KB ET_FS ?= 8m # 8Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0xFE000 # where to flash blank.bin to erase wireless settings @@ -163,6 +163,7 @@ else ifeq ("$(FLASH_SIZE)","2MB") ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz +ESP_FLASH_MAX ?= 503808 # max bin file for 2MB flash: 492KB ET_FS ?= 16m # 16Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0x1FE000 # where to flash blank.bin to erase wireless settings @@ -175,6 +176,8 @@ else ESP_SPI_SIZE ?= 4 # 6->4MB (1MB+1MB) or 4->4MB (512KB+512KB) ESP_FLASH_MODE ?= 0 # 0->QIO, 2->DIO ESP_FLASH_FREQ_DIV ?= 15 # 15->80Mhz +ESP_FLASH_MAX ?= 503808 # max bin file for 512KB flash partition: 492KB +#ESP_FLASH_MAX ?= 1028096 # max bin file for 1MB flash partition: 1004KB ET_FS ?= 32m # 32Mbit flash size in esptool flash command ET_FF ?= 80m # 80Mhz flash speed in esptool flash command ET_BLANK ?= 0x3FE000 # where to flash blank.bin to erase wireless settings @@ -187,12 +190,17 @@ endif # Steps to release: create release on github, git pull, git describe --tags to verify you're # on the release tag, make release, upload esp-link.tgz into the release files #VERSION ?= "esp-link custom version" -DATE := $(shell date '+%F %T') +DATE := $(shell date '+%F') +TIME := $(shell date '+%T') BRANCH ?= $(shell if git diff --quiet HEAD; then git describe --tags; \ else git symbolic-ref --short HEAD; fi) SHA := $(shell if git diff --quiet HEAD; then git rev-parse --short HEAD | cut -d"/" -f 3; \ else echo "development"; fi) -VERSION ?=esp-link $(BRANCH) - $(DATE) - $(SHA) +VERSION ?=esp-link $(BRANCH) - $(DATE) - $(TIME) - $(SHA) + +BUILD_NUMBER_FILE = $(abspath ./build-number.txt) +BUILD_NUMBER_SRC = $(abspath ./user/buildnum.c) +BUILD_NUMBER := $(shell if ! test -f $(BUILD_NUMBER_FILE); then echo 1 > $(BUILD_NUMBER_FILE); fi; cat $(BUILD_NUMBER_FILE)) # Output directors to store intermediate compiled files # relative to the project directory @@ -227,15 +235,15 @@ MODULES += $(foreach sdir,$(LIBRARIES_DIR),$(wildcard $(sdir)/*)) EXTRA_INCDIR = include . # libraries used in this project, mainly provided by the SDK -LIBS = c gcc hal phy pp net80211 wpa main lwip crypto +LIBS = c gcc hal phy pp net80211 wpa main lwip crypto ssl # compiler flags using during compilation of source files -CFLAGS += -Os -ggdb -std=c99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \ +CFLAGS += -Os -ggdb -std=c99 -Werror -Wno-unused-value -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \ -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections \ -D__ets__ -DICACHE_FLASH -Wno-address -DFIRMWARE_SIZE=$(ESP_FLASH_MAX) \ -DMCU_RESET_PIN=$(MCU_RESET_PIN) -DMCU_ISP_PIN=$(MCU_ISP_PIN) \ -DLED_CONN_PIN=$(LED_CONN_PIN) -DLED_SERIAL_PIN=$(LED_SERIAL_PIN) \ - -DVERSION="$(VERSION)" + -DVERSION="$(VERSION)" -DBUILD_DATE="$(DATE)" -DBUILD_TIME="$(TIME)" -DBUILD_NUM="$(BUILD_NUMBER)" # linker flags used to generate the main object file LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--gc-sections @@ -343,13 +351,23 @@ all: echo_version checkdirs $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin echo_version: @echo VERSION: $(VERSION) +# Create an auto-incrementing build number. + @echo "#define VER_STR2(V) #V" > $(BUILD_NUMBER_SRC) + @echo "#define VER_STR(V) VER_STR2(V)" >> $(BUILD_NUMBER_SRC) + @echo "char esp_link_version[] = VER_STR(VERSION);" >> $(BUILD_NUMBER_SRC) + @echo "char esp_link_date[] = VER_STR(BUILD_DATE);" >> $(BUILD_NUMBER_SRC) + @echo "char esp_link_time[] = VER_STR(BUILD_TIME);" >> $(BUILD_NUMBER_SRC) + @echo "char esp_link_build[] = VER_STR(BUILD_NUM);" >> $(BUILD_NUMBER_SRC) + +# Build number file. Increment if firmware file changes +$(BUILD_NUMBER_FILE): $(USER1_OUT) + @if ! test -f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi + @echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE) $(USER1_OUT): $(APP_AR) $(LD_SCRIPT1) $(vecho) "LD $@" $(Q) $(LD) -L$(SDK_LIBDIR) -T$(LD_SCRIPT1) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@ - @echo Dump : $(OBJDP) -x $(USER1_OUT) - @echo Disass: $(OBJDP) -d -l -x $(USER1_OUT) -# $(Q) $(OBJDP) -x $(TARGET_OUT) | egrep espfs_img + $(Q) $(OBJDP) -S $(USER1_OUT) > $(addprefix $(BUILD_BASE)/,$(TARGET).dump) $(USER2_OUT): $(APP_AR) $(LD_SCRIPT2) $(vecho) "LD $@" @@ -360,16 +378,15 @@ $(FW_BASE): $(vecho) "FW $@" $(Q) mkdir -p $@ -$(FW_BASE)/user1.bin: $(USER1_OUT) $(FW_BASE) +$(FW_BASE)/user1.bin: $(USER1_OUT) $(FW_BASE) $(BUILD_NUMBER_FILE) $(Q) $(OBJCP) --only-section .text -O binary $(USER1_OUT) eagle.app.v6.text.bin $(Q) $(OBJCP) --only-section .data -O binary $(USER1_OUT) eagle.app.v6.data.bin $(Q) $(OBJCP) --only-section .rodata -O binary $(USER1_OUT) eagle.app.v6.rodata.bin $(Q) $(OBJCP) --only-section .irom0.text -O binary $(USER1_OUT) eagle.app.v6.irom0text.bin - ls -ls eagle*bin $(Q) COMPILE=gcc PATH=$(XTENSA_TOOLS_ROOT):$(PATH) python $(APPGEN_TOOL) $(USER1_OUT) 2 $(ESP_FLASH_MODE) $(ESP_FLASH_FREQ_DIV) $(ESP_SPI_SIZE) 0 $(Q) rm -f eagle.app.v6.*.bin $(Q) mv eagle.app.flash.bin $@ - @echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available" + @echo "** user1.bin uses $$(stat -c '%s' $@) bytes of" $(ESP_FLASH_MAX) "available =" $(shell expr $$(stat -c '%s' $@) \* 100 / $(ESP_FLASH_MAX) ) "%" $(Q) if [ $$(stat -c '%s' $@) -gt $$(( $(ESP_FLASH_MAX) )) ]; then echo "$@ too big!"; false; fi $(FW_BASE)/user2.bin: $(USER2_OUT) $(FW_BASE) @@ -410,60 +427,55 @@ tools/$(HTML_COMPRESSOR): else tools/$(HTML_COMPRESSOR): $(Q) mkdir -p tools - cd tools; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) - cd tools; wget https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR) + $(Q) if ! test -f tools/$(YUI_COMPRESSOR); then wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) -O tools/$(YUI_COMPRESSOR); fi + $(Q) if ! test -f tools/$(HTML_COMPRESSOR); then wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/htmlcompressor/$(HTML_COMPRESSOR) -O tools/$(HTML_COMPRESSOR); fi endif ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes") $(BUILD_BASE)/espfs_img.o: tools/$(HTML_COMPRESSOR) endif -$(BUILD_BASE)/espfs_img.o: html/ html/wifi/ espfs/mkespfsimage/mkespfsimage - $(Q) rm -rf html_compressed; mkdir html_compressed; mkdir html_compressed/wifi; - $(Q) cp -r html/*.ico html_compressed; - $(Q) cp -r html/*.css html_compressed; - $(Q) cp -r html/*.js html_compressed; - $(Q) cp -r html/wifi/*.png html_compressed/wifi; - $(Q) cp -r html/wifi/*.js html_compressed/wifi; +$(BUILD_BASE)/espfs_img.o: $(shell find html) espfs/mkespfsimage/mkespfsimage + $(Q) rm -rf html_compressed; mkdir -p html_compressed; cp -r html/* html_compressed; ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes") - $(Q) echo "Compression assets with htmlcompressor. This may take a while..." - $(Q) java -jar tools/$(HTML_COMPRESSOR) \ - -t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \ - -o $(abspath ./html_compressed)/ \ - $(HTML_PATH)head- \ - $(HTML_PATH)*.html - $(Q) java -jar tools/$(HTML_COMPRESSOR) \ - -t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \ - -o $(abspath ./html_compressed)/wifi/ \ - $(WIFI_PATH)*.html - $(Q) echo "Compression assets with yui-compressor. This may take a while..." + $(Q) echo "Compression assets with htmlcompressor. This is fast..." + $(Q) for file in `find html_compressed -type f -name "*.html"`; do \ + java -jar yui/$(HTML_COMPRESSOR) \ + -t html --remove-surrounding-spaces max --remove-quotes --remove-intertag-spaces \ + -o $$file $$file; \ + done + $(Q) echo "Compressing JS/CSS with yui-compressor. This may take a while..." $(Q) for file in `find html_compressed -type f -name "*.js"`; do \ - java -jar tools/$(YUI_COMPRESSOR) $$file --line-break 0 -o $$file; \ + java -jar yui/$(YUI_COMPRESSOR) $$file --line-break 0 -o $$file; \ done $(Q) for file in `find html_compressed -type f -name "*.css"`; do \ - java -jar tools/$(YUI_COMPRESSOR) $$file -o $$file; \ - done -else - $(Q) cp -r html/head- html_compressed; - $(Q) cp -r html/*.html html_compressed; - $(Q) cp -r html/wifi/*.html html_compressed/wifi; + java -jar yui/$(YUI_COMPRESSOR) $$file -o $$file; \ + done endif ifeq (,$(findstring mqtt,$(MODULES))) $(Q) rm -rf html_compressed/mqtt.html $(Q) rm -rf html_compressed/mqtt.js endif - $(Q) for file in `find html_compressed -type f -name "*.htm*"`; do \ - cat html_compressed/head- $$file >$${file}-; \ - mv $$file- $$file; \ - done - $(Q) rm html_compressed/head- + $(Q) echo "Now building espFS ..." $(Q) cd html_compressed; find . \! -name \*- | ../espfs/mkespfsimage/mkespfsimage > ../build/espfs.img; cd ..; - $(Q) ls -sl build/espfs.img + @echo "espFS image is $$(stat -c '%s' build/espfs.img) bytes =" $(shell expr $$(stat -c '%s' build/espfs.img) \* 100 / $$(du -sb html_compressed | { read first _ ; echo $$first; })) "% of uncompressed originals" $(Q) cd build; $(OBJCP) -I binary -O elf32-xtensa-le -B xtensa --rename-section .data=.espfs \ - espfs.img espfs_img.o; cd .. + espfs.img espfs_img.o; cd .. # edit the loader script to add the espfs section to the end of irom with a 4 byte alignment. # we also adjust the sizes of the segments 'cause we need more irom0 +# in the end the only thing that matters wrt size is that the whole shebang fits into the +# 236KB available (in a 512KB flash) +ifeq ("$(FLASH_SIZE)","512KB") +build/eagle.esphttpd1.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.512.app1.ld + $(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \ + -e '/^ irom0_0_seg/ s/2B000/38000/' \ + $(SDK_LDDIR)/eagle.app.v6.new.512.app1.ld >$@ +build/eagle.esphttpd2.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.512.app2.ld + $(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \ + -e '/^ irom0_0_seg/ s/2B000/38000/' \ + $(SDK_LDDIR)/eagle.app.v6.new.512.app2.ld >$@ +else build/eagle.esphttpd1.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.1024.app1.ld $(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \ -e '/^ irom0_0_seg/ s/6B000/7C000/' \ @@ -472,8 +484,9 @@ build/eagle.esphttpd2.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.1024.app2.ld $(Q) sed -e '/\.irom\.text/{' -e 'a . = ALIGN (4);' -e 'a *(.espfs)' -e '}' \ -e '/^ irom0_0_seg/ s/6B000/7C000/' \ $(SDK_LDDIR)/eagle.app.v6.new.1024.app2.ld >$@ +endif -espfs/mkespfsimage/mkespfsimage: espfs/mkespfsimage/ +espfs/mkespfsimage/mkespfsimage: espfs/mkespfsimage/*.c $(Q) $(MAKE) -C espfs/mkespfsimage GZIP_COMPRESSION="$(GZIP_COMPRESSION)" release: all diff --git a/esp-link/cgi.c b/esp-link/cgi.c index 96c03e9..20e7d2e 100644 --- a/esp-link/cgi.c +++ b/esp-link/cgi.c @@ -27,10 +27,11 @@ void ICACHE_FLASH_ATTR noCacheHeaders(HttpdConnData *connData, int code) { httpdStartResponse(connData, code); httpdHeader(connData, "Cache-Control", "no-cache, no-store, must-revalidate"); httpdHeader(connData, "Pragma", "no-cache"); - httpdHeader(connData, "Expires", "0"); + httpdHeader(connData, "Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); } void ICACHE_FLASH_ATTR jsonHeader(HttpdConnData *connData, int code) { + httpdStartResponse(connData, code); noCacheHeaders(connData, code); httpdHeader(connData, "Content-Type", "application/json"); httpdEndHeaders(connData); @@ -187,8 +188,6 @@ int ICACHE_FLASH_ATTR printGlobalInfo(char *buff, int buflen, char *token) { } #endif -extern char *esp_link_version; // in user_main.c - int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; // Connection aborted. Clean up. char buff[1024]; @@ -214,6 +213,7 @@ int ICACHE_FLASH_ATTR cgiMenu(HttpdConnData *connData) { "\"REST/MQTT\", \"/mqtt.html\", " #endif "\"Debug log\", \"/log.html\"" + "\"Firmware\", \"/flash/flash.html\"" " ], " "\"version\": \"%s\", " "\"name\": \"%s\"" diff --git a/esp-link/cgiflash.c b/esp-link/cgiflash.c index 4b9277d..937ed10 100644 --- a/esp-link/cgiflash.c +++ b/esp-link/cgiflash.c @@ -57,11 +57,11 @@ int ICACHE_FLASH_ATTR cgiGetFirmwareNext(HttpdConnData *connData) { } uint8 id = system_upgrade_userbin_check(); - httpdStartResponse(connData, 200); + noCacheHeaders(connData, 200); httpdHeader(connData, "Content-Type", "text/plain"); httpdHeader(connData, "Content-Length", "9"); httpdEndHeaders(connData); - char *next = id == 1 ? "user1.bin" : "user2.bin"; + char *next = (id == 1 ? "user1.bin" : "user2.bin"); httpdSend(connData, next, -1); DBG("Next firmware: %s (got %d)\n", next, id); return HTTPD_CGI_DONE; @@ -124,7 +124,7 @@ int ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { // erase next flash block if necessary if (address % SPI_FLASH_SEC_SIZE == 0){ - DBG("Flashing 0x%05x (id=%d)\n", address, 2 - id); + DBG("Flashing 0x%05X (id=%d)\n", address, 2 - id); spi_flash_erase_sector(address/SPI_FLASH_SEC_SIZE); } diff --git a/esp-link/cgiwifi.c b/esp-link/cgiwifi.c index afb6223..8aeea73 100644 --- a/esp-link/cgiwifi.c +++ b/esp-link/cgiwifi.c @@ -732,8 +732,8 @@ int ICACHE_FLASH_ATTR printWifiInfo(char *buff) { if (rssi > 0) rssi = 0; uint8 mac_addr[6]; uint8 apmac_addr[6]; - wifi_get_macaddr(0, mac_addr); - wifi_get_macaddr(1, apmac_addr); + wifi_get_macaddr(STATION_IF, mac_addr); + wifi_get_macaddr(SOFTAP_IF, apmac_addr); uint8_t chan = wifi_get_channel(); len = os_sprintf(buff, diff --git a/esp-link/main.c b/esp-link/main.c index 49a228a..6fbef41 100644 --- a/esp-link/main.c +++ b/esp-link/main.c @@ -64,6 +64,8 @@ should be placed above the URLs they protect. HttpdBuiltInUrl builtInUrls[] = { { "/", cgiRedirect, "/home.html" }, { "/menu", cgiMenu, NULL }, + {"/flash", cgiRedirect, "/flash/flash.html"}, + {"/flash/", cgiRedirect, "/flash/flash.html"}, { "/flash/next", cgiGetFirmwareNext, NULL }, { "/flash/upload", cgiUploadFirmware, NULL }, { "/flash/reboot", cgiRebootFirmware, NULL }, @@ -107,10 +109,6 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { } #endif -# define VERS_STR_STR(V) #V -# define VERS_STR(V) VERS_STR_STR(V) -char* esp_link_version = VERS_STR(VERSION); - // address of espfs binary blob extern uint32_t _binary_espfs_img_start; @@ -139,7 +137,7 @@ void user_init(void) { logInit(); // must come after init of uart // Say hello (leave some time to cause break in TX after boot loader's msg os_delay_us(10000L); - os_printf("\n\n** %s\n", esp_link_version); + os_printf("\n\n** %s, build %s\n", esp_link_version, esp_link_build); os_printf("Flash config restore %s\n", restoreOk ? "ok" : "*FAILED*"); // Status LEDs statusInit(); @@ -162,26 +160,26 @@ void user_init(void) { #endif struct rst_info *rst_info = system_get_rst_info(); - NOTICE("Reset cause: %d=%s", rst_info->reason, rst_codes[rst_info->reason]); - NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x", + NOTICE("Reset cause: %d=%s\n", rst_info->reason, rst_codes[rst_info->reason]); + NOTICE("exccause=%d epc1=0x%x epc2=0x%x epc3=0x%x excvaddr=0x%x depc=0x%x\n", rst_info->exccause, rst_info->epc1, rst_info->epc2, rst_info->epc3, rst_info->excvaddr, rst_info->depc); uint32_t fid = spi_flash_get_id(); - NOTICE("Flash map %s, manuf 0x%02X chip 0x%04X", flash_maps[system_get_flash_size_map()], + NOTICE("Flash map %s, manuf 0x%02X chip 0x%04X\n", flash_maps[system_get_flash_size_map()], fid & 0xff, (fid&0xff00)|((fid>>16)&0xff)); - NOTICE("** %s: ready, heap=%ld", esp_link_version, (unsigned long)system_get_free_heap_size()); + NOTICE("** %s: ready, heap=%ld\n", esp_link_version, (unsigned long)system_get_free_heap_size()); // Init SNTP service cgiServicesSNTPInit(); #ifdef MQTT if (flashConfig.mqtt_enable) { - NOTICE("initializing MQTT"); + NOTICE("initializing MQTT\n"); mqtt_client_init(); } #endif - NOTICE("initializing user application"); + NOTICE("initializing user application\n"); app_init(); - NOTICE("Waiting for work to do..."); + NOTICE("Waiting for work to do...\n"); #ifdef MEMLEAK_DEBUG system_show_malloc(); #endif diff --git a/html/console.html b/html/console.html index d84da72..119300a 100644 --- a/html/console.html +++ b/html/console.html @@ -1,25 +1,38 @@ + + + esp-link + + + + + +

Microcontroller Console

-

+

The Microcontroller console shows the last 1024 characters + received from UART0, to which a microcontroller is typically attached. + The UART is configured for 8 bits, no parity, 1 stop bit (8N1). +

+
Reset µC   Clear Log -   Baud: +   Baud (8N1): -   Fmt: 8N1 -

+
Console
@@ -56,49 +69,7 @@
- - + - + diff --git a/html/home.html b/html/home.html index 138222e..5745f91 100644 --- a/html/home.html +++ b/html/home.html @@ -1,3 +1,12 @@ + + + esp-link + + + + + +
JEELABS
@@ -6,150 +15,137 @@
-
- -
-
-

System overview

-
- - - - - - - - - -
-
-

Info

-

The JeeLabs esp-link firmware bridges the ESP8266 - serial port to WiFi and can - program microcontrollers over the serial port, in particular Arduinos, AVRs, and - NXP's LPC800 and other ARM processors. Typical avrdude command line to - program an Arduino:

-
- /home/arduino/hardware/tools/avrdude \
-   -DV -patmega328p \
-   -Pnet:esp-link.local:23 \
-   -carduino -b115200 \
-   -U flash:w:my_sketch.hex:i\
-   -C /home/arduino/hardware/tools/avrdude.conf -
-

where -Pnet:esp-link.local:23 tells avrdude to connect to port 23 of esp-link. - You can substitute the IP address of your esp-link for esp-link.local if necessary. - Please refer to - the online README - for up-to-date help.

+
+
+

System overview

+
+ + + + + + + + + +
+
+

Info

+

The JeeLabs esp-link firmware bridges the ESP8266 + serial port to WiFi and can + program microcontrollers over the serial port, in particular Arduinos, AVRs, and + NXP's LPC800 and other ARM processors. Typical avrdude command line to + program an Arduino:

+
+ /home/arduino/hardware/tools/avrdude \
+   -DV -patmega328p \
+   -Pnet:esp-link.local:23 \
+   -carduino -b115200 \
+   -U flash:w:my_sketch.hex:i\
+   -C /home/arduino/hardware/tools/avrdude.conf
+

where -Pnet:esp-link.local:23 tells avrdude to connect to port 23 of esp-link. + You can substitute the IP address of your esp-link for esp-link.local if necessary. + Please refer to + the online README + for up-to-date help.

- -
-
-

Pin assignment

-
- +
+
+

System details

+
+ + + + - - - +
+
+ + + +
+ +
-
-
- - + + diff --git a/html/log.html b/html/log.html index 884cf20..74c1e72 100644 --- a/html/log.html +++ b/html/log.html @@ -1,11 +1,19 @@ + + + esp-link + + + + + +

Debug Log

-

The debug log shows the most recent characters printed by the esp-link software itself to - its own debug log.

+

The debug log shows the most recent characters printed by the ESP-LINK software itself to its own debug log.

Refresh @@ -14,8 +22,11 @@

UART debug log: auto +   off +   on uart0 +   on uart1

@@ -23,38 +34,7 @@
- - + - + diff --git a/html/mqtt.html b/html/mqtt.html index 37b8179..993e034 100644 --- a/html/mqtt.html +++ b/html/mqtt.html @@ -1,3 +1,12 @@ + + + esp-link + + + + + +

REST & MQTT

@@ -92,13 +101,6 @@
- + - diff --git a/html/mqtt.js b/html/mqtt.js index 19c6930..fb6e7ce 100644 --- a/html/mqtt.js +++ b/html/mqtt.js @@ -1,3 +1,9 @@ +onLoad(function() { + fetchMqtt(); + bnd($("#mqtt-form"), "submit", changeMqtt); + bnd($("#mqtt-status-form"), "submit", changeMqttStatus); +}); + //===== MQTT cards function changeMqtt(e) { diff --git a/html/pure.css b/html/pure.css index b895c0e..de3beb1 100644 --- a/html/pure.css +++ b/html/pure.css @@ -693,8 +693,8 @@ this the same font stack that Normalize.css sets for the `body`. font-family: inherit; font-size: 100%; padding: 0.5em 1em; - color: #444; /* rgba not supported (IE 8) */ - color: rgba(0, 0, 0, 0.80); /* rgba supported */ + color: #fff; /* rgba not supported (IE 8) */ + color: rgba(f, f, f, 0.80); /* rgba supported */ border: 1px solid #999; /*IE 6/7/8*/ border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/ background-color: #E6E6E6; diff --git a/html/services.html b/html/services.html index 53f4fcc..69cce40 100644 --- a/html/services.html +++ b/html/services.html @@ -1,120 +1,121 @@ + + + esp-link + + + + + +

Services

-
-
-
-

- Syslog -
-

- +
+
+
+

+ mDNS +
+

+
-
-
-

- SNTP -
-

-
- + - diff --git a/html/services.js b/html/services.js index 56d799f..1aff66b 100644 --- a/html/services.js +++ b/html/services.js @@ -1,3 +1,10 @@ +onLoad(function() { + fetchServices(); + bnd($("#Syslog-form"), "submit", changeServices); + bnd($("#SNTP-form"), "submit", changeServices); + bnd($("#mDNS-form"), "submit", changeServices); +}); + function changeServices(e) { e.preventDefault(); var url = "services/update?1=1"; diff --git a/html/style.css b/html/style.css index 1bb11cd..6a2ae40 100644 --- a/html/style.css +++ b/html/style.css @@ -26,6 +26,8 @@ a:hover { background-color: #eee; padding: 1em; margin: 0.5em; + -moz-border-radius: 0.5em; + -webkit-border-radius: 0.5em; border-radius: 0.5em; border: 0px solid #000000; } @@ -39,7 +41,7 @@ a:hover { } .click-to-edit input, .click-to-edit textarea { color: black; - background-color: #eee; + background-color: #F0CAA6; width: 100%; } .click-to-edit span, .click-to-edit div { @@ -49,9 +51,9 @@ a:hover { width: 100%; color: #444; /* rgba not supported (IE 8) */ color: rgba(0, 0, 0, 0.80); /* rgba supported */ - border: 1px solid #999; /*IE 6/7/8*/ + border: 1px solid #111; /*IE 6/7/8*/ border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/ - background-color: #E6E6E6; + background-color: #CCCCCC; text-decoration: none; border-radius: 2px; } @@ -155,6 +157,9 @@ fieldset fields { /* Add transition to containers so they can push in and out */ #layout, #menu, .menu-link { -webkit-transition: all 0.2s ease-out; + -moz-transition: all 0.2s ease-out; + -ms-transition: all 0.2s ease-out; + -o-transition: all 0.2s ease-out; transition: all 0.2s ease-out; } @@ -186,10 +191,10 @@ div.tt { .content { margin: 0 auto; padding: 0 2em; - max-width: 800px; + /*max-width: 800px;*/ margin-bottom: 20px; line-height: 1.6em; - width: 100%; + /*width: 100%;*/ box-sizing: border-box; overflow: auto; } @@ -198,12 +203,12 @@ div.tt { margin: 0; color: #333; text-align: center; - padding: 2.5em 2em 0; + padding: 0.5em; border-bottom: 1px solid #eee; background-color: #fc0; } .header h1 { - margin: 0.2em 0; + margin: 0; font-size: 3em; font-weight: 300; } @@ -251,6 +256,8 @@ input.inline { /* Text console */ pre.console { background-color: #663300; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; border-radius: 5px; border: 0px solid #000000; color: #66ff66; @@ -495,6 +502,8 @@ pre.console a { height: 50px; width: 50px; -webkit-animation: rotation 1s infinite linear; + -moz-animation: rotation 1s infinite linear; + -o-animation: rotation 1s infinite linear; animation: rotation 1s infinite linear; border-left: 10px solid rgba(204, 51, 0, 0.15); border-right: 10px solid rgba(204, 51, 0, 0.15); @@ -518,6 +527,23 @@ pre.console a { } } +@-moz-keyframes rotation { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(359deg); + } +} +@-o-keyframes rotation { + from { + -o-transform: rotate(0deg); + } + to { + -o-transform: rotate(359deg); + } +} + @keyframes rotation { from { -webkit-transform: rotate(0deg); @@ -528,3 +554,36 @@ pre.console a { transform: rotate(359deg); } } + +a +{ + color: #5873DD; + font-family: Arial; + font-size: 10pt; + font-weight: bold; + text-decoration: none; +} + +a.btn +{ + white-space: nowrap; + text-align: center; + vertical-align: middle; + display: inline-block; + border-radius: 6px; + font-size: 16pt; + line-height: 1.33; + padding: 10px 10px; +} + +a.btn-yes +{ + background-color: #5CB85C; + color: white; +} + +a.btn-no +{ + background-color: #D9534F; + color: white; +} diff --git a/html/ui.js b/html/ui.js index aa66f69..4b4c582 100644 --- a/html/ui.js +++ b/html/ui.js @@ -330,6 +330,15 @@ function makeAjaxInput(klass, field) { eoff.setAttribute('hidden',''); domForEach(eon, function(el){ el.removeAttribute('hidden'); }); eon[0].select(); + old_hostname = eon[0].value; + return false; + } + + var just_close = function() + { + domForEach(eon, function(el){ el.setAttribute('hidden',''); }); + eoff.removeAttribute('hidden'); + setEditToClick(klass+"-"+field, old_hostname); return false; } @@ -347,9 +356,10 @@ function makeAjaxInput(klass, field) { } bnd(eoff, "click", function(){return enableEditToClick();}); - bnd(eon[0], "blur", function(){return submitEditToClick(eon[0].value);}); + bnd(eon[0], "blur", function(){return just_close();}); bnd(eon[0], "keyup", function(ev){ if ((ev||window.event).keyCode==13) return submitEditToClick(eon[0].value); + else if ((ev||window.event).keyCode==27) return just_close(); }); }); } @@ -369,11 +379,17 @@ function setEditToClick(klass, value) { //===== Notifications +var notifTimeout = null; function showWarning(text) { var el = $("#warning"); el.innerHTML = text; el.removeAttribute('hidden'); window.scrollTo(0, 0); + if (notifTimeout != null) clearTimeout(notifTimeout); + notifTimout = setTimeout(function() { + el.setAttribute('hidden', ''); + notifTimout = null; + }, 6000); } function hideWarning() { el = $("#warning").setAttribute('hidden', ''); diff --git a/html/wifi/wifiAp.html b/html/wifi/wifiAp.html index 41b3697..9a93f60 100644 --- a/html/wifi/wifiAp.html +++ b/html/wifi/wifiAp.html @@ -1,50 +1,74 @@ + + + esp-link + + + + + +

WiFi Soft-AP Configuration

-
-
-
-
+
+

Soft-AP State

-
-
+
- - - - - - - - - - + + + + + + + + + + -
-
-
- +
+
+
-

Soft-AP Settings

-
- - -
-
-
-
-
- - +
+ + +
+
+
+
+
+ - diff --git a/html/wifi/wifiAp.js b/html/wifi/wifiAp.js index 59dd6ce..1f74b98 100644 --- a/html/wifi/wifiAp.js +++ b/html/wifi/wifiAp.js @@ -7,7 +7,7 @@ specials["ap_beacon"] = "Beacon Interval"; function changeWifiMode(m) { blockScan = 1; hideWarning(); - ajaxSpin("POST", "setmode?mode=" + m, function(resp) { + ajaxSpin("POST", "/wifi/setmode?mode=" + m, function(resp) { showNotification("Mode changed"); window.setTimeout(getWifiInfo, 100); blockScan = 0; @@ -83,3 +83,28 @@ function fetchApSettings() { window.setTimeout(fetchApSettings, 1000); }); } + +function doApAdvanced() { + $('#AP_Settings-on').removeAttribute('hidden'); + $("#AP_Settings-off").setAttribute("hidden", ""); + $("#AP_Settings-roff").removeAttribute("checked"); +} + +function undoApAdvanced(){ + $("#AP_Settings-on").setAttribute("hidden", ""); + $("#AP_Settings-off").removeAttribute("hidden"); + $("#AP_Settings-roff").setAttribute("checked", ""); +} + +onLoad(function() { + // Show info about AP + getWifiInfo(); + // Fetch actual settings + fetchApSettings(); + // Hide advanced settings + undoApAdvanced(); + document.ap_form.ap.value='off'; + bnd($("#AP_Settings-ron"), "click", doApAdvanced); + bnd($("#AP_Settings-roff"), "click", undoApAdvanced); + bnd($("#AP_Settings-form"), "submit", changeApSettings); +}); diff --git a/html/wifi/wifiSta.html b/html/wifi/wifiSta.html index bdc6dca..14ffde7 100644 --- a/html/wifi/wifiSta.html +++ b/html/wifi/wifiSta.html @@ -1,47 +1,37 @@ + + + esp-link + + + + + +

WiFi Station Configuration

-
-
+
+

WiFi State

- - - - - - - - - + + + + + + + + +
- -
-
-

WiFi Association

- -
- To connect to a WiFi network, please select one of the detected networks, - enter the password, and hit the connect button... - -
Scanning...
- - - - -
-
-
-
+
+

Special Settings

Special settings, use with care! @@ -64,23 +54,30 @@
-
+
+
+
+
+

WiFi Association

+ +
+ To connect to a WiFi network - choose one of detected networks (or enter a SSID),
+ enter the password, and hit the CONNECT button...
+ +
Scanning...
+ + + + +
+
- - + - diff --git a/html/wifi/wifiSta.js b/html/wifi/wifiSta.js index 0ab167a..0257571 100644 --- a/html/wifi/wifiSta.js +++ b/html/wifi/wifiSta.js @@ -201,3 +201,12 @@ function doStatic() { $('#dhcp-off').removeAttribute('hidden'); $('#dhcp-on').setAttribute('hidden', ''); } + +onLoad(function() { + getWifiInfo(); + bnd($("#wifiform"), "submit", changeWifiAp); + bnd($("#specform"), "submit", changeSpecial); + bnd($("#dhcp-ron"), "click", doDhcp); + bnd($("#dhcp-roff"), "click", doStatic); + scanTimeout = window.setTimeout(scanAPs, 500); +}); diff --git a/httpd/auth.c b/httpd/auth.c index df14175..3cf6fd2 100644 --- a/httpd/auth.c +++ b/httpd/auth.c @@ -31,10 +31,10 @@ int ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData) { r=httpdGetHeader(connData, "Authorization", hdr, sizeof(hdr)); if (r && strncmp(hdr, "Basic", 5)==0) { - r=base64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass); + r=ubase64_decode(strlen(hdr)-6, hdr+6, sizeof(userpass), (unsigned char *)userpass); if (r<0) r=0; //just clean out string on decode error userpass[r]=0; //zero-terminate user:pass string -// os_printf("Auth: %s\n", userpass); +// DBG("Auth: %s\n", userpass); while (((AuthGetUserPw)(connData->cgiArg))(connData, no, user, AUTH_MAX_USER_LEN, pass, AUTH_MAX_PASS_LEN)) { //Check user/pass against auth header diff --git a/httpd/base64.c b/httpd/base64.c index 9d97a26..bba2730 100644 --- a/httpd/base64.c +++ b/httpd/base64.c @@ -39,7 +39,7 @@ static int ICACHE_FLASH_ATTR base64decode(const char in[4], char out[3]) { #endif /* decode a base64 string in one shot */ -int ICACHE_FLASH_ATTR base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) { +int ICACHE_FLASH_ATTR ubase64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out) { unsigned int ii, io; uint32_t v; unsigned int rem; diff --git a/httpd/base64.h b/httpd/base64.h index 4dc8621..d26b316 100644 --- a/httpd/base64.h +++ b/httpd/base64.h @@ -1,6 +1,6 @@ #ifndef BASE64_H #define BASE64_H -int base64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out); +int ubase64_decode(size_t in_len, const char *in, size_t out_len, unsigned char *out); #endif \ No newline at end of file diff --git a/httpd/httpd.c b/httpd/httpd.c index f3c5594..f3e8657 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -396,7 +396,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) { return; } else { - if (!(r == HTTPD_CGI_NOTFOUND || r == HTTPD_CGI_AUTHENTICATED)) { + if (r == HTTPD_CGI_NOTFOUND) { os_printf("%shandler for %s returned invalid result %d\n", connStr, conn->url, r); } //URL doesn't want to handle the request: either the data isn't found or there's no diff --git a/include/user_config.h b/include/user_config.h index 131e1b9..3c8bee2 100644 --- a/include/user_config.h +++ b/include/user_config.h @@ -37,7 +37,10 @@ // If defined, the default hostname for DHCP will include the chip ID to make it unique #undef CHIP_IN_HOSTNAME -extern char* esp_link_version; +extern char esp_link_version[]; +extern char esp_link_date[]; +extern char esp_link_time[]; +extern char esp_link_build[]; extern uint8_t UTILS_StrToIP(const char* str, void *ip); #endif