diff options
| author | Dan Halbert <halbert@halwitz.org> | 2019-01-20 21:47:13 -0500 |
|---|---|---|
| committer | Dan Halbert <halbert@halwitz.org> | 2019-01-20 21:47:13 -0500 |
| commit | a8f4aa4796aaba964b17932f0ae9299d18db1649 (patch) | |
| tree | fea7576c8221fc5519ba86c8a97ddb601477cce3 /shared-bindings | |
| parent | 7a09af73ec7f4a11a1404dff6276e09072d06983 (diff) | |
| parent | 6b88d0f94eb1459562d0f159688b504a6f5d408f (diff) | |
Merge remote-tracking branch 'adafruit/master' into struct-compat
Diffstat (limited to 'shared-bindings')
| -rw-r--r-- | shared-bindings/displayio/Display.c | 181 | ||||
| -rw-r--r-- | shared-bindings/displayio/Display.h | 59 | ||||
| -rw-r--r-- | shared-bindings/displayio/FourWire.c | 93 | ||||
| -rw-r--r-- | shared-bindings/displayio/FourWire.h | 31 | ||||
| -rw-r--r-- | shared-bindings/displayio/ParallelBus.c | 126 | ||||
| -rw-r--r-- | shared-bindings/displayio/ParallelBus.h | 49 | ||||
| -rw-r--r-- | shared-bindings/displayio/__init__.c | 28 | ||||
| -rw-r--r-- | shared-bindings/displayio/__init__.h | 4 |
8 files changed, 493 insertions, 78 deletions
diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c new file mode 100644 index 000000000..d61732f6f --- /dev/null +++ b/shared-bindings/displayio/Display.c @@ -0,0 +1,181 @@ +/* + * 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/Display.h" + +#include <stdint.h> + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`Display` -- Manage updating a display over a display bus +//| ========================================================================== +//| +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c) +//| +//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`). +//| +//| The ``init_sequence`` is bitbacked to minimize the ram impact. Every command begins with a +//| command byte followed by a byte to determine the parameter count and if a delay is need after. +//| When the top bit of the second byte is 1, the next byte will be the delay time in milliseconds. +//| The remaining 7 bits are the parameter count excluding any delay byte. The third through final +//| bytes are the remaining command parameters. The next byte will begin a new command definition. +//| Here is a portion of ILI9341 init code: +//| +//| .. code-block:: python +//| +//| init_sequence = (b"\xe1\x0f\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F" # Set Gamma +//| b"\x11\x80\x78"# Exit Sleep then delay 0x78 (120ms) +//| b"\x29\x80\x78"# Display on then delay 0x78 (120ms) +//| ) +//| display = displayio.Display(display_bus, init_sequence, width=320, height=240) +//| +//| The first command is 0xe1 with 15 (0xf) parameters following. The second and third are 0x11 and +//| 0x29 respectively with delays (0x80) of 120ms (0x78) and no parameters. Multiple byte literals +//| (b"") are merged together on load. The parens are needed to allow byte literals on subsequent +//| lines. +//| +//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to +//| :param buffer init_sequence: Byte-packed initialization sequence. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :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 +//| +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 }; + 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 }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { 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_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 display_bus = args[ARG_display_bus].u_obj; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + displayio_display_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL || + displays[i].display.base.type == &mp_type_NoneType) { + self = &displays[i].display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many displays")); + } + self->base.type = &displayio_display_type; + 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); + + return self; +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. +//| +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 = MP_OBJ_TO_PTR(native_layer); + common_hal_displayio_display_show(self, group); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); + +//| .. method:: refresh_soon() +//| +//| Queues up a display refresh that happens in the background. +//| +STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_displayio_display_refresh_soon(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_refresh_soon_obj, displayio_display_obj_refresh_soon); + +//| .. method:: wait_for_frame() +//| +//| Waits until the next frame has been transmitted to the display unless the wait count is +//| behind the rendered frames. In that case, this will return immediately with the wait count. +//| +STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) { + displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame); + + +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) }, +}; +STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table); + +const mp_obj_type_t displayio_display_type = { + { &mp_type_type }, + .name = MP_QSTR_Display, + .make_new = displayio_display_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_display_locals_dict, +}; diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h new file mode 100644 index 000000000..4cec66058 --- /dev/null +++ b/shared-bindings/displayio/Display.h @@ -0,0 +1,59 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 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_DISPLAYBUSIO_DISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Display.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_display_type; + +#define DELAY 0x80 + +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); + +int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self); + +void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group); + +void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self); + +void displayio_display_start_region_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); +void displayio_display_finish_region_update(displayio_display_obj_t* self); +bool displayio_display_frame_queued(displayio_display_obj_t* self); + +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); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_DISPLAY_H diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 80aa814df..dceb4fe69 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2018-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 @@ -35,6 +35,7 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" #include "supervisor/shared/translate.h" //| .. currentmodule:: displayio @@ -47,14 +48,54 @@ //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| -//| .. class:: FourWire(*, clock, data, command, chip_select, width, height, colstart, rowstart, -//| color_depth, set_column_command, set_row_command, write_ram_command) +//| .. class:: FourWire(spi_bus, *, command, chip_select, reset) //| //| Create a FourWire object associated with the given pins. //| +//| :param busio.SPI spi_bus: The SPI bus that make up the clock and data lines +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin reset: Reset pin +//| STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, 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; + enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_reset, 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 command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + assert_pin_free(command); + assert_pin_free(chip_select); + mp_obj_t reset = args[ARG_reset].u_obj; + if (reset != mp_const_none) { + assert_pin_free(reset); + } else { + reset = NULL; + } + + displayio_fourwire_obj_t* self = NULL; + mp_obj_t spi = args[ARG_spi_bus].u_obj; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type == NULL || + displays[i].fourwire_bus.base.type == &mp_type_NoneType) { + self = &displays[i].fourwire_bus; + self->base.type = &displayio_fourwire_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many display busses")); + } + + common_hal_displayio_fourwire_construct(self, + MP_OBJ_TO_PTR(spi), command, chip_select, reset); + return self; } @@ -68,50 +109,8 @@ STATIC mp_obj_t displayio_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(displayio_fourwire_send_obj, 1, displayio_fourwire_obj_send); -//| .. method:: show(group) -//| -//| Switches do displaying the given group of elements. -//| -STATIC mp_obj_t displayio_fourwire_obj_show(mp_obj_t self_in, mp_obj_t group_in) { - displayio_fourwire_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 = MP_OBJ_TO_PTR(native_layer); - common_hal_displayio_fourwire_show(self, group); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(displayio_fourwire_show_obj, displayio_fourwire_obj_show); - -//| .. method:: refresh_soon() -//| -//| Queues up a display refresh that happens in the background. -//| -STATIC mp_obj_t displayio_fourwire_obj_refresh_soon(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_displayio_fourwire_refresh_soon(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_refresh_soon_obj, displayio_fourwire_obj_refresh_soon); - -//| .. method:: wait_for_frame() -//| -//| Waits until the next frame has been transmitted to the display unless the wait count is -//| behind the rendered frames. In that case, this will return immediately with the wait count. -//| -STATIC mp_obj_t displayio_fourwire_obj_wait_for_frame(mp_obj_t self_in) { - displayio_fourwire_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_fourwire_wait_for_frame(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(displayio_fourwire_wait_for_frame_obj, displayio_fourwire_obj_wait_for_frame); - - 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) }, - { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_fourwire_show_obj) }, - { MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_fourwire_refresh_soon_obj) }, - { MP_ROM_QSTR(MP_QSTR_wait_for_frame), MP_ROM_PTR(&displayio_fourwire_wait_for_frame_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_fourwire_locals_dict, displayio_fourwire_locals_dict_table); diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index fc51f558d..b8b00372c 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -27,39 +27,24 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H -#include "common-hal/displayio/FourWire.h" +#include "shared-module/displayio/FourWire.h" #include "common-hal/microcontroller/Pin.h" #include "shared-module/displayio/Group.h" +#include "supervisor/shared/board_busses.h" extern const mp_obj_type_t displayio_fourwire_type; -// TODO(tannewt): Split this apart into FourWire and a Display object because the dimensions and -// commands are also used for the parallel buses. void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, - const mcu_pin_obj_t* clock, const mcu_pin_obj_t* data, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, 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); + busio_spi_obj_t* spi, const mcu_pin_obj_t* command, + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); -int32_t common_hal_displayio_fourwire_wait_for_frame(displayio_fourwire_obj_t* self); +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); -bool common_hal_displayio_fourwire_begin_transaction(displayio_fourwire_obj_t* self); +bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); -void common_hal_displayio_fourwire_send(displayio_fourwire_obj_t* self, bool command, uint8_t *data, uint32_t data_length); +void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); -void common_hal_displayio_fourwire_end_transaction(displayio_fourwire_obj_t* self); - -void common_hal_displayio_fourwire_show(displayio_fourwire_obj_t* self, displayio_group_t* root_group); - -void common_hal_displayio_fourwire_refresh_soon(displayio_fourwire_obj_t* self); - -void displayio_fourwire_start_region_update(displayio_fourwire_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); -void displayio_fourwire_finish_region_update(displayio_fourwire_obj_t* self); -bool displayio_fourwire_frame_queued(displayio_fourwire_obj_t* self); - -bool displayio_fourwire_refresh_queued(displayio_fourwire_obj_t* self); -void displayio_fourwire_finish_refresh(displayio_fourwire_obj_t* self); -bool displayio_fourwire_send_pixels(displayio_fourwire_obj_t* self, uint32_t* pixels, uint32_t length); +void common_hal_displayio_fourwire_end_transaction(mp_obj_t self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_FOURWIRE_H diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c new file mode 100644 index 000000000..916c5f852 --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.c @@ -0,0 +1,126 @@ +/* + * 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. + */ + +#include "shared-bindings/displayio/ParallelBus.h" + +#include <stdint.h> + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: displayio +//| +//| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol +//| ============================================================================== +//| +//| Manage updating a display over SPI four wire protocol in the background while Python code runs. +//| It doesn't handle display initialization. +//| +//| .. warning:: This will be changed before 4.0.0. Consider it very experimental. +//| +//| .. class:: ParallelBus(*, data0, command, chip_select, write, read, reset) +//| +//| Create a ParallelBus object associated with the given pins. The bus is inferred from data0 +//| by implying the next 7 additional pins on a given GPIO port. +//| +//| :param microcontroller.Pin: The first data pin. The rest are implied +//| :param microcontroller.Pin command: Data or command pin +//| :param microcontroller.Pin chip_select: Chip select pin +//| :param microcontroller.Pin write: Write pin +//| :param microcontroller.Pin read: Read pin +//| :param microcontroller.Pin reset: Reset pin +//| +STATIC mp_obj_t displayio_parallelbus_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_data0, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data0, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_write, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_read, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_reset, 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 data0 = args[ARG_data0].u_obj; + mp_obj_t command = args[ARG_command].u_obj; + mp_obj_t chip_select = args[ARG_chip_select].u_obj; + mp_obj_t write = args[ARG_write].u_obj; + mp_obj_t read = args[ARG_read].u_obj; + mp_obj_t reset = args[ARG_reset].u_obj; + assert_pin_free(data0); + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(write); + assert_pin_free(read); + assert_pin_free(reset); + + displayio_parallelbus_obj_t* self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].parallel_bus.base.type== NULL || + displays[i].parallel_bus.base.type == &mp_type_NoneType) { + self = &displays[i].parallel_bus; + self->base.type = &displayio_parallelbus_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Too many display busses")); + } + + common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); + 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); + +const mp_obj_type_t displayio_parallelbus_type = { + { &mp_type_type }, + .name = MP_QSTR_ParallelBus, + .make_new = displayio_parallelbus_make_new, + .locals_dict = (mp_obj_dict_t*)&displayio_parallelbus_locals_dict, +}; diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h new file mode 100644 index 000000000..c4cde5ff5 --- /dev/null +++ b/shared-bindings/displayio/ParallelBus.h @@ -0,0 +1,49 @@ +/* + * 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_DISPLAYBUSIO_PARALLELBUS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H + +#include "common-hal/displayio/ParallelBus.h" +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t displayio_parallelbus_type; + +void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* self, + const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, + const mcu_pin_obj_t* write, const mcu_pin_obj_t* read, const mcu_pin_obj_t* reset); + +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); + +bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); + +void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); + +void common_hal_displayio_parallelbus_end_transaction(mp_obj_t self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_PARALLELBUS_H diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index d485d8095..6ed1218b2 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -32,10 +32,12 @@ #include "shared-bindings/displayio/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ParallelBus.h" #include "shared-bindings/displayio/Shape.h" #include "shared-bindings/displayio/Sprite.h" @@ -44,13 +46,10 @@ //| //| .. module:: displayio //| :synopsis: Native helpers for driving displays -//| :platform: SAMD21, SAMD51 +//| :platform: SAMD21, SAMD51, nRF52 //| //| The `displayio` module contains classes to manage display output -//| including synchronizing with refresh rates and partial updating. It does -//| not include display initialization commands. It should live in a Python -//| driver for use when a display is connected to a board. It should also be -//| built into the board init when the board has the display on it. +//| including synchronizing with refresh rates and partial updating. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| @@ -61,20 +60,36 @@ //| //| Bitmap //| ColorConverter +//| Display //| FourWire //| Group //| OnDiskBitmap //| Palette +//| ParallelBus //| Shape //| Sprite //| //| All libraries change hardware state but are never deinit //| + +//| .. method:: release_displays() +//| +//| Releases any actively used displays so their busses and pins can be used again. This will also +//| release the builtin display on boards that have one. You will need to reinitialize it yourself +//| afterwards. +//| +STATIC mp_obj_t displayio_release_displays(void) { + common_hal_displayio_release_displays(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays); + STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, @@ -82,6 +97,9 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_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) }, + + { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index a6663bf57..427ddb47d 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -27,8 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -#include "py/obj.h" - -// Nothing now. +void common_hal_displayio_release_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H |
