Pico Scroll: Add support for PicoGraphics.

This commit is contained in:
Phil Howard 2023-03-16 16:59:31 +00:00
parent b83bdbf198
commit 1b0b783a2f
9 changed files with 107 additions and 9 deletions

View File

@ -11,4 +11,4 @@ target_sources(pico_scroll INTERFACE
target_include_directories(pico_scroll INTERFACE ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(pico_scroll INTERFACE ${CMAKE_CURRENT_LIST_DIR})
# Pull in pico libraries that we need # Pull in pico libraries that we need
target_link_libraries(pico_scroll INTERFACE pico_stdlib hardware_i2c) target_link_libraries(pico_scroll INTERFACE pico_stdlib pico_graphics hardware_i2c)

View File

@ -171,4 +171,61 @@ namespace pimoroni {
memcpy(&buffer[1], data, len); memcpy(&buffer[1], data, len);
i2c_write_blocking(i2c0, DEFAULT_ADDRESS, buffer, len + 1, true); i2c_write_blocking(i2c0, DEFAULT_ADDRESS, buffer, len + 1, true);
} }
void PicoScroll::update(PicoGraphics *graphics) {
if(graphics->pen_type == PicoGraphics::PEN_RGB888) {
uint32_t *p = (uint32_t *)graphics->frame_buffer;
for(int y = 0; y < HEIGHT; y++) {
for(int x = 0; x < WIDTH; x++) {
uint32_t col = *p;
uint8_t r = (col & 0xff0000) >> 16;
uint8_t g = (col & 0x00ff00) >> 8;
uint8_t b = (col & 0x0000ff) >> 0;
p++;
set_pixel(x, y, (r + g + b) / 3);
}
}
update();
}
else if(graphics->pen_type == PicoGraphics::PEN_RGB565) {
uint16_t *p = (uint16_t *)graphics->frame_buffer;
for(int y = 0; y < HEIGHT; y++) {
for(int x = 0; x < WIDTH; x++) {
uint16_t col = __builtin_bswap16(*p);
uint8_t r = (col & 0b1111100000000000) >> 8;
uint8_t g = (col & 0b0000011111100000) >> 3;
uint8_t b = (col & 0b0000000000011111) << 3;
p++;
set_pixel(x, y, (r + g + b) / 3);
}
}
update();
}
else if(graphics->pen_type == PicoGraphics::PEN_P8 || graphics->pen_type == PicoGraphics::PEN_P4) {
int offset = 0;
graphics->frame_convert(PicoGraphics::PEN_RGB888, [this, offset](void *data, size_t length) mutable {
uint32_t *p = (uint32_t *)data;
for(auto i = 0u; i < length / 4; i++) {
int x = offset % WIDTH;
int y = offset / WIDTH;
uint32_t col = *p;
uint8_t r = (col & 0xff0000) >> 16;
uint8_t g = (col & 0x00ff00) >> 8;
uint8_t b = (col & 0x0000ff) >> 0;
set_pixel(x, y, (r + g + b) / 3);
offset++;
p++;
}
});
update();
}
}
} }

View File

@ -1,6 +1,8 @@
#include <string>
#pragma once #pragma once
#include <string>
#include "pico_graphics.hpp"
namespace pimoroni { namespace pimoroni {
class PicoScroll { class PicoScroll {
@ -36,6 +38,7 @@ namespace pimoroni {
void clear(); void clear();
bool is_pressed(uint8_t button); bool is_pressed(uint8_t button);
void update(PicoGraphics *graphics);
private: private:
void i2c_write(uint8_t reg, const char *data, uint8_t len); void i2c_write(uint8_t reg, const char *data, uint8_t len);
}; };

View File

@ -18,7 +18,7 @@ enum buttons
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll___del___obj, picoscroll___del__); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll___del___obj, picoscroll___del__);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_get_width_obj, picoscroll_get_width); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_get_width_obj, picoscroll_get_width);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_get_height_obj, picoscroll_get_height); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_get_height_obj, picoscroll_get_height);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_update_obj, picoscroll_update); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_show_obj, picoscroll_show);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_set_pixel_obj, 4, 4, picoscroll_set_pixel); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_set_pixel_obj, 4, 4, picoscroll_set_pixel);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoscroll_set_pixels_obj, picoscroll_set_pixels); STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoscroll_set_pixels_obj, picoscroll_set_pixels);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_show_text_obj, 4, 4, picoscroll_show_text); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_show_text_obj, 4, 4, picoscroll_show_text);
@ -26,13 +26,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_scroll_text_obj, 4, 4, pic
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_show_bitmap_1d_obj, 4, 4, picoscroll_show_bitmap_1d); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picoscroll_show_bitmap_1d_obj, 4, 4, picoscroll_show_bitmap_1d);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_clear_obj, picoscroll_clear); STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_clear_obj, picoscroll_clear);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoscroll_is_pressed_obj, picoscroll_is_pressed); STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoscroll_is_pressed_obj, picoscroll_is_pressed);
STATIC MP_DEFINE_CONST_FUN_OBJ_2(picoscroll_update_obj, picoscroll_update);
/* Class Methods */ /* Class Methods */
STATIC const mp_rom_map_elem_t picoscroll_locals[] = { STATIC const mp_rom_map_elem_t picoscroll_locals[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&picoscroll___del___obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&picoscroll___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picoscroll_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&picoscroll_show_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picoscroll_get_width_obj) }, { MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picoscroll_get_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picoscroll_get_height_obj) }, { MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picoscroll_get_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picoscroll_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pixel), MP_ROM_PTR(&picoscroll_set_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_set_pixel), MP_ROM_PTR(&picoscroll_set_pixel_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pixels), MP_ROM_PTR(&picoscroll_set_pixels_obj) }, { MP_ROM_QSTR(MP_QSTR_set_pixels), MP_ROM_PTR(&picoscroll_set_pixels_obj) },
{ MP_ROM_QSTR(MP_QSTR_show_text), MP_ROM_PTR(&picoscroll_show_text_obj) }, { MP_ROM_QSTR(MP_QSTR_show_text), MP_ROM_PTR(&picoscroll_show_text_obj) },

