Skip to content

protomatter: Update to version that supports tiling #4068

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ msgstr ""

#: shared-bindings/rgbmatrix/RGBMatrix.c
#, c-format
msgid "%d address pins and %d rgb pins indicate a height of %d, not %d"
msgid ""
"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"
msgstr ""

#: ports/atmel-samd/common-hal/sdioio/SDCard.c
Expand Down Expand Up @@ -516,7 +517,6 @@ msgstr ""
msgid "Buffer must be a multiple of 512 bytes"
msgstr ""

#: shared-bindings/adafruit_bus_device/I2CDevice.c
#: shared-bindings/bitbangio/I2C.c shared-bindings/busio/I2C.c
msgid "Buffer must be at least length 1"
msgstr ""
Expand Down Expand Up @@ -3710,6 +3710,10 @@ msgstr ""
msgid "threshold must be in the range 0-65536"
msgstr ""

#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "tile must be greater than zero"
msgstr ""

#: shared-bindings/time/__init__.c
msgid "time.struct_time() takes a 9-sequence"
msgstr ""
Expand Down
28 changes: 18 additions & 10 deletions shared-bindings/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
}
}

//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0) -> None:
//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0, tile: int = 1, serpentine: bool = False) -> None:
//| """Create a RGBMatrix object with the given attributes. The height of
//| the display is determined by the number of rgb and address pins:
//| len(rgb_pins) // 3 * 2 ** len(address_pins). With 6 RGB pins and 4
//| address lines, the display will be 32 pixels tall. If the optional height
//| the display is determined by the number of rgb and address pins and the number of tiles:
//| ``len(rgb_pins) // 3 * 2 ** len(address_pins) * abs(tile)``. With 6 RGB pins, 4
//| address lines, and a single matrix, the display will be 32 pixels tall. If the optional height
//| parameter is specified and is not 0, it is checked against the calculated
//| height.
//|
Expand Down Expand Up @@ -172,7 +172,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_

STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list,
ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height };
ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height, ARG_tile, ARG_serpentine };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
{ MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
Expand All @@ -184,6 +184,8 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
{ MP_QSTR_doublebuffer, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = true } },
{ MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } },
{ MP_QSTR_tile, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 1 } },
{ MP_QSTR_serpentine, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
Expand All @@ -210,12 +212,18 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
mp_raise_ValueError_varg(translate("Must use a multiple of 6 rgb pins, not %d"), rgb_count);
}

// TODO(@jepler) Use fewer than all rows of pixels if height < computed_height
int tile = args[ARG_tile].u_int;

if (tile <= 0) {
mp_raise_ValueError_varg(
translate("tile must be greater than zero"));
}

int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile;
if (args[ARG_height].u_int != 0) {
int computed_height = (rgb_count / 3) << (addr_count);
if (computed_height != args[ARG_height].u_int) {
mp_raise_ValueError_varg(
translate("%d address pins and %d rgb pins indicate a height of %d, not %d"), addr_count, rgb_count, computed_height, args[ARG_height].u_int);
translate("%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"), addr_count, rgb_count, tile, computed_height, args[ARG_height].u_int);
}
}

Expand All @@ -228,7 +236,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
if (framebuffer == mp_const_none) {
int width = args[ARG_width].u_int;
int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count);
int bufsize = 2 * width * computed_height;
framebuffer = mp_obj_new_bytearray_of_zeros(bufsize);
}

Expand All @@ -239,7 +247,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
addr_count, addr_pins,
clock_pin, latch_pin, output_enable_pin,
args[ARG_doublebuffer].u_bool,
framebuffer, NULL);
framebuffer, tile, args[ARG_serpentine].u_bool, NULL);

claim_and_never_reset_pins(args[ARG_rgb_list].u_obj);
claim_and_never_reset_pins(args[ARG_addr_list].u_obj);
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;

void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer);
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void* timer);
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*);
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t*);
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer);
Expand Down
11 changes: 7 additions & 4 deletions shared-module/rgbmatrix/RGBMatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

extern Protomatter_core *_PM_protoPtr;

void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void *timer) {
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void *timer) {
self->width = width;
self->bit_depth = bit_depth;
self->rgb_count = rgb_count;
Expand All @@ -53,14 +53,16 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
self->oe_pin = oe_pin;
self->latch_pin = latch_pin;
self->doublebuffer = doublebuffer;
self->tile = tile;
self->serpentine = serpentine;

self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate();
if (self->timer == NULL) {
mp_raise_ValueError(translate("No timer available"));
}

self->width = width;
self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count);
self->bufsize = 2 * width * common_hal_rgbmatrix_rgbmatrix_get_height(self);

common_hal_rgbmatrix_rgbmatrix_reconstruct(self, framebuffer);
}
Expand Down Expand Up @@ -95,7 +97,8 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
self->rgb_count/6, self->rgb_pins,
self->addr_count, self->addr_pins,
self->clock_pin, self->latch_pin, self->oe_pin,
self->doublebuffer, self->timer);
self->doublebuffer, self->serpentine ? -self->tile : self->tile,
self->timer);

if (stat == PROTOMATTER_OK) {
_PM_protoPtr = &self->protomatter;
Expand Down Expand Up @@ -209,7 +212,7 @@ int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self) {
}

int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self) {
int computed_height = (self->rgb_count / 3) << (self->addr_count);
int computed_height = (self->rgb_count / 3) * (1 << (self->addr_count)) * self->tile;
return computed_height;
}

Expand Down
2 changes: 2 additions & 0 deletions shared-module/rgbmatrix/RGBMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ typedef struct {
bool core_is_initialized;
bool paused;
bool doublebuffer;
bool serpentine;
int8_t tile;
} rgbmatrix_rgbmatrix_obj_t;