mirror of https://github.com/arendst/Tasmota.git
Merge pull request #15986 from gemu2015/scripter_update
some fixes and fast pin multiplexer
This commit is contained in:
commit
74b3c7d56f
|
@ -3595,6 +3595,48 @@ chknext:
|
||||||
goto strexit;
|
goto strexit;
|
||||||
}
|
}
|
||||||
#endif //USE_MORITZ
|
#endif //USE_MORITZ
|
||||||
|
#ifdef ESP32_FAST_MUX
|
||||||
|
if (!strncmp(lp, "mux(", 4)) {
|
||||||
|
lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, gv);
|
||||||
|
if (fvar == 0) {
|
||||||
|
// start
|
||||||
|
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
|
||||||
|
uint16_t alen;
|
||||||
|
float *fa;
|
||||||
|
lp = get_array_by_name(lp, &fa, &alen, 0);
|
||||||
|
if (!fa) {
|
||||||
|
fvar = -1;
|
||||||
|
goto nfuncexit;
|
||||||
|
}
|
||||||
|
float falen;
|
||||||
|
lp = GetNumericArgument(lp, OPER_EQU, &falen, gv);
|
||||||
|
if (falen > alen) {
|
||||||
|
falen = alen;
|
||||||
|
}
|
||||||
|
fvar = fast_mux(0, fvar, fa, falen);
|
||||||
|
} else if (fvar == 1) {
|
||||||
|
// stop
|
||||||
|
fvar = fast_mux(1, 0, 0, 0);
|
||||||
|
} else if (fvar == 2) {
|
||||||
|
// set array
|
||||||
|
uint16_t alen;
|
||||||
|
float *fa;
|
||||||
|
lp = get_array_by_name(lp, &fa, &alen, 0);
|
||||||
|
if (!fa) {
|
||||||
|
fvar = -1;
|
||||||
|
goto nfuncexit;
|
||||||
|
}
|
||||||
|
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
|
||||||
|
if (fvar > alen) {
|
||||||
|
fvar = alen;
|
||||||
|
}
|
||||||
|
fvar = fast_mux(2, 0, fa, fvar);
|
||||||
|
} else {
|
||||||
|
fvar = fast_mux(3, 0, 0, 0);
|
||||||
|
}
|
||||||
|
goto nfuncexit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -3722,6 +3764,36 @@ chknext:
|
||||||
len++;
|
len++;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
if (!strncmp(lp, "rma(", 4)) {
|
||||||
|
uint16_t alen;
|
||||||
|
float *array;
|
||||||
|
lp = get_array_by_name(lp + 4, &array, &alen, 0);
|
||||||
|
char str[SCRIPT_MAXSSIZE];
|
||||||
|
lp = GetStringArgument(lp, OPER_EQU, str, 0);
|
||||||
|
uint32_t raddr = strtol(str, NULL, 16);
|
||||||
|
raddr &= 0xfffffffc;
|
||||||
|
const uint32_t *addr = (const uint32_t*)raddr;
|
||||||
|
lp = GetNumericArgument(lp, OPER_EQU, &fvar, gv);
|
||||||
|
uint32_t mlen = fvar;
|
||||||
|
mlen &= 0xfffffffc;
|
||||||
|
uint32_t *lp = (uint32_t*)special_malloc(mlen);
|
||||||
|
if (lp) {
|
||||||
|
for (uint32_t cnt = 0; cnt < mlen/4; cnt++) {
|
||||||
|
lp[cnt] = addr[cnt];
|
||||||
|
}
|
||||||
|
//esp_flash_read();
|
||||||
|
|
||||||
|
uint8_t *ucp = (uint8_t*)lp;
|
||||||
|
for (uint32_t cnt = 0; cnt < mlen; cnt++) {
|
||||||
|
array[cnt] = ucp[cnt];
|
||||||
|
}
|
||||||
|
free(lp);
|
||||||
|
fvar = 0;
|
||||||
|
} else {
|
||||||
|
fvar = -1;
|
||||||
|
}
|
||||||
|
goto nfuncexit;
|
||||||
|
}
|
||||||
#if defined(ESP32) && (defined(USE_M5STACK_CORE2))
|
#if defined(ESP32) && (defined(USE_M5STACK_CORE2))
|
||||||
if (!strncmp(lp, "rec(", 4)) {
|
if (!strncmp(lp, "rec(", 4)) {
|
||||||
char str[SCRIPT_MAXSSIZE];
|
char str[SCRIPT_MAXSSIZE];
|
||||||
|
@ -6115,13 +6187,17 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
|
||||||
lp += 4;
|
lp += 4;
|
||||||
// skip one space after cmd
|
// skip one space after cmd
|
||||||
web_send_line(0, lp);
|
web_send_line(0, lp);
|
||||||
WSContentFlush();
|
//WSContentFlush();
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
else if (!strncmp(lp, "wfs", 3)) {
|
else if (!strncmp(lp, "wfs", 3)) {
|
||||||
lp += 4;
|
lp += 4;
|
||||||
// skip one space after cmd
|
// skip one space after cmd
|
||||||
web_send_file(0, lp);
|
web_send_file(0, lp);
|
||||||
|
//WSContentFlush();
|
||||||
|
goto next_line;
|
||||||
|
}
|
||||||
|
else if (!strncmp(lp, "wcf", 3)) {
|
||||||
WSContentFlush();
|
WSContentFlush();
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
|
@ -6139,7 +6215,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SENDMAIL
|
#if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL)
|
||||||
else if (!strncmp(lp, "mail", 4)) {
|
else if (!strncmp(lp, "mail", 4)) {
|
||||||
lp+=5;
|
lp+=5;
|
||||||
//char tmp[256];
|
//char tmp[256];
|
||||||
|
@ -6151,7 +6227,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) {
|
||||||
}
|
}
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
#endif // USE_SENDMAIL
|
#endif
|
||||||
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
|
||||||
// execute cmd
|
// execute cmd
|
||||||
uint8_t sflag = 0,pflg = 0,svmqtt,swll;
|
uint8_t sflag = 0,pflg = 0,svmqtt,swll;
|
||||||
|
@ -7755,8 +7831,8 @@ bool ScriptCommand(void) {
|
||||||
// is array
|
// is array
|
||||||
Response_P(PSTR("{\"script\":{\"%s\":["), lp);
|
Response_P(PSTR("{\"script\":{\"%s\":["), lp);
|
||||||
for (uint16_t cnt = 0; cnt < alend; cnt++) {
|
for (uint16_t cnt = 0; cnt < alend; cnt++) {
|
||||||
ext_snprintf_P(str, sizeof(str), PSTR("%*_f"), -glob_script_mem.script_dprec, fpd);
|
float tvar = *fpd++;
|
||||||
fpd++;
|
ext_snprintf_P(str, sizeof(str), PSTR("%*_f"), -glob_script_mem.script_dprec, &tvar);
|
||||||
if (cnt) {
|
if (cnt) {
|
||||||
ResponseAppend_P(PSTR(",%s"), str);
|
ResponseAppend_P(PSTR(",%s"), str);
|
||||||
} else {
|
} else {
|
||||||
|
@ -9720,7 +9796,7 @@ exgc:
|
||||||
#endif //USE_SCRIPT_WEB_DISPLAY
|
#endif //USE_SCRIPT_WEB_DISPLAY
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SENDMAIL
|
#if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL)
|
||||||
|
|
||||||
void script_send_email_body(void(*func)(char *)) {
|
void script_send_email_body(void(*func)(char *)) {
|
||||||
uint8_t msect = Run_Scripter1(">m", -2, 0);
|
uint8_t msect = Run_Scripter1(">m", -2, 0);
|
||||||
|
@ -9753,7 +9829,7 @@ uint8_t msect = Run_Scripter1(">m", -2, 0);
|
||||||
func((char*)"*");
|
func((char*)"*");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_SENDMAIL
|
#endif //USE_SENDMAIL
|
||||||
|
|
||||||
#ifdef USE_SCRIPT_JSON_EXPORT
|
#ifdef USE_SCRIPT_JSON_EXPORT
|
||||||
void ScriptJsonAppend(void) {
|
void ScriptJsonAppend(void) {
|
||||||
|
@ -9799,6 +9875,122 @@ bool RulesProcessEvent(const char *json_event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#ifdef ESP32_FAST_MUX
|
||||||
|
|
||||||
|
#define MUX_SIZE 128
|
||||||
|
struct FAST_PIN_MUX {
|
||||||
|
volatile uint8_t scan_cnt;
|
||||||
|
uint8_t scan_buff[MUX_SIZE];
|
||||||
|
uint8_t scan_buff_size;
|
||||||
|
uint8_t time;
|
||||||
|
uint32_t low_pins;
|
||||||
|
uint32_t high_pins;
|
||||||
|
hw_timer_t * scan_timer = NULL;
|
||||||
|
portMUX_TYPE scan_timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
} fast_pin_mux;
|
||||||
|
|
||||||
|
|
||||||
|
void IRAM_ATTR fast_mux_irq() {
|
||||||
|
portENTER_CRITICAL_ISR(&fast_pin_mux.scan_timerMux);
|
||||||
|
// this could be optimized for multiple pins
|
||||||
|
if (fast_pin_mux.scan_buff_size) {
|
||||||
|
while (fast_pin_mux.scan_cnt < fast_pin_mux.scan_buff_size) {
|
||||||
|
uint8_t iob = fast_pin_mux.scan_buff[fast_pin_mux.scan_cnt];
|
||||||
|
if (iob & 0x20) {
|
||||||
|
if (iob & 1) {
|
||||||
|
GPIO.out_w1tc = fast_pin_mux.low_pins;
|
||||||
|
}
|
||||||
|
if (iob & 2) {
|
||||||
|
GPIO.out_w1ts = fast_pin_mux.high_pins;
|
||||||
|
}
|
||||||
|
if (iob & 4) {
|
||||||
|
// modify mux timer
|
||||||
|
uint8_t fac = (iob & 0x1f) >> 2;
|
||||||
|
timerAlarmWrite(fast_pin_mux.scan_timer, fast_pin_mux.time * fac, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint8_t mode = (iob >> 6) & 1;
|
||||||
|
digitalWrite(iob & 0x1f, mode);
|
||||||
|
}
|
||||||
|
fast_pin_mux.scan_cnt++;
|
||||||
|
if (iob & 0x80) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fast_pin_mux.scan_cnt >= fast_pin_mux.scan_buff_size) {
|
||||||
|
fast_pin_mux.scan_cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL_ISR(&fast_pin_mux.scan_timerMux);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* uint8_t pin nr, 0x40 = value, 0x80 = next
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32_t fast_mux(uint32_t flag, uint32_t time, float *buf, uint32_t len) {
|
||||||
|
int32_t retval;
|
||||||
|
if (!flag) {
|
||||||
|
if (len > MUX_SIZE) {
|
||||||
|
len = MUX_SIZE;
|
||||||
|
}
|
||||||
|
fast_pin_mux.high_pins = 0;
|
||||||
|
fast_pin_mux.low_pins = 0;
|
||||||
|
for (uint32_t cnt = 0; cnt < len; cnt++) {
|
||||||
|
uint8_t iob = *buf++;
|
||||||
|
fast_pin_mux.scan_buff[cnt] = iob;
|
||||||
|
uint8_t pin = iob & 0x1f;
|
||||||
|
pinMode(pin, OUTPUT);
|
||||||
|
if (iob & 0x40) {
|
||||||
|
digitalWrite(pin, 1);
|
||||||
|
fast_pin_mux.high_pins |= (1 << pin);
|
||||||
|
} else {
|
||||||
|
digitalWrite(pin, 0);
|
||||||
|
fast_pin_mux.low_pins |= (1 << pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fast_pin_mux.scan_buff_size = 0;
|
||||||
|
|
||||||
|
if (fast_pin_mux.scan_timer) {
|
||||||
|
timerStop(fast_pin_mux.scan_timer);
|
||||||
|
timerDetachInterrupt(fast_pin_mux.scan_timer);
|
||||||
|
timerEnd(fast_pin_mux.scan_timer);
|
||||||
|
}
|
||||||
|
fast_pin_mux.scan_timer = timerBegin(3, 1000, true);
|
||||||
|
if (!fast_pin_mux.scan_timer) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fast_pin_mux.time = time;
|
||||||
|
timerAttachInterrupt(fast_pin_mux.scan_timer, &fast_mux_irq, true);
|
||||||
|
timerSetAutoReload(fast_pin_mux.scan_timer, true);
|
||||||
|
timerAlarmWrite(fast_pin_mux.scan_timer, fast_pin_mux.time, true);
|
||||||
|
timerAlarmEnable(fast_pin_mux.scan_timer);
|
||||||
|
timerStart(fast_pin_mux.scan_timer);
|
||||||
|
} else if (flag == 1) {
|
||||||
|
if (fast_pin_mux.scan_timer) {
|
||||||
|
timerStop(fast_pin_mux.scan_timer);
|
||||||
|
timerDetachInterrupt(fast_pin_mux.scan_timer);
|
||||||
|
timerEnd(fast_pin_mux.scan_timer);
|
||||||
|
fast_pin_mux.scan_timer = 0;
|
||||||
|
}
|
||||||
|
} else if (flag == 2) {
|
||||||
|
portENTER_CRITICAL(&fast_pin_mux.scan_timerMux);
|
||||||
|
for (uint32_t cnt = 0; cnt < len; cnt++) {
|
||||||
|
fast_pin_mux.scan_buff[cnt] = *buf++;
|
||||||
|
}
|
||||||
|
fast_pin_mux.scan_buff_size = len;
|
||||||
|
portEXIT_CRITICAL(&fast_pin_mux.scan_timerMux);
|
||||||
|
} else {
|
||||||
|
portENTER_CRITICAL(&fast_pin_mux.scan_timerMux);
|
||||||
|
retval = fast_pin_mux.scan_cnt;
|
||||||
|
portEXIT_CRITICAL(&fast_pin_mux.scan_timerMux);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // ESP32_FAST_MUX
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#ifdef USE_SCRIPT_TASK
|
#ifdef USE_SCRIPT_TASK
|
||||||
|
|
||||||
|
@ -9912,7 +10104,7 @@ int32_t url2file(uint8_t fref, char *url) {
|
||||||
uint32_t read = stream->readBytes(buff, size);
|
uint32_t read = stream->readBytes(buff, size);
|
||||||
glob_script_mem.files[fref].write(buff, read);
|
glob_script_mem.files[fref].write(buff, read);
|
||||||
len -= read;
|
len -= read;
|
||||||
AddLog(LOG_LEVEL_INFO,PSTR("HTTP read %d"), len);
|
AddLog(LOG_LEVEL_DEBUG,PSTR("HTTP read %d"), len);
|
||||||
}
|
}
|
||||||
delayMicroseconds(1);
|
delayMicroseconds(1);
|
||||||
}
|
}
|
||||||
|
@ -10610,6 +10802,9 @@ bool Xdrv10(uint8_t function)
|
||||||
switch (function) {
|
switch (function) {
|
||||||
//case FUNC_PRE_INIT:
|
//case FUNC_PRE_INIT:
|
||||||
case FUNC_INIT:
|
case FUNC_INIT:
|
||||||
|
|
||||||
|
//bitWrite(Settings->rule_enabled, 0, 0); // >>>>>>>>>>>
|
||||||
|
|
||||||
// set defaults to rules memory
|
// set defaults to rules memory
|
||||||
//bitWrite(Settings->rule_enabled,0,0);
|
//bitWrite(Settings->rule_enabled,0,0);
|
||||||
glob_script_mem.script_ram = Settings->rules[0];
|
glob_script_mem.script_ram = Settings->rules[0];
|
||||||
|
|
Loading…
Reference in New Issue