Mapping for LEDs to diplay

This commit is contained in:
gamblor21 2021-11-20 12:42:58 -06:00
parent 9fa3feffb1
commit 6b2d43d3c8
6 changed files with 56 additions and 23 deletions

View File

@ -574,6 +574,7 @@ msgstr ""
#: shared-bindings/displayio/Display.c
#: shared-bindings/framebufferio/FramebufferDisplay.c
#: shared-bindings/is31fl3741/is31fl3741.c
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "Brightness must be 0-1.0"
msgstr ""
@ -2081,6 +2082,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
#: shared-bindings/is31fl3741/is31fl3741.c
msgid "Scale dimensions must divide by 3"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Scan already in progess. Stop with stop_scan."
msgstr ""
@ -2342,7 +2347,7 @@ msgstr ""
msgid "Unable to create lock"
msgstr ""
#: shared-module/displayio/I2CDisplay.c
#: shared-module/displayio/I2CDisplay.c shared-module/is31fl3741/is31fl3741.c
#, c-format
msgid "Unable to find I2C Display at %x"
msgstr ""
@ -4453,6 +4458,7 @@ msgstr ""
msgid "width must be from 2 to 8 (inclusive), not %d"
msgstr ""
#: shared-bindings/is31fl3741/is31fl3741.c
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "width must be greater than zero"
msgstr ""

View File

@ -31,9 +31,6 @@
#include "shared-bindings/is31fl3741/is31fl3741.h"
//| """Low-level routines for bitbanged LED matrices"""
//|
STATIC const mp_rom_map_elem_t is31fl3741_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_is31fl3741) },
{ MP_ROM_QSTR(MP_QSTR_is31fl3741), MP_ROM_PTR(&is31fl3741_is31fl3741_type) },

View File

@ -57,13 +57,14 @@
//|
STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer, ARG_scale, ARG_gamma };
enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer, ARG_mapping, ARG_scale, ARG_gamma };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
{ MP_QSTR_i2c, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
{ MP_QSTR_addr, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0x30 } },
{ MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } },
{ MP_QSTR_mapping, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_scale, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
{ MP_QSTR_gamma, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
};
@ -79,9 +80,12 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t
mp_raise_ValueError(translate("width must be greater than zero"));
}
// TODO make sure height/width divisible by 3
self->scale = args[ARG_scale].u_bool;
if (self->scale) {
if (((args[ARG_height].u_int % 3) != 0) || ((args[ARG_width].u_int % 3) != 0)) {
mp_raise_ValueError(translate("Scale dimensions must divide by 3"));
}
self->scale_width = args[ARG_width].u_int / 3;
self->scale_height = args[ARG_height].u_int / 3;
}
@ -101,7 +105,8 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t
args[ARG_height].u_int,
framebuffer,
MP_OBJ_TO_PTR(i2c),
args[ARG_addr].u_int
args[ARG_addr].u_int,
args[ARG_mapping].u_obj
);
return MP_OBJ_FROM_PTR(self);

View File

@ -30,7 +30,7 @@
extern const mp_obj_type_t is31fl3741_is31fl3741_type;
void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *self, int width, int height, mp_obj_t framebuffer, busio_i2c_obj_t *i2c, uint8_t addr);
void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *self, int width, int height, mp_obj_t framebuffer, busio_i2c_obj_t *i2c, uint8_t addr, mp_obj_t mapping);
void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *);
@ -58,4 +58,4 @@ void is31fl3741_send_reset(busio_i2c_obj_t *i2c, uint8_t addr);
void is31fl3741_set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current);
uint8_t is31fl3741_get_current(busio_i2c_obj_t *i2c, uint8_t addr);
void is31fl3741_set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, uint8_t page);
void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color);
void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color, uint16_t *mapping);

View File

