Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@
* If you want to update to the current master then delete your local copy and clone it again from scratch.


## *MicroPythonOS Branching Model*

The MicroPythonOS fork of this repository keeps long-running work split into topic branches and then combines them in a single integration branch.

* `integration`: the branch used by MicroPythonOS builds; this is where all selected topic branches are merged.
* `topic/lv-conf`: MicroPythonOS-specific LVGL configuration defaults and tuning.
* `topic/platform`: platform-level fixes and compatibility updates (unix/macOS/SDL and related plumbing).
* `topic/error-handling`: runtime hardening and callback/task exception handling improvements.
* `topic/fonts`: custom font source updates and related font/symbol changes used by MicroPythonOS.
* `topic/esp32-uart-repl-runtime`: adds the ESP32 UART REPL runtime-toggle patch file (`esp32_uart_repl_runtime.patch`).

Typical flow in this fork:

1. Make focused changes on a `topic/*` branch.
2. Push the topic branch for review/testing.
3. Merge (usually fast-forward) into `integration`.
4. Push `integration`, which is the branch consumed by MicroPythonOS.

`main` stays closer to upstream layout, while `integration` is the curated branch that aggregates the MicroPythonOS fork-specific deltas.



# LVGL binding for Micropython
______________________________
Expand Down Expand Up @@ -957,4 +978,3 @@ Bit orders are a tuple of durations. The first 2 numbers define a bit as 0 and t
https://github.com/fabse-hack/temp_humidity_micropython_lvgl



10 changes: 9 additions & 1 deletion api_drivers/common_api_drivers/frozen/other/task_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def _task_handler(self, _):
self.exception_hook(err)
else:
sys.print_exception(err) # NOQA
print(f"TaskHandler callback {cb} threw exception, disabling it")
self.remove_event_cb(cb)

stop_time = time.ticks_ms() # NOQA

Expand All @@ -133,7 +135,13 @@ def _task_handler(self, _):
lv.tick_inc(ticks_diff)

if run_update:
lv.task_handler()
try:
lv.task_handler()
except Exception as e:
print(f"lv.task_handler() threw exception: {e}")
sys.print_exception(e)
# LVGL UI still hangs

start_time = time.ticks_ms() # NOQA

for cb, evt, data in self._callbacks:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def __init__(
backlight_on_state = STATE_HIGH
else:
self._backlight_pin = machine.PWM(
self._backlight_pin, freq=38000)
self._backlight_pin, freq=3800)

if (
backlight_on_state != STATE_PWM and
Expand Down
94 changes: 79 additions & 15 deletions builder/macOS.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@ def parse_args(extra_args, lv_cflags, board):


def build_commands(not_sure, extra_args, script_dir, lv_cflags, board):
return _build_commands(not_sure, extra_args, script_dir, lv_cflags, board)
extra_args = _build_commands(not_sure, extra_args, script_dir, lv_cflags, board)

static_flag = 'LDFLAGS_EXTRA=-static'
for cmd in (unix.unix_cmd, unix.clean_cmd, unix.compile_cmd, unix.submodules_cmd):
while static_flag in cmd:
cmd.remove(static_flag)

return extra_args


def build_manifest(
Expand Down Expand Up @@ -57,29 +64,86 @@ def build_sdl(_):


unix.build_sdl = build_sdl
is_arm = os.uname().machine == "arm64"


def is_homebrew_arm(cmd):
ret_val, output = spawn(cmd, out_to_screen=False)
if ret_val:
if cmd[0][0] == '/opt/homebrew/bin/brew':
raise RuntimeError('Unable to locate homebrew installation')

return is_homebrew_arm([['/opt/homebrew/bin/brew', 'config']])

# Tolerate blank lines / section banners in `brew config` output —
# newer Homebrew versions occasionally emit lines without ':' which
# would otherwise IndexError out the whole macOS build.
data = {line.split(':', 1)[0].strip(): line.split(':', 1)[1].strip() for
line in output.split('\n') if ':' in line}

if 'macOS' not in data:
raise RuntimeError('Unable to determine Homebrew CPU type')

if 'arm64' in data['macOS']:
if 'Rosetta 2' not in data:
if cmd[0][0] != '/opt/homebrew/bin/brew':
return is_homebrew_arm([['/opt/homebrew/bin/brew', 'config']])

raise RuntimeError('Unable to determine Homebrew platform')

if data['Rosetta 2'] == 'true':
if cmd[0][0] != '/opt/homebrew/bin/brew':
return is_homebrew_arm([['/opt/homebrew/bin/brew', 'config']])

raise RuntimeError('Unable to locate Homebrew for Arm processors.')

return True, cmd[0][0]

return False, cmd[0][0]


def submodules():
is_arm, brew_path = is_homebrew_arm([['brew', 'config']])

if is_arm:
path = '/opt/homebrew/opt'
else:
path = '/usr/local/opt'
ret, out = spawn([[brew_path, 'info', 'libffi']], out_to_screen=False)
if ret:
print(out)
sys.exit(ret)

if 'Installed' not in out:
print(out)
raise RuntimeError('libffi is not installed')

out = out.split('Installed\n', 1)[-1]
alt_path = out.split('(', 1)[0].strip().split('Cellar', 1)[0]

if 'export LDFLAGS=' in out:
out = out.split('export LDFLAGS="', 1)[-1]
ldflags = out.split('"', 1)[0]
else:
ldflags = f'"-L{alt_path}opt/libffi/lib"'

if 'export CPPFLAGS=' in out:
out = out.split('export CPPFLAGS="', 1)[-1]
cflags = out.split('"', 1)[0]
else:
cflags = f'"-I{alt_path}opt/libffi/include"'

if not os.path.exists(f'{path}/libffi'):
raise RuntimeError('libffi needs to be installed using Homebrew.')
ret, out = spawn([[brew_path, 'info', 'sdl2']], out_to_screen=False)

ldflags = [f'-L{path}/libffi/lib']
cflags = [f'-I{path}/libffi/include']
if ret:
print(out)
sys.exit(ret)

if not os.path.exists(f'{path}/sdl2'):
raise RuntimeError('sdl2 needs to be installed using Homebrew.')
if 'Installed' not in out:
print(out)
raise RuntimeError('sdl2 is not installed')

ldflags.append(f'-L{path}/sdl2/lib')
cflags.append(f'-I{path}/sdl2/include')
ldflags += f' "-L{alt_path}lib"'
cflags += f' "-I{alt_path}include"'

os.environ['LDFLAGS'] = ' '.join(ldflags)
os.environ['CFLAGS'] = ' '.join(cflags)
os.environ['LDFLAGS'] = f'{ldflags}'
os.environ['CFLAGS'] = f'{cflags}'

berkeley_db = os.path.abspath('lib/micropython/lib/berkeley-db-1.xx/README')

Expand Down
10 changes: 7 additions & 3 deletions builder/unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,13 @@ def build_commands(_, extra_args, script_dir, lv_cflags, board):
'-Wno-unused-command-line-argument '
'-Wno-missing-field-initializers"'
# 'export CPPFLAGS="-I/opt/homebrew/opt/libffi/include"'
)
),
]
)

