Cleanup and scaling addition

This commit is contained in:
gamblor21 2021-11-09 22:53:01 -06:00
parent 29c58575b0
commit aa92d3a476
5 changed files with 121 additions and 108 deletions

View File

@ -85,14 +85,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 };
enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer, ARG_scale };
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_scale, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@ -106,6 +106,9 @@ 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;
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
if (framebuffer == mp_const_none) {
int width = args[ARG_width].u_int;

View File

@ -38,6 +38,9 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *);
int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self);
int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *self);
void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self);
void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_is31fl3741_obj_t *self);
void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current);
uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl3741_obj_t *self);
@ -46,6 +49,5 @@ bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *se
void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows);
void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer);
/*
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t *);
*/
void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self);

View File

@ -66,7 +66,7 @@ displayio_buffer_transform_t null_transform = {
};
#if CIRCUITPY_RGBMATRIX
#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741
STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
@ -143,6 +143,10 @@ void common_hal_displayio_release_displays(void) {
} else if (bus_type == &rgbmatrix_RGBMatrix_type) {
common_hal_rgbmatrix_rgbmatrix_deinit(&displays[i].rgbmatrix);
#endif
#if CIRCUITPY_IS31FL3741
} else if (bus_type == &is31fl3741_is31fl3741_type) {
common_hal_is31fl3741_is31fl3741_deinit(&displays[i].is31fl3741);
#endif
#if CIRCUITPY_SHARPDISPLAY
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
common_hal_sharpdisplay_framebuffer_deinit(&displays[i].sharpdisplay);
@ -217,6 +221,15 @@ void reset_displays(void) {
common_hal_rgbmatrix_rgbmatrix_set_paused(pm, true);
}
#endif
#if CIRCUITPY_IS31FL3741
} else if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) {
is31fl3741_is31fl3741_obj_t *pm = &displays[i].is31fl3741;
if (!any_display_uses_this_framebuffer(&pm->base)) {
common_hal_is31fl3741_is31fl3741_deinit(pm);
} else {
common_hal_is31fl3741_is31fl3741_set_paused(pm, true);
}
#endif
#if CIRCUITPY_SHARPDISPLAY
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
sharpdisplay_framebuffer_obj_t *sharp = &displays[i].sharpdisplay;
@ -251,6 +264,11 @@ void displayio_gc_collect(void) {
rgbmatrix_rgbmatrix_collect_ptrs(&displays[i].rgbmatrix);
}
#endif
#if CIRCUITPY_IS31FL3741
if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) {
is31fl3741_is31fl3741_collect_ptrs(&displays[i].is31fl3741);
}
#endif
#if CIRCUITPY_SHARPDISPLAY
if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
common_hal_sharpdisplay_framebuffer_collect_ptrs(&displays[i].sharpdisplay);

View File

