From 73cf490635809c2e5b1f57675d59507a247456f2 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 24 Jan 2019 13:43:39 -0800 Subject: Add TileGrid --- shared-bindings/displayio/Sprite.c | 2 +- shared-bindings/displayio/TileGrid.c | 226 +++++++++++++++++++++++++++++++++++ shared-bindings/displayio/TileGrid.h | 44 +++++++ shared-bindings/displayio/__init__.c | 3 + 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 shared-bindings/displayio/TileGrid.c create mode 100644 shared-bindings/displayio/TileGrid.h (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/Sprite.c b/shared-bindings/displayio/Sprite.c index 6f4704e45..864ecc959 100644 --- a/shared-bindings/displayio/Sprite.c +++ b/shared-bindings/displayio/Sprite.c @@ -39,7 +39,7 @@ #include "shared-bindings/displayio/Shape.h" #include "supervisor/shared/translate.h" -void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { +static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { // TODO(tannewt): Support any value sequence such as bytearray or bytes. mp_obj_tuple_t *position = MP_OBJ_TO_PTR(position_obj); if (MP_OBJ_IS_TYPE(position_obj, &mp_type_tuple) && position->len == 2) { diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c new file mode 100644 index 000000000..b8531a923 --- /dev/null +++ b/shared-bindings/displayio/TileGrid.c @@ -0,0 +1,226 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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 "shared-bindings/displayio/TileGrid.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/OnDiskBitmap.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Shape.h" +#include "supervisor/shared/translate.h" + +static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { + // TODO(tannewt): Support any value sequence such as bytearray or bytes. + mp_obj_tuple_t *position = MP_OBJ_TO_PTR(position_obj); + if (MP_OBJ_IS_TYPE(position_obj, &mp_type_tuple) && position->len == 2) { + *x = mp_obj_get_int(position->items[0]); + *y = mp_obj_get_int(position->items[1]); + } else if (position != mp_const_none) { + mp_raise_TypeError(translate("position must be 2-tuple")); + } +} + +//| .. currentmodule:: displayio +//| +//| :class:`TileGrid` -- A grid of tiles sourced out of one bitmap +//| ========================================================================== +//| +//| Position a grid of tiles sourced from a bitmap and pixel_shader combination. Multiple grids +//| can share bitmaps and pixel shaders. +//| +//| A single tile grid is also known as a Sprite. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: TileGrid(bitmap, *, pixel_shader, position, width=1, height=1, tile_width=None, tile_height=None, default_tile=0) +//| +//| Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to +//| convert the value and its location to a display native pixel color. This may be a simple color +//| palette lookup, a gradient, a pattern or a color transformer. +//| +//| tile_width and tile_height match the height of the bitmap by default. +//| +//| :param displayio.Bitmap bitmap: The bitmap storing one or more tiles. +//| :param displayio.Palette pixel_shader: The pixel shader that produces colors from values +//| :param tuple position: Upper left corner of the grid +//| :param int width: Width of the grid in tiles. +//| :param int height: Height of the grid in tiles. +//| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. +//| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. +//| :param in default_tile: Default tile index to show. +//| +STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_bitmap, ARG_pixel_shader, ARG_position, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_position, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_tile_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_tile_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_default_tile, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t bitmap = args[ARG_bitmap].u_obj; + + uint16_t bitmap_width; + uint16_t bitmap_height; + mp_obj_t native = mp_instance_cast_to_native_base(bitmap, &displayio_shape_type); + if (native != MP_OBJ_NULL) { + displayio_shape_t* bmp = MP_OBJ_TO_PTR(native); + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { + displayio_bitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_ondiskbitmap_type)) { + displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); + native = bitmap; + bitmap_width = bmp->width; + bitmap_height = bmp->height; + } else { + mp_raise_TypeError(translate("unsupported bitmap type")); + } + uint16_t tile_width = args[ARG_tile_width].u_int; + if (tile_width == 0) { + tile_width = bitmap_width; + } + uint16_t tile_height = args[ARG_tile_height].u_int; + if (tile_height == 0) { + tile_height = bitmap_height; + } + if (bitmap_width % tile_width != 0) { + mp_raise_ValueError(translate("Tile width must exactly divide bitmap width")); + } + if (bitmap_height % tile_height != 0) { + mp_raise_ValueError(translate("Tile height must exactly divide bitmap height")); + } + + int16_t x = 0; + int16_t y = 0; + mp_obj_t position_obj = args[ARG_position].u_obj; + unpack_position(position_obj, &x, &y); + + displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t); + self->base.type = &displayio_tilegrid_type; + common_hal_displayio_tilegrid_construct(self, native, args[ARG_pixel_shader].u_obj, + args[ARG_width].u_int, args[ARG_height].u_int, tile_width, tile_height, x, y, + args[ARG_default_tile].u_int); + return MP_OBJ_FROM_PTR(self); +} + +//| .. attribute:: position +//| +//| The position of the top-left corner of the tilegrid. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_position(mp_obj_t self_in) { + displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); + int16_t x; + int16_t y; + common_hal_displayio_tilegrid_get_position(self, &x, &y); + + mp_obj_t coords[2]; + coords[0] = mp_obj_new_int(x); + coords[1] = mp_obj_new_int(y); + + return mp_obj_new_tuple(2, coords); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_position_obj, displayio_tilegrid_obj_get_position); + +STATIC mp_obj_t displayio_tilegrid_obj_set_position(mp_obj_t self_in, mp_obj_t value) { + displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); + + int16_t x = 0; + int16_t y = 0; + unpack_position(value, &x, &y); + + common_hal_displayio_tilegrid_set_position(self, x, y); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_position_obj, displayio_tilegrid_obj_set_position); + +const mp_obj_property_t displayio_tilegrid_position_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_position_obj, + (mp_obj_t)&displayio_tilegrid_set_position_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: pixel_shader +//| +//| The pixel shader of the tilegrid. +//| +STATIC mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) { + displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_displayio_tilegrid_get_pixel_shader(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_tilegrid_obj_get_pixel_shader); + +STATIC mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { + displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); + if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { + mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); + } + + common_hal_displayio_tilegrid_set_pixel_shader(self, pixel_shader); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_pixel_shader_obj, displayio_tilegrid_obj_set_pixel_shader); + +const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_tilegrid_get_pixel_shader_obj, + (mp_obj_t)&displayio_tilegrid_set_pixel_shader_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&displayio_tilegrid_position_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_locals_dict_table); + +const mp_obj_type_t displayio_tilegrid_type = { + { &mp_type_type }, + .name = MP_QSTR_Sprite, + .make_new = displayio_tilegrid_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_tilegrid_locals_dict, +}; diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h new file mode 100644 index 000000000..54ca5389c --- /dev/null +++ b/shared-bindings/displayio/TileGrid.h @@ -0,0 +1,44 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H + +#include "shared-module/displayio/TileGrid.h" + +extern const mp_obj_type_t displayio_tilegrid_type; + +void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, + mp_obj_t pixel_shader, uint16_t width, uint16_t height, + uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile); + +void common_hal_displayio_tilegrid_get_position(displayio_tilegrid_t *self, int16_t* x, int16_t* y); +void common_hal_displayio_tilegrid_set_position(displayio_tilegrid_t *self, int16_t x, int16_t y); + +mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self); +void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 6ed1218b2..749f21803 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -40,6 +40,7 @@ #include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/Sprite.h" +#include "shared-bindings/displayio/TileGrid.h" //| :mod:`displayio` --- Native display driving //| ========================================================================= @@ -68,6 +69,7 @@ //| ParallelBus //| Shape //| Sprite +//| TileGrid //| //| All libraries change hardware state but are never deinit //| @@ -95,6 +97,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, { MP_ROM_QSTR(MP_QSTR_Shape), MP_ROM_PTR(&displayio_shape_type) }, { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, + { MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, { MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) }, -- cgit v1.2.3 From fb0970ec6e2fee42d748718557c35fe84a4d0ce5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 24 Jan 2019 15:49:02 -0800 Subject: Add terminalio --- ports/atmel-samd/Makefile | 2 + ports/atmel-samd/mpconfigport.h | 4 +- shared-bindings/displayio/TileGrid.h | 2 + shared-bindings/terminalio/Terminal.c | 131 ++++++++++++++++++++++++++++++++++ shared-bindings/terminalio/Terminal.h | 45 ++++++++++++ shared-bindings/terminalio/__init__.c | 64 +++++++++++++++++ shared-bindings/terminalio/__init__.h | 34 +++++++++ shared-module/displayio/TileGrid.c | 9 +++ shared-module/displayio/TileGrid.h | 1 + shared-module/terminalio/Terminal.c | 82 +++++++++++++++++++++ shared-module/terminalio/Terminal.h | 45 ++++++++++++ shared-module/terminalio/__init__.c | 27 +++++++ shared-module/terminalio/__init__.h | 30 ++++++++ 13 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 shared-bindings/terminalio/Terminal.c create mode 100644 shared-bindings/terminalio/Terminal.h create mode 100644 shared-bindings/terminalio/__init__.c create mode 100644 shared-bindings/terminalio/__init__.h create mode 100644 shared-module/terminalio/Terminal.c create mode 100644 shared-module/terminalio/Terminal.h create mode 100644 shared-module/terminalio/__init__.c create mode 100644 shared-module/terminalio/__init__.h (limited to 'shared-bindings/displayio') diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index ff0d82e34..4cdfc265d 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -399,6 +399,8 @@ SRC_SHARED_MODULE = \ os/__init__.c \ random/__init__.c \ struct/__init__.c \ + terminalio/__init__.c \ + terminalio/Terminal.c \ uheap/__init__.c \ ustack/__init__.c \ usb_hid/__init__.c \ diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index da3383f8e..811d4eda4 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -235,6 +235,7 @@ extern const struct _mp_obj_module_t ustack_module; extern const struct _mp_obj_module_t supervisor_module; extern const struct _mp_obj_module_t gamepad_module; extern const struct _mp_obj_module_t stage_module; +extern const struct _mp_obj_module_t terminalio_module; extern const struct _mp_obj_module_t touchio_module; extern const struct _mp_obj_module_t usb_hid_module; extern const struct _mp_obj_module_t usb_midi_module; @@ -286,7 +287,8 @@ extern const struct _mp_obj_module_t pixelbuf_module; #if !defined(CIRCUITPY_DISPLAYIO) || CIRCUITPY_DISPLAYIO #define CIRCUITPY_DISPLAYIO (1) #define CIRCUITPY_DISPLAY_LIMIT (3) - #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, + #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, #else #define CIRCUITPY_DISPLAYIO (0) #define CIRCUITPY_DISPLAY_LIMIT (0) diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index 54ca5389c..f553be423 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -41,4 +41,6 @@ void common_hal_displayio_tilegrid_set_position(displayio_tilegrid_t *self, int1 mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self); void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader); +void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c new file mode 100644 index 000000000..f460f4abd --- /dev/null +++ b/shared-bindings/terminalio/Terminal.c @@ -0,0 +1,131 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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 "shared-bindings/terminalio/Terminal.h" +#include "shared-bindings/util.h" + +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "supervisor/shared/translate.h" + + +//| .. currentmodule:: terminalio +//| +//| :class:`Terminal` -- manage a +//| ============================================================== +//| +//| .. class:: Terminal(tilegrid, *, unicode_characters="") +//| +//| Terminal manages tile indices and cursor position based on VT100 commands. Visible ASCII +//| characters are mapped to the first 94 tile indices by substracting 0x20 from characters value. +//| Unicode characters are mapped based on unicode_characters starting at index 94. +//| + +STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_tilegrid, ARG_unicode_characters }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_tilegrid, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_unicode_characters, 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(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t tilegrid = args[ARG_tilegrid].u_obj; + if (!MP_OBJ_IS_TYPE(tilegrid, &displayio_tilegrid_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), displayio_tilegrid_type.name); + } + + mp_obj_t unicode_characters_obj = args[ARG_unicode_characters].u_obj; + if (MP_OBJ_IS_STR(unicode_characters_obj)) { + mp_raise_TypeError(translate("unicode_characters must be a string")); + } + + GET_STR_DATA_LEN(unicode_characters_obj, unicode_characters, unicode_characters_len); + terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t); + self->base.type = &terminalio_terminal_type; + common_hal_terminalio_terminal_construct(self, MP_OBJ_TO_PTR(tilegrid), unicode_characters, unicode_characters_len); + return MP_OBJ_FROM_PTR(self); +} + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| +STATIC mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + const byte *buf = buf_in; + + return common_hal_terminalio_terminal_write(self, buf, size, errcode); +} + +STATIC mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_WR) && common_hal_terminalio_terminal_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +STATIC const mp_rom_map_elem_t terminalio_terminal_locals_dict_table[] = { + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(terminalio_terminal_locals_dict, terminalio_terminal_locals_dict_table); + +STATIC const mp_stream_p_t terminalio_terminal_stream_p = { + .read = NULL, + .write = terminalio_terminal_write, + .ioctl = terminalio_terminal_ioctl, + .is_text = true, +}; + +const mp_obj_type_t terminalio_terminal_type = { + { &mp_type_type }, + .name = MP_QSTR_Terminal, + .make_new = terminalio_terminal_make_new, + .getiter = mp_identity_getiter, + .iternext = mp_stream_unbuffered_iter, + .protocol = &terminalio_terminal_stream_p, + .locals_dict = (mp_obj_dict_t*)&terminalio_terminal_locals_dict, +}; diff --git a/shared-bindings/terminalio/Terminal.h b/shared-bindings/terminalio/Terminal.h new file mode 100644 index 000000000..43912243a --- /dev/null +++ b/shared-bindings/terminalio/Terminal.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H + +#include "shared-module/terminalio/Terminal.h" + +#include "shared-bindings/displayio/TileGrid.h" + +extern const mp_obj_type_t terminalio_terminal_type; + +extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, + displayio_tilegrid_t* tilegrid, const byte* unicode_characters, size_t unicode_characters_len); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO_TERMINAL_H diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c new file mode 100644 index 000000000..1031124dc --- /dev/null +++ b/shared-bindings/terminalio/__init__.c @@ -0,0 +1,64 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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/terminalio/__init__.h" +#include "shared-bindings/terminalio/Terminal.h" + +#include "py/runtime.h" + +//| :mod:`terminalio` --- MIDI over USB +//| ================================================= +//| +//| .. module:: terminalio +//| :synopsis: MIDI over USB +//| +//| The `terminalio` module contains classes to transmit and receive MIDI messages over USB +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Terminal +//| +//| +STATIC const mp_rom_map_elem_t terminalio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_terminalio) }, + { MP_ROM_QSTR(MP_QSTR_Terminal), MP_OBJ_FROM_PTR(&terminalio_terminal_type) }, +}; + + +STATIC MP_DEFINE_CONST_DICT(terminalio_module_globals, terminalio_module_globals_table); + +const mp_obj_module_t terminalio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&terminalio_module_globals, +}; diff --git a/shared-bindings/terminalio/__init__.h b/shared-bindings/terminalio/__init__.h new file mode 100644 index 000000000..e81818e04 --- /dev/null +++ b/shared-bindings/terminalio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H + +#include "py/obj.h" + +extern mp_obj_dict_t usb_midi_module_globals; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 7e4bfe0a4..44874e283 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -45,6 +45,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->inline_tiles = false; } self->width_in_tiles = width; + self->height_in_tiles = width; self->total_width = width * tile_width; self->total_height = height * tile_height; self->tile_width = tile_width; @@ -112,6 +113,14 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t return false; } +void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) { + uint8_t* tiles = self->tiles; + if (self->inline_tiles) { + tiles = (uint8_t*) &self->tiles; + } + tiles[y * self->width_in_tiles + x] = tile_index; +} + bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) { return self->needs_refresh || displayio_palette_needs_refresh(self->pixel_shader); } diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index 880895304..c24a606a3 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -39,6 +39,7 @@ typedef struct { uint16_t x; uint16_t y; uint16_t width_in_tiles; + uint16_t height_in_tiles; uint16_t total_width; uint16_t total_height; uint16_t tile_width; diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c new file mode 100644 index 000000000..c47f9f6cf --- /dev/null +++ b/shared-module/terminalio/Terminal.c @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft 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 "shared-module/terminalio/Terminal.h" + +#include "shared-bindings/displayio/TileGrid.h" + +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, uint8_t* unicode_characters, uint16_t unicode_characters_len) { + self->cursor_x = 0; + self->cursor_y = 0; + self->tilegrid = tilegrid; + self->unicode_characters = unicode_characters; + self->unicode_characters_len = unicode_characters_len; +} + +size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { + const byte* i = data; + while (i < data + len) { + unichar c = utf8_get_char(i); + i = utf8_next_char(i); + // Always handle ASCII. + if (c < 128) { + if (c >= 0x20 && c <= 0x7e) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, c - 0x20); + self->cursor_x++; + } + if (c == '\r') { + self->cursor_x = 0; + } else if (c == '\n') { + self->cursor_y++; + } + } else { + // Do a linear search of the mapping for unicode. + const byte* j = self->unicode_characters; + uint8_t k = 0; + while (j < self->unicode_characters + self->unicode_characters_len) { + unichar potential_c = utf8_get_char(j); + j = utf8_next_char(j); + if (c == potential_c) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, self->cursor_x, self->cursor_y, 0x7f - 0x20 + k); + self->cursor_x++; + break; + } + } + } + if (self->cursor_x >= self->tilegrid->width_in_tiles) { + self->cursor_y++; + self->cursor_x %= self->tilegrid->width_in_tiles; + } + if (self->cursor_y >= self->tilegrid->height_in_tiles) { + self->cursor_y %= self->tilegrid->height_in_tiles; + } + } + return i - data; +} + +bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) { + return true; +} diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h new file mode 100644 index 000000000..1896075f3 --- /dev/null +++ b/shared-module/terminalio/Terminal.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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. + */ + +#ifndef SHARED_MODULE_TERMINALIO_TERMINAL_H +#define SHARED_MODULE_TERMINALIO_TERMINAL_H + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/TileGrid.h" + +typedef struct { + mp_obj_base_t base; + uint16_t cursor_x; + uint16_t cursor_y; + displayio_tilegrid_t* tilegrid; + const byte* unicode_characters; + uint16_t unicode_characters_len; +} terminalio_terminal_obj_t; + +#endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */ diff --git a/shared-module/terminalio/__init__.c b/shared-module/terminalio/__init__.c new file mode 100644 index 000000000..3f61f4823 --- /dev/null +++ b/shared-module/terminalio/__init__.c @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 hathach 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 "shared-bindings/terminalio/__init__.h" diff --git a/shared-module/terminalio/__init__.h b/shared-module/terminalio/__init__.h new file mode 100644 index 000000000..e925dd429 --- /dev/null +++ b/shared-module/terminalio/__init__.h @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft 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. + */ + +#ifndef SHARED_MODULE_TERMINALIO___INIT___H +#define SHARED_MODULE_TERMINALIO___INIT___H + +#endif /* SHARED_MODULE_TERMINALIO___INIT___H */ -- cgit v1.2.3 From 1a1dbef992442682413f6103e36440a26bc2dad7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Jan 2019 16:59:18 -0800 Subject: Hook up the terminal based on the first display. --- main.c | 7 ++ ports/atmel-samd/mpconfigport.h | 1 + shared-bindings/displayio/Display.c | 12 ++- shared-bindings/displayio/TileGrid.c | 6 +- shared-bindings/displayio/TileGrid.h | 2 +- shared-module/displayio/Display.c | 13 +++ shared-module/displayio/Group.c | 18 +++- shared-module/displayio/TileGrid.c | 15 ++- shared-module/displayio/TileGrid.h | 1 + shared-module/displayio/__init__.c | 106 ++++----------------- shared-module/displayio/__init__.h | 3 + shared-module/terminalio/Terminal.c | 44 ++++++++- supervisor/memory.h | 3 + supervisor/shared/display.c | 177 +++++++++++++++++++++++++++++++++++ supervisor/shared/display.h | 15 ++- supervisor/shared/memory.c | 6 ++ supervisor/shared/serial.c | 4 + supervisor/supervisor.mk | 3 +- tools/bitmap_font | 2 +- tools/gen_display_resources.py | 142 ++++++++++++++++++++++++---- 20 files changed, 454 insertions(+), 126 deletions(-) create mode 100644 supervisor/shared/display.c (limited to 'shared-bindings/displayio') diff --git a/main.c b/main.c index e137f7d47..45c6da817 100755 --- a/main.c +++ b/main.c @@ -209,6 +209,7 @@ bool run_code_py(safe_mode_t safe_mode) { #endif stop_mp(); free_memory(heap); + supervisor_move_memory(); reset_port(); reset_board_busses(); @@ -221,6 +222,10 @@ bool run_code_py(safe_mode_t safe_mode) { } // Wait for connection or character. + if (!serial_connected_at_start) { + serial_write_compressed(translate("\nCode done running. Waiting for USB.\n")); + } + bool serial_connected_before_animation = false; rgb_status_animation_t animation; prep_rgb_status_animation(&result, found_main, safe_mode, &animation); @@ -342,6 +347,7 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { reset_board(); stop_mp(); free_memory(heap); + supervisor_move_memory(); } } @@ -362,6 +368,7 @@ int run_repl(void) { reset_board(); stop_mp(); free_memory(heap); + supervisor_move_memory(); autoreload_resume(); return exit_code; } diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 811d4eda4..4c8002c56 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -467,6 +467,7 @@ extern const struct _mp_obj_module_t pixelbuf_module; mp_obj_t rtc_time_source; \ FLASH_ROOT_POINTERS \ mp_obj_t gamepad_singleton; \ + mp_obj_t terminal_tilegrid_tiles; \ NETWORK_ROOT_POINTERS \ void run_background_tasks(void); diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index d61732f6f..1838228af 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -133,11 +133,15 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a //| STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - mp_raise_ValueError(translate("Must be a Group subclass.")); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type); + if (native_layer == MP_OBJ_NULL) { + mp_raise_ValueError(translate("Must be a Group subclass.")); + } + group = MP_OBJ_TO_PTR(native_layer); } - displayio_group_t* group = MP_OBJ_TO_PTR(native_layer); + common_hal_displayio_display_show(self, group); return mp_const_none; } diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index b8531a923..0026cd62f 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -138,9 +138,9 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t); self->base.type = &displayio_tilegrid_type; - common_hal_displayio_tilegrid_construct(self, native, args[ARG_pixel_shader].u_obj, - args[ARG_width].u_int, args[ARG_height].u_int, tile_width, tile_height, x, y, - args[ARG_default_tile].u_int); + common_hal_displayio_tilegrid_construct(self, native, bitmap_width / tile_width, + args[ARG_pixel_shader].u_obj, args[ARG_width].u_int, args[ARG_height].u_int, + tile_width, tile_height, x, y, args[ARG_default_tile].u_int); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index f553be423..a74fa4d39 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -32,7 +32,7 @@ extern const mp_obj_type_t displayio_tilegrid_type; void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, - mp_obj_t pixel_shader, uint16_t width, uint16_t height, + uint16_t bitmap_width_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile); void common_hal_displayio_tilegrid_get_position(displayio_tilegrid_t *self, int16_t* x, int16_t* y); diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 7946111b7..fd082c19d 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -30,6 +30,8 @@ #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/display.h" #include @@ -47,6 +49,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->set_column_command = set_column_command; self->set_row_command = set_row_command; self->write_ram_command = write_ram_command; + self->refresh = false; self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; @@ -86,9 +89,19 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, i += 2 + data_size; } self->end_transaction(self->bus); + + supervisor_start_terminal(width, height); + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + self->refresh = true; + self->current_group = &circuitpython_splash; } void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { + if (root_group == NULL) { + root_group = &circuitpython_splash; + } self->current_group = root_group; common_hal_displayio_display_refresh_soon(self); } diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index 46898fb8e..bbbd83486 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -105,12 +105,19 @@ bool displayio_group_needs_refresh(displayio_group_t *self) { } for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i]; - if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + if (displayio_tilegrid_needs_refresh(layer)) { + return true; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + if (displayio_group_needs_refresh(layer)) { + return true; + } + } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { if (displayio_sprite_needs_refresh(layer)) { return true; } } - // TODO: Tiled layer } return false; } @@ -119,9 +126,12 @@ void displayio_group_finish_refresh(displayio_group_t *self) { self->needs_refresh = false; for (int32_t i = self->size - 1; i >= 0 ; i--) { mp_obj_t layer = self->children[i]; - if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { + if (MP_OBJ_IS_TYPE(layer, &displayio_tilegrid_type)) { + displayio_tilegrid_finish_refresh(layer); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { + displayio_group_finish_refresh(layer); + } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { displayio_sprite_finish_refresh(layer); } - // TODO: Tiled layer } } diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 44874e283..ed724bf10 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -33,6 +33,7 @@ #include "shared-bindings/displayio/Shape.h" void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, + uint16_t bitmap_width_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) { uint32_t total_tiles = width * height; @@ -44,8 +45,9 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->tiles = (uint8_t*) m_malloc(total_tiles, false); self->inline_tiles = false; } + self->bitmap_width_in_tiles = bitmap_width_in_tiles; self->width_in_tiles = width; - self->height_in_tiles = width; + self->height_in_tiles = height; self->total_width = width * tile_width; self->total_height = height * tile_height; self->tile_width = tile_width; @@ -87,10 +89,13 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; } + if (tiles == NULL) { + return false; + } uint16_t tile_location = (y / self->tile_height) * self->width_in_tiles + x / self->tile_width; uint8_t tile = tiles[tile_location]; - uint16_t tile_x = tile_x = (tile % self->width_in_tiles) * self->tile_width + x % self->tile_width; - uint16_t tile_y = tile_y = (tile / self->width_in_tiles) * self->tile_height + y % self->tile_height; + uint16_t tile_x = tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + x % self->tile_width; + uint16_t tile_y = tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + y % self->tile_height; uint32_t value = 0; if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { @@ -118,7 +123,11 @@ void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t if (self->inline_tiles) { tiles = (uint8_t*) &self->tiles; } + if (tiles == NULL) { + return; + } tiles[y * self->width_in_tiles + x] = tile_index; + self->needs_refresh = true; } bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) { diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index c24a606a3..84e3e7ef2 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -38,6 +38,7 @@ typedef struct { mp_obj_t pixel_shader; uint16_t x; uint16_t y; + uint16_t bitmap_width_in_tiles; uint16_t width_in_tiles; uint16_t height_in_tiles; uint16_t total_width; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 61228f8d2..dbfeacc3d 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -9,6 +9,7 @@ #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/Sprite.h" #include "supervisor/shared/display.h" +#include "supervisor/memory.h" #include "supervisor/usb.h" primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; @@ -68,76 +69,24 @@ void displayio_refresh_displays(void) { } } -uint32_t blinka_bitmap_data[32] = { - 0x00000011, 0x11000000, - 0x00000111, 0x53100000, - 0x00000111, 0x56110000, - 0x00000111, 0x11140000, - 0x00000111, 0x20002000, - 0x00000011, 0x13000000, - 0x00000001, 0x11200000, - 0x00000000, 0x11330000, - 0x00000000, 0x01122000, - 0x00001111, 0x44133000, - 0x00032323, 0x24112200, - 0x00111114, 0x44113300, - 0x00323232, 0x34112200, - 0x11111144, 0x44443300, - 0x11111111, 0x11144401, - 0x23232323, 0x21111110 -}; - -displayio_bitmap_t blinka_bitmap = { - .base = {.type = &displayio_bitmap_type }, - .width = 16, - .height = 16, - .data = blinka_bitmap_data, - .stride = 2, - .bits_per_value = 4, - .x_shift = 3, - .x_mask = 0x7, - .bitmask = 0xf -}; - -uint32_t blinka_transparency[1] = {0x80000000}; - -// These colors are RGB 565 with the bytes swapped. -uint32_t blinka_colors[8] = {0x78890000, 0x9F86B8FC, 0xffff0D5A, 0x0000f501, - 0x00000000, 0x00000000, 0x00000000, 0x00000000}; - -displayio_palette_t blinka_palette = { - .base = {.type = &displayio_palette_type }, - .opaque = blinka_transparency, - .colors = blinka_colors, - .color_count = 16, - .needs_refresh = false -}; - -displayio_sprite_t blinka_sprite = { - .base = {.type = &displayio_sprite_type }, - .bitmap = &blinka_bitmap, - .pixel_shader = &blinka_palette, - .x = 0, - .y = 0, - .width = 16, - .height = 16, - .needs_refresh = false -}; - -mp_obj_t splash_children[1] = { - &blinka_sprite, -}; +void common_hal_displayio_release_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_parallelbus_type) { + common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = &mp_type_NoneType; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + displays[i].display.base.type = &mp_type_NoneType; + } -displayio_group_t splash = { - .base = {.type = &displayio_group_type }, - .x = 0, - .y = 0, - .scale = 2, - .size = 1, - .max_size = 1, - .children = splash_children, - .needs_refresh = true -}; + supervisor_stop_terminal(); +} void reset_displays(void) { // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. @@ -168,23 +117,6 @@ void reset_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; - common_hal_displayio_display_show(display, &splash); - } -} - -void common_hal_displayio_release_displays(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; - if (bus_type == NULL) { - continue; - } else if (bus_type == &displayio_fourwire_type) { - common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); - } else if (bus_type == &displayio_parallelbus_type) { - common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); - } - displays[i].fourwire_bus.base.type = &mp_type_NoneType; - } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - displays[i].display.base.type = &mp_type_NoneType; + common_hal_displayio_display_show(display, &circuitpython_splash); } } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index fdabd4ec4..5b56ed55c 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -29,6 +29,7 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/ParallelBus.h" typedef struct { @@ -41,6 +42,8 @@ typedef struct { extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +extern displayio_group_t circuitpython_splash; + void displayio_refresh_displays(void); void reset_displays(void); diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index c47f9f6cf..1cd5d341e 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -28,7 +28,7 @@ #include "shared-bindings/displayio/TileGrid.h" -void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, uint8_t* unicode_characters, uint16_t unicode_characters_len) { +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, uint16_t unicode_characters_len) { self->cursor_x = 0; self->cursor_y = 0; self->tilegrid = tilegrid; @@ -38,6 +38,7 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { const byte* i = data; + uint16_t start_y = self->cursor_y; while (i < data + len) { unichar c = utf8_get_char(i); i = utf8_next_char(i); @@ -51,6 +52,40 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con self->cursor_x = 0; } else if (c == '\n') { self->cursor_y++; + // Commands below are used by MicroPython in the REPL + } else if (c == '\b') { + if (self->cursor_x > 0) { + self->cursor_x--; + } + } else if (c == 0x1b) { + if (i[0] == '[') { + if (i[1] == 'K') { + // Clear the rest of the line. + for (uint16_t j = self->cursor_x; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + } + i += 2; + } else { + // Handle commands of the form \x1b[####D + uint16_t n = 0; + uint8_t j = 1; + for (; j < 6; j++) { + if ('0' <= i[j] && i[j] <= '9') { + n = n * 10 + (i[j] - '0'); + } else { + c = i[j]; + } + } + if (c == 'D') { + if (n > self->cursor_x) { + self->cursor_x = 0; + } else { + self->cursor_x -= n; + } + i += j; + } + } + } } } else { // Do a linear search of the mapping for unicode. @@ -73,6 +108,13 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con if (self->cursor_y >= self->tilegrid->height_in_tiles) { self->cursor_y %= self->tilegrid->height_in_tiles; } + if (self->cursor_y != start_y) { + // clear the new row + for (uint16_t j = 0; j < self->tilegrid->width_in_tiles; j++) { + common_hal_displayio_textgrid_set_tile(self->tilegrid, j, self->cursor_y, 0); + start_y = self->cursor_y; + } + } } return i - data; } diff --git a/supervisor/memory.h b/supervisor/memory.h index c89f14bd9..f557744ae 100755 --- a/supervisor/memory.h +++ b/supervisor/memory.h @@ -57,4 +57,7 @@ static inline uint16_t align32_size(uint16_t size) { return size; } +// Called after the heap is freed in case the supervisor wants to save some values. +void supervisor_move_memory(void); + #endif // MICROPY_INCLUDED_SUPERVISOR_MEMORY_H diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c new file mode 100644 index 000000000..18693266f --- /dev/null +++ b/supervisor/shared/display.c @@ -0,0 +1,177 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft 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 "supervisor/shared/display.h" + +#include + +#include "py/mpstate.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Sprite.h" +#include "supervisor/memory.h" + +extern uint32_t blinka_bitmap_data[]; +extern displayio_bitmap_t blinka_bitmap; +extern displayio_group_t circuitpython_splash; + +static supervisor_allocation* tilegrid_tiles = NULL; + +void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { + displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; + uint16_t width_in_tiles = (width_px - blinka_bitmap.width) / grid->tile_width; + // determine scale based on h + uint8_t scale = 1; + if (width_in_tiles > 80) { + scale = 2; + } + width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale); + uint16_t height_in_tiles = height_px / (grid->tile_height * scale); + circuitpython_splash.scale = scale; + + uint16_t total_tiles = width_in_tiles * height_in_tiles; + + // First try to allocate outside the heap. This will fail when the VM is running. + tilegrid_tiles = allocate_memory(total_tiles, false); + uint8_t* tiles; + if (tilegrid_tiles == NULL) { + tiles = m_malloc(total_tiles, true); + MP_STATE_VM(terminal_tilegrid_tiles) = tiles; + } else { + tiles = (uint8_t*) tilegrid_tiles->ptr; + } + + if (tiles == NULL) { + return; + } + + grid->width_in_tiles = width_in_tiles; + grid->height_in_tiles = height_in_tiles; + grid->total_width = width_in_tiles * grid->tile_width; + grid->total_height = height_in_tiles * grid->tile_height; + grid->tiles = tiles; + + supervisor_terminal.cursor_x = 0; + supervisor_terminal.cursor_y = 0; +} + +void supervisor_stop_terminal(void) { + if (tilegrid_tiles != NULL) { + free_memory(tilegrid_tiles); + supervisor_terminal_text_grid.inline_tiles = false; + supervisor_terminal_text_grid.tiles = NULL; + } +} + +void supervisor_display_move_memory(void) { + displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; + if (MP_STATE_VM(terminal_tilegrid_tiles) == NULL || grid->tiles != MP_STATE_VM(terminal_tilegrid_tiles)) { + return; + } + uint16_t total_tiles = grid->width_in_tiles * grid->height_in_tiles; + + tilegrid_tiles = allocate_memory(total_tiles, false); + if (tilegrid_tiles != NULL) { + memcpy(tilegrid_tiles->ptr, grid->tiles, total_tiles); + grid->tiles = (uint8_t*) tilegrid_tiles->ptr; + } else { + grid->tiles = NULL; + grid->inline_tiles = false; + } + MP_STATE_VM(terminal_tilegrid_tiles) = NULL; +} + +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; + +displayio_bitmap_t blinka_bitmap = { + .base = {.type = &displayio_bitmap_type }, + .width = 16, + .height = 16, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf +}; + +uint32_t blinka_transparency[1] = {0x80000000}; + +// These colors are RGB 565 with the bytes swapped. +uint32_t blinka_colors[8] = {0x78890000, 0x9F86B8FC, 0xffff0D5A, 0x0000f501, + 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + +displayio_palette_t blinka_palette = { + .base = {.type = &displayio_palette_type }, + .opaque = blinka_transparency, + .colors = blinka_colors, + .color_count = 16, + .needs_refresh = false +}; + +displayio_sprite_t blinka_sprite = { + .base = {.type = &displayio_sprite_type }, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .width = 16, + .height = 16, + .needs_refresh = false +}; + +mp_obj_t splash_children[2] = { + &blinka_sprite, + &supervisor_terminal_text_grid +}; + +displayio_group_t circuitpython_splash = { + .base = {.type = &displayio_group_type }, + .x = 0, + .y = 0, + .scale = 2, + .size = 2, + .max_size = 2, + .children = splash_children, + .needs_refresh = true +}; diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index 5c420e590..cca907916 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -28,8 +28,21 @@ #define MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H #include "shared-bindings/displayio/Bitmap.h" +#include "shared-bindings/displayio/TileGrid.h" +#include "shared-bindings/terminalio/Terminal.h" + // These are autogenerated resources. -const displayio_bitmap_t terminal_font; +// This is fixed so it doesn't need to be in RAM. +extern const displayio_bitmap_t supervisor_terminal_font; + +// These will change so they must live in RAM. +extern displayio_tilegrid_t supervisor_terminal_text_grid; +extern terminalio_terminal_obj_t supervisor_terminal; + +void supervisor_start_terminal(uint16_t width_px, uint16_t height_px); +void supervisor_stop_terminal(void); + +void supervisor_display_move_memory(void); #endif // MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 6c8be3be8..11133415d 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -28,6 +28,8 @@ #include +#include "supervisor/shared/display.h" + #define CIRCUITPY_SUPERVISOR_ALLOC_COUNT 8 static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; @@ -114,3 +116,7 @@ supervisor_allocation* allocate_memory(uint32_t length, bool high) { alloc->length = length; return alloc; } + +void supervisor_move_memory(void) { + supervisor_display_move_memory(); +} diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index c57688ddc..ac5239a84 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -26,6 +26,8 @@ #include +#include "supervisor/shared/display.h" +#include "shared-bindings/terminalio/Terminal.h" #include "supervisor/serial.h" #include "supervisor/usb.h" @@ -48,6 +50,8 @@ bool serial_bytes_available(void) { } void serial_write_substring(const char* text, uint32_t length) { + int errcode; + common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode); if (!tud_cdc_connected()) { return; } diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 174abd9d9..0e315a742 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -3,6 +3,7 @@ SRC_SUPERVISOR = \ supervisor/port.c \ supervisor/shared/autoreload.c \ supervisor/shared/board_busses.c \ + supervisor/shared/display.c \ supervisor/shared/filesystem.c \ supervisor/shared/flash.c \ supervisor/shared/micropython.c \ @@ -91,7 +92,7 @@ autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile --output_c_file $(BUILD)/autogen_usb_descriptor.c\ --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h -CIRCUITPY_DISPLAY_FONT = "fonts/test.bdf" +CIRCUITPY_DISPLAY_FONT = "../../tools/Tecate-bitmap-fonts/bitmap/cherry/cherry-10-r.bdf" $(BUILD)/autogen_display_resources.c: ../../tools/gen_display_resources.py $(HEADER_BUILD)/qstrdefs.generated.h Makefile | $(HEADER_BUILD) $(STEPECHO) "GEN $@" diff --git a/tools/bitmap_font b/tools/bitmap_font index 7320e8ff9..62dd78abd 160000 --- a/tools/bitmap_font +++ b/tools/bitmap_font @@ -1 +1 @@ -Subproject commit 7320e8ff94312c791aeed1a6956f8640e1dddc66 +Subproject commit 62dd78abdd0b823824fe15d1bab0611246145c23 diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index 3bcdc9952..27ea2a471 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -1,9 +1,11 @@ import argparse import os +import struct import sys sys.path.append("bitmap_font") +sys.path.append("../../tools/bitmap_font") from adafruit_bitmap_font import bitmap_font @@ -14,16 +16,6 @@ parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=Tru args = parser.parse_args() -args.font - -c_file = args.output_c_file - -c_file.write("""\ - -#include "supervisor/shared/display.h" - -""") - class BitmapStub: def __init__(self, width, height, color_depth): self.width = width @@ -39,30 +31,140 @@ print(f.get_bounding_box()) real_bb = [0, 0] visible_ascii = bytes(range(0x20, 0x7f)).decode("utf-8") -all_characters = visible_ascii +extra_characters = "üàêùéáçãÍóíαψ◌" +all_characters = visible_ascii + extra_characters +filtered_characters = all_characters for c in all_characters: g = f.get_glyph(ord(c)) + if not g: + print("Font missing character:", c, ord(c)) + filtered_characters = filtered_characters.replace(c, "") + extra_characters = extra_characters.replace(c, "") + continue x, y, dx, dy = g["bounds"] - print(c, g["bounds"], g["shift"]) + #print(c, g["bounds"], g["shift"]) if g["shift"][1] != 0: raise RuntimeError("y shift") - real_bb[0] = max(max(real_bb[0], x - dx), g["shift"][0]) + real_bb[0] = max(real_bb[0], x - dx) real_bb[1] = max(real_bb[1], y - dy) -real_bb[1] += 1 -print(real_bb) +#real_bb[1] += 1 +#print(real_bb) tile_x, tile_y = real_bb +total_bits = tile_x * len(all_characters) +total_bits += 32 - total_bits % 32 +bytes_per_row = total_bits // 8 +b = bytearray(bytes_per_row * tile_y) -for c in all_characters: +for x, c in enumerate(filtered_characters): g = f.get_glyph(ord(c)) - #print(c, g["bounds"], g["shift"]) - for row in g["bitmap"].rows: + start_bit = x * tile_x + g["bounds"][2] + start_y = (tile_y - 2) - (g["bounds"][1] + g["bounds"][3]) + # print(c, g["bounds"], g["shift"], tile_y, start_y) + for y, row in enumerate(g["bitmap"].rows): for i in range(g["bounds"][0]): byte = i // 8 bit = i % 8 - # if row[byte] & (1 << (7-bit)) != 0: - # print("*",end="") + if row[byte] & (1 << (7-bit)) != 0: + overall_bit = start_bit + (start_y + y) * bytes_per_row * 8 + i + b[overall_bit // 8] |= 1 << (7 - (overall_bit % 8)) + # print("*",end="") # else: # print("_",end="") #print() + +# print(b) +# print("tile_x = {}".format(tile_x)) +# print("tile_y = {}".format(tile_y)) +# print("tiles = {}".format(len(all_characters))) +# print("font = displayio.Bitmap(tile_x * tiles, tile_y, 2)") +# for row in range(tile_y): +# print("font._load_row({}, {})".format(row, bytes(b[row*bytes_per_row:row*bytes_per_row+bytes_per_row]))) + +# for row in range(tile_y): +# for byte in b[row*bytes_per_row:row*bytes_per_row+bytes_per_row]: +# print("{:08b} ".format(byte),end="") +# print() + +c_file = args.output_c_file + +c_file.write("""\ + +#include "shared-bindings/displayio/Palette.h" +#include "supervisor/shared/display.h" + +""") + +c_file.write("""\ +uint32_t terminal_transparency[1] = {0x00000000}; + +// These colors are RGB 565 with the bytes swapped. +uint32_t terminal_colors[1] = {0xffff0000}; + +displayio_palette_t supervisor_terminal_color = { + .base = {.type = &displayio_palette_type }, + .opaque = terminal_transparency, + .colors = terminal_colors, + .color_count = 2, + .needs_refresh = false +}; +""") + +c_file.write("""\ +displayio_tilegrid_t supervisor_terminal_text_grid = {{ + .base = {{ .type = &displayio_tilegrid_type }}, + .bitmap = (displayio_bitmap_t*) &supervisor_terminal_font, + .pixel_shader = &supervisor_terminal_color, + .x = 16, + .y = 0, + .bitmap_width_in_tiles = {0}, + .width_in_tiles = 1, + .height_in_tiles = 1, + .total_width = {1}, + .total_height = {2}, + .tile_width = {1}, + .tile_height = {2}, + .tiles = NULL, + .needs_refresh = false, + .inline_tiles = false +}}; +""".format(len(all_characters), tile_x, tile_y)) + +c_file.write("""\ +const uint32_t font_bitmap_data[{}] = {{ +""".format(bytes_per_row * tile_y // 4)) + +for i, word in enumerate(struct.iter_unpack(">I", b)): + c_file.write("0x{:08x}, ".format(word[0])) + if (i + 1) % (bytes_per_row // 4) == 0: + c_file.write("\n") + +c_file.write("""\ +}; +""") + +c_file.write("""\ +const displayio_bitmap_t supervisor_terminal_font = {{ + .base = {{.type = &displayio_bitmap_type }}, + .width = {}, + .height = {}, + .data = (uint32_t*) font_bitmap_data, + .stride = {}, + .bits_per_value = 1, + .x_shift = 5, + .x_mask = 0x1f, + .bitmask = 0x1 +}}; +""".format(len(all_characters) * tile_x, tile_y, bytes_per_row / 4)) + +c_file.write("""\ +terminalio_terminal_obj_t supervisor_terminal = {{ + .base = {{.type = &terminalio_terminal_type }}, + .cursor_x = 0, + .cursor_y = 0, + .tilegrid = &supervisor_terminal_text_grid, + .unicode_characters = (const uint8_t*) "{}", + .unicode_characters_len = {} +}}; +""".format(extra_characters, len(extra_characters.encode("utf-8")))) -- cgit v1.2.3 From 69bc5e189baef183918dc21dadaacf55ce66bee3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 25 Jan 2019 18:31:27 -0800 Subject: Rudamentary backlight support --- ports/atmel-samd/boards/pyportal/board.c | 3 +- ports/atmel-samd/common-hal/pulseio/PWMOut.c | 47 +++++++++++++++++++++------- shared-bindings/displayio/Display.c | 3 +- shared-bindings/displayio/Display.h | 2 +- shared-bindings/pulseio/PWMOut.c | 11 ++++++- shared-bindings/pulseio/PWMOut.h | 14 ++++++++- shared-module/displayio/Display.c | 43 ++++++++++++++++++++++++- shared-module/displayio/Display.h | 14 ++++++++- shared-module/displayio/__init__.c | 3 ++ 9 files changed, 122 insertions(+), 18 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 6e5b37dd2..980a28e9b 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -87,7 +87,8 @@ void board_init(void) { MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, - sizeof(display_init_sequence)); + sizeof(display_init_sequence), + &pin_PB31); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c index 825bdd181..2740a9e55 100644 --- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -58,6 +58,26 @@ uint8_t tcc_channels[3]; // Set by pwmout_reset() to {0xf0, 0xfc, 0xfc} initia uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, 0xfc} initially. #endif +static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] += 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] += 1; + } + + never_reset_pin_number(self->pin->number); +} + +void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { + if (self->timer->is_tc) { + never_reset_tc_or_tcc[self->timer->index] -= 1; + } else { + never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] -= 1; + } +} + void pwmout_reset(void) { // Reset all timers for (int i = 0; i < TCC_INST_NUM; i++) { @@ -66,6 +86,9 @@ void pwmout_reset(void) { } Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; for (int i = 0; i < TCC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[TC_INST_NUM + i] > 0) { + continue; + } // Disable the module before resetting it. if (tccs[i]->CTRLA.bit.ENABLE == 1) { tccs[i]->CTRLA.bit.ENABLE = 0; @@ -81,6 +104,9 @@ void pwmout_reset(void) { } Tc *tcs[TC_INST_NUM] = TC_INSTS; for (int i = 0; i < TC_INST_NUM; i++) { + if (never_reset_tc_or_tcc[i] > 0) { + continue; + } tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; while (tcs[i]->COUNT16.CTRLA.bit.SWRST == 1) { } @@ -99,11 +125,11 @@ bool channel_ok(const pin_timer_t* t) { t->is_tc; } -void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, - uint16_t duty, - uint32_t frequency, - bool variable_frequency) { +pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { self->pin = pin; self->variable_frequency = variable_frequency; @@ -113,11 +139,11 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, && pin->timer[2].index >= TCC_INST_NUM #endif ) { - mp_raise_ValueError(translate("Invalid pin")); + return PWMOUT_INVALID_PIN; } if (frequency == 0 || frequency > 6000000) { - mp_raise_ValueError(translate("Invalid PWM frequency")); + return PWMOUT_INVALID_FREQUENCY; } // Figure out which timer we are using. @@ -184,11 +210,9 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, if (timer == NULL) { if (found) { - mp_raise_ValueError(translate("All timers for this pin are in use")); - } else { - mp_raise_RuntimeError(translate("All timers in use")); + return PWMOUT_ALL_TIMERS_ON_PIN_IN_USE; } - return; + return PWMOUT_ALL_TIMERS_IN_USE; } uint8_t resolution = 0; @@ -259,6 +283,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, gpio_set_pin_function(pin->number, GPIO_PIN_FUNCTION_E + mux_position); common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return PWMOUT_OK; } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 1838228af..398bca166 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -119,10 +119,11 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_raise_RuntimeError(translate("Too many displays")); } self->base.type = &displayio_display_type; + // TODO(tannewt): Support backlight pin. common_hal_displayio_display_construct(self, display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, - args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len); + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, NULL); return self; } diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 4cec66058..181afc941 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -40,7 +40,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, - uint8_t* init_sequence, uint16_t init_sequence_len); + uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin); int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index ed3acd804..bba5fe883 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -108,7 +108,16 @@ STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args // create PWM object from the given pin pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); self->base.type = &pulseio_pwmout_type; - common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + pwmout_result_t result = common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + if (result == PWMOUT_INVALID_PIN) { + mp_raise_ValueError(translate("Invalid pin")); + } else if (result == PWMOUT_INVALID_FREQUENCY) { + mp_raise_ValueError(translate("Invalid PWM frequency")); + } else if (result == PWMOUT_ALL_TIMERS_ON_PIN_IN_USE) { + mp_raise_ValueError(translate("All timers for this pin are in use")); + } else if (result == PWMOUT_ALL_TIMERS_IN_USE) { + mp_raise_RuntimeError(translate("All timers in use")); + } return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/pulseio/PWMOut.h b/shared-bindings/pulseio/PWMOut.h index 0b630816b..c01e0c926 100644 --- a/shared-bindings/pulseio/PWMOut.h +++ b/shared-bindings/pulseio/PWMOut.h @@ -32,7 +32,15 @@ extern const mp_obj_type_t pulseio_pwmout_type; -extern void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, +typedef enum { + PWMOUT_OK, + PWMOUT_INVALID_PIN, + PWMOUT_INVALID_FREQUENCY, + PWMOUT_ALL_TIMERS_ON_PIN_IN_USE, + PWMOUT_ALL_TIMERS_IN_USE +} pwmout_result_t; + +extern pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, bool variable_frequency); extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self); @@ -43,4 +51,8 @@ extern void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, extern uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self); extern bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self); +// This is used by the supervisor to claim PWMOut devices indefinitely. +extern void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self); +extern void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index fd082c19d..504f130c7 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/time/__init__.h" #include "shared-module/displayio/__init__.h" #include "supervisor/shared/display.h" @@ -42,7 +43,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t color_depth, uint8_t set_column_command, uint8_t set_row_command, - uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len) { + uint8_t write_ram_command, uint8_t* init_sequence, uint16_t init_sequence_len, + const mcu_pin_obj_t* backlight_pin) { self->width = width; self->height = height; self->color_depth = color_depth; @@ -96,6 +98,19 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, // initialization. self->refresh = true; self->current_group = &circuitpython_splash; + + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 5000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + never_reset_pin_number(backlight_pin->number); + } else { + self->backlight_pwm.base.type = &pulseio_pwmout_type; + common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); + } + } + self->auto_brightness = true; } void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { @@ -158,3 +173,29 @@ bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixe self->send(self->bus, false, (uint8_t*) pixels, length * 4); return true; } + +void displayio_display_update_backlight(displayio_display_obj_t* self) { + if (!self->auto_brightness || self->updating_backlight) { + return; + } + if (ticks_ms - self->last_backlight_refresh < 100) { + return; + } + self->updating_backlight = true; + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, 0xffff); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, true); + } + self->updating_backlight = false; + self->last_backlight_refresh = ticks_ms; +} + +void release_display(displayio_display_obj_t* self) { + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); + common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } +} diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h index 1f1355d31..0d7393aff 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -27,7 +27,9 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H #define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H -#include "shared-module/displayio/Group.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); typedef void (*display_bus_send)(mp_obj_t bus, bool command, uint8_t *data, uint32_t data_length); @@ -50,6 +52,16 @@ typedef struct { display_bus_begin_transaction begin_transaction; display_bus_send send; display_bus_end_transaction end_transaction; + union { + digitalio_digitalinout_obj_t backlight_inout; + pulseio_pwmout_obj_t backlight_pwm; + }; + uint64_t last_backlight_refresh; + bool auto_brightness:1; + bool updating_backlight:1; } displayio_display_obj_t; +void displayio_display_update_backlight(displayio_display_obj_t* self); +void release_display(displayio_display_obj_t* self); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dbfeacc3d..8e4904954 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -20,6 +20,7 @@ void displayio_refresh_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; + displayio_display_update_backlight(display); if (!displayio_display_frame_queued(display)) { return; @@ -82,6 +83,7 @@ void common_hal_displayio_release_displays(void) { displays[i].fourwire_bus.base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + release_display(&displays[i].display); displays[i].display.base.type = &mp_type_NoneType; } @@ -117,6 +119,7 @@ void reset_displays(void) { continue; } displayio_display_obj_t* display = &displays[i].display; + display->auto_brightness = true; common_hal_displayio_display_show(display, &circuitpython_splash); } } -- cgit v1.2.3 From 6145f08cc89946d138737b149d390265def67077 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 28 Jan 2019 18:23:32 -0800 Subject: Support adjustable backlight brightness --- main.c | 2 +- shared-bindings/displayio/Display.c | 71 +++++++++++++++++++++++++++++++++++-- shared-bindings/displayio/Display.h | 6 ++++ shared-module/displayio/Display.c | 49 ++++++++++++++++++++----- shared-module/terminalio/Terminal.c | 1 + shared-module/terminalio/Terminal.h | 1 + 6 files changed, 118 insertions(+), 12 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/main.c b/main.c index 45c6da817..39d1cd3d0 100755 --- a/main.c +++ b/main.c @@ -223,7 +223,7 @@ bool run_code_py(safe_mode_t safe_mode) { // Wait for connection or character. if (!serial_connected_at_start) { - serial_write_compressed(translate("\nCode done running. Waiting for USB.\n")); + serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); } bool serial_connected_before_animation = false; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 398bca166..e59905258 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -84,9 +84,10 @@ //| :param int set_column_command: Command used to set the start and end columns to update //| :param int set_row_command: Command used so set the start and end rows to update //| :param int write_ram_command: Command used to write pixels values into the update region +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_backlight_pin }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -98,6 +99,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, + { MP_QSTR_backlight_pin, 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(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -107,6 +109,9 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + mp_obj_t backlight_pin = args[ARG_backlight_pin].u_obj; + assert_pin_free(backlight_pin); + displayio_display_obj_t *self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].display.base.type == NULL || @@ -119,11 +124,10 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_raise_RuntimeError(translate("Too many displays")); } self->base.type = &displayio_display_type; - // TODO(tannewt): Support backlight pin. common_hal_displayio_display_construct(self, display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, - args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, NULL); + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, backlight_pin); return self; } @@ -170,11 +174,72 @@ STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame); +//| .. attribute:: brightness +//| +//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When +//| `auto_brightness` is True this value will change automatically and setting it will have no +//| effect. To control the brightness, auto_brightness must be false. +//| +STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_float_t brightness = common_hal_displayio_display_get_brightness(self); + if (brightness < 0) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_obj_new_float(brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_display_obj_get_brightness); + +STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + bool ok = common_hal_displayio_display_set_brightness(self, mp_obj_get_float(brightness)); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_brightness_obj, displayio_display_obj_set_brightness); + +const mp_obj_property_t displayio_display_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_brightness_obj, + (mp_obj_t)&displayio_display_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: auto_brightness +//| +//| True when the display brightness is auto adjusted. +//| +STATIC mp_obj_t displayio_display_obj_get_auto_brightness(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_displayio_display_get_auto_brightness(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_brightness_obj, displayio_display_obj_get_auto_brightness); + +STATIC mp_obj_t displayio_display_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_displayio_display_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_set_auto_brightness_obj, displayio_display_obj_set_auto_brightness); + +const mp_obj_property_t displayio_display_auto_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&displayio_display_get_auto_brightness_obj, + (mp_obj_t)&displayio_display_set_auto_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) }, { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) }, { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_display_wait_for_frame_obj) }, + + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&displayio_display_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&displayio_display_auto_brightness_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table); diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 181afc941..906c3620d 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -56,4 +56,10 @@ bool displayio_display_refresh_queued(displayio_display_obj_t* self); void displayio_display_finish_refresh(displayio_display_obj_t* self); bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length); +bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self); +void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness); + +mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self); +bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 504f130c7..a2a60227d 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -55,6 +55,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; + self->auto_brightness = false; if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; @@ -110,7 +111,6 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); } } - self->auto_brightness = true; } void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) { @@ -133,6 +133,42 @@ int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* sel return 0; } +bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self) { + return self->auto_brightness; +} + +void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness) { + self->auto_brightness = auto_brightness; +} + +mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* self) { + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + uint16_t duty_cycle = common_hal_pulseio_pwmout_get_duty_cycle(&self->backlight_pwm); + return duty_cycle / ((mp_float_t) 0xffff); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + if (common_hal_digitalio_digitalinout_get_value(&self->backlight_inout)) { + return 1.0; + } else { + return 0.0; + } + } + return -1.0; +} + +bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) { + self->updating_backlight = true; + bool ok = false; + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); + ok = true; + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); + ok = true; + } + self->updating_backlight = false; + return ok; +} + void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { // TODO(tannewt): Handle displays with single byte bounds. self->begin_transaction(self->bus); @@ -181,13 +217,10 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) { if (ticks_ms - self->last_backlight_refresh < 100) { return; } - self->updating_backlight = true; - if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, 0xffff); - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, true); - } - self->updating_backlight = false; + // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target + // should account for ambient light when possible. + common_hal_displayio_display_set_brightness(self, 1.0); + self->last_backlight_refresh = ticks_ms; } diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 1cd5d341e..444bf53ad 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -34,6 +34,7 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, d self->tilegrid = tilegrid; self->unicode_characters = unicode_characters; self->unicode_characters_len = unicode_characters_len; + self->first_row = 0; } size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h index 1896075f3..fe9dcf0c4 100644 --- a/shared-module/terminalio/Terminal.h +++ b/shared-module/terminalio/Terminal.h @@ -40,6 +40,7 @@ typedef struct { displayio_tilegrid_t* tilegrid; const byte* unicode_characters; uint16_t unicode_characters_len; + uint16_t first_row; } terminalio_terminal_obj_t; #endif /* SHARED_MODULE_TERMINALIO_TERMINAL_H */ -- cgit v1.2.3 From 601a910f4eb83cf1ae7516a25c011b469ac76b8b Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 29 Jan 2019 15:04:07 -0800 Subject: More improvements to Terminal: * Fix Hallowing. * Fix builds without displayio. * Fix y bounds that appears as untrollable row of pixels. * Add scrolling to TileGrid. * Remove Sprite to save space. TileGrid is a drop in replacement. --- main.c | 7 +- ports/atmel-samd/Makefile | 1 - .../atmel-samd/boards/hallowing_m0_express/board.c | 5 +- ports/atmel-samd/mpconfigport.h | 1 + shared-bindings/displayio/Sprite.c | 195 --------------------- shared-bindings/displayio/Sprite.h | 43 ----- shared-bindings/displayio/TileGrid.h | 1 + shared-bindings/displayio/__init__.c | 1 - shared-module/displayio/Display.c | 4 +- shared-module/displayio/Group.c | 13 -- shared-module/displayio/Sprite.c | 102 ----------- shared-module/displayio/Sprite.h | 50 ------ shared-module/displayio/TileGrid.c | 8 +- shared-module/displayio/TileGrid.h | 2 + shared-module/displayio/__init__.c | 2 + shared-module/terminalio/Terminal.c | 4 +- supervisor/shared/display.c | 21 ++- supervisor/shared/serial.c | 4 + 18 files changed, 42 insertions(+), 422 deletions(-) delete mode 100644 shared-bindings/displayio/Sprite.c delete mode 100644 shared-bindings/displayio/Sprite.h delete mode 100644 shared-module/displayio/Sprite.c delete mode 100644 shared-module/displayio/Sprite.h (limited to 'shared-bindings/displayio') diff --git a/main.c b/main.c index 39d1cd3d0..b17c11137 100755 --- a/main.c +++ b/main.c @@ -44,6 +44,7 @@ #include "lib/utils/pyexec.h" #include "mpconfigboard.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/cpu.h" #include "supervisor/memory.h" #include "supervisor/port.h" @@ -61,10 +62,6 @@ #include "shared-module/network/__init__.h" #endif -#ifdef CIRCUITPY_DISPLAYIO -#include "shared-module/displayio/__init__.h" -#endif - void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -203,10 +200,8 @@ bool run_code_py(safe_mode_t safe_mode) { serial_write_compressed(translate("WARNING: Your code filename has two extensions\n")); } } - #ifdef CIRCUITPY_DISPLAYIO // Turn off the display before the heap disappears. reset_displays(); - #endif stop_mp(); free_memory(heap); supervisor_move_memory(); diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 4cdfc265d..56c31e5d8 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -388,7 +388,6 @@ SRC_SHARED_MODULE = \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ displayio/Shape.c \ - displayio/Sprite.c \ displayio/TileGrid.c \ gamepad/__init__.c \ gamepad/GamePad.c \ diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 2b12ae464..72306e14a 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -84,13 +84,14 @@ void board_init(void) { 128, // Width 128, // Height 2, // column start - 0, // row start + 1, // row start 16, // Color depth MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, - sizeof(display_init_sequence)); + sizeof(display_init_sequence), + &pin_PA00); } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 4c8002c56..137091b6d 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -351,6 +351,7 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) + #define CIRCUITPY_DISPLAYIO (0) #define CIRCUITPY_DISPLAY_LIMIT (0) #endif diff --git a/shared-bindings/displayio/Sprite.c b/shared-bindings/displayio/Sprite.c deleted file mode 100644 index 864ecc959..000000000 --- a/shared-bindings/displayio/Sprite.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft 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 "shared-bindings/displayio/Sprite.h" - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/binary.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/displayio/Bitmap.h" -#include "shared-bindings/displayio/ColorConverter.h" -#include "shared-bindings/displayio/OnDiskBitmap.h" -#include "shared-bindings/displayio/Palette.h" -#include "shared-bindings/displayio/Shape.h" -#include "supervisor/shared/translate.h" - -static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) { - // TODO(tannewt): Support any value sequence such as bytearray or bytes. - mp_obj_tuple_t *position = MP_OBJ_TO_PTR(position_obj); - if (MP_OBJ_IS_TYPE(position_obj, &mp_type_tuple) && position->len == 2) { - *x = mp_obj_get_int(position->items[0]); - *y = mp_obj_get_int(position->items[1]); - } else if (position != mp_const_none) { - mp_raise_TypeError(translate("position must be 2-tuple")); - } -} - -//| .. currentmodule:: displayio -//| -//| :class:`Sprite` -- A particular copy of an image to display -//| ========================================================================== -//| -//| Position a particular image and pixel_shader combination. Multiple sprites can share bitmaps -//| pixel shaders. -//| -//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. -//| -//| .. class:: Sprite(bitmap, *, pixel_shader, position, width, height) -//| -//| Create a Sprite object. The bitmap is source for 2d pixels. The pixel_shader is used to -//| convert the value and its location to a display native pixel color. This may be a simple color -//| palette lookup, a gradient, a pattern or a color transformer. -//| -//| -STATIC mp_obj_t displayio_sprite_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_bitmap, ARG_pixel_shader, ARG_position, ARG_width, ARG_height }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY }, - { MP_QSTR_position, MP_ARG_OBJ | MP_ARG_KW_ONLY }, - { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, - { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_obj_t bitmap = args[ARG_bitmap].u_obj; - - uint16_t width; - uint16_t height; - mp_obj_t native = mp_instance_cast_to_native_base(bitmap, &displayio_shape_type); - if (native != MP_OBJ_NULL) { - displayio_shape_t* bmp = MP_OBJ_TO_PTR(native); - width = bmp->width; - height = bmp->height; - } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_bitmap_type)) { - displayio_bitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); - native = bitmap; - width = bmp->width; - height = bmp->height; - } else if (MP_OBJ_IS_TYPE(bitmap, &displayio_ondiskbitmap_type)) { - displayio_ondiskbitmap_t* bmp = MP_OBJ_TO_PTR(bitmap); - native = bitmap; - width = bmp->width; - height = bmp->height; - } else { - mp_raise_TypeError(translate("unsupported bitmap type")); - } - int16_t x = 0; - int16_t y = 0; - mp_obj_t position_obj = args[ARG_position].u_obj; - unpack_position(position_obj, &x, &y); - - displayio_sprite_t *self = m_new_obj(displayio_sprite_t); - self->base.type = &displayio_sprite_type; - common_hal_displayio_sprite_construct(self, native, args[ARG_pixel_shader].u_obj, - width, height, x, y); - return MP_OBJ_FROM_PTR(self); -} - -//| .. attribute:: position -//| -//| The position of the top-left corner of the sprite. -//| -STATIC mp_obj_t displayio_sprite_obj_get_position(mp_obj_t self_in) { - displayio_sprite_t *self = MP_OBJ_TO_PTR(self_in); - int16_t x; - int16_t y; - common_hal_displayio_sprite_get_position(self, &x, &y); - - mp_obj_t coords[2]; - coords[0] = mp_obj_new_int(x); - coords[1] = mp_obj_new_int(y); - - return mp_obj_new_tuple(2, coords); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_sprite_get_position_obj, displayio_sprite_obj_get_position); - -STATIC mp_obj_t displayio_sprite_obj_set_position(mp_obj_t self_in, mp_obj_t value) { - displayio_sprite_t *self = MP_OBJ_TO_PTR(self_in); - - int16_t x = 0; - int16_t y = 0; - unpack_position(value, &x, &y); - - common_hal_displayio_sprite_set_position(self, x, y); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_sprite_set_position_obj, displayio_sprite_obj_set_position); - -const mp_obj_property_t displayio_sprite_position_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&displayio_sprite_get_position_obj, - (mp_obj_t)&displayio_sprite_set_position_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: pixel_shader -//| -//| The pixel shader of the sprite. -//| -STATIC mp_obj_t displayio_sprite_obj_get_pixel_shader(mp_obj_t self_in) { - displayio_sprite_t *self = MP_OBJ_TO_PTR(self_in); - return common_hal_displayio_sprite_get_pixel_shader(self); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_sprite_get_pixel_shader_obj, displayio_sprite_obj_get_pixel_shader); - -STATIC mp_obj_t displayio_sprite_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { - displayio_sprite_t *self = MP_OBJ_TO_PTR(self_in); - if (!MP_OBJ_IS_TYPE(pixel_shader, &displayio_palette_type) && !MP_OBJ_IS_TYPE(pixel_shader, &displayio_colorconverter_type)) { - mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); - } - - common_hal_displayio_sprite_set_pixel_shader(self, pixel_shader); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_sprite_set_pixel_shader_obj, displayio_sprite_obj_set_pixel_shader); - -const mp_obj_property_t displayio_sprite_pixel_shader_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&displayio_sprite_get_pixel_shader_obj, - (mp_obj_t)&displayio_sprite_set_pixel_shader_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t displayio_sprite_locals_dict_table[] = { - // Properties - { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&displayio_sprite_position_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_sprite_pixel_shader_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(displayio_sprite_locals_dict, displayio_sprite_locals_dict_table); - -const mp_obj_type_t displayio_sprite_type = { - { &mp_type_type }, - .name = MP_QSTR_Sprite, - .make_new = displayio_sprite_make_new, - .locals_dict = (mp_obj_dict_t*)&displayio_sprite_locals_dict, -}; diff --git a/shared-bindings/displayio/Sprite.h b/shared-bindings/displayio/Sprite.h deleted file mode 100644 index 1944e1d74..000000000 --- a/shared-bindings/displayio/Sprite.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SPRITE_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SPRITE_H - -#include "shared-module/displayio/Sprite.h" - -extern const mp_obj_type_t displayio_sprite_type; - -void common_hal_displayio_sprite_construct(displayio_sprite_t *self, mp_obj_t bitmap, - mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t x, uint16_t y); - -void common_hal_displayio_sprite_get_position(displayio_sprite_t *self, int16_t* x, int16_t* y); -void common_hal_displayio_sprite_set_position(displayio_sprite_t *self, int16_t x, int16_t y); - -mp_obj_t common_hal_displayio_sprite_get_pixel_shader(displayio_sprite_t *self); -void common_hal_displayio_sprite_set_pixel_shader(displayio_sprite_t *self, mp_obj_t pixel_shader); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_SPRITE_H diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index a74fa4d39..2260db413 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -42,5 +42,6 @@ mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *se void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader); void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index); +void common_hal_displayio_textgrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 749f21803..e164d9b8f 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -96,7 +96,6 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, { MP_ROM_QSTR(MP_QSTR_Shape), MP_ROM_PTR(&displayio_shape_type) }, - { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index a2a60227d..ac1d0e933 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -178,8 +178,8 @@ void displayio_display_start_region_update(displayio_display_obj_t* self, uint16 data[1] = __builtin_bswap16(x1 - 1 + self->colstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->set_row_command, 1); - data[0] = __builtin_bswap16(y0 + 1 + self->rowstart); - data[1] = __builtin_bswap16(y1 + self->rowstart); + data[0] = __builtin_bswap16(y0 + self->rowstart); + data[1] = __builtin_bswap16(y1 - 1 + self->rowstart); self->send(self->bus, false, (uint8_t*) data, 4); self->send(self->bus, true, &self->write_ram_command, 1); } diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index bbbd83486..c31bfe841 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -40,9 +40,6 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer) mp_raise_RuntimeError(translate("Group full")); } mp_obj_t native_layer = mp_instance_cast_to_native_base(layer, &displayio_group_type); - if (native_layer == MP_OBJ_NULL) { - native_layer = mp_instance_cast_to_native_base(layer, &displayio_sprite_type); - } if (native_layer == MP_OBJ_NULL) { native_layer = mp_instance_cast_to_native_base(layer, &displayio_tilegrid_type); } @@ -85,10 +82,6 @@ bool displayio_group_get_pixel(displayio_group_t *self, int16_t x, int16_t y, ui if (displayio_tilegrid_get_pixel(layer, x, y, pixel)) { return true; } - } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { - if (displayio_sprite_get_pixel(layer, x, y, pixel)) { - return true; - } } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { if (displayio_group_get_pixel(layer, x, y, pixel)) { return true; @@ -113,10 +106,6 @@ bool displayio_group_needs_refresh(displayio_group_t *self) { if (displayio_group_needs_refresh(layer)) { return true; } - } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { - if (displayio_sprite_needs_refresh(layer)) { - return true; - } } } return false; @@ -130,8 +119,6 @@ void displayio_group_finish_refresh(displayio_group_t *self) { displayio_tilegrid_finish_refresh(layer); } else if (MP_OBJ_IS_TYPE(layer, &displayio_group_type)) { displayio_group_finish_refresh(layer); - } else if (MP_OBJ_IS_TYPE(layer, &displayio_sprite_type)) { - displayio_sprite_finish_refresh(layer); } } } diff --git a/shared-module/displayio/Sprite.c b/shared-module/displayio/Sprite.c deleted file mode 100644 index da6eff896..000000000 --- a/shared-module/displayio/Sprite.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft 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 "shared-bindings/displayio/Sprite.h" - -#include "shared-bindings/displayio/Bitmap.h" -#include "shared-bindings/displayio/ColorConverter.h" -#include "shared-bindings/displayio/OnDiskBitmap.h" -#include "shared-bindings/displayio/Palette.h" -#include "shared-bindings/displayio/Shape.h" - -void common_hal_displayio_sprite_construct(displayio_sprite_t *self, mp_obj_t bitmap, - mp_obj_t pixel_shader, uint16_t width, uint16_t height, uint16_t x, uint16_t y) { - self->width = width; - self->height = height; - self->bitmap = bitmap; - self->pixel_shader = pixel_shader; - self->x = x; - self->y = y; -} - -void common_hal_displayio_sprite_get_position(displayio_sprite_t *self, int16_t* x, int16_t* y) { - *x = self->x; - *y = self->y; -} - -void common_hal_displayio_sprite_set_position(displayio_sprite_t *self, int16_t x, int16_t y) { - self->x = x; - self->y = y; - self->needs_refresh = true; -} - - -mp_obj_t common_hal_displayio_sprite_get_pixel_shader(displayio_sprite_t *self) { - return self->pixel_shader; -} - -void common_hal_displayio_sprite_set_pixel_shader(displayio_sprite_t *self, mp_obj_t pixel_shader) { - self->pixel_shader = pixel_shader; - self->needs_refresh = true; -} - -bool displayio_sprite_get_pixel(displayio_sprite_t *self, int16_t x, int16_t y, uint16_t* pixel) { - x -= self->x; - y -= self->y; - if (y < 0 || y >= self->height || x >= self->width || x < 0) { - return false; - } - uint32_t value = 0; - if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_bitmap_type)) { - value = common_hal_displayio_bitmap_get_pixel(self->bitmap, x, y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_shape_type)) { - value = common_hal_displayio_shape_get_pixel(self->bitmap, x, y); - } else if (MP_OBJ_IS_TYPE(self->bitmap, &displayio_ondiskbitmap_type)) { - value = common_hal_displayio_ondiskbitmap_get_pixel(self->bitmap, x, y); - } - - if (self->pixel_shader == mp_const_none) { - *pixel = value; - return true; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_palette_type) && displayio_palette_get_color(self->pixel_shader, value, pixel)) { - return true; - } else if (MP_OBJ_IS_TYPE(self->pixel_shader, &displayio_colorconverter_type) && common_hal_displayio_colorconverter_convert(self->pixel_shader, value, pixel)) { - return true; - } - - return false; -} - -bool displayio_sprite_needs_refresh(displayio_sprite_t *self) { - return self->needs_refresh || displayio_palette_needs_refresh(self->pixel_shader); -} - -void displayio_sprite_finish_refresh(displayio_sprite_t *self) { - self->needs_refresh = false; - displayio_palette_finish_refresh(self->pixel_shader); - // TODO(tannewt): We could double buffer changes to position and move them over here. - // That way they won't change during a refresh and tear. -} diff --git a/shared-module/displayio/Sprite.h b/shared-module/displayio/Sprite.h deleted file mode 100644 index dc368c4b7..000000000 --- a/shared-module/displayio/Sprite.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft 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. - */ - -#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H -#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H - -#include -#include - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - mp_obj_t bitmap; - mp_obj_t pixel_shader; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; - bool needs_refresh; -} displayio_sprite_t; - -bool displayio_sprite_get_pixel(displayio_sprite_t *sprite, int16_t x, int16_t y, uint16_t *pixel); -bool displayio_sprite_needs_refresh(displayio_sprite_t *self); -void displayio_sprite_finish_refresh(displayio_sprite_t *self); - -#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_SPRITE_H diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index ed724bf10..b90603afe 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -92,7 +92,7 @@ bool displayio_tilegrid_get_pixel(displayio_tilegrid_t *self, int16_t x, int16_t if (tiles == NULL) { return false; } - uint16_t tile_location = (y / self->tile_height) * self->width_in_tiles + x / self->tile_width; + uint16_t tile_location = ((y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (x / self->tile_width + self->top_left_x) % self->width_in_tiles; uint8_t tile = tiles[tile_location]; uint16_t tile_x = tile_x = (tile % self->bitmap_width_in_tiles) * self->tile_width + x % self->tile_width; uint16_t tile_y = tile_y = (tile / self->bitmap_width_in_tiles) * self->tile_height + y % self->tile_height; @@ -130,6 +130,12 @@ void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t self->needs_refresh = true; } + +void common_hal_displayio_textgrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { + self->top_left_x = x; + self->top_left_y = y; +} + bool displayio_tilegrid_needs_refresh(displayio_tilegrid_t *self) { return self->needs_refresh || displayio_palette_needs_refresh(self->pixel_shader); } diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index 84e3e7ef2..59645553d 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -45,6 +45,8 @@ typedef struct { uint16_t total_height; uint16_t tile_width; uint16_t tile_height; + uint16_t top_left_x; + uint16_t top_left_y; uint8_t* tiles; bool needs_refresh; bool inline_tiles; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 8e4904954..38349e9a3 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -91,6 +91,7 @@ void common_hal_displayio_release_displays(void) { } void reset_displays(void) { + #if CIRCUITPY_DISPLAYIO // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) { @@ -122,4 +123,5 @@ void reset_displays(void) { display->auto_brightness = true; common_hal_displayio_display_show(display, &circuitpython_splash); } + #endif } diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index 444bf53ad..6734fa30e 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -26,9 +26,10 @@ #include "shared-module/terminalio/Terminal.h" +#include "shared-module/displayio/__init__.h" #include "shared-bindings/displayio/TileGrid.h" -void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, uint16_t unicode_characters_len) { +void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, displayio_tilegrid_t* tilegrid, const uint8_t* unicode_characters, size_t unicode_characters_len) { self->cursor_x = 0; self->cursor_y = 0; self->tilegrid = tilegrid; @@ -115,6 +116,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con common_hal_displayio_textgrid_set_tile(self->tilegrid, j, self->cursor_y, 0); start_y = self->cursor_y; } + common_hal_displayio_textgrid_set_top_left(self->tilegrid, 0, (start_y + self->tilegrid->height_in_tiles + 1) % self->tilegrid->height_in_tiles); } } return i - data; diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 18693266f..bef9247c0 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -87,6 +87,7 @@ void supervisor_stop_terminal(void) { } void supervisor_display_move_memory(void) { + #if CIRCUITPY_DISPLAYIO displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; if (MP_STATE_VM(terminal_tilegrid_tiles) == NULL || grid->tiles != MP_STATE_VM(terminal_tilegrid_tiles)) { return; @@ -102,6 +103,7 @@ void supervisor_display_move_memory(void) { grid->inline_tiles = false; } MP_STATE_VM(terminal_tilegrid_tiles) = NULL; + #endif } uint32_t blinka_bitmap_data[32] = { @@ -149,15 +151,24 @@ displayio_palette_t blinka_palette = { .needs_refresh = false }; -displayio_sprite_t blinka_sprite = { - .base = {.type = &displayio_sprite_type }, +displayio_tilegrid_t blinka_sprite = { + .base = {.type = &displayio_tilegrid_type }, .bitmap = &blinka_bitmap, .pixel_shader = &blinka_palette, .x = 0, .y = 0, - .width = 16, - .height = 16, - .needs_refresh = false + .bitmap_width_in_tiles = 1, + .width_in_tiles = 1, + .height_in_tiles = 1, + .total_width = 16, + .total_height = 16, + .tile_width = 16, + .tile_height = 16, + .top_left_x = 16, + .top_left_y = 16, + .tiles = 0, + .needs_refresh = false, + .inline_tiles = true }; mp_obj_t splash_children[2] = { diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index ac5239a84..ed210416f 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -26,6 +26,8 @@ #include +#include "py/mpconfig.h" + #include "supervisor/shared/display.h" #include "shared-bindings/terminalio/Terminal.h" #include "supervisor/serial.h" @@ -50,8 +52,10 @@ bool serial_bytes_available(void) { } void serial_write_substring(const char* text, uint32_t length) { + #if CIRCUITPY_DISPLAYIO int errcode; common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode); + #endif if (!tud_cdc_connected()) { return; } -- cgit v1.2.3 From 4672866eecebffed383b7882db13c71d3495d846 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 29 Jan 2019 15:40:20 -0800 Subject: Remove Sprite references --- shared-bindings/displayio/__init__.c | 1 - shared-module/displayio/Group.c | 1 - shared-module/displayio/__init__.c | 1 - supervisor/shared/display.c | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index e164d9b8f..86cb9c6b0 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -39,7 +39,6 @@ #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/displayio/Shape.h" -#include "shared-bindings/displayio/Sprite.h" #include "shared-bindings/displayio/TileGrid.h" //| :mod:`displayio` --- Native display driving diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index c31bfe841..95043e4f3 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -27,7 +27,6 @@ #include "shared-bindings/displayio/Group.h" #include "py/runtime.h" -#include "shared-bindings/displayio/Sprite.h" #include "shared-bindings/displayio/TileGrid.h" void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size) { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 38349e9a3..32fe6ac5e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -7,7 +7,6 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" -#include "shared-bindings/displayio/Sprite.h" #include "supervisor/shared/display.h" #include "supervisor/memory.h" #include "supervisor/usb.h" diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index bef9247c0..4da44eb3b 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -31,7 +31,7 @@ #include "py/mpstate.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" -#include "shared-bindings/displayio/Sprite.h" +#include "shared-bindings/displayio/TileGrid.h" #include "supervisor/memory.h" extern uint32_t blinka_bitmap_data[]; -- cgit v1.2.3 From ec0388704095a7d3ab0cda65509db2fa0ef589dc Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 29 Jan 2019 17:10:17 -0800 Subject: Fix hallowing and nrf builds --- .../boards/hallowing_m0_express/mpconfigboard.mk | 1 - ports/nrf/Makefile | 6 ++- ports/nrf/common-hal/pulseio/PWMOut.c | 40 +++++++++++--- ports/nrf/mpconfigport.h | 1 + shared-bindings/displayio/FourWire.c | 12 ----- shared-bindings/displayio/ParallelBus.c | 12 ----- supervisor/shared/display.c | 2 +- supervisor/supervisor.mk | 3 +- tools/gen_display_resources.py | 62 ++++++++++++---------- 9 files changed, 74 insertions(+), 65 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk index fea4bc222..00e2dfa0d 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk @@ -17,6 +17,5 @@ CHIP_FAMILY = samd21 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 2f762e2a3..a75d45f1f 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -226,8 +226,10 @@ SRC_SHARED_MODULE = \ displayio/OnDiskBitmap.c \ displayio/Palette.c \ displayio/Shape.c \ - displayio/Sprite.c \ - storage/__init__.c + displayio/TileGrid.c \ + storage/__init__.c \ + terminalio/__init__.c \ + terminalio/Terminal.c ifndef EXCLUDE_PIXELBUF diff --git a/ports/nrf/common-hal/pulseio/PWMOut.c b/ports/nrf/common-hal/pulseio/PWMOut.c index f321f848d..cf2330934 100644 --- a/ports/nrf/common-hal/pulseio/PWMOut.c +++ b/ports/nrf/common-hal/pulseio/PWMOut.c @@ -55,8 +55,33 @@ STATIC NRF_PWM_Type* pwms[] = { STATIC uint16_t pwm_seq[MP_ARRAY_SIZE(pwms)][CHANNELS_PER_PWM]; +static uint8_t never_reset_pwm[MP_ARRAY_SIZE(pwms)]; + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + for(int i=0; i < MP_ARRAY_SIZE(pwms); i++) { + NRF_PWM_Type* pwm = pwms[i]; + if (pwm == self->pwm) { + never_reset_pwm[i] += 1; + } + } + + never_reset_pin_number(self->pin_number); +} + +void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { + for(int i=0; i < MP_ARRAY_SIZE(pwms); i++) { + NRF_PWM_Type* pwm = pwms[i]; + if (pwm == self->pwm) { + never_reset_pwm[i] -= 1; + } + } +} + void pwmout_reset(void) { for(int i=0; i < MP_ARRAY_SIZE(pwms); i++) { + if (never_reset_pwm[i] > 0) { + continue; + } NRF_PWM_Type* pwm = pwms[i]; pwm->ENABLE = 0; @@ -104,11 +129,11 @@ bool convert_frequency(uint32_t frequency, uint16_t *countertop, nrf_pwm_clk_t * return false; } -void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, - uint16_t duty, - uint32_t frequency, - bool variable_frequency) { +pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { // We don't use the nrfx driver here because we want to dynamically allocate channels // as needed in an already-enabled PWM. @@ -116,7 +141,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, uint16_t countertop; nrf_pwm_clk_t base_clock; if (frequency == 0 || !convert_frequency(frequency, &countertop, &base_clock)) { - mp_raise_ValueError(translate("Invalid PWM frequency")); + return PWMOUT_INVALID_FREQUENCY; } self->pwm = NULL; @@ -158,7 +183,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, } if (self->pwm == NULL) { - mp_raise_ValueError(translate("All PWM peripherals are in use")); + return PWMOUT_ALL_TIMERS_IN_USE; } self->pin_number = pin->number; @@ -183,6 +208,7 @@ void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, nrf_pwm_enable(pwm); common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return PWMOUT_OK; } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index f63265129..e97c13d81 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -229,6 +229,7 @@ extern const struct _mp_obj_module_t touchio_module; #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ mp_obj_t gamepad_singleton; \ + mp_obj_t terminal_tilegrid_tiles; \ FLASH_ROOT_POINTERS \ // We need to provide a declaration/definition of alloca() diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index dceb4fe69..eab3bd57a 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -98,19 +98,7 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ return self; } - -//| .. method:: send(command, data) -//| -//| -STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 1, displayio_fourwire_obj_send); - STATIC const mp_rom_map_elem_t displayio_fourwire_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_fourwire_send_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 916c5f852..1ce1e2aff 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -102,19 +102,7 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t return self; } - -//| .. method:: send(command, data) -//| -//| -STATIC mp_obj_t displayio_parallelbus_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_raise_NotImplementedError(translate("displayio is a work in progress")); - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(displayio_parallelbus_send_obj, 1, displayio_parallelbus_obj_send); - STATIC const mp_rom_map_elem_t displayio_parallelbus_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_parallelbus_send_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_parallelbus_locals_dict, displayio_parallelbus_locals_dict_table); diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 4da44eb3b..3a430f568 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -94,7 +94,7 @@ void supervisor_display_move_memory(void) { } uint16_t total_tiles = grid->width_in_tiles * grid->height_in_tiles; - tilegrid_tiles = allocate_memory(total_tiles, false); + tilegrid_tiles = allocate_memory(align32_size(total_tiles), false); if (tilegrid_tiles != NULL) { memcpy(tilegrid_tiles->ptr, grid->tiles, total_tiles); grid->tiles = (uint8_t*) tilegrid_tiles->ptr; diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 0e315a742..f21365d2a 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -92,11 +92,12 @@ autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile --output_c_file $(BUILD)/autogen_usb_descriptor.c\ --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h -CIRCUITPY_DISPLAY_FONT = "../../tools/Tecate-bitmap-fonts/bitmap/cherry/cherry-10-r.bdf" +CIRCUITPY_DISPLAY_FONT = "../../tools/Tecate-bitmap-fonts/bitmap/terminus-font-4.39/ter-u12n.bdf" $(BUILD)/autogen_display_resources.c: ../../tools/gen_display_resources.py $(HEADER_BUILD)/qstrdefs.generated.h Makefile | $(HEADER_BUILD) $(STEPECHO) "GEN $@" $(Q)install -d $(BUILD)/genhdr $(Q)$(PYTHON3) ../../tools/gen_display_resources.py \ --font $(CIRCUITPY_DISPLAY_FONT) \ + --sample_file $(HEADER_BUILD)/qstrdefs.generated.h \ --output_c_file $(BUILD)/autogen_display_resources.c diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index 27ea2a471..e0021650d 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -11,7 +11,11 @@ from adafruit_bitmap_font import bitmap_font parser = argparse.ArgumentParser(description='Generate USB descriptors.') parser.add_argument('--font', type=str, - help='manufacturer of the device', required=True) + help='Font path', required=True) +parser.add_argument('--extra_characters', type=str, + help='Unicode string of extra characters') +parser.add_argument('--sample_file', type=argparse.FileType('r'), + help='Text file that includes strings to support.') parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True) args = parser.parse_args() @@ -25,32 +29,44 @@ class BitmapStub: self.rows[y] = bytes(row) f = bitmap_font.load_font(args.font, BitmapStub) -f.load_glyphs(range(0x20, 0x7f)) - -print(f.get_bounding_box()) real_bb = [0, 0] +# Load extra characters from the sample file. +sample_characters = set() +if args.sample_file: + for line in args.sample_file: + # Skip comments because we add additional characters in our huffman comments. + if line.startswith("//"): + continue + for c in line.strip(): + sample_characters.add(c) + +# Merge visible ascii, sample characters and extra characters. visible_ascii = bytes(range(0x20, 0x7f)).decode("utf-8") -extra_characters = "üàêùéáçãÍóíαψ◌" -all_characters = visible_ascii + extra_characters +all_characters = visible_ascii +for c in sample_characters: + if c not in all_characters: + all_characters += c +if args.extra_characters: + all_characters.extend(args.extra_characters) filtered_characters = all_characters + +# Try to pre-load all of the glyphs. Misses will still be slow later. +f.load_glyphs(set(all_characters)) + +# Get each glyph. for c in all_characters: g = f.get_glyph(ord(c)) if not g: print("Font missing character:", c, ord(c)) filtered_characters = filtered_characters.replace(c, "") - extra_characters = extra_characters.replace(c, "") continue x, y, dx, dy = g["bounds"] - #print(c, g["bounds"], g["shift"]) if g["shift"][1] != 0: raise RuntimeError("y shift") real_bb[0] = max(real_bb[0], x - dx) real_bb[1] = max(real_bb[1], y - dy) -#real_bb[1] += 1 -#print(real_bb) - tile_x, tile_y = real_bb total_bits = tile_x * len(all_characters) total_bits += 32 - total_bits % 32 @@ -61,7 +77,6 @@ for x, c in enumerate(filtered_characters): g = f.get_glyph(ord(c)) start_bit = x * tile_x + g["bounds"][2] start_y = (tile_y - 2) - (g["bounds"][1] + g["bounds"][3]) - # print(c, g["bounds"], g["shift"], tile_y, start_y) for y, row in enumerate(g["bitmap"].rows): for i in range(g["bounds"][0]): byte = i // 8 @@ -69,23 +84,12 @@ for x, c in enumerate(filtered_characters): if row[byte] & (1 << (7-bit)) != 0: overall_bit = start_bit + (start_y + y) * bytes_per_row * 8 + i b[overall_bit // 8] |= 1 << (7 - (overall_bit % 8)) - # print("*",end="") - # else: - # print("_",end="") - #print() - -# print(b) -# print("tile_x = {}".format(tile_x)) -# print("tile_y = {}".format(tile_y)) -# print("tiles = {}".format(len(all_characters))) -# print("font = displayio.Bitmap(tile_x * tiles, tile_y, 2)") -# for row in range(tile_y): -# print("font._load_row({}, {})".format(row, bytes(b[row*bytes_per_row:row*bytes_per_row+bytes_per_row]))) - -# for row in range(tile_y): -# for byte in b[row*bytes_per_row:row*bytes_per_row+bytes_per_row]: -# print("{:08b} ".format(byte),end="") -# print() + + +extra_characters = "" +for c in filtered_characters: + if c not in visible_ascii: + extra_characters += c c_file = args.output_c_file -- cgit v1.2.3 From 73bc614a4b03fda2e65b83090c02ffe451619dbe Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 09:38:08 -0800 Subject: Remove doc reference to Sprite --- shared-bindings/displayio/__init__.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 86cb9c6b0..df7162cf1 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -67,7 +67,6 @@ //| Palette //| ParallelBus //| Shape -//| Sprite //| TileGrid //| //| All libraries change hardware state but are never deinit -- cgit v1.2.3 From 2c069a5685c9e5bf6b1a081d5566357139c4dff3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 10:29:29 -0800 Subject: Polish up comments --- shared-bindings/displayio/Display.c | 3 ++- shared-bindings/terminalio/Terminal.c | 4 ++-- shared-bindings/terminalio/__init__.c | 8 ++++---- shared-bindings/terminalio/__init__.h | 12 +++++------- shared-module/displayio/__init__.c | 1 - 5 files changed, 13 insertions(+), 15 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index e59905258..0d056bc3b 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -134,7 +134,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a //| .. method:: show(group) //| -//| Switches to displaying the given group of layers. +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. //| STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index f460f4abd..67c7ead57 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -39,8 +39,8 @@ //| .. currentmodule:: terminalio //| -//| :class:`Terminal` -- manage a -//| ============================================================== +//| :class:`Terminal` -- display a character stream with a TileGrid +//| ================================================================ //| //| .. class:: Terminal(tilegrid, *, unicode_characters="") //| diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c index 1031124dc..482cb78e6 100644 --- a/shared-bindings/terminalio/__init__.c +++ b/shared-bindings/terminalio/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Scott Shawcroft 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 @@ -34,13 +34,13 @@ #include "py/runtime.h" -//| :mod:`terminalio` --- MIDI over USB +//| :mod:`terminalio` --- Displays text in a TileGrid //| ================================================= //| //| .. module:: terminalio -//| :synopsis: MIDI over USB +//| :synopsis: Displays text in a TileGrid //| -//| The `terminalio` module contains classes to transmit and receive MIDI messages over USB +//| The `terminalio` module contains classes to display a character stream on a display //| //| Libraries //| diff --git a/shared-bindings/terminalio/__init__.h b/shared-bindings/terminalio/__init__.h index e81818e04..4be14dfc6 100644 --- a/shared-bindings/terminalio/__init__.h +++ b/shared-bindings/terminalio/__init__.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft + * Copyright (c) 2019 Scott Shawcroft * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,11 +24,9 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H -#include "py/obj.h" +// Nothing now. -extern mp_obj_dict_t usb_midi_module_globals; - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_TERMINALIO___INIT___H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 32fe6ac5e..f09e4e791 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -2,7 +2,6 @@ #include #include "shared-module/displayio/__init__.h" - #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/Group.h" -- cgit v1.2.3 From 354a26963b9df6dcf281e49954483f147a6394a8 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 11:00:12 -0800 Subject: Correctly handle no backlight pin. --- shared-bindings/displayio/Display.c | 11 ++++++++--- shared-module/displayio/Display.c | 2 ++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 0d056bc3b..109df8af4 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -109,8 +109,13 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - mp_obj_t backlight_pin = args[ARG_backlight_pin].u_obj; - assert_pin_free(backlight_pin); + mp_obj_t backlight_pin_obj = args[ARG_backlight_pin].u_obj; + assert_pin(backlight_pin_obj, true); + const mcu_pin_obj_t* backlight_pin = NULL; + if (backlight_pin_obj != NULL && backlight_pin_obj != mp_const_none) { + backlight_pin = MP_OBJ_TO_PTR(backlight_pin_obj); + assert_pin_free(backlight_pin); + } displayio_display_obj_t *self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { @@ -127,7 +132,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a common_hal_displayio_display_construct(self, display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, - args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, backlight_pin); + args[ARG_write_ram_command].u_int, bufinfo.buf, bufinfo.len, MP_OBJ_TO_PTR(backlight_pin)); return self; } diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index ac1d0e933..ef0334d10 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -100,6 +100,8 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->refresh = true; self->current_group = &circuitpython_splash; + // Always set the backlight type in case we're reusing memory. + self->backlight_inout.base.type = &mp_type_NoneType; if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 5000, false); if (result != PWMOUT_OK) { -- cgit v1.2.3 From d72cd5b2d6cbc95665c41a43d6d914e71ac58017 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 31 Jan 2019 11:41:45 -0800 Subject: Correct TileGrid class name. --- shared-bindings/displayio/TileGrid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-bindings/displayio') diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 0026cd62f..d0be43fbf 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -220,7 +220,7 @@ STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_l const mp_obj_type_t displayio_tilegrid_type = { { &mp_type_type }, - .name = MP_QSTR_Sprite, + .name = MP_QSTR_TileGrid, .make_new = displayio_tilegrid_make_new, .locals_dict = (mp_obj_dict_t*)&displayio_tilegrid_locals_dict, }; -- cgit v1.2.3