Skip to content

Commit

Permalink
Merge pull request #199 from bwhitman/lvgl8
Browse files Browse the repository at this point in the history
Native rgb332 rendering in LVGL
  • Loading branch information
bwhitman authored Apr 4, 2024
2 parents 93a6454 + f896d7f commit 5809710
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
url = https://github.com/bwhitman/amy
[submodule "lv_binding_micropython"]
path = lv_binding_micropython
url = https://github.com/lvgl/lv_binding_micropython
url = https://github.com/bwhitman/lv_binding_micropython
2 changes: 1 addition & 1 deletion amy
Submodule amy updated from 29796c to a4d7b7
2 changes: 1 addition & 1 deletion lv_binding_micropython
3 changes: 1 addition & 2 deletions tulip/macos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ INC += -I./SDL2.framework/Headers

# compiler settings
CWARN = -Wall -Werror
CWARN += -Wextra -Wno-unused-parameter -Wno-unused-but-set-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Wno-missing-declarations
CWARN += -Wextra -Wno-unused-parameter -Wno-unused-but-set-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Wno-missing-declarations -Wno-unused-but-set-variable -Wno-sign-compare -Wno-gnu-variable-sized-type-not-at-end -Wno-undefined-internal
CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(CFLAGS_MOD) $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EXTRA)
CFLAGS += -DTULIP_DESKTOP
#CFLAGS += -DAMY_DEBUG
Expand Down Expand Up @@ -242,7 +242,6 @@ SRC_C += \
../../amy/src/libminiaudio-audio.c \
$(MICROPY_PORT_DIR)/gccollect.c \
$(MICROPY_PORT_DIR)/input.c \
$(MICROPY_PORT_DIR)/modmachine.c \
$(MICROPY_PORT_DIR)/modselect.c \
$(MICROPY_PORT_DIR)/alloc.c \
$(MICROPY_PORT_DIR)/fatfs_port.c \
Expand Down
30 changes: 24 additions & 6 deletions tulip/shared/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ uint32_t *sprite_mem;//[SPRITES];
uint16_t *line_emits_rle;
uint16_t *line_emits_y;


uint16_t * lv_buf;
uint8_t * lv_buf;

uint8_t *TFB;//[TFB_ROWS][TFB_COLS];
uint8_t *TFBfg;//[TFB_ROWS][TFB_COLS];
Expand Down Expand Up @@ -1018,6 +1017,22 @@ void lv_flush_cb(lv_display_t * display, const lv_area_t * area, unsigned char *
lv_display_flush_ready(display);
}

void lv_flush_cb_8b(lv_display_t * display, const lv_area_t * area, unsigned char * px_map)
{
/* uint8_t * buf = (uint8_t *)px_map;
int16_t x, y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
bg[y*(H_RES+OFFSCREEN_X_PX) + x] = (*buf); //((*buf >> 8) & 0xe0) | ((*buf >> 6) & 0x1c) | ((*buf >> 3 & 0x3));
buf++;
}
}
*/
// Inform LVGL that you are ready with the flushing and buf is not used anymore
lv_display_flush_ready(display);
}