@ -47,10 +47,7 @@ uint8_t cur_page = 99;
void send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) {
uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command
uint8_t result = common_hal_busio_i2c_write(i2c, addr, unlock, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "Unlock error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, unlock, 2, true);
}
void set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) {
@ -63,55 +60,35 @@ void set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) {
uint8_t page[2] = { 0xFD, 0x00 }; // page command
page[1] = p;
uint8_t result = common_hal_busio_i2c_write(i2c, addr, page, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "Set Page error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, page, 2, true);
}
void send_enable(busio_i2c_obj_t *i2c, uint8_t addr) {
set_page(i2c, addr, 4);
uint8_t enable[2] = { 0x00, 0x01 }; // enable command
uint8_t result = common_hal_busio_i2c_write(i2c, addr, enable, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "Enable error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, enable, 2, true);
}
void send_reset(busio_i2c_obj_t *i2c, uint8_t addr) {
set_page(i2c, addr, 4);
uint8_t rst[2] = { 0x3F, 0xAE }; // reset command
uint8_t result = common_hal_busio_i2c_write(i2c, addr, rst, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "reset error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, rst, 2, true);
}
void set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current) {
set_page(i2c, addr, 4);
uint8_t gcur[2] = { 0x01, 0x00 }; // global current command
gcur[1] = current;
uint8_t result = common_hal_busio_i2c_write(i2c, addr, gcur, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "set current error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, gcur, 2, true);
}
uint8_t get_current(busio_i2c_obj_t *i2c, uint8_t addr) {
set_page(i2c, addr, 4);
uint8_t gcur = 0x01; // global current command
uint8_t result = common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true);
if (result != 0) {
mp_printf(&mp_plat_print, "get current error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true);
uint8_t data = 0;
result = common_hal_busio_i2c_read(i2c, addr, &data, 1);
if (result != 0) {
mp_printf(&mp_plat_print, "get current error %x\n", result);
}
common_hal_busio_i2c_read(i2c, addr, &data, 1);
return data;
}
@ -129,10 +106,7 @@ void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, ui
cmd[1] = level;
uint8_t result = common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
if (result != 0) {
mp_printf(&mp_plat_print, "set led error %x\n", result);
}
common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
}
void drawPixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color) {
@ -168,7 +142,7 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel
common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer);
common_hal_busio_i2c_try_lock(i2c);
common_hal_displayio_is31fl3741_begin_transaction(self);
uint8_t command = 0xFC;
common_hal_busio_i2c_write(i2c, addr, &command, 1, false);
@ -184,7 +158,7 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel
set_led(i2c, addr, i, 0xFF, 2);
}
common_hal_busio_i2c_unlock(i2c);
common_hal_displayio_is31fl3741_end_transaction(self);
}
void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer) {
@ -210,69 +184,12 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
}
/*
memset(&self->protomatter, 0, sizeof(self->protomatter));
ProtomatterStatus stat = _PM_init(&self->protomatter,
self->width, self->bit_depth,
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->serpentine ? -self->tile : self->tile,
self->timer);
// initialize LEDs here
if (stat == PROTOMATTER_OK) {
_PM_protoPtr = &self->protomatter;
common_hal_is31fl3741_timer_enable(self->timer);
stat = _PM_begin(&self->protomatter);
if (stat == PROTOMATTER_OK) {
_PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
_PM_swapbuffer_maybe(&self->protomatter);
}
}
if (stat != PROTOMATTER_OK) {
common_hal_is31fl3741_is31fl3741_deinit(self);
switch (stat) {
case PROTOMATTER_ERR_PINS:
mp_raise_ValueError(translate("Invalid pin"));
break;
case PROTOMATTER_ERR_ARG:
mp_raise_ValueError(translate("Invalid argument"));
break;
case PROTOMATTER_ERR_MALLOC:
mp_raise_msg(&mp_type_MemoryError, NULL);
break;
default:
mp_raise_msg_varg(&mp_type_RuntimeError,
translate("Internal error #%d"), (int)stat);
break;
}
}
*/
self->paused = 0;
}
void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) {
/*
if (self->timer) {
common_hal_is31fl3741_timer_free(self->timer);
self->timer = 0;
}
if (_PM_protoPtr == &self->protomatter) {
_PM_protoPtr = NULL;
}
if (self->protomatter.rgbPins) {
_PM_deallocate(&self->protomatter);
}
memset(&self->protomatter, 0, sizeof(self->protomatter));
// If it was supervisor-allocated, it is supervisor-freed and the pointer
// is zeroed, otherwise the pointer is just zeroed
_PM_free(self->bufinfo.buf);
*/
self->base.type = NULL;
// If a framebuffer was passed in to the constructor, NULL the reference
@ -289,30 +206,67 @@ bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *se
}
void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current) {
common_hal_displayio_is31fl3741_begin_transaction(self);
set_current(self->i2c, self->device_address, current);
common_hal_displayio_is31fl3741_end_transaction(self);
}
uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl3741_obj_t *self) {
return get_current(self->i2c, self->device_address);
common_hal_displayio_is31fl3741_begin_transaction(self);
uint8_t current = get_current(self->i2c, self->device_address);
common_hal_displayio_is31fl3741_end_transaction(self);
return current;
}
void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows) {
uint8_t dirty_row_flags = 0xFF;
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) {
uint32_t *buffer = self->bufinfo.buf;
for (int y = 0; y < 5; y++) {
if ((dirty_row_flags >> y) & 0x1) {
for (int x = 0; x < 18; x++) {
drawPixel(self->i2c, self->device_address, x, y, *buffer);
buffer++;
if (self->scale) {
uint32_t *buffer = self->bufinfo.buf;
for (int x = 0; x < 18; x++) {
uint32_t *ptr = &buffer[x * 3]; // Entry along top scan line w/x offset
for (int y = 0; y < 5; y++) {
uint16_t rsum = 0, gsum = 0, bsum = 0;
// Inner x/y loops are row-major on purpose (less pointer math)
for (uint8_t yy = 0; yy < 3; yy++) {
for (uint8_t xx = 0; xx < 3; xx++) {
uint32_t rgb = ptr[xx];
rsum += rgb >> 16 & 0xFF;
gsum += (rgb >> 8) & 0xFF;
bsum += rgb & 0xFF;
}
ptr += 54; // canvas->width(); // Advance one scan line
}
rsum = rsum / 9;
gsum = gsum / 9;
bsum = bsum / 9;
uint32_t color = (IS31GammaTable[rsum] << 16) +
(IS31GammaTable[gsum] << 8) +
(IS31GammaTable[bsum] / 9);
drawPixel(self->i2c, self->device_address, x, y, color);
}
}
} else {
uint32_t *buffer = self->bufinfo.buf;
for (int y = 0; y < self->height; y++) {
if ((dirty_row_flags >> y) & 0x1) {
for (int x = 0; x < self->width; x++) {
drawPixel(self->i2c, self->device_address, x, y, *buffer);
buffer++;
}
}
}
}
}
common_hal_displayio_is31fl3741_end_transaction(self);
}
int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self) {
@ -323,6 +277,16 @@ int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *sel
return self->height;
}
void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self) {
while (!common_hal_busio_i2c_try_lock(self->i2c)) {
RUN_BACKGROUND_TASKS;
}
}
void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_is31fl3741_obj_t *self) {
common_hal_busio_i2c_unlock(self->i2c);
}
void *common_hal_is31fl3741_allocator_impl(size_t sz) {
supervisor_allocation *allocation = allocate_memory(align32_size(sz), false, true);
return allocation ? allocation->ptr : NULL;
@ -331,3 +295,7 @@ void *common_hal_is31fl3741_allocator_impl(size_t sz) {
void common_hal_is31fl3741_free_impl(void *ptr_in) {
free_memory(allocation_from_ptr(ptr_in));
}
void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self) {
gc_collect_ptr(self->framebuffer);
}

View File

@ -41,6 +41,7 @@ typedef struct {
uint8_t bit_depth;
bool paused;
bool doublebuffer;
bool scale;
} is31fl3741_is31fl3741_obj_t;
static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = {
@ -135,3 +136,24 @@ static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = {
23, 25, 24, // (17,3) / 6
276, 22, 277, // (17,4) / 7
};
static const uint8_t IS31GammaTable[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 17,
17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35,
36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 80, 81,
82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96, 97, 99, 100, 102,
103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 124, 125,
127, 129, 130, 132, 134, 136, 137, 139, 141, 143, 145, 146, 148, 150, 152,
154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182,
184, 186, 188, 191, 193, 195, 197, 199, 202, 204, 206, 209, 211, 213, 215,
218, 220, 223, 225, 227, 230, 232, 235, 237, 240, 242, 245, 247, 250, 252,
255
};