summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorfoamyguy <foamyguy@gmail.com>2020-11-08 18:32:15 -0600
committerGitHub <noreply@github.com>2020-11-08 18:32:15 -0600
commitcf21c4da601e00a614efd8ade774a0c8e5444c64 (patch)
tree118a157edbc1884f502de8e9e26f79d178ed8c9a /shared-module
parent7611e71a1bc49bcb426e0854519d5143eb262a17 (diff)
parenteec9821fdc19ca81c2d0811a6b6c5909a54b8c81 (diff)
Merge pull request #1 from adafruit/main
merge from adafruit
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/_stage/__init__.c2
-rw-r--r--shared-module/board/__init__.c30
-rw-r--r--shared-module/canio/Match.c43
-rw-r--r--shared-module/canio/Match.h36
-rw-r--r--shared-module/canio/Message.c77
-rw-r--r--shared-module/canio/Message.h37
-rw-r--r--shared-module/canio/RemoteTransmissionRequest.c67
-rw-r--r--shared-module/canio/RemoteTransmissionRequest.h33
-rw-r--r--shared-module/displayio/ColorConverter.c28
-rw-r--r--shared-module/displayio/ColorConverter.h1
-rw-r--r--shared-module/displayio/Display.c32
-rw-r--r--shared-module/displayio/Display.h2
-rw-r--r--shared-module/displayio/EPaperDisplay.c18
-rw-r--r--shared-module/displayio/EPaperDisplay.h1
-rw-r--r--shared-module/displayio/FourWire.c8
-rw-r--r--shared-module/displayio/I2CDisplay.c5
-rw-r--r--shared-module/displayio/Palette.h1
-rw-r--r--shared-module/displayio/__init__.c10
-rw-r--r--shared-module/displayio/display_core.c43
-rw-r--r--shared-module/displayio/display_core.h8
-rw-r--r--shared-module/framebufferio/FramebufferDisplay.c8
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.c20
-rw-r--r--shared-module/rgbmatrix/RGBMatrix.h2
-rw-r--r--shared-module/rgbmatrix/allocator.h4
-rw-r--r--shared-module/sharpdisplay/SharpMemoryFramebuffer.c28
25 files changed, 460 insertions, 84 deletions
diff --git a/shared-module/_stage/__init__.c b/shared-module/_stage/__init__.c
index 0323c32cb..6dfc18880 100644
--- a/shared-module/_stage/__init__.c
+++ b/shared-module/_stage/__init__.c
@@ -45,7 +45,7 @@ void render_stage(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1,
area.y2 = y1;
displayio_display_core_set_region_to_update(
&display->core, display->set_column_command, display->set_row_command,
- NO_COMMAND, NO_COMMAND, display->data_as_commands, false, &area);
+ NO_COMMAND, NO_COMMAND, display->data_as_commands, false, &area, display->SH1107_addressing);
while (!displayio_display_core_begin_transaction(&display->core)) {
RUN_BACKGROUND_TASKS;
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index 7d99f2d4e..2f1c34e56 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -55,13 +55,12 @@ mp_obj_t common_hal_board_get_i2c(void) {
}
mp_obj_t common_hal_board_create_i2c(void) {
- if (i2c_singleton != NULL) {
- return i2c_singleton;
- }
+ // All callers have either already verified this or come so early that it can't be otherwise.
+ assert(i2c_singleton == NULL || common_hal_busio_i2c_deinited(i2c_singleton));
busio_i2c_obj_t *self = &i2c_obj;
self->base.type = &busio_i2c_type;
- common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
+ common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 100000, 0);
i2c_singleton = (mp_obj_t)self;
return i2c_singleton;
}
@@ -79,9 +78,8 @@ mp_obj_t common_hal_board_get_spi(void) {
}
mp_obj_t common_hal_board_create_spi(void) {
- if (spi_singleton != NULL) {
- return spi_singleton;
- }
+ // All callers have either already verified this or come so early that it can't be otherwise.
+ assert(spi_singleton == NULL || common_hal_busio_spi_deinited(spi_singleton));
busio_spi_obj_t *self = &spi_obj;
self->base.type = &busio_spi_type;
@@ -139,14 +137,17 @@ void reset_board_busses(void) {
bool display_using_i2c = false;
#if CIRCUITPY_DISPLAYIO
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
- if (displays[i].i2cdisplay_bus.bus == i2c_singleton) {
+ if (displays[i].bus_base.type == &displayio_i2cdisplay_type && displays[i].i2cdisplay_bus.bus == i2c_singleton) {
display_using_i2c = true;
break;
}
}
#endif
- if (!display_using_i2c) {
- i2c_singleton = NULL;
+ if (i2c_singleton != NULL) {
+ if (!display_using_i2c) {
+ common_hal_busio_i2c_deinit(i2c_singleton);
+ i2c_singleton = NULL;
+ }
}
#endif
#if BOARD_SPI
@@ -167,9 +168,12 @@ void reset_board_busses(void) {
}
#endif
// make sure SPI lock is not held over a soft reset
- common_hal_busio_spi_unlock(&spi_obj);
- if (!display_using_spi) {
- spi_singleton = NULL;
+ if (spi_singleton != NULL) {
+ common_hal_busio_spi_unlock(spi_singleton);
+ if (!display_using_spi) {
+ common_hal_busio_spi_deinit(spi_singleton);
+ spi_singleton = NULL;
+ }
}
#endif
#if BOARD_UART
diff --git a/shared-module/canio/Match.c b/shared-module/canio/Match.c
new file mode 100644
index 000000000..b4e8616e9
--- /dev/null
+++ b/shared-module/canio/Match.c
@@ -0,0 +1,43 @@
+/*
+ * 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 "shared-module/canio/Match.h"
+
+void common_hal_canio_match_construct(canio_match_obj_t *self, int id, int mask, bool extended) {
+ self->id = id;
+ self->mask = mask;
+ self->extended = extended;
+}
+
+int common_hal_canio_match_get_id(const canio_match_obj_t *self) {
+ return self->id;
+}
+int common_hal_canio_match_get_mask(const canio_match_obj_t *self) {
+ return self->mask;
+}
+bool common_hal_canio_match_get_extended(const canio_match_obj_t *self) {
+ return self->extended;
+}
diff --git a/shared-module/canio/Match.h b/shared-module/canio/Match.h
new file mode 100644
index 000000000..b52191d7c
--- /dev/null
+++ b/shared-module/canio/Match.h
@@ -0,0 +1,36 @@
+/*
+ * 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"
+
+typedef struct {
+ mp_obj_base_t base;
+ int id;
+ int mask;
+ bool extended;
+} canio_match_obj_t;
diff --git a/shared-module/canio/Message.c b/shared-module/canio/Message.c
new file mode 100644
index 000000000..a1df4f693
--- /dev/null
+++ b/shared-module/canio/Message.c
@@ -0,0 +1,77 @@
+/*
+ * 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 "shared-module/canio/Message.h"
+
+#include <string.h>
+
+void common_hal_canio_message_construct(canio_message_obj_t *self, int id, void *data, size_t size, bool extended)
+{
+ self->id = id;
+ self->size = size;
+ self->extended = extended;
+ if (data) {
+ memcpy(self->data, data, size);
+ }
+}
+
+int common_hal_canio_message_get_id(const canio_message_obj_t *self)
+{
+ return self->id;
+}
+
+void common_hal_canio_message_set_id(canio_message_obj_t *self, int id)
+{
+ self->id = id;
+}
+
+
+const void *common_hal_canio_message_get_data(const canio_message_obj_t *self)
+{
+ return self->data;
+}
+
+const void common_hal_canio_message_set_data(canio_message_obj_t *self, const void *data, size_t size)
+{
+ self->size = size;
+ memcpy(self->data, data, size);
+}
+
+
+size_t common_hal_canio_message_get_length(const canio_message_obj_t *self)
+{
+ return self->size;
+}
+
+bool common_hal_canio_message_get_extended(const canio_message_obj_t *self)
+{
+ return self->extended;
+}
+
+void common_hal_canio_message_set_extended(canio_message_obj_t *self, bool extended)
+{
+ self->extended = extended;
+}
diff --git a/shared-module/canio/Message.h b/shared-module/canio/Message.h
new file mode 100644
index 000000000..1ca0d42e2
--- /dev/null
+++ b/shared-module/canio/Message.h
@@ -0,0 +1,37 @@
+/*
+ * 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"
+
+typedef struct {
+ mp_obj_base_t base;
+ int id;
+ uint8_t data[8];
+ size_t size:4;
+ bool extended:1;
+} canio_message_obj_t;
diff --git a/shared-module/canio/RemoteTransmissionRequest.c b/shared-module/canio/RemoteTransmissionRequest.c
new file mode 100644
index 000000000..9b4d5632f
--- /dev/null
+++ b/shared-module/canio/RemoteTransmissionRequest.c
@@ -0,0 +1,67 @@
+/*
+ * 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 "shared-module/canio/RemoteTransmissionRequest.h"
+#include "shared-bindings/canio/RemoteTransmissionRequest.h"
+
+#include <string.h>
+
+void common_hal_canio_remote_transmission_request_construct(canio_remote_transmission_request_obj_t *self, int id, size_t size, bool extended)
+{
+ self->id = id;
+ self->size = size;
+ self->extended = extended;
+}
+
+int common_hal_canio_remote_transmission_request_get_id(const canio_remote_transmission_request_obj_t *self)
+{
+ return self->id;
+}
+
+void common_hal_canio_remote_transmission_request_set_id(canio_remote_transmission_request_obj_t *self, int id)
+{
+ self->id = id;
+}
+
+size_t common_hal_canio_remote_transmission_request_get_length(const canio_remote_transmission_request_obj_t *self)
+{
+ return self->size;
+}
+
+void common_hal_canio_remote_transmission_request_set_length(canio_remote_transmission_request_obj_t *self, size_t size)
+{
+ self->size = size;
+}
+
+bool common_hal_canio_remote_transmission_request_get_extended(const canio_remote_transmission_request_obj_t *self)
+{
+ return self->extended;
+}
+
+void common_hal_canio_remote_transmission_request_set_extended(canio_remote_transmission_request_obj_t *self, bool extended)
+{
+ self->extended = extended;
+}
diff --git a/shared-module/canio/RemoteTransmissionRequest.h b/shared-module/canio/RemoteTransmissionRequest.h
new file mode 100644
index 000000000..2f09b19c6
--- /dev/null
+++ b/shared-module/canio/RemoteTransmissionRequest.h
@@ -0,0 +1,33 @@
+/*
+ * 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/canio/Message.h"
+
+typedef canio_message_obj_t canio_remote_transmission_request_obj_t;
diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c
index c2c3214aa..03ec99ceb 100644
--- a/shared-module/displayio/ColorConverter.c
+++ b/shared-module/displayio/ColorConverter.c
@@ -27,6 +27,7 @@
#include "shared-bindings/displayio/ColorConverter.h"
#include "py/misc.h"
+#include "py/runtime.h"
uint32_t displayio_colorconverter_dither_noise_1 (uint32_t n)
{
@@ -128,9 +129,27 @@ bool common_hal_displayio_colorconverter_get_dither(displayio_colorconverter_t*
return self->dither;
}
+void common_hal_displayio_colorconverter_make_transparent(displayio_colorconverter_t* self, uint32_t transparent_color) {
+ if (self->transparent_color >= 0x1000000) {
+ mp_raise_RuntimeError(translate("Only one color can be transparent at a time"));
+ }
+ self->transparent_color = transparent_color;
+}
+
+void common_hal_displayio_colorconverter_make_opaque(displayio_colorconverter_t* self, uint32_t transparent_color) {
+ (void) transparent_color;
+ // 0x1000000 will never equal a valid color
+ self->transparent_color = 0x1000000;
+}
+
void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t* colorspace, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) {
uint32_t pixel = input_pixel->pixel;
+ if (self->transparent_color == pixel) {
+ output_color->opaque = false;
+ return;
+ }
+
if (self->dither){
uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y));
uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x+33,input_pixel->tile_y));
@@ -146,9 +165,9 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
g8 = MIN(255,g8 + (randg&0x03));
} else {
int bitmask = 0xFF >> colorspace->depth;
- b8 = MIN(255,b8 + (randb&bitmask));
- r8 = MIN(255,r8 + (randr&bitmask));
- g8 = MIN(255,g8 + (randg&bitmask));
+ b8 = MIN(255,b8 + (randb & bitmask));
+ r8 = MIN(255,r8 + (randr & bitmask));
+ g8 = MIN(255,g8 + (randg & bitmask));
}
pixel = r8 << 16 | g8 << 8 | b8;
}
@@ -177,7 +196,8 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d
return;
} else if (colorspace->grayscale && colorspace->depth <= 8) {
uint8_t luma = displayio_colorconverter_compute_luma(pixel);
- output_color->pixel = luma >> (8 - colorspace->depth);
+ size_t bitmask = (1 << colorspace->depth) - 1;
+ output_color->pixel = (luma >> colorspace->grayscale_bit) & bitmask;
output_color->opaque = true;
return;
}
diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h
index 10b1604a4..b402625ef 100644
--- a/shared-module/displayio/ColorConverter.h
+++ b/shared-module/displayio/ColorConverter.h
@@ -36,6 +36,7 @@
typedef struct {
mp_obj_base_t base;
bool dither;
+ uint32_t transparent_color;
} displayio_colorconverter_t;
bool displayio_colorconverter_needs_refresh(displayio_colorconverter_t *self);
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 021159c0d..7c8c9280b 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -48,7 +48,9 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll,
uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin,
uint16_t brightness_command, mp_float_t brightness, bool auto_brightness,
- bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second, bool backlight_on_high) {
+ bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second,
+ bool backlight_on_high, bool SH1107_addressing) {
+
// Turn off auto-refresh as we init.
self->auto_refresh = false;
uint16_t ram_width = 0x100;
@@ -68,6 +70,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
self->first_manual_refresh = !auto_refresh;
self->data_as_commands = data_as_commands;
self->backlight_on_high = backlight_on_high;
+ self->SH1107_addressing = SH1107_addressing;
self->native_frames_per_second = native_frames_per_second;
self->native_ms_per_frame = 1000 / native_frames_per_second;
@@ -104,8 +107,6 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
i += 2 + data_size;
}
- supervisor_start_terminal(width, height);
-
// Always set the backlight type in case we're reusing memory.
self->backlight_inout.base.type = &mp_type_NoneType;
if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) {
@@ -240,11 +241,17 @@ STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t*
if (!displayio_display_core_clip_area(&self->core, area, &clipped)) {
return true;
}
- uint16_t subrectangles = 1;
uint16_t rows_per_buffer = displayio_area_height(&clipped);
uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth;
uint16_t pixels_per_buffer = displayio_area_size(&clipped);
- if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) {
+
+ uint16_t subrectangles = 1;
+ // for SH1107 and other boundary constrained controllers
+ // write one single row at a time
+ if (self->SH1107_addressing) {
+ subrectangles = rows_per_buffer; // vertical (column mode) write each separately (height times)
+ rows_per_buffer = 1;
+ } else if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) {
rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped);
if (rows_per_buffer == 0) {
rows_per_buffer = 1;
@@ -286,7 +293,9 @@ STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t*
}
remaining_rows -= rows_per_buffer;
- displayio_display_core_set_region_to_update(&self->core, self->set_column_command, self->set_row_command, NO_COMMAND, NO_COMMAND, self->data_as_commands, false, &subrectangle);
+ displayio_display_core_set_region_to_update(&self->core, self->set_column_command,
+ self->set_row_command, NO_COMMAND, NO_COMMAND, self->data_as_commands, false,
+ &subrectangle, self->SH1107_addressing);
uint16_t subrectangle_size_bytes;
if (self->core.colorspace.depth >= 8) {
@@ -317,11 +326,10 @@ STATIC bool _refresh_area(displayio_display_obj_t* self, const displayio_area_t*
}
STATIC void _refresh_display(displayio_display_obj_t* self) {
- if (!displayio_display_core_bus_free(&self->core)) {
- // Can't acquire display bus; skip updating this display. Try next display.
+ if (!displayio_display_core_start_refresh(&self->core)) {
+ // A refresh on this bus is already in progress. Try next display.
return;
}
- displayio_display_core_start_refresh(&self->core);
const displayio_area_t* current_area = _get_refresh_areas(self);
while (current_area != NULL) {
_refresh_area(self, current_area);
@@ -339,8 +347,10 @@ void common_hal_displayio_display_set_rotation(displayio_display_obj_t* self, in
self->core.height = tmp;
}
displayio_display_core_set_rotation(&self->core, rotation);
- supervisor_stop_terminal();
- supervisor_start_terminal(self->core.width, self->core.height);
+ if (self == &displays[0].display) {
+ supervisor_stop_terminal();
+ supervisor_start_terminal(self->core.width, self->core.height);
+ }
if (self->core.current_group != NULL) {
displayio_group_update_transform(self->core.current_group, &self->core.transform);
}
diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h
index bdb861aa0..cc9cd54c4 100644
--- a/shared-module/displayio/Display.h
+++ b/shared-module/displayio/Display.h
@@ -60,6 +60,8 @@ typedef struct {
bool auto_brightness;
bool updating_backlight;
bool backlight_on_high;
+ // new quirk for sh1107
+ bool SH1107_addressing;
} displayio_display_obj_t;
void displayio_display_background(displayio_display_obj_t* self);
diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c
index 6d9e915b4..514b99a13 100644
--- a/shared-module/displayio/EPaperDisplay.c
+++ b/shared-module/displayio/EPaperDisplay.c
@@ -49,7 +49,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t*
uint16_t set_column_window_command, uint16_t set_row_window_command,
uint16_t set_current_column_command, uint16_t set_current_row_command,
uint16_t write_black_ram_command, bool black_bits_inverted, uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, uint16_t refresh_display_command, mp_float_t refresh_time,
- const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select) {
+ const mcu_pin_obj_t* busy_pin, bool busy_state, mp_float_t seconds_per_frame, bool chip_select, bool grayscale) {
if (highlight_color != 0x000000) {
self->core.colorspace.tricolor = true;
self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color);
@@ -72,6 +72,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t*
self->refreshing = false;
self->milliseconds_per_frame = seconds_per_frame * 1000;
self->chip_select = chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED;
+ self->grayscale = grayscale;
self->start_sequence = start_sequence;
self->start_sequence_len = start_sequence_len;
@@ -90,8 +91,6 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t*
// TODO: Clear
}
- supervisor_start_terminal(width, height);
-
// Set the group after initialization otherwise we may send pixels while we delay in
// initialization.
common_hal_displayio_epaperdisplay_show(self, &circuitpython_splash);
@@ -232,14 +231,16 @@ bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t* self, c
uint32_t mask[mask_length];
uint8_t passes = 1;
- if (self->core.colorspace.tricolor) {
+ if (self->core.colorspace.tricolor || self->grayscale) {
passes = 2;
}
for (uint8_t pass = 0; pass < passes; pass++) {
uint16_t remaining_rows = displayio_area_height(&clipped);
if (self->set_row_window_command != NO_COMMAND) {
- displayio_display_core_set_region_to_update(&self->core, self->set_column_window_command, self->set_row_window_command, self->set_current_column_command, self->set_current_row_command, false, self->chip_select, &clipped);
+ displayio_display_core_set_region_to_update(&self->core, self->set_column_window_command,
+ self->set_row_window_command, self->set_current_column_command, self->set_current_row_command,
+ false, self->chip_select, &clipped, false /* SH1107_addressing */);
}
uint8_t write_command = self->write_black_ram_command;
@@ -269,8 +270,13 @@ bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t* self, c
memset(buffer, 0, buffer_size * sizeof(buffer[0]));
self->core.colorspace.grayscale = true;
+ self->core.colorspace.grayscale_bit = 7;
if (pass == 1) {
- self->core.colorspace.grayscale = false;
+ if (self->grayscale) { // 4-color grayscale
+ self->core.colorspace.grayscale_bit = 6;
+ } else { // Tri-color
+ self->core.colorspace.grayscale = false;
+ }
}
displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer);
diff --git a/shared-module/displayio/EPaperDisplay.h b/shared-module/displayio/EPaperDisplay.h
index 3b9f6e368..4103fe5fc 100644
--- a/shared-module/displayio/EPaperDisplay.h
+++ b/shared-module/displayio/EPaperDisplay.h
@@ -55,6 +55,7 @@ typedef struct {
bool black_bits_inverted;
bool color_bits_inverted;
bool refreshing;
+ bool grayscale;
display_chip_select_behavior_t chip_select;
} displayio_epaperdisplay_obj_t;
diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c
index 17e8cfa1d..8c56d7ab6 100644
--- a/shared-module/displayio/FourWire.c
+++ b/shared-module/displayio/FourWire.c
@@ -76,7 +76,9 @@ void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
common_hal_reset_pin(self->command.pin);
common_hal_reset_pin(self->chip_select.pin);
- common_hal_reset_pin(self->reset.pin);
+ if (self->reset.pin) {
+ common_hal_reset_pin(self->reset.pin);
+ }
}
bool common_hal_displayio_fourwire_reset(mp_obj_t obj) {
@@ -85,9 +87,9 @@ bool common_hal_displayio_fourwire_reset(mp_obj_t obj) {
return false;
}
common_hal_digitalio_digitalinout_set_value(&self->reset, false);
- common_hal_time_delay_ms(1);
+ common_hal_mcu_delay_us(1000);
common_hal_digitalio_digitalinout_set_value(&self->reset, true);
- common_hal_time_delay_ms(1);
+ common_hal_mcu_delay_us(1000);
return true;
}
diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c
index 0c8f2e69a..5bd03dcd6 100644
--- a/shared-module/displayio/I2CDisplay.c
+++ b/shared-module/displayio/I2CDisplay.c
@@ -53,6 +53,7 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
// Probe the bus to see if a device acknowledges the given address.
if (!common_hal_busio_i2c_probe(i2c, device_address)) {
+ self->base.type = &mp_type_NoneType;
mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), device_address);
}
@@ -71,7 +72,9 @@ void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
common_hal_busio_i2c_deinit(self->bus);
}
- common_hal_reset_pin(self->reset.pin);
+ if (self->reset.base.type == &digitalio_digitalinout_type) {
+ common_hal_digitalio_digitalinout_deinit(&self->reset);
+ }
}
bool common_hal_displayio_i2cdisplay_reset(mp_obj_t obj) {
diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h
index da72f250f..993912cc5 100644
--- a/shared-module/displayio/Palette.h
+++ b/shared-module/displayio/Palette.h
@@ -37,6 +37,7 @@ typedef struct {
uint8_t bytes_per_cell;
uint8_t tricolor_hue;
uint8_t tricolor_luma;
+ uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth.
bool grayscale;
bool tricolor;
bool pixels_in_byte_share_row;
diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c
index 101dac4b3..a9bb3b21b 100644
--- a/shared-module/displayio/__init__.c
+++ b/shared-module/displayio/__init__.c
@@ -40,8 +40,6 @@ STATIC bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
}
#endif
-// Check for recursive calls to displayio_background.
-bool displayio_background_in_progress = false;
void displayio_background(void) {
if (mp_hal_is_interrupted()) {
@@ -52,12 +50,6 @@ void displayio_background(void) {
return;
}
- if (displayio_background_in_progress) {
- // Don't allow recursive calls to this routine.
- return;
- }
-
- displayio_background_in_progress = true;
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
if (displays[i].display.base.type == NULL || displays[i].display.base.type == &mp_type_NoneType) {
@@ -75,8 +67,6 @@ void displayio_background(void) {
}
}
- // All done.
- displayio_background_in_progress = false;
}
void common_hal_displayio_release_displays(void) {
diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c
index 43f2d1937..57d33b565 100644
--- a/shared-module/displayio/display_core.c
+++ b/shared-module/displayio/display_core.c
@@ -48,6 +48,7 @@ void displayio_display_core_construct(displayio_display_core_t* self,
uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word) {
self->colorspace.depth = color_depth;
self->colorspace.grayscale = grayscale;
+ self->colorspace.grayscale_bit = 8 - color_depth;
self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row;
self->colorspace.bytes_per_cell = bytes_per_cell;
self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte;
@@ -85,7 +86,10 @@ void displayio_display_core_construct(displayio_display_core_t* self,
self->bus = bus;
- supervisor_start_terminal(width, height);
+ // (offsetof core is equal in all display types)
+ if (self == &displays[0].display.core) {
+ supervisor_start_terminal(width, height);
+ }
self->width = width;
self->height = height;
@@ -197,7 +201,7 @@ bool displayio_display_core_get_dither(displayio_display_core_t* self){
}
bool displayio_display_core_bus_free(displayio_display_core_t *self) {
- return self->bus_free(self->bus);
+ return !self->bus || self->bus_free(self->bus);
}
bool displayio_display_core_begin_transaction(displayio_display_core_t* self) {
@@ -208,7 +212,10 @@ void displayio_display_core_end_transaction(displayio_display_core_t* self) {
self->end_transaction(self->bus);
}
-void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area) {
+void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command,
+ uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command,
+ bool data_as_commands, bool always_toggle_chip_select,
+ displayio_area_t* area, bool SH1107_addressing) {
uint16_t x1 = area->x1;
uint16_t x2 = area->x2;
uint16_t y1 = area->y1;
@@ -253,8 +260,17 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
data[data_length++] = x2 >> 8;
data[data_length++] = x2 & 0xff;
}
+ // Quirk for SH1107 "SH1107_addressing"
+ // Note... column is y! page is x!
+ // Page address command = 0xB0
+ if (SH1107_addressing) {
+ // set the page to our x value
+ data[0] = 0xB0 | (x1 & 0x0F);
+ data_length = 1;
+ }
self->send(self->bus, data_type, chip_select, data, data_length);
displayio_display_core_end_transaction(self);
+
if (set_current_column_command != NO_COMMAND) {
uint8_t command = set_current_column_command;
displayio_display_core_begin_transaction(self);
@@ -283,7 +299,16 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
data[data_length++] = y2 >> 8;
data[data_length++] = y2 & 0xff;
}
+ // Quirk for SH1107 "SH1107_addressing"
+ // Note... column is y! page is x!
+ // Column lower command = 0x00, Column upper command = 0x10
+ if (SH1107_addressing) {
+ data[0] = y1 & 0x0F; // 0x00 to 0x0F
+ data[1] = (y1 >> 4 & 0x0F) | 0x10; // 0x10 to 0x17
+ data_length = 2;
+ }
self->send(self->bus, data_type, chip_select, data, data_length);
+
displayio_display_core_end_transaction(self);
if (set_current_row_command != NO_COMMAND) {
@@ -295,8 +320,17 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
}
}
-void displayio_display_core_start_refresh(displayio_display_core_t* self) {
+bool displayio_display_core_start_refresh(displayio_display_core_t* self) {
+ if (!displayio_display_core_bus_free(self)) {
+ // Can't acquire display bus; skip updating this display. Try next display.
+ return false;
+ }
+ if (self->refresh_in_progress) {
+ return false;
+ }
+ self->refresh_in_progress = true;
self->last_refresh = supervisor_ticks_ms64();
+ return true;
}
void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
@@ -305,6 +339,7 @@ void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
displayio_group_finish_refresh(self->current_group);
}
self->full_refresh = false;
+ self->refresh_in_progress = false;
self->last_refresh = supervisor_ticks_ms64();
}
diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h
index e4fd62d4a..fe6cb6f3f 100644
--- a/shared-module/displayio/display_core.h
+++ b/shared-module/displayio/display_core.h
@@ -54,6 +54,7 @@ typedef struct {
int16_t colstart;
int16_t rowstart;
bool full_refresh; // New group means we need to refresh the whole display.
+ bool refresh_in_progress;
} displayio_display_core_t;
void displayio_display_core_construct(displayio_display_core_t* self,
@@ -74,11 +75,14 @@ bool displayio_display_core_bus_free(displayio_display_core_t *self);
bool displayio_display_core_begin_transaction(displayio_display_core_t* self);
void displayio_display_core_end_transaction(displayio_display_core_t* self);
-void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command, uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command, bool data_as_commands, bool always_toggle_chip_select, displayio_area_t* area);
+void displayio_display_core_set_region_to_update(displayio_display_core_t* self, uint8_t column_command,
+ uint8_t row_command, uint16_t set_current_column_command, uint16_t set_current_row_command,
+ bool data_as_commands, bool always_toggle_chip_select,
+ displayio_area_t* area, bool SH1107_addressing);
void release_display_core(displayio_display_core_t* self);
-void displayio_display_core_start_refresh(displayio_display_core_t* self);
+bool displayio_display_core_start_refresh(displayio_display_core_t* self);
void displayio_display_core_finish_refresh(displayio_display_core_t* self);
void displayio_display_core_collect_ptrs(displayio_display_core_t* self);
diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c
index 5163c3a7b..03e121c91 100644
--- a/shared-module/framebufferio/FramebufferDisplay.c
+++ b/shared-module/framebufferio/FramebufferDisplay.c
@@ -96,8 +96,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu
common_hal_framebufferio_framebufferdisplay_set_rotation(self, rotation);
}
- supervisor_start_terminal(self->core.width, self->core.height);
-
// Set the group after initialization otherwise we may send pixels while we delay in
// initialization.
common_hal_framebufferio_framebufferdisplay_show(self, &circuitpython_splash);
@@ -282,8 +280,10 @@ void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_fram
self->core.height = tmp;
}
displayio_display_core_set_rotation(&self->core, rotation);
- supervisor_stop_terminal();
- supervisor_start_terminal(self->core.width, self->core.height);
+ if (self == &displays[0].framebuffer_display) {
+ supervisor_stop_terminal();
+ supervisor_start_terminal(self->core.width, self->core.height);
+ }
if (self->core.current_group != NULL) {
displayio_group_update_transform(self->core.current_group, &self->core.transform);
}
diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c
index 3007ca4db..94c3eda27 100644
--- a/shared-module/rgbmatrix/RGBMatrix.c
+++ b/shared-module/rgbmatrix/RGBMatrix.c
@@ -78,10 +78,10 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self,
// verify that the matrix is big enough
mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize-1), false);
} else {
- _PM_FREE(self->bufinfo.buf);
- _PM_FREE(self->protomatter.rgbPins);
- _PM_FREE(self->protomatter.addr);
- _PM_FREE(self->protomatter.screenData);
+ _PM_free(self->bufinfo.buf);
+ _PM_free(self->protomatter.rgbPins);
+ _PM_free(self->protomatter.addr);
+ _PM_free(self->protomatter.screenData);
self->framebuffer = NULL;
self->bufinfo.buf = common_hal_rgbmatrix_allocator_impl(self->bufsize);
@@ -164,13 +164,13 @@ void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t* self) {
free_pin(&self->oe_pin);
if (self->protomatter.rgbPins) {
- _PM_free(&self->protomatter);
+ _PM_deallocate(&self->protomatter);
}
memset(&self->protomatter, 0, sizeof(self->protomatter));
// If it was supervisor-allocated, it is supervisor-freed and the pointer
// is zeroed, otherwise the pointer is just zeroed
- _PM_FREE(self->bufinfo.buf);
+ _PM_free(self->bufinfo.buf);
self->base.type = NULL;
// If a framebuffer was passed in to the constructor, NULL the reference
@@ -190,6 +190,8 @@ void common_hal_rgbmatrix_rgbmatrix_set_paused(rgbmatrix_rgbmatrix_obj_t* self,
_PM_stop(&self->protomatter);
} else if (!paused && self->paused) {
_PM_resume(&self->protomatter);
+ _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
+ _PM_swapbuffer_maybe(&self->protomatter);
}
self->paused = paused;
}
@@ -199,8 +201,10 @@ bool common_hal_rgbmatrix_rgbmatrix_get_paused(rgbmatrix_rgbmatrix_obj_t* self)
}
void common_hal_rgbmatrix_rgbmatrix_refresh(rgbmatrix_rgbmatrix_obj_t* self) {
- _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
- _PM_swapbuffer_maybe(&self->protomatter);
+ if (!self->paused) {
+ _PM_convert_565(&self->protomatter, self->bufinfo.buf, self->width);
+ _PM_swapbuffer_maybe(&self->protomatter);
+ }
}
int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self) {
diff --git a/shared-module/rgbmatrix/RGBMatrix.h b/shared-module/rgbmatrix/RGBMatrix.h
index 19d7d5f2e..6dbc6fd41 100644
--- a/shared-module/rgbmatrix/RGBMatrix.h
+++ b/shared-module/rgbmatrix/RGBMatrix.h
@@ -26,7 +26,7 @@
#pragma once
-#include "lib/protomatter/core.h"
+#include "lib/protomatter/src/core.h"
extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
typedef struct {
diff --git a/shared-module/rgbmatrix/allocator.h b/shared-module/rgbmatrix/allocator.h
index 323fa5ec0..3431046d5 100644
--- a/shared-module/rgbmatrix/allocator.h
+++ b/shared-module/rgbmatrix/allocator.h
@@ -31,7 +31,7 @@
#include "py/misc.h"
#include "supervisor/memory.h"
-#define _PM_ALLOCATOR common_hal_rgbmatrix_allocator_impl
-#define _PM_FREE(x) (common_hal_rgbmatrix_free_impl((x)), (x)=NULL, (void)0)
+#define _PM_allocate common_hal_rgbmatrix_allocator_impl
+#define _PM_free(x) (common_hal_rgbmatrix_free_impl((x)), (x)=NULL, (void)0)
extern void *common_hal_rgbmatrix_allocator_impl(size_t sz);
extern void common_hal_rgbmatrix_free_impl(void *);
diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c
index 71e00d7f0..b199e98d6 100644
--- a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c
+++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c
@@ -34,21 +34,22 @@
#include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h"
#include "supervisor/memory.h"
+#include "supervisor/shared/safe_mode.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;
- }
+static void *hybrid_alloc(size_t sz) {
+ supervisor_allocation *allocation = allocate_memory(align32_size(sz), false);
+ if (allocation) {
memset(allocation->ptr, 0, sz);
return allocation->ptr;
}
+ if (gc_alloc_possible()) {
+ return m_malloc(sz, true);
+ }
+ reset_into_safe_mode(MEM_MANAGE);
+ return NULL; // unreached
}
static inline void hybrid_free(void *ptr_in) {
@@ -90,10 +91,6 @@ bool common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(sharpdispl
}
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()
@@ -105,7 +102,9 @@ void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *s
}
void common_hal_sharpdisplay_framebuffer_reconstruct(sharpdisplay_framebuffer_obj_t *self) {
-
+ if (!allocation_from_ptr(self->bufinfo.buf)) {
+ self->bufinfo.buf = NULL;
+ }
}
void common_hal_sharpdisplay_framebuffer_get_bufinfo(sharpdisplay_framebuffer_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -157,7 +156,8 @@ void common_hal_sharpdisplay_framebuffer_construct(sharpdisplay_framebuffer_obj_
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);
+ // re-use a supervisor allocation if possible
+ self->bufinfo.buf = hybrid_alloc(self->bufinfo.len);
uint8_t *data = self->bufinfo.buf;
*data++ = SHARPMEM_BIT_WRITECMD_LSB;