diff --git a/components/micropython/usermodule/micropython.cmake b/components/micropython/usermodule/micropython.cmake index a8d4be37ce958bb4313571b5c29a989a470a1806..86115b6e3a21e192fead240f151482a21289690e 100644 --- a/components/micropython/usermodule/micropython.cmake +++ b/components/micropython/usermodule/micropython.cmake @@ -5,7 +5,7 @@ add_library(usermod_badge23 INTERFACE) target_sources(usermod_badge23 INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/mp_hardware.c + ${CMAKE_CURRENT_LIST_DIR}/mp_sys_buttons.c ${CMAKE_CURRENT_LIST_DIR}/mp_leds.c ${CMAKE_CURRENT_LIST_DIR}/mp_audio.c ${CMAKE_CURRENT_LIST_DIR}/mp_sys_bl00mbox.c @@ -14,6 +14,7 @@ target_sources(usermod_badge23 INTERFACE ${CMAKE_CURRENT_LIST_DIR}/mp_kernel.c ${CMAKE_CURRENT_LIST_DIR}/mp_uctx.c ${CMAKE_CURRENT_LIST_DIR}/mp_captouch.c + ${CMAKE_CURRENT_LIST_DIR}/mp_sys_display.c ) target_include_directories(usermod_badge23 INTERFACE diff --git a/components/micropython/usermodule/mp_hardware.c b/components/micropython/usermodule/mp_hardware.c deleted file mode 100644 index ef956f8bd2e4558e68c7aa6ebbaed5739e9e4a43..0000000000000000000000000000000000000000 --- a/components/micropython/usermodule/mp_hardware.c +++ /dev/null @@ -1,206 +0,0 @@ -// probably doesn't need all of these idk -#include <stdio.h> -#include <string.h> - -#include "extmod/virtpin.h" -#include "machine_rtc.h" -#include "modmachine.h" -#include "mphalport.h" -#include "py/builtin.h" -#include "py/mphal.h" -#include "py/runtime.h" - -#include "flow3r_bsp.h" -#include "st3m_console.h" -#include "st3m_gfx.h" -#include "st3m_io.h" -#include "st3m_scope.h" -#include "st3m_usb.h" - -// clang-format off -#include "ctx_config.h" -#include "ctx.h" -// clang-format on - -mp_obj_t mp_ctx_from_ctx(Ctx *ctx); - -STATIC mp_obj_t mp_display_set_backlight(mp_obj_t percent_in) { - uint8_t percent = mp_obj_get_int(percent_in); - flow3r_bsp_display_set_backlight(percent); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_display_set_backlight_obj, - mp_display_set_backlight); - -STATIC mp_obj_t mp_left_button_get() { - return mp_obj_new_int(st3m_io_left_button_get()); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_left_button_get_obj, mp_left_button_get); - -STATIC mp_obj_t mp_right_button_get() { - return mp_obj_new_int(st3m_io_right_button_get()); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_right_button_get_obj, mp_right_button_get); - -STATIC mp_obj_t mp_version(void) { - mp_obj_t str = - mp_obj_new_str(flow3r_bsp_hw_name, strlen(flow3r_bsp_hw_name)); - return str; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_version_obj, mp_version); - -static st3m_ctx_desc_t *gfx_last_desc = NULL; - -STATIC mp_obj_t mp_get_ctx(void) { - if (gfx_last_desc == NULL) { - gfx_last_desc = st3m_gfx_drawctx_free_get(0); - if (gfx_last_desc == NULL) { - return mp_const_none; - } - } - mp_obj_t mp_ctx = mp_ctx_from_ctx(gfx_last_desc->ctx); - return mp_ctx; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_ctx_obj, mp_get_ctx); - -STATIC mp_obj_t mp_freertos_sleep(mp_obj_t ms_in) { - uint32_t ms = mp_obj_get_int(ms_in); - MP_THREAD_GIL_EXIT(); - vTaskDelay(ms / portTICK_PERIOD_MS); - MP_THREAD_GIL_ENTER(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_freertos_sleep_obj, mp_freertos_sleep); - -STATIC mp_obj_t mp_display_update(mp_obj_t in_ctx) { - // TODO(q3k): check in_ctx? Or just drop from API? - - if (gfx_last_desc != NULL) { - st3m_gfx_drawctx_pipe_put(gfx_last_desc); - gfx_last_desc = NULL; - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_display_update_obj, mp_display_update); - -STATIC mp_obj_t mp_display_pipe_full(void) { - if (st3m_gfx_drawctx_pipe_full()) { - return mp_const_true; - } - return mp_const_false; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_display_pipe_full_obj, - mp_display_pipe_full); - -STATIC mp_obj_t mp_display_pipe_flush(void) { - st3m_gfx_flush(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_display_pipe_flush_obj, - mp_display_pipe_flush); - -STATIC mp_obj_t mp_scope_draw(mp_obj_t ctx_in) { - // TODO(q3k): check in_ctx? Or just drop from API? - - if (gfx_last_desc != NULL) { - st3m_scope_draw(gfx_last_desc->ctx); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_scope_draw_obj, mp_scope_draw); - -STATIC mp_obj_t mp_i2c_scan(void) { - flow3r_bsp_i2c_scan_result_t scan; - flow3r_bsp_i2c_scan(&scan); - - mp_obj_t res = mp_obj_new_list(0, NULL); - for (int i = 0; i < 127; i++) { - size_t ix = i / 32; - size_t offs = i % 32; - if (scan.res[ix] & (1 << offs)) { - mp_obj_list_append(res, mp_obj_new_int_from_uint(i)); - } - } - return res; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_i2c_scan_obj, mp_i2c_scan); - -STATIC mp_obj_t mp_usb_connected(void) { - static int64_t last_check = 0; - static bool value = false; - int64_t now = esp_timer_get_time(); - - if (last_check == 0) { - last_check = now; - value = st3m_usb_connected(); - } - - if ((now - last_check) > 10000) { - value = st3m_usb_connected(); - last_check = now; - } - return mp_obj_new_bool(value); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_usb_connected_obj, mp_usb_connected); - -STATIC mp_obj_t mp_usb_console_active(void) { - static int64_t last_check = 0; - static bool value = false; - int64_t now = esp_timer_get_time(); - - if (last_check == 0) { - last_check = now; - value = st3m_console_active(); - } - - if ((now - last_check) > 10000) { - value = st3m_console_active(); - last_check = now; - } - return mp_obj_new_bool(value); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_usb_console_active_obj, - mp_usb_console_active); - -STATIC const mp_rom_map_elem_t mp_module_hardware_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hardware) }, - - { MP_ROM_QSTR(MP_QSTR_left_button_get), - MP_ROM_PTR(&mp_left_button_get_obj) }, - { MP_ROM_QSTR(MP_QSTR_right_button_get), - MP_ROM_PTR(&mp_right_button_get_obj) }, - - { MP_ROM_QSTR(MP_QSTR_display_update), MP_ROM_PTR(&mp_display_update_obj) }, - { MP_ROM_QSTR(MP_QSTR_freertos_sleep), MP_ROM_PTR(&mp_freertos_sleep_obj) }, - { MP_ROM_QSTR(MP_QSTR_display_pipe_full), - MP_ROM_PTR(&mp_display_pipe_full_obj) }, - { MP_ROM_QSTR(MP_QSTR_display_pipe_flush), - MP_ROM_PTR(&mp_display_pipe_flush_obj) }, - { MP_ROM_QSTR(MP_QSTR_display_set_backlight), - MP_ROM_PTR(&mp_display_set_backlight_obj) }, - { MP_ROM_QSTR(MP_QSTR_version), MP_ROM_PTR(&mp_version_obj) }, - { MP_ROM_QSTR(MP_QSTR_get_ctx), MP_ROM_PTR(&mp_get_ctx_obj) }, - { MP_ROM_QSTR(MP_QSTR_usb_connected), MP_ROM_PTR(&mp_usb_connected_obj) }, - { MP_ROM_QSTR(MP_QSTR_usb_console_active), - MP_ROM_PTR(&mp_usb_console_active_obj) }, - { MP_ROM_QSTR(MP_QSTR_i2c_scan), MP_ROM_PTR(&mp_i2c_scan_obj) }, - - { MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED_LEFT), MP_ROM_INT(st3m_tripos_left) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED_RIGHT), - MP_ROM_INT(st3m_tripos_right) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED_DOWN), MP_ROM_INT(st3m_tripos_mid) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON_NOT_PRESSED), MP_ROM_INT(st3m_tripos_none) }, - - { MP_ROM_QSTR(MP_QSTR_scope_draw), MP_ROM_PTR(&mp_scope_draw_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_hardware_globals, - mp_module_hardware_globals_table); - -const mp_obj_module_t mp_module_hardware = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&mp_module_hardware_globals, -}; - -MP_REGISTER_MODULE(MP_QSTR_hardware, mp_module_hardware); diff --git a/components/micropython/usermodule/mp_kernel.c b/components/micropython/usermodule/mp_kernel.c index 72d4bce0cb5a30debfe153eb8a6b52c5acd7dde1..cbaff5919c77dd97b57fa19e3553b42f7febd792 100644 --- a/components/micropython/usermodule/mp_kernel.c +++ b/components/micropython/usermodule/mp_kernel.c @@ -4,8 +4,11 @@ #include <stdio.h> #include <string.h> +#include "flow3r_bsp.h" #include "py/obj.h" #include "py/runtime.h" +#include "st3m_console.h" +#include "st3m_usb.h" #include "st3m_version.h" #if (configUSE_TRACE_FACILITY != 1) @@ -299,12 +302,89 @@ STATIC mp_obj_t mp_firmware_version(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_firmware_version_obj, mp_firmware_version); +STATIC mp_obj_t mp_hardware_version(void) { + mp_obj_t str = + mp_obj_new_str(flow3r_bsp_hw_name, strlen(flow3r_bsp_hw_name)); + return str; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_hardware_version_obj, mp_hardware_version); + +STATIC mp_obj_t mp_freertos_sleep(mp_obj_t ms_in) { + uint32_t ms = mp_obj_get_int(ms_in); + MP_THREAD_GIL_EXIT(); + vTaskDelay(ms / portTICK_PERIOD_MS); + MP_THREAD_GIL_ENTER(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_freertos_sleep_obj, mp_freertos_sleep); + +STATIC mp_obj_t mp_usb_connected(void) { + static int64_t last_check = 0; + static bool value = false; + int64_t now = esp_timer_get_time(); + + if (last_check == 0) { + last_check = now; + value = st3m_usb_connected(); + } + + if ((now - last_check) > 10000) { + value = st3m_usb_connected(); + last_check = now; + } + return mp_obj_new_bool(value); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_usb_connected_obj, mp_usb_connected); + +STATIC mp_obj_t mp_usb_console_active(void) { + static int64_t last_check = 0; + static bool value = false; + int64_t now = esp_timer_get_time(); + + if (last_check == 0) { + last_check = now; + value = st3m_console_active(); + } + + if ((now - last_check) > 10000) { + value = st3m_console_active(); + last_check = now; + } + return mp_obj_new_bool(value); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_usb_console_active_obj, + mp_usb_console_active); + +STATIC mp_obj_t mp_i2c_scan(void) { + flow3r_bsp_i2c_scan_result_t scan; + flow3r_bsp_i2c_scan(&scan); + + mp_obj_t res = mp_obj_new_list(0, NULL); + for (int i = 0; i < 127; i++) { + size_t ix = i / 32; + size_t offs = i % 32; + if (scan.res[ix] & (1 << offs)) { + mp_obj_list_append(res, mp_obj_new_int_from_uint(i)); + } + } + return res; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_i2c_scan_obj, mp_i2c_scan); + STATIC const mp_rom_map_elem_t globals_table[] = { { MP_ROM_QSTR(MP_QSTR_scheduler_snapshot), MP_ROM_PTR(&mp_scheduler_snapshot_obj) }, { MP_ROM_QSTR(MP_QSTR_heap_stats), MP_ROM_PTR(&mp_heap_stats_obj) }, { MP_ROM_QSTR(MP_QSTR_firmware_version), MP_ROM_PTR(&mp_firmware_version_obj) }, + { MP_ROM_QSTR(MP_QSTR_hardware_version), + MP_ROM_PTR(&mp_hardware_version_obj) }, + { MP_ROM_QSTR(MP_QSTR_freertos_sleep), MP_ROM_PTR(&mp_freertos_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_usb_connected), MP_ROM_PTR(&mp_usb_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_usb_console_active), + MP_ROM_PTR(&mp_usb_console_active_obj) }, + { MP_ROM_QSTR(MP_QSTR_i2c_scan), MP_ROM_PTR(&mp_i2c_scan_obj) }, { MP_ROM_QSTR(MP_QSTR_RUNNING), MP_ROM_INT(eRunning) }, { MP_ROM_QSTR(MP_QSTR_READY), MP_ROM_INT(eReady) }, diff --git a/components/micropython/usermodule/mp_sys_buttons.c b/components/micropython/usermodule/mp_sys_buttons.c new file mode 100644 index 0000000000000000000000000000000000000000..76a87dc03b8ff083dea48e2750c19ec0ef54eb85 --- /dev/null +++ b/components/micropython/usermodule/mp_sys_buttons.c @@ -0,0 +1,51 @@ +// probably doesn't need all of these idk +#include <stdio.h> +#include <string.h> + +#include "extmod/virtpin.h" +#include "machine_rtc.h" +#include "modmachine.h" +#include "mphalport.h" +#include "py/builtin.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "flow3r_bsp.h" +#include "st3m_console.h" +#include "st3m_gfx.h" +#include "st3m_io.h" +#include "st3m_scope.h" + +#include "mp_uctx.h" + +STATIC mp_obj_t mp_get_left() { + return mp_obj_new_int(st3m_io_left_button_get()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_left_obj, mp_get_left); + +STATIC mp_obj_t mp_get_right() { + return mp_obj_new_int(st3m_io_right_button_get()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_right_obj, mp_get_right); + +STATIC const mp_rom_map_elem_t mp_module_sys_buttons_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_buttons) }, + + { MP_ROM_QSTR(MP_QSTR_get_left), MP_ROM_PTR(&mp_get_left_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_right), MP_ROM_PTR(&mp_get_right_obj) }, + + { MP_ROM_QSTR(MP_QSTR_PRESSED_LEFT), MP_ROM_INT(st3m_tripos_left) }, + { MP_ROM_QSTR(MP_QSTR_PRESSED_RIGHT), MP_ROM_INT(st3m_tripos_right) }, + { MP_ROM_QSTR(MP_QSTR_PRESSED_DOWN), MP_ROM_INT(st3m_tripos_mid) }, + { MP_ROM_QSTR(MP_QSTR_NOT_PRESSED), MP_ROM_INT(st3m_tripos_none) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_sys_buttons_globals, + mp_module_sys_buttons_globals_table); + +const mp_obj_module_t mp_module_sys_buttons = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mp_module_sys_buttons_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_sys_buttons, mp_module_sys_buttons); diff --git a/components/micropython/usermodule/mp_sys_display.c b/components/micropython/usermodule/mp_sys_display.c new file mode 100644 index 0000000000000000000000000000000000000000..959499a78edf41c18b35e11ff3012a89b595678c --- /dev/null +++ b/components/micropython/usermodule/mp_sys_display.c @@ -0,0 +1,93 @@ +// probably doesn't need all of these idk +#include <stdio.h> +#include <string.h> + +#include "extmod/virtpin.h" +#include "machine_rtc.h" +#include "modmachine.h" +#include "mphalport.h" +#include "py/builtin.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "flow3r_bsp.h" +#include "st3m_console.h" +#include "st3m_gfx.h" +#include "st3m_io.h" +#include "st3m_scope.h" + +#include "mp_uctx.h" + +static st3m_ctx_desc_t *gfx_last_desc = NULL; + +STATIC mp_obj_t mp_set_backlight(mp_obj_t percent_in) { + uint8_t percent = mp_obj_get_int(percent_in); + flow3r_bsp_display_set_backlight(percent); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_set_backlight_obj, mp_set_backlight); + +STATIC mp_obj_t mp_get_ctx(void) { + if (gfx_last_desc == NULL) { + gfx_last_desc = st3m_gfx_drawctx_free_get(0); + if (gfx_last_desc == NULL) { + return mp_const_none; + } + } + mp_obj_t mp_ctx = mp_ctx_from_ctx(gfx_last_desc->ctx); + return mp_ctx; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_ctx_obj, mp_get_ctx); + +STATIC mp_obj_t mp_update(mp_obj_t ctx_in) { + mp_ctx_obj_t *self = MP_OBJ_TO_PTR(ctx_in); + if (self->base.type != &mp_ctx_type) { + mp_raise_ValueError("not a ctx"); + return mp_const_none; + } + + if (gfx_last_desc != NULL) { + if (gfx_last_desc->ctx != self->ctx) { + mp_raise_ValueError( + "not the correct ctx (do not hold on to ctx objects!)"); + return mp_const_none; + } + st3m_gfx_drawctx_pipe_put(gfx_last_desc); + gfx_last_desc = NULL; + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_update_obj, mp_update); + +STATIC mp_obj_t mp_pipe_full(void) { + if (st3m_gfx_drawctx_pipe_full()) { + return mp_const_true; + } + return mp_const_false; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_pipe_full_obj, mp_pipe_full); + +STATIC mp_obj_t mp_pipe_flush(void) { + st3m_gfx_flush(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_pipe_flush_obj, mp_pipe_flush); + +STATIC const mp_rom_map_elem_t mp_module_sys_display_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys_display) }, + { MP_ROM_QSTR(MP_QSTR_pipe_full), MP_ROM_PTR(&mp_pipe_full_obj) }, + { MP_ROM_QSTR(MP_QSTR_pipe_flush), MP_ROM_PTR(&mp_pipe_flush_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&mp_set_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mp_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_ctx), MP_ROM_PTR(&mp_get_ctx_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_sys_display_globals, + mp_module_sys_display_globals_table); + +const mp_obj_module_t mp_module_sys_display = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mp_module_sys_display_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_sys_display, mp_module_sys_display); diff --git a/components/micropython/usermodule/mp_uctx.c b/components/micropython/usermodule/mp_uctx.c index bc0373ee074684cac39d98d016f140d04bbb6c68..c668bf2a5273f0a7d1eaf0346390711dafd2b2c7 100644 --- a/components/micropython/usermodule/mp_uctx.c +++ b/components/micropython/usermodule/mp_uctx.c @@ -4,16 +4,8 @@ #include "py/objarray.h" #include "py/runtime.h" -// clang-format off -#include "ctx_config.h" -#include "ctx.h" -// clang-format on - -typedef struct _mp_ctx_obj_t { - mp_obj_base_t base; - Ctx *ctx; - mp_obj_t user_data; -} mp_ctx_obj_t; +#include "mp_uctx.h" +#include "st3m_scope.h" void gc_collect(void); #ifdef EMSCRIPTEN @@ -245,6 +237,13 @@ MP_CTX_COMMON_FUN_6F(radial_gradient); MP_CTX_COMMON_FUN_3F(logo); +static mp_obj_t mp_ctx_scope(mp_obj_t self_in) { + mp_ctx_obj_t *self = MP_OBJ_TO_PTR(self_in); + st3m_scope_draw(self->ctx); + return self_in; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_ctx_scope_obj, mp_ctx_scope); + static mp_obj_t mp_ctx_key_down(size_t n_args, const mp_obj_t *args) { mp_ctx_obj_t *self = MP_OBJ_TO_PTR(args[0]); ctx_key_down(self->ctx, @@ -514,8 +513,6 @@ STATIC void generic_method_lookup(mp_obj_t obj, qstr attr, mp_obj_t *dest) { } } -extern const mp_obj_type_t mp_ctx_type; - #if CTX_TINYVG static mp_obj_t mp_ctx_tinyvg_get_size(mp_obj_t self_in, mp_obj_t buffer_in) { mp_buffer_info_t buffer_info; @@ -857,6 +854,7 @@ static const mp_rom_map_elem_t mp_ctx_locals_dict_table[] = { #endif #endif MP_CTX_METHOD(logo), + MP_CTX_METHOD(scope), // Instance attributes MP_CTX_ATTR(x), diff --git a/components/micropython/usermodule/mp_uctx.h b/components/micropython/usermodule/mp_uctx.h new file mode 100644 index 0000000000000000000000000000000000000000..96b4f2633c66bea212a5a1ac17f9291c650d44d7 --- /dev/null +++ b/components/micropython/usermodule/mp_uctx.h @@ -0,0 +1,16 @@ +#pragma once + +// clang-format off +#include "ctx_config.h" +#include "ctx.h" +// clang-format on + +typedef struct _mp_ctx_obj_t { + mp_obj_base_t base; + Ctx *ctx; + mp_obj_t user_data; +} mp_ctx_obj_t; + +extern const mp_obj_type_t mp_ctx_type; + +mp_obj_t mp_ctx_from_ctx(Ctx *ctx); \ No newline at end of file diff --git a/docs/api/hardware.rst b/docs/api/hardware.rst deleted file mode 100644 index 63fa6e05dec3d52e371c27d00549a60d6d42ce79..0000000000000000000000000000000000000000 --- a/docs/api/hardware.rst +++ /dev/null @@ -1,7 +0,0 @@ -``hardware`` module -=================== - -.. automodule:: hardware - :members: - :undoc-members: - diff --git a/docs/api/sys_buttons.rst b/docs/api/sys_buttons.rst new file mode 100644 index 0000000000000000000000000000000000000000..fbe227077f98cb143b95839211fdafddca795e92 --- /dev/null +++ b/docs/api/sys_buttons.rst @@ -0,0 +1,7 @@ +``sys_buttons`` module +====================== + +.. automodule:: sys_buttons + :members: + :undoc-members: + diff --git a/docs/api/sys_display.rst b/docs/api/sys_display.rst new file mode 100644 index 0000000000000000000000000000000000000000..288b8eca26601c735c9558e57fc5af68054ebe4a --- /dev/null +++ b/docs/api/sys_display.rst @@ -0,0 +1,7 @@ +``sys_display`` module +====================== + +.. automodule:: sys_display + :members: + :undoc-members: + diff --git a/docs/badge/application-programming.rst b/docs/badge/application-programming.rst index 4d1d5e0bbf05ab82d4f393d4859191ec3ba973f3..2d7124023be61c81e1eb15670eae515ede9fab3f 100644 --- a/docs/badge/application-programming.rst +++ b/docs/badge/application-programming.rst @@ -80,13 +80,14 @@ Example 1b: React to input If we want to react to the user, we can use the :py:class:`InputState` which got handed to us. In this example we look at the state of the app (by default left) -shoulder button. The values contained in the input state are the same as used -by the :py:mod:`hardware` module. +shoulder button. The values for buttons contained in the input state are one of +``InputButtonState.PRESSED_LEFT``, ``PRESSED_RIGHT``, ``PRESSED_DOWN``, +``NOT_PRESSED`` - same values as in the low-level +:py:mod:`sys_buttons`. .. code-block:: python from st3m.reactor import Responder - from hardware import BUTTON_PRESSED_LEFT, BUTTON_PRESSED_RIGHT, BUTTON_PRESSED_DOWN import st3m.run class Example(Responder): @@ -103,9 +104,9 @@ by the :py:mod:`hardware` module. def think(self, ins: InputState, delta_ms: int) -> None: direction = ins.buttons.app - if direction == BUTTON_PRESSED_LEFT: + if direction == ins.buttons.PRESSED_LEFT: self._x -= 1 - elif direction == BUTTON_PRESSED_RIGHT: + elif direction == ins.buttons.PRESSED_RIGHT: self._x += 1 @@ -128,7 +129,6 @@ represents the time which has passed since the last call to `think()`. .. code-block:: python from st3m.reactor import Responder - from hardware import BUTTON_PRESSED_LEFT, BUTTON_PRESSED_RIGHT, BUTTON_PRESSED_DOWN import st3m.run class Example(Responder): @@ -145,9 +145,9 @@ represents the time which has passed since the last call to `think()`. def think(self, ins: InputState, delta_ms: int) -> None: direction = ins.buttons.app # -1 (left), 1 (right), or 2 (pressed) - if direction == BUTTON_PRESSED_LEFT: + if direction == ins.buttons.PRESSED_LEFT: self._x -= 20 * delta_ms / 1000 - elif direction == BUTTON_PRESSED_RIGHT: + elif direction == ins.buttons.PRESSED_RIGHT: self._x += 40 * delta_ms / 1000 @@ -213,7 +213,6 @@ a square. from st3m.input import InputController from st3m.utils import tau - from hardware import BUTTON_PRESSED_LEFT, BUTTON_PRESSED_RIGHT, BUTTON_PRESSED_DOWN import st3m.run class Example(Responder): diff --git a/docs/index.rst b/docs/index.rst index fbebc5de7061d054d6e525e8b7502db12a2e71af..6129613d2742045c2d38945170397d77010cc317 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,10 +26,11 @@ Welcome to flow3r's documentation! api/audio.rst api/badgelink.rst api/captouch.rst - api/hardware.rst api/kernel.rst api/leds.rst api/ctx.rst + api/sys_buttons.rst + api/sys_display.rst Indices and tables ================== diff --git a/python_payload/apps/demo_cap_touch/main.py b/python_payload/apps/demo_cap_touch/main.py index 2819745974e53ece984f554ae476e8879ad8a5be..c5057ceb33a98b1708c085aa66747adb7011442c 100644 --- a/python_payload/apps/demo_cap_touch/main.py +++ b/python_payload/apps/demo_cap_touch/main.py @@ -11,8 +11,6 @@ import cmath import math import time -import hardware - class Dot: def __init__(self, size: float, imag: float, real: float) -> None: diff --git a/python_payload/apps/demo_harmonic/__init__.py b/python_payload/apps/demo_harmonic/__init__.py index 98402812b3506a1af08b3db5fd6a1ffd021ca643..f2683276cd9d71f7f173bc4b23fcf1a7b389391c 100644 --- a/python_payload/apps/demo_harmonic/__init__.py +++ b/python_payload/apps/demo_harmonic/__init__.py @@ -3,7 +3,6 @@ import bl00mbox blm = bl00mbox.Channel("Harmonic Demo") import leds -import hardware from st3m.goose import List from st3m.input import InputState @@ -57,7 +56,7 @@ class HarmonicApp(Application): ctx.rgb(i, i, i).rectangle(-120, -120, 240, 240).fill() ctx.rgb(0, 0, 0) - hardware.scope_draw(ctx) + ctx.scope() ctx.fill() def think(self, ins: InputState, delta_ms: int) -> None: diff --git a/python_payload/apps/demo_melodic/__init__.py b/python_payload/apps/demo_melodic/__init__.py index 6866af46cd3012c466e0f50389f024938878108c..97e4cc19510fba58ae686fdd51c3d4e416b2c007 100644 --- a/python_payload/apps/demo_melodic/__init__.py +++ b/python_payload/apps/demo_melodic/__init__.py @@ -2,7 +2,6 @@ import bl00mbox blm = bl00mbox.Channel("Melodic Demo") -from hardware import * import captouch import leds @@ -97,7 +96,7 @@ class MelodicApp(Application): def draw(self, ctx: Context) -> None: ctx.rgb(1, 1, 1).rectangle(-120, -120, 240, 240).fill() ctx.rgb(0, 0, 0) - scope_draw(ctx) + ctx.scope() ctx.fill() def on_enter(self, vm: Optional[ViewManager]) -> None: diff --git a/python_payload/apps/shoegaze/__init__.py b/python_payload/apps/shoegaze/__init__.py index f625b651ced7efb7bd33485e753a7276c5742b6a..e45d1b1f980275cd9d3aaf64553526d864eeb280 100644 --- a/python_payload/apps/shoegaze/__init__.py +++ b/python_payload/apps/shoegaze/__init__.py @@ -10,7 +10,6 @@ import captouch import bl00mbox import leds -import hardware import random chords = [ diff --git a/python_payload/apps/simple_drums/__init__.py b/python_payload/apps/simple_drums/__init__.py index b9ade9a3a060cfa9041b3a73fa25c93cb67fc0b2..6ee84938b2286aefb44a52dc744698980fcfb64d 100644 --- a/python_payload/apps/simple_drums/__init__.py +++ b/python_payload/apps/simple_drums/__init__.py @@ -1,5 +1,4 @@ import bl00mbox -import hardware import captouch import leds diff --git a/python_payload/mypystubs/ctx.pyi b/python_payload/mypystubs/ctx.pyi index 7e50072c324fef8601b21c57e049662a9fda080e..bbd830b3767a2d469112a65c174b4e9521c99cd5 100644 --- a/python_payload/mypystubs/ctx.pyi +++ b/python_payload/mypystubs/ctx.pyi @@ -313,3 +313,11 @@ class Context(Protocol): TOD(q3k): document """ pass + def scope(self) -> "Context": + """ + Draw an audio 'oscilloscope'-style visualizer at -120,-120,120,120 + bounding box. + + Needs to be stroked/filled afterwards. + """ + pass diff --git a/python_payload/mypystubs/hardware.pyi b/python_payload/mypystubs/hardware.pyi deleted file mode 100644 index 57de5ae57b1b028533bf9e3ba301d96a7557d6ee..0000000000000000000000000000000000000000 --- a/python_payload/mypystubs/hardware.pyi +++ /dev/null @@ -1,26 +0,0 @@ -import time - -from ctx import Context - -def freertos_sleep(ms: int) -> None: ... -def get_ctx() -> Context: ... -def display_pipe_full() -> bool: ... -def display_pipe_flush() -> None: ... -def display_update(c: Context) -> None: ... -def display_set_backlight(percent: int) -> None: ... -def usb_connected() -> bool: ... -def usb_console_active() -> bool: ... -def version() -> str: ... -def i2c_scan() -> list[int]: ... -def menu_button_get() -> int: ... -def application_button_get() -> int: ... -def left_button_get() -> int: ... -def right_button_get() -> int: ... -def menu_button_set_left(left: int) -> None: ... -def menu_button_get_left() -> int: ... -def scope_draw(ctx: Context) -> None: ... - -BUTTON_PRESSED_LEFT: int -BUTTON_PRESSED_RIGHT: int -BUTTON_PRESSED_DOWN: int -BUTTON_NOT_PRESSED: int diff --git a/python_payload/mypystubs/kernel.pyi b/python_payload/mypystubs/kernel.pyi index 95e1ab33de9d0b7c76f50b1cb4423265f45fa4f6..a737a3059f634399587364bc9922f1f93213a3d5 100644 --- a/python_payload/mypystubs/kernel.pyi +++ b/python_payload/mypystubs/kernel.pyi @@ -64,3 +64,10 @@ BLOCKED: int SUSPENDED: int DELETED: int INVALID: int + +def freertos_sleep(ms: int) -> None: ... +def usb_connected() -> bool: ... +def usb_console_active() -> bool: ... +def hardware_version() -> str: ... +def firmware_version() -> str: ... +def i2c_scan() -> list[int]: ... diff --git a/python_payload/mypystubs/sys_buttons.pyi b/python_payload/mypystubs/sys_buttons.pyi new file mode 100644 index 0000000000000000000000000000000000000000..4b3346a2106c0ceac5d9fa6744dbe5826e7024e1 --- /dev/null +++ b/python_payload/mypystubs/sys_buttons.pyi @@ -0,0 +1,7 @@ +def get_left() -> int: ... +def get_right() -> int: ... + +PRESSED_LEFT: int +PRESSED_RIGHT: int +PRESSED_DOWN: int +NOT_PRESSED: int diff --git a/python_payload/mypystubs/sys_display.pyi b/python_payload/mypystubs/sys_display.pyi new file mode 100644 index 0000000000000000000000000000000000000000..38e4e6325c14990a7d108f61b09d7cf4a68a04c1 --- /dev/null +++ b/python_payload/mypystubs/sys_display.pyi @@ -0,0 +1,7 @@ +from ctx import Context + +def get_ctx() -> Context: ... +def pipe_full() -> bool: ... +def pipe_flush() -> None: ... +def update(c: Context) -> None: ... +def set_backlight(percent: int) -> None: ... diff --git a/python_payload/st3m/input.py b/python_payload/st3m/input.py index a1fdbbc5e5d62547bce3a1c826d061cfe1d267f3..99dafd6b7f8a83f3ce129b71dcbe885544636871 100644 --- a/python_payload/st3m/input.py +++ b/python_payload/st3m/input.py @@ -1,6 +1,6 @@ from st3m.goose import List, Optional, Enum, Tuple -import hardware +import sys_buttons import captouch import imu from st3m.power import Power @@ -53,6 +53,11 @@ class InputButtonState: __slots__ = ("app", "os", "_left", "_right", "app_is_left") + PRESSED_LEFT = sys_buttons.PRESSED_LEFT + PRESSED_RIGHT = sys_buttons.PRESSED_RIGHT + PRESSED_DOWN = sys_buttons.PRESSED_DOWN + NOT_PRESSED = sys_buttons.NOT_PRESSED + def __init__(self, left: int, right: int, swapped: bool): app = left os = right @@ -96,8 +101,8 @@ class InputState: Reactor. """ cts = captouch.read() - left = hardware.left_button_get() - right = hardware.right_button_get() + left = sys_buttons.get_left() + right = sys_buttons.get_right() buttons = InputButtonState(left, right, swapped_buttons) acc = imu.acc_read() diff --git a/python_payload/st3m/reactor.py b/python_payload/st3m/reactor.py index b24384d8dd7778ed5564ec9ecfeae739dc4f5e4d..3094719097f96919f6cdd71c0e7ee3bf774c8861 100644 --- a/python_payload/st3m/reactor.py +++ b/python_payload/st3m/reactor.py @@ -2,7 +2,9 @@ from st3m.goose import ABCBase, abstractmethod, List, Optional from st3m.input import InputState from ctx import Context -import time, hardware +import time +import sys_display +import kernel class Responder(ABCBase): @@ -126,7 +128,7 @@ class Reactor: self.stats.record_run_time(elapsed) wait = deadline - end if wait > 0: - hardware.freertos_sleep(wait) + kernel.freertos_sleep(wait) def _run_top(self, start: int) -> None: # Skip if we have no top Responder. @@ -148,7 +150,7 @@ class Reactor: # Draw! if self._ctx is None: - self._ctx = hardware.get_ctx() + self._ctx = sys_display.get_ctx() if self._ctx is not None: if self._last_ctx_get is not None: diff = start - self._last_ctx_get @@ -158,6 +160,6 @@ class Reactor: self._ctx.save() self._top.draw(self._ctx) self._ctx.restore() - if self._ctx is not None and not hardware.display_pipe_full(): - hardware.display_update(self._ctx) + if self._ctx is not None and not sys_display.pipe_full(): + sys_display.update(self._ctx) self._ctx = None diff --git a/python_payload/st3m/ui/elements/overlays.py b/python_payload/st3m/ui/elements/overlays.py index aa6ca04944f81c068eb4c0966808a01daacd4594..47a1fcabb8f4520bf4d6d8243390ac26f9c0ac94 100644 --- a/python_payload/st3m/ui/elements/overlays.py +++ b/python_payload/st3m/ui/elements/overlays.py @@ -13,7 +13,7 @@ from ctx import Context import math import audio -import hardware +import kernel class OverlayKind(Enum): @@ -343,7 +343,7 @@ class USBIcon(Icon): """ def visible(self) -> bool: - return hardware.usb_connected() + return kernel.usb_connected() def draw(self, ctx: Context) -> None: ctx.gray(1.0) diff --git a/sim/fakes/hardware.py b/sim/fakes/_sim.py similarity index 93% rename from sim/fakes/hardware.py rename to sim/fakes/_sim.py index 12637406fd6a64a80ff71220ad01f5c3c1c0866a..68101a8cb4c433c8d3e4e644d82ae3a87b39edbe 100644 --- a/sim/fakes/hardware.py +++ b/sim/fakes/_sim.py @@ -440,10 +440,6 @@ class Simulation: _sim = Simulation() -def init_done(): - return True - - import ctx @@ -501,14 +497,6 @@ def display_update(subctx): fbm.put(fbp, c) -def display_pipe_full(): - return False - - -def set_global_volume_dB(a): - pass - - def get_button_state(left): _sim.process_events() _sim.render_gui_lazy() @@ -528,64 +516,3 @@ def get_button_state(left): elif sub[2]: return +1 return 0 - - -menu_button_left = 0 - - -def menu_button_get(): - return get_button_state(menu_button_left) - - -def application_button_get(): - return get_button_state(1 - menu_button_left) - - -def left_button_get(): - return get_button_state(1) - - -def right_button_get(): - return get_button_state(0) - - -def menu_button_set_left(_broken): - global menu_button_left - menu_button_left = 1 - - -def menu_button_get_left(): - return menu_button_left - - -def freertos_sleep(ms): - import _time - - _time.sleep(ms / 1000.0) - - -def scope_draw(ctx): - import math - - x = -120 - ctx.move_to(x, 0) - for i in range(240): - x2 = x + i - y2 = math.sin(i / 10) * 80 - ctx.line_to(x2, y2) - ctx.line_to(130, 0) - ctx.line_to(130, 130) - ctx.line_to(-130, 130) - ctx.line_to(-130, 0) - - -def usb_connected(): - return True - - -def usb_console_active(): - return True - - -def i2c_scan(): - return [16, 44, 45, 85, 109, 110] diff --git a/sim/fakes/captouch.py b/sim/fakes/captouch.py index 19dea2197a66bcba9df4bd5503b00c887eacf2e2..028384fbd9e9915c318091511c69fc6e0e009cf7 100644 --- a/sim/fakes/captouch.py +++ b/sim/fakes/captouch.py @@ -67,11 +67,11 @@ class CaptouchState: def read() -> CaptouchState: - import hardware + import _sim - hardware._sim.process_events() - hardware._sim.render_gui_lazy() - petals = hardware._sim.petals + _sim._sim.process_events() + _sim._sim.render_gui_lazy() + petals = _sim._sim.petals res = [] for petal in range(10): diff --git a/sim/fakes/ctx.py b/sim/fakes/ctx.py index 845d0fe4c127f458f9715d913d1d3c1cb70d9083..a6b65efca30cee150b1d93234ed004d0484ce999 100644 --- a/sim/fakes/ctx.py +++ b/sim/fakes/ctx.py @@ -6,6 +6,7 @@ serialized ctx protocol as described in [1]. [1] - https://ctx.graphics/protocol/ """ import os +import math import wasmer import wasmer_compiler_cranelift @@ -285,3 +286,16 @@ class Context: "Camp Font 3", "Material Icons", ][i] + + def scope(self): + x = -120 + self.move_to(x, 0) + for i in range(240): + x2 = x + i + y2 = math.sin(i / 10) * 80 + self.line_to(x2, y2) + self.line_to(130, 0) + self.line_to(130, 130) + self.line_to(-130, 130) + self.line_to(-130, 0) + return self diff --git a/sim/fakes/kernel.py b/sim/fakes/kernel.py index 25fe328f2ac239c9d0bfc6a54ebc17dad6f6c5ce..4f33a799c9d4675a8e58bab32b80a0e4b4941013 100644 --- a/sim/fakes/kernel.py +++ b/sim/fakes/kernel.py @@ -13,3 +13,21 @@ class FakeHeapStats: def heap_stats(): return FakeHeapStats() + + +def usb_connected(): + return True + + +def usb_console_active(): + return True + + +def freertos_sleep(ms): + import _time + + _time.sleep(ms / 1000.0) + + +def i2c_scan(): + return [16, 44, 45, 85, 109, 110] diff --git a/sim/fakes/leds.py b/sim/fakes/leds.py index ff13695998890c85ff3a35db762993e4359c058e..2235346c62956db4f053684515941c2eb53c68a4 100644 --- a/sim/fakes/leds.py +++ b/sim/fakes/leds.py @@ -1,4 +1,4 @@ -from hardware import _sim +from _sim import _sim import pygame diff --git a/sim/fakes/sys_buttons.py b/sim/fakes/sys_buttons.py new file mode 100644 index 0000000000000000000000000000000000000000..46e4aef28dc6d13f5490367c4459ef99d57d3701 --- /dev/null +++ b/sim/fakes/sys_buttons.py @@ -0,0 +1,15 @@ +import _sim + + +def get_left(): + return _sim.get_button_state(1) + + +def get_right(): + return _sim.get_button_state(0) + + +PRESSED_LEFT = -1 +PRESSED_RIGHT = 1 +PRESSED_DOWN = 2 +NOT_PRESSED = 0 diff --git a/sim/fakes/sys_display.py b/sim/fakes/sys_display.py new file mode 100644 index 0000000000000000000000000000000000000000..3180dc2030586d54a34a7a969254a369cec45424 --- /dev/null +++ b/sim/fakes/sys_display.py @@ -0,0 +1,9 @@ +import _sim + + +def pipe_full(): + return False + + +update = _sim.display_update +get_ctx = _sim.get_ctx diff --git a/sim/run.py b/sim/run.py index 8da91ef535ded29c6deb630037505508d8f8ec97..b07e31245b21ef2ad44ba3d5357c4c42a0a62c0c 100644 --- a/sim/run.py +++ b/sim/run.py @@ -108,9 +108,9 @@ def _stat(path): os.stat = _stat if len(sys.argv) >= 2 and sys.argv[1] == "screenshot": - import hardware + import _sim - hardware.SCREENSHOT = True + _sim.SCREENSHOT = True elif len(sys.argv) == 2: import st3m.run