Skip to content

Commit aa92d3a

Browse files
committed
Cleanup and scaling addition
1 parent 29c5857 commit aa92d3a

File tree

5 files changed

+121
-108
lines changed

5 files changed

+121
-108
lines changed

shared-bindings/is31fl3741/is31fl3741.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@
8585
//|
8686

8787
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) {
88-
enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer };
88+
enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer, ARG_scale };
8989
static const mp_arg_t allowed_args[] = {
9090
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
9191
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
9292
{ MP_QSTR_i2c, MP_ARG_OBJ | MP_ARG_REQUIRED | MP_ARG_KW_ONLY },
9393
{ MP_QSTR_addr, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0x30 } },
9494
{ MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } },
95-
95+
{ MP_QSTR_scale, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } },
9696
};
9797
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
9898
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
106106
mp_raise_ValueError(translate("width must be greater than zero"));
107107
}
108108

109+
// TODO make sure height/width divisible by 3
110+
self->scale = args[ARG_scale].u_bool;
111+
109112
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
110113
if (framebuffer == mp_const_none) {
111114
int width = args[ARG_width].u_int;

shared-bindings/is31fl3741/is31fl3741.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *);
3838
int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self);
3939
int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *self);
4040

41+
void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self);
42+
void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_is31fl3741_obj_t *self);
43+
4144
void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current);
4245
uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl3741_obj_t *self);
4346

@@ -46,6 +49,5 @@ bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *se
4649
void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows);
4750

4851
void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer);
49-
/*
50-
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t *);
51-
*/
52+
53+
void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self);

shared-module/displayio/__init__.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ displayio_buffer_transform_t null_transform = {
6666
};
6767

6868

69-
#if CIRCUITPY_RGBMATRIX
69+
#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741
7070
STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
7171
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
7272
if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
@@ -143,6 +143,10 @@ void common_hal_displayio_release_displays(void) {
143143
} else if (bus_type == &rgbmatrix_RGBMatrix_type) {
144144
common_hal_rgbmatrix_rgbmatrix_deinit(&displays[i].rgbmatrix);
145145
#endif
146+
#if CIRCUITPY_IS31FL3741
147+
} else if (bus_type == &is31fl3741_is31fl3741_type) {
148+
common_hal_is31fl3741_is31fl3741_deinit(&displays[i].is31fl3741);
149+
#endif
146150
#if CIRCUITPY_SHARPDISPLAY
147151
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
148152
common_hal_sharpdisplay_framebuffer_deinit(&displays[i].sharpdisplay);
@@ -217,6 +221,15 @@ void reset_displays(void) {
217221
common_hal_rgbmatrix_rgbmatrix_set_paused(pm, true);
218222
}
219223
#endif
224+
#if CIRCUITPY_IS31FL3741
225+
} else if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) {
226+
is31fl3741_is31fl3741_obj_t *pm = &displays[i].is31fl3741;
227+
if (!any_display_uses_this_framebuffer(&pm->base)) {
228+
common_hal_is31fl3741_is31fl3741_deinit(pm);
229+
} else {
230+
common_hal_is31fl3741_is31fl3741_set_paused(pm, true);
231+
}
232+
#endif
220233
#if CIRCUITPY_SHARPDISPLAY
221234
} else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
222235
sharpdisplay_framebuffer_obj_t *sharp = &displays[i].sharpdisplay;
@@ -251,6 +264,11 @@ void displayio_gc_collect(void) {
251264
rgbmatrix_rgbmatrix_collect_ptrs(&displays[i].rgbmatrix);
252265
}
253266
#endif
267+
#if CIRCUITPY_IS31FL3741
268+
if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) {
269+
is31fl3741_is31fl3741_collect_ptrs(&displays[i].is31fl3741);
270+
}
271+
#endif
254272
#if CIRCUITPY_SHARPDISPLAY
255273
if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) {
256274
common_hal_sharpdisplay_framebuffer_collect_ptrs(&displays[i].sharpdisplay);

shared-module/is31fl3741/is31fl3741.c

Lines changed: 70 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ uint8_t cur_page = 99;
4747

4848
void send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) {
4949
uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command
50-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, unlock, 2, true);
51-
if (result != 0) {
52-
mp_printf(&mp_plat_print, "Unlock error %x\n", result);
53-
}
50+
common_hal_busio_i2c_write(i2c, addr, unlock, 2, true);
5451
}
5552

5653
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) {
6360

6461
uint8_t page[2] = { 0xFD, 0x00 }; // page command
6562
page[1] = p;
66-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, page, 2, true);
67-
if (result != 0) {
68-
mp_printf(&mp_plat_print, "Set Page error %x\n", result);
69-
}
63+
common_hal_busio_i2c_write(i2c, addr, page, 2, true);
7064
}
7165

