LVGL Prepare last phase custom types

This commit is contained in:
Stephan Hadinger 2021-06-29 13:24:11 +02:00
parent 6b05b62099
commit 1a39656ff0
6 changed files with 1567 additions and 17 deletions

View File

@ -13,6 +13,7 @@
#include "be_exec.h" #include "be_exec.h"
#include "be_vm.h" #include "be_vm.h"
#include "be_mem.h" #include "be_mem.h"
#include "be_constobj.h"
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@ -47,13 +48,6 @@ static void buf_set_len(buf_impl* buf, const size_t len)
} }
} }
static void buf_set1(buf_impl* buf, const size_t offset, const uint8_t data)
{
if (offset < buf->len) {
buf->buf[offset] = data;
}
}
static size_t buf_add1(buf_impl* buf, const uint8_t data) // append 8 bits value static size_t buf_add1(buf_impl* buf, const uint8_t data) // append 8 bits value
{ {
if (buf->len < buf->size) { // do we have room for 1 byte if (buf->len < buf->size) { // do we have room for 1 byte
@ -120,7 +114,31 @@ static uint8_t buf_get1(buf_impl* buf, int offset)
return 0; return 0;
} }
static uint16_t buf_get2_le(buf_impl* buf, int offset) { static void buf_set1(buf_impl* buf, const size_t offset, const uint8_t data)
{
if (offset < buf->len) {
buf->buf[offset] = data;
}
}
static void buf_set2_le(buf_impl* buf, const size_t offset, const uint16_t data)
{
if ((offset >= 0) && (offset < buf->len - 1)) {
buf->buf[offset] = data & 0xFF;
buf->buf[offset+1] = data >> 8;
}
}
static void buf_set2_be(buf_impl* buf, const size_t offset, const uint16_t data)
{
if ((offset >= 0) && (offset < buf->len - 1)) {
buf->buf[offset+1] = data & 0xFF;
buf->buf[offset] = data >> 8;
}
}
static uint16_t buf_get2_le(buf_impl* buf, int offset)
{
if ((offset >= 0) && (offset < buf->len - 1)) { if ((offset >= 0) && (offset < buf->len - 1)) {
return buf->buf[offset] | (buf->buf[offset+1] << 8); return buf->buf[offset] | (buf->buf[offset+1] << 8);
} }
@ -135,6 +153,26 @@ static uint16_t buf_get2_be(buf_impl* buf, int offset)
return 0; return 0;
} }
static void buf_set4_le(buf_impl* buf, const size_t offset, const uint32_t data)
{
if ((offset >= 0) && (offset < buf->len - 3)) {
buf->buf[offset] = data & 0xFF;
buf->buf[offset+1] = (data >> 8) & 0xFF;
buf->buf[offset+2] = (data >> 16) & 0xFF;
buf->buf[offset+3] = data >> 24;
}
}
static void buf_set4_be(buf_impl* buf, const size_t offset, const uint32_t data)
{
if ((offset >= 0) && (offset < buf->len - 3)) {
buf->buf[offset+3] = data & 0xFF;
buf->buf[offset+2] = (data >> 8) & 0xFF;
buf->buf[offset+1] = (data >> 16) & 0xFF;
buf->buf[offset] = data >> 24;
}
}
static uint32_t buf_get4_le(buf_impl* buf, int offset) static uint32_t buf_get4_le(buf_impl* buf, int offset)
{ {
if ((offset >= 0) && (offset < buf->len - 3)) { if ((offset >= 0) && (offset < buf->len - 3)) {
@ -383,13 +421,13 @@ static int m_add(bvm *vm)
/* /*
* Get an int made of 1, 2 or 4 bytes, in little or big endian * Get an int made of 1, 2 or 4 bytes, in little or big endian
* `get(index:int[, size:int = 1]) -> instance` * `get(index:int[, size:int = 1]) -> int`
* *
* size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian) * size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
* obvisouly -1 is idntical to 1 * obvisouly -1 is identical to 1
* 0 returns nil * 0 returns nil
*/ */
static int m_get(bvm *vm) static int m_get(bvm *vm, bbool sign)
{ {
int argc = be_top(vm); int argc = be_top(vm);
buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */ buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
@ -403,10 +441,16 @@ static int m_get(bvm *vm)
switch (vsize) { switch (vsize) {
case 0: break; case 0: break;
case -1: /* fallback below */ case -1: /* fallback below */
case 1: ret = buf_get1(buf, idx); break; case 1: ret = buf_get1(buf, idx);
case 2: ret = buf_get2_le(buf, idx); break; if (sign) { ret = (int8_t)(uint8_t) ret; }
break;
case 2: ret = buf_get2_le(buf, idx);
if (sign) { ret = (int16_t)(uint16_t) ret; }
break;
case 4: ret = buf_get4_le(buf, idx); break; case 4: ret = buf_get4_le(buf, idx); break;
case -2: ret = buf_get2_be(buf, idx); break; case -2: ret = buf_get2_be(buf, idx);
if (sign) { ret = (int16_t)(uint16_t) ret; }
break;
case -4: ret = buf_get4_be(buf, idx); break; case -4: ret = buf_get4_be(buf, idx); break;
default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4."); default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
} }
@ -421,6 +465,53 @@ static int m_get(bvm *vm)
be_return_nil(vm); be_return_nil(vm);
} }
/* signed int */
static int m_geti(bvm *vm)
{
return m_get(vm, 1);
}
/* unsigned int */
static int m_getu(bvm *vm)
{
return m_get(vm, 0);
}
/*
* Set an int made of 1, 2 or 4 bytes, in little or big endian
* `set(index:int, value:int[, size:int = 1]) -> nil`
*
* size: may be 1, 2, 4 (little endian), or -1, -2, -4 (big endian)
* obvisouly -1 is identical to 1
* 0 returns nil
*/
static int m_set(bvm *vm)
{
int argc = be_top(vm);
buf_impl * buf = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
if (argc >=3 && be_isint(vm, 2) && be_isint(vm, 3)) {
int32_t idx = be_toint(vm, 2);
int32_t value = be_toint(vm, 3);
int vsize = 1;
if (argc >= 4 && be_isint(vm, 4)) {
vsize = be_toint(vm, 4);
}
switch (vsize) {
case 0: break;
case -1: /* fallback below */
case 1: buf_set1(buf, idx, value); break;
case 2: buf_set2_le(buf, idx, value); break;
case 4: buf_set4_le(buf, idx, value); break;
case -2: buf_set2_be(buf, idx, value); break;
case -4: buf_set4_be(buf, idx, value); break;
default: be_raise(vm, "type_error", "size must be -4, -2, -1, 0, 1, 2 or 4.");
}
be_pop(vm, argc - 1);
be_return_nil(vm);
}
be_return_nil(vm);
}
static int m_setitem(bvm *vm) static int m_setitem(bvm *vm)
{ {
int argc = be_top(vm); int argc = be_top(vm);
@ -608,6 +699,26 @@ static int m_nequal(bvm *vm)
return bytes_equal(vm, bfalse); return bytes_equal(vm, bfalse);
} }
/*
* Advanced API
*/
/*
* Retrieve the memory address of the raw buffer
* to be used in C functions.
*
* Note: the address is guaranteed not to move unless you
* resize the buffer
*
* `_buffer() -> comptr`
*/
static int m_buffer(bvm *vm)
{
buf_impl * buf = bytes_check_data(vm, 0);
be_pushcomptr(vm, &buf->buf);
be_return(vm);
}
/* /*
* External API * External API
*/ */
@ -642,17 +753,219 @@ BERRY_API const void *be_tobytes(bvm *vm, int rel_index, size_t *len)
return NULL; return NULL;
} }
/* Helper code to compile bytecode
class Bytes : bytes
#-------------------------------------------------------------
#- 'getbits' function
#-
#- Reads a bit-field in a `bytes()` object
#-
#- Input:
#- 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)
#-------------------------------------------------------------#
def getbits(offset_bits, len_bits)
if len_bits <= 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
var ret = 0
var offset_bytes = offset_bits >> 3
offset_bits = offset_bits % 8
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
ret = ret | ( ((self[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
#-------------------------------------------------------------
#- 'setbits' function
#-
#- Writes a bit-field in a `bytes()` object
#-
#- Input:
#- 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)
#-------------------------------------------------------------#
def setbits(offset_bits, len_bits, val)
if len_bits < 0 || len_bits > 32 raise "value_error", "length in bits must be between 0 and 32" end
var offset_bytes = offset_bits >> 3
offset_bits = offset_bits % 8
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)
self[offset_bytes] = (self[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 self
end
end
*/
/********************************************************************
** Solidified function: getbits
********************************************************************/
be_local_closure(getbits, /* name */
be_nested_proto(
9, /* nstack */
3, /* argc */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 5]) { /* constants */
{ { .i=0 }, BE_INT},
{ { .s=be_nested_const_str("value_error", 773297791, 11) }, BE_STRING},
{ { .s=be_nested_const_str("length in bits must be between 0 and 32", -1710458168, 39) }, BE_STRING},
{ { .i=3 }, BE_INT},
{ { .i=1 }, BE_INT},
}),
(be_nested_const_str("getbits", -1200798317, 7)),
(be_nested_const_str("stdin", -1529146723, 5)),
( &(const binstruction[32]) { /* code */
0x180C0500, // 0000 LE R3 R2 R256
0x740E0002, // 0001 JMPT R3 #0005
0x540E001F, // 0002 LDINT R3 32
0x240C0403, // 0003 GT R3 R2 R3
0x780E0000, // 0004 JMPF R3 #0006
0xB0060302, // 0005 RAISE 1 R257 R258
0x580C0000, // 0006 LDCONST R3 K0
0x3C100303, // 0007 SHR R4 R1 R259
0x54160007, // 0008 LDINT R5 8
0x10040205, // 0009 MOD R1 R1 R5
0x58140000, // 000A LDCONST R5 K0
0x24180500, // 000B GT R6 R2 R256
0x781A0011, // 000C JMPF R6 #001F
0x541A0007, // 000D LDINT R6 8
0x04180C01, // 000E SUB R6 R6 R1
0x241C0C02, // 000F GT R7 R6 R2
0x781E0000, // 0010 JMPF R7 #0012
0x5C180400, // 0011 MOVE R6 R2
0x381E0806, // 0012 SHL R7 R260 R6
0x041C0F04, // 0013 SUB R7 R7 R260
0x381C0E01, // 0014 SHL R7 R7 R1
0x94200004, // 0015 GETIDX R8 R0 R4
0x2C201007, // 0016 AND R8 R8 R7
0x3C201001, // 0017 SHR R8 R8 R1
0x38201005, // 0018 SHL R8 R8 R5
0x300C0608, // 0019 OR R3 R3 R8
0x00140A06, // 001A ADD R5 R5 R6
0x04080406, // 001B SUB R2 R2 R6
0x58040000, // 001C LDCONST R1 K0
0x00100904, // 001D ADD R4 R4 R260
0x7001FFEB, // 001E JMP #000B
0x80040600, // 001F RET 1 R3
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: setbits
********************************************************************/
be_local_closure(setbits, /* name */
be_nested_proto(
10, /* nstack */
4, /* argc */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 5]) { /* constants */
{ { .i=0 }, BE_INT},
{ { .s=be_nested_const_str("value_error", 773297791, 11) }, BE_STRING},
{ { .s=be_nested_const_str("length in bits must be between 0 and 32", -1710458168, 39) }, BE_STRING},
{ { .i=3 }, BE_INT},
{ { .i=1 }, BE_INT},
}),
(be_nested_const_str("setbits", -1532559129, 7)),
(be_nested_const_str("stdin", -1529146723, 5)),
( &(const binstruction[33]) { /* code */
0x14100500, // 0000 LT R4 R2 R256
0x74120002, // 0001 JMPT R4 #0005
0x5412001F, // 0002 LDINT R4 32
0x24100404, // 0003 GT R4 R2 R4
0x78120000, // 0004 JMPF R4 #0006
0xB0060302, // 0005 RAISE 1 R257 R258
0x3C100303, // 0006 SHR R4 R1 R259
0x54160007, // 0007 LDINT R5 8
0x10040205, // 0008 MOD R1 R1 R5
0x24140500, // 0009 GT R5 R2 R256
0x78160014, // 000A JMPF R5 #0020
0x54160007, // 000B LDINT R5 8
0x04140A01, // 000C SUB R5 R5 R1
0x24180A02, // 000D GT R6 R5 R2
0x781A0000, // 000E JMPF R6 #0010
0x5C140400, // 000F MOVE R5 R2
0x381A0805, // 0010 SHL R6 R260 R5
0x04180D04, // 0011 SUB R6 R6 R260
0x541E00FE, // 0012 LDINT R7 255
0x38200C01, // 0013 SHL R8 R6 R1
0x041C0E08, // 0014 SUB R7 R7 R8
0x94200004, // 0015 GETIDX R8 R0 R4
0x2C201007, // 0016 AND R8 R8 R7
0x2C240606, // 0017 AND R9 R3 R6
0x38241201, // 0018 SHL R9 R9 R1
0x30201009, // 0019 OR R8 R8 R9
0x98000808, // 001A SETIDX R0 R4 R8
0x3C0C0605, // 001B SHR R3 R3 R5
0x04080405, // 001C SUB R2 R2 R5
0x58040000, // 001D LDCONST R1 K0
0x00100904, // 001E ADD R4 R4 R260
0x7001FFE8, // 001F JMP #0009
0x80040000, // 0020 RET 1 R0
})
)
);
/*******************************************************************/
#if !BE_USE_PRECOMPILED_OBJECT #if !BE_USE_PRECOMPILED_OBJECT
void be_load_byteslib(bvm *vm) void be_load_byteslib(bvm *vm)
{ {
static const bnfuncinfo members[] = { static const bnfuncinfo members[] = {
{ ".p", NULL }, { ".p", NULL },
{ "_buffer", m_buffer },
{ "init", m_init }, { "init", m_init },
{ "tostring", m_tostring }, { "tostring", m_tostring },
{ "asstring", m_asstring }, { "asstring", m_asstring },
{ "fromstring", m_fromstring }, { "fromstring", m_fromstring },
{ "add", m_add }, { "add", m_add },
{ "get", m_get }, { "get", m_getu },
{ "geti", m_geti },
{ "set", m_set },
{ "item", m_item }, { "item", m_item },
{ "setitem", m_setitem }, { "setitem", m_setitem },
{ "size", m_size }, { "size", m_size },
@ -663,6 +976,11 @@ void be_load_byteslib(bvm *vm)
{ "..", m_connect }, { "..", m_connect },
{ "==", m_equal }, { "==", m_equal },
{ "!=", m_nequal }, { "!=", m_nequal },
{ NULL, (bntvfunc) BE_CLOSURE }, /* mark section for berry closures */
{ "getbits", (bntvfunc) &getbits_closure },
{ "setbits", (bntvfunc) &setbits_closure },
{ NULL, NULL } { NULL, NULL }
}; };
be_regclass(vm, "bytes", members); be_regclass(vm, "bytes", members);
@ -671,12 +989,15 @@ void be_load_byteslib(bvm *vm)
/* @const_object_info_begin /* @const_object_info_begin
class be_class_bytes (scope: global, name: bytes) { class be_class_bytes (scope: global, name: bytes) {
.p, var .p, var
_buffer, func(m_buffer)
init, func(m_init) init, func(m_init)
tostring, func(m_tostring) tostring, func(m_tostring)
asstring, func(m_asstring) asstring, func(m_asstring)
fromstring, func(m_fromstring) fromstring, func(m_fromstring)
add, func(m_add) add, func(m_add)
get, func(m_get) get, func(m_getu)
geti, func(m_geti)
set, func(m_set)
item, func(m_item) item, func(m_item)
setitem, func(m_setitem) setitem, func(m_setitem)
size, func(m_size) size, func(m_size)
@ -687,6 +1008,9 @@ class be_class_bytes (scope: global, name: bytes) {
.., func(m_connect) .., func(m_connect)
==, func(m_equal) ==, func(m_equal)
!=, func(m_nequal) !=, func(m_nequal)
getbits, closure(getbits_closure)
setbits, closure(setbits_closure)
} }
@const_object_info_end */ @const_object_info_end */
#include "../generate/be_fixed_be_class_bytes.h" #include "../generate/be_fixed_be_class_bytes.h"

View File

@ -122,7 +122,7 @@ static void m_solidify_proto(bvm *vm, bproto *pr, const char * func_name, int bu
logfmt("%*s( &(const binstruction[%2d]) { /* code */\n", indent, "", pr->codesize); logfmt("%*s( &(const binstruction[%2d]) { /* code */\n", indent, "", pr->codesize);
for (int pc = 0; pc < pr->codesize; pc++) { for (int pc = 0; pc < pr->codesize; pc++) {
uint32_t ins = pr->code[pc]; uint32_t ins = pr->code[pc];
logfmt("%*s 0x%04X, //", indent, "", ins); logfmt("%*s 0x%08X, //", indent, "", ins);
be_print_inst(ins, pc); be_print_inst(ins, pc);
bopcode op = IGET_OP(ins); bopcode op = IGET_OP(ins);
if (op == OP_GETGBL || op == OP_SETGBL) { if (op == OP_GETGBL || op == OP_SETGBL) {

View File

@ -165,3 +165,33 @@ assert(str(b) =="bytes('416130')")
b=bytes() b=bytes()
b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") b.fromstring("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')") assert(str(b) =="bytes('4C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742C2073656420646F20656975736D6F642074656D706F7220696E6369646964756E74207574206C61626F726520657420646F6C6F7265206D61676E6120616C697175612E')")
#- setters -#
b=bytes().resize(16)
b.set(5,-1,2)
assert(b == bytes('0000000000FFFF000000000000000000'))
b.set(10,-2,4)
assert(b == bytes('0000000000FFFF000000FEFFFFFF0000'))
b.set(0,0xAA55,1)
assert(b == bytes('5500000000FFFF000000FEFFFFFF0000'))
#- getbits -#
b=bytes("00AAFF55010300")
assert(b.getbits(8,8) == 0xAA)
assert(b.getbits(0,1) == 0)
assert(b.getbits(8,1) == 0)
assert(b.getbits(9,1) == 1)
assert(b.getbits(16,8) == 0xFF)
assert(b.getbits(16,16) == 0x55FF)
assert(b.getbits(16,24) == 0x0155FF)
assert(b.getbits(16,32) == 0x030155FF)
assert(b.getbits(20,8) == 0x5F)
#- setbits -#
b=bytes("00000000FFFFFFFF")
assert(b.setbits(0,1,1) == bytes('01000000FFFFFFFF'))
assert(b.setbits(1,1,1) == bytes('03000000FFFFFFFF'))
assert(b.setbits(0,1,0) == bytes('02000000FFFFFFFF'))
assert(b.setbits(12,16,0xAA55) == bytes('0250A50AFFFFFFFF'))
assert(b.setbits(63,0,0) == bytes('0250A50AFFFFFFFF'))
assert(b.setbits(63,1,0) == bytes('0250A50AFFFFFF7F'))

View File

@ -0,0 +1,563 @@
#-------------------------------------------------------------
#- 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
# 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
#-------------------------------------------------------------
#- '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("enum {")
print(" ctypes_ptr = 0,")
print(" ctypes_uint = 1,")
print(" ctypes_int = 2,")
print(" ctypes_str = 3,")
print("};")
print()
print("typedef struct be_ctypes_structure_t {")
print(" const char * name;")
print(" uint16_t offset_bits;")
print(" uint16_t len_bits : 13;")
print(" uint16_t type : 3;")
print("} be_ctypes_structure_t;")
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
if name != nil
print(string.format("const be_ctypes_structure_t be_%s[%d] = {", name, 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, %s },", n, args[0], args[1], args[2]))
end
print("};")
print()
end
# clear any outstanding bitfield
self.align(1)
self.size_bytes = self.cur_offset
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)
elif type(type_obj) == 'int'
# TODO check actual type
if type_obj > ctypes.bf_0
# bit field
self.get_bitfield_closure(name, type_obj - ctypes.bf_0)
else
# multi-bytes
self.get_int_closure(name, type_obj)
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
#- 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
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
# inlcude nested
for subname:type_obj.mapping.keys()
var val = type_obj.mapping[subname]
self.mapping[name+"_"+subname] = [val[0] + (offset << 3), val[1], val[2]]
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, size_in_bytes_le_be) # can be 1/2/4
#- abs size -#
var size_in_bytes = size_in_bytes_le_be < 0 ? - size_in_bytes_le_be : size_in_bytes_le_be
var signed = size_in_bytes > 10
size_in_bytes_le_be = size_in_bytes_le_be % 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 << 3, size_in_bytes_le_be << 3, signed ? "ctypes_int" : "ctypes_uint"]
#- 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_bitfield_closure(name, size_in_bits) # 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] = [bit_offset + (cur_offset << 3), size_in_bits, "ctypes_uint"]
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 += size_in_bits / 8
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
-#
# def get_bits(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 wrtie to
# while (len_bits > 0)
# var block_bits = 8 - offset_bits # bit number to read in 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
# Test
# b=bytes("AAFF10")
# assert(get_bits(b, 0, 0, 1) == 0)
# assert(get_bits(b, 0, 1, 1) == 1)
# assert(get_bits(b, 0, 2, 1) == 0)
# assert(get_bits(b, 0, 3, 1) == 1)
# assert(get_bits(b, 0, 0, 2) == 2)
# assert(get_bits(b, 0, 1, 2) == 1)
# assert(get_bits(b, 0, 2, 2) == 2)
# assert(get_bits(b, 0, 0, 8) == 0xAA)
# assert(get_bits(b, 0, 0, 10) == 0x3AA)
# assert(get_bits(b, 0, 2, 8) == 0xEA)
# assert(get_bits(b, 1, 0, 8) == 0xFF)
# assert(get_bits(b, 1, 0, 10) == 0x0FF)
# assert(get_bits(b, 1, 0, 16) == 0x10FF)
# assert(get_bits(b, 1, 7, 4) == 0x01)
# assert(get_bits(b, 1, 7, 6) == 0x21)
# def set_bits(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
# b=bytes("00000000")
# assert(set_bits(b,0,0,1,1) == bytes('01000000'))
# assert(set_bits(b,1,0,1,1) == bytes('01010000'))
# assert(set_bits(b,0,0,1,2) == bytes('00010000'))
# assert(set_bits(b,0,4,1,1) == bytes('10010000'))
# assert(set_bits(b,0,4,1,0) == bytes('00010000'))
# b=bytes("FF000000")
# assert(set_bits(b,0,4,1,0) == bytes('EF000000'))
# assert(set_bits(b,0,4,1,1) == bytes('FF000000'))
# b=bytes("00000000")
# assert(set_bits(b,2,6,1,-1) == bytes('00004000'))
# b=bytes("00000000")
# assert(set_bits(b,2,1,6,-1) == bytes('00007E00'))

View File

@ -0,0 +1,315 @@
#
# ctype buidings for LVGL
#
# To generate C bindings, do:
# > compile("lvgl_ctypes.be","file")()
#
# and copy/paste output in C format
#
import ctypes
ctypes.print_types()
lv_style_int_t = ctypes.i16
lv_color_t = ctypes.u16 # depends on colors
lv_grad_dir_t = ctypes.u8
lv_opa_t = ctypes.u8
lv_blend_mode_t = ctypes.u8
lv_align_t = ctypes.u8
lv_coord_t = ctypes.i16
lv_bidi_dir_t = ctypes.u8
lv_txt_flag_t = ctypes.u8
lv_text_decor_t = ctypes.u8
lv_font_t = ctypes.u32
uint8_t_1 = ctypes.bf_1
uint8_t_2 = ctypes.bf_2
uint8_t = ctypes.u8
uint16_t = ctypes.u16
uint32_t = ctypes.u32
int32_t = ctypes.i32
ptr = ctypes.u32
lv_point_t = [
[lv_coord_t, "x"],
[lv_coord_t, "y"],
]
lv_point_t = ctypes.structure(lv_point_t, "lv_point_t")
lv_area_t = [
[lv_coord_t, "x1"],
[lv_coord_t, "y1"],
[lv_coord_t, "x2"],
[lv_coord_t, "y2"],
]
lv_area_t = ctypes.structure(lv_area_t, "lv_area_t")
test_t = [
[lv_area_t, "a"],
[lv_area_t, "b"]
]
test_t = ctypes.structure(test_t, "test_t")
lv_draw_rect_dsc_t = [
[lv_style_int_t, "radius"],
#/*Background*/
[lv_color_t, "bg_color"],
[lv_color_t, "bg_grad_color"],
[lv_grad_dir_t, "bg_grad_dir"],
[lv_style_int_t, "bg_main_color_stop"],
[lv_style_int_t, "bg_grad_color_stop"],
[lv_opa_t, "bg_opa"],
[lv_blend_mode_t, "bg_blend_mode"],
#/*Border*/
[lv_color_t, "border_color"],
[lv_style_int_t, "border_width"],
[lv_style_int_t, "border_side"],
[lv_opa_t, "border_opa"],
[lv_blend_mode_t, "border_blend_mode"],
[uint8_t_1, "border_post"],
#/*Outline*/
[lv_color_t, "outline_color"],
[lv_style_int_t, "outline_width"],
[lv_style_int_t, "outline_pad"],
[lv_opa_t, "outline_opa"],
[lv_blend_mode_t, "outline_blend_mode"],
#/*Shadow*/
[lv_color_t, "shadow_color"],
[lv_style_int_t, "shadow_width"],
[lv_style_int_t, "shadow_ofs_x"],
[lv_style_int_t, "shadow_ofs_y"],
[lv_style_int_t, "shadow_spread"],
[lv_opa_t, "shadow_opa"],
[lv_blend_mode_t, "shadow_blend_mode"],
#/*Pattern*/
[ptr, "pattern_image"],
[ptr, "pattern_font"],
[lv_color_t, "pattern_recolor"],
[lv_opa_t, "pattern_opa"],
[lv_opa_t, "pattern_recolor_opa"],
[uint8_t_1, "pattern_repeat"],
[lv_blend_mode_t, "pattern_blend_mode"],
#/*Value*/
[ptr, "value_str"],
[ptr, "value_font"],
[lv_opa_t, "value_opa"],
[lv_color_t, "value_color"],
[lv_style_int_t, "value_ofs_x"],
[lv_style_int_t, "value_ofs_y"],
[lv_style_int_t, "value_letter_space"],
[lv_style_int_t, "value_line_space"],
[lv_align_t, "value_align"],
[lv_blend_mode_t, "value_blend_mode"],
]
lv_draw_rect_dsc_t = ctypes.structure(lv_draw_rect_dsc_t, "lv_draw_rect_dsc_t")
lv_draw_line_dsc_t = [
[lv_color_t, "color"],
[lv_style_int_t, "width"],
[lv_style_int_t, "dash_width"],
[lv_style_int_t, "dash_gap"],
[lv_opa_t, "opa"],
[uint8_t_2, "blend_mode"],
[uint8_t_1, "round_start"],
[uint8_t_1, "round_end"],
[uint8_t_1, "raw_end"],
]
lv_draw_line_dsc_t = ctypes.structure(lv_draw_line_dsc_t, "lv_draw_line_dsc_t")
lv_draw_img_dsc_t = [
[lv_opa_t, "opa"],
[uint16_t, "angle"],
[lv_point_t, "pivot"],
[uint16_t, "zoom"],
[lv_opa_t, "recolor_opa"],
[lv_color_t, "recolor"],
[lv_blend_mode_t, "blend_mode"],
[uint8_t_1, "antialias"],
]
lv_draw_img_dsc_t = ctypes.structure(lv_draw_img_dsc_t, "lv_draw_img_dsc_t")
lv_draw_label_dsc_t = [
[lv_color_t, "color"],
[lv_color_t, "sel_color"],
[lv_color_t, "sel_bg_color"],
[lv_font_t, "font"],
[lv_opa_t, "opa"],
[lv_style_int_t, "line_space"],
[lv_style_int_t, "letter_space"],
[uint32_t, "sel_start"],
[uint32_t, "sel_end"],
[lv_coord_t, "ofs_x"],
[lv_coord_t, "ofs_y"],
[lv_bidi_dir_t, "bidi_dir"],
[lv_txt_flag_t, "flag"],
[lv_text_decor_t, "decor"],
[lv_blend_mode_t, "blend_mode"],
]
lv_draw_label_dsc_t = ctypes.structure(lv_draw_label_dsc_t, "lv_draw_label_dsc_t")
#- --------- lv_mask --------- -#
lv_draw_mask_xcb_t = ptr # callback
lv_draw_mask_type_t = ctypes.u8
lv_draw_mask_line_side_t = ctypes.u8
lv_draw_mask_common_dsc_t = [
[lv_draw_mask_xcb_t, "cb"],
[lv_draw_mask_type_t, "type"],
]
lv_draw_mask_common_dsc_t = ctypes.structure(lv_draw_mask_common_dsc_t, "lv_draw_mask_common_dsc_t")
lv_draw_mask_line_param_cfg_t = [
#/*First point */
[lv_point_t, "p1"],
#/*Second point*/
[lv_point_t, "p2"],
#/*Which side to keep?*/
[uint8_t_2, "side"],
]
lv_draw_mask_line_param_cfg_t = ctypes.structure(lv_draw_mask_line_param_cfg_t, "lv_draw_mask_line_param_cfg_t")
lv_draw_mask_line_param_t = [
#/*The first element must be the common descriptor*/
[lv_draw_mask_common_dsc_t, "dsc"],
[lv_draw_mask_line_param_cfg_t, "cfg"],
#/*A point of the line*/
[lv_point_t, "origo"],
#/* X / (1024*Y) steepness (X is 0..1023 range). What is the change of X in 1024 Y?*/
[int32_t, "xy_steep"],
#/* Y / (1024*X) steepness (Y is 0..1023 range). What is the change of Y in 1024 X?*/
[int32_t, "yx_steep"],
#/*Helper which stores yx_steep for flat lines and xy_steep for steep (non flat) lines */
[int32_t, "steep"],
#/*Steepness in 1 px in 0..255 range. Used only by flat lines. */
[int32_t, "spx"],
#/*1: It's a flat line? (Near to horizontal)*/
[uint8_t_1, "flat"],
#/* Invert the mask. The default is: Keep the left part.
# * It is used to select left/right/top/bottom*/
[uint8_t_1, "inv"],
]
lv_draw_mask_line_param_t = ctypes.structure(lv_draw_mask_line_param_t, "lv_draw_mask_line_param_t")
lv_draw_mask_angle_param_cfg_t = [
[lv_point_t, "vertex_p"],
[lv_coord_t, "start_angle"],
[lv_coord_t, "end_angle"],
]
lv_draw_mask_angle_param_cfg_t = ctypes.structure(lv_draw_mask_angle_param_cfg_t, "lv_draw_mask_angle_param_cfg_t")
lv_draw_mask_angle_param_t = [
#/*The first element must be the common descriptor*/
[lv_draw_mask_common_dsc_t, "dsc"],
[lv_draw_mask_angle_param_cfg_t, "cfg"],
[lv_draw_mask_line_param_t, "start_line"],
[lv_draw_mask_line_param_t, "end_line"],
[uint16_t, "delta_deg"],
]
lv_draw_mask_angle_param_t = ctypes.structure(lv_draw_mask_angle_param_t, "lv_draw_mask_angle_param_t")
lv_draw_mask_radius_param_cfg_t = [
[lv_area_t, "rect"],
[lv_coord_t, "radius"],
[uint8_t_1, "outer"],
]
lv_draw_mask_radius_param_cfg_t = ctypes.structure(lv_draw_mask_radius_param_cfg_t, "lv_draw_mask_radius_param_cfg_t")
lv_sqrt_res_t = [
[uint16_t, "i"],
[uint16_t, "f"],
]
lv_sqrt_res_t = ctypes.structure(lv_sqrt_res_t, "lv_sqrt_res_t")
lv_draw_mask_radius_param_t = [
#/*The first element must be the common descriptor*/
[lv_draw_mask_common_dsc_t, "dsc"],
[lv_draw_mask_radius_param_cfg_t, "cfg"],
[int32_t, "y_prev"],
[lv_sqrt_res_t, "y_prev_x"],
]
lv_draw_mask_radius_param_t = ctypes.structure(lv_draw_mask_radius_param_t, "lv_draw_mask_radius_param_t")
lv_draw_mask_fade_param_cfg_t = [
[lv_area_t, "coords"],
[lv_coord_t, "y_top"],
[lv_coord_t, "y_bottom"],
[lv_opa_t, "opa_top"],
[lv_opa_t, "opa_bottom"],
]
lv_draw_mask_fade_param_cfg_t = ctypes.structure(lv_draw_mask_fade_param_cfg_t, "lv_draw_mask_fade_param_cfg_t")
lv_draw_mask_fade_param_t = [
# /*The first element must be the common descriptor*/
[lv_draw_mask_common_dsc_t, "dsc"],
[lv_draw_mask_fade_param_cfg_t, "cfg"],
]
lv_draw_mask_fade_param_t = ctypes.structure(lv_draw_mask_fade_param_t, "lv_draw_mask_fade_param_t")
lv_draw_mask_map_param_cfg_t = [
[lv_area_t, "coords"],
[ptr, "map"],
]
lv_draw_mask_map_param_cfg_t = ctypes.structure(lv_draw_mask_map_param_cfg_t, "lv_draw_mask_map_param_cfg_t")
lv_draw_mask_map_param_t = [
#/*The first element must be the common descriptor*/
[lv_draw_mask_common_dsc_t, "dsc"],
[lv_draw_mask_map_param_cfg_t, "cfg"],
]
lv_draw_mask_map_param_t = ctypes.structure(lv_draw_mask_map_param_t, "lv_draw_mask_map_param_t")
lv_draw_mask_saved_t = [
[ptr, "param"],
[ptr, "custom_id"],
]
lv_draw_mask_saved_t = ctypes.structure(lv_draw_mask_saved_t, "lv_draw_mask_saved_t")
# Ex:
# bb = ctypes.buffer(test_t, bytes("0101020203030404FFFFFEFEFCFC8080"))
# Ex:
# bb = ctypes.buffer(lv_draw_rect)
#- Ex
bb=ctypes.buffer(lv_draw_line_dsc_t)
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_t = [
[lv_color_t, "color"],
[lv_style_int_t, "width"],
[lv_style_int_t, "dash_width"],
[lv_style_int_t, "dash_gap"],
[lv_opa_t, "opa"],
[uint8_t_2, "blend_mode"],
[uint8_t_1, "round_start"],
[uint8_t_1, "round_end"],
[uint8_t_1, "raw_end"],
]
-#

View File

@ -0,0 +1,318 @@
/*
xdrv_52_3_berry_native.ino - Berry scripting language, native fucnctions
Copyright (C) 2021 Stephan Hadinger, Berry language by Guan Wenliang https://github.com/Skiars/berry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_BERRY
#ifdef USE_LVGL
#include <berry.h>
#include "lvgl.h"
#include "be_lvgl.h"
// Berry easy logging
extern "C" {
extern void berry_log_C(const char * berry_buf, ...);
}
/********************************************************************
* Generated code, don't edit
*******************************************************************/
enum {
ctypes_ptr = 0,
ctypes_uint = 1,
ctypes_int = 2,
ctypes_str = 3,
};
typedef struct be_ctypes_structure_t {
const char * name;
uint16_t offset_bits;
uint16_t len_bits : 13;
uint16_t type : 3;
} be_ctypes_structure_t;
const be_ctypes_structure_t be_lv_point_t[2] = {
{ "x", 0, 16, ctypes_int },
{ "y", 16, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_area_t[4] = {
{ "x1", 0, 16, ctypes_int },
{ "x2", 32, 16, ctypes_int },
{ "y1", 16, 16, ctypes_int },
{ "y2", 48, 16, ctypes_int },
};
const be_ctypes_structure_t be_test_t[8] = {
{ "a_x1", 0, 16, ctypes_int },
{ "a_x2", 32, 16, ctypes_int },
{ "a_y1", 16, 16, ctypes_int },
{ "a_y2", 48, 16, ctypes_int },
{ "b_x1", 64, 16, ctypes_int },
{ "b_x2", 96, 16, ctypes_int },
{ "b_y1", 80, 16, ctypes_int },
{ "b_y2", 112, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_rect_dsc_t[43] = {
{ "bg_blend_mode", 96, 8, ctypes_uint },
{ "bg_color", 16, 16, ctypes_uint },
{ "bg_grad_color", 32, 16, ctypes_uint },
{ "bg_grad_color_stop", 72, 16, ctypes_int },
{ "bg_grad_dir", 48, 8, ctypes_uint },
{ "bg_main_color_stop", 56, 16, ctypes_int },
{ "bg_opa", 88, 8, ctypes_uint },
{ "border_blend_mode", 160, 8, ctypes_uint },
{ "border_color", 104, 16, ctypes_uint },
{ "border_opa", 152, 8, ctypes_uint },
{ "border_post", 168, 1, ctypes_uint },
{ "border_side", 136, 16, ctypes_int },
{ "border_width", 120, 16, ctypes_int },
{ "outline_blend_mode", 232, 8, ctypes_uint },
{ "outline_color", 176, 16, ctypes_uint },
{ "outline_opa", 224, 8, ctypes_uint },
{ "outline_pad", 208, 16, ctypes_int },
{ "outline_width", 192, 16, ctypes_int },
{ "pattern_blend_mode", 440, 8, ctypes_uint },
{ "pattern_font", 368, 32, ctypes_uint },
{ "pattern_image", 336, 32, ctypes_uint },
{ "pattern_opa", 416, 8, ctypes_uint },
{ "pattern_recolor", 400, 16, ctypes_uint },
{ "pattern_recolor_opa", 424, 8, ctypes_uint },
{ "pattern_repeat", 432, 1, ctypes_uint },
{ "radius", 0, 16, ctypes_int },
{ "shadow_blend_mode", 328, 8, ctypes_uint },
{ "shadow_color", 240, 16, ctypes_uint },
{ "shadow_ofs_x", 272, 16, ctypes_int },
{ "shadow_ofs_y", 288, 16, ctypes_int },
{ "shadow_opa", 320, 8, ctypes_uint },
{ "shadow_spread", 304, 16, ctypes_int },
{ "shadow_width", 256, 16, ctypes_int },
{ "value_align", 600, 8, ctypes_uint },
{ "value_blend_mode", 608, 8, ctypes_uint },
{ "value_color", 520, 16, ctypes_uint },
{ "value_font", 480, 32, ctypes_uint },
{ "value_letter_space", 568, 16, ctypes_int },
{ "value_line_space", 584, 16, ctypes_int },
{ "value_ofs_x", 536, 16, ctypes_int },
{ "value_ofs_y", 552, 16, ctypes_int },
{ "value_opa", 512, 8, ctypes_uint },
{ "value_str", 448, 32, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_line_dsc_t[9] = {
{ "blend_mode", 72, 2, ctypes_uint },
{ "color", 0, 16, ctypes_uint },
{ "dash_gap", 48, 16, ctypes_int },
{ "dash_width", 32, 16, ctypes_int },
{ "opa", 64, 8, ctypes_uint },
{ "raw_end", 76, 1, ctypes_uint },
{ "round_end", 75, 1, ctypes_uint },
{ "round_start", 74, 1, ctypes_uint },
{ "width", 16, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_img_dsc_t[9] = {
{ "angle", 8, 16, ctypes_uint },
{ "antialias", 104, 1, ctypes_uint },
{ "blend_mode", 96, 8, ctypes_uint },
{ "opa", 0, 8, ctypes_uint },
{ "pivot_x", 24, 16, ctypes_int },
{ "pivot_y", 40, 16, ctypes_int },
{ "recolor", 80, 16, ctypes_uint },
{ "recolor_opa", 72, 8, ctypes_uint },
{ "zoom", 56, 16, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_label_dsc_t[15] = {
{ "bidi_dir", 216, 8, ctypes_uint },
{ "blend_mode", 240, 8, ctypes_uint },
{ "color", 0, 16, ctypes_uint },
{ "decor", 232, 8, ctypes_uint },
{ "flag", 224, 8, ctypes_uint },
{ "font", 48, 32, ctypes_uint },
{ "letter_space", 104, 16, ctypes_int },
{ "line_space", 88, 16, ctypes_int },
{ "ofs_x", 184, 16, ctypes_int },
{ "ofs_y", 200, 16, ctypes_int },
{ "opa", 80, 8, ctypes_uint },
{ "sel_bg_color", 32, 16, ctypes_uint },
{ "sel_color", 16, 16, ctypes_uint },
{ "sel_end", 152, 32, ctypes_uint },
{ "sel_start", 120, 32, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_common_dsc_t[2] = {
{ "cb", 0, 32, ctypes_uint },
{ "type", 32, 8, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_line_param_cfg_t[5] = {
{ "p1_x", 0, 16, ctypes_int },
{ "p1_y", 16, 16, ctypes_int },
{ "p2_x", 32, 16, ctypes_int },
{ "p2_y", 48, 16, ctypes_int },
{ "side", 64, 2, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_line_param_t[15] = {
{ "cfg_p1_x", 40, 16, ctypes_int },
{ "cfg_p1_y", 56, 16, ctypes_int },
{ "cfg_p2_x", 72, 16, ctypes_int },
{ "cfg_p2_y", 88, 16, ctypes_int },
{ "cfg_side", 104, 2, ctypes_uint },
{ "dsc_cb", 0, 32, ctypes_uint },
{ "dsc_type", 32, 8, ctypes_uint },
{ "flat", 272, 1, ctypes_uint },
{ "inv", 273, 1, ctypes_uint },
{ "origo_x", 112, 16, ctypes_int },
{ "origo_y", 128, 16, ctypes_int },
{ "spx", 240, 32, ctypes_int },
{ "steep", 208, 32, ctypes_int },
{ "xy_steep", 144, 32, ctypes_int },
{ "yx_steep", 176, 32, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_mask_angle_param_cfg_t[4] = {
{ "end_angle", 48, 16, ctypes_int },
{ "start_angle", 32, 16, ctypes_int },
{ "vertex_p_x", 0, 16, ctypes_int },
{ "vertex_p_y", 16, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_mask_angle_param_t[37] = {
{ "cfg_end_angle", 88, 16, ctypes_int },
{ "cfg_start_angle", 72, 16, ctypes_int },
{ "cfg_vertex_p_x", 40, 16, ctypes_int },
{ "cfg_vertex_p_y", 56, 16, ctypes_int },
{ "delta_deg", 664, 16, ctypes_uint },
{ "dsc_cb", 0, 32, ctypes_uint },
{ "dsc_type", 32, 8, ctypes_uint },
{ "end_line_cfg_p1_x", 424, 16, ctypes_int },
{ "end_line_cfg_p1_y", 440, 16, ctypes_int },
{ "end_line_cfg_p2_x", 456, 16, ctypes_int },
{ "end_line_cfg_p2_y", 472, 16, ctypes_int },
{ "end_line_cfg_side", 488, 2, ctypes_uint },
{ "end_line_dsc_cb", 384, 32, ctypes_uint },
{ "end_line_dsc_type", 416, 8, ctypes_uint },
{ "end_line_flat", 656, 1, ctypes_uint },
{ "end_line_inv", 657, 1, ctypes_uint },
{ "end_line_origo_x", 496, 16, ctypes_int },
{ "end_line_origo_y", 512, 16, ctypes_int },
{ "end_line_spx", 624, 32, ctypes_int },
{ "end_line_steep", 592, 32, ctypes_int },
{ "end_line_xy_steep", 528, 32, ctypes_int },
{ "end_line_yx_steep", 560, 32, ctypes_int },
{ "start_line_cfg_p1_x", 144, 16, ctypes_int },
{ "start_line_cfg_p1_y", 160, 16, ctypes_int },
{ "start_line_cfg_p2_x", 176, 16, ctypes_int },
{ "start_line_cfg_p2_y", 192, 16, ctypes_int },
{ "start_line_cfg_side", 208, 2, ctypes_uint },
{ "start_line_dsc_cb", 104, 32, ctypes_uint },
{ "start_line_dsc_type", 136, 8, ctypes_uint },
{ "start_line_flat", 376, 1, ctypes_uint },
{ "start_line_inv", 377, 1, ctypes_uint },
{ "start_line_origo_x", 216, 16, ctypes_int },
{ "start_line_origo_y", 232, 16, ctypes_int },
{ "start_line_spx", 344, 32, ctypes_int },
{ "start_line_steep", 312, 32, ctypes_int },
{ "start_line_xy_steep", 248, 32, ctypes_int },
{ "start_line_yx_steep", 280, 32, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_mask_radius_param_cfg_t[6] = {
{ "outer", 80, 1, ctypes_uint },
{ "radius", 64, 16, ctypes_int },
{ "rect_x1", 0, 16, ctypes_int },
{ "rect_x2", 32, 16, ctypes_int },
{ "rect_y1", 16, 16, ctypes_int },
{ "rect_y2", 48, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_sqrt_res_t[2] = {
{ "f", 16, 16, ctypes_uint },
{ "i", 0, 16, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_radius_param_t[11] = {
{ "cfg_outer", 120, 1, ctypes_uint },
{ "cfg_radius", 104, 16, ctypes_int },
{ "cfg_rect_x1", 40, 16, ctypes_int },
{ "cfg_rect_x2", 72, 16, ctypes_int },
{ "cfg_rect_y1", 56, 16, ctypes_int },
{ "cfg_rect_y2", 88, 16, ctypes_int },
{ "dsc_cb", 0, 32, ctypes_uint },
{ "dsc_type", 32, 8, ctypes_uint },
{ "y_prev", 128, 32, ctypes_int },
{ "y_prev_x_f", 176, 16, ctypes_uint },
{ "y_prev_x_i", 160, 16, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_fade_param_cfg_t[8] = {
{ "coords_x1", 0, 16, ctypes_int },
{ "coords_x2", 32, 16, ctypes_int },
{ "coords_y1", 16, 16, ctypes_int },
{ "coords_y2", 48, 16, ctypes_int },
{ "opa_bottom", 104, 8, ctypes_uint },
{ "opa_top", 96, 8, ctypes_uint },
{ "y_bottom", 80, 16, ctypes_int },
{ "y_top", 64, 16, ctypes_int },
};
const be_ctypes_structure_t be_lv_draw_mask_fade_param_t[10] = {
{ "cfg_coords_x1", 40, 16, ctypes_int },
{ "cfg_coords_x2", 72, 16, ctypes_int },
{ "cfg_coords_y1", 56, 16, ctypes_int },
{ "cfg_coords_y2", 88, 16, ctypes_int },
{ "cfg_opa_bottom", 144, 8, ctypes_uint },
{ "cfg_opa_top", 136, 8, ctypes_uint },
{ "cfg_y_bottom", 120, 16, ctypes_int },
{ "cfg_y_top", 104, 16, ctypes_int },
{ "dsc_cb", 0, 32, ctypes_uint },
{ "dsc_type", 32, 8, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_map_param_cfg_t[5] = {
{ "coords_x1", 0, 16, ctypes_int },
{ "coords_x2", 32, 16, ctypes_int },
{ "coords_y1", 16, 16, ctypes_int },
{ "coords_y2", 48, 16, ctypes_int },
{ "map", 64, 32, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_map_param_t[7] = {
{ "cfg_coords_x1", 40, 16, ctypes_int },
{ "cfg_coords_x2", 72, 16, ctypes_int },
{ "cfg_coords_y1", 56, 16, ctypes_int },
{ "cfg_coords_y2", 88, 16, ctypes_int },
{ "cfg_map", 104, 32, ctypes_uint },
{ "dsc_cb", 0, 32, ctypes_uint },
{ "dsc_type", 32, 8, ctypes_uint },
};
const be_ctypes_structure_t be_lv_draw_mask_saved_t[2] = {
{ "custom_id", 32, 32, ctypes_uint },
{ "param", 0, 32, ctypes_uint },
};
/********************************************************************/
#endif // USE_LVGL
#endif // USE_BERRY