Skip to content

Commit

Permalink
Merge branch 'development' into prerelease-13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
arendst committed Jun 26, 2023
2 parents 0ced0c2 + 1d74c35 commit 654f420
Show file tree
Hide file tree
Showing 14 changed files with 11,393 additions and 36 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file.
- Berry add global function `format` as a simpler syntax to `string.format`
- Berry added f-strings as an alternative to string formatting
- Matter display the remote Device Name instead of IP address
- Berry Walrus operator ':='
- Zigbee firmware for Sonoff-ZB-Pro v20230507

### Changed
- Berry `webclient.url_encode()` is now a static class method, no change required to existing code (#18775)
Expand Down
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Support for PCA9557 8-bit I/O expander [#18632](https://github.com/arendst/Tasmota/issues/18632)
- Display descriptor for ST7735 128x160 display [#18741](https://github.com/arendst/Tasmota/issues/18741)
- Zigbee support for air sensors [#18665](https://github.com/arendst/Tasmota/issues/18665)
- Zigbee firmware for Sonoff-ZB-Pro v20230507 [#18968](https://github.com/arendst/Tasmota/issues/18968)
- ESP32 command ``Shuttersetup`` for "Shelly 2.5 pro" automatic calibration and setup (experimental)
- ESP32 Enhanced Shutterbuttons functionality to control tilt position, additionally incr/decr possible to position and tilt.
- Berry RS256 crypto algorithm (RSASSA-MCKS1_v1-5 with SHA256) used for JWT [#18763](https://github.com/arendst/Tasmota/issues/18763)
Expand All @@ -129,6 +130,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry `string.format()` now automatically converts type according to format [#18890](https://github.com/arendst/Tasmota/issues/18890)
- Berry global function `format` as a simpler syntax to `string.format` [#18925](https://github.com/arendst/Tasmota/issues/18925)
- Berry f-strings as an alternative to string formatting [#18937](https://github.com/arendst/Tasmota/issues/18937)
- Berry Walrus operator ':=' [#18963](https://github.com/arendst/Tasmota/issues/18963)
- HASPmota `meta` attribute and improved `berry_run` [#18685](https://github.com/arendst/Tasmota/issues/18685)
- Matter sensors Humidity, Pressure, Illuminance [#18441](https://github.com/arendst/Tasmota/issues/18441)
- Matter allow `Matter#Initialized` rule once the device is configured [#18451](https://github.com/arendst/Tasmota/issues/18451)
Expand Down
29 changes: 20 additions & 9 deletions lib/libesp32/berry/src/be_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ static int codeABx(bfuncinfo *finfo, bopcode op, int a, int bx)
return codeinst(finfo, ISET_OP(op) | ISET_RA(a) | ISET_Bx(bx));
}

/* Move value from register b to register a */
static void code_move_nooptim(bfuncinfo *finfo, int a, int b)
{
if (isK(b)) {
codeABx(finfo, OP_LDCONST, a, b & 0xFF);
} else {
codeABC(finfo, OP_MOVE, a, b, 0);
}
}

/* Move value from register b to register a */
/* Check the previous instruction to compact both instruction as one if possible */
/* If b is a constant, add LDCONST or add MOVE otherwise */
Expand All @@ -95,11 +105,7 @@ static void code_move(bfuncinfo *finfo, int a, int b)
}
}
}
if (isK(b)) {
codeABx(finfo, OP_LDCONST, a, b & 0xFF);
} else {
codeABC(finfo, OP_MOVE, a, b, 0);
}
code_move_nooptim(finfo, a, b);
}

/* Free register at top (checks that it´s a register) */
Expand Down Expand Up @@ -670,20 +676,25 @@ static void setsfxvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)

/* Assign expr e2 to e1 */
/* e1 must be in a register and have a valid idx */
/* if `keep_reg` is true, do not release registre */
/* return 1 if assignment was possible, 0 if type is not compatible */
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2)
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg)
{
int src = exp2reg(finfo, e2,
e1->type == ETLOCAL ? e1->v.idx : -1); /* Convert e2 to kreg */
/* If e1 is a local variable, use the register */

if (e1->type != ETLOCAL || e1->v.idx != src) {
if (!keep_reg && (e1->type != ETLOCAL || e1->v.idx != src)) {
free_expreg(finfo, e2); /* free source (checks only ETREG) */ /* TODO e2 is at top */
}
switch (e1->type) {
case ETLOCAL: /* It can't be ETREG. */
if (e1->v.idx != src) {
code_move(finfo, e1->v.idx, src); /* do explicit move only if needed */
if (keep_reg) {
code_move_nooptim(finfo, e1->v.idx, src); /* always do explicit move */
} else {
code_move(finfo, e1->v.idx, src); /* do explicit move only if needed */
}
}
break;
case ETGLOBAL: /* store to grobal R(A) -> G(Bx) by global index */
Expand Down Expand Up @@ -887,7 +898,7 @@ void be_code_import(bfuncinfo *finfo, bexpdesc *m, bexpdesc *v)
codeABC(finfo, OP_IMPORT, dst, src, 0);
m->type = ETREG;
m->v.idx = dst;
be_code_setvar(finfo, v, m);
be_code_setvar(finfo, v, m, bfalse);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/libesp32/berry/src/be_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int be_code_allocregs(bfuncinfo *finfo, int count);
void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e);
void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst);
int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e);
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2);
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, bbool keep_reg);
int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e);
int be_code_jump(bfuncinfo *finfo);
void be_code_jumpto(bfuncinfo *finfo, int dst);
Expand Down
2 changes: 2 additions & 0 deletions lib/libesp32/berry/src/be_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ static void hook_callnative(bvm *vm, int mask)
be_stack_require(vm, BE_STACK_FREE_MIN + 2);
info.type = mask;
info.line = cf->lineinfo->linenumber;
#if BE_DEBUG_SOURCE_FILE
info.source = str(cl->proto->source);
#endif
info.func_name = str(cl->proto->name);
info.data = hb->data;
hb->hook(vm, &info);
Expand Down
4 changes: 3 additions & 1 deletion lib/libesp32/berry/src/be_lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,9 @@ static btokentype lexer_next(blexer *lexer)
case '}': next(lexer); return OptRBR;
case ',': next(lexer); return OptComma;
case ';': next(lexer); return OptSemic;
case ':': next(lexer); return OptColon;
case ':':
next(lexer);
return check_next(lexer, '=') ? OptWalrus : OptColon;
case '?': next(lexer); return OptQuestion;
case '^': return scan_assign(lexer, OptXorAssign, OptBitXor);
case '~': next(lexer); return OptFlip;
Expand Down
4 changes: 3 additions & 1 deletion lib/libesp32/berry/src/be_lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ typedef enum {
KeyTry, /* keyword try */
KeyExcept, /* keyword except */
KeyRaise, /* keyword raise */
KeyStatic /* keyword static */
KeyStatic, /* keyword static */
/* Walrus operator */
OptWalrus, /* operator, := */
} btokentype;

struct blexerreader {
Expand Down
2 changes: 1 addition & 1 deletion lib/libesp32/berry/src/be_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ static char* fixpath(bvm *vm, bstring *path, size_t *size)
{
char *buffer;
const char *split, *base;
#if BE_DEBUG_SOURCE_FILE
bvalue *func = vm->cf->func;
bclosure *cl = var_toobj(func);
#if BE_DEBUG_SOURCE_FILE
if (var_isclosure(func)) {
base = str(cl->proto->source); /* get the source file path */
} else {
Expand Down
46 changes: 33 additions & 13 deletions lib/libesp32/berry/src/be_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ typedef struct {
static void stmtlist(bparser *parser);
static void block(bparser *parser, int type);
static void expr(bparser *parser, bexpdesc *e);
static void walrus_expr(bparser *parser, bexpdesc *e);
static void sub_expr(bparser *parser, bexpdesc *e, int prio);

static const bbyte binary_op_prio_tab[] = {
Expand Down Expand Up @@ -224,17 +225,17 @@ static void end_block(bparser *parser)
end_block_ex(parser, -1);
}

#if BE_DEBUG_SOURCE_FILE
/* Return the name of the source for this parser, could be `string`,
`stdin` or the name of the current function */
static bstring* parser_source(bparser *parser)
{
#if BE_DEBUG_SOURCE_FILE
if (parser->finfo) {
return parser->finfo->proto->source;
}
#endif
return be_newstr(parser->vm, parser->lexer.fname);
}
#endif

/* Initialize a function block and create a new `bprotoˋ */
static void begin_func(bparser *parser, bfuncinfo *finfo, bblockinfo *binfo)
Expand Down Expand Up @@ -368,7 +369,7 @@ static btokentype get_unary_op(bparser *parser)
static btokentype get_assign_op(bparser *parser)
{
btokentype op = next_type(parser);
if (op >= OptAssign && op <= OptRsfAssign) {
if ((op >= OptAssign && op <= OptRsfAssign) || op == OptWalrus) {
return op;
}
return OP_NOT_ASSIGN;
Expand Down Expand Up @@ -631,7 +632,7 @@ static bproto* funcbody(bparser *parser, bstring *name, bclass *c, int type)
new_var(parser, parser_newstr(parser, "_class"), &e1); /* new implicit variable '_class' */
init_exp(&e2, ETCONST, 0);
be_code_implicit_class(parser->finfo, &e2, c);
be_code_setvar(parser->finfo, &e1, &e2);
be_code_setvar(parser->finfo, &e1, &e2, bfalse);
finfo.proto->varg |= BE_VA_STATICMETHOD;
}
stmtlist(parser); /* parse statement without final `end` */
Expand Down Expand Up @@ -735,7 +736,7 @@ static void map_nextmember(bparser *parser, bexpdesc *l)
match_token(parser, OptColon); /* ':' */
expr(parser, &e); /* value in `e` */
check_var(parser, &e); /* check if value is correct */
be_code_setvar(finfo, &v, &e); /* set suffi INDEX value to e */
be_code_setvar(finfo, &v, &e, bfalse); /* set suffi INDEX value to e */
}

static void list_expr(bparser *parser, bexpdesc *e)
Expand Down Expand Up @@ -892,8 +893,7 @@ static void primary_expr(bparser *parser, bexpdesc *e)
switch (next_type(parser)) {
case OptLBK: /* '(' expr ')' */
scan_next_token(parser); /* skip '(' */
/* sub_expr() is more efficient because there is no need to initialize e. */
sub_expr(parser, e, ASSIGN_OP_PRIO);
expr(parser, e);
check_var(parser, e);
match_token(parser, OptRBK); /* skip ')' */
break;
Expand Down Expand Up @@ -1040,7 +1040,7 @@ static void assign_expr(bparser *parser)
if (check_newvar(parser, &e)) { /* new variable */
new_var(parser, e.v.s, &e);
}
if (be_code_setvar(parser->finfo, &e, &e1)) {
if (be_code_setvar(parser->finfo, &e, &e1, bfalse)) {
parser->lexer.linenumber = line;
parser_error(parser,
"try to assign constant expressions.");
Expand Down Expand Up @@ -1125,13 +1125,33 @@ static void sub_expr(bparser *parser, bexpdesc *e, int prio)
}
}

static void walrus_expr(bparser *parser, bexpdesc *e)
{
int line = parser->lexer.linenumber;
sub_expr(parser, e, ASSIGN_OP_PRIO); /* left expression */
btokentype op = next_type(parser);
if (op == OptWalrus) {
bexpdesc e1 = *e; /* copy var to e1, e will get the result of expression */
scan_next_token(parser); /* skip ':=' */
expr(parser, e);
if (check_newvar(parser, &e1)) { /* new variable */
new_var(parser, e1.v.s, e);
}
if (be_code_setvar(parser->finfo, &e1, e, btrue /* do not release register */ )) {
parser->lexer.linenumber = line;
parser_error(parser,
"try to assign constant expressions.");
}
}
}

/* Parse new expression and return value in `e` (overwritten) */
/* Initializes an empty expdes and parse subexpr */
/* Always allocates a new temp register at top of freereg */
static void expr(bparser *parser, bexpdesc *e)
{
init_exp(e, ETVOID, 0);
sub_expr(parser, e, ASSIGN_OP_PRIO);
walrus_expr(parser, e);
}

static void expr_stmt(bparser *parser)
Expand Down Expand Up @@ -1250,7 +1270,7 @@ static void for_iter(bparser *parser, bstring *var, bexpdesc *it)
finfo->binfo->beginpc = finfo->pc;
/* itvar = .it() */
init_exp(&e, ETLOCAL, new_localvar(parser, var)); /* new itvar */
be_code_setvar(finfo, &e, it); /* code function to variable '.it' */
be_code_setvar(finfo, &e, it, bfalse); /* code function to variable '.it' */
be_code_call(finfo, e.v.idx, 0); /* itvar <- call .it() */
stmtlist(parser);
}
Expand Down Expand Up @@ -1444,7 +1464,7 @@ static void class_static_assignment_expr(bparser *parser, bexpdesc *e, bstring *
key.v.s = name;

be_code_member(parser->finfo, &e1, &key); /* compute member accessor */
be_code_setvar(parser->finfo, &e1, &e2); /* set member */
be_code_setvar(parser->finfo, &e1, &e2, bfalse); /* set member */
}
}

Expand Down Expand Up @@ -1568,7 +1588,7 @@ static void classstaticclass_stmt(bparser *parser, bclass *c_out, bexpdesc *e_ou
key.v.s = name;
/* assign the class to the static member */
be_code_member(parser->finfo, &e1, &key); /* compute member accessor */
be_code_setvar(parser->finfo, &e1, &e_class); /* set member */
be_code_setvar(parser->finfo, &e1, &e_class, bfalse); /* set member */
} else {
parser_error(parser, "class name error");
}
Expand Down Expand Up @@ -1620,7 +1640,7 @@ static void var_field(bparser *parser)
init_exp(&e2, ETNIL, 0);
}
new_var(parser, name, &e1); /* new variable */
be_code_setvar(parser->finfo, &e1, &e2);
be_code_setvar(parser->finfo, &e1, &e2, bfalse);
}

static void var_stmt(bparser *parser)
Expand Down
5 changes: 4 additions & 1 deletion pio-tools/post_esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,12 @@ def esp32_build_filesystem(fs_size):
if "no_files" in file:
continue
if "http" and "://" in file:
response = requests.get(file)
response = requests.get(file.split(" ")[0])
if response.ok:
target = join(filesystem_dir,file.split(os.path.sep)[-1])
if len(file.split(" ")) > 1:
target = join(filesystem_dir,file.split(" ")[1])
print("Renaming",(file.split(os.path.sep)[-1]).split(" ")[0],"to",file.split(" ")[1])
open(target, "wb").write(response.content)
else:
print("Failed to download: ",file)
Expand Down
28 changes: 21 additions & 7 deletions tasmota/berry/zigbee/intelhex.be
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class intelhex

# internally used, verify each line
def munch_line(parse_cb)
import string
import crc
var crc_sum = crc.sum
var tas = tasmota
Expand All @@ -84,25 +85,35 @@ class intelhex
var b_fromhex = b.fromhex
var self_f = self.f
var readline = self_f.readline
var defer = 10
while true
yield(tas) # tasmota.yield() -- faster version
defer = defer - 1
if defer <= 0
yield(tas) # tasmota.yield() -- faster version
defer = 10
end
var line = readline(self_f) # self.f.readline()
if line[-1] == '\n' line = line[0..-2] end
if line[-1] == '\r' line = line[0..-2] end

# line = string.tr(line, '\r', '')
# line = string.tr(line, '\n', '')
# print(line)
if line == "" raise "value_error", "unexpected end of file" end
if line[0] != ":" continue end # ignore empty line or not starting with ':'

b = b_fromhex(b, line, 1) # b.fromhex(line, 1) # convert to bytes, avoid allocating a new object
var sz = b[0]

# check size
if size(b) != sz+5 raise "value_error", "invalid size for line: "+line end
if size(b) != sz+5 raise "value_error", f"invalid size for line: {line} {size(b)=} {sz=}" end

var record_type = b[3]
# 00: low address + data
# 01: end of file
# 02: Extended Segment Address
# 04: high address
if record_type != 0 && record_type != 1 && record_type != 4
raise "value_error", "unsupported record_type: "+str(record_type)
if record_type != 0 && record_type != 1 && record_type != 2 && record_type != 4
raise "value_error", f"unsupported record_type: {record_type} {line=}"
end

offset_low = b_get(b, 1, -2) # b.get(1,-2)
Expand All @@ -112,16 +123,19 @@ class intelhex
if record_type == 1 break end # end of file
if record_type == 0
# data
var address = offset_high << 16 | offset_low # full address
var address = offset_high + offset_low # full address
#var data = b[4..-2] # actual payload
parse_cb(address, sz, b, 4)

# OK
# do whatever needed
# print(format("addr=0x%06X len=0x%02X", address, sz))
elif record_type == 2
if offset_low != 0 raise "value_error", "offset_low not null for cmd 02" end
offset_high = b_get(b, 4, -2) << 4
elif record_type == 4
if offset_low != 0 raise "value_error", "offset_low not null for cmd 04" end
offset_high = b_get(b, 4, -2) # b.get(4,-2)
offset_high = b_get(b, 4, -2) << 16

end
end
Expand Down
Loading

0 comments on commit 654f420

Please sign in to comment.