7266
void send_enable(busio_i2c_obj_t *i2c, uint8_t addr) {
7367
set_page(i2c, addr, 4);
7468
uint8_t enable[2] = { 0x00, 0x01 }; // enable command
75-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, enable, 2, true);
76-
if (result != 0) {
77-
mp_printf(&mp_plat_print, "Enable error %x\n", result);
78-
}
69+
common_hal_busio_i2c_write(i2c, addr, enable, 2, true);
7970
}
8071

8172
void send_reset(busio_i2c_obj_t *i2c, uint8_t addr) {
8273
set_page(i2c, addr, 4);
8374
uint8_t rst[2] = { 0x3F, 0xAE }; // reset command
84-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, rst, 2, true);
85-
if (result != 0) {
86-
mp_printf(&mp_plat_print, "reset error %x\n", result);
87-
}
75+
common_hal_busio_i2c_write(i2c, addr, rst, 2, true);
8876
}
8977

9078
void set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current) {
9179
set_page(i2c, addr, 4);
9280
uint8_t gcur[2] = { 0x01, 0x00 }; // global current command
9381
gcur[1] = current;
94-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, gcur, 2, true);
95-
if (result != 0) {
96-
mp_printf(&mp_plat_print, "set current error %x\n", result);
97-
}
82+
common_hal_busio_i2c_write(i2c, addr, gcur, 2, true);
9883
}
9984

10085
uint8_t get_current(busio_i2c_obj_t *i2c, uint8_t addr) {
10186
set_page(i2c, addr, 4);
10287
uint8_t gcur = 0x01; // global current command
103-
104-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true);
105-
if (result != 0) {
106-
mp_printf(&mp_plat_print, "get current error %x\n", result);
107-
}
88+
common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true);
10889

10990
uint8_t data = 0;
110-
result = common_hal_busio_i2c_read(i2c, addr, &data, 1);
111-
if (result != 0) {
112-
mp_printf(&mp_plat_print, "get current error %x\n", result);
113-
}
114-
91+
common_hal_busio_i2c_read(i2c, addr, &data, 1);
11592
return data;
11693
}
11794

@@ -129,10 +106,7 @@ void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, ui
129106

130107
cmd[1] = level;
131108

132-
uint8_t result = common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
133-
if (result != 0) {
134-
mp_printf(&mp_plat_print, "set led error %x\n", result);
135-
}
109+
common_hal_busio_i2c_write(i2c, addr, cmd, 2, true);
136110
}
137111

138112
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
168142

169143
common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer);
170144

171-
common_hal_busio_i2c_try_lock(i2c);
145+
common_hal_displayio_is31fl3741_begin_transaction(self);
172146

173147
uint8_t command = 0xFC;
174148
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
184158
set_led(i2c, addr, i, 0xFF, 2);
185159
}
186160

187-
common_hal_busio_i2c_unlock(i2c);
161+
common_hal_displayio_is31fl3741_end_transaction(self);
188162
}
189163

190164
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
210184
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
211185
}
212186

213-
/*
214-
memset(&self->protomatter, 0, sizeof(self->protomatter));
215-
ProtomatterStatus stat = _PM_init(&self->protomatter,
216-
self->width, self->bit_depth,
217-
self->rgb_count / 6, self->rgb_pins,
218-
self->addr_count, self->addr_pins,
219-
self->clock_pin, self->latch_pin, self->oe_pin,
220-
self->doublebuffer, self->serpentine ? -self->tile : self->tile,
221-
self->timer);
222-
223-
if (stat == PROTOMATTER_OK) {
224-
_PM_protoPtr = &self->protomatter;
225-
common_hal_is31fl3741_timer_enable(self->timer);
226-
stat = _PM_begin(&self->protomatter);
227-
228-
if (stat == PROTOMATTER_OK) {
229-
_PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
230-
_PM_swapbuffer_maybe(&self->protomatter);
231-
}
232-
}
187+
// initialize LEDs here
233188

234-
if (stat != PROTOMATTER_OK) {
235-
common_hal_is31fl3741_is31fl3741_deinit(self);
236-
switch (stat) {
237-
case PROTOMATTER_ERR_PINS:
238-
mp_raise_ValueError(translate("Invalid pin"));
239-
break;
240-
case PROTOMATTER_ERR_ARG:
241-
mp_raise_ValueError(translate("Invalid argument"));
242-
break;
243-
case PROTOMATTER_ERR_MALLOC:
244-
mp_raise_msg(&mp_type_MemoryError, NULL);
245-
break;
246-
default:
247-
mp_raise_msg_varg(&mp_type_RuntimeError,
248-
translate("Internal error #%d"), (int)stat);
249-
break;
250-
}
251-
}
252-
*/
253189
self->paused = 0;
254190
}
255191

