diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index f7614caa2f..dbcf703b68 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -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 "" diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index d6b4732d04..9f72d07fc3 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -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) }, diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index d98ed91744..723687d227 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -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); diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index 7fa7269bee..b9375d8734 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -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); diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index b830596c19..78d2d1efce 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -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); diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index 530bae90ab..999e6ce64e 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -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] = {