diff --git a/CHANGELOG.md b/CHANGELOG.md index eb781e0d4..804a381a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,11 @@ All notable changes to this project will be documented in this file. - (Internal) Range conversion edge values - NimBLE to v.1.3.3 - MQTT TLS dual mode (CA or fingeprint) in same firmware, ``SetOption132 1`` to force fingerprint +- Toolchains for ESP32x changed from 8.4.0-2021r1 to 8.4.0-2021r2 ### Fixed - Tuya dimmer range issue (#13849) -- BLE Memory leak with update NimBLE v.1.3.1 to v.1.3.3 +- BLE Memory leak with update NimBLE v.1.3.1 to v.1.3.3 ## [10.0.0.3] 20211130 ### Added diff --git a/lib/libesp32/Berry/src/be_api.c b/lib/libesp32/Berry/src/be_api.c index d883c08d7..79d5c48ff 100644 --- a/lib/libesp32/Berry/src/be_api.c +++ b/lib/libesp32/Berry/src/be_api.c @@ -51,7 +51,7 @@ static void class_init(bvm *vm, bclass *c, const bnfuncinfo *lib) ++slib; } } - be_map_release(vm, c->members); /* clear space */ + be_map_compact(vm, c->members); /* clear space */ } } diff --git a/lib/libesp32/Berry/src/be_class.c b/lib/libesp32/Berry/src/be_class.c index a960d4b24..0f4efb3d5 100644 --- a/lib/libesp32/Berry/src/be_class.c +++ b/lib/libesp32/Berry/src/be_class.c @@ -40,7 +40,7 @@ bclass* be_newclass(bvm *vm, bstring *name, bclass *super) void be_class_compress(bvm *vm, bclass *c) { if (!gc_isconst(c) && c->members) { - be_map_release(vm, c->members); /* clear space */ + be_map_compact(vm, c->members); /* clear space */ } } @@ -220,7 +220,7 @@ static binstance* newobject(bvm *vm, bclass *c) /* Instanciate new instance from stack with argc parameters */ /* Pushes the constructor on the stack to be executed if a construtor is found */ /* Returns true if a constructor is found */ -bbool be_class_newobj(bvm *vm, bclass *c, int32_t pos, int argc, int mode) +bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode) { bvalue init; binstance *obj = newobject(vm, c); /* create empty object hierarchy from class hierarchy */ diff --git a/lib/libesp32/Berry/src/be_class.h b/lib/libesp32/Berry/src/be_class.h index 59abbab30..405ea6d38 100644 --- a/lib/libesp32/Berry/src/be_class.h +++ b/lib/libesp32/Berry/src/be_class.h @@ -58,7 +58,7 @@ void be_prim_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f); void be_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl); int be_class_closure_count(bclass *c); void be_class_upvalue_init(bvm *vm, bclass *c); -bbool be_class_newobj(bvm *vm, bclass *c, int32_t pos, int argc, int mode); +bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode); int be_instance_member_simple(bvm *vm, binstance *obj, bstring *name, bvalue *dst); int be_instance_member(bvm *vm, binstance *obj, bstring *name, bvalue *dst); int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst); diff --git a/lib/libesp32/Berry/src/be_jsonlib.c b/lib/libesp32/Berry/src/be_jsonlib.c index 2ee2a4daa..1d7049ea1 100644 --- a/lib/libesp32/Berry/src/be_jsonlib.c +++ b/lib/libesp32/Berry/src/be_jsonlib.c @@ -54,7 +54,7 @@ static int is_object(bvm *vm, const char *class, int idx) } be_remove(vm, -2); } - const char *name = be_classname(vm, idx); + const char *name = be_classname(vm, -1); bbool ret = !strcmp(name, class); be_pop(vm, 1); return ret; diff --git a/lib/libesp32/Berry/src/be_map.c b/lib/libesp32/Berry/src/be_map.c index 004406f46..37f9efc62 100644 --- a/lib/libesp32/Berry/src/be_map.c +++ b/lib/libesp32/Berry/src/be_map.c @@ -343,7 +343,7 @@ bmapnode* be_map_val2node(bvalue *value) return (bmapnode *)((size_t)value - sizeof(bmapkey)); } -void be_map_release(bvm *vm, bmap *map) +void be_map_compact(bvm *vm, bmap *map) { (void)vm; if (!gc_isconst(map)) { diff --git a/lib/libesp32/Berry/src/be_map.h b/lib/libesp32/Berry/src/be_map.h index d632f0d0b..7ae76962c 100644 --- a/lib/libesp32/Berry/src/be_map.h +++ b/lib/libesp32/Berry/src/be_map.h @@ -56,6 +56,6 @@ bvalue* be_map_insertstr(bvm *vm, bmap *map, bstring *key, bvalue *value); void be_map_removestr(bvm *vm, bmap *map, bstring *key); bmapnode* be_map_next(bmap *map, bmapiter *iter); bmapnode* be_map_val2node(bvalue *value); -void be_map_release(bvm *vm, bmap *map); +void be_map_compact(bvm *vm, bmap *map); #endif diff --git a/lib/libesp32/Berry/src/be_module.c b/lib/libesp32/Berry/src/be_module.c index c661528a1..0256809af 100644 --- a/lib/libesp32/Berry/src/be_module.c +++ b/lib/libesp32/Berry/src/be_module.c @@ -99,7 +99,7 @@ static bmodule* new_module(bvm *vm, const bntvmodule *nm) obj->table = NULL; /* gc protection */ obj->table = be_map_new(vm); insert_attrs(vm, obj->table, nm); - be_map_release(vm, obj->table); /* clear space */ + be_map_compact(vm, obj->table); /* clear space */ be_stackpop(vm, 1); } return obj; diff --git a/lib/libesp32/Berry/src/be_solidifylib.c b/lib/libesp32/Berry/src/be_solidifylib.c index d8291b365..2b82b44fd 100644 --- a/lib/libesp32/Berry/src/be_solidifylib.c +++ b/lib/libesp32/Berry/src/be_solidifylib.c @@ -42,7 +42,7 @@ static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, co static void m_solidify_map(bvm *vm, bmap * map, const char *class_name) { // compact first - be_map_release(vm, map); + be_map_compact(vm, map); logfmt(" be_nested_map(%i,\n", map->count); diff --git a/lib/libesp32/Berry/src/be_strlib.c b/lib/libesp32/Berry/src/be_strlib.c index e82ec3cf2..53f35607b 100644 --- a/lib/libesp32/Berry/src/be_strlib.c +++ b/lib/libesp32/Berry/src/be_strlib.c @@ -330,7 +330,6 @@ static bstring* string_range(bvm *vm, bstring *str, binstance *range) { bint lower, upper; bint size = str_len(str); /* size of source string */ - // bint size = be_data_size(vm, -1); /* get source list size */ /* get index range */ bvalue temp; be_instance_member(vm, range, be_newstr(vm, "__lower__"), &temp); diff --git a/lib/libesp32/Berry/src/be_var.c b/lib/libesp32/Berry/src/be_var.c index ebc70ecea..4fee144cd 100644 --- a/lib/libesp32/Berry/src/be_var.c +++ b/lib/libesp32/Berry/src/be_var.c @@ -87,7 +87,7 @@ bvalue* be_global_var(bvm *vm, int index) void be_global_release_space(bvm *vm) { - be_map_release(vm, global(vm).vtab); + be_map_compact(vm, global(vm).vtab); be_vector_release(vm, &global(vm).vlist); } @@ -130,7 +130,7 @@ int be_builtin_new(bvm *vm, bstring *name) void be_bulitin_release_space(bvm *vm) { - be_map_release(vm, builtin(vm).vtab); + be_map_compact(vm, builtin(vm).vtab); be_vector_release(vm, &builtin(vm).vlist); } #else diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c index dd60e34b7..67519ee39 100644 --- a/lib/libesp32/Berry/src/be_vm.c +++ b/lib/libesp32/Berry/src/be_vm.c @@ -142,7 +142,7 @@ _vm->cf->status = PRIM_FUNC; \ } -static void prep_closure(bvm *vm, int32_t pos, int argc, int mode); +static void prep_closure(bvm *vm, int pos, int argc, int mode); static void attribute_error(bvm *vm, const char *t, bvalue *b, bvalue *c) { @@ -1186,7 +1186,7 @@ newframe: /* a new call frame */ } } -static void prep_closure(bvm *vm, int32_t pos, int argc, int mode) +static void prep_closure(bvm *vm, int pos, int argc, int mode) { bvalue *v, *end; bproto *proto = var2cl(vm->reg + pos)->proto; @@ -1211,7 +1211,7 @@ static void prep_closure(bvm *vm, int32_t pos, int argc, int mode) } } -static void do_closure(bvm *vm, int32_t pos, int argc) +static void do_closure(bvm *vm, int pos, int argc) { // bvalue *v, *end; // bproto *proto = var2cl(reg)->proto; @@ -1225,7 +1225,7 @@ static void do_closure(bvm *vm, int32_t pos, int argc) vm_exec(vm); } -static void do_ntvclos(bvm *vm, int32_t pos, int argc) +static void do_ntvclos(bvm *vm, int pos, int argc) { bntvclos *f = var_toobj(vm->reg + pos); push_native(vm, vm->reg + pos, argc, 0); @@ -1233,7 +1233,7 @@ static void do_ntvclos(bvm *vm, int32_t pos, int argc) ret_native(vm); } -static void do_ntvfunc(bvm *vm, int32_t pos, int argc) +static void do_ntvfunc(bvm *vm, int pos, int argc) { bntvfunc f = var_tontvfunc(vm->reg + pos); push_native(vm, vm->reg + pos, argc, 0); @@ -1241,7 +1241,7 @@ static void do_ntvfunc(bvm *vm, int32_t pos, int argc) ret_native(vm); } -static void do_class(bvm *vm, int32_t pos, int argc) +static void do_class(bvm *vm, int pos, int argc) { if (be_class_newobj(vm, var_toobj(vm->reg + pos), pos, ++argc, 0)) { be_incrtop(vm); @@ -1254,7 +1254,7 @@ void be_dofunc(bvm *vm, bvalue *v, int argc) { be_assert(vm->reg <= v && v < vm->stacktop); be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop); - int32_t pos = v - vm->reg; + int pos = v - vm->reg; switch (var_type(v)) { case BE_CLASS: do_class(vm, pos, argc); break; case BE_CLOSURE: do_closure(vm, pos, argc); break; diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 5ef6f0463..575f9d160 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -32,14 +32,14 @@ build_flags = ${esp_defaults.build_flags} -Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception [core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/v3.4.0/Tasmota-platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/v3.4.1/Tasmota-platform-espressif32.zip platform_packages = build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} [core32solo1] -platform = https://github.com/tasmota/platform-espressif32/releases/download/v3.4.0/Tasmota-platform-espressif32.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/v3.4.1/Tasmota-platform-espressif32.zip platform_packages = framework-arduinoespressif32 @ https://github.com/tasmota/arduino-esp32/releases/download/2.0.1.1/framework-arduinoespressif32-solo1-release_IDF4.4.tar.gz build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 62ffd8920..a97df50be 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "te laag" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pomptyd oorskry" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_AF_AF_H_ diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index d4015f984..249100589 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "твърде ниско" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "превишено време за помпане" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_BG_BG_H_ diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 08e72f1ea..0d193693e 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_CS_CZ_H_ diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index cc8080529..9ecbc9a03 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "zu niedrig" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "Pumpzeit überschritten" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_DE_DE_H_ diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index df517a383..630f19471 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_EL_GR_H_ diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 0fed4b222..9ea7bb50b 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -1084,9 +1084,9 @@ #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" // xdrv_60_shift595.ino -#define D_GPIO_SHIFT595_SRCLK "74HC595 SRCLK" -#define D_GPIO_SHIFT595_RCLK "74HC595 RCLK" -#define D_GPIO_SHIFT595_OE "74HC595 OE" -#define D_GPIO_SHIFT595_SER "74HC595 SER" +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" #endif // _LANGUAGE_EN_GB_H_ diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 6ef4fa653..88b371826 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "muy bajo" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "tiempo de bomba excedido" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_ES_ES_H_ diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 5dad0c998..f0c3031ed 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -1082,4 +1082,10 @@ #define D_NEOPOOL_PH_LOW "Trop bas" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "durée pompage expirée" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_FR_FR_H_ diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 569a0a830..486a540a1 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_FY_NL_H_ diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index b77b75a23..44853211d 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_HE_HE_H_ diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 713979b48..710d3ba3c 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_HU_HU_H_ diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index f706ee9ad..881f735e0 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "troppo basso" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "tempo pompa superato" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_IT_IT_H_ diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index a4ce5eae0..90c0f5138 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_KO_KO_H_ diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 7076b545f..dcc075d19 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "te laag" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pomptijd bereikt" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_NL_NL_H_ diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 52802b75c..dfd2c155b 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "czas pompowania przekroczony" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_PL_PL_D_H_ diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 4b59fce59..bcc837cd0 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "Muito baixo" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "tempo da bomba excedido" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_PT_BR_H_ diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index a5bdc4974..07804c950 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "Muito baixo" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "tempo da bomba excedido" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_PT_PT_H_ diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index d4ca37c23..a87dda8bc 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_RO_RO_H_ diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 25942817c..7808dba8b 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_RU_RU_H_ diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index aa77fbaef..0afdc669d 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_SK_SK_H_ diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 1ff6c8108..e86ddd99a 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_SV_SE_H_ diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 301feed7e..13487d3b3 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_TR_TR_H_ diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 044eaf47e..da89a72a7 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_UK_UA_H_ diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index f31be5015..d5e4c5543 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_VI_VN_H_ diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 3bfed5647..1ec0c7eac 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_ZH_CN_H_ diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index a82028e71..5d3c7ced5 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -1083,4 +1083,10 @@ #define D_NEOPOOL_PH_LOW "too low" #define D_NEOPOOL_PUMP_TIME_EXCEEDED "pump time exceeded" +// xdrv_60_shift595.ino +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" + #endif // _LANGUAGE_ZH_TW_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index d34174a56..dcdb5acc9 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -351,7 +351,7 @@ #define ZIGBEE_RMV_ZBRECEIVED false // [SetOption100] Remove ZbReceived form JSON message #define ZIGBEE_INDEX_EP false // [SetOption101] Add the source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 #define SHIFT595_INVERT_OUTPUTS false // [SetOption133] Don't invert outputs of 74x595 shift register -#define SHIFT595_DEVICE_COUNT 1 // [Shift595Devices] Set the number of connected 74x595 shift registers +#define SHIFT595_DEVICE_COUNT 1 // [Shift595DeviceCount] Set the number of connected 74x595 shift registers /*********************************************************************************************\ * END OF SECTION 1 diff --git a/tasmota/settings.h b/tasmota/settings.h index 02571350a..6e75d1bfd 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -162,7 +162,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t show_heap_with_timestamp : 1; // bit 16 (v9.5.0.9) - SetOption130 - (Debug) Show heap with logging timestamp uint32_t tuya_allow_dimmer_0 : 1; // bit 17 (v10.0.0.3) - SetOption131 - (Tuya) Allow save dimmer = 0 receved by MCU uint32_t tls_use_fingerprint : 1; // bit 18 (v10.0.0.4) - SetOption132 - (TLS) use fingerprint validation instead of CA based - uint32_t shift595_invert_outputs : 1; // bit 19 (v10.0.0.5) - SetOption133 - (Shift595) invert outputs of 74x595 shift registers + uint32_t shift595_invert_outputs : 1; // bit 19 (v10.0.0.4) - SetOption133 - (Shift595) invert outputs of 74x595 shift registers uint32_t spare20 : 1; // bit 20 uint32_t spare21 : 1; // bit 21 uint32_t spare22 : 1; // bit 22 @@ -487,8 +487,7 @@ typedef struct { int32_t energy_kWhyesterday_ph[3]; // 320 int32_t energy_kWhtotal_ph[3]; // 32C - uint8_t shift595_device_count; // 338 - uint8_t free_339[6]; // 339 + uint8_t free_338[7]; // 338 uint8_t tuyamcu_topic; // 33F Manage tuyaSend topic. ex_energy_power_delta on 6.6.0.20, replaced on 8.5.0.1 uint16_t domoticz_update_timer; // 340 @@ -687,8 +686,9 @@ typedef struct { uint8_t weight_change; // E9F uint8_t web_color2[2][3]; // EA0 Needs to be on integer / 3 distance from web_color - uint8_t free_ea6[33]; // EA6 + uint8_t free_ea6[32]; // EA6 + uint8_t shift595_device_count; // EC6 uint8_t sta_config; // EC7 uint8_t sta_active; // EC8 uint8_t rule_stop; // EC9 diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index f3e4fe977..3129c2831 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1043,7 +1043,7 @@ void Every100mSeconds(void) if (TasmotaGlobal.pulse_timer[i] != 0L) { // Timer active? if (TimeReached(TasmotaGlobal.pulse_timer[i])) { // Timer finished? TasmotaGlobal.pulse_timer[i] = 0L; // Turn off this timer - for (uint32_t j = 0; j < TasmotaGlobal.devices_present; j = j +MAX_PULSETIMERS) { + for (uint32_t j = 0; (i + j) < TasmotaGlobal.devices_present; j = j +MAX_PULSETIMERS) { ExecuteCommandPower(i + j +1, (POWER_ALL_OFF_PULSETIME_ON == Settings->poweronstate) ? POWER_ON : POWER_OFF, SRC_PULSETIMER); } } diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 9e08aedb1..311ac9388 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -176,7 +176,7 @@ enum UserSelectablePins { GPIO_BL0942_RX, // BL0942 Serial interface GPIO_HM330X_SET, // HM330X SET pin (sleep when low) GPIO_HEARTBEAT, GPIO_HEARTBEAT_INV, - GPIO_SHIFT595_SRCLK, GPIO_SHIFT595_RCLK, GPIO_SHIFT595_OE, GPIO_SHIFT595_SER, // 74HC595 Shift register + GPIO_SHIFT595_SRCLK, GPIO_SHIFT595_RCLK, GPIO_SHIFT595_OE, GPIO_SHIFT595_SER, // 74x595 Shift register GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -937,7 +937,7 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif // ESP32 #ifdef USE_SHIFT595 - AGPIO(GPIO_SHIFT595_SRCLK), // 74HC595 shift register + AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register AGPIO(GPIO_SHIFT595_RCLK), AGPIO(GPIO_SHIFT595_OE), AGPIO(GPIO_SHIFT595_SER), diff --git a/tasmota/xdrv_52_3_berry_lvgl.ino b/tasmota/xdrv_52_3_berry_lvgl.ino index af435851b..a8bd61dda 100644 --- a/tasmota/xdrv_52_3_berry_lvgl.ino +++ b/tasmota/xdrv_52_3_berry_lvgl.ino @@ -404,6 +404,10 @@ extern "C" { be_return(vm); } + /*********************************************************************************************\ + * Support for lv_fonts + \*********************************************************************************************/ + // load font by name on file-system int lv0_load_font(bvm *vm) { int argc = be_top(vm); if (argc == 1 && be_isstring(vm, 1)) { @@ -421,6 +425,10 @@ extern "C" { be_raise(vm, kTypeError, nullptr); } + /*********************************************************************************************\ + * Support for Freetype fonts + \*********************************************************************************************/ + // load freetype font by name in file-system int lv0_load_freetype_font(bvm *vm) { #ifdef USE_LVGL_FREETYPE int argc = be_top(vm); @@ -448,261 +456,212 @@ extern "C" { #endif // USE_LVGL_FREETYPE } - int lv0_load_montserrat_font(bvm *vm) { - int argc = be_top(vm); - if (argc == 1 && be_isint(vm, 1)) { - const lv_font_t * font = nullptr; - int32_t font_size = be_toindex(vm, 1); + /*********************************************************************************************\ + * Support for embedded fonts in Flash + \*********************************************************************************************/ + // We create tables for Font matching + // Size of `0` indicates end of table + typedef struct { + int16_t size; + const lv_font_t *font; + } lv_font_table_t; - switch (font_size) { + typedef struct { + const char * name; + const lv_font_table_t * table; + } lv_font_names_t; - #if LV_FONT_MONTSERRAT_8 - case 8: - font = &lv_font_montserrat_8; - break; - #endif + // Montserrat Font + const lv_font_table_t lv_montserrat_fonts[] = { + #if LV_FONT_MONTSERRAT_8 + { 8, &lv_font_montserrat_8 }, + #endif + #if LV_FONT_MONTSERRAT_10 + { 10, &lv_font_montserrat_10 }, + #endif + #if LV_FONT_MONTSERRAT_12 + { 12, &lv_font_montserrat_12 }, + #endif + #if LV_FONT_MONTSERRAT_14 + { 14, &lv_font_montserrat_14 }, + #endif + #if LV_FONT_MONTSERRAT_16 + { 16, &lv_font_montserrat_16 }, + #endif + #if LV_FONT_MONTSERRAT_18 + { 18, &lv_font_montserrat_18 }, + #endif + #if LV_FONT_MONTSERRAT_20 + { 20, &lv_font_montserrat_20 }, + #endif + #if LV_FONT_MONTSERRAT_22 + { 22, &lv_font_montserrat_22 }, + #endif + #if LV_FONT_MONTSERRAT_24 + { 24, &lv_font_montserrat_24 }, + #endif + #if LV_FONT_MONTSERRAT_26 + { 26, &lv_font_montserrat_26 }, + #endif + #if LV_FONT_MONTSERRAT_28 + { 28, &lv_font_montserrat_28 }, + #endif + #if LV_FONT_MONTSERRAT_28_COMPRESSED + { 28, &lv_font_montserrat_28_compressed, }, + #endif + #if LV_FONT_MONTSERRAT_30 + { 30, &lv_font_montserrat_30 }, + #endif + #if LV_FONT_MONTSERRAT_32 + { 32, &lv_font_montserrat_32 }, + #endif + #if LV_FONT_MONTSERRAT_34 + { 34, &lv_font_montserrat_34 }, + #endif + #if LV_FONT_MONTSERRAT_36 + { 36, &lv_font_montserrat_36 }, + #endif + #if LV_FONT_MONTSERRAT_38 + { 38, &lv_font_montserrat_38 }, + #endif + #if LV_FONT_MONTSERRAT_40 + { 40, &lv_font_montserrat_40 }, + #endif + #if LV_FONT_MONTSERRAT_42 + { 42, &lv_font_montserrat_42 }, + #endif + #if LV_FONT_MONTSERRAT_44 + { 44, &lv_font_montserrat_44 }, + #endif + #if LV_FONT_MONTSERRAT_46 + { 46, &lv_font_montserrat_46 }, + #endif + #if LV_FONT_MONTSERRAT_48 + { 48, &lv_font_montserrat_48 }, + #endif + { 0, nullptr} + }; - #if LV_FONT_MONTSERRAT_10 - case 10: - font = &lv_font_montserrat_10; - break; - #endif + // Seg7 Font + const lv_font_table_t lv_seg7_fonts[] = { + { 8, &seg7_8 }, + { 10, &seg7_10 }, + { 12, &seg7_12 }, + { 14, &seg7_14 }, + { 16, &seg7_16 }, + { 18, &seg7_18 }, + { 20, &seg7_20 }, + { 24, &seg7_24 }, + { 28, &seg7_28 }, + { 36, &seg7_36 }, + { 48, &seg7_48 }, + }; - #if LV_FONT_MONTSERRAT_12 - case 12: - font = &lv_font_montserrat_12; - break; - #endif + // robotocondensed-latin1 + const lv_font_table_t lv_robotocondensed_fonts[] = { +#if ROBOTOCONDENSED_REGULAR_12_LATIN1 + { 12, &robotocondensed_regular_12_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_14_LATIN1 + { 14, &robotocondensed_regular_14_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_16_LATIN1 + { 16, &robotocondensed_regular_16_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_20_LATIN1 + { 20, &robotocondensed_regular_20_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_22_LATIN1 + { 22, &robotocondensed_regular_22_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_24_LATIN1 + { 24, &robotocondensed_regular_24_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_28_LATIN1 + { 28, &robotocondensed_regular_28_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_32_LATIN1 + { 32, &robotocondensed_regular_32_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_36_LATIN1 + { 36, &robotocondensed_regular_36_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_38_LATIN1 + { 38, &robotocondensed_regular_38_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_40_LATIN1 + { 40, &robotocondensed_regular_40_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_44_LATIN1 + { 44, &robotocondensed_regular_44_latin1 }, +#endif +#if ROBOTOCONDENSED_REGULAR_48_LATIN1 + { 48, &robotocondensed_regular_48_latin1 }, +#endif + }; - #if LV_FONT_MONTSERRAT_14 - case 14: - font = &lv_font_montserrat_14; - break; - #endif + // register all included fonts + const lv_font_names_t lv_embedded_fonts[] = { + { "montserrat", lv_montserrat_fonts }, + { "seg7", lv_seg7_fonts }, +#ifdef USE_LVGL_OPENHASP + { "robotocondensed", lv_robotocondensed_fonts }, +#endif + { nullptr, nullptr} + }; - #if LV_FONT_MONTSERRAT_16 - case 16: - font = &lv_font_montserrat_16; - break; - #endif - - #if LV_FONT_MONTSERRAT_18 - case 18: - font = &lv_font_montserrat_18; - break; - #endif - - #if LV_FONT_MONTSERRAT_20 - case 20: - font = &lv_font_montserrat_20; - break; - #endif - - #if LV_FONT_MONTSERRAT_22 - case 22: - font = &lv_font_montserrat_22; - break; - #endif - - #if LV_FONT_MONTSERRAT_24 - case 24: - font = &lv_font_montserrat_24; - break; - #endif - - #if LV_FONT_MONTSERRAT_26 - case 26: - font = &lv_font_montserrat_26; - break; - #endif - - #if LV_FONT_MONTSERRAT_28 - case 28: - font = &lv_font_montserrat_28; - break; - #endif - - #if LV_FONT_MONTSERRAT_30 - case 30: - font = &lv_font_montserrat_30; - break; - #endif - - #if LV_FONT_MONTSERRAT_32 - case 32: - font = &lv_font_montserrat_32; - break; - #endif - - #if LV_FONT_MONTSERRAT_34 - case 34: - font = &lv_font_montserrat_34; - break; - #endif - - #if LV_FONT_MONTSERRAT_36 - case 36: - font = &lv_font_montserrat_36; - break; - #endif - - #if LV_FONT_MONTSERRAT_38 - case 38: - font = &lv_font_montserrat_38; - break; - #endif - - #if LV_FONT_MONTSERRAT_40 - case 40: - font = &lv_font_montserrat_40; - break; - #endif - - #if LV_FONT_MONTSERRAT_42 - case 42: - font = &lv_font_montserrat_42; - break; - #endif - - #if LV_FONT_MONTSERRAT_44 - case 44: - font = &lv_font_montserrat_44; - break; - #endif - - #if LV_FONT_MONTSERRAT_46 - case 46: - font = &lv_font_montserrat_46; - break; - #endif - - #if LV_FONT_MONTSERRAT_48 - case 48: - font = &lv_font_montserrat_48; - break; - #endif - - #if LV_FONT_MONTSERRAT_28_COMPRESSED - case 28: - font = &lv_font_montserrat_28_compressed; - break; - #endif - - default: - break; - } - - if (font != nullptr) { - be_find_class(vm, "lv.lv_font"); - be_pushcomptr(vm, (void*)font); - be_call(vm, 1); - be_pop(vm, 1); - be_return(vm); - } else { - be_return_nil(vm); + // If size is zero, it is read at arg 1 + int lv_load_embedded_font(bvm *vm, const char * name, int16_t size) { + if (0 == size) { + if (be_top(vm) >= 1 && be_isint(vm, 1)) { + size = be_toindex(vm, 1); } } - be_raise(vm, kTypeError, nullptr); + if (name == nullptr || 0 == size) { + be_raise(vm, "value_error", ""); + } + // first look for font + const lv_font_names_t * font_name_cursor = lv_embedded_fonts; + for (font_name_cursor = lv_embedded_fonts; font_name_cursor->name; font_name_cursor++) { + if (strcmp(name, font_name_cursor->name) == 0) break; // found + } + if (font_name_cursor->name == nullptr) { + be_raisef(vm, "value_error", "unknown font '%s'", name); + } + // scan for font size + const lv_font_table_t * font_entry = font_name_cursor->table; + for (font_entry = font_name_cursor->table; font_entry->size; font_entry++) { + if (font_entry->size == size) break; // found + } + if (font_entry->size == 0) { + be_raisef(vm, "value_error", "unknown font size '%s-%i'", name, size); + } + + be_find_class(vm, "lv.lv_font"); + be_pushcomptr(vm, (void*)font_entry->font); + be_call(vm, 1); + be_pop(vm, 1); + be_return(vm); + } + + int lv0_load_montserrat_font(bvm *vm) { + return lv_load_embedded_font(vm, "montserrat", 0); } int lv0_load_seg7_font(bvm *vm) { - int argc = be_top(vm); - if (argc == 1 && be_isint(vm, 1)) { - const lv_font_t * font = nullptr; - int32_t font_size = be_toindex(vm, 1); - - switch (font_size) { - case 8: font = &seg7_8; break; - case 10: font = &seg7_10; break; - case 12: font = &seg7_12; break; - case 14: font = &seg7_14; break; - case 16: font = &seg7_16; break; - case 18: font = &seg7_18; break; - case 20: font = &seg7_20; break; - case 24: font = &seg7_24; break; - case 28: font = &seg7_28; break; - case 36: font = &seg7_36; break; - case 48: font = &seg7_48; break; - default: break; - } - - if (font != nullptr) { - be_find_class(vm, "lv.lv_font"); - be_pushcomptr(vm, (void*)font); - be_call(vm, 1); - be_pop(vm, 1); - be_return(vm); - } else { - be_return_nil(vm); - } - } - be_raise(vm, kTypeError, nullptr); + return lv_load_embedded_font(vm, "seg7", 0); } int lv0_load_robotocondensed_latin1_font(bvm *vm) { #ifdef USE_LVGL_OPENHASP - int argc = be_top(vm); - if (argc == 1 && be_isint(vm, 1)) { - const lv_font_t * font = nullptr; - int32_t font_size = be_toindex(vm, 1); - - switch (font_size) { -#if ROBOTOCONDENSED_REGULAR_12_LATIN1 - case 12: font = &robotocondensed_regular_12_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_14_LATIN1 - case 14: font = &robotocondensed_regular_14_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_16_LATIN1 - case 16: font = &robotocondensed_regular_16_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_20_LATIN1 - case 20: font = &robotocondensed_regular_20_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_22_LATIN1 - case 22: font = &robotocondensed_regular_22_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_24_LATIN1 - case 24: font = &robotocondensed_regular_24_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_28_LATIN1 - case 28: font = &robotocondensed_regular_28_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_32_LATIN1 - case 32: font = &robotocondensed_regular_32_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_36_LATIN1 - case 36: font = &robotocondensed_regular_36_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_38_LATIN1 - case 38: font = &robotocondensed_regular_38_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_40_LATIN1 - case 40: font = &robotocondensed_regular_40_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_44_LATIN1 - case 44: font = &robotocondensed_regular_44_latin1; break; -#endif -#if ROBOTOCONDENSED_REGULAR_48_LATIN1 - case 48: font = &robotocondensed_regular_48_latin1; break; -#endif - default: break; - } - - if (font != nullptr) { - be_find_class(vm, "lv.lv_font"); - be_pushcomptr(vm, (void*)font); - be_call(vm, 1); - be_pop(vm, 1); - be_return(vm); - } else { - be_return_nil(vm); - } - } + return lv_load_embedded_font(vm, "robotocondensed", 0); #endif // USE_LVGL_OPENHASP be_raise(vm, kTypeError, nullptr); } + /*********************************************************************************************\ + * Tasmota Logo + \*********************************************************************************************/ #include "lvgl_berry/tasmota_logo_64_truecolor_alpha.h" void lv_img_set_tasmota_logo(lv_obj_t * img) { @@ -956,11 +915,53 @@ extern "C" { if (!glue) { be_return_nil(vm); } char fname[32]; - snprintf(fname, sizeof(fname), "/screenshot-%d.raw", Rtc.utc_time); + snprintf(fname, sizeof(fname), "/screenshot-%d.bmp", Rtc.utc_time); File f = dfsp->open(fname, "w"); if (f) { glue->setScreenshotFile(&f); + uint32_t bmp_width = lv_disp_get_hor_res(nullptr); + uint32_t bmp_height = lv_disp_get_ver_res(nullptr); + + // write BMP header + static const uint8_t bmp_sign[] = { 0x42, 0x4d }; // BM = Windows + f.write(bmp_sign, sizeof(bmp_sign)); + size_t bmp_size = bmp_width * bmp_height * LV_COLOR_DEPTH / 8 + 0x44; + f.write((uint8_t*)&bmp_size, sizeof(bmp_size)); + uint32_t zero = 0; + f.write((uint8_t*) &zero, sizeof(zero)); // reserved 4-bytes + uint32_t bmp_offset_to_pixels = 0x44; // TODO + f.write((uint8_t*) &bmp_offset_to_pixels, sizeof(bmp_offset_to_pixels)); + + // DIB Header BITMAPINFOHEADER + size_t bmp_dib_header_size = 52; // BITMAPV2INFOHEADER + f.write((uint8_t*) &bmp_dib_header_size, sizeof(bmp_dib_header_size)); + + f.write((uint8_t*) &bmp_width, sizeof(bmp_width)); + f.write((uint8_t*) &bmp_height, sizeof(bmp_height)); + + // rest of header + // BITMAPV2INFOHEADER = 52 bytes header, 40 bytes sub-header + static const uint8_t bmp_dib_header[] = { + 0x01, 0x00, // planes + 16, 0x00, // bits per pixel = 16 + 0x03, 0x00, 0x00, 0x00, // compression = BI_BITFIELDS uncrompressed + 0x00, 0x00, 0x00, 0x00, // Image size, 0 is valid for BI_RGB (uncompressed) TODO + 0x00, 0x00, 0x00, 0x00, // X pixels per meter + 0x00, 0x00, 0x00, 0x00, // Y pixels per meter + 0x00, 0x00, 0x00, 0x00, // Colors in table + 0x00, 0x00, 0x00, 0x00, // Important color count + + // RGB masks + 0x00, 0xF8, 0x00, 0x00, // Red channel mask + 0xE0, 0x07, 0x00, 0x00, // Green channel mask + 0x1F, 0x00, 0x00, 0x00, // Blue channel mask + + 0x00, 0x00, // Padding to align on 4 bytes boundary + }; + f.write(bmp_dib_header, sizeof(bmp_dib_header)); + // now we can write the pixels array + // redraw screen lv_obj_invalidate(lv_scr_act()); lv_refr_now(lv_disp_get_default()); diff --git a/tasmota/xdrv_60_shift595.ino b/tasmota/xdrv_60_shift595.ino index 6e45194fa..9bae92196 100644 --- a/tasmota/xdrv_60_shift595.ino +++ b/tasmota/xdrv_60_shift595.ino @@ -21,16 +21,16 @@ #define XDRV_60 60 const char kShift595Commands[] PROGMEM = "|" D_CMND_SHIFT595_DEVICE_COUNT ; -void (* const Shit595Command[])(void) PROGMEM = { &CmndShift595Devices }; +void (* const Shift595Command[])(void) PROGMEM = { &CmndShift595Devices }; struct Shift595 { int8_t pinSRCLK; int8_t pinRCLK; int8_t pinSER; int8_t pinOE; - bool connected = false; int8_t outputs; int8_t first = TasmotaGlobal.devices_present; + bool connected = false; } Shift595; void Shift595Init(void) @@ -56,7 +56,7 @@ void Shift595Init(void) Shift595.outputs = Settings->shift595_device_count * 8; TasmotaGlobal.devices_present += Shift595.outputs; Shift595.connected = true; - AddLog(LOG_LEVEL_DEBUG, PSTR("595: Controlling relays POWER%d to POWER%d"), Shift595.first + 1, Shift595.outputs); + AddLog(LOG_LEVEL_DEBUG, PSTR("595: Controlling relays POWER%d to POWER%d"), Shift595.first + 1, Shift595.first + Shift595.outputs); } } @@ -70,8 +70,7 @@ void Shift595SwitchRelay(void) if (Shift595.connected == true) { for (uint32_t i = 0; i < Shift595.outputs; i++) { uint8_t relay_state = bitRead(XdrvMailbox.index, Shift595.first + Shift595.outputs -1 -i); - // digitalWrite(Shift595.pinSER, Settings->flag5.shift595_invert_outputs ? !relay_state : relay_state); - digitalWrite(Shift595.pinSER, relay_state); + digitalWrite(Shift595.pinSER, Settings->flag5.shift595_invert_outputs ? !relay_state : relay_state); Shift595LatchPin(Shift595.pinSRCLK); } @@ -108,6 +107,7 @@ bool Xdrv60(uint8_t function) case FUNC_COMMAND: result = DecodeCommand(kShift595Commands, Shift595Command); break; + } return result; } diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino index 9f858691b..afe70b115 100644 --- a/tasmota/xdrv_86_esp32_sonoff_spm.ino +++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino @@ -175,6 +175,7 @@ typedef struct { uint8_t command_sequence; uint8_t mstate; uint8_t last_button; + uint8_t gui_display; bool discovery_triggered; } TSspm; @@ -1082,29 +1083,30 @@ bool SSPMButton(void) { /*********************************************************************************************/ const uint16_t SSPM_SIZE = 128; -const char kSSPMEnergyPhases[] PROGMEM = "%*_f%*_f%*_f%*_f|[%*_f,%*_f,%*_f,%*_f]"; -char* SSPMEnergyFormat(char* result, float* input, uint32_t resolution, bool json) { - char layout[100]; - GetTextIndexed(layout, sizeof(layout), json, kSSPMEnergyPhases); - ext_snprintf_P(result, SSPM_SIZE, layout, resolution, &input[0], resolution, &input[1], resolution, &input[2], resolution, &input[3]); +char* SSPMEnergyFormat(char* result, float* input, uint32_t resolution, uint8_t* indirect, uint8_t offset, uint32_t count) { + result[0] = '\0'; + for (uint32_t i = 0; i < count; i++) { + ext_snprintf_P(result, SSPM_SIZE, PSTR("%s%*_f"), result, resolution, &input[indirect[offset +i]]); + } + ext_snprintf_P(result, SSPM_SIZE, PSTR("%s"), result); return result; } const char HTTP_SSPM_VOLTAGE[] PROGMEM = - "{s}" D_VOLTAGE "%s" D_UNIT_VOLT "{e}"; // {s} = , {m} = , {e} = + "{s}" D_VOLTAGE "%s" D_UNIT_VOLT "{e}"; // {s} = , {m} = , {e} = const char HTTP_SSPM_CURRENT[] PROGMEM = - "{s}" D_CURRENT "%s" D_UNIT_AMPERE "{e}"; + "{s}" D_CURRENT "%s" D_UNIT_AMPERE "{e}"; const char HTTP_SSPM_POWER[] PROGMEM = - "{s}" D_POWERUSAGE_ACTIVE "%s" D_UNIT_WATT "{e}"; + "{s}" D_POWERUSAGE_ACTIVE "%s" D_UNIT_WATT "{e}"; const char HTTP_SSPM_POWER2[] PROGMEM = - "{s}" D_POWERUSAGE_APPARENT "%s" D_UNIT_VA "{e}" - "{s}" D_POWERUSAGE_REACTIVE "%s" D_UNIT_VAR "{e}" - "{s}" D_POWER_FACTOR "%s{e}"; + "{s}" D_POWERUSAGE_APPARENT "%s" D_UNIT_VA "{e}" + "{s}" D_POWERUSAGE_REACTIVE "%s" D_UNIT_VAR "{e}" + "{s}" D_POWER_FACTOR "%s{e}"; const char HTTP_SSPM_ENERGY[] PROGMEM = - "{s}" D_ENERGY_TODAY "%s" D_UNIT_KILOWATTHOUR "{e}" - "{s}" D_ENERGY_YESTERDAY "%s" D_UNIT_KILOWATTHOUR "{e}" - "{s}" D_ENERGY_TOTAL "%s" D_UNIT_KILOWATTHOUR "{e}"; + "{s}" D_ENERGY_TODAY "%s" D_UNIT_KILOWATTHOUR "{e}" + "{s}" D_ENERGY_YESTERDAY "%s" D_UNIT_KILOWATTHOUR "{e}" + "{s}" D_ENERGY_TOTAL "%s" D_UNIT_KILOWATTHOUR "{e}"; void SSPMEnergyShow(bool json) { if (!TasmotaGlobal.devices_present) { return; } // Not ready yet @@ -1152,30 +1154,50 @@ void SSPMEnergyShow(bool json) { } ResponseAppend_P(PSTR("]}")); } else { - Sspm->rotate++; - if (Sspm->rotate >= TasmotaGlobal.devices_present) { - Sspm->rotate = 0; + uint8_t relay[SSPM_MAX_MODULES * 4]; + uint8_t indirect[SSPM_MAX_MODULES * 4]; + + uint32_t index = 0; + power_t power = TasmotaGlobal.power; + for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) { + if ((0 == Sspm->gui_display) || + ((1 == Sspm->gui_display) && (power >> i) &1)) { + relay[index] = i +1; + indirect[index] = i; + index++; + } } - uint32_t module = Sspm->rotate >> 2; - uint32_t relay_base = module * 4; - WSContentSend_P(PSTR("{t}{s}")); // First column is empty ({t} = , {s} =
) - for (uint32_t i = 1; i < 5; i++) { - WSContentSend_P(PSTR("L%d"), relay_base +i); + + if (index) { + uint32_t offset = 0; + if (index > 4) { + Sspm->rotate++; + if (Sspm->rotate >= ((index -1) >> 2) << 3) { + Sspm->rotate = 0; + } + offset = (Sspm->rotate >> 2) * 4; + } + uint32_t count = index - offset; + if (count > 4) { count = 4; } + WSContentSend_P(PSTR("
{t}{s}")); // First column is empty ({t} = , {s} = ) + char value_chr[SSPM_SIZE]; + WSContentSend_PD(HTTP_SSPM_VOLTAGE, SSPMEnergyFormat(value_chr, Sspm->voltage[0], Settings->flag2.voltage_resolution, indirect, offset, count)); + WSContentSend_PD(HTTP_SSPM_CURRENT, SSPMEnergyFormat(value_chr, Sspm->current[0], Settings->flag2.current_resolution, indirect, offset, count)); + WSContentSend_PD(HTTP_SSPM_POWER, SSPMEnergyFormat(value_chr, Sspm->active_power[0], Settings->flag2.wattage_resolution, indirect, offset, count)); + char valu2_chr[SSPM_SIZE]; + char valu3_chr[SSPM_SIZE]; + WSContentSend_PD(HTTP_SSPM_POWER2, SSPMEnergyFormat(value_chr, Sspm->apparent_power[0], Settings->flag2.wattage_resolution, indirect, offset, count), + SSPMEnergyFormat(valu2_chr, Sspm->reactive_power[0], Settings->flag2.wattage_resolution, indirect, offset, count), + SSPMEnergyFormat(valu3_chr, Sspm->power_factor[0], 2, indirect, offset, count)); + WSContentSend_PD(HTTP_SSPM_ENERGY, SSPMEnergyFormat(value_chr, Sspm->energy_today[0], Settings->flag2.energy_resolution, indirect, offset, count), + SSPMEnergyFormat(valu2_chr, Sspm->energy_yesterday[0], Settings->flag2.energy_resolution, indirect, offset, count), + SSPMEnergyFormat(valu3_chr, Sspm->energy_total[0], Settings->flag2.energy_resolution, indirect, offset, count)); + WSContentSend_P(PSTR("
) + for (uint32_t i = 0; i < count; i++) { + WSContentSend_P(PSTR("L%d"), relay[offset +i]); + } + WSContentSend_P(PSTR("{e}")); // Last column is units ({e} =
{t}")); // {t} = - Define for next FUNC_WEB_SENSOR } - WSContentSend_P(PSTR(") - char value_chr[SSPM_SIZE]; - WSContentSend_PD(HTTP_SSPM_VOLTAGE, SSPMEnergyFormat(value_chr, Sspm->voltage[module], Settings->flag2.voltage_resolution, json)); - WSContentSend_PD(HTTP_SSPM_CURRENT, SSPMEnergyFormat(value_chr, Sspm->current[module], Settings->flag2.current_resolution, json)); - WSContentSend_PD(HTTP_SSPM_POWER, SSPMEnergyFormat(value_chr, Sspm->active_power[module], Settings->flag2.wattage_resolution, json)); - char valu2_chr[SSPM_SIZE]; - char valu3_chr[SSPM_SIZE]; - WSContentSend_PD(HTTP_SSPM_POWER2, SSPMEnergyFormat(value_chr, Sspm->apparent_power[module], Settings->flag2.wattage_resolution, json), - SSPMEnergyFormat(valu2_chr, Sspm->reactive_power[module], Settings->flag2.wattage_resolution, json), - SSPMEnergyFormat(valu3_chr, Sspm->power_factor[module], 2, json)); - WSContentSend_PD(HTTP_SSPM_ENERGY, SSPMEnergyFormat(value_chr, Sspm->energy_today[module], Settings->flag2.energy_resolution, json), - SSPMEnergyFormat(valu2_chr, Sspm->energy_yesterday[module], Settings->flag2.energy_resolution, json), - SSPMEnergyFormat(valu3_chr, Sspm->energy_total[module], Settings->flag2.energy_resolution, json)); - WSContentSend_P(PSTR("
{e}")); // Last column is units ({e} =
{t}")); // {t} = - Define for next FUNC_WEB_SENSOR } } @@ -1184,10 +1206,10 @@ void SSPMEnergyShow(bool json) { \*********************************************************************************************/ const char kSSPMCommands[] PROGMEM = "SSPM|" // Prefix - "Log|Energy|History|Scan|IamHere" ; + "Log|Energy|History|Scan|IamHere|Display" ; void (* const SSPMCommand[])(void) PROGMEM = { - &CmndSSPMLog, &CmndSSPMEnergy, &CmndSSPMEnergyHistory, &CmndSSPMScan, &CmndSSPMIamHere }; + &CmndSSPMLog, &CmndSSPMEnergy, &CmndSSPMEnergyHistory, &CmndSSPMScan, &CmndSSPMIamHere, &CmndSSPMDisplay }; void CmndSSPMLog(void) { // Report 29 log entries @@ -1222,6 +1244,14 @@ void CmndSSPMIamHere(void) { ResponseCmndDone(); } +void CmndSSPMDisplay(void) { + // Select either all relays or only powered on relays + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Sspm->gui_display = XdrvMailbox.payload; + } + ResponseCmndNumber(Sspm->gui_display); +} + /*********************************************************************************************\ * Interface \*********************************************************************************************/