256192
void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) {
257-
/*
258-
if (self->timer) {
259-
common_hal_is31fl3741_timer_free(self->timer);
260-
self->timer = 0;
261-
}
262-
263-
if (_PM_protoPtr == &self->protomatter) {
264-
_PM_protoPtr = NULL;
265-
}
266-
267-
if (self->protomatter.rgbPins) {
268-
_PM_deallocate(&self->protomatter);
269-
}
270-
memset(&self->protomatter, 0, sizeof(self->protomatter));
271-
272-
// If it was supervisor-allocated, it is supervisor-freed and the pointer
273-
// is zeroed, otherwise the pointer is just zeroed
274-
_PM_free(self->bufinfo.buf);
275-
*/
276193
self->base.type = NULL;
277194

278195
// 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
289206
}
290207

291208
void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current) {
209+
common_hal_displayio_is31fl3741_begin_transaction(self);
292210
set_current(self->i2c, self->device_address, current);
211+
common_hal_displayio_is31fl3741_end_transaction(self);
293212
}
294213

295214
uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl3741_obj_t *self) {
296-
return get_current(self->i2c, self->device_address);
215+
common_hal_displayio_is31fl3741_begin_transaction(self);
216+
uint8_t current = get_current(self->i2c, self->device_address);
217+
common_hal_displayio_is31fl3741_end_transaction(self);
218+
return current;
297219
}
298220

299221
void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows) {
300-
uint8_t dirty_row_flags = 0xFF;
222+
common_hal_displayio_is31fl3741_begin_transaction(self);
223+
224+
uint8_t dirty_row_flags = 0xFF; // only supports 8 rows gotta fix
301225
if (dirtyrows != 0) {
302226
dirty_row_flags = *dirtyrows;
303227
}
304228

305229
if (!self->paused) {
306-
uint32_t *buffer = self->bufinfo.buf;
307-
for (int y = 0; y < 5; y++) {
308-
if ((dirty_row_flags >> y) & 0x1) {
309-
for (int x = 0; x < 18; x++) {
310-
drawPixel(self->i2c, self->device_address, x, y, *buffer);
311-
buffer++;
230+
if (self->scale) {
231+
uint32_t *buffer = self->bufinfo.buf;
232+
233+
for (int x = 0; x < 18; x++) {
234+
uint32_t *ptr = &buffer[x * 3]; // Entry along top scan line w/x offset
235+
for (int y = 0; y < 5; y++) {
236+
uint16_t rsum = 0, gsum = 0, bsum = 0;
237+
// Inner x/y loops are row-major on purpose (less pointer math)
238+
for (uint8_t yy = 0; yy < 3; yy++) {
239+
for (uint8_t xx = 0; xx < 3; xx++) {
240+
uint32_t rgb = ptr[xx];
241+
rsum += rgb >> 16 & 0xFF;
242+
gsum += (rgb >> 8) & 0xFF;
243+
bsum += rgb & 0xFF;
244+
}
245+
ptr += 54; // canvas->width(); // Advance one scan line
246+
}
247+
rsum = rsum / 9;
248+
gsum = gsum / 9;
249+
bsum = bsum / 9;
250+
uint32_t color = (IS31GammaTable[rsum] << 16) +
251+
(IS31GammaTable[gsum] << 8) +
252+
(IS31GammaTable[bsum] / 9);
253+
drawPixel(self->i2c, self->device_address, x, y, color);
254+
}
255+
}
256+
} else {
257+
uint32_t *buffer = self->bufinfo.buf;
258+
for (int y = 0; y < self->height; y++) {
259+
if ((dirty_row_flags >> y) & 0x1) {
260+
for (int x = 0; x < self->width; x++) {
261+
drawPixel(self->i2c, self->device_address, x, y, *buffer);
262+
buffer++;
263+
}
312264
}
313265
}
314266
}
315267
}
268+
269+
common_hal_displayio_is31fl3741_end_transaction(self);
316270
}
317271

318272
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
323277
return self->height;
324278
}
325279

280+
void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self) {
281+
while (!common_hal_busio_i2c_try_lock(self->i2c)) {
282+
RUN_BACKGROUND_TASKS;
283+
}
284+
}
285+
286+
void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_is31fl3741_obj_t *self) {
287+
common_hal_busio_i2c_unlock(self->i2c);
288+
}
289+
326290
void *common_hal_is31fl3741_allocator_impl(size_t sz) {
327291
supervisor_allocation *allocation = allocate_memory(align32_size(sz), false, true);
328292
return allocation ? allocation->ptr : NULL;
@@ -331,3 +295,7 @@ void *common_hal_is31fl3741_allocator_impl(size_t sz) {
331295
void common_hal_is31fl3741_free_impl(void *ptr_in) {
332296
free_memory(allocation_from_ptr(ptr_in));
333297
}
298+
299+
void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self) {
300+
gc_collect_ptr(self->framebuffer);
301+
}

0 commit comments

Comments
 (0)