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})
# 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);
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
#include <string>
#include "pico_graphics.hpp"
namespace pimoroni {
class PicoScroll {
@ -36,6 +38,7 @@ namespace pimoroni {
void clear();
bool is_pressed(uint8_t button);
void update(PicoGraphics *graphics);
private:
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_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_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_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);
@ -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_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_update_obj, picoscroll_update);
/* Class Methods */
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_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_pixels), MP_ROM_PTR(&picoscroll_set_pixels_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" {
#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 INCORRECT_SIZE_MSG "Scroll height wrong: > 8 pixels."
@ -24,6 +26,17 @@ typedef struct _PicoScroll_obj_t {
PicoScroll* scroll;
} 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) {
_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);
}
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);
self->scroll->update();
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;
}
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"
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
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_get_width(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_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);
@ -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_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_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_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_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_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(pen_type == -1) pen_type = PEN_RGB888;
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:
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_GALACTIC_UNICORN
|| display == DISPLAY_COSMIC_UNICORN
|| display == DISPLAY_UNICORN_PACK) {
|| display == DISPLAY_UNICORN_PACK
|| display == DISPLAY_SCROLL_PACK) {
// Create a dummy display driver
self->display = m_new_class(DisplayDriver, width, height, (Rotation)rotate);

View File

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