From c3136f4f32df28cc29596fc9ba76dcc0bfd533f0 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Sat, 6 Apr 2019 14:02:18 +0200 Subject: [PATCH 1/5] Enable displayio for uGame10 board Also, make the _stage library work with the fourwire bus, to re-use the display. --- frozen/circuitpython-stage | 2 +- ports/atmel-samd/boards/ugame10/board.c | 73 +++++++++++++++++++ .../atmel-samd/boards/ugame10/mpconfigboard.h | 9 +-- .../boards/ugame10/mpconfigboard.mk | 7 +- ports/atmel-samd/boards/ugame10/pins.c | 5 +- shared-bindings/_stage/__init__.c | 11 ++- 6 files changed, 95 insertions(+), 12 deletions(-) diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index d8a9d8c1d7..347b020954 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit d8a9d8c1d73041e4cc5669c5441f531ecba517fc +Subproject commit 347b02095449075d3e9bb1b7bac6d3a8a2151df2 diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index d7e856d611..cd67dabe36 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -26,7 +26,80 @@ #include "boards/board.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/displayio/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/busio/SPI.h" + +#include "tick.h" + +displayio_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + 0x11, 0 | DELAY, 255, // SLPOUT + 0xb1, 3, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 3, 0x01, 0x2C, 0x2D, // + 0xb3, 6, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, + 0xb4, 1, 0x07, // _INVCTR line inversion + 0xc0, 3, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 1, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 2, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 2, 0x8a, 0x2a, + 0xc4, 2, 0x8a, 0xee, + 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x2a, 0, // _INVOFF + 0x36, 1, 0xa8, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, + // fix on VTL + 0x3a, 1, 0x05, // COLMOD - 16bit color + 0xe0, 16, 0x02, 0x1c, 0x07, 0x12, // _GMCTRP1 Gamma + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + 0xe1, 16, 0x03, 0x1d, 0x07, 0x06, // _GMCTRN1 + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + 0x2a, 3, 0x02, 0x00, 0x81, // _CASET XSTART = 2, XEND = 129 + 0x2b, 3, 0x02, 0x00, 0x81, // _RASET XSTART = 2, XEND = 129 + 0x13, 0 | DELAY, 10, // _NORON + 0x29, 0 | DELAY, 100, // _DISPON +}; + void board_init(void) { + displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + busio_spi_obj_t *spi = common_hal_board_create_spi(); + common_hal_busio_spi_configure(spi, 24000000, 0, 0, 8); + common_hal_displayio_fourwire_construct(bus, + spi, + &pin_PA09, // Command or data + &pin_PA08, // Chip select + NULL); // Reset + + displayio_display_obj_t* display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct(display, + bus, + 128, // Width + 128, // Height + 3, // column start + 2, // row start + 0, // rotation + 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 + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + NULL, + false, // single_byte_bounds + false); // data as commands } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h index caa05bc1ae..4526336491 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h @@ -7,7 +7,7 @@ #define SPI_FLASH_CS_PIN &pin_PA18 // These are pins not to reset. -#define MICROPY_PORT_A (0) +#define MICROPY_PORT_A (PORT_PA06 | PORT_PA07 | PORT_PA08 | PORT_PA09) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) @@ -19,10 +19,9 @@ #define BOARD_FLASH_SIZE (0x00040000 - 0x2000 - CIRCUITPY_INTERNAL_NVM_SIZE) -#define EXTRA_BUILTIN_MODULES \ - { MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module } +#define DEFAULT_SPI_BUS_SCK (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA11) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA06) #define IGNORE_PIN_PB00 1 #define IGNORE_PIN_PB01 1 diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index 0a727c8b16..4a0330d57d 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -17,13 +17,16 @@ CIRCUITPY_MATH = 1 CIRCUITPY_AUDIOIO = 1 CIRCUITPY_ANALOGIO = 1 CIRCUITPY_GAMEPAD = 1 +CIRCUITPY_DISPLAYIO = 1 + CIRCUITPY_TOUCHIO = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 CIRCUITPY_RTC = 0 -CIRCUITPY_SAMD = 0 CIRCUITPY_USB_MIDI = 0 CIRCUITPY_USB_HID = 0 +CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_SMALL_BUILD = 1 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_PIXELBUF = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage diff --git a/ports/atmel-samd/boards/ugame10/pins.c b/ports/atmel-samd/boards/ugame10/pins.c index 904ac224b1..4a03f8bb5c 100644 --- a/ports/atmel-samd/boards/ugame10/pins.c +++ b/ports/atmel-samd/boards/ugame10/pins.c @@ -1,4 +1,5 @@ #include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_X), MP_ROM_PTR(&pin_PA00) }, @@ -23,8 +24,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_B), MP_ROM_PTR(&pin_PA14) }, { MP_ROM_QSTR(MP_QSTR_C), MP_ROM_PTR(&pin_PA15) }, { MP_ROM_QSTR(MP_QSTR_D), MP_ROM_PTR(&pin_PA28) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 24a3596645..95cbda8463 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -28,6 +28,7 @@ #include "py/mperrno.h" #include "py/runtime.h" #include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/FourWire.h" #include "shared-module/_stage/__init__.h" #include "Layer.h" #include "Text.h" @@ -85,12 +86,18 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { uint16_t *buffer = bufinfo.buf; size_t buffer_size = bufinfo.len / 2; // 16-bit indexing - busio_spi_obj_t *spi = MP_OBJ_TO_PTR(args[6]); + displayio_fourwire_obj_t *bus = MP_OBJ_TO_PTR(args[6]); + while (!common_hal_displayio_fourwire_begin_transaction(bus)) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP ; +#endif + } if (!render_stage(x0, y0, x1, y1, layers, layers_size, - buffer, buffer_size, spi)) { + buffer, buffer_size, bus->bus)) { mp_raise_OSError(MP_EIO); } + common_hal_displayio_fourwire_end_transaction(bus); return mp_const_none; } From dabbded622878f8c8dbea17310b4b63f71a387d3 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Fri, 12 Apr 2019 11:19:19 +0200 Subject: [PATCH 2/5] Got back to using Display object in the Stage library --- frozen/circuitpython-stage | 2 +- ports/atmel-samd/boards/ugame10/board.c | 2 +- ports/atmel-samd/boards/ugame10/mpconfigboard.mk | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index 347b020954..a7b3295ff5 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit 347b02095449075d3e9bb1b7bac6d3a8a2151df2 +Subproject commit a7b3295ff573ce03cd7111a6cf7bf9cfe1e4f657 diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index cd67dabe36..a4f6bb175e 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -52,7 +52,7 @@ uint8_t display_init_sequence[] = { 0xc4, 2, 0x8a, 0xee, 0xc5, 1, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V 0x2a, 0, // _INVOFF - 0x36, 1, 0xa8, // _MADCTL bottom to top refresh + 0x36, 1, 0xa0, // _MADCTL bottom to top refresh // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, // fix on VTL 0x3a, 1, 0x05, // COLMOD - 16bit color diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk index 4a0330d57d..cafd84b214 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.mk +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.mk @@ -29,4 +29,6 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_PIXELBUF = 0 -FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame10 + +CIRCUITPY_DISPLAY_FONT = "../../tools/Tecate-bitmap-fonts/bitmap/phallus/lemon.bdf" From d39e7e7dd51aa55e92cfda3e05ea80ae1abe409d Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Fri, 12 Apr 2019 11:56:23 +0200 Subject: [PATCH 3/5] Use displayio.Display directly --- frozen/circuitpython-stage | 2 +- shared-bindings/_stage/__init__.c | 24 +++++++++++------------- shared-module/_stage/__init__.c | 14 ++++---------- shared-module/_stage/__init__.h | 6 +++--- supervisor/supervisor.mk | 2 +- 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index a7b3295ff5..069fad8357 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit a7b3295ff573ce03cd7111a6cf7bf9cfe1e4f657 +Subproject commit 069fad8357623f5ea2ff3c865a5b8ed54608afd7 diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 95cbda8463..4660980610 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -28,7 +28,7 @@ #include "py/mperrno.h" #include "py/runtime.h" #include "shared-bindings/busio/SPI.h" -#include "shared-bindings/displayio/FourWire.h" +#include "shared-bindings/displayio/Display.h" #include "shared-module/_stage/__init__.h" #include "Layer.h" #include "Text.h" @@ -50,7 +50,7 @@ //| Layer //| Text //| -//| .. function:: render(x0, y0, x1, y1, layers, buffer, spi) +//| .. function:: render(x0, y0, x1, y1, layers, buffer, display) //| //| Render and send to the display a fragment of the screen. //| @@ -60,11 +60,8 @@ //| :param int y1: Bottom edge of the fragment. //| :param list layers: A list of the :py:class:`~_stage.Layer` objects. //| :param bytearray buffer: A buffer to use for rendering. -//| :param ~busio.SPI spi: The SPI bus to use. +//| :param ~displayio.Display display: The display to use. //| -//| Note that this function only sends the raw pixel data. Setting up -//| the display for receiving it and handling the chip-select and -//| data-command pins has to be done outside of it. //| There are also no sanity checks, outside of the basic overflow //| checking. The caller is responsible for making the passed parameters //| valid. @@ -86,18 +83,19 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { uint16_t *buffer = bufinfo.buf; size_t buffer_size = bufinfo.len / 2; // 16-bit indexing - displayio_fourwire_obj_t *bus = MP_OBJ_TO_PTR(args[6]); + if (!MP_OBJ_IS_TYPE(args[6], &displayio_display_type)) { + mp_raise_TypeError(translate("expected displayio.Display")); + } + displayio_display_obj_t *display = MP_OBJ_TO_PTR(args[6]); - while (!common_hal_displayio_fourwire_begin_transaction(bus)) { + while (!displayio_display_begin_transaction(display)) { #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP ; #endif } - if (!render_stage(x0, y0, x1, y1, layers, layers_size, - buffer, buffer_size, bus->bus)) { - mp_raise_OSError(MP_EIO); - } - common_hal_displayio_fourwire_end_transaction(bus); + displayio_display_set_region_to_update(display, x0, y0, x1, y1); + render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, display); + displayio_display_end_transaction(display); return mp_const_none; } diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c index 86f5ee7957..1af279e92b 100644 --- a/shared-module/_stage/__init__.c +++ b/shared-module/_stage/__init__.c @@ -31,10 +31,10 @@ #include "shared-bindings/_stage/Text.h" -bool render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, +void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, mp_obj_t *layers, size_t layers_size, uint16_t *buffer, size_t buffer_size, - busio_spi_obj_t *spi) { + displayio_display_obj_t *display) { size_t index = 0; for (uint16_t y = y0; y < y1; ++y) { @@ -55,19 +55,13 @@ bool render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, index += 1; // The buffer is full, send it. if (index >= buffer_size) { - if (!common_hal_busio_spi_write(spi, - ((uint8_t*)buffer), buffer_size * 2)) { - return false; - } + display->send(display->bus, false, ((uint8_t*)buffer), buffer_size * 2); index = 0; } } } // Send the remaining data. if (index) { - if (!common_hal_busio_spi_write(spi, ((uint8_t*)buffer), index * 2)) { - return false; - } + display->send(display->bus, false, ((uint8_t*)buffer), index * 2); } - return true; } diff --git a/shared-module/_stage/__init__.h b/shared-module/_stage/__init__.h index d56a26940f..d263302b48 100644 --- a/shared-module/_stage/__init__.h +++ b/shared-module/_stage/__init__.h @@ -27,16 +27,16 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE__STAGE_H #define MICROPY_INCLUDED_SHARED_MODULE__STAGE_H -#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/displayio/Display.h" #include #include #include "py/obj.h" #define TRANSPARENT (0x1ff8) -bool render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, +void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, mp_obj_t *layers, size_t layers_size, uint16_t *buffer, size_t buffer_size, - busio_spi_obj_t *spi); + displayio_display_obj_t *display); #endif // MICROPY_INCLUDED_SHARED_MODULE__STAGE diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 95cffc0982..f94f19353f 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -101,7 +101,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 = "../../tools/Tecate-bitmap-fonts/bitmap/terminus-font-4.39/ter-u12n.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 $@" From 0599286e32d0f81a175a20fe608c8a6c91725411 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Fri, 12 Apr 2019 20:45:52 +0200 Subject: [PATCH 4/5] Use never_reset in ugame10 --- ports/atmel-samd/boards/ugame10/mpconfigboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/ugame10/mpconfigboard.h b/ports/atmel-samd/boards/ugame10/mpconfigboard.h index 4526336491..b5590d986c 100644 --- a/ports/atmel-samd/boards/ugame10/mpconfigboard.h +++ b/ports/atmel-samd/boards/ugame10/mpconfigboard.h @@ -7,7 +7,7 @@ #define SPI_FLASH_CS_PIN &pin_PA18 // These are pins not to reset. -#define MICROPY_PORT_A (PORT_PA06 | PORT_PA07 | PORT_PA08 | PORT_PA09) +#define MICROPY_PORT_A (0) #define MICROPY_PORT_B (0) #define MICROPY_PORT_C (0) From 7aab3e8c9394ad8f07d101b426d13ec59c36c01c Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Fri, 12 Apr 2019 21:31:06 +0200 Subject: [PATCH 5/5] Re-use an error message in _stage --- shared-bindings/_stage/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 4660980610..dc9dbef659 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -84,7 +84,7 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { size_t buffer_size = bufinfo.len / 2; // 16-bit indexing if (!MP_OBJ_IS_TYPE(args[6], &displayio_display_type)) { - mp_raise_TypeError(translate("expected displayio.Display")); + mp_raise_TypeError(translate("argument num/types mismatch")); } displayio_display_obj_t *display = MP_OBJ_TO_PTR(args[6]);