View File

@ -15,6 +15,8 @@ PicoScroll *scroll = nullptr;
extern "C" { extern "C" {
#include "pico_scroll.h" #include "pico_scroll.h"
#include "micropython/modules/pimoroni_i2c/pimoroni_i2c.h"
#include "py/builtin.h"
#define BUFFER_TOO_SMALL_MSG "bytearray too small: len(image) < width * height." #define BUFFER_TOO_SMALL_MSG "bytearray too small: len(image) < width * height."
#define INCORRECT_SIZE_MSG "Scroll height wrong: > 8 pixels." #define INCORRECT_SIZE_MSG "Scroll height wrong: > 8 pixels."
@ -24,6 +26,17 @@ typedef struct _PicoScroll_obj_t {
PicoScroll* scroll; PicoScroll* scroll;
} PicoScroll_obj_t; } PicoScroll_obj_t;
// from picographics/picographics.cpp
// used to support accepting a PicoGraphics class
typedef struct _ModPicoGraphics_obj_t {
mp_obj_base_t base;
PicoGraphics *graphics;
DisplayDriver *display;
void *spritedata;
void *buffer;
_PimoroniI2C_obj_t *i2c;
} ModPicoGraphics_obj_t;
mp_obj_t picoscroll_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_obj_t picoscroll_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
_PicoScroll_obj_t *self = nullptr; _PicoScroll_obj_t *self = nullptr;
@ -52,7 +65,7 @@ mp_obj_t picoscroll_get_height(mp_obj_t self_in) {
return mp_obj_new_int(PicoScroll::HEIGHT); return mp_obj_new_int(PicoScroll::HEIGHT);
} }
mp_obj_t picoscroll_update(mp_obj_t self_in) { mp_obj_t picoscroll_show(mp_obj_t self_in) {
PicoScroll_obj_t *self = MP_OBJ_TO_PTR2(self_in, PicoScroll_obj_t); PicoScroll_obj_t *self = MP_OBJ_TO_PTR2(self_in, PicoScroll_obj_t);
self->scroll->update(); self->scroll->update();
return mp_const_none; return mp_const_none;
@ -207,4 +220,14 @@ mp_obj_t picoscroll_is_pressed(mp_obj_t self_in, mp_obj_t button_obj) {
return buttonPressed ? mp_const_true : mp_const_false; return buttonPressed ? mp_const_true : mp_const_false;
} }
mp_obj_t picoscroll_update(mp_obj_t self_in, mp_obj_t graphics_in) {
PicoScroll_obj_t *self = MP_OBJ_TO_PTR2(self_in, PicoScroll_obj_t);
ModPicoGraphics_obj_t *picographics = MP_OBJ_TO_PTR2(graphics_in, ModPicoGraphics_obj_t);
if(picographics->base.type == &ModPicoGraphics_type) {
self->scroll->update(picographics->graphics);
}
return mp_const_none;
}
} }

View File