if REAL_PORT == 'unix':
unix_cmd.append('LDFLAGS_EXTRA=-static') # static binary (all libraries included) so it's more portable

# unix_cmd.extend(extra_args)

clean_cmd.extend(unix_cmd[:])
Expand Down Expand Up @@ -453,9 +456,10 @@ def compile(*args): # NOQA
dst = f'build/lvgl_micropy_{REAL_PORT}'
shutil.copyfile(src, dst)

print(f'compiled binary is {os.path.abspath(os.path.split(dst)[0])}')
buildpath = f"{os.path.abspath(os.path.split(dst)[0])}/lvgl_micropy_{REAL_PORT}"
print(f'compiled binary is {buildpath}')
print('You need to make the binary executable by running')
print(f'"sudo chmod +x lvgl_micropy_{REAL_PORT}"')
print(f'"sudo chmod +x {buildpath}"')


def mpy_cross():
Expand Down
14 changes: 14 additions & 0 deletions esp32_inisetup_warn_and_format.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/ports/esp32/modules/inisetup.py b/ports/esp32/modules/inisetup.py
index 17373185..9ce3d463 100644
--- a/ports/esp32/modules/inisetup.py
+++ b/ports/esp32/modules/inisetup.py
@@ -13,7 +13,8 @@ def check_bootsec():
break
if empty:
return True
- fs_corrupted()
+ # fs_corrupted()
+ print("WARNING: could not mount filesystem and it doesn't seem to be empty either, formatting anyway!")


def fs_corrupted():
131 changes: 131 additions & 0 deletions esp32_uart_repl_runtime.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
diff --git a/ports/esp32/modesp.c b/ports/esp32/modesp.c
index d3cefbe2..3dd11ece 100644
--- a/ports/esp32/modesp.c
+++ b/ports/esp32/modesp.c
@@ -36,6 +36,8 @@
#include "py/mperrno.h"
#include "py/mphal.h"

