mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-22 21:23:07 +03:00
Merge remote-tracking branch 'remotes/esp8266/esp8266' into esp8266
This commit is contained in:
commit
8f72a4f05f
@ -112,6 +112,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 ####
|
||||
|
||||
@ -148,7 +149,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.)
|
||||
|
||||
|
75
boards.txt
75
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)
|
||||
@ -120,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
|
||||
@ -166,12 +181,13 @@ 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
|
||||
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
|
||||
@ -215,6 +231,57 @@ nodemcu.menu.UploadSpeed.512000.upload.speed=512000
|
||||
nodemcu.menu.UploadSpeed.921600=921600
|
||||
nodemcu.menu.UploadSpeed.921600.upload.speed=921600
|
||||
|
||||
##############################################################
|
||||
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_data_size=81920
|
||||
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.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
|
||||
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
|
||||
|
||||
##############################################################
|
||||
# wifio.name=Wifio
|
||||
#
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
### Tools
|
||||
|
||||
- SDK updated to 1.1.0 (#306)
|
||||
|
||||
|
||||
## 1.6.4-673-g8cd3697
|
||||
May 22, 2015
|
||||
|
@ -209,7 +209,6 @@ void loop(void);
|
||||
#include "WString.h"
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
#include "FileSystem.h"
|
||||
#include "Esp.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,388 +0,0 @@
|
||||
/*
|
||||
FileSystem.cpp - SPIFS implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. 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 "FileSystem.h"
|
||||
#include "Arduino.h"
|
||||
#include "spiffs/spiffs_esp8266.h"
|
||||
|
||||
// These addresses and sizes are defined in the linker script.
|
||||
// For each flash memory size there is a linker script variant
|
||||
// which sets spiffs location and size.
|
||||
extern "C" uint32_t _SPIFFS_start;
|
||||
extern "C" uint32_t _SPIFFS_end;
|
||||
extern "C" uint32_t _SPIFFS_page;
|
||||
extern "C" uint32_t _SPIFFS_block;
|
||||
|
||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
|
||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src);
|
||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size);
|
||||
|
||||
FSClass FS((uint32_t) &_SPIFFS_start, (uint32_t) &_SPIFFS_end, (uint32_t) &_SPIFFS_page, (uint32_t) &_SPIFFS_block, 4);
|
||||
|
||||
FSClass::FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFiles)
|
||||
: _beginAddress(beginAddress)
|
||||
, _endAddress(endAddress)
|
||||
, _pageSize(pageSize)
|
||||
, _blockSize(blockSize)
|
||||
, _maxOpenFiles(maxOpenFiles)
|
||||
, _fs({0})
|
||||
{
|
||||
}
|
||||
|
||||
int FSClass::_mountInternal(){
|
||||
if (_beginAddress == 0 || _beginAddress >= _endAddress){
|
||||
SPIFFS_API_DBG_E("Can't start file system, wrong address\r\n");
|
||||
return SPIFFS_ERR_NOT_CONFIGURED;
|
||||
}
|
||||
if(_pageSize == 0) _pageSize = 256;
|
||||
if(_blockSize == 0) _blockSize = 4096;
|
||||
|
||||
spiffs_config cfg = {0};
|
||||
cfg.phys_addr = _beginAddress;
|
||||
cfg.phys_size = _endAddress - _beginAddress;
|
||||
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE;
|
||||
cfg.log_block_size = _blockSize;
|
||||
cfg.log_page_size = _pageSize;
|
||||
cfg.hal_read_f = api_spiffs_read;
|
||||
cfg.hal_write_f = api_spiffs_write;
|
||||
cfg.hal_erase_f = api_spiffs_erase;
|
||||
|
||||
SPIFFS_API_DBG_V("FSClass::_mountInternal: start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
||||
|
||||
_work.reset(new uint8_t[2*_pageSize]);
|
||||
_fdsSize = 32 * _maxOpenFiles;
|
||||
_fds.reset(new uint8_t[_fdsSize]);
|
||||
_cacheSize = (32 + _pageSize) * _maxOpenFiles;
|
||||
_cache.reset(new uint8_t[_cacheSize]);
|
||||
|
||||
s32_t res = SPIFFS_mount(&_fs,
|
||||
&cfg,
|
||||
_work.get(),
|
||||
_fds.get(),
|
||||
_fdsSize,
|
||||
_cache.get(),
|
||||
_cacheSize,
|
||||
NULL);
|
||||
SPIFFS_API_DBG_V("FSClass::_mountInternal: %d\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool FSClass::mount() {
|
||||
if(SPIFFS_mounted(&_fs))
|
||||
return true;
|
||||
|
||||
int res = _mountInternal();
|
||||
if(res != SPIFFS_OK){
|
||||
int formated = SPIFFS_format(&_fs);
|
||||
if(formated != SPIFFS_OK)
|
||||
return false;
|
||||
res = _mountInternal();
|
||||
}
|
||||
return (res == SPIFFS_OK);
|
||||
}
|
||||
|
||||
// TODO: need to invalidate open file objects
|
||||
void FSClass::unmount() {
|
||||
if(SPIFFS_mounted(&_fs))
|
||||
SPIFFS_unmount(&_fs);
|
||||
}
|
||||
|
||||
bool FSClass::format() {
|
||||
if(!SPIFFS_mounted(&_fs)){
|
||||
_mountInternal();
|
||||
}
|
||||
SPIFFS_unmount(&_fs);
|
||||
int formated = SPIFFS_format(&_fs);
|
||||
if(formated != SPIFFS_OK)
|
||||
return false;
|
||||
return (_mountInternal() == SPIFFS_OK);
|
||||
}
|
||||
|
||||
bool FSClass::check() {
|
||||
return SPIFFS_check(&_fs) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::exists(char *filename) {
|
||||
spiffs_stat stat = {0};
|
||||
if (SPIFFS_stat(&_fs, filename, &stat) < 0)
|
||||
return false;
|
||||
return stat.name[0] != '\0';
|
||||
}
|
||||
|
||||
bool FSClass::create(char *filepath){
|
||||
return SPIFFS_creat(&_fs, filepath, 0) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::remove(char *filepath){
|
||||
return SPIFFS_remove(&_fs, filepath) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::rename(char *filename, char *newname) {
|
||||
return SPIFFS_rename(&_fs, filename, newname) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
size_t FSClass::totalBytes(){
|
||||
u32_t totalBytes;
|
||||
u32_t usedBytes;
|
||||
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||
return totalBytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t FSClass::usedBytes(){
|
||||
u32_t totalBytes;
|
||||
u32_t usedBytes;
|
||||
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||
return usedBytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSFile FSClass::open(char *filename, uint8_t mode) {
|
||||
if(strcmp(filename, "") == 0 ||
|
||||
strcmp(filename, "/") == 0)
|
||||
return FSFile(&_fs, "/");
|
||||
|
||||
int repeats = 0;
|
||||
bool notExist;
|
||||
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
|
||||
int res;
|
||||
|
||||
do{
|
||||
notExist = false;
|
||||
res = SPIFFS_open(&_fs, filename, (spiffs_flags)mode, 0);
|
||||
int code = SPIFFS_errno(&_fs);
|
||||
if (res < 0){
|
||||
SPIFFS_API_DBG_E("open errno %d\n", code);
|
||||
notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
|
||||
if (notExist && canRecreate)
|
||||
remove(filename); // fix for deleted files
|
||||
}
|
||||
} while (notExist && canRecreate && repeats++ < 3);
|
||||
|
||||
if(res){
|
||||
return FSFile(&_fs, res);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
FSFile FSClass::open(spiffs_dirent* entry, uint8_t mode){
|
||||
int res = SPIFFS_open_by_dirent(&_fs, entry, (spiffs_flags)mode, 0);
|
||||
if (res){
|
||||
return FSFile(&_fs, res);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
FSFile::FSFile()
|
||||
: _file(0)
|
||||
, _stats({0})
|
||||
, _fs(0)
|
||||
{
|
||||
}
|
||||
|
||||
FSFile::FSFile(spiffs* fs, String path)
|
||||
: _fs(fs)
|
||||
{
|
||||
if(path == "/"){
|
||||
_file = 0x1;
|
||||
os_sprintf((char*)_stats.name, "%s", (char*)path.c_str());
|
||||
_stats.size = 0;
|
||||
_stats.type = SPIFFS_TYPE_DIR;
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
} else {
|
||||
_file = SPIFFS_open(_fs, (char *)path.c_str(), (spiffs_flags)FSFILE_READ, 0);
|
||||
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||
}
|
||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FSFile::FSFile(spiffs* fs, file_t f)
|
||||
: _file(f)
|
||||
, _fs(fs)
|
||||
{
|
||||
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||
}
|
||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
}
|
||||
|
||||
void FSFile::close() {
|
||||
if (!_file)
|
||||
return;
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_closedir(&_dir);
|
||||
}
|
||||
if(os_strlen((char*)_stats.name) > 1)
|
||||
SPIFFS_close(_fs, _file);
|
||||
_file = 0;
|
||||
}
|
||||
|
||||
char * FSFile::name(){
|
||||
return (char*)_stats.name;
|
||||
}
|
||||
|
||||
bool FSFile::isDirectory(void) {
|
||||
return _stats.type == SPIFFS_TYPE_DIR;
|
||||
}
|
||||
|
||||
void FSFile::rewindDirectory() {
|
||||
if (!_file || !isDirectory())
|
||||
return;
|
||||
SPIFFS_closedir(&_dir);
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
|
||||
FSFile FSFile::openNextFile(){
|
||||
if (!_file || !isDirectory())
|
||||
return FSFile();
|
||||
struct spiffs_dirent e;
|
||||
struct spiffs_dirent *pe = &e;
|
||||
if ((pe = SPIFFS_readdir(&_dir, pe))){
|
||||
// TODO: store actual FS pointer
|
||||
return FS.open((char *)pe->name);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
uint32_t FSFile::size() {
|
||||
if(!_file)
|
||||
return 0;
|
||||
if(_stats.size)
|
||||
return _stats.size;
|
||||
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||
SPIFFS_lseek(_fs, _file, 0, SPIFFS_SEEK_END);
|
||||
_stats.size = SPIFFS_tell(_fs, _file);
|
||||
SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||
return _stats.size;
|
||||
}
|
||||
|
||||
int FSFile::available() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||
return size() - pos;
|
||||
}
|
||||
|
||||
uint32_t FSFile::seek(uint32_t pos) {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||
}
|
||||
|
||||
uint32_t FSFile::position() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_tell(_fs, _file);
|
||||
}
|
||||
|
||||
bool FSFile::eof() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_eof(_fs, _file);
|
||||
}
|
||||
|
||||
int FSFile::read(void *buf, uint16_t nbyte) {
|
||||
if (!_file || isDirectory())
|
||||
return -1;
|
||||
return SPIFFS_read(_fs, _file, buf, nbyte);
|
||||
}
|
||||
|
||||
int FSFile::read() {
|
||||
if (! _file || isDirectory())
|
||||
return -1;
|
||||
int val;
|
||||
if(SPIFFS_read(_fs, _file, &val, 1) != 1) return -1;
|
||||
return val;
|
||||
}
|
||||
|
||||
int FSFile::peek() {
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
int c = read();
|
||||
SPIFFS_lseek(_fs, _file, -1, SPIFFS_SEEK_CUR);
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t FSFile::write(const uint8_t *buf, size_t size){
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
int res = SPIFFS_write(_fs, _file, (uint8_t *)buf, size);
|
||||
return (res > 0)?(size_t)res:0;
|
||||
}
|
||||
|
||||
size_t FSFile::write(uint8_t val) {
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
return write(&val, 1);
|
||||
}
|
||||
|
||||
void FSFile::flush(){
|
||||
if (!_file || isDirectory())
|
||||
return;
|
||||
SPIFFS_fflush(_fs, _file);
|
||||
}
|
||||
|
||||
bool FSFile::remove(){
|
||||
if (!_file)
|
||||
return 0;
|
||||
close();
|
||||
return SPIFFS_remove(_fs, (char *)_stats.name) == 0;
|
||||
}
|
||||
|
||||
int FSFile::lastError(){
|
||||
return SPIFFS_errno(_fs);
|
||||
}
|
||||
|
||||
void FSFile::clearError(){
|
||||
_fs->err_code = SPIFFS_OK;
|
||||
}
|
||||
|
||||
|
||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
|
||||
SPIFFS_API_DBG_V("api_spiffs_read: 0x%08x len: %u\n", addr, size);
|
||||
flashmem_read(dst, addr, size);
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
|
||||
SPIFFS_API_DBG_V("api_spiffs_write: 0x%08x len: %u\n", addr, size);
|
||||
flashmem_write(src, addr, size);
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size){
|
||||
SPIFFS_API_DBG_V("api_spiffs_erase: 0x%08x len: %u\n", addr, size);
|
||||
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
||||
u32_t sect_last = flashmem_get_sector_of_address(addr+size);
|
||||
while( sect_first <= sect_last )
|
||||
if( !flashmem_erase_sector( sect_first ++ ) )
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
FileSystem.h - SPIFS implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. 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
|
||||
*/
|
||||
#ifndef _SPIFFS_CORE_FILESYSTEM_H_
|
||||
#define _SPIFFS_CORE_FILESYSTEM_H_
|
||||
|
||||
#include <memory>
|
||||
#include "spiffs/spiffs.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
#define FSFILE_READ SPIFFS_RDONLY
|
||||
#define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND )
|
||||
#define FSFILE_OVERWRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND | SPIFFS_TRUNC )
|
||||
|
||||
class FSFile : public Stream {
|
||||
private:
|
||||
spiffs_stat _stats;
|
||||
file_t _file;
|
||||
spiffs_DIR _dir;
|
||||
spiffs * _fs;
|
||||
|
||||
public:
|
||||
FSFile(spiffs* fs, String path);
|
||||
FSFile(spiffs* fs, file_t f);
|
||||
FSFile(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual int read();
|
||||
virtual int peek();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
int read(void *buf, uint16_t nbyte);
|
||||
uint32_t seek(uint32_t pos);
|
||||
uint32_t position();
|
||||
uint32_t size();
|
||||
bool eof();
|
||||
void close();
|
||||
bool remove();
|
||||
int lastError();
|
||||
void clearError();
|
||||
operator bool() { return _file > 0; }
|
||||
char * name();
|
||||
bool isDirectory(void);
|
||||
void rewindDirectory(void);
|
||||
FSFile openNextFile(void);
|
||||
|
||||
template<typename T> size_t write(T &src){
|
||||
const size_t bufferSize = 64;
|
||||
uint8_t obuf[bufferSize];
|
||||
size_t bytesWritten = 0;
|
||||
while (true){
|
||||
size_t available = src.available();
|
||||
if(!available)
|
||||
return bytesWritten;
|
||||
size_t willWrite = (available < bufferSize) ? available : bufferSize;
|
||||
src.read(obuf, willWrite);
|
||||
size_t cb = write(obuf, willWrite);
|
||||
if (cb != willWrite) {
|
||||
return bytesWritten;
|
||||
}
|
||||
bytesWritten += cb;
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
class FSClass {
|
||||
public:
|
||||
FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFiles);
|
||||
|
||||
bool mount();
|
||||
void unmount();
|
||||
bool format();
|
||||
bool check();
|
||||
bool exists(char *filename);
|
||||
bool create(char *filepath);
|
||||
bool remove(char *filepath);
|
||||
bool rename(char *filename, char *newname);
|
||||
size_t totalBytes();
|
||||
size_t usedBytes();
|
||||
size_t size(){ return _fs.cfg.phys_size; }
|
||||
size_t blockSize(){ return _fs.cfg.log_block_size; }
|
||||
size_t totalBlocks(){ return _fs.block_count; }
|
||||
size_t freeBlocks(){ return _fs.free_blocks; }
|
||||
size_t pageSize(){ return _fs.cfg.log_page_size; }
|
||||
size_t allocatedPages(){ return _fs.stats_p_allocated; }
|
||||
size_t deletedPages(){ return _fs.stats_p_deleted; }
|
||||
|
||||
FSFile open(char *filename, uint8_t mode = FSFILE_READ);
|
||||
FSFile open(spiffs_dirent* entry, uint8_t mode = FSFILE_READ);
|
||||
|
||||
protected:
|
||||
int _mountInternal();
|
||||
std::unique_ptr<uint8_t[]> _work;
|
||||
std::unique_ptr<uint8_t[]> _fds;
|
||||
size_t _fdsSize;
|
||||
std::unique_ptr<uint8_t[]> _cache;
|
||||
size_t _cacheSize;
|
||||
uint32_t _beginAddress;
|
||||
uint32_t _endAddress;
|
||||
uint32_t _pageSize;
|
||||
uint32_t _blockSize;
|
||||
uint32_t _maxOpenFiles;
|
||||
spiffs _fs;
|
||||
|
||||
|
||||
private:
|
||||
friend class FSFile;
|
||||
};
|
||||
|
||||
extern FSClass FS;
|
||||
|
||||
#endif
|
@ -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));
|
||||
|
@ -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){
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -1,164 +0,0 @@
|
||||
/****
|
||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
||||
* Created 2015 by Skurydin Alexey
|
||||
* http://github.com/anakod/Sming
|
||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
||||
****/
|
||||
|
||||
#include "spiffs_esp8266.h"
|
||||
#include "spi_flash.h"
|
||||
#include "esp8266_peri.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
/*
|
||||
FLASH ACCESS FUNCTIONS
|
||||
*/
|
||||
|
||||
//lowest level sector erase method
|
||||
bool flashmem_erase_sector( uint32_t sector_id ){
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
bool erased = spi_flash_erase_sector( sector_id ) == SPI_FLASH_RESULT_OK;
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
return erased;
|
||||
}
|
||||
|
||||
//lowest level data write method
|
||||
uint32_t flashmem_write_internal( const void *from, uint32_t toaddr, uint32_t size ){
|
||||
toaddr -= INTERNAL_FLASH_START_ADDRESS;
|
||||
SpiFlashOpResult r;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
|
||||
uint32_t *apbuf = NULL;
|
||||
if(((uint32_t)from) & blkmask){
|
||||
apbuf = (uint32_t *)os_malloc(size);
|
||||
if(!apbuf)
|
||||
return 0;
|
||||
os_memcpy(apbuf, from, size);
|
||||
}
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
r = spi_flash_write(toaddr, apbuf?(uint32 *)apbuf:(uint32 *)from, size);
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
if(apbuf)
|
||||
os_free(apbuf);
|
||||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
SPIFFS_API_DBG_E( "ERROR in flash_write: r=%d at %08X\n", ( int )r, ( unsigned )toaddr+INTERNAL_FLASH_START_ADDRESS );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//lowest level data read method
|
||||
uint32_t flashmem_read_internal( void *to, uint32_t fromaddr, uint32_t size ){
|
||||
fromaddr -= INTERNAL_FLASH_START_ADDRESS;
|
||||
SpiFlashOpResult r;
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
r = spi_flash_read(fromaddr, (uint32 *)to, size);
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
SPIFFS_API_DBG_E( "ERROR in flash_read: r=%d at %08X\n", ( int )r, ( unsigned )fromaddr+INTERNAL_FLASH_START_ADDRESS );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//mid level data write method
|
||||
uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size ){
|
||||
uint32_t temp, rest, ssize = size;
|
||||
unsigned i;
|
||||
char tmpdata[ INTERNAL_FLASH_WRITE_UNIT_SIZE ];
|
||||
const uint8_t *pfrom = ( const uint8_t* )from;
|
||||
const uint32_t blksize = INTERNAL_FLASH_WRITE_UNIT_SIZE;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
|
||||
|
||||
// Align the start
|
||||
if(toaddr & blkmask){
|
||||
rest = toaddr & blkmask;
|
||||
temp = toaddr & ~blkmask; // this is the actual aligned address
|
||||
// c_memcpy( tmpdata, ( const void* )temp, blksize );
|
||||
flashmem_read_internal( tmpdata, temp, blksize );
|
||||
for( i = rest; size && ( i < blksize ); i ++, size --, pfrom ++ )
|
||||
tmpdata[ i ] = *pfrom;
|
||||
flashmem_write_internal( tmpdata, temp, blksize );
|
||||
if( size == 0 )
|
||||
return ssize;
|
||||
toaddr = temp + blksize;
|
||||
}
|
||||
// The start address is now a multiple of blksize
|
||||
// Compute how many bytes we can write as multiples of blksize
|
||||
rest = size & blkmask;
|
||||
temp = size & ~blkmask;
|
||||
// Program the blocks now
|
||||
if(temp){
|
||||
flashmem_write_internal( pfrom, toaddr, temp );
|
||||
toaddr += temp;
|
||||
pfrom += temp;
|
||||
}
|
||||
// And the final part of a block if needed
|
||||
if(rest){
|
||||
// c_memcpy( tmpdata, ( const void* )toaddr, blksize );
|
||||
flashmem_read_internal( tmpdata, toaddr, blksize );
|
||||
for( i = 0; size && ( i < rest ); i ++, size --, pfrom ++ )
|
||||
tmpdata[ i ] = *pfrom;
|
||||
flashmem_write_internal( tmpdata, toaddr, blksize );
|
||||
}
|
||||
return ssize;
|
||||
}
|
||||
|
||||
//mid level data write method
|
||||
uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size ){
|
||||
uint32_t temp, rest, ssize = size;
|
||||
unsigned i;
|
||||
char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ];
|
||||
uint8_t *pto = ( uint8_t* )to;
|
||||
const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1;
|
||||
|
||||
// Align the start
|
||||
if(fromaddr & blkmask){
|
||||
rest = fromaddr & blkmask;
|
||||
temp = fromaddr & ~blkmask; // this is the actual aligned address
|
||||
flashmem_read_internal( tmpdata, temp, blksize );
|
||||
for( i = rest; size && ( i < blksize ); i ++, size --, pto ++ )
|
||||
*pto = tmpdata[ i ];
|
||||
|
||||
if( size == 0 )
|
||||
return ssize;
|
||||
fromaddr = temp + blksize;
|
||||
}
|
||||
// The start address is now a multiple of blksize
|
||||
// Compute how many bytes we can read as multiples of blksize
|
||||
rest = size & blkmask;
|
||||
temp = size & ~blkmask;
|
||||
// Program the blocks now
|
||||
if(temp){
|
||||
flashmem_read_internal( pto, fromaddr, temp );
|
||||
fromaddr += temp;
|
||||
pto += temp;
|
||||
}
|
||||
// And the final part of a block if needed
|
||||
if(rest){
|
||||
flashmem_read_internal( tmpdata, fromaddr, blksize );
|
||||
for( i = 0; size && ( i < rest ); i ++, size --, pto ++ )
|
||||
*pto = tmpdata[ i ];
|
||||
}
|
||||
return ssize;
|
||||
}
|
||||
|
||||
//shorthand when start and end addresses of the sector are not needed
|
||||
uint32_t flashmem_get_sector_of_address( uint32_t addr ){
|
||||
return (addr - INTERNAL_FLASH_START_ADDRESS) / INTERNAL_FLASH_SECTOR_SIZE;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/****
|
||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
||||
* Created 2015 by Skurydin Alexey
|
||||
* http://github.com/anakod/Sming
|
||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
||||
****/
|
||||
|
||||
#ifndef SYSTEM_FLASHMEM_H_
|
||||
#define SYSTEM_FLASHMEM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "spiffs.h"
|
||||
|
||||
/*******************
|
||||
The W25Q32BV array is organized into 16,384 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time.
|
||||
Pages can be erased in groups of 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block erase) or
|
||||
the entire chip (chip erase). The W25Q32BV has 1,024 erasable sectors and 64 erasable blocks respectively.
|
||||
The small 4KB sectors allow for greater flexibility in applications that require data and parameter storage.
|
||||
********************/
|
||||
|
||||
#define SPIFFS_API_DBG_V(fmt, ...) //os_printf(fmt, ##__VA_ARGS__)
|
||||
#define SPIFFS_API_DBG_E(fmt, ...) //os_printf("ERROR: " fmt , ##__VA_ARGS__)
|
||||
|
||||
#define INTERNAL_FLASH_SECTOR_SIZE 4096
|
||||
#define INTERNAL_FLASH_START_ADDRESS 0x40200000
|
||||
|
||||
#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4
|
||||
#define INTERNAL_FLASH_READ_UNIT_SIZE 4
|
||||
|
||||
extern uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size );
|
||||
extern uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size );
|
||||
extern bool flashmem_erase_sector( uint32_t sector_id );
|
||||
uint32_t flashmem_get_sector_of_address( uint32_t addr );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_FLASHMEM_H_ */
|
@ -1,273 +0,0 @@
|
||||
/*
|
||||
FSWebServer - Example WebServer with SPIFFS backend for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library 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
|
||||
|
||||
upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
!!! This will erase any previous SPIFFS data you may have!
|
||||
!!! Make Backups First !!!
|
||||
if you do not have it, get it at : <<<FILL THIS
|
||||
access the sample web page at http://esp8266fs.local
|
||||
edit the page by going to http://esp8266fs.local/edit
|
||||
|
||||
*/
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <FileSystem.h>
|
||||
|
||||
#define DBG_OUTPUT_PORT Serial
|
||||
|
||||
const char* ssid = "**********";
|
||||
const char* password = "**********";
|
||||
const char* hostname = "esp8266fs";
|
||||
|
||||
MDNSResponder mdns;
|
||||
ESP8266WebServer server(80);
|
||||
//holds the current upload
|
||||
FSFile fsUploadFile;
|
||||
|
||||
//format bytes
|
||||
char *formatBytes(size_t bytes){
|
||||
if (bytes < 1024){
|
||||
return (char *)String(String(bytes)+"B").c_str();
|
||||
} else if(bytes < (1024 * 1024)){
|
||||
return (char *)String(String(bytes/1024.0)+"KB").c_str();
|
||||
} else if(bytes < (1024 * 1024 * 1024)){
|
||||
return (char *)String(String(bytes/1024.0/1024.0)+"MB").c_str();
|
||||
} else {
|
||||
return (char *)String(String(bytes/1024.0/1024.0/1024.0)+"GB").c_str();
|
||||
}
|
||||
}
|
||||
|
||||
String getContentType(String filename){
|
||||
if(server.hasArg("download")) return "application/octet-stream";
|
||||
else if(filename.endsWith(".htm")) return "text/html";
|
||||
else if(filename.endsWith(".css")) return "text/css";
|
||||
else if(filename.endsWith(".js")) return "application/javascript";
|
||||
else if(filename.endsWith(".png")) return "image/png";
|
||||
else if(filename.endsWith(".gif")) return "image/gif";
|
||||
else if(filename.endsWith(".jpg")) return "image/jpeg";
|
||||
else if(filename.endsWith(".ico")) return "image/x-icon";
|
||||
else if(filename.endsWith(".xml")) return "text/xml";
|
||||
else if(filename.endsWith(".pdf")) return "application/x-pdf";
|
||||
else if(filename.endsWith(".zip")) return "application/x-zip";
|
||||
else if(filename.endsWith(".gz")) return "application/x-gzip";
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(String path){
|
||||
if(path.endsWith("/")) path += "index.htm";
|
||||
String contentType = getContentType(path);
|
||||
if(FS.exists((char *)(path+".gz").c_str()) || FS.exists((char *)path.c_str())){
|
||||
if(FS.exists((char *)(path+".gz").c_str()))
|
||||
path += ".gz";
|
||||
FSFile file = FS.open((char *)path.c_str());
|
||||
server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleFileUpdate(){
|
||||
if(server.uri() != "/edit") return;
|
||||
HTTPUpload& upload = server.upload();
|
||||
if(upload.status == UPLOAD_FILE_START){
|
||||
String filename = upload.filename;
|
||||
DBG_OUTPUT_PORT.print("Upload Name: "); DBG_OUTPUT_PORT.println(filename);
|
||||
fsUploadFile = FS.open((char *)filename.c_str(), FSFILE_OVERWRITE);
|
||||
filename = String();
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE){
|
||||
//DBG_OUTPUT_PORT.print("Upload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
|
||||
if(fsUploadFile)
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END){
|
||||
if(fsUploadFile)
|
||||
fsUploadFile.close();
|
||||
DBG_OUTPUT_PORT.print("Upload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFileDelete(){
|
||||
if(server.args() == 0) {
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
String path = server.arg(0);
|
||||
if(path == "/") {
|
||||
server.send(500, "text/plain", "BAD PATH");
|
||||
return;
|
||||
}
|
||||
if(!FS.exists((char *)(path.c_str()))) {
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
return;
|
||||
}
|
||||
FS.remove((char *)path.c_str());
|
||||
server.send(200, "text/plain", "");
|
||||
path = String();
|
||||
}
|
||||
|
||||
void handleFileCreate(){
|
||||
if(server.args() == 0) {
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
String path = server.arg(0);
|
||||
if(path == "/") {
|
||||
server.send(500, "text/plain", "BAD PATH");
|
||||
return;
|
||||
}
|
||||
if(FS.exists((char *)path.c_str())) {
|
||||
server.send(500, "text/plain", "FILE EXISTS");
|
||||
return;
|
||||
}
|
||||
FSFile file = FS.open((char *)path.c_str(), FSFILE_OVERWRITE);
|
||||
if(file)
|
||||
file.close();
|
||||
else {
|
||||
server.send(500, "text/plain", "CREATE FAILED");
|
||||
return;
|
||||
}
|
||||
server.send(200, "text/plain", "");
|
||||
path = String();
|
||||
}
|
||||
|
||||
void handleFileList() {
|
||||
if(!server.hasArg("dir")) {
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
String path = server.arg("dir");
|
||||
|
||||
FSFile entry;
|
||||
FSFile dir = FS.open((char *)path.c_str());
|
||||
path = String();
|
||||
if(!dir.isDirectory()){
|
||||
dir.close();
|
||||
server.send(500, "text/plain", "NOT DIR");
|
||||
return;
|
||||
}
|
||||
dir.rewindDirectory();
|
||||
|
||||
String output = "[";
|
||||
while(true){
|
||||
entry = dir.openNextFile();
|
||||
if (!entry)
|
||||
break;
|
||||
|
||||
if(!FS.exists(entry.name())){
|
||||
os_printf("Entry[%s] Not Exists!\n", entry.name());
|
||||
entry.remove();
|
||||
entry.close();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(output != "[")
|
||||
output += ',';
|
||||
output += "{\"type\":\"";
|
||||
output += (entry.isDirectory())?"dir":"file";
|
||||
output += "\",\"name\":\"";
|
||||
output += String(entry.name()).substring(1);
|
||||
output += "\"}";
|
||||
entry.close();
|
||||
}
|
||||
dir.close();
|
||||
|
||||
output += "]";
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
void setup(void){
|
||||
DBG_OUTPUT_PORT.begin(115200);
|
||||
DBG_OUTPUT_PORT.print("\n");
|
||||
|
||||
//SPIFFS INIT
|
||||
DBG_OUTPUT_PORT.printf("\n==== SPIFFS Info ====\n");
|
||||
DBG_OUTPUT_PORT.printf("FS Mount: %d\n", FS.mount());
|
||||
DBG_OUTPUT_PORT.printf("FS Size: %s\n", formatBytes(FS.size()));
|
||||
DBG_OUTPUT_PORT.printf("FS Bytes: total: %s, used: %s\n", formatBytes(FS.totalBytes()), formatBytes(FS.usedBytes()));
|
||||
DBG_OUTPUT_PORT.printf("FS Blocks: total: %d, free: %d, size: %s\n", FS.totalBlocks(), FS.freeBlocks(), formatBytes(FS.blockSize()));
|
||||
DBG_OUTPUT_PORT.printf("FS Pages: allocated: %d, deleted: %d, size: %s\n", FS.allocatedPages(), FS.deletedPages(), formatBytes(FS.pageSize()));
|
||||
FSFile entry;
|
||||
FSFile dir = FS.open((char *)"/");
|
||||
while(true){
|
||||
entry = dir.openNextFile();
|
||||
if (!entry) break;
|
||||
DBG_OUTPUT_PORT.printf("FS File: %s, type: %s, size: %s\n", entry.name(), (entry.isDirectory())?"dir":"file", formatBytes(entry.size()));
|
||||
entry.close();
|
||||
}
|
||||
dir.close();
|
||||
DBG_OUTPUT_PORT.printf("\n");
|
||||
|
||||
//WIFI INIT
|
||||
DBG_OUTPUT_PORT.printf("Connecting to %s\n", ssid);
|
||||
WiFi.begin(ssid, password);
|
||||
if(WiFi.waitForConnectResult() != WL_CONNECTED){
|
||||
DBG_OUTPUT_PORT.printf("Could not connect to %s\n", ssid);
|
||||
while(1) delay(500);
|
||||
}
|
||||
DBG_OUTPUT_PORT.print("Connected! IP address: ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
|
||||
//mDNS INIT
|
||||
if (mdns.begin(hostname, WiFi.localIP()))
|
||||
DBG_OUTPUT_PORT.printf("mDNS responder started for %s.local\n", hostname);
|
||||
|
||||
//SERVER INIT
|
||||
//list directory
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
//load editor
|
||||
server.on("/edit", HTTP_GET, [](){
|
||||
if(!handleFileRead("/edit.htm")) server.send(404, "text/plain", "FileNotFound");
|
||||
});
|
||||
//create file
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
//delete file
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
//called after file upload
|
||||
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); });
|
||||
//called when a file is received inside POST data
|
||||
server.onFileUpload(handleFileUpdate);
|
||||
|
||||
//called when the url is not defined here
|
||||
//use it to load content from SPIFFS
|
||||
server.onNotFound([](){
|
||||
if(!handleFileRead(server.uri()))
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
});
|
||||
|
||||
//get heap status, analog input value and all GPIO statuses in one json call
|
||||
server.on("/all", HTTP_GET, [](){
|
||||
String json = "{";
|
||||
json += "\"heap\":"+String(ESP.getFreeHeap());
|
||||
json += ", \"analog\":"+String(analogRead(A0));
|
||||
json += ", \"gpio\":"+String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
|
||||
json += "}";
|
||||
server.send(200, "text/json", json);
|
||||
json = String();
|
||||
});
|
||||
server.begin();
|
||||
DBG_OUTPUT_PORT.println("HTTP server started");
|
||||
|
||||
}
|
||||
|
||||
void loop(void){
|
||||
server.handleClient();
|
||||
}
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
@ -1,100 +0,0 @@
|
||||
<!--
|
||||
FSWebServer - Example Index Page
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library 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
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
@ -1,512 +0,0 @@
|
||||
<!--
|
||||
FSWebServer - SPIFFS Editor/Manager
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library 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
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>ESP Editor</title>
|
||||
<style type="text/css" media="screen">
|
||||
.cm {
|
||||
z-index: 300;
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
border: 1px solid #444;
|
||||
background-color: #F5F5F5;
|
||||
display: none;
|
||||
box-shadow: 0 0 10px rgba( 0, 0, 0, .4 );
|
||||
font-size: 12px;
|
||||
font-family: sans-serif;
|
||||
font-weight:bold;
|
||||
}
|
||||
.cm ul {
|
||||
list-style: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.cm li {
|
||||
position: relative;
|
||||
min-width: 60px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cm span {
|
||||
color: #444;
|
||||
display: inline-block;
|
||||
padding: 6px;
|
||||
}
|
||||
.cm li:hover { background: #444; }
|
||||
.cm li:hover span { color: #EEE; }
|
||||
.tvu ul, .tvu li {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.tvu input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
}
|
||||
.tvu {
|
||||
font: normal 12px Verdana, Arial, Sans-serif;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
color: #444;
|
||||
line-height: 16px;
|
||||
}
|
||||
.tvu span {
|
||||
margin-bottom:5px;
|
||||
padding: 0 0 0 18px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADoSURBVBgZBcExblNBGAbA2ceegTRBuIKOgiihSZNTcC5LUHAihNJR0kGKCDcYJY6D3/77MdOinTvzAgCw8ysThIvn/VojIyMjIyPP+bS1sUQIV2s95pBDDvmbP/mdkft83tpYguZq5Jh/OeaYh+yzy8hTHvNlaxNNczm+la9OTlar1UdA/+C2A4trRCnD3jS8BB1obq2Gk6GU6QbQAS4BUaYSQAf4bhhKKTFdAzrAOwAxEUAH+KEM01SY3gM6wBsEAQB0gJ+maZoC3gI6iPYaAIBJsiRmHU0AALOeFC3aK2cWAACUXe7+AwO0lc9eTHYTAAAAAElFTkSuQmCC') no-repeat;
|
||||
background-position: 0px 0px;
|
||||
}
|
||||
.tvu span:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0){
|
||||
.tvu{
|
||||
-webkit-animation: webkit-adjacent-element-selector-bugfix infinite 1s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes webkit-adjacent-element-selector-bugfix {
|
||||
from {
|
||||
padding: 0;
|
||||
}
|
||||
to {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#uploader {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height:28px;
|
||||
line-height: 24px;
|
||||
padding-left: 10px;
|
||||
background-color: #444;
|
||||
color:#EEE;
|
||||
}
|
||||
#tree {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width:160px;
|
||||
padding: 8px;
|
||||
}
|
||||
#editor, #preview {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 160px;
|
||||
border-left:1px solid #EEE;
|
||||
}
|
||||
#preview {
|
||||
background-color: #EEE;
|
||||
padding:5px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function createFileUploader(element, tree, editor){
|
||||
var xmlHttp;
|
||||
var input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.multiple = false;
|
||||
input.name = "data";
|
||||
document.getElementById(element).appendChild(input);
|
||||
var path = document.createElement("input");
|
||||
path.id = "upload-path";
|
||||
path.type = "text";
|
||||
path.name = "path";
|
||||
path.defaultValue = "/";
|
||||
document.getElementById(element).appendChild(path);
|
||||
var button = document.createElement("button");
|
||||
button.innerHTML = 'Upload';
|
||||
document.getElementById(element).appendChild(button);
|
||||
var mkfile = document.createElement("button");
|
||||
mkfile.innerHTML = 'MkDir';
|
||||
document.getElementById(element).appendChild(mkfile);
|
||||
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
else {
|
||||
tree.refreshPath(path.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
function createPath(p){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("path", p);
|
||||
xmlHttp.open("PUT", "/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
mkfile.onclick = function(e){
|
||||
if(path.value.indexOf(".") === -1) return;
|
||||
createPath(path.value);
|
||||
editor.loadUrl(path.value);
|
||||
};
|
||||
button.onclick = function(e){
|
||||
if(input.files.length === 0){
|
||||
return;
|
||||
}
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", input.files[0], path.value);
|
||||
xmlHttp.open("POST", "/edit");
|
||||
xmlHttp.send(formData);
|
||||
};
|
||||
input.onchange = function(e){
|
||||
if(input.files.length === 0) return;
|
||||
var filename = input.files[0].name;
|
||||
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
|
||||
var name = /(.*)\.[^.]+$/.exec(filename)[1];
|
||||
if(typeof name !== undefined){
|
||||
filename = name;
|
||||
}
|
||||
if(typeof ext !== undefined){
|
||||
if(ext === "html") ext = "htm";
|
||||
else if(ext === "jpeg") ext = "jpg";
|
||||
filename = filename + "." + ext;
|
||||
}
|
||||
if(path.value === "/" || path.value.lastIndexOf("/") === 0){
|
||||
path.value = "/"+filename;
|
||||
} else {
|
||||
path.value = path.value.substring(0, path.value.lastIndexOf("/")+1)+filename;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createTree(element, editor){
|
||||
var preview = document.getElementById("preview");
|
||||
var treeRoot = document.createElement("div");
|
||||
treeRoot.className = "tvu";
|
||||
document.getElementById(element).appendChild(treeRoot);
|
||||
|
||||
function loadDownload(path){
|
||||
document.getElementById('download-frame').src = path+"?download=true";
|
||||
}
|
||||
|
||||
function loadPreview(path){
|
||||
document.getElementById("editor").style.display = "none";
|
||||
preview.style.display = "block";
|
||||
preview.innerHTML = '<img src="'+path+'?_cb='+Date.now()+'" style="max-width:100%; max-height:100%; margin:auto; display:block;" />';
|
||||
}
|
||||
|
||||
function fillFileMenu(el, path){
|
||||
var list = document.createElement("ul");
|
||||
el.appendChild(list);
|
||||
var action = document.createElement("li");
|
||||
list.appendChild(action);
|
||||
if(isTextFile(path)){
|
||||
action.innerHTML = "<span>Edit</span>";
|
||||
action.onclick = function(e){
|
||||
editor.loadUrl(path);
|
||||
if(document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
} else if(isImageFile(path)){
|
||||
action.innerHTML = "<span>Preview</span>";
|
||||
action.onclick = function(e){
|
||||
loadPreview(path);
|
||||
if(document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
var download = document.createElement("li");
|
||||
list.appendChild(download);
|
||||
download.innerHTML = "<span>Download</span>";
|
||||
download.onclick = function(e){
|
||||
loadDownload(path);
|
||||
if(document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
var delFile = document.createElement("li");
|
||||
list.appendChild(delFile);
|
||||
delFile.innerHTML = "<span>Delete</span>";
|
||||
delFile.onclick = function(e){
|
||||
httpDelete(path);
|
||||
if(document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(el);
|
||||
};
|
||||
}
|
||||
|
||||
function showContextMenu(e, path, isfile){
|
||||
var divContext = document.createElement("div");
|
||||
var scrollTop = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
|
||||
var scrollLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;
|
||||
var left = event.clientX + scrollLeft;
|
||||
var top = event.clientY + scrollTop;
|
||||
divContext.className = 'cm';
|
||||
divContext.style.display = 'block';
|
||||
divContext.style.left = left + 'px';
|
||||
divContext.style.top = top + 'px';
|
||||
fillFileMenu(divContext, path);
|
||||
document.body.appendChild(divContext);
|
||||
var width = divContext.offsetWidth;
|
||||
var height = divContext.offsetHeight;
|
||||
divContext.onmouseout = function(e){
|
||||
if(e.clientX < left || e.clientX > (left + width) || e.clientY < top || e.clientY > (top + height)){
|
||||
if(document.body.getElementsByClassName('cm').length > 0) document.body.removeChild(divContext);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createTreeLeaf(path, name, size){
|
||||
var leaf = document.createElement("li");
|
||||
leaf.id = (((path == "/")?"":path)+"/"+name);
|
||||
var label = document.createElement("span");
|
||||
label.innerText = name;
|
||||
leaf.appendChild(label);
|
||||
leaf.onclick = function(e){
|
||||
if(isTextFile(leaf.id.toLowerCase())){
|
||||
editor.loadUrl(leaf.id);
|
||||
} else if(isImageFile(leaf.id.toLowerCase())){
|
||||
loadPreview(leaf.id);
|
||||
}
|
||||
};
|
||||
leaf.oncontextmenu = function(e){
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
showContextMenu(e, leaf.id, true);
|
||||
};
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function addList(parent, path, items){
|
||||
var list = document.createElement("ul");
|
||||
parent.appendChild(list);
|
||||
var ll = items.length;
|
||||
for(var i = 0; i < ll; i++){
|
||||
if(items[i].type === "file")
|
||||
list.appendChild(createTreeLeaf(path, items[i].name, items[i].size));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function isTextFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "txt":
|
||||
case "htm":
|
||||
case "js":
|
||||
case "c":
|
||||
case "cpp":
|
||||
case "css":
|
||||
case "xml":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isImageFile(path){
|
||||
var ext = /(?:\.([^.]+))?$/.exec(path)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "png":
|
||||
case "jpg":
|
||||
case "gif":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.refreshPath = function(path){
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
};
|
||||
|
||||
function delCb(path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200){
|
||||
alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
} else {
|
||||
treeRoot.removeChild(treeRoot.childNodes[0]);
|
||||
httpGet(treeRoot, "/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpDelete(filename){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = delCb(filename);
|
||||
var formData = new FormData();
|
||||
formData.append("path", filename);
|
||||
xmlHttp.open("DELETE", "/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
|
||||
function getCb(parent, path){
|
||||
return function(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status == 200) addList(parent, path, JSON.parse(xmlHttp.responseText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpGet(parent, path){
|
||||
xmlHttp = new XMLHttpRequest(parent, path);
|
||||
xmlHttp.onreadystatechange = getCb(parent, path);
|
||||
xmlHttp.open("GET", "/list?dir="+path, true);
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
httpGet(treeRoot, "/");
|
||||
return this;
|
||||
}
|
||||
|
||||
function createEditor(element, file, lang, theme, type){
|
||||
function getLangFromFilename(filename){
|
||||
var lang = "plain";
|
||||
var ext = /(?:\.([^.]+))?$/.exec(filename)[1];
|
||||
if(typeof ext !== undefined){
|
||||
switch(ext){
|
||||
case "txt": lang = "plain"; break;
|
||||
case "htm": lang = "html"; break;
|
||||
case "js": lang = "javascript"; break;
|
||||
case "c": lang = "c_cpp"; break;
|
||||
case "cpp": lang = "c_cpp"; break;
|
||||
case "css":
|
||||
case "scss":
|
||||
case "php":
|
||||
case "html":
|
||||
case "json":
|
||||
case "xml":
|
||||
lang = ext;
|
||||
}
|
||||
}
|
||||
return lang;
|
||||
}
|
||||
|
||||
if(typeof file === "undefined") file = "/index.htm";
|
||||
|
||||
if(typeof lang === "undefined"){
|
||||
lang = getLangFromFilename(file);
|
||||
}
|
||||
|
||||
if(typeof theme === "undefined") theme = "textmate";
|
||||
|
||||
if(typeof type === "undefined"){
|
||||
type = "text/"+lang;
|
||||
if(lang === "c_cpp") type = "text/plain";
|
||||
}
|
||||
|
||||
var xmlHttp = null;
|
||||
var editor = ace.edit(element);
|
||||
function httpPostProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||
}
|
||||
}
|
||||
function httpPost(filename, data, type){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpPostProcessRequest;
|
||||
var formData = new FormData();
|
||||
formData.append("data", new Blob([data], { type: type }), filename);
|
||||
xmlHttp.open("POST", "/edit");
|
||||
xmlHttp.send(formData);
|
||||
}
|
||||
function httpGetProcessRequest(){
|
||||
if (xmlHttp.readyState == 4){
|
||||
document.getElementById("preview").style.display = "none";
|
||||
document.getElementById("editor").style.display = "block";
|
||||
if(xmlHttp.status == 200) editor.setValue(xmlHttp.responseText);
|
||||
else editor.setValue("");
|
||||
editor.clearSelection();
|
||||
}
|
||||
}
|
||||
function httpGet(theUrl){
|
||||
xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.onreadystatechange = httpGetProcessRequest;
|
||||
xmlHttp.open("GET", theUrl, true);
|
||||
xmlHttp.send(null);
|
||||
}
|
||||
|
||||
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
|
||||
editor.setTheme("ace/theme/"+theme);
|
||||
editor.$blockScrolling = Infinity;
|
||||
editor.getSession().setUseSoftTabs(true);
|
||||
editor.getSession().setTabSize(2);
|
||||
editor.setHighlightActiveLine(true);
|
||||
editor.setShowPrintMargin(false);
|
||||
editor.commands.addCommand({
|
||||
name: 'saveCommand',
|
||||
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
||||
exec: function(editor) {
|
||||
httpPost(file, editor.getValue()+"", type);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'undoCommand',
|
||||
bindKey: {win: 'Ctrl-Z', mac: 'Command-Z'},
|
||||
exec: function(editor) {
|
||||
editor.getSession().getUndoManager().undo(false);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
editor.commands.addCommand({
|
||||
name: 'redoCommand',
|
||||
bindKey: {win: 'Ctrl-Shift-Z', mac: 'Command-Shift-Z'},
|
||||
exec: function(editor) {
|
||||
editor.getSession().getUndoManager().redo(false);
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
httpGet(file);
|
||||
editor.loadUrl = function(filename){
|
||||
file = filename;
|
||||
lang = getLangFromFilename(file);
|
||||
type = "text/"+lang;
|
||||
if(lang !== "plain") editor.getSession().setMode("ace/mode/"+lang);
|
||||
httpGet(file);
|
||||
};
|
||||
return editor;
|
||||
}
|
||||
function onBodyLoad(){
|
||||
var vars = {};
|
||||
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; });
|
||||
var editor = createEditor("editor", vars.file, vars.lang, vars.theme);
|
||||
var tree = createTree("tree", editor);
|
||||
createFileUploader("uploader", tree, editor);
|
||||
};
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.9/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
</head>
|
||||
<body onload="onBodyLoad();">
|
||||
<div id="uploader"></div>
|
||||
<div id="tree"></div>
|
||||
<div id="editor"></div>
|
||||
<div id="preview" style="display:none;"></div>
|
||||
<iframe id=download-frame style='display:none;'></iframe>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
@ -1,281 +0,0 @@
|
||||
/*
|
||||
FSWebServer - Sample Graphing Library
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library 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
|
||||
*/
|
||||
function ce(t){ return document.createElement(t); }
|
||||
function ac(a,b){ a.appendChild(b); }
|
||||
|
||||
function createGraph(el, t, w, h, l, m, ib, tc, cb){
|
||||
if(typeof el === "undefined" || !el) return null;
|
||||
if(typeof ib === "undefined" || !ib) ib = false;
|
||||
w = (w>360)?w:360;
|
||||
h = (h<100)?100:h;
|
||||
var vs = new Array();
|
||||
var bgc = "black";
|
||||
var lc = (typeof tc === "undefined" && tc)?"yellow":tc;
|
||||
var bc = "#444";
|
||||
var vcb = (typeof cb === "undefined" && cb)?null:cb;
|
||||
var minV = m;
|
||||
var maxV = 0;
|
||||
var sv = 1;
|
||||
var ov = l;
|
||||
var gh = h+20;
|
||||
|
||||
el.style.display = "block";
|
||||
el.style.backgroundColor = "#eee";
|
||||
el.style.border = "1px solid "+bc;
|
||||
el.style.padding = "5px";
|
||||
el.style.margin = "5px";
|
||||
el.style.width = (w+2)+"px";
|
||||
|
||||
var g = ce("canvas");
|
||||
g.style.border = "1px solid "+bc;
|
||||
g.style.marginTop = "5px";
|
||||
g.width = w;
|
||||
g.height = gh;
|
||||
|
||||
var c = g.getContext("2d");
|
||||
|
||||
var sl = ce("span");
|
||||
sl.innerText = "Scale: ";
|
||||
sl.style.paddingLeft = "5px";
|
||||
|
||||
var st = ce("input");
|
||||
st.type = "text";
|
||||
st.size = 3;
|
||||
st.value = sv;
|
||||
st.onchange = function(e){ sv = st.value; };
|
||||
|
||||
var sm = ce("button");
|
||||
sm.innerText = "-";
|
||||
sm.onclick = function(e){ if(sv > 1) sv--; st.value = sv; };
|
||||
|
||||
var sp = ce("button");
|
||||
sp.innerText = "+";
|
||||
sp.onclick = function(e){ sv++; st.value = parseInt(sv); };
|
||||
|
||||
var ol = ce("span");
|
||||
ol.innerText = "Offset: ";
|
||||
ol.style.paddingLeft = "5px";
|
||||
|
||||
var ot = ce("input");
|
||||
ot.type = "text";
|
||||
ot.size = 5;
|
||||
ot.value = ov;
|
||||
ot.onchange = function(e){ ov = parseInt(ot.value); };
|
||||
|
||||
var om = ce("button");
|
||||
om.innerText = "-";
|
||||
om.onclick = function(e){ if(ov > l) ov--; ot.value = ov; };
|
||||
|
||||
var op = ce("button");
|
||||
op.innerText = "+";
|
||||
op.onclick = function(e){ if(ov < m) ov++; ot.value = ov; };
|
||||
|
||||
ac(el,sl);
|
||||
ac(el,sm);
|
||||
ac(el,st);
|
||||
ac(el,sp);
|
||||
ac(el,ol);
|
||||
ac(el,om);
|
||||
ac(el,ot);
|
||||
ac(el,op);
|
||||
ac(el,ce("br"));
|
||||
ac(el,g);
|
||||
|
||||
function scv(v){
|
||||
if(v <= ov) return 0;
|
||||
if(v > (((m - l) / sv) + ov)) return h;
|
||||
return Math.round((v - ov) * (h / ((m - l) / sv)));
|
||||
}
|
||||
|
||||
g.add = function(v){
|
||||
if(vcb) v = vcb(v);
|
||||
vs.push(v);
|
||||
if(v < minV) minV = v;
|
||||
if(v > maxV) maxV = v;
|
||||
if(vs.length > w) vs.shift();
|
||||
c.canvas.width = w;
|
||||
c.lineWidth = 1;
|
||||
c.shadowBlur=2;
|
||||
c.shadowColor="black";
|
||||
|
||||
c.fillStyle = bc;
|
||||
c.fillRect(0, 0, w, 20);
|
||||
c.fillStyle = lc;
|
||||
c.font = "14px Verdana";
|
||||
var header = t+": "+(vs[vs.length - 1])+" | Min: "+minV+" | Max: "+maxV;
|
||||
c.fillText(header,5,15);
|
||||
|
||||
c.fillStyle = bgc;
|
||||
c.fillRect(0, 20, w, gh);
|
||||
c.strokeStyle = lc;
|
||||
|
||||
for(var i = 0; i < vs.length; i++){
|
||||
if(ib){
|
||||
c.moveTo(i, gh);
|
||||
c.lineTo(i, gh - scv(vs[i]));
|
||||
c.stroke();
|
||||
continue;
|
||||
}
|
||||
if(i === 0){
|
||||
c.moveTo(0, gh - scv(vs[0]));
|
||||
c.lineTo(0, gh - scv(vs[0]));
|
||||
c.stroke();
|
||||
} else {
|
||||
c.moveTo((i - 1), gh - scv(vs[i - 1]));
|
||||
c.lineTo(i, gh - scv(vs[i]));
|
||||
c.stroke();
|
||||
}
|
||||
}
|
||||
c.fillStyle = lc;
|
||||
c.font = "10px Verdana";
|
||||
c.fillText(ov, 2, gh - 5);
|
||||
c.fillText(Math.round((((m - l) / sv) + ov) * 10) / 10, 2, 30);
|
||||
};
|
||||
return g;
|
||||
}
|
||||
|
||||
function createDigiGraph(el, t, w, h, m, tc){
|
||||
if(typeof el === "undefined" || !el) return null;
|
||||
w = (w>360)?w:360;
|
||||
h = (h<20)?20:h;
|
||||
var vs = new Array();
|
||||
var bgc = "black";
|
||||
var lc = (typeof tc === "undefined" && tc)?"pink":tc;
|
||||
var bc = "#444";
|
||||
var sv = 1;
|
||||
var gh = h+20;
|
||||
|
||||
el.style.display = "block";
|
||||
el.style.backgroundColor = "#eee";
|
||||
el.style.border = "1px solid "+bc;
|
||||
el.style.padding = "5px";
|
||||
el.style.margin = "5px";
|
||||
el.style.width = (w+2)+"px";
|
||||
|
||||
var g = ce("canvas");
|
||||
g.style.border = "1px solid "+bc;
|
||||
g.style.marginTop = "5px";
|
||||
g.width = w;
|
||||
g.height = gh;
|
||||
|
||||
var c = g.getContext("2d");
|
||||
|
||||
var sl = ce("span");
|
||||
sl.innerText = "Scale: ";
|
||||
sl.style.paddingLeft = "5px";
|
||||
|
||||
var st = ce("input");
|
||||
st.type = "text";
|
||||
st.size = 3;
|
||||
st.value = sv;
|
||||
st.onchange = function(e){ sv = st.value; };
|
||||
|
||||
var sm = ce("button");
|
||||
sm.innerText = "-";
|
||||
sm.onclick = function(e){ if(sv > 1) sv--; st.value = sv; };
|
||||
|
||||
var sp = ce("button");
|
||||
sp.innerText = "+";
|
||||
sp.onclick = function(e){ sv++; st.value = parseInt(sv); };
|
||||
|
||||
ac(el,sl);
|
||||
ac(el,sm);
|
||||
ac(el,st);
|
||||
ac(el,sp);
|
||||
ac(el,ce("br"));
|
||||
ac(el,g);
|
||||
|
||||
function gpos(p){
|
||||
var each = Math.floor(((h - ((m.length - 1)*2))/m.length));
|
||||
var s = (p * 2) + (p * each);
|
||||
return [s, s + each];
|
||||
}
|
||||
|
||||
function gact(i,p){
|
||||
return ((vs[i] & (1 << m[p])) !== 0);;
|
||||
}
|
||||
|
||||
var vc = ["aqua","yellow","#FF4500","#00FF7F","orange","cyan","magenta","#7FFF00","#FAF0E6","#00CED1","#FFD700","#EE82EE","#00FF00","#00BFFF","#FF4500","#EEE8AA","#FF1493"];
|
||||
|
||||
g.add = function(v){
|
||||
vs.push(v);
|
||||
if(vs.length > w) vs.shift();
|
||||
c.canvas.width = w;
|
||||
c.lineWidth=1;
|
||||
c.shadowBlur=2;
|
||||
c.shadowColor="black";
|
||||
|
||||
c.fillStyle = bc;
|
||||
c.fillRect(0, 0, w, 20);
|
||||
c.fillStyle = lc;
|
||||
c.font = "14px Verdana";
|
||||
c.fillText(t,5,15);
|
||||
|
||||
c.fillStyle = bgc;
|
||||
c.fillRect(0, 20, w, gh);
|
||||
|
||||
c.strokeStyle = bc;
|
||||
c.lineWidth = 1;
|
||||
c.shadowBlur=0;
|
||||
c.shadowColor="";
|
||||
for(var p=0;p<m.length;p++){
|
||||
var pos = gpos(p);
|
||||
c.moveTo(0, 20 + pos[1] + 1);
|
||||
c.lineTo(w, 20 + pos[1] + 1);
|
||||
c.stroke();
|
||||
}
|
||||
|
||||
c.shadowBlur=2;
|
||||
c.font = "14px Verdana";
|
||||
var pn = Math.round(w / sv);
|
||||
var stv = w - pn - (w - vs.length);
|
||||
if(stv < 0) stv = 0;
|
||||
for(var i = stv; i < vs.length; i++){
|
||||
for(var p=0;p<m.length;p++){
|
||||
var pos = gpos(p);
|
||||
var act = gact(i, p);
|
||||
c.fillStyle = vc[p];
|
||||
c.shadowColor="black";
|
||||
c.font = "12px Verdana";
|
||||
c.fillText(""+m[p], 2, pos[0] + 32);
|
||||
c.shadowColor=vc[p];
|
||||
var x1 = ((i-stv)*sv) - (sv / 2);
|
||||
var wa = gact(i - 1, p);
|
||||
if(i && act != wa){
|
||||
if(!wa){
|
||||
c.fillRect(x1, 20 + (pos[1] - 2), sv/2, 2);
|
||||
c.fillRect(x1+(sv/2), 20 + pos[0], 2, pos[1] - pos[0]);
|
||||
c.fillRect(x1+(sv/2), 20 + pos[0], sv/2, 2);
|
||||
} else {
|
||||
c.fillRect(x1, 20 + pos[0], sv/2, 2);
|
||||
c.fillRect(x1+(sv/2), 20 + pos[0], 2, pos[1] - pos[0]);
|
||||
c.fillRect(x1+(sv/2), 20 + (pos[1] - 2), sv/2, 2);
|
||||
}
|
||||
} else if(act){
|
||||
c.fillRect(x1, 20 + pos[0], sv, 2);
|
||||
} else {
|
||||
c.fillRect(x1, 20 + (pos[1] - 2), sv, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
return g;
|
||||
}
|
@ -1 +0,0 @@
|
||||
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('8 H(t){K 21.1Y(t)}8 9(a,b){a.1S(b)}8 1O(b,t,w,h,l,m,d,f,j){6(Q b==="S"||!b)K 1f;6(Q d==="S"||!d)d=1P;w=(w>1b)?w:1b;h=(h<1N)?1N:h;4 k=1M 1L();4 n="V";4 o=(Q f==="S"&&f)?"1J":f;4 p="#1I";4 q=(Q j==="S"&&j)?1f:j;4 r=m;4 s=0;4 u=1;4 x=l;4 y=h+20;b.7.1H="1G";b.7.1F="#1s";b.7.1c="12 11 "+p;b.7.1D="N";b.7.1C="N";b.7.P=(w+2)+"1B";4 g=H("1a");g.7.1c="12 11 "+p;g.7.1z="N";g.P=w;g.1w=y;4 c=g.1v("2d");4 z=H("1j");z.M="1u: ";z.7.1m="N";4 A=H("1p");A.1i="1r";A.1e=3;A.I=u;A.1h=8(e){u=A.I};4 B=H("T");B.M="-";B.U=8(e){6(u>1)u--;A.I=u};4 C=H("T");C.M="+";C.U=8(e){u++;A.I=1n(u)};4 D=H("1j");D.M="1Q: ";D.7.1m="N";4 E=H("1p");E.1i="1r";E.1e=5;E.I=x;E.1h=8(e){x=1n(E.I)};4 F=H("T");F.M="-";F.U=8(e){6(x>l)x--;E.I=x};4 G=H("T");G.M="+";G.U=8(e){6(x<m)x++;E.I=x};9(b,z);9(b,B);9(b,A);9(b,C);9(b,D);9(b,F);9(b,E);9(b,G);9(b,H("1E"));9(b,g);8 R(v){6(v<=x)K 0;6(v>(((m-l)/u)+x))K h;K 1d.1o((v-x)*(h/((m-l)/u)))}g.1x=8(v){6(q)v=q(v);k.1y(v);6(v<r)r=v;6(v>s)s=v;6(k.L>w)k.1A();c.1a.P=w;c.1g=1;c.17=2;c.Y="V";c.O=p;c.J(0,0,w,20);c.O=o;c.X="1q Z";4 a=t+": "+(k[k.L-1])+" | 1U: "+r+" | 23: "+s;c.W(a,5,15);c.O=n;c.J(0,20,w,y);c.1K=o;18(4 i=0;i<k.L;i++){6(d){c.13(i,y);c.14(i,y-R(k[i]));c.16();1R}6(i===0){c.13(0,y-R(k[0]));c.14(0,y-R(k[0]));c.16()}19{c.13((i-1),y-R(k[i-1]));c.14(i,y-R(k[i]));c.16()}}c.O=o;c.X="1T Z";c.W(x,2,y-5);c.W(1d.1o((((m-l)/u)+x)*10)/10,2,1V)};K g}8 1W(j,t,w,h,m,k){6(Q j==="S"||!j)K 1f;w=(w>1b)?w:1b;h=(h<20)?20:h;4 l=1M 1L();4 n="V";4 o=(Q k==="S"&&k)?"1X":k;4 q="#1I";4 r=1;4 u=h+20;j.7.1H="1G";j.7.1F="#1s";j.7.1c="12 11 "+q;j.7.1D="N";j.7.1C="N";j.7.P=(w+2)+"1B";4 g=H("1a");g.7.1c="12 11 "+q;g.7.1z="N";g.P=w;g.1w=u;4 c=g.1v("2d");4 x=H("1j");x.M="1u: ";x.7.1m="N";4 y=H("1p");y.1i="1r";y.1e=3;y.I=r;y.1h=8(e){r=y.I};4 z=H("T");z.M="-";z.U=8(e){6(r>1)r--;y.I=r};4 A=H("T");A.M="+";A.U=8(e){r++;y.I=1n(r)};9(j,x);9(j,z);9(j,y);9(j,A);9(j,H("1E"));9(j,g);8 1l(p){4 a=1d.1Z(((h-((m.L-1)*2))/m.L));4 s=(p*2)+(p*a);K[s,s+a]}8 1k(i,p){K((l[i]&(1<<m[p]))!==0)}4 B=["22","1J","#1t","#24","25","26","27","#28","#29","#2a","#2b","#2c","#2e","#2f","#1t","#2g","#2h"];g.1x=8(v){l.1y(v);6(l.L>w)l.1A();c.1a.P=w;c.1g=1;c.17=2;c.Y="V";c.O=q;c.J(0,0,w,20);c.O=o;c.X="1q Z";c.W(t,5,15);c.O=n;c.J(0,20,w,u);c.1K=q;c.1g=1;c.17=0;c.Y="";18(4 p=0;p<m.L;p++){4 a=1l(p);c.13(0,20+a[1]+1);c.14(w,20+a[1]+1);c.16()}c.17=2;c.X="1q Z";4 b=1d.1o(w/r);4 d=w-b-(w-l.L);6(d<0)d=0;18(4 i=d;i<l.L;i++){18(4 p=0;p<m.L;p++){4 a=1l(p);4 e=1k(i,p);c.O=B[p];c.Y="V";c.X="2i Z";c.W(""+m[p],2,a[0]+2j);c.Y=B[p];4 f=((i-d)*r)-(r/2);4 g=1k(i-1,p);6(i&&e!=g){6(!g){c.J(f,20+(a[1]-2),r/2,2);c.J(f+(r/2),20+a[0],2,a[1]-a[0]);c.J(f+(r/2),20+a[0],r/2,2)}19{c.J(f,20+a[0],r/2,2);c.J(f+(r/2),20+a[0],2,a[1]-a[0]);c.J(f+(r/2),20+(a[1]-2),r/2,2)}}19 6(e){c.J(f,20+a[0],r,2)}19{c.J(f,20+(a[1]-2),r,2)}}}};K g}',62,144,'||||var||if|style|function|ac||||||||||||||||||||||||||||||||||ce|value|fillRect|return|length|innerText|5px|fillStyle|width|typeof|scv|undefined|button|onclick|black|fillText|font|shadowColor|Verdana||solid|1px|moveTo|lineTo||stroke|shadowBlur|for|else|canvas|360|border|Math|size|null|lineWidth|onchange|type|span|gact|gpos|paddingLeft|parseInt|round|input|14px|text|eee|FF4500|Scale|getContext|height|add|push|marginTop|shift|px|margin|padding|br|backgroundColor|block|display|444|yellow|strokeStyle|Array|new|100|createGraph|false|Offset|continue|appendChild|10px|Min|30|createDigiGraph|pink|createElement|floor||document|aqua|Max|00FF7F|orange|cyan|magenta|7FFF00|FAF0E6|00CED1|FFD700|EE82EE||00FF00|00BFFF|EEE8AA|FF1493|12px|32'.split('|'),0,{}))
|
@ -1,100 +0,0 @@
|
||||
<!--
|
||||
FSWebServer - Sample Index Page
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library 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
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 22000, 25000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
@ -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<sc_callback_t>(&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)
|
||||
{
|
||||
sc_status status = (sc_status) st;
|
||||
if (status == SC_STATUS_LINK) {
|
||||
station_config* sta_conf = reinterpret_cast<station_config*>(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)
|
||||
{
|
||||
|
@ -287,8 +287,9 @@ public:
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
uint16_t remotePort();
|
||||
bool getNoDelay();
|
||||
void setNoDelay(bool nodelay);
|
||||
static void setLocalPortStart(uint16_t port) { _localPort = port; }
|
||||
|
||||
template<typename T> size_t write(T &src){
|
||||
uint8_t obuf[1460];
|
||||
@ -97,6 +98,7 @@ private:
|
||||
void _err(int8_t err);
|
||||
|
||||
ClientContext* _client;
|
||||
static uint16_t _localPort;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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]+).*
|
||||
|
||||
# ------------------------------
|
||||
|
@ -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)]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
@ -254,63 +240,6 @@ sint8 espconn_get_connection_info(struct espconn *pespconn, remot_info **pcon_in
|
||||
|
||||
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
|
||||
@ -474,26 +464,6 @@ 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
|
||||
@ -512,7 +482,21 @@ sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
|
||||
*******************************************************************************/
|
||||
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
|
||||
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
6
tools/sdk/include/sntp.h
Executable file → Normal file
6
tools/sdk/include/sntp.h
Executable file → Normal file
@ -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).
|
||||
|
@ -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
|
||||
|
BIN
tools/sdk/lib/libjson.a
Executable file → Normal file
BIN
tools/sdk/lib/libjson.a
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tools/sdk/lib/libupgrade.a
Executable file → Normal file
BIN
tools/sdk/lib/libupgrade.a
Executable file → Normal file
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
||||
1.0.1_15_05_04_p1
|
||||
1.1.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user