summaryrefslogtreecommitdiff
path: root/shared-bindings
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2019-01-20 21:47:13 -0500
committerDan Halbert <halbert@halwitz.org>2019-01-20 21:47:13 -0500
commita8f4aa4796aaba964b17932f0ae9299d18db1649 (patch)
treefea7576c8221fc5519ba86c8a97ddb601477cce3 /shared-bindings
parent7a09af73ec7f4a11a1404dff6276e09072d06983 (diff)
parent6b88d0f94eb1459562d0f159688b504a6f5d408f (diff)
Merge remote-tracking branch 'adafruit/master' into struct-compat
Diffstat (limited to 'shared-bindings')
-rw-r--r--shared-bindings/displayio/Display.c181
-rw-r--r--shared-bindings/displayio/Display.h59
-rw-r--r--shared-bindings/displayio/FourWire.c93
-rw-r--r--shared-bindings/displayio/FourWire.h31
-rw-r--r--shared-bindings/displayio/ParallelBus.c126
-rw-r--r--shared-bindings/displayio/ParallelBus.h49
-rw-r--r--shared-bindings/displayio/__init__.c28
-rw-r--r--shared-bindings/displayio/__init__.h4
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