+#include "uart.h"
+
static mp_obj_t esp_osdebug(size_t n_args, const mp_obj_t *args) {
esp_log_level_t level = LOG_LOCAL_LEVEL; // Maximum available level
if (n_args == 2) {
@@ -53,6 +55,18 @@ static mp_obj_t esp_osdebug(size_t n_args, const mp_obj_t *args) {
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_osdebug_obj, 1, 2, esp_osdebug);

+#if MICROPY_HW_ENABLE_UART_REPL
+static mp_obj_t esp_uart_repl(size_t n_args, const mp_obj_t *args) {
+ if (n_args == 0) {
+ return mp_obj_new_bool(uart_stdout_is_enabled());
+ }
+
+ uart_stdout_set_enabled(mp_obj_is_true(args[0]));
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_uart_repl_obj, 0, 1, esp_uart_repl);
+#endif
+
static mp_obj_t esp_flash_read_(mp_obj_t offset_in, mp_obj_t buf_in) {
mp_int_t offset = mp_obj_get_int(offset_in);
mp_buffer_info_t bufinfo;
@@ -117,6 +131,10 @@ static const mp_rom_map_elem_t esp_module_globals_table[] = {

{ MP_ROM_QSTR(MP_QSTR_osdebug), MP_ROM_PTR(&esp_osdebug_obj) },

+ #if MICROPY_HW_ENABLE_UART_REPL
+ { MP_ROM_QSTR(MP_QSTR_uart_repl), MP_ROM_PTR(&esp_uart_repl_obj) },
+ #endif
+
{ MP_ROM_QSTR(MP_QSTR_flash_read), MP_ROM_PTR(&esp_flash_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_flash_write), MP_ROM_PTR(&esp_flash_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_flash_erase), MP_ROM_PTR(&esp_flash_erase_obj) },
diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c
index 5197ccc0..911dbf67 100644
--- a/ports/esp32/mphalport.c
+++ b/ports/esp32/mphalport.c
@@ -162,8 +162,10 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) {
did_write = true;
#endif
#if MICROPY_HW_ENABLE_UART_REPL
- uart_stdout_tx_strn(str, len);
- did_write = true;
+ if (uart_stdout_is_enabled()) {
+ uart_stdout_tx_strn(str, len);
+ did_write = true;
+ }
#endif
if (release_gil) {
MP_THREAD_GIL_ENTER();
diff --git a/ports/esp32/uart.c b/ports/esp32/uart.c
index 6e00fa3a..62d59505 100644
--- a/ports/esp32/uart.c
+++ b/ports/esp32/uart.c
@@ -29,10 +29,13 @@

#include "py/runtime.h"
#include "py/mphal.h"
+#include "mphalport.h"
#include "uart.h"

#if MICROPY_HW_ENABLE_UART_REPL

+static volatile bool uart_repl_enabled = true;
+
#include <stdio.h>
#include "driver/uart.h" // For uart_get_sclk_freq()
#include "hal/uart_hal.h"
@@ -81,6 +84,20 @@ void uart_stdout_init(void) {
uart_hal_ena_intr_mask(&repl_hal, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
}

+bool uart_stdout_is_enabled(void) {
+ return uart_repl_enabled;
+}
+
+void uart_stdout_set_enabled(bool enabled) {
+ mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+ uart_repl_enabled = enabled;
+ if (!enabled) {
+ while (ringbuf_get(&stdin_ringbuf) != -1) {
+ }
+ }
+ MICROPY_END_ATOMIC_SECTION(atomic_state);
+}
+
int uart_stdout_tx_strn(const char *str, size_t len) {
uart_hal_context_t repl_hal = REPL_HAL_DEFN();
size_t remaining = len;
@@ -112,6 +129,9 @@ static void IRAM_ATTR uart_irq_handler(void *arg) {
uart_hal_read_rxfifo(&repl_hal, rbuf, &len);

for (int i = 0; i < len; i++) {
+ if (!uart_repl_enabled) {
+ continue;
+ }
if (rbuf[i] == mp_interrupt_char) {
mp_sched_keyboard_interrupt();
} else {
diff --git a/ports/esp32/uart.h b/ports/esp32/uart.h
index fe08e268..b3ba8a2d 100644
--- a/ports/esp32/uart.h
+++ b/ports/esp32/uart.h
@@ -28,6 +28,8 @@
#ifndef MICROPY_INCLUDED_ESP32_UART_H
#define MICROPY_INCLUDED_ESP32_UART_H

+#include <stdbool.h>
+
// Whether to enable the REPL on a UART.
#ifndef MICROPY_HW_ENABLE_UART_REPL
#define MICROPY_HW_ENABLE_UART_REPL (!MICROPY_HW_USB_CDC && !MICROPY_HW_ESP_USB_SERIAL_JTAG)
@@ -45,6 +47,8 @@

void uart_stdout_init(void);
int uart_stdout_tx_strn(const char *str, size_t len);
+bool uart_stdout_is_enabled(void);
+void uart_stdout_set_enabled(bool enabled);

#endif // MICROPY_HW_ENABLE_UART_REPL

8 changes: 8 additions & 0 deletions ext_mod/lcd_bus/sdl_bus/sdl_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@
SDL_SetTextureBlendMode(self->texture, SDL_BLENDMODE_BLEND);
SDL_SetWindowSize(self->window, width, height);

// Check for SDL_WINDOW_FULLSCREEN environment variable
if (getenv("SDL_WINDOW_FULLSCREEN") != NULL) {
SDL_SetWindowFullscreen(self->window, SDL_WINDOW_FULLSCREEN);
}
// Set arrow cursor
SDL_Cursor* cursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
SDL_SetCursor(cursor);

self->rgb565_byte_swap = false;
self->trans_done = true;

Expand Down
Loading