From 75560ea038746df91c6effeb38a9e85807e87a0a Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Wed, 20 Jan 2021 15:59:48 +0000 Subject: [PATCH 01/13] Added outline of an mpy wrapper for pico_display --- drivers/st7789/st7789.cpp | 2 +- drivers/st7789/st7789.hpp | 8 +- examples/pico_display/demo.cpp | 1 + libraries/pico_display/pico_display.cpp | 20 ++- libraries/pico_display/pico_display.hpp | 22 +-- libraries/pico_graphics/pico_graphics.hpp | 5 +- .../modules/pico_display/micropython.mk | 6 + .../modules/pico_display/pico_display.c | 84 ++++++++++ .../modules/pico_display/pico_display.cpp | 150 ++++++++++++++++++ .../modules/pico_display/pico_display.h | 31 ++++ 10 files changed, 309 insertions(+), 20 deletions(-) create mode 100755 micropython/modules/pico_display/micropython.mk create mode 100755 micropython/modules/pico_display/pico_display.c create mode 100644 micropython/modules/pico_display/pico_display.cpp create mode 100644 micropython/modules/pico_display/pico_display.h diff --git a/drivers/st7789/st7789.cpp b/drivers/st7789/st7789.cpp index bd412252..251e8e90 100644 --- a/drivers/st7789/st7789.cpp +++ b/drivers/st7789/st7789.cpp @@ -140,7 +140,7 @@ namespace pimoroni { // gamma correct the provided 0-255 brightness value onto a // 0-65535 range for the pwm counter float gamma = 2.8; - uint16_t value = (uint16_t)(pow((float)(brightness) / 255.0f, gamma) * 65536.0f + 0.5f); + uint16_t value = (uint16_t)(pow((float)(brightness) / 255.0f, gamma) * 65535.0f + 0.5f); pwm_set_gpio_level(bl, value); } diff --git a/drivers/st7789/st7789.hpp b/drivers/st7789/st7789.hpp index a2ee83ff..d4b62bff 100644 --- a/drivers/st7789/st7789.hpp +++ b/drivers/st7789/st7789.hpp @@ -16,11 +16,11 @@ namespace pimoroni { uint16_t row_stride; // interface pins with our standard defaults where appropriate + int8_t cs = 17; + int8_t dc = 16; int8_t sck = 18; int8_t mosi = 19; int8_t miso = -1; // we generally don't use this pin - int8_t cs = 17; - int8_t dc = 16; int8_t bl = 20; int8_t vsync = -1; // only available on some products @@ -37,9 +37,9 @@ namespace pimoroni { ST7789(uint16_t width, uint16_t height, uint16_t *frame_buffer, spi_inst_t *spi, uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = -1) : - width(width), height(height), frame_buffer(frame_buffer), spi(spi), - cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso) {} + width(width), height(height), + cs(cs), dc(dc), sck(sck), mosi(mosi), miso(miso), frame_buffer(frame_buffer) {} void init(bool auto_init_sequence = true); diff --git a/examples/pico_display/demo.cpp b/examples/pico_display/demo.cpp index 2a2659c8..92cc217b 100644 --- a/examples/pico_display/demo.cpp +++ b/examples/pico_display/demo.cpp @@ -70,6 +70,7 @@ void sprite(uint8_t *p, int x, int y, bool flip, uint16_t c) { }*/ int main() { + pico_display.init(); pico_display.set_backlight(100); // uint16_t white = pico_display.create_pen(255, 255, 255); diff --git a/libraries/pico_display/pico_display.cpp b/libraries/pico_display/pico_display.cpp index c8906c1d..fa9c94a0 100644 --- a/libraries/pico_display/pico_display.cpp +++ b/libraries/pico_display/pico_display.cpp @@ -1,4 +1,5 @@ #include +#include #include "hardware/pwm.h" @@ -11,8 +12,11 @@ const uint8_t LED_B = 8; namespace pimoroni { PicoDisplay::PicoDisplay() - : screen(240, 135, __fb), PicoGraphics(240, 135, __fb) { + : PicoGraphics(WIDTH, HEIGHT, __fb), screen(WIDTH, HEIGHT, __fb) { + memset(__fb, 0, sizeof(__fb)); + } + void PicoDisplay::init() { // setup the rgb led for pwm control pwm_config cfg = pwm_get_default_config(); pwm_config_set_output_polarity(&cfg, true, true); @@ -42,6 +46,14 @@ namespace pimoroni { screen.init(); } + void PicoDisplay::update() { + screen.update(); + } + + void PicoDisplay::set_backlight(uint8_t brightness) { + screen.set_backlight(brightness); + } + void PicoDisplay::set_led(uint8_t r, uint8_t g, uint8_t b) { // gamma correct the provided 0-255 brightness value onto a // 0-65535 range for the pwm counter @@ -50,15 +62,15 @@ namespace pimoroni { uint16_t value; // red - value = (uint16_t)(pow((float)(r) / 255.0f, gamma) * 65536.0f + 0.5f); + value = (uint16_t)(pow((float)(r) / 255.0f, gamma) * 65535.0f + 0.5f); pwm_set_gpio_level(LED_R, value); // green - value = (uint16_t)(pow((float)(g) / 255.0f, gamma) * 65536.0f + 0.5f); + value = (uint16_t)(pow((float)(g) / 255.0f, gamma) * 65535.0f + 0.5f); pwm_set_gpio_level(LED_G, value); // blue - value = (uint16_t)(pow((float)(b) / 255.0f, gamma) * 65536.0f + 0.5f); + value = (uint16_t)(pow((float)(b) / 255.0f, gamma) * 65535.0f + 0.5f); pwm_set_gpio_level(LED_B, value); } diff --git a/libraries/pico_display/pico_display.hpp b/libraries/pico_display/pico_display.hpp index b1c53d66..e9060b19 100644 --- a/libraries/pico_display/pico_display.hpp +++ b/libraries/pico_display/pico_display.hpp @@ -6,22 +6,26 @@ namespace pimoroni { class PicoDisplay : public PicoGraphics { - uint16_t __fb[240 * 135]; + public: + static const int WIDTH = 240; + static const int HEIGHT = 135; + static const uint8_t A = 12; + static const uint8_t B = 13; + static const uint8_t X = 14; + static const uint8_t Y = 15; + + private: + uint16_t __fb[WIDTH * HEIGHT]; ST7789 screen; public: PicoDisplay(); - void set_backlight(uint8_t brightness) {screen.set_backlight(brightness);} - void update() {screen.update();} - + void init(); + void update(); + void set_backlight(uint8_t brightness); void set_led(uint8_t r, uint8_t g, uint8_t b); bool is_pressed(uint8_t button); - - static const uint8_t A = 12; - static const uint8_t B = 13; - static const uint8_t X = 14; - static const uint8_t Y = 15; }; } \ No newline at end of file diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index 2aef657e..de3b133b 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -39,11 +40,11 @@ namespace pimoroni { class PicoGraphics { public: + uint16_t *frame_buffer; + rect bounds; rect clip; - uint16_t *frame_buffer; - uint16_t pen; public: diff --git a/micropython/modules/pico_display/micropython.mk b/micropython/modules/pico_display/micropython.mk new file mode 100755 index 00000000..a6faed27 --- /dev/null +++ b/micropython/modules/pico_display/micropython.mk @@ -0,0 +1,6 @@ +DISPLAY_MOD_DIR := $(USERMOD_DIR) +# Add all C files to SRC_USERMOD. +SRC_USERMOD += $(DISPLAY_MOD_DIR)/pico_display.c +# # We can add our module folder to include paths if needed +# # This is not actually needed in this example. +CFLAGS_USERMOD += -I$(DISPLAY_MOD_DIR) diff --git a/micropython/modules/pico_display/pico_display.c b/micropython/modules/pico_display/pico_display.c new file mode 100755 index 00000000..13122696 --- /dev/null +++ b/micropython/modules/pico_display/pico_display.c @@ -0,0 +1,84 @@ +#include "pico_display.h" + +/***** Constants *****/ +enum buttons +{ + BUTTON_A = 0, + BUTTON_B, + BUTTON_X, + BUTTON_Y, +}; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// picodisplay Module +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/***** Module Functions *****/ +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_init_obj, picodisplay_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_width_obj, picodisplay_get_width); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_height_obj, picodisplay_get_height); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_update_obj, picodisplay_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_backlight_obj, picodisplay_set_backlight); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_led_obj, picodisplay_set_led); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_is_pressed_obj, picodisplay_is_pressed); + +//From PicoGraphics parent class +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_pen_rgb_obj, picodisplay_set_pen_rgb); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_pen_obj, picodisplay_set_pen); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_create_pen_obj, picodisplay_create_pen); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_clip_obj, picodisplay_set_clip); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_remove_clip_obj, picodisplay_remove_clip); +//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr); +//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr); +//STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_ptr_obj, picodisplay_ptr); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_clear_obj, picodisplay_clear); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_pixel_obj, picodisplay_pixel); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_pixel_span_obj, picodisplay_pixel_span); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_rectangle_obj, picodisplay_rectangle); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_circle_obj, picodisplay_circle); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_text_obj, picodisplay_text); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_character_obj, picodisplay_character); + + +/***** Globals Table *****/ +STATIC const mp_map_elem_t picodisplay_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picodisplay) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picodisplay_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picodisplay_get_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picodisplay_get_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picodisplay_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&picodisplay_set_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_led), MP_ROM_PTR(&picodisplay_set_led_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picodisplay_is_pressed_obj) }, + + { MP_ROM_QSTR(MP_QSTR_set_pen_rgb), MP_ROM_PTR(&picodisplay_set_pen_rgb_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&picodisplay_set_pen_obj) }, + { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&picodisplay_create_pen_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&picodisplay_set_clip_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove_clip), MP_ROM_PTR(&picodisplay_remove_clip_obj) }, + // + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picodisplay_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&picodisplay_pixel_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_span), MP_ROM_PTR(&picodisplay_pixel_span_obj) }, + { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&picodisplay_rectangle_obj) }, + { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&picodisplay_circle_obj) }, + { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&picodisplay_text_obj) }, + { MP_ROM_QSTR(MP_QSTR_character), MP_ROM_PTR(&picodisplay_character_obj) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_Y), MP_ROM_INT(BUTTON_Y) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_picodisplay_globals, picodisplay_globals_table); + +/***** Module Definition *****/ +const mp_obj_module_t picodisplay_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_picodisplay_globals, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +MP_REGISTER_MODULE(MP_QSTR_picodisplay, picodisplay_user_cmodule, MODULE_PICODISPLAY_ENABLED); +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp new file mode 100644 index 00000000..c3e4f75d --- /dev/null +++ b/micropython/modules/pico_display/pico_display.cpp @@ -0,0 +1,150 @@ +#include "hardware/spi.h" +#include "hardware/sync.h" +#include "pico/binary_info.h" + +#include "../../../pimoroni-pico/libraries/pico_display/pico_display.hpp" + +using namespace pimoroni; + +PicoDisplay display; + + +extern "C" { +#include "pico_display.h" + +mp_obj_t picodisplay_init() { + display.init(); + return mp_const_none; +} + +mp_obj_t picodisplay_get_width() { + return mp_obj_new_int(PicoDisplay::WIDTH); +} + +mp_obj_t picodisplay_get_height() { + return mp_obj_new_int(PicoDisplay::HEIGHT); +} + +mp_obj_t picodisplay_update() { + display.update(); + return mp_const_none; +} + +mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj) { + float brightness = mp_obj_get_float(brightness_obj); + + if(brightness < 0 || brightness > 1.0f) + mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0"); + else + display.set_backlight((uint8_t)(brightness * 255.0f)); + + return mp_const_none; +} + +mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { + int r = mp_obj_get_int(r_obj); + int g = mp_obj_get_int(g_obj); + int b = mp_obj_get_int(b_obj); + + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + display.set_led(r, g, b); + + return mp_const_none; +} + +mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj) { + int buttonID = mp_obj_get_int(button_obj); + + bool buttonPressed = false; + switch(buttonID) + { + case 0: + buttonPressed = display.is_pressed(PicoDisplay::A); + break; + + case 1: + buttonPressed = display.is_pressed(PicoDisplay::B); + break; + + case 2: + buttonPressed = display.is_pressed(PicoDisplay::X); + break; + + case 3: + buttonPressed = display.is_pressed(PicoDisplay::Y); + break; + + default: + mp_raise_ValueError("button not valid. Expected 0 to 3"); + break; + } + + return buttonPressed ? mp_const_true : mp_const_false; +} + +mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_set_pen(mp_obj_t p_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_set_clip(mp_obj_t r_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_remove_clip() { + return mp_const_none; +} + +// mp_obj_t picodisplay_ptr(mp_obj_t p_obj) { +// return mp_const_none; +// } + +// mp_obj_t picodisplay_ptr(mp_obj_t r_obj) { +// return mp_const_none; +// } + +// mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj) { +// return mp_const_none; +// } + +mp_obj_t picodisplay_clear() { + return mp_const_none; +} + +mp_obj_t picodisplay_pixel(mp_obj_t p_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_rectangle(mp_obj_t r_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj) { + return mp_const_none; +} + +mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj) { + return mp_const_none; +} +} \ No newline at end of file diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h new file mode 100644 index 00000000..5e60033b --- /dev/null +++ b/micropython/modules/pico_display/pico_display.h @@ -0,0 +1,31 @@ +// Include MicroPython API. +#include "py/runtime.h" + +// Declare the functions we'll make available in Python +extern mp_obj_t picodisplay_init(); +extern mp_obj_t picodisplay_get_width(); +extern mp_obj_t picodisplay_get_height(); +extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj); +extern mp_obj_t picodisplay_update(); +extern mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); +extern mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj); + +// From PicoGraphics parent class +extern mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); +extern mp_obj_t picodisplay_set_pen(mp_obj_t p_obj); +extern mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); + +extern mp_obj_t picodisplay_set_clip(mp_obj_t r_obj); +extern mp_obj_t picodisplay_remove_clip(); + +//extern mp_obj_t picodisplay_ptr(mp_obj_t p_obj); +//extern mp_obj_t picodisplay_ptr(mp_obj_t r_obj); +//extern mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj); + +extern mp_obj_t picodisplay_clear(); +extern mp_obj_t picodisplay_pixel(mp_obj_t p_obj); +extern mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj); +extern mp_obj_t picodisplay_rectangle(mp_obj_t r_obj); +extern mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj); +extern mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj); +extern mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj); \ No newline at end of file From 9a7687fd6c7c28ae57d711dbebf3c6bcae0dd720 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 20 Jan 2021 15:19:38 +0000 Subject: [PATCH 02/13] Add usermod.cmake files for building against upstream usermod micropython usermod branch Only *one* usermod directory can be specified, so the build command becomes something like: make USER_C_MODULES=/path/to/pimoroni-pico/micropython/modules/ The `usermod.cmake` in the "modules" dir will then include all of the modules. Comment lines our here to disable them. No need to configure anythign in `mpconfigport.h` since the defines are set by the `usermod.cmake` files. --- .../modules/pico_rgb_keypad/usermod.cmake | 17 +++++++++++++++++ micropython/modules/pico_scroll/usermod.cmake | 17 +++++++++++++++++ .../modules/pico_unicorn/usermod.cmake | 19 +++++++++++++++++++ micropython/modules/usermod.cmake | 3 +++ 4 files changed, 56 insertions(+) create mode 100644 micropython/modules/pico_rgb_keypad/usermod.cmake create mode 100644 micropython/modules/pico_scroll/usermod.cmake create mode 100644 micropython/modules/pico_unicorn/usermod.cmake create mode 100644 micropython/modules/usermod.cmake diff --git a/micropython/modules/pico_rgb_keypad/usermod.cmake b/micropython/modules/pico_rgb_keypad/usermod.cmake new file mode 100644 index 00000000..4d961684 --- /dev/null +++ b/micropython/modules/pico_rgb_keypad/usermod.cmake @@ -0,0 +1,17 @@ +add_library(usermod_pico_rgb_keypad INTERFACE) + +target_sources(usermod_pico_rgb_keypad INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad.c + ${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_rgb_keypad/pico_rgb_keypad.cpp +) + +target_include_directories(usermod_pico_rgb_keypad INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_pico_rgb_keypad INTERFACE + -DMODULE_PICOKEYPAD_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_pico_rgb_keypad) \ No newline at end of file diff --git a/micropython/modules/pico_scroll/usermod.cmake b/micropython/modules/pico_scroll/usermod.cmake new file mode 100644 index 00000000..2a79f81c --- /dev/null +++ b/micropython/modules/pico_scroll/usermod.cmake @@ -0,0 +1,17 @@ +add_library(usermod_pico_scroll INTERFACE) + +target_sources(usermod_pico_scroll INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_scroll.c + ${CMAKE_CURRENT_LIST_DIR}/pico_scroll.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_scroll/pico_scroll.cpp +) + +target_include_directories(usermod_pico_scroll INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_pico_scroll INTERFACE + -DMODULE_PICOSCROLL_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_pico_scroll) \ No newline at end of file diff --git a/micropython/modules/pico_unicorn/usermod.cmake b/micropython/modules/pico_unicorn/usermod.cmake new file mode 100644 index 00000000..3b59b135 --- /dev/null +++ b/micropython/modules/pico_unicorn/usermod.cmake @@ -0,0 +1,19 @@ +add_library(usermod_pico_unicorn INTERFACE) + +target_sources(usermod_pico_unicorn INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_unicorn.c + ${CMAKE_CURRENT_LIST_DIR}/pico_unicorn.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_unicorn/pico_unicorn.cpp +) + +pico_generate_pio_header(usermod_pico_unicorn ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_unicorn/pico_unicorn.pio) + +target_include_directories(usermod_pico_unicorn INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_pico_unicorn INTERFACE + -DMODULE_PICOUNICORN_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_pico_unicorn) \ No newline at end of file diff --git a/micropython/modules/usermod.cmake b/micropython/modules/usermod.cmake new file mode 100644 index 00000000..0183744c --- /dev/null +++ b/micropython/modules/usermod.cmake @@ -0,0 +1,3 @@ +include(${CMAKE_CURRENT_LIST_DIR}/pico_scroll/usermod.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad/usermod.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/pico_unicorn/usermod.cmake) \ No newline at end of file From 2030ff54a90a3aa645f2638f4263cbb1cefa78c3 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 20 Jan 2021 18:18:14 +0000 Subject: [PATCH 03/13] Add usermod.cmake for pico_display --- .../modules/pico_display/usermod.cmake | 21 +++++++++++++++++++ micropython/modules/usermod.cmake | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 micropython/modules/pico_display/usermod.cmake diff --git a/micropython/modules/pico_display/usermod.cmake b/micropython/modules/pico_display/usermod.cmake new file mode 100644 index 00000000..f3e7d813 --- /dev/null +++ b/micropython/modules/pico_display/usermod.cmake @@ -0,0 +1,21 @@ +add_library(usermod_pico_display INTERFACE) + +target_sources(usermod_pico_display INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_display.c + ${CMAKE_CURRENT_LIST_DIR}/pico_display.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_display/pico_display.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/st7789/st7789.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/types.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/font_data.cpp +) + +target_include_directories(usermod_pico_display INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_pico_display INTERFACE + -DMODULE_PICODISPLAY_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_pico_display) \ No newline at end of file diff --git a/micropython/modules/usermod.cmake b/micropython/modules/usermod.cmake index 0183744c..44191c83 100644 --- a/micropython/modules/usermod.cmake +++ b/micropython/modules/usermod.cmake @@ -1,3 +1,4 @@ include(${CMAKE_CURRENT_LIST_DIR}/pico_scroll/usermod.cmake) include(${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad/usermod.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/pico_unicorn/usermod.cmake) \ No newline at end of file +include(${CMAKE_CURRENT_LIST_DIR}/pico_unicorn/usermod.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/pico_display/usermod.cmake) \ No newline at end of file From 84e98b7040eba08be73a69582b40c4b87c202402 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Wed, 20 Jan 2021 21:05:07 +0000 Subject: [PATCH 04/13] Completed mpy wrapper for pico_display, and included example --- libraries/pico_graphics/pico_graphics.cpp | 4 +- libraries/pico_graphics/pico_graphics.hpp | 4 +- micropython/examples/pico_display/demo.py | 49 ++++++ .../modules/pico_display/pico_display.c | 24 +-- .../modules/pico_display/pico_display.cpp | 154 +++++++++++++++--- .../modules/pico_display/pico_display.h | 24 +-- 6 files changed, 200 insertions(+), 59 deletions(-) create mode 100644 micropython/examples/pico_display/demo.py diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index 6e2a8465..803068a4 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -131,11 +131,9 @@ namespace pimoroni { } } - void PicoGraphics::text(const std::string &t, const point &p, int32_t wrap) { + void PicoGraphics::text(const std::string &t, const point &p, int32_t wrap, uint8_t scale) { uint32_t co = 0, lo = 0; // character and line (if wrapping) offset - uint8_t scale = 2; - size_t i = 0; while(i < t.length()) { // find length of current word diff --git a/libraries/pico_graphics/pico_graphics.hpp b/libraries/pico_graphics/pico_graphics.hpp index de3b133b..545ac9e5 100644 --- a/libraries/pico_graphics/pico_graphics.hpp +++ b/libraries/pico_graphics/pico_graphics.hpp @@ -67,8 +67,8 @@ namespace pimoroni { void pixel_span(const point &p, int32_t l); void rectangle(const rect &r); void circle(const point &p, int32_t r); - void text(const std::string &t, const point &p, int32_t wrap); - void character(const char c, const point &p, uint8_t scale); + void character(const char c, const point &p, uint8_t scale = 2); + void text(const std::string &t, const point &p, int32_t wrap, uint8_t scale = 2); //void polygon(std::vector); }; diff --git a/micropython/examples/pico_display/demo.py b/micropython/examples/pico_display/demo.py new file mode 100644 index 00000000..9236d0b3 --- /dev/null +++ b/micropython/examples/pico_display/demo.py @@ -0,0 +1,49 @@ +import time, random +import picodisplay as display +display.init() +display.set_backlight(1.0) +i = 0 +width = display.get_width() +height = display.get_height() + +class Ball: + def __init__(self, x, y, r, dx, dy, pen): + self.x = x + self.y = y + self.r = r + self.dx = dx + self.dy = dy + self.pen = pen + +# initialise shapes +balls = [] +for i in range(0, 100): + balls.append( + Ball( + random.randint(0, width), + random.randint(0, height), + random.randint(0, 10) + 3, + random.randint(0, 255) / 128, + random.randint(0, 255) / 128, + display.create_pen(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)), + ) + ) + +while True: + display.set_pen(120, 40, 60) + display.clear() + + for ball in balls: + ball.x += ball.dx + ball.y += ball.dy + + if ball.x < 0 or ball.x > width: + ball.dx *= -1 + if ball.y < 0 or ball.y > height: + ball.dy *= -1 + + display.set_pen(ball.pen) + display.circle(int(ball.x), int(ball.y), int(ball.r)) + + display.update() + time.sleep(0.01) \ No newline at end of file diff --git a/micropython/modules/pico_display/pico_display.c b/micropython/modules/pico_display/pico_display.c index 13122696..f096c17d 100755 --- a/micropython/modules/pico_display/pico_display.c +++ b/micropython/modules/pico_display/pico_display.c @@ -24,21 +24,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_led_obj, picodisplay_set_led); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_is_pressed_obj, picodisplay_is_pressed); //From PicoGraphics parent class -STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_set_pen_rgb_obj, picodisplay_set_pen_rgb); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_pen_obj, picodisplay_set_pen); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picodisplay_set_pen_obj, 1, 3, picodisplay_set_pen); STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_create_pen_obj, picodisplay_create_pen); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_set_clip_obj, picodisplay_set_clip); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picodisplay_set_clip_obj, 4, 4, picodisplay_set_clip); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_remove_clip_obj, picodisplay_remove_clip); -//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr); -//STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_ptr_obj, picodisplay_ptr); -//STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_ptr_obj, picodisplay_ptr); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_clear_obj, picodisplay_clear); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_pixel_obj, picodisplay_pixel); -STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_pixel_span_obj, picodisplay_pixel_span); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_rectangle_obj, picodisplay_rectangle); -STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_circle_obj, picodisplay_circle); -STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_text_obj, picodisplay_text); -STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_character_obj, picodisplay_character); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(picodisplay_pixel_obj, picodisplay_pixel); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_pixel_span_obj, picodisplay_pixel_span); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picodisplay_rectangle_obj, 4, 4, picodisplay_rectangle); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picodisplay_circle_obj, picodisplay_circle); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picodisplay_character_obj, 3, 4, picodisplay_character); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picodisplay_text_obj, 4, 5, picodisplay_text); /***** Globals Table *****/ @@ -52,19 +48,17 @@ STATIC const mp_map_elem_t picodisplay_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_set_led), MP_ROM_PTR(&picodisplay_set_led_obj) }, { MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picodisplay_is_pressed_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_pen_rgb), MP_ROM_PTR(&picodisplay_set_pen_rgb_obj) }, { MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&picodisplay_set_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&picodisplay_create_pen_obj) }, { MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&picodisplay_set_clip_obj) }, { MP_ROM_QSTR(MP_QSTR_remove_clip), MP_ROM_PTR(&picodisplay_remove_clip_obj) }, - // { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picodisplay_clear_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&picodisplay_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_span), MP_ROM_PTR(&picodisplay_pixel_span_obj) }, { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&picodisplay_rectangle_obj) }, { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&picodisplay_circle_obj) }, - { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&picodisplay_text_obj) }, { MP_ROM_QSTR(MP_QSTR_character), MP_ROM_PTR(&picodisplay_character_obj) }, + { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&picodisplay_text_obj) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) }, diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index c3e4f75d..f2e45ca8 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -88,63 +88,169 @@ mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj) { return buttonPressed ? mp_const_true : mp_const_false; } -mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { - return mp_const_none; -} +mp_obj_t picodisplay_set_pen(mp_uint_t n_args, const mp_obj_t *args) { + switch(n_args) + { + case 1: { + int p = mp_obj_get_int(args[0]); + + if(p < 0 || p > 0xffff) + mp_raise_ValueError("p is not a valid pen."); + else + display.set_pen(p); + } break; + + case 3: { + int r = mp_obj_get_int(args[0]); + int g = mp_obj_get_int(args[1]); + int b = mp_obj_get_int(args[2]); + + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + display.set_pen(r, g, b); + } break; + + default: { + char *buffer; + buffer = (char*)malloc(100); + sprintf(buffer, "function takes 1 or 3 (r,g,b) positional arguments but %d were given", n_args); + mp_raise_TypeError(buffer); + } break; + } -mp_obj_t picodisplay_set_pen(mp_obj_t p_obj) { return mp_const_none; } mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { - return mp_const_none; + int r = mp_obj_get_int(r_obj); + int g = mp_obj_get_int(g_obj); + int b = mp_obj_get_int(b_obj); + + int pen = 0; + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + pen = display.create_pen(r, g, b); + + return mp_obj_new_int(pen); } -mp_obj_t picodisplay_set_clip(mp_obj_t r_obj) { +mp_obj_t picodisplay_set_clip(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 4 + + int x = mp_obj_get_int(args[0]); + int y = mp_obj_get_int(args[1]); + int w = mp_obj_get_int(args[2]); + int h = mp_obj_get_int(args[3]); + + rect r(x, y, w, h); + display.set_clip(r); + return mp_const_none; } mp_obj_t picodisplay_remove_clip() { + display.remove_clip(); return mp_const_none; } -// mp_obj_t picodisplay_ptr(mp_obj_t p_obj) { -// return mp_const_none; -// } - -// mp_obj_t picodisplay_ptr(mp_obj_t r_obj) { -// return mp_const_none; -// } - -// mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj) { -// return mp_const_none; -// } - mp_obj_t picodisplay_clear() { + display.clear(); return mp_const_none; } -mp_obj_t picodisplay_pixel(mp_obj_t p_obj) { +mp_obj_t picodisplay_pixel(mp_obj_t x_obj, mp_obj_t y_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + + point p(x, y); + display.pixel(p); + return mp_const_none; } -mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj) { +mp_obj_t picodisplay_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + int l = mp_obj_get_int(l_obj); + + point p(x, y); + display.pixel_span(p, l); + return mp_const_none; } -mp_obj_t picodisplay_rectangle(mp_obj_t r_obj) { +mp_obj_t picodisplay_rectangle(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 4 + + int x = mp_obj_get_int(args[0]); + int y = mp_obj_get_int(args[1]); + int w = mp_obj_get_int(args[2]); + int h = mp_obj_get_int(args[3]); + + rect r(x, y, w, h); + display.rectangle(r); + return mp_const_none; } -mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj) { +mp_obj_t picodisplay_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + int r = mp_obj_get_int(r_obj); + + point p(x, y); + display.circle(p, r); + return mp_const_none; } -mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj) { +mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args) { + + int c = mp_obj_get_int(args[0]); + int x = mp_obj_get_int(args[1]); + int y = mp_obj_get_int(args[2]); + + point p(x, y); + if(n_args == 4) { + int scale = mp_obj_get_int(args[3]); + display.character((char)c, p, scale); + } + else + display.character((char)c, p); + return mp_const_none; } -mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj) { +mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 4 + + mp_check_self(mp_obj_is_str_or_bytes(args[0])); + GET_STR_DATA_LEN(args[0], str, str_len); + + std::string t((const char*)str); + + int x = mp_obj_get_int(args[1]); + int y = mp_obj_get_int(args[2]); + int wrap = mp_obj_get_int(args[3]); + + point p(x, y); + if(n_args == 5) { + int scale = mp_obj_get_int(args[4]); + display.text(t, p, wrap, scale); + } + else + display.text(t, p, wrap); + return mp_const_none; } } \ No newline at end of file diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h index 5e60033b..526fdd12 100644 --- a/micropython/modules/pico_display/pico_display.h +++ b/micropython/modules/pico_display/pico_display.h @@ -1,5 +1,6 @@ // Include MicroPython API. #include "py/runtime.h" +#include "py/objstr.h" // Declare the functions we'll make available in Python extern mp_obj_t picodisplay_init(); @@ -11,21 +12,14 @@ extern mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_o extern mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj); // From PicoGraphics parent class -extern mp_obj_t picodisplay_set_pen_rgb(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); -extern mp_obj_t picodisplay_set_pen(mp_obj_t p_obj); +extern mp_obj_t picodisplay_set_pen(mp_uint_t n_args, const mp_obj_t *args); extern mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); - -extern mp_obj_t picodisplay_set_clip(mp_obj_t r_obj); +extern mp_obj_t picodisplay_set_clip(mp_uint_t n_args, const mp_obj_t *args); extern mp_obj_t picodisplay_remove_clip(); - -//extern mp_obj_t picodisplay_ptr(mp_obj_t p_obj); -//extern mp_obj_t picodisplay_ptr(mp_obj_t r_obj); -//extern mp_obj_t picodisplay_ptr(mp_obj_t x_obj, mp_obj_t y_obj); - extern mp_obj_t picodisplay_clear(); -extern mp_obj_t picodisplay_pixel(mp_obj_t p_obj); -extern mp_obj_t picodisplay_pixel_span(mp_obj_t p_obj, mp_obj_t l_obj); -extern mp_obj_t picodisplay_rectangle(mp_obj_t r_obj); -extern mp_obj_t picodisplay_circle(mp_obj_t p_obj, mp_obj_t r_obj); -extern mp_obj_t picodisplay_text(mp_obj_t t_obj, mp_obj_t p_obj, mp_obj_t wrap_obj); -extern mp_obj_t picodisplay_character(mp_obj_t c_obj, mp_obj_t p_obj, mp_obj_t scale_obj); \ No newline at end of file +extern mp_obj_t picodisplay_pixel(mp_obj_t x_obj, mp_obj_t y_obj); +extern mp_obj_t picodisplay_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj); +extern mp_obj_t picodisplay_rectangle(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picodisplay_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj); +extern mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args); \ No newline at end of file From 4f6691be8b75dea1f97b9106bd4596d3c54676e9 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 20 Jan 2021 18:21:53 +0000 Subject: [PATCH 05/13] Very messy attempt at using a bytearray as the buffer --- libraries/pico_display/pico_display.cpp | 6 ++-- libraries/pico_display/pico_display.hpp | 4 +-- libraries/pico_graphics/pico_graphics.cpp | 3 +- .../modules/pico_display/pico_display.c | 2 +- .../modules/pico_display/pico_display.cpp | 28 +++++++++++-------- .../modules/pico_display/pico_display.h | 2 +- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/libraries/pico_display/pico_display.cpp b/libraries/pico_display/pico_display.cpp index fa9c94a0..9810e84f 100644 --- a/libraries/pico_display/pico_display.cpp +++ b/libraries/pico_display/pico_display.cpp @@ -11,9 +11,9 @@ const uint8_t LED_B = 8; namespace pimoroni { - PicoDisplay::PicoDisplay() - : PicoGraphics(WIDTH, HEIGHT, __fb), screen(WIDTH, HEIGHT, __fb) { - memset(__fb, 0, sizeof(__fb)); + PicoDisplay::PicoDisplay(uint16_t *buf) + : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf) { + __fb = buf; } void PicoDisplay::init() { diff --git a/libraries/pico_display/pico_display.hpp b/libraries/pico_display/pico_display.hpp index e9060b19..152c6e7c 100644 --- a/libraries/pico_display/pico_display.hpp +++ b/libraries/pico_display/pico_display.hpp @@ -14,12 +14,12 @@ namespace pimoroni { static const uint8_t X = 14; static const uint8_t Y = 15; + uint16_t *__fb; private: - uint16_t __fb[WIDTH * HEIGHT]; ST7789 screen; public: - PicoDisplay(); + PicoDisplay(uint16_t *buf); void init(); void update(); diff --git a/libraries/pico_graphics/pico_graphics.cpp b/libraries/pico_graphics/pico_graphics.cpp index 803068a4..eba9f06d 100644 --- a/libraries/pico_graphics/pico_graphics.cpp +++ b/libraries/pico_graphics/pico_graphics.cpp @@ -18,8 +18,7 @@ namespace pimoroni { ((g & 0b11111100) << 3) | ((b & 0b11111000) >> 3); - // endian swap, this should be possible another way... - return ((p & 0xff00) >> 8) | ((p & 0xff) << 8); + return __builtin_bswap16(p); } void PicoGraphics::set_clip(const rect &r) { diff --git a/micropython/modules/pico_display/pico_display.c b/micropython/modules/pico_display/pico_display.c index f096c17d..7678d78f 100755 --- a/micropython/modules/pico_display/pico_display.c +++ b/micropython/modules/pico_display/pico_display.c @@ -15,7 +15,7 @@ enum buttons //////////////////////////////////////////////////////////////////////////////////////////////////// /***** Module Functions *****/ -STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_init_obj, picodisplay_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_init_obj, picodisplay_init); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_width_obj, picodisplay_get_width); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_height_obj, picodisplay_get_height); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_update_obj, picodisplay_update); diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index f2e45ca8..f8065e24 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -6,14 +6,20 @@ using namespace pimoroni; -PicoDisplay display; +PicoDisplay *display; extern "C" { #include "pico_display.h" -mp_obj_t picodisplay_init() { - display.init(); +mp_obj_t buf_obj; + +mp_obj_t picodisplay_init(mp_obj_t buf) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_RW); + buf_obj = buf; + display = new PicoDisplay((uint16_t *)bufinfo.buf); + display->init(); return mp_const_none; } @@ -26,7 +32,7 @@ mp_obj_t picodisplay_get_height() { } mp_obj_t picodisplay_update() { - display.update(); + display->update(); return mp_const_none; } @@ -36,7 +42,7 @@ mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj) { if(brightness < 0 || brightness > 1.0f) mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0"); else - display.set_backlight((uint8_t)(brightness * 255.0f)); + display->set_backlight((uint8_t)(brightness * 255.0f)); return mp_const_none; } @@ -53,7 +59,7 @@ mp_obj_t picodisplay_set_led(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { else if(b < 0 || b > 255) mp_raise_ValueError("b out of range. Expected 0 to 255"); else - display.set_led(r, g, b); + display->set_led(r, g, b); return mp_const_none; } @@ -65,19 +71,19 @@ mp_obj_t picodisplay_is_pressed(mp_obj_t button_obj) { switch(buttonID) { case 0: - buttonPressed = display.is_pressed(PicoDisplay::A); + buttonPressed = display->is_pressed(PicoDisplay::A); break; case 1: - buttonPressed = display.is_pressed(PicoDisplay::B); + buttonPressed = display->is_pressed(PicoDisplay::B); break; case 2: - buttonPressed = display.is_pressed(PicoDisplay::X); + buttonPressed = display->is_pressed(PicoDisplay::X); break; case 3: - buttonPressed = display.is_pressed(PicoDisplay::Y); + buttonPressed = display->is_pressed(PicoDisplay::Y); break; default: @@ -253,4 +259,4 @@ mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args) { return mp_const_none; } -} \ No newline at end of file +} diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h index 526fdd12..3201df89 100644 --- a/micropython/modules/pico_display/pico_display.h +++ b/micropython/modules/pico_display/pico_display.h @@ -3,7 +3,7 @@ #include "py/objstr.h" // Declare the functions we'll make available in Python -extern mp_obj_t picodisplay_init(); +extern mp_obj_t picodisplay_init(mp_obj_t buf); extern mp_obj_t picodisplay_get_width(); extern mp_obj_t picodisplay_get_height(); extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj); From 032d509d8edbbe3a0ace5d435409df329f0ddb6a Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 20 Jan 2021 21:31:52 +0000 Subject: [PATCH 06/13] Convert . to -> mostly --- .../modules/pico_display/pico_display.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index f8065e24..43afdc51 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -103,7 +103,7 @@ mp_obj_t picodisplay_set_pen(mp_uint_t n_args, const mp_obj_t *args) { if(p < 0 || p > 0xffff) mp_raise_ValueError("p is not a valid pen."); else - display.set_pen(p); + display->set_pen(p); } break; case 3: { @@ -118,7 +118,7 @@ mp_obj_t picodisplay_set_pen(mp_uint_t n_args, const mp_obj_t *args) { else if(b < 0 || b > 255) mp_raise_ValueError("b out of range. Expected 0 to 255"); else - display.set_pen(r, g, b); + display->set_pen(r, g, b); } break; default: { @@ -145,7 +145,7 @@ mp_obj_t picodisplay_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) else if(b < 0 || b > 255) mp_raise_ValueError("b out of range. Expected 0 to 255"); else - pen = display.create_pen(r, g, b); + pen = display->create_pen(r, g, b); return mp_obj_new_int(pen); } @@ -159,18 +159,18 @@ mp_obj_t picodisplay_set_clip(mp_uint_t n_args, const mp_obj_t *args) { int h = mp_obj_get_int(args[3]); rect r(x, y, w, h); - display.set_clip(r); + display->set_clip(r); return mp_const_none; } mp_obj_t picodisplay_remove_clip() { - display.remove_clip(); + display->remove_clip(); return mp_const_none; } mp_obj_t picodisplay_clear() { - display.clear(); + display->clear(); return mp_const_none; } @@ -179,7 +179,7 @@ mp_obj_t picodisplay_pixel(mp_obj_t x_obj, mp_obj_t y_obj) { int y = mp_obj_get_int(y_obj); point p(x, y); - display.pixel(p); + display->pixel(p); return mp_const_none; } @@ -190,7 +190,7 @@ mp_obj_t picodisplay_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj) int l = mp_obj_get_int(l_obj); point p(x, y); - display.pixel_span(p, l); + display->pixel_span(p, l); return mp_const_none; } @@ -204,7 +204,7 @@ mp_obj_t picodisplay_rectangle(mp_uint_t n_args, const mp_obj_t *args) { int h = mp_obj_get_int(args[3]); rect r(x, y, w, h); - display.rectangle(r); + display->rectangle(r); return mp_const_none; } @@ -215,7 +215,7 @@ mp_obj_t picodisplay_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) { int r = mp_obj_get_int(r_obj); point p(x, y); - display.circle(p, r); + display->circle(p, r); return mp_const_none; } @@ -229,10 +229,10 @@ mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args) { point p(x, y); if(n_args == 4) { int scale = mp_obj_get_int(args[3]); - display.character((char)c, p, scale); + display->character((char)c, p, scale); } else - display.character((char)c, p); + display->character((char)c, p); return mp_const_none; } @@ -252,10 +252,10 @@ mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args) { point p(x, y); if(n_args == 5) { int scale = mp_obj_get_int(args[4]); - display.text(t, p, wrap, scale); + display->text(t, p, wrap, scale); } else - display.text(t, p, wrap); + display->text(t, p, wrap); return mp_const_none; } From 5f4fed5a27084c9b303e6c4aea3d8c7483512df4 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Wed, 20 Jan 2021 23:35:33 +0000 Subject: [PATCH 07/13] Swiched picodisplay demo over to creating local frame buffer --- examples/pico_display/demo.cpp | 3 ++- micropython/modules/pico_display/pico_display.cpp | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/pico_display/demo.cpp b/examples/pico_display/demo.cpp index 92cc217b..86b0801c 100644 --- a/examples/pico_display/demo.cpp +++ b/examples/pico_display/demo.cpp @@ -10,7 +10,8 @@ using namespace pimoroni; extern unsigned char image_tif[]; extern unsigned int image_tif_len; -PicoDisplay pico_display; +uint16_t buffer[PicoDisplay::WIDTH * PicoDisplay::HEIGHT]; +PicoDisplay pico_display(buffer); /* void pixel(int x, int y, uint16_t c) { x *= 2; diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index 43afdc51..129b756c 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -221,7 +221,6 @@ mp_obj_t picodisplay_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) { } mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args) { - int c = mp_obj_get_int(args[0]); int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); @@ -238,8 +237,6 @@ mp_obj_t picodisplay_character(mp_uint_t n_args, const mp_obj_t *args) { } mp_obj_t picodisplay_text(mp_uint_t n_args, const mp_obj_t *args) { - (void)n_args; //Unused input parameter, we know it's 4 - mp_check_self(mp_obj_is_str_or_bytes(args[0])); GET_STR_DATA_LEN(args[0], str, str_len); From 7f05e35622d9ed056261827b4f8dfa847a4f61b5 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Wed, 20 Jan 2021 23:46:13 +0000 Subject: [PATCH 08/13] Attempt to allocate a bytearray behind the sCenes This rebuilds the crucial parts of MicroPython's bytearray creation and calls it quietly from inside the C-bindings, avoiding the need for a bytearray to be passed in by the user. Whether this magically holds a reference and evades GC remains to be seen. --- micropython/modules/pico_display/pico_display.c | 16 +++++++++++++++- .../modules/pico_display/pico_display.cpp | 8 +++----- micropython/modules/pico_display/pico_display.h | 4 +++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/micropython/modules/pico_display/pico_display.c b/micropython/modules/pico_display/pico_display.c index 7678d78f..bae8e178 100755 --- a/micropython/modules/pico_display/pico_display.c +++ b/micropython/modules/pico_display/pico_display.c @@ -1,4 +1,6 @@ #include "pico_display.h" +#include "py/binary.h" +#include "py/objarray.h" /***** Constants *****/ enum buttons @@ -9,13 +11,25 @@ enum buttons BUTTON_Y, }; +mp_obj_t alloc_new_bytearray(int len) { + int typecode_size = mp_binary_get_size('@', BYTEARRAY_TYPECODE, NULL); + mp_obj_array_t *o = m_new_obj(mp_obj_array_t); + o->base.type = &mp_type_bytearray; + o->typecode = BYTEARRAY_TYPECODE; + o->free = 0; + o->len = len; + o->items = m_new(byte, typecode_size * o->len); + memset(o->items, 0, len); + return MP_OBJ_FROM_PTR(o); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // picodisplay Module //////////////////////////////////////////////////////////////////////////////////////////////////// /***** Module Functions *****/ -STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_init_obj, picodisplay_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_init_obj, picodisplay_init); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_width_obj, picodisplay_get_width); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_height_obj, picodisplay_get_height); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_update_obj, picodisplay_update); diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index 43afdc51..69d0b96e 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -12,12 +12,10 @@ PicoDisplay *display; extern "C" { #include "pico_display.h" -mp_obj_t buf_obj; - -mp_obj_t picodisplay_init(mp_obj_t buf) { +mp_obj_t picodisplay_init() { + mp_obj_t ba = alloc_new_bytearray(PicoDisplay::WIDTH * PicoDisplay::HEIGHT * sizeof(uint16_t)); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_RW); - buf_obj = buf; + mp_get_buffer_raise(ba, &bufinfo, MP_BUFFER_RW); display = new PicoDisplay((uint16_t *)bufinfo.buf); display->init(); return mp_const_none; diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h index 3201df89..cfb86716 100644 --- a/micropython/modules/pico_display/pico_display.h +++ b/micropython/modules/pico_display/pico_display.h @@ -2,8 +2,10 @@ #include "py/runtime.h" #include "py/objstr.h" +extern mp_obj_t alloc_new_bytearray(int len); + // Declare the functions we'll make available in Python -extern mp_obj_t picodisplay_init(mp_obj_t buf); +extern mp_obj_t picodisplay_init(); extern mp_obj_t picodisplay_get_width(); extern mp_obj_t picodisplay_get_height(); extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj); From bccd30136220bb4c083bb3ef14038996d89f4fc8 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 21 Jan 2021 00:36:01 +0000 Subject: [PATCH 09/13] Revert "Attempt to allocate a bytearray behind the sCenes" --- micropython/modules/pico_display/pico_display.c | 16 +--------------- .../modules/pico_display/pico_display.cpp | 8 +++++--- micropython/modules/pico_display/pico_display.h | 4 +--- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/micropython/modules/pico_display/pico_display.c b/micropython/modules/pico_display/pico_display.c index bae8e178..7678d78f 100755 --- a/micropython/modules/pico_display/pico_display.c +++ b/micropython/modules/pico_display/pico_display.c @@ -1,6 +1,4 @@ #include "pico_display.h" -#include "py/binary.h" -#include "py/objarray.h" /***** Constants *****/ enum buttons @@ -11,25 +9,13 @@ enum buttons BUTTON_Y, }; -mp_obj_t alloc_new_bytearray(int len) { - int typecode_size = mp_binary_get_size('@', BYTEARRAY_TYPECODE, NULL); - mp_obj_array_t *o = m_new_obj(mp_obj_array_t); - o->base.type = &mp_type_bytearray; - o->typecode = BYTEARRAY_TYPECODE; - o->free = 0; - o->len = len; - o->items = m_new(byte, typecode_size * o->len); - memset(o->items, 0, len); - return MP_OBJ_FROM_PTR(o); -} - //////////////////////////////////////////////////////////////////////////////////////////////////// // picodisplay Module //////////////////////////////////////////////////////////////////////////////////////////////////// /***** Module Functions *****/ -STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_init_obj, picodisplay_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picodisplay_init_obj, picodisplay_init); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_width_obj, picodisplay_get_width); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_get_height_obj, picodisplay_get_height); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picodisplay_update_obj, picodisplay_update); diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index c48b3e81..129b756c 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -12,10 +12,12 @@ PicoDisplay *display; extern "C" { #include "pico_display.h" -mp_obj_t picodisplay_init() { - mp_obj_t ba = alloc_new_bytearray(PicoDisplay::WIDTH * PicoDisplay::HEIGHT * sizeof(uint16_t)); +mp_obj_t buf_obj; + +mp_obj_t picodisplay_init(mp_obj_t buf) { mp_buffer_info_t bufinfo; - mp_get_buffer_raise(ba, &bufinfo, MP_BUFFER_RW); + mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_RW); + buf_obj = buf; display = new PicoDisplay((uint16_t *)bufinfo.buf); display->init(); return mp_const_none; diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h index cfb86716..3201df89 100644 --- a/micropython/modules/pico_display/pico_display.h +++ b/micropython/modules/pico_display/pico_display.h @@ -2,10 +2,8 @@ #include "py/runtime.h" #include "py/objstr.h" -extern mp_obj_t alloc_new_bytearray(int len); - // Declare the functions we'll make available in Python -extern mp_obj_t picodisplay_init(); +extern mp_obj_t picodisplay_init(mp_obj_t buf); extern mp_obj_t picodisplay_get_width(); extern mp_obj_t picodisplay_get_height(); extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj); From 1b2d2faad5c1fd963ee44eba6c3713adf06dcfe8 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 21 Jan 2021 00:52:33 +0000 Subject: [PATCH 10/13] Added mpy wrapper for pico_explorer --- examples/pico_explorer/demo.cpp | 4 +- libraries/pico_explorer/pico_explorer.cpp | 16 +- libraries/pico_explorer/pico_explorer.hpp | 39 +-- .../modules/pico_display/pico_display.cpp | 8 +- .../modules/pico_display/pico_display.h | 2 +- .../modules/pico_explorer/micropython.mk | 6 + .../modules/pico_explorer/pico_explorer.c | 133 ++++++++ .../modules/pico_explorer/pico_explorer.cpp | 293 ++++++++++++++++++ .../modules/pico_explorer/pico_explorer.h | 28 ++ 9 files changed, 503 insertions(+), 26 deletions(-) create mode 100755 micropython/modules/pico_explorer/micropython.mk create mode 100644 micropython/modules/pico_explorer/pico_explorer.c create mode 100644 micropython/modules/pico_explorer/pico_explorer.cpp create mode 100644 micropython/modules/pico_explorer/pico_explorer.h diff --git a/examples/pico_explorer/demo.cpp b/examples/pico_explorer/demo.cpp index 629b7810..71fb7f58 100644 --- a/examples/pico_explorer/demo.cpp +++ b/examples/pico_explorer/demo.cpp @@ -10,7 +10,8 @@ using namespace pimoroni; extern unsigned char _binary_fox_tga_start[]; -PicoExplorer pico_explorer; +uint16_t buffer[PicoExplorer::WIDTH * PicoExplorer::HEIGHT]; +PicoExplorer pico_explorer(buffer); MSA301 msa301; uint8_t arrow[] = { @@ -54,6 +55,7 @@ void sprite(uint8_t *p, int x, int y, bool flip, uint16_t c) { }*/ int main() { + pico_explorer.init(); msa301.init(); bool a_pressed = false; diff --git a/libraries/pico_explorer/pico_explorer.cpp b/libraries/pico_explorer/pico_explorer.cpp index b2df3df0..6195c07f 100644 --- a/libraries/pico_explorer/pico_explorer.cpp +++ b/libraries/pico_explorer/pico_explorer.cpp @@ -1,4 +1,5 @@ #include +#include #include "hardware/pwm.h" #include "hardware/adc.h" @@ -12,9 +13,12 @@ const uint8_t MOTOR2P = 11; namespace pimoroni { - PicoExplorer::PicoExplorer() - : screen(240, 240, __fb), PicoGraphics(240, 240, __fb) { + PicoExplorer::PicoExplorer(uint16_t *buf) + : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf) { + __fb = buf; + } + void PicoExplorer::init() { // setup button inputs gpio_set_function(A, GPIO_FUNC_SIO); gpio_set_dir(A, GPIO_IN); gpio_pull_up(A); gpio_set_function(B, GPIO_FUNC_SIO); gpio_set_dir(B, GPIO_IN); gpio_pull_up(B); @@ -48,6 +52,14 @@ namespace pimoroni { screen.init(); } + void PicoExplorer::update() { + screen.update(); + } + + void PicoExplorer::set_backlight(uint8_t brightness) { + screen.set_backlight(brightness); + } + bool PicoExplorer::is_pressed(uint8_t button) { return !gpio_get(button); } diff --git a/libraries/pico_explorer/pico_explorer.hpp b/libraries/pico_explorer/pico_explorer.hpp index c44438e0..cb6b0551 100644 --- a/libraries/pico_explorer/pico_explorer.hpp +++ b/libraries/pico_explorer/pico_explorer.hpp @@ -6,25 +6,9 @@ namespace pimoroni { class PicoExplorer : public PicoGraphics { - uint16_t __fb[240 * 240]; - ST7789 screen; - int8_t audio_pin = -1; - public: - PicoExplorer(); - - void set_backlight(uint8_t brightness) {screen.set_backlight(brightness);} - void update() {screen.update();} - - bool is_pressed(uint8_t button); - - float get_adc(uint8_t channel); - - void set_motor(uint8_t channel, uint8_t action, float speed = 0.0f); - - void set_audio_pin(uint8_t pin); - void set_tone(uint16_t frequency, float duty = 0.2f); - + static const int WIDTH = 240; + static const int HEIGHT = 240; static const uint8_t A = 12; static const uint8_t B = 13; static const uint8_t X = 14; @@ -50,6 +34,25 @@ namespace pimoroni { static const uint8_t GP6 = 6; static const uint8_t GP7 = 7; + uint16_t *__fb; + private: + ST7789 screen; + int8_t audio_pin = -1; + + public: + PicoExplorer(uint16_t *buf); + + void init(); + void update(); + void set_backlight(uint8_t brightness); + bool is_pressed(uint8_t button); + + float get_adc(uint8_t channel); + + void set_motor(uint8_t channel, uint8_t action, float speed = 0.0f); + + void set_audio_pin(uint8_t pin); + void set_tone(uint16_t frequency, float duty = 0.2f); }; } \ No newline at end of file diff --git a/micropython/modules/pico_display/pico_display.cpp b/micropython/modules/pico_display/pico_display.cpp index 129b756c..79e9c79d 100644 --- a/micropython/modules/pico_display/pico_display.cpp +++ b/micropython/modules/pico_display/pico_display.cpp @@ -12,12 +12,12 @@ PicoDisplay *display; extern "C" { #include "pico_display.h" -mp_obj_t buf_obj; +mp_obj_t picodisplay_buf_obj; -mp_obj_t picodisplay_init(mp_obj_t buf) { +mp_obj_t picodisplay_init(mp_obj_t buf_obj) { mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_RW); - buf_obj = buf; + mp_get_buffer_raise(buf_obj, &bufinfo, MP_BUFFER_RW); + picodisplay_buf_obj = buf_obj; display = new PicoDisplay((uint16_t *)bufinfo.buf); display->init(); return mp_const_none; diff --git a/micropython/modules/pico_display/pico_display.h b/micropython/modules/pico_display/pico_display.h index 3201df89..d93fc360 100644 --- a/micropython/modules/pico_display/pico_display.h +++ b/micropython/modules/pico_display/pico_display.h @@ -3,7 +3,7 @@ #include "py/objstr.h" // Declare the functions we'll make available in Python -extern mp_obj_t picodisplay_init(mp_obj_t buf); +extern mp_obj_t picodisplay_init(mp_obj_t buf_obj); extern mp_obj_t picodisplay_get_width(); extern mp_obj_t picodisplay_get_height(); extern mp_obj_t picodisplay_set_backlight(mp_obj_t brightness_obj); diff --git a/micropython/modules/pico_explorer/micropython.mk b/micropython/modules/pico_explorer/micropython.mk new file mode 100755 index 00000000..275a59ee --- /dev/null +++ b/micropython/modules/pico_explorer/micropython.mk @@ -0,0 +1,6 @@ +EXPLORER_MOD_DIR := $(USERMOD_DIR) +# Add all C files to SRC_USERMOD. +SRC_USERMOD += $(EXPLORER_MOD_DIR)/pico_explorer.c +# # We can add our module folder to include paths if needed +# # This is not actually needed in this example. +CFLAGS_USERMOD += -I$(EXPLORER_MOD_DIR) diff --git a/micropython/modules/pico_explorer/pico_explorer.c b/micropython/modules/pico_explorer/pico_explorer.c new file mode 100644 index 00000000..e68fdbed --- /dev/null +++ b/micropython/modules/pico_explorer/pico_explorer.c @@ -0,0 +1,133 @@ +#include "pico_explorer.h" + +/***** Constants *****/ +enum buttons +{ + BUTTON_A = 0, + BUTTON_B, + BUTTON_X, + BUTTON_Y, +}; + +enum adcs +{ + ADC0 = 0, + ADC1, + ADC2, +}; + +enum motors +{ + MOTOR1 = 0, + MOTOR2, +}; + +enum motions +{ + FORWARD = 0, + REVERSE, + STOP, +}; + +enum gps +{ + GP0 = 0, + GP1, + GP2, + GP3, + GP4, + GP5, + GP6, + GP7, +}; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// picoexplorer Module +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/***** Module Functions *****/ +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoexplorer_init_obj, picoexplorer_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoexplorer_get_width_obj, picoexplorer_get_width); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoexplorer_get_height_obj, picoexplorer_get_height); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoexplorer_set_backlight_obj, picoexplorer_set_backlight); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoexplorer_update_obj, picoexplorer_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoexplorer_is_pressed_obj, picoexplorer_is_pressed); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoexplorer_get_adc_obj, picoexplorer_get_adc); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_set_motor_obj, 2, 3, picoexplorer_set_motor); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoexplorer_set_audio_pin_obj, picoexplorer_set_audio_pin); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_set_tone_obj, 1, 2, picoexplorer_set_tone); + +//From PicoGraphics parent class +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_set_pen_obj, 1, 3, picoexplorer_set_pen); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picoexplorer_create_pen_obj, picoexplorer_create_pen); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_set_clip_obj, 4, 4, picoexplorer_set_clip); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoexplorer_remove_clip_obj, picoexplorer_remove_clip); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoexplorer_clear_obj, picoexplorer_clear); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoexplorer_pixel_obj, picoexplorer_pixel); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picoexplorer_pixel_span_obj, picoexplorer_pixel_span); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_rectangle_obj, 4, 4, picoexplorer_rectangle); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(picoexplorer_circle_obj, picoexplorer_circle); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_character_obj, 3, 4, picoexplorer_character); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoexplorer_text_obj, 4, 5, picoexplorer_text); + + +/***** Globals Table *****/ +STATIC const mp_map_elem_t picoexplorer_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picoexplorer) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picoexplorer_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picoexplorer_get_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picoexplorer_get_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&picoexplorer_set_backlight_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picoexplorer_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picoexplorer_is_pressed_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_adc), MP_ROM_PTR(&picoexplorer_get_adc_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_motor), MP_ROM_PTR(&picoexplorer_set_motor_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_audio_pin), MP_ROM_PTR(&picoexplorer_set_audio_pin_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_tone), MP_ROM_PTR(&picoexplorer_set_tone_obj) }, + + { MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&picoexplorer_set_pen_obj) }, + { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&picoexplorer_create_pen_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&picoexplorer_set_clip_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove_clip), MP_ROM_PTR(&picoexplorer_remove_clip_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picoexplorer_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&picoexplorer_pixel_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_span), MP_ROM_PTR(&picoexplorer_pixel_span_obj) }, + { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&picoexplorer_rectangle_obj) }, + { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&picoexplorer_circle_obj) }, + { MP_ROM_QSTR(MP_QSTR_character), MP_ROM_PTR(&picoexplorer_character_obj) }, + { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&picoexplorer_text_obj) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_Y), MP_ROM_INT(BUTTON_Y) }, + + { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_INT(ADC0) }, + { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_INT(ADC1) }, + { MP_ROM_QSTR(MP_QSTR_ADC2), MP_ROM_INT(ADC2) }, + { MP_ROM_QSTR(MP_QSTR_MOTOR1), MP_ROM_INT(MOTOR1) }, + { MP_ROM_QSTR(MP_QSTR_MOTOR2), MP_ROM_INT(MOTOR2) }, + { MP_ROM_QSTR(MP_QSTR_FORWARD), MP_ROM_INT(FORWARD) }, + { MP_ROM_QSTR(MP_QSTR_REVERSE), MP_ROM_INT(REVERSE) }, + { MP_ROM_QSTR(MP_QSTR_STOP), MP_ROM_INT(STOP) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_INT(GP0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_INT(GP1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_INT(GP2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_INT(GP3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_INT(GP4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_INT(GP5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_INT(GP6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_INT(GP7) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_picoexplorer_globals, picoexplorer_globals_table); + +/***** Module Definition *****/ +const mp_obj_module_t picoexplorer_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_picoexplorer_globals, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +MP_REGISTER_MODULE(MP_QSTR_picoexplorer, picoexplorer_user_cmodule, MODULE_PICOEXPLORER_ENABLED); +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/micropython/modules/pico_explorer/pico_explorer.cpp b/micropython/modules/pico_explorer/pico_explorer.cpp new file mode 100644 index 00000000..b993960a --- /dev/null +++ b/micropython/modules/pico_explorer/pico_explorer.cpp @@ -0,0 +1,293 @@ +#include "hardware/spi.h" +#include "hardware/sync.h" +#include "pico/binary_info.h" + +#include "../../../pimoroni-pico/libraries/pico_explorer/pico_explorer.hpp" + +using namespace pimoroni; + +PicoExplorer *explorer; + + +extern "C" { +#include "pico_explorer.h" + +mp_obj_t picoexplorer_buf_obj; + +mp_obj_t picoexplorer_init(mp_obj_t buf_obj) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_obj, &bufinfo, MP_BUFFER_RW); + picoexplorer_buf_obj = buf_obj; + explorer = new PicoExplorer((uint16_t *)bufinfo.buf); + explorer->init(); + return mp_const_none; +} + +mp_obj_t picoexplorer_get_width() { + return mp_obj_new_int(PicoExplorer::WIDTH); +} + +mp_obj_t picoexplorer_get_height() { + return mp_obj_new_int(PicoExplorer::HEIGHT); +} + +mp_obj_t picoexplorer_update() { + explorer->update(); + return mp_const_none; +} + +mp_obj_t picoexplorer_set_backlight(mp_obj_t brightness_obj) { + float brightness = mp_obj_get_float(brightness_obj); + + if(brightness < 0 || brightness > 1.0f) + mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0"); + else + explorer->set_backlight((uint8_t)(brightness * 255.0f)); + + return mp_const_none; +} + +mp_obj_t picoexplorer_is_pressed(mp_obj_t button_obj) { + int buttonID = mp_obj_get_int(button_obj); + + bool buttonPressed = false; + switch(buttonID) + { + case 0: + buttonPressed = explorer->is_pressed(PicoExplorer::A); + break; + + case 1: + buttonPressed = explorer->is_pressed(PicoExplorer::B); + break; + + case 2: + buttonPressed = explorer->is_pressed(PicoExplorer::X); + break; + + case 3: + buttonPressed = explorer->is_pressed(PicoExplorer::Y); + break; + + default: + mp_raise_ValueError("button not valid. Expected 0 to 3"); + break; + } + + return buttonPressed ? mp_const_true : mp_const_false; +} + +extern mp_obj_t picoexplorer_get_adc(mp_obj_t channel_obj) { + int channel = mp_obj_get_int(channel_obj); + + float reading = 0.0f; + if(channel < 0 || channel > 2) + mp_raise_ValueError("adc channel not valid. Expected 0 to 2"); + else + reading = explorer->get_adc(channel); + + return mp_obj_new_float(reading); +} + +extern mp_obj_t picoexplorer_set_motor(mp_uint_t n_args, const mp_obj_t *args) { + int channel = mp_obj_get_int(args[0]); + int action = mp_obj_get_int(args[1]); + + if(channel < 0 || channel > 1) + mp_raise_ValueError("motor channel not valid. Expected 0 to 1"); + else if(action < 0 || action > 2) + mp_raise_ValueError("motor action not valid. Expected 0 to 2"); + else { + if(n_args == 3) { + float speed = mp_obj_get_float(args[2]); + explorer->set_motor(channel, action, speed); + } + else + explorer->set_motor(channel, action); + } + + return mp_const_none; +} + +extern mp_obj_t picoexplorer_set_audio_pin(mp_obj_t pin_obj) { + int pin = mp_obj_get_int(pin_obj); + explorer->set_audio_pin(pin); + return mp_const_none; +} + +extern mp_obj_t picoexplorer_set_tone(mp_uint_t n_args, const mp_obj_t *args) { + int frequency = mp_obj_get_int(args[0]); + + if(n_args == 2) { + float duty = mp_obj_get_int(args[1]); + explorer->set_tone(frequency, duty); + } + else + explorer->set_tone(frequency); + + return mp_const_none; +} + +mp_obj_t picoexplorer_set_pen(mp_uint_t n_args, const mp_obj_t *args) { + switch(n_args) + { + case 1: { + int p = mp_obj_get_int(args[0]); + + if(p < 0 || p > 0xffff) + mp_raise_ValueError("p is not a valid pen."); + else + explorer->set_pen(p); + } break; + + case 3: { + int r = mp_obj_get_int(args[0]); + int g = mp_obj_get_int(args[1]); + int b = mp_obj_get_int(args[2]); + + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + explorer->set_pen(r, g, b); + } break; + + default: { + char *buffer; + buffer = (char*)malloc(100); + sprintf(buffer, "function takes 1 or 3 (r,g,b) positional arguments but %d were given", n_args); + mp_raise_TypeError(buffer); + } break; + } + + return mp_const_none; +} + +mp_obj_t picoexplorer_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj) { + int r = mp_obj_get_int(r_obj); + int g = mp_obj_get_int(g_obj); + int b = mp_obj_get_int(b_obj); + + int pen = 0; + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + pen = explorer->create_pen(r, g, b); + + return mp_obj_new_int(pen); +} + +mp_obj_t picoexplorer_set_clip(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 4 + + int x = mp_obj_get_int(args[0]); + int y = mp_obj_get_int(args[1]); + int w = mp_obj_get_int(args[2]); + int h = mp_obj_get_int(args[3]); + + rect r(x, y, w, h); + explorer->set_clip(r); + + return mp_const_none; +} + +mp_obj_t picoexplorer_remove_clip() { + explorer->remove_clip(); + return mp_const_none; +} + +mp_obj_t picoexplorer_clear() { + explorer->clear(); + return mp_const_none; +} + +mp_obj_t picoexplorer_pixel(mp_obj_t x_obj, mp_obj_t y_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + + point p(x, y); + explorer->pixel(p); + + return mp_const_none; +} + +mp_obj_t picoexplorer_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + int l = mp_obj_get_int(l_obj); + + point p(x, y); + explorer->pixel_span(p, l); + + return mp_const_none; +} + +mp_obj_t picoexplorer_rectangle(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 4 + + int x = mp_obj_get_int(args[0]); + int y = mp_obj_get_int(args[1]); + int w = mp_obj_get_int(args[2]); + int h = mp_obj_get_int(args[3]); + + rect r(x, y, w, h); + explorer->rectangle(r); + + return mp_const_none; +} + +mp_obj_t picoexplorer_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj) { + int x = mp_obj_get_int(x_obj); + int y = mp_obj_get_int(y_obj); + int r = mp_obj_get_int(r_obj); + + point p(x, y); + explorer->circle(p, r); + + return mp_const_none; +} + +mp_obj_t picoexplorer_character(mp_uint_t n_args, const mp_obj_t *args) { + int c = mp_obj_get_int(args[0]); + int x = mp_obj_get_int(args[1]); + int y = mp_obj_get_int(args[2]); + + point p(x, y); + if(n_args == 4) { + int scale = mp_obj_get_int(args[3]); + explorer->character((char)c, p, scale); + } + else + explorer->character((char)c, p); + + return mp_const_none; +} + +mp_obj_t picoexplorer_text(mp_uint_t n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_str_or_bytes(args[0])); + GET_STR_DATA_LEN(args[0], str, str_len); + + std::string t((const char*)str); + + int x = mp_obj_get_int(args[1]); + int y = mp_obj_get_int(args[2]); + int wrap = mp_obj_get_int(args[3]); + + point p(x, y); + if(n_args == 5) { + int scale = mp_obj_get_int(args[4]); + explorer->text(t, p, wrap, scale); + } + else + explorer->text(t, p, wrap); + + return mp_const_none; +} +} \ No newline at end of file diff --git a/micropython/modules/pico_explorer/pico_explorer.h b/micropython/modules/pico_explorer/pico_explorer.h new file mode 100644 index 00000000..b446b58b --- /dev/null +++ b/micropython/modules/pico_explorer/pico_explorer.h @@ -0,0 +1,28 @@ +// Include MicroPython API. +#include "py/runtime.h" +#include "py/objstr.h" + +// Declare the functions we'll make available in Python +extern mp_obj_t picoexplorer_init(mp_obj_t buf_obj); +extern mp_obj_t picoexplorer_get_width(); +extern mp_obj_t picoexplorer_get_height(); +extern mp_obj_t picoexplorer_set_backlight(mp_obj_t brightness_obj); +extern mp_obj_t picoexplorer_update(); +extern mp_obj_t picoexplorer_is_pressed(mp_obj_t button_obj); +extern mp_obj_t picoexplorer_get_adc(mp_obj_t channel_obj); +extern mp_obj_t picoexplorer_set_motor(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picoexplorer_set_audio_pin(mp_obj_t pin_obj); +extern mp_obj_t picoexplorer_set_tone(mp_uint_t n_args, const mp_obj_t *args); + +// From PicoGraphics parent class +extern mp_obj_t picoexplorer_set_pen(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picoexplorer_create_pen(mp_obj_t r_obj, mp_obj_t g_obj, mp_obj_t b_obj); +extern mp_obj_t picoexplorer_set_clip(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picoexplorer_remove_clip(); +extern mp_obj_t picoexplorer_clear(); +extern mp_obj_t picoexplorer_pixel(mp_obj_t x_obj, mp_obj_t y_obj); +extern mp_obj_t picoexplorer_pixel_span(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t l_obj); +extern mp_obj_t picoexplorer_rectangle(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picoexplorer_circle(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t r_obj); +extern mp_obj_t picoexplorer_character(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picoexplorer_text(mp_uint_t n_args, const mp_obj_t *args); \ No newline at end of file From b2f13f103c8e46668a9924ad7a3020a8efa1ea3d Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 21 Jan 2021 00:56:11 +0000 Subject: [PATCH 11/13] Added cmake file for picoexplorer mpy wrapper --- .../modules/pico_explorer/usermod.cmake | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 micropython/modules/pico_explorer/usermod.cmake diff --git a/micropython/modules/pico_explorer/usermod.cmake b/micropython/modules/pico_explorer/usermod.cmake new file mode 100644 index 00000000..67690461 --- /dev/null +++ b/micropython/modules/pico_explorer/usermod.cmake @@ -0,0 +1,21 @@ +add_library(usermod_pico_explorer INTERFACE) + +target_sources(usermod_pico_explorer INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_explorer.c + ${CMAKE_CURRENT_LIST_DIR}/pico_explorer.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_explorer/pico_explorer.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/st7789/st7789.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/pico_graphics.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/types.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../libraries/pico_graphics/font_data.cpp +) + +target_include_directories(usermod_pico_explorer INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(usermod_pico_explorer INTERFACE + -DMODULE_PICODISPLAY_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_pico_explorer) \ No newline at end of file From 5afc67f53d0c5c3ce67faee5eac91881f63b1662 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 21 Jan 2021 00:59:25 +0000 Subject: [PATCH 12/13] Added cmake file for picoexplorer mpy wrapper --- micropython/modules/pico_explorer/usermod.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micropython/modules/pico_explorer/usermod.cmake b/micropython/modules/pico_explorer/usermod.cmake index 67690461..cae51ada 100644 --- a/micropython/modules/pico_explorer/usermod.cmake +++ b/micropython/modules/pico_explorer/usermod.cmake @@ -15,7 +15,7 @@ target_include_directories(usermod_pico_explorer INTERFACE ) target_compile_definitions(usermod_pico_explorer INTERFACE - -DMODULE_PICODISPLAY_ENABLED=1 + -DMODULE_PICOEXPLORER_ENABLED=1 ) target_link_libraries(usermod INTERFACE usermod_pico_explorer) \ No newline at end of file From 9a8bcc9f8a75c8ce16f489ced73c60f39beee186 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 21 Jan 2021 16:56:04 +0000 Subject: [PATCH 13/13] Fixed issue with clear of picoscroll not working under mpy, and added demo --- libraries/pico_scroll/pico_scroll.cpp | 4 +++ micropython/examples/pico_scroll/demo.py | 36 +++++++++++++++++++ micropython/modules/pico_scroll/pico_scroll.c | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 micropython/examples/pico_scroll/demo.py diff --git a/libraries/pico_scroll/pico_scroll.cpp b/libraries/pico_scroll/pico_scroll.cpp index f04aabe9..4b36c47d 100644 --- a/libraries/pico_scroll/pico_scroll.cpp +++ b/libraries/pico_scroll/pico_scroll.cpp @@ -55,6 +55,10 @@ namespace pimoroni { gpio_set_function(pin::B, GPIO_FUNC_SIO); gpio_set_dir(pin::B, GPIO_IN); gpio_pull_up(pin::B); gpio_set_function(pin::X, GPIO_FUNC_SIO); gpio_set_dir(pin::X, GPIO_IN); gpio_pull_up(pin::X); gpio_set_function(pin::Y, GPIO_FUNC_SIO); gpio_set_dir(pin::Y, GPIO_IN); gpio_pull_up(pin::Y); + + // reset the screen + clear(); + update(); } void PicoScroll::set_pixel(uint8_t x, uint8_t y, uint8_t v) { diff --git a/micropython/examples/pico_scroll/demo.py b/micropython/examples/pico_scroll/demo.py new file mode 100644 index 00000000..4be9a55c --- /dev/null +++ b/micropython/examples/pico_scroll/demo.py @@ -0,0 +1,36 @@ +import time +import picoscroll as scroll + +scroll.init() +i = 0 +loop = 18 +br_mult = 1 +br_pressed = 32 +tail = 12 + +width = scroll.get_width() +height = scroll.get_height() +while True: + scroll.clear(); + for y in range(0, height): + for x in range(0, width): + if x < 3 and y < 3 and scroll.is_pressed(scroll.BUTTON_A): + scroll.set_pixel(x, y, br_pressed) + elif x < 3 and y > 3 and scroll.is_pressed(scroll.BUTTON_B): + scroll.set_pixel(x, y, br_pressed) + elif x > width - 4 and y < 3 and scroll.is_pressed(scroll.BUTTON_X): + scroll.set_pixel(x, y, br_pressed) + elif x > width - 4 and y > 3 and scroll.is_pressed(scroll.BUTTON_Y): + scroll.set_pixel(x, y, br_pressed) + else: + m = (x + (y * width)) % loop + for b in range(0, loop): + if m == (i + (loop - b)) % loop and b < tail: + scroll.set_pixel(x, y, br_mult * (tail - b)) + + + scroll.update() + i += 1 + if i >= loop: + i = 0 + time.sleep(0.02) diff --git a/micropython/modules/pico_scroll/pico_scroll.c b/micropython/modules/pico_scroll/pico_scroll.c index d59b7008..61b3be46 100644 --- a/micropython/modules/pico_scroll/pico_scroll.c +++ b/micropython/modules/pico_scroll/pico_scroll.c @@ -20,7 +20,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_get_width_obj, picoscroll_get_width) STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_get_height_obj, picoscroll_get_height); STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_update_obj, picoscroll_update); STATIC MP_DEFINE_CONST_FUN_OBJ_3(picoscroll_set_pixel_obj, picoscroll_set_pixel); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_clear_obj, picoscroll_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_clear_obj, picoscroll_clear); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_is_pressed_obj, picoscroll_is_pressed); /***** Globals Table *****/