mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
Resolved conflicts
This commit is contained in:
commit
dad81769e3
@ -251,7 +251,7 @@ void Renderer::setTextFont(uint8_t f) {
|
||||
#else
|
||||
#ifdef USE_EPD_FONTS
|
||||
switch (font) {
|
||||
case 1:
|
||||
case 1:
|
||||
selected_font = &Font12;
|
||||
break;
|
||||
case 2:
|
||||
@ -540,8 +540,14 @@ void Renderer::drawPixel(int16_t x, int16_t y, uint16_t color) {
|
||||
|
||||
}
|
||||
|
||||
extern uint16_t index_colors[MAX_INDEXCOLORS];
|
||||
|
||||
// this is called for every driver
|
||||
void Renderer::setDrawMode(uint8_t mode) {
|
||||
drawmode=mode;
|
||||
for (uint32_t count = 0; count < MAX_INDEXCOLORS; count++) {
|
||||
index_colors[count] = GetColorFromIndex(count);
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::invertDisplay(boolean i) {
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define WHITE 1
|
||||
#define INVERSE 2
|
||||
|
||||
#define MAX_INDEXCOLORS 32
|
||||
|
||||
// depends on GFX driver
|
||||
// GFX patched
|
||||
// a. in class GFX setCursor,setTextSize => virtual
|
||||
|
@ -11,6 +11,7 @@ extern int l_cmd(bvm *vm);
|
||||
extern int l_getoption(bvm *vm);
|
||||
extern int l_millis(bvm *vm);
|
||||
extern int l_timereached(bvm *vm);
|
||||
extern int l_yield(bvm *vm);
|
||||
|
||||
// #if !BE_USE_PRECOMPILED_OBJECT
|
||||
#if 1 // TODO we will do pre-compiled later
|
||||
@ -21,6 +22,7 @@ be_native_module_attr_table(tasmota) {
|
||||
be_native_module_function("getoption", l_getoption),
|
||||
be_native_module_function("millis", l_millis),
|
||||
be_native_module_function("timereached", l_timereached),
|
||||
be_native_module_function("yield", l_yield),
|
||||
};
|
||||
|
||||
be_define_native_module(tasmota, NULL);
|
@ -1,46 +0,0 @@
|
||||

|
||||
|
||||
## ESP32 port with minimal changes
|
||||
## Description:
|
||||
This is my esp32 port, i try to make only minimal changes to the original source code
|
||||
from Theo Arends, now again for development branch.
|
||||
|
||||
## Checklist:
|
||||
- [x] The pull request is done against the latest dev branch
|
||||
- [x] Only relevant files were touched
|
||||
- [x] Only one feature/fix was added per PR.
|
||||
- [x] The code change is tested and works on core Tasmota_core_stage
|
||||
- [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass**
|
||||
- [x] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
|
||||
- [x] i checked binary "tasmota.bin" to be the same in development and development_esp32 branch
|
||||
|
||||
Here are the main things i have done
|
||||
|
||||
- in "lib_extra_dirs" i have libesp32 directory for things missing in ESP32 framework
|
||||
my "ESP32-to-ESP8266-compat" has all files that are not available in ESP32
|
||||
so you dont have to change the source code and i write code to get the informations from ESP32
|
||||
- all librarys that are not compatibel i add to lib_ignore
|
||||
- all code that is not for ESP32 i put in "#ifdef ESP8266" the define is from espessif platform
|
||||
- all code for ESP32 is in "#ifdef ESP32"
|
||||
- SerConfu8 type uint8_t for SerialConfig list
|
||||
- changed "HTTP_HEADER" to "HTTP_HEADER1", in ESP32 its an enum
|
||||
- for ip adress 0 i used IPAddress(0,0,0,0)
|
||||
- Special ESP.xxx call i change to ESP_xxx (ESP_rtcUserMemoryWrite, ...) and write macros for ESP8266
|
||||
- because ESP32 has only WEMOS 32 modul, i exclude all code like this:
|
||||
"if (SONOFF_xxx == Settings.module)" in "#ifdef ESP8266"
|
||||
- variable "sleep" i changed to "ssleep" because of standard library sleep(..) function
|
||||
- all esp32 stuff is in support_esp32.ino
|
||||
- in tasmota.ino i include "tasmota_compat.h"
|
||||
- in tasmota_template.h i use ifdef and tasmota_templESP32.h
|
||||
- defines for sensors that currently don't work, i undef in tasmota_templESP32.h
|
||||
- comment fo "no warnig" in "xdrv_20_hue.ino" thats the only warning i had
|
||||
|
||||
Build info
|
||||
|
||||
Copy platformio_override_esp32.ini to platformio_override.ini an select your imagetype.
|
||||
You can build tasmota and tasmota32 Version with one build.
|
||||
If you need other versions change platformio_override.ini
|
||||
|
||||
stay at home, have fun and keep good
|
||||
|
||||
Jörg
|
@ -87,7 +87,8 @@ upload_speed = 115200
|
||||
upload_resetmethod = nodemcu
|
||||
upload_port = COM5
|
||||
extra_scripts = ${scripts_defaults.extra_scripts}
|
||||
lib_ldf_mode = chain+
|
||||
lib_ldf_mode = chain
|
||||
lib_compat_mode = strict
|
||||
shared_libdeps_dir = lib
|
||||
lib_extra_dirs =
|
||||
lib/lib_basic
|
||||
|
@ -136,7 +136,6 @@ build_flags = ${esp32_defaults.build_flags}
|
||||
;-DESP32_STAGE=true
|
||||
|
||||
[library]
|
||||
lib_ldf_mode = chain+
|
||||
shared_libdeps_dir = lib
|
||||
; *** Library disable / enable for variant Tasmota(32). Disable reduces compile time
|
||||
; *** !!! Disabling needed libs will generate compile errors !!!
|
||||
@ -178,7 +177,6 @@ platform_packages = framework-arduinoespressif32 @ https://github.com/
|
||||
build_unflags = ${esp32_defaults.build_unflags}
|
||||
build_flags = ${common32.build_flags}
|
||||
lib_ignore =
|
||||
cc1101
|
||||
NimBLE-Arduino
|
||||
Micro-RTSP
|
||||
ESP32 Ethernet
|
||||
|
@ -61,7 +61,8 @@ upload_port = ${common.upload_port}
|
||||
upload_resetmethod = ${common.upload_resetmethod}
|
||||
upload_speed = 921600
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
lib_ldf_mode = chain+
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_compat_mode = ${common.lib_compat_mode}
|
||||
shared_libdeps_dir = lib
|
||||
lib_extra_dirs =
|
||||
lib/libesp32
|
||||
|
@ -16,6 +16,8 @@ upload_resetmethod = ${common.upload_resetmethod}
|
||||
upload_speed = ${common.upload_speed}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
lib_extra_dirs = ${common.lib_extra_dirs}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_compat_mode = ${common.lib_compat_mode}
|
||||
lib_ignore =
|
||||
Servo(esp8266)
|
||||
ESP8266AVRISP
|
||||
|
@ -16,8 +16,9 @@ extra_scripts = ${common32.extra_scripts}
|
||||
build_unflags = ${common32.build_unflags}
|
||||
build_flags = ${common32.build_flags}
|
||||
lib_extra_dirs = ${common32.lib_extra_dirs}
|
||||
lib_ldf_mode = ${common32.lib_ldf_mode}
|
||||
lib_compat_mode = ${common32.lib_compat_mode}
|
||||
lib_ignore =
|
||||
cc1101
|
||||
ESP32 Azure IoT Arduino
|
||||
ESP32 Async UDP
|
||||
ESP32 BLE Arduino
|
||||
|
@ -100,6 +100,13 @@ tasmota.exec_rules = def (ev_json)
|
||||
return ret
|
||||
end
|
||||
|
||||
tasmota.delay = def(ms)
|
||||
tend = tasmota.millis(ms)
|
||||
while !tasmota.timereached(tend)
|
||||
tasmota.yield()
|
||||
end
|
||||
end
|
||||
|
||||
#- Test
|
||||
#################################################################
|
||||
|
||||
@ -154,4 +161,11 @@ br def backlog(cmd_list) delay_backlog = tasmota.getoption(34) delay = 0 for cmd
|
||||
|
||||
br backlog( [ "Power 0", "Status 4", "Power 1" ] )
|
||||
|
||||
-#
|
||||
|
||||
#-
|
||||
|
||||
tasmota.delay = def(ms) tend = tasmota.millis(ms) log(str(tasmota.millis())) while !tasmota.timereached(tend) end log(str(tasmota.millis())) end
|
||||
tasmota.delay = def(ms) a=0 tend = tasmota.millis(ms) log(str(tasmota.millis())) while !tasmota.timereached(tend) a=a+1 end log(str(tasmota.millis())) log(str(a)) end
|
||||
|
||||
-#
|
@ -1338,7 +1338,7 @@ int ICACHE_RAM_ATTR Pin(uint32_t gpio, uint32_t index) {
|
||||
|
||||
bool PinUsed(uint32_t gpio, uint32_t index = 0);
|
||||
bool PinUsed(uint32_t gpio, uint32_t index) {
|
||||
return (Pin(gpio, index) > -1);
|
||||
return (Pin(gpio, index) >= 0);
|
||||
}
|
||||
|
||||
uint32_t GetPin(uint32_t lpin) {
|
||||
|
@ -168,7 +168,7 @@ void RotaryInit(void) {
|
||||
attachInterruptArg(Encoder[index].pina, RotaryIsrArg, &Encoder[index], FALLING);
|
||||
}
|
||||
}
|
||||
Rotary.present |= (Encoder[index].pinb > -1);
|
||||
Rotary.present |= (Encoder[index].pinb >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ void RotaryHandler(void) {
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control
|
||||
bool second_rotary = (Encoder[1].pinb > -1);
|
||||
bool second_rotary = (Encoder[1].pinb >= 0);
|
||||
if (0 == index) { // Rotary1
|
||||
if (button_pressed) {
|
||||
if (second_rotary) { // Color RGB
|
||||
|
@ -412,7 +412,7 @@ void SetLedLink(uint32_t state)
|
||||
if (-1 == led_pin) { // Legacy - LED1 is status
|
||||
SetLedPowerIdx(0, state);
|
||||
}
|
||||
else if (led_pin > -1) {
|
||||
else if (led_pin >= 0) {
|
||||
if (state) { state = 1; }
|
||||
digitalWrite(led_pin, (led_inv) ? !state : state);
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log
|
||||
#define D_CMND_DISP_WIDTH "Width"
|
||||
#define D_CMND_DISP_HEIGHT "Height"
|
||||
#define D_CMND_DISP_BLINKRATE "Blinkrate"
|
||||
#define D_CMND_DISP_BATCH "Batch"
|
||||
#define D_CMND_DISP_CLEAR "Clear"
|
||||
#define D_CMND_DISP_NUMBER "Number"
|
||||
#define D_CMND_DISP_FLOAT "Float"
|
||||
@ -78,6 +79,7 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log
|
||||
#define D_CMND_DISP_CLOCK "Clock"
|
||||
#define D_CMND_DISP_TEXTNC "TextNC" // NC - "No Clear"
|
||||
|
||||
|
||||
enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND,
|
||||
FUNC_DISPLAY_MODEL, FUNC_DISPLAY_MODE, FUNC_DISPLAY_POWER,
|
||||
FUNC_DISPLAY_CLEAR, FUNC_DISPLAY_DRAW_FRAME,
|
||||
@ -85,27 +87,42 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E
|
||||
FUNC_DISPLAY_DRAW_CIRCLE, FUNC_DISPLAY_FILL_CIRCLE,
|
||||
FUNC_DISPLAY_DRAW_RECTANGLE, FUNC_DISPLAY_FILL_RECTANGLE,
|
||||
FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING,
|
||||
FUNC_DISPLAY_DIM, FUNC_DISPLAY_BLINKRATE, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT,
|
||||
FUNC_DISPLAY_DIM, FUNC_DISPLAY_BLINKRATE
|
||||
#ifdef USE_UFILESYS
|
||||
,FUNC_DISPLAY_BATCH
|
||||
#endif
|
||||
, FUNC_DISPLAY_NUMBER, FUNC_DISPLAY_FLOAT,
|
||||
FUNC_DISPLAY_NUMBERNC, FUNC_DISPLAY_FLOATNC, FUNC_DISPLAY_BRIGHTNESS, FUNC_DISPLAY_RAW,
|
||||
FUNC_DISPLAY_LEVEL, FUNC_DISPLAY_SEVENSEG_TEXT, FUNC_DISPLAY_SEVENSEG_TEXTNC,
|
||||
FUNC_DISPLAY_SCROLLDELAY, FUNC_DISPLAY_CLOCK };
|
||||
|
||||
};
|
||||
|
||||
enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL };
|
||||
|
||||
const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix
|
||||
"|" D_CMND_DISP_MODEL "|" D_CMND_DISP_WIDTH "|" D_CMND_DISP_HEIGHT "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|"
|
||||
D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|"
|
||||
D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE "|" D_CMND_DISP_CLEAR "|"
|
||||
D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|" D_CMND_DISP_BRIGHTNESS "|"
|
||||
D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
|
||||
D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE
|
||||
#ifdef USE_UFILESYS
|
||||
"|" D_CMND_DISP_BATCH
|
||||
#endif
|
||||
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
|
||||
D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
|
||||
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC;
|
||||
|
||||
;
|
||||
|
||||
void (* const DisplayCommand[])(void) PROGMEM = {
|
||||
&CmndDisplay, &CmndDisplayModel, &CmndDisplayWidth, &CmndDisplayHeight, &CmndDisplayMode, &CmndDisplayRefresh,
|
||||
&CmndDisplayDimmer, &CmndDisplayColumns, &CmndDisplayRows, &CmndDisplaySize, &CmndDisplayFont,
|
||||
&CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate, &CmndDisplayClear, &CmndDisplayNumber,
|
||||
&CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayBrightness, &CmndDisplayRaw,
|
||||
&CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC };
|
||||
&CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate
|
||||
#ifdef USE_UFILESYS
|
||||
,&CmndDisplayBatch
|
||||
#endif
|
||||
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC, &CmndDisplayBrightness, &CmndDisplayRaw,
|
||||
&CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC, &CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC
|
||||
};
|
||||
|
||||
char *dsp_str;
|
||||
|
||||
@ -128,6 +145,8 @@ uint8_t dsp_font;
|
||||
uint8_t dsp_flag;
|
||||
uint8_t dsp_on;
|
||||
|
||||
uint16_t index_colors[MAX_INDEXCOLORS];
|
||||
|
||||
#ifdef USE_DISPLAY_MODES1TO5
|
||||
|
||||
char **disp_log_buffer;
|
||||
@ -384,6 +403,11 @@ uint32_t decode_te(char *line) {
|
||||
|
||||
#define DISPLAY_BUFFER_COLS 128 // Max number of characters in linebuf
|
||||
|
||||
uint16_t GetColorFromIndex(uint32_t index) {
|
||||
if (index >= MAX_INDEXCOLORS) index = 0;
|
||||
return index_colors[index];
|
||||
}
|
||||
|
||||
void DisplayText(void)
|
||||
{
|
||||
uint8_t lpos;
|
||||
@ -489,7 +513,7 @@ void DisplayText(void)
|
||||
// color index 0-18
|
||||
cp++;
|
||||
var = atoiv(cp, &temp);
|
||||
if (renderer) ftemp=renderer->GetColorFromIndex(temp);
|
||||
if (renderer) ftemp = GetColorFromIndex(temp);
|
||||
} else {
|
||||
// float because it must handle unsigned 16 bit
|
||||
var = fatoiv(cp,&ftemp);
|
||||
@ -504,7 +528,7 @@ void DisplayText(void)
|
||||
// color index 0-18
|
||||
cp++;
|
||||
var = atoiv(cp, &temp);
|
||||
if (renderer) ftemp=renderer->GetColorFromIndex(temp);
|
||||
if (renderer) ftemp = GetColorFromIndex(temp);
|
||||
} else {
|
||||
var = fatoiv(cp,&ftemp);
|
||||
}
|
||||
@ -661,6 +685,18 @@ void DisplayText(void)
|
||||
}
|
||||
break; }
|
||||
case 'd':
|
||||
if (*cp == 'c') {
|
||||
cp++;
|
||||
// define index colo
|
||||
var = atoiv(cp, &temp);
|
||||
cp += var;
|
||||
cp++;
|
||||
var = fatoiv(cp, &ftemp);
|
||||
cp += var;
|
||||
if (temp >= MAX_INDEXCOLORS) temp = 0;
|
||||
index_colors[temp] = ftemp;
|
||||
break;
|
||||
}
|
||||
// force draw grafics buffer
|
||||
if (renderer) renderer->Updateframe();
|
||||
else DisplayDrawFrame();
|
||||
@ -876,8 +912,8 @@ void DisplayText(void)
|
||||
if (buttons[num]) {
|
||||
if (!sbt) {
|
||||
buttons[num]->vpower.slider = 0;
|
||||
buttons[num]->initButtonUL(renderer, gxp, gyp, gxs, gys, renderer->GetColorFromIndex(outline),\
|
||||
renderer->GetColorFromIndex(fill), renderer->GetColorFromIndex(textcolor), bbuff, textsize);
|
||||
buttons[num]->initButtonUL(renderer, gxp, gyp, gxs, gys, GetColorFromIndex(outline),\
|
||||
GetColorFromIndex(fill), GetColorFromIndex(textcolor), bbuff, textsize);
|
||||
if (!bflags) {
|
||||
// power button
|
||||
if (dflg) buttons[num]->xdrawButton(bitRead(TasmotaGlobal.power, num));
|
||||
@ -898,8 +934,8 @@ void DisplayText(void)
|
||||
} else {
|
||||
// slider
|
||||
buttons[num]->vpower.slider = 1;
|
||||
buttons[num]->SliderInit(renderer, gxp, gyp, gxs, gys, outline, renderer->GetColorFromIndex(fill),\
|
||||
renderer->GetColorFromIndex(textcolor), renderer->GetColorFromIndex(textsize));
|
||||
buttons[num]->SliderInit(renderer, gxp, gyp, gxs, gys, outline, GetColorFromIndex(fill),\
|
||||
GetColorFromIndex(textcolor), GetColorFromIndex(textsize));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -945,6 +981,45 @@ void DisplayText(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
extern FS *ufsp;
|
||||
void Display_Text_From_File(const char *file) {
|
||||
File fp;
|
||||
fp = ufsp->open(file, FS_FILE_READ);
|
||||
if (fp >= 0) {
|
||||
char *savptr = XdrvMailbox.data;
|
||||
char linebuff[128];
|
||||
while (fp.available()) {
|
||||
uint16_t index = 0;
|
||||
while (fp.available()) {
|
||||
uint8_t buf[1];
|
||||
fp.read(buf,1);
|
||||
if (buf[0]=='\n' || buf[0]=='\r') {
|
||||
break;
|
||||
} else {
|
||||
linebuff[index] = buf[0];
|
||||
index++;
|
||||
if (index >= sizeof(linebuff) - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
linebuff[index] = 0;
|
||||
char *cp = linebuff;
|
||||
while (*cp==' ') cp++;
|
||||
if (*cp == ';') continue;
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("displaytext %s"), cp);
|
||||
// execute display text here
|
||||
XdrvMailbox.data = cp;
|
||||
XdrvMailbox.data_len = 0;
|
||||
DisplayText();
|
||||
}
|
||||
XdrvMailbox.data = savptr;
|
||||
fp.close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#ifdef USE_DISPLAY_MODES1TO5
|
||||
@ -1329,6 +1404,7 @@ void DisplayLocalSensor(void)
|
||||
|
||||
#endif // USE_DISPLAY_MODES1TO5
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Public
|
||||
\*********************************************************************************************/
|
||||
@ -1344,6 +1420,9 @@ void DisplayInitDriver(void)
|
||||
renderer->setDrawMode(0);
|
||||
}
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
Display_Text_From_File("/display.ini");
|
||||
#endif
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings.display_model);
|
||||
|
||||
@ -1594,6 +1673,16 @@ void CmndDisplayClock(void)
|
||||
}
|
||||
ResponseCmndNumber(XdrvMailbox.payload);
|
||||
}
|
||||
#ifdef USE_UFILESYS
|
||||
void CmndDisplayBatch(void) {
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
if (!Settings.display_mode) {
|
||||
Display_Text_From_File(XdrvMailbox.data);
|
||||
}
|
||||
ResponseCmndChar(XdrvMailbox.data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CmndDisplaySize(void)
|
||||
{
|
||||
@ -2168,7 +2257,7 @@ void RedrawGraph(uint8_t num, uint8_t flags) {
|
||||
uint16_t linecol=fg_color;
|
||||
|
||||
if (color_type==COLOR_COLOR) {
|
||||
linecol=renderer->GetColorFromIndex(gp->color_index);
|
||||
linecol = GetColorFromIndex(gp->color_index);
|
||||
}
|
||||
|
||||
if (!gp->flags.overlay) {
|
||||
@ -2190,7 +2279,7 @@ void AddGraph(uint8_t num,uint8_t val) {
|
||||
|
||||
uint16_t linecol=fg_color;
|
||||
if (color_type==COLOR_COLOR) {
|
||||
linecol=renderer->GetColorFromIndex(gp->color_index);
|
||||
linecol = GetColorFromIndex(gp->color_index);
|
||||
}
|
||||
gp->xcnt++;
|
||||
if (gp->xcnt>gp->xs) {
|
||||
|
@ -230,29 +230,29 @@ void HueRespondToMSearch(void)
|
||||
* Hue web server additions
|
||||
\*********************************************************************************************/
|
||||
|
||||
//<?xml version="1.0"?><root xmlns="urn:schemas-upnp-org:device-1-0"><specVersion><major>1</major><minor>0</minor></specVersion>"<URLBase>http://{x1:80/</URLBase><device><deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType><friendlyName>Amazon-Echo-HA-Bridge ({x1)</friendlyName><manufacturer>Royal Philips Electronics</manufacturer><manufacturerURL>http://www.philips.com</manufacturerURL><modelDescription>Philips hue Personal Wireless Lighting</modelDescription><modelName>Philips hue bridge 2012</modelName><modelNumber>929000226503</modelNumber><serialNumber>{x3</serialNumber><UDN>uuid:{x2</UDN></device></root>\r\n\r\n
|
||||
//Successfully compressed from 626 to 394 bytes (-37.1%)
|
||||
const size_t HUE_DESCRIPTION_XML_SIZE = 626;
|
||||
//<?xml version="1.0"?><root xmlns="urn:schemas-upnp-org:device-1-0"><specVersion><major>1</major><minor>0</minor></specVersion><URLBase>http://{x1:80/</URLBase><device><deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType><friendlyName>Amazon-Echo-HA-Bridge ({x1)</friendlyName><manufacturer>Royal Philips Electronics</manufacturer><manufacturerURL>http://www.philips.com</manufacturerURL><modelDescription>Philips hue Personal Wireless Lighting</modelDescription><modelName>Philips hue bridge 2012</modelName><modelNumber>929000226503</modelNumber><serialNumber>{x3</serialNumber><UDN>uuid:{x2</UDN></device></root>\r\n\r\n
|
||||
//Successfully compressed from 625 to 391 bytes (-37.4%)
|
||||
const size_t HUE_DESCRIPTION_XML_SIZE = 625;
|
||||
const char HUE_DESCRIPTION_XML_COMPRESSED[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E"
|
||||
"\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\xF0\x62\x98\xDB\xF1\xD6\x2C"
|
||||
"\x67\x0C\x3A\xF3\xE3\xC7\x98\x8C\xCF\x43\x67\x59\xC8\x75\xB3\xD8\x7E\x1E\x85\xE1"
|
||||
"\x8C\x32\x33\x04\x1C\x78\xFC\x3D\x06\xD9\xAF\x3E\x7E\x1C\x87\xA1\xD8\x40\x83\x14"
|
||||
"\xF4\x1B\xBD\x9F\x3F\x0E\x33\xD0\xEC\x20\x41\x8A\x7A\x1D\x80\x8F\x85\x1E\xC3\xD0"
|
||||
"\x85\x97\xC8\x22\x1D\x7E\x67\xE0\xAA\xA1\x87\x99\xD8\x76\x1E\xD3\x61\xC8\x79\xFD"
|
||||
"\x9D\x87\xA1\xD8\x40\x87\x50\xF4\x04\x1D\x18\x10\xE2\x15\x19\x0C\x67\xE0\x2B\x6D"
|
||||
"\xC7\x99\x0E\xBF\x68\x67\x99\xC8\x7A\x1D\x84\x08\xD8\x61\xE8\x63\xFA\xF8\x40\x8C"
|
||||
"\x8B\xAC\x6B\x3F\x0A\xC6\xD9\xB7\x38\xEB\x26\x18\xAC\x3A\xC8\x51\x59\xD6\x43\xBF"
|
||||
"\xA2\x0F\x34\x77\x4F\x69\xB0\xE4\x3B\xC7\xA1\xD8\x40\x91\x83\x1E\x83\x6F\x85\x98"
|
||||
"\xB0\xE8\x5F\xDF\xCF\xC2\xFE\x19\x58\x48\x86\x0A\xD0\xB4\x67\x91\x30\x98\x75\xFC"
|
||||
"\xED\x0F\xC7\xA1\xD8\x09\x18\x20\x24\x62\x44\x2C\xBE\x41\x02\x1F\x06\xE3\xE3\xE3"
|
||||
"\xE7\x41\x80\x83\x8D\x1D\x03\xC1\xA0\x93\x89\x10\xB2\xF9\x04\x7E\x1E\x83\x70\x46"
|
||||
"\x11\x08\xFC\x1F\xF4\x65\x6E\x71\xF8\x08\x7A\x48\xA1\x6D\x10\xC7\xFF\x67\x58\x48"
|
||||
"\x87\xF7\xEC\x27\xEF\x22\x0B\x47\x85\x56\xF0\xF1\xE8\x76\x02\x66\x2A\x2B\x08\x39"
|
||||
"\x39\x75\x8D\x60\x91\x90\x0E\x04\x1E\x12\x0E\x53\x94\x40\x85\x88\x82\x17\x08\x98"
|
||||
"\x23\x08\xB8\x58\xD1\xCF\xE7\xE1\xC5\x49\xB7\x55\xDA\xEC\x81\x0F\x01\x04\x1A\xC7"
|
||||
"\xA7\x9F\xF6\xC1\x0E\x51\xED\x36\x1C\xB3\xD0\xEC\x20\x48\x9C\x7A\x10\xB2\x10\xB8"
|
||||
"\xFC\x16\x2F\x44\x3C\xCF\x69\xB0\xE5\x1E\x87\x61\x10\xB2\x10\xB8\xFC\x04\x3E\x38"
|
||||
"\xCF\xC3\xD0\xEC\xFE\x65\x1F\x93\x85\x23\x74\xE1\x48\xDC";
|
||||
"\xF4\x1B\xBD\x9F\x3F\x0E\x33\xD0\xEC\x20\x41\x8A\x7A\x1D\x80\x91\x85\x10\xB2\xF9"
|
||||
"\x04\x43\xAF\xCC\xFC\x15\x54\x30\xF3\x3B\x0E\xC3\xDA\x6C\x39\x0F\x3F\xB3\xB0\xF4"
|
||||
"\x3B\x08\x10\xEA\x1E\x80\x83\xA2\x82\x1C\x42\xA3\x21\x8C\xFC\x05\x6D\xB4\xF3\x21"
|
||||
"\xD7\xED\x0C\xF3\x39\x0F\x43\xB0\x81\x1B\x0C\x3D\x0C\x7F\x5F\x08\x11\x91\x75\x8D"
|
||||
"\x67\xE1\x58\xDB\x36\xE7\x1D\x64\xC3\x15\x87\x59\x0A\x2B\x3A\xC8\x77\xF4\x41\xE6"
|
||||
"\x8E\xE9\xED\x36\x1C\x87\x78\xF4\x3B\x08\x12\x30\x63\xD0\x6D\xF0\xB3\x16\x1D\x0B"
|
||||
"\xFB\xF9\xF8\x5F\xC3\x2B\x09\x10\xC1\x5A\x16\x8C\xF2\x26\x13\x0E\xBF\x9D\xA1\xF8"
|
||||
"\xF4\x3B\x01\x23\x04\x04\x8C\x48\x85\x97\xC8\x20\x43\xE0\xDC\x7C\x7C\x7C\xE8\x30"
|
||||
"\x10\x71\xA3\xA0\x78\x34\x12\x71\x22\x16\x5F\x20\x8F\xC3\xD0\x6E\x08\xC2\x21\x1F"
|
||||
"\x83\xFE\x8C\xAD\xCE\x3F\x01\x0F\x49\x14\x2D\xA2\x18\xFF\xEC\xEB\x09\x10\xFE\xFD"
|
||||
"\x84\xFD\xE4\x41\x68\xF0\xAA\xDE\x1E\x3D\x0E\xC0\x4C\xC5\x41\x07\x27\x2E\xB1\xAC"
|
||||
"\x12\x32\x01\xC0\x83\xC2\x41\xCA\x72\x88\x10\xB1\x10\x42\xE1\x13\x04\x61\x17\x0B"
|
||||
"\x1A\x39\xFC\xFC\x38\xA9\x36\xEA\xBB\x5D\x90\x21\xE0\x20\x83\x58\xF4\xF3\xFE\xD8"
|
||||
"\x21\xCA\x3D\xA6\xC3\x96\x7A\x1D\x84\x09\x13\x8F\x42\x16\x42\x17\x1F\x82\xC5\xE8"
|
||||
"\x87\x99\xED\x36\x1C\xA3\xD0\xEC\x22\x16\x42\x17\x1F\x80\x87\xC7\x19\xF8\x7A\x1D"
|
||||
"\x9F\xCC\xA3\xF2\x70\xA4\x6E\x9C\x29\x1B\x8D";
|
||||
// const char HUE_DESCRIPTION_XML[] PROGMEM =
|
||||
// "<?xml version=\"1.0\"?>"
|
||||
// "<root xmlns=\"urn:schemas-upnp-org:device-1-0\">"
|
||||
|
@ -142,6 +142,15 @@ bool Z_Mapper::addEdge(const Z_Mapper_Edge & edge2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String EscapeHTMLString(const char *s_P) {
|
||||
String s((const __FlashStringHelper*) s_P);
|
||||
s.replace(F("&"), F("&"));
|
||||
s.replace(F("\""), F("""));
|
||||
s.replace(F("<"), F("<"));
|
||||
s.replace(F(">"), F(">"));
|
||||
return s;
|
||||
}
|
||||
|
||||
void Z_Mapper::dumpInternals(void) const {
|
||||
WSContentSend_P(PSTR("nodes:[" "{id:\"0x0000\",label:\"Coordinator\",group:\"o\",title:\"0x0000\"}"));
|
||||
for (const auto & device : zigbee_devices.getDevices()) {
|
||||
@ -150,7 +159,7 @@ void Z_Mapper::dumpInternals(void) const {
|
||||
|
||||
const char *fname = device.friendlyName;
|
||||
if (fname != nullptr) {
|
||||
WSContentSend_P(PSTR("%s"), fname);
|
||||
WSContentSend_P(PSTR("%s"), EscapeJSONString(fname).c_str());
|
||||
} else {
|
||||
WSContentSend_P(PSTR("0x%04X"), device.shortaddr);
|
||||
}
|
||||
|
@ -138,10 +138,10 @@ void ZigbeeInputLoop(void) {
|
||||
// buffer received, now check integrity
|
||||
if (zigbee_buffer->len() != zigbee_frame_len) {
|
||||
// Len is not correct, log and reject frame
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %_B, len %d, expected %d"), &zigbee_buffer, zigbee_buffer->len(), zigbee_frame_len);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %_B, len %d, expected %d"), zigbee_buffer, zigbee_buffer->len(), zigbee_frame_len);
|
||||
} else if (0x00 != fcs) {
|
||||
// FCS is wrong, packet is corrupt, log and reject frame
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %_B, %d"), &zigbee_buffer, fcs);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %_B, %d"), zigbee_buffer, fcs);
|
||||
} else {
|
||||
// frame is correct
|
||||
//AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char);
|
||||
@ -243,7 +243,7 @@ void ZigbeeInputLoop(void) {
|
||||
// remove 2 last bytes
|
||||
|
||||
if (crc_received != crc) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %_B"), crc_received, crc, &zigbee_buffer);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %_B"), crc_received, crc, zigbee_buffer);
|
||||
} else {
|
||||
// copy buffer
|
||||
SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC
|
||||
@ -265,7 +265,7 @@ void ZigbeeInputLoop(void) {
|
||||
}
|
||||
} else {
|
||||
// the buffer timed-out, print error and discard
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %_B"), &zigbee_buffer);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %_B"), zigbee_buffer);
|
||||
}
|
||||
zigbee_buffer->setLen(0); // empty buffer
|
||||
escape = false;
|
||||
|
@ -1517,7 +1517,7 @@ void ZigbeeGlowPermitJoinLight(void) {
|
||||
|
||||
// change the led state
|
||||
int led_pin = Pin(GPIO_LEDLNK);
|
||||
if (led_pin > -1) {
|
||||
if (led_pin >= 0) {
|
||||
analogWrite(led_pin, TasmotaGlobal.ledlnk_inverted ? 1023 - led_power : led_power);
|
||||
}
|
||||
}
|
||||
@ -1960,9 +1960,9 @@ void ZigbeeShow(bool json)
|
||||
|
||||
WSContentSend_PD(msg[ZB_WEB_STATUS_LINE],
|
||||
shortaddr,
|
||||
device.modelId ? device.modelId : "",
|
||||
device.manufacturerId ? device.manufacturerId : "",
|
||||
name, sbatt, slqi);
|
||||
device.modelId ? EscapeHTMLString(device.modelId).c_str() : "",
|
||||
device.manufacturerId ? EscapeHTMLString(device.manufacturerId).c_str() : "",
|
||||
EscapeHTMLString(name).c_str(), sbatt, slqi);
|
||||
|
||||
if(device.validLqi()) {
|
||||
for(uint32_t j = 0; j < 4; ++j) {
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include <berry.h>
|
||||
#include <csetjmp>
|
||||
|
||||
const size_t BERRY_STACK = 4096; // size for the alternate stack for continuation
|
||||
|
||||
const char kBrCommands[] PROGMEM = D_PRFX_BR "|" // prefix
|
||||
D_CMND_BR_RUN "|" D_CMND_BR_RESET
|
||||
;
|
||||
@ -35,49 +33,10 @@ void (* const BerryCommand[])(void) PROGMEM = {
|
||||
CmndBrRun, CmndBrReset,
|
||||
};
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Async mode for Berry VM
|
||||
*
|
||||
* We enhance the berry language with `yield()` and `wait(ms)` functions.
|
||||
* When called, the VM is frozen and control is given back to Tasmota. Then Tasmota
|
||||
* at next tick or when the time is reached, resumes the VM.
|
||||
*
|
||||
* This is based on coroutines scheme, similar to the contiuation stack of ESP8266.
|
||||
* The basic concept is that Tasmota records a longjump target including current stack position
|
||||
* and return address.
|
||||
* The Berry VM is then called with an alternate stack so that we can switch from both stacks
|
||||
* and keep the callchain intact.
|
||||
*
|
||||
* High level view:
|
||||
* - Tasmota records a return vector with `setjmp`
|
||||
* - Tasmota changes replaces the native stack with an alternate stack pre-allocated on the heap
|
||||
* - Tasmota calls the Berry VM with `be_pcall`
|
||||
* - During the flow of Berry VM, the user code calls `yield()` or `wait(ms)`
|
||||
* - Corresponding native function is called (still on alternate stack)
|
||||
* - Native function records VM resume target with `setjmp`
|
||||
* - and gives back function to Tasmota via `longjmp`.
|
||||
* Note: `longjmp` restores at the same time the native stack.
|
||||
*
|
||||
* Note: trampoline functions relies on global variables, since stack variable don't work anymore
|
||||
* when replacing stack.
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
class BerrySupport {
|
||||
public:
|
||||
bvm *vm = nullptr; // berry vm
|
||||
bool rules_busy = false; // are we already processing rules, avoid infinite loop
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
// Alternate stack for the Berry VM
|
||||
uint8_t *stack_alloc = nullptr; // stack malloc address
|
||||
uint8_t *stack = nullptr; // alternate stack for continuation (top of stack)
|
||||
// longjmp vectors to yield from Tasmota to VM and reverse
|
||||
bool ta_cont_ok = false; // is the Tasmota continuation address valid?
|
||||
bool vm_cont_ok = false; // is the VM continuation address valid?
|
||||
jmp_buf ta_cont; // continuation structure for the longjump back to Tasmota
|
||||
jmp_buf vm_cont;
|
||||
// used by trampoline to call be_pcall()
|
||||
#endif // USE_BERRY_ASYNC
|
||||
const char *fname = nullptr; // name of berry function to call
|
||||
int32_t fret = 0;
|
||||
};
|
||||
@ -109,6 +68,7 @@ void checkBeTop(void) {
|
||||
* tasmota.getoption(index:int) -> int
|
||||
* tasmota.millis([delay:int]) -> int
|
||||
* tasmota.timereached(timer:int) -> bool
|
||||
* tasmota.yield() -> nil
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
extern "C" {
|
||||
@ -216,37 +176,16 @@ extern "C" {
|
||||
}
|
||||
be_return_nil(vm); // Return nil when something goes wrong
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Berry: `printStack() -> nul`
|
||||
// print stack pointer
|
||||
// int32_t l_printStack(bvm *vm) {
|
||||
// int r = 0;
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("Trampo: stack = 0x%08X"), &r);
|
||||
// be_return(vm);
|
||||
// }
|
||||
|
||||
// Yield
|
||||
int32_t l_yield(struct bvm *vm) {
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
if (berry.ta_cont_ok) { // if no ta_cont address, then ignore
|
||||
if (setjmp(berry.vm_cont) == 0) { // record the current state
|
||||
berry.vm_cont_ok = true;
|
||||
longjmp(berry.ta_cont, -1); // give back control to Tasmota
|
||||
}
|
||||
// Berry: `yield() -> nil`
|
||||
// ESP object
|
||||
int32_t l_yield(bvm *vm);
|
||||
int32_t l_yield(bvm *vm) {
|
||||
optimistic_yield(10);
|
||||
be_return(vm);
|
||||
}
|
||||
berry.vm_cont_ok = false; // from now, berry.vm_cont is no more valid
|
||||
#endif // USE_BERRY_ASYNC
|
||||
be_return(vm);
|
||||
}
|
||||
|
||||
// be_native_module_attr_table(esp) {
|
||||
// be_native_module_function("getFreeHeap", l_getFreeHeap),
|
||||
// };
|
||||
// be_define_native_module(math, nullptr);
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Handlers for Berry calls and async
|
||||
@ -329,82 +268,6 @@ void callBerryFunctionVoid(const char * fname) {
|
||||
checkBeTop();
|
||||
}
|
||||
|
||||
void test_input(void) {
|
||||
int i = 0;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("test_input stack = 0x%08X"), &i);
|
||||
callBerryFunctionVoid("noop");
|
||||
}
|
||||
|
||||
int be_pcall_with_alt_stack() {
|
||||
berry.fret = be_pcall(berry.vm, 0);
|
||||
return berry.fret;
|
||||
}
|
||||
|
||||
void printStack(void) {
|
||||
int r = 0;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: stack = 0x%08X"), &r);
|
||||
}
|
||||
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
int32_t callTrampoline(void *func) {
|
||||
// Tasmota stack active
|
||||
// ----------------------------------
|
||||
static int r;
|
||||
berry.vm_cont_ok = false;
|
||||
|
||||
if ((r = setjmp(berry.ta_cont)) == 0) { // capture registers
|
||||
// Tasmota stack active
|
||||
// ----------------------------------
|
||||
// on the first run, we call back ourselves with the alternate stack
|
||||
|
||||
// we clone the return vector and change the stack pointer
|
||||
static jmp_buf trampo;
|
||||
memmove(trampo, berry.ta_cont, sizeof(berry.ta_cont));
|
||||
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
trampo[1] = (int32_t) berry.stack; // change stack
|
||||
#else
|
||||
#error "Need CPU specific code for setting alternate stack"
|
||||
#endif
|
||||
longjmp(trampo, (int)func);
|
||||
// this part is unreachable (longjmp does not return)
|
||||
} else if (r == -1) {
|
||||
// Tasmota stack active
|
||||
// ----------------------------------
|
||||
// the call has completed normally, and `yield` was not called
|
||||
berry.ta_cont_ok = false;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: old stack restored"));
|
||||
// printStack();
|
||||
} else {
|
||||
// WARNING
|
||||
// ALTERNATE stack active
|
||||
// - DON'T USE ANY LOCAL VARIABLE HERE
|
||||
// -----------------------------------
|
||||
// r contains the address of the function to call
|
||||
// AddLog(LOG_LEVEL_INFO, "Trampo: new stack reg");
|
||||
// printStack();
|
||||
berry.ta_cont_ok = true; // Berry can call back Tasmota thread
|
||||
callBerryFunctionVoid("noop");
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: after callBerryFunctionVoid"));
|
||||
// printStack();
|
||||
longjmp(berry.ta_cont, -1);
|
||||
// this part is unreachable (longjmp does not return)
|
||||
// which protects us from accidentally using the alternate stack
|
||||
// in regular code
|
||||
}
|
||||
// Tasmota stack active
|
||||
// ----------------------------------
|
||||
}
|
||||
#endif // USE_BERRY_ASYNC
|
||||
|
||||
// void fake_callBerryFunctionVoid(const char * fname, jmp_buf * env) {
|
||||
// (void) setjmp(env);
|
||||
// }
|
||||
// void call_callBerryFunctionVoid(const char * fname, jmp_buf * ret_env, ) {
|
||||
// callBerryFunctionVoid(fname);
|
||||
// longjump(env, 1);
|
||||
// }
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Handlers for Berry calls and async
|
||||
*
|
||||
@ -553,10 +416,16 @@ const char berry_prog[] PROGMEM =
|
||||
"end "
|
||||
"end "
|
||||
|
||||
// Delay function, internally calls yield() every 10ms to avoid WDT
|
||||
"tasmota.delay = def(ms) "
|
||||
"tend = tasmota.millis(ms) "
|
||||
"while !tasmota.timereached(tend) "
|
||||
"tasmota.yield() "
|
||||
"end "
|
||||
"end "
|
||||
|
||||
// trigger Garbage Collector
|
||||
"gc.collect() "
|
||||
// "n = 1;"
|
||||
// "def every_second() n = n + 1; if (n % 100 == 10) log('foobar '+str(n)+' free_heap = '+str(tasmota.getfreeheap())) end end; "
|
||||
;
|
||||
|
||||
/*********************************************************************************************\
|
||||
@ -567,28 +436,17 @@ void BrReset(void) {
|
||||
if (berry.vm != nullptr) {
|
||||
be_vm_delete(berry.vm);
|
||||
berry.vm = nullptr;
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
berry.ta_cont_ok = false; // is the Tasmota continuation address valid?
|
||||
berry.vm_cont_ok = false; // is the VM continuation address valid?
|
||||
#endif // USE_BERRY_ASYNC
|
||||
}
|
||||
|
||||
int32_t ret_code1, ret_code2;
|
||||
bool berry_init_ok = false;
|
||||
do {
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
berry.stack_alloc = (uint8_t*) malloc(BERRY_STACK); // alternate stack
|
||||
berry.stack = berry.stack_alloc + BERRY_STACK; // top of stack
|
||||
#endif // USE_BERRY_ASYNC
|
||||
|
||||
do {
|
||||
uint32_t heap_before = ESP.getFreeHeap();
|
||||
berry.vm = be_vm_new(); /* create a virtual machine instance */
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry VM created, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
|
||||
|
||||
// Register functions
|
||||
be_regfunc(berry.vm, PSTR("log"), l_logInfo);
|
||||
// be_regfunc(berry.vm, "printStack", l_printStack);
|
||||
be_regfunc(berry.vm, PSTR("yield"), l_yield);
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry function registered, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
|
||||
|
||||
@ -608,83 +466,6 @@ void BrReset(void) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry code ran, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
|
||||
be_pop(berry.vm, 1);
|
||||
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("Get function"));
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("BE_TOP = %d"), be_top(berry.vm));
|
||||
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("Get function"));
|
||||
// be_getglobal(vm, PSTR("func"));
|
||||
// be_pushint(vm, 3);
|
||||
// be_pcall(vm, 1);
|
||||
// be_pop(vm, 2);
|
||||
// // AddLog(LOG_LEVEL_INFO, PSTR("BE_TOP = %d"), be_top(vm));
|
||||
|
||||
// be_getglobal(vm, "testreal");
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("is_nil -1 = %d"), be_isnil(vm, -1));
|
||||
// be_pcall(vm, 0);
|
||||
// // AddLog(LOG_LEVEL_INFO, PSTR("is_nil -1 = %d"), be_isnil(vm, -1));
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("to_string -1 = %s"), be_tostring(vm, -1));
|
||||
// be_pop(vm, 1);
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("BE_TOP = %d"), be_top(vm));
|
||||
|
||||
// try a non-existant function
|
||||
// be_getglobal(vm, "doesnotexist");
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("is_nil -1 = %d"), be_isnil(vm, -1));
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("BE_TOP = %d"), be_top(vm));
|
||||
// be_pop(vm, 1);
|
||||
|
||||
// Try
|
||||
// callBerryFunctionVoid("noop");
|
||||
// callBerryFunctionVoid("noop2");
|
||||
|
||||
// test_input();
|
||||
|
||||
/////////////////////////////////
|
||||
// callTrampoline(nullptr);
|
||||
|
||||
// // Try coroutines
|
||||
// int jmp_val;
|
||||
// if ((jmp_val=setjmp(berry.ta_cont)) == 0) {
|
||||
// AddLog(LOG_LEVEL_INFO, "vm return address = 0x%08X", berry.ta_cont[0]);
|
||||
// AddLog(LOG_LEVEL_INFO, "vm stack address = 0x%08X", berry.ta_cont[1]);
|
||||
// callTrampoline(nullptr);
|
||||
// // // call routine
|
||||
// // jmp_buf trampoline_env;
|
||||
// // fake_callBerryFunctionVoid("noop", &tasmota_env);
|
||||
// // trampoline_env[0] = call_callBerryFunctionVoid
|
||||
// } else {
|
||||
// AddLog(LOG_LEVEL_INFO, "vm return address = 0x%08X", berry.ta_cont[0]);
|
||||
// // we get back control
|
||||
// }
|
||||
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
if (berry.vm_cont_ok) {
|
||||
printStack();
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: we need to complete vm exec 1"));
|
||||
if (setjmp(berry.ta_cont) == 0) {
|
||||
berry.ta_cont_ok = true;
|
||||
berry.vm_cont_ok = false;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: call exec 1"));
|
||||
longjmp(berry.vm_cont, 1);
|
||||
}
|
||||
berry.ta_cont_ok = false;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: returned from exec 1"));
|
||||
}
|
||||
printStack();
|
||||
|
||||
if (berry.vm_cont_ok) {
|
||||
printStack();
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: we need to complete vm exec 2"));
|
||||
if (setjmp(berry.ta_cont) == 0) {
|
||||
berry.ta_cont_ok = true;
|
||||
berry.vm_cont_ok = false;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: call exec 2"));
|
||||
longjmp(berry.vm_cont, 1);
|
||||
}
|
||||
berry.ta_cont_ok = false;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("Trampo: returned from exec 2"));
|
||||
}
|
||||
printStack();
|
||||
#endif // USE_BERRY_ASYNC
|
||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_BERRY "Berry initialized, RAM consumed=%u (Heap=%u)"), heap_before - ESP.getFreeHeap(), ESP.getFreeHeap());
|
||||
// AddLog(LOG_LEVEL_INFO, PSTR("Delete Berry VM"));
|
||||
// be_vm_delete(vm);
|
||||
@ -699,12 +480,6 @@ void BrReset(void) {
|
||||
be_vm_delete(berry.vm);
|
||||
berry.vm = nullptr;
|
||||
}
|
||||
#ifdef USE_BERRY_ASYNC
|
||||
if (berry.stack_alloc != nullptr) {
|
||||
free(berry.stack_alloc);
|
||||
berry.stack_alloc = nullptr;
|
||||
}
|
||||
#endif // USE_BERRY_ASYNC
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user