From 2a7ef0142901d033a4ad7bae6730de379447f44d Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Wed, 8 Jun 2022 22:11:22 +0200 Subject: [PATCH] Ported berry_ctypes to python --- .../src/be_lvgl_ctypes_definitions.c | 2 +- .../src/embedded/berry_ctypes.py | 386 +++++++++++ .../lv_binding_berry/src/embedded/ctypes.be | 629 ------------------ .../{lvgl_ctypes.be => lvgl_ctypes.py} | 222 +++---- .../lv_binding_berry/tools/gen.sh | 6 + 5 files changed, 488 insertions(+), 757 deletions(-) create mode 100644 lib/libesp32_lvgl/lv_binding_berry/src/embedded/berry_ctypes.py delete mode 100644 lib/libesp32_lvgl/lv_binding_berry/src/embedded/ctypes.be rename lib/libesp32_lvgl/lv_binding_berry/src/embedded/{lvgl_ctypes.be => lvgl_ctypes.py} (69%) create mode 100755 lib/libesp32_lvgl/lv_binding_berry/tools/gen.sh diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c b/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c index cc7030dab..62b092dd8 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c +++ b/lib/libesp32_lvgl/lv_binding_berry/src/be_lvgl_ctypes_definitions.c @@ -2,10 +2,10 @@ * Tasmota LVGL ctypes mapping *******************************************************************/ #include "be_ctypes.h" - #include "lvgl.h" #include "be_mapping.h" + /******************************************************************** * Generated code, don't edit *******************************************************************/ diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/berry_ctypes.py b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/berry_ctypes.py new file mode 100644 index 000000000..789267cd6 --- /dev/null +++ b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/berry_ctypes.py @@ -0,0 +1,386 @@ +#------------------------------------------------------------- +#- Ctypes for Berry +#- +#- Inspired from Python's ctypes structure +#-------------------------------------------------------------# + +#------------------------------------------------------------- +#- Basic types for mapping +#- +#- ints of size 1/2/4 bytes (little endian by default) +#- usigned ints of size 1/2/4 bytes (little endian by default) +#- +#- (Big Endian are negative numbers) +#-------------------------------------------------------------# + +types = { + # default is little_endian + "i32" : 14, + "i16" : 12, + "i8" : 11, + "u32" : 4, + "u16" : 2, + "u8" : 1, + + # explicit little endian + "le_i32" : 14, + "le_i16" : 12, + "le_i8" : 11, + "le_u32" : 4, + "le_u16" : 2, + "le_u8" : 1, + + # big endian + "be_i32" : -14, + "be_i16" : -12, + "be_i8" : -11, + "be_u32" : -4, + "be_u16" : -2, + "be_u8" : -1, + + # floating point + "float32" : 5, + "double64" : 10, + + # pointer + "ptr32" : 9, + "ptr64" : -9, + + # bitfields (always unsigned) + "bf_x" : 0, # generic bitfield + "bf_0" : 100, # serves as base + "bf_1" : 101, + "bf_2" : 102, + "bf_3" : 103, + "bf_4" : 104, + "bf_5" : 105, + "bf_6" : 106, + "bf_7" : 107, + "bf_8" : 108, + "bf_9" : 109, + "bf_10" : 110, + "bf_11" : 111, + "bf_12" : 112, + "bf_13" : 113, + "bf_14" : 114, + "bf_15" : 115, + "bf_16" : 116, +} + +# default is little_endian +i32 = 14 +i16 = 12 +i8 = 11 +u32 = 4 +u16 = 2 +u8 = 1 + +# explicit little endian +le_i32 = 14 +le_i16 = 12 +le_i8 = 11 +le_u32 = 4 +le_u16 = 2 +le_u8 = 1 + +# big endian +be_i32 = -14 +be_i16 = -12 +be_i8 = -11 +be_u32 = -4 +be_u16 = -2 +be_u8 = -1 + +# floating point +float32 = 5 +double64 = 10 + +# pointer +ptr32 = 9 +ptr64 = -9 + +# bitfields (always unsigned) +bf_x = 0 # generic bitfield +bf_0 = 100 # serves as base +bf_1 = 101 +bf_2 = 102 +bf_3 = 103 +bf_4 = 104 +bf_5 = 105 +bf_6 = 106 +bf_7 = 107 +bf_8 = 108 +bf_9 = 109 +bf_10 = 110 +bf_11 = 111 +bf_12 = 112 +bf_13 = 113 +bf_14 = 114 +bf_15 = 115 +bf_16 = 116 + +type_mapping = { + 14: "ctypes_i32", + 12: "ctypes_i16", + 11: "ctypes_i8", + 4: "ctypes_u32", + 2: "ctypes_u16", + 1: "ctypes_u8", + + -14:"ctypes_be_i32", # big endian + -12:"ctypes_be_i16", + -11:"ctypes_be_i8", + -4: "ctypes_be_u32", + -2: "ctypes_be_u16", + -1: "ctypes_be_u8", + + 5: "ctypes_float", + 10: "ctypes_double", + 9: "ctypes_ptr32", + -9: "ctypes_ptr64", + + 0: "ctypes_bf" # bitfield +} + +def type_to_str(type_num): + return type_mapping.get(type_num, str(type_num)) + +#- print the C types -#1 +def print_types(): + print("/********************************************************************") + print(" * Generated code, don't edit") + print(" *******************************************************************/") + print() + print("static const char * be_ctypes_instance_mappings[]; /* forward definition */") + print() + +global_classes = [] # track the list of all classes and +global_mappings = [] # mapping to Berry classes, ex: lv_color + +def print_classes(module_name): + # print mappings + global global_classes + if len(global_mappings) > 7: + raise Exception("too many mappings, 7 max") + + print("static const char * be_ctypes_instance_mappings[] = {") + for n in global_mappings: + print(f" \"{n}\",") + + print(" NULL") + print("};") + print() + + global_classes = sorted(global_classes) + + for elt in global_classes: + print(f"static be_define_ctypes_class({elt}, &be_{elt}, &be_class_ctypes_bytes, \"{elt}\");") + + print() + print(f"void be_load_ctypes_{module_name}_definitions_lib(bvm *vm) {{") + for elt in global_classes: + print(f" ctypes_register_class(vm, &be_class_{elt});") + + print("}") + print() + print("be_ctypes_class_by_name_t be_ctypes_lvgl_classes[] = {") + for elt in global_classes: + print(f" {{ \"{elt}\", &be_class_{elt} }},") + + print("};") + print("const size_t be_ctypes_lvgl_classes_size = sizeof(be_ctypes_lvgl_classes)/sizeof(be_ctypes_lvgl_classes[0]);") + print() + + print("/********************************************************************/") + + +#------------------------------------------------------------- +#- 'berry_ctypes.structure' class +#- +#- Parses a ctypes structure descriptor and creates +#- a set of getters and setters +#- +#-------------------------------------------------------------# +class structure: + # var cur_offset # offset in bytes from buffer start + # var bit_offset # are we intra-byte? + # var size_bytes # size in bytes + # var mapping # map to generate C binding + + # init world + def __init__(self, mapping, name): + self.cur_offset = 0 + self.bit_offset = 0 + self.size_bytes = 0 # overall size in bytes + self.mapping = {} + + # parse mapping + self.parse_mapping(mapping, name) + + #- iteratively parse mapping + #- + #- if name is not nil, it also outputs a C structure for the mapping + #- + #-------------------------------------------------------------# + def parse_mapping(self, mapping, name): + for map_line in mapping: + self.parse_line(map_line) + + # clear any outstanding bitfield + self.align(1) + self.size_bytes = self.cur_offset + + if name != None: + size_aligned = self.size_bytes + # as a final structure, we align to 2/4 bytes boundaries + if size_aligned >= 3: + size_aligned = int((size_aligned + 3)/4)*4 + + print(f"const be_ctypes_structure_t be_{name} = {{") + print(f" {size_aligned}, /* size in bytes */") + print(f" {len(self.mapping)}, /* number of elements */") + print(f" be_ctypes_instance_mappings,") + print(f" (const be_ctypes_structure_item_t[{len(self.mapping)}]) {{") + # list keys for future binary search + names = [] + for n in self.mapping.keys(): names.append(n) # convert to list + names = sorted(names) + for n in names: + args = self.mapping[n] + print(f" {{ \"{n}\", {args[0]}, {args[1]}, {args[2]}, {type_to_str(args[3])}, {args[4]} }},") + + print("}};") + print() + + # retain class definition + global_classes.append(name) + + def size(self): + return self.size_bytes + + # parse a single line + def parse_line(self, map_line): + # print(f"parse_line: {map_line}") + line_type = map_line[0] + line_name = map_line[1] + + if isinstance(line_type, structure): # TODO + # nested structure + self.nested(line_name, line_type) + + # special case where the type is a list + # which means a specific mapping to a class + # Ex: `[ct.u16, "lv_color"]` + mapping_idx = 0 # mapping starts at 1 + if isinstance(line_type, list): # TODO + # it may be a list to denote a mapping to an instance + mapping_name = line_type[1] + if not mapping_name in global_mappings: # TODO + global_mappings.append(mapping_name) + + mapping_idx = global_mappings.index(mapping_name) + 1 + line_type = line_type[0] # take the simple value of first element in the list + + # regular type as int + if isinstance(line_type, int): # TODO + # simple attibute + # TODO check actual type + if line_type > bf_0: + # bit field + self.parse_bitfield(line_name, line_type - bf_0, mapping_idx) + elif (line_type == ptr32) or (line_type == ptr64): + # pointer + self.parse_ptr(line_name, line_type, mapping_idx) + elif (line_type == float32) or (line_type == double64): + # multi-bytes + self.parse_float(line_name, line_type, mapping_idx) + else: + # multi-bytes + self.parse_int(line_name, line_type, mapping_idx) + + #- ensure alignment to 1/2/4 bytes -# + def align(self, n): + if n != 1 and n != 2 and n != 4: + raise Exception("acceptable values are 1/2/4") + + #- align to byte boundary if we're in a bitfield -# + if self.bit_offset != 0: + #- we are not byte aligned, let's re-aling -# + self.cur_offset += 1 + self.bit_offset = 0 + + #- check 2/4 bytes alignment -# + if self.cur_offset % n != 0: + # we are not aligned with current size + self.cur_offset += n - self.cur_offset % n + + def nested(self, name, type_obj): + sub_size = type_obj.size() + if sub_size <= 0: + raise Exception("empty sub-structure not supported") + + # align to appropriate sub-size + align_size = sub_size + if align_size == 3 or align_size > 4: align_size = 4 + self.align(align_size) + + offset = self.cur_offset # var for closure + + # include nested + for subname in type_obj.mapping.keys(): + val = type_obj.mapping[subname] + self.mapping[name+"_"+subname] = [val[0] + offset, val[1], val[2], val[3], val[4]] + # self.mapping[name] = [offset << 3, sub_size << 3] + + self.cur_offset += sub_size + + def parse_int(self, name, type, instance_mapping): # can be 1/2/4 + # print(f"parse_int name={name} type={type} map={instance_mapping}") + #- abs size -# + size_in_bytes = type + if size_in_bytes < 0: size_in_bytes = -type + + signed = size_in_bytes > 10 + size_in_bytes_le_be = type % 10 # remove sign marker + size_in_bytes = size_in_bytes % 10 # remove sign marker + + # print(f"size_in_bytes={size_in_bytes} signed={signed} size_in_bytes_le_be={size_in_bytes_le_be}") + + self.align(size_in_bytes) # force alignment + offset = self.cur_offset # prepare variable for capture in closure + + self.mapping[name] = [offset, 0, 0, type, instance_mapping] + + self.cur_offset += size_in_bytes # next offset + + def parse_ptr(self, name, type, instance_mapping): # can be 1/2/4 + #- actual size -# + size_in_bytes = 4 + if type == ptr64: size_in_bytes = 8 + + self.align(size_in_bytes) # force alignment + offset = self.cur_offset # prepare variable for capture in closure + + self.mapping[name] = [offset, 0, 0, type, instance_mapping] + + self.cur_offset += size_in_bytes # next offset + + def parse_float(self, name, type, instance_mapping): # can be 1/2/4 + #- actual size -# + size_in_bytes = 4 + if type == double64: size_in_bytes = 8 + + self.align(size_in_bytes) # force alignment + offset = self.cur_offset # prepare variable for capture in closure + + self.mapping[name] = [offset, 0, 0, type, instance_mapping] + + self.cur_offset += size_in_bytes # next offset + + def parse_bitfield(self, name, size_in_bits, instance_mapping): # can be 1..32 + cur_offset = self.cur_offset # prepare variable for capture in closure + bit_offset = self.bit_offset + self.mapping[name] = [cur_offset, bit_offset, size_in_bits, 0, instance_mapping] + + self.cur_offset += int((self.bit_offset + size_in_bits) / 8) + self.bit_offset = (self.bit_offset + size_in_bits) % 8 diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/ctypes.be b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/ctypes.be deleted file mode 100644 index c9f6249ab..000000000 --- a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/ctypes.be +++ /dev/null @@ -1,629 +0,0 @@ -#------------------------------------------------------------- -#- Ctypes for Berry -#- -#- Inspired from Python's ctypes structure -#-------------------------------------------------------------# -import string - -ctypes = module('ctypes') - -#------------------------------------------------------------- -#- Basic types for mapping -#- -#- ints of size 1/2/4 bytes (little endian by default) -#- usigned ints of size 1/2/4 bytes (little endian by default) -#- -#- (Big Endian are negative numbers) -#-------------------------------------------------------------# - -# default is little_endian -ctypes.i32 = 14 -ctypes.i16 = 12 -ctypes.i8 = 11 -ctypes.u32 = 4 -ctypes.u16 = 2 -ctypes.u8 = 1 - -# explicit little endian -ctypes.le_i32 = 14 -ctypes.le_i16 = 12 -ctypes.le_i8 = 11 -ctypes.le_u32 = 4 -ctypes.le_u16 = 2 -ctypes.le_u8 = 1 - -# big endian -ctypes.be_i32 = -14 -ctypes.be_i16 = -12 -ctypes.be_i8 = -11 -ctypes.be_u32 = -4 -ctypes.be_u16 = -2 -ctypes.be_u8 = -1 - -# floating point -ctypes.float = 5 -ctypes.double = 10 - -# pointer -ctypes.ptr32 = 9 -ctypes.ptr64 = -9 - -ctypes.bf_x = 0 # generic bitfield -# bitfields (always unsigned) -ctypes.bf_0 = 100 # serves as base -ctypes.bf_1 = 101 -ctypes.bf_2 = 102 -ctypes.bf_3 = 103 -ctypes.bf_4 = 104 -ctypes.bf_5 = 105 -ctypes.bf_6 = 106 -ctypes.bf_7 = 107 -ctypes.bf_8 = 108 -ctypes.bf_9 = 109 -ctypes.bf_10 = 110 -ctypes.bf_11 = 111 -ctypes.bf_12 = 112 -ctypes.bf_13 = 113 -ctypes.bf_14 = 114 -ctypes.bf_15 = 115 -ctypes.bf_16 = 116 - -ctypes.type_mapping = { - 14: "ctypes_i32", - 12: "ctypes_i16", - 11: "ctypes_i8", - 4: "ctypes_u32", - 2: "ctypes_u16", - 1: "ctypes_u8", - - -14:"ctypes_be_i32", # big endian - -12:"ctypes_be_i16", - -11:"ctypes_be_i8", - -4: "ctypes_be_u32", - -2: "ctypes_be_u16", - -1: "ctypes_be_u8", - - 5: "ctypes_float", - 10: "ctypes_double", - 9: "ctypes_ptr32", - -9: "ctypes_ptr64", - - 0: "ctypes_bf" # bitfield -} - -ctypes.type_to_str = def (type_num) - var type_name = ctypes.type_mapping.find(type_num) - if type_name == nil - return str(type_num) - end - return type_name -end - -def findinlist(l, x) - for i:0..size(l)-1 - if l[i] == x - return i - end - end -end - -#------------------------------------------------------------- -#- 'get_bits' function -#- -#- Reads a bit-field in a `bytes()` object -#- -#- Input: -#- b: bytes() object to read from -#- offset_bytes (int): byte offset in the bytes() object -#- offset_bits (int): bit number to start reading from (0 = LSB) -#- len_bits (int): how many bits to read -#- Output: -#- valuer (int) -#-------------------------------------------------------------# -ctypes.get_bits = def (b, offset_bytes, offset_bits, len_bits) - if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end - if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end - if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end - var ret = 0 - - var bit_shift = 0 # bit number to write to - - while (len_bits > 0) - var block_bits = 8 - offset_bits # how many bits to read in the current block (block = byte) - if block_bits > len_bits block_bits = len_bits end - - var mask = ( (1<> offset_bits) << bit_shift) - - # move the input window - bit_shift += block_bits - len_bits -= block_bits - offset_bits = 0 # start at full next byte - offset_bytes += 1 - end - - return ret -end - -ctypes.sort = def (l) - # insertion sort - for i:1..size(l)-1 - var k = l[i] - var j = i - while (j > 0) && (l[j-1] > k) - l[j] = l[j-1] - j -= 1 - end - l[j] = k - end - return l -end - -#------------------------------------------------------------- -#- 'set_bits' function -#- -#- Writes a bit-field in a `bytes()` object -#- -#- Input: -#- b: bytes() object to write to -#- offset_bytes (int): byte offset in the bytes() object -#- offset_bits (int): bit number to start writing to (0 = LSB) -#- len_bits (int): how many bits to write -#- Output: -#- bytes() object modified (by reference) -#-------------------------------------------------------------# -ctypes.set_bits = def (b, offset_bytes, offset_bits, len_bits, val) - if !isinstance(b, bytes) raise "value_error", "first argument must be of type 'bytes'" end - if offset_bits < 0 || offset_bits > 7 raise "value_error", "offset_bits must be between 0 and 7" end - if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end - - while (len_bits > 0) - var block_bits = 8 - offset_bits # how many bits to write in the current block (block = byte) - if block_bits > len_bits block_bits = len_bits end - - var mask_val = (1<>= block_bits - len_bits -= block_bits - offset_bits = 0 # start at full next byte - offset_bytes += 1 - end - return b -end - - -#- print the C types -#1 -ctypes.print_types = def () - print("/********************************************************************") - print(" * Generated code, don't edit") - print(" *******************************************************************/") - print() - print("static const char * be_ctypes_instance_mappings[]; /* forward definition */") - print() -end - -global_classes = [] # track the list of all classes and -global_mappings = [] # mapping to Berry classes, ex: lv_color - -ctypes.print_classes = def (module_name) - # print mappings - if size(global_mappings) > 7 - raise "internal_error", "too many mappings, 7 max" - end - print("static const char * be_ctypes_instance_mappings[] = {") - for n:global_mappings.iter() - print(string.format(" \"%s\",", n)) - end - print(" NULL") - print("};") - print() - - ctypes.sort(global_classes) - - for elt:global_classes - print(string.format("static be_define_ctypes_class(%s, &be_%s, &be_class_ctypes_bytes, \"%s\");", elt, elt, elt)) - end - - print() - print(string.format("void be_load_ctypes_%s_definitions_lib(bvm *vm) {", module_name)) - for elt:global_classes - print(string.format(" ctypes_register_class(vm, &be_class_%s);", elt)) - end - print("}") - print() - print("be_ctypes_class_by_name_t be_ctypes_lvgl_classes[] = {") - for elt:global_classes - print(string.format(" { \"%s\", &be_class_%s },", elt, elt)) - end - print("};") - print("const size_t be_ctypes_lvgl_classes_size = sizeof(be_ctypes_lvgl_classes)/sizeof(be_ctypes_lvgl_classes[0]);") - print() - - print("/********************************************************************/") - print() -end - -#------------------------------------------------------------- -#- 'ctypes.structure' class -#- -#- Parses a ctypes structure descriptor and creates -#- a set of getters and setters -#- -#-------------------------------------------------------------# -class structure - var cur_offset # offset in bytes from buffer start - var bit_offset # are we intra-byte? - var get_closures # - var set_closures # - var size_bytes # size in bytes - var mapping # map to generate C binding - - # init world - def init(mapping, name) - self.cur_offset = 0 - self.bit_offset = 0 - self.size_bytes = 0 # overall size in bytes - self.get_closures = {} - self.set_closures = {} - self.mapping = {} - - # parse mapping - self.parse_mapping(mapping, name) - end - #- iteratively parse mapping - #- - #- if name is not nil, it also outputs a C structure for the mapping - #- - #-------------------------------------------------------------# - def parse_mapping(mapping, name) - for map_line: mapping - self.parse_line(map_line) - end - - # clear any outstanding bitfield - self.align(1) - self.size_bytes = self.cur_offset - - if name != nil - var size_aligned = self.size_bytes - # as a final structure, we align to 2/4 bytes boundaries - if size_aligned >= 3 - size_aligned = ((size_aligned + 3)/4)*4 - end - - print(string.format("const be_ctypes_structure_t be_%s = {", name)) - print(string.format(" %i, /* size in bytes */", size_aligned)) - print(string.format(" %i, /* number of elements */", size(self.mapping))) - print(string.format(" be_ctypes_instance_mappings,")) - print(string.format(" (const be_ctypes_structure_item_t[%i]) {", size(self.mapping))) - # list keys for future binary search - var names = [] - for n:self.mapping.keys() names.push(n) end # convert to list - ctypes.sort(names) - for n:names - var args = self.mapping[n] - print(string.format(" { \"%s\", %i, %i, %i, %s, %i },", n, args[0], args[1], args[2], ctypes.type_to_str(args[3]), args[4])) - end - print("}};") - print() - - # retain class definition - global_classes.push(name) - end - end - - def size() - return self.size_bytes - end - - # parse a single line - def parse_line(map_line) - var type_obj = map_line[0] - var name = map_line[1] - var bits = 0 - if size(map_line) >= 3 bits = map_line[2] end - - if isinstance(type_obj, ctypes.structure) - # nested structure - self.nested(name, type_obj) - end - - var mapping_idx = 0 # mapping starts at 1 - if isinstance(type_obj, list) - # it may be a list to denote a mapping to an instance - var mapping_name = type_obj[1] - if findinlist(global_mappings, mapping_name) == nil - global_mappings.push(mapping_name) - end - mapping_idx = findinlist(global_mappings, mapping_name) + 1 - - type_obj = type_obj[0] # take the simple value of first element in the list - end - - if type(type_obj) == 'int' - # simple attibute - # TODO check actual type - if type_obj > ctypes.bf_0 - # bit field - self.get_bitfield_closure(name, type_obj - ctypes.bf_0, mapping_idx) - elif (type_obj == ctypes.ptr32) || (type_obj == ctypes.ptr64) - # pointer - self.get_ptr_closure(name, type_obj, mapping_idx) - elif (type_obj == ctypes.float) || (type_obj == ctypes.double) - # multi-bytes - self.get_float_closure(name, type_obj, mapping_idx) - else - # multi-bytes - self.get_int_closure(name, type_obj, mapping_idx) - end - end - end - - #- ensure alignment to 1/2/4 bytes -# - def align(n) - if n != 1 && n != 2 && n != 4 raise "value_error", "acceptable values are 1/2/4" end - - #- align to byte boundary if we're in a bitfield -# - if self.bit_offset != 0 - #- we are not byte aligned, let's re-aling -# - self.cur_offset += 1 - self.bit_offset = 0 - end - - #- check 2/4 bytes alignment -# - if self.cur_offset % n != 0 - # we are not aligned with current size - self.cur_offset += n - self.cur_offset % n - end - end - - def nested(name, type_obj) - var sub_size = type_obj.size() - if sub_size <= 0 raise "value_error", "empty sub-structure not supported" end - - # align to appropriate sub-size - var align_size = sub_size - if align_size == 3 || align_size > 4 align_size = 4 end - self.align(align_size) - - var offset = self.cur_offset # var for closure - - # include nested - for subname:type_obj.mapping.keys() - var val = type_obj.mapping[subname] - self.mapping[name+"_"+subname] = [val[0] + offset, val[1], val[2], val[3], val[4]] - end - # self.mapping[name] = [offset << 3, sub_size << 3] - - self.get_closures[name] = def (b, p) return ctypes.nested_buffer(type_obj, offset + p, b) end - # self.set_closures[name] = def (b, p, v) return ctypes.nested_buffer(type_obj, offset + p, b) end - - self.cur_offset += sub_size - end - - def get_int_closure(name, type, instance_mapping) # can be 1/2/4 - #- abs size -# - var size_in_bytes = type < 0 ? - type : type - var signed = size_in_bytes > 10 - var size_in_bytes_le_be = type % 10 # remove sign marker - size_in_bytes = size_in_bytes % 10 # remove sign marker - - self.align(size_in_bytes) # force alignment - var offset = self.cur_offset # prepare variable for capture in closure - - self.mapping[name] = [offset, 0, 0, type, instance_mapping] - - #- add closures -# - if signed - self.get_closures[name] = def (b, p) return b.geti(offset + p, size_in_bytes_le_be) end - else - self.get_closures[name] = def (b, p) return b.get(offset + p, size_in_bytes_le_be) end - end - self.set_closures[name] = def (b, p, v) return b.set(offset+ p, v, size_in_bytes_le_be) end - - self.cur_offset += size_in_bytes # next offset - end - - def get_ptr_closure(name, type, instance_mapping) # can be 1/2/4 - #- actual size -# - import introspect - var size_in_bytes = (type == ctypes.ptr32) ? 4 : 8 - - self.align(size_in_bytes) # force alignment - var offset = self.cur_offset # prepare variable for capture in closure - - self.mapping[name] = [offset, 0, 0, type, instance_mapping] - - #- add closures -# - # TODO no closure yet, anyways need to rethink closures, they are too heavy - # if signed - # self.get_closures[name] = def (b, p) return b.geti(offset + p, size_in_bytes_le_be) end - # else - # self.get_closures[name] = def (b, p) return b.get(offset + p, size_in_bytes_le_be) end - # end - # self.set_closures[name] = def (b, p, v) return b.set(offset+ p, v, size_in_bytes_le_be) end - - self.cur_offset += size_in_bytes # next offset - end - - def get_float_closure(name, type, instance_mapping) # can be 1/2/4 - #- actual size -# - var size_in_bytes = (type == ctypes.float) ? 4 : 8 - - self.align(size_in_bytes) # force alignment - var offset = self.cur_offset # prepare variable for capture in closure - - self.mapping[name] = [offset, 0, 0, type, instance_mapping] - - #- add closures -# - # TODO no closure yet, anyways need to rethink closures, they are too heavy - # if signed - # self.get_closures[name] = def (b, p) return b.geti(offset + p, size_in_bytes_le_be) end - # else - # self.get_closures[name] = def (b, p) return b.get(offset + p, size_in_bytes_le_be) end - # end - # self.set_closures[name] = def (b, p, v) return b.set(offset+ p, v, size_in_bytes_le_be) end - - self.cur_offset += size_in_bytes # next offset - end - - def get_bitfield_closure(name, size_in_bits, instance_mapping) # can be 1..32 - var cur_offset = self.cur_offset # prepare variable for capture in closure - var bit_offset = self.bit_offset - self.mapping[name] = [cur_offset, bit_offset, size_in_bits, 0, instance_mapping] - self.get_closures[name] = def (b, p) return ctypes.get_bits(b, cur_offset + p, bit_offset, size_in_bits) end - self.set_closures[name] = def (b, p, v) return ctypes.set_bits(b, cur_offset+ p, bit_offset, size_in_bits, v) end - - self.cur_offset += (self.bit_offset + size_in_bits) / 8 - self.bit_offset = (self.bit_offset + size_in_bits) % 8 - end -end - -ctypes.structure = structure - -#------------------------------------------------------------- -#- Structured buffer -#- -#- Inspired from Python's ctypes structure -#- -#- This class is a wrapper around `bytes()` object (actually a subclass) -#- providing virtual members mapped to the ctypes structure. -#- -#- Takes as argument a ctypes.structure and an optional bytes() object -#-------------------------------------------------------------# -class buffer : bytes - var _cs # ctypes_structure associated - - def init(cs, b) - if !isinstance(cs, ctypes.structure) raise "value_error", "first argument must be an instance of 'ctypes.structure'" end - self._cs = cs - var size = self._cs.size() # size in bytes of the structure - - super(self, bytes).init(size) # init bytes object with reserved size in memory - - if isinstance(b, bytes) - self..b - end - self.resize(size) # size once for all to the target size and complete with 00s - end - - # accessor for virtual member - def member(name) - return self._cs.get_closures[name](self, 0) - end - - # setter for virtual member - def setmember(name, value) - self._cs.set_closures[name](self, 0, value) - end -end -ctypes.buffer = buffer - -#------------------------------------------------------------- -#- Nested buffer -#- -#- Nested structures are just pointers to the master bytes() object -#-------------------------------------------------------------# -class nested_buffer - var _cs # ctypes.structure instance for this buffer - var _offset # offset un bytes() to the structure - var _bytes # reference to the overall buffer (by reference) - - def init(cs, offset, b) - if !isinstance(cs, ctypes.structure) raise "value_error", "first argument must be an instance of 'ctypes.structure'" end - if type(offset) != 'int' raise "value_error", "second argument must be of type 'int'" end - if !isinstance(b, bytes) raise "value_error", "third argument must be an instance of 'bytes'" end - self._cs = cs - self._offset = offset - self._bytes = b - end - - # accessor for virtual member - def member(name) - return self._cs.get_closures[name](self._bytes, self._offset) - end - - # setter for virtual member - def setmember(name, value) - self._cs.set_closures[name](self._bytes, self._offset, value) - end - - def tostring() - return self._bytes[self._offset..self._offset+self._cs.size()-1].tostring() - end -end -ctypes.nested_buffer = nested_buffer - - -return ctypes - -# ex = [ -# [ctypes.u32, "a"], -# [ctypes.u16, "b"], -# [ctypes.i8, "c"], -# [ctypes.i32, "d"], # should infer an empty byte -# ] - -# cs = ctypes.structure(ex) -# bb = ctypes.buffer(cs, bytes("aabb")) - -# fa = cp.get_int_closure('a', 4) -# fb = cp.get_int_closure('b', 2) -# fc = cp.get_int_closure('c', 1) -# fd = cp.get_int_closure('d', 4) - -# b = bytes("04030201AA55FFFF00010001") - -# cp.get_closures['a'](b) -# cp.get_closures['b'](b) -# cp.get_closures['c'](b) -# cp.get_closures['d'](b) - -# bb = ctypes_buffer(cp, b) - -# bb.a = 0x11223344 -# bb -# bb.a - - -# > bb = ctypes_buffer(cp, b) -# > bb.a -# 16909060 -# > bb.b -# 21930 -# > bb.c -# 255 -# > bb.d -# 16777472 -# > bb.e -# key_error: e -# stack traceback: -# : in native function -# stdin:11: in function `member` -# stdin:1: in function `main` - - -# > bb['a'] -# 16909060 -# > bb['b'] -# 21930 -# > bb['c'] -# 255 -# > bb['d'] -# 16777472 - -#- -> fa(b) -16909060 -> fb(b) -21930 -> fc(b) -255 -> fd(b) -16777472 - --# diff --git a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.be b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py similarity index 69% rename from lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.be rename to lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py index a8bf280fc..e193ece08 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.be +++ b/lib/libesp32_lvgl/lv_binding_berry/src/embedded/lvgl_ctypes.py @@ -1,55 +1,61 @@ -# -# ctype buidings for LVGL -# -# To generate C bindings, do: -# > compile("lvgl_ctypes.be","file")() -# -# and copy/paste output in C format in `be_lvgl_ctypes_definitions.c` -# -import ctypes +# define LVGL low-level C structures -ctypes.print_types() +import sys +import berry_ctypes as ct -lv_style_int = ctypes.i16 -lv_color = [ctypes.u16, "lv_color"] # cast to the class instance, constructor is called with 2 args: (nil, value) -lv_grad_dir = ctypes.u8 -lv_meter_indicator_type_t = ctypes.u8 -lv_opa = ctypes.u8 -lv_blend_mode = ctypes.u8 -lv_align = ctypes.u8 -lv_coord_t = ctypes.i16 -lv_bidi_dir = ctypes.u8 -lv_txt_flag = ctypes.u8 -lv_text_decor = ctypes.u8 -lv_font = ctypes.u32 -lv_blend_mode = ctypes.u8 -lv_draw_mask_line_side = ctypes.u8 -lv_dir = ctypes.u8 -uint8_t_1 = ctypes.bf_1 -uint8_t_2 = ctypes.bf_2 -uint8_t_3 = ctypes.bf_3 -uint8_t_4 = ctypes.bf_4 -uint8_t_5 = ctypes.bf_5 -uint8_t_11 = ctypes.bf_11 -uint8_t = ctypes.u8 -int16_t = ctypes.i16 -uint16_t = ctypes.u16 -uint16_t_15 = ctypes.bf_15 -uint16_t_16 = ctypes.bf_16 -uint32_t = ctypes.u32 -int32_t = ctypes.i32 -ptr = ctypes.ptr32 +sys.stdout = open("../be_lvgl_ctypes_definitions.c", 'w') + +print("""/******************************************************************** + * Tasmota LVGL ctypes mapping + *******************************************************************/ +#include "be_ctypes.h" +#include "lvgl.h" +#include "be_mapping.h" + +""") + +ct.print_types() + +lv_style_int = ct.i16 +lv_color = [ct.u16, "lv_color"] # cast to the class instance, constructor is called with 2 args: (nil, value) +lv_grad_dir = ct.u8 +lv_meter_indicator_type_t = ct.u8 +lv_opa = ct.u8 +lv_blend_mode = ct.u8 +lv_align = ct.u8 +lv_coord_t = ct.i16 +lv_bidi_dir = ct.u8 +lv_txt_flag = ct.u8 +lv_text_decor = ct.u8 +lv_font = ct.u32 +lv_blend_mode = ct.u8 +lv_draw_mask_line_side = ct.u8 +lv_dir = ct.u8 +uint8_t_1 = ct.bf_1 +uint8_t_2 = ct.bf_2 +uint8_t_3 = ct.bf_3 +uint8_t_4 = ct.bf_4 +uint8_t_5 = ct.bf_5 +uint8_t_11 = ct.bf_11 +uint8_t = ct.u8 +int16_t = ct.i16 +uint16_t = ct.u16 +uint16_t_15 = ct.bf_15 +uint16_t_16 = ct.bf_16 +uint32_t = ct.u32 +int32_t = ct.i32 +ptr = ct.ptr32 lv_coord = [ # valid LVGL8 [lv_coord_t, "v"], ] -lv_coord = ctypes.structure(lv_coord, "lv_coord") +lv_coord = ct.structure(lv_coord, "lv_coord") lv_point = [ # valid LVGL8 [lv_coord_t, "x"], [lv_coord_t, "y"], ] -lv_point = ctypes.structure(lv_point, "lv_point") +lv_point = ct.structure(lv_point, "lv_point") lv_area = [ # valid LVGL8 [lv_coord_t, "x1"], @@ -57,7 +63,7 @@ lv_area = [ # valid LVGL8 [lv_coord_t, "x2"], [lv_coord_t, "y2"], ] -lv_area = ctypes.structure(lv_area, "lv_area") +lv_area = ct.structure(lv_area, "lv_area") ####################################################################### # lv_grad_dsc @@ -65,7 +71,7 @@ lv_gradient_stop = [ [lv_color, "color"], [uint8_t, "frac"], ] -lv_gradient_stop = ctypes.structure(lv_gradient_stop, "lv_gradient_stop") +lv_gradient_stop = ct.structure(lv_gradient_stop, "lv_gradient_stop") lv_grad_dsc = [ [lv_gradient_stop, "stops_0"], @@ -74,7 +80,7 @@ lv_grad_dsc = [ [uint8_t_3, "dir"], [uint8_t_3, "dither"], ] -lv_grad_dsc = ctypes.structure(lv_grad_dsc, "lv_grad_dsc") +lv_grad_dsc = ct.structure(lv_grad_dsc, "lv_grad_dsc") lv_draw_rect_dsc = [ # valid LVGL8.2 [lv_coord_t, "radius"], @@ -114,7 +120,7 @@ lv_draw_rect_dsc = [ # valid LVGL8.2 [lv_coord_t, "shadow_spread"], [lv_opa, "shadow_opa"], ] -lv_draw_rect_dsc = ctypes.structure(lv_draw_rect_dsc, "lv_draw_rect_dsc") +lv_draw_rect_dsc = ct.structure(lv_draw_rect_dsc, "lv_draw_rect_dsc") lv_draw_line_dsc = [ # valid LVGL8.2 [lv_color, "color"], @@ -127,7 +133,7 @@ lv_draw_line_dsc = [ # valid LVGL8.2 [uint8_t_1, "round_end"], [uint8_t_1, "raw_end"], ] -lv_draw_line_dsc = ctypes.structure(lv_draw_line_dsc, "lv_draw_line_dsc") +lv_draw_line_dsc = ct.structure(lv_draw_line_dsc, "lv_draw_line_dsc") lv_draw_arc_dsc = [ # valid LVGL8.2 [lv_color, "color"], @@ -139,7 +145,7 @@ lv_draw_arc_dsc = [ # valid LVGL8.2 [uint8_t_2, "blend_mode"], [uint8_t_1, "rounded"], ] -lv_draw_arc_dsc = ctypes.structure(lv_draw_arc_dsc, "lv_draw_arc_dsc") +lv_draw_arc_dsc = ct.structure(lv_draw_arc_dsc, "lv_draw_arc_dsc") lv_draw_img_dsc = [ # valid LVGL8.2 [uint16_t, "angle"], @@ -155,7 +161,7 @@ lv_draw_img_dsc = [ # valid LVGL8.2 [int32_t, "frame_id"], [uint8_t_1, "antialias"], ] -lv_draw_img_dsc = ctypes.structure(lv_draw_img_dsc, "lv_draw_img_dsc") +lv_draw_img_dsc = ct.structure(lv_draw_img_dsc, "lv_draw_img_dsc") lv_obj_draw_part_dsc = [ # valid LVGL8.2 [ptr, "draw_ctx"], @@ -177,18 +183,18 @@ lv_obj_draw_part_dsc = [ # valid LVGL8.2 [int32_t, "value"], [ptr, "sub_part_ptr"], ] -lv_obj_draw_part_dsc = ctypes.structure(lv_obj_draw_part_dsc, "lv_obj_draw_part_dsc") +lv_obj_draw_part_dsc = ct.structure(lv_obj_draw_part_dsc, "lv_obj_draw_part_dsc") #- --------- lv_mask --------- -# lv_draw_mask_xcb = ptr # callback -lv_draw_mask_type = ctypes.u8 -lv_draw_mask_line_side = ctypes.u8 +lv_draw_mask_type = ct.u8 +lv_draw_mask_line_side = ct.u8 lv_draw_mask_common_dsc = [ # valid LVGL8.2 [lv_draw_mask_xcb, "cb"], [lv_draw_mask_type, "type"], ] -lv_draw_mask_common_dsc = ctypes.structure(lv_draw_mask_common_dsc, "lv_draw_mask_common_dsc") +lv_draw_mask_common_dsc = ct.structure(lv_draw_mask_common_dsc, "lv_draw_mask_common_dsc") lv_draw_mask_line_param_cfg = [ # valid LVGL8.2 #/*First point */ @@ -200,7 +206,7 @@ lv_draw_mask_line_param_cfg = [ # valid LVGL8.2 #/*Which side to keep?*/ [uint8_t_2, "side"], ] -lv_draw_mask_line_param_cfg = ctypes.structure(lv_draw_mask_line_param_cfg, "lv_draw_mask_line_param_cfg") +lv_draw_mask_line_param_cfg = ct.structure(lv_draw_mask_line_param_cfg, "lv_draw_mask_line_param_cfg") lv_draw_mask_line_param = [ # valid LVGL8.2 #/*The first element must be the common descriptor*/ @@ -222,14 +228,14 @@ lv_draw_mask_line_param = [ # valid LVGL8.2 # * It is used to select left/right/top/bottom*/ [uint8_t_1, "inv"], ] -lv_draw_mask_line_param = ctypes.structure(lv_draw_mask_line_param, "lv_draw_mask_line_param") +lv_draw_mask_line_param = ct.structure(lv_draw_mask_line_param, "lv_draw_mask_line_param") lv_draw_mask_angle_param_cfg = [ # valid LVGL8.2 [lv_point, "vertex_p"], [lv_coord_t, "start_angle"], [lv_coord_t, "end_angle"], ] -lv_draw_mask_angle_param_cfg = ctypes.structure(lv_draw_mask_angle_param_cfg, "lv_draw_mask_angle_param_cfg") +lv_draw_mask_angle_param_cfg = ct.structure(lv_draw_mask_angle_param_cfg, "lv_draw_mask_angle_param_cfg") lv_draw_mask_angle_param = [ # valid LVGL8.2 #/*The first element must be the common descriptor*/ @@ -240,7 +246,7 @@ lv_draw_mask_angle_param = [ # valid LVGL8.2 [lv_draw_mask_line_param, "end_line"], [uint16_t, "delta_deg"], ] -lv_draw_mask_angle_param = ctypes.structure(lv_draw_mask_angle_param, "lv_draw_mask_angle_param") +lv_draw_mask_angle_param = ct.structure(lv_draw_mask_angle_param, "lv_draw_mask_angle_param") lv_draw_mask_radius_param_cfg = [ # valid LVGL8.2 @@ -248,7 +254,7 @@ lv_draw_mask_radius_param_cfg = [ # valid LVGL8.2 [lv_coord_t, "radius"], [uint8_t_1, "outer"], ] -lv_draw_mask_radius_param_cfg = ctypes.structure(lv_draw_mask_radius_param_cfg, "lv_draw_mask_radius_param_cfg") +lv_draw_mask_radius_param_cfg = ct.structure(lv_draw_mask_radius_param_cfg, "lv_draw_mask_radius_param_cfg") lv_draw_mask_radius_circle_dsc = [ # valid LVGL8.2 [ptr, "buf"], @@ -259,7 +265,7 @@ lv_draw_mask_radius_circle_dsc = [ # valid LVGL8.2 [uint32_t, "used_cnt"], [lv_coord_t, "radius"], ] -lv_draw_mask_radius_circle_dsc = ctypes.structure(lv_draw_mask_radius_circle_dsc, "lv_draw_mask_radius_circle_dsc") +lv_draw_mask_radius_circle_dsc = ct.structure(lv_draw_mask_radius_circle_dsc, "lv_draw_mask_radius_circle_dsc") lv_draw_mask_radius_param = [ # valid LVGL8.2 #/*The first element must be the common descriptor*/ @@ -267,7 +273,7 @@ lv_draw_mask_radius_param = [ # valid LVGL8.2 [lv_draw_mask_radius_param_cfg, "cfg"], [lv_draw_mask_radius_circle_dsc, "circle"], ] -lv_draw_mask_radius_param = ctypes.structure(lv_draw_mask_radius_param, "lv_draw_mask_radius_param") +lv_draw_mask_radius_param = ct.structure(lv_draw_mask_radius_param, "lv_draw_mask_radius_param") lv_draw_mask_fade_param_cfg = [ # valid LVGL8.2 @@ -277,47 +283,47 @@ lv_draw_mask_fade_param_cfg = [ # valid LVGL8.2 [lv_opa, "opa_top"], [lv_opa, "opa_bottom"], ] -lv_draw_mask_fade_param_cfg = ctypes.structure(lv_draw_mask_fade_param_cfg, "lv_draw_mask_fade_param_cfg") +lv_draw_mask_fade_param_cfg = ct.structure(lv_draw_mask_fade_param_cfg, "lv_draw_mask_fade_param_cfg") lv_draw_mask_fade_param = [ # valid LVGL8.2 # /*The first element must be the common descriptor*/ [lv_draw_mask_common_dsc, "dsc"], [lv_draw_mask_fade_param_cfg, "cfg"], ] -lv_draw_mask_fade_param = ctypes.structure(lv_draw_mask_fade_param, "lv_draw_mask_fade_param") +lv_draw_mask_fade_param = ct.structure(lv_draw_mask_fade_param, "lv_draw_mask_fade_param") lv_draw_mask_map_param_cfg = [ # valid LVGL8.2 [lv_area, "coords"], [ptr, "map"], ] -lv_draw_mask_map_param_cfg = ctypes.structure(lv_draw_mask_map_param_cfg, "lv_draw_mask_map_param_cfg") +lv_draw_mask_map_param_cfg = ct.structure(lv_draw_mask_map_param_cfg, "lv_draw_mask_map_param_cfg") lv_draw_mask_map_param = [ # valid LVGL8.2 [lv_draw_mask_common_dsc, "dsc"], [lv_draw_mask_map_param_cfg, "cfg"], ] -lv_draw_mask_map_param = ctypes.structure(lv_draw_mask_map_param, "lv_draw_mask_map_param") +lv_draw_mask_map_param = ct.structure(lv_draw_mask_map_param, "lv_draw_mask_map_param") lv_draw_mask_polygon_param_cfg = [ # valid LVGL8.2 [ptr, "points"], [uint16_t, "point_cnt"], ] -lv_draw_mask_polygon_param_cfg = ctypes.structure(lv_draw_mask_polygon_param_cfg, "lv_draw_mask_polygon_param_cfg") +lv_draw_mask_polygon_param_cfg = ct.structure(lv_draw_mask_polygon_param_cfg, "lv_draw_mask_polygon_param_cfg") lv_draw_mask_polygon_param = [ # valid LVGL8.2 [lv_draw_mask_common_dsc, "dsc"], [lv_draw_mask_polygon_param_cfg, "cfg"], ] -lv_draw_mask_polygon_param = ctypes.structure(lv_draw_mask_polygon_param, "lv_draw_mask_polygon_param") +lv_draw_mask_polygon_param = ct.structure(lv_draw_mask_polygon_param, "lv_draw_mask_polygon_param") lv_draw_mask_saved = [ # valid LVGL8.2 [ptr, "param"], [ptr, "custom_id"], ] -lv_draw_mask_saved = ctypes.structure(lv_draw_mask_saved, "lv_draw_mask_saved") +lv_draw_mask_saved = ct.structure(lv_draw_mask_saved, "lv_draw_mask_saved") # lv_meter @@ -342,7 +348,7 @@ lv_meter_scale = [ # valid LVGL8.2 [uint16_t, "angle_range"], [int16_t, "rotation"], ] -lv_meter_scale = ctypes.structure(lv_meter_scale, "lv_meter_scale") +lv_meter_scale = ct.structure(lv_meter_scale, "lv_meter_scale") # lv_meter_indicator_t lv_meter_indicator = [ # valid LVGL8.2 @@ -356,7 +362,7 @@ lv_meter_indicator = [ # valid LVGL8.2 [ptr, "data1"], [ptr, "data2"], ] -lv_meter_indicator = ctypes.structure(lv_meter_indicator, "lv_meter_indicator") +lv_meter_indicator = ct.structure(lv_meter_indicator, "lv_meter_indicator") # variants lv_meter_indicator_needle_img = [ # valid LVGL8.2 @@ -369,7 +375,7 @@ lv_meter_indicator_needle_img = [ # valid LVGL8.2 [ptr, "src"], [lv_point, "pivot"], ] -lv_meter_indicator_needle_img = ctypes.structure(lv_meter_indicator_needle_img, "lv_meter_indicator_needle_img") +lv_meter_indicator_needle_img = ct.structure(lv_meter_indicator_needle_img, "lv_meter_indicator_needle_img") lv_meter_indicator_needle_line = [ # valid LVGL8.2 [ptr, "scale"], @@ -382,7 +388,7 @@ lv_meter_indicator_needle_line = [ # valid LVGL8.2 [int16_t, "r_mod"], [lv_color, "color"], ] -lv_meter_indicator_needle_line = ctypes.structure(lv_meter_indicator_needle_line, "lv_meter_indicator_needle_line") +lv_meter_indicator_needle_line = ct.structure(lv_meter_indicator_needle_line, "lv_meter_indicator_needle_line") lv_meter_indicator_arc = [ # valid LVGL8.2 [ptr, "scale"], @@ -396,7 +402,7 @@ lv_meter_indicator_arc = [ # valid LVGL8.2 [lv_color, "color"], [int16_t, "r_mod"], ] -lv_meter_indicator_arc = ctypes.structure(lv_meter_indicator_arc, "lv_meter_indicator_arc") +lv_meter_indicator_arc = ct.structure(lv_meter_indicator_arc, "lv_meter_indicator_arc") lv_meter_indicator_scale_lines = [ # valid LVGL8.2 [ptr, "scale"], @@ -410,7 +416,7 @@ lv_meter_indicator_scale_lines = [ # valid LVGL8.2 [lv_color, "color_end"], [uint8_t_1, "local_grad"], ] -lv_meter_indicator_scale_lines = ctypes.structure(lv_meter_indicator_scale_lines, "lv_meter_indicator_scale_lines") +lv_meter_indicator_scale_lines = ct.structure(lv_meter_indicator_scale_lines, "lv_meter_indicator_scale_lines") lv_chart_series = [ # valid LVGL8.2 [ptr, "x_points"], @@ -423,7 +429,7 @@ lv_chart_series = [ # valid LVGL8.2 [uint8_t_1, "x_axis_sec"], [uint8_t_1, "y_axis_sec"], ] -lv_chart_series = ctypes.structure(lv_chart_series, "lv_chart_series") +lv_chart_series = ct.structure(lv_chart_series, "lv_chart_series") lv_chart_cursor = [ # valid LVGL8.2 [lv_point, "pos"], @@ -433,7 +439,7 @@ lv_chart_cursor = [ # valid LVGL8.2 [lv_dir, "dir"], [uint8_t_1, "pos_set"], ] -lv_chart_cursor = ctypes.structure(lv_chart_cursor, "lv_chart_cursor") +lv_chart_cursor = ct.structure(lv_chart_cursor, "lv_chart_cursor") lv_chart_tick_dsc = [ # valid LVGL8.2 [lv_coord_t, "major_len"], @@ -443,7 +449,7 @@ lv_chart_tick_dsc = [ # valid LVGL8.2 [uint16_t_15, "major_cnt"], [uint8_t_1, "label_en"], ] -lv_chart_tick_dsc = ctypes.structure(lv_chart_tick_dsc, "lv_chart_tick_dsc") +lv_chart_tick_dsc = ct.structure(lv_chart_tick_dsc, "lv_chart_tick_dsc") #- --------- class system --------- -# @@ -453,7 +459,7 @@ lv_event_ptr = ptr constructor_cb = ptr # callback destructor_cb = ptr # callback event_cb = ptr # callback -lv_event_code = ctypes.i32 +lv_event_code = ct.i32 lv_obj_class = [ # valid LVGL8.2 [lv_obj_class_ptr, "base_class"], @@ -467,7 +473,7 @@ lv_obj_class = [ # valid LVGL8.2 [uint8_t_2, "group_def"], [uint16_t_16, "instance_size"], ] -lv_obj_class = ctypes.structure(lv_obj_class, "lv_obj_class") +lv_obj_class = ct.structure(lv_obj_class, "lv_obj_class") lv_event = [ # valid LVGL8.2 [lv_obj_ptr, "target"], @@ -480,13 +486,13 @@ lv_event = [ # valid LVGL8.2 [uint8_t_1, "stop_processing"], [uint8_t_1, "stop_bubbling"], ] -lv_event = ctypes.structure(lv_event, "lv_event") +lv_event = ct.structure(lv_event, "lv_event") lv_sqrt_res = [ # valid LVGL8.2 [uint16_t, "i"], [uint16_t, "f"], ] -lv_sqrt_res = ctypes.structure(lv_sqrt_res, "lv_sqrt_res") +lv_sqrt_res = ct.structure(lv_sqrt_res, "lv_sqrt_res") ####################################################################### # lv_img structures @@ -497,14 +503,14 @@ lv_img_header = [ # valid LVGL8.2 [uint8_t_11, "w"], [uint8_t_11, "h"], ] -lv_img_header = ctypes.structure(lv_img_header, "lv_img_header") +lv_img_header = ct.structure(lv_img_header, "lv_img_header") lv_img_dsc = [ # valid LVGL8.2 [lv_img_header, "header"], [uint32_t, "data_size"], [ptr, "data"], ] -lv_img_dsc = ctypes.structure(lv_img_dsc, "lv_img_dsc") +lv_img_dsc = ct.structure(lv_img_dsc, "lv_img_dsc") ####################################################################### # lv_style @@ -515,7 +521,7 @@ lv_style_transition_dsc = [ # valid LVGL8.2 [uint32_t, "time"], [uint32_t, "delay"], ] -lv_style_transition_dsc = ctypes.structure(lv_style_transition_dsc, "lv_style_transition_dsc") +lv_style_transition_dsc = ct.structure(lv_style_transition_dsc, "lv_style_transition_dsc") ####################################################################### # lv_color @@ -524,13 +530,13 @@ lv_style_transition_dsc = ctypes.structure(lv_style_transition_dsc, "lv_style_tr # [uint8_t, "s"], # [uint8_t, "v"], # ] -# lv_color_hsv = ctypes.structure(lv_color_hsv, "lv_color_hsv") +# lv_color_hsv = ct.structure(lv_color_hsv, "lv_color_hsv") lv_color_filter_dsc = [ # valid LVGL8.2 [ptr, "filter_cb"], [ptr, "user_data"], ] -lv_color_filter_dsc = ctypes.structure(lv_color_filter_dsc, "lv_color_filter_dsc") +lv_color_filter_dsc = ct.structure(lv_color_filter_dsc, "lv_color_filter_dsc") ####################################################################### # lv_timer @@ -542,7 +548,7 @@ lv_timer = [ # valid LVGL8.2 [int32_t, "repeat_count"], [uint8_t_1, "paused"], ] -lv_timer = ctypes.structure(lv_timer, "lv_timer") +lv_timer = ct.structure(lv_timer, "lv_timer") # ####################################################################### # # lv_anim @@ -572,7 +578,7 @@ lv_timer = ctypes.structure(lv_timer, "lv_timer") # [uint8_t_1, "start_cb_called"], # ] -# lv_anim = ctypes.structure(lv_anim, "lv_anim") +# lv_anim = ct.structure(lv_anim, "lv_anim") ####################################################################### # lv_draw_ctx @@ -591,7 +597,7 @@ lv_draw_ctx = [ # valid LVGL8.2 [ptr, "wait_for_finish"], [ptr, "user_data"], ] -lv_draw_ctx = ctypes.structure(lv_draw_ctx, "lv_draw_ctx") +lv_draw_ctx = ct.structure(lv_draw_ctx, "lv_draw_ctx") ####################################################################### # Special structure used to calibrate resistive touchscreens @@ -603,45 +609,7 @@ lv_ts_calibration = [ # valid LVGL8 [lv_coord_t, "y"], [int32_t, "state"], ] -lv_ts_calibration = ctypes.structure(lv_ts_calibration, "lv_ts_calibration") +lv_ts_calibration = ct.structure(lv_ts_calibration, "lv_ts_calibration") # -ctypes.print_classes("lvgl") - -# Ex: -# bb = ctypes.buffer(test_t, bytes("0101020203030404FFFFFEFEFCFC8080")) - -# Ex: -# bb = ctypes.buffer(lv_draw_rect) - -#- Ex - -bb=ctypes.buffer(lv_draw_line_dsc) -bb.color -bb.blend_mode - -bb.color = -1 -- bytes('FFFF0000000000000003') - -bb.blend_mode=3 -- bytes('FFFF0000000000000003') - -bb.raw_end = 1 -- bytes('FFFF0000000000000013') - -bb.blend_mode=0 -- bytes('FFFF0000000000000010') - -lv_draw_line_dsc = [ - [lv_color, "color"], - [lv_style_int, "width"], - [lv_style_int, "dash_width"], - [lv_style_int, "dash_gap"], - [lv_opa, "opa"], - [uint8_t_2, "blend_mode"], - [uint8_t_1, "round_start"], - [uint8_t_1, "round_end"], - [uint8_t_1, "raw_end"], -] - --# \ No newline at end of file +ct.print_classes("lvgl") diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/gen.sh b/lib/libesp32_lvgl/lv_binding_berry/tools/gen.sh new file mode 100755 index 000000000..5bd081698 --- /dev/null +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/gen.sh @@ -0,0 +1,6 @@ +# + +python3 preprocessor.py +python3 convert.py +cd ../src/embedded +python3 berry_ctypes.py \ No newline at end of file