diff --git a/esp32_partition_app1984k_spiffs60k.csv b/esp32_partition_app1984k_spiffs60k.csv
new file mode 100644
index 000000000..e8bcd9d49
--- /dev/null
+++ b/esp32_partition_app1984k_spiffs60k.csv
@@ -0,0 +1,7 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x5000,
+otadata, data, ota, 0xe000, 0x2000,
+app0, app, ota_0, 0x10000, 0x1F0000,
+app1, app, ota_1, 0x200000, 0x1F0000,
+spiffs, data, spiffs, 0x3F0000,0xf000,
+eeprom, data, nvs, 0x3FF000,0x1000,
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 050c2e390..b6008abcf 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -399,6 +399,7 @@
#define USE_RULES // Add support for rules (+8k code)
#define USE_RULES_COMPRESSION // Compresses rules in Flash at about ~50% (+3.3k code)
//#define USE_SCRIPT // Add support for script (+17k code)
+ #define USE_SCRIPT_COMPRESSION
//#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support
// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem)
diff --git a/tasmota/support_eeprom.ino b/tasmota/support_eeprom.ino
new file mode 100644
index 000000000..b990aa242
--- /dev/null
+++ b/tasmota/support_eeprom.ino
@@ -0,0 +1,89 @@
+/*
+ support_eeprom.ino - eeprom support for Sonoff-Tasmota
+
+ Copyright (C) 2020 Theo Arends & Gerhard Mutz
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+
+ supports hardware i2c eeprom 24c256 and flash eeprom simulation on ESP8266 and ESP32
+ all ESP8266 linker files contain 4k eeprom partition
+ ESP32 requires esp32_partition_app1984k_spiffs60k.csv for 4k eeprom
+*/
+
+
+#ifdef USE_EEPROM
+
+#ifdef USE_24C256
+ // i2c eeprom
+#include
+#define EEPROM_ADDRESS 0x50
+static Eeprom24C128_256 m_eeprom(EEPROM_ADDRESS);
+
+void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) {
+ m_eeprom.writeBytes(addr,len,(uint8_t*)buff);
+}
+void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) {
+ m_eeprom.readBytes(addr,len,(uint8_t*)buff);
+}
+
+uint32_t eeprom_init(uint32_t size) {
+ if (i2c_flg) {
+ if (I2cActive(EEPROM_ADDRESS) || I2cSetDevice(EEPROM_ADDRESS)) {
+ // eeprom is present
+ I2cSetActiveFound(EEPROM_ADDRESS, "24C256");
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#else // USE_24C256
+
+#ifdef ESP32
+
+// esp32 uses eeprom section
+uint32_t eeprom_init(uint32_t size) {
+ return EEPROM.begin(size);
+}
+void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) {
+ EEPROM.writeBytes(addr, buff, len);
+ EEPROM.commit();
+}
+void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) {
+ EEPROM.readBytes(addr, buff, len);
+}
+
+#else
+// esp8266 uses eeprom section
+uint32_t eeprom_init(uint32_t size) {
+ EEPROM.begin(size);
+ return 1;
+}
+void eeprom_writeBytes(uint32_t adr, uint32_t len, uint8_t *buf) {
+ for (uint32_t cnt=0; cnt
-//Unishox compressor; // singleton
#define SCRIPT_COMPRESS compressor.unishox_compress
#define SCRIPT_DECOMPRESS compressor.unishox_decompress
#ifndef UNISHOXRSIZE
@@ -78,17 +119,19 @@ uint32_t DecodeLightId(uint32_t hue_id);
#endif
#endif // USE_SCRIPT_COMPRESSION
-#if (defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)) || (USE_SCRIPT_FATFS==-1)
+#if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1)
#ifdef ESP32
#include "FS.h"
#include "SPIFFS.h"
#else
#include
#endif
-
FS *fsp;
+#endif // LITTLEFS_SCRIPT_SIZE
+
+#ifdef LITTLEFS_SCRIPT_SIZE
void SaveFile(const char *name,const uint8_t *buf,uint32_t len) {
File file = fsp->open(name, "w");
if (!file) return;
@@ -116,7 +159,7 @@ void LoadFile(const char *name,uint8_t *buf,uint32_t len) {
file.read(buf, len);
file.close();
}
-#endif
+#endif // LITTLEFS_SCRIPT_SIZE
// offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution
#define EPOCH_OFFSET 1546300800
@@ -317,23 +360,10 @@ void RulesTeleperiod(void) {
}
// EEPROM MACROS
-#ifdef USE_24C256
-#ifndef USE_SCRIPT_FATFS
// i2c eeprom
-#include
-#define EEPROM_ADDRESS 0x50
-// strange bug, crashes with powers of 2 ??? 4096 crashes
-#ifndef EEP_SCRIPT_SIZE
-#define EEP_SCRIPT_SIZE 4095
-#endif
+#define EEP_WRITE(A,B,C) eeprom_writeBytes(A,B,(uint8_t*)C);
+#define EEP_READ(A,B,C) eeprom_readBytes(A,B,(uint8_t*)C);
-static Eeprom24C128_256 eeprom(EEPROM_ADDRESS);
-// eeprom.writeBytes(address, length, buffer);
-#define EEP_WRITE(A,B,C) eeprom.writeBytes(A,B,(uint8_t*)C);
-// eeprom.readBytes(address, length, buffer);
-#define EEP_READ(A,B,C) eeprom.readBytes(A,B,(uint8_t*)C);
-#endif
-#endif
#define SCRIPT_SKIP_SPACES while (*lp==' ' || *lp=='\t') lp++;
#define SCRIPT_SKIP_EOL while (*lp==SCRIPT_EOL) lp++;
@@ -651,13 +681,7 @@ char *script;
#if USE_SCRIPT_FATFS>=0
fsp=&SD;
-
-#ifdef USE_MMC
- if (fsp->begin()) {
-#else
if (SD.begin(USE_SCRIPT_FATFS)) {
-#endif
-
#else
if (fsp->begin()) {
#endif
@@ -738,13 +762,14 @@ float median_array(float *array,uint8_t len) {
}
-float *Get_MFAddr(uint8_t index,uint8_t *len) {
+float *Get_MFAddr(uint8_t index,uint8_t *len,uint8_t *ipos) {
*len=0;
uint8_t *mp=(uint8_t*)glob_script_mem.mfilt;
for (uint8_t count=0; countnumvals&0x7f;
+ if (ipos) *ipos=mflp->index;
return mflp->rbuff;
}
mp+=sizeof(struct M_FILT)+((mflp->numvals&0x7f)-1)*sizeof(float);
@@ -936,6 +961,56 @@ if (hsv.S == 0) {
#endif
//#endif
+#ifdef USE_ANGLE_FUNC
+uint32_t pulse_time_hl;
+uint32_t pulse_time_lh;
+uint32_t pulse_ltime_hl;
+uint32_t pulse_ltime_lh;
+uint8_t pt_pin;
+
+void MP_Timer(void) ICACHE_RAM_ATTR;
+
+#define MPT_DEBOUNCE 10
+
+void MP_Timer(void) {
+ uint32_t level = digitalRead(pt_pin&0x3f);
+ uint32_t ms = millis();
+ uint32_t time;
+ if (level) {
+ // rising edge
+ pulse_ltime_lh = ms;
+ time = ms - pulse_ltime_hl;
+ if (time>MPT_DEBOUNCE) pulse_time_hl = time;
+ } else {
+ // falling edge
+ pulse_ltime_hl = ms;
+ time = ms - pulse_ltime_lh;
+ if (time>MPT_DEBOUNCE) pulse_time_lh = time;
+ }
+}
+
+uint32_t MeasurePulseTime(int32_t in) {
+ if (in >= 0) {
+ // define pin;
+ pt_pin = in;
+ pinMode(pt_pin&0x3f,INPUT_PULLUP);
+ attachInterrupt(pt_pin&0x3f, MP_Timer, CHANGE);
+ pulse_ltime_lh = millis();
+ pulse_ltime_hl = millis();
+ return 0;
+ }
+ uint32_t ptime;
+ if (in==-1) {
+ ptime = pulse_time_lh;
+ pulse_time_lh = 0;
+ } else {
+ ptime = pulse_time_hl;
+ pulse_time_hl = 0;
+ }
+ return ptime;
+}
+#endif // USE_ANGLE_FUNC
+
// vtype => ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number
// no flash strings here for performance reasons!!!
char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) {
@@ -1720,6 +1795,15 @@ chknext:
len=0;
goto exit;
}
+#ifdef USE_ANGLE_FUNC
+ if (!strncmp(vname,"mpt(",4)) {
+ lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
+ fvar=MeasurePulseTime(fvar);
+ lp++;
+ len=0;
+ goto exit;
+ }
+#endif
if (!strncmp(vname,"micros",6)) {
fvar=micros();
goto exit;
@@ -3159,7 +3243,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
// numeric result
if (glob_script_mem.type[ind.index].bits.is_filter) {
uint8_t len=0;
- float *fa=Get_MFAddr(index,&len);
+ float *fa=Get_MFAddr(index,&len,0);
//Serial.printf(">> 2 %d\n",(uint32_t)*fa);
if (fa && len) ws2812_set_array(fa,len,fvar);
}
@@ -4065,26 +4149,26 @@ void ScriptSaveSettings(void) {
}
-#if defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
+#ifdef EEP_SCRIPT_SIZE
if (glob_script_mem.flags&1) {
EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram);
}
-#endif
+#endif // EEP_SCRIPT_SIZE
-#if !defined(USE_24C256) && defined(USE_SCRIPT_FATFS)
+#ifdef USE_SCRIPT_FATFS
if (glob_script_mem.flags&1) {
fsp->remove(FAT_SCRIPT_NAME);
File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE);
file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE);
file.close();
}
-#endif
+#endif // USE_SCRIPT_FATFS
-#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
+#ifdef LITTLEFS_SCRIPT_SIZE
if (glob_script_mem.flags&1) {
SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE);
}
-#endif
+#endif // LITTLEFS_SCRIPT_SIZE
}
if (glob_script_mem.script_mem) {
@@ -4095,10 +4179,6 @@ void ScriptSaveSettings(void) {
}
#ifdef USE_SCRIPT_COMPRESSION
-#ifndef USE_24C256
-#ifndef USE_SCRIPT_FATFS
-#ifndef LITTLEFS_SCRIPT_SIZE
-
//AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram));
uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1);
if (len_compressed > 0) {
@@ -4107,10 +4187,6 @@ void ScriptSaveSettings(void) {
} else {
AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed);
}
-
-#endif
-#endif
-#endif
#endif // USE_SCRIPT_COMPRESSION
if (bitRead(Settings.rule_enabled, 0)) {
@@ -5068,10 +5144,11 @@ const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'";
#define MAX_GARRAY 4
-char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries) {
+char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries, uint8_t *ipos) {
struct T_INDEX ind;
uint8_t vtype;
uint8 entries=0;
+uint8_t cipos=0;
uint8_t anum=0;
while (anum> 2 %d\n",(uint32_t)*fa);
if (fa && len>=entries) {
- if (!entries) {entries = len;}
+ if (!entries) {
+ entries = len;
+ }
// add array to list
arrays[anum]=fa;
anum++;
@@ -5111,6 +5190,7 @@ uint8 entries=0;
//Serial.printf(">> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]);
*ranum=anum;
*rentries=entries;
+ *ipos=cipos;
return lp;
}
@@ -5409,7 +5489,8 @@ void ScriptWebShow(char mc) {
float *arrays[MAX_GARRAY];
uint8_t anum=0;
uint8 entries=0;
- lp=gc_get_arrays(lp, &arrays[0], &anum, &entries);
+ uint8 ipos=0;
+ lp=gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos);
if (anum>nanum) {
goto nextwebline;
@@ -5456,28 +5537,38 @@ void ScriptWebShow(char mc) {
int8_t todflg=-1;
if (!strncmp(label,"cnt",3)) {
todflg=atoi(&label[3]);
+ if (todflg>=entries) todflg=entries-1;
}
+ uint32_t aind=ipos;
+ if (aind>=entries) aind=entries-1;
for (uint32_t cnt=0; cnt=0) {
sprintf(lbl,"%d",todflg);
todflg++;
+ if (todflg>=entries) {
+ todflg=0;
+ }
} else {
- GetTextIndexed(lbl, sizeof(lbl), cnt, label);
+ GetTextIndexed(lbl, sizeof(lbl), aind, label);
}
WSContentSend_PD(lbl);
WSContentSend_PD("',");
for (uint32_t ind=0; ind=entries) {
+ aind=0;
+ }
}
// get header
@@ -5722,7 +5813,7 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) {
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
-
+//const esp_partition_t *esp32_part;
bool Xdrv10(uint8_t function)
{
@@ -5740,9 +5831,6 @@ bool Xdrv10(uint8_t function)
glob_script_mem.script_pram_size=PMEM_SIZE;
#ifdef USE_SCRIPT_COMPRESSION
-#ifndef USE_24C256
-#ifndef USE_SCRIPT_FATFS
-#ifndef LITTLEFS_SCRIPT_SIZE
int32_t len_decompressed;
sprt=(char*)calloc(UNISHOXRSIZE+8,1);
if (!sprt) { break; }
@@ -5751,9 +5839,6 @@ bool Xdrv10(uint8_t function)
len_decompressed = SCRIPT_DECOMPRESS(Settings.rules[0], strlen(Settings.rules[0]), glob_script_mem.script_ram, glob_script_mem.script_size);
if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed]=0;
//AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed);
-#endif
-#endif
-#endif
#endif // USE_SCRIPT_COMPRESSION
#ifdef USE_BUTTON_EVENT
@@ -5762,10 +5847,8 @@ bool Xdrv10(uint8_t function)
}
#endif
-#ifdef USE_24C256
-#ifndef USE_SCRIPT_FATFS
- if (I2cEnabled(XI2C_37)) {
- if (I2cSetDevice(EEPROM_ADDRESS)) {
+#ifdef EEP_SCRIPT_SIZE
+ if (eeprom_init(EEP_SCRIPT_SIZE)) {
// found 32kb eeprom
char *script;
script=(char*)calloc(EEP_SCRIPT_SIZE+4,1);
@@ -5782,34 +5865,26 @@ bool Xdrv10(uint8_t function)
glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE;
glob_script_mem.flags=1;
- I2cSetActiveFound(EEPROM_ADDRESS, "EEPROM");
- }
}
-#endif
-#endif
+#endif // EEP_SCRIPT_SIZE
#ifdef USE_SCRIPT_FATFS
#if USE_SCRIPT_FATFS>=0
- fsp = &SD;
-
-#ifdef USE_MMC
- if (fsp->begin()) {
-#else
-
+ // fs on SD card
#ifdef ESP32
if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) {
- SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1);
+ SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1);
}
-#endif
+#endif // ESP32
+ fsp = &SD;
if (SD.begin(USE_SCRIPT_FATFS)) {
-#endif
-
#else
- fsp = &LittleFS;
- if (fsp->begin()) {
-#endif
+ // fs on flash
+ fsp = &LittleFS;
+ if (fsp->begin()) {
+#endif // USE_SCRIPT_FATFS>=0
//fsp->dateTimeCallback(dateTime);
@@ -5834,14 +5909,18 @@ bool Xdrv10(uint8_t function)
} else {
glob_script_mem.script_sd_found=0;
}
-#endif
+#endif // USE_SCRIPT_FATFS
-#if defined(LITTLEFS_SCRIPT_SIZE) && !defined(USE_24C256) && !defined(USE_SCRIPT_FATFS)
+#ifdef LITTLEFS_SCRIPT_SIZE
#ifdef ESP32
+ // spiffs on esp32
fsp = &SPIFFS;
+ //esp32_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_SPIFFS,NULL);
+ //Serial.printf("address %d - %d - %s\n",esp32_part->address,esp32_part->size, esp32_part->label);
#else
+ // lfs on esp8266
fsp = &LittleFS;
#endif
char *script;
@@ -5856,7 +5935,7 @@ bool Xdrv10(uint8_t function)
glob_script_mem.script_pram=(uint8_t*)Settings.rules[0];
glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE;
glob_script_mem.flags=1;
-#endif
+#endif // LITTLEFS_SCRIPT_SIZE
// a valid script MUST start with >D
if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {