From 710c2dc54b7c97088890b084f0ed0ab5132011e8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 4 Aug 2020 12:46:07 -0500 Subject: safe_mode: Exclude NORDIC_SOFT_DEVICE_ASSERT str if possible --- supervisor/shared/safe_mode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'supervisor') diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index a167ab392..3275cc66f 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -151,9 +151,13 @@ void print_safe_mode_message(safe_mode_t reason) { case GC_ALLOC_OUTSIDE_VM: serial_write_compressed(translate("Attempted heap allocation when MicroPython VM not running.")); break; +#ifdef SOFTDEVICE_PRESENT + // defined in ports/nrf/bluetooth/bluetooth_common.mk + // will print "Unknown reason" if somehow encountered on other ports case NORDIC_SOFT_DEVICE_ASSERT: serial_write_compressed(translate("Nordic Soft Device failure assertion.")); break; +#endif case FLASH_WRITE_FAIL: serial_write_compressed(translate("Failed to write internal flash.")); break; -- cgit v1.2.3 From 14b3b51c58ca368227d8890a2aa32e7acb94175b Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Tue, 4 Aug 2020 18:40:24 -0400 Subject: Rework build flags, prevent idf errors --- ports/esp32s2/common-hal/microcontroller/Pin.c | 4 ++++ ports/esp32s2/common-hal/pulseio/PWMOut.c | 17 +++++++++++++---- ports/esp32s2/mpconfigport.mk | 25 ++++++++++--------------- ports/esp32s2/peripherals/rmt.c | 1 + supervisor/shared/rgb_led_status.c | 1 + 5 files changed, 29 insertions(+), 19 deletions(-) (limited to 'supervisor') diff --git a/ports/esp32s2/common-hal/microcontroller/Pin.c b/ports/esp32s2/common-hal/microcontroller/Pin.c index 2b2b70a45..03a83cfe6 100644 --- a/ports/esp32s2/common-hal/microcontroller/Pin.c +++ b/ports/esp32s2/common-hal/microcontroller/Pin.c @@ -98,6 +98,10 @@ void claim_pin(const mcu_pin_obj_t* pin) { #endif } +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) { + claim_pin(pin); +} + bool pin_number_is_free(gpio_num_t pin_number) { #ifdef MICROPY_HW_NEOPIXEL if (pin_number == MICROPY_HW_NEOPIXEL->number) { diff --git a/ports/esp32s2/common-hal/pulseio/PWMOut.c b/ports/esp32s2/common-hal/pulseio/PWMOut.c index f38bd4434..3172023b6 100644 --- a/ports/esp32s2/common-hal/pulseio/PWMOut.c +++ b/ports/esp32s2/common-hal/pulseio/PWMOut.c @@ -39,13 +39,17 @@ STATIC bool never_reset_chan[LEDC_CHANNEL_MAX]; void pwmout_reset(void) { for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++ ) { - ledc_stop(LEDC_LOW_SPEED_MODE, i, 0); + if (reserved_channels[i] != INDEX_EMPTY) { + ledc_stop(LEDC_LOW_SPEED_MODE, i, 0); + } if (!never_reset_chan[i]) { reserved_channels[i] = INDEX_EMPTY; } } for (size_t i = 0; i < LEDC_TIMER_MAX; i++ ) { - ledc_timer_rst(LEDC_LOW_SPEED_MODE, i); + if (reserved_timer_freq[i]) { + ledc_timer_rst(LEDC_LOW_SPEED_MODE, i); + } if (!never_reset_tim[i]) { reserved_timer_freq[i] = 0; } @@ -157,7 +161,10 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { if (common_hal_pulseio_pwmout_deinited(self)) { return; } - ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0); + + if (reserved_channels[self->chan_handle.channel] != INDEX_EMPTY) { + ledc_stop(LEDC_LOW_SPEED_MODE, self->chan_handle.channel, 0); + } // Search if any other channel is using the timer bool taken = false; for (size_t i =0; i < LEDC_CHANNEL_MAX; i++) { @@ -167,7 +174,9 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { } // Variable frequency means there's only one channel on the timer if (!taken || self->variable_frequency) { - ledc_timer_rst(LEDC_LOW_SPEED_MODE, self->tim_handle.timer_num); + if (reserved_timer_freq[self->tim_handle.timer_num] != 0) { + ledc_timer_rst(LEDC_LOW_SPEED_MODE, self->tim_handle.timer_num); + } reserved_timer_freq[self->tim_handle.timer_num] = 0; } reset_pin_number(self->pin_number); diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 21d6e7cff..20a30c82e 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -14,26 +14,21 @@ LONGINT_IMPL = MPZ CIRCUITPY_NEOPIXEL_WRITE = 1 -CIRCUITPY_FULL_BUILD = 0 +# These modules are implemented in ports//common-hal: CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_NVM = 0 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 -CIRCUITPY_BITBANGIO = 1 -CIRCUITPY_BOARD = 1 -CIRCUITPY_DIGITALIO = 1 -CIRCUITPY_BUSIO = 1 -CIRCUITPY_DISPLAYIO = 1 -CIRCUITPY_FREQUENCYIO = 0 -CIRCUITPY_I2CPERIPHERAL = 0 -CIRCUITPY_MICROCONTROLLER = 1 -CIRCUITPY_NVM = 0 -CIRCUITPY_PULSEIO = 1 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 -CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_I2CPERIPHERAL = 0 +CIRCUITPY_COUNTIO = 0 -# Enable USB HID support -CIRCUITPY_USB_HID = 1 -CIRCUITPY_USB_MIDI = 0 +# These modules are implemented in shared-module/ - they can be included in +# any port once their prerequisites in common-hal are complete. +CIRCUITPY_RANDOM = 0 # Requires OS +CIRCUITPY_USB_MIDI = 0 # Requires USB +CIRCUITPY_ULAB = 0 # No requirements, but takes extra flash CIRCUITPY_MODULE ?= none diff --git a/ports/esp32s2/peripherals/rmt.c b/ports/esp32s2/peripherals/rmt.c index e9ad2c32e..f17957c1c 100644 --- a/ports/esp32s2/peripherals/rmt.c +++ b/ports/esp32s2/peripherals/rmt.c @@ -42,4 +42,5 @@ rmt_channel_t esp32s2_peripherals_find_and_reserve_rmt(void) { void esp32s2_peripherals_free_rmt(rmt_channel_t chan) { rmt_reserved_channels[chan] = false; + rmt_driver_uninstall(chan); } diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index f3c210647..1de745a56 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -28,6 +28,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "rgb_led_status.h" #include "supervisor/shared/tick.h" +#include "py/obj.h" #ifdef MICROPY_HW_NEOPIXEL uint8_t rgb_status_brightness = 63; -- cgit v1.2.3 From 78d049d0f14206d653b89c8cdcc91199954858c1 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Wed, 5 Aug 2020 14:05:53 -0400 Subject: Fix pwm reset spew, protect against null reference in led status --- ports/esp32s2/common-hal/pulseio/PWMOut.c | 4 +++- supervisor/shared/rgb_led_status.c | 30 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'supervisor') diff --git a/ports/esp32s2/common-hal/pulseio/PWMOut.c b/ports/esp32s2/common-hal/pulseio/PWMOut.c index 3172023b6..0ac42852a 100644 --- a/ports/esp32s2/common-hal/pulseio/PWMOut.c +++ b/ports/esp32s2/common-hal/pulseio/PWMOut.c @@ -32,6 +32,7 @@ #define INDEX_EMPTY 0xFF +STATIC bool not_first_reset = false; STATIC uint32_t reserved_timer_freq[LEDC_TIMER_MAX]; STATIC uint8_t reserved_channels[LEDC_CHANNEL_MAX]; STATIC bool never_reset_tim[LEDC_TIMER_MAX]; @@ -39,7 +40,7 @@ STATIC bool never_reset_chan[LEDC_CHANNEL_MAX]; void pwmout_reset(void) { for (size_t i = 0; i < LEDC_CHANNEL_MAX; i++ ) { - if (reserved_channels[i] != INDEX_EMPTY) { + if (reserved_channels[i] != INDEX_EMPTY && not_first_reset) { ledc_stop(LEDC_LOW_SPEED_MODE, i, 0); } if (!never_reset_chan[i]) { @@ -54,6 +55,7 @@ void pwmout_reset(void) { reserved_timer_freq[i] = 0; } } + not_first_reset = true; } pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index 1de745a56..b66bbd9d5 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -387,20 +387,22 @@ void prep_rgb_status_animation(const pyexec_result_t* result, if (!status->ok) { status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places; } - if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) { - status->exception_color = INDENTATION_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) { - status->exception_color = SYNTAX_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) { - status->exception_color = NAME_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) { - status->exception_color = OS_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) { - status->exception_color = VALUE_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) { - status->exception_color = MPY_ERROR; - } else { - status->exception_color = OTHER_ERROR; + if (result->exception_type) { + if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) { + status->exception_color = INDENTATION_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) { + status->exception_color = SYNTAX_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) { + status->exception_color = NAME_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) { + status->exception_color = OS_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) { + status->exception_color = VALUE_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) { + status->exception_color = MPY_ERROR; + } else { + status->exception_color = OTHER_ERROR; + } } #endif } -- cgit v1.2.3 From d47bd5529c8e2944f5e18dec87ed432c742622ee Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Mon, 10 Aug 2020 13:16:20 -0400 Subject: Fix neopixel macro issue, set default neopixel color --- .../boards/espressif_saola_1_wroom/mpconfigboard.h | 2 ++ .../espressif_saola_1_wroom/mpconfigboard.mk | 2 -- .../espressif_saola_1_wrover/mpconfigboard.mk | 2 -- .../unexpectedmaker_feathers2/mpconfigboard.mk | 3 -- ports/esp32s2/mpconfigport.mk | 2 -- supervisor/shared/rgb_led_status.c | 32 +++++++++++----------- 6 files changed, 18 insertions(+), 25 deletions(-) (limited to 'supervisor') diff --git a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h index 78652e215..a94f10ea4 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h +++ b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -29,4 +29,6 @@ #define MICROPY_HW_BOARD_NAME "Saola 1 w/Wroom" #define MICROPY_HW_MCU_NAME "ESP32S2" +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + #define AUTORESET_DELAY_MS 500 diff --git a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.mk b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.mk index 6e7627265..9c9ca6169 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.mk +++ b/ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.mk @@ -10,8 +10,6 @@ LONGINT_IMPL = MPZ # so increase it to 32. CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 -CIRCUITPY_NEOPIXEL_WRITE = 0 - CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.mk b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.mk index 1437df7f4..d5ff1c5ac 100644 --- a/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.mk +++ b/ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.mk @@ -10,8 +10,6 @@ LONGINT_IMPL = MPZ # so increase it to 32. CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 -CIRCUITPY_NEOPIXEL_WRITE = 0 - CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=4MB diff --git a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk index ea3484d2f..294736d17 100644 --- a/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk +++ b/ports/esp32s2/boards/unexpectedmaker_feathers2/mpconfigboard.mk @@ -4,7 +4,6 @@ USB_PRODUCT = "FeatherS2" USB_MANUFACTURER = "UnexpectedMaker" USB_DEVICES = "CDC,MSC,HID" - INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = MPZ @@ -12,8 +11,6 @@ LONGINT_IMPL = MPZ # so increase it to 32. CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 -CIRCUITPY_NEOPIXEL_WRITE = 0 - CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=16MB diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 20a30c82e..a7873aa46 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -12,8 +12,6 @@ USB_SERIAL_NUMBER_LENGTH = 12 # Longints can be implemented as mpz, as longlong, or not LONGINT_IMPL = MPZ -CIRCUITPY_NEOPIXEL_WRITE = 1 - # These modules are implemented in ports//common-hal: CIRCUITPY_ANALOGIO = 0 CIRCUITPY_NVM = 0 diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index b66bbd9d5..fe99129f8 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -387,22 +387,22 @@ void prep_rgb_status_animation(const pyexec_result_t* result, if (!status->ok) { status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places; } - if (result->exception_type) { - if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) { - status->exception_color = INDENTATION_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) { - status->exception_color = SYNTAX_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) { - status->exception_color = NAME_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) { - status->exception_color = OS_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) { - status->exception_color = VALUE_ERROR; - } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) { - status->exception_color = MPY_ERROR; - } else { - status->exception_color = OTHER_ERROR; - } + if (!result->exception_type) { + status->exception_color = OTHER_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_IndentationError)) { + status->exception_color = INDENTATION_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_SyntaxError)) { + status->exception_color = SYNTAX_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_NameError)) { + status->exception_color = NAME_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_OSError)) { + status->exception_color = OS_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_ValueError)) { + status->exception_color = VALUE_ERROR; + } else if (mp_obj_is_subclass_fast(result->exception_type, &mp_type_MpyError)) { + status->exception_color = MPY_ERROR; + } else { + status->exception_color = OTHER_ERROR; } #endif } -- cgit v1.2.3 From 4613b58a31c8d439d92961f2034eb9f60b0d97c1 Mon Sep 17 00:00:00 2001 From: Lucian Copeland Date: Mon, 10 Aug 2020 18:00:50 -0400 Subject: Add skip for rgb matrix exception handling --- main.c | 2 +- supervisor/shared/rgb_led_status.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'supervisor') diff --git a/main.c b/main.c index 8c5c9ac37..7c69cde08 100755 --- a/main.c +++ b/main.c @@ -276,7 +276,7 @@ bool run_code_py(safe_mode_t safe_mode) { } } - // Wait for connection or character. + // Display a different completion message if the user has no USB attached (cannot save files) if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); } diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index fe99129f8..2f23e3125 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -366,6 +366,11 @@ void prep_rgb_status_animation(const pyexec_result_t* result, status->safe_mode = safe_mode; status->found_main = found_main; status->total_exception_cycle = 0; + status->ok = result->return_code != PYEXEC_EXCEPTION; + if (status->ok) { + // If this isn't an exception, skip exception sorting and handling + return; + } status->ones = result->exception_line % 10; status->ones += status->ones > 0 ? 1 : 0; status->tens = (result->exception_line / 10) % 10; @@ -383,7 +388,6 @@ void prep_rgb_status_animation(const pyexec_result_t* result, } line /= 10; } - status->ok = result->return_code != PYEXEC_EXCEPTION; if (!status->ok) { status->total_exception_cycle = EXCEPTION_TYPE_LENGTH_MS * 3 + LINE_NUMBER_TOGGLE_LENGTH * status->digit_sum + LINE_NUMBER_TOGGLE_LENGTH * num_places; } -- cgit v1.2.3 From c1400bae9bbdd55f650ddfe24edf6778f08c35b8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 6 Aug 2020 16:03:31 -0500 Subject: sharpmemory: Implement support for Sharp Memory Displays in framebufferio --- py/circuitpy_defns.mk | 5 + py/circuitpy_mpconfig.h | 22 +- py/circuitpy_mpconfig.mk | 6 +- py/qstr.c | 1 + .../sharpdisplay/SharpMemoryFramebuffer.c | 92 +++++++ .../sharpdisplay/SharpMemoryFramebuffer.h | 34 +++ shared-bindings/sharpdisplay/__init__.c | 47 ++++ shared-bindings/sharpdisplay/__init__.h | 0 shared-module/displayio/__init__.c | 33 ++- shared-module/displayio/__init__.h | 10 + shared-module/framebufferio/FramebufferDisplay.c | 21 +- shared-module/framebufferio/FramebufferDisplay.h | 3 +- .../sharpdisplay/SharpMemoryFramebuffer.c | 282 +++++++++++++++++++++ .../sharpdisplay/SharpMemoryFramebuffer.h | 60 +++++ shared-module/sharpdisplay/__init__.c | 0 shared-module/sharpdisplay/__init__.h | 0 supervisor/shared/display.c | 21 +- 17 files changed, 608 insertions(+), 29 deletions(-) create mode 100644 shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c create mode 100644 shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h create mode 100644 shared-bindings/sharpdisplay/__init__.c create mode 100644 shared-bindings/sharpdisplay/__init__.h create mode 100644 shared-module/sharpdisplay/SharpMemoryFramebuffer.c create mode 100644 shared-module/sharpdisplay/SharpMemoryFramebuffer.h create mode 100644 shared-module/sharpdisplay/__init__.c create mode 100644 shared-module/sharpdisplay/__init__.h (limited to 'supervisor') diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index a39e0c9dd..515b386f9 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -222,6 +222,9 @@ endif ifeq ($(CIRCUITPY_SDIOIO),1) SRC_PATTERNS += sdioio/% endif +ifeq ($(CIRCUITPY_SHARPDISPLAY),1) +SRC_PATTERNS += sharpdisplay/% +endif ifeq ($(CIRCUITPY_STAGE),1) SRC_PATTERNS += _stage/% endif @@ -409,6 +412,8 @@ SRC_SHARED_MODULE_ALL = \ random/__init__.c \ rgbmatrix/RGBMatrix.c \ rgbmatrix/__init__.c \ + sharpdisplay/SharpMemoryFramebuffer.c \ + sharpdisplay/__init__.c \ socket/__init__.c \ storage/__init__.c \ struct/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 255ab99b9..f0e8adffa 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -499,13 +499,6 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define PIXELBUF_MODULE #endif -#if CIRCUITPY_RGBMATRIX -extern const struct _mp_obj_module_t rgbmatrix_module; -#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module }, -#else -#define RGBMATRIX_MODULE -#endif - #if CIRCUITPY_PULSEIO extern const struct _mp_obj_module_t pulseio_module; #define PULSEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, @@ -520,6 +513,13 @@ extern const struct _mp_obj_module_t ps2io_module; #define PS2IO_MODULE #endif +#if CIRCUITPY_RGBMATRIX +extern const struct _mp_obj_module_t rgbmatrix_module; +#define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module }, +#else +#define RGBMATRIX_MODULE +#endif + #if CIRCUITPY_RANDOM extern const struct _mp_obj_module_t random_module; #define RANDOM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, @@ -562,6 +562,13 @@ extern const struct _mp_obj_module_t sdioio_module; #define SDIOIO_MODULE #endif +#if CIRCUITPY_SHARPDISPLAY +extern const struct _mp_obj_module_t sharpdisplay_module; +#define SHARPDISPLAY_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_sharpdisplay),(mp_obj_t)&sharpdisplay_module }, +#else +#define SHARPDISPLAY_MODULE +#endif + #if CIRCUITPY_STAGE extern const struct _mp_obj_module_t stage_module; #define STAGE_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, @@ -737,6 +744,7 @@ extern const struct _mp_obj_module_t watchdog_module; SAMD_MODULE \ SDCARDIO_MODULE \ SDIOIO_MODULE \ + SHARPDISPLAY_MODULE \ STAGE_MODULE \ STORAGE_MODULE \ STRUCT_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 2cf8426e5..1ba71fa02 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -95,7 +95,7 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) -CIRCUITPY_FRAMEBUFFERIO ?= 0 +CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO) CIRCUITPY_VECTORIO ?= $(CIRCUITPY_DISPLAYIO) @@ -144,7 +144,6 @@ CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS) CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) -# Only for SAMD boards for the moment CIRCUITPY_RGBMATRIX ?= 0 CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX) @@ -176,6 +175,9 @@ CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO) CIRCUITPY_SDIOIO ?= 0 CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO) +CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) +CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) + # Currently always off. CIRCUITPY_STAGE ?= 0 CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE) diff --git a/py/qstr.c b/py/qstr.c index 17d8517c9..c9ba298fb 100755 --- a/py/qstr.c +++ b/py/qstr.c @@ -137,6 +137,7 @@ STATIC const byte *find_qstr(qstr q) { while (q < pool->total_prev_len) { pool = pool->prev; } + assert(q - pool->total_prev_len < pool->len); return pool->qstrs[q - pool->total_prev_len]; } diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c new file mode 100644 index 000000000..e8f4e970a --- /dev/null +++ b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c @@ -0,0 +1,92 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler 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 "py/objarray.h" +#include "py/runtime.h" + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" + +STATIC mp_obj_t sharpdisplay_framebuffer_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_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_spi_bus, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = 0} }, + { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 2000000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); + busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi_bus].u_obj); + + sharpdisplay_framebuffer_obj_t* self = &allocate_display_bus_or_raise()->sharpdisplay; + self->base.type = &sharpdisplay_framebuffer_type; + + common_hal_sharpdisplay_framebuffer_construct(self, spi, chip_select, args[ARG_baudrate].u_int, args[ARG_width].u_int, args[ARG_height].u_int); + + return MP_OBJ_FROM_PTR(self); +} + + +STATIC mp_int_t sharpdisplay_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t*)self_in; + // a readonly framebuffer would be unusual but not impossible + if ((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { + return 1; + } + *bufinfo = self->bufinfo; + return 0; +} + +STATIC mp_obj_t sharpdisplay_framebuffer_deinit(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t*)self_in; + common_hal_sharpdisplay_framebuffer_deinit(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(sharpdisplay_framebuffer_deinit_obj, sharpdisplay_framebuffer_deinit); + +STATIC const mp_rom_map_elem_t sharpdisplay_framebuffer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sharpdisplay_framebuffer_deinit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(sharpdisplay_framebuffer_locals_dict, sharpdisplay_framebuffer_locals_dict_table); + +const mp_obj_type_t sharpdisplay_framebuffer_type = { + { &mp_type_type }, + .name = MP_QSTR_SharpMemoryFramebuffer, + .buffer_p = { .get_buffer = sharpdisplay_framebuffer_get_buffer, }, + .make_new = sharpdisplay_framebuffer_make_new, + .protocol = &sharpdisplay_framebuffer_proto, + .locals_dict = (mp_obj_dict_t*)&sharpdisplay_framebuffer_locals_dict, +}; diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h new file mode 100644 index 000000000..30f1b867b --- /dev/null +++ b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler 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. + */ + +#pragma once + +// #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" +// #include "shared-module/framebufferio/FramebufferDisplay.h" + +#include "py/objtype.h" + +extern const mp_obj_type_t sharpdisplay_framebuffer_type; diff --git a/shared-bindings/sharpdisplay/__init__.c b/shared-bindings/sharpdisplay/__init__.c new file mode 100644 index 000000000..d1f728c61 --- /dev/null +++ b/shared-bindings/sharpdisplay/__init__.c @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" + +//| """Support for Sharp Memory Display framebuffers""" +//| + +STATIC const mp_rom_map_elem_t sharpdisplay_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sharpdisplay) }, + { MP_ROM_QSTR(MP_QSTR_SharpMemoryFramebuffer), MP_ROM_PTR(&sharpdisplay_framebuffer_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(sharpdisplay_module_globals, sharpdisplay_module_globals_table); + +const mp_obj_module_t sharpdisplay_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&sharpdisplay_module_globals, +}; diff --git a/shared-bindings/sharpdisplay/__init__.h b/shared-bindings/sharpdisplay/__init__.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index efc28470f..e52ec5b9e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -19,14 +19,19 @@ #include "supervisor/spi_flash_api.h" #include "py/mpconfig.h" +#if CIRCUITPY_SHARPDISPLAY +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" +#endif + primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -#if CIRCUITPY_RGBMATRIX -STATIC bool any_display_uses_this_rgbmatrix(rgbmatrix_rgbmatrix_obj_t* pm) { +#if CIRCUITPY_RGBMATRIX || CIRCUITPY_SHARPDISPLAY +STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) { framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display; - if (display->framebuffer == pm) { + if (display->framebuffer == obj) { return true; } } @@ -105,6 +110,10 @@ void common_hal_displayio_release_displays(void) { #if CIRCUITPY_FRAMEBUFFERIO } else if (bus_type == &rgbmatrix_RGBMatrix_type) { common_hal_rgbmatrix_rgbmatrix_deinit(&displays[i].rgbmatrix); +#endif +#if CIRCUITPY_SHARPDISPLAY + } else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) { + common_hal_sharpdisplay_framebuffer_deinit(&displays[i].sharpdisplay); #endif } displays[i].fourwire_bus.base.type = &mp_type_NoneType; @@ -170,9 +179,18 @@ void reset_displays(void) { #if CIRCUITPY_RGBMATRIX } else if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) { rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix; - if(!any_display_uses_this_rgbmatrix(pm)) { + if(!any_display_uses_this_framebuffer(&pm->base)) { common_hal_rgbmatrix_rgbmatrix_deinit(pm); } +#endif +#if CIRCUITPY_SHARPDISPLAY + } else if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) { + sharpdisplay_framebuffer_obj_t * sharp = &displays[i].sharpdisplay; + if(any_display_uses_this_framebuffer(&sharp->base)) { + common_hal_sharpdisplay_framebuffer_reset(sharp); + } else { + common_hal_sharpdisplay_framebuffer_deinit(sharp); + } #endif } else { // Not an active display bus. @@ -203,6 +221,11 @@ void displayio_gc_collect(void) { rgbmatrix_rgbmatrix_collect_ptrs(&displays[i].rgbmatrix); } #endif +#if CIRCUITPY_SHARPDISPLAY + if (displays[i].rgbmatrix.base.type == &sharpdisplay_framebuffer_type) { + common_hal_sharpdisplay_framebuffer_collect_ptrs(&displays[i].sharpdisplay); + } +#endif if (displays[i].display.base.type == NULL) { continue; diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 9eb10c28b..44ad5a9a9 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -36,18 +36,28 @@ #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/I2CDisplay.h" #include "shared-bindings/displayio/ParallelBus.h" +#if CIRCUITPY_RGBMATRIX #include "shared-bindings/rgbmatrix/RGBMatrix.h" +#endif +#if CIRCUITPY_SHARPDISPLAY +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" +#endif typedef struct { union { + mp_obj_base_t bus_base; displayio_fourwire_obj_t fourwire_bus; displayio_i2cdisplay_obj_t i2cdisplay_bus; displayio_parallelbus_obj_t parallel_bus; #if CIRCUITPY_RGBMATRIX rgbmatrix_rgbmatrix_obj_t rgbmatrix; +#endif +#if CIRCUITPY_SHARPDISPLAY + sharpdisplay_framebuffer_obj_t sharpdisplay; #endif }; union { + mp_obj_base_t display_base; displayio_display_obj_t display; displayio_epaperdisplay_obj_t epaper_display; #if CIRCUITPY_FRAMEBUFFERIO diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index 9a6797cd8..6b5346877 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -156,7 +156,7 @@ STATIC const displayio_area_t* _get_refresh_areas(framebufferio_framebufferdispl return NULL; } -#define MARK_ROW_DIRTY(r) (dirty_row_bitmask[r/8] = (1 << (r & 7))) +#define MARK_ROW_DIRTY(r) (dirty_row_bitmask[r/8] |= (1 << (r & 7))) STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area, uint8_t *dirty_row_bitmask) { uint16_t buffer_size = 128; // In uint32_ts @@ -250,6 +250,10 @@ STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const di } STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t* self) { + self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); + if(!self->bufinfo.buf) { + return; + } displayio_display_core_start_refresh(&self->core); const displayio_area_t* current_area = _get_refresh_areas(self); if (current_area) { @@ -348,17 +352,18 @@ void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { self->base.type = &mp_type_NoneType; } -void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { - common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true); - common_hal_framebufferio_framebufferdisplay_show(self, NULL); -} - void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self) { gc_collect_ptr(self->framebuffer); displayio_display_core_collect_ptrs(&self->core); } void framebufferio_framebufferdisplay_reset(framebufferio_framebufferdisplay_obj_t* self) { - common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true); - common_hal_framebufferio_framebufferdisplay_show(self, NULL); + mp_obj_type_t *fb_type = mp_obj_get_type(self->framebuffer); + if(fb_type != NULL && fb_type != &mp_type_NoneType) { + common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, true); + common_hal_framebufferio_framebufferdisplay_show(self, NULL); + self->core.full_refresh = true; + } else { + release_framebufferdisplay(self); + } } diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h index 027086b5a..111c9f670 100644 --- a/shared-module/framebufferio/FramebufferDisplay.h +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -55,7 +55,6 @@ typedef struct { void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self); void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self); -void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self); void framebufferio_framebufferdisplay_reset(framebufferio_framebufferdisplay_obj_t* self); void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self); @@ -73,7 +72,7 @@ typedef int (*framebuffer_get_first_pixel_offset_fun)(mp_obj_t); typedef int (*framebuffer_get_grayscale_fun)(mp_obj_t); typedef int (*framebuffer_get_height_fun)(mp_obj_t); typedef int (*framebuffer_get_native_frames_per_second_fun)(mp_obj_t); -typedef int (*framebuffer_get_pixels_in_byte_share_row_fun)(mp_obj_t); +typedef bool (*framebuffer_get_pixels_in_byte_share_row_fun)(mp_obj_t); typedef int (*framebuffer_get_row_stride_fun)(mp_obj_t); typedef int (*framebuffer_get_width_fun)(mp_obj_t); typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t); diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c new file mode 100644 index 000000000..ac9c22572 --- /dev/null +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c @@ -0,0 +1,282 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/gc.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" + +#include "supervisor/memory.h" + +#define SHARPMEM_BIT_WRITECMD_LSB (0x80) +#define SHARPMEM_BIT_VCOM_LSB (0x40) + +static inline void *hybrid_alloc(size_t sz) { + if (gc_alloc_possible()) { + return m_malloc(sz + sizeof(void*), true); + } else { + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); + if (!allocation) { + return NULL; + } + memset(allocation->ptr, 0, sz); + return allocation->ptr; + } +} + +static inline void hybrid_free(void *ptr_in) { + supervisor_allocation *allocation = allocation_from_ptr(ptr_in); + + if (allocation) { + free_memory(allocation); + } +} + +STATIC uint8_t bitrev(uint8_t n) { + uint8_t r = 0; + for(int i=0;i<8;i++) r |= ((n>>i) & 1)<<(7-i); + return r; +} + +int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self) { + return self->width; +} + +int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self) { + return self->height; +} + +int common_hal_sharpdisplay_framebuffer_get_row_stride(sharpdisplay_framebuffer_obj_t *self) { + return (self->width + 7) / 8 + 2; +} + +int common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(sharpdisplay_framebuffer_obj_t *self) { + return 2; +} + +bool common_hal_sharpdisplay_framebuffer_get_reverse_pixels_in_byte(sharpdisplay_framebuffer_obj_t *self) { + return true; +} + +bool common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(sharpdisplay_framebuffer_obj_t *self) { + return true; +} + +void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self) { + if (!allocation_from_ptr(self->bufinfo.buf)) { + self->bufinfo.buf = NULL; + } + + if (self->bus != &self->inline_bus +#if BOARD_SPI + && self->bus != common_hal_board_get_spi() +#endif + ) { + memcpy(&self->inline_bus, self->bus, sizeof(busio_spi_obj_t)); + self->bus = &self->inline_bus; + } +} + +void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self) { + +} + +void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo) { + if (!self->bufinfo.buf) { + int row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self); + int height = common_hal_sharpdisplay_framebuffer_get_height(self); + self->bufinfo.len = row_stride * height + 2; + self->bufinfo.buf = hybrid_alloc(self->bufinfo.len); + + uint8_t *data = self->bufinfo.buf; + *data++ = SHARPMEM_BIT_WRITECMD_LSB; + + for(int y=0; yfull_refresh = true; + } + *bufinfo = self->bufinfo; +} + +void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self) { + if (self->base.type != &sharpdisplay_framebuffer_type) { + return; + } + + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + common_hal_reset_pin(self->chip_select.pin); + + hybrid_free(self->bufinfo.buf); + + memset(self, 0, sizeof(*self)); +} + +void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *chip_select, int baudrate, int width, int height) { + common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); + common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + common_hal_never_reset_pin(chip_select); + + self->bus = spi; + common_hal_busio_spi_never_reset(self->bus); + + self->width = width; + self->height = height; + self->baudrate = baudrate; + + int row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self); + self->bufinfo.len = row_stride * height + 2; + self->bufinfo.buf = gc_alloc(self->bufinfo.len, false, true); + + uint8_t *data = self->bufinfo.buf; + *data++ = SHARPMEM_BIT_WRITECMD_LSB; + + for(int y=0; yheight; y++) { + *data = bitrev(y+1); + data += row_stride; + } + self->full_refresh = true; +} + +void common_hal_sharpdisplay_framebuffer_swapbuffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask) { + // claim SPI bus + if (!common_hal_busio_spi_try_lock(self->bus)) { + return; + } + common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8); + + // set chip select high + common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + + // output the toggling signal + uint8_t *data = self->bufinfo.buf; + data[0] ^= SHARPMEM_BIT_VCOM_LSB; + +#define PARTIAL_UPDATES (1) +#if PARTIAL_UPDATES + common_hal_busio_spi_write(self->bus, data++, 1); + + // output each changed row + size_t row_stride = common_hal_sharpdisplay_framebuffer_get_row_stride(self); + for(int y=0; yheight; y++) { + if(self->full_refresh || (dirty_row_bitmask[y/8] & (1 << (y & 7)))) { + common_hal_busio_spi_write(self->bus, data, row_stride); + } + data += row_stride; + } + + // output a trailing zero + common_hal_busio_spi_write(self->bus, data, 1); +#else + common_hal_busio_spi_write(self->bus, data, self->bufinfo.len); +#endif + + // set chip select low + common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + + // release SPI bus + common_hal_busio_spi_unlock(self->bus); + + self->full_refresh = false; +} + +STATIC void sharpdisplay_framebuffer_deinit(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + common_hal_sharpdisplay_framebuffer_deinit(self); +} + +STATIC void sharpdisplay_framebuffer_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + sharpdisplay_framebuffer_obj_t *self = self_in; + common_hal_sharpdisplay_framebuffer_get_bufinfo(self, bufinfo); +} + +STATIC int sharpdisplay_framebuffer_get_color_depth(mp_obj_t self_in) { + return 1; +} + +STATIC int sharpdisplay_framebuffer_get_height(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_height(self); +} + +STATIC int sharpdisplay_framebuffer_get_width(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_width(self); +} + +STATIC int sharpdisplay_framebuffer_get_first_pixel_offset(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_first_pixel_offset(self); +} + +STATIC bool sharpdisplay_framebuffer_get_pixels_in_byte_share_row(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(self); +} + +STATIC bool sharpdisplay_framebuffer_get_reverse_pixels_in_byte(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_reverse_pixels_in_byte(self); +} + +STATIC int sharpdisplay_framebuffer_get_row_stride(mp_obj_t self_in) { + sharpdisplay_framebuffer_obj_t *self = self_in; + return common_hal_sharpdisplay_framebuffer_get_row_stride(self); +} + +STATIC void sharpdisplay_framebuffer_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmask) { + sharpdisplay_framebuffer_obj_t *self = self_in; + common_hal_sharpdisplay_framebuffer_swapbuffers(self, dirty_row_bitmask); +} + +const framebuffer_p_t sharpdisplay_framebuffer_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .deinit = sharpdisplay_framebuffer_deinit, + .get_bufinfo = sharpdisplay_framebuffer_get_bufinfo, + .get_color_depth = sharpdisplay_framebuffer_get_color_depth, + .get_height = sharpdisplay_framebuffer_get_height, + .get_width = sharpdisplay_framebuffer_get_width, + .swapbuffers = sharpdisplay_framebuffer_swapbuffers, + + .get_first_pixel_offset = sharpdisplay_framebuffer_get_first_pixel_offset, + .get_pixels_in_byte_share_row = sharpdisplay_framebuffer_get_pixels_in_byte_share_row, + .get_reverse_pixels_in_byte = sharpdisplay_framebuffer_get_reverse_pixels_in_byte, + .get_row_stride = sharpdisplay_framebuffer_get_row_stride, +}; + +void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t *self) { + gc_collect_ptr(self->framebuffer); + gc_collect_ptr(self->bus); + gc_collect_ptr(self->bufinfo.buf); +} diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.h b/shared-module/sharpdisplay/SharpMemoryFramebuffer.h new file mode 100644 index 000000000..8acacc94e --- /dev/null +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.h @@ -0,0 +1,60 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler 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. + */ + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t framebuffer; + busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; + digitalio_digitalinout_obj_t chip_select; + mp_buffer_info_t bufinfo; + + uint16_t width, height; + uint32_t baudrate; + + bool full_refresh:1; +} sharpdisplay_framebuffer_obj_t; + +void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_t *self, busio_spi_obj_t *spi, mcu_pin_obj_t *chip_select, int baudrate, int width, int height); +void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); +void common_hal_sharpdisplay_framebuffer_deinit(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo); +int common_hal_sharpdisplay_framebuffer_get_height(sharpdisplay_framebuffer_obj_t *self); +int common_hal_sharpdisplay_framebuffer_get_width(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_swap_buffers(sharpdisplay_framebuffer_obj_t *self, uint8_t *dirty_row_bitmask); +void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self); +void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self); + +extern const framebuffer_p_t sharpdisplay_framebuffer_proto; + +void common_hal_sharpdisplay_framebuffer_collect_ptrs(sharpdisplay_framebuffer_obj_t*); diff --git a/shared-module/sharpdisplay/__init__.c b/shared-module/sharpdisplay/__init__.c new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/sharpdisplay/__init__.h b/shared-module/sharpdisplay/__init__.h new file mode 100644 index 000000000..e69de29bb diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 9c074209b..a86ef6396 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -38,6 +38,11 @@ #include "shared-module/displayio/__init__.h" #endif +#if CIRCUITPY_SHARPDISPLAY +#include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" +#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" +#endif + extern size_t blinka_bitmap_data[]; extern displayio_bitmap_t blinka_bitmap; extern displayio_group_t circuitpython_splash; @@ -116,15 +121,21 @@ void supervisor_display_move_memory(void) { grid->inline_tiles = false; } MP_STATE_VM(terminal_tilegrid_tiles) = NULL; - #if CIRCUITPY_RGBMATRIX for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) { - rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix; + #if CIRCUITPY_RGBMATRIX + if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) { + rgbmatrix_rgbmatrix_obj_t * pm = &displays[i].rgbmatrix; common_hal_rgbmatrix_rgbmatrix_reconstruct(pm, NULL); - } + } + #endif + #if CIRCUITPY_SHARPDISPLAY + if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) { + sharpdisplay_framebuffer_obj_t * sharp = &displays[i].sharpdisplay; + common_hal_sharpdisplay_framebuffer_reconstruct(sharp); + } + #endif } #endif - #endif } size_t blinka_bitmap_data[32] = { -- cgit v1.2.3 From 759ded9c38390c6d4328bd34aa211499b7e9f4f6 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 12 Aug 2020 07:39:12 -0500 Subject: Fix build errors when SHARPDISPLAY && !RGBMATRIX --- shared-module/displayio/__init__.c | 4 ++-- supervisor/shared/display.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'supervisor') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index e52ec5b9e..5afcba35e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -107,7 +107,7 @@ void common_hal_displayio_release_displays(void) { common_hal_displayio_i2cdisplay_deinit(&displays[i].i2cdisplay_bus); } else if (bus_type == &displayio_parallelbus_type) { common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); -#if CIRCUITPY_FRAMEBUFFERIO +#if CIRCUITPY_RGBMATRIX } else if (bus_type == &rgbmatrix_RGBMatrix_type) { common_hal_rgbmatrix_rgbmatrix_deinit(&displays[i].rgbmatrix); #endif @@ -222,7 +222,7 @@ void displayio_gc_collect(void) { } #endif #if CIRCUITPY_SHARPDISPLAY - if (displays[i].rgbmatrix.base.type == &sharpdisplay_framebuffer_type) { + if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type) { common_hal_sharpdisplay_framebuffer_collect_ptrs(&displays[i].sharpdisplay); } #endif diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index a86ef6396..08dd71404 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -39,6 +39,7 @@ #endif #if CIRCUITPY_SHARPDISPLAY +#include "shared-module/displayio/__init__.h" #include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" #endif -- cgit v1.2.3 From d01f5dc0bdb3ea98d4cf234b7c08c8cc36694c1a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 17 Aug 2020 17:17:59 -0700 Subject: Turn off terminalio for ja and ko The font is missing many characters and the build needs the space. We can optimize font storage when we get a good font. The serial output will work as usual. --- ports/atmel-samd/mpconfigport.mk | 10 +++++++ py/circuitpy_defns.mk | 5 +++- py/circuitpy_mpconfig.h | 10 +++++-- py/circuitpy_mpconfig.mk | 3 ++ supervisor/shared/display.c | 60 +++++++++++++++++++++++++++------------- supervisor/shared/display.h | 6 ++++ supervisor/shared/serial.c | 2 +- supervisor/supervisor.mk | 4 ++- 8 files changed, 75 insertions(+), 25 deletions(-) (limited to 'supervisor') diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 5788a160b..3fecf867e 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -47,6 +47,16 @@ USB_MSC_EP_NUM_OUT = 1 CIRCUITPY_ULAB = 0 +ifeq ($(TRANSLATION), ja) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CIRCUITPY_TERMINALIO = 0 +endif + +ifeq ($(TRANSLATION), ko) +RELEASE_NEEDS_CLEAN_BUILD = 1 +CIRCUITPY_TERMINALIO = 0 +endif + endif # samd21 # Put samd51-only choices here. diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 515b386f9..b70ae64a8 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -145,7 +145,7 @@ ifeq ($(CIRCUITPY_DIGITALIO),1) SRC_PATTERNS += digitalio/% endif ifeq ($(CIRCUITPY_DISPLAYIO),1) -SRC_PATTERNS += displayio/% terminalio/% fontio/% +SRC_PATTERNS += displayio/% endif ifeq ($(CIRCUITPY_VECTORIO),1) SRC_PATTERNS += vectorio/% @@ -237,6 +237,9 @@ endif ifeq ($(CIRCUITPY_SUPERVISOR),1) SRC_PATTERNS += supervisor/% endif +ifeq ($(CIRCUITPY_TERMINALIO),1) +SRC_PATTERNS += terminalio/% fontio/% +endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index f0e8adffa..12d667d8f 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -347,16 +347,20 @@ extern const struct _mp_obj_module_t displayio_module; extern const struct _mp_obj_module_t fontio_module; extern const struct _mp_obj_module_t terminalio_module; #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, -#define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, -#define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, #ifndef CIRCUITPY_DISPLAY_LIMIT #define CIRCUITPY_DISPLAY_LIMIT (1) #endif #else #define DISPLAYIO_MODULE +#define CIRCUITPY_DISPLAY_LIMIT (0) +#endif + +#if CIRCUITPY_DISPLAYIO && CIRCUITPY_TERMINALIO +#define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, +#define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, +#else #define FONTIO_MODULE #define TERMINALIO_MODULE -#define CIRCUITPY_DISPLAY_LIMIT (0) #endif #if CIRCUITPY_FRAMEBUFFERIO diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 56060fa59..bdc1e77d5 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -195,6 +195,9 @@ CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT) CIRCUITPY_SUPERVISOR ?= 1 CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR) +CIRCUITPY_TERMINALIO ?= $(CIRCUITPY_DISPLAYIO) +CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) + CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 08dd71404..634720d0a 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -29,6 +29,7 @@ #include #include "py/mpstate.h" +#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" @@ -48,15 +49,21 @@ extern size_t blinka_bitmap_data[]; extern displayio_bitmap_t blinka_bitmap; extern displayio_group_t circuitpython_splash; +#if CIRCUITPY_TERMINALIO static supervisor_allocation* tilegrid_tiles = NULL; +#endif void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { + // Default the scale to 2 because we may show blinka without the terminal for + // languages that don't have font support. + uint8_t scale = 2; + + #if CIRCUITPY_TERMINALIO displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; uint16_t width_in_tiles = (width_px - blinka_bitmap.width) / grid->tile_width; // determine scale based on h - uint8_t scale = 1; - if (width_in_tiles > 80) { - scale = 2; + if (width_in_tiles < 80) { + scale = 1; } width_in_tiles = (width_px - blinka_bitmap.width * scale) / (grid->tile_width * scale); uint16_t height_in_tiles = height_px / (grid->tile_height * scale); @@ -64,7 +71,6 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { if (remaining_pixels > 0) { height_in_tiles += 1; } - circuitpython_splash.scale = scale; uint16_t total_tiles = width_in_tiles * height_in_tiles; @@ -94,34 +100,42 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { grid->full_change = true; common_hal_terminalio_terminal_construct(&supervisor_terminal, grid, &supervisor_terminal_font); + #endif + + circuitpython_splash.scale = scale; } void supervisor_stop_terminal(void) { + #if CIRCUITPY_TERMINALIO if (tilegrid_tiles != NULL) { free_memory(tilegrid_tiles); tilegrid_tiles = NULL; supervisor_terminal_text_grid.inline_tiles = false; supervisor_terminal_text_grid.tiles = NULL; } + #endif } void supervisor_display_move_memory(void) { - #if CIRCUITPY_DISPLAYIO + #if CIRCUITPY_TERMINALIO displayio_tilegrid_t* grid = &supervisor_terminal_text_grid; - if (MP_STATE_VM(terminal_tilegrid_tiles) == NULL || grid->tiles != MP_STATE_VM(terminal_tilegrid_tiles)) { - return; - } - uint16_t total_tiles = grid->width_in_tiles * grid->height_in_tiles; + if (MP_STATE_VM(terminal_tilegrid_tiles) != NULL && + grid->tiles == MP_STATE_VM(terminal_tilegrid_tiles)) { + uint16_t total_tiles = grid->width_in_tiles * grid->height_in_tiles; - tilegrid_tiles = allocate_memory(align32_size(total_tiles), false); - if (tilegrid_tiles != NULL) { - memcpy(tilegrid_tiles->ptr, grid->tiles, total_tiles); - grid->tiles = (uint8_t*) tilegrid_tiles->ptr; - } else { - grid->tiles = NULL; - grid->inline_tiles = false; + tilegrid_tiles = allocate_memory(align32_size(total_tiles), false); + if (tilegrid_tiles != NULL) { + memcpy(tilegrid_tiles->ptr, grid->tiles, total_tiles); + grid->tiles = (uint8_t*) tilegrid_tiles->ptr; + } else { + grid->tiles = NULL; + grid->inline_tiles = false; + } + MP_STATE_VM(terminal_tilegrid_tiles) = NULL; } - MP_STATE_VM(terminal_tilegrid_tiles) = NULL; + #endif + + #if CIRCUITPY_DISPLAYIO for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { #if CIRCUITPY_RGBMATRIX if (displays[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) { @@ -254,18 +268,26 @@ displayio_tilegrid_t blinka_sprite = { .in_group = true }; +#if CIRCUITPY_TERMINALIO +#define CHILD_COUNT 2 displayio_group_child_t splash_children[2] = { {&blinka_sprite, &blinka_sprite}, {&supervisor_terminal_text_grid, &supervisor_terminal_text_grid} }; +#else +#define CHILD_COUNT 1 +displayio_group_child_t splash_children[1] = { + {&blinka_sprite, &blinka_sprite}, +}; +#endif displayio_group_t circuitpython_splash = { .base = {.type = &displayio_group_type }, .x = 0, .y = 0, .scale = 2, - .size = 2, - .max_size = 2, + .size = CHILD_COUNT, + .max_size = CHILD_COUNT, .children = splash_children, .item_removed = false, .in_group = false, diff --git a/supervisor/shared/display.h b/supervisor/shared/display.h index 2a2ccf46d..4110cfe8e 100644 --- a/supervisor/shared/display.h +++ b/supervisor/shared/display.h @@ -27,6 +27,10 @@ #ifndef MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H #define MICROPY_INCLUDED_SUPERVISOR_SHARED_DISPLAY_H +#include + +#if CIRCUITPY_TERMINALIO + #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/TileGrid.h" #include "shared-bindings/fontio/BuiltinFont.h" @@ -42,6 +46,8 @@ extern displayio_bitmap_t supervisor_terminal_font_bitmap; extern displayio_tilegrid_t supervisor_terminal_text_grid; extern terminalio_terminal_obj_t supervisor_terminal; +#endif + void supervisor_start_terminal(uint16_t width_px, uint16_t height_px); void supervisor_stop_terminal(void); diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 8eb78a90e..303f89e75 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -99,7 +99,7 @@ void serial_write_substring(const char* text, uint32_t length) { if (length == 0) { return; } -#if CIRCUITPY_DISPLAYIO +#if CIRCUITPY_TERMINALIO int errcode; common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode); #endif diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index a066fc0fd..25b240036 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -110,7 +110,9 @@ ifeq ($(CIRCUITPY_DISPLAYIO), 1) SRC_SUPERVISOR += \ supervisor/shared/display.c - SUPERVISOR_O += $(BUILD)/autogen_display_resources.o + ifeq ($(CIRCUITPY_TERMINALIO), 1) + SUPERVISOR_O += $(BUILD)/autogen_display_resources.o + endif endif ifndef USB_INTERFACE_NAME USB_INTERFACE_NAME = "CircuitPython" -- cgit v1.2.3