From 146e8830f9c01b75abd32822d0fcc5a939f7aa5e Mon Sep 17 00:00:00 2001 From: Aivar Annamaa Date: Thu, 18 Nov 2021 10:21:51 +0200 Subject: [PATCH 01/25] Don't run main script when soft-rebooting in raw mode --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index a189add5e2..42b9630105 100644 --- a/main.c +++ b/main.c @@ -333,7 +333,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // Collects stickiness bits that apply in the current situation. uint8_t next_code_stickiness_situation = SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; - if (safe_mode == NO_SAFE_MODE) { + if (safe_mode == NO_SAFE_MODE && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { static const char *const supported_filenames[] = STRING_LIST( "code.txt", "code.py", "main.py", "main.txt"); #if CIRCUITPY_FULL_BUILD From d063bf2675c24e378151fed54cf6bdb16d3ff730 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 6 Nov 2021 14:00:11 -0500 Subject: [PATCH 02/25] Initial commit for IS31 --- ports/nrf/mpconfigport.mk | 2 + py/circuitpy_defns.mk | 5 + py/circuitpy_mpconfig.h | 1 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/is31fl3741/__init__.c | 49 ++++ shared-bindings/is31fl3741/is31fl3741.c | 333 +++++++++++++++++++++++ shared-bindings/is31fl3741/is31fl3741.h | 50 ++++ shared-module/displayio/Palette.c | 3 + shared-module/displayio/TileGrid.c | 2 + shared-module/displayio/__init__.h | 6 + shared-module/is31fl3741/__init__.c | 0 shared-module/is31fl3741/__init__.h | 0 shared-module/is31fl3741/allocator.h | 37 +++ shared-module/is31fl3741/is31fl3741.c | 348 ++++++++++++++++++++++++ shared-module/is31fl3741/is31fl3741.h | 137 ++++++++++ 15 files changed, 976 insertions(+) create mode 100644 shared-bindings/is31fl3741/__init__.c create mode 100644 shared-bindings/is31fl3741/is31fl3741.c create mode 100644 shared-bindings/is31fl3741/is31fl3741.h create mode 100644 shared-module/is31fl3741/__init__.c create mode 100644 shared-module/is31fl3741/__init__.h create mode 100644 shared-module/is31fl3741/allocator.h create mode 100644 shared-module/is31fl3741/is31fl3741.c create mode 100644 shared-module/is31fl3741/is31fl3741.h diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 87d79cb0e5..0795ae4e82 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -32,6 +32,8 @@ CIRCUITPY_BLEIO ?= 1 # No I2CPeripheral implementation CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_IS31FL3741 = 1 + CIRCUITPY_RTC ?= 1 # frequencyio not yet implemented diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 68b529a05f..dd690355bd 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -209,6 +209,9 @@ endif ifeq ($(CIRCUITPY_IPADDRESS),1) SRC_PATTERNS += ipaddress/% endif +ifeq ($(CIRCUITPY_IS31FL3741),1) +SRC_PATTERNS += is31fl3741/% +endif ifeq ($(CIRCUITPY_KEYPAD),1) SRC_PATTERNS += keypad/% endif @@ -548,6 +551,8 @@ SRC_SHARED_MODULE_ALL = \ imagecapture/ParallelImageCapture.c \ ipaddress/IPv4Address.c \ ipaddress/__init__.c \ + is31fl3741/is31fl3741.c \ + is31fl3741/__init__.c \ keypad/__init__.c \ keypad/Event.c \ keypad/EventQueue.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 5105be4d95..2474356a81 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -392,6 +392,7 @@ extern const struct _mp_obj_module_t nvm_module; // CIRCUITPY_I2CPERIPHERAL // CIRCUITPY_IMAGECAPTURE // CIRCUITPY_IPADDRESS +// CIRCUITPY_IS31FL3741 // CIRCUITPY_KEYPAD // CIRCUITPY_MATH // CIRCUITPY_MEMORYMONITOR diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index ccb9daf5eb..cbd9c0e9d1 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -247,6 +247,9 @@ CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS) +CIRCUITPY_IS31FL3741 ?= 0 +CFLAGS += -DCIRCUITPY_IS31FL3741=$(CIRCUITPY_IS31FL3741) + CIRCUITPY_JSON ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_JSON=$(CIRCUITPY_JSON) diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c new file mode 100644 index 0000000000..7a93702d0e --- /dev/null +++ b/shared-bindings/is31fl3741/__init__.c @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#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) }, +}; + +STATIC MP_DEFINE_CONST_DICT(is31fl3741_module_globals, is31fl3741_module_globals_table); + +const mp_obj_module_t is31fl3741_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&is31fl3741_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_is31fl3741, is31fl3741_module, CIRCUITPY_IS31FL3741); diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c new file mode 100644 index 0000000000..70892dc233 --- /dev/null +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -0,0 +1,333 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objarray.h" + +// #include "common-hal/is31fl3741/is31fl3741.h" +#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" +#include "shared-bindings/busio/I2C.h" + +//| class is31fl3741: +//| """Displays an in-memory framebuffer to a HUB75-style RGB LED matrix.""" +//| + +// extern Protomatter_core *_PM_protoPtr; + + +//| def __init__(self, *, width: int) -> None: +//| """Create a Is31fl3741 object with the given attributes. The height of +//| 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. +//| +//| Up to 30 RGB pins and 8 address pins are supported. +//| +//| The RGB pins must be within a single "port" and performance and memory +//| usage are best when they are all within "close by" bits of the port. +//| The clock pin must also be on the same port as the RGB pins. See the +//| documentation of the underlying protomatter C library for more +//| information. Generally, Adafruit's interface boards are designed so +//| that these requirements are met when matched with the intended +//| microcontroller board. For instance, the Feather M4 Express works +//| together with the RGB Matrix Feather. +//| +//| The framebuffer is in "RGB565" format. +//| +//| "RGB565" means that it is organized as a series of 16-bit numbers +//| where the highest 5 bits are interpreted as red, the next 6 as +//| green, and the final 5 as blue. The object can be any buffer, but +//| `array.array` and ``ulab.ndarray`` objects are most often useful. +//| To update the content, modify the framebuffer and call refresh. +//| +//| If a framebuffer is not passed in, one is allocated and initialized +//| to all black. In any case, the framebuffer can be retrieved +//| by passing the Is31fl3741 object to memoryview(). +//| +//| If doublebuffer is False, some memory is saved, but the display may +//| flicker during updates. +//| +//| A Is31fl3741 is often used in conjunction with a +//| `framebufferio.FramebufferDisplay`.""" +//| + +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 }; + 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_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); + + mp_printf(&mp_plat_print, "IS make new\n"); + + mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); + + is31fl3741_is31fl3741_obj_t *self = &allocate_display_bus_or_raise()->is31fl3741; + self->base.type = &is31fl3741_is31fl3741_type; + + if (args[ARG_width].u_int <= 0) { + mp_raise_ValueError(translate("width must be greater than zero")); + } + + mp_printf(&mp_plat_print, "w %d h %d\n", args[ARG_width].u_int, args[ARG_height].u_int); + + mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; + if (framebuffer == mp_const_none) { + int width = args[ARG_width].u_int; + int height = args[ARG_height].u_int; + int bufsize = 4 * width * height; + framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); + } + mp_printf(&mp_plat_print, "framebuffer is %x\n", MP_OBJ_TO_PTR(framebuffer)); + + common_hal_is31fl3741_is31fl3741_construct(self, + args[ARG_width].u_int, + args[ARG_height].u_int, + framebuffer, + MP_OBJ_TO_PTR(i2c), + args[ARG_addr].u_int + ); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| is31fl3741 instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| +STATIC mp_obj_t is31fl3741_is31fl3741_deinit(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS Deinit\n"); + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + common_hal_is31fl3741_is31fl3741_deinit(self); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_deinit_obj, is31fl3741_is31fl3741_deinit); + +static void check_for_deinit(is31fl3741_is31fl3741_obj_t *self) { + // if (!self->protomatter.rgbPins) { + // raise_deinited_error(); + // } +} + +//| brightness: float +//| """In the current implementation, 0.0 turns the display off entirely +//| and any other value up to 1.0 turns the display on fully.""" +//| +STATIC mp_obj_t is31fl3741_is31fl3741_get_brightness(mp_obj_t self_in) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + check_for_deinit(self); + return mp_obj_new_float(common_hal_is31fl3741_is31fl3741_get_paused(self)? 0.0f : 1.0f); +} +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_brightness_obj, is31fl3741_is31fl3741_get_brightness); + +STATIC mp_obj_t is31fl3741_is31fl3741_set_brightness(mp_obj_t self_in, mp_obj_t value_in) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + check_for_deinit(self); + mp_float_t brightness = mp_obj_get_float(value_in); + if (brightness < 0.0f || brightness > 1.0f) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + common_hal_is31fl3741_is31fl3741_set_paused(self, brightness <= 0); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(is31fl3741_is31fl3741_set_brightness_obj, is31fl3741_is31fl3741_set_brightness); + +const mp_obj_property_t is31fl3741_is31fl3741_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_brightness_obj, + (mp_obj_t)&is31fl3741_is31fl3741_set_brightness_obj, + MP_ROM_NONE}, +}; + +//| def refresh(self) -> None: +//| """Transmits the color data in the buffer to the pixels so that +//| they are shown.""" +//| ... +//| +STATIC mp_obj_t is31fl3741_is31fl3741_refresh(mp_obj_t self_in) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + check_for_deinit(self); + common_hal_is31fl3741_is31fl3741_refresh(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_refresh_obj, is31fl3741_is31fl3741_refresh); + +//| width: int +//| """The width of the display, in pixels""" +//| +STATIC mp_obj_t is31fl3741_is31fl3741_get_width(mp_obj_t self_in) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_is31fl3741_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_width_obj, is31fl3741_is31fl3741_get_width); +const mp_obj_property_t is31fl3741_is31fl3741_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_width_obj, + MP_ROM_NONE, + MP_ROM_NONE}, +}; + +//| height: int +//| """The height of the display, in pixels""" +//| +STATIC mp_obj_t is31fl3741_is31fl3741_get_height(mp_obj_t self_in) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_is31fl3741_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_height_obj, is31fl3741_is31fl3741_get_height); +const mp_obj_property_t is31fl3741_is31fl3741_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_height_obj, + MP_ROM_NONE, + MP_ROM_NONE}, +}; + +STATIC const mp_rom_map_elem_t is31fl3741_is31fl3741_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&is31fl3741_is31fl3741_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&is31fl3741_is31fl3741_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&is31fl3741_is31fl3741_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&is31fl3741_is31fl3741_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&is31fl3741_is31fl3741_height_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(is31fl3741_is31fl3741_locals_dict, is31fl3741_is31fl3741_locals_dict_table); + +STATIC void is31fl3741_is31fl3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + // mp_printf(&mp_plat_print, "IS get bufinfo %x\n", self->bufinfo.buf); + check_for_deinit(self); + + *bufinfo = self->bufinfo; +} + +// These version exists so that the prototype matches the protocol, +// avoiding a type cast that can hide errors +STATIC void is31fl3741_is31fl3741_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { + // mp_printf(&mp_plat_print, "IS swapbuffers\n"); + (void)dirty_row_bitmap; + common_hal_is31fl3741_is31fl3741_refresh(self_in); +} + +STATIC void is31fl3741_is31fl3741_deinit_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS deinit proto\n"); + common_hal_is31fl3741_is31fl3741_deinit(self_in); +} + +STATIC float is31fl3741_is31fl3741_get_brightness_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get brigthness\n"); + return common_hal_is31fl3741_is31fl3741_get_paused(self_in) ? 0.0f : 1.0f; +} + +STATIC bool is31fl3741_is31fl3741_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { + mp_printf(&mp_plat_print, "IS set brightness\n"); + common_hal_is31fl3741_is31fl3741_set_paused(self_in, value <= 0); + return true; +} + +STATIC int is31fl3741_is31fl3741_get_width_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get width\n"); + return common_hal_is31fl3741_is31fl3741_get_width(self_in); +} + +STATIC int is31fl3741_is31fl3741_get_height_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get height\n"); + return common_hal_is31fl3741_is31fl3741_get_height(self_in); +} + +STATIC int is31fl3741_is31fl3741_get_color_depth_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get color depth\n"); + return 32; +} + +STATIC int is31fl3741_is31fl3741_get_bytes_per_cell_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get bytes per cell\n"); + return 1; +} + +STATIC int is31fl3741_is31fl3741_get_native_frames_per_second_proto(mp_obj_t self_in) { + mp_printf(&mp_plat_print, "IS get fps\n"); + return 60; +} + + +STATIC const framebuffer_p_t is31fl3741_is31fl3741_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .get_bufinfo = is31fl3741_is31fl3741_get_bufinfo, + .set_brightness = is31fl3741_is31fl3741_set_brightness_proto, + .get_brightness = is31fl3741_is31fl3741_get_brightness_proto, + .get_width = is31fl3741_is31fl3741_get_width_proto, + .get_height = is31fl3741_is31fl3741_get_height_proto, + .get_color_depth = is31fl3741_is31fl3741_get_color_depth_proto, + .get_bytes_per_cell = is31fl3741_is31fl3741_get_bytes_per_cell_proto, + .get_native_frames_per_second = is31fl3741_is31fl3741_get_native_frames_per_second_proto, + .swapbuffers = is31fl3741_is31fl3741_swapbuffers, + .deinit = is31fl3741_is31fl3741_deinit_proto, +}; + +STATIC mp_int_t is31fl3741_is31fl3741_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; + // a readonly framebuffer would be unusual but not impossible + mp_printf(&mp_plat_print, "IS IS get buffer\n"); + if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { + return 1; + } + *bufinfo = self->bufinfo; + bufinfo->typecode = 'H'; + return 0; +} + +const mp_obj_type_t is31fl3741_is31fl3741_type = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_is31fl3741, + .locals_dict = (mp_obj_dict_t *)&is31fl3741_is31fl3741_locals_dict, + .make_new = is31fl3741_is31fl3741_make_new, + MP_TYPE_EXTENDED_FIELDS( + .buffer_p = { .get_buffer = is31fl3741_is31fl3741_get_buffer, }, + .protocol = &is31fl3741_is31fl3741_proto, + ), +}; diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h new file mode 100644 index 0000000000..dfcc995c47 --- /dev/null +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "shared-module/is31fl3741/is31fl3741.h" +// #include "lib/protomatter/src/core.h" + +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_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_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused); +bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self); +void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self); + +void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer); +/* +void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t *); + + +*/ diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index 47cad11ea5..1dd88a4419 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -89,6 +89,9 @@ bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_col } else if (colorspace->grayscale) { size_t bitmask = (1 << colorspace->depth) - 1; *color = (self->colors[palette_index].luma >> colorspace->grayscale_bit) & bitmask; + } else if (colorspace->depth == 32) { + uint32_t c = self->colors[palette_index].rgb888; + *color = c; } else { uint16_t packed = self->colors[palette_index].rgb565; if (colorspace->reverse_bytes_in_word) { diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 044674f415..9e00dbafcc 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -472,6 +472,8 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_c mask[offset / 32] |= 1 << (offset % 32); if (colorspace->depth == 16) { *(((uint16_t *)buffer) + offset) = output_pixel.pixel; + } else if (colorspace->depth == 32) { + *(((uint32_t *)buffer) + offset) = output_pixel.pixel; } else if (colorspace->depth == 8) { *(((uint8_t *)buffer) + offset) = output_pixel.pixel; } else if (colorspace->depth < 8) { diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 5bfee4d67d..1d16cdad59 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -41,6 +41,9 @@ #if CIRCUITPY_RGBMATRIX #include "shared-bindings/rgbmatrix/RGBMatrix.h" #endif +#if CIRCUITPY_IS31FL3741 +#include "shared-bindings/is31fl3741/is31fl3741.h" +#endif #if CIRCUITPY_SHARPDISPLAY #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" #endif @@ -56,6 +59,9 @@ typedef struct { #if CIRCUITPY_RGBMATRIX rgbmatrix_rgbmatrix_obj_t rgbmatrix; #endif + #if CIRCUITPY_IS31FL3741 + is31fl3741_is31fl3741_obj_t is31fl3741; + #endif #if CIRCUITPY_SHARPDISPLAY sharpdisplay_framebuffer_obj_t sharpdisplay; #endif diff --git a/shared-module/is31fl3741/__init__.c b/shared-module/is31fl3741/__init__.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/is31fl3741/__init__.h b/shared-module/is31fl3741/__init__.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared-module/is31fl3741/allocator.h b/shared-module/is31fl3741/allocator.h new file mode 100644 index 0000000000..ecf926c01c --- /dev/null +++ b/shared-module/is31fl3741/allocator.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include +#include "py/gc.h" +#include "py/misc.h" +#include "supervisor/memory.h" + +// #define _PM_allocate common_hal_rgbmatrix_allocator_impl +// #define _PM_free(x) (common_hal_rgbmatrix_free_impl((x)), (x) = NULL, (void)0) +extern void *common_hal_is31fl3741_allocator_impl(size_t sz); +extern void common_hal_is31fl3741_free_impl(void *); diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c new file mode 100644 index 0000000000..7f60ff750f --- /dev/null +++ b/shared-module/is31fl3741/is31fl3741.c @@ -0,0 +1,348 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/gc.h" +#include "py/obj.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +// #include "common-hal/is31fl3741/Is31fl3741.h" +#include "shared-module/is31fl3741/allocator.h" +#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" +#include "shared-bindings/busio/I2C.h" + +extern Protomatter_core *_PM_protoPtr; + +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); + } +} + +void set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) { + if (p == cur_page) { + return; + } + + cur_page = p; + send_unlock(i2c, addr); + + uint8_t page[2] = { 0xFD, 0x00 }; // page command + page[1] = p; + // mp_printf(&mp_plat_print, "Set Page %x -> %x\n", page[0], page[1]); + 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); + } +} + +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); + } + mp_printf(&mp_plat_print, "CH IS construct: enable\n"); +} + +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); + } + mp_printf(&mp_plat_print, "CH IS construct: reset\n"); +} + +void set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t cur) { + set_page(i2c, addr, 4); + uint8_t gcur[2] = { 0x01, 0x00 }; // global current command + gcur[1] = cur; + 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); + } + mp_printf(&mp_plat_print, "CH IS construct: set global current\n"); +} + +void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, uint8_t page) { + uint8_t cmd[2] = { 0x00, 0x00 }; + + if (led < 180) { + set_page(i2c, addr, page); + cmd[0] = (uint8_t)led; + } else { + set_page(i2c, addr, page + 1); + cmd[0] = (uint8_t)(led - 180); + } + + 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); + } + // mp_printf(&mp_plat_print, "CH IS construct: set led %x -> %x\n", led, level); +} + +void drawPixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color) { + 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]; + if (ridx != 65535) { + uint16_t gidx = glassesmatrix_ledmap[x1 + 1]; + uint16_t bidx = glassesmatrix_ledmap[x1 + 0]; + set_led(i2c, addr, ridx, r, 0); + set_led(i2c, addr, gidx, g, 0); + set_led(i2c, addr, bidx, b, 0); + // mp_printf(&mp_plat_print, "drawPixel: x %d y %d r %02x g %02x b %02x ri %d gi %d bi %d\n", x, y, r, g, b, ridx, gidx, bidx); + } else { + // mp_printf(&mp_plat_print, "drawPixel: x %d y %d r %02x g %02x b %02x OOB\n", x, y, r, g, b); + } + +} + + + + +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_printf(&mp_plat_print, "CH IS construct %x\n", addr); + self->width = width; + self->height = height; + + self->bufsize = 4 * width * height; + + // Probe the bus to see if a device acknowledges the given address. + if (!common_hal_busio_i2c_probe(i2c, addr)) { + self->base.type = &mp_type_NoneType; + mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), addr); + } + + self->i2c = i2c; + self->device_address = addr; + + common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer); + + common_hal_busio_i2c_try_lock(i2c); + + uint8_t command = 0xFC; + common_hal_busio_i2c_write(i2c, addr, &command, 1, false); + uint8_t data = 0; + common_hal_busio_i2c_read(i2c, addr, &data, 1); + mp_printf(&mp_plat_print, "CH IS construct device %x\n", data); + + send_reset(i2c, addr); + send_enable(i2c, addr); + set_current(i2c, addr, 0x08); + + // set scale to max for all + for (int i; i < 351; i++) { + set_led(i2c, addr, i, 0xFF, 2); + } + + // set_led(i2c, addr, 0x09, 0xA1, 0); + // set_led(i2c, addr, 309, 0xA1, 0); + // set_led(i2c, addr, 0x09, 0xCC, 2); + + // set_led(i2c, addr, 0x19, 0xA2, 0); + // set_led(i2c, addr, 0x19, 0x02, 2); + + // set_led(i2c, addr, 0x2A, 0xA3, 1); + // set_led(i2c, addr, 0x29, 0xEE, 3); + + common_hal_busio_i2c_unlock(i2c); + + +} + +void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer) { + self->paused = 1; + + if (framebuffer) { + mp_printf(&mp_plat_print, "CH IS reconstruct framebuffer %x\n", MP_OBJ_TO_PTR(framebuffer)); + self->framebuffer = framebuffer; + mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ); + if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) { + self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; + } else { + self->bufinfo.typecode = 'H'; + } + mp_printf(&mp_plat_print, "CH IS reconstruct self->bufinfo is %x\n", self->bufinfo.buf); + // verify that the matrix is big enough + mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize - 1), false); + } else { + mp_printf(&mp_plat_print, "CH IS reconstruct NO framebuffer\n"); + common_hal_is31fl3741_free_impl(self->bufinfo.buf); + + self->framebuffer = NULL; + self->bufinfo.buf = common_hal_is31fl3741_allocator_impl(self->bufsize); + self->bufinfo.len = self->bufsize; + 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); + + 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) { + mp_printf(&mp_plat_print, "IS CH Deinit\n"); + /* + 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 + // here so that it will become GC'able + self->framebuffer = NULL; +} + +void common_hal_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused) { + mp_printf(&mp_plat_print, "CH IS set paused\n"); + /*if (paused && !self->paused) { + _PM_stop(&self->protomatter); + } else if (!paused && self->paused) { + _PM_resume(&self->protomatter); + _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width); + _PM_swapbuffer_maybe(&self->protomatter); + }*/ + self->paused = paused; +} + +bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self) { + mp_printf(&mp_plat_print, "CH IS get paused\n"); + return self->paused; +} + +void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self) { + // mp_printf(&mp_plat_print, "CH IS refresh len %x addr %x\n", self->bufinfo.len, self->bufinfo.buf); + + if (!self->paused) { + uint32_t *buffer = self->bufinfo.buf; + for (int y = 0; y < 5; y++) { + for (int x = 0; x < 18; x++) { + drawPixel(self->i2c, self->device_address, x, y, *buffer); + // mp_printf(&mp_plat_print, "%06x ", *buffer); + buffer++; + } + // mp_printf(&mp_plat_print, "\n"); + } + // + // _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width); + // _PM_swapbuffer_maybe(&self->protomatter); + } +} + +int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self) { + mp_printf(&mp_plat_print, "CH IS get width\n"); + return self->width; +} + +int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *self) { + mp_printf(&mp_plat_print, "CH IS get height\n"); + return self->height; +} + +void *common_hal_is31fl3741_allocator_impl(size_t sz) { + mp_printf(&mp_plat_print, "CH IS allocator\n"); + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false, true); + return allocation ? allocation->ptr : NULL; +} + +void common_hal_is31fl3741_free_impl(void *ptr_in) { + mp_printf(&mp_plat_print, "CH IS free\n"); + free_memory(allocation_from_ptr(ptr_in)); +} diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h new file mode 100644 index 0000000000..280192e0d4 --- /dev/null +++ b/shared-module/is31fl3741/is31fl3741.h @@ -0,0 +1,137 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include "py/obj.h" +#include "lib/protomatter/src/core.h" +#include "shared-bindings/busio/I2C.h" + +extern const mp_obj_type_t is31fl3741_is31fl3741_type; +typedef struct { + mp_obj_base_t base; + mp_obj_t framebuffer; + mp_buffer_info_t bufinfo; + uint16_t bufsize, width, height; + busio_i2c_obj_t *i2c; + uint8_t device_address; + uint8_t bit_depth; + bool paused; + bool doublebuffer; +} 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 + 13, 11, 12, // (0,2) / 19 + 16, 14, 15, // (0,3) / 18 + 4, 2, 3, // (0,4) / 17 + 217, 215, 216, // (1,0) / right ring pixel #21 + 220, 218, 219, // (1,1) + 223, 221, 222, // (1,2) + 226, 224, 225, // (1,3) + 214, 212, 213, // (1,4) + 187, 185, 186, // (2,0) + 190, 188, 189, // (2,1) + 193, 191, 192, // (2,2) + 196, 194, 195, // (2,3) + 184, 182, 183, // (2,4) + 37, 35, 36, // (3,0) + 40, 38, 39, // (3,1) + 43, 41, 42, // (3,2) + 46, 44, 45, // (3,3) + 34, 32, 33, // (3,4) + 67, 65, 66, // (4,0) + 70, 68, 69, // (4,1) + 73, 71, 72, // (4,2) + 76, 74, 75, // (4,3) + 64, 62, 63, // (4,4) + 97, 95, 96, // (5,0) + 100, 98, 99, // (5,1) + 103, 101, 102, // (5,2) + 106, 104, 105, // (5,3) + 94, 92, 93, // (5,4) + 127, 125, 126, // (6,0) / right ring pixel 3 + 130, 128, 129, // (6,1) + 133, 131, 132, // (6,2) + 136, 134, 135, // (6,3) + 124, 122, 123, // (6,4) + 157, 155, 156, // (7,0) + 160, 158, 159, // (7,1) + 163, 161, 162, // (7,2) / right ring pixel 5 + 166, 164, 165, // (7,3) / 6 + 244, 242, 243, // (7,4) / 7 + 247, 245, 246, // (8,0) + 250, 248, 249, // (8,1) + 253, 251, 252, // (8,2) + 256, 254, 255, // (8,3) + 65535, 65535, 65535, // (8,4) (clipped, nose bridge) + 345, 347, 346, // (9,0) + 342, 344, 343, // (9,1) + 267, 269, 268, // (9,2) + 263, 265, 264, // (9,3) + 65535, 65535, 65535, // (9,4) (clipped, nose bridge) + 336, 338, 337, // (10,0) + 333, 335, 334, // (10,1) + 237, 239, 238, // (10,2) / left ring pixel 19 + 233, 235, 234, // (10,3) / 18 + 348, 262, 349, // (10,4) / 17 + 327, 329, 328, // (11,0) / left ring pixel 21 + 324, 326, 325, // (11,1) + 207, 209, 208, // (11,2) + 203, 205, 204, // (11,3) + 330, 202, 331, // (11,4) + 318, 320, 319, // (12,0) + 315, 317, 316, // (12,1) + 177, 179, 178, // (12,2) + 173, 175, 174, // (12,3) + 321, 172, 322, // (12,4) + 309, 311, 310, // (13,0) + 306, 308, 307, // (13,1) + 147, 149, 148, // (13,2) + 143, 145, 144, // (13,3) + 312, 142, 313, // (13,4) + 300, 302, 301, // (14,0) + 297, 299, 298, // (14,1) + 117, 119, 118, // (14,2) + 113, 115, 114, // (14,3) + 303, 112, 304, // (14,4) + 291, 293, 292, // (15,0) + 288, 290, 289, // (15,1) + 87, 89, 88, // (15,2) + 83, 85, 84, // (15,3) + 294, 82, 295, // (15,4) + 282, 284, 283, // (16,0) / left ring pixel 3 + 279, 281, 280, // (16,1) + 57, 59, 58, // (16,2) + 53, 55, 54, // (16,3) + 285, 52, 286, // (16,4) + 65535, 65535, 65535, // (17,0) (clipped, corner) + 270, 272, 271, // (17,1) / left ring pixel 4 + 27, 29, 28, // (17,2) / 5 + 23, 25, 24, // (17,3) / 6 + 276, 22, 277, // (17,4) / 7 +}; From 29c58575b036c723347c343e3243ce44165ff407 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sun, 7 Nov 2021 14:13:11 -0600 Subject: [PATCH 03/25] Removed prints updated brightness --- shared-bindings/is31fl3741/is31fl3741.c | 34 ++++----- shared-bindings/is31fl3741/is31fl3741.h | 7 +- shared-module/is31fl3741/is31fl3741.c | 95 +++++++++++-------------- 3 files changed, 56 insertions(+), 80 deletions(-) diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index 70892dc233..b6ed81a634 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -97,8 +97,6 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t 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); - mp_printf(&mp_plat_print, "IS make new\n"); - mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); is31fl3741_is31fl3741_obj_t *self = &allocate_display_bus_or_raise()->is31fl3741; @@ -108,8 +106,6 @@ 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")); } - mp_printf(&mp_plat_print, "w %d h %d\n", args[ARG_width].u_int, args[ARG_height].u_int); - mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; if (framebuffer == mp_const_none) { int width = args[ARG_width].u_int; @@ -117,7 +113,6 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t int bufsize = 4 * width * height; framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); } - mp_printf(&mp_plat_print, "framebuffer is %x\n", MP_OBJ_TO_PTR(framebuffer)); common_hal_is31fl3741_is31fl3741_construct(self, args[ARG_width].u_int, @@ -137,7 +132,6 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t //| ... //| STATIC mp_obj_t is31fl3741_is31fl3741_deinit(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS Deinit\n"); is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; common_hal_is31fl3741_is31fl3741_deinit(self); return mp_const_none; @@ -158,7 +152,10 @@ static void check_for_deinit(is31fl3741_is31fl3741_obj_t *self) { STATIC mp_obj_t is31fl3741_is31fl3741_get_brightness(mp_obj_t self_in) { is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; check_for_deinit(self); - return mp_obj_new_float(common_hal_is31fl3741_is31fl3741_get_paused(self)? 0.0f : 1.0f); + uint8_t current = common_hal_is31fl3741_is31fl3741_get_global_current(self); + + float brightness = (float)current / (float)0xFF; + return mp_obj_new_float(brightness); } MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_brightness_obj, is31fl3741_is31fl3741_get_brightness); @@ -169,7 +166,9 @@ STATIC mp_obj_t is31fl3741_is31fl3741_set_brightness(mp_obj_t self_in, mp_obj_t if (brightness < 0.0f || brightness > 1.0f) { mp_raise_ValueError(translate("Brightness must be 0-1.0")); } - common_hal_is31fl3741_is31fl3741_set_paused(self, brightness <= 0); + + uint8_t current = (uint8_t)(brightness * 0xFF); + common_hal_is31fl3741_is31fl3741_set_global_current(self, current); return mp_const_none; } @@ -190,7 +189,7 @@ const mp_obj_property_t is31fl3741_is31fl3741_brightness_obj = { STATIC mp_obj_t is31fl3741_is31fl3741_refresh(mp_obj_t self_in) { is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; check_for_deinit(self); - common_hal_is31fl3741_is31fl3741_refresh(self); + common_hal_is31fl3741_is31fl3741_refresh(self, 0); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_refresh_obj, is31fl3741_is31fl3741_refresh); @@ -238,7 +237,6 @@ STATIC MP_DEFINE_CONST_DICT(is31fl3741_is31fl3741_locals_dict, is31fl3741_is31fl STATIC void is31fl3741_is31fl3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; - // mp_printf(&mp_plat_print, "IS get bufinfo %x\n", self->bufinfo.buf); check_for_deinit(self); *bufinfo = self->bufinfo; @@ -247,49 +245,42 @@ STATIC void is31fl3741_is31fl3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t // These version exists so that the prototype matches the protocol, // avoiding a type cast that can hide errors STATIC void is31fl3741_is31fl3741_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { - // mp_printf(&mp_plat_print, "IS swapbuffers\n"); - (void)dirty_row_bitmap; - common_hal_is31fl3741_is31fl3741_refresh(self_in); + common_hal_is31fl3741_is31fl3741_refresh(self_in, dirty_row_bitmap); } STATIC void is31fl3741_is31fl3741_deinit_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS deinit proto\n"); common_hal_is31fl3741_is31fl3741_deinit(self_in); } STATIC float is31fl3741_is31fl3741_get_brightness_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get brigthness\n"); return common_hal_is31fl3741_is31fl3741_get_paused(self_in) ? 0.0f : 1.0f; } STATIC bool is31fl3741_is31fl3741_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { - mp_printf(&mp_plat_print, "IS set brightness\n"); common_hal_is31fl3741_is31fl3741_set_paused(self_in, value <= 0); return true; } STATIC int is31fl3741_is31fl3741_get_width_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get width\n"); return common_hal_is31fl3741_is31fl3741_get_width(self_in); } STATIC int is31fl3741_is31fl3741_get_height_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get height\n"); return common_hal_is31fl3741_is31fl3741_get_height(self_in); } STATIC int is31fl3741_is31fl3741_get_color_depth_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get color depth\n"); + // The way displayio works depth is used to calculate bytes + // We use an uint32_t for color already so setting to 24 causes + // more changes required return 32; } STATIC int is31fl3741_is31fl3741_get_bytes_per_cell_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get bytes per cell\n"); return 1; } STATIC int is31fl3741_is31fl3741_get_native_frames_per_second_proto(mp_obj_t self_in) { - mp_printf(&mp_plat_print, "IS get fps\n"); return 60; } @@ -311,7 +302,6 @@ STATIC const framebuffer_p_t is31fl3741_is31fl3741_proto = { STATIC mp_int_t is31fl3741_is31fl3741_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; // a readonly framebuffer would be unusual but not impossible - mp_printf(&mp_plat_print, "IS IS get buffer\n"); if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { return 1; } diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index dfcc995c47..172e0820a3 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -38,13 +38,14 @@ 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_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); + void common_hal_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused); bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self); -void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self); +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 *); - - */ diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index 7f60ff750f..b3fca18d03 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -63,7 +63,6 @@ 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; - // mp_printf(&mp_plat_print, "Set Page %x -> %x\n", page[0], page[1]); 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); @@ -77,7 +76,6 @@ void send_enable(busio_i2c_obj_t *i2c, uint8_t addr) { if (result != 0) { mp_printf(&mp_plat_print, "Enable error %x\n", result); } - mp_printf(&mp_plat_print, "CH IS construct: enable\n"); } void send_reset(busio_i2c_obj_t *i2c, uint8_t addr) { @@ -87,20 +85,37 @@ void send_reset(busio_i2c_obj_t *i2c, uint8_t addr) { if (result != 0) { mp_printf(&mp_plat_print, "reset error %x\n", result); } - mp_printf(&mp_plat_print, "CH IS construct: reset\n"); } -void set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t cur) { +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] = cur; + 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); } - mp_printf(&mp_plat_print, "CH IS construct: set global current\n"); } +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); + } + + 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); + } + + return data; +} + + void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, uint8_t page) { uint8_t cmd[2] = { 0x00, 0x00 }; @@ -118,7 +133,6 @@ void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, ui if (result != 0) { mp_printf(&mp_plat_print, "set led error %x\n", result); } - // mp_printf(&mp_plat_print, "CH IS construct: set led %x -> %x\n", led, level); } void drawPixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_t color) { @@ -134,18 +148,10 @@ void drawPixel(busio_i2c_obj_t *i2c, uint8_t addr, int16_t x, int16_t y, uint32_ set_led(i2c, addr, ridx, r, 0); set_led(i2c, addr, gidx, g, 0); set_led(i2c, addr, bidx, b, 0); - // mp_printf(&mp_plat_print, "drawPixel: x %d y %d r %02x g %02x b %02x ri %d gi %d bi %d\n", x, y, r, g, b, ridx, gidx, bidx); - } else { - // mp_printf(&mp_plat_print, "drawPixel: x %d y %d r %02x g %02x b %02x OOB\n", x, y, r, g, b); } - } - - - 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_printf(&mp_plat_print, "CH IS construct %x\n", addr); self->width = width; self->height = height; @@ -168,7 +174,6 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel common_hal_busio_i2c_write(i2c, addr, &command, 1, false); uint8_t data = 0; common_hal_busio_i2c_read(i2c, addr, &data, 1); - mp_printf(&mp_plat_print, "CH IS construct device %x\n", data); send_reset(i2c, addr); send_enable(i2c, addr); @@ -179,26 +184,13 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel set_led(i2c, addr, i, 0xFF, 2); } - // set_led(i2c, addr, 0x09, 0xA1, 0); - // set_led(i2c, addr, 309, 0xA1, 0); - // set_led(i2c, addr, 0x09, 0xCC, 2); - - // set_led(i2c, addr, 0x19, 0xA2, 0); - // set_led(i2c, addr, 0x19, 0x02, 2); - - // set_led(i2c, addr, 0x2A, 0xA3, 1); - // set_led(i2c, addr, 0x29, 0xEE, 3); - common_hal_busio_i2c_unlock(i2c); - - } void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer) { self->paused = 1; if (framebuffer) { - mp_printf(&mp_plat_print, "CH IS reconstruct framebuffer %x\n", MP_OBJ_TO_PTR(framebuffer)); self->framebuffer = framebuffer; mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ); if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) { @@ -206,11 +198,10 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s } else { self->bufinfo.typecode = 'H'; } - mp_printf(&mp_plat_print, "CH IS reconstruct self->bufinfo is %x\n", self->bufinfo.buf); + // verify that the matrix is big enough mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize - 1), false); } else { - mp_printf(&mp_plat_print, "CH IS reconstruct NO framebuffer\n"); common_hal_is31fl3741_free_impl(self->bufinfo.buf); self->framebuffer = NULL; @@ -263,7 +254,6 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s } void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) { - mp_printf(&mp_plat_print, "IS CH Deinit\n"); /* if (self->timer) { common_hal_is31fl3741_timer_free(self->timer); @@ -291,58 +281,53 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) } void common_hal_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused) { - mp_printf(&mp_plat_print, "CH IS set paused\n"); - /*if (paused && !self->paused) { - _PM_stop(&self->protomatter); - } else if (!paused && self->paused) { - _PM_resume(&self->protomatter); - _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width); - _PM_swapbuffer_maybe(&self->protomatter); - }*/ self->paused = paused; } bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self) { - mp_printf(&mp_plat_print, "CH IS get paused\n"); return self->paused; } -void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self) { - // mp_printf(&mp_plat_print, "CH IS refresh len %x addr %x\n", self->bufinfo.len, self->bufinfo.buf); +void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current) { + set_current(self->i2c, self->device_address, current); +} + +uint8_t common_hal_is31fl3741_is31fl3741_get_global_current(is31fl3741_is31fl3741_obj_t *self) { + return get_current(self->i2c, self->device_address); +} + +void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows) { + uint8_t dirty_row_flags = 0xFF; + if (dirtyrows != 0) { + dirty_row_flags = *dirtyrows; + } if (!self->paused) { uint32_t *buffer = self->bufinfo.buf; for (int y = 0; y < 5; y++) { - for (int x = 0; x < 18; x++) { - drawPixel(self->i2c, self->device_address, x, y, *buffer); - // mp_printf(&mp_plat_print, "%06x ", *buffer); - buffer++; + if ((dirty_row_flags >> y) & 0x1) { + for (int x = 0; x < 18; x++) { + drawPixel(self->i2c, self->device_address, x, y, *buffer); + buffer++; + } } - // mp_printf(&mp_plat_print, "\n"); } - // - // _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width); - // _PM_swapbuffer_maybe(&self->protomatter); } } int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self) { - mp_printf(&mp_plat_print, "CH IS get width\n"); return self->width; } int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *self) { - mp_printf(&mp_plat_print, "CH IS get height\n"); return self->height; } void *common_hal_is31fl3741_allocator_impl(size_t sz) { - mp_printf(&mp_plat_print, "CH IS allocator\n"); supervisor_allocation *allocation = allocate_memory(align32_size(sz), false, true); return allocation ? allocation->ptr : NULL; } void common_hal_is31fl3741_free_impl(void *ptr_in) { - mp_printf(&mp_plat_print, "CH IS free\n"); free_memory(allocation_from_ptr(ptr_in)); } From aa92d3a4765e8341db49f8bb30bfaa603f6e7377 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 9 Nov 2021 22:53:01 -0600 Subject: [PATCH 04/25] Cleanup and scaling addition --- shared-bindings/is31fl3741/is31fl3741.c | 7 +- shared-bindings/is31fl3741/is31fl3741.h | 8 +- shared-module/displayio/__init__.c | 20 ++- shared-module/is31fl3741/is31fl3741.c | 172 ++++++++++-------------- shared-module/is31fl3741/is31fl3741.h | 22 +++ 5 files changed, 121 insertions(+), 108 deletions(-) diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index b6ed81a634..2343fe5522 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -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; diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index 172e0820a3..83cb3d0549 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -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); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index eff86b81df..ca181406d7 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -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); diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index b3fca18d03..b4a96c9acd 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -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); +} diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index 280192e0d4..19471187fa 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -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 +}; From e877449ae0355e8394016af3ace2039898c827d2 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Fri, 12 Nov 2021 17:10:27 -0600 Subject: [PATCH 05/25] Cleanup --- shared-bindings/is31fl3741/is31fl3741.c | 9 +- shared-bindings/is31fl3741/is31fl3741.h | 9 + shared-module/is31fl3741/allocator.h | 2 - shared-module/is31fl3741/is31fl3741.c | 238 ++++++++++++------------ shared-module/is31fl3741/is31fl3741.h | 5 +- 5 files changed, 143 insertions(+), 120 deletions(-) diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index 2343fe5522..8f8c28db47 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -85,7 +85,7 @@ //| 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 }; + enum { ARG_width, ARG_height, ARG_i2c, ARG_addr, ARG_framebuffer, 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 }, @@ -93,6 +93,7 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t { 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_QSTR_gamma, 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); @@ -108,6 +109,12 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t // TODO make sure height/width divisible by 3 self->scale = args[ARG_scale].u_bool; + if (self->scale) { + self->scale_width = args[ARG_width].u_int / 3; + self->scale_height = args[ARG_height].u_int / 3; + } + + self->auto_gamma = args[ARG_gamma].u_bool; mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; if (framebuffer == mp_const_none) { diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index 83cb3d0549..5e5d0ae787 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -51,3 +51,12 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer); void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self); + +void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr); +void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p); +void is31fl3741_send_enable(busio_i2c_obj_t *i2c, uint8_t addr); +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); diff --git a/shared-module/is31fl3741/allocator.h b/shared-module/is31fl3741/allocator.h index ecf926c01c..9a574fc8b7 100644 --- a/shared-module/is31fl3741/allocator.h +++ b/shared-module/is31fl3741/allocator.h @@ -31,7 +31,5 @@ #include "py/misc.h" #include "supervisor/memory.h" -// #define _PM_allocate common_hal_rgbmatrix_allocator_impl -// #define _PM_free(x) (common_hal_rgbmatrix_free_impl((x)), (x) = NULL, (void)0) extern void *common_hal_is31fl3741_allocator_impl(size_t sz); extern void common_hal_is31fl3741_free_impl(void *); diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index b4a96c9acd..e95537dade 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -32,7 +32,6 @@ #include "py/objproperty.h" #include "py/runtime.h" -// #include "common-hal/is31fl3741/Is31fl3741.h" #include "shared-module/is31fl3741/allocator.h" #include "shared-bindings/is31fl3741/is31fl3741.h" #include "shared-bindings/microcontroller/Pin.h" @@ -41,95 +40,11 @@ #include "shared-module/framebufferio/FramebufferDisplay.h" #include "shared-bindings/busio/I2C.h" -extern Protomatter_core *_PM_protoPtr; - -uint8_t cur_page = 99; - -void send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) { - uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command - common_hal_busio_i2c_write(i2c, addr, unlock, 2, true); -} - -void set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) { - if (p == cur_page) { - return; - } - - cur_page = p; - send_unlock(i2c, addr); - - uint8_t page[2] = { 0xFD, 0x00 }; // page command - page[1] = p; - 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 - 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 - 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; - 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 - common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true); - - uint8_t data = 0; - common_hal_busio_i2c_read(i2c, addr, &data, 1); - return data; -} - - -void set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, uint8_t page) { - uint8_t cmd[2] = { 0x00, 0x00 }; - - if (led < 180) { - set_page(i2c, addr, page); - cmd[0] = (uint8_t)led; - } else { - set_page(i2c, addr, page + 1); - cmd[0] = (uint8_t)(led - 180); - } - - cmd[1] = level; - - 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) { - 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]; - if (ridx != 65535) { - uint16_t gidx = glassesmatrix_ledmap[x1 + 1]; - uint16_t bidx = glassesmatrix_ledmap[x1 + 0]; - set_led(i2c, addr, ridx, r, 0); - set_led(i2c, addr, gidx, g, 0); - set_led(i2c, addr, bidx, b, 0); - } -} - 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) { self->width = width; self->height = height; - self->bufsize = 4 * width * height; + self->bufsize = sizeof(uint32_t) * width * height; // Probe the bus to see if a device acknowledges the given address. if (!common_hal_busio_i2c_probe(i2c, addr)) { @@ -141,24 +56,6 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel self->device_address = addr; common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer); - - common_hal_displayio_is31fl3741_begin_transaction(self); - - uint8_t command = 0xFC; - common_hal_busio_i2c_write(i2c, addr, &command, 1, false); - uint8_t data = 0; - common_hal_busio_i2c_read(i2c, addr, &data, 1); - - send_reset(i2c, addr); - send_enable(i2c, addr); - set_current(i2c, addr, 0x08); - - // set scale to max for all - for (int i; i < 351; i++) { - set_led(i2c, addr, i, 0xFF, 2); - } - - common_hal_displayio_is31fl3741_end_transaction(self); } void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer) { @@ -184,7 +81,23 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; } - // initialize LEDs here + common_hal_displayio_is31fl3741_begin_transaction(self); + + uint8_t command = 0xFC; + common_hal_busio_i2c_write(self->i2c, self->device_address, &command, 1, false); + uint8_t data = 0; + common_hal_busio_i2c_read(self->i2c, self->device_address, &data, 1); + + is31fl3741_send_reset(self->i2c, self->device_address); + is31fl3741_send_enable(self->i2c, self->device_address); + is31fl3741_set_current(self->i2c, self->device_address, 0x08); + + // set scale to max for all + for (int i; i < 351; i++) { + is31fl3741_set_led(self->i2c, self->device_address, i, 0xFF, 2); + } + + common_hal_displayio_is31fl3741_end_transaction(self); self->paused = 0; } @@ -207,13 +120,13 @@ 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); + is31fl3741_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) { common_hal_displayio_is31fl3741_begin_transaction(self); - uint8_t current = get_current(self->i2c, self->device_address); + uint8_t current = is31fl3741_get_current(self->i2c, self->device_address); common_hal_displayio_is31fl3741_end_transaction(self); return current; } @@ -230,9 +143,9 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, if (self->scale) { uint32_t *buffer = self->bufinfo.buf; - for (int x = 0; x < 18; x++) { + for (int x = 0; x < self->scale_width; x++) { uint32_t *ptr = &buffer[x * 3]; // Entry along top scan line w/x offset - for (int y = 0; y < 5; y++) { + for (int y = 0; y < self->scale_height; 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++) { @@ -242,23 +155,37 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, gsum += (rgb >> 8) & 0xFF; bsum += rgb & 0xFF; } - ptr += 54; // canvas->width(); // Advance one scan line + ptr += self->width; // 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); + uint32_t color = 0; + if (self->auto_gamma) { + color = (IS31GammaTable[rsum] << 16) + + (IS31GammaTable[gsum] << 8) + + IS31GammaTable[bsum]; + } else { + color = (rsum << 16) + (gsum << 8) + bsum; + } + is31fl3741_draw_pixel(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) { + uint32_t color = 0; + if (self->auto_gamma) { + color = IS31GammaTable[((*buffer) >> 16 & 0xFF)] + + IS31GammaTable[((*buffer) >> 8 & 0xFF)] + + IS31GammaTable[((*buffer) & 0xFF)]; + } else { + color = *buffer; + } + for (int x = 0; x < self->width; x++) { - drawPixel(self->i2c, self->device_address, x, y, *buffer); + is31fl3741_draw_pixel(self->i2c, self->device_address, x, y, color); buffer++; } } @@ -299,3 +226,84 @@ void common_hal_is31fl3741_free_impl(void *ptr_in) { void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self) { gc_collect_ptr(self->framebuffer); } + +uint8_t cur_page = 99; // set to invalid page to start + +void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) { + uint8_t unlock[2] = { 0xFE, 0xC5 }; // unlock command + common_hal_busio_i2c_write(i2c, addr, unlock, 2, true); +} + +void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p) { + if (p == cur_page) { + return; + } + + cur_page = p; + is31fl3741_send_unlock(i2c, addr); + + uint8_t page[2] = { 0xFD, 0x00 }; // page command + page[1] = p; + common_hal_busio_i2c_write(i2c, addr, page, 2, true); +} + +void is31fl3741_send_enable(busio_i2c_obj_t *i2c, uint8_t addr) { + is31fl3741_set_page(i2c, addr, 4); + uint8_t enable[2] = { 0x00, 0x01 }; // enable command + common_hal_busio_i2c_write(i2c, addr, enable, 2, true); +} + +void is31fl3741_send_reset(busio_i2c_obj_t *i2c, uint8_t addr) { + is31fl3741_set_page(i2c, addr, 4); + uint8_t rst[2] = { 0x3F, 0xAE }; // reset command + common_hal_busio_i2c_write(i2c, addr, rst, 2, true); +} + +void is31fl3741_set_current(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t current) { + is31fl3741_set_page(i2c, addr, 4); + uint8_t gcur[2] = { 0x01, 0x00 }; // global current command + gcur[1] = current; + common_hal_busio_i2c_write(i2c, addr, gcur, 2, true); +} + +uint8_t is31fl3741_get_current(busio_i2c_obj_t *i2c, uint8_t addr) { + is31fl3741_set_page(i2c, addr, 4); + uint8_t gcur = 0x01; // global current command + common_hal_busio_i2c_write(i2c, addr, &gcur, 1, true); + + uint8_t data = 0; + common_hal_busio_i2c_read(i2c, addr, &data, 1); + return data; +} + +void is31fl3741_set_led(busio_i2c_obj_t *i2c, uint8_t addr, uint16_t led, uint8_t level, uint8_t page) { + uint8_t cmd[2] = { 0x00, 0x00 }; + + if (led < 180) { + is31fl3741_set_page(i2c, addr, page); + cmd[0] = (uint8_t)led; + } else { + is31fl3741_set_page(i2c, addr, page + 1); + cmd[0] = (uint8_t)(led - 180); + } + + cmd[1] = level; + + 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) { + 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]; + if (ridx != 65535) { + uint16_t gidx = glassesmatrix_ledmap[x1 + 1]; + uint16_t bidx = glassesmatrix_ledmap[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 19471187fa..f1f4be3c10 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -35,13 +35,13 @@ typedef struct { mp_obj_base_t base; mp_obj_t framebuffer; mp_buffer_info_t bufinfo; - uint16_t bufsize, width, height; + uint16_t bufsize, width, height, scale_width, scale_height; busio_i2c_obj_t *i2c; uint8_t device_address; uint8_t bit_depth; bool paused; - bool doublebuffer; bool scale; + bool auto_gamma; } is31fl3741_is31fl3741_obj_t; static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = { @@ -137,6 +137,7 @@ static const uint16_t glassesmatrix_ledmap[18 * 5 * 3] = { 276, 22, 277, // (17,4) / 7 }; +// Gamma correction table 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, From 2f277eba3ede51f51a1279a3a34a07f94750013b Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 13 Nov 2021 15:19:54 -0600 Subject: [PATCH 06/25] Cleanup and i2c fix --- shared-module/displayio/__init__.c | 30 +++++++++++++++++++++++---- shared-module/is31fl3741/is31fl3741.c | 14 +++++++++++-- shared-module/is31fl3741/is31fl3741.h | 1 + 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index ca181406d7..32f6c853a1 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -223,11 +223,33 @@ void reset_displays(void) { #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); + is31fl3741_is31fl3741_obj_t *is31 = &displays[i].is31fl3741; + if (((uint32_t)is31->i2c) < ((uint32_t)&displays) || + ((uint32_t)is31->i2c) > ((uint32_t)&displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_i2c_obj_t *original_i2c = is31->i2c; + #if BOARD_I2C + // We don't need to move original_i2c if it is the board.I2C object because it is + // statically allocated already. (Doing so would also make it impossible to reference in + // a subsequent VM run.) + if (original_i2c == common_hal_board_get_i2c()) { + continue; + } + #endif + memcpy(&is31->inline_i2c, original_i2c, sizeof(busio_i2c_obj_t)); + is31->i2c = &is31->inline_i2c; + // Check for other displays that use the same i2c bus and swap them too. + /*for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].i2cdisplay_bus.base.type == &displayio_i2cdisplay_type && + displays[i].i2cdisplay_bus.bus == original_i2c) { + displays[i].i2cdisplay_bus.bus = &i2c->inline_bus; + } + }*/ + } + + if (!any_display_uses_this_framebuffer(&is31->base)) { + common_hal_is31fl3741_is31fl3741_deinit(is31); } else { - common_hal_is31fl3741_is31fl3741_set_paused(pm, true); + common_hal_is31fl3741_is31fl3741_set_paused(is31, true); } #endif #if CIRCUITPY_SHARPDISPLAY diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index e95537dade..9006de177e 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -54,6 +54,10 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel self->i2c = i2c; self->device_address = addr; + common_hal_busio_i2c_never_reset(self->i2c); + // Our object is statically allocated off the heap so make sure the bus object lives to the end + // of the heap as well. + gc_never_free(self->i2c); common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer); } @@ -83,14 +87,14 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s common_hal_displayio_is31fl3741_begin_transaction(self); - uint8_t command = 0xFC; + uint8_t command = 0xFC; // device ID common_hal_busio_i2c_write(self->i2c, self->device_address, &command, 1, false); uint8_t data = 0; common_hal_busio_i2c_read(self->i2c, self->device_address, &data, 1); is31fl3741_send_reset(self->i2c, self->device_address); is31fl3741_send_enable(self->i2c, self->device_address); - is31fl3741_set_current(self->i2c, self->device_address, 0x08); + is31fl3741_set_current(self->i2c, self->device_address, 0xFF); // set scale to max for all for (int i; i < 351; i++) { @@ -103,6 +107,12 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s } void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) { + common_hal_displayio_is31fl3741_end_transaction(self); // in case we still had a lock + + if (self->i2c == &self->inline_i2c) { + common_hal_busio_i2c_deinit(self->i2c); + } + self->base.type = NULL; // If a framebuffer was passed in to the constructor, NULL the reference diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index f1f4be3c10..f45778e964 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -37,6 +37,7 @@ typedef struct { mp_buffer_info_t bufinfo; uint16_t bufsize, width, height, scale_width, scale_height; busio_i2c_obj_t *i2c; + busio_i2c_obj_t inline_i2c; uint8_t device_address; uint8_t bit_depth; bool paused; From 9fa3feffb176f82a484feb4aadb569953460d72a Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 13 Nov 2021 15:36:59 -0600 Subject: [PATCH 07/25] Cleanup --- shared-bindings/is31fl3741/__init__.c | 2 +- shared-bindings/is31fl3741/is31fl3741.c | 55 ++++++------------------- shared-bindings/is31fl3741/is31fl3741.h | 3 +- shared-module/is31fl3741/allocator.h | 2 +- shared-module/is31fl3741/is31fl3741.c | 15 +++++-- shared-module/is31fl3741/is31fl3741.h | 2 +- 6 files changed, 28 insertions(+), 51 deletions(-) diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index 7a93702d0e..d6b4732d04 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index 8f8c28db47..d98ed91744 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,10 +29,9 @@ #include "py/runtime.h" #include "py/objarray.h" -// #include "common-hal/is31fl3741/is31fl3741.h" #include "shared-bindings/is31fl3741/is31fl3741.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/microcontroller/__init__.h" +// #include "shared-bindings/microcontroller/Pin.h" +// #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/util.h" #include "shared-module/displayio/__init__.h" #include "shared-module/framebufferio/__init__.h" @@ -40,46 +39,19 @@ #include "shared-bindings/busio/I2C.h" //| class is31fl3741: -//| """Displays an in-memory framebuffer to a HUB75-style RGB LED matrix.""" +//| """Displays an in-memory framebuffer to a IS31FL3741 drive display.""" //| -// extern Protomatter_core *_PM_protoPtr; - - //| def __init__(self, *, width: int) -> None: -//| """Create a Is31fl3741 object with the given attributes. The height of -//| 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. +//| """Create a Is31fl3741 object with the given attributes. //| -//| Up to 30 RGB pins and 8 address pins are supported. -//| -//| The RGB pins must be within a single "port" and performance and memory -//| usage are best when they are all within "close by" bits of the port. -//| The clock pin must also be on the same port as the RGB pins. See the -//| documentation of the underlying protomatter C library for more -//| information. Generally, Adafruit's interface boards are designed so -//| that these requirements are met when matched with the intended -//| microcontroller board. For instance, the Feather M4 Express works -//| together with the RGB Matrix Feather. -//| -//| The framebuffer is in "RGB565" format. -//| -//| "RGB565" means that it is organized as a series of 16-bit numbers -//| where the highest 5 bits are interpreted as red, the next 6 as -//| green, and the final 5 as blue. The object can be any buffer, but -//| `array.array` and ``ulab.ndarray`` objects are most often useful. -//| To update the content, modify the framebuffer and call refresh. +//| The framebuffer is in "RGB888" format using 4 bytes per pixel. +//| Bits 24-31 are ignored. The format is in RGB order. //| //| If a framebuffer is not passed in, one is allocated and initialized //| to all black. In any case, the framebuffer can be retrieved //| by passing the Is31fl3741 object to memoryview(). //| -//| If doublebuffer is False, some memory is saved, but the display may -//| flicker during updates. -//| //| A Is31fl3741 is often used in conjunction with a //| `framebufferio.FramebufferDisplay`.""" //| @@ -136,7 +108,7 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t } //| def deinit(self) -> None: -//| """Free the resources (pins, timers, etc.) associated with this +//| """Free the resources associated with this //| is31fl3741 instance. After deinitialization, no further operations //| may be performed.""" //| ... @@ -150,9 +122,9 @@ STATIC mp_obj_t is31fl3741_is31fl3741_deinit(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_deinit_obj, is31fl3741_is31fl3741_deinit); static void check_for_deinit(is31fl3741_is31fl3741_obj_t *self) { - // if (!self->protomatter.rgbPins) { - // raise_deinited_error(); - // } + if (self->framebuffer == NULL) { + raise_deinited_error(); + } } //| brightness: float @@ -252,8 +224,6 @@ STATIC void is31fl3741_is31fl3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo = self->bufinfo; } -// These version exists so that the prototype matches the protocol, -// avoiding a type cast that can hide errors STATIC void is31fl3741_is31fl3741_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { common_hal_is31fl3741_is31fl3741_refresh(self_in, dirty_row_bitmap); } @@ -291,10 +261,9 @@ STATIC int is31fl3741_is31fl3741_get_bytes_per_cell_proto(mp_obj_t self_in) { } STATIC int is31fl3741_is31fl3741_get_native_frames_per_second_proto(mp_obj_t self_in) { - return 60; + return 60; // This was just chosen may vary based on LEDs used? } - STATIC const framebuffer_p_t is31fl3741_is31fl3741_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) .get_bufinfo = is31fl3741_is31fl3741_get_bufinfo, diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index 5e5d0ae787..7fa7269bee 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,6 @@ #pragma once #include "shared-module/is31fl3741/is31fl3741.h" -// #include "lib/protomatter/src/core.h" extern const mp_obj_type_t is31fl3741_is31fl3741_type; diff --git a/shared-module/is31fl3741/allocator.h b/shared-module/is31fl3741/allocator.h index 9a574fc8b7..43906f54fc 100644 --- a/shared-module/is31fl3741/allocator.h +++ b/shared-module/is31fl3741/allocator.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index 9006de177e..b830596c19 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -96,7 +96,7 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s is31fl3741_send_enable(self->i2c, self->device_address); is31fl3741_set_current(self->i2c, self->device_address, 0xFF); - // set scale to max for all + // set scale (brightness) to max for all LEDs for (int i; i < 351; i++) { is31fl3741_set_led(self->i2c, self->device_address, i, 0xFF, 2); } @@ -111,6 +111,7 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) if (self->i2c == &self->inline_i2c) { common_hal_busio_i2c_deinit(self->i2c); + self->i2c = NULL; } self->base.type = NULL; @@ -151,6 +152,7 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, if (!self->paused) { if (self->scale) { + // Based on the Arduino IS31FL3741 driver code uint32_t *buffer = self->bufinfo.buf; for (int x = 0; x < self->scale_width; x++) { @@ -165,7 +167,7 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, gsum += (rgb >> 8) & 0xFF; bsum += rgb & 0xFF; } - ptr += self->width; // canvas->width(); // Advance one scan line + ptr += self->width; // Advance one scan line } rsum = rsum / 9; gsum = gsum / 9; @@ -217,6 +219,9 @@ int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *sel void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self) { while (!common_hal_busio_i2c_try_lock(self->i2c)) { RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + break; + } } } @@ -237,6 +242,10 @@ void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self) { gc_collect_ptr(self->framebuffer); } +// The following are routines to manipulate the IS31FL3741 chip +// They are not meant to be called by user code but only used +// internally. + uint8_t cur_page = 99; // set to invalid page to start void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr) { diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index f45778e964..530bae90ab 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * Copyright (c) 2021 Mark Komus * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal From 6b2d43d3c83423b7a36f023b98d5c4f9d26744cd Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 12:42:58 -0600 Subject: [PATCH 08/25] Mapping for LEDs to diplay --- locale/circuitpython.pot | 8 +++- shared-bindings/is31fl3741/__init__.c | 3 -- shared-bindings/is31fl3741/is31fl3741.c | 11 ++++-- shared-bindings/is31fl3741/is31fl3741.h | 4 +- shared-module/is31fl3741/is31fl3741.c | 50 ++++++++++++++++++------- shared-module/is31fl3741/is31fl3741.h | 3 ++ 6 files changed, 56 insertions(+), 23 deletions(-) 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] = { From 6d412e20c45deb39d56a49f89d444f9307614800 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 13:17:54 -0600 Subject: [PATCH 09/25] Disabling from some boards --- ports/nrf/boards/microbit_v2/mpconfigboard.mk | 2 ++ ports/nrf/boards/pca10100/mpconfigboard.mk | 1 + ports/nrf/boards/simmel/mpconfigboard.mk | 1 + 3 files changed, 4 insertions(+) diff --git a/ports/nrf/boards/microbit_v2/mpconfigboard.mk b/ports/nrf/boards/microbit_v2/mpconfigboard.mk index a52aa08f9a..008510a85f 100644 --- a/ports/nrf/boards/microbit_v2/mpconfigboard.mk +++ b/ports/nrf/boards/microbit_v2/mpconfigboard.mk @@ -13,9 +13,11 @@ CIRCUITPY_BUILTINS_POW3=0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_COUNTIO = 0 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_JSON = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_MSGPACK = 0 diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index 59f2b217c3..8ae25393f8 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -19,6 +19,7 @@ CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_JSON = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_MSGPACK = 0 diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk index 67f5dfbd6d..85bdca6dc1 100644 --- a/ports/nrf/boards/simmel/mpconfigboard.mk +++ b/ports/nrf/boards/simmel/mpconfigboard.mk @@ -22,6 +22,7 @@ CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_ERRNO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GETPASS = 0 +CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 From 16c52b76d624f6da863d6ecda2e8d960ceb842a6 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 13:20:16 -0600 Subject: [PATCH 10/25] Capitalize module --- shared-bindings/is31fl3741/__init__.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index 9f72d07fc3..a68467497b 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -33,7 +33,7 @@ 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) }, + { MP_ROM_QSTR(MP_QSTR_IS31FL3741), MP_ROM_PTR(&is31fl3741_is31fl3741_type) }, }; STATIC MP_DEFINE_CONST_DICT(is31fl3741_module_globals, is31fl3741_module_globals_table); @@ -43,4 +43,4 @@ const mp_obj_module_t is31fl3741_module = { .globals = (mp_obj_dict_t *)&is31fl3741_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_is31fl3741, is31fl3741_module, CIRCUITPY_IS31FL3741); +MP_REGISTER_MODULE(MP_QSTR_IS31FL3741, is31fl3741_module, CIRCUITPY_IS31FL3741); From 5243a33584fe4ceb691b6f87bc4ee4f623e4cddd Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 13:41:18 -0600 Subject: [PATCH 11/25] Check map to display size --- locale/circuitpython.pot | 4 ++++ shared-bindings/is31fl3741/is31fl3741.c | 3 +++ shared-module/is31fl3741/is31fl3741.c | 5 ++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index dbcf703b68..9f6ea16bbb 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -1458,6 +1458,10 @@ msgstr "" msgid "Key must be 16, 24, or 32 bytes long" msgstr "" +#: shared-module/is31fl3741/is31fl3741.c +msgid "LED mappings must match display size" +msgstr "" + #: py/compile.c msgid "LHS of keyword arg must be an id" msgstr "" diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index 723687d227..aa98972b24 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -88,6 +88,9 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t self->scale_width = args[ARG_width].u_int / 3; self->scale_height = args[ARG_height].u_int / 3; + } else { + self->scale_width = args[ARG_width].u_int; + self->scale_height = args[ARG_height].u_int; } self->auto_gamma = args[ARG_gamma].u_bool; diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index 78d2d1efce..c616d3a20c 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/is31fl3741.c @@ -59,11 +59,14 @@ 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); + if (len != (size_t)(self->scale_width * self->scale_height * 3)) { + mp_raise_ValueError(translate("LED mappings must match display size")); + } + 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]); From 5337e45411470c27d1b72611e8548e9fe58f8436 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 15:33:22 -0600 Subject: [PATCH 12/25] Only enable if not disabled --- ports/nrf/mpconfigport.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 0795ae4e82..55ade5562f 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -32,7 +32,7 @@ CIRCUITPY_BLEIO ?= 1 # No I2CPeripheral implementation CIRCUITPY_I2CPERIPHERAL = 0 -CIRCUITPY_IS31FL3741 = 1 +CIRCUITPY_IS31FL3741 ?= 1 CIRCUITPY_RTC ?= 1 From c38612d59dff478c8d4bc97380ea826ec84deb44 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 20 Nov 2021 15:43:11 -0600 Subject: [PATCH 13/25] Fixed capitalization --- shared-bindings/is31fl3741/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index a68467497b..070a795e35 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -43,4 +43,4 @@ const mp_obj_module_t is31fl3741_module = { .globals = (mp_obj_dict_t *)&is31fl3741_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_IS31FL3741, is31fl3741_module, CIRCUITPY_IS31FL3741); +MP_REGISTER_MODULE(MP_QSTR_is31fl3741, is31fl3741_module, CIRCUITPY_IS31FL3741); From 0c4597f38752ffbf94804f5d1e2b75586a0bca9f Mon Sep 17 00:00:00 2001 From: Aivar Annamaa Date: Mon, 22 Nov 2021 21:28:39 +0200 Subject: [PATCH 14/25] Move friendly REPL check to main function --- main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 42b9630105..ae1322d916 100644 --- a/main.c +++ b/main.c @@ -333,7 +333,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // Collects stickiness bits that apply in the current situation. uint8_t next_code_stickiness_situation = SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; - if (safe_mode == NO_SAFE_MODE && pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { + if (safe_mode == NO_SAFE_MODE) { static const char *const supported_filenames[] = STRING_LIST( "code.txt", "code.py", "main.py", "main.txt"); #if CIRCUITPY_FULL_BUILD @@ -858,7 +858,11 @@ int __attribute__((used)) main(void) { serial_write_compressed(translate("soft reboot\n")); } first_run = false; - skip_repl = run_code_py(safe_mode); + if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { + skip_repl = run_code_py(safe_mode); + } else { + skip_repl = false; + } } else if (exit_code != 0) { break; } From e8c809e5945016ba0bfe779e14dccd5aee778b80 Mon Sep 17 00:00:00 2001 From: Aivar Annamaa Date: Mon, 22 Nov 2021 23:45:28 +0200 Subject: [PATCH 15/25] Fix formatting --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index ae1322d916..b43df23a6d 100644 --- a/main.c +++ b/main.c @@ -859,9 +859,9 @@ int __attribute__((used)) main(void) { } first_run = false; if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { - skip_repl = run_code_py(safe_mode); + skip_repl = run_code_py(safe_mode); } else { - skip_repl = false; + skip_repl = false; } } else if (exit_code != 0) { break; From f495ea476087511c4e6c40cb5920eaff1bb17813 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 23 Nov 2021 10:47:46 -0600 Subject: [PATCH 16/25] Don't use reset reason to skip writing boot_out.txt As @neradoc and @anecdata noted, we can't depend on the reset reason. Instead, just rely on the existing safe mode logic (the write already is skipped anytime boot.py was skipped), and otherwise potentially write boot_out.txt anytime it differs from the version on disk (or if the file doesn't exist in the first place) Testing performed: On qtpy m0 haxpress, removed boot_out.txt and clicked reset button. verified boot_out.txt was recreated. Closes #5588 --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index a189add5e2..89b1f492d6 100644 --- a/main.c +++ b/main.c @@ -678,7 +678,7 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { FATFS *fs = &vfs->fatfs; boot_output = NULL; - bool write_boot_output = (common_hal_mcu_processor_get_reset_reason() == RESET_REASON_POWER_ON); + bool write_boot_output = true; FIL boot_output_file; if (f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) { char *file_contents = m_new(char, boot_text.alloc); From f7df39ef883921eaafbf974cecb303b48ce800ff Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Nov 2021 13:20:00 -0600 Subject: [PATCH 17/25] Re-enable on microbit v2 --- ports/nrf/boards/microbit_v2/mpconfigboard.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/nrf/boards/microbit_v2/mpconfigboard.mk b/ports/nrf/boards/microbit_v2/mpconfigboard.mk index 008510a85f..a893acec44 100644 --- a/ports/nrf/boards/microbit_v2/mpconfigboard.mk +++ b/ports/nrf/boards/microbit_v2/mpconfigboard.mk @@ -17,7 +17,6 @@ CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 -CIRCUITPY_IS31FL3741 = 0 CIRCUITPY_JSON = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_MSGPACK = 0 From fc3b0340b5918f0d95307d2c5583cc09e5606a58 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Nov 2021 13:21:09 -0600 Subject: [PATCH 18/25] Remove hard coded mapping of LEDs --- shared-module/is31fl3741/is31fl3741.h | 95 --------------------------- 1 file changed, 95 deletions(-) diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index 999e6ce64e..bbc73df1d1 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -46,101 +46,6 @@ typedef struct { 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 - 13, 11, 12, // (0,2) / 19 - 16, 14, 15, // (0,3) / 18 - 4, 2, 3, // (0,4) / 17 - 217, 215, 216, // (1,0) / right ring pixel #21 - 220, 218, 219, // (1,1) - 223, 221, 222, // (1,2) - 226, 224, 225, // (1,3) - 214, 212, 213, // (1,4) - 187, 185, 186, // (2,0) - 190, 188, 189, // (2,1) - 193, 191, 192, // (2,2) - 196, 194, 195, // (2,3) - 184, 182, 183, // (2,4) - 37, 35, 36, // (3,0) - 40, 38, 39, // (3,1) - 43, 41, 42, // (3,2) - 46, 44, 45, // (3,3) - 34, 32, 33, // (3,4) - 67, 65, 66, // (4,0) - 70, 68, 69, // (4,1) - 73, 71, 72, // (4,2) - 76, 74, 75, // (4,3) - 64, 62, 63, // (4,4) - 97, 95, 96, // (5,0) - 100, 98, 99, // (5,1) - 103, 101, 102, // (5,2) - 106, 104, 105, // (5,3) - 94, 92, 93, // (5,4) - 127, 125, 126, // (6,0) / right ring pixel 3 - 130, 128, 129, // (6,1) - 133, 131, 132, // (6,2) - 136, 134, 135, // (6,3) - 124, 122, 123, // (6,4) - 157, 155, 156, // (7,0) - 160, 158, 159, // (7,1) - 163, 161, 162, // (7,2) / right ring pixel 5 - 166, 164, 165, // (7,3) / 6 - 244, 242, 243, // (7,4) / 7 - 247, 245, 246, // (8,0) - 250, 248, 249, // (8,1) - 253, 251, 252, // (8,2) - 256, 254, 255, // (8,3) - 65535, 65535, 65535, // (8,4) (clipped, nose bridge) - 345, 347, 346, // (9,0) - 342, 344, 343, // (9,1) - 267, 269, 268, // (9,2) - 263, 265, 264, // (9,3) - 65535, 65535, 65535, // (9,4) (clipped, nose bridge) - 336, 338, 337, // (10,0) - 333, 335, 334, // (10,1) - 237, 239, 238, // (10,2) / left ring pixel 19 - 233, 235, 234, // (10,3) / 18 - 348, 262, 349, // (10,4) / 17 - 327, 329, 328, // (11,0) / left ring pixel 21 - 324, 326, 325, // (11,1) - 207, 209, 208, // (11,2) - 203, 205, 204, // (11,3) - 330, 202, 331, // (11,4) - 318, 320, 319, // (12,0) - 315, 317, 316, // (12,1) - 177, 179, 178, // (12,2) - 173, 175, 174, // (12,3) - 321, 172, 322, // (12,4) - 309, 311, 310, // (13,0) - 306, 308, 307, // (13,1) - 147, 149, 148, // (13,2) - 143, 145, 144, // (13,3) - 312, 142, 313, // (13,4) - 300, 302, 301, // (14,0) - 297, 299, 298, // (14,1) - 117, 119, 118, // (14,2) - 113, 115, 114, // (14,3) - 303, 112, 304, // (14,4) - 291, 293, 292, // (15,0) - 288, 290, 289, // (15,1) - 87, 89, 88, // (15,2) - 83, 85, 84, // (15,3) - 294, 82, 295, // (15,4) - 282, 284, 283, // (16,0) / left ring pixel 3 - 279, 281, 280, // (16,1) - 57, 59, 58, // (16,2) - 53, 55, 54, // (16,3) - 285, 52, 286, // (16,4) - 65535, 65535, 65535, // (17,0) (clipped, corner) - 270, 272, 271, // (17,1) / left ring pixel 4 - 27, 29, 28, // (17,2) / 5 - 23, 25, 24, // (17,3) / 6 - 276, 22, 277, // (17,4) / 7 -}; -*/ - // Gamma correction table static const uint8_t IS31GammaTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, From 9b85714b7666d6ad24ee0f2fa30a3ede7cf9abb8 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Nov 2021 13:24:36 -0600 Subject: [PATCH 19/25] Removed unused imports --- shared-bindings/is31fl3741/is31fl3741.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index aa98972b24..0c02b93122 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -30,8 +30,6 @@ #include "py/objarray.h" #include "shared-bindings/is31fl3741/is31fl3741.h" -// #include "shared-bindings/microcontroller/Pin.h" -// #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/util.h" #include "shared-module/displayio/__init__.h" #include "shared-module/framebufferio/__init__.h" From 9f2660f6ac6ff27d6cdebe3702e4f28865d10f32 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Nov 2021 17:06:39 -0600 Subject: [PATCH 20/25] Capitalization changes --- shared-bindings/is31fl3741/__init__.c | 2 +- shared-bindings/is31fl3741/is31fl3741.c | 162 ++++++++++++------------ shared-bindings/is31fl3741/is31fl3741.h | 28 ++-- shared-module/displayio/__init__.c | 16 +-- shared-module/displayio/__init__.h | 2 +- shared-module/is31fl3741/is31fl3741.c | 28 ++-- shared-module/is31fl3741/is31fl3741.h | 2 +- 7 files changed, 120 insertions(+), 120 deletions(-) diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index 070a795e35..609749ac83 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -33,7 +33,7 @@ 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) }, + { MP_ROM_QSTR(MP_QSTR_IS31FL3741), MP_ROM_PTR(&is31fl3741_IS31FL3741_type) }, }; STATIC MP_DEFINE_CONST_DICT(is31fl3741_module_globals, is31fl3741_module_globals_table); diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/is31fl3741.c index 0c02b93122..b74da1f9f8 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/is31fl3741.c @@ -36,12 +36,12 @@ #include "shared-module/framebufferio/FramebufferDisplay.h" #include "shared-bindings/busio/I2C.h" -//| class is31fl3741: +//| class IS31FL3741: //| """Displays an in-memory framebuffer to a IS31FL3741 drive display.""" //| //| def __init__(self, *, width: int) -> None: -//| """Create a Is31fl3741 object with the given attributes. +//| """Create a IS31FL3741 object with the given attributes. //| //| The framebuffer is in "RGB888" format using 4 bytes per pixel. //| Bits 24-31 are ignored. The format is in RGB order. @@ -54,7 +54,7 @@ //| `framebufferio.FramebufferDisplay`.""" //| -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) { +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_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 }, @@ -71,8 +71,8 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); - is31fl3741_is31fl3741_obj_t *self = &allocate_display_bus_or_raise()->is31fl3741; - self->base.type = &is31fl3741_is31fl3741_type; + is31fl3741_IS31FL3741_obj_t *self = &allocate_display_bus_or_raise()->is31fl3741; + self->base.type = &is31fl3741_IS31FL3741_type; if (args[ARG_width].u_int <= 0) { mp_raise_ValueError(translate("width must be greater than zero")); @@ -101,7 +101,7 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); } - common_hal_is31fl3741_is31fl3741_construct(self, + common_hal_is31fl3741_IS31FL3741_construct(self, args[ARG_width].u_int, args[ARG_height].u_int, framebuffer, @@ -115,19 +115,19 @@ STATIC mp_obj_t is31fl3741_is31fl3741_make_new(const mp_obj_type_t *type, size_t //| def deinit(self) -> None: //| """Free the resources associated with this -//| is31fl3741 instance. After deinitialization, no further operations +//| IS31FL3741 instance. After deinitialization, no further operations //| may be performed.""" //| ... //| -STATIC mp_obj_t is31fl3741_is31fl3741_deinit(mp_obj_t self_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; - common_hal_is31fl3741_is31fl3741_deinit(self); +STATIC mp_obj_t is31fl3741_IS31FL3741_deinit(mp_obj_t self_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; + common_hal_is31fl3741_IS31FL3741_deinit(self); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_deinit_obj, is31fl3741_is31fl3741_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_deinit_obj, is31fl3741_IS31FL3741_deinit); -static void check_for_deinit(is31fl3741_is31fl3741_obj_t *self) { +static void check_for_deinit(is31fl3741_IS31FL3741_obj_t *self) { if (self->framebuffer == NULL) { raise_deinited_error(); } @@ -137,18 +137,18 @@ static void check_for_deinit(is31fl3741_is31fl3741_obj_t *self) { //| """In the current implementation, 0.0 turns the display off entirely //| and any other value up to 1.0 turns the display on fully.""" //| -STATIC mp_obj_t is31fl3741_is31fl3741_get_brightness(mp_obj_t self_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_obj_t is31fl3741_IS31FL3741_get_brightness(mp_obj_t self_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); - uint8_t current = common_hal_is31fl3741_is31fl3741_get_global_current(self); + uint8_t current = common_hal_is31fl3741_IS31FL3741_get_global_current(self); float brightness = (float)current / (float)0xFF; return mp_obj_new_float(brightness); } -MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_brightness_obj, is31fl3741_is31fl3741_get_brightness); +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_get_brightness_obj, is31fl3741_IS31FL3741_get_brightness); -STATIC mp_obj_t is31fl3741_is31fl3741_set_brightness(mp_obj_t self_in, mp_obj_t value_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_obj_t is31fl3741_IS31FL3741_set_brightness(mp_obj_t self_in, mp_obj_t value_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); mp_float_t brightness = mp_obj_get_float(value_in); if (brightness < 0.0f || brightness > 1.0f) { @@ -156,16 +156,16 @@ STATIC mp_obj_t is31fl3741_is31fl3741_set_brightness(mp_obj_t self_in, mp_obj_t } uint8_t current = (uint8_t)(brightness * 0xFF); - common_hal_is31fl3741_is31fl3741_set_global_current(self, current); + common_hal_is31fl3741_IS31FL3741_set_global_current(self, current); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(is31fl3741_is31fl3741_set_brightness_obj, is31fl3741_is31fl3741_set_brightness); +MP_DEFINE_CONST_FUN_OBJ_2(is31fl3741_IS31FL3741_set_brightness_obj, is31fl3741_IS31FL3741_set_brightness); -const mp_obj_property_t is31fl3741_is31fl3741_brightness_obj = { +const mp_obj_property_t is31fl3741_IS31FL3741_brightness_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_brightness_obj, - (mp_obj_t)&is31fl3741_is31fl3741_set_brightness_obj, + .proxy = {(mp_obj_t)&is31fl3741_IS31FL3741_get_brightness_obj, + (mp_obj_t)&is31fl3741_IS31FL3741_set_brightness_obj, MP_ROM_NONE}, }; @@ -174,26 +174,26 @@ const mp_obj_property_t is31fl3741_is31fl3741_brightness_obj = { //| they are shown.""" //| ... //| -STATIC mp_obj_t is31fl3741_is31fl3741_refresh(mp_obj_t self_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_obj_t is31fl3741_IS31FL3741_refresh(mp_obj_t self_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); - common_hal_is31fl3741_is31fl3741_refresh(self, 0); + common_hal_is31fl3741_IS31FL3741_refresh(self, 0); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_refresh_obj, is31fl3741_is31fl3741_refresh); +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_refresh_obj, is31fl3741_IS31FL3741_refresh); //| width: int //| """The width of the display, in pixels""" //| -STATIC mp_obj_t is31fl3741_is31fl3741_get_width(mp_obj_t self_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_obj_t is31fl3741_IS31FL3741_get_width(mp_obj_t self_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_is31fl3741_get_width(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_IS31FL3741_get_width(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_width_obj, is31fl3741_is31fl3741_get_width); -const mp_obj_property_t is31fl3741_is31fl3741_width_obj = { +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_get_width_obj, is31fl3741_IS31FL3741_get_width); +const mp_obj_property_t is31fl3741_IS31FL3741_width_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_width_obj, + .proxy = {(mp_obj_t)&is31fl3741_IS31FL3741_get_width_obj, MP_ROM_NONE, MP_ROM_NONE}, }; @@ -201,91 +201,91 @@ const mp_obj_property_t is31fl3741_is31fl3741_width_obj = { //| height: int //| """The height of the display, in pixels""" //| -STATIC mp_obj_t is31fl3741_is31fl3741_get_height(mp_obj_t self_in) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_obj_t is31fl3741_IS31FL3741_get_height(mp_obj_t self_in) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_is31fl3741_get_height(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_is31fl3741_IS31FL3741_get_height(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_is31fl3741_get_height_obj, is31fl3741_is31fl3741_get_height); -const mp_obj_property_t is31fl3741_is31fl3741_height_obj = { +MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_get_height_obj, is31fl3741_IS31FL3741_get_height); +const mp_obj_property_t is31fl3741_IS31FL3741_height_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&is31fl3741_is31fl3741_get_height_obj, + .proxy = {(mp_obj_t)&is31fl3741_IS31FL3741_get_height_obj, MP_ROM_NONE, MP_ROM_NONE}, }; -STATIC const mp_rom_map_elem_t is31fl3741_is31fl3741_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&is31fl3741_is31fl3741_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&is31fl3741_is31fl3741_brightness_obj) }, - { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&is31fl3741_is31fl3741_refresh_obj) }, - { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&is31fl3741_is31fl3741_width_obj) }, - { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&is31fl3741_is31fl3741_height_obj) }, +STATIC const mp_rom_map_elem_t is31fl3741_IS31FL3741_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&is31fl3741_IS31FL3741_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&is31fl3741_IS31FL3741_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&is31fl3741_IS31FL3741_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&is31fl3741_IS31FL3741_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&is31fl3741_IS31FL3741_height_obj) }, }; -STATIC MP_DEFINE_CONST_DICT(is31fl3741_is31fl3741_locals_dict, is31fl3741_is31fl3741_locals_dict_table); +STATIC MP_DEFINE_CONST_DICT(is31fl3741_IS31FL3741_locals_dict, is31fl3741_IS31FL3741_locals_dict_table); -STATIC void is31fl3741_is31fl3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC void is31fl3741_IS31FL3741_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; check_for_deinit(self); *bufinfo = self->bufinfo; } -STATIC void is31fl3741_is31fl3741_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { - common_hal_is31fl3741_is31fl3741_refresh(self_in, dirty_row_bitmap); +STATIC void is31fl3741_IS31FL3741_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { + common_hal_is31fl3741_IS31FL3741_refresh(self_in, dirty_row_bitmap); } -STATIC void is31fl3741_is31fl3741_deinit_proto(mp_obj_t self_in) { - common_hal_is31fl3741_is31fl3741_deinit(self_in); +STATIC void is31fl3741_IS31FL3741_deinit_proto(mp_obj_t self_in) { + common_hal_is31fl3741_IS31FL3741_deinit(self_in); } -STATIC float is31fl3741_is31fl3741_get_brightness_proto(mp_obj_t self_in) { - return common_hal_is31fl3741_is31fl3741_get_paused(self_in) ? 0.0f : 1.0f; +STATIC float is31fl3741_IS31FL3741_get_brightness_proto(mp_obj_t self_in) { + return common_hal_is31fl3741_IS31FL3741_get_paused(self_in) ? 0.0f : 1.0f; } -STATIC bool is31fl3741_is31fl3741_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { - common_hal_is31fl3741_is31fl3741_set_paused(self_in, value <= 0); +STATIC bool is31fl3741_IS31FL3741_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { + common_hal_is31fl3741_IS31FL3741_set_paused(self_in, value <= 0); return true; } -STATIC int is31fl3741_is31fl3741_get_width_proto(mp_obj_t self_in) { - return common_hal_is31fl3741_is31fl3741_get_width(self_in); +STATIC int is31fl3741_IS31FL3741_get_width_proto(mp_obj_t self_in) { + return common_hal_is31fl3741_IS31FL3741_get_width(self_in); } -STATIC int is31fl3741_is31fl3741_get_height_proto(mp_obj_t self_in) { - return common_hal_is31fl3741_is31fl3741_get_height(self_in); +STATIC int is31fl3741_IS31FL3741_get_height_proto(mp_obj_t self_in) { + return common_hal_is31fl3741_IS31FL3741_get_height(self_in); } -STATIC int is31fl3741_is31fl3741_get_color_depth_proto(mp_obj_t self_in) { +STATIC int is31fl3741_IS31FL3741_get_color_depth_proto(mp_obj_t self_in) { // The way displayio works depth is used to calculate bytes // We use an uint32_t for color already so setting to 24 causes // more changes required return 32; } -STATIC int is31fl3741_is31fl3741_get_bytes_per_cell_proto(mp_obj_t self_in) { +STATIC int is31fl3741_IS31FL3741_get_bytes_per_cell_proto(mp_obj_t self_in) { return 1; } -STATIC int is31fl3741_is31fl3741_get_native_frames_per_second_proto(mp_obj_t self_in) { +STATIC int is31fl3741_IS31FL3741_get_native_frames_per_second_proto(mp_obj_t self_in) { return 60; // This was just chosen may vary based on LEDs used? } -STATIC const framebuffer_p_t is31fl3741_is31fl3741_proto = { +STATIC const framebuffer_p_t is31fl3741_IS31FL3741_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) - .get_bufinfo = is31fl3741_is31fl3741_get_bufinfo, - .set_brightness = is31fl3741_is31fl3741_set_brightness_proto, - .get_brightness = is31fl3741_is31fl3741_get_brightness_proto, - .get_width = is31fl3741_is31fl3741_get_width_proto, - .get_height = is31fl3741_is31fl3741_get_height_proto, - .get_color_depth = is31fl3741_is31fl3741_get_color_depth_proto, - .get_bytes_per_cell = is31fl3741_is31fl3741_get_bytes_per_cell_proto, - .get_native_frames_per_second = is31fl3741_is31fl3741_get_native_frames_per_second_proto, - .swapbuffers = is31fl3741_is31fl3741_swapbuffers, - .deinit = is31fl3741_is31fl3741_deinit_proto, + .get_bufinfo = is31fl3741_IS31FL3741_get_bufinfo, + .set_brightness = is31fl3741_IS31FL3741_set_brightness_proto, + .get_brightness = is31fl3741_IS31FL3741_get_brightness_proto, + .get_width = is31fl3741_IS31FL3741_get_width_proto, + .get_height = is31fl3741_IS31FL3741_get_height_proto, + .get_color_depth = is31fl3741_IS31FL3741_get_color_depth_proto, + .get_bytes_per_cell = is31fl3741_IS31FL3741_get_bytes_per_cell_proto, + .get_native_frames_per_second = is31fl3741_IS31FL3741_get_native_frames_per_second_proto, + .swapbuffers = is31fl3741_IS31FL3741_swapbuffers, + .deinit = is31fl3741_IS31FL3741_deinit_proto, }; -STATIC mp_int_t is31fl3741_is31fl3741_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { - is31fl3741_is31fl3741_obj_t *self = (is31fl3741_is31fl3741_obj_t *)self_in; +STATIC mp_int_t is31fl3741_IS31FL3741_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; // a readonly framebuffer would be unusual but not impossible if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { return 1; @@ -295,14 +295,14 @@ STATIC mp_int_t is31fl3741_is31fl3741_get_buffer(mp_obj_t self_in, mp_buffer_inf return 0; } -const mp_obj_type_t is31fl3741_is31fl3741_type = { +const mp_obj_type_t is31fl3741_IS31FL3741_type = { { &mp_type_type }, .flags = MP_TYPE_FLAG_EXTENDED, .name = MP_QSTR_is31fl3741, - .locals_dict = (mp_obj_dict_t *)&is31fl3741_is31fl3741_locals_dict, - .make_new = is31fl3741_is31fl3741_make_new, + .locals_dict = (mp_obj_dict_t *)&is31fl3741_IS31FL3741_locals_dict, + .make_new = is31fl3741_IS31FL3741_make_new, MP_TYPE_EXTENDED_FIELDS( - .buffer_p = { .get_buffer = is31fl3741_is31fl3741_get_buffer, }, - .protocol = &is31fl3741_is31fl3741_proto, + .buffer_p = { .get_buffer = is31fl3741_IS31FL3741_get_buffer, }, + .protocol = &is31fl3741_IS31FL3741_proto, ), }; diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/is31fl3741.h index b9375d8734..74a9981aef 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/is31fl3741.h @@ -28,28 +28,28 @@ #include "shared-module/is31fl3741/is31fl3741.h" -extern const mp_obj_type_t is31fl3741_is31fl3741_type; +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, mp_obj_t mapping); +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 *); +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); +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_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); +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); -void common_hal_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused); -bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self); -void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, uint8_t *dirtyrows); +void common_hal_is31fl3741_IS31FL3741_set_paused(is31fl3741_IS31FL3741_obj_t *self, bool paused); +bool common_hal_is31fl3741_IS31FL3741_get_paused(is31fl3741_IS31FL3741_obj_t *self); +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 common_hal_is31fl3741_IS31FL3741_reconstruct(is31fl3741_IS31FL3741_obj_t *self, mp_obj_t framebuffer); -void is31fl3741_is31fl3741_collect_ptrs(is31fl3741_is31fl3741_obj_t *self); +void is31fl3741_IS31FL3741_collect_ptrs(is31fl3741_IS31FL3741_obj_t *self); void is31fl3741_send_unlock(busio_i2c_obj_t *i2c, uint8_t addr); void is31fl3741_set_page(busio_i2c_obj_t *i2c, uint8_t addr, uint8_t p); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 32f6c853a1..fcda0948a8 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -144,8 +144,8 @@ void common_hal_displayio_release_displays(void) { 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); + } 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) { @@ -222,8 +222,8 @@ void reset_displays(void) { } #endif #if CIRCUITPY_IS31FL3741 - } else if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) { - is31fl3741_is31fl3741_obj_t *is31 = &displays[i].is31fl3741; + } else if (displays[i].is31fl3741.base.type == &is31fl3741_IS31FL3741_type) { + is31fl3741_IS31FL3741_obj_t *is31 = &displays[i].is31fl3741; if (((uint32_t)is31->i2c) < ((uint32_t)&displays) || ((uint32_t)is31->i2c) > ((uint32_t)&displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_i2c_obj_t *original_i2c = is31->i2c; @@ -247,9 +247,9 @@ void reset_displays(void) { } if (!any_display_uses_this_framebuffer(&is31->base)) { - common_hal_is31fl3741_is31fl3741_deinit(is31); + common_hal_is31fl3741_IS31FL3741_deinit(is31); } else { - common_hal_is31fl3741_is31fl3741_set_paused(is31, true); + common_hal_is31fl3741_IS31FL3741_set_paused(is31, true); } #endif #if CIRCUITPY_SHARPDISPLAY @@ -287,8 +287,8 @@ void displayio_gc_collect(void) { } #endif #if CIRCUITPY_IS31FL3741 - if (displays[i].is31fl3741.base.type == &is31fl3741_is31fl3741_type) { - is31fl3741_is31fl3741_collect_ptrs(&displays[i].is31fl3741); + if (displays[i].is31fl3741.base.type == &is31fl3741_IS31FL3741_type) { + is31fl3741_IS31FL3741_collect_ptrs(&displays[i].is31fl3741); } #endif #if CIRCUITPY_SHARPDISPLAY diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 1d16cdad59..cee3290f7d 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -60,7 +60,7 @@ typedef struct { rgbmatrix_rgbmatrix_obj_t rgbmatrix; #endif #if CIRCUITPY_IS31FL3741 - is31fl3741_is31fl3741_obj_t is31fl3741; + is31fl3741_IS31FL3741_obj_t is31fl3741; #endif #if CIRCUITPY_SHARPDISPLAY sharpdisplay_framebuffer_obj_t sharpdisplay; diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/is31fl3741.c index c616d3a20c..4dc6d1a825 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, mp_obj_t mapping) { +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; @@ -77,10 +77,10 @@ void common_hal_is31fl3741_is31fl3741_construct(is31fl3741_is31fl3741_obj_t *sel self->mapping[i] = (uint16_t)value; } - common_hal_is31fl3741_is31fl3741_reconstruct(self, framebuffer); + common_hal_is31fl3741_IS31FL3741_reconstruct(self, framebuffer); } -void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *self, mp_obj_t framebuffer) { +void common_hal_is31fl3741_IS31FL3741_reconstruct(is31fl3741_IS31FL3741_obj_t *self, mp_obj_t framebuffer) { self->paused = 1; if (framebuffer) { @@ -124,7 +124,7 @@ void common_hal_is31fl3741_is31fl3741_reconstruct(is31fl3741_is31fl3741_obj_t *s self->paused = 0; } -void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) { +void common_hal_is31fl3741_IS31FL3741_deinit(is31fl3741_IS31FL3741_obj_t *self) { common_hal_displayio_is31fl3741_end_transaction(self); // in case we still had a lock if (self->i2c == &self->inline_i2c) { @@ -144,28 +144,28 @@ void common_hal_is31fl3741_is31fl3741_deinit(is31fl3741_is31fl3741_obj_t *self) self->framebuffer = NULL; } -void common_hal_is31fl3741_is31fl3741_set_paused(is31fl3741_is31fl3741_obj_t *self, bool paused) { +void common_hal_is31fl3741_IS31FL3741_set_paused(is31fl3741_IS31FL3741_obj_t *self, bool paused) { self->paused = paused; } -bool common_hal_is31fl3741_is31fl3741_get_paused(is31fl3741_is31fl3741_obj_t *self) { +bool common_hal_is31fl3741_IS31FL3741_get_paused(is31fl3741_IS31FL3741_obj_t *self) { return self->paused; } -void common_hal_is31fl3741_is31fl3741_set_global_current(is31fl3741_is31fl3741_obj_t *self, uint8_t current) { +void common_hal_is31fl3741_IS31FL3741_set_global_current(is31fl3741_IS31FL3741_obj_t *self, uint8_t current) { common_hal_displayio_is31fl3741_begin_transaction(self); is31fl3741_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) { +uint8_t common_hal_is31fl3741_IS31FL3741_get_global_current(is31fl3741_IS31FL3741_obj_t *self) { common_hal_displayio_is31fl3741_begin_transaction(self); uint8_t current = is31fl3741_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) { +void common_hal_is31fl3741_IS31FL3741_refresh(is31fl3741_IS31FL3741_obj_t *self, uint8_t *dirtyrows) { common_hal_displayio_is31fl3741_begin_transaction(self); if (!self->paused) { uint8_t dirty_row_flags = 0xFF; // only supports 8 rows gotta fix @@ -232,15 +232,15 @@ void common_hal_is31fl3741_is31fl3741_refresh(is31fl3741_is31fl3741_obj_t *self, common_hal_displayio_is31fl3741_end_transaction(self); } -int common_hal_is31fl3741_is31fl3741_get_width(is31fl3741_is31fl3741_obj_t *self) { +int common_hal_is31fl3741_IS31FL3741_get_width(is31fl3741_IS31FL3741_obj_t *self) { return self->width; } -int common_hal_is31fl3741_is31fl3741_get_height(is31fl3741_is31fl3741_obj_t *self) { +int common_hal_is31fl3741_IS31FL3741_get_height(is31fl3741_IS31FL3741_obj_t *self) { return self->height; } -void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj_t *self) { +void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_IS31FL3741_obj_t *self) { while (!common_hal_busio_i2c_try_lock(self->i2c)) { RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { @@ -249,7 +249,7 @@ void common_hal_displayio_is31fl3741_begin_transaction(is31fl3741_is31fl3741_obj } } -void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_is31fl3741_obj_t *self) { +void common_hal_displayio_is31fl3741_end_transaction(is31fl3741_IS31FL3741_obj_t *self) { common_hal_busio_i2c_unlock(self->i2c); } @@ -262,7 +262,7 @@ 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) { +void is31fl3741_IS31FL3741_collect_ptrs(is31fl3741_IS31FL3741_obj_t *self) { gc_collect_ptr(self->framebuffer); gc_collect_ptr(self->mapping); } diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/is31fl3741.h index bbc73df1d1..c2ccfde849 100644 --- a/shared-module/is31fl3741/is31fl3741.h +++ b/shared-module/is31fl3741/is31fl3741.h @@ -44,7 +44,7 @@ typedef struct { bool paused; bool scale; bool auto_gamma; -} is31fl3741_is31fl3741_obj_t; +} is31fl3741_IS31FL3741_obj_t; // Gamma correction table static const uint8_t IS31GammaTable[256] = { From 97032fdbd0831a8b986a1497c0c6c2d2d776fe23 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 23 Nov 2021 17:21:13 -0600 Subject: [PATCH 21/25] Renaming files --- py/circuitpy_defns.mk | 2 +- shared-bindings/is31fl3741/{is31fl3741.c => IS31FL3741.c} | 2 +- shared-bindings/is31fl3741/{is31fl3741.h => IS31FL3741.h} | 2 +- shared-bindings/is31fl3741/__init__.c | 2 +- shared-module/displayio/__init__.h | 2 +- shared-module/is31fl3741/{is31fl3741.c => IS31FL3741.c} | 2 +- shared-module/is31fl3741/{is31fl3741.h => IS31FL3741.h} | 0 7 files changed, 6 insertions(+), 6 deletions(-) rename shared-bindings/is31fl3741/{is31fl3741.c => IS31FL3741.c} (99%) rename shared-bindings/is31fl3741/{is31fl3741.h => IS31FL3741.h} (98%) rename shared-module/is31fl3741/{is31fl3741.c => IS31FL3741.c} (99%) rename shared-module/is31fl3741/{is31fl3741.h => IS31FL3741.h} (100%) diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index dd690355bd..04bcb801db 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -551,7 +551,7 @@ SRC_SHARED_MODULE_ALL = \ imagecapture/ParallelImageCapture.c \ ipaddress/IPv4Address.c \ ipaddress/__init__.c \ - is31fl3741/is31fl3741.c \ + is31fl3741/IS31FL3741.c \ is31fl3741/__init__.c \ keypad/__init__.c \ keypad/Event.c \ diff --git a/shared-bindings/is31fl3741/is31fl3741.c b/shared-bindings/is31fl3741/IS31FL3741.c similarity index 99% rename from shared-bindings/is31fl3741/is31fl3741.c rename to shared-bindings/is31fl3741/IS31FL3741.c index b74da1f9f8..758dd114a0 100644 --- a/shared-bindings/is31fl3741/is31fl3741.c +++ b/shared-bindings/is31fl3741/IS31FL3741.c @@ -29,7 +29,7 @@ #include "py/runtime.h" #include "py/objarray.h" -#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/is31fl3741/IS31FL3741.h" #include "shared-bindings/util.h" #include "shared-module/displayio/__init__.h" #include "shared-module/framebufferio/__init__.h" diff --git a/shared-bindings/is31fl3741/is31fl3741.h b/shared-bindings/is31fl3741/IS31FL3741.h similarity index 98% rename from shared-bindings/is31fl3741/is31fl3741.h rename to shared-bindings/is31fl3741/IS31FL3741.h index 74a9981aef..3815f10de0 100644 --- a/shared-bindings/is31fl3741/is31fl3741.h +++ b/shared-bindings/is31fl3741/IS31FL3741.h @@ -26,7 +26,7 @@ #pragma once -#include "shared-module/is31fl3741/is31fl3741.h" +#include "shared-module/is31fl3741/IS31FL3741.h" extern const mp_obj_type_t is31fl3741_IS31FL3741_type; diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index 609749ac83..90b9426a4d 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -29,7 +29,7 @@ #include "py/obj.h" #include "py/runtime.h" -#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/is31fl3741/IS31FL3741.h" STATIC const mp_rom_map_elem_t is31fl3741_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_is31fl3741) }, diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index cee3290f7d..1f9da47669 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -42,7 +42,7 @@ #include "shared-bindings/rgbmatrix/RGBMatrix.h" #endif #if CIRCUITPY_IS31FL3741 -#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/is31fl3741/IS31FL3741.h" #endif #if CIRCUITPY_SHARPDISPLAY #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" diff --git a/shared-module/is31fl3741/is31fl3741.c b/shared-module/is31fl3741/IS31FL3741.c similarity index 99% rename from shared-module/is31fl3741/is31fl3741.c rename to shared-module/is31fl3741/IS31FL3741.c index 4dc6d1a825..9d7316e1cd 100644 --- a/shared-module/is31fl3741/is31fl3741.c +++ b/shared-module/is31fl3741/IS31FL3741.c @@ -33,7 +33,7 @@ #include "py/runtime.h" #include "shared-module/is31fl3741/allocator.h" -#include "shared-bindings/is31fl3741/is31fl3741.h" +#include "shared-bindings/is31fl3741/IS31FL3741.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/util.h" diff --git a/shared-module/is31fl3741/is31fl3741.h b/shared-module/is31fl3741/IS31FL3741.h similarity index 100% rename from shared-module/is31fl3741/is31fl3741.h rename to shared-module/is31fl3741/IS31FL3741.h From 61916962320ec0256df997cd126e55f8c83960ea Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 24 Nov 2021 09:05:11 -0600 Subject: [PATCH 22/25] bitmaptools: Fix the DitgherAlorithm.FloydStenberg value --- shared-bindings/bitmaptools/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index 57ac779081..ec26eab98e 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -664,7 +664,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_readinto_obj, 0, bitmaptools_readinto); //| """The Floyd-Stenberg dither""" //| MAKE_ENUM_VALUE(bitmaptools_dither_algorithm_type, dither_algorithm, Atkinson, DITHER_ALGORITHM_ATKINSON); -MAKE_ENUM_VALUE(bitmaptools_dither_algorithm_type, dither_algorithm, FloydStenberg, DITHER_ALGORITHM_ATKINSON); +MAKE_ENUM_VALUE(bitmaptools_dither_algorithm_type, dither_algorithm, FloydStenberg, DITHER_ALGORITHM_FLOYD_STENBERG); MAKE_ENUM_MAP(bitmaptools_dither_algorithm) { MAKE_ENUM_MAP_ENTRY(dither_algorithm, Atkinson), From 9af76a2f0388aad732433156bade06b59f558e55 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 24 Nov 2021 09:15:17 -0600 Subject: [PATCH 23/25] bitmaptools dither: Fix off-by-one error filling row data --- shared-module/bitmaptools/__init__.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 80b4a38964..1ce84a239b 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -761,13 +761,13 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi rows[1] = rows[2]; rows[2] = tmp; - fill_row(source_bitmap, swap, rows[2], y + 2, info->mx); - y++; if (y == height) { break; } + fill_row(source_bitmap, swap, rows[2], y + 2, info->mx); + // Serpentine dither. Going right-to-left... for (int x = width; x--;) { int16_t pixel_in = rows[0][x] + err; @@ -790,7 +790,7 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi rows[1] = rows[2]; rows[2] = tmp; - fill_row(source_bitmap, swap, rows[2], y + 2, info->mx); + fill_row(source_bitmap, swap, rows[2], y + 3, info->mx); } displayio_area_t a = { 0, 0, width, height, NULL }; From 30c07a772ffa348fecfee7cd54c759565981fc32 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 24 Nov 2021 09:48:32 -0600 Subject: [PATCH 24/25] bitmaptools: dither: get rid of shifts this happens to make the occasional FS dither artifact disappear. I guess `a * b >> 8` and `(a * b) / 256` are not identical. I'm not sure if it was just the parens or not, but write the clearer code and rely on the compiler to substitute an appropriate shift if possible. --- shared-module/bitmaptools/__init__.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 1ce84a239b..6b5def2904 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -749,9 +749,9 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi int x1 = x + info->terms[i].dx; int dy = info->terms[i].dy; - rows[dy][x1] = ((info->terms[i].dl * err) >> 8) + rows[dy][x1]; + rows[dy][x1] = ((info->terms[i].dl * err) / 256) + rows[dy][x1]; } - err = err * info->dl >> 8; + err = (err * info->dl) / 256; } write_pixels(dest_bitmap, y, out); @@ -779,9 +779,9 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi int x1 = x - info->terms[i].dx; int dy = info->terms[i].dy; - rows[dy][x1] = ((info->terms[i].dl * err) >> 8) + rows[dy][x1]; + rows[dy][x1] = ((info->terms[i].dl * err) / 256) + rows[dy][x1]; } - err = err * info->dl >> 8; + err = (err * info->dl) / 256; } write_pixels(dest_bitmap, y, out); From ddf24772c32774c4f423473671fe0ec2dada1ddd Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 24 Nov 2021 09:53:19 -0600 Subject: [PATCH 25/25] tests: move bitmaptools files to their own directory --- .../{ => bitmaptools}/_bmp16.py | 0 .../{ => bitmaptools}/blend.py | 0 .../{ => bitmaptools}/blinka16.bmp | Bin .../bitmaptools/dither-atkinson.bmp | Bin 0 -> 153670 bytes .../bitmaptools/dither-floydstenberg.bmp | Bin 0 -> 153670 bytes .../bitmaptools/dither.py | 18 ++++++++++ .../bitmaptools/ellipse.bmp | Bin 0 -> 8330 bytes .../{ => bitmaptools}/minerva16.bmp | Bin tests/circuitpython-manual/dither.py | 31 ------------------ 9 files changed, 18 insertions(+), 31 deletions(-) rename tests/circuitpython-manual/{ => bitmaptools}/_bmp16.py (100%) rename tests/circuitpython-manual/{ => bitmaptools}/blend.py (100%) rename tests/circuitpython-manual/{ => bitmaptools}/blinka16.bmp (100%) create mode 100644 tests/circuitpython-manual/bitmaptools/dither-atkinson.bmp create mode 100644 tests/circuitpython-manual/bitmaptools/dither-floydstenberg.bmp create mode 100644 tests/circuitpython-manual/bitmaptools/dither.py create mode 100644 tests/circuitpython-manual/bitmaptools/ellipse.bmp rename tests/circuitpython-manual/{ => bitmaptools}/minerva16.bmp (100%) delete mode 100644 tests/circuitpython-manual/dither.py diff --git a/tests/circuitpython-manual/_bmp16.py b/tests/circuitpython-manual/bitmaptools/_bmp16.py similarity index 100% rename from tests/circuitpython-manual/_bmp16.py rename to tests/circuitpython-manual/bitmaptools/_bmp16.py diff --git a/tests/circuitpython-manual/blend.py b/tests/circuitpython-manual/bitmaptools/blend.py similarity index 100% rename from tests/circuitpython-manual/blend.py rename to tests/circuitpython-manual/bitmaptools/blend.py diff --git a/tests/circuitpython-manual/blinka16.bmp b/tests/circuitpython-manual/bitmaptools/blinka16.bmp similarity index 100% rename from tests/circuitpython-manual/blinka16.bmp rename to tests/circuitpython-manual/bitmaptools/blinka16.bmp diff --git a/tests/circuitpython-manual/bitmaptools/dither-atkinson.bmp b/tests/circuitpython-manual/bitmaptools/dither-atkinson.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1829b8e7aec2499efa949ec98731702fe2151693 GIT binary patch literal 153670 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 dULWN?yQ95 literal 0 HcmV?d00001 diff --git a/tests/circuitpython-manual/bitmaptools/dither-floydstenberg.bmp b/tests/circuitpython-manual/bitmaptools/dither-floydstenberg.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e7481b040615b0342db477467306153e0a46cc0e GIT binary patch literal 153670 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 i0jZqyKVkGfpG%0f%`dk0{;&KboHnJ literal 0 HcmV?d00001 diff --git a/tests/circuitpython-manual/bitmaptools/dither.py b/tests/circuitpython-manual/bitmaptools/dither.py new file mode 100644 index 0000000000..13d0a5be6d --- /dev/null +++ b/tests/circuitpython-manual/bitmaptools/dither.py @@ -0,0 +1,18 @@ +import bitmaptools +import displayio +import _bmp16 + +if "/" in __file__: + here = __file__.rsplit("/", 1)[0] +else: + here = "." + +c = displayio.Colorspace.BGR565 + +b1 = _bmp16.loadbmp16(here + "/minerva16.bmp") +b3 = displayio.Bitmap(320, 240, 65536) + +bitmaptools.dither(b3, b1, c) +_bmp16.writebmp16(f"dither-atkinson.bmp", b3) +bitmaptools.dither(b3, b1, c, bitmaptools.DitherAlgorithm.FloydStenberg) +_bmp16.writebmp16(f"dither-floydstenberg.bmp", b3) diff --git a/tests/circuitpython-manual/bitmaptools/ellipse.bmp b/tests/circuitpython-manual/bitmaptools/ellipse.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c048cb17c73cdafcd4e35fe230dc834210de2003 GIT binary patch literal 8330 zcmc&(F>3-b6i(ZrYex~GLicXE3B{#Tmx3T&Z*&y5x;Z%ua)@q@9d8ovC%7pna&~ic zDO?93HEQrU?wRBz<(-_#y}b9nqX7``OyE>y!Ap;wFcX0*YD|LpE&!y(N06P z7RzdCiZ1w9Q!V96rosk;E@TQDrE(31`WTB}A8V*ru zC0@ELc_Hcztese2^ai&V`POq^TEa)IfpSO6+m_`HIK{z+_RbbHDc?5Ui`}d}*$4AA zXz%$XwkXZLU~C-mB=OSqxCg#ypdo0ab=W)y4FCopkDSgv(Q~tC5Fc|vRx*pl1~W(x zmOhvPrp_eiLo5y?mk%?60HXf|>A}+dF90f&oEu_sAi3Ny69^!hpLZZ!N$(qZ0C#(j z#5dc6=GJka#Fgc|379&Q+;ZyuL?2p49?(tXCC4txl9xG9fS8nYRR^Fl$*wSydNP3k zBDMXg=O6X@qxL`4{+D|Hq27O~;}7cii#qxJ{B{}`CV+DuKnNl=RfzwT{8dx literal 0 HcmV?d00001 diff --git a/tests/circuitpython-manual/minerva16.bmp b/tests/circuitpython-manual/bitmaptools/minerva16.bmp similarity index 100% rename from tests/circuitpython-manual/minerva16.bmp rename to tests/circuitpython-manual/bitmaptools/minerva16.bmp diff --git a/tests/circuitpython-manual/dither.py b/tests/circuitpython-manual/dither.py deleted file mode 100644 index 49a63c458c..0000000000 --- a/tests/circuitpython-manual/dither.py +++ /dev/null @@ -1,31 +0,0 @@ -import bitmaptools -import displayio -import _bmp16 - -if "/" in __file__: - here = __file__.rsplit("/", 1)[0] -else: - here = "." - -c = displayio.Colorspace.BGR565 - -b1 = _bmp16.loadbmp16(here + "/minerva16.bmp") -b3 = displayio.Bitmap(320, 240, 65536) - -for i in ( - 0, - 1 / 64, - 3 / 64, - 3 / 32, - 3 / 16, - 0.5, - 1 - 3 / 16, - 1 - 3 / 32, - 1 - 3 / 64, - 1 - 1 / 64, - 1, -): - bitmaptools.dither(b3, b1, c) - _bmp16.writebmp16(f"dither-atkinson.bmp", b3) - bitmaptools.dither(b3, b1, c, bitmaptools.DitherAlgorithm.FloydStenberg) - _bmp16.writebmp16(f"dither-floydstenberg.bmp", b3)