// Shim for lvgl to read ticks
uint32_t u32_ticks_ms() {
return (uint32_t) get_ticks_ms();
Expand Down Expand Up @@ -1055,10 +1070,14 @@ void setup_lvgl() {
lv_init();

//lv_log_register_print_cb(my_log_cb);
lv_display_t * lv_display = lv_display_create(H_RES, V_RES);
lv_display_t * lv_display = lv_display_create(H_RES+OFFSCREEN_X_PX, V_RES+OFFSCREEN_Y_PX);
lv_display_set_physical_resolution(lv_display, H_RES, V_RES); // for touchpad
lv_display_set_offset(lv_display,0,0);
lv_display_set_antialiasing(lv_display, 0);
lv_display_set_flush_cb(lv_display, lv_flush_cb);
lv_display_set_buffers(lv_display, lv_buf, NULL, H_RES*V_RES*2/10, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_color_format(lv_display, LV_COLOR_FORMAT_RGB332);
lv_display_set_flush_cb(lv_display, lv_flush_cb_8b);
lv_display_set_buffers(lv_display, bg, NULL, (H_RES+OFFSCREEN_X_PX)*(V_RES+OFFSCREEN_Y_PX), LV_DISPLAY_RENDER_MODE_DIRECT);

lv_tick_set_cb(u32_ticks_ms);

// Create a input device (uses tulip.touch())
Expand Down Expand Up @@ -1100,7 +1119,6 @@ void display_init(void) {
line_emits_y = (uint16_t*)calloc_caps(32, 1, MAX_LINE_EMITS*2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
// 122880 bytes

lv_buf = malloc_caps(H_RES*V_RES*2 / 10, MALLOC_CAP_SPIRAM);

TFB = (uint8_t*)malloc_caps(TFB_ROWS*TFB_COLS*sizeof(uint8_t), MALLOC_CAP_INTERNAL);
TFBf = (uint8_t*)malloc_caps(TFB_ROWS*TFB_COLS*sizeof(uint8_t), MALLOC_CAP_INTERNAL);
Expand Down
3 changes: 3 additions & 0 deletions tulip/shared/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ extern const unsigned char portfolio_glyph_bitmap[1792];
#define FONT_WIDTH 8
#endif

//#define OFFSCREEN_X_PX 0
//#define OFFSCREEN_Y_PX 0

#define OFFSCREEN_X_PX 1024
#define OFFSCREEN_Y_PX 100
#define DEFAULT_PIXEL_CLOCK_MHZ 28
Expand Down
19 changes: 13 additions & 6 deletions tulip/shared/lv_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,21 @@
// This is generated by the preprocessor but our version of MP doesn't use it
#define mp_generic_unary_op NULL

#define LV_STDINT_INCLUDE <stdint.h>
#define LV_STDDEF_INCLUDE <stddef.h>
#define LV_STDBOOL_INCLUDE <stdbool.h>
#define LV_INTTYPES_INCLUDE <inttypes.h>
#define LV_LIMITS_INCLUDE <limits.h>
#define LV_STDARG_INCLUDE <stdarg.h>

/*====================
COLOR SETTINGS
*====================*/

// TODO : hack this to do RGB332

/*Color depth: 8 (A8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
#define LV_COLOR_DEPTH 16
#define LV_COLOR_DEPTH 8

/*=========================
STDLIB WRAPPER SETTINGS
Expand Down Expand Up @@ -947,10 +954,10 @@ extern void mp_lv_init_gc();
#define LV_USE_EVDEV 0

/*Drivers for LCD devices connected via SPI/parallel port*/
#define LV_USE_ST7735 0
#define LV_USE_ST7789 0
#define LV_USE_ST7796 0
#define LV_USE_ILI9341 0
#define LV_USE_ST7735 0
#define LV_USE_ST7789 0
#define LV_USE_ST7796 0
#define LV_USE_ILI9341 0

#define LV_USE_GENERIC_MIPI (LV_USE_ST7735 | LV_USE_ST7789 | LV_USE_ST7796 | LV_USE_ILI9341)

Expand Down Expand Up @@ -1016,4 +1023,4 @@ extern void mp_lv_init_gc();

#endif /*LV_CONF_H*/

#endif /*End of "Content enable"*/
#endif /*End of "Content enable"*/
4 changes: 0 additions & 4 deletions tulip/shared/py/_boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,3 @@
alles.local() # start in local mode
midi.setup()


# Don't boot the launcher on T-Deck
#if(tulip.board()!='TDECK'):
# tulip.launcher()
44 changes: 24 additions & 20 deletions tulip/shared/py/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ def lv_depad(obj):

def current_uiscreen():
return running_apps[current_app_string]

def current_lv_group():
return current_uiscreen().group

# The entire UI is loaded into this screen, which we can swap out from "main" REPL screen
class UIScreen():
Expand All @@ -58,13 +59,19 @@ class UIScreen():

def __init__(self, name, keep_tfb = False, bg_color=default_bg_color, offset_x=default_offset_x, offset_y=default_offset_y,
activate_callback=None, quit_callback=None, deactivate_callback=None, handle_keyboard=False):
self.group = lv.obj() # a screen, really
self.screen = lv.obj() # a screen, will be display size (which is actually 2x H_RES)
self.group = lv.obj(self.screen) # the group to write UI elements to in the screen
self.group.set_width(tulip.screen_size()[0])
self.group.set_height(tulip.screen_size()[1])
self.group.set_style_radius(0,lv.PART.MAIN)
self.group.set_style_border_width(0, lv.PART.MAIN)

lv_depad(self.group)
self.keep_tfb = keep_tfb
self.handle_keyboard = handle_keyboard
self.bg_color = bg_color
self.offset_x = offset_x
self.offset_y = offset_y
self.last_screen = lv.screen_active()
self.last_obj_added = None
self.group.set_style_bg_color(pal_to_lv(self.bg_color), lv.PART.MAIN)
self.name = name
Expand Down Expand Up @@ -176,7 +183,9 @@ def present(self):
current_app_string = self.name
self.active = True
self.draw_task_bar()
lv.screen_load(self.group)

lv.screen_load(self.screen)

if(self.handle_keyboard):
get_keypad_indev().set_group(self.kb_group)
if(self.name == 'repl'):
Expand All @@ -191,17 +200,12 @@ def present(self):
if(self.activate_callback is not None):
self.activate_callback(self)

# Keep everything around, but load the repl screen
def clear(self):
lv.screen_load(self.last_screen)

# Remove the elements you created
def remove_items(self):
self.clear()
things = self.group.get_child_count()
things = self.screen.get_child_count()
for i in range(things):
if(self.group.get_child(0) is not None):
self.group.get_child(0).delete()
if(self.screen.get_child(0) is not None):
self.screen.get_child(0).delete()
self.last_obj_added = None


Expand Down Expand Up @@ -253,7 +257,7 @@ def keyboard():
lv_soft_kb.delete()
lv_soft_kb = None
return
lv_soft_kb = lv.keyboard(lv.screen_active())
lv_soft_kb = lv.keyboard(current_lv_group())
lv_soft_kb.add_event_cb(lv_soft_kb_cb, lv.EVENT.VALUE_CHANGED, None)
lv_last_mode = lv_soft_kb.get_mode()

Expand Down Expand Up @@ -292,7 +296,7 @@ def launcher(ignore=True):
lv_launcher=None
return
#print("starting up launcher")
lv_launcher = lv.list(lv.screen_active())
lv_launcher = lv.list(repl_screen.group)
lv_launcher.set_size(195, 140)
lv_launcher.set_align(lv.ALIGN.BOTTOM_RIGHT)
b_close = lv_launcher.add_button(lv.SYMBOL.CLOSE, "Close")
Expand Down Expand Up @@ -323,7 +327,7 @@ def lv_callback(e, extra):

# Draw a msgbox on screen.
def ui_msgbox(buttons=['OK', 'Cancel'], title='Title', message='Message box', ui_id=None):
mbox = lv.msgbox(lv.screen_active())
mbox = lv.msgbox(current_lv_group())
mbox.add_text(message)
mbox.add_title(title)
mbox.add_close_button()
Expand All @@ -339,7 +343,7 @@ def ui_msgbox(buttons=['OK', 'Cancel'], title='Title', message='Message box', ui
# handle_radius - 0 for square
def ui_slider(val=0, x=0, y=0, w=None, h=None, bar_color=None, unset_bar_color=None, handle_color=None, handle_radius=None,
handle_v_pad=None, handle_h_pad=None, ui_id=None):
slider = lv.slider(lv.screen_active())
slider = lv.slider(current_lv_group())
slider.set_pos(x,y)
# Set opacity to full (COVER). Default is to mix the color with the BG.
slider.set_style_bg_opa(lv.OPA.COVER, lv.PART.MAIN)
Expand Down Expand Up @@ -369,7 +373,7 @@ def ui_slider(val=0, x=0, y=0, w=None, h=None, bar_color=None, unset_bar_color=N
# Copy of our "ui_button" with lvgl buttons
#tulip.ui_button(ui_element_id, "Button text", x, y, w, h, bg_pal_idx, fg_pal_idx, filled, font_number)
def ui_button(text=None, x=0, y=0, w=None, h=None, bg_color=None, fg_color=None, font=None, radius=None, ui_id=None):
button = lv.button(lv.screen_active())
button = lv.button(current_lv_group())
button.set_x(x)
button.set_y(y)
if(w is not None):
Expand All @@ -396,7 +400,7 @@ def ui_button(text=None, x=0, y=0, w=None, h=None, bg_color=None, fg_color=None,
return button

def ui_label(text="", x=0, y=0, fg_color=None, w=None, font=None):
label = lv.label(lv.screen_active())
label = lv.label(current_lv_group())
label.set_pos(x,y)
if(w is not None):
label.set_width(w)
Expand All @@ -411,7 +415,7 @@ def ui_label(text="", x=0, y=0, fg_color=None, w=None, font=None):
# Copy of our ui_text with lvgl textarea
#tulip.ui_text(ui_element_id, default_value, x, y, w, h, text_color, box_color, font_number)
def ui_text(ui_id=None, text=None, placeholder=None, x=0, y=0, w=None, h=None, bg_color=None, fg_color=None, font=None, one_line=True):
ta = lv.textarea(lv.screen_active())
ta = lv.textarea(current_lv_group())
ta.set_pos(x,y)
if(w is not None):
ta.set_width(w)
Expand All @@ -435,7 +439,7 @@ def ui_text(ui_id=None, text=None, placeholder=None, x=0, y=0, w=None, h=None, b

# Copy of our ui_checkbox with lvgl
def ui_checkbox(ui_id=None, text=None, val=False, x=0, y=0, bg_color=None, fg_color=None):
cb = lv.checkbox(lv.screen_active())
cb = lv.checkbox(current_lv_group())
if(text is not None):
cb.set_text(text)
cb.set_pos(x,y)
Expand Down

0 comments on commit 5809710

Please sign in to comment.