summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/displayio/Display.c149
-rw-r--r--shared-module/displayio/Display.h55
-rw-r--r--shared-module/displayio/__init__.c57
-rw-r--r--shared-module/displayio/__init__.h16
4 files changed, 237 insertions, 40 deletions
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
new file mode 100644
index 000000000..0a14e74bb
--- /dev/null
+++ b/shared-module/displayio/Display.c
@@ -0,0 +1,149 @@
+/*
+ * 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 "shared-bindings/displayio/Display.h"
+
+#include "py/runtime.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-bindings/displayio/ParallelBus.h"
+
+#include <stdint.h>
+
+#include "tick.h"
+
+#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) {
+ self->width = width;
+ self->height = height;
+ self->color_depth = color_depth;
+ self->set_column_command = set_column_command;
+ self->set_row_command = set_row_command;
+ self->write_ram_command = write_ram_command;
+ self->current_group = NULL;
+ self->colstart = colstart;
+ self->rowstart = rowstart;
+
+ if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) {
+ self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction;
+ self->send = common_hal_displayio_parallelbus_send;
+ self->end_transaction = common_hal_displayio_parallelbus_end_transaction;
+ } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) {
+ self->begin_transaction = common_hal_displayio_fourwire_begin_transaction;
+ self->send = common_hal_displayio_fourwire_send;
+ self->end_transaction = common_hal_displayio_fourwire_end_transaction;
+ } else {
+ mp_raise_ValueError(translate("Unsupported display bus type"));
+ }
+ self->bus = bus;
+
+ uint32_t i = 0;
+ self->begin_transaction(self->bus);
+ while (i < init_sequence_len) {
+ uint8_t *cmd = init_sequence + i;
+ uint8_t data_size = *(cmd + 1);
+ bool delay = (data_size & DELAY) != 0;
+ data_size &= ~DELAY;
+ uint8_t *data = cmd + 2;
+ self->send(self->bus, true, cmd, 1);
+ self->send(self->bus, false, data, data_size);
+ if (delay) {
+ data_size++;
+ uint16_t delay_length_ms = *(cmd + 1 + data_size);
+ if (delay_length_ms == 255) {
+ delay_length_ms = 500;
+ }
+ uint64_t start = ticks_ms;
+ while (ticks_ms - start < delay_length_ms) {}
+ } else {
+ uint64_t start = ticks_ms;
+ while (ticks_ms - start < 10) {}
+ }
+ i += 2 + data_size;
+ }
+ self->end_transaction(self->bus);
+}
+
+void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
+ self->current_group = root_group;
+ common_hal_displayio_display_refresh_soon(self);
+}
+
+void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self) {
+ self->refresh = true;
+}
+
+int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self) {
+ uint64_t last_refresh = self->last_refresh;
+ while (last_refresh == self->last_refresh) {
+ MICROPY_VM_HOOK_LOOP
+ }
+ return 0;
+}
+
+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);
+ uint16_t data[2];
+ self->send(self->bus, true, &self->set_column_command, 1);
+ data[0] = __builtin_bswap16(x0 + self->colstart);
+ data[1] = __builtin_bswap16(x1 + 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 + self->rowstart);
+ data[1] = __builtin_bswap16(y1 + self->rowstart);
+ self->send(self->bus, false, (uint8_t*) data, 4);
+ self->send(self->bus, true, &self->write_ram_command, 1);
+}
+
+void displayio_display_finish_region_update(displayio_display_obj_t* self) {
+ self->end_transaction(self->bus);
+}
+
+bool displayio_display_frame_queued(displayio_display_obj_t* self) {
+ // Refresh at ~30 fps.
+ return (ticks_ms - self->last_refresh) > 32;
+}
+
+bool displayio_display_refresh_queued(displayio_display_obj_t* self) {
+ return self->refresh || (self->current_group != NULL && displayio_group_needs_refresh(self->current_group));
+}
+
+void displayio_display_finish_refresh(displayio_display_obj_t* self) {
+ if (self->current_group != NULL) {
+ displayio_group_finish_refresh(self->current_group);
+ }
+ self->refresh = false;
+ self->last_refresh = ticks_ms;
+}
+
+bool displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length) {
+ self->send(self->bus, false, (uint8_t*) pixels, length * 4);
+ return true;
+}
diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h
new file mode 100644
index 000000000..1f1355d31
--- /dev/null
+++ b/shared-module/displayio/Display.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
+#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
+
+#include "shared-module/displayio/Group.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);
+typedef void (*display_bus_end_transaction)(mp_obj_t bus);
+
+typedef struct {
+ mp_obj_base_t base;
+ mp_obj_t bus;
+ uint16_t width;
+ uint16_t height;
+ uint16_t color_depth;
+ uint8_t set_column_command;
+ uint8_t set_row_command;
+ uint8_t write_ram_command;
+ displayio_group_t *current_group;
+ bool refresh;
+ uint64_t last_refresh;
+ int16_t colstart;
+ int16_t rowstart;
+ display_bus_begin_transaction begin_transaction;
+ display_bus_send send;
+ display_bus_end_transaction end_transaction;
+} displayio_display_obj_t;
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_DISPLAY_H
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index f1a00db9f..b528c3289 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -1,44 +1,17 @@
-#include "shared-bindings/displayio/FourWire.h"
-extern displayio_fourwire_obj_t board_display_obj;
+#include "shared-module/displayio/__init__.h"
-void start_region_update(displayio_fourwire_obj_t* display, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
- // TODO delegate between different display types
- displayio_fourwire_start_region_update(display, x0, y0, x1, y1);
-}
-
-void finish_region_update(displayio_fourwire_obj_t* display) {
- // TODO delegate between different display types
- displayio_fourwire_finish_region_update(display);
-}
-
-void finish_refresh(displayio_fourwire_obj_t* display) {
- // TODO delegate between different display types
- displayio_fourwire_finish_refresh(display);
-}
-
-bool frame_queued(displayio_fourwire_obj_t* display) {
- // TODO delegate between different display types
- return displayio_fourwire_frame_queued(display);
-}
-
-bool refresh_queued(displayio_fourwire_obj_t* display) {
- // TODO delegate between different display types
- return displayio_fourwire_refresh_queued(display);
-}
+#include "shared-bindings/displayio/Display.h"
-bool send_pixels(displayio_fourwire_obj_t* display, uint32_t* pixels, uint32_t length) {
- // TODO delegate between different display types
- return displayio_fourwire_send_pixels(display, pixels, length);
-}
+primary_display_t primary_display;
void displayio_refresh_display(void) {
- displayio_fourwire_obj_t* display = &board_display_obj;
+ displayio_display_obj_t* display = &primary_display.display;
- if (!frame_queued(display)) {
+ if (!displayio_display_frame_queued(display)) {
return;
}
- if (refresh_queued(display)) {
+ if (displayio_display_refresh_queued(display)) {
PORT->Group[1].DIRSET.reg = 1 << 22;
// We compute the pixels
@@ -50,7 +23,7 @@ void displayio_refresh_display(void) {
//size_t row_size = (x1 - x0);
uint16_t buffer_size = 256;
uint32_t buffer[buffer_size / 2];
- start_region_update(display, x0, y0, x1, y1);
+ displayio_display_start_region_update(display, x0, y0, x1, y1);
for (uint16_t y = y0; y < y1; ++y) {
for (uint16_t x = x0; x < x1; ++x) {
uint16_t* pixel = &(((uint16_t*)buffer)[index]);
@@ -72,8 +45,8 @@ void displayio_refresh_display(void) {
index += 1;
// The buffer is full, send it.
if (index >= buffer_size) {
- if (!send_pixels(display, buffer, buffer_size / 2)) {
- finish_region_update(display);
+ if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) {
+ displayio_display_finish_region_update(display);
return;
}
index = 0;
@@ -81,11 +54,15 @@ void displayio_refresh_display(void) {
}
}
// Send the remaining data.
- if (index && !send_pixels(display, buffer, index * 2)) {
- finish_region_update(display);
+ if (index && !displayio_display_send_pixels(display, buffer, index * 2)) {
+ displayio_display_finish_region_update(display);
return;
}
- finish_region_update(display);
+ displayio_display_finish_region_update(display);
}
- finish_refresh(display);
+ displayio_display_finish_refresh(display);
+}
+
+void reset_primary_display(void) {
+ common_hal_displayio_display_show(&primary_display.display, NULL);
}
diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h
index 556af430d..84db98fcc 100644
--- a/shared-module/displayio/__init__.h
+++ b/shared-module/displayio/__init__.h
@@ -27,6 +27,22 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H
+#include "shared-bindings/displayio/Display.h"
+#include "shared-bindings/displayio/FourWire.h"
+#include "shared-bindings/displayio/ParallelBus.h"
+
+typedef struct {
+ union {
+ displayio_fourwire_obj_t fourwire_bus;
+ displayio_parallelbus_obj_t parallel_bus;
+ };
+ mp_const_obj_t bus_type;
+ displayio_display_obj_t display;
+} primary_display_t;
+
+extern primary_display_t primary_display;
+
void displayio_refresh_display(void);
+void reset_primary_display(void);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H