@ -3,13 +3,14 @@
#include "py/objstr.h" #include "py/objstr.h"
extern const mp_obj_type_t PicoScroll_type; extern const mp_obj_type_t PicoScroll_type;
extern const mp_obj_type_t ModPicoGraphics_type;
// Declare the functions we'll make available in Python // Declare the functions we'll make available in Python
extern mp_obj_t picoscroll_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); extern mp_obj_t picoscroll_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
extern mp_obj_t picoscroll___del__(mp_obj_t self_in); extern mp_obj_t picoscroll___del__(mp_obj_t self_in);
extern mp_obj_t picoscroll_get_width(mp_obj_t self_in); extern mp_obj_t picoscroll_get_width(mp_obj_t self_in);
extern mp_obj_t picoscroll_get_height(mp_obj_t self_in); extern mp_obj_t picoscroll_get_height(mp_obj_t self_in);
extern mp_obj_t picoscroll_update(mp_obj_t self_in); extern mp_obj_t picoscroll_show(mp_obj_t self_in);
extern mp_obj_t picoscroll_set_pixel(mp_uint_t n_args, const mp_obj_t *args); extern mp_obj_t picoscroll_set_pixel(mp_uint_t n_args, const mp_obj_t *args);
extern mp_obj_t picoscroll_set_pixels(mp_obj_t self_in, mp_obj_t image_obj); extern mp_obj_t picoscroll_set_pixels(mp_obj_t self_in, mp_obj_t image_obj);
extern mp_obj_t picoscroll_show_text(mp_uint_t n_args, const mp_obj_t *args); extern mp_obj_t picoscroll_show_text(mp_uint_t n_args, const mp_obj_t *args);
@ -17,3 +18,5 @@ extern mp_obj_t picoscroll_scroll_text(mp_uint_t n_args, const mp_obj_t *args);
extern mp_obj_t picoscroll_show_bitmap_1d(mp_uint_t n_args, const mp_obj_t *args); extern mp_obj_t picoscroll_show_bitmap_1d(mp_uint_t n_args, const mp_obj_t *args);
extern mp_obj_t picoscroll_clear(mp_obj_t self_in); extern mp_obj_t picoscroll_clear(mp_obj_t self_in);
extern mp_obj_t picoscroll_is_pressed(mp_obj_t self_in, mp_obj_t button_obj); extern mp_obj_t picoscroll_is_pressed(mp_obj_t self_in, mp_obj_t button_obj);
extern mp_obj_t picoscroll_update(mp_obj_t self_in, mp_obj_t graphics_in);

View File

@ -153,6 +153,7 @@ STATIC const mp_map_elem_t picographics_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME_7), MP_ROM_INT(DISPLAY_INKY_FRAME_7) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INKY_FRAME_7), MP_ROM_INT(DISPLAY_INKY_FRAME_7) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_COSMIC_UNICORN), MP_ROM_INT(DISPLAY_COSMIC_UNICORN) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_COSMIC_UNICORN), MP_ROM_INT(DISPLAY_COSMIC_UNICORN) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_UNICORN_PACK), MP_ROM_INT(DISPLAY_UNICORN_PACK) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_UNICORN_PACK), MP_ROM_INT(DISPLAY_UNICORN_PACK) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_SCROLL_PACK), MP_ROM_INT(DISPLAY_SCROLL_PACK) },
{ MP_ROM_QSTR(MP_QSTR_PEN_1BIT), MP_ROM_INT(PEN_1BIT) }, { MP_ROM_QSTR(MP_QSTR_PEN_1BIT), MP_ROM_INT(PEN_1BIT) },
{ MP_ROM_QSTR(MP_QSTR_PEN_P4), MP_ROM_INT(PEN_P4) }, { MP_ROM_QSTR(MP_QSTR_PEN_P4), MP_ROM_INT(PEN_P4) },

View File

@ -217,6 +217,13 @@ bool get_display_settings(PicoGraphicsDisplay display, int &width, int &height,
if(rotate == -1) rotate = (int)Rotation::ROTATE_0; if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
if(pen_type == -1) pen_type = PEN_RGB888; if(pen_type == -1) pen_type = PEN_RGB888;
break; break;
case DISPLAY_SCROLL_PACK:
width = 17;
height = 7;
bus_type = BUS_PIO;
if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
if(pen_type == -1) pen_type = PEN_RGB888;
break;
default: default:
return false; return false;
} }
@ -347,7 +354,8 @@ mp_obj_t ModPicoGraphics_make_new(const mp_obj_type_t *type, size_t n_args, size
|| display == DISPLAY_INTERSTATE75_64X32 || display == DISPLAY_INTERSTATE75_64X32
|| display == DISPLAY_GALACTIC_UNICORN || display == DISPLAY_GALACTIC_UNICORN
|| display == DISPLAY_COSMIC_UNICORN || display == DISPLAY_COSMIC_UNICORN
|| display == DISPLAY_UNICORN_PACK) { || display == DISPLAY_UNICORN_PACK
|| display == DISPLAY_SCROLL_PACK) {
// Create a dummy display driver // Create a dummy display driver
self->display = m_new_class(DisplayDriver, width, height, (Rotation)rotate); self->display = m_new_class(DisplayDriver, width, height, (Rotation)rotate);

View File

@ -26,7 +26,8 @@ enum PicoGraphicsDisplay {
DISPLAY_INTERSTATE75_256X64, DISPLAY_INTERSTATE75_256X64,
DISPLAY_INKY_FRAME_7, DISPLAY_INKY_FRAME_7,
DISPLAY_COSMIC_UNICORN, DISPLAY_COSMIC_UNICORN,
DISPLAY_UNICORN_PACK DISPLAY_UNICORN_PACK,
DISPLAY_SCROLL_PACK
}; };
enum PicoGraphicsPenType { enum PicoGraphicsPenType {