@ -40,7 +40,7 @@
#include "shared-module/framebufferio/FramebufferDisplay.h"
#include "shared-bindings/busio/I2C.h"
void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *self, int width, int height, mp_obj_t framebuffer, busio_i2c_obj_t *i2c, uint8_t addr) {
void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *self, int width, int height, mp_obj_t framebuffer, busio_i2c_obj_t *i2c, uint8_t addr, mp_obj_t mapping) {
self->width = width;
self->height = height;
@ -59,6 +59,21 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel
// of the heap as well.
gc_never_free(self->i2c);
// TODO mapping should be equal to height * width * 3
mp_obj_t *items;
size_t len;
mp_obj_list_get(mapping, &len, &items);
self->mapping = common_hal_is31fl3741_allocator_impl(sizeof(uint16_t) * len);
for (size_t i = 0; i < len; i++) {
mp_int_t value = mp_obj_get_int(items[i]);
// We only store up to 16 bits
if (value > 0xFFFF) {
value = 0xFFFF;
}
self->mapping[i] = (uint16_t)value;
}
common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer);
}
@ -114,6 +129,11 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self)
self->i2c = NULL;
}
if (self->mapping != 0) {
common_hal_is31fl3741_free_impl(self->mapping);
self->mapping = 0;
}
self->base.type = NULL;
// If a framebuffer was passed in to the constructor, NULL the reference
@ -144,15 +164,12 @@ uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl374
void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows) {
common_hal_displayio_is31fl3741_begin_transaction(self);
uint8_t dirty_row_flags = 0xFF; // only supports 8 rows gotta fix
if (dirtyrows != 0) {
dirty_row_flags = *dirtyrows;
}
if (!self->paused) {
uint8_t dirty_row_flags = 0xFF; // only supports 8 rows gotta fix
if (self->scale) {
// Based on the Arduino IS31FL3741 driver code
// dirtyrows flag current not implemented for scaled displays
uint32_t *buffer = self->bufinfo.buf;
for (int x = 0; x < self->scale_width; x++) {
@ -180,13 +197,17 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self,
} else {
color = (rsum << 16) + (gsum << 8) + bsum;
}
is31fl3741_draw_pixel(self->i2c, self->device_address, x, y, color);
is31fl3741_draw_pixel(self->i2c, self->device_address, x, y, color, self->mapping);
}
}
} else {
uint32_t *buffer = self->bufinfo.buf;
for (int y = 0; y < self->height; y++) {
if ((dirty_row_flags >> y) & 0x1) {
if ((dirtyrows != 0) && ((y % 8) == 0)) {
dirty_row_flags = *dirtyrows++;
}
if ((dirty_row_flags >> (y % 8)) & 0x1) {
uint32_t color = 0;
if (self->auto_gamma) {
color = IS31GammaTable[((*buffer) >> 16 & 0xFF)] +
@ -197,7 +218,7 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self,
}
for (int x = 0; x < self->width; x++) {
is31fl3741_draw_pixel(self->i2c, self->device_address, x, y, color);
is31fl3741_draw_pixel(self->i2c, self->device_address, x, y, color, self->mapping);
buffer++;
}
}
@ -240,6 +261,7 @@ void common_hal_is31fl3741_free_impl(void *ptr_in) {
void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self) {
gc_collect_ptr(self->framebuffer);
gc_collect_ptr(self->mapping);
}
// The following are routines to manipulate the IS31FL3741 chip
@ -311,16 +333,16 @@ void is31fl3741_set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_
common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
}
void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color) {
void is31fl3741_draw_pixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color, uint16_t *mapping) {
uint8_t r = color >> 16 & 0xFF;
uint8_t g = color >> 8 & 0xFF;
uint8_t b = color & 0xFF;
int16_t x1 = (x * 5 + y) * 3;
uint16_t ridx = glassesmatrix_ledmap[x1 + 2];
uint16_t ridx = mapping[x1 + 2];
if (ridx != 65535) {
uint16_t gidx = glassesmatrix_ledmap[x1 + 1];
uint16_t bidx = glassesmatrix_ledmap[x1 + 0];
uint16_t gidx = mapping[x1 + 1];
uint16_t bidx = mapping[x1 + 0];
is31fl3741_set_led(i2c, addr, ridx, r, 0);
is31fl3741_set_led(i2c, addr, gidx, g, 0);
is31fl3741_set_led(i2c, addr, bidx, b, 0);

View File

@ -39,12 +39,14 @@ typedef struct {
busio_i2c_obj_t *i2c;
busio_i2c_obj_t inline_i2c;
uint8_t device_address;
uint16_t *mapping;
uint8_t bit_depth;
bool paused;
bool scale;
bool auto_gamma;
} is31fl3741_is31fl3741_obj_t;
/*
static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = {
65535, 65535, 65535, // (0,0) (clipped, corner)
10, 8, 9, // (0,1) / right ring pixel 20
@ -137,6 +139,7 @@ static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = {
23, 25, 24, // (17,3) / 6
276, 22, 277, // (17,4) / 7
};
*/
// Gamma correction table
static const uint8_t IS31GammaTable[256] = {