Merge pull request #15774 from s-hadinger/ctypes_simplified

Ported berry_ctypes to python
This commit is contained in:
s-hadinger 2022-06-08 22:23:09 +02:00 committed by GitHub
commit f69421ced5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 488 additions and 757 deletions

View File

@ -2,10 +2,10 @@
* Tasmota LVGL ctypes mapping
*******************************************************************/
#include "be_ctypes.h"
#include "lvgl.h"
#include "be_mapping.h"
/********************************************************************
* Generated code, don't edit
*******************************************************************/

View File

@ -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

View File

@ -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<<block_bits) - 1) << offset_bits
# print(string.format("mask = %02X", mask))
ret = ret | ( ((b[offset_bytes] & mask) >> 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) - 1 # mask to the n bits to get for this block
var mask_b_inv = 0xFF - (mask_val << offset_bits)
b[offset_bytes] = (b[offset_bytes] & mask_b_inv) | ((val & mask_val) << offset_bits)
# move the input window
val >>= 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:
# <native>: 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
-#

View File

@ -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"],
]
-#
ct.print_classes("lvgl")

View File

@ -0,0 +1,6 @@
#
python3 preprocessor.py
python3 convert.py
cd ../src/embedded
python3 berry